Fix reading Time zone rules using Julian days (#17672)
[platform/upstream/coreclr.git] / src / jit / gentree.h
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4
5 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7 XX                                                                           XX
8 XX                          GenTree                                          XX
9 XX                                                                           XX
10 XX  This is the node in the semantic tree graph. It represents the operation XX
11 XX  corresponding to the node, and other information during code-gen.        XX
12 XX                                                                           XX
13 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
14 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
15 */
16
17 /*****************************************************************************/
18 #ifndef _GENTREE_H_
19 #define _GENTREE_H_
20 /*****************************************************************************/
21
22 #include "vartype.h"   // For "var_types"
23 #include "target.h"    // For "regNumber"
24 #include "ssaconfig.h" // For "SsaConfig::RESERVED_SSA_NUM"
25 #include "reglist.h"
26 #include "valuenumtype.h"
27 #include "jitstd.h"
28 #include "jithashtable.h"
29 #include "nodeinfo.h"
30 #include "simd.h"
31 #include "namedintrinsiclist.h"
32
33 // Debugging GenTree is much easier if we add a magic virtual function to make the debugger able to figure out what type
34 // it's got. This is enabled by default in DEBUG. To enable it in RET builds (temporarily!), you need to change the
35 // build to define DEBUGGABLE_GENTREE=1, as well as pass /OPT:NOICF to the linker (or else all the vtables get merged,
36 // making the debugging value supplied by them useless). See protojit.nativeproj for a commented example of setting the
37 // build flags correctly.
38 #ifndef DEBUGGABLE_GENTREE
39 #ifdef DEBUG
40 #define DEBUGGABLE_GENTREE 1
41 #else // !DEBUG
42 #define DEBUGGABLE_GENTREE 0
43 #endif // !DEBUG
44 #endif // !DEBUGGABLE_GENTREE
45
46 // The SpecialCodeKind enum is used to indicate the type of special (unique)
47 // target block that will be targeted by an instruction.
48 // These are used by:
49 //   GenTreeBoundsChk nodes (SCK_RNGCHK_FAIL, SCK_ARG_EXCPN, SCK_ARG_RNG_EXCPN)
50 //     - these nodes have a field (gtThrowKind) to indicate which kind
51 //   GenTreeOps nodes, for which codegen will generate the branch
52 //     - it will use the appropriate kind based on the opcode, though it's not
53 //       clear why SCK_OVERFLOW == SCK_ARITH_EXCPN
54 // SCK_PAUSE_EXEC is not currently used.
55 //
56 enum SpecialCodeKind
57 {
58     SCK_NONE,
59     SCK_RNGCHK_FAIL,                // target when range check fails
60     SCK_PAUSE_EXEC,                 // target to stop (e.g. to allow GC)
61     SCK_DIV_BY_ZERO,                // target for divide by zero (Not used on X86/X64)
62     SCK_ARITH_EXCPN,                // target on arithmetic exception
63     SCK_OVERFLOW = SCK_ARITH_EXCPN, // target on overflow
64     SCK_ARG_EXCPN,                  // target on ArgumentException (currently used only for SIMD intrinsics)
65     SCK_ARG_RNG_EXCPN,              // target on ArgumentOutOfRangeException (currently used only for SIMD intrinsics)
66     SCK_COUNT
67 };
68
69 /*****************************************************************************/
70
71 enum genTreeOps : BYTE
72 {
73 #define GTNODE(en, st, cm, ok) GT_##en,
74 #include "gtlist.h"
75
76     GT_COUNT,
77
78 #ifdef _TARGET_64BIT_
79     // GT_CNS_NATIVELONG is the gtOper symbol for GT_CNS_LNG or GT_CNS_INT, depending on the target.
80     // For the 64-bit targets we will only use GT_CNS_INT as it used to represent all the possible sizes
81     GT_CNS_NATIVELONG = GT_CNS_INT,
82 #else
83     // For the 32-bit targets we use a GT_CNS_LNG to hold a 64-bit integer constant and GT_CNS_INT for all others.
84     // In the future when we retarget the JIT for x86 we should consider eliminating GT_CNS_LNG
85     GT_CNS_NATIVELONG = GT_CNS_LNG,
86 #endif
87 };
88
89 /*****************************************************************************
90  *
91  *  The following enum defines a set of bit flags that can be used
92  *  to classify expression tree nodes. Note that some operators will
93  *  have more than one bit set, as follows:
94  *
95  *          GTK_CONST    implies    GTK_LEAF
96  *          GTK_RELOP    implies    GTK_BINOP
97  *          GTK_LOGOP    implies    GTK_BINOP
98  */
99
100 enum genTreeKinds
101 {
102     GTK_SPECIAL = 0x0000, // unclassified operator (special handling reqd)
103
104     GTK_CONST = 0x0001, // constant     operator
105     GTK_LEAF  = 0x0002, // leaf         operator
106     GTK_UNOP  = 0x0004, // unary        operator
107     GTK_BINOP = 0x0008, // binary       operator
108     GTK_RELOP = 0x0010, // comparison   operator
109     GTK_LOGOP = 0x0020, // logical      operator
110 #ifdef LEGACY_BACKEND
111     GTK_ASGOP = 0x0040, // assignment   operator
112 #endif
113
114     GTK_KINDMASK = 0x007F, // operator kind mask
115
116     GTK_COMMUTE = 0x0080, // commutative  operator
117
118     GTK_EXOP = 0x0100, // Indicates that an oper for a node type that extends GenTreeOp (or GenTreeUnOp)
119                        // by adding non-node fields to unary or binary operator.
120
121     GTK_LOCAL = 0x0200, // is a local access (load, store, phi)
122
123     GTK_NOVALUE = 0x0400, // node does not produce a value
124     GTK_NOTLIR  = 0x0800, // node is not allowed in LIR
125
126     GTK_NOCONTAIN = 0x1000, // this node is a value, but may not be contained
127
128     /* Define composite value(s) */
129
130     GTK_SMPOP = (GTK_UNOP | GTK_BINOP | GTK_RELOP | GTK_LOGOP)
131 };
132
133 /*****************************************************************************/
134
135 #define SMALL_TREE_NODES 1
136
137 /*****************************************************************************/
138
139 enum gtCallTypes : BYTE
140 {
141     CT_USER_FUNC, // User function
142     CT_HELPER,    // Jit-helper
143     CT_INDIRECT,  // Indirect call
144
145     CT_COUNT // fake entry (must be last)
146 };
147
148 /*****************************************************************************/
149
150 struct BasicBlock;
151
152 struct InlineCandidateInfo;
153
154 typedef unsigned short AssertionIndex;
155
156 static const AssertionIndex NO_ASSERTION_INDEX = 0;
157
158 //------------------------------------------------------------------------
159 // GetAssertionIndex: return 1-based AssertionIndex from 0-based int index.
160 //
161 // Arguments:
162 //    index - 0-based index
163 // Return Value:
164 //    1-based AssertionIndex.
165 inline AssertionIndex GetAssertionIndex(unsigned index)
166 {
167     return (AssertionIndex)(index + 1);
168 }
169
170 class AssertionInfo
171 {
172     // true if the assertion holds on the bbNext edge instead of the bbJumpDest edge (for GT_JTRUE nodes)
173     unsigned short m_isNextEdgeAssertion : 1;
174     // 1-based index of the assertion
175     unsigned short m_assertionIndex : 15;
176
177     AssertionInfo(bool isNextEdgeAssertion, AssertionIndex assertionIndex)
178         : m_isNextEdgeAssertion(isNextEdgeAssertion), m_assertionIndex(assertionIndex)
179     {
180         assert(m_assertionIndex == assertionIndex);
181     }
182
183 public:
184     AssertionInfo() : AssertionInfo(false, 0)
185     {
186     }
187
188     AssertionInfo(AssertionIndex assertionIndex) : AssertionInfo(false, assertionIndex)
189     {
190     }
191
192     static AssertionInfo ForNextEdge(AssertionIndex assertionIndex)
193     {
194         // Ignore the edge information if there's no assertion
195         bool isNextEdge = (assertionIndex != NO_ASSERTION_INDEX);
196         return AssertionInfo(isNextEdge, assertionIndex);
197     }
198
199     void Clear()
200     {
201         m_isNextEdgeAssertion = 0;
202         m_assertionIndex      = NO_ASSERTION_INDEX;
203     }
204
205     bool HasAssertion() const
206     {
207         return m_assertionIndex != NO_ASSERTION_INDEX;
208     }
209
210     AssertionIndex GetAssertionIndex() const
211     {
212         return m_assertionIndex;
213     }
214
215     bool IsNextEdgeAssertion() const
216     {
217         return m_isNextEdgeAssertion;
218     }
219 };
220
221 /*****************************************************************************/
222
223 // GT_FIELD nodes will be lowered into more "code-gen-able" representations, like
224 // GT_IND's of addresses, or GT_LCL_FLD nodes.  We'd like to preserve the more abstract
225 // information, and will therefore annotate such lowered nodes with FieldSeq's.  A FieldSeq
226 // represents a (possibly) empty sequence of fields.  The fields are in the order
227 // in which they are dereferenced.  The first field may be an object field or a struct field;
228 // all subsequent fields must be struct fields.
229 struct FieldSeqNode
230 {
231     CORINFO_FIELD_HANDLE m_fieldHnd;
232     FieldSeqNode*        m_next;
233
234     FieldSeqNode(CORINFO_FIELD_HANDLE fieldHnd, FieldSeqNode* next) : m_fieldHnd(fieldHnd), m_next(next)
235     {
236     }
237
238     // returns true when this is the pseudo #FirstElem field sequence
239     bool IsFirstElemFieldSeq();
240
241     // returns true when this is the pseudo #ConstantIndex field sequence
242     bool IsConstantIndexFieldSeq();
243
244     // returns true when this is the the pseudo #FirstElem field sequence or the pseudo #ConstantIndex field sequence
245     bool IsPseudoField();
246
247     // Make sure this provides methods that allow it to be used as a KeyFuncs type in SimplerHash.
248     static int GetHashCode(FieldSeqNode fsn)
249     {
250         return static_cast<int>(reinterpret_cast<intptr_t>(fsn.m_fieldHnd)) ^
251                static_cast<int>(reinterpret_cast<intptr_t>(fsn.m_next));
252     }
253
254     static bool Equals(FieldSeqNode fsn1, FieldSeqNode fsn2)
255     {
256         return fsn1.m_fieldHnd == fsn2.m_fieldHnd && fsn1.m_next == fsn2.m_next;
257     }
258 };
259
260 // This class canonicalizes field sequences.
261 class FieldSeqStore
262 {
263     typedef JitHashTable<FieldSeqNode, /*KeyFuncs*/ FieldSeqNode, FieldSeqNode*> FieldSeqNodeCanonMap;
264
265     CompAllocator*        m_alloc;
266     FieldSeqNodeCanonMap* m_canonMap;
267
268     static FieldSeqNode s_notAField; // No value, just exists to provide an address.
269
270     // Dummy variables to provide the addresses for the "pseudo field handle" statics below.
271     static int FirstElemPseudoFieldStruct;
272     static int ConstantIndexPseudoFieldStruct;
273
274 public:
275     FieldSeqStore(CompAllocator* alloc);
276
277     // Returns the (canonical in the store) singleton field sequence for the given handle.
278     FieldSeqNode* CreateSingleton(CORINFO_FIELD_HANDLE fieldHnd);
279
280     // This is a special distinguished FieldSeqNode indicating that a constant does *not*
281     // represent a valid field sequence.  This is "infectious", in the sense that appending it
282     // (on either side) to any field sequence yields the "NotAField()" sequence.
283     static FieldSeqNode* NotAField()
284     {
285         return &s_notAField;
286     }
287
288     // Returns the (canonical in the store) field sequence representing the concatenation of
289     // the sequences represented by "a" and "b".  Assumes that "a" and "b" are canonical; that is,
290     // they are the results of CreateSingleton, NotAField, or Append calls.  If either of the arguments
291     // are the "NotAField" value, so is the result.
292     FieldSeqNode* Append(FieldSeqNode* a, FieldSeqNode* b);
293
294     // We have a few "pseudo" field handles:
295
296     // This treats the constant offset of the first element of something as if it were a field.
297     // Works for method table offsets of boxed structs, or first elem offset of arrays/strings.
298     static CORINFO_FIELD_HANDLE FirstElemPseudoField;
299
300     // If there is a constant index, we make a psuedo field to correspond to the constant added to
301     // offset of the indexed field.  This keeps the field sequence structure "normalized", especially in the
302     // case where the element type is a struct, so we might add a further struct field offset.
303     static CORINFO_FIELD_HANDLE ConstantIndexPseudoField;
304
305     static bool IsPseudoField(CORINFO_FIELD_HANDLE hnd)
306     {
307         return hnd == FirstElemPseudoField || hnd == ConstantIndexPseudoField;
308     }
309 };
310
311 class GenTreeUseEdgeIterator;
312 class GenTreeOperandIterator;
313
314 /*****************************************************************************/
315
316 // Forward declarations of the subtypes
317 #define GTSTRUCT_0(fn, en) struct GenTree##fn;
318 #define GTSTRUCT_1(fn, en) struct GenTree##fn;
319 #define GTSTRUCT_2(fn, en, en2) struct GenTree##fn;
320 #define GTSTRUCT_3(fn, en, en2, en3) struct GenTree##fn;
321 #define GTSTRUCT_4(fn, en, en2, en3, en4) struct GenTree##fn;
322 #define GTSTRUCT_N(fn, ...) struct GenTree##fn;
323 #define GTSTRUCT_2_SPECIAL(fn, en, en2) GTSTRUCT_2(fn, en, en2)
324 #define GTSTRUCT_3_SPECIAL(fn, en, en2, en3) GTSTRUCT_3(fn, en, en2, en3)
325 #include "gtstructs.h"
326
327 /*****************************************************************************/
328
329 #ifndef _HOST_64BIT_
330 #include <pshpack4.h>
331 #endif
332
333 struct GenTree
334 {
335 // We use GT_STRUCT_0 only for the category of simple ops.
336 #define GTSTRUCT_0(fn, en)                                                                                             \
337     GenTree##fn* As##fn()                                                                                              \
338     {                                                                                                                  \
339         assert(OperIsSimple());                                                                                        \
340         return reinterpret_cast<GenTree##fn*>(this);                                                                   \
341     }                                                                                                                  \
342     const GenTree##fn* As##fn() const                                                                                  \
343     {                                                                                                                  \
344         assert(OperIsSimple());                                                                                        \
345         return reinterpret_cast<const GenTree##fn*>(this);                                                             \
346     }                                                                                                                  \
347     GenTree##fn& As##fn##Ref()                                                                                         \
348     {                                                                                                                  \
349         return *As##fn();                                                                                              \
350     }                                                                                                                  \
351     __declspec(property(get = As##fn##Ref)) GenTree##fn& gt##fn;
352
353 #define GTSTRUCT_N(fn, ...)                                                                                            \
354     GenTree##fn* As##fn()                                                                                              \
355     {                                                                                                                  \
356         assert(OperIs(__VA_ARGS__));                                                                                   \
357         return reinterpret_cast<GenTree##fn*>(this);                                                                   \
358     }                                                                                                                  \
359     const GenTree##fn* As##fn() const                                                                                  \
360     {                                                                                                                  \
361         assert(OperIs(__VA_ARGS__));                                                                                   \
362         return reinterpret_cast<const GenTree##fn*>(this);                                                             \
363     }                                                                                                                  \
364     GenTree##fn& As##fn##Ref()                                                                                         \
365     {                                                                                                                  \
366         return *As##fn();                                                                                              \
367     }                                                                                                                  \
368     __declspec(property(get = As##fn##Ref)) GenTree##fn& gt##fn;
369
370 #define GTSTRUCT_1(fn, en) GTSTRUCT_N(fn, en)
371 #define GTSTRUCT_2(fn, en, en2) GTSTRUCT_N(fn, en, en2)
372 #define GTSTRUCT_3(fn, en, en2, en3) GTSTRUCT_N(fn, en, en2, en3)
373 #define GTSTRUCT_4(fn, en, en2, en3, en4) GTSTRUCT_N(fn, en, en2, en3, en4)
374 #define GTSTRUCT_2_SPECIAL(fn, en, en2) GTSTRUCT_2(fn, en, en2)
375 #define GTSTRUCT_3_SPECIAL(fn, en, en2, en3) GTSTRUCT_3(fn, en, en2, en3)
376
377 #include "gtstructs.h"
378
379     genTreeOps gtOper; // enum subtype BYTE
380     var_types  gtType; // enum subtype BYTE
381
382     genTreeOps OperGet() const
383     {
384         return gtOper;
385     }
386     var_types TypeGet() const
387     {
388         return gtType;
389     }
390
391 #ifdef DEBUG
392     genTreeOps gtOperSave; // Only used to save gtOper when we destroy a node, to aid debugging.
393 #endif
394
395 #if FEATURE_ANYCSE
396
397 #define NO_CSE (0)
398
399 #define IS_CSE_INDEX(x) (x != 0)
400 #define IS_CSE_USE(x) (x > 0)
401 #define IS_CSE_DEF(x) (x < 0)
402 #define GET_CSE_INDEX(x) ((x > 0) ? x : -x)
403 #define TO_CSE_DEF(x) (-x)
404
405     signed char gtCSEnum; // 0 or the CSE index (negated if def)
406                           // valid only for CSE expressions
407
408 #endif // FEATURE_ANYCSE
409
410     unsigned char gtLIRFlags; // Used for nodes that are in LIR. See LIR::Flags in lir.h for the various flags.
411
412 #if ASSERTION_PROP
413     AssertionInfo gtAssertionInfo; // valid only for non-GT_STMT nodes
414
415     bool GeneratesAssertion() const
416     {
417         return gtAssertionInfo.HasAssertion();
418     }
419
420     void ClearAssertion()
421     {
422         gtAssertionInfo.Clear();
423     }
424
425     AssertionInfo GetAssertionInfo() const
426     {
427         return gtAssertionInfo;
428     }
429
430     void SetAssertionInfo(AssertionInfo info)
431     {
432         gtAssertionInfo = info;
433     }
434 #endif
435
436 #if FEATURE_STACK_FP_X87
437     unsigned char gtFPlvl; // x87 stack depth at this node
438     void gtCopyFPlvl(GenTree* other)
439     {
440         gtFPlvl = other->gtFPlvl;
441     }
442     void gtSetFPlvl(unsigned level)
443     {
444         noway_assert(FitsIn<unsigned char>(level));
445         gtFPlvl = (unsigned char)level;
446     }
447 #else // FEATURE_STACK_FP_X87
448
449     void gtCopyFPlvl(GenTree* other)
450     {
451     }
452     void gtSetFPlvl(unsigned level)
453     {
454     }
455
456 #endif // FEATURE_STACK_FP_X87
457
458     //
459     // Cost metrics on the node. Don't allow direct access to the variable for setting.
460     //
461
462 public:
463 #ifdef DEBUG
464     // You are not allowed to read the cost values before they have been set in gtSetEvalOrder().
465     // Keep track of whether the costs have been initialized, and assert if they are read before being initialized.
466     // Obviously, this information does need to be initialized when a node is created.
467     // This is public so the dumpers can see it.
468
469     bool gtCostsInitialized;
470 #endif // DEBUG
471
472 #define MAX_COST UCHAR_MAX
473 #define IND_COST_EX 3 // execution cost for an indirection
474
475     __declspec(property(get = GetCostEx)) unsigned char gtCostEx; // estimate of expression execution cost
476
477     __declspec(property(get = GetCostSz)) unsigned char gtCostSz; // estimate of expression code size cost
478
479     unsigned char GetCostEx() const
480     {
481         assert(gtCostsInitialized);
482         return _gtCostEx;
483     }
484     unsigned char GetCostSz() const
485     {
486         assert(gtCostsInitialized);
487         return _gtCostSz;
488     }
489
490     // Set the costs. They are always both set at the same time.
491     // Don't use the "put" property: force calling this function, to make it more obvious in the few places
492     // that set the values.
493     // Note that costs are only set in gtSetEvalOrder() and its callees.
494     void SetCosts(unsigned costEx, unsigned costSz)
495     {
496         assert(costEx != (unsigned)-1); // looks bogus
497         assert(costSz != (unsigned)-1); // looks bogus
498         INDEBUG(gtCostsInitialized = true;)
499
500         _gtCostEx = (costEx > MAX_COST) ? MAX_COST : (unsigned char)costEx;
501         _gtCostSz = (costSz > MAX_COST) ? MAX_COST : (unsigned char)costSz;
502     }
503
504     // Opimized copy function, to avoid the SetCosts() function comparisons, and make it more clear that a node copy is
505     // happening.
506     void CopyCosts(const GenTree* const tree)
507     {
508         INDEBUG(gtCostsInitialized =
509                     tree->gtCostsInitialized;) // If the 'tree' costs aren't initialized, we'll hit an assert below.
510         _gtCostEx = tree->gtCostEx;
511         _gtCostSz = tree->gtCostSz;
512     }
513
514     // Same as CopyCosts, but avoids asserts if the costs we are copying have not been initialized.
515     // This is because the importer, for example, clones nodes, before these costs have been initialized.
516     // Note that we directly access the 'tree' costs, not going through the accessor functions (either
517     // directly or through the properties).
518     void CopyRawCosts(const GenTree* const tree)
519     {
520         INDEBUG(gtCostsInitialized = tree->gtCostsInitialized;)
521         _gtCostEx = tree->_gtCostEx;
522         _gtCostSz = tree->_gtCostSz;
523     }
524
525 private:
526     unsigned char _gtCostEx; // estimate of expression execution cost
527     unsigned char _gtCostSz; // estimate of expression code size cost
528
529     //
530     // Register or register pair number of the node.
531     //
532     CLANG_FORMAT_COMMENT_ANCHOR;
533
534 #ifdef DEBUG
535 public:
536     enum genRegTag
537     {
538         GT_REGTAG_NONE, // Nothing has been assigned to _gtRegNum/_gtRegPair
539         GT_REGTAG_REG,  // _gtRegNum  has been assigned
540 #if CPU_LONG_USES_REGPAIR
541         GT_REGTAG_REGPAIR // _gtRegPair has been assigned
542 #endif
543     };
544     genRegTag GetRegTag() const
545     {
546 #if CPU_LONG_USES_REGPAIR
547         assert(gtRegTag == GT_REGTAG_NONE || gtRegTag == GT_REGTAG_REG || gtRegTag == GT_REGTAG_REGPAIR);
548 #else
549         assert(gtRegTag == GT_REGTAG_NONE || gtRegTag == GT_REGTAG_REG);
550 #endif
551         return gtRegTag;
552     }
553
554 private:
555     genRegTag gtRegTag; // What is in _gtRegNum/_gtRegPair?
556 #endif                  // DEBUG
557
558 private:
559     union {
560         // These store the register assigned to the node. If a register is not assigned, _gtRegNum is set to REG_NA
561         // or _gtRegPair is set to REG_PAIR_NONE, depending on the node type.
562         // For the LEGACY_BACKEND,these are valid only if GTF_REG_VAL is set in gtFlags.
563         regNumberSmall _gtRegNum;  // which register      the value is in
564         regPairNoSmall _gtRegPair; // which register pair the value is in
565     };
566
567 public:
568     // The register number is stored in a small format (8 bits), but the getters return and the setters take
569     // a full-size (unsigned) format, to localize the casts here.
570
571     __declspec(property(get = GetRegNum, put = SetRegNum)) regNumber gtRegNum;
572
573     bool canBeContained() const;
574
575     // for codegen purposes, is this node a subnode of its parent
576     bool isContained() const;
577
578     bool isContainedIndir() const;
579
580     bool isIndirAddrMode();
581
582     bool isIndir() const;
583
584     bool isContainedIntOrIImmed() const
585     {
586         return isContained() && IsCnsIntOrI() && !isUsedFromSpillTemp();
587     }
588
589     bool isContainedFltOrDblImmed() const
590     {
591         return isContained() && (OperGet() == GT_CNS_DBL);
592     }
593
594     bool isLclField() const
595     {
596         return OperGet() == GT_LCL_FLD || OperGet() == GT_STORE_LCL_FLD;
597     }
598
599     bool isUsedFromSpillTemp() const;
600
601     // Indicates whether it is a memory op.
602     // Right now it includes Indir and LclField ops.
603     bool isMemoryOp() const
604     {
605         return isIndir() || isLclField();
606     }
607
608     bool isUsedFromMemory() const
609     {
610         return ((isContained() && (isMemoryOp() || (OperGet() == GT_LCL_VAR) || (OperGet() == GT_CNS_DBL))) ||
611                 isUsedFromSpillTemp());
612     }
613
614     bool isLclVarUsedFromMemory() const
615     {
616         return (OperGet() == GT_LCL_VAR) && (isContained() || isUsedFromSpillTemp());
617     }
618
619     bool isLclFldUsedFromMemory() const
620     {
621         return isLclField() && (isContained() || isUsedFromSpillTemp());
622     }
623
624     bool isUsedFromReg() const
625     {
626         return !isContained() && !isUsedFromSpillTemp();
627     }
628
629     regNumber GetRegNum() const
630     {
631         assert((gtRegTag == GT_REGTAG_REG) || (gtRegTag == GT_REGTAG_NONE)); // TODO-Cleanup: get rid of the NONE case,
632                                                                              // and fix everyplace that reads undefined
633                                                                              // values
634         regNumber reg = (regNumber)_gtRegNum;
635         assert((gtRegTag == GT_REGTAG_NONE) || // TODO-Cleanup: get rid of the NONE case, and fix everyplace that reads
636                                                // undefined values
637                (reg >= REG_FIRST && reg <= REG_COUNT));
638         return reg;
639     }
640
641     void SetRegNum(regNumber reg)
642     {
643         assert(reg >= REG_FIRST && reg <= REG_COUNT);
644         // Make sure the upper bits of _gtRegPair are clear
645         _gtRegPair = (regPairNoSmall)0;
646         _gtRegNum  = (regNumberSmall)reg;
647         INDEBUG(gtRegTag = GT_REGTAG_REG;)
648         assert(_gtRegNum == reg);
649     }
650
651 #if CPU_LONG_USES_REGPAIR
652     __declspec(property(get = GetRegPair, put = SetRegPair)) regPairNo gtRegPair;
653
654     regPairNo GetRegPair() const
655     {
656         assert((gtRegTag == GT_REGTAG_REGPAIR) || (gtRegTag == GT_REGTAG_NONE)); // TODO-Cleanup: get rid of the NONE
657                                                                                  // case, and fix everyplace that reads
658                                                                                  // undefined values
659         regPairNo regPair = (regPairNo)_gtRegPair;
660         assert((gtRegTag == GT_REGTAG_NONE) || // TODO-Cleanup: get rid of the NONE case, and fix everyplace that reads
661                                                // undefined values
662                (regPair >= REG_PAIR_FIRST && regPair <= REG_PAIR_LAST) ||
663                (regPair == REG_PAIR_NONE)); // allow initializing to an undefined value
664         return regPair;
665     }
666
667     void SetRegPair(regPairNo regPair)
668     {
669         assert((regPair >= REG_PAIR_FIRST && regPair <= REG_PAIR_LAST) ||
670                (regPair == REG_PAIR_NONE)); // allow initializing to an undefined value
671         _gtRegPair = (regPairNoSmall)regPair;
672         INDEBUG(gtRegTag = GT_REGTAG_REGPAIR;)
673         assert(_gtRegPair == regPair);
674     }
675 #endif
676
677     // Copy the _gtRegNum/_gtRegPair/gtRegTag fields
678     void CopyReg(GenTree* from);
679     bool gtHasReg() const;
680
681     int GetRegisterDstCount() const;
682
683     regMaskTP gtGetRegMask() const;
684
685     unsigned gtFlags; // see GTF_xxxx below
686
687 #if defined(DEBUG)
688     unsigned gtDebugFlags; // see GTF_DEBUG_xxx below
689 #endif                     // defined(DEBUG)
690
691     ValueNumPair gtVNPair;
692
693     regMaskSmall gtRsvdRegs; // set of fixed trashed  registers
694
695 #ifndef LEGACY_BACKEND
696     unsigned AvailableTempRegCount(regMaskTP mask = (regMaskTP)-1) const;
697     regNumber GetSingleTempReg(regMaskTP mask = (regMaskTP)-1);
698     regNumber ExtractTempReg(regMaskTP mask = (regMaskTP)-1);
699 #endif // !LEGACY_BACKEND
700
701 #ifdef LEGACY_BACKEND
702     regMaskSmall gtUsedRegs; // set of used (trashed) registers
703 #endif                       // LEGACY_BACKEND
704
705     void SetVNsFromNode(GenTree* tree)
706     {
707         gtVNPair = tree->gtVNPair;
708     }
709
710     ValueNum GetVN(ValueNumKind vnk) const
711     {
712         if (vnk == VNK_Liberal)
713         {
714             return gtVNPair.GetLiberal();
715         }
716         else
717         {
718             assert(vnk == VNK_Conservative);
719             return gtVNPair.GetConservative();
720         }
721     }
722     void SetVN(ValueNumKind vnk, ValueNum vn)
723     {
724         if (vnk == VNK_Liberal)
725         {
726             return gtVNPair.SetLiberal(vn);
727         }
728         else
729         {
730             assert(vnk == VNK_Conservative);
731             return gtVNPair.SetConservative(vn);
732         }
733     }
734     void SetVNs(ValueNumPair vnp)
735     {
736         gtVNPair = vnp;
737     }
738     void ClearVN()
739     {
740         gtVNPair = ValueNumPair(); // Initializes both elements to "NoVN".
741     }
742
743 // clang-format off
744
745 //---------------------------------------------------------------------
746 //
747 // GenTree flags stored in gtFlags.
748 //
749 //---------------------------------------------------------------------
750
751 //---------------------------------------------------------------------
752 //  The first set of flags can be used with a large set of nodes, and
753 //  thus they must all have distinct values. That is, one can test any
754 //  expression node for one of these flags.
755 //---------------------------------------------------------------------
756
757 #define GTF_ASG           0x00000001 // sub-expression contains an assignment
758 #define GTF_CALL          0x00000002 // sub-expression contains a  func. call
759 #define GTF_EXCEPT        0x00000004 // sub-expression might throw an exception
760 #define GTF_GLOB_REF      0x00000008 // sub-expression uses global variable(s)
761 #define GTF_ORDER_SIDEEFF 0x00000010 // sub-expression has a re-ordering side effect
762
763 // If you set these flags, make sure that code:gtExtractSideEffList knows how to find the tree,
764 // otherwise the C# (run csc /o-) code:
765 //     var v = side_eff_operation
766 // with no use of v will drop your tree on the floor.
767 #define GTF_PERSISTENT_SIDE_EFFECTS (GTF_ASG | GTF_CALL)
768 #define GTF_SIDE_EFFECT             (GTF_PERSISTENT_SIDE_EFFECTS | GTF_EXCEPT)
769 #define GTF_GLOB_EFFECT             (GTF_SIDE_EFFECT | GTF_GLOB_REF)
770 #define GTF_ALL_EFFECT              (GTF_GLOB_EFFECT | GTF_ORDER_SIDEEFF)
771
772 // The extra flag GTF_IS_IN_CSE is used to tell the consumer of these flags
773 // that we are calling in the context of performing a CSE, thus we
774 // should allow the run-once side effects of running a class constructor.
775 //
776 // The only requirement of this flag is that it not overlap any of the
777 // side-effect flags. The actual bit used is otherwise arbitrary.
778 #define GTF_IS_IN_CSE GTF_BOOLEAN
779 #define GTF_PERSISTENT_SIDE_EFFECTS_IN_CSE (GTF_ASG | GTF_CALL | GTF_IS_IN_CSE)
780
781 // Can any side-effects be observed externally, say by a caller method?
782 // For assignments, only assignments to global memory can be observed
783 // externally, whereas simple assignments to local variables can not.
784 //
785 // Be careful when using this inside a "try" protected region as the
786 // order of assignments to local variables would need to be preserved
787 // wrt side effects if the variables are alive on entry to the
788 // "catch/finally" region. In such cases, even assignments to locals
789 // will have to be restricted.
790 #define GTF_GLOBALLY_VISIBLE_SIDE_EFFECTS(flags)                                                                       \
791     (((flags) & (GTF_CALL | GTF_EXCEPT)) || (((flags) & (GTF_ASG | GTF_GLOB_REF)) == (GTF_ASG | GTF_GLOB_REF)))
792
793 #define GTF_REVERSE_OPS 0x00000020 // operand op2 should be evaluated before op1 (normally, op1 is evaluated first and op2 is evaluated second)
794
795 #ifdef LEGACY_BACKEND
796 #define GTF_REG_VAL     0x00000040 // operand is sitting in a register (or part of a TYP_LONG operand is sitting in a register)
797 #else  // !LEGACY_BACKEND
798 #define GTF_CONTAINED   0x00000040 // This node is contained (executed as part of its parent)
799 #endif // !LEGACY_BACKEND
800
801 #define GTF_SPILLED     0x00000080 // the value has been spilled
802
803 #ifdef LEGACY_BACKEND
804 #define GTF_SPILLED_OPER 0x00000100 // op1 has been spilled
805 #define GTF_SPILLED_OP2  0x00000200 // op2 has been spilled
806 #define GTF_ZSF_SET      0x00000400 // the zero(ZF) and sign(SF) flags set to the operand
807 #else  // !LEGACY_BACKEND
808 #define GTF_NOREG_AT_USE 0x00000100 // tree node is in memory at the point of use
809 #endif // !LEGACY_BACKEND
810
811 #define GTF_SET_FLAGS   0x00000800 // Requires that codegen for this node set the flags. Use gtSetFlags() to check this flag.
812 #define GTF_USE_FLAGS   0x00001000 // Indicates that this node uses the flags bits.
813
814 #define GTF_MAKE_CSE    0x00002000 // Hoisted expression: try hard to make this into CSE (see optPerformHoistExpr)
815 #define GTF_DONT_CSE    0x00004000 // Don't bother CSE'ing this expr
816 #define GTF_COLON_COND  0x00008000 // This node is conditionally executed (part of ? :)
817
818 #define GTF_NODE_MASK (GTF_COLON_COND)
819
820 #define GTF_BOOLEAN     0x00040000 // value is known to be 0/1
821 #if CPU_HAS_BYTE_REGS && defined(LEGACY_BACKEND)
822 #define GTF_SMALL_OK    0x00080000 // actual small int sufficient
823 #endif
824
825 #define GTF_UNSIGNED    0x00100000 // With GT_CAST:   the source operand is an unsigned type
826                                    // With operators: the specified node is an unsigned operator
827 #define GTF_LATE_ARG    0x00200000 // The specified node is evaluated to a temp in the arg list, and this temp is added to gtCallLateArgs.
828 #define GTF_SPILL       0x00400000 // Needs to be spilled here
829
830 #define GTF_COMMON_MASK 0x007FFFFF // mask of all the flags above
831
832 #define GTF_REUSE_REG_VAL 0x00800000 // This is set by the register allocator on nodes whose value already exists in the
833                                      // register assigned to this node, so the code generator does not have to generate
834                                      // code to produce the value. It is currently used only on constant nodes.
835                                      // It CANNOT be set on var (GT_LCL*) nodes, or on indir (GT_IND or GT_STOREIND) nodes, since
836                                      // it is not needed for lclVars and is highly unlikely to be useful for indir nodes.
837
838 //---------------------------------------------------------------------
839 //  The following flags can be used only with a small set of nodes, and
840 //  thus their values need not be distinct (other than within the set
841 //  that goes with a particular node/nodes, of course). That is, one can
842 //  only test for one of these flags if the 'gtOper' value is tested as
843 //  well to make sure it's the right operator for the particular flag.
844 //---------------------------------------------------------------------
845
846 // NB: GTF_VAR_* and GTF_REG_* share the same namespace of flags, because
847 // GT_LCL_VAR nodes may be changed to GT_REG_VAR nodes without resetting
848 // the flags. These are also used by GT_LCL_FLD.
849 #define GTF_VAR_DEF         0x80000000 // GT_LCL_VAR -- this is a definition
850 #define GTF_VAR_USEASG      0x40000000 // GT_LCL_VAR -- this is a use/def for a x<op>=y
851 #define GTF_VAR_CAST        0x10000000 // GT_LCL_VAR -- has been explictly cast (variable node may not be type of local)
852 #define GTF_VAR_ITERATOR    0x08000000 // GT_LCL_VAR -- this is a iterator reference in the loop condition
853 #define GTF_VAR_CLONED      0x01000000 // GT_LCL_VAR -- this node has been cloned or is a clone
854                                        // Relevant for inlining optimizations (see fgInlinePrependStatements)
855
856 // TODO-Cleanup: Currently, GTF_REG_BIRTH is used only by stackfp
857 //         We should consider using it more generally for VAR_BIRTH, instead of
858 //         GTF_VAR_DEF && !GTF_VAR_USEASG
859 #define GTF_REG_BIRTH       0x04000000 // GT_REG_VAR -- enregistered variable born here
860 #define GTF_VAR_DEATH       0x02000000 // GT_LCL_VAR, GT_REG_VAR -- variable dies here (last use)
861
862 #define GTF_VAR_ARR_INDEX   0x00000020 // The variable is part of (the index portion of) an array index expression.
863                                        // Shares a value with GTF_REVERSE_OPS, which is meaningless for local var.
864
865 #define GTF_LIVENESS_MASK (GTF_VAR_DEF | GTF_VAR_USEASG | GTF_REG_BIRTH | GTF_VAR_DEATH)
866
867 #define GTF_CALL_UNMANAGED          0x80000000 // GT_CALL -- direct call to unmanaged code
868 #define GTF_CALL_INLINE_CANDIDATE   0x40000000 // GT_CALL -- this call has been marked as an inline candidate
869
870 #define GTF_CALL_VIRT_KIND_MASK     0x30000000 // GT_CALL -- mask of the below call kinds
871 #define GTF_CALL_NONVIRT            0x00000000 // GT_CALL -- a non virtual call
872 #define GTF_CALL_VIRT_STUB          0x10000000 // GT_CALL -- a stub-dispatch virtual call
873 #define GTF_CALL_VIRT_VTABLE        0x20000000 // GT_CALL -- a  vtable-based virtual call
874
875 #define GTF_CALL_NULLCHECK          0x08000000 // GT_CALL -- must check instance pointer for null
876 #define GTF_CALL_POP_ARGS           0x04000000 // GT_CALL -- caller pop arguments?
877 #define GTF_CALL_HOISTABLE          0x02000000 // GT_CALL -- call is hoistable
878 #ifdef LEGACY_BACKEND
879 #ifdef _TARGET_ARM_
880 // The GTF_CALL_REG_SAVE flag indicates that the call preserves all integer registers. This is used for
881 // the PollGC helper. However, since the PollGC helper on ARM follows the standard calling convention,
882 // for that target we don't use this flag.
883 #define GTF_CALL_REG_SAVE           0x00000000
884 #else
885 #define GTF_CALL_REG_SAVE           0x01000000 // GT_CALL -- This call preserves all integer regs
886 #endif // _TARGET_ARM_
887 #endif // LEGACY_BACKEND
888                                                // For additional flags for GT_CALL node see GTF_CALL_M_*
889
890 #define GTF_NOP_DEATH               0x40000000 // GT_NOP -- operand dies here
891
892 #define GTF_FLD_NULLCHECK           0x80000000 // GT_FIELD -- need to nullcheck the "this" pointer
893 #define GTF_FLD_VOLATILE            0x40000000 // GT_FIELD/GT_CLS_VAR -- same as GTF_IND_VOLATILE
894 #define GTF_FLD_INITCLASS           0x20000000 // GT_FIELD/GT_CLS_VAR -- field access requires preceding class/static init helper
895
896 #define GTF_INX_RNGCHK              0x80000000 // GT_INDEX/GT_INDEX_ADDR -- the array reference should be range-checked.
897 #define GTF_INX_REFARR_LAYOUT       0x20000000 // GT_INDEX
898 #define GTF_INX_STRING_LAYOUT       0x40000000 // GT_INDEX -- this uses the special string array layout
899
900 #define GTF_IND_ARR_LEN             0x80000000 // GT_IND   -- the indirection represents an array length (of the REF
901                                                //             contribution to its argument).
902 #define GTF_IND_VOLATILE            0x40000000 // GT_IND   -- the load or store must use volatile sematics (this is a nop on X86)
903 #define GTF_IND_NONFAULTING         0x20000000 // Operations for which OperIsIndir() is true  -- An indir that cannot fault.
904                                                // Same as GTF_ARRLEN_NONFAULTING.
905 #define GTF_IND_TGTANYWHERE         0x10000000 // GT_IND   -- the target could be anywhere
906 #define GTF_IND_TLS_REF             0x08000000 // GT_IND   -- the target is accessed via TLS
907 #define GTF_IND_ASG_LHS             0x04000000 // GT_IND   -- this GT_IND node is (the effective val) of the LHS of an
908                                                //             assignment; don't evaluate it independently.
909 #define GTF_IND_REQ_ADDR_IN_REG GTF_IND_ASG_LHS // GT_IND  -- requires its addr operand to be evaluated
910                                                // into a register. This flag is useful in cases where it
911                                                // is required to generate register indirect addressing mode.
912                                                // One such case is virtual stub calls on xarch.  This is only
913                                                // valid in the backend, where GTF_IND_ASG_LHS is not necessary
914                                                // (all such indirections will be lowered to GT_STOREIND).
915 #define GTF_IND_UNALIGNED           0x02000000 // GT_IND   -- the load or store is unaligned (we assume worst case
916                                                //             alignment of 1 byte)
917 #define GTF_IND_INVARIANT           0x01000000 // GT_IND   -- the target is invariant (a prejit indirection)
918 #define GTF_IND_ARR_INDEX           0x00800000 // GT_IND   -- the indirection represents an (SZ) array index
919
920 #define GTF_IND_FLAGS \
921     (GTF_IND_VOLATILE | GTF_IND_TGTANYWHERE | GTF_IND_NONFAULTING | GTF_IND_TLS_REF |          \
922      GTF_IND_UNALIGNED | GTF_IND_INVARIANT | GTF_IND_ARR_INDEX)
923
924 #define GTF_CLS_VAR_VOLATILE        0x40000000 // GT_FIELD/GT_CLS_VAR -- same as GTF_IND_VOLATILE
925 #define GTF_CLS_VAR_INITCLASS       0x20000000 // GT_FIELD/GT_CLS_VAR -- same as GTF_FLD_INITCLASS
926 #define GTF_CLS_VAR_ASG_LHS         0x04000000 // GT_CLS_VAR   -- this GT_CLS_VAR node is (the effective val) of the LHS
927                                                //                 of an assignment; don't evaluate it independently.
928
929 #define GTF_ADDR_ONSTACK            0x80000000 // GT_ADDR    -- this expression is guaranteed to be on the stack
930
931 #define GTF_ADDRMODE_NO_CSE         0x80000000 // GT_ADD/GT_MUL/GT_LSH -- Do not CSE this node only, forms complex
932                                                //                         addressing mode
933
934 #define GTF_MUL_64RSLT              0x40000000 // GT_MUL     -- produce 64-bit result
935
936 #ifdef LEGACY_BACKEND
937 #define GTF_MOD_INT_RESULT          0x80000000 // GT_MOD,    -- the real tree represented by this
938                                                // GT_UMOD       node evaluates to an int even though its type is long.
939                                                //               The result is placed in the low member of the reg pair.
940 #endif // LEGACY_BACKEND
941
942 #define GTF_RELOP_NAN_UN            0x80000000 // GT_<relop> -- Is branch taken if ops are NaN?
943 #define GTF_RELOP_JMP_USED          0x40000000 // GT_<relop> -- result of compare used for jump or ?:
944 #define GTF_RELOP_QMARK             0x20000000 // GT_<relop> -- the node is the condition for ?:
945 #define GTF_RELOP_ZTT               0x08000000 // GT_<relop> -- Loop test cloned for converting while-loops into do-while
946                                                //               with explicit "loop test" in the header block.
947
948 #define GTF_JCMP_EQ                 0x80000000 // GTF_JCMP_EQ  -- Branch on equal rather than not equal
949 #define GTF_JCMP_TST                0x40000000 // GTF_JCMP_TST -- Use bit test instruction rather than compare against zero instruction
950
951 #define GTF_RET_MERGED              0x80000000 // GT_RETURN -- This is a return generated during epilog merging.
952
953 #define GTF_QMARK_CAST_INSTOF       0x80000000 // GT_QMARK -- Is this a top (not nested) level qmark created for
954                                                //             castclass or instanceof?
955
956 #define GTF_BOX_VALUE               0x80000000 // GT_BOX -- "box" is on a value type
957
958 #define GTF_ICON_HDL_MASK           0xF0000000 // Bits used by handle types below
959 #define GTF_ICON_SCOPE_HDL          0x10000000 // GT_CNS_INT -- constant is a scope handle
960 #define GTF_ICON_CLASS_HDL          0x20000000 // GT_CNS_INT -- constant is a class handle
961 #define GTF_ICON_METHOD_HDL         0x30000000 // GT_CNS_INT -- constant is a method handle
962 #define GTF_ICON_FIELD_HDL          0x40000000 // GT_CNS_INT -- constant is a field handle
963 #define GTF_ICON_STATIC_HDL         0x50000000 // GT_CNS_INT -- constant is a handle to static data
964 #define GTF_ICON_STR_HDL            0x60000000 // GT_CNS_INT -- constant is a string handle
965 #define GTF_ICON_PSTR_HDL           0x70000000 // GT_CNS_INT -- constant is a ptr to a string handle
966 #define GTF_ICON_PTR_HDL            0x80000000 // GT_CNS_INT -- constant is a ldptr handle
967 #define GTF_ICON_VARG_HDL           0x90000000 // GT_CNS_INT -- constant is a var arg cookie handle
968 #define GTF_ICON_PINVKI_HDL         0xA0000000 // GT_CNS_INT -- constant is a pinvoke calli handle
969 #define GTF_ICON_TOKEN_HDL          0xB0000000 // GT_CNS_INT -- constant is a token handle
970 #define GTF_ICON_TLS_HDL            0xC0000000 // GT_CNS_INT -- constant is a TLS ref with offset
971 #define GTF_ICON_FTN_ADDR           0xD0000000 // GT_CNS_INT -- constant is a function address
972 #define GTF_ICON_CIDMID_HDL         0xE0000000 // GT_CNS_INT -- constant is a class ID or a module ID
973 #define GTF_ICON_BBC_PTR            0xF0000000 // GT_CNS_INT -- constant is a basic block count pointer
974
975 #define GTF_ICON_FIELD_OFF          0x08000000 // GT_CNS_INT -- constant is a field offset
976 #define GTF_ICON_SIMD_COUNT         0x04000000 // GT_CNS_INT -- constant is Vector<T>.Count
977
978 #define GTF_ICON_INITCLASS          0x02000000 // GT_CNS_INT -- Constant is used to access a static that requires preceding
979                                                //               class/static init helper.  In some cases, the constant is
980                                                //               the address of the static field itself, and in other cases
981                                                //               there's an extra layer of indirection and it is the address
982                                                //               of the cell that the runtime will fill in with the address
983                                                //               of the static field; in both of those cases, the constant
984                                                //               is what gets flagged.
985
986 #define GTF_BLK_VOLATILE            GTF_IND_VOLATILE  // GT_ASG, GT_STORE_BLK, GT_STORE_OBJ, GT_STORE_DYNBLK -- is a volatile block operation
987 #define GTF_BLK_UNALIGNED           GTF_IND_UNALIGNED // GT_ASG, GT_STORE_BLK, GT_STORE_OBJ, GT_STORE_DYNBLK -- is an unaligned block operation
988
989 #define GTF_OVERFLOW                0x10000000 // GT_ADD, GT_SUB, GT_MUL, -- Need overflow check. Use gtOverflow(Ex)() to check this flag.
990                                                // GT_ASG_ADD, GT_ASG_SUB,
991                                                // GT_CAST
992
993 #define GTF_ARR_BOUND_INBND         0x80000000 // GT_ARR_BOUNDS_CHECK -- have proved this check is always in-bounds
994
995 #define GTF_ARRLEN_ARR_IDX          0x80000000 // GT_ARR_LENGTH -- Length which feeds into an array index expression
996 #define GTF_ARRLEN_NONFAULTING      0x20000000 // GT_ARR_LENGTH  -- An array length operation that cannot fault. Same as GT_IND_NONFAULTING.
997
998 #define GTF_FIELD_LIST_HEAD         0x80000000 // GT_FIELD_LIST -- Indicates that this is the first field in a list of
999                                                //                  struct fields constituting a single call argument.
1000
1001 #define GTF_SIMD12_OP               0x80000000 // GT_SIMD -- Indicates that the operands need to be handled as SIMD12
1002                                                //            even if they have been retyped as SIMD16.
1003
1004 #define GTF_STMT_CMPADD             0x80000000 // GT_STMT -- added by compiler
1005 #define GTF_STMT_HAS_CSE            0x40000000 // GT_STMT -- CSE def or use was subsituted
1006
1007 //---------------------------------------------------------------------
1008 //
1009 // GenTree flags stored in gtDebugFlags.
1010 //
1011 //---------------------------------------------------------------------
1012
1013 #if defined(DEBUG)
1014 #define GTF_DEBUG_NONE              0x00000000 // No debug flags.
1015
1016 #define GTF_DEBUG_NODE_MORPHED      0x00000001 // the node has been morphed (in the global morphing phase)
1017 #define GTF_DEBUG_NODE_SMALL        0x00000002
1018 #define GTF_DEBUG_NODE_LARGE        0x00000004
1019 #define GTF_DEBUG_NODE_CG_PRODUCED  0x00000008 // genProduceReg has been called on this node
1020 #define GTF_DEBUG_NODE_CG_CONSUMED  0x00000010 // genConsumeReg has been called on this node
1021 #define GTF_DEBUG_NODE_LSRA_ADDED   0x00000020 // This node was added by LSRA
1022
1023 #define GTF_DEBUG_NODE_MASK         0x0000003F // These flags are all node (rather than operation) properties.
1024
1025 #define GTF_DEBUG_VAR_CSE_REF       0x00800000 // GT_LCL_VAR -- This is a CSE LCL_VAR node
1026 #endif // defined(DEBUG)
1027
1028 //---------------------------------------------------------------------
1029 //
1030 // end of GenTree flags definitions
1031 //
1032 //---------------------------------------------------------------------
1033
1034     // clang-format on
1035
1036     GenTree* gtNext;
1037     GenTree* gtPrev;
1038
1039 #ifdef DEBUG
1040     unsigned gtTreeID;
1041     unsigned gtSeqNum; // liveness traversal order within the current statement
1042
1043     int gtUseNum; // use-ordered traversal within the function
1044 #endif
1045
1046     static const unsigned short gtOperKindTable[];
1047
1048     static unsigned OperKind(unsigned gtOper)
1049     {
1050         assert(gtOper < GT_COUNT);
1051
1052         return gtOperKindTable[gtOper];
1053     }
1054
1055     unsigned OperKind() const
1056     {
1057         assert(gtOper < GT_COUNT);
1058
1059         return gtOperKindTable[gtOper];
1060     }
1061
1062     static bool IsExOp(unsigned opKind)
1063     {
1064         return (opKind & GTK_EXOP) != 0;
1065     }
1066     // Returns the operKind with the GTK_EX_OP bit removed (the
1067     // kind of operator, unary or binary, that is extended).
1068     static unsigned StripExOp(unsigned opKind)
1069     {
1070         return opKind & ~GTK_EXOP;
1071     }
1072
1073     bool IsValue() const
1074     {
1075         if ((OperKind(gtOper) & GTK_NOVALUE) != 0)
1076         {
1077             return false;
1078         }
1079
1080         if (gtType == TYP_VOID)
1081         {
1082             // These are the only operators which can produce either VOID or non-VOID results.
1083             assert(OperIs(GT_NOP, GT_CALL, GT_LOCKADD, GT_FIELD_LIST, GT_COMMA) || OperIsCompare() || OperIsLong() ||
1084                    OperIsSIMD() || OperIsHWIntrinsic());
1085             return false;
1086         }
1087
1088         if (gtOper == GT_FIELD_LIST)
1089         {
1090             return (gtFlags & GTF_FIELD_LIST_HEAD) != 0;
1091         }
1092
1093         return true;
1094     }
1095
1096     bool IsLIR() const
1097     {
1098         if ((OperKind(gtOper) & GTK_NOTLIR) != 0)
1099         {
1100             return false;
1101         }
1102
1103         switch (gtOper)
1104         {
1105             case GT_NOP:
1106                 // NOPs may only be present in LIR if they do not produce a value.
1107                 return IsNothingNode();
1108
1109             case GT_LIST:
1110                 // LIST nodes may not be present in a block's LIR sequence, but they may
1111                 // be present as children of an LIR node.
1112                 return (gtNext == nullptr) && (gtPrev == nullptr);
1113
1114             case GT_FIELD_LIST:
1115                 // Only the head of the FIELD_LIST is present in the block's LIR sequence.
1116                 return (((gtFlags & GTF_FIELD_LIST_HEAD) != 0) || ((gtNext == nullptr) && (gtPrev == nullptr)));
1117
1118             case GT_ADDR:
1119             {
1120                 // ADDR ndoes may only be present in LIR if the location they refer to is not a
1121                 // local, class variable, or IND node.
1122                 GenTree*   location   = gtGetOp1();
1123                 genTreeOps locationOp = location->OperGet();
1124                 return !location->IsLocal() && (locationOp != GT_CLS_VAR) && (locationOp != GT_IND);
1125             }
1126
1127             default:
1128                 // All other nodes are assumed to be correct.
1129                 return true;
1130         }
1131     }
1132
1133     // LIR flags
1134     //   These helper methods, along with the flag values they manipulate, are defined in lir.h
1135     //
1136     // UnusedValue indicates that, although this node produces a value, it is unused.
1137     inline void SetUnusedValue();
1138     inline void ClearUnusedValue();
1139     inline bool IsUnusedValue() const;
1140     // RegOptional indicates that codegen can still generate code even if it isn't allocated a register.
1141     inline bool IsRegOptional() const;
1142     inline void SetRegOptional();
1143     inline void ClearRegOptional();
1144 #ifdef DEBUG
1145     void dumpLIRFlags();
1146 #endif
1147
1148     bool OperIs(genTreeOps oper) const
1149     {
1150         return OperGet() == oper;
1151     }
1152
1153     template <typename... T>
1154     bool OperIs(genTreeOps oper, T... rest) const
1155     {
1156         return OperIs(oper) || OperIs(rest...);
1157     }
1158
1159     static bool OperIsConst(genTreeOps gtOper)
1160     {
1161         return (OperKind(gtOper) & GTK_CONST) != 0;
1162     }
1163
1164     bool OperIsConst() const
1165     {
1166         return (OperKind(gtOper) & GTK_CONST) != 0;
1167     }
1168
1169     static bool OperIsLeaf(genTreeOps gtOper)
1170     {
1171         return (OperKind(gtOper) & GTK_LEAF) != 0;
1172     }
1173
1174     bool OperIsLeaf() const
1175     {
1176         return (OperKind(gtOper) & GTK_LEAF) != 0;
1177     }
1178
1179     static bool OperIsCompare(genTreeOps gtOper)
1180     {
1181         return (OperKind(gtOper) & GTK_RELOP) != 0;
1182     }
1183
1184     static bool OperIsLocal(genTreeOps gtOper)
1185     {
1186         bool result = (OperKind(gtOper) & GTK_LOCAL) != 0;
1187         assert(result == (gtOper == GT_LCL_VAR || gtOper == GT_PHI_ARG || gtOper == GT_REG_VAR ||
1188                           gtOper == GT_LCL_FLD || gtOper == GT_STORE_LCL_VAR || gtOper == GT_STORE_LCL_FLD));
1189         return result;
1190     }
1191
1192     static bool OperIsLocalAddr(genTreeOps gtOper)
1193     {
1194         return (gtOper == GT_LCL_VAR_ADDR || gtOper == GT_LCL_FLD_ADDR);
1195     }
1196
1197     static bool OperIsLocalField(genTreeOps gtOper)
1198     {
1199         return (gtOper == GT_LCL_FLD || gtOper == GT_LCL_FLD_ADDR || gtOper == GT_STORE_LCL_FLD);
1200     }
1201
1202     inline bool OperIsLocalField() const
1203     {
1204         return OperIsLocalField(gtOper);
1205     }
1206
1207     static bool OperIsScalarLocal(genTreeOps gtOper)
1208     {
1209         return (gtOper == GT_LCL_VAR || gtOper == GT_REG_VAR || gtOper == GT_STORE_LCL_VAR);
1210     }
1211
1212     static bool OperIsNonPhiLocal(genTreeOps gtOper)
1213     {
1214         return OperIsLocal(gtOper) && (gtOper != GT_PHI_ARG);
1215     }
1216
1217     static bool OperIsLocalRead(genTreeOps gtOper)
1218     {
1219         return (OperIsLocal(gtOper) && !OperIsLocalStore(gtOper));
1220     }
1221
1222     static bool OperIsLocalStore(genTreeOps gtOper)
1223     {
1224         return (gtOper == GT_STORE_LCL_VAR || gtOper == GT_STORE_LCL_FLD);
1225     }
1226
1227     static bool OperIsAddrMode(genTreeOps gtOper)
1228     {
1229         return (gtOper == GT_LEA);
1230     }
1231
1232     static bool OperIsInitVal(genTreeOps gtOper)
1233     {
1234         return (gtOper == GT_INIT_VAL);
1235     }
1236
1237     bool OperIsInitVal() const
1238     {
1239         return OperIsInitVal(OperGet());
1240     }
1241
1242     bool IsConstInitVal()
1243     {
1244         return (gtOper == GT_CNS_INT) || (OperIsInitVal() && (gtGetOp1()->gtOper == GT_CNS_INT));
1245     }
1246
1247     bool OperIsBlkOp();
1248     bool OperIsCopyBlkOp();
1249     bool OperIsInitBlkOp();
1250     bool OperIsDynBlkOp();
1251
1252     static bool OperIsBlk(genTreeOps gtOper)
1253     {
1254         return ((gtOper == GT_BLK) || (gtOper == GT_OBJ) || (gtOper == GT_DYN_BLK) || (gtOper == GT_STORE_BLK) ||
1255                 (gtOper == GT_STORE_OBJ) || (gtOper == GT_STORE_DYN_BLK));
1256     }
1257
1258     bool OperIsBlk() const
1259     {
1260         return OperIsBlk(OperGet());
1261     }
1262
1263     static bool OperIsDynBlk(genTreeOps gtOper)
1264     {
1265         return ((gtOper == GT_DYN_BLK) || (gtOper == GT_STORE_DYN_BLK));
1266     }
1267
1268     bool OperIsDynBlk() const
1269     {
1270         return OperIsDynBlk(OperGet());
1271     }
1272
1273     static bool OperIsStoreBlk(genTreeOps gtOper)
1274     {
1275         return ((gtOper == GT_STORE_BLK) || (gtOper == GT_STORE_OBJ) || (gtOper == GT_STORE_DYN_BLK));
1276     }
1277
1278     bool OperIsStoreBlk() const
1279     {
1280         return OperIsStoreBlk(OperGet());
1281     }
1282
1283     bool OperIsPutArgSplit() const
1284     {
1285 #if !defined(LEGACY_BACKEND) && defined(_TARGET_ARM_)
1286         return gtOper == GT_PUTARG_SPLIT;
1287 #else
1288         return false;
1289 #endif
1290     }
1291
1292     bool OperIsPutArgStk() const
1293     {
1294         return gtOper == GT_PUTARG_STK;
1295     }
1296
1297     bool OperIsPutArgStkOrSplit() const
1298     {
1299         return OperIsPutArgStk() || OperIsPutArgSplit();
1300     }
1301
1302     bool OperIsPutArgReg() const
1303     {
1304         return gtOper == GT_PUTARG_REG;
1305     }
1306
1307     bool OperIsPutArg() const
1308     {
1309         return OperIsPutArgStk() || OperIsPutArgReg() || OperIsPutArgSplit();
1310     }
1311
1312     bool OperIsMultiRegOp() const
1313     {
1314 #if !defined(LEGACY_BACKEND) && defined(_TARGET_ARM_)
1315         if ((gtOper == GT_MUL_LONG) || (gtOper == GT_PUTARG_REG) || (gtOper == GT_BITCAST))
1316         {
1317             return true;
1318         }
1319 #endif
1320
1321         return false;
1322     }
1323
1324     bool OperIsAddrMode() const
1325     {
1326         return OperIsAddrMode(OperGet());
1327     }
1328
1329     bool OperIsLocal() const
1330     {
1331         return OperIsLocal(OperGet());
1332     }
1333
1334     bool OperIsLocalAddr() const
1335     {
1336         return OperIsLocalAddr(OperGet());
1337     }
1338
1339     bool OperIsScalarLocal() const
1340     {
1341         return OperIsScalarLocal(OperGet());
1342     }
1343
1344     bool OperIsNonPhiLocal() const
1345     {
1346         return OperIsNonPhiLocal(OperGet());
1347     }
1348
1349     bool OperIsLocalStore() const
1350     {
1351         return OperIsLocalStore(OperGet());
1352     }
1353
1354     bool OperIsLocalRead() const
1355     {
1356         return OperIsLocalRead(OperGet());
1357     }
1358
1359     bool OperIsCompare() const
1360     {
1361         return (OperKind(gtOper) & GTK_RELOP) != 0;
1362     }
1363
1364     static bool OperIsLogical(genTreeOps gtOper)
1365     {
1366         return (OperKind(gtOper) & GTK_LOGOP) != 0;
1367     }
1368
1369     bool OperIsLogical() const
1370     {
1371         return (OperKind(gtOper) & GTK_LOGOP) != 0;
1372     }
1373
1374     static bool OperIsShift(genTreeOps gtOper)
1375     {
1376         return (gtOper == GT_LSH) || (gtOper == GT_RSH) || (gtOper == GT_RSZ);
1377     }
1378
1379     bool OperIsShift() const
1380     {
1381         return OperIsShift(OperGet());
1382     }
1383
1384     static bool OperIsRotate(genTreeOps gtOper)
1385     {
1386         return (gtOper == GT_ROL) || (gtOper == GT_ROR);
1387     }
1388
1389     bool OperIsRotate() const
1390     {
1391         return OperIsRotate(OperGet());
1392     }
1393
1394     static bool OperIsShiftOrRotate(genTreeOps gtOper)
1395     {
1396         return OperIsShift(gtOper) || OperIsRotate(gtOper);
1397     }
1398
1399     bool OperIsShiftOrRotate() const
1400     {
1401         return OperIsShiftOrRotate(OperGet());
1402     }
1403
1404     bool OperIsArithmetic() const
1405     {
1406         genTreeOps op = OperGet();
1407         return op == GT_ADD || op == GT_SUB || op == GT_MUL || op == GT_DIV || op == GT_MOD
1408
1409                || op == GT_UDIV || op == GT_UMOD
1410
1411                || op == GT_OR || op == GT_XOR || op == GT_AND
1412
1413                || OperIsShiftOrRotate(op);
1414     }
1415
1416 #ifdef _TARGET_XARCH_
1417     static bool OperIsRMWMemOp(genTreeOps gtOper)
1418     {
1419         // Return if binary op is one of the supported operations for RMW of memory.
1420         return (gtOper == GT_ADD || gtOper == GT_SUB || gtOper == GT_AND || gtOper == GT_OR || gtOper == GT_XOR ||
1421                 gtOper == GT_NOT || gtOper == GT_NEG || OperIsShiftOrRotate(gtOper));
1422     }
1423     bool OperIsRMWMemOp() const
1424     {
1425         // Return if binary op is one of the supported operations for RMW of memory.
1426         return OperIsRMWMemOp(gtOper);
1427     }
1428 #endif // _TARGET_XARCH_
1429
1430     static bool OperIsUnary(genTreeOps gtOper)
1431     {
1432         return (OperKind(gtOper) & GTK_UNOP) != 0;
1433     }
1434
1435     bool OperIsUnary() const
1436     {
1437         return OperIsUnary(gtOper);
1438     }
1439
1440     static bool OperIsBinary(genTreeOps gtOper)
1441     {
1442         return (OperKind(gtOper) & GTK_BINOP) != 0;
1443     }
1444
1445     bool OperIsBinary() const
1446     {
1447         return OperIsBinary(gtOper);
1448     }
1449
1450     static bool OperIsSimple(genTreeOps gtOper)
1451     {
1452         return (OperKind(gtOper) & GTK_SMPOP) != 0;
1453     }
1454
1455     static bool OperIsSpecial(genTreeOps gtOper)
1456     {
1457         return ((OperKind(gtOper) & GTK_KINDMASK) == GTK_SPECIAL);
1458     }
1459
1460     bool OperIsSimple() const
1461     {
1462         return OperIsSimple(gtOper);
1463     }
1464
1465 #ifdef FEATURE_SIMD
1466     bool isCommutativeSIMDIntrinsic();
1467 #else  // !
1468     bool isCommutativeSIMDIntrinsic()
1469     {
1470         return false;
1471     }
1472 #endif // FEATURE_SIMD
1473
1474 #ifdef FEATURE_HW_INTRINSICS
1475     bool isCommutativeHWIntrinsic() const;
1476     bool isContainableHWIntrinsic() const;
1477     bool isRMWHWIntrinsic(Compiler* comp);
1478 #else
1479     bool isCommutativeHWIntrinsic() const
1480     {
1481         return false;
1482     }
1483
1484     bool isContainableHWIntrinsic() const
1485     {
1486         return false;
1487     }
1488
1489     bool isRMWHWIntrinsic(Compiler* comp)
1490     {
1491         return false;
1492     }
1493 #endif // FEATURE_HW_INTRINSICS
1494
1495     static bool OperIsCommutative(genTreeOps gtOper)
1496     {
1497         return (OperKind(gtOper) & GTK_COMMUTE) != 0;
1498     }
1499
1500     bool OperIsCommutative()
1501     {
1502         return OperIsCommutative(gtOper) || (OperIsSIMD(gtOper) && isCommutativeSIMDIntrinsic()) ||
1503                (OperIsHWIntrinsic(gtOper) && isCommutativeHWIntrinsic());
1504     }
1505
1506     static bool OperIsAssignment(genTreeOps gtOper)
1507     {
1508 #ifdef LEGACY_BACKEND
1509         return (OperKind(gtOper) & GTK_ASGOP) != 0;
1510 #else
1511         return gtOper == GT_ASG;
1512 #endif
1513     }
1514
1515     bool OperIsAssignment() const
1516     {
1517         return OperIsAssignment(gtOper);
1518     }
1519
1520     static bool OperMayOverflow(genTreeOps gtOper)
1521     {
1522         return ((gtOper == GT_ADD) || (gtOper == GT_SUB) || (gtOper == GT_MUL) || (gtOper == GT_CAST)
1523 #ifdef LEGACY_BACKEND
1524                 || (gtOper == GT_ASG_ADD) || (gtOper == GT_ASG_SUB)
1525 #elif !defined(_TARGET_64BIT_)
1526                 || (gtOper == GT_ADD_HI) || (gtOper == GT_SUB_HI)
1527 #endif
1528                     );
1529     }
1530
1531     bool OperMayOverflow() const
1532     {
1533         return OperMayOverflow(gtOper);
1534     }
1535
1536     static bool OperIsIndir(genTreeOps gtOper)
1537     {
1538         return gtOper == GT_IND || gtOper == GT_STOREIND || gtOper == GT_NULLCHECK || OperIsBlk(gtOper);
1539     }
1540
1541     static bool OperIsIndirOrArrLength(genTreeOps gtOper)
1542     {
1543         return OperIsIndir(gtOper) || (gtOper == GT_ARR_LENGTH);
1544     }
1545
1546     bool OperIsIndir() const
1547     {
1548         return OperIsIndir(gtOper);
1549     }
1550
1551     bool OperIsIndirOrArrLength() const
1552     {
1553         return OperIsIndirOrArrLength(gtOper);
1554     }
1555
1556     bool OperIsImplicitIndir() const;
1557
1558     bool OperIsStore() const
1559     {
1560         return OperIsStore(gtOper);
1561     }
1562
1563     static bool OperIsStore(genTreeOps gtOper)
1564     {
1565         return (gtOper == GT_STOREIND || gtOper == GT_STORE_LCL_VAR || gtOper == GT_STORE_LCL_FLD ||
1566                 gtOper == GT_STORE_BLK || gtOper == GT_STORE_OBJ || gtOper == GT_STORE_DYN_BLK);
1567     }
1568
1569     static bool OperIsAtomicOp(genTreeOps gtOper)
1570     {
1571         return (gtOper == GT_XADD || gtOper == GT_XCHG || gtOper == GT_LOCKADD || gtOper == GT_CMPXCHG);
1572     }
1573
1574     bool OperIsAtomicOp() const
1575     {
1576         return OperIsAtomicOp(gtOper);
1577     }
1578
1579     // This is here for cleaner FEATURE_SIMD #ifdefs.
1580     static bool OperIsSIMD(genTreeOps gtOper)
1581     {
1582 #ifdef FEATURE_SIMD
1583         return gtOper == GT_SIMD;
1584 #else  // !FEATURE_SIMD
1585         return false;
1586 #endif // !FEATURE_SIMD
1587     }
1588
1589     bool OperIsSIMD() const
1590     {
1591         return OperIsSIMD(gtOper);
1592     }
1593
1594     static bool OperIsHWIntrinsic(genTreeOps gtOper)
1595     {
1596 #ifdef FEATURE_HW_INTRINSICS
1597         return gtOper == GT_HWIntrinsic;
1598 #else
1599         return false;
1600 #endif // FEATURE_HW_INTRINSICS
1601     }
1602
1603     bool OperIsHWIntrinsic() const
1604     {
1605         return OperIsHWIntrinsic(gtOper);
1606     }
1607
1608 #ifdef FEATURE_HW_INTRINSICS
1609     inline bool OperIsSimdHWIntrinsic() const;
1610 #else
1611     inline bool OperIsSimdHWIntrinsic() const
1612     {
1613         return false;
1614     }
1615 #endif
1616
1617     bool OperIsSIMDorSimdHWintrinsic() const
1618     {
1619         return OperIsSIMD() || OperIsSimdHWIntrinsic();
1620     }
1621
1622     // This is here for cleaner GT_LONG #ifdefs.
1623     static bool OperIsLong(genTreeOps gtOper)
1624     {
1625 #if defined(_TARGET_64BIT_) || defined(LEGACY_BACKEND)
1626         return false;
1627 #else
1628         return gtOper == GT_LONG;
1629 #endif
1630     }
1631
1632     bool OperIsLong() const
1633     {
1634         return OperIsLong(gtOper);
1635     }
1636
1637     bool OperIsFieldListHead()
1638     {
1639         return (gtOper == GT_FIELD_LIST) && ((gtFlags & GTF_FIELD_LIST_HEAD) != 0);
1640     }
1641
1642     bool OperIsConditionalJump() const
1643     {
1644         return (gtOper == GT_JTRUE) || (gtOper == GT_JCMP) || (gtOper == GT_JCC);
1645     }
1646
1647     static bool OperIsBoundsCheck(genTreeOps op)
1648     {
1649         if (op == GT_ARR_BOUNDS_CHECK)
1650         {
1651             return true;
1652         }
1653 #ifdef FEATURE_SIMD
1654         if (op == GT_SIMD_CHK)
1655         {
1656             return true;
1657         }
1658 #endif // FEATURE_SIMD
1659 #ifdef FEATURE_HW_INTRINSICS
1660         if (op == GT_HW_INTRINSIC_CHK)
1661         {
1662             return true;
1663         }
1664 #endif // FEATURE_HW_INTRINSICS
1665         return false;
1666     }
1667
1668     bool OperIsBoundsCheck() const
1669     {
1670         return OperIsBoundsCheck(OperGet());
1671     }
1672
1673 #ifdef LEGACY_BACKEND
1674     // Requires that "op" is an op= operator.  Returns
1675     // the corresponding "op".
1676     static genTreeOps OpAsgToOper(genTreeOps op);
1677 #endif
1678
1679 #ifdef DEBUG
1680     bool NullOp1Legal() const
1681     {
1682         assert(OperIsSimple(gtOper));
1683         switch (gtOper)
1684         {
1685             case GT_PHI:
1686             case GT_LEA:
1687             case GT_RETFILT:
1688             case GT_NOP:
1689 #ifdef FEATURE_HW_INTRINSICS
1690             case GT_HWIntrinsic:
1691 #endif // FEATURE_HW_INTRINSICS
1692                 return true;
1693             case GT_RETURN:
1694                 return gtType == TYP_VOID;
1695             default:
1696                 return false;
1697         }
1698     }
1699
1700     bool NullOp2Legal() const
1701     {
1702         assert(OperIsSimple(gtOper) || OperIsBlk(gtOper));
1703         if (!OperIsBinary(gtOper))
1704         {
1705             return true;
1706         }
1707         switch (gtOper)
1708         {
1709             case GT_LIST:
1710             case GT_FIELD_LIST:
1711             case GT_INTRINSIC:
1712             case GT_LEA:
1713 #ifdef FEATURE_SIMD
1714             case GT_SIMD:
1715 #endif // !FEATURE_SIMD
1716
1717 #ifdef FEATURE_HW_INTRINSICS
1718             case GT_HWIntrinsic:
1719 #endif // FEATURE_HW_INTRINSICS
1720
1721 #if !defined(LEGACY_BACKEND) && defined(_TARGET_ARM_)
1722             case GT_PUTARG_REG:
1723 #endif // !defined(LEGACY_BACKEND) && defined(_TARGET_ARM_)
1724                 return true;
1725             default:
1726                 return false;
1727         }
1728     }
1729
1730     static inline bool RequiresNonNullOp2(genTreeOps oper);
1731     bool IsValidCallArgument();
1732 #endif // DEBUG
1733
1734     inline bool IsFPZero();
1735     inline bool IsIntegralConst(ssize_t constVal);
1736     inline bool IsIntegralConstVector(ssize_t constVal);
1737
1738     inline bool IsBoxedValue();
1739
1740     inline bool IsSIMDEqualityOrInequality() const;
1741
1742     static bool OperIsList(genTreeOps gtOper)
1743     {
1744         return gtOper == GT_LIST;
1745     }
1746
1747     bool OperIsList() const
1748     {
1749         return OperIsList(gtOper);
1750     }
1751
1752     static bool OperIsFieldList(genTreeOps gtOper)
1753     {
1754         return gtOper == GT_FIELD_LIST;
1755     }
1756
1757     bool OperIsFieldList() const
1758     {
1759         return OperIsFieldList(gtOper);
1760     }
1761
1762     static bool OperIsAnyList(genTreeOps gtOper)
1763     {
1764         return OperIsList(gtOper) || OperIsFieldList(gtOper);
1765     }
1766
1767     bool OperIsAnyList() const
1768     {
1769         return OperIsAnyList(gtOper);
1770     }
1771
1772     inline GenTree* MoveNext();
1773
1774     inline GenTree* Current();
1775
1776     inline GenTree** pCurrent();
1777
1778     inline GenTree* gtGetOp1() const;
1779
1780     // Directly return op2. Asserts the node is binary. Might return nullptr if the binary node allows
1781     // a nullptr op2, such as GT_LIST. This is more efficient than gtGetOp2IfPresent() if you know what
1782     // node type you have.
1783     inline GenTree* gtGetOp2() const;
1784
1785     // The returned pointer might be nullptr if the node is not binary, or if non-null op2 is not required.
1786     inline GenTree* gtGetOp2IfPresent() const;
1787
1788     // Given a tree node, if this is a child of that node, return the pointer to the child node so that it
1789     // can be modified; otherwise, return null.
1790     GenTree** gtGetChildPointer(GenTree* parent) const;
1791
1792     // Given a tree node, if this node uses that node, return the use as an out parameter and return true.
1793     // Otherwise, return false.
1794     bool TryGetUse(GenTree* def, GenTree*** use);
1795
1796 private:
1797     bool TryGetUseList(GenTree* def, GenTree*** use);
1798
1799     bool TryGetUseBinOp(GenTree* def, GenTree*** use);
1800
1801 public:
1802     // Get the parent of this node, and optionally capture the pointer to the child so that it can be modified.
1803     GenTree* gtGetParent(GenTree*** parentChildPtrPtr) const;
1804
1805     void ReplaceOperand(GenTree** useEdge, GenTree* replacement);
1806
1807     inline GenTree* gtEffectiveVal(bool commaOnly = false);
1808
1809     // Tunnel through any GT_RET_EXPRs
1810     inline GenTree* gtRetExprVal();
1811
1812     // Return the child of this node if it is a GT_RELOAD or GT_COPY; otherwise simply return the node itself
1813     inline GenTree* gtSkipReloadOrCopy();
1814
1815     // Returns true if it is a call node returning its value in more than one register
1816     inline bool IsMultiRegCall() const;
1817
1818     // Returns true if it is a node returning its value in more than one register
1819     inline bool IsMultiRegNode() const;
1820
1821     // Returns true if it is a GT_COPY or GT_RELOAD node
1822     inline bool IsCopyOrReload() const;
1823
1824     // Returns true if it is a GT_COPY or GT_RELOAD of a multi-reg call node
1825     inline bool IsCopyOrReloadOfMultiRegCall() const;
1826
1827     bool OperRequiresAsgFlag();
1828
1829     bool OperMayThrow(Compiler* comp);
1830
1831     unsigned GetScaleIndexMul();
1832     unsigned GetScaleIndexShf();
1833     unsigned GetScaledIndex();
1834
1835     // Returns true if "addr" is a GT_ADD node, at least one of whose arguments is an integer
1836     // (<= 32 bit) constant.  If it returns true, it sets "*offset" to (one of the) constant value(s), and
1837     // "*addr" to the other argument.
1838     bool IsAddWithI32Const(GenTree** addr, int* offset);
1839
1840 public:
1841 #if SMALL_TREE_NODES
1842     static unsigned char s_gtNodeSizes[];
1843 #if NODEBASH_STATS || MEASURE_NODE_SIZE || COUNT_AST_OPERS
1844     static unsigned char s_gtTrueSizes[];
1845 #endif
1846 #if COUNT_AST_OPERS
1847     static LONG s_gtNodeCounts[];
1848 #endif
1849 #endif // SMALL_TREE_NODES
1850
1851     static void InitNodeSize();
1852
1853     size_t GetNodeSize() const;
1854
1855     bool IsNodeProperlySized() const;
1856
1857     void ReplaceWith(GenTree* src, Compiler* comp);
1858
1859     static genTreeOps ReverseRelop(genTreeOps relop);
1860
1861     static genTreeOps SwapRelop(genTreeOps relop);
1862
1863     //---------------------------------------------------------------------
1864
1865     static bool Compare(GenTree* op1, GenTree* op2, bool swapOK = false);
1866
1867 //---------------------------------------------------------------------
1868
1869 #if defined(DEBUG) || NODEBASH_STATS || MEASURE_NODE_SIZE || COUNT_AST_OPERS
1870     static const char* OpName(genTreeOps op);
1871 #endif
1872
1873 #if MEASURE_NODE_SIZE && SMALL_TREE_NODES
1874     static const char* OpStructName(genTreeOps op);
1875 #endif
1876
1877     //---------------------------------------------------------------------
1878
1879     bool IsNothingNode() const;
1880     void gtBashToNOP();
1881
1882     // Value number update action enumeration
1883     enum ValueNumberUpdate
1884     {
1885         CLEAR_VN,   // Clear value number
1886         PRESERVE_VN // Preserve value number
1887     };
1888
1889     void SetOper(genTreeOps oper, ValueNumberUpdate vnUpdate = CLEAR_VN); // set gtOper
1890     void SetOperResetFlags(genTreeOps oper);                              // set gtOper and reset flags
1891
1892     void ChangeOperConst(genTreeOps oper); // ChangeOper(constOper)
1893     // set gtOper and only keep GTF_COMMON_MASK flags
1894     void ChangeOper(genTreeOps oper, ValueNumberUpdate vnUpdate = CLEAR_VN);
1895     void ChangeOperUnchecked(genTreeOps oper);
1896     void SetOperRaw(genTreeOps oper);
1897
1898     void ChangeType(var_types newType)
1899     {
1900         var_types oldType = gtType;
1901         gtType            = newType;
1902         GenTree* node     = this;
1903         while (node->gtOper == GT_COMMA)
1904         {
1905             node = node->gtGetOp2();
1906             assert(node->gtType == oldType);
1907             node->gtType = newType;
1908         }
1909     }
1910
1911 #if SMALL_TREE_NODES
1912 #if NODEBASH_STATS
1913     static void RecordOperBashing(genTreeOps operOld, genTreeOps operNew);
1914     static void ReportOperBashing(FILE* fp);
1915 #else
1916     static void RecordOperBashing(genTreeOps operOld, genTreeOps operNew)
1917     { /* do nothing */
1918     }
1919     static void ReportOperBashing(FILE* fp)
1920     { /* do nothing */
1921     }
1922 #endif
1923 #endif
1924
1925     bool IsLocal() const
1926     {
1927         return OperIsLocal(OperGet());
1928     }
1929
1930     // Returns "true" iff 'this' is a GT_LCL_FLD or GT_STORE_LCL_FLD on which the type
1931     // is not the same size as the type of the GT_LCL_VAR.
1932     bool IsPartialLclFld(Compiler* comp);
1933
1934     // Returns "true" iff "this" defines a local variable.  Requires "comp" to be the
1935     // current compilation.  If returns "true", sets "*pLclVarTree" to the
1936     // tree for the local that is defined, and, if "pIsEntire" is non-null, sets "*pIsEntire" to
1937     // true or false, depending on whether the assignment writes to the entirety of the local
1938     // variable, or just a portion of it.
1939     bool DefinesLocal(Compiler* comp, GenTreeLclVarCommon** pLclVarTree, bool* pIsEntire = nullptr);
1940
1941     // Returns true if "this" represents the address of a local, or a field of a local.  If returns true, sets
1942     // "*pLclVarTree" to the node indicating the local variable.  If the address is that of a field of this node,
1943     // sets "*pFldSeq" to the field sequence representing that field, else null.
1944     bool IsLocalAddrExpr(Compiler* comp, GenTreeLclVarCommon** pLclVarTree, FieldSeqNode** pFldSeq);
1945
1946     // Simpler variant of the above which just returns the local node if this is an expression that
1947     // yields an address into a local
1948     GenTreeLclVarCommon* IsLocalAddrExpr();
1949
1950     // Determine if this is a LclVarCommon node and return some additional info about it in the
1951     // two out parameters.
1952     bool IsLocalExpr(Compiler* comp, GenTreeLclVarCommon** pLclVarTree, FieldSeqNode** pFldSeq);
1953
1954     // Determine whether this is an assignment tree of the form X = X (op) Y,
1955     // where Y is an arbitrary tree, and X is a lclVar.
1956     unsigned IsLclVarUpdateTree(GenTree** otherTree, genTreeOps* updateOper);
1957
1958     // If returns "true", "this" may represent the address of a static or instance field
1959     // (or a field of such a field, in the case of an object field of type struct).
1960     // If returns "true", then either "*pObj" is set to the object reference,
1961     // or "*pStatic" is set to the baseAddr or offset to be added to the "*pFldSeq"
1962     // Only one of "*pObj" or "*pStatic" will be set, the other one will be null.
1963     // The boolean return value only indicates that "this" *may* be a field address
1964     // -- the field sequence must also be checked.
1965     // If it is a field address, the field sequence will be a sequence of length >= 1,
1966     // starting with an instance or static field, and optionally continuing with struct fields.
1967     bool IsFieldAddr(Compiler* comp, GenTree** pObj, GenTree** pStatic, FieldSeqNode** pFldSeq);
1968
1969     // Requires "this" to be the address of an array (the child of a GT_IND labeled with GTF_IND_ARR_INDEX).
1970     // Sets "pArr" to the node representing the array (either an array object pointer, or perhaps a byref to the some
1971     // element).
1972     // Sets "*pArrayType" to the class handle for the array type.
1973     // Sets "*inxVN" to the value number inferred for the array index.
1974     // Sets "*pFldSeq" to the sequence, if any, of struct fields used to index into the array element.
1975     void ParseArrayAddress(
1976         Compiler* comp, struct ArrayInfo* arrayInfo, GenTree** pArr, ValueNum* pInxVN, FieldSeqNode** pFldSeq);
1977
1978     // Helper method for the above.
1979     void ParseArrayAddressWork(
1980         Compiler* comp, ssize_t inputMul, GenTree** pArr, ValueNum* pInxVN, ssize_t* pOffset, FieldSeqNode** pFldSeq);
1981
1982     // Requires "this" to be a GT_IND.  Requires the outermost caller to set "*pFldSeq" to nullptr.
1983     // Returns true if it is an array index expression, or access to a (sequence of) struct field(s)
1984     // within a struct array element.  If it returns true, sets *arrayInfo to the array information, and sets *pFldSeq
1985     // to the sequence of struct field accesses.
1986     bool ParseArrayElemForm(Compiler* comp, ArrayInfo* arrayInfo, FieldSeqNode** pFldSeq);
1987
1988     // Requires "this" to be the address of a (possible) array element (or struct field within that).
1989     // If it is, sets "*arrayInfo" to the array access info, "*pFldSeq" to the sequence of struct fields
1990     // accessed within the array element, and returns true.  If not, returns "false".
1991     bool ParseArrayElemAddrForm(Compiler* comp, ArrayInfo* arrayInfo, FieldSeqNode** pFldSeq);
1992
1993     // Requires "this" to be an int expression.  If it is a sequence of one or more integer constants added together,
1994     // returns true and sets "*pFldSeq" to the sequence of fields with which those constants are annotated.
1995     bool ParseOffsetForm(Compiler* comp, FieldSeqNode** pFldSeq);
1996
1997     // Labels "*this" as an array index expression: label all constants and variables that could contribute, as part of
1998     // an affine expression, to the value of the of the index.
1999     void LabelIndex(Compiler* comp, bool isConst = true);
2000
2001     // Assumes that "this" occurs in a context where it is being dereferenced as the LHS of an assignment-like
2002     // statement (assignment, initblk, or copyblk).  The "width" should be the number of bytes copied by the
2003     // operation.  Returns "true" if "this" is an address of (or within)
2004     // a local variable; sets "*pLclVarTree" to that local variable instance; and, if "pIsEntire" is non-null,
2005     // sets "*pIsEntire" to true if this assignment writes the full width of the local.
2006     bool DefinesLocalAddr(Compiler* comp, unsigned width, GenTreeLclVarCommon** pLclVarTree, bool* pIsEntire);
2007
2008 #ifdef LEGACY_BACKEND
2009     bool IsRegVar() const
2010     {
2011         return OperGet() == GT_REG_VAR ? true : false;
2012     }
2013     bool InReg() const
2014     {
2015         return (gtFlags & GTF_REG_VAL) ? true : false;
2016     }
2017     void SetInReg(bool value = true)
2018     {
2019         if (value == true)
2020         {
2021             gtFlags |= GTF_REG_VAL;
2022         }
2023         else
2024         {
2025             gtFlags &= ~GTF_REG_VAL;
2026         }
2027     }
2028     regNumber GetReg() const
2029     {
2030         return InReg() ? gtRegNum : REG_NA;
2031     }
2032
2033 #else // !LEGACY_BACKEND
2034     // For the non-legacy backend, these are only used for dumping.
2035     // The gtRegNum is only valid in LIR, but the dumping methods are not easily
2036     // modified to check this.
2037     CLANG_FORMAT_COMMENT_ANCHOR;
2038 #ifdef DEBUG
2039     bool InReg() const
2040     {
2041         return (GetRegTag() != GT_REGTAG_NONE) ? true : false;
2042     }
2043     regNumber GetReg() const
2044     {
2045         return (GetRegTag() != GT_REGTAG_NONE) ? gtRegNum : REG_NA;
2046     }
2047 #endif
2048
2049     static bool IsContained(unsigned flags)
2050     {
2051         return ((flags & GTF_CONTAINED) != 0);
2052     }
2053
2054     void SetContained()
2055     {
2056         assert(IsValue());
2057         gtFlags |= GTF_CONTAINED;
2058         assert(isContained());
2059     }
2060
2061     void ClearContained()
2062     {
2063         assert(IsValue());
2064         gtFlags &= ~GTF_CONTAINED;
2065         ClearRegOptional();
2066     }
2067
2068 #endif // !LEGACY_BACKEND
2069
2070     bool IsRegVarDeath() const
2071     {
2072         assert(OperGet() == GT_REG_VAR);
2073         return (gtFlags & GTF_VAR_DEATH) ? true : false;
2074     }
2075     bool IsRegVarBirth() const
2076     {
2077         assert(OperGet() == GT_REG_VAR);
2078         return (gtFlags & GTF_REG_BIRTH) ? true : false;
2079     }
2080     bool IsReverseOp() const
2081     {
2082         return (gtFlags & GTF_REVERSE_OPS) ? true : false;
2083     }
2084     bool IsUnsigned() const
2085     {
2086         return ((gtFlags & GTF_UNSIGNED) != 0);
2087     }
2088
2089     inline bool IsCnsIntOrI() const;
2090
2091     inline bool IsIntegralConst() const;
2092
2093     inline bool IsIntCnsFitsInI32(); // Constant fits in INT32
2094
2095     inline bool IsCnsFltOrDbl() const;
2096
2097     inline bool IsCnsNonZeroFltOrDbl();
2098
2099     bool IsIconHandle() const
2100     {
2101         assert(gtOper == GT_CNS_INT);
2102         return (gtFlags & GTF_ICON_HDL_MASK) ? true : false;
2103     }
2104
2105     bool IsIconHandle(unsigned handleType) const
2106     {
2107         assert(gtOper == GT_CNS_INT);
2108         assert((handleType & GTF_ICON_HDL_MASK) != 0); // check that handleType is one of the valid GTF_ICON_* values
2109         assert((handleType & ~GTF_ICON_HDL_MASK) == 0);
2110         return (gtFlags & GTF_ICON_HDL_MASK) == handleType;
2111     }
2112
2113     // Return just the part of the flags corresponding to the GTF_ICON_*_HDL flag. For example,
2114     // GTF_ICON_SCOPE_HDL. The tree node must be a const int, but it might not be a handle, in which
2115     // case we'll return zero.
2116     unsigned GetIconHandleFlag() const
2117     {
2118         assert(gtOper == GT_CNS_INT);
2119         return (gtFlags & GTF_ICON_HDL_MASK);
2120     }
2121
2122     // Mark this node as no longer being a handle; clear its GTF_ICON_*_HDL bits.
2123     void ClearIconHandleMask()
2124     {
2125         assert(gtOper == GT_CNS_INT);
2126         gtFlags &= ~GTF_ICON_HDL_MASK;
2127     }
2128
2129     // Return true if the two GT_CNS_INT trees have the same handle flag (GTF_ICON_*_HDL).
2130     static bool SameIconHandleFlag(GenTree* t1, GenTree* t2)
2131     {
2132         return t1->GetIconHandleFlag() == t2->GetIconHandleFlag();
2133     }
2134
2135     bool IsArgPlaceHolderNode() const
2136     {
2137         return OperGet() == GT_ARGPLACE;
2138     }
2139     bool IsCall() const
2140     {
2141         return OperGet() == GT_CALL;
2142     }
2143     bool IsStatement() const
2144     {
2145         return OperGet() == GT_STMT;
2146     }
2147     inline bool IsHelperCall();
2148
2149     bool IsVarAddr() const;
2150     bool gtOverflow() const;
2151     bool gtOverflowEx() const;
2152     bool gtSetFlags() const;
2153     bool gtRequestSetFlags();
2154
2155 #ifdef LEGACY_BACKEND
2156     // Returns true if the codegen of this tree node
2157     // sets ZF and SF flags.
2158     bool gtSetZSFlags() const
2159     {
2160         return (gtFlags & GTF_ZSF_SET) != 0;
2161     }
2162 #endif
2163
2164 #ifdef DEBUG
2165     bool       gtIsValid64RsltMul();
2166     static int gtDispFlags(unsigned flags, unsigned debugFlags);
2167 #endif
2168
2169     // cast operations
2170     inline var_types  CastFromType();
2171     inline var_types& CastToType();
2172
2173     // Returns "true" iff "this" is a phi-related node (i.e. a GT_PHI_ARG, GT_PHI, or a PhiDefn).
2174     bool IsPhiNode();
2175
2176     // Returns "true" iff "*this" is an assignment (GT_ASG) tree that defines an SSA name (lcl = phi(...));
2177     bool IsPhiDefn();
2178
2179     // Returns "true" iff "*this" is a statement containing an assignment that defines an SSA name (lcl = phi(...));
2180     bool IsPhiDefnStmt();
2181
2182     // Can't use an assignment operator, because we need the extra "comp" argument
2183     // (to provide the allocator necessary for the VarSet assignment).
2184     // TODO-Cleanup: Not really needed now, w/o liveset on tree nodes
2185     void CopyTo(class Compiler* comp, const GenTree& gt);
2186
2187     // Like the above, excepts assumes copying from small node to small node.
2188     // (Following the code it replaces, it does *not* copy the GenTree fields,
2189     // which CopyTo does.)
2190     void CopyToSmall(const GenTree& gt);
2191
2192     // Because of the fact that we hid the assignment operator of "BitSet" (in DEBUG),
2193     // we can't synthesize an assignment operator.
2194     // TODO-Cleanup: Could change this w/o liveset on tree nodes
2195     // (This is also necessary for the VTable trick.)
2196     GenTree()
2197     {
2198     }
2199
2200     // Returns the number of children of the current node.
2201     unsigned NumChildren();
2202
2203     // Requires "childNum < NumChildren()".  Returns the "n"th child of "this."
2204     GenTree* GetChild(unsigned childNum);
2205
2206     // Returns an iterator that will produce the use edge to each operand of this node. Differs
2207     // from the sequence of nodes produced by a loop over `GetChild` in its handling of call, phi,
2208     // and block op nodes.
2209     GenTreeUseEdgeIterator UseEdgesBegin();
2210     GenTreeUseEdgeIterator UseEdgesEnd();
2211
2212     IteratorPair<GenTreeUseEdgeIterator> UseEdges();
2213
2214     // Returns an iterator that will produce each operand of this node. Differs from the sequence
2215     // of nodes produced by a loop over `GetChild` in its handling of call, phi, and block op
2216     // nodes.
2217     GenTreeOperandIterator OperandsBegin();
2218     GenTreeOperandIterator OperandsEnd();
2219
2220     // Returns a range that will produce the operands of this node in use order.
2221     IteratorPair<GenTreeOperandIterator> Operands();
2222
2223     enum class VisitResult
2224     {
2225         Abort    = false,
2226         Continue = true
2227     };
2228
2229     // Visits each operand of this node. The operand must be either a lambda, function, or functor with the signature
2230     // `GenTree::VisitResult VisitorFunction(GenTree* operand)`. Here is a simple example:
2231     //
2232     //     unsigned operandCount = 0;
2233     //     node->VisitOperands([&](GenTree* operand) -> GenTree::VisitResult)
2234     //     {
2235     //         operandCount++;
2236     //         return GenTree::VisitResult::Continue;
2237     //     });
2238     //
2239     // This function is generally more efficient that the operand iterator and should be preferred over that API for
2240     // hot code, as it affords better opportunities for inlining and acheives shorter dynamic path lengths when
2241     // deciding how operands need to be accessed.
2242     //
2243     // Note that this function does not respect `GTF_REVERSE_OPS` and `gtEvalSizeFirst`. This is always safe in LIR,
2244     // but may be dangerous in HIR if for some reason you need to visit operands in the order in which they will
2245     // execute.
2246     template <typename TVisitor>
2247     void VisitOperands(TVisitor visitor);
2248
2249 private:
2250     template <typename TVisitor>
2251     VisitResult VisitListOperands(TVisitor visitor);
2252
2253     template <typename TVisitor>
2254     void VisitBinOpOperands(TVisitor visitor);
2255
2256 public:
2257     bool Precedes(GenTree* other);
2258
2259     // The maximum possible # of children of any node.
2260     static const int MAX_CHILDREN = 6;
2261
2262     bool IsReuseRegVal() const
2263     {
2264         // This can be extended to non-constant nodes, but not to local or indir nodes.
2265         if (OperIsConst() && ((gtFlags & GTF_REUSE_REG_VAL) != 0))
2266         {
2267             return true;
2268         }
2269         return false;
2270     }
2271     void SetReuseRegVal()
2272     {
2273         assert(OperIsConst());
2274         gtFlags |= GTF_REUSE_REG_VAL;
2275     }
2276     void ResetReuseRegVal()
2277     {
2278         assert(OperIsConst());
2279         gtFlags &= ~GTF_REUSE_REG_VAL;
2280     }
2281
2282     void SetIndirExceptionFlags(Compiler* comp)
2283     {
2284         assert(OperIsIndirOrArrLength());
2285         gtFlags |= OperMayThrow(comp) ? GTF_EXCEPT : GTF_IND_NONFAULTING;
2286     }
2287
2288 #if MEASURE_NODE_SIZE
2289     static void DumpNodeSizes(FILE* fp);
2290 #endif
2291
2292 #ifdef DEBUG
2293
2294 private:
2295     GenTree& operator=(const GenTree& gt)
2296     {
2297         assert(!"Don't copy");
2298         return *this;
2299     }
2300 #endif // DEBUG
2301
2302 #if DEBUGGABLE_GENTREE
2303     // In DEBUG builds, add a dummy virtual method, to give the debugger run-time type information.
2304     virtual void DummyVirt()
2305     {
2306     }
2307
2308     typedef void* VtablePtr;
2309
2310     VtablePtr GetVtableForOper(genTreeOps oper);
2311     void SetVtableForOper(genTreeOps oper);
2312
2313     static VtablePtr s_vtablesForOpers[GT_COUNT];
2314     static VtablePtr s_vtableForOp;
2315 #endif // DEBUGGABLE_GENTREE
2316
2317 public:
2318     inline void* operator new(size_t sz, class Compiler*, genTreeOps oper);
2319
2320     inline GenTree(genTreeOps oper, var_types type DEBUGARG(bool largeNode = false));
2321 };
2322
2323 //------------------------------------------------------------------------
2324 // GenTreeUseEdgeIterator: an iterator that will produce each use edge of a GenTree node in the order in which
2325 //                         they are used.
2326 //
2327 // The use edges of a node may not correspond exactly to the nodes on the other ends of its use edges: in
2328 // particular, GT_LIST nodes are expanded into their component parts. This differs from the behavior of
2329 // GenTree::GetChildPointer(), which does not expand lists.
2330 //
2331 // Operand iteration is common enough in the back end of the compiler that the implementation of this type has
2332 // traded some simplicity for speed:
2333 // - As much work as is reasonable is done in the constructor rather than during operand iteration
2334 // - Node-specific functionality is handled by a small class of "advance" functions called by operator++
2335 //   rather than making operator++ itself handle all nodes
2336 // - Some specialization has been performed for specific node types/shapes (e.g. the advance function for
2337 //   binary nodes is specialized based on whether or not the node has the GTF_REVERSE_OPS flag set)
2338 //
2339 // Valid values of this type may be obtained by calling `GenTree::UseEdgesBegin` and `GenTree::UseEdgesEnd`.
2340 //
2341 class GenTreeUseEdgeIterator final
2342 {
2343     friend class GenTreeOperandIterator;
2344     friend GenTreeUseEdgeIterator GenTree::UseEdgesBegin();
2345     friend GenTreeUseEdgeIterator GenTree::UseEdgesEnd();
2346
2347     enum
2348     {
2349         CALL_INSTANCE     = 0,
2350         CALL_ARGS         = 1,
2351         CALL_LATE_ARGS    = 2,
2352         CALL_CONTROL_EXPR = 3,
2353         CALL_COOKIE       = 4,
2354         CALL_ADDRESS      = 5,
2355         CALL_TERMINAL     = 6,
2356     };
2357
2358     typedef void (GenTreeUseEdgeIterator::*AdvanceFn)();
2359
2360     AdvanceFn m_advance;
2361     GenTree*  m_node;
2362     GenTree** m_edge;
2363     GenTree*  m_argList;
2364     int       m_state;
2365
2366     GenTreeUseEdgeIterator(GenTree* node);
2367
2368     // Advance functions for special nodes
2369     void AdvanceCmpXchg();
2370     void AdvanceBoundsChk();
2371     void AdvanceArrElem();
2372     void AdvanceArrOffset();
2373     void AdvanceDynBlk();
2374     void AdvanceStoreDynBlk();
2375
2376     template <bool ReverseOperands>
2377     void           AdvanceBinOp();
2378     void           SetEntryStateForBinOp();
2379
2380     // An advance function for list-like nodes (Phi, SIMDIntrinsicInitN, FieldList)
2381     void AdvanceList();
2382     void SetEntryStateForList(GenTree* list);
2383
2384     // The advance function for call nodes
2385     template <int state>
2386     void          AdvanceCall();
2387
2388     void Terminate();
2389
2390 public:
2391     GenTreeUseEdgeIterator();
2392
2393     inline GenTree** operator*()
2394     {
2395         assert(m_state != -1);
2396         return m_edge;
2397     }
2398
2399     inline GenTree** operator->()
2400     {
2401         assert(m_state != -1);
2402         return m_edge;
2403     }
2404
2405     inline bool operator==(const GenTreeUseEdgeIterator& other) const
2406     {
2407         if (m_state == -1 || other.m_state == -1)
2408         {
2409             return m_state == other.m_state;
2410         }
2411
2412         return (m_node == other.m_node) && (m_edge == other.m_edge) && (m_argList == other.m_argList) &&
2413                (m_state == other.m_state);
2414     }
2415
2416     inline bool operator!=(const GenTreeUseEdgeIterator& other) const
2417     {
2418         return !(operator==(other));
2419     }
2420
2421     GenTreeUseEdgeIterator& operator++();
2422 };
2423
2424 //------------------------------------------------------------------------
2425 // GenTreeOperandIterator: an iterator that will produce each operand of a
2426 //                         GenTree node in the order in which they are
2427 //                         used. This uses `GenTreeUseEdgeIterator` under
2428 //                         the covers and comes with the same caveats
2429 //                         w.r.t. `GetChild`.
2430 //
2431 // Note: valid values of this type may be obtained by calling
2432 // `GenTree::OperandsBegin` and `GenTree::OperandsEnd`.
2433 class GenTreeOperandIterator final
2434 {
2435     friend GenTreeOperandIterator GenTree::OperandsBegin();
2436     friend GenTreeOperandIterator GenTree::OperandsEnd();
2437
2438     GenTreeUseEdgeIterator m_useEdges;
2439
2440     GenTreeOperandIterator(GenTree* node) : m_useEdges(node)
2441     {
2442     }
2443
2444 public:
2445     GenTreeOperandIterator() : m_useEdges()
2446     {
2447     }
2448
2449     inline GenTree* operator*()
2450     {
2451         return *(*m_useEdges);
2452     }
2453
2454     inline GenTree* operator->()
2455     {
2456         return *(*m_useEdges);
2457     }
2458
2459     inline bool operator==(const GenTreeOperandIterator& other) const
2460     {
2461         return m_useEdges == other.m_useEdges;
2462     }
2463
2464     inline bool operator!=(const GenTreeOperandIterator& other) const
2465     {
2466         return !(operator==(other));
2467     }
2468
2469     inline GenTreeOperandIterator& operator++()
2470     {
2471         ++m_useEdges;
2472         return *this;
2473     }
2474 };
2475
2476 /*****************************************************************************/
2477 // In the current design, we never instantiate GenTreeUnOp: it exists only to be
2478 // used as a base class.  For unary operators, we instantiate GenTreeOp, with a NULL second
2479 // argument.  We check that this is true dynamically.  We could tighten this and get static
2480 // checking, but that would entail accessing the first child of a unary operator via something
2481 // like gtUnOp.gtOp1 instead of gtOp.gtOp1.
2482 struct GenTreeUnOp : public GenTree
2483 {
2484     GenTree* gtOp1;
2485
2486 protected:
2487     GenTreeUnOp(genTreeOps oper, var_types type DEBUGARG(bool largeNode = false))
2488         : GenTree(oper, type DEBUGARG(largeNode)), gtOp1(nullptr)
2489     {
2490     }
2491
2492     GenTreeUnOp(genTreeOps oper, var_types type, GenTree* op1 DEBUGARG(bool largeNode = false))
2493         : GenTree(oper, type DEBUGARG(largeNode)), gtOp1(op1)
2494     {
2495         assert(op1 != nullptr || NullOp1Legal());
2496         if (op1 != nullptr)
2497         { // Propagate effects flags from child.
2498             gtFlags |= op1->gtFlags & GTF_ALL_EFFECT;
2499         }
2500     }
2501
2502 #if DEBUGGABLE_GENTREE
2503     GenTreeUnOp() : GenTree(), gtOp1(nullptr)
2504     {
2505     }
2506 #endif
2507 };
2508
2509 struct GenTreeOp : public GenTreeUnOp
2510 {
2511     GenTree* gtOp2;
2512
2513     GenTreeOp(genTreeOps oper, var_types type, GenTree* op1, GenTree* op2 DEBUGARG(bool largeNode = false))
2514         : GenTreeUnOp(oper, type, op1 DEBUGARG(largeNode)), gtOp2(op2)
2515     {
2516         // comparisons are always integral types
2517         assert(!GenTree::OperIsCompare(oper) || varTypeIsIntegral(type));
2518         // Binary operators, with a few exceptions, require a non-nullptr
2519         // second argument.
2520         assert(op2 != nullptr || NullOp2Legal());
2521         // Unary operators, on the other hand, require a null second argument.
2522         assert(!OperIsUnary(oper) || op2 == nullptr);
2523         // Propagate effects flags from child.  (UnOp handled this for first child.)
2524         if (op2 != nullptr)
2525         {
2526             gtFlags |= op2->gtFlags & GTF_ALL_EFFECT;
2527         }
2528     }
2529
2530     // A small set of types are unary operators with optional arguments.  We use
2531     // this constructor to build those.
2532     GenTreeOp(genTreeOps oper, var_types type DEBUGARG(bool largeNode = false))
2533         : GenTreeUnOp(oper, type DEBUGARG(largeNode)), gtOp2(nullptr)
2534     {
2535         // Unary operators with optional arguments:
2536         assert(oper == GT_NOP || oper == GT_RETURN || oper == GT_RETFILT || OperIsBlk(oper));
2537     }
2538
2539 #if DEBUGGABLE_GENTREE
2540     GenTreeOp() : GenTreeUnOp(), gtOp2(nullptr)
2541     {
2542     }
2543 #endif
2544 };
2545
2546 struct GenTreeVal : public GenTree
2547 {
2548     size_t gtVal1;
2549
2550     GenTreeVal(genTreeOps oper, var_types type, ssize_t val) : GenTree(oper, type), gtVal1(val)
2551     {
2552     }
2553 #if DEBUGGABLE_GENTREE
2554     GenTreeVal() : GenTree()
2555     {
2556     }
2557 #endif
2558 };
2559
2560 struct GenTreeIntConCommon : public GenTree
2561 {
2562     inline INT64 LngValue();
2563     inline void SetLngValue(INT64 val);
2564     inline ssize_t IconValue();
2565     inline void SetIconValue(ssize_t val);
2566     inline INT64 IntegralValue();
2567
2568     GenTreeIntConCommon(genTreeOps oper, var_types type DEBUGARG(bool largeNode = false))
2569         : GenTree(oper, type DEBUGARG(largeNode))
2570     {
2571     }
2572
2573     bool FitsInI8() // IconValue() fits into 8-bit signed storage
2574     {
2575         return FitsInI8(IconValue());
2576     }
2577
2578     static bool FitsInI8(ssize_t val) // Constant fits into 8-bit signed storage
2579     {
2580         return (int8_t)val == val;
2581     }
2582
2583     bool FitsInI32() // IconValue() fits into 32-bit signed storage
2584     {
2585         return FitsInI32(IconValue());
2586     }
2587
2588     static bool FitsInI32(ssize_t val) // Constant fits into 32-bit signed storage
2589     {
2590 #ifdef _TARGET_64BIT_
2591         return (int32_t)val == val;
2592 #else
2593         return true;
2594 #endif
2595     }
2596
2597     bool ImmedValNeedsReloc(Compiler* comp);
2598     bool ImmedValCanBeFolded(Compiler* comp, genTreeOps op);
2599
2600 #ifdef _TARGET_XARCH_
2601     bool FitsInAddrBase(Compiler* comp);
2602     bool AddrNeedsReloc(Compiler* comp);
2603 #endif
2604
2605 #if DEBUGGABLE_GENTREE
2606     GenTreeIntConCommon() : GenTree()
2607     {
2608     }
2609 #endif
2610 };
2611
2612 // node representing a read from a physical register
2613 struct GenTreePhysReg : public GenTree
2614 {
2615     // physregs need a field beyond gtRegNum because
2616     // gtRegNum indicates the destination (and can be changed)
2617     // whereas reg indicates the source
2618     regNumber gtSrcReg;
2619     GenTreePhysReg(regNumber r, var_types type = TYP_I_IMPL) : GenTree(GT_PHYSREG, type), gtSrcReg(r)
2620     {
2621     }
2622 #if DEBUGGABLE_GENTREE
2623     GenTreePhysReg() : GenTree()
2624     {
2625     }
2626 #endif
2627 };
2628
2629 #ifndef LEGACY_BACKEND
2630 // gtJumpTable - Switch Jump Table
2631 //
2632 // This node stores a DWORD constant that represents the
2633 // absolute address of a jump table for switches.  The code
2634 // generator uses this table to code the destination for every case
2635 // in an array of addresses which starting position is stored in
2636 // this constant.
2637 struct GenTreeJumpTable : public GenTreeIntConCommon
2638 {
2639     ssize_t gtJumpTableAddr;
2640
2641     GenTreeJumpTable(var_types type DEBUGARG(bool largeNode = false))
2642         : GenTreeIntConCommon(GT_JMPTABLE, type DEBUGARG(largeNode))
2643     {
2644     }
2645 #if DEBUGGABLE_GENTREE
2646     GenTreeJumpTable() : GenTreeIntConCommon()
2647     {
2648     }
2649 #endif // DEBUG
2650 };
2651 #endif // !LEGACY_BACKEND
2652
2653 /* gtIntCon -- integer constant (GT_CNS_INT) */
2654 struct GenTreeIntCon : public GenTreeIntConCommon
2655 {
2656     /*
2657      * This is the GT_CNS_INT struct definition.
2658      * It's used to hold for both int constants and pointer handle constants.
2659      * For the 64-bit targets we will only use GT_CNS_INT as it used to represent all the possible sizes
2660      * For the 32-bit targets we use a GT_CNS_LNG to hold a 64-bit integer constant and GT_CNS_INT for all others.
2661      * In the future when we retarget the JIT for x86 we should consider eliminating GT_CNS_LNG
2662      */
2663     ssize_t gtIconVal; // Must overlap and have the same offset with the gtIconVal field in GenTreeLngCon below.
2664
2665     /* The InitializeArray intrinsic needs to go back to the newarray statement
2666        to find the class handle of the array so that we can get its size.  However,
2667        in ngen mode, the handle in that statement does not correspond to the compile
2668        time handle (rather it lets you get a handle at run-time).  In that case, we also
2669        need to store a compile time handle, which goes in this gtCompileTimeHandle field.
2670     */
2671     ssize_t gtCompileTimeHandle;
2672
2673     // TODO-Cleanup: It's not clear what characterizes the cases where the field
2674     // above is used.  It may be that its uses and those of the "gtFieldSeq" field below
2675     // are mutually exclusive, and they could be put in a union.  Or else we should separate
2676     // this type into three subtypes.
2677
2678     // If this constant represents the offset of one or more fields, "gtFieldSeq" represents that
2679     // sequence of fields.
2680     FieldSeqNode* gtFieldSeq;
2681
2682     GenTreeIntCon(var_types type, ssize_t value DEBUGARG(bool largeNode = false))
2683         : GenTreeIntConCommon(GT_CNS_INT, type DEBUGARG(largeNode))
2684         , gtIconVal(value)
2685         , gtCompileTimeHandle(0)
2686         , gtFieldSeq(FieldSeqStore::NotAField())
2687     {
2688     }
2689
2690     GenTreeIntCon(var_types type, ssize_t value, FieldSeqNode* fields DEBUGARG(bool largeNode = false))
2691         : GenTreeIntConCommon(GT_CNS_INT, type DEBUGARG(largeNode))
2692         , gtIconVal(value)
2693         , gtCompileTimeHandle(0)
2694         , gtFieldSeq(fields)
2695     {
2696         assert(fields != nullptr);
2697     }
2698
2699     void FixupInitBlkValue(var_types asgType);
2700
2701 #ifdef _TARGET_64BIT_
2702     void TruncateOrSignExtend32()
2703     {
2704         if (gtFlags & GTF_UNSIGNED)
2705         {
2706             gtIconVal = UINT32(gtIconVal);
2707         }
2708         else
2709         {
2710             gtIconVal = INT32(gtIconVal);
2711         }
2712     }
2713 #endif // _TARGET_64BIT_
2714
2715 #if DEBUGGABLE_GENTREE
2716     GenTreeIntCon() : GenTreeIntConCommon()
2717     {
2718     }
2719 #endif
2720 };
2721
2722 /* gtLngCon -- long    constant (GT_CNS_LNG) */
2723
2724 struct GenTreeLngCon : public GenTreeIntConCommon
2725 {
2726     INT64 gtLconVal; // Must overlap and have the same offset with the gtIconVal field in GenTreeIntCon above.
2727     INT32 LoVal()
2728     {
2729         return (INT32)(gtLconVal & 0xffffffff);
2730     }
2731
2732     INT32 HiVal()
2733     {
2734         return (INT32)(gtLconVal >> 32);
2735     }
2736
2737     GenTreeLngCon(INT64 val) : GenTreeIntConCommon(GT_CNS_NATIVELONG, TYP_LONG)
2738     {
2739         SetLngValue(val);
2740     }
2741 #if DEBUGGABLE_GENTREE
2742     GenTreeLngCon() : GenTreeIntConCommon()
2743     {
2744     }
2745 #endif
2746 };
2747
2748 inline INT64 GenTreeIntConCommon::LngValue()
2749 {
2750 #ifndef _TARGET_64BIT_
2751     assert(gtOper == GT_CNS_LNG);
2752     return AsLngCon()->gtLconVal;
2753 #else
2754     return IconValue();
2755 #endif
2756 }
2757
2758 inline void GenTreeIntConCommon::SetLngValue(INT64 val)
2759 {
2760 #ifndef _TARGET_64BIT_
2761     assert(gtOper == GT_CNS_LNG);
2762     AsLngCon()->gtLconVal = val;
2763 #else
2764     // Compile time asserts that these two fields overlap and have the same offsets:  gtIconVal and gtLconVal
2765     C_ASSERT(offsetof(GenTreeLngCon, gtLconVal) == offsetof(GenTreeIntCon, gtIconVal));
2766     C_ASSERT(sizeof(AsLngCon()->gtLconVal) == sizeof(AsIntCon()->gtIconVal));
2767
2768     SetIconValue(ssize_t(val));
2769 #endif
2770 }
2771
2772 inline ssize_t GenTreeIntConCommon::IconValue()
2773 {
2774     assert(gtOper == GT_CNS_INT); //  We should never see a GT_CNS_LNG for a 64-bit target!
2775     return AsIntCon()->gtIconVal;
2776 }
2777
2778 inline void GenTreeIntConCommon::SetIconValue(ssize_t val)
2779 {
2780     assert(gtOper == GT_CNS_INT); //  We should never see a GT_CNS_LNG for a 64-bit target!
2781     AsIntCon()->gtIconVal = val;
2782 }
2783
2784 inline INT64 GenTreeIntConCommon::IntegralValue()
2785 {
2786 #ifdef _TARGET_64BIT_
2787     return LngValue();
2788 #else
2789     return gtOper == GT_CNS_LNG ? LngValue() : (INT64)IconValue();
2790 #endif // _TARGET_64BIT_
2791 }
2792
2793 /* gtDblCon -- double  constant (GT_CNS_DBL) */
2794
2795 struct GenTreeDblCon : public GenTree
2796 {
2797     double gtDconVal;
2798
2799     bool isBitwiseEqual(GenTreeDblCon* other)
2800     {
2801         unsigned __int64 bits      = *(unsigned __int64*)(&gtDconVal);
2802         unsigned __int64 otherBits = *(unsigned __int64*)(&(other->gtDconVal));
2803         return (bits == otherBits);
2804     }
2805
2806     GenTreeDblCon(double val) : GenTree(GT_CNS_DBL, TYP_DOUBLE), gtDconVal(val)
2807     {
2808     }
2809 #if DEBUGGABLE_GENTREE
2810     GenTreeDblCon() : GenTree()
2811     {
2812     }
2813 #endif
2814 };
2815
2816 /* gtStrCon -- string  constant (GT_CNS_STR) */
2817
2818 struct GenTreeStrCon : public GenTree
2819 {
2820     unsigned              gtSconCPX;
2821     CORINFO_MODULE_HANDLE gtScpHnd;
2822
2823     // Because this node can come from an inlined method we need to
2824     // have the scope handle, since it will become a helper call.
2825     GenTreeStrCon(unsigned sconCPX, CORINFO_MODULE_HANDLE mod DEBUGARG(bool largeNode = false))
2826         : GenTree(GT_CNS_STR, TYP_REF DEBUGARG(largeNode)), gtSconCPX(sconCPX), gtScpHnd(mod)
2827     {
2828     }
2829 #if DEBUGGABLE_GENTREE
2830     GenTreeStrCon() : GenTree()
2831     {
2832     }
2833 #endif
2834 };
2835
2836 // Common supertype of LCL_VAR, LCL_FLD, REG_VAR, PHI_ARG
2837 // This inherits from UnOp because lclvar stores are Unops
2838 struct GenTreeLclVarCommon : public GenTreeUnOp
2839 {
2840 private:
2841     unsigned _gtLclNum; // The local number. An index into the Compiler::lvaTable array.
2842     unsigned _gtSsaNum; // The SSA number.
2843
2844 public:
2845     GenTreeLclVarCommon(genTreeOps oper, var_types type, unsigned lclNum DEBUGARG(bool largeNode = false))
2846         : GenTreeUnOp(oper, type DEBUGARG(largeNode))
2847     {
2848         SetLclNum(lclNum);
2849     }
2850
2851     unsigned GetLclNum() const
2852     {
2853         return _gtLclNum;
2854     }
2855     __declspec(property(get = GetLclNum)) unsigned gtLclNum;
2856
2857     void SetLclNum(unsigned lclNum)
2858     {
2859         _gtLclNum = lclNum;
2860         _gtSsaNum = SsaConfig::RESERVED_SSA_NUM;
2861     }
2862
2863     unsigned GetSsaNum() const
2864     {
2865         return _gtSsaNum;
2866     }
2867     __declspec(property(get = GetSsaNum)) unsigned gtSsaNum;
2868
2869     void SetSsaNum(unsigned ssaNum)
2870     {
2871         _gtSsaNum = ssaNum;
2872     }
2873
2874     bool HasSsaName()
2875     {
2876         return (gtSsaNum != SsaConfig::RESERVED_SSA_NUM);
2877     }
2878
2879 #if DEBUGGABLE_GENTREE
2880     GenTreeLclVarCommon() : GenTreeUnOp()
2881     {
2882     }
2883 #endif
2884 };
2885
2886 // gtLclVar -- load/store/addr of local variable
2887
2888 struct GenTreeLclVar : public GenTreeLclVarCommon
2889 {
2890     IL_OFFSET gtLclILoffs; // instr offset of ref (only for debug info)
2891
2892     GenTreeLclVar(var_types type, unsigned lclNum, IL_OFFSET ilOffs DEBUGARG(bool largeNode = false))
2893         : GenTreeLclVarCommon(GT_LCL_VAR, type, lclNum DEBUGARG(largeNode)), gtLclILoffs(ilOffs)
2894     {
2895     }
2896
2897     GenTreeLclVar(genTreeOps oper, var_types type, unsigned lclNum, IL_OFFSET ilOffs DEBUGARG(bool largeNode = false))
2898         : GenTreeLclVarCommon(oper, type, lclNum DEBUGARG(largeNode)), gtLclILoffs(ilOffs)
2899     {
2900         assert(OperIsLocal(oper) || OperIsLocalAddr(oper));
2901     }
2902
2903 #if DEBUGGABLE_GENTREE
2904     GenTreeLclVar() : GenTreeLclVarCommon()
2905     {
2906     }
2907 #endif
2908 };
2909
2910 // gtLclFld -- load/store/addr of local variable field
2911
2912 struct GenTreeLclFld : public GenTreeLclVarCommon
2913 {
2914     unsigned gtLclOffs; // offset into the variable to access
2915
2916     FieldSeqNode* gtFieldSeq; // This LclFld node represents some sequences of accesses.
2917
2918     // old/FE style constructor where load/store/addr share same opcode
2919     GenTreeLclFld(var_types type, unsigned lclNum, unsigned lclOffs)
2920         : GenTreeLclVarCommon(GT_LCL_FLD, type, lclNum), gtLclOffs(lclOffs), gtFieldSeq(nullptr)
2921     {
2922         assert(sizeof(*this) <= s_gtNodeSizes[GT_LCL_FLD]);
2923     }
2924
2925     GenTreeLclFld(genTreeOps oper, var_types type, unsigned lclNum, unsigned lclOffs)
2926         : GenTreeLclVarCommon(oper, type, lclNum), gtLclOffs(lclOffs), gtFieldSeq(nullptr)
2927     {
2928         assert(sizeof(*this) <= s_gtNodeSizes[GT_LCL_FLD]);
2929     }
2930 #if DEBUGGABLE_GENTREE
2931     GenTreeLclFld() : GenTreeLclVarCommon()
2932     {
2933     }
2934 #endif
2935 };
2936
2937 struct GenTreeRegVar : public GenTreeLclVarCommon
2938 {
2939     // TODO-Cleanup: Note that the base class GenTree already has a gtRegNum field.
2940     // It's not clear exactly why a GT_REG_VAR has a separate field. When
2941     // GT_REG_VAR is created, the two are identical. It appears that they may
2942     // or may not remain so. In particular, there is a comment in stackfp.cpp
2943     // that states:
2944     //
2945     //      There used to be an assertion: assert(src->gtRegNum == src->gtRegVar.gtRegNum, ...)
2946     //      here, but there's actually no reason to assume that.  AFAICT, for FP vars under stack FP,
2947     //      src->gtRegVar.gtRegNum is the allocated stack pseudo-register, but src->gtRegNum is the
2948     //      FP stack position into which that is loaded to represent a particular use of the variable.
2949     //
2950     // It might be the case that only for stackfp do they ever differ.
2951     //
2952     // The following might be possible: the GT_REG_VAR node has a last use prior to a complex
2953     // subtree being evaluated. It could then be spilled from the register. Later,
2954     // it could be unspilled into a different register, which would be recorded at
2955     // the unspill time in the GenTree::gtRegNum, whereas GenTreeRegVar::gtRegNum
2956     // is left alone. It's not clear why that is useful.
2957     //
2958     // Assuming there is a particular use, like stack fp, that requires it, maybe we
2959     // can get rid of GT_REG_VAR and just leave it as GT_LCL_VAR, using the base class gtRegNum field.
2960     // If we need it for stackfp, we could add a GenTreeStackFPRegVar type, which carries both the
2961     // pieces of information, in a clearer and more specific way (in particular, with
2962     // a different member name).
2963     //
2964
2965 private:
2966     regNumberSmall _gtRegNum;
2967
2968 public:
2969     GenTreeRegVar(var_types type, unsigned lclNum, regNumber regNum) : GenTreeLclVarCommon(GT_REG_VAR, type, lclNum)
2970     {
2971         gtRegNum = regNum;
2972     }
2973
2974     // The register number is stored in a small format (8 bits), but the getters return and the setters take
2975     // a full-size (unsigned) format, to localize the casts here.
2976
2977     __declspec(property(get = GetRegNum, put = SetRegNum)) regNumber gtRegNum;
2978
2979     regNumber GetRegNum() const
2980     {
2981         return (regNumber)_gtRegNum;
2982     }
2983
2984     void SetRegNum(regNumber reg)
2985     {
2986         _gtRegNum = (regNumberSmall)reg;
2987         assert(_gtRegNum == reg);
2988     }
2989
2990 #if DEBUGGABLE_GENTREE
2991     GenTreeRegVar() : GenTreeLclVarCommon()
2992     {
2993     }
2994 #endif
2995 };
2996
2997 /* gtCast -- conversion to a different type  (GT_CAST) */
2998
2999 struct GenTreeCast : public GenTreeOp
3000 {
3001     GenTree*& CastOp()
3002     {
3003         return gtOp1;
3004     }
3005     var_types gtCastType;
3006
3007     GenTreeCast(var_types type, GenTree* op, bool fromUnsigned, var_types castType DEBUGARG(bool largeNode = false))
3008         : GenTreeOp(GT_CAST, type, op, nullptr DEBUGARG(largeNode)), gtCastType(castType)
3009     {
3010         gtFlags |= fromUnsigned ? GTF_UNSIGNED : 0;
3011     }
3012 #if DEBUGGABLE_GENTREE
3013     GenTreeCast() : GenTreeOp()
3014     {
3015     }
3016 #endif
3017 };
3018
3019 // GT_BOX nodes are place markers for boxed values.  The "real" tree
3020 // for most purposes is in gtBoxOp.
3021 struct GenTreeBox : public GenTreeUnOp
3022 {
3023     // An expanded helper call to implement the "box" if we don't get
3024     // rid of it any other way.  Must be in same position as op1.
3025
3026     GenTree*& BoxOp()
3027     {
3028         return gtOp1;
3029     }
3030     // This is the statement that contains the assignment tree when the node is an inlined GT_BOX on a value
3031     // type
3032     GenTree* gtAsgStmtWhenInlinedBoxValue;
3033     // And this is the statement that copies from the value being boxed to the box payload
3034     GenTree* gtCopyStmtWhenInlinedBoxValue;
3035
3036     GenTreeBox(var_types type,
3037                GenTree*  boxOp,
3038                GenTree*  asgStmtWhenInlinedBoxValue,
3039                GenTree*  copyStmtWhenInlinedBoxValue)
3040         : GenTreeUnOp(GT_BOX, type, boxOp)
3041         , gtAsgStmtWhenInlinedBoxValue(asgStmtWhenInlinedBoxValue)
3042         , gtCopyStmtWhenInlinedBoxValue(copyStmtWhenInlinedBoxValue)
3043     {
3044     }
3045 #if DEBUGGABLE_GENTREE
3046     GenTreeBox() : GenTreeUnOp()
3047     {
3048     }
3049 #endif
3050 };
3051
3052 /* gtField  -- data member ref  (GT_FIELD) */
3053
3054 struct GenTreeField : public GenTree
3055 {
3056     GenTree*             gtFldObj;
3057     CORINFO_FIELD_HANDLE gtFldHnd;
3058     DWORD                gtFldOffset;
3059     bool                 gtFldMayOverlap;
3060 #ifdef FEATURE_READYTORUN_COMPILER
3061     CORINFO_CONST_LOOKUP gtFieldLookup;
3062 #endif
3063
3064     GenTreeField(var_types type) : GenTree(GT_FIELD, type)
3065     {
3066         gtFldMayOverlap = false;
3067     }
3068 #if DEBUGGABLE_GENTREE
3069     GenTreeField() : GenTree()
3070     {
3071     }
3072 #endif
3073 };
3074
3075 // Represents the Argument list of a call node, as a Lisp-style linked list.
3076 // (Originally I had hoped that this could have *only* the m_arg/m_rest fields, but it turns out
3077 // that enough of the GenTree mechanism is used that it makes sense just to make it a subtype.  But
3078 // note that in many ways, this is *not* a "real" node of the tree, but rather a mechanism for
3079 // giving call nodes a flexible number of children.  GenTreeArgListNodes never evaluate to registers,
3080 // for example.)
3081
3082 // Note that while this extends GenTreeOp, it is *not* an EXOP.  We don't add any new fields, and one
3083 // is free to allocate a GenTreeOp of type GT_LIST.  If you use this type, you get the convenient Current/Rest
3084 // method names for the arguments.
3085 struct GenTreeArgList : public GenTreeOp
3086 {
3087     GenTree*& Current()
3088     {
3089         return gtOp1;
3090     }
3091     GenTreeArgList*& Rest()
3092     {
3093         assert(gtOp2 == nullptr || gtOp2->OperIsAnyList());
3094         return *reinterpret_cast<GenTreeArgList**>(&gtOp2);
3095     }
3096
3097 #if DEBUGGABLE_GENTREE
3098     GenTreeArgList() : GenTreeOp()
3099     {
3100     }
3101 #endif
3102
3103     GenTreeArgList(GenTree* arg) : GenTreeArgList(arg, nullptr)
3104     {
3105     }
3106
3107     GenTreeArgList(GenTree* arg, GenTreeArgList* rest) : GenTreeArgList(GT_LIST, arg, rest)
3108     {
3109     }
3110
3111     GenTreeArgList(genTreeOps oper, GenTree* arg, GenTreeArgList* rest) : GenTreeOp(oper, TYP_VOID, arg, rest)
3112     {
3113         assert(OperIsAnyList(oper));
3114         assert((arg != nullptr) && arg->IsValidCallArgument());
3115         gtFlags |= arg->gtFlags & GTF_ALL_EFFECT;
3116         if (rest != nullptr)
3117         {
3118             gtFlags |= rest->gtFlags & GTF_ALL_EFFECT;
3119         }
3120     }
3121 };
3122
3123 // Represents a list of fields constituting a struct, when it is passed as an argument.
3124 // The first field of the struct is marked with the GTF_FIELD_LIST_HEAD flag, and
3125 // in LIR form it is the only member of the list that is threaded into the execution
3126 // order.
3127 // It differs from the GenTreeArgList in a couple of ways:
3128 // - The entire list represents a single argument.
3129 // - It contains additional fields to provide the offset and type of the field.
3130 //
3131 struct GenTreeFieldList : public GenTreeArgList
3132 {
3133     unsigned  gtFieldOffset;
3134     var_types gtFieldType;
3135
3136     bool IsFieldListHead() const
3137     {
3138         return (gtFlags & GTF_FIELD_LIST_HEAD) != 0;
3139     }
3140
3141 #if DEBUGGABLE_GENTREE
3142     GenTreeFieldList() : GenTreeArgList()
3143     {
3144     }
3145 #endif
3146
3147     GenTreeFieldList*& Rest()
3148     {
3149         assert(gtOp2 == nullptr || gtOp2->OperGet() == GT_FIELD_LIST);
3150         return *reinterpret_cast<GenTreeFieldList**>(&gtOp2);
3151     }
3152
3153     GenTreeFieldList(GenTree* arg, unsigned fieldOffset, var_types fieldType, GenTreeFieldList* prevList)
3154         : GenTreeArgList(GT_FIELD_LIST, arg, nullptr)
3155     {
3156         // While GT_FIELD_LIST can be in a GT_LIST, GT_FIELD_LISTs cannot be nested or have GT_LISTs.
3157         assert(!arg->OperIsAnyList());
3158         gtFieldOffset = fieldOffset;
3159         gtFieldType   = fieldType;
3160         gtType        = fieldType;
3161         if (prevList == nullptr)
3162         {
3163             gtFlags |= GTF_FIELD_LIST_HEAD;
3164 #ifndef LEGACY_BACKEND
3165             // A GT_FIELD_LIST head is always contained. Other nodes return false from IsValue()
3166             // and should not be marked as contained.
3167             SetContained();
3168 #endif
3169         }
3170         else
3171         {
3172             prevList->gtOp2 = this;
3173         }
3174     }
3175 };
3176
3177 // There was quite a bit of confusion in the code base about which of gtOp1 and gtOp2 was the
3178 // 'then' and 'else' clause of a colon node.  Adding these accessors, while not enforcing anything,
3179 // at least *allows* the programmer to be obviously correct.
3180 // However, these conventions seem backward.
3181 // TODO-Cleanup: If we could get these accessors used everywhere, then we could switch them.
3182 struct GenTreeColon : public GenTreeOp
3183 {
3184     GenTree*& ThenNode()
3185     {
3186         return gtOp2;
3187     }
3188     GenTree*& ElseNode()
3189     {
3190         return gtOp1;
3191     }
3192
3193 #if DEBUGGABLE_GENTREE
3194     GenTreeColon() : GenTreeOp()
3195     {
3196     }
3197 #endif
3198
3199     GenTreeColon(var_types typ, GenTree* thenNode, GenTree* elseNode) : GenTreeOp(GT_COLON, typ, elseNode, thenNode)
3200     {
3201     }
3202 };
3203
3204 // gtCall   -- method call      (GT_CALL)
3205 enum class InlineObservation;
3206
3207 // Return type descriptor of a GT_CALL node.
3208 // x64 Unix, Arm64, Arm32 and x86 allow a value to be returned in multiple
3209 // registers. For such calls this struct provides the following info
3210 // on their return type
3211 //    - type of value returned in each return register
3212 //    - ABI return register numbers in which the value is returned
3213 //    - count of return registers in which the value is returned
3214 //
3215 // TODO-ARM: Update this to meet the needs of Arm64 and Arm32
3216 //
3217 // TODO-AllArch: Right now it is used for describing multi-reg returned types.
3218 // Eventually we would want to use it for describing even single-reg
3219 // returned types (e.g. structs returned in single register x64/arm).
3220 // This would allow us not to lie or normalize single struct return
3221 // values in importer/morph.
3222 struct ReturnTypeDesc
3223 {
3224 private:
3225     var_types m_regType[MAX_RET_REG_COUNT];
3226
3227 #ifdef DEBUG
3228     bool m_inited;
3229 #endif
3230
3231 public:
3232     ReturnTypeDesc()
3233     {
3234         Reset();
3235     }
3236
3237     // Initialize the Return Type Descriptor for a method that returns a struct type
3238     void InitializeStructReturnType(Compiler* comp, CORINFO_CLASS_HANDLE retClsHnd);
3239
3240     // Initialize the Return Type Descriptor for a method that returns a TYP_LONG
3241     // Only needed for X86
3242     void InitializeLongReturnType(Compiler* comp);
3243
3244     // Reset type descriptor to defaults
3245     void Reset()
3246     {
3247         for (unsigned i = 0; i < MAX_RET_REG_COUNT; ++i)
3248         {
3249             m_regType[i] = TYP_UNKNOWN;
3250         }
3251 #ifdef DEBUG
3252         m_inited = false;
3253 #endif
3254     }
3255
3256 #ifdef DEBUG
3257     // NOTE: we only use this function when writing out IR dumps. These dumps may take place before the ReturnTypeDesc
3258     // has been initialized.
3259     unsigned TryGetReturnRegCount() const
3260     {
3261         return m_inited ? GetReturnRegCount() : 0;
3262     }
3263 #endif // DEBUG
3264
3265     //--------------------------------------------------------------------------------------------
3266     // GetReturnRegCount:  Get the count of return registers in which the return value is returned.
3267     //
3268     // Arguments:
3269     //    None
3270     //
3271     // Return Value:
3272     //   Count of return registers.
3273     //   Returns 0 if the return type is not returned in registers.
3274     unsigned GetReturnRegCount() const
3275     {
3276         assert(m_inited);
3277
3278         int regCount = 0;
3279         for (unsigned i = 0; i < MAX_RET_REG_COUNT; ++i)
3280         {
3281             if (m_regType[i] == TYP_UNKNOWN)
3282             {
3283                 break;
3284             }
3285             // otherwise
3286             regCount++;
3287         }
3288
3289 #ifdef DEBUG
3290         // Any remaining elements in m_regTypes[] should also be TYP_UNKNOWN
3291         for (unsigned i = regCount + 1; i < MAX_RET_REG_COUNT; ++i)
3292         {
3293             assert(m_regType[i] == TYP_UNKNOWN);
3294         }
3295 #endif
3296
3297         return regCount;
3298     }
3299
3300     //-----------------------------------------------------------------------
3301     // IsMultiRegRetType: check whether the type is returned in multiple
3302     // return registers.
3303     //
3304     // Arguments:
3305     //    None
3306     //
3307     // Return Value:
3308     //    Returns true if the type is returned in multiple return registers.
3309     //    False otherwise.
3310     // Note that we only have to examine the first two values to determine this
3311     //
3312     bool IsMultiRegRetType() const
3313     {
3314         if (MAX_RET_REG_COUNT < 2)
3315         {
3316             return false;
3317         }
3318         else
3319         {
3320             return ((m_regType[0] != TYP_UNKNOWN) && (m_regType[1] != TYP_UNKNOWN));
3321         }
3322     }
3323
3324     //--------------------------------------------------------------------------
3325     // GetReturnRegType:  Get var_type of the return register specified by index.
3326     //
3327     // Arguments:
3328     //    index - Index of the return register.
3329     //            First return register will have an index 0 and so on.
3330     //
3331     // Return Value:
3332     //    var_type of the return register specified by its index.
3333     //    asserts if the index does not have a valid register return type.
3334
3335     var_types GetReturnRegType(unsigned index)
3336     {
3337         var_types result = m_regType[index];
3338         assert(result != TYP_UNKNOWN);
3339
3340         return result;
3341     }
3342
3343     // Get ith ABI return register
3344     regNumber GetABIReturnReg(unsigned idx);
3345
3346     // Get reg mask of ABI return registers
3347     regMaskTP GetABIReturnRegs();
3348 };
3349
3350 class fgArgInfo;
3351
3352 struct GenTreeCall final : public GenTree
3353 {
3354     GenTree*        gtCallObjp;     // The instance argument ('this' pointer)
3355     GenTreeArgList* gtCallArgs;     // The list of arguments in original evaluation order
3356     GenTreeArgList* gtCallLateArgs; // On x86:     The register arguments in an optimal order
3357                                     // On ARM/x64: - also includes any outgoing arg space arguments
3358                                     //             - that were evaluated into a temp LclVar
3359     fgArgInfo* fgArgInfo;
3360
3361 #if !FEATURE_FIXED_OUT_ARGS
3362     int     regArgListCount;
3363     regList regArgList;
3364 #endif
3365
3366     // TODO-Throughput: Revisit this (this used to be only defined if
3367     // FEATURE_FIXED_OUT_ARGS was enabled, so this makes GenTreeCall 4 bytes bigger on x86).
3368     CORINFO_SIG_INFO* callSig; // Used by tail calls and to register callsites with the EE
3369
3370 #ifdef LEGACY_BACKEND
3371     regMaskTP gtCallRegUsedMask; // mask of registers used to pass parameters
3372 #endif                           // LEGACY_BACKEND
3373
3374 #if FEATURE_MULTIREG_RET
3375
3376     // State required to support multi-reg returning call nodes.
3377     // For now it is enabled only for x64 unix.
3378     //
3379     // TODO-AllArch: enable for all call nodes to unify single-reg and multi-reg returns.
3380     ReturnTypeDesc gtReturnTypeDesc;
3381
3382     // gtRegNum would always be the first return reg.
3383     // The following array holds the other reg numbers of multi-reg return.
3384     regNumberSmall gtOtherRegs[MAX_RET_REG_COUNT - 1];
3385
3386     // GTF_SPILL or GTF_SPILLED flag on a multi-reg call node indicates that one or
3387     // more of its result regs are in that state.  The spill flag of each of the
3388     // return register is stored here. We only need 2 bits per returned register,
3389     // so this is treated as a 2-bit array. No architecture needs more than 8 bits.
3390
3391     static const unsigned PACKED_GTF_SPILL   = 1;
3392     static const unsigned PACKED_GTF_SPILLED = 2;
3393     unsigned char         gtSpillFlags;
3394
3395 #endif // FEATURE_MULTIREG_RET
3396
3397     //-----------------------------------------------------------------------
3398     // GetReturnTypeDesc: get the type descriptor of return value of the call
3399     //
3400     // Arguments:
3401     //    None
3402     //
3403     // Returns
3404     //    Type descriptor of the value returned by call
3405     //
3406     // Note:
3407     //    Right now implemented only for x64 unix and yet to be
3408     //    implemented for other multi-reg target arch (Arm64/Arm32/x86).
3409     //
3410     // TODO-AllArch: enable for all call nodes to unify single-reg and multi-reg returns.
3411     ReturnTypeDesc* GetReturnTypeDesc()
3412     {
3413 #if FEATURE_MULTIREG_RET
3414         return &gtReturnTypeDesc;
3415 #else
3416         return nullptr;
3417 #endif
3418     }
3419
3420     //---------------------------------------------------------------------------
3421     // GetRegNumByIdx: get ith return register allocated to this call node.
3422     //
3423     // Arguments:
3424     //     idx   -   index of the return register
3425     //
3426     // Return Value:
3427     //     Return regNumber of ith return register of call node.
3428     //     Returns REG_NA if there is no valid return register for the given index.
3429     //
3430     regNumber GetRegNumByIdx(unsigned idx) const
3431     {
3432         assert(idx < MAX_RET_REG_COUNT);
3433
3434         if (idx == 0)
3435         {
3436             return gtRegNum;
3437         }
3438
3439 #if FEATURE_MULTIREG_RET
3440         return (regNumber)gtOtherRegs[idx - 1];
3441 #else
3442         return REG_NA;
3443 #endif
3444     }
3445
3446     //----------------------------------------------------------------------
3447     // SetRegNumByIdx: set ith return register of this call node
3448     //
3449     // Arguments:
3450     //    reg    -   reg number
3451     //    idx    -   index of the return register
3452     //
3453     // Return Value:
3454     //    None
3455     //
3456     void SetRegNumByIdx(regNumber reg, unsigned idx)
3457     {
3458         assert(idx < MAX_RET_REG_COUNT);
3459
3460         if (idx == 0)
3461         {
3462             gtRegNum = reg;
3463         }
3464 #if FEATURE_MULTIREG_RET
3465         else
3466         {
3467             gtOtherRegs[idx - 1] = (regNumberSmall)reg;
3468             assert(gtOtherRegs[idx - 1] == reg);
3469         }
3470 #else
3471         unreached();
3472 #endif
3473     }
3474
3475     //----------------------------------------------------------------------------
3476     // ClearOtherRegs: clear multi-reg state to indicate no regs are allocated
3477     //
3478     // Arguments:
3479     //    None
3480     //
3481     // Return Value:
3482     //    None
3483     //
3484     void ClearOtherRegs()
3485     {
3486 #if FEATURE_MULTIREG_RET
3487         for (unsigned i = 0; i < MAX_RET_REG_COUNT - 1; ++i)
3488         {
3489             gtOtherRegs[i] = REG_NA;
3490         }
3491 #endif
3492     }
3493
3494     //----------------------------------------------------------------------------
3495     // CopyOtherRegs: copy multi-reg state from the given call node to this node
3496     //
3497     // Arguments:
3498     //    fromCall  -  GenTreeCall node from which to copy multi-reg state
3499     //
3500     // Return Value:
3501     //    None
3502     //
3503     void CopyOtherRegs(GenTreeCall* fromCall)
3504     {
3505 #if FEATURE_MULTIREG_RET
3506         for (unsigned i = 0; i < MAX_RET_REG_COUNT - 1; ++i)
3507         {
3508             this->gtOtherRegs[i] = fromCall->gtOtherRegs[i];
3509         }
3510 #endif
3511     }
3512
3513     // Get reg mask of all the valid registers of gtOtherRegs array
3514     regMaskTP GetOtherRegMask() const;
3515
3516     //----------------------------------------------------------------------
3517     // GetRegSpillFlagByIdx: get spill flag associated with the return register
3518     // specified by its index.
3519     //
3520     // Arguments:
3521     //    idx  -  Position or index of the return register
3522     //
3523     // Return Value:
3524     //    Returns GTF_* flags associated with the register. Only GTF_SPILL and GTF_SPILLED are considered.
3525     //
3526     unsigned GetRegSpillFlagByIdx(unsigned idx) const
3527     {
3528         static_assert_no_msg(MAX_RET_REG_COUNT * 2 <= sizeof(unsigned char) * BITS_PER_BYTE);
3529         assert(idx < MAX_RET_REG_COUNT);
3530
3531 #if FEATURE_MULTIREG_RET
3532         unsigned bits = gtSpillFlags >> (idx * 2); // It doesn't matter that we possibly leave other high bits here.
3533         unsigned spillFlags = 0;
3534         if (bits & PACKED_GTF_SPILL)
3535         {
3536             spillFlags |= GTF_SPILL;
3537         }
3538         if (bits & PACKED_GTF_SPILLED)
3539         {
3540             spillFlags |= GTF_SPILLED;
3541         }
3542         return spillFlags;
3543 #else
3544         assert(!"unreached");
3545         return 0;
3546 #endif
3547     }
3548
3549     //----------------------------------------------------------------------
3550     // SetRegSpillFlagByIdx: set spill flags for the return register
3551     // specified by its index.
3552     //
3553     // Arguments:
3554     //    flags  -  GTF_* flags. Only GTF_SPILL and GTF_SPILLED are allowed.
3555     //    idx    -  Position or index of the return register
3556     //
3557     // Return Value:
3558     //    None
3559     //
3560     void SetRegSpillFlagByIdx(unsigned flags, unsigned idx)
3561     {
3562         static_assert_no_msg(MAX_RET_REG_COUNT * 2 <= sizeof(unsigned char) * BITS_PER_BYTE);
3563         assert(idx < MAX_RET_REG_COUNT);
3564
3565 #if FEATURE_MULTIREG_RET
3566         unsigned bits = 0;
3567         if (flags & GTF_SPILL)
3568         {
3569             bits |= PACKED_GTF_SPILL;
3570         }
3571         if (flags & GTF_SPILLED)
3572         {
3573             bits |= PACKED_GTF_SPILLED;
3574         }
3575
3576         const unsigned char packedFlags = PACKED_GTF_SPILL | PACKED_GTF_SPILLED;
3577
3578         // Clear anything that was already there by masking out the bits before 'or'ing in what we want there.
3579         gtSpillFlags = (unsigned char)((gtSpillFlags & ~(packedFlags << (idx * 2))) | (bits << (idx * 2)));
3580 #else
3581         unreached();
3582 #endif
3583     }
3584
3585     //-------------------------------------------------------------------
3586     // clearOtherRegFlags: clear GTF_* flags associated with gtOtherRegs
3587     //
3588     // Arguments:
3589     //     None
3590     //
3591     // Return Value:
3592     //     None
3593     void ClearOtherRegFlags()
3594     {
3595 #if FEATURE_MULTIREG_RET
3596         gtSpillFlags = 0;
3597 #endif
3598     }
3599
3600     //-------------------------------------------------------------------------
3601     // CopyOtherRegFlags: copy GTF_* flags associated with gtOtherRegs from
3602     // the given call node.
3603     //
3604     // Arguments:
3605     //    fromCall  -  GenTreeCall node from which to copy
3606     //
3607     // Return Value:
3608     //    None
3609     //
3610     void CopyOtherRegFlags(GenTreeCall* fromCall)
3611     {
3612 #if FEATURE_MULTIREG_RET
3613         this->gtSpillFlags = fromCall->gtSpillFlags;
3614 #endif
3615     }
3616
3617 // clang-format off
3618
3619 #define GTF_CALL_M_EXPLICIT_TAILCALL     0x00000001 // GT_CALL -- the call is "tail" prefixed and
3620                                                     // importer has performed tail call checks
3621 #define GTF_CALL_M_TAILCALL              0x00000002 // GT_CALL -- the call is a tailcall
3622 #define GTF_CALL_M_VARARGS               0x00000004 // GT_CALL -- the call uses varargs ABI
3623 #define GTF_CALL_M_RETBUFFARG            0x00000008 // GT_CALL -- first parameter is the return buffer argument
3624 #define GTF_CALL_M_DELEGATE_INV          0x00000010 // GT_CALL -- call to Delegate.Invoke
3625 #define GTF_CALL_M_NOGCCHECK             0x00000020 // GT_CALL -- not a call for computing full interruptability
3626 #define GTF_CALL_M_SPECIAL_INTRINSIC     0x00000040 // GT_CALL -- function that could be optimized as an intrinsic
3627                                                     // in special cases. Used to optimize fast way out in morphing
3628 #define GTF_CALL_M_UNMGD_THISCALL        0x00000080 // GT_CALL -- "this" pointer (first argument)
3629                                                     // should be enregistered (only for GTF_CALL_UNMANAGED)
3630 #define GTF_CALL_M_VIRTSTUB_REL_INDIRECT 0x00000080 // the virtstub is indirected through
3631                                                     // a relative address (only for GTF_CALL_VIRT_STUB)
3632 #define GTF_CALL_M_NONVIRT_SAME_THIS     0x00000080 // GT_CALL -- callee "this" pointer is
3633                                                     // equal to caller this pointer (only for GTF_CALL_NONVIRT)
3634 #define GTF_CALL_M_FRAME_VAR_DEATH       0x00000100 // GT_CALL -- the compLvFrameListRoot variable dies here (last use)
3635
3636 #ifndef LEGACY_BACKEND
3637 #define GTF_CALL_M_TAILCALL_VIA_HELPER   0x00000200 // GT_CALL -- call is a tail call dispatched via tail call JIT helper.
3638 #endif
3639
3640 #if FEATURE_TAILCALL_OPT
3641 #define GTF_CALL_M_IMPLICIT_TAILCALL     0x00000400 // GT_CALL -- call is an opportunistic
3642                                                     // tail call and importer has performed tail call checks
3643 #define GTF_CALL_M_TAILCALL_TO_LOOP      0x00000800 // GT_CALL -- call is a fast recursive tail call
3644                                                     // that can be converted into a loop
3645 #endif
3646
3647 #define GTF_CALL_M_PINVOKE               0x00001000 // GT_CALL -- call is a pinvoke.  This mirrors VM flag CORINFO_FLG_PINVOKE.
3648                                                     // A call marked as Pinvoke is not necessarily a GT_CALL_UNMANAGED. For e.g.
3649                                                     // an IL Stub dynamically generated for a PInvoke declaration is flagged as
3650                                                     // a Pinvoke but not as an unmanaged call. See impCheckForPInvokeCall() to
3651                                                     // know when these flags are set.
3652
3653 #define GTF_CALL_M_R2R_REL_INDIRECT      0x00002000 // GT_CALL -- ready to run call is indirected through a relative address
3654 #define GTF_CALL_M_DOES_NOT_RETURN       0x00004000 // GT_CALL -- call does not return
3655 #define GTF_CALL_M_SECURE_DELEGATE_INV   0x00008000 // GT_CALL -- call is in secure delegate
3656 #define GTF_CALL_M_FAT_POINTER_CHECK     0x00010000 // GT_CALL -- CoreRT managed calli needs transformation, that checks
3657                                                     // special bit in calli address. If it is set, then it is necessary
3658                                                     // to restore real function address and load hidden argument
3659                                                     // as the first argument for calli. It is CoreRT replacement for instantiating
3660                                                     // stubs, because executable code cannot be generated at runtime.
3661 #define GTF_CALL_M_HELPER_SPECIAL_DCE    0x00020000 // GT_CALL -- this helper call can be removed if it is part of a comma and
3662                                                     // the comma result is unused.
3663
3664     // clang-format on
3665
3666     bool IsUnmanaged() const
3667     {
3668         return (gtFlags & GTF_CALL_UNMANAGED) != 0;
3669     }
3670     bool NeedsNullCheck() const
3671     {
3672         return (gtFlags & GTF_CALL_NULLCHECK) != 0;
3673     }
3674     bool CallerPop() const
3675     {
3676         return (gtFlags & GTF_CALL_POP_ARGS) != 0;
3677     }
3678     bool IsVirtual() const
3679     {
3680         return (gtFlags & GTF_CALL_VIRT_KIND_MASK) != GTF_CALL_NONVIRT;
3681     }
3682     bool IsVirtualStub() const
3683     {
3684         return (gtFlags & GTF_CALL_VIRT_KIND_MASK) == GTF_CALL_VIRT_STUB;
3685     }
3686     bool IsVirtualVtable() const
3687     {
3688         return (gtFlags & GTF_CALL_VIRT_KIND_MASK) == GTF_CALL_VIRT_VTABLE;
3689     }
3690     bool IsInlineCandidate() const
3691     {
3692         return (gtFlags & GTF_CALL_INLINE_CANDIDATE) != 0;
3693     }
3694
3695 #ifndef LEGACY_BACKEND
3696     bool HasNonStandardAddedArgs(Compiler* compiler) const;
3697     int GetNonStandardAddedArgCount(Compiler* compiler) const;
3698 #endif // !LEGACY_BACKEND
3699
3700     // Returns true if this call uses a retBuf argument and its calling convention
3701     bool HasRetBufArg() const
3702     {
3703         return (gtCallMoreFlags & GTF_CALL_M_RETBUFFARG) != 0;
3704     }
3705
3706     //-------------------------------------------------------------------------
3707     // TreatAsHasRetBufArg:
3708     //
3709     // Arguments:
3710     //     compiler, the compiler instance so that we can call eeGetHelperNum
3711     //
3712     // Return Value:
3713     //     Returns true if we treat the call as if it has a retBuf argument
3714     //     This method may actually have a retBuf argument
3715     //     or it could be a JIT helper that we are still transforming during
3716     //     the importer phase.
3717     //
3718     // Notes:
3719     //     On ARM64 marking the method with the GTF_CALL_M_RETBUFFARG flag
3720     //     will make HasRetBufArg() return true, but will also force the
3721     //     use of register x8 to pass the RetBuf argument.
3722     //
3723     bool TreatAsHasRetBufArg(Compiler* compiler) const;
3724
3725     //-----------------------------------------------------------------------------------------
3726     // HasMultiRegRetVal: whether the call node returns its value in multiple return registers.
3727     //
3728     // Arguments:
3729     //     None
3730     //
3731     // Return Value:
3732     //     True if the call is returning a multi-reg return value. False otherwise.
3733     //
3734     // Note:
3735     //     This is implemented only for x64 Unix and yet to be implemented for
3736     //     other multi-reg return target arch (arm64/arm32/x86).
3737     //
3738     bool HasMultiRegRetVal() const
3739     {
3740 #if defined(_TARGET_X86_) && !defined(LEGACY_BACKEND)
3741         // LEGACY_BACKEND does not use multi reg returns for calls with long return types
3742         return varTypeIsLong(gtType);
3743 #elif FEATURE_MULTIREG_RET && (defined(_TARGET_ARM_) && !defined(LEGACY_BACKEND))
3744         // LEGACY_BACKEND does not use multi reg returns for calls with long return types
3745         return varTypeIsLong(gtType) || (varTypeIsStruct(gtType) && !HasRetBufArg());
3746 #elif FEATURE_MULTIREG_RET
3747         return varTypeIsStruct(gtType) && !HasRetBufArg();
3748 #else
3749         return false;
3750 #endif
3751     }
3752
3753     // Returns true if VM has flagged this method as CORINFO_FLG_PINVOKE.
3754     bool IsPInvoke() const
3755     {
3756         return (gtCallMoreFlags & GTF_CALL_M_PINVOKE) != 0;
3757     }
3758
3759     // Note that the distinction of whether tail prefixed or an implicit tail call
3760     // is maintained on a call node till fgMorphCall() after which it will be
3761     // either a tail call (i.e. IsTailCall() is true) or a non-tail call.
3762     bool IsTailPrefixedCall() const
3763     {
3764         return (gtCallMoreFlags & GTF_CALL_M_EXPLICIT_TAILCALL) != 0;
3765     }
3766
3767     // This method returning "true" implies that tail call flowgraph morhphing has
3768     // performed final checks and committed to making a tail call.
3769     bool IsTailCall() const
3770     {
3771         return (gtCallMoreFlags & GTF_CALL_M_TAILCALL) != 0;
3772     }
3773
3774     // This method returning "true" implies that importer has performed tail call checks
3775     // and providing a hint that this can be converted to a tail call.
3776     bool CanTailCall() const
3777     {
3778         return IsTailPrefixedCall() || IsImplicitTailCall();
3779     }
3780
3781 #ifndef LEGACY_BACKEND
3782     bool IsTailCallViaHelper() const
3783     {
3784         return IsTailCall() && (gtCallMoreFlags & GTF_CALL_M_TAILCALL_VIA_HELPER);
3785     }
3786 #else  // LEGACY_BACKEND
3787     bool IsTailCallViaHelper() const
3788     {
3789         return true;
3790     }
3791 #endif // LEGACY_BACKEND
3792
3793 #if FEATURE_FASTTAILCALL
3794     bool IsFastTailCall() const
3795     {
3796         return IsTailCall() && !(gtCallMoreFlags & GTF_CALL_M_TAILCALL_VIA_HELPER);
3797     }
3798 #else  // !FEATURE_FASTTAILCALL
3799     bool IsFastTailCall() const
3800     {
3801         return false;
3802     }
3803 #endif // !FEATURE_FASTTAILCALL
3804
3805 #if FEATURE_TAILCALL_OPT
3806     // Returns true if this is marked for opportunistic tail calling.
3807     // That is, can be tail called though not explicitly prefixed with "tail" prefix.
3808     bool IsImplicitTailCall() const
3809     {
3810         return (gtCallMoreFlags & GTF_CALL_M_IMPLICIT_TAILCALL) != 0;
3811     }
3812     bool IsTailCallConvertibleToLoop() const
3813     {
3814         return (gtCallMoreFlags & GTF_CALL_M_TAILCALL_TO_LOOP) != 0;
3815     }
3816 #else  // !FEATURE_TAILCALL_OPT
3817     bool IsImplicitTailCall() const
3818     {
3819         return false;
3820     }
3821     bool IsTailCallConvertibleToLoop() const
3822     {
3823         return false;
3824     }
3825 #endif // !FEATURE_TAILCALL_OPT
3826
3827     bool IsSameThis() const
3828     {
3829         return (gtCallMoreFlags & GTF_CALL_M_NONVIRT_SAME_THIS) != 0;
3830     }
3831     bool IsDelegateInvoke() const
3832     {
3833         return (gtCallMoreFlags & GTF_CALL_M_DELEGATE_INV) != 0;
3834     }
3835     bool IsVirtualStubRelativeIndir() const
3836     {
3837         return (gtCallMoreFlags & GTF_CALL_M_VIRTSTUB_REL_INDIRECT) != 0;
3838     }
3839
3840 #ifdef FEATURE_READYTORUN_COMPILER
3841     bool IsR2RRelativeIndir() const
3842     {
3843         return (gtCallMoreFlags & GTF_CALL_M_R2R_REL_INDIRECT) != 0;
3844     }
3845     void setEntryPoint(CORINFO_CONST_LOOKUP entryPoint)
3846     {
3847         gtEntryPoint = entryPoint;
3848         if (gtEntryPoint.accessType == IAT_PVALUE)
3849         {
3850             gtCallMoreFlags |= GTF_CALL_M_R2R_REL_INDIRECT;
3851         }
3852     }
3853 #endif // FEATURE_READYTORUN_COMPILER
3854
3855     bool IsVarargs() const
3856     {
3857         return (gtCallMoreFlags & GTF_CALL_M_VARARGS) != 0;
3858     }
3859
3860     bool IsNoReturn() const
3861     {
3862         return (gtCallMoreFlags & GTF_CALL_M_DOES_NOT_RETURN) != 0;
3863     }
3864
3865     bool IsFatPointerCandidate() const
3866     {
3867         return (gtCallMoreFlags & GTF_CALL_M_FAT_POINTER_CHECK) != 0;
3868     }
3869
3870     bool IsPure(Compiler* compiler) const;
3871
3872     bool HasSideEffects(Compiler* compiler, bool ignoreExceptions = false, bool ignoreCctors = false) const;
3873
3874     void ClearFatPointerCandidate()
3875     {
3876         gtCallMoreFlags &= ~GTF_CALL_M_FAT_POINTER_CHECK;
3877     }
3878
3879     void SetFatPointerCandidate()
3880     {
3881         gtCallMoreFlags |= GTF_CALL_M_FAT_POINTER_CHECK;
3882     }
3883
3884     unsigned gtCallMoreFlags; // in addition to gtFlags
3885
3886     unsigned char gtCallType : 3;   // value from the gtCallTypes enumeration
3887     unsigned char gtReturnType : 5; // exact return type
3888
3889     CORINFO_CLASS_HANDLE gtRetClsHnd; // The return type handle of the call if it is a struct; always available
3890
3891     union {
3892         // only used for CALLI unmanaged calls (CT_INDIRECT)
3893         GenTree* gtCallCookie;
3894         // gtInlineCandidateInfo is only used when inlining methods
3895         InlineCandidateInfo*   gtInlineCandidateInfo;
3896         void*                  gtStubCallStubAddr;              // GTF_CALL_VIRT_STUB - these are never inlined
3897         CORINFO_GENERIC_HANDLE compileTimeHelperArgumentHandle; // Used to track type handle argument of dynamic helpers
3898         void*                  gtDirectCallAddress; // Used to pass direct call address between lower and codegen
3899     };
3900
3901     // expression evaluated after args are placed which determines the control target
3902     GenTree* gtControlExpr;
3903
3904     union {
3905         CORINFO_METHOD_HANDLE gtCallMethHnd; // CT_USER_FUNC
3906         GenTree*              gtCallAddr;    // CT_INDIRECT
3907     };
3908
3909 #ifdef FEATURE_READYTORUN_COMPILER
3910     // Call target lookup info for method call from a Ready To Run module
3911     CORINFO_CONST_LOOKUP gtEntryPoint;
3912 #endif
3913
3914 #if defined(DEBUG) || defined(INLINE_DATA)
3915     // For non-inline candidates, track the first observation
3916     // that blocks candidacy.
3917     InlineObservation gtInlineObservation;
3918
3919     // IL offset of the call wrt its parent method.
3920     IL_OFFSET gtRawILOffset;
3921 #endif // defined(DEBUG) || defined(INLINE_DATA)
3922
3923     bool IsHelperCall() const
3924     {
3925         return gtCallType == CT_HELPER;
3926     }
3927
3928     bool IsHelperCall(CORINFO_METHOD_HANDLE callMethHnd) const
3929     {
3930         return IsHelperCall() && (callMethHnd == gtCallMethHnd);
3931     }
3932
3933     bool IsHelperCall(Compiler* compiler, unsigned helper) const;
3934
3935     void ReplaceCallOperand(GenTree** operandUseEdge, GenTree* replacement);
3936
3937     bool AreArgsComplete() const;
3938
3939     GenTreeCall(var_types type) : GenTree(GT_CALL, type)
3940     {
3941         fgArgInfo = nullptr;
3942     }
3943 #if DEBUGGABLE_GENTREE
3944     GenTreeCall() : GenTree()
3945     {
3946     }
3947 #endif
3948 };
3949
3950 struct GenTreeCmpXchg : public GenTree
3951 {
3952     GenTree* gtOpLocation;
3953     GenTree* gtOpValue;
3954     GenTree* gtOpComparand;
3955
3956     GenTreeCmpXchg(var_types type, GenTree* loc, GenTree* val, GenTree* comparand)
3957         : GenTree(GT_CMPXCHG, type), gtOpLocation(loc), gtOpValue(val), gtOpComparand(comparand)
3958     {
3959         // There's no reason to do a compare-exchange on a local location, so we'll assume that all of these
3960         // have global effects.
3961         gtFlags |= (GTF_GLOB_REF | GTF_ASG);
3962     }
3963 #if DEBUGGABLE_GENTREE
3964     GenTreeCmpXchg() : GenTree()
3965     {
3966     }
3967 #endif
3968 };
3969
3970 #if !defined(LEGACY_BACKEND) && defined(_TARGET_ARM_)
3971 struct GenTreeMultiRegOp : public GenTreeOp
3972 {
3973     regNumber gtOtherReg;
3974
3975     // GTF_SPILL or GTF_SPILLED flag on a multi-reg node indicates that one or
3976     // more of its result regs are in that state.  The spill flag of each of the
3977     // return register is stored here. We only need 2 bits per returned register,
3978     // so this is treated as a 2-bit array. No architecture needs more than 8 bits.
3979
3980     static const unsigned PACKED_GTF_SPILL   = 1;
3981     static const unsigned PACKED_GTF_SPILLED = 2;
3982     unsigned char         gtSpillFlags;
3983
3984     GenTreeMultiRegOp(genTreeOps oper, var_types type, GenTree* op1, GenTree* op2)
3985         : GenTreeOp(oper, type, op1, op2), gtOtherReg(REG_NA)
3986     {
3987         ClearOtherRegFlags();
3988     }
3989
3990     unsigned GetRegCount() const
3991     {
3992         if (gtRegNum == REG_NA || gtRegNum == REG_STK)
3993         {
3994             return 0;
3995         }
3996         return (gtOtherReg == REG_NA || gtOtherReg == REG_STK) ? 1 : 2;
3997     }
3998
3999     //---------------------------------------------------------------------------
4000     // GetRegNumByIdx: get ith register allocated to this struct argument.
4001     //
4002     // Arguments:
4003     //     idx   -   index of the register
4004     //
4005     // Return Value:
4006     //     Return regNumber of ith register of this register argument
4007     //
4008     regNumber GetRegNumByIdx(unsigned idx) const
4009     {
4010         assert(idx < 2);
4011
4012         if (idx == 0)
4013         {
4014             return gtRegNum;
4015         }
4016
4017         return gtOtherReg;
4018     }
4019
4020     //----------------------------------------------------------------------
4021     // GetRegSpillFlagByIdx: get spill flag associated with the register
4022     // specified by its index.
4023     //
4024     // Arguments:
4025     //    idx  -  Position or index of the register
4026     //
4027     // Return Value:
4028     //    Returns GTF_* flags associated with the register. Only GTF_SPILL and GTF_SPILLED are considered.
4029     //
4030     unsigned GetRegSpillFlagByIdx(unsigned idx) const
4031     {
4032         assert(idx < MAX_REG_ARG);
4033
4034         unsigned bits = gtSpillFlags >> (idx * 2); // It doesn't matter that we possibly leave other high bits here.
4035         unsigned spillFlags = 0;
4036         if (bits & PACKED_GTF_SPILL)
4037         {
4038             spillFlags |= GTF_SPILL;
4039         }
4040         if (bits & PACKED_GTF_SPILLED)
4041         {
4042             spillFlags |= GTF_SPILLED;
4043         }
4044
4045         return spillFlags;
4046     }
4047
4048     //----------------------------------------------------------------------
4049     // SetRegSpillFlagByIdx: set spill flags for the register
4050     // specified by its index.
4051     //
4052     // Arguments:
4053     //    flags  -  GTF_* flags. Only GTF_SPILL and GTF_SPILLED are allowed.
4054     //    idx    -  Position or index of the register
4055     //
4056     // Return Value:
4057     //    None
4058     //
4059     void SetRegSpillFlagByIdx(unsigned flags, unsigned idx)
4060     {
4061         assert(idx < MAX_REG_ARG);
4062
4063         unsigned bits = 0;
4064         if (flags & GTF_SPILL)
4065         {
4066             bits |= PACKED_GTF_SPILL;
4067         }
4068         if (flags & GTF_SPILLED)
4069         {
4070             bits |= PACKED_GTF_SPILLED;
4071         }
4072
4073         const unsigned char packedFlags = PACKED_GTF_SPILL | PACKED_GTF_SPILLED;
4074
4075         // Clear anything that was already there by masking out the bits before 'or'ing in what we want there.
4076         gtSpillFlags = (unsigned char)((gtSpillFlags & ~(packedFlags << (idx * 2))) | (bits << (idx * 2)));
4077     }
4078
4079     //--------------------------------------------------------------------------
4080     // GetRegType:  Get var_type of the register specified by index.
4081     //
4082     // Arguments:
4083     //    index - Index of the register.
4084     //            First register will have an index 0 and so on.
4085     //
4086     // Return Value:
4087     //    var_type of the register specified by its index.
4088
4089     var_types GetRegType(unsigned index)
4090     {
4091         assert(index < 2);
4092         // The type of register is usually the same as GenTree type
4093         // since most of time GenTreeMultiRegOp uses only a single reg (when gtOtherReg is REG_NA).
4094         // The special case is when we have TYP_LONG here, which was `TYP_DOUBLE` originally
4095         // (copied to int regs for argument push on armel). Then we need to separate them into int for each index.
4096         var_types result = TypeGet();
4097         if (result == TYP_LONG)
4098         {
4099             assert(gtOtherReg != REG_NA);
4100             result = TYP_INT;
4101         }
4102         return result;
4103     }
4104
4105     //-------------------------------------------------------------------
4106     // clearOtherRegFlags: clear GTF_* flags associated with gtOtherRegs
4107     //
4108     // Arguments:
4109     //     None
4110     //
4111     // Return Value:
4112     //     None
4113     //
4114     void ClearOtherRegFlags()
4115     {
4116         gtSpillFlags = 0;
4117     }
4118
4119 #if DEBUGGABLE_GENTREE
4120     GenTreeMultiRegOp() : GenTreeOp()
4121     {
4122     }
4123 #endif
4124 };
4125 #endif
4126
4127 struct GenTreeFptrVal : public GenTree
4128 {
4129     CORINFO_METHOD_HANDLE gtFptrMethod;
4130
4131 #ifdef FEATURE_READYTORUN_COMPILER
4132     CORINFO_CONST_LOOKUP gtEntryPoint;
4133 #endif
4134
4135     GenTreeFptrVal(var_types type, CORINFO_METHOD_HANDLE meth) : GenTree(GT_FTN_ADDR, type), gtFptrMethod(meth)
4136     {
4137     }
4138 #if DEBUGGABLE_GENTREE
4139     GenTreeFptrVal() : GenTree()
4140     {
4141     }
4142 #endif
4143 };
4144
4145 /* gtQmark */
4146 struct GenTreeQmark : public GenTreeOp
4147 {
4148 #ifdef LEGACY_BACKEND
4149     // Livesets on entry to then and else subtrees
4150     VARSET_TP gtThenLiveSet;
4151     VARSET_TP gtElseLiveSet;
4152 #endif
4153
4154     // The "Compiler*" argument is not a DEBUGARG here because we use it to keep track of the set of
4155     // (possible) QMark nodes.
4156     GenTreeQmark(var_types type, GenTree* cond, GenTree* colonOp, class Compiler* comp);
4157
4158 #if DEBUGGABLE_GENTREE
4159     GenTreeQmark() : GenTreeOp(GT_QMARK, TYP_INT, nullptr, nullptr)
4160     {
4161     }
4162 #endif
4163 };
4164
4165 /* gtIntrinsic   -- intrinsic   (possibly-binary op [NULL op2 is allowed] with an additional field) */
4166
4167 struct GenTreeIntrinsic : public GenTreeOp
4168 {
4169     CorInfoIntrinsics     gtIntrinsicId;
4170     CORINFO_METHOD_HANDLE gtMethodHandle; // Method handle of the method which is treated as an intrinsic.
4171
4172 #ifdef FEATURE_READYTORUN_COMPILER
4173     // Call target lookup info for method call from a Ready To Run module
4174     CORINFO_CONST_LOOKUP gtEntryPoint;
4175 #endif
4176
4177     GenTreeIntrinsic(var_types type, GenTree* op1, CorInfoIntrinsics intrinsicId, CORINFO_METHOD_HANDLE methodHandle)
4178         : GenTreeOp(GT_INTRINSIC, type, op1, nullptr), gtIntrinsicId(intrinsicId), gtMethodHandle(methodHandle)
4179     {
4180     }
4181
4182     GenTreeIntrinsic(
4183         var_types type, GenTree* op1, GenTree* op2, CorInfoIntrinsics intrinsicId, CORINFO_METHOD_HANDLE methodHandle)
4184         : GenTreeOp(GT_INTRINSIC, type, op1, op2), gtIntrinsicId(intrinsicId), gtMethodHandle(methodHandle)
4185     {
4186     }
4187
4188 #if DEBUGGABLE_GENTREE
4189     GenTreeIntrinsic() : GenTreeOp()
4190     {
4191     }
4192 #endif
4193 };
4194
4195 struct GenTreeJitIntrinsic : public GenTreeOp
4196 {
4197     var_types gtSIMDBaseType; // SIMD vector base type
4198     unsigned  gtSIMDSize;     // SIMD vector size in bytes, use 0 for scalar intrinsics
4199
4200     GenTreeJitIntrinsic(genTreeOps oper, var_types type, GenTree* op1, GenTree* op2, var_types baseType, unsigned size)
4201         : GenTreeOp(oper, type, op1, op2), gtSIMDBaseType(baseType), gtSIMDSize(size)
4202     {
4203     }
4204
4205     bool isSIMD() const
4206     {
4207         return gtSIMDSize != 0;
4208     }
4209
4210 #if DEBUGGABLE_GENTREE
4211     GenTreeJitIntrinsic() : GenTreeOp()
4212     {
4213     }
4214 #endif
4215 };
4216
4217 #ifdef FEATURE_SIMD
4218
4219 /* gtSIMD   -- SIMD intrinsic   (possibly-binary op [NULL op2 is allowed] with additional fields) */
4220 struct GenTreeSIMD : public GenTreeJitIntrinsic
4221 {
4222     SIMDIntrinsicID gtSIMDIntrinsicID; // operation Id
4223
4224     GenTreeSIMD(var_types type, GenTree* op1, SIMDIntrinsicID simdIntrinsicID, var_types baseType, unsigned size)
4225         : GenTreeJitIntrinsic(GT_SIMD, type, op1, nullptr, baseType, size), gtSIMDIntrinsicID(simdIntrinsicID)
4226     {
4227     }
4228
4229     GenTreeSIMD(
4230         var_types type, GenTree* op1, GenTree* op2, SIMDIntrinsicID simdIntrinsicID, var_types baseType, unsigned size)
4231         : GenTreeJitIntrinsic(GT_SIMD, type, op1, op2, baseType, size), gtSIMDIntrinsicID(simdIntrinsicID)
4232     {
4233     }
4234
4235 #if DEBUGGABLE_GENTREE
4236     GenTreeSIMD() : GenTreeJitIntrinsic()
4237     {
4238     }
4239 #endif
4240 };
4241 #endif // FEATURE_SIMD
4242
4243 #ifdef FEATURE_HW_INTRINSICS
4244 struct GenTreeHWIntrinsic : public GenTreeJitIntrinsic
4245 {
4246     NamedIntrinsic gtHWIntrinsicId;
4247
4248     GenTreeHWIntrinsic(var_types type, NamedIntrinsic hwIntrinsicID, var_types baseType, unsigned size)
4249         : GenTreeJitIntrinsic(GT_HWIntrinsic, type, nullptr, nullptr, baseType, size), gtHWIntrinsicId(hwIntrinsicID)
4250     {
4251     }
4252
4253     GenTreeHWIntrinsic(var_types type, GenTree* op1, NamedIntrinsic hwIntrinsicID, var_types baseType, unsigned size)
4254         : GenTreeJitIntrinsic(GT_HWIntrinsic, type, op1, nullptr, baseType, size), gtHWIntrinsicId(hwIntrinsicID)
4255     {
4256     }
4257
4258     GenTreeHWIntrinsic(
4259         var_types type, GenTree* op1, GenTree* op2, NamedIntrinsic hwIntrinsicID, var_types baseType, unsigned size)
4260         : GenTreeJitIntrinsic(GT_HWIntrinsic, type, op1, op2, baseType, size), gtHWIntrinsicId(hwIntrinsicID)
4261     {
4262     }
4263
4264     // Note that HW Instrinsic instructions are a sub class of GenTreeOp which only supports two operands
4265     // However there are HW Instrinsic instructions that have 3 or even 4 operands and this is
4266     // supported using a single op1 and using an ArgList for it:  gtNewArgList(op1, op2, op3)
4267
4268     bool OperIsMemoryLoad();        // Returns true for the HW Instrinsic instructions that have MemoryLoad semantics,
4269                                     // false otherwise
4270     bool OperIsMemoryStore();       // Returns true for the HW Instrinsic instructions that have MemoryStore semantics,
4271                                     // false otherwise
4272     bool OperIsMemoryLoadOrStore(); // Returns true for the HW Instrinsic instructions that have MemoryLoad or
4273                                     // MemoryStore semantics, false otherwise
4274
4275 #if DEBUGGABLE_GENTREE
4276     GenTreeHWIntrinsic() : GenTreeJitIntrinsic()
4277     {
4278     }
4279 #endif
4280 };
4281
4282 inline bool GenTree::OperIsSimdHWIntrinsic() const
4283 {
4284     if (gtOper == GT_HWIntrinsic)
4285     {
4286         return this->AsHWIntrinsic()->isSIMD();
4287     }
4288     return false;
4289 }
4290 #endif // FEATURE_HW_INTRINSICS
4291
4292 /* gtIndex -- array access */
4293
4294 struct GenTreeIndex : public GenTreeOp
4295 {
4296     GenTree*& Arr()
4297     {
4298         return gtOp1;
4299     }
4300     GenTree*& Index()
4301     {
4302         return gtOp2;
4303     }
4304
4305     unsigned             gtIndElemSize;     // size of elements in the array
4306     CORINFO_CLASS_HANDLE gtStructElemClass; // If the element type is a struct, this is the struct type.
4307
4308     GenTreeIndex(var_types type, GenTree* arr, GenTree* ind, unsigned indElemSize)
4309         : GenTreeOp(GT_INDEX, type, arr, ind)
4310         , gtIndElemSize(indElemSize)
4311         , gtStructElemClass(nullptr) // We always initialize this after construction.
4312     {
4313 #ifdef DEBUG
4314         if (JitConfig.JitSkipArrayBoundCheck() == 1)
4315         {
4316             // Skip bounds check
4317         }
4318         else
4319 #endif
4320         {
4321             // Do bounds check
4322             gtFlags |= GTF_INX_RNGCHK;
4323         }
4324
4325         if (type == TYP_REF)
4326         {
4327             gtFlags |= GTF_INX_REFARR_LAYOUT;
4328         }
4329
4330         gtFlags |= GTF_EXCEPT | GTF_GLOB_REF;
4331     }
4332 #if DEBUGGABLE_GENTREE
4333     GenTreeIndex() : GenTreeOp()
4334     {
4335     }
4336 #endif
4337 };
4338
4339 // gtIndexAddr: given an array object and an index, checks that the index is within the bounds of the array if
4340 //              necessary and produces the address of the value at that index of the array.
4341 struct GenTreeIndexAddr : public GenTreeOp
4342 {
4343     GenTree*& Arr()
4344     {
4345         return gtOp1;
4346     }
4347     GenTree*& Index()
4348     {
4349         return gtOp2;
4350     }
4351
4352     CORINFO_CLASS_HANDLE gtStructElemClass; // If the element type is a struct, this is the struct type.
4353
4354     GenTree* gtIndRngFailBB; // Label to jump to for array-index-out-of-range
4355     unsigned gtStkDepth;     // Stack depth at which the jump occurs (required for fgSetRngChkTarget)
4356
4357     var_types gtElemType;   // The element type of the array.
4358     unsigned  gtElemSize;   // size of elements in the array
4359     unsigned  gtLenOffset;  // The offset from the array's base address to its length.
4360     unsigned  gtElemOffset; // The offset from the array's base address to its first element.
4361
4362     GenTreeIndexAddr(GenTree*             arr,
4363                      GenTree*             ind,
4364                      var_types            elemType,
4365                      CORINFO_CLASS_HANDLE structElemClass,
4366                      unsigned             elemSize,
4367                      unsigned             lenOffset,
4368                      unsigned             elemOffset)
4369         : GenTreeOp(GT_INDEX_ADDR, TYP_BYREF, arr, ind)
4370         , gtStructElemClass(structElemClass)
4371         , gtIndRngFailBB(nullptr)
4372         , gtStkDepth(0)
4373         , gtElemType(elemType)
4374         , gtElemSize(elemSize)
4375         , gtLenOffset(lenOffset)
4376         , gtElemOffset(elemOffset)
4377     {
4378 #ifdef DEBUG
4379         if (JitConfig.JitSkipArrayBoundCheck() == 1)
4380         {
4381             // Skip bounds check
4382         }
4383         else
4384 #endif
4385         {
4386             // Do bounds check
4387             gtFlags |= GTF_INX_RNGCHK;
4388         }
4389
4390         // REVERSE_OPS is set because we must evaluate the index before the array address.
4391         gtFlags |= GTF_EXCEPT | GTF_GLOB_REF | GTF_REVERSE_OPS;
4392     }
4393
4394 #if DEBUGGABLE_GENTREE
4395     GenTreeIndexAddr() : GenTreeOp()
4396     {
4397     }
4398 #endif
4399 };
4400
4401 /* gtArrLen -- array length (GT_ARR_LENGTH)
4402    GT_ARR_LENGTH is used for "arr.length" */
4403
4404 struct GenTreeArrLen : public GenTreeUnOp
4405 {
4406     GenTree*& ArrRef()
4407     {
4408         return gtOp1;
4409     } // the array address node
4410 private:
4411     int gtArrLenOffset; // constant to add to "gtArrRef" to get the address of the array length.
4412
4413 public:
4414     inline int ArrLenOffset()
4415     {
4416         return gtArrLenOffset;
4417     }
4418
4419     GenTreeArrLen(var_types type, GenTree* arrRef, int lenOffset)
4420         : GenTreeUnOp(GT_ARR_LENGTH, type, arrRef), gtArrLenOffset(lenOffset)
4421     {
4422     }
4423
4424 #if DEBUGGABLE_GENTREE
4425     GenTreeArrLen() : GenTreeUnOp()
4426     {
4427     }
4428 #endif
4429 };
4430
4431 // This takes:
4432 // - a comparison value (generally an array length),
4433 // - an index value, and
4434 // - the label to jump to if the index is out of range.
4435 // - the "kind" of the throw block to branch to on failure
4436 // It generates no result.
4437
4438 struct GenTreeBoundsChk : public GenTree
4439 {
4440     GenTree* gtIndex;  // The index expression.
4441     GenTree* gtArrLen; // An expression for the length of the array being indexed.
4442
4443     GenTree*        gtIndRngFailBB; // Label to jump to for array-index-out-of-range
4444     SpecialCodeKind gtThrowKind;    // Kind of throw block to branch to on failure
4445
4446     /* Only out-of-ranges at same stack depth can jump to the same label (finding return address is easier)
4447        For delayed calling of fgSetRngChkTarget() so that the
4448        optimizer has a chance of eliminating some of the rng checks */
4449     unsigned gtStkDepth;
4450
4451     GenTreeBoundsChk(genTreeOps oper, var_types type, GenTree* index, GenTree* arrLen, SpecialCodeKind kind)
4452         : GenTree(oper, type)
4453         , gtIndex(index)
4454         , gtArrLen(arrLen)
4455         , gtIndRngFailBB(nullptr)
4456         , gtThrowKind(kind)
4457         , gtStkDepth(0)
4458     {
4459         // Effects flags propagate upwards.
4460         gtFlags |= (arrLen->gtFlags & GTF_ALL_EFFECT);
4461         gtFlags |= GTF_EXCEPT;
4462     }
4463 #if DEBUGGABLE_GENTREE
4464     GenTreeBoundsChk() : GenTree()
4465     {
4466     }
4467 #endif
4468
4469     // If the gtArrLen is really an array length, returns array reference, else "NULL".
4470     GenTree* GetArray()
4471     {
4472         if (gtArrLen->OperGet() == GT_ARR_LENGTH)
4473         {
4474             return gtArrLen->gtArrLen.ArrRef();
4475         }
4476         else
4477         {
4478             return nullptr;
4479         }
4480     }
4481 };
4482
4483 // gtArrElem -- general array element (GT_ARR_ELEM), for non "SZ_ARRAYS"
4484 //              -- multidimensional arrays, or 1-d arrays with non-zero lower bounds.
4485
4486 struct GenTreeArrElem : public GenTree
4487 {
4488     GenTree* gtArrObj;
4489
4490 #define GT_ARR_MAX_RANK 3
4491     GenTree*      gtArrInds[GT_ARR_MAX_RANK]; // Indices
4492     unsigned char gtArrRank;                  // Rank of the array
4493
4494     unsigned char gtArrElemSize; // !!! Caution, this is an "unsigned char", it is used only
4495                                  // on the optimization path of array intrisics.
4496                                  // It stores the size of array elements WHEN it can fit
4497                                  // into an "unsigned char".
4498                                  // This has caused VSW 571394.
4499     var_types gtArrElemType;     // The array element type
4500
4501     // Requires that "inds" is a pointer to an array of "rank" GenTreePtrs for the indices.
4502     GenTreeArrElem(
4503         var_types type, GenTree* arr, unsigned char rank, unsigned char elemSize, var_types elemType, GenTree** inds)
4504         : GenTree(GT_ARR_ELEM, type), gtArrObj(arr), gtArrRank(rank), gtArrElemSize(elemSize), gtArrElemType(elemType)
4505     {
4506         for (unsigned char i = 0; i < rank; i++)
4507         {
4508             gtArrInds[i] = inds[i];
4509         }
4510         gtFlags |= GTF_EXCEPT;
4511     }
4512 #if DEBUGGABLE_GENTREE
4513     GenTreeArrElem() : GenTree()
4514     {
4515     }
4516 #endif
4517 };
4518
4519 //--------------------------------------------
4520 //
4521 // GenTreeArrIndex (gtArrIndex): Expression to bounds-check the index for one dimension of a
4522 //    multi-dimensional or non-zero-based array., and compute the effective index
4523 //    (i.e. subtracting the lower bound).
4524 //
4525 // Notes:
4526 //    This node is similar in some ways to GenTreeBoundsChk, which ONLY performs the check.
4527 //    The reason that this node incorporates the check into the effective index computation is
4528 //    to avoid duplicating the codegen, as the effective index is required to compute the
4529 //    offset anyway.
4530 //    TODO-CQ: Enable optimization of the lower bound and length by replacing this:
4531 //                /--*  <arrObj>
4532 //                +--*  <index0>
4533 //             +--* ArrIndex[i, ]
4534 //    with something like:
4535 //                   /--*  <arrObj>
4536 //                /--*  ArrLowerBound[i, ]
4537 //                |  /--*  <arrObj>
4538 //                +--*  ArrLen[i, ]    (either generalize GT_ARR_LENGTH or add a new node)
4539 //                +--*  <index0>
4540 //             +--* ArrIndex[i, ]
4541 //    Which could, for example, be optimized to the following when known to be within bounds:
4542 //                /--*  TempForLowerBoundDim0
4543 //                +--*  <index0>
4544 //             +--* - (GT_SUB)
4545 //
4546 struct GenTreeArrIndex : public GenTreeOp
4547 {
4548     // The array object - may be any expression producing an Array reference, but is likely to be a lclVar.
4549     GenTree*& ArrObj()
4550     {
4551         return gtOp1;
4552     }
4553     // The index expression - may be any integral expression.
4554     GenTree*& IndexExpr()
4555     {
4556         return gtOp2;
4557     }
4558     unsigned char gtCurrDim;     // The current dimension
4559     unsigned char gtArrRank;     // Rank of the array
4560     var_types     gtArrElemType; // The array element type
4561
4562     GenTreeArrIndex(var_types     type,
4563                     GenTree*      arrObj,
4564                     GenTree*      indexExpr,
4565                     unsigned char currDim,
4566                     unsigned char arrRank,
4567                     var_types     elemType)
4568         : GenTreeOp(GT_ARR_INDEX, type, arrObj, indexExpr)
4569         , gtCurrDim(currDim)
4570         , gtArrRank(arrRank)
4571         , gtArrElemType(elemType)
4572     {
4573         gtFlags |= GTF_EXCEPT;
4574     }
4575 #if DEBUGGABLE_GENTREE
4576 protected:
4577     friend GenTree;
4578     // Used only for GenTree::GetVtableForOper()
4579     GenTreeArrIndex() : GenTreeOp()
4580     {
4581     }
4582 #endif
4583 };
4584
4585 //--------------------------------------------
4586 //
4587 // GenTreeArrOffset (gtArrOffset): Expression to compute the accumulated offset for the address
4588 //    of an element of a multi-dimensional or non-zero-based array.
4589 //
4590 // Notes:
4591 //    The result of this expression is (gtOffset * dimSize) + gtIndex
4592 //    where dimSize is the length/stride/size of the dimension, and is obtained from gtArrObj.
4593 //    This node is generated in conjunction with the GenTreeArrIndex node, which computes the
4594 //    effective index for a single dimension.  The sub-trees can be separately optimized, e.g.
4595 //    within a loop body where the expression for the 0th dimension may be invariant.
4596 //
4597 //    Here is an example of how the tree might look for a two-dimension array reference:
4598 //                /--*  const 0
4599 //                |  /--* <arrObj>
4600 //                |  +--* <index0>
4601 //                +--* ArrIndex[i, ]
4602 //                +--*  <arrObj>
4603 //             /--| arrOffs[i, ]
4604 //             |  +--*  <arrObj>
4605 //             |  +--*  <index1>
4606 //             +--* ArrIndex[*,j]
4607 //             +--*  <arrObj>
4608 //          /--| arrOffs[*,j]
4609 //    TODO-CQ: see comment on GenTreeArrIndex for how its representation may change.  When that
4610 //    is done, we will also want to replace the <arrObj> argument to arrOffs with the
4611 //    ArrLen as for GenTreeArrIndex.
4612 //
4613 struct GenTreeArrOffs : public GenTree
4614 {
4615     GenTree* gtOffset;           // The accumulated offset for lower dimensions - must be TYP_I_IMPL, and
4616                                  // will either be a CSE temp, the constant 0, or another GenTreeArrOffs node.
4617     GenTree* gtIndex;            // The effective index for the current dimension - must be non-negative
4618                                  // and can be any expression (though it is likely to be either a GenTreeArrIndex,
4619                                  // node, a lclVar, or a constant).
4620     GenTree* gtArrObj;           // The array object - may be any expression producing an Array reference,
4621                                  // but is likely to be a lclVar.
4622     unsigned char gtCurrDim;     // The current dimension
4623     unsigned char gtArrRank;     // Rank of the array
4624     var_types     gtArrElemType; // The array element type
4625
4626     GenTreeArrOffs(var_types     type,
4627                    GenTree*      offset,
4628                    GenTree*      index,
4629                    GenTree*      arrObj,
4630                    unsigned char currDim,
4631                    unsigned char rank,
4632                    var_types     elemType)
4633         : GenTree(GT_ARR_OFFSET, type)
4634         , gtOffset(offset)
4635         , gtIndex(index)
4636         , gtArrObj(arrObj)
4637         , gtCurrDim(currDim)
4638         , gtArrRank(rank)
4639         , gtArrElemType(elemType)
4640     {
4641         assert(index->gtFlags & GTF_EXCEPT);
4642         gtFlags |= GTF_EXCEPT;
4643     }
4644 #if DEBUGGABLE_GENTREE
4645     GenTreeArrOffs() : GenTree()
4646     {
4647     }
4648 #endif
4649 };
4650
4651 /* gtAddrMode -- Target-specific canonicalized addressing expression (GT_LEA) */
4652
4653 struct GenTreeAddrMode : public GenTreeOp
4654 {
4655     // Address is Base + Index*Scale + Offset.
4656     // These are the legal patterns:
4657     //
4658     //      Base                                // Base != nullptr && Index == nullptr && Scale == 0 && Offset == 0
4659     //      Base + Index*Scale                  // Base != nullptr && Index != nullptr && Scale != 0 && Offset == 0
4660     //      Base + Offset                       // Base != nullptr && Index == nullptr && Scale == 0 && Offset != 0
4661     //      Base + Index*Scale + Offset         // Base != nullptr && Index != nullptr && Scale != 0 && Offset != 0
4662     //             Index*Scale                  // Base == nullptr && Index != nullptr && Scale >  1 && Offset == 0
4663     //             Index*Scale + Offset         // Base == nullptr && Index != nullptr && Scale >  1 && Offset != 0
4664     //                           Offset         // Base == nullptr && Index == nullptr && Scale == 0 && Offset != 0
4665     //
4666     // So, for example:
4667     //      1. Base + Index is legal with Scale==1
4668     //      2. If Index is null, Scale should be zero (or unintialized / unused)
4669     //      3. If Scale==1, then we should have "Base" instead of "Index*Scale", and "Base + Offset" instead of
4670     //         "Index*Scale + Offset".
4671
4672     // First operand is base address/pointer
4673     bool HasBase() const
4674     {
4675         return gtOp1 != nullptr;
4676     }
4677     GenTree*& Base()
4678     {
4679         return gtOp1;
4680     }
4681
4682     // Second operand is scaled index value
4683     bool HasIndex() const
4684     {
4685         return gtOp2 != nullptr;
4686     }
4687     GenTree*& Index()
4688     {
4689         return gtOp2;
4690     }
4691
4692     int Offset()
4693     {
4694         return static_cast<int>(gtOffset);
4695     }
4696
4697     unsigned gtScale; // The scale factor
4698
4699 #ifndef LEGACY_BACKEND
4700 private:
4701 #endif
4702     // TODO-Cleanup: gtOffset should be changed to 'int' to match the getter function and avoid accidental
4703     // zero extension to 64 bit. However, this is used by legacy code and initialized, via the offset
4704     // parameter of the constructor, by Lowering::TryCreateAddrMode & CodeGenInterface::genCreateAddrMode.
4705     // The later computes the offset as 'ssize_t' but returns it as 'unsigned'. We should change
4706     // genCreateAddrMode to return 'int' or 'ssize_t' and then update this as well.
4707     unsigned gtOffset; // The offset to add
4708
4709 public:
4710     GenTreeAddrMode(var_types type, GenTree* base, GenTree* index, unsigned scale, unsigned offset)
4711         : GenTreeOp(GT_LEA, type, base, index)
4712     {
4713         assert(base != nullptr || index != nullptr);
4714         gtScale  = scale;
4715         gtOffset = offset;
4716     }
4717 #if DEBUGGABLE_GENTREE
4718 protected:
4719     friend GenTree;
4720     // Used only for GenTree::GetVtableForOper()
4721     GenTreeAddrMode() : GenTreeOp()
4722     {
4723     }
4724 #endif
4725 };
4726
4727 // Indir is just an op, no additional data, but some additional abstractions
4728 struct GenTreeIndir : public GenTreeOp
4729 {
4730     // The address for the indirection.
4731     // Since GenTreeDynBlk derives from this, but is an "EXOP" (i.e. it has extra fields),
4732     // we can't access Op1 and Op2 in the normal manner if we may have a DynBlk.
4733     GenTree*& Addr()
4734     {
4735         return gtOp1;
4736     }
4737
4738     // these methods provide an interface to the indirection node which
4739     bool     HasBase();
4740     bool     HasIndex();
4741     GenTree* Base();
4742     GenTree* Index();
4743     unsigned Scale();
4744     ssize_t  Offset();
4745
4746     GenTreeIndir(genTreeOps oper, var_types type, GenTree* addr, GenTree* data) : GenTreeOp(oper, type, addr, data)
4747     {
4748     }
4749
4750 #if DEBUGGABLE_GENTREE
4751 protected:
4752     friend GenTree;
4753     // Used only for GenTree::GetVtableForOper()
4754     GenTreeIndir() : GenTreeOp()
4755     {
4756     }
4757 #endif
4758 };
4759
4760 // gtBlk  -- 'block' (GT_BLK, GT_STORE_BLK).
4761 //
4762 // This is the base type for all of the nodes that represent block or struct
4763 // values.
4764 // Since it can be a store, it includes gtBlkOpKind to specify the type of
4765 // code generation that will be used for the block operation.
4766
4767 struct GenTreeBlk : public GenTreeIndir
4768 {
4769 public:
4770     // The data to be stored (null for GT_BLK)
4771     GenTree*& Data()
4772     {
4773         return gtOp2;
4774     }
4775     void SetData(GenTree* dataNode)
4776     {
4777         gtOp2 = dataNode;
4778     }
4779
4780     // The size of the buffer to be copied.
4781     unsigned Size() const
4782     {
4783         return gtBlkSize;
4784     }
4785
4786     unsigned gtBlkSize;
4787
4788     // Return true iff the object being copied contains one or more GC pointers.
4789     bool HasGCPtr();
4790
4791     // True if this BlkOpNode is a volatile memory operation.
4792     bool IsVolatile() const
4793     {
4794         return (gtFlags & GTF_BLK_VOLATILE) != 0;
4795     }
4796
4797     // True if this BlkOpNode is an unaligned memory operation.
4798     bool IsUnaligned() const
4799     {
4800         return (gtFlags & GTF_BLK_UNALIGNED) != 0;
4801     }
4802
4803     // Instruction selection: during codegen time, what code sequence we will be using
4804     // to encode this operation.
4805     enum
4806     {
4807         BlkOpKindInvalid,
4808         BlkOpKindHelper,
4809         BlkOpKindRepInstr,
4810         BlkOpKindUnroll,
4811     } gtBlkOpKind;
4812
4813     bool gtBlkOpGcUnsafe;
4814
4815     GenTreeBlk(genTreeOps oper, var_types type, GenTree* addr, unsigned size)
4816         : GenTreeIndir(oper, type, addr, nullptr)
4817         , gtBlkSize(size)
4818         , gtBlkOpKind(BlkOpKindInvalid)
4819         , gtBlkOpGcUnsafe(false)
4820     {
4821         assert(OperIsBlk(oper));
4822         gtFlags |= (addr->gtFlags & GTF_ALL_EFFECT);
4823     }
4824
4825     GenTreeBlk(genTreeOps oper, var_types type, GenTree* addr, GenTree* data, unsigned size)
4826         : GenTreeIndir(oper, type, addr, data), gtBlkSize(size), gtBlkOpKind(BlkOpKindInvalid), gtBlkOpGcUnsafe(false)
4827     {
4828         assert(OperIsBlk(oper));
4829         gtFlags |= (addr->gtFlags & GTF_ALL_EFFECT);
4830         gtFlags |= (data->gtFlags & GTF_ALL_EFFECT);
4831     }
4832
4833 #if DEBUGGABLE_GENTREE
4834 protected:
4835     friend GenTree;
4836     GenTreeBlk() : GenTreeIndir()
4837     {
4838     }
4839 #endif // DEBUGGABLE_GENTREE
4840 };
4841
4842 // gtObj  -- 'object' (GT_OBJ).
4843 //
4844 // This node is used for block values that may have GC pointers.
4845
4846 struct GenTreeObj : public GenTreeBlk
4847 {
4848     CORINFO_CLASS_HANDLE gtClass; // the class of the object
4849
4850     // If non-null, this array represents the gc-layout of the class.
4851     // This may be simply copied when cloning this node, because it is not changed once computed.
4852     BYTE* gtGcPtrs;
4853
4854     // If non-zero, this is the number of slots in the class layout that
4855     // contain gc-pointers.
4856     __declspec(property(get = GetGcPtrCount)) unsigned gtGcPtrCount;
4857     unsigned GetGcPtrCount() const
4858     {
4859         assert(_gtGcPtrCount != UINT32_MAX);
4860         return _gtGcPtrCount;
4861     }
4862     unsigned _gtGcPtrCount;
4863
4864     // If non-zero, the number of pointer-sized slots that constitutes the class token.
4865     unsigned gtSlots;
4866
4867     bool IsGCInfoInitialized()
4868     {
4869         return (_gtGcPtrCount != UINT32_MAX);
4870     }
4871
4872     void SetGCInfo(BYTE* gcPtrs, unsigned gcPtrCount, unsigned slots)
4873     {
4874         gtGcPtrs      = gcPtrs;
4875         _gtGcPtrCount = gcPtrCount;
4876         gtSlots       = slots;
4877         if (gtGcPtrCount != 0)
4878         {
4879             // We assume that we cannot have a struct with GC pointers that is not a multiple
4880             // of the register size.
4881             // The EE currently does not allow this, but it could change.
4882             // Let's assert it just to be safe.
4883             noway_assert(roundUp(gtBlkSize, REGSIZE_BYTES) == gtBlkSize);
4884         }
4885         else
4886         {
4887             genTreeOps newOper = GT_BLK;
4888             if (gtOper == GT_STORE_OBJ)
4889             {
4890                 newOper = GT_STORE_BLK;
4891             }
4892             else
4893             {
4894                 assert(gtOper == GT_OBJ);
4895             }
4896             SetOper(newOper);
4897         }
4898     }
4899
4900     void CopyGCInfo(GenTreeObj* srcObj)
4901     {
4902         if (srcObj->IsGCInfoInitialized())
4903         {
4904             gtGcPtrs      = srcObj->gtGcPtrs;
4905             _gtGcPtrCount = srcObj->gtGcPtrCount;
4906             gtSlots       = srcObj->gtSlots;
4907         }
4908     }
4909
4910     GenTreeObj(var_types type, GenTree* addr, CORINFO_CLASS_HANDLE cls, unsigned size)
4911         : GenTreeBlk(GT_OBJ, type, addr, size), gtClass(cls)
4912     {
4913         // By default, an OBJ is assumed to be a global reference.
4914         gtFlags |= GTF_GLOB_REF;
4915         noway_assert(cls != NO_CLASS_HANDLE);
4916         _gtGcPtrCount = UINT32_MAX;
4917     }
4918
4919     GenTreeObj(var_types type, GenTree* addr, GenTree* data, CORINFO_CLASS_HANDLE cls, unsigned size)
4920         : GenTreeBlk(GT_STORE_OBJ, type, addr, data, size), gtClass(cls)
4921     {
4922         // By default, an OBJ is assumed to be a global reference.
4923         gtFlags |= GTF_GLOB_REF;
4924         noway_assert(cls != NO_CLASS_HANDLE);
4925         _gtGcPtrCount = UINT32_MAX;
4926     }
4927
4928 #if DEBUGGABLE_GENTREE
4929     GenTreeObj() : GenTreeBlk()
4930     {
4931     }
4932 #endif
4933 };
4934
4935 // gtDynBlk  -- 'dynamic block' (GT_DYN_BLK).
4936 //
4937 // This node is used for block values that have a dynamic size.
4938 // Note that such a value can never have GC pointers.
4939
4940 struct GenTreeDynBlk : public GenTreeBlk
4941 {
4942 public:
4943     GenTree* gtDynamicSize;
4944     bool     gtEvalSizeFirst;
4945
4946     GenTreeDynBlk(GenTree* addr, GenTree* dynamicSize)
4947         : GenTreeBlk(GT_DYN_BLK, TYP_STRUCT, addr, 0), gtDynamicSize(dynamicSize), gtEvalSizeFirst(false)
4948     {
4949         // Conservatively the 'addr' could be null or point into the global heap.
4950         gtFlags |= GTF_EXCEPT | GTF_GLOB_REF;
4951         gtFlags |= (dynamicSize->gtFlags & GTF_ALL_EFFECT);
4952     }
4953
4954 #if DEBUGGABLE_GENTREE
4955 protected:
4956     friend GenTree;
4957     GenTreeDynBlk() : GenTreeBlk()
4958     {
4959     }
4960 #endif // DEBUGGABLE_GENTREE
4961 };
4962
4963 // Read-modify-write status of a RMW memory op rooted at a storeInd
4964 enum RMWStatus
4965 {
4966     STOREIND_RMW_STATUS_UNKNOWN, // RMW status of storeInd unknown
4967                                  // Default status unless modified by IsRMWMemOpRootedAtStoreInd()
4968
4969     // One of these denote storeind is a RMW memory operation.
4970     STOREIND_RMW_DST_IS_OP1, // StoreInd is known to be a RMW memory op and dst candidate is op1
4971     STOREIND_RMW_DST_IS_OP2, // StoreInd is known to be a RMW memory op and dst candidate is op2
4972
4973     // One of these denote the reason for storeind is marked as non-RMW operation
4974     STOREIND_RMW_UNSUPPORTED_ADDR, // Addr mode is not yet supported for RMW memory
4975     STOREIND_RMW_UNSUPPORTED_OPER, // Operation is not supported for RMW memory
4976     STOREIND_RMW_UNSUPPORTED_TYPE, // Type is not supported for RMW memory
4977     STOREIND_RMW_INDIR_UNEQUAL     // Indir to read value is not equivalent to indir that writes the value
4978 };
4979
4980 // StoreInd is just a BinOp, with additional RMW status
4981 struct GenTreeStoreInd : public GenTreeIndir
4982 {
4983 #if !CPU_LOAD_STORE_ARCH
4984     // The below flag is set and used during lowering
4985     RMWStatus gtRMWStatus;
4986
4987     bool IsRMWStatusUnknown()
4988     {
4989         return gtRMWStatus == STOREIND_RMW_STATUS_UNKNOWN;
4990     }
4991     bool IsNonRMWMemoryOp()
4992     {
4993         return gtRMWStatus == STOREIND_RMW_UNSUPPORTED_ADDR || gtRMWStatus == STOREIND_RMW_UNSUPPORTED_OPER ||
4994                gtRMWStatus == STOREIND_RMW_UNSUPPORTED_TYPE || gtRMWStatus == STOREIND_RMW_INDIR_UNEQUAL;
4995     }
4996     bool IsRMWMemoryOp()
4997     {
4998         return gtRMWStatus == STOREIND_RMW_DST_IS_OP1 || gtRMWStatus == STOREIND_RMW_DST_IS_OP2;
4999     }
5000     bool IsRMWDstOp1()
5001     {
5002         return gtRMWStatus == STOREIND_RMW_DST_IS_OP1;
5003     }
5004     bool IsRMWDstOp2()
5005     {
5006         return gtRMWStatus == STOREIND_RMW_DST_IS_OP2;
5007     }
5008 #endif //! CPU_LOAD_STORE_ARCH
5009
5010     RMWStatus GetRMWStatus()
5011     {
5012 #if !CPU_LOAD_STORE_ARCH
5013         return gtRMWStatus;
5014 #else
5015         return STOREIND_RMW_STATUS_UNKNOWN;
5016 #endif
5017     }
5018
5019     void SetRMWStatusDefault()
5020     {
5021 #if !CPU_LOAD_STORE_ARCH
5022         gtRMWStatus = STOREIND_RMW_STATUS_UNKNOWN;
5023 #endif
5024     }
5025
5026     void SetRMWStatus(RMWStatus status)
5027     {
5028 #if !CPU_LOAD_STORE_ARCH
5029         gtRMWStatus = status;
5030 #endif
5031     }
5032
5033     GenTree*& Data()
5034     {
5035         return gtOp2;
5036     }
5037
5038     GenTreeStoreInd(var_types type, GenTree* destPtr, GenTree* data) : GenTreeIndir(GT_STOREIND, type, destPtr, data)
5039     {
5040         SetRMWStatusDefault();
5041     }
5042
5043 #if DEBUGGABLE_GENTREE
5044 protected:
5045     friend GenTree;
5046     // Used only for GenTree::GetVtableForOper()
5047     GenTreeStoreInd() : GenTreeIndir()
5048     {
5049         SetRMWStatusDefault();
5050     }
5051 #endif
5052 };
5053
5054 /* gtRetExp -- Place holder for the return expression from an inline candidate (GT_RET_EXPR) */
5055
5056 struct GenTreeRetExpr : public GenTree
5057 {
5058     GenTree* gtInlineCandidate;
5059
5060     CORINFO_CLASS_HANDLE gtRetClsHnd;
5061
5062     GenTreeRetExpr(var_types type) : GenTree(GT_RET_EXPR, type)
5063     {
5064     }
5065 #if DEBUGGABLE_GENTREE
5066     GenTreeRetExpr() : GenTree()
5067     {
5068     }
5069 #endif
5070 };
5071
5072 /* gtStmt   -- 'statement expr' (GT_STMT) */
5073
5074 class InlineContext;
5075
5076 struct GenTreeStmt : public GenTree
5077 {
5078     GenTree*       gtStmtExpr;      // root of the expression tree
5079     GenTree*       gtStmtList;      // first node (for forward walks)
5080     InlineContext* gtInlineContext; // The inline context for this statement.
5081     IL_OFFSETX     gtStmtILoffsx;   // instr offset (if available)
5082
5083 #ifdef DEBUG
5084     IL_OFFSET gtStmtLastILoffs; // instr offset at end of stmt
5085 #endif
5086
5087     __declspec(property(get = getNextStmt)) GenTreeStmt* gtNextStmt;
5088
5089     __declspec(property(get = getPrevStmt)) GenTreeStmt* gtPrevStmt;
5090
5091     GenTreeStmt* getNextStmt()
5092     {
5093         if (gtNext == nullptr)
5094         {
5095             return nullptr;
5096         }
5097         else
5098         {
5099             return gtNext->AsStmt();
5100         }
5101     }
5102
5103     GenTreeStmt* getPrevStmt()
5104     {
5105         if (gtPrev == nullptr)
5106         {
5107             return nullptr;
5108         }
5109         else
5110         {
5111             return gtPrev->AsStmt();
5112         }
5113     }
5114
5115     GenTreeStmt(GenTree* expr, IL_OFFSETX offset)
5116         : GenTree(GT_STMT, TYP_VOID)
5117         , gtStmtExpr(expr)
5118         , gtStmtList(nullptr)
5119         , gtInlineContext(nullptr)
5120         , gtStmtILoffsx(offset)
5121 #ifdef DEBUG
5122         , gtStmtLastILoffs(BAD_IL_OFFSET)
5123 #endif
5124     {
5125         // Statements can't have statements as part of their expression tree.
5126         assert(expr->gtOper != GT_STMT);
5127
5128         // Set the statement to have the same costs as the top node of the tree.
5129         // This is used long before costs have been assigned, so we need to copy
5130         // the raw costs.
5131         CopyRawCosts(expr);
5132     }
5133
5134 #if DEBUGGABLE_GENTREE
5135     GenTreeStmt() : GenTree(GT_STMT, TYP_VOID)
5136     {
5137     }
5138 #endif
5139 };
5140
5141 /*  NOTE: Any tree nodes that are larger than 8 bytes (two ints or
5142     pointers) must be flagged as 'large' in GenTree::InitNodeSize().
5143  */
5144
5145 /* gtClsVar -- 'static data member' (GT_CLS_VAR) */
5146
5147 struct GenTreeClsVar : public GenTree
5148 {
5149     CORINFO_FIELD_HANDLE gtClsVarHnd;
5150     FieldSeqNode*        gtFieldSeq;
5151
5152     GenTreeClsVar(var_types type, CORINFO_FIELD_HANDLE clsVarHnd, FieldSeqNode* fldSeq)
5153         : GenTree(GT_CLS_VAR, type), gtClsVarHnd(clsVarHnd), gtFieldSeq(fldSeq)
5154     {
5155         gtFlags |= GTF_GLOB_REF;
5156     }
5157 #if DEBUGGABLE_GENTREE
5158     GenTreeClsVar() : GenTree()
5159     {
5160     }
5161 #endif
5162 };
5163
5164 /* gtArgPlace -- 'register argument placeholder' (GT_ARGPLACE) */
5165
5166 struct GenTreeArgPlace : public GenTree
5167 {
5168     CORINFO_CLASS_HANDLE gtArgPlaceClsHnd; // Needed when we have a TYP_STRUCT argument
5169
5170     GenTreeArgPlace(var_types type, CORINFO_CLASS_HANDLE clsHnd) : GenTree(GT_ARGPLACE, type), gtArgPlaceClsHnd(clsHnd)
5171     {
5172     }
5173 #if DEBUGGABLE_GENTREE
5174     GenTreeArgPlace() : GenTree()
5175     {
5176     }
5177 #endif
5178 };
5179
5180 /* gtLabel  -- code label target    (GT_LABEL) */
5181
5182 struct GenTreeLabel : public GenTree
5183 {
5184     BasicBlock* gtLabBB;
5185
5186     GenTreeLabel(BasicBlock* bb) : GenTree(GT_LABEL, TYP_VOID), gtLabBB(bb)
5187     {
5188     }
5189 #if DEBUGGABLE_GENTREE
5190     GenTreeLabel() : GenTree()
5191     {
5192     }
5193 #endif
5194 };
5195
5196 /* gtPhiArg -- phi node rhs argument, var = phi(phiarg, phiarg, phiarg...); GT_PHI_ARG */
5197 struct GenTreePhiArg : public GenTreeLclVarCommon
5198 {
5199     BasicBlock* gtPredBB;
5200
5201     GenTreePhiArg(var_types type, unsigned lclNum, unsigned snum, BasicBlock* block)
5202         : GenTreeLclVarCommon(GT_PHI_ARG, type, lclNum), gtPredBB(block)
5203     {
5204         SetSsaNum(snum);
5205     }
5206
5207 #if DEBUGGABLE_GENTREE
5208     GenTreePhiArg() : GenTreeLclVarCommon()
5209     {
5210     }
5211 #endif
5212 };
5213
5214 /* gtPutArgStk -- Argument passed on stack (GT_PUTARG_STK) */
5215
5216 struct GenTreePutArgStk : public GenTreeUnOp
5217 {
5218     unsigned gtSlotNum; // Slot number of the argument to be passed on stack
5219 #if defined(UNIX_X86_ABI)
5220     unsigned gtPadAlign; // Number of padding slots for stack alignment
5221 #endif
5222
5223     // Don't let clang-format mess with the GenTreePutArgStk constructor.
5224     // clang-format off
5225
5226     GenTreePutArgStk(genTreeOps   oper,
5227                      var_types    type,
5228                      GenTree*   op1,
5229                      unsigned     slotNum
5230                      PUT_STRUCT_ARG_STK_ONLY_ARG(unsigned numSlots),
5231                      bool         putInIncomingArgArea = false,
5232                      GenTreeCall* callNode = nullptr)
5233         : GenTreeUnOp(oper, type, op1 DEBUGARG(/*largeNode*/ false))
5234         , gtSlotNum(slotNum)
5235 #if defined(UNIX_X86_ABI)
5236         , gtPadAlign(0)
5237 #endif
5238 #if FEATURE_FASTTAILCALL
5239         , gtPutInIncomingArgArea(putInIncomingArgArea)
5240 #endif // FEATURE_FASTTAILCALL
5241 #ifdef FEATURE_PUT_STRUCT_ARG_STK
5242         , gtPutArgStkKind(Kind::Invalid)
5243         , gtNumSlots(numSlots)
5244         , gtNumberReferenceSlots(0)
5245         , gtGcPtrs(nullptr)
5246 #endif // FEATURE_PUT_STRUCT_ARG_STK
5247 #if defined(DEBUG) || defined(UNIX_X86_ABI)
5248         , gtCall(callNode)
5249 #endif
5250     {
5251     }
5252
5253 // clang-format on
5254
5255 #if FEATURE_FASTTAILCALL
5256
5257     bool gtPutInIncomingArgArea; // Whether this arg needs to be placed in incoming arg area.
5258                                  // By default this is false and will be placed in out-going arg area.
5259                                  // Fast tail calls set this to true.
5260                                  // In future if we need to add more such bool fields consider bit fields.
5261
5262     bool putInIncomingArgArea() const
5263     {
5264         return gtPutInIncomingArgArea;
5265     }
5266
5267 #else // !FEATURE_FASTTAILCALL
5268
5269     bool putInIncomingArgArea() const
5270     {
5271         return false;
5272     }
5273
5274 #endif // !FEATURE_FASTTAILCALL
5275
5276     unsigned getArgOffset()
5277     {
5278         return gtSlotNum * TARGET_POINTER_SIZE;
5279     }
5280
5281 #if defined(UNIX_X86_ABI)
5282     unsigned getArgPadding()
5283     {
5284         return gtPadAlign;
5285     }
5286
5287     void setArgPadding(unsigned padAlign)
5288     {
5289         gtPadAlign = padAlign;
5290     }
5291 #endif
5292
5293 #ifdef FEATURE_PUT_STRUCT_ARG_STK
5294
5295     unsigned getArgSize()
5296     {
5297         return gtNumSlots * TARGET_POINTER_SIZE;
5298     }
5299
5300     // Return true if this is a PutArgStk of a SIMD12 struct.
5301     // This is needed because such values are re-typed to SIMD16, and the type of PutArgStk is VOID.
5302     unsigned isSIMD12()
5303     {
5304         return (varTypeIsSIMD(gtOp1) && (gtNumSlots == 3));
5305     }
5306
5307     //------------------------------------------------------------------------
5308     // setGcPointers: Sets the number of references and the layout of the struct object returned by the VM.
5309     //
5310     // Arguments:
5311     //    numPointers - Number of pointer references.
5312     //    pointers    - layout of the struct (with pointers marked.)
5313     //
5314     // Return Value:
5315     //    None
5316     //
5317     // Notes:
5318     //    This data is used in the codegen for GT_PUTARG_STK to decide how to copy the struct to the stack by value.
5319     //    If no pointer references are used, block copying instructions are used.
5320     //    Otherwise the pointer reference slots are copied atomically in a way that gcinfo is emitted.
5321     //    Any non pointer references between the pointer reference slots are copied in block fashion.
5322     //
5323     void setGcPointers(unsigned numPointers, BYTE* pointers)
5324     {
5325         gtNumberReferenceSlots = numPointers;
5326         gtGcPtrs               = pointers;
5327     }
5328
5329     // Instruction selection: during codegen time, what code sequence we will be using
5330     // to encode this operation.
5331     // TODO-Throughput: The following information should be obtained from the child
5332     // block node.
5333
5334     enum class Kind : __int8{
5335         Invalid, RepInstr, Unroll, Push, PushAllSlots,
5336     };
5337
5338     Kind gtPutArgStkKind;
5339     bool isPushKind()
5340     {
5341         return (gtPutArgStkKind == Kind::Push) || (gtPutArgStkKind == Kind::PushAllSlots);
5342     }
5343
5344     unsigned gtNumSlots;             // Number of slots for the argument to be passed on stack
5345     unsigned gtNumberReferenceSlots; // Number of reference slots.
5346     BYTE*    gtGcPtrs;               // gcPointers
5347
5348 #elif !defined(LEGACY_BACKEND)
5349     unsigned getArgSize();
5350 #endif // !LEGACY_BACKEND
5351
5352 #if defined(DEBUG) || defined(UNIX_X86_ABI)
5353     GenTreeCall* gtCall; // the call node to which this argument belongs
5354 #endif
5355
5356 #if DEBUGGABLE_GENTREE
5357     GenTreePutArgStk() : GenTreeUnOp()
5358     {
5359     }
5360 #endif
5361 };
5362
5363 #if !defined(LEGACY_BACKEND) && defined(_TARGET_ARM_)
5364 // Represent the struct argument: split value in register(s) and stack
5365 struct GenTreePutArgSplit : public GenTreePutArgStk
5366 {
5367     unsigned gtNumRegs;
5368
5369     GenTreePutArgSplit(GenTree* op1,
5370                        unsigned slotNum PUT_STRUCT_ARG_STK_ONLY_ARG(unsigned numSlots),
5371                        unsigned     numRegs,
5372                        bool         putIncomingArgArea = false,
5373                        GenTreeCall* callNode           = nullptr)
5374         : GenTreePutArgStk(GT_PUTARG_SPLIT,
5375                            TYP_STRUCT,
5376                            op1,
5377                            slotNum PUT_STRUCT_ARG_STK_ONLY_ARG(numSlots),
5378                            putIncomingArgArea,
5379                            callNode)
5380         , gtNumRegs(numRegs)
5381     {
5382         ClearOtherRegs();
5383         ClearOtherRegFlags();
5384     }
5385
5386     // Type required to support multi-reg struct arg.
5387     var_types m_regType[MAX_REG_ARG];
5388
5389     // First reg of struct is always given by gtRegNum.
5390     // gtOtherRegs holds the other reg numbers of struct.
5391     regNumberSmall gtOtherRegs[MAX_REG_ARG - 1];
5392
5393     // GTF_SPILL or GTF_SPILLED flag on a multi-reg struct node indicates that one or
5394     // more of its result regs are in that state.  The spill flag of each of the
5395     // return register is stored here. We only need 2 bits per register,
5396     // so this is treated as a 2-bit array.
5397     static const unsigned PACKED_GTF_SPILL   = 1;
5398     static const unsigned PACKED_GTF_SPILLED = 2;
5399     unsigned char         gtSpillFlags;
5400
5401     //---------------------------------------------------------------------------
5402     // GetRegNumByIdx: get ith register allocated to this struct argument.
5403     //
5404     // Arguments:
5405     //     idx   -   index of the struct
5406     //
5407     // Return Value:
5408     //     Return regNumber of ith register of this struct argument
5409     //
5410     regNumber GetRegNumByIdx(unsigned idx) const
5411     {
5412         assert(idx < MAX_REG_ARG);
5413
5414         if (idx == 0)
5415         {
5416             return gtRegNum;
5417         }
5418
5419         return (regNumber)gtOtherRegs[idx - 1];
5420     }
5421
5422     //----------------------------------------------------------------------
5423     // SetRegNumByIdx: set ith register of this struct argument
5424     //
5425     // Arguments:
5426     //    reg    -   reg number
5427     //    idx    -   index of the struct
5428     //
5429     // Return Value:
5430     //    None
5431     //
5432     void SetRegNumByIdx(regNumber reg, unsigned idx)
5433     {
5434         assert(idx < MAX_REG_ARG);
5435         if (idx == 0)
5436         {
5437             gtRegNum = reg;
5438         }
5439         else
5440         {
5441             gtOtherRegs[idx - 1] = (regNumberSmall)reg;
5442             assert(gtOtherRegs[idx - 1] == reg);
5443         }
5444     }
5445
5446     //----------------------------------------------------------------------------
5447     // ClearOtherRegs: clear multi-reg state to indicate no regs are allocated
5448     //
5449     // Arguments:
5450     //    None
5451     //
5452     // Return Value:
5453     //    None
5454     //
5455     void ClearOtherRegs()
5456     {
5457         for (unsigned i = 0; i < MAX_REG_ARG - 1; ++i)
5458         {
5459             gtOtherRegs[i] = REG_NA;
5460         }
5461     }
5462
5463     //----------------------------------------------------------------------
5464     // GetRegSpillFlagByIdx: get spill flag associated with the register
5465     // specified by its index.
5466     //
5467     // Arguments:
5468     //    idx  -  Position or index of the register
5469     //
5470     // Return Value:
5471     //    Returns GTF_* flags associated with the register. Only GTF_SPILL and GTF_SPILLED are considered.
5472     //
5473     unsigned GetRegSpillFlagByIdx(unsigned idx) const
5474     {
5475         assert(idx < MAX_REG_ARG);
5476
5477         unsigned bits = gtSpillFlags >> (idx * 2); // It doesn't matter that we possibly leave other high bits here.
5478         unsigned spillFlags = 0;
5479         if (bits & PACKED_GTF_SPILL)
5480         {
5481             spillFlags |= GTF_SPILL;
5482         }
5483         if (bits & PACKED_GTF_SPILLED)
5484         {
5485             spillFlags |= GTF_SPILLED;
5486         }
5487
5488         return spillFlags;
5489     }
5490
5491     //----------------------------------------------------------------------
5492     // SetRegSpillFlagByIdx: set spill flags for the register
5493     // specified by its index.
5494     //
5495     // Arguments:
5496     //    flags  -  GTF_* flags. Only GTF_SPILL and GTF_SPILLED are allowed.
5497     //    idx    -  Position or index of the register
5498     //
5499     // Return Value:
5500     //    None
5501     //
5502     void SetRegSpillFlagByIdx(unsigned flags, unsigned idx)
5503     {
5504         assert(idx < MAX_REG_ARG);
5505
5506         unsigned bits = 0;
5507         if (flags & GTF_SPILL)
5508         {
5509             bits |= PACKED_GTF_SPILL;
5510         }
5511         if (flags & GTF_SPILLED)
5512         {
5513             bits |= PACKED_GTF_SPILLED;
5514         }
5515
5516         const unsigned char packedFlags = PACKED_GTF_SPILL | PACKED_GTF_SPILLED;
5517
5518         // Clear anything that was already there by masking out the bits before 'or'ing in what we want there.
5519         gtSpillFlags = (unsigned char)((gtSpillFlags & ~(packedFlags << (idx * 2))) | (bits << (idx * 2)));
5520     }
5521
5522     //--------------------------------------------------------------------------
5523     // GetRegType:  Get var_type of the register specified by index.
5524     //
5525     // Arguments:
5526     //    index - Index of the register.
5527     //            First register will have an index 0 and so on.
5528     //
5529     // Return Value:
5530     //    var_type of the register specified by its index.
5531
5532     var_types GetRegType(unsigned index)
5533     {
5534         assert(index < gtNumRegs);
5535         var_types result = m_regType[index];
5536         return result;
5537     }
5538
5539     //-------------------------------------------------------------------
5540     // clearOtherRegFlags: clear GTF_* flags associated with gtOtherRegs
5541     //
5542     // Arguments:
5543     //     None
5544     //
5545     // Return Value:
5546     //     None
5547     //
5548     void ClearOtherRegFlags()
5549     {
5550         gtSpillFlags = 0;
5551     }
5552
5553 #ifdef FEATURE_PUT_STRUCT_ARG_STK
5554     unsigned getArgSize()
5555     {
5556         return (gtNumSlots + gtNumRegs) * TARGET_POINTER_SIZE;
5557     }
5558 #endif // FEATURE_PUT_STRUCT_ARG_STK
5559
5560 #if DEBUGGABLE_GENTREE
5561     GenTreePutArgSplit() : GenTreePutArgStk()
5562     {
5563     }
5564 #endif
5565 };
5566 #endif // !LEGACY_BACKEND && _TARGET_ARM_
5567
5568 // Represents GT_COPY or GT_RELOAD node
5569 struct GenTreeCopyOrReload : public GenTreeUnOp
5570 {
5571 #if FEATURE_MULTIREG_RET
5572     // State required to support copy/reload of a multi-reg call node.
5573     // First register is is always given by gtRegNum.
5574     //
5575     regNumberSmall gtOtherRegs[MAX_RET_REG_COUNT - 1];
5576 #endif
5577
5578     //----------------------------------------------------------
5579     // ClearOtherRegs: set gtOtherRegs to REG_NA.
5580     //
5581     // Arguments:
5582     //    None
5583     //
5584     // Return Value:
5585     //    None
5586     //
5587     void ClearOtherRegs()
5588     {
5589 #if FEATURE_MULTIREG_RET
5590         for (unsigned i = 0; i < MAX_RET_REG_COUNT - 1; ++i)
5591         {
5592             gtOtherRegs[i] = REG_NA;
5593         }
5594 #endif
5595     }
5596
5597     //-----------------------------------------------------------
5598     // GetRegNumByIdx: Get regNumber of ith position.
5599     //
5600     // Arguments:
5601     //    idx   -   register position.
5602     //
5603     // Return Value:
5604     //    Returns regNumber assigned to ith position.
5605     //
5606     regNumber GetRegNumByIdx(unsigned idx) const
5607     {
5608         assert(idx < MAX_RET_REG_COUNT);
5609
5610         if (idx == 0)
5611         {
5612             return gtRegNum;
5613         }
5614
5615 #if FEATURE_MULTIREG_RET
5616         return (regNumber)gtOtherRegs[idx - 1];
5617 #else
5618         return REG_NA;
5619 #endif
5620     }
5621
5622     //-----------------------------------------------------------
5623     // SetRegNumByIdx: Set the regNumber for ith position.
5624     //
5625     // Arguments:
5626     //    reg   -   reg number
5627     //    idx   -   register position.
5628     //
5629     // Return Value:
5630     //    None.
5631     //
5632     void SetRegNumByIdx(regNumber reg, unsigned idx)
5633     {
5634         assert(idx < MAX_RET_REG_COUNT);
5635
5636         if (idx == 0)
5637         {
5638             gtRegNum = reg;
5639         }
5640 #if FEATURE_MULTIREG_RET
5641         else
5642         {
5643             gtOtherRegs[idx - 1] = (regNumberSmall)reg;
5644             assert(gtOtherRegs[idx - 1] == reg);
5645         }
5646 #else
5647         else
5648         {
5649             unreached();
5650         }
5651 #endif
5652     }
5653
5654     //----------------------------------------------------------------------------
5655     // CopyOtherRegs: copy multi-reg state from the given copy/reload node to this
5656     // node.
5657     //
5658     // Arguments:
5659     //    from  -  GenTree node from which to copy multi-reg state
5660     //
5661     // Return Value:
5662     //    None
5663     //
5664     // TODO-ARM: Implement this routine for Arm64 and Arm32
5665     // TODO-X86: Implement this routine for x86
5666     void CopyOtherRegs(GenTreeCopyOrReload* from)
5667     {
5668         assert(OperGet() == from->OperGet());
5669
5670 #ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
5671         for (unsigned i = 0; i < MAX_RET_REG_COUNT - 1; ++i)
5672         {
5673             gtOtherRegs[i] = from->gtOtherRegs[i];
5674         }
5675 #endif
5676     }
5677
5678     GenTreeCopyOrReload(genTreeOps oper, var_types type, GenTree* op1) : GenTreeUnOp(oper, type, op1)
5679     {
5680         gtRegNum = REG_NA;
5681         ClearOtherRegs();
5682     }
5683
5684 #if DEBUGGABLE_GENTREE
5685     GenTreeCopyOrReload() : GenTreeUnOp()
5686     {
5687     }
5688 #endif
5689 };
5690
5691 // Represents GT_ALLOCOBJ node
5692
5693 struct GenTreeAllocObj final : public GenTreeUnOp
5694 {
5695     unsigned int         gtNewHelper; // Value returned by ICorJitInfo::getNewHelper
5696     CORINFO_CLASS_HANDLE gtAllocObjClsHnd;
5697
5698     GenTreeAllocObj(var_types type, unsigned int helper, CORINFO_CLASS_HANDLE clsHnd, GenTree* op)
5699         : GenTreeUnOp(GT_ALLOCOBJ, type, op DEBUGARG(/*largeNode*/ TRUE))
5700         , // This node in most cases will be changed to a call node
5701         gtNewHelper(helper)
5702         , gtAllocObjClsHnd(clsHnd)
5703     {
5704     }
5705 #if DEBUGGABLE_GENTREE
5706     GenTreeAllocObj() : GenTreeUnOp()
5707     {
5708     }
5709 #endif
5710 };
5711
5712 // Represents GT_RUNTIMELOOKUP node
5713
5714 struct GenTreeRuntimeLookup final : public GenTreeUnOp
5715 {
5716     CORINFO_GENERIC_HANDLE   gtHnd;
5717     CorInfoGenericHandleType gtHndType;
5718
5719     GenTreeRuntimeLookup(CORINFO_GENERIC_HANDLE hnd, CorInfoGenericHandleType hndTyp, GenTree* tree)
5720         : GenTreeUnOp(GT_RUNTIMELOOKUP, tree->gtType, tree DEBUGARG(/*largeNode*/ FALSE)), gtHnd(hnd), gtHndType(hndTyp)
5721     {
5722         assert(hnd != nullptr);
5723     }
5724 #if DEBUGGABLE_GENTREE
5725     GenTreeRuntimeLookup() : GenTreeUnOp()
5726     {
5727     }
5728 #endif
5729
5730     // Return reference to the actual tree that does the lookup
5731     GenTree*& Lookup()
5732     {
5733         return gtOp1;
5734     }
5735
5736     bool IsClassHandle() const
5737     {
5738         return gtHndType == CORINFO_HANDLETYPE_CLASS;
5739     }
5740     bool IsMethodHandle() const
5741     {
5742         return gtHndType == CORINFO_HANDLETYPE_METHOD;
5743     }
5744     bool IsFieldHandle() const
5745     {
5746         return gtHndType == CORINFO_HANDLETYPE_FIELD;
5747     }
5748
5749     // Note these operations describe the handle that is input to the
5750     // lookup, not the handle produced by the lookup.
5751     CORINFO_CLASS_HANDLE GetClassHandle() const
5752     {
5753         assert(IsClassHandle());
5754         return (CORINFO_CLASS_HANDLE)gtHnd;
5755     }
5756     CORINFO_METHOD_HANDLE GetMethodHandle() const
5757     {
5758         assert(IsMethodHandle());
5759         return (CORINFO_METHOD_HANDLE)gtHnd;
5760     }
5761     CORINFO_FIELD_HANDLE GetFieldHandle() const
5762     {
5763         assert(IsMethodHandle());
5764         return (CORINFO_FIELD_HANDLE)gtHnd;
5765     }
5766 };
5767
5768 // Represents a GT_JCC or GT_SETCC node.
5769
5770 struct GenTreeCC final : public GenTree
5771 {
5772     genTreeOps gtCondition; // any relop
5773
5774     GenTreeCC(genTreeOps oper, genTreeOps condition, var_types type = TYP_VOID)
5775         : GenTree(oper, type DEBUGARG(/*largeNode*/ FALSE)), gtCondition(condition)
5776     {
5777         assert(OperIs(GT_JCC, GT_SETCC));
5778         assert(OperIsCompare(condition));
5779     }
5780
5781 #if DEBUGGABLE_GENTREE
5782     GenTreeCC() : GenTree()
5783     {
5784     }
5785 #endif // DEBUGGABLE_GENTREE
5786 };
5787
5788 //------------------------------------------------------------------------
5789 // Deferred inline functions of GenTree -- these need the subtypes above to
5790 // be defined already.
5791 //------------------------------------------------------------------------
5792
5793 inline bool GenTree::OperIsBlkOp()
5794 {
5795     return (((gtOper == GT_ASG) && varTypeIsStruct(gtOp.gtOp1))
5796 #ifndef LEGACY_BACKEND
5797             || (OperIsBlk() && (AsBlk()->Data() != nullptr))
5798 #endif
5799                 );
5800 }
5801
5802 inline bool GenTree::OperIsDynBlkOp()
5803 {
5804     if (gtOper == GT_ASG)
5805     {
5806         return gtGetOp1()->OperGet() == GT_DYN_BLK;
5807     }
5808 #ifndef LEGACY_BACKEND
5809     else if (gtOper == GT_STORE_DYN_BLK)
5810     {
5811         return true;
5812     }
5813 #endif
5814     return false;
5815 }
5816
5817 inline bool GenTree::OperIsInitBlkOp()
5818 {
5819     if (!OperIsBlkOp())
5820     {
5821         return false;
5822     }
5823 #ifndef LEGACY_BACKEND
5824     GenTree* src;
5825     if (gtOper == GT_ASG)
5826     {
5827         src = gtGetOp2();
5828     }
5829     else
5830     {
5831         src = AsBlk()->Data()->gtSkipReloadOrCopy();
5832     }
5833 #else  // LEGACY_BACKEND
5834     GenTree* src = gtGetOp2();
5835 #endif // LEGACY_BACKEND
5836     return src->OperIsInitVal() || src->OperIsConst();
5837 }
5838
5839 inline bool GenTree::OperIsCopyBlkOp()
5840 {
5841     return OperIsBlkOp() && !OperIsInitBlkOp();
5842 }
5843
5844 //------------------------------------------------------------------------
5845 // IsFPZero: Checks whether this is a floating point constant with value 0.0
5846 //
5847 // Return Value:
5848 //    Returns true iff the tree is an GT_CNS_DBL, with value of 0.0.
5849
5850 inline bool GenTree::IsFPZero()
5851 {
5852     if ((gtOper == GT_CNS_DBL) && (gtDblCon.gtDconVal == 0.0))
5853     {
5854         return true;
5855     }
5856     return false;
5857 }
5858
5859 //------------------------------------------------------------------------
5860 // IsIntegralConst: Checks whether this is a constant node with the given value
5861 //
5862 // Arguments:
5863 //    constVal - the value of interest
5864 //
5865 // Return Value:
5866 //    Returns true iff the tree is an integral constant opcode, with
5867 //    the given value.
5868 //
5869 // Notes:
5870 //    Like gtIconVal, the argument is of ssize_t, so cannot check for
5871 //    long constants in a target-independent way.
5872
5873 inline bool GenTree::IsIntegralConst(ssize_t constVal)
5874
5875 {
5876     if ((gtOper == GT_CNS_INT) && (gtIntConCommon.IconValue() == constVal))
5877     {
5878         return true;
5879     }
5880
5881     if ((gtOper == GT_CNS_LNG) && (gtIntConCommon.LngValue() == constVal))
5882     {
5883         return true;
5884     }
5885
5886     return false;
5887 }
5888
5889 //-------------------------------------------------------------------
5890 // IsIntegralConstVector: returns true if this this is a SIMD vector
5891 // with all its elements equal to an integral constant.
5892 //
5893 // Arguments:
5894 //     constVal  -  const value of vector element
5895 //
5896 // Returns:
5897 //     True if this represents an integral const SIMD vector.
5898 //
5899 inline bool GenTree::IsIntegralConstVector(ssize_t constVal)
5900 {
5901 #ifdef FEATURE_SIMD
5902     // SIMDIntrinsicInit intrinsic with a const value as initializer
5903     // represents a const vector.
5904     if ((gtOper == GT_SIMD) && (gtSIMD.gtSIMDIntrinsicID == SIMDIntrinsicInit) && gtGetOp1()->IsIntegralConst(constVal))
5905     {
5906         assert(varTypeIsIntegral(gtSIMD.gtSIMDBaseType));
5907         assert(gtGetOp2IfPresent() == nullptr);
5908         return true;
5909     }
5910 #endif
5911
5912     return false;
5913 }
5914
5915 inline bool GenTree::IsBoxedValue()
5916 {
5917     assert(gtOper != GT_BOX || gtBox.BoxOp() != nullptr);
5918     return (gtOper == GT_BOX) && (gtFlags & GTF_BOX_VALUE);
5919 }
5920
5921 inline bool GenTree::IsSIMDEqualityOrInequality() const
5922 {
5923 #ifdef FEATURE_SIMD
5924     if (gtOper == GT_SIMD)
5925     {
5926         SIMDIntrinsicID id = AsSIMD()->gtSIMDIntrinsicID;
5927         return (id == SIMDIntrinsicOpEquality) || (id == SIMDIntrinsicOpInEquality);
5928     }
5929 #endif
5930
5931     return false;
5932 }
5933
5934 inline GenTree* GenTree::MoveNext()
5935 {
5936     assert(OperIsAnyList());
5937     return gtOp.gtOp2;
5938 }
5939
5940 #ifdef DEBUG
5941 //------------------------------------------------------------------------
5942 // IsValidCallArgument: Given an GenTree node that represents an argument
5943 //                      enforce (or don't enforce) the following invariant.
5944 //
5945 // Arguments:
5946 //    instance method for a GenTree node
5947 //
5948 // Return values:
5949 //    true:      the GenTree node is accepted as a valid argument
5950 //    false:     the GenTree node is not accepted as a valid argumeny
5951 //
5952 // Notes:
5953 //    For targets that don't support arguments as a list of fields, we do not support GT_FIELD_LIST.
5954 //
5955 //    Currently for AMD64 UNIX we allow a limited case where a GT_FIELD_LIST is
5956 //    allowed but every element must be a GT_LCL_FLD.
5957 //
5958 //    For the future targets that allow for Multireg args (and this includes the current ARM64 target),
5959 //    or that allow for passing promoted structs, we allow a GT_FIELD_LIST of arbitrary nodes.
5960 //    These would typically start out as GT_LCL_VARs or GT_LCL_FLDS or GT_INDs,
5961 //    but could be changed into constants or GT_COMMA trees by the later
5962 //    optimization phases.
5963
5964 inline bool GenTree::IsValidCallArgument()
5965 {
5966     if (OperIsList())
5967     {
5968         // GT_FIELD_LIST is the only list allowed.
5969         return false;
5970     }
5971     if (OperIsFieldList())
5972     {
5973 #if defined(LEGACY_BACKEND) || (!FEATURE_MULTIREG_ARGS && !FEATURE_PUT_STRUCT_ARG_STK)
5974         // Not allowed to have a GT_FIELD_LIST for an argument
5975         // unless we have a RyuJIT backend and FEATURE_MULTIREG_ARGS or FEATURE_PUT_STRUCT_ARG_STK
5976
5977         return false;
5978
5979 #else // we have RyuJIT backend and FEATURE_MULTIREG_ARGS or FEATURE_PUT_STRUCT_ARG_STK
5980
5981 #ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
5982         // For UNIX ABI we currently only allow a GT_FIELD_LIST of GT_LCL_FLDs nodes
5983         GenTree* gtListPtr = this;
5984         while (gtListPtr != nullptr)
5985         {
5986             // ToDo: fix UNIX_AMD64 so that we do not generate this kind of a List
5987             //  Note the list as currently created is malformed, as the last entry is a nullptr
5988             if (gtListPtr->Current() == nullptr)
5989             {
5990                 break;
5991             }
5992
5993             // Only a list of GT_LCL_FLDs is allowed
5994             if (gtListPtr->Current()->OperGet() != GT_LCL_FLD)
5995             {
5996                 return false;
5997             }
5998             gtListPtr = gtListPtr->MoveNext();
5999         }
6000 #endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
6001
6002         // Note that for non-UNIX ABI the GT_FIELD_LIST may contain any node
6003         //
6004         // We allow this GT_FIELD_LIST as an argument
6005         return true;
6006
6007 #endif // FEATURE_MULTIREG_ARGS
6008     }
6009     // We don't have either kind of list, so it satisfies the invariant.
6010     return true;
6011 }
6012 #endif // DEBUG
6013
6014 inline GenTree* GenTree::Current()
6015 {
6016     assert(OperIsAnyList());
6017     return gtOp.gtOp1;
6018 }
6019
6020 inline GenTree** GenTree::pCurrent()
6021 {
6022     assert(OperIsAnyList());
6023     return &(gtOp.gtOp1);
6024 }
6025
6026 inline GenTree* GenTree::gtGetOp1() const
6027 {
6028     return AsOp()->gtOp1;
6029 }
6030
6031 #ifdef DEBUG
6032 /* static */
6033 inline bool GenTree::RequiresNonNullOp2(genTreeOps oper)
6034 {
6035     switch (oper)
6036     {
6037         case GT_ADD:
6038         case GT_SUB:
6039         case GT_MUL:
6040         case GT_DIV:
6041         case GT_MOD:
6042         case GT_UDIV:
6043         case GT_UMOD:
6044         case GT_OR:
6045         case GT_XOR:
6046         case GT_AND:
6047         case GT_LSH:
6048         case GT_RSH:
6049         case GT_RSZ:
6050         case GT_ROL:
6051         case GT_ROR:
6052         case GT_INDEX:
6053         case GT_ASG:
6054 #ifdef LEGACY_BACKEND
6055         case GT_ASG_ADD:
6056         case GT_ASG_SUB:
6057         case GT_ASG_MUL:
6058         case GT_ASG_DIV:
6059         case GT_ASG_MOD:
6060         case GT_ASG_UDIV:
6061         case GT_ASG_UMOD:
6062         case GT_ASG_OR:
6063         case GT_ASG_XOR:
6064         case GT_ASG_AND:
6065         case GT_ASG_LSH:
6066         case GT_ASG_RSH:
6067         case GT_ASG_RSZ:
6068 #endif
6069         case GT_EQ:
6070         case GT_NE:
6071         case GT_LT:
6072         case GT_LE:
6073         case GT_GE:
6074         case GT_GT:
6075         case GT_COMMA:
6076         case GT_QMARK:
6077         case GT_COLON:
6078         case GT_MKREFANY:
6079             return true;
6080         default:
6081             return false;
6082     }
6083 }
6084 #endif // DEBUG
6085
6086 inline GenTree* GenTree::gtGetOp2() const
6087 {
6088     assert(OperIsBinary());
6089
6090     GenTree* op2 = AsOp()->gtOp2;
6091
6092     // Only allow null op2 if the node type allows it, e.g. GT_LIST.
6093     assert((op2 != nullptr) || !RequiresNonNullOp2(gtOper));
6094
6095     return op2;
6096 }
6097
6098 inline GenTree* GenTree::gtGetOp2IfPresent() const
6099 {
6100     /* gtOp.gtOp2 is only valid for GTK_BINOP nodes. */
6101
6102     GenTree* op2 = OperIsBinary() ? AsOp()->gtOp2 : nullptr;
6103
6104     // This documents the genTreeOps for which gtOp.gtOp2 cannot be nullptr.
6105     // This helps prefix in its analysis of code which calls gtGetOp2()
6106
6107     assert((op2 != nullptr) || !RequiresNonNullOp2(gtOper));
6108
6109     return op2;
6110 }
6111
6112 inline GenTree* GenTree::gtEffectiveVal(bool commaOnly)
6113 {
6114     GenTree* effectiveVal = this;
6115     for (;;)
6116     {
6117         if (effectiveVal->gtOper == GT_COMMA)
6118         {
6119             effectiveVal = effectiveVal->gtOp.gtOp2;
6120         }
6121         else if (!commaOnly && (effectiveVal->gtOper == GT_NOP) && (effectiveVal->gtOp.gtOp1 != nullptr))
6122         {
6123             effectiveVal = effectiveVal->gtOp.gtOp1;
6124         }
6125         else
6126         {
6127             return effectiveVal;
6128         }
6129     }
6130 }
6131
6132 //-------------------------------------------------------------------------
6133 // gtRetExprVal - walk back through GT_RET_EXPRs
6134 //
6135 // Returns:
6136 //    tree representing return value from a successful inline,
6137 //    or original call for failed or yet to be determined inline.
6138 //
6139 // Notes:
6140 //    Multi-level inlines can form chains of GT_RET_EXPRs.
6141 //    This method walks back to the root of the chain.
6142
6143 inline GenTree* GenTree::gtRetExprVal()
6144 {
6145     GenTree* retExprVal = this;
6146     for (;;)
6147     {
6148         if (retExprVal->gtOper == GT_RET_EXPR)
6149         {
6150             retExprVal = retExprVal->gtRetExpr.gtInlineCandidate;
6151         }
6152         else
6153         {
6154             return retExprVal;
6155         }
6156     }
6157 }
6158
6159 inline GenTree* GenTree::gtSkipReloadOrCopy()
6160 {
6161     // There can be only one reload or copy (we can't have a reload/copy of a reload/copy)
6162     if (gtOper == GT_RELOAD || gtOper == GT_COPY)
6163     {
6164         assert(gtGetOp1()->OperGet() != GT_RELOAD && gtGetOp1()->OperGet() != GT_COPY);
6165         return gtGetOp1();
6166     }
6167     return this;
6168 }
6169
6170 //-----------------------------------------------------------------------------------
6171 // IsMultiRegCall: whether a call node returning its value in more than one register
6172 //
6173 // Arguments:
6174 //     None
6175 //
6176 // Return Value:
6177 //     Returns true if this GenTree is a multi register returning call
6178 inline bool GenTree::IsMultiRegCall() const
6179 {
6180     if (this->IsCall())
6181     {
6182         // We cannot use AsCall() as it is not declared const
6183         const GenTreeCall* call = reinterpret_cast<const GenTreeCall*>(this);
6184         return call->HasMultiRegRetVal();
6185     }
6186
6187     return false;
6188 }
6189
6190 //-----------------------------------------------------------------------------------
6191 // IsMultiRegNode: whether a node returning its value in more than one register
6192 //
6193 // Arguments:
6194 //     None
6195 //
6196 // Return Value:
6197 //     Returns true if this GenTree is a multi-reg node.
6198 inline bool GenTree::IsMultiRegNode() const
6199 {
6200     if (IsMultiRegCall())
6201     {
6202         return true;
6203     }
6204
6205 #if !defined(LEGACY_BACKEND) && defined(_TARGET_ARM_)
6206     if (OperIsMultiRegOp() || OperIsPutArgSplit() || (gtOper == GT_COPY))
6207     {
6208         return true;
6209     }
6210 #endif
6211
6212     return false;
6213 }
6214
6215 //-------------------------------------------------------------------------
6216 // IsCopyOrReload: whether this is a GT_COPY or GT_RELOAD node.
6217 //
6218 // Arguments:
6219 //     None
6220 //
6221 // Return Value:
6222 //     Returns true if this GenTree is a copy or reload node.
6223 inline bool GenTree::IsCopyOrReload() const
6224 {
6225     return (gtOper == GT_COPY || gtOper == GT_RELOAD);
6226 }
6227
6228 //-----------------------------------------------------------------------------------
6229 // IsCopyOrReloadOfMultiRegCall: whether this is a GT_COPY or GT_RELOAD of a multi-reg
6230 // call node.
6231 //
6232 // Arguments:
6233 //     None
6234 //
6235 // Return Value:
6236 //     Returns true if this GenTree is a copy or reload of multi-reg call node.
6237 inline bool GenTree::IsCopyOrReloadOfMultiRegCall() const
6238 {
6239     if (IsCopyOrReload())
6240     {
6241         return gtGetOp1()->IsMultiRegCall();
6242     }
6243
6244     return false;
6245 }
6246
6247 inline bool GenTree::IsCnsIntOrI() const
6248 {
6249     return (gtOper == GT_CNS_INT);
6250 }
6251
6252 inline bool GenTree::IsIntegralConst() const
6253 {
6254 #ifdef _TARGET_64BIT_
6255     return IsCnsIntOrI();
6256 #else  // !_TARGET_64BIT_
6257     return ((gtOper == GT_CNS_INT) || (gtOper == GT_CNS_LNG));
6258 #endif // !_TARGET_64BIT_
6259 }
6260
6261 // Is this node an integer constant that fits in a 32-bit signed integer (INT32)
6262 inline bool GenTree::IsIntCnsFitsInI32()
6263 {
6264 #ifdef _TARGET_64BIT_
6265     return IsCnsIntOrI() && AsIntCon()->FitsInI32();
6266 #else  // !_TARGET_64BIT_
6267     return IsCnsIntOrI();
6268 #endif // !_TARGET_64BIT_
6269 }
6270
6271 inline bool GenTree::IsCnsFltOrDbl() const
6272 {
6273     return OperGet() == GT_CNS_DBL;
6274 }
6275
6276 inline bool GenTree::IsCnsNonZeroFltOrDbl()
6277 {
6278     if (OperGet() == GT_CNS_DBL)
6279     {
6280         double constValue = gtDblCon.gtDconVal;
6281         return *(__int64*)&constValue != 0;
6282     }
6283
6284     return false;
6285 }
6286
6287 inline bool GenTree::IsHelperCall()
6288 {
6289     return OperGet() == GT_CALL && gtCall.gtCallType == CT_HELPER;
6290 }
6291
6292 inline var_types GenTree::CastFromType()
6293 {
6294     return this->gtCast.CastOp()->TypeGet();
6295 }
6296 inline var_types& GenTree::CastToType()
6297 {
6298     return this->gtCast.gtCastType;
6299 }
6300
6301 //-----------------------------------------------------------------------------------
6302 // HasGCPtr: determine whether this block op involves GC pointers
6303 //
6304 // Arguments:
6305 //     None
6306 //
6307 // Return Value:
6308 //    Returns true iff the object being copied contains one or more GC pointers.
6309 //
6310 // Notes:
6311 //    Of the block nodes, only GT_OBJ and ST_STORE_OBJ are allowed to have GC pointers.
6312 //
6313 inline bool GenTreeBlk::HasGCPtr()
6314 {
6315     if ((gtOper == GT_OBJ) || (gtOper == GT_STORE_OBJ))
6316     {
6317         return (AsObj()->gtGcPtrCount != 0);
6318     }
6319     return false;
6320 }
6321
6322 inline bool GenTree::isUsedFromSpillTemp() const
6323 {
6324 #if !defined(LEGACY_BACKEND)
6325     // If spilled and no reg at use, then it is used from the spill temp location rather than being reloaded.
6326     if (((gtFlags & GTF_SPILLED) != 0) && ((gtFlags & GTF_NOREG_AT_USE) != 0))
6327     {
6328         return true;
6329     }
6330 #endif //! LEGACY_BACKEND
6331
6332     return false;
6333 }
6334
6335 /*****************************************************************************/
6336
6337 #ifndef _HOST_64BIT_
6338 #include <poppack.h>
6339 #endif
6340
6341 /*****************************************************************************/
6342
6343 #if SMALL_TREE_NODES
6344
6345 // In debug, on some platforms (e.g., when LATE_DISASM is defined), GenTreeIntCon is bigger than GenTreeLclFld.
6346 const size_t TREE_NODE_SZ_SMALL = max(sizeof(GenTreeIntCon), sizeof(GenTreeLclFld));
6347
6348 #endif // SMALL_TREE_NODES
6349
6350 const size_t TREE_NODE_SZ_LARGE = sizeof(GenTreeCall);
6351
6352 /*****************************************************************************
6353  * Types returned by GenTree::lvaLclVarRefs()
6354  */
6355
6356 enum varRefKinds
6357 {
6358     VR_INVARIANT = 0x00, // an invariant value
6359     VR_NONE      = 0x00,
6360     VR_IND_REF   = 0x01, // an object reference
6361     VR_IND_SCL   = 0x02, // a non-object reference
6362     VR_GLB_VAR   = 0x04, // a global (clsVar)
6363 };
6364 // Add a temp define to avoid merge conflict.
6365 #define VR_IND_PTR VR_IND_REF
6366
6367 /*****************************************************************************/
6368 #endif // !GENTREE_H
6369 /*****************************************************************************/