Less Conservative GtObj
[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 "simplerhash.h"
28 #include "nodeinfo.h"
29 #include "simd.h"
30
31 // Debugging GenTree is much easier if we add a magic virtual function to make the debugger able to figure out what type it's got.
32 // This is enabled by default in DEBUG. To enable it in RET builds (temporarily!), you need to change the build to define DEBUGGABLE_GENTREE=1,
33 // as well as pass /OPT:NOICF to the linker (or else all the vtables get merged, making the debugging value supplied by them useless).
34 // See protojit.nativeproj for a commented example of setting the build flags correctly.
35 #ifndef DEBUGGABLE_GENTREE
36 #ifdef DEBUG
37 #define DEBUGGABLE_GENTREE  1
38 #else // !DEBUG
39 #define DEBUGGABLE_GENTREE  0
40 #endif // !DEBUG
41 #endif // !DEBUGGABLE_GENTREE
42
43 // The SpecialCodeKind enum is used to indicate the type of special (unique)
44 // target block that will be targeted by an instruction.
45 // These are used by:
46 //   GenTreeBoundsChk nodes (SCK_RNGCHK_FAIL, SCK_ARG_EXCPN, SCK_ARG_RNG_EXCPN)
47 //     - these nodes have a field (gtThrowKind) to indicate which kind
48 //   GenTreeOps nodes, for which codegen will generate the branch
49 //     - it will use the appropriate kind based on the opcode, though it's not
50 //       clear why SCK_OVERFLOW == SCK_ARITH_EXCPN
51 // SCK_PAUSE_EXEC is not currently used.
52 //   
53 enum        SpecialCodeKind
54 {
55     SCK_NONE,
56     SCK_RNGCHK_FAIL,                // target when range check fails
57     SCK_PAUSE_EXEC,                 // target to stop (e.g. to allow GC)
58     SCK_DIV_BY_ZERO,                // target for divide by zero (Not used on X86/X64)
59     SCK_ARITH_EXCPN,                // target on arithmetic exception
60     SCK_OVERFLOW = SCK_ARITH_EXCPN, // target on overflow
61     SCK_ARG_EXCPN,                  // target on ArgumentException (currently used only for SIMD intrinsics)
62     SCK_ARG_RNG_EXCPN,              // target on ArgumentOutOfRangeException (currently used only for SIMD intrinsics)
63     SCK_COUNT
64 };
65
66 /*****************************************************************************/
67
68 DECLARE_TYPED_ENUM(genTreeOps,BYTE)
69 {
70     #define GTNODE(en,sn,cm,ok) GT_ ## en,
71     #include "gtlist.h"
72
73     GT_COUNT,
74
75     // GT_CNS_NATIVELONG is the gtOper symbol for GT_CNS_LNG or GT_CNS_INT, depending on the target.
76     // For the 64-bit targets we will only use GT_CNS_INT as it used to represent all the possible sizes
77     // 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.
78     // In the future when we retarget the JIT for x86 we should consider eliminating GT_CNS_LNG
79     //
80 #ifdef _TARGET_64BIT_
81     GT_CNS_NATIVELONG = GT_CNS_INT,
82 #else
83     GT_CNS_NATIVELONG = GT_CNS_LNG,
84 #endif
85 }
86 END_DECLARE_TYPED_ENUM(genTreeOps,BYTE)
87
88 /*****************************************************************************
89  *
90  *  The following enum defines a set of bit flags that can be used
91  *  to classify expression tree nodes. Note that some operators will
92  *  have more than one bit set, as follows:
93  *
94  *          GTK_CONST    implies    GTK_LEAF
95  *          GTK_RELOP    implies    GTK_BINOP
96  *          GTK_LOGOP    implies    GTK_BINOP
97  */
98
99 enum genTreeKinds
100 {
101     GTK_SPECIAL = 0x0000,       // unclassified operator (special handling reqd)
102
103     GTK_CONST   = 0x0001,       // constant     operator
104     GTK_LEAF    = 0x0002,       // leaf         operator
105     GTK_UNOP    = 0x0004,       // unary        operator
106     GTK_BINOP   = 0x0008,       // binary       operator
107     GTK_RELOP   = 0x0010,       // comparison   operator
108     GTK_LOGOP   = 0x0020,       // logical      operator
109     GTK_ASGOP   = 0x0040,       // assignment   operator
110
111     GTK_KINDMASK= 0x007F,       // operator kind mask
112
113     GTK_COMMUTE = 0x0080,       // commutative  operator
114
115     GTK_EXOP    = 0x0100,       // Indicates that an oper for a node type that extends GenTreeOp (or GenTreeUnOp)
116                                 // by adding non-node fields to unary or binary operator.
117
118     GTK_LOCAL   = 0x0200,       // is a local access (load, store, phi)
119
120     /* Define composite value(s) */
121
122     GTK_SMPOP   = (GTK_UNOP|GTK_BINOP|GTK_RELOP|GTK_LOGOP)
123 };
124
125 /*****************************************************************************/
126
127 #define SMALL_TREE_NODES    1
128
129 /*****************************************************************************/
130
131 DECLARE_TYPED_ENUM(gtCallTypes,BYTE)
132 {
133     CT_USER_FUNC,       // User function
134     CT_HELPER,          // Jit-helper
135     CT_INDIRECT,        // Indirect call
136
137     CT_COUNT            // fake entry (must be last)
138 }
139 END_DECLARE_TYPED_ENUM(gtCallTypes,BYTE)
140
141
142 /*****************************************************************************/
143
144 struct                  BasicBlock;
145  
146 struct                  InlineCandidateInfo;
147
148 /*****************************************************************************/
149
150 // GT_FIELD nodes will be lowered into more "code-gen-able" representations, like
151 // GT_IND's of addresses, or GT_LCL_FLD nodes.  We'd like to preserve the more abstract
152 // information, and will therefore annotate such lowered nodes with FieldSeq's.  A FieldSeq
153 // represents a (possibly) empty sequence of fields.  The fields are in the order
154 // in which they are dereferenced.  The first field may be an object field or a struct field;
155 // all subsequent fields must be struct fields.
156 struct FieldSeqNode
157 {
158     CORINFO_FIELD_HANDLE m_fieldHnd;
159     FieldSeqNode*        m_next;
160
161     FieldSeqNode(CORINFO_FIELD_HANDLE fieldHnd, FieldSeqNode* next) : m_fieldHnd(fieldHnd), m_next(next) {}
162
163     // returns true when this is the pseudo #FirstElem field sequence
164     bool IsFirstElemFieldSeq();
165
166     // returns true when this is the pseudo #ConstantIndex field sequence
167     bool IsConstantIndexFieldSeq();
168
169     // returns true when this is the the pseudo #FirstElem field sequence or the pseudo #ConstantIndex field sequence
170     bool IsPseudoField();
171
172     // Make sure this provides methods that allow it to be used as a KeyFuncs type in SimplerHash.
173     static int GetHashCode(FieldSeqNode fsn)
174     {
175         return static_cast<int>(reinterpret_cast<intptr_t>(fsn.m_fieldHnd)) ^ static_cast<int>(reinterpret_cast<intptr_t>(fsn.m_next));
176     }
177
178     static bool Equals(FieldSeqNode fsn1, FieldSeqNode fsn2)
179     {
180         return fsn1.m_fieldHnd == fsn2.m_fieldHnd && fsn1.m_next == fsn2.m_next;
181     }
182 };
183
184 // This class canonicalizes field sequences.
185 class FieldSeqStore
186 {
187     typedef SimplerHashTable<FieldSeqNode, /*KeyFuncs*/FieldSeqNode, FieldSeqNode*, JitSimplerHashBehavior> FieldSeqNodeCanonMap;
188
189     IAllocator*           m_alloc;
190     FieldSeqNodeCanonMap* m_canonMap;
191
192     static FieldSeqNode   s_notAField;  // No value, just exists to provide an address.
193
194     // Dummy variables to provide the addresses for the "pseudo field handle" statics below.
195     static int FirstElemPseudoFieldStruct;
196     static int ConstantIndexPseudoFieldStruct;
197
198 public:
199     FieldSeqStore(IAllocator* alloc);
200
201     // Returns the (canonical in the store) singleton field sequence for the given handle.
202     FieldSeqNode* CreateSingleton(CORINFO_FIELD_HANDLE fieldHnd);
203
204     // This is a special distinguished FieldSeqNode indicating that a constant does *not*
205     // represent a valid field sequence.  This is "infectious", in the sense that appending it
206     // (on either side) to any field sequence yields the "NotAField()" sequence.
207     static FieldSeqNode* NotAField() { return &s_notAField; }
208
209     // Returns the (canonical in the store) field sequence representing the concatenation of
210     // the sequences represented by "a" and "b".  Assumes that "a" and "b" are canonical; that is,
211     // they are the results of CreateSingleton, NotAField, or Append calls.  If either of the arguments
212     // are the "NotAField" value, so is the result.
213     FieldSeqNode* Append(FieldSeqNode* a, FieldSeqNode* b);
214
215     // We have a few "pseudo" field handles:
216
217     // This treats the constant offset of the first element of something as if it were a field.
218     // Works for method table offsets of boxed structs, or first elem offset of arrays/strings.
219     static CORINFO_FIELD_HANDLE FirstElemPseudoField;
220
221     // If there is a constant index, we make a psuedo field to correspond to the constant added to
222     // offset of the indexed field.  This keeps the field sequence structure "normalized", especially in the
223     // case where the element type is a struct, so we might add a further struct field offset.
224     static CORINFO_FIELD_HANDLE ConstantIndexPseudoField;
225
226     static bool IsPseudoField(CORINFO_FIELD_HANDLE hnd)
227     {
228         return hnd == FirstElemPseudoField || hnd == ConstantIndexPseudoField;
229     }
230 };
231
232
233
234 /*****************************************************************************/
235
236 typedef struct GenTree *  GenTreePtr;
237 struct GenTreeArgList;
238
239 // Forward declarations of the subtypes
240 #define GTSTRUCT_0(fn, en)                struct GenTree##fn;
241 #define GTSTRUCT_1(fn, en)                struct GenTree##fn;
242 #define GTSTRUCT_2(fn, en, en2)           struct GenTree##fn;
243 #define GTSTRUCT_3(fn, en, en2, en3)      struct GenTree##fn;
244 #define GTSTRUCT_4(fn, en, en2, en3, en4) struct GenTree##fn;
245 #define GTSTRUCT_N(fn, ...) struct GenTree##fn;
246 #include "gtstructs.h"
247
248 /*****************************************************************************/
249
250 #ifndef _HOST_64BIT_
251 #include <pshpack4.h>
252 #endif
253
254 struct GenTree
255 {
256     // We use GT_STRUCT_0 only for the category of simple ops.
257 #define GTSTRUCT_0(fn, en)           GenTree##fn* As##fn() \
258                                      { \
259                                          assert(this->OperIsSimple()); \
260                                          return reinterpret_cast<GenTree##fn*>(this); \
261                                      } \
262                                      GenTree##fn& As##fn##Ref() { return *As##fn(); } \
263                                      __declspec(property(get=As##fn##Ref)) GenTree##fn& gt##fn;
264 #define GTSTRUCT_1(fn, en)           GenTree##fn* As##fn() \
265                                      { \
266                                          assert(this->gtOper == en); \
267                                          return reinterpret_cast<GenTree##fn*>(this); \
268                                      } \
269                                      GenTree##fn& As##fn##Ref() { return *As##fn(); } \
270                                      __declspec(property(get=As##fn##Ref)) GenTree##fn& gt##fn;
271 #define GTSTRUCT_2(fn, en, en2)      GenTree##fn* As##fn() \
272                                      { \
273                                          assert(this->gtOper == en || this->gtOper == en2); \
274                                          return reinterpret_cast<GenTree##fn*>(this); \
275                                      } \
276                                      GenTree##fn& As##fn##Ref() { return *As##fn(); } \
277                                      __declspec(property(get=As##fn##Ref)) GenTree##fn& gt##fn;
278 #define GTSTRUCT_3(fn, en, en2, en3) GenTree##fn* As##fn() \
279                                      { \
280                                          assert(this->gtOper == en || this->gtOper == en2 || this->gtOper == en3); \
281                                          return reinterpret_cast<GenTree##fn*>(this); \
282                                      } \
283                                      GenTree##fn& As##fn##Ref() { return *As##fn(); } \
284                                      __declspec(property(get=As##fn##Ref)) GenTree##fn& gt##fn;
285
286 #define GTSTRUCT_4(fn, en, en2, en3, en4) GenTree##fn* As##fn() \
287                                      { \
288                                          assert(this->gtOper == en || this->gtOper == en2 || this->gtOper == en3 || this->gtOper == en4); \
289                                          return reinterpret_cast<GenTree##fn*>(this); \
290                                      } \
291                                      GenTree##fn& As##fn##Ref() { return *As##fn(); } \
292                                      __declspec(property(get=As##fn##Ref)) GenTree##fn& gt##fn;
293
294 #ifdef DEBUG
295 // VC does not optimize out this loop in retail even though the value it computes is unused
296 // so we need a separate version for non-debug
297 #define GTSTRUCT_N(fn, ...)          GenTree##fn* As##fn() \
298                                      { \
299                                          genTreeOps validOps[] = {__VA_ARGS__}; \
300                                          bool found = false;            \
301                                          for (unsigned i=0; i<ArrLen(validOps); i++) { \
302                                              if (this->gtOper == validOps[i]) \
303                                              {                          \
304                                                  found = true;          \
305                                                  break;                 \
306                                              }                          \
307                                          }                              \
308                                          assert(found);                 \
309                                          return reinterpret_cast<GenTree##fn*>(this); \
310                                      }                                  \
311                                      GenTree##fn& As##fn##Ref() { return *As##fn(); }                    \
312                                      __declspec(property(get=As##fn##Ref)) GenTree##fn& gt##fn;
313 #else
314 #define GTSTRUCT_N(fn, ...)          GenTree##fn* As##fn()    \
315                                      { \
316                                          return reinterpret_cast<GenTree##fn*>(this); \
317                                      }                                  \
318                                      GenTree##fn& As##fn##Ref() { return *As##fn(); }                    \
319                                      __declspec(property(get=As##fn##Ref)) GenTree##fn& gt##fn;
320 #endif
321
322 #include "gtstructs.h"
323
324     genTreeOps          gtOper;       // enum subtype BYTE
325     var_types           gtType;       // enum subtype BYTE 
326
327     genTreeOps          OperGet() const { return gtOper; }
328     var_types           TypeGet() const { return gtType; }
329
330 #ifdef DEBUG
331     genTreeOps          gtOperSave;   // Only used to save gtOper when we destroy a node, to aid debugging.
332 #endif
333
334 #if FEATURE_ANYCSE
335
336 #define NO_CSE           (0)
337
338 #define IS_CSE_INDEX(x)  (x != 0)
339 #define IS_CSE_USE(x)    (x > 0)
340 #define IS_CSE_DEF(x)    (x < 0)
341 #define GET_CSE_INDEX(x) ((x > 0) ? x : -x)
342 #define TO_CSE_DEF(x)    (-x)
343
344     signed char       gtCSEnum;        // 0 or the CSE index (negated if def)
345                                        // valid only for CSE expressions
346
347 #endif // FEATURE_ANYCSE
348
349 #if ASSERTION_PROP
350     unsigned short     gtAssertionNum;  // 0 or Assertion table index
351                                         // valid only for non-GT_STMT nodes
352
353     bool         HasAssertion() const             { return gtAssertionNum != 0; }
354     void         ClearAssertion()                 { gtAssertionNum = 0;         }
355
356     unsigned short GetAssertion() const             { return gtAssertionNum;  }
357     void           SetAssertion(unsigned short value) { assert((unsigned short)value == value); gtAssertionNum = (unsigned short)value; }
358
359 #endif
360
361 #if FEATURE_STACK_FP_X87
362     unsigned char       gtFPlvl;        // x87 stack depth at this node
363     void                gtCopyFPlvl(GenTree * other) { gtFPlvl = other->gtFPlvl; }
364     void                gtSetFPlvl(unsigned level) { noway_assert(FitsIn<unsigned char>(level)); gtFPlvl = (unsigned char)level; }
365 #else // FEATURE_STACK_FP_X87
366     void                gtCopyFPlvl(GenTree * other) { }
367     void                gtSetFPlvl(unsigned level) { }
368 #endif // FEATURE_STACK_FP_X87
369
370     //
371     // Cost metrics on the node. Don't allow direct access to the variable for setting.
372     //
373
374 public:
375
376 #ifdef DEBUG
377     // You are not allowed to read the cost values before they have been set in gtSetEvalOrder().
378     // Keep track of whether the costs have been initialized, and assert if they are read before being initialized.
379     // Obviously, this information does need to be initialized when a node is created.
380     // This is public so the dumpers can see it.
381
382     bool gtCostsInitialized;
383 #endif // DEBUG
384
385 #define MAX_COST        UCHAR_MAX
386 #define IND_COST_EX     3             // execution cost for an indirection
387
388     __declspec(property(get=GetCostEx))
389     unsigned char    gtCostEx;     // estimate of expression execution cost
390
391     __declspec(property(get=GetCostSz))
392     unsigned char    gtCostSz;     // estimate of expression code size cost
393
394     unsigned char GetCostEx() const { assert(gtCostsInitialized); return _gtCostEx; }
395     unsigned char GetCostSz() const { assert(gtCostsInitialized); return _gtCostSz; }
396
397     // Set the costs. They are always both set at the same time.
398     // Don't use the "put" property: force calling this function, to make it more obvious in the few places
399     // that set the values.
400     // Note that costs are only set in gtSetEvalOrder() and its callees.
401     void            SetCosts(unsigned costEx, unsigned costSz)
402     {
403         assert(costEx != (unsigned)-1); // looks bogus
404         assert(costSz != (unsigned)-1); // looks bogus
405         INDEBUG(gtCostsInitialized = true;)
406
407         _gtCostEx = (costEx > MAX_COST) ? MAX_COST : (unsigned char)costEx;
408         _gtCostSz = (costSz > MAX_COST) ? MAX_COST : (unsigned char)costSz;
409     }
410
411     // Opimized copy function, to avoid the SetCosts() function comparisons, and make it more clear that a node copy is happening.
412     void            CopyCosts(const GenTree* const tree)
413     {
414         INDEBUG(gtCostsInitialized = tree->gtCostsInitialized;) // If the 'tree' costs aren't initialized, we'll hit an assert below.
415         _gtCostEx = tree->gtCostEx;
416         _gtCostSz = tree->gtCostSz;
417     }
418
419     // Same as CopyCosts, but avoids asserts if the costs we are copying have not been initialized.
420     // This is because the importer, for example, clones nodes, before these costs have been initialized.
421     // Note that we directly access the 'tree' costs, not going through the accessor functions (either
422     // directly or through the properties).
423     void            CopyRawCosts(const GenTree* const tree)
424     {
425         INDEBUG(gtCostsInitialized = tree->gtCostsInitialized;)
426         _gtCostEx = tree->_gtCostEx;
427         _gtCostSz = tree->_gtCostSz;
428     }
429
430 private:
431
432     unsigned char    _gtCostEx;     // estimate of expression execution cost
433     unsigned char    _gtCostSz;     // estimate of expression code size cost
434
435     //
436     // Register or register pair number of the node.
437     //
438
439 #ifdef DEBUG
440 public:
441     enum genRegTag
442     {
443         GT_REGTAG_NONE,     // Nothing has been assigned to _gtRegNum/_gtRegPair
444         GT_REGTAG_REG,      // _gtRegNum  has been assigned
445 #if CPU_LONG_USES_REGPAIR
446         GT_REGTAG_REGPAIR   // _gtRegPair has been assigned
447 #endif
448     };
449     genRegTag GetRegTag() const
450     {
451 #if CPU_LONG_USES_REGPAIR
452         assert(gtRegTag == GT_REGTAG_NONE || gtRegTag == GT_REGTAG_REG || gtRegTag == GT_REGTAG_REGPAIR);
453 #else
454         assert(gtRegTag == GT_REGTAG_NONE || gtRegTag == GT_REGTAG_REG);
455 #endif
456         return gtRegTag;
457     }
458 private:
459     genRegTag           gtRegTag; // What is in _gtRegNum/_gtRegPair?
460 #endif // DEBUG
461
462 private:
463
464     union
465     { 
466         // NOTE: After LSRA, one of these values may be valid even if GTF_REG_VAL is not set in gtFlags.
467         // They store the register assigned to the node. If a register is not assigned, _gtRegNum is set to REG_NA
468         // or _gtRegPair is set to REG_PAIR_NONE, depending on the node type.
469         regNumberSmall   _gtRegNum;     // which register      the value is in
470         regPairNoSmall   _gtRegPair;    // which register pair the value is in
471     };
472
473 public:
474
475     // The register number is stored in a small format (8 bits), but the getters return and the setters take
476     // a full-size (unsigned) format, to localize the casts here.
477
478     __declspec(property(get=GetRegNum,put=SetRegNum))
479     regNumber           gtRegNum;
480
481     // for codegen purposes, is this node a subnode of its parent
482     bool isContained() const;
483
484     bool isContainedIndir() const;
485
486     bool isIndirAddrMode();
487
488     bool isIndir() const;
489
490     bool isContainedIntOrIImmed() const     { return isContained() && IsCnsIntOrI(); }
491
492     bool isContainedFltOrDblImmed() const   { return isContained() && (OperGet() == GT_CNS_DBL); }
493
494     bool isLclField() const                 { return OperGet() == GT_LCL_FLD || OperGet() == GT_STORE_LCL_FLD; }
495
496     bool isContainedLclField() const        { return isContained() && isLclField(); }
497
498     // Indicates whether it is a memory op.
499     // Right now it includes Indir and LclField ops.
500     bool isMemoryOp() const                 { return isIndir() || isLclField(); }
501
502     bool isContainedMemoryOp() const        { return isContained() && isMemoryOp(); }
503
504     regNumber GetRegNum() const
505     {
506         assert((gtRegTag == GT_REGTAG_REG) ||
507                (gtRegTag == GT_REGTAG_NONE)); // TODO-Cleanup: get rid of the NONE case, and fix everyplace that reads undefined values
508         regNumber reg = (regNumber) _gtRegNum;
509         assert((gtRegTag == GT_REGTAG_NONE) || // TODO-Cleanup: get rid of the NONE case, and fix everyplace that reads undefined values
510                (reg >= REG_FIRST &&
511                 reg <= REG_COUNT));
512         return reg;
513     }
514
515     void SetRegNum(regNumber reg)
516     {
517         assert(reg >= REG_FIRST &&
518                reg <= REG_COUNT);
519         // Make sure the upper bits of _gtRegPair are clear
520         _gtRegPair = (regPairNoSmall) 0;
521         _gtRegNum = (regNumberSmall) reg;
522         INDEBUG(gtRegTag = GT_REGTAG_REG;)
523         assert(_gtRegNum == reg);
524     }
525
526 #if CPU_LONG_USES_REGPAIR
527     __declspec(property(get=GetRegPair,put=SetRegPair))
528     regPairNo           gtRegPair;
529
530     regPairNo GetRegPair() const
531     {
532         assert((gtRegTag == GT_REGTAG_REGPAIR) ||
533                (gtRegTag == GT_REGTAG_NONE)); // TODO-Cleanup: get rid of the NONE case, and fix everyplace that reads undefined values
534         regPairNo regPair = (regPairNo) _gtRegPair;
535         assert((gtRegTag == GT_REGTAG_NONE) || // TODO-Cleanup: get rid of the NONE case, and fix everyplace that reads undefined values
536                (regPair >= REG_PAIR_FIRST &&
537                 regPair <= REG_PAIR_LAST) ||
538                (regPair == REG_PAIR_NONE));     // allow initializing to an undefined value
539         return regPair;
540     }
541
542     void SetRegPair(regPairNo regPair)
543     {
544         assert((regPair >= REG_PAIR_FIRST &&
545                 regPair <= REG_PAIR_LAST) ||
546                (regPair == REG_PAIR_NONE));     // allow initializing to an undefined value
547         _gtRegPair = (regPairNoSmall) regPair;
548         INDEBUG(gtRegTag = GT_REGTAG_REGPAIR;)
549         assert(_gtRegPair == regPair);
550     }
551 #endif
552
553     // Copy the _gtRegNum/_gtRegPair/gtRegTag fields
554     void CopyReg(GenTreePtr from);
555
556     void gtClearReg(Compiler* compiler);
557
558     bool gtHasReg() const;
559
560     regMaskTP gtGetRegMask() const;
561
562     unsigned            gtFlags;        // see GTF_xxxx below
563
564 #if defined(DEBUG)
565     unsigned            gtDebugFlags;   // see GTF_DEBUG_xxx below
566 #endif // defined(DEBUG)
567
568     ValueNumPair        gtVNPair;
569
570     regMaskSmall        gtRsvdRegs;     // set of fixed trashed  registers
571 #ifdef LEGACY_BACKEND
572     regMaskSmall        gtUsedRegs;     // set of used (trashed) registers
573 #endif // LEGACY_BACKEND
574
575 #ifndef LEGACY_BACKEND
576     TreeNodeInfo        gtLsraInfo;
577 #endif // !LEGACY_BACKEND
578
579     void                SetVNsFromNode(GenTreePtr tree)
580     {
581         gtVNPair = tree->gtVNPair;
582     }
583
584     ValueNum            GetVN(ValueNumKind vnk) const
585     {
586         if (vnk == VNK_Liberal)
587         {
588             return gtVNPair.GetLiberal();
589         }
590         else
591         {
592             assert(vnk == VNK_Conservative);
593             return gtVNPair.GetConservative();
594         }
595     }
596     void                SetVN(ValueNumKind vnk, ValueNum vn)
597     {
598         if (vnk == VNK_Liberal)
599         {
600             return gtVNPair.SetLiberal(vn);
601         }
602         else
603         {
604             assert(vnk == VNK_Conservative);
605             return gtVNPair.SetConservative(vn);
606         }
607     }
608     void                SetVNs(ValueNumPair vnp)
609     {
610         gtVNPair = vnp;
611     }
612     void                ClearVN()
613     {
614         gtVNPair = ValueNumPair();          // Initializes both elements to "NoVN".
615     }
616
617     //---------------------------------------------------------------------
618     //  The first set of flags can be used with a large set of nodes, and
619     //  thus they must all have distinct values. That is, one can test any
620     //  expression node for one of these flags.
621     //---------------------------------------------------------------------
622
623     #define GTF_ASG             0x00000001  // sub-expression contains an assignment
624     #define GTF_CALL            0x00000002  // sub-expression contains a  func. call
625     #define GTF_EXCEPT          0x00000004  // sub-expression might throw an exception
626     #define GTF_GLOB_REF        0x00000008  // sub-expression uses global variable(s)
627     #define GTF_ORDER_SIDEEFF   0x00000010  // sub-expression has a re-ordering side effect
628
629     // If you set these flags, make sure that code:gtExtractSideEffList knows how to find the tree,
630     // otherwise the C# (run csc /o-)
631     // var v = side_eff_operation
632     // with no use of v will drop your tree on the floor.
633     #define GTF_PERSISTENT_SIDE_EFFECTS (GTF_ASG|GTF_CALL)
634     #define GTF_SIDE_EFFECT     (GTF_PERSISTENT_SIDE_EFFECTS|GTF_EXCEPT)
635     #define GTF_GLOB_EFFECT     (GTF_SIDE_EFFECT|GTF_GLOB_REF)
636     #define GTF_ALL_EFFECT      (GTF_GLOB_EFFECT|GTF_ORDER_SIDEEFF)
637
638     // The extra flag GTF_IS_IN_CSE is used to tell the consumer of these flags
639     // that we are calling in the context of performing a CSE, thus we
640     // should allow the run-once side effects of running a class constructor.
641     //
642     // The only requirement of this flag is that it not overlap any of the
643     // side-effect flags. The actual bit used is otherwise arbitrary.
644     #define GTF_IS_IN_CSE  GTF_MAKE_CSE
645     #define GTF_PERSISTENT_SIDE_EFFECTS_IN_CSE (GTF_ASG|GTF_CALL|GTF_IS_IN_CSE)
646
647     // Can any side-effects be observed externally, say by a caller method?
648     // For assignments, only assignments to global memory can be observed
649     // externally, whereas simple assignments to local variables can not.
650     //
651     // Be careful when using this inside a "try" protected region as the
652     // order of assignments to local variables would need to be preserved
653     // wrt side effects if the variables are alive on entry to the
654     // "catch/finally" region. In such cases, even assignments to locals 
655     // will have to be restricted.
656     #define GTF_GLOBALLY_VISIBLE_SIDE_EFFECTS(flags)                    \
657         (((flags) & (GTF_CALL|GTF_EXCEPT))                   ||         \
658          (((flags) & (GTF_ASG|GTF_GLOB_REF)) == (GTF_ASG|GTF_GLOB_REF)))
659     
660     #define GTF_REVERSE_OPS     0x00000020  // operand op2 should be evaluated before op1 (normally, op1 is evaluated first and op2 is evaluated second)
661     #define GTF_REG_VAL         0x00000040  // operand is sitting in a register (or part of a TYP_LONG operand is sitting in a register)
662
663     #define GTF_SPILLED         0x00000080  // the value   has been spilled
664     #define GTF_SPILLED_OPER    0x00000100  //   op1 has been spilled
665
666 #ifdef LEGACY_BACKEND
667     #define GTF_SPILLED_OP2     0x00000200  //   op2 has been spilled
668 #endif // LEGACY_BACKEND
669
670     #define GTF_REDINDEX_CHECK  0x00000100  // Used for redundant range checks. Disjoint from GTF_SPILLED_OPER
671
672     #define GTF_ZSF_SET         0x00000400  // the zero(ZF) and sign(SF) flags set to the operand
673 #if FEATURE_SET_FLAGS
674     #define GTF_SET_FLAGS       0x00000800  // Requires that codegen for this node set the flags
675                                             // Use gtSetFlags() to check this flags
676 #endif
677     #define GTF_IND_NONFAULTING 0x00000800  // An indir that cannot fault.  GTF_SET_FLAGS is not used on indirs
678
679     #define GTF_MAKE_CSE        0x00002000  // Hoisted Expression: try hard to make this into CSE  (see optPerformHoistExpr)
680     #define GTF_DONT_CSE        0x00004000  // don't bother CSE'ing this expr
681     #define GTF_COLON_COND      0x00008000  // this node is conditionally executed (part of ? :)
682
683     #define GTF_NODE_MASK       (GTF_COLON_COND)
684
685     #define GTF_BOOLEAN         0x00040000  // value is known to be 0/1
686
687     #define GTF_SMALL_OK        0x00080000  // actual small int sufficient
688
689     #define GTF_UNSIGNED        0x00100000  // with GT_CAST:   the source operand is an unsigned type
690                                             // with operators: the specified node is an unsigned operator
691
692     #define GTF_LATE_ARG        0x00200000  // the specified node is evaluated to a temp in the arg list, and this temp is added to gtCallLateArgs.
693
694     #define GTF_SPILL           0x00400000  // needs to be spilled here
695     #define GTF_SPILL_HIGH      0x00040000  // shared with GTF_BOOLEAN
696
697     #define GTF_COMMON_MASK     0x007FFFFF  // mask of all the flags above
698
699     #define GTF_REUSE_REG_VAL   0x00800000  // This is set by the register allocator on nodes whose value already exists in the
700                                             // register assigned to this node, so the code generator does not have to generate
701                                             // code to produce the value.
702                                             // It is currently used only on constant nodes.
703                                             // It CANNOT be set on var (GT_LCL*) nodes, or on indir (GT_IND or GT_STOREIND) nodes, since
704                                             // it is not needed for lclVars and is highly unlikely to be useful for indir nodes
705
706     //---------------------------------------------------------------------
707     //  The following flags can be used only with a small set of nodes, and
708     //  thus their values need not be distinct (other than within the set
709     //  that goes with a particular node/nodes, of course). That is, one can
710     //  only test for one of these flags if the 'gtOper' value is tested as
711     //  well to make sure it's the right operator for the particular flag.
712     //---------------------------------------------------------------------
713
714     // NB: GTF_VAR_* and GTF_REG_* share the same namespace of flags, because
715     // GT_LCL_VAR nodes may be changed to GT_REG_VAR nodes without resetting
716     // the flags. These are also used by GT_LCL_FLD.
717     #define GTF_VAR_DEF         0x80000000  // GT_LCL_VAR -- this is a definition
718     #define GTF_VAR_USEASG      0x40000000  // GT_LCL_VAR -- this is a use/def for a x<op>=y
719     #define GTF_VAR_USEDEF      0x20000000  // GT_LCL_VAR -- this is a use/def as in x=x+y (only the lhs x is tagged)
720     #define GTF_VAR_CAST        0x10000000  // GT_LCL_VAR -- has been explictly cast (variable node may not be type of local)
721     #define GTF_VAR_ITERATOR    0x08000000  // GT_LCL_VAR -- this is a iterator reference in the loop condition
722     #define GTF_VAR_CLONED      0x01000000  // GT_LCL_VAR -- this node has been cloned or is a clone
723                                             // Relevant for inlining optimizations (see fgInlinePrependStatements)
724
725     // TODO-Cleanup: Currently, GTF_REG_BIRTH is used only by stackfp
726     //         We should consider using it more generally for VAR_BIRTH, instead of
727     //         GTF_VAR_DEF && !GTF_VAR_USEASG
728     #define GTF_REG_BIRTH       0x04000000  // GT_REG_VAR -- enregistered variable born here
729     #define GTF_VAR_DEATH       0x02000000  // GT_LCL_VAR, GT_REG_VAR -- variable dies here (last use)
730
731     #define GTF_VAR_ARR_INDEX   0x00000020  // The variable is part of (the index portion of) an array index expression.
732                                             // Shares a value with GTF_REVERSE_OPS, which is meaningless for local var.
733
734     #define GTF_LIVENESS_MASK   (GTF_VAR_DEF|GTF_VAR_USEASG|GTF_VAR_USEDEF|GTF_REG_BIRTH|GTF_VAR_DEATH)
735
736     #define GTF_CALL_UNMANAGED  0x80000000  // GT_CALL    -- direct call to unmanaged code
737     #define GTF_CALL_INLINE_CANDIDATE 0x40000000 // GT_CALL -- this call has been marked as an inline candidate
738 //  
739     #define GTF_CALL_VIRT_KIND_MASK  0x30000000 
740     #define GTF_CALL_NONVIRT         0x00000000  // GT_CALL    -- a non virtual call
741     #define GTF_CALL_VIRT_STUB       0x10000000  // GT_CALL    -- a stub-dispatch virtual call
742     #define GTF_CALL_VIRT_VTABLE     0x20000000  // GT_CALL    -- a  vtable-based virtual call
743
744     #define GTF_CALL_NULLCHECK  0x08000000  // GT_CALL    -- must check instance pointer for null
745     #define GTF_CALL_POP_ARGS   0x04000000  // GT_CALL    -- caller pop arguments?
746     #define GTF_CALL_HOISTABLE  0x02000000  // GT_CALL    -- call is hoistable
747     #define GTF_CALL_REG_SAVE   0x01000000  // GT_CALL    -- This call preserves all integer regs
748                                             // For additional flags for GT_CALL node see GTF_CALL_M_
749
750     #define GTF_NOP_DEATH         0x40000000  // GT_NOP     -- operand dies here
751
752     #define GTF_FLD_NULLCHECK     0x80000000  // GT_FIELD -- need to nullcheck the "this" pointer
753     #define GTF_FLD_VOLATILE      0x40000000  // GT_FIELD/GT_CLS_VAR -- same as GTF_IND_VOLATILE
754
755     #define GTF_INX_RNGCHK        0x80000000  // GT_INDEX -- the array reference should be range-checked.
756     #define GTF_INX_REFARR_LAYOUT 0x20000000  // GT_INDEX -- same as GTF_IND_REFARR_LAYOUT
757     #define GTF_INX_STRING_LAYOUT 0x40000000  // GT_INDEX -- this uses the special string array layout
758
759     #define GTF_IND_VOLATILE      0x40000000  // GT_IND   -- the load or store must use volatile sematics (this is a nop on X86)
760     #define GTF_IND_REFARR_LAYOUT 0x20000000  // GT_IND   -- the array holds object refs (only effects layout of Arrays)
761     #define GTF_IND_TGTANYWHERE   0x10000000  // GT_IND   -- the target could be anywhere
762     #define GTF_IND_TLS_REF       0x08000000  // GT_IND   -- the target is accessed via TLS
763     #define GTF_IND_ASG_LHS       0x04000000  // GT_IND   -- this GT_IND node is (the effective val) of the LHS of an assignment; don't evaluate it independently.
764     #define GTF_IND_UNALIGNED     0x02000000  // GT_IND   -- the load or store is unaligned (we assume worst case alignment of 1 byte) 
765     #define GTF_IND_INVARIANT     0x01000000  // GT_IND   -- the target is invariant (a prejit indirection)
766     #define GTF_IND_ARR_LEN       0x80000000  // GT_IND   -- the indirection represents an array length (of the REF contribution to its argument).
767     #define GTF_IND_ARR_INDEX     0x00800000  // GT_IND   -- the indirection represents an (SZ) array index
768
769     #define GTF_IND_FLAGS         (GTF_IND_VOLATILE|GTF_IND_REFARR_LAYOUT|GTF_IND_TGTANYWHERE|GTF_IND_NONFAULTING|\
770                                    GTF_IND_TLS_REF|GTF_IND_UNALIGNED|GTF_IND_INVARIANT|GTF_IND_ARR_INDEX)
771
772     #define GTF_CLS_VAR_ASG_LHS   0x04000000  // GT_CLS_VAR   -- this GT_CLS_VAR node is (the effective val) of the LHS of an assignment; don't evaluate it independently.
773
774     #define GTF_ADDR_ONSTACK      0x80000000  // GT_ADDR    -- this expression is guaranteed to be on the stack
775
776
777     #define GTF_ADDRMODE_NO_CSE 0x80000000  // GT_ADD/GT_MUL/GT_LSH -- Do not CSE this node only, forms complex addressing mode
778
779     #define GTF_MUL_64RSLT      0x40000000  // GT_MUL     -- produce 64-bit result
780
781     #define GTF_MOD_INT_RESULT  0x80000000  // GT_MOD,    -- the real tree represented by this
782                                             // GT_UMOD       node evaluates to an int even though
783                                             //               its type is long.  The result is
784                                             //               placed in the low member of the
785                                             //               reg pair
786
787     #define GTF_RELOP_NAN_UN    0x80000000  // GT_<relop> -- Is branch taken if ops are NaN?
788     #define GTF_RELOP_JMP_USED  0x40000000  // GT_<relop> -- result of compare used for jump or ?:
789     #define GTF_RELOP_QMARK     0x20000000  // GT_<relop> -- the node is the condition for ?:
790     #define GTF_RELOP_SMALL     0x10000000  // GT_<relop> -- We should use a byte or short sized compare (op1->gtType is the small type)
791     #define GTF_RELOP_ZTT       0x08000000  // GT_<relop> -- Loop test cloned for converting while-loops into do-while with explicit "loop test" in the header block.
792
793     #define GTF_QMARK_CAST_INSTOF 0x80000000  // GT_QMARK   -- Is this a top (not nested) level qmark created for castclass or instanceof?
794
795     #define GTF_BOX_VALUE 0x80000000  // GT_BOX   -- "box" is on a value type
796
797     #define GTF_ICON_HDL_MASK   0xF0000000  // Bits used by handle types below
798
799     #define GTF_ICON_SCOPE_HDL  0x10000000  // GT_CNS_INT -- constant is a scope handle
800     #define GTF_ICON_CLASS_HDL  0x20000000  // GT_CNS_INT -- constant is a class handle
801     #define GTF_ICON_METHOD_HDL 0x30000000  // GT_CNS_INT -- constant is a method handle
802     #define GTF_ICON_FIELD_HDL  0x40000000  // GT_CNS_INT -- constant is a field handle
803     #define GTF_ICON_STATIC_HDL 0x50000000  // GT_CNS_INT -- constant is a handle to static data
804     #define GTF_ICON_STR_HDL    0x60000000  // GT_CNS_INT -- constant is a string handle
805     #define GTF_ICON_PSTR_HDL   0x70000000  // GT_CNS_INT -- constant is a ptr to a string handle
806     #define GTF_ICON_PTR_HDL    0x80000000  // GT_CNS_INT -- constant is a ldptr handle
807     #define GTF_ICON_VARG_HDL   0x90000000  // GT_CNS_INT -- constant is a var arg cookie handle
808     #define GTF_ICON_PINVKI_HDL 0xA0000000  // GT_CNS_INT -- constant is a pinvoke calli handle
809     #define GTF_ICON_TOKEN_HDL  0xB0000000  // GT_CNS_INT -- constant is a token handle
810     #define GTF_ICON_TLS_HDL    0xC0000000  // GT_CNS_INT -- constant is a TLS ref with offset
811     #define GTF_ICON_FTN_ADDR   0xD0000000  // GT_CNS_INT -- constant is a function address
812     #define GTF_ICON_CIDMID_HDL 0xE0000000  // GT_CNS_INT -- constant is a class or module ID handle
813     #define GTF_ICON_BBC_PTR    0xF0000000  // GT_CNS_INT -- constant is a basic block count pointer
814
815     #define GTF_ICON_FIELD_OFF  0x08000000  // GT_CNS_INT -- constant is a field offset
816
817     #define GTF_BLK_HASGCPTR    0x80000000  // GT_COPYBLK -- This struct copy will copy GC Pointers
818     #define GTF_BLK_VOLATILE    0x40000000  // GT_INITBLK/GT_COPYBLK -- is a volatile block operation
819     #define GTF_BLK_UNALIGNED   0x02000000  // GT_INITBLK/GT_COPYBLK -- is an unaligned block operation
820
821     #define GTF_OVERFLOW        0x10000000  // GT_ADD, GT_SUB, GT_MUL, - Need overflow check
822                                             // GT_ASG_ADD, GT_ASG_SUB,
823                                             // GT_CAST
824                                             // Use gtOverflow(Ex)() to check this flag
825
826     #define GTF_NO_OP_NO        0x80000000  // GT_NO_OP   --Have the codegenerator generate a special nop
827
828     //----------------------------------------------------------------
829
830     #define GTF_STMT_CMPADD     0x80000000  // GT_STMT    -- added by compiler
831     #define GTF_STMT_HAS_CSE    0x40000000  // GT_STMT    -- CSE def or use was subsituted
832     #define GTF_STMT_TOP_LEVEL  0x20000000  // GT_STMT    -- Top-level statement - true iff gtStmtList->gtPrev == nullptr
833                                             //               True for all stmts when in FGOrderTree
834     #define GTF_STMT_SKIP_LOWER 0x10000000  // GT_STMT    -- Skip lowering if we already lowered an embedded stmt.
835
836     //----------------------------------------------------------------
837
838 #if defined(DEBUG)
839     #define GTF_DEBUG_NONE            0x00000000  // No debug flags.
840
841     #define GTF_DEBUG_NODE_MORPHED    0x00000001  // the node has been morphed (in the global morphing phase)
842     #define GTF_DEBUG_NODE_SMALL      0x00000002
843     #define GTF_DEBUG_NODE_LARGE      0x00000004
844
845     #define GTF_DEBUG_NODE_MASK       0x00000007  // These flags are all node (rather than operation) properties.
846
847     #define GTF_DEBUG_VAR_CSE_REF     0x00800000  // GT_LCL_VAR -- This is a CSE LCL_VAR node
848 #endif // defined(DEBUG)
849
850     GenTreePtr          gtNext;
851     GenTreePtr          gtPrev;
852
853 #ifdef DEBUG
854     unsigned            gtTreeID;
855     unsigned            gtSeqNum;       // liveness traversal order within the current statement
856 #endif
857
858     static
859     const unsigned short   gtOperKindTable[];
860
861     static
862     unsigned        OperKind(unsigned gtOper)
863     {
864         assert(gtOper < GT_COUNT);
865
866         return  gtOperKindTable[gtOper];
867     }
868
869     unsigned        OperKind() const
870     {
871         assert(gtOper < GT_COUNT);
872
873         return  gtOperKindTable[gtOper];
874     }
875
876     static bool     IsExOp(unsigned opKind)
877     {
878         return (opKind & GTK_EXOP) != 0;
879     }
880     // Returns the operKind with the GTK_EX_OP bit removed (the
881     // kind of operator, unary or binary, that is extended).
882     static unsigned StripExOp(unsigned opKind)
883     {
884         return opKind & ~GTK_EXOP;
885     }
886
887     static
888     bool            OperIsConst(genTreeOps gtOper)
889     {
890         return  (OperKind(gtOper) & GTK_CONST  ) != 0;
891     }
892
893     bool            OperIsConst() const
894     {
895         return  (OperKind(gtOper) & GTK_CONST  ) != 0;
896     }
897
898     static
899     bool            OperIsLeaf(genTreeOps gtOper)
900     {
901         return  (OperKind(gtOper) & GTK_LEAF   ) != 0;
902     }
903
904     bool            OperIsLeaf() const
905     {
906         return  (OperKind(gtOper) & GTK_LEAF   ) != 0;
907     }
908
909     static
910     bool            OperIsCompare(genTreeOps gtOper)
911     {
912         return  (OperKind(gtOper) & GTK_RELOP  ) != 0;
913     }
914
915     static
916     bool            OperIsLocal(genTreeOps gtOper)
917     {
918         bool result = (OperKind(gtOper) & GTK_LOCAL) != 0;
919         assert(result ==
920                (gtOper == GT_LCL_VAR ||
921                 gtOper == GT_PHI_ARG ||
922                 gtOper == GT_REG_VAR ||
923                 gtOper == GT_LCL_FLD ||
924                 gtOper == GT_STORE_LCL_VAR ||
925                 gtOper == GT_STORE_LCL_FLD));
926         return result;
927     }
928
929     static
930     bool            OperIsBlkOp(genTreeOps gtOper)
931     {
932         return (gtOper == GT_INITBLK ||
933                 gtOper == GT_COPYBLK ||
934                 gtOper == GT_COPYOBJ);
935     }
936
937     static
938     bool            OperIsCopyBlkOp(genTreeOps gtOper)
939     {
940         return (gtOper == GT_COPYOBJ || gtOper == GT_COPYBLK);
941     }
942
943
944     static
945     bool            OperIsLocalAddr(genTreeOps gtOper)
946     {
947         return (gtOper == GT_LCL_VAR_ADDR ||
948                 gtOper == GT_LCL_FLD_ADDR);
949     }
950
951     static
952     bool           OperIsScalarLocal(genTreeOps gtOper)
953     {
954         return (gtOper == GT_LCL_VAR ||
955                 gtOper == GT_REG_VAR ||
956                 gtOper == GT_STORE_LCL_VAR);
957     }
958
959     static
960     bool            OperIsNonPhiLocal(genTreeOps gtOper)
961     {
962         return OperIsLocal(gtOper) && (gtOper != GT_PHI_ARG);
963     }
964
965     static
966     bool            OperIsLocalRead(genTreeOps gtOper)
967     {
968         return (OperIsLocal(gtOper) && !OperIsLocalStore(gtOper));
969     }
970
971     static
972     bool            OperIsLocalStore(genTreeOps gtOper)
973     {
974         return (gtOper == GT_STORE_LCL_VAR ||
975                 gtOper == GT_STORE_LCL_FLD);
976
977     }
978
979     static
980     bool            OperIsAddrMode(genTreeOps gtOper)
981     {
982         return (gtOper == GT_LEA);
983     }
984
985     bool            OperIsBlkOp() const
986     {
987         return OperIsBlkOp(OperGet());
988     }
989
990     bool            OperIsCopyBlkOp() const
991     {
992         return OperIsCopyBlkOp(OperGet());
993     }
994
995     bool            OperIsPutArgStk() const
996     {
997         return gtOper == GT_PUTARG_STK;
998     }
999
1000     bool            OperIsAddrMode() const
1001     {
1002         return OperIsAddrMode(OperGet());
1003     }
1004
1005     bool            OperIsLocal() const
1006     {
1007         return OperIsLocal(OperGet());
1008     }
1009
1010     bool            OperIsLocalAddr() const
1011     {
1012         return OperIsLocalAddr(OperGet());
1013     }
1014
1015     bool            OperIsScalarLocal() const
1016     {
1017         return OperIsScalarLocal(OperGet());
1018     }
1019
1020     bool            OperIsNonPhiLocal() const
1021     {
1022         return OperIsNonPhiLocal(OperGet());
1023     }
1024
1025     bool            OperIsLocalStore() const
1026     {
1027         return OperIsLocalStore(OperGet());
1028     }
1029
1030     bool            OperIsLocalRead() const
1031     {
1032         return OperIsLocalRead(OperGet());
1033     }
1034
1035     bool            OperIsCompare()
1036     {
1037         return  (OperKind(gtOper) & GTK_RELOP  ) != 0;
1038     }
1039
1040     static
1041     bool            OperIsLogical(genTreeOps gtOper)
1042     {
1043         return  (OperKind(gtOper) & GTK_LOGOP  ) != 0;
1044     }
1045
1046     bool            OperIsLogical() const
1047     {
1048         return  (OperKind(gtOper) & GTK_LOGOP  ) != 0;
1049     }
1050
1051     static
1052     bool            OperIsShift(genTreeOps gtOper)
1053     {
1054         return (gtOper == GT_LSH) ||
1055                (gtOper == GT_RSH) ||
1056                (gtOper == GT_RSZ);
1057     }
1058
1059     bool            OperIsShift() const
1060     {
1061         return OperIsShift(OperGet());
1062     }
1063
1064     static
1065     bool            OperIsRotate(genTreeOps gtOper)
1066     {
1067         return (gtOper == GT_ROL) ||
1068                (gtOper == GT_ROR);
1069     }
1070
1071     bool            OperIsRotate() const
1072     {
1073         return OperIsRotate(OperGet());
1074     }
1075
1076     static
1077     bool            OperIsShiftOrRotate(genTreeOps gtOper)
1078     {
1079         return OperIsShift(gtOper) ||
1080                OperIsRotate(gtOper);
1081     }
1082
1083     bool            OperIsShiftOrRotate() const
1084     {
1085         return OperIsShiftOrRotate(OperGet());
1086     }
1087
1088     bool            OperIsArithmetic() const
1089     {
1090         genTreeOps op = OperGet();
1091         return     op==GT_ADD
1092                 || op==GT_SUB
1093                 || op==GT_MUL
1094                 || op==GT_DIV
1095                 || op==GT_MOD
1096
1097                 || op==GT_UDIV
1098                 || op==GT_UMOD
1099
1100                 || op==GT_OR
1101                 || op==GT_XOR
1102                 || op==GT_AND
1103
1104                 || OperIsShiftOrRotate(op);
1105     }
1106
1107 #if !defined(LEGACY_BACKEND) && !defined(_TARGET_64BIT_)
1108     static
1109     bool            OperIsHigh(genTreeOps gtOper)
1110     {
1111         switch (gtOper)
1112         {
1113         case GT_ADD_HI:
1114         case GT_SUB_HI:
1115         case GT_MUL_HI:
1116         case GT_DIV_HI:
1117         case GT_MOD_HI:
1118             return true;
1119         default:
1120             return false;
1121         }
1122     }
1123
1124     bool            OperIsHigh() const
1125     {
1126         return OperIsHigh(OperGet());
1127     }
1128 #endif // !defined(LEGACY_BACKEND) && !defined(_TARGET_64BIT_)
1129
1130     static
1131     bool            OperIsUnary(genTreeOps gtOper)
1132     {
1133         return  (OperKind(gtOper) & GTK_UNOP   ) != 0;
1134     }
1135
1136     bool            OperIsUnary() const
1137     {
1138         return   OperIsUnary(gtOper);
1139     }
1140
1141     static
1142     bool            OperIsBinary(genTreeOps gtOper)
1143     {
1144         return  (OperKind(gtOper) & GTK_BINOP  ) != 0;
1145     }
1146
1147     bool            OperIsBinary() const
1148     {
1149         return   OperIsBinary(gtOper);
1150     }
1151
1152     static
1153     bool            OperIsSimple(genTreeOps gtOper)
1154     {
1155         return (OperKind(gtOper) & GTK_SMPOP  ) != 0;
1156     }
1157
1158     static
1159     bool            OperIsSpecial(genTreeOps gtOper)
1160     {        
1161         return  ((OperKind(gtOper) & GTK_KINDMASK) == GTK_SPECIAL);
1162     }
1163
1164     bool            OperIsSimple() const
1165     {
1166         return  OperIsSimple(gtOper);
1167     }
1168
1169 #ifdef FEATURE_SIMD
1170     bool             isCommutativeSIMDIntrinsic();
1171 #else // !
1172     bool             isCommutativeSIMDIntrinsic()
1173     {
1174         return false;
1175     }
1176 #endif // FEATURE_SIMD
1177
1178     static
1179     bool            OperIsCommutative(genTreeOps gtOper)
1180     {
1181         return  (OperKind(gtOper) & GTK_COMMUTE) != 0;
1182     }
1183
1184     bool            OperIsCommutative()
1185     {
1186         return OperIsCommutative(gtOper) || (OperIsSIMD(gtOper) && isCommutativeSIMDIntrinsic());
1187     }
1188
1189     static
1190     bool            OperIsAssignment(genTreeOps gtOper)
1191     {
1192         return  (OperKind(gtOper) & GTK_ASGOP) != 0;
1193     }
1194
1195     bool            OperIsAssignment() const
1196     {
1197         return  OperIsAssignment(gtOper);
1198     }
1199
1200     static
1201     bool            OperIsIndir(genTreeOps gtOper)
1202     {
1203         return  gtOper == GT_IND || gtOper == GT_STOREIND || gtOper == GT_NULLCHECK;
1204     }
1205
1206     bool            OperIsIndir() const
1207     {
1208         return  OperIsIndir(gtOper);
1209     }
1210
1211     static 
1212     bool            OperIsImplicitIndir(genTreeOps gtOper)
1213     {
1214         switch (gtOper)
1215         {
1216         case GT_LOCKADD:
1217         case GT_XADD:
1218         case GT_CMPXCHG:
1219         case GT_COPYBLK:
1220         case GT_COPYOBJ:
1221         case GT_INITBLK:
1222         case GT_OBJ:
1223         case GT_BOX:
1224         case GT_ARR_INDEX:
1225         case GT_ARR_ELEM:
1226         case GT_ARR_OFFSET:
1227             return true;
1228         default:
1229             return false;
1230         }
1231     }
1232
1233     bool            OperIsImplicitIndir() const
1234     {
1235         return  OperIsImplicitIndir(gtOper);
1236     }
1237
1238     bool            OperIsStore() const
1239     {
1240         return OperIsStore(gtOper);
1241     }
1242
1243     static
1244     bool            OperIsStore(genTreeOps gtOper)
1245     {
1246         return (gtOper == GT_STOREIND
1247                 || gtOper == GT_STORE_LCL_VAR
1248                 || gtOper == GT_STORE_LCL_FLD
1249                 || gtOper == GT_STORE_CLS_VAR);
1250     }
1251
1252     static
1253     bool            OperIsAtomicOp(genTreeOps gtOper)
1254     {
1255         return  (gtOper == GT_XADD 
1256                  || gtOper == GT_XCHG  
1257                  || gtOper == GT_LOCKADD 
1258                  || gtOper == GT_CMPXCHG);
1259     }
1260
1261     bool            OperIsAtomicOp()
1262     {
1263         return  OperIsAtomicOp(gtOper);
1264     }
1265
1266     // This is basically here for cleaner FEATURE_SIMD #ifdefs.
1267     static
1268     bool            OperIsSIMD(genTreeOps gtOper)
1269     {
1270 #ifdef FEATURE_SIMD
1271         return gtOper == GT_SIMD;
1272 #else // !FEATURE_SIMD
1273         return false;
1274 #endif // !FEATURE_SIMD
1275     }
1276
1277     bool            OperIsSIMD()
1278     {
1279         return OperIsSIMD(gtOper);
1280     }
1281
1282     // Requires that "op" is an op= operator.  Returns
1283     // the corresponding "op".
1284     static
1285     genTreeOps      OpAsgToOper(genTreeOps op);
1286
1287 #ifdef DEBUG
1288     bool            NullOp1Legal() const
1289     {
1290         assert(OperIsSimple(gtOper));
1291         switch (gtOper)
1292         {
1293         case GT_PHI: case GT_LEA: case GT_RETFILT: case GT_NOP:
1294             return true;
1295         case GT_RETURN:
1296             return gtType == TYP_VOID;
1297         default:
1298             return false;
1299         }
1300     }
1301
1302     bool            NullOp2Legal() const
1303     {
1304         assert(OperIsSimple(gtOper));
1305         if (!OperIsBinary(gtOper))
1306         {
1307             return true;
1308         }
1309         switch (gtOper)
1310         {
1311         case GT_LIST:
1312         case GT_INTRINSIC:
1313         case GT_LEA:
1314         case GT_STOREIND:
1315         case GT_INITBLK:
1316         case GT_COPYBLK:
1317         case GT_COPYOBJ:
1318 #ifdef FEATURE_SIMD
1319         case GT_SIMD:
1320 #endif // !FEATURE_SIMD
1321             return true;
1322         default:
1323             return false;
1324         }
1325     }
1326
1327     static
1328     inline bool RequiresNonNullOp2(genTreeOps oper);
1329     bool IsListForMultiRegArg();
1330 #endif // DEBUG
1331
1332     inline bool IsFPZero();
1333     inline bool IsIntegralConst(ssize_t constVal);
1334
1335     inline bool IsBoxedValue();
1336
1337     bool IsList() const
1338     {
1339         return gtOper == GT_LIST;
1340     }
1341
1342     inline GenTreePtr MoveNext();
1343
1344     inline GenTreePtr Current();
1345
1346     inline GenTreePtr *pCurrent();
1347
1348     inline GenTreePtr gtGetOp1();
1349
1350     inline GenTreePtr gtGetOp2();
1351
1352     // Given a tree node, if this is a child of that node, return the pointer to the child node so that it
1353     // can be modified; otherwise, return null.
1354     GenTreePtr*       gtGetChildPointer(GenTreePtr parent);
1355
1356     // Get the parent of this node, and optionally capture the pointer to the child so that it can be modified.
1357     GenTreePtr        gtGetParent(GenTreePtr** parentChildPtrPtr);
1358
1359     inline GenTreePtr gtEffectiveVal(bool commaOnly = false);
1360
1361     // Return the child of this node if it is a GT_RELOAD or GT_COPY; otherwise simply return the node itself
1362     inline GenTree*   gtSkipReloadOrCopy();
1363
1364     // Returns true if it is a call node returning its value in more than one register
1365     inline bool     IsMultiRegCall() const;
1366
1367     // Returns true if it is a GT_COPY or GT_RELOAD node
1368     inline bool     IsCopyOrReload() const;
1369
1370     // Returns true if it is a GT_COPY or GT_RELOAD of a multi-reg call node
1371     inline bool     IsCopyOrReloadOfMultiRegCall() const;
1372
1373     bool            OperMayThrow();
1374
1375     unsigned        GetScaleIndexMul();
1376     unsigned        GetScaleIndexShf();
1377     unsigned        GetScaledIndex();
1378
1379     // Returns true if "addr" is a GT_ADD node, at least one of whose arguments is an integer
1380     // (<= 32 bit) constant.  If it returns true, it sets "*offset" to (one of the) constant value(s), and
1381     // "*addr" to the other argument.
1382     bool            IsAddWithI32Const(GenTreePtr* addr, int* offset);
1383
1384     // Insert 'node' after this node in execution order.
1385     void            InsertAfterSelf(GenTree* node, GenTreeStmt* stmt = nullptr);
1386
1387 public:
1388
1389 #if SMALL_TREE_NODES
1390     static
1391     unsigned char   s_gtNodeSizes[];
1392 #endif
1393
1394     static
1395     void            InitNodeSize();
1396
1397     size_t          GetNodeSize() const;
1398
1399     bool            IsNodeProperlySized() const;
1400
1401     void            CopyFrom(const GenTree* src, Compiler* comp);
1402
1403     static
1404     genTreeOps      ReverseRelop(genTreeOps relop);
1405
1406     static
1407     genTreeOps      SwapRelop(genTreeOps relop);
1408
1409     //---------------------------------------------------------------------
1410
1411     static
1412     bool            Compare(GenTreePtr op1, GenTreePtr op2, bool swapOK = false);
1413
1414     //---------------------------------------------------------------------
1415     #ifdef DEBUG
1416     //---------------------------------------------------------------------
1417
1418     static
1419     const   char *  NodeName(genTreeOps op);
1420
1421     static
1422     const   char *  OpName(genTreeOps op);
1423
1424     //---------------------------------------------------------------------
1425     #endif
1426     //---------------------------------------------------------------------
1427
1428     bool                        IsNothingNode       () const;
1429     void                        gtBashToNOP         ();
1430
1431     // Value number update action enumeration
1432     enum ValueNumberUpdate
1433     {
1434         CLEAR_VN,       // Clear value number
1435         PRESERVE_VN     // Preserve value number
1436     };
1437
1438     void                        SetOper(genTreeOps oper, ValueNumberUpdate vnUpdate = CLEAR_VN);  // set gtOper
1439     void                        SetOperResetFlags   (genTreeOps oper);  // set gtOper and reset flags
1440
1441     void                        ChangeOperConst     (genTreeOps oper);  // ChangeOper(constOper)
1442     // set gtOper and only keep GTF_COMMON_MASK flags
1443     void                        ChangeOper(genTreeOps oper, ValueNumberUpdate vnUpdate = CLEAR_VN);
1444     void                        ChangeOperUnchecked (genTreeOps oper);
1445
1446     bool IsLocal() const
1447     {
1448         return OperIsLocal(OperGet());
1449     }
1450
1451     // Returns "true" iff 'this' is a GT_LCL_FLD or GT_STORE_LCL_FLD on which the type
1452     // is not the same size as the type of the GT_LCL_VAR.
1453     bool IsPartialLclFld(Compiler* comp);
1454
1455     // Returns "true" iff "this" defines a local variable.  Requires "comp" to be the 
1456     // current compilation.  If returns "true", sets "*pLclVarTree" to the
1457     // tree for the local that is defined, and, if "pIsEntire" is non-null, sets "*pIsEntire" to
1458     // true or false, depending on whether the assignment writes to the entirety of the local
1459     // variable, or just a portion of it.
1460     bool DefinesLocal(Compiler* comp, GenTreeLclVarCommon** pLclVarTree, bool* pIsEntire = nullptr);
1461
1462     // Returns true if "this" represents the address of a local, or a field of a local.  If returns true, sets
1463     // "*pLclVarTree" to the node indicating the local variable.  If the address is that of a field of this node,
1464     // sets "*pFldSeq" to the field sequence representing that field, else null.
1465     bool IsLocalAddrExpr(Compiler* comp, GenTreeLclVarCommon** pLclVarTree, FieldSeqNode** pFldSeq);
1466
1467     // Simpler variant of the above which just returns the local node if this is an expression that 
1468     // yields an address into a local
1469     GenTreeLclVarCommon* IsLocalAddrExpr();
1470
1471     // Determine whether this is an assignment tree of the form X = X (op) Y,
1472     // where Y is an arbitrary tree, and X is a lclVar.
1473     unsigned             IsLclVarUpdateTree(GenTree** otherTree, genTreeOps *updateOper);
1474
1475     // If returns "true", "this" may represent the address of a static or instance field
1476     // (or a field of such a field, in the case of an object field of type struct).  
1477     // If returns "true", then either "*pObj" is set to the object reference, 
1478     // or "*pStatic" is set to the baseAddr or offset to be added to the "*pFldSeq" 
1479     // Only one of "*pObj" or "*pStatic" will be set, the other one will be null.
1480     // The boolean return value only indicates that "this" *may* be a field address 
1481     // -- the field sequence must also be checked.  
1482     // If it is a field address, the field sequence will be a sequence of length >= 1, 
1483     // starting with an instance or static field, and optionally continuing with struct fields.
1484     bool IsFieldAddr(Compiler* comp, GenTreePtr* pObj, GenTreePtr* pStatic, FieldSeqNode** pFldSeq);
1485
1486     // Requires "this" to be the address of an array (the child of a GT_IND labeled with GTF_IND_ARR_INDEX).
1487     // Sets "pArr" to the node representing the array (either an array object pointer, or perhaps a byref to the some element).
1488     // Sets "*pArrayType" to the class handle for the array type.
1489     // Sets "*inxVN" to the value number inferred for the array index.
1490     // Sets "*pFldSeq" to the sequence, if any, of struct fields used to index into the array element.
1491     void ParseArrayAddress(Compiler* comp, 
1492                            struct ArrayInfo* arrayInfo, 
1493                            GenTreePtr* pArr, 
1494                            ValueNum* pInxVN,
1495                            FieldSeqNode** pFldSeq);
1496
1497     // Helper method for the above.
1498     void ParseArrayAddressWork(Compiler* comp, ssize_t inputMul, GenTreePtr* pArr, ValueNum* pInxVN, ssize_t* pOffset, FieldSeqNode** pFldSeq);
1499
1500     // Requires "this" to be a GT_IND.  Requires the outermost caller to set "*pFldSeq" to nullptr.
1501     // Returns true if it is an array index expression, or access to a (sequence of) struct field(s)
1502     // within a struct array element.  If it returns true, sets *arrayInfo to the array information, and sets *pFldSeq to the sequence
1503     // of struct field accesses.
1504     bool ParseArrayElemForm(Compiler* comp, ArrayInfo* arrayInfo, FieldSeqNode** pFldSeq);
1505
1506     // Requires "this" to be the address of a (possible) array element (or struct field within that).
1507     // If it is, sets "*arrayInfo" to the array access info, "*pFldSeq" to the sequence of struct fields
1508     // accessed within the array element, and returns true.  If not, returns "false".
1509     bool ParseArrayElemAddrForm(Compiler* comp, ArrayInfo* arrayInfo, FieldSeqNode** pFldSeq);
1510
1511     // Requires "this" to be an int expression.  If it is a sequence of one or more integer constants added together,
1512     // returns true and sets "*pFldSeq" to the sequence of fields with which those constants are annotated.
1513     bool ParseOffsetForm(Compiler* comp, FieldSeqNode** pFldSeq);
1514
1515     // Labels "*this" as an array index expression: label all constants and variables that could contribute, as part of an affine expression, to the value of the
1516     // of the index.
1517     void LabelIndex(Compiler* comp, bool isConst = true);
1518
1519     // Assumes that "this" occurs in a context where it is being dereferenced as the LHS of an assignment-like
1520     // statement (assignment, initblk, or copyblk).  The "width" should be the number of bytes copied by the
1521     // operation.  Returns "true" if "this" is an address of (or within)
1522     // a local variable; sets "*pLclVarTree" to that local variable instance; and, if "pIsEntire" is non-null,
1523     // sets "*pIsEntire" to true if this assignment writes the full width of the local.
1524     bool DefinesLocalAddr(Compiler* comp, unsigned width, GenTreeLclVarCommon** pLclVarTree, bool* pIsEntire);
1525
1526     bool                        IsRegVar            () const
1527     {
1528         return OperGet() == GT_REG_VAR?true:false;
1529     }
1530     bool                        InReg() const
1531     {
1532         return (gtFlags & GTF_REG_VAL)?true:false;       
1533     }
1534     void                        SetInReg()
1535     {
1536         gtFlags |= GTF_REG_VAL;
1537     }
1538
1539     regNumber                   GetReg() const
1540     {
1541         return InReg() ? gtRegNum : REG_NA;
1542     }
1543     bool                        IsRegVarDeath       () const
1544     {
1545         assert(OperGet() == GT_REG_VAR);
1546         return (gtFlags & GTF_VAR_DEATH)?true:false;       
1547     }
1548     bool                        IsRegVarBirth       () const
1549     {
1550         assert(OperGet() == GT_REG_VAR);
1551         return (gtFlags & GTF_REG_BIRTH)?true:false;       
1552     }
1553     bool                        IsReverseOp() const
1554     {
1555         return (gtFlags & GTF_REVERSE_OPS)?true:false;
1556     }
1557
1558     inline bool                 IsCnsIntOrI         () const;
1559
1560     inline bool                 IsIntegralConst     () const;
1561
1562     inline bool                 IsIntCnsFitsInI32   ();
1563
1564     inline bool                 IsCnsFltOrDbl() const;
1565
1566     inline bool                 IsCnsNonZeroFltOrDbl();    
1567
1568     bool                        IsIconHandle        () const
1569     {
1570         assert(gtOper == GT_CNS_INT);
1571         return (gtFlags & GTF_ICON_HDL_MASK) ? true : false;
1572     }
1573
1574     bool                        IsIconHandle        (unsigned handleType) const
1575     {
1576         assert(gtOper == GT_CNS_INT);
1577         assert((handleType & GTF_ICON_HDL_MASK) != 0);      // check that handleType is one of the valid GTF_ICON_* values
1578         assert((handleType & ~GTF_ICON_HDL_MASK) == 0);
1579         return (gtFlags & GTF_ICON_HDL_MASK) == handleType;
1580     }
1581
1582     // Return just the part of the flags corresponding to the GTF_ICON_*_HDL flag. For example,
1583     // GTF_ICON_SCOPE_HDL. The tree node must be a const int, but it might not be a handle, in which
1584     // case we'll return zero.
1585     unsigned                    GetIconHandleFlag   () const
1586     {
1587         assert(gtOper == GT_CNS_INT);
1588         return (gtFlags & GTF_ICON_HDL_MASK);
1589     }
1590
1591     // Mark this node as no longer being a handle; clear its GTF_ICON_*_HDL bits.
1592     void                        ClearIconHandleMask()
1593     {
1594         assert(gtOper == GT_CNS_INT);
1595         gtFlags &= ~GTF_ICON_HDL_MASK;
1596     }
1597
1598     // Return true if the two GT_CNS_INT trees have the same handle flag (GTF_ICON_*_HDL).
1599     static bool                 SameIconHandleFlag(GenTree* t1, GenTree* t2)
1600     {
1601         return t1->GetIconHandleFlag() == t2->GetIconHandleFlag();
1602     }
1603
1604     bool                        IsArgPlaceHolderNode() const { return OperGet() == GT_ARGPLACE; }
1605     bool                        IsCall              () const { return OperGet() == GT_CALL; }
1606     bool                        IsStatement         () const { return OperGet() == GT_STMT; }
1607     inline bool                 IsHelperCall        ();
1608
1609     bool                        IsVarAddr           () const;
1610     bool                        gtOverflow          () const;
1611     bool                        gtOverflowEx        () const;
1612     bool                        gtSetFlags          () const;
1613     bool                        gtRequestSetFlags   ();
1614 #ifdef DEBUG
1615     bool                        gtIsValid64RsltMul  ();
1616     static int                  gtDispFlags         (unsigned flags, unsigned debugFlags);
1617 #endif
1618
1619     // cast operations 
1620     inline var_types            CastFromType();
1621     inline var_types&           CastToType();
1622
1623     // Returns "true" iff "*this" is an assignment (GT_ASG) tree that defines an SSA name (lcl = phi(...));
1624     bool IsPhiDefn();
1625
1626     // Returns "true" iff "*this" is a statement containing an assignment that defines an SSA name (lcl = phi(...));
1627     bool IsPhiDefnStmt();
1628
1629     // Can't use an assignment operator, because we need the extra "comp" argument
1630     // (to provide the allocator necessary for the VarSet assignment).
1631     // TODO-Cleanup: Not really needed now, w/o liveset on tree nodes
1632     void CopyTo(class Compiler* comp, const GenTree& gt);
1633
1634     // Like the above, excepts assumes copying from small node to small node.
1635     // (Following the code it replaces, it does *not* copy the GenTree fields,
1636     // which CopyTo does.)
1637     void CopyToSmall(const GenTree& gt);
1638
1639     // Because of the fact that we hid the assignment operator of "BitSet" (in DEBUG),
1640     // we can't synthesize an assignment operator.
1641     // TODO-Cleanup: Could change this w/o liveset on tree nodes
1642     // (This is also necessary for the VTable trick.)
1643     GenTree() {}
1644
1645     // Returns the number of children of the current node.
1646     unsigned NumChildren();
1647
1648     // Requires "childNum < NumChildren()".  Returns the "n"th child of "this."
1649     GenTreePtr GetChild(unsigned childNum);
1650
1651     // The maximum possible # of children of any node.
1652     static const int MAX_CHILDREN = 6;
1653
1654     bool IsReuseRegVal() const
1655     {
1656         // This can be extended to non-constant nodes, but not to local or indir nodes.
1657         if(OperIsConst() && ((gtFlags & GTF_REUSE_REG_VAL) != 0))
1658         {
1659             return true;
1660         }
1661         return false;
1662     }
1663     void SetReuseRegVal()
1664     {
1665         assert(OperIsConst());
1666         gtFlags |= GTF_REUSE_REG_VAL;
1667     }
1668     void ResetReuseRegVal()
1669     {
1670         assert(OperIsConst());
1671         gtFlags &= ~GTF_REUSE_REG_VAL;
1672     }
1673
1674 #ifdef DEBUG
1675   private:
1676     GenTree& operator=(const GenTree& gt) {
1677         assert(!"Don't copy");
1678         return *this;
1679     }
1680 #endif // DEBUG
1681
1682 #if DEBUGGABLE_GENTREE
1683     // In DEBUG builds, add a dummy virtual method, to give the debugger run-time type information.
1684     virtual void DummyVirt() {}
1685
1686     typedef void* VtablePtr;
1687
1688     VtablePtr GetVtableForOper(genTreeOps oper);
1689     void SetVtableForOper(genTreeOps oper);
1690
1691     static VtablePtr s_vtablesForOpers[GT_COUNT];
1692     static VtablePtr s_vtableForOp;
1693 #endif // DEBUGGABLE_GENTREE
1694
1695   public:
1696     inline void* operator new(size_t sz, class Compiler*, genTreeOps oper);
1697
1698     inline GenTree(genTreeOps oper, var_types type
1699                    DEBUGARG(bool largeNode = false));
1700 };
1701
1702
1703 /*****************************************************************************/
1704 // In the current design, we never instantiate GenTreeUnOp: it exists only to be
1705 // used as a base class.  For unary operators, we instantiate GenTreeOp, with a NULL second
1706 // argument.  We check that this is true dynamically.  We could tighten this and get static
1707 // checking, but that would entail accessing the first child of a unary operator via something
1708 // like gtUnOp.gtOp1 instead of gtOp.gtOp1.
1709 struct GenTreeUnOp: public GenTree
1710 {
1711     GenTreePtr      gtOp1;
1712
1713 protected:
1714     GenTreeUnOp(genTreeOps oper, var_types type 
1715                 DEBUGARG(bool largeNode = false)) : 
1716         GenTree(oper, type 
1717                 DEBUGARG(largeNode)),
1718         gtOp1(nullptr)
1719         {}
1720
1721     GenTreeUnOp(genTreeOps oper, var_types type, GenTreePtr op1 
1722                 DEBUGARG(bool largeNode = false)) : 
1723         GenTree(oper, type 
1724                 DEBUGARG(largeNode)), 
1725         gtOp1(op1)
1726         {
1727             assert(op1 != nullptr || NullOp1Legal());
1728             if (op1 != nullptr)  // Propagate effects flags from child.
1729                 gtFlags |= op1->gtFlags & GTF_ALL_EFFECT;
1730         }
1731
1732 #if DEBUGGABLE_GENTREE
1733     GenTreeUnOp() : GenTree(), gtOp1(nullptr) {}
1734 #endif
1735 };
1736
1737 struct GenTreeOp: public GenTreeUnOp
1738 {
1739     GenTreePtr      gtOp2;
1740
1741     GenTreeOp(genTreeOps oper, var_types type, GenTreePtr op1, GenTreePtr op2 
1742               DEBUGARG(bool largeNode = false)) : 
1743         GenTreeUnOp(oper, type, op1 
1744                     DEBUGARG(largeNode)), 
1745         gtOp2(op2) 
1746         {
1747             // comparisons are always integral types
1748             assert(!GenTree::OperIsCompare(oper) || varTypeIsIntegral(type));
1749             // Binary operators, with a few exceptions, require a non-nullptr
1750             // second argument.
1751             assert(op2 != nullptr || NullOp2Legal());
1752             // Unary operators, on the other hand, require a null second argument.
1753             assert(!OperIsUnary(oper) || op2 == nullptr);
1754             // Propagate effects flags from child.  (UnOp handled this for first child.)
1755             if (op2 != nullptr)
1756             {
1757                 gtFlags |= op2->gtFlags & GTF_ALL_EFFECT;
1758             }
1759         }
1760
1761     // A small set of types are unary operators with optional arguments.  We use
1762     // this constructor to build those.
1763     GenTreeOp(genTreeOps oper, var_types type 
1764               DEBUGARG(bool largeNode = false)) : 
1765         GenTreeUnOp(oper, type 
1766                     DEBUGARG(largeNode)),
1767         gtOp2(nullptr)
1768         {
1769             // Unary operators with optional arguments:
1770             assert(oper == GT_NOP     ||
1771                    oper == GT_RETURN  ||
1772                    oper == GT_RETFILT ||
1773                    OperIsBlkOp(oper));
1774         }
1775
1776 #if DEBUGGABLE_GENTREE
1777     GenTreeOp() : GenTreeUnOp(), gtOp2(nullptr) {}
1778 #endif
1779 };
1780
1781
1782 struct GenTreeVal: public GenTree
1783 {
1784     size_t          gtVal1;
1785
1786     GenTreeVal(genTreeOps oper, var_types type, ssize_t val) : 
1787         GenTree(oper, type),
1788         gtVal1(val)
1789         {}
1790 #if DEBUGGABLE_GENTREE
1791     GenTreeVal() : GenTree() {}
1792 #endif
1793 };
1794
1795 struct GenTreeIntConCommon: public GenTree
1796 {
1797     inline INT64   LngValue();
1798     inline void    SetLngValue(INT64 val);
1799     inline ssize_t IconValue();
1800     inline void SetIconValue(ssize_t val);
1801     
1802     GenTreeIntConCommon(genTreeOps oper, var_types type
1803                         DEBUGARG(bool largeNode = false)) : 
1804         GenTree(oper, type 
1805                 DEBUGARG(largeNode))
1806         {}
1807
1808         bool FitsInI32() 
1809         {  
1810             return FitsInI32(IconValue());
1811         }
1812
1813         static bool FitsInI32(ssize_t val)
1814         {
1815 #ifdef _TARGET_64BIT_
1816             return (int)val == val;
1817 #else
1818             return true;
1819 #endif
1820         }
1821
1822         bool ImmedValNeedsReloc(Compiler* comp);
1823         bool GenTreeIntConCommon::ImmedValCanBeFolded(Compiler* comp, genTreeOps op);
1824
1825 #ifdef _TARGET_XARCH_
1826         bool FitsInAddrBase(Compiler* comp);
1827         bool AddrNeedsReloc(Compiler* comp);
1828 #endif
1829
1830 #if DEBUGGABLE_GENTREE
1831     GenTreeIntConCommon() : GenTree() {}
1832 #endif
1833 };
1834
1835 // node representing a read from a physical register
1836 struct GenTreePhysReg: public GenTree
1837 {
1838     // physregs need a field beyond gtRegNum because 
1839     // gtRegNum indicates the destination (and can be changed)
1840     // whereas reg indicates the source
1841     regNumber gtSrcReg;
1842     GenTreePhysReg(regNumber r, var_types type=TYP_I_IMPL) : 
1843         GenTree(GT_PHYSREG, type), gtSrcReg(r)
1844     {
1845     }
1846 #if DEBUGGABLE_GENTREE
1847     GenTreePhysReg() : GenTree() {}
1848 #endif
1849 };
1850
1851 #ifndef LEGACY_BACKEND
1852 // gtJumpTable - Switch Jump Table
1853 //
1854 // This node stores a DWORD constant that represents the
1855 // absolute address of a jump table for switches.  The code 
1856 // generator uses this table to code the destination for every case
1857 // in an array of addresses which starting position is stored in
1858 // this constant.
1859 struct GenTreeJumpTable : public GenTreeIntConCommon
1860 {
1861     ssize_t        gtJumpTableAddr;
1862
1863     GenTreeJumpTable(var_types type
1864                   DEBUGARG(bool largeNode = false)) : 
1865         GenTreeIntConCommon(GT_JMPTABLE, type 
1866                             DEBUGARG(largeNode)) 
1867         {}
1868 #if DEBUGGABLE_GENTREE
1869     GenTreeJumpTable() : GenTreeIntConCommon() {}
1870 #endif // DEBUG
1871 };
1872 #endif // !LEGACY_BACKEND
1873
1874 /* gtIntCon -- integer constant (GT_CNS_INT) */
1875 struct GenTreeIntCon: public GenTreeIntConCommon
1876 {
1877     /* 
1878      * This is the GT_CNS_INT struct definition.
1879      * It's used to hold for both int constants and pointer handle constants.
1880      * For the 64-bit targets we will only use GT_CNS_INT as it used to represent all the possible sizes
1881      * 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.
1882      * In the future when we retarget the JIT for x86 we should consider eliminating GT_CNS_LNG
1883      */
1884     ssize_t         gtIconVal;   // Must overlap and have the same offset with the gtIconVal field in GenTreeLngCon below.
1885     
1886     /* The InitializeArray intrinsic needs to go back to the newarray statement
1887        to find the class handle of the array so that we can get its size.  However,
1888        in ngen mode, the handle in that statement does not correspond to the compile
1889        time handle (rather it lets you get a handle at run-time).  In that case, we also
1890        need to store a compile time handle, which goes in this gtCompileTimeHandle field.
1891     */
1892     ssize_t         gtCompileTimeHandle;
1893
1894     // TODO-Cleanup: It's not clear what characterizes the cases where the field
1895     // above is used.  It may be that its uses and those of the "gtFieldSeq" field below
1896     // are mutually exclusive, and they could be put in a union.  Or else we should separate
1897     // this type into three subtypes.
1898
1899     // If this constant represents the offset of one or more fields, "gtFieldSeq" represents that
1900     // sequence of fields.
1901     FieldSeqNode*   gtFieldSeq;
1902
1903 #if defined (LATE_DISASM)
1904
1905     /*  If the constant was morphed from some other node,
1906         these fields enable us to get back to what the node
1907         originally represented. See use of gtNewIconHandleNode()
1908      */
1909
1910     union
1911     {
1912         /* Template struct - The significant field of the other
1913          * structs should overlap exactly with this struct
1914          */
1915
1916         struct
1917         {
1918             unsigned        gtIconHdl1;
1919             void *          gtIconHdl2;
1920         }
1921                             gtIconHdl;
1922
1923         /* GT_FIELD, etc */
1924
1925         struct
1926         {
1927             unsigned                gtIconCPX;
1928             CORINFO_CLASS_HANDLE    gtIconCls;
1929         }
1930                                     gtIconFld;
1931     };
1932 #endif
1933
1934     GenTreeIntCon(var_types type, ssize_t value
1935                   DEBUGARG(bool largeNode = false)) : 
1936         GenTreeIntConCommon(GT_CNS_INT, type 
1937                             DEBUGARG(largeNode)),
1938         gtIconVal(value),
1939         gtCompileTimeHandle(0),
1940         gtFieldSeq(FieldSeqStore::NotAField())
1941         {}
1942
1943     GenTreeIntCon(var_types type, ssize_t value, FieldSeqNode* fields
1944                   DEBUGARG(bool largeNode = false)) : 
1945         GenTreeIntConCommon(GT_CNS_INT, type 
1946                             DEBUGARG(largeNode)),
1947         gtIconVal(value),
1948         gtCompileTimeHandle(0),
1949         gtFieldSeq(fields)
1950         {
1951             assert(fields != NULL);
1952         }
1953
1954 #ifdef _TARGET_64BIT_
1955     void TruncateOrSignExtend32()
1956     {        
1957         if (gtFlags & GTF_UNSIGNED)
1958         {
1959             gtIconVal = UINT32(gtIconVal);
1960         }
1961         else
1962         {
1963             gtIconVal = INT32(gtIconVal);
1964         }
1965     }
1966 #endif // _TARGET_64BIT_
1967
1968 #if DEBUGGABLE_GENTREE
1969     GenTreeIntCon() : GenTreeIntConCommon() {}
1970 #endif
1971 };
1972
1973
1974 /* gtLngCon -- long    constant (GT_CNS_LNG) */
1975
1976 struct GenTreeLngCon: public GenTreeIntConCommon
1977 {
1978     INT64 gtLconVal;   // Must overlap and have the same offset with the gtIconVal field in GenTreeIntCon above.
1979     INT32 LoVal()
1980     {
1981         return (INT32)(gtLconVal & 0xffffffff);
1982     }
1983
1984     INT32 HiVal()
1985     {
1986         return (INT32)(gtLconVal >> 32);;
1987     }
1988
1989     GenTreeLngCon(INT64 val) : 
1990         GenTreeIntConCommon(GT_CNS_NATIVELONG, TYP_LONG)
1991         { SetLngValue(val); }
1992 #if DEBUGGABLE_GENTREE
1993     GenTreeLngCon() : GenTreeIntConCommon() {}
1994 #endif
1995 };
1996
1997
1998 inline INT64 GenTreeIntConCommon::LngValue()
1999 {
2000 #ifndef _TARGET_64BIT_
2001     assert(gtOper == GT_CNS_LNG);
2002     return AsLngCon()->gtLconVal;
2003 #else
2004     return IconValue();
2005 #endif
2006 }
2007
2008 inline void GenTreeIntConCommon::SetLngValue(INT64 val)
2009 {
2010 #ifndef _TARGET_64BIT_
2011     assert(gtOper == GT_CNS_LNG);
2012     AsLngCon()->gtLconVal = val;
2013 #else
2014     // Compile time asserts that these two fields overlap and have the same offsets:  gtIconVal and gtLconVal
2015     C_ASSERT(offsetof(GenTreeLngCon, gtLconVal) == offsetof(GenTreeIntCon, gtIconVal));
2016     C_ASSERT(sizeof(AsLngCon()->gtLconVal) == sizeof(AsIntCon()->gtIconVal));
2017
2018     SetIconValue(ssize_t(val));
2019 #endif
2020 }
2021
2022 inline ssize_t GenTreeIntConCommon::IconValue()
2023 {
2024     assert(gtOper == GT_CNS_INT);   //  We should never see a GT_CNS_LNG for a 64-bit target!
2025     return AsIntCon()->gtIconVal;
2026 }
2027
2028 inline void GenTreeIntConCommon::SetIconValue(ssize_t val)
2029 {
2030     assert(gtOper == GT_CNS_INT);   //  We should never see a GT_CNS_LNG for a 64-bit target!
2031     AsIntCon()->gtIconVal = val;
2032 }
2033
2034 /* gtDblCon -- double  constant (GT_CNS_DBL) */
2035
2036 struct GenTreeDblCon: public GenTree
2037 {
2038     double          gtDconVal;
2039
2040     bool            isBitwiseEqual(GenTreeDblCon* other)
2041     {
2042         unsigned __int64 bits = *(unsigned __int64 *)(&gtDconVal);
2043         unsigned __int64 otherBits = *(unsigned __int64 *)(&(other->gtDconVal));
2044         return (bits == otherBits);
2045     }
2046
2047     GenTreeDblCon(double val) : 
2048         GenTree(GT_CNS_DBL, TYP_DOUBLE),
2049         gtDconVal(val)
2050         {}
2051 #if DEBUGGABLE_GENTREE
2052     GenTreeDblCon() : GenTree() {}
2053 #endif
2054 };
2055
2056
2057 /* gtStrCon -- string  constant (GT_CNS_STR) */
2058
2059 struct GenTreeStrCon: public GenTree
2060 {
2061     unsigned              gtSconCPX;
2062     CORINFO_MODULE_HANDLE gtScpHnd;
2063
2064     // Because this node can come from an inlined method we need to
2065     // have the scope handle, since it will become a helper call.
2066     GenTreeStrCon(unsigned sconCPX, CORINFO_MODULE_HANDLE mod
2067                   DEBUGARG(bool largeNode = false)) : 
2068         GenTree(GT_CNS_STR, TYP_REF 
2069                 DEBUGARG(largeNode)),
2070         gtSconCPX(sconCPX), gtScpHnd(mod)
2071         {}
2072 #if DEBUGGABLE_GENTREE
2073     GenTreeStrCon() : GenTree() {}
2074 #endif
2075 };
2076
2077 // Common supertype of LCL_VAR, LCL_FLD, REG_VAR, PHI_ARG
2078 // This inherits from UnOp because lclvar stores are Unops
2079 struct GenTreeLclVarCommon: public GenTreeUnOp
2080 {
2081 private:
2082     unsigned        _gtLclNum;      // The local number. An index into the Compiler::lvaTable array.
2083     unsigned        _gtSsaNum;      // The SSA number.
2084
2085 public:
2086     GenTreeLclVarCommon(genTreeOps oper, var_types type, unsigned lclNum
2087                         DEBUGARG(bool largeNode = false)) : 
2088         GenTreeUnOp(oper, type 
2089                 DEBUGARG(largeNode))
2090     {
2091         SetLclNum(lclNum);
2092     }
2093
2094     unsigned GetLclNum() const
2095     {
2096         return _gtLclNum;
2097     }
2098     __declspec(property(get=GetLclNum))  unsigned  gtLclNum;
2099
2100     void SetLclNum(unsigned lclNum)
2101     {
2102         _gtLclNum = lclNum;
2103         _gtSsaNum = SsaConfig::RESERVED_SSA_NUM;
2104     }
2105
2106     unsigned GetSsaNum() const
2107     {
2108         return _gtSsaNum;
2109     }
2110     __declspec(property(get=GetSsaNum))  unsigned  gtSsaNum;
2111
2112     void SetSsaNum(unsigned ssaNum)
2113     {
2114         _gtSsaNum = ssaNum;
2115     }
2116
2117     bool HasSsaName()
2118     {
2119         return (gtSsaNum != SsaConfig::RESERVED_SSA_NUM);
2120     }
2121
2122 #if DEBUGGABLE_GENTREE
2123     GenTreeLclVarCommon() : GenTreeUnOp() {}
2124 #endif
2125 };
2126
2127 // gtLclVar -- load/store/addr of local variable 
2128
2129 struct GenTreeLclVar: public GenTreeLclVarCommon
2130 {
2131     IL_OFFSET       gtLclILoffs;    // instr offset of ref (only for debug info)
2132
2133     GenTreeLclVar(var_types type, unsigned lclNum, IL_OFFSET ilOffs
2134                   DEBUGARG(bool largeNode = false)) : 
2135         GenTreeLclVarCommon(GT_LCL_VAR, type, lclNum
2136                             DEBUGARG(largeNode)),
2137             gtLclILoffs(ilOffs)
2138             {}
2139     
2140     GenTreeLclVar(genTreeOps oper, var_types type, unsigned lclNum, IL_OFFSET ilOffs
2141               DEBUGARG(bool largeNode = false)) : 
2142         GenTreeLclVarCommon(oper, type, lclNum
2143                             DEBUGARG(largeNode)),
2144             gtLclILoffs(ilOffs)
2145             {
2146                 assert(OperIsLocal(oper) || OperIsLocalAddr(oper));
2147             }
2148     
2149 #if DEBUGGABLE_GENTREE
2150     GenTreeLclVar() : GenTreeLclVarCommon() {}
2151 #endif
2152 };
2153
2154 // gtLclFld -- load/store/addr of local variable field 
2155
2156 struct GenTreeLclFld: public GenTreeLclVarCommon
2157 {
2158     unsigned        gtLclOffs;      // offset into the variable to access
2159
2160     FieldSeqNode*   gtFieldSeq;     // This LclFld node represents some sequences of accesses.
2161
2162     // old/FE style constructor where load/store/addr share same opcode
2163     GenTreeLclFld(var_types type, unsigned lclNum, unsigned lclOffs) : 
2164         GenTreeLclVarCommon(GT_LCL_FLD, type, lclNum),
2165         gtLclOffs(lclOffs), gtFieldSeq(NULL)
2166         {
2167             assert(sizeof(*this) <= s_gtNodeSizes[GT_LCL_FLD]);
2168         }
2169
2170
2171     GenTreeLclFld(genTreeOps oper, var_types type, unsigned lclNum, unsigned lclOffs) : 
2172         GenTreeLclVarCommon(oper, type, lclNum),
2173         gtLclOffs(lclOffs), gtFieldSeq(NULL)
2174         {
2175             assert(sizeof(*this) <= s_gtNodeSizes[GT_LCL_FLD]);
2176         }
2177 #if DEBUGGABLE_GENTREE
2178     GenTreeLclFld() : GenTreeLclVarCommon() {}
2179 #endif
2180 };
2181
2182 struct GenTreeRegVar: public GenTreeLclVarCommon
2183 {
2184     // TODO-Cleanup: Note that the base class GenTree already has a gtRegNum field.
2185     // It's not clear exactly why a GT_REG_VAR has a separate field. When
2186     // GT_REG_VAR is created, the two are identical. It appears that they may
2187     // or may not remain so. In particular, there is a comment in stackfp.cpp
2188     // that states:
2189     //
2190     //      There used to be an assertion: assert(src->gtRegNum == src->gtRegVar.gtRegNum, ...)
2191     //      here, but there's actually no reason to assume that.  AFAICT, for FP vars under stack FP,
2192     //      src->gtRegVar.gtRegNum is the allocated stack pseudo-register, but src->gtRegNum is the
2193     //      FP stack position into which that is loaded to represent a particular use of the variable.
2194     //
2195     // It might be the case that only for stackfp do they ever differ.
2196     //
2197     // The following might be possible: the GT_REG_VAR node has a last use prior to a complex
2198     // subtree being evaluated. It could then be spilled from the register. Later,
2199     // it could be unspilled into a different register, which would be recorded at
2200     // the unspill time in the GenTree::gtRegNum, whereas GenTreeRegVar::gtRegNum
2201     // is left alone. It's not clear why that is useful.
2202     //
2203     // Assuming there is a particular use, like stack fp, that requires it, maybe we
2204     // can get rid of GT_REG_VAR and just leave it as GT_LCL_VAR, using the base class gtRegNum field.
2205     // If we need it for stackfp, we could add a GenTreeStackFPRegVar type, which carries both the
2206     // pieces of information, in a clearer and more specific way (in particular, with
2207     // a different member name).
2208     //
2209
2210 private:
2211
2212     regNumberSmall  _gtRegNum;
2213
2214 public:
2215
2216     GenTreeRegVar(var_types type, unsigned lclNum, regNumber regNum) : 
2217         GenTreeLclVarCommon(GT_REG_VAR, type, lclNum
2218                             )
2219         {
2220             gtRegNum = regNum;
2221         }
2222
2223     // The register number is stored in a small format (8 bits), but the getters return and the setters take
2224     // a full-size (unsigned) format, to localize the casts here.
2225
2226     __declspec(property(get=GetRegNum,put=SetRegNum))
2227     regNumber           gtRegNum;
2228
2229     regNumber GetRegNum() const
2230     {
2231         return (regNumber) _gtRegNum;
2232     }
2233
2234     void SetRegNum(regNumber reg)
2235     {
2236         _gtRegNum = (regNumberSmall) reg;
2237         assert(_gtRegNum == reg);
2238     }
2239
2240 #if DEBUGGABLE_GENTREE
2241     GenTreeRegVar() : GenTreeLclVarCommon() {}
2242 #endif
2243 };
2244                               
2245 /* gtCast -- conversion to a different type  (GT_CAST) */
2246
2247 struct GenTreeCast: public GenTreeOp
2248 {
2249     GenTreePtr&     CastOp() { return gtOp1; }
2250     var_types       gtCastType;
2251
2252     GenTreeCast(var_types type, GenTreePtr op, var_types castType 
2253                 DEBUGARG(bool largeNode = false)) : 
2254         GenTreeOp(GT_CAST, type, op, nullptr
2255                     DEBUGARG(largeNode)), 
2256         gtCastType(castType) 
2257         {}
2258 #if DEBUGGABLE_GENTREE
2259     GenTreeCast() : GenTreeOp() {}
2260 #endif
2261 };
2262
2263
2264 // GT_BOX nodes are place markers for boxed values.  The "real" tree
2265 // for most purposes is in gtBoxOp.
2266 struct GenTreeBox: public GenTreeUnOp
2267 {
2268     // An expanded helper call to implement the "box" if we don't get
2269     // rid of it any other way.  Must be in same position as op1.
2270
2271     GenTreePtr&      BoxOp() { return gtOp1; }
2272     // This is the statement that contains the assignment tree when the node is an inlined GT_BOX on a value
2273     // type            
2274     GenTreePtr       gtAsgStmtWhenInlinedBoxValue;
2275
2276     GenTreeBox(var_types type, GenTreePtr boxOp, GenTreePtr asgStmtWhenInlinedBoxValue) : 
2277         GenTreeUnOp(GT_BOX, type, boxOp),
2278         gtAsgStmtWhenInlinedBoxValue(asgStmtWhenInlinedBoxValue)
2279         {}
2280 #if DEBUGGABLE_GENTREE
2281     GenTreeBox() : GenTreeUnOp() {}
2282 #endif
2283 };
2284
2285
2286
2287 /* gtField  -- data member ref  (GT_FIELD) */
2288
2289 struct GenTreeField: public GenTree
2290 {
2291     GenTreePtr      gtFldObj;
2292     CORINFO_FIELD_HANDLE    gtFldHnd;
2293     DWORD           gtFldOffset;
2294     bool            gtFldMayOverlap;
2295 #ifdef FEATURE_READYTORUN_COMPILER
2296     CORINFO_CONST_LOOKUP gtFieldLookup;
2297 #endif
2298
2299     GenTreeField(var_types type) : 
2300         GenTree(GT_FIELD, type 
2301                 ) 
2302     {
2303         gtFldMayOverlap = false;
2304     }
2305 #if DEBUGGABLE_GENTREE
2306     GenTreeField() : GenTree() {}
2307 #endif
2308 };
2309
2310 // Represents the Argument list of a call node, as a Lisp-style linked list.
2311 // (Originally I had hoped that this could have *only* the m_arg/m_rest fields, but it turns out
2312 // that enough of the GenTree mechanism is used that it makes sense just to make it a subtype.  But
2313 // note that in many ways, this is *not* a "real" node of the tree, but rather a mechanism for
2314 // giving call nodes a flexible number of children.  GenTreeArgListNodes never evaluate to registers,
2315 // for example.)
2316
2317 // Note that while this extends GenTreeOp, it is *not* an EXOP.  We don't add any new fields, and one
2318 // is free to allocate a GenTreeOp of type GT_LIST.  If you use this type, you get the convenient Current/Rest
2319 // method names for the arguments.
2320 struct GenTreeArgList: public GenTreeOp  
2321 {
2322     GenTreePtr&      Current() { return gtOp1; }
2323     GenTreeArgList*& Rest()    { assert(gtOp2 == NULL || gtOp2->OperGet() == GT_LIST); return *reinterpret_cast<GenTreeArgList**>(&gtOp2); }
2324
2325 #if DEBUGGABLE_GENTREE
2326     GenTreeArgList() : GenTreeOp() {}
2327 #endif
2328
2329     GenTreeArgList(GenTreePtr arg) :
2330         GenTreeArgList(arg, nullptr) {}
2331       
2332     GenTreeArgList(GenTreePtr arg, GenTreeArgList* rest) : 
2333         GenTreeOp(GT_LIST, TYP_VOID, arg, rest) 
2334     {
2335         // With structs passed in multiple args we could have an arg
2336         // GT_LIST containing a list of LCL_FLDs, see IsListForMultiRegArg()
2337         //
2338         assert((arg != nullptr) && ((!arg->IsList()) || (arg->IsListForMultiRegArg())));
2339         gtFlags |=  arg->gtFlags & GTF_ALL_EFFECT;
2340         if (rest != NULL)
2341         {
2342             gtFlags |= rest->gtFlags & GTF_ALL_EFFECT;
2343         }
2344     }
2345 };
2346
2347 // There was quite a bit of confusion in the code base about which of gtOp1 and gtOp2 was the
2348 // 'then' and 'else' clause of a colon node.  Adding these accessors, while not enforcing anything,
2349 // at least *allows* the programmer to be obviously correct.
2350 // However, these conventions seem backward.
2351 // TODO-Cleanup: If we could get these accessors used everywhere, then we could switch them.
2352 struct GenTreeColon: public GenTreeOp
2353 {
2354     GenTreePtr&      ThenNode() { return gtOp2; }
2355     GenTreePtr&      ElseNode() { return gtOp1; }
2356
2357 #if DEBUGGABLE_GENTREE
2358     GenTreeColon() : GenTreeOp() {}
2359 #endif
2360
2361     GenTreeColon(var_types typ, GenTreePtr thenNode, GenTreePtr elseNode) : 
2362         GenTreeOp(GT_COLON, typ, elseNode, thenNode)
2363         {}
2364 };
2365
2366 // gtCall   -- method call      (GT_CALL)
2367 typedef class fgArgInfo *  fgArgInfoPtr;
2368 enum class InlineObservation;
2369
2370 // Return type descriptor of a GT_CALL node.
2371 // x64 Unix, Arm64, Arm32 and x86 allow a value to be returned in multiple
2372 // registers. For such calls this struct provides the following info 
2373 // on their return type
2374 //    - type of value returned in each return register
2375 //    - ABI return register numbers in which the value is returned
2376 //    - count of return registers in which the value is returned
2377 //
2378 // TODO-ARM: Update this to meet the needs of Arm64 and Arm32
2379 //
2380 // TODO-AllArch: Right now it is used for describing multi-reg returned types.
2381 // Eventually we would want to use it for describing even single-reg
2382 // returned types (e.g. structs returned in single register x64/arm).
2383 // This would allow us not to lie or normalize single struct return
2384 // values in importer/morph.
2385 struct ReturnTypeDesc
2386 {
2387 private:
2388     var_types m_regType[MAX_RET_REG_COUNT];
2389
2390 #ifdef DEBUG
2391     bool m_inited;
2392 #endif
2393
2394 public:
2395     ReturnTypeDesc()
2396     {
2397         Reset();
2398     }
2399
2400     // Initialize the return type descriptor given its type handle
2401     void InitializeReturnType(Compiler* comp, CORINFO_CLASS_HANDLE retClsHnd);
2402
2403     // Reset type descriptor to defaults
2404     void Reset()
2405     {
2406         for (unsigned i = 0; i < MAX_RET_REG_COUNT; ++i)
2407         {
2408             m_regType[i] = TYP_UNKNOWN;
2409         }
2410 #ifdef DEBUG
2411         m_inited = false;
2412 #endif
2413     }
2414
2415     //--------------------------------------------------------------------------------------------
2416     // GetReturnRegCount:  Get the count of return registers in which the return value is returned.
2417     //
2418     // Arguments:
2419     //    None
2420     //
2421     // Return Value:
2422     //   Count of return registers.
2423     //   Returns 0 if the return type is not returned in registers.
2424     unsigned GetReturnRegCount() const
2425     {
2426         assert(m_inited);
2427
2428         int regCount = 0;
2429         for (unsigned i = 0; i < MAX_RET_REG_COUNT; ++i)
2430         {
2431             if (m_regType[i] == TYP_UNKNOWN)
2432             {
2433                 break;
2434             }
2435             // otherwise
2436             regCount++;
2437         }
2438
2439 #ifdef DEBUG
2440         // Any remaining elements in m_regTypes[] should also be TYP_UNKNOWN
2441         for (unsigned i = regCount+1; i < MAX_RET_REG_COUNT; ++i)
2442         {
2443             assert(m_regType[i] == TYP_UNKNOWN);
2444         }
2445 #endif        
2446
2447         return regCount;
2448     }
2449
2450     //-----------------------------------------------------------------------
2451     // IsMultiRegRetType: check whether the type is returned in multiple 
2452     // return registers.
2453     //
2454     // Arguments: 
2455     //    None
2456     //
2457     // Return Value:
2458     //    Returns true if the type is returned in multiple return registers.
2459     //    False otherwise.
2460     // Note that we only have to examine the first two values to determine this
2461     //
2462     bool IsMultiRegRetType() const
2463     {
2464         if (MAX_RET_REG_COUNT < 2)
2465         {
2466             return false;
2467         }
2468         else
2469         {
2470             return ((m_regType[0] != TYP_UNKNOWN) &&
2471                     (m_regType[1] != TYP_UNKNOWN));
2472         }
2473     }
2474
2475     //--------------------------------------------------------------------------
2476     // GetReturnRegType:  Get var_type of the return register specified by index.
2477     // 
2478     // Arguments:
2479     //    index - Index of the return register.
2480     //            First return register will have an index 0 and so on.
2481     //
2482     // Return Value:
2483     //    var_type of the return register specified by its index.
2484     //    asserts if the index does not have a valid register return type.
2485     
2486     var_types GetReturnRegType(unsigned index)
2487     {
2488         var_types result = m_regType[index];
2489         assert(result != TYP_UNKNOWN);
2490
2491         return result;
2492     }
2493
2494     // Get ith ABI return register 
2495     regNumber GetABIReturnReg(unsigned idx);
2496
2497     // Get reg mask of ABI return registers 
2498     regMaskTP GetABIReturnRegs();
2499 };
2500
2501 struct GenTreeCall final : public GenTree
2502 {
2503     GenTreePtr        gtCallObjp;             // The instance argument ('this' pointer)
2504     GenTreeArgList*   gtCallArgs;             // The list of arguments in original evaluation order
2505     GenTreeArgList*   gtCallLateArgs;         // On x86:     The register arguments in an optimal order
2506                                               // On ARM/x64: - also includes any outgoing arg space arguments
2507                                               //             - that were evaluated into a temp LclVar
2508     fgArgInfoPtr      fgArgInfo;
2509
2510 #if !FEATURE_FIXED_OUT_ARGS
2511     int               regArgListCount;
2512     regList           regArgList;  
2513 #endif
2514     
2515     // TODO-Throughput: Revisit this (this used to be only defined if
2516     // FEATURE_FIXED_OUT_ARGS was enabled, so this makes GenTreeCall 4 bytes bigger on x86). 
2517     CORINFO_SIG_INFO* callSig;                // Used by tail calls and to register callsites with the EE
2518
2519 #ifdef LEGACY_BACKEND
2520     regMaskTP         gtCallRegUsedMask;      // mask of registers used to pass parameters
2521 #endif // LEGACY_BACKEND
2522
2523     // State required to support multi-reg returning call nodes.
2524     // For now it is enabled only for x64 unix.
2525     //
2526     // TODO-AllArch: enable for all call nodes to unify single-reg and multi-reg returns.
2527 #if FEATURE_MULTIREG_RET
2528     ReturnTypeDesc    gtReturnTypeDesc;
2529
2530     // gtRegNum would always be the first return reg.
2531     // The following array holds the other reg numbers of multi-reg return.
2532     regNumber         gtOtherRegs[MAX_RET_REG_COUNT - 1];
2533
2534     // GTF_SPILL or GTF_SPILLED flag on a multi-reg call node indicates that one or
2535     // more of its result regs are in that state.  The spill flag of each of the
2536     // return register is stored in the below array.
2537     unsigned          gtSpillFlags[MAX_RET_REG_COUNT];
2538 #endif 
2539
2540     //-----------------------------------------------------------------------
2541     // GetReturnTypeDesc: get the type descriptor of return value of the call
2542     //
2543     // Arguments:
2544     //    None
2545     //
2546     // Returns
2547     //    Type descriptor of the value returned by call
2548     //
2549     // Note:
2550     //    Right now implemented only for x64 unix and yet to be 
2551     //    implemented for other multi-reg target arch (Arm64/Arm32/x86).
2552     //
2553     // TODO-AllArch: enable for all call nodes to unify single-reg and multi-reg returns.
2554     ReturnTypeDesc*   GetReturnTypeDesc()
2555     {
2556 #if FEATURE_MULTIREG_RET
2557         return &gtReturnTypeDesc;
2558 #else
2559         return nullptr;
2560 #endif
2561     }
2562
2563     //---------------------------------------------------------------------------
2564     // GetRegNumByIdx: get ith return register allocated to this call node.
2565     //
2566     // Arguments:
2567     //     idx   -   index of the return register
2568     //
2569     // Return Value:
2570     //     Return regNumber of ith return register of call node.
2571     //     Returns REG_NA if there is no valid return register for the given index.
2572     //
2573     regNumber  GetRegNumByIdx(unsigned idx) const
2574     {
2575         assert(idx < MAX_RET_REG_COUNT);
2576
2577         if (idx == 0)
2578         {
2579             return gtRegNum;
2580         }
2581
2582 #if FEATURE_MULTIREG_RET
2583         return gtOtherRegs[idx-1];
2584 #else
2585         return REG_NA;
2586 #endif
2587     }
2588
2589     //----------------------------------------------------------------------
2590     // SetRegNumByIdx: set ith return register of this call node
2591     //
2592     // Arguments:
2593     //    reg    -   reg number
2594     //    idx    -   index of the return register
2595     //
2596     // Return Value:
2597     //    None
2598     //
2599     void  SetRegNumByIdx(regNumber reg, unsigned idx)
2600     {
2601         assert(idx < MAX_RET_REG_COUNT);
2602
2603         if (idx == 0)
2604         {
2605             gtRegNum = reg;
2606         }
2607 #if FEATURE_MULTIREG_RET
2608         else
2609         {
2610             gtOtherRegs[idx - 1] = reg;
2611             assert(gtOtherRegs[idx - 1] == reg);
2612         }
2613 #else
2614         unreached();
2615 #endif
2616     }
2617
2618     //----------------------------------------------------------------------------
2619     // ClearOtherRegs: clear multi-reg state to indicate no regs are allocated
2620     //
2621     // Arguments:
2622     //    None
2623     //
2624     // Return Value:
2625     //    None
2626     //
2627     void  ClearOtherRegs()
2628     {
2629 #if FEATURE_MULTIREG_RET
2630         for (unsigned i = 0; i < MAX_RET_REG_COUNT - 1; ++i)
2631         {
2632             gtOtherRegs[i] = REG_NA;
2633         }
2634 #endif
2635     }
2636
2637     //----------------------------------------------------------------------------
2638     // CopyOtherRegs: copy multi-reg state from the given call node to this node
2639     //
2640     // Arguments:
2641     //    fromCall  -  GenTreeCall node from which to copy multi-reg state
2642     //
2643     // Return Value:
2644     //    None
2645     //
2646     void CopyOtherRegs(GenTreeCall* fromCall)
2647     {
2648 #if FEATURE_MULTIREG_RET
2649         for (unsigned i = 0; i < MAX_RET_REG_COUNT - 1; ++i)
2650         {
2651             this->gtOtherRegs[i] = fromCall->gtOtherRegs[i];
2652         }
2653 #endif
2654     }
2655
2656     // Get reg mask of all the valid registers of gtOtherRegs array
2657     regMaskTP  GetOtherRegMask() const;
2658
2659     //----------------------------------------------------------------------
2660     // GetRegSpillFlagByIdx: get spill flag associated with the return register 
2661     // specified by its index.
2662     //
2663     // Arguments:
2664     //    idx  -  Position or index of the return register
2665     //
2666     // Return Value:
2667     //    Returns GTF_* flags associated with.
2668     unsigned GetRegSpillFlagByIdx(unsigned idx) const
2669     {
2670         assert(idx < MAX_RET_REG_COUNT);
2671
2672 #if FEATURE_MULTIREG_RET
2673         return gtSpillFlags[idx];
2674 #else
2675         assert(!"unreached");
2676         return 0;
2677 #endif
2678     }
2679
2680     //----------------------------------------------------------------------
2681     // SetRegSpillFlagByIdx: set spill flags for the return register 
2682     // specified by its index.
2683     //
2684     // Arguments:
2685     //    flags  -  GTF_* flags
2686     //    idx    -  Position or index of the return register
2687     //
2688     // Return Value:
2689     //    None
2690     void SetRegSpillFlagByIdx(unsigned flags, unsigned idx)
2691     {
2692         assert(idx < MAX_RET_REG_COUNT);
2693
2694 #if FEATURE_MULTIREG_RET
2695         gtSpillFlags[idx] = flags;
2696 #else
2697         unreached();
2698 #endif
2699     }
2700
2701     //-------------------------------------------------------------------
2702     // clearOtherRegFlags: clear GTF_* flags associated with gtOtherRegs
2703     //
2704     // Arguments:
2705     //     None
2706     //
2707     // Return Value:
2708     //     None
2709     void ClearOtherRegFlags()
2710     {
2711 #if FEATURE_MULTIREG_RET
2712         for (unsigned i = 0; i < MAX_RET_REG_COUNT; ++i)
2713         {
2714             gtSpillFlags[i] = 0;
2715         }
2716 #endif
2717     }
2718
2719     //-------------------------------------------------------------------------
2720     // CopyOtherRegFlags: copy GTF_* flags associated with gtOtherRegs from
2721     // the given call node.
2722     //
2723     // Arguments:
2724     //    fromCall  -  GenTreeCall node from which to copy
2725     //
2726     // Return Value:
2727     //    None
2728     //
2729     void CopyOtherRegFlags(GenTreeCall* fromCall)
2730     {
2731 #if FEATURE_MULTIREG_RET
2732         for (unsigned i = 0; i < MAX_RET_REG_COUNT; ++i)
2733         {
2734             this->gtSpillFlags[i] = fromCall->gtSpillFlags[i];
2735         }
2736 #endif
2737     }
2738
2739 #define     GTF_CALL_M_EXPLICIT_TAILCALL       0x0001  // GT_CALL -- the call is "tail" prefixed and importer has performed tail call checks
2740 #define     GTF_CALL_M_TAILCALL                0x0002  // GT_CALL -- the call is a tailcall
2741 #define     GTF_CALL_M_VARARGS                 0x0004  // GT_CALL -- the call uses varargs ABI
2742 #define     GTF_CALL_M_RETBUFFARG              0x0008  // GT_CALL -- first parameter is the return buffer argument
2743 #define     GTF_CALL_M_DELEGATE_INV            0x0010  // GT_CALL -- call to Delegate.Invoke
2744 #define     GTF_CALL_M_NOGCCHECK               0x0020  // GT_CALL -- not a call for computing full interruptability
2745 #define     GTF_CALL_M_SPECIAL_INTRINSIC       0x0040  // GT_CALL -- function that could be optimized as an intrinsic 
2746                                                        // in special cases. Used to optimize fast way out in morphing
2747 #define     GTF_CALL_M_UNMGD_THISCALL          0x0080  // "this" pointer (first argument) should be enregistered (only for GTF_CALL_UNMANAGED)
2748 #define     GTF_CALL_M_VIRTSTUB_REL_INDIRECT   0x0080  // the virtstub is indirected through a relative address (only for GTF_CALL_VIRT_STUB)
2749 #define     GTF_CALL_M_NONVIRT_SAME_THIS       0x0080  // callee "this" pointer is equal to caller this pointer (only for GTF_CALL_NONVIRT)
2750 #define     GTF_CALL_M_FRAME_VAR_DEATH         0x0100  // GT_CALL -- the compLvFrameListRoot variable dies here (last use)
2751
2752 #ifndef LEGACY_BACKEND
2753 #define     GTF_CALL_M_TAILCALL_VIA_HELPER     0x0200  // GT_CALL -- call is a tail call dispatched via tail call JIT helper.
2754 #endif // !LEGACY_BACKEND
2755
2756 #if FEATURE_TAILCALL_OPT
2757 #define     GTF_CALL_M_IMPLICIT_TAILCALL       0x0400  // GT_CALL -- call is an opportunistic tail call and importer has performed tail call checks
2758 #define     GTF_CALL_M_TAILCALL_TO_LOOP        0x0800  // GT_CALL -- call is a fast recursive tail call that can be converted into a loop
2759 #endif
2760
2761 #define     GTF_CALL_M_PINVOKE                 0x1000  // GT_CALL -- call is a pinvoke.  This mirrors VM flag CORINFO_FLG_PINVOKE.
2762                                                        // A call marked as Pinvoke is not necessarily a GT_CALL_UNMANAGED. For e.g.
2763                                                        // an IL Stub dynamically generated for a PInvoke declaration is flagged as
2764                                                        // a Pinvoke but not as an unmanaged call. See impCheckForPInvokeCall() to
2765                                                        // know when these flags are set.
2766
2767 #define     GTF_CALL_M_R2R_REL_INDIRECT        0x2000  // GT_CALL -- ready to run call is indirected through a relative address
2768
2769     bool IsUnmanaged()       const { return (gtFlags & GTF_CALL_UNMANAGED) != 0; }
2770     bool NeedsNullCheck()    const { return (gtFlags & GTF_CALL_NULLCHECK) != 0; }
2771     bool CallerPop()         const { return (gtFlags & GTF_CALL_POP_ARGS) != 0;  }
2772     bool IsVirtual()         const { return (gtFlags & GTF_CALL_VIRT_KIND_MASK) != GTF_CALL_NONVIRT; }
2773     bool IsVirtualStub()     const { return (gtFlags & GTF_CALL_VIRT_KIND_MASK) == GTF_CALL_VIRT_STUB; }
2774     bool IsVirtualVtable()   const { return (gtFlags & GTF_CALL_VIRT_KIND_MASK) == GTF_CALL_VIRT_VTABLE; }
2775     bool IsInlineCandidate() const { return (gtFlags & GTF_CALL_INLINE_CANDIDATE) != 0; }
2776
2777 #ifndef LEGACY_BACKEND
2778     bool HasNonStandardAddedArgs(Compiler* compiler) const;
2779     int GetNonStandardAddedArgCount(Compiler* compiler) const;
2780 #endif // !LEGACY_BACKEND
2781
2782     // Returns true if this call uses a retBuf argument and its calling convention
2783     bool HasRetBufArg() const
2784     {
2785          return (gtCallMoreFlags & GTF_CALL_M_RETBUFFARG) != 0;
2786     }
2787
2788     //-------------------------------------------------------------------------
2789     // TreatAsHasRetBufArg:
2790     //
2791     // Arguments:
2792     //     compiler, the compiler instance so that we can call eeGetHelperNum
2793     //
2794     // Return Value:
2795     //     Returns true if we treat the call as if it has a retBuf argument
2796     //     This method may actually have a retBuf argument 
2797     //     or it could be a JIT helper that we are still transforming during 
2798     //     the importer phase.
2799     //
2800     // Notes:
2801     //     On ARM64 marking the method with the GTF_CALL_M_RETBUFFARG flag
2802     //     will make HasRetBufArg() return true, but will also force the 
2803     //     use of register x8 to pass the RetBuf argument.
2804     //
2805     bool TreatAsHasRetBufArg(Compiler* compiler) const;
2806
2807     //-----------------------------------------------------------------------------------------
2808     // HasMultiRegRetVal: whether the call node returns its value in multiple return registers.
2809     //
2810     // Arguments:
2811     //     None
2812     //
2813     // Return Value:
2814     //     True if the call is returning a multi-reg return value. False otherwise.
2815     //
2816     // Note:
2817     //     This is implemented only for x64 Unix and yet to be implemented for
2818     //     other multi-reg return target arch (arm64/arm32/x86).
2819     //
2820     // TODO-ARM: Implement this routine for Arm64 and Arm32
2821     bool HasMultiRegRetVal() const 
2822     { 
2823 #ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
2824         return varTypeIsStruct(gtType) && !HasRetBufArg(); 
2825 #elif defined(_TARGET_X86_) && !defined(LEGACY_BACKEND)
2826         // LEGACY_BACKEND does not use multi reg returns for calls with long return types
2827         return varTypeIsLong(gtType);
2828 #else
2829         return false;
2830 #endif
2831     }
2832
2833     // Returns true if VM has flagged this method as CORINFO_FLG_PINVOKE.
2834     bool IsPInvoke() const              { return (gtCallMoreFlags & GTF_CALL_M_PINVOKE) != 0; }
2835
2836     // Note that the distinction of whether tail prefixed or an implicit tail call
2837     // is maintained on a call node till fgMorphCall() after which it will be
2838     // either a tail call (i.e. IsTailCall() is true) or a non-tail call.
2839     bool IsTailPrefixedCall() const     { return (gtCallMoreFlags & GTF_CALL_M_EXPLICIT_TAILCALL) != 0; }     
2840
2841     // This method returning "true" implies that tail call flowgraph morhphing has 
2842     // performed final checks and committed to making a tail call.
2843     bool IsTailCall() const             { return (gtCallMoreFlags & GTF_CALL_M_TAILCALL) != 0; }
2844
2845     // This method returning "true" implies that importer has performed tail call checks
2846     // and providing a hint that this can be converted to a tail call.
2847     bool CanTailCall() const            { return IsTailPrefixedCall() || IsImplicitTailCall(); }
2848
2849 #ifndef LEGACY_BACKEND
2850     bool IsTailCallViaHelper() const    { return IsTailCall() && (gtCallMoreFlags & GTF_CALL_M_TAILCALL_VIA_HELPER); } 
2851 #else // LEGACY_BACKEND
2852     bool IsTailCallViaHelper() const    { return true; }
2853 #endif // LEGACY_BACKEND
2854
2855 #if FEATURE_FASTTAILCALL    
2856     bool IsFastTailCall() const         { return IsTailCall() && !(gtCallMoreFlags & GTF_CALL_M_TAILCALL_VIA_HELPER); }
2857 #else // !FEATURE_FASTTAILCALL
2858     bool IsFastTailCall() const         { return false; }    
2859 #endif // !FEATURE_FASTTAILCALL
2860
2861 #if FEATURE_TAILCALL_OPT
2862     // Returns true if this is marked for opportunistic tail calling.
2863     // That is, can be tail called though not explicitly prefixed with "tail" prefix.
2864     bool IsImplicitTailCall() const             { return (gtCallMoreFlags & GTF_CALL_M_IMPLICIT_TAILCALL) != 0; }
2865     bool IsTailCallConvertibleToLoop() const    { return (gtCallMoreFlags & GTF_CALL_M_TAILCALL_TO_LOOP) != 0; }
2866 #else // !FEATURE_TAILCALL_OPT
2867     bool IsImplicitTailCall() const             { return false; }
2868     bool IsTailCallConvertibleToLoop() const    { return false; }
2869 #endif // !FEATURE_TAILCALL_OPT
2870
2871     bool IsSameThis() const                 { return (gtCallMoreFlags & GTF_CALL_M_NONVIRT_SAME_THIS) != 0; } 
2872     bool IsDelegateInvoke() const           { return (gtCallMoreFlags & GTF_CALL_M_DELEGATE_INV) != 0; } 
2873     bool IsVirtualStubRelativeIndir() const { return (gtCallMoreFlags & GTF_CALL_M_VIRTSTUB_REL_INDIRECT) != 0; } 
2874
2875 #ifdef FEATURE_READYTORUN_COMPILER
2876     bool IsR2RRelativeIndir() const         { return (gtCallMoreFlags & GTF_CALL_M_R2R_REL_INDIRECT) != 0; }
2877     void setEntryPoint(CORINFO_CONST_LOOKUP entryPoint)
2878     {
2879         gtEntryPoint = entryPoint;
2880         if (gtEntryPoint.accessType == IAT_PVALUE)
2881         {
2882             gtCallMoreFlags |= GTF_CALL_M_R2R_REL_INDIRECT;
2883         }
2884     }
2885 #endif // FEATURE_READYTORUN_COMPILER
2886
2887     bool IsVarargs() const                  { return (gtCallMoreFlags & GTF_CALL_M_VARARGS) != 0; }
2888
2889     unsigned short  gtCallMoreFlags;        // in addition to gtFlags
2890     
2891     unsigned char   gtCallType   :3;        // value from the gtCallTypes enumeration
2892     unsigned char   gtReturnType :5;        // exact return type
2893
2894     CORINFO_CLASS_HANDLE    gtRetClsHnd;    // The return type handle of the call if it is a struct; always available
2895
2896     union
2897     {
2898         // only used for CALLI unmanaged calls (CT_INDIRECT)
2899         GenTreePtr      gtCallCookie;           
2900         // gtInlineCandidateInfo is only used when inlining methods 
2901         InlineCandidateInfo* gtInlineCandidateInfo;
2902         void* gtStubCallStubAddr;             // GTF_CALL_VIRT_STUB - these are never inlined                
2903         CORINFO_GENERIC_HANDLE compileTimeHelperArgumentHandle; // Used to track type handle argument of dynamic helpers
2904         void* gtDirectCallAddress; // Used to pass direct call address between lower and codegen
2905     };
2906
2907     // expression evaluated after args are placed which determines the control target
2908     GenTree * gtControlExpr; 
2909
2910     union
2911     {
2912         CORINFO_METHOD_HANDLE gtCallMethHnd;  // CT_USER_FUNC
2913         GenTreePtr  gtCallAddr;               // CT_INDIRECT
2914     };
2915
2916 #ifdef FEATURE_READYTORUN_COMPILER
2917     // Call target lookup info for method call from a Ready To Run module
2918     CORINFO_CONST_LOOKUP gtEntryPoint;
2919 #endif
2920
2921 #if defined(DEBUG) || defined(INLINE_DATA)
2922     // For non-inline candidates, track the first observation
2923     // that blocks candidacy.
2924     InlineObservation gtInlineObservation;
2925
2926     // IL offset of the call wrt its parent method.
2927     IL_OFFSET gtRawILOffset;
2928 #endif // defined(DEBUG) || defined(INLINE_DATA)
2929  
2930     bool IsHelperCall() const
2931     {
2932         return gtCallType == CT_HELPER;
2933     }
2934  
2935     bool IsHelperCall(CORINFO_METHOD_HANDLE callMethHnd) const
2936     {
2937         return IsHelperCall() && (callMethHnd == gtCallMethHnd);
2938     }
2939  
2940     bool IsHelperCall(Compiler* compiler, unsigned helper) const;
2941
2942     GenTreeCall(var_types type) : 
2943         GenTree(GT_CALL, type) 
2944     {
2945     }
2946 #if DEBUGGABLE_GENTREE
2947     GenTreeCall() : GenTree()
2948     {
2949     }
2950 #endif
2951 };
2952
2953 struct GenTreeCmpXchg: public GenTree
2954 {
2955     GenTreePtr      gtOpLocation;
2956     GenTreePtr      gtOpValue;
2957     GenTreePtr      gtOpComparand;
2958
2959     GenTreeCmpXchg(var_types type, GenTreePtr loc, GenTreePtr val, GenTreePtr comparand) : 
2960         GenTree(GT_CMPXCHG, type), 
2961         gtOpLocation(loc), gtOpValue(val),  gtOpComparand(comparand)
2962         {
2963             // There's no reason to do a compare-exchange on a local location, so we'll assume that all of these
2964             // have global effects.
2965             gtFlags |= GTF_GLOB_EFFECT;
2966         }
2967 #if DEBUGGABLE_GENTREE
2968     GenTreeCmpXchg() : GenTree() {}
2969 #endif
2970 };
2971
2972
2973
2974 struct GenTreeFptrVal: public GenTree
2975 {
2976     CORINFO_METHOD_HANDLE gtFptrMethod;
2977
2978 #ifdef FEATURE_READYTORUN_COMPILER
2979     CORINFO_CONST_LOOKUP gtEntryPoint;
2980     CORINFO_RESOLVED_TOKEN* gtLdftnResolvedToken;
2981 #endif
2982
2983     GenTreeFptrVal(var_types type, CORINFO_METHOD_HANDLE meth) : 
2984         GenTree(GT_FTN_ADDR, type), 
2985         gtFptrMethod(meth) 
2986         {}
2987 #if DEBUGGABLE_GENTREE
2988     GenTreeFptrVal() : GenTree() {}
2989 #endif
2990 };
2991
2992 /* gtQmark */
2993 struct GenTreeQmark : public GenTreeOp
2994 {
2995     // Livesets on entry to then and else subtrees
2996     VARSET_TP       gtThenLiveSet;
2997     VARSET_TP       gtElseLiveSet;
2998     
2999     // The "Compiler*" argument is not a DEBUGARG here because we use it to keep track of the set of
3000     // (possible) QMark nodes.
3001     GenTreeQmark(var_types type, GenTreePtr cond, GenTreePtr colonOp, class Compiler* comp);
3002
3003 #if DEBUGGABLE_GENTREE
3004     GenTreeQmark() : GenTreeOp(GT_QMARK, TYP_INT, NULL, NULL) {}
3005 #endif
3006 };
3007
3008 /* gtIntrinsic   -- intrinsic   (possibly-binary op [NULL op2 is allowed] with an additional field) */
3009
3010 struct GenTreeIntrinsic: public GenTreeOp
3011 {
3012     CorInfoIntrinsics     gtIntrinsicId;
3013     CORINFO_METHOD_HANDLE gtMethodHandle;    // Method handle of the method which is treated as an intrinsic.
3014
3015 #ifdef FEATURE_READYTORUN_COMPILER
3016     // Call target lookup info for method call from a Ready To Run module
3017     CORINFO_CONST_LOOKUP gtEntryPoint;
3018 #endif
3019
3020     GenTreeIntrinsic(var_types type, GenTreePtr op1, CorInfoIntrinsics intrinsicId, CORINFO_METHOD_HANDLE methodHandle) :
3021         GenTreeOp(GT_INTRINSIC, type, op1, NULL),
3022         gtIntrinsicId(intrinsicId),
3023         gtMethodHandle(methodHandle)
3024         {}
3025
3026     GenTreeIntrinsic(var_types type, GenTreePtr op1, GenTreePtr op2, CorInfoIntrinsics intrinsicId, CORINFO_METHOD_HANDLE methodHandle) :
3027         GenTreeOp(GT_INTRINSIC, type, op1, op2),
3028         gtIntrinsicId(intrinsicId),
3029         gtMethodHandle(methodHandle)
3030         {}
3031
3032 #if DEBUGGABLE_GENTREE
3033     GenTreeIntrinsic() : GenTreeOp() {}
3034 #endif
3035 };
3036
3037 #ifdef FEATURE_SIMD
3038
3039 /* gtSIMD   -- SIMD intrinsic   (possibly-binary op [NULL op2 is allowed] with additional fields) */
3040 struct GenTreeSIMD: public GenTreeOp
3041 {
3042     SIMDIntrinsicID         gtSIMDIntrinsicID;  // operation Id
3043     var_types               gtSIMDBaseType;     // SIMD vector base type
3044     unsigned                gtSIMDSize;         // SIMD vector size in bytes
3045
3046     GenTreeSIMD(var_types type, GenTreePtr op1, SIMDIntrinsicID simdIntrinsicID, var_types baseType, unsigned size) : 
3047         GenTreeOp(GT_SIMD, type, op1, nullptr),
3048         gtSIMDIntrinsicID(simdIntrinsicID),
3049         gtSIMDBaseType(baseType),
3050         gtSIMDSize(size)
3051         {}
3052
3053     GenTreeSIMD(var_types type, GenTreePtr op1, GenTreePtr op2, SIMDIntrinsicID simdIntrinsicID, var_types baseType, unsigned size) : 
3054         GenTreeOp(GT_SIMD, type, op1, op2),
3055         gtSIMDIntrinsicID(simdIntrinsicID),
3056         gtSIMDBaseType(baseType),
3057         gtSIMDSize(size)
3058         {}
3059
3060 #if DEBUGGABLE_GENTREE
3061     GenTreeSIMD() : GenTreeOp() {}
3062 #endif
3063 };
3064 #endif // FEATURE_SIMD
3065
3066 /* gtIndex -- array access */
3067
3068 struct GenTreeIndex: public GenTreeOp
3069 {
3070     GenTreePtr&     Arr()   { return gtOp1; }
3071     GenTreePtr&     Index() { return gtOp2; }
3072
3073     unsigned        gtIndElemSize;  // size of elements in the array
3074     CORINFO_CLASS_HANDLE gtStructElemClass;   // If the element type is a struct, this is the struct type.
3075
3076     GenTreeIndex(var_types type, GenTreePtr arr, GenTreePtr ind, unsigned indElemSize) :
3077         GenTreeOp(GT_INDEX, type, arr, ind),
3078         gtIndElemSize(indElemSize),
3079         gtStructElemClass(nullptr)  // We always initialize this after construction.
3080         {
3081 #ifdef DEBUG
3082             if (JitConfig.JitSkipArrayBoundCheck() == 1)
3083             {
3084                 // Skip bounds check
3085             }
3086             else
3087 #endif
3088             {
3089                 // Do bounds check
3090                 gtFlags |= GTF_INX_RNGCHK;
3091             }
3092
3093             if (type == TYP_REF)
3094             {
3095                 gtFlags |= GTF_INX_REFARR_LAYOUT;
3096             }
3097
3098             gtFlags |= GTF_EXCEPT|GTF_GLOB_REF;
3099         }
3100 #if DEBUGGABLE_GENTREE
3101     GenTreeIndex() : GenTreeOp() {}
3102 #endif
3103 };
3104
3105 /* gtArrLen -- array length (GT_ARR_LENGTH)
3106    GT_ARR_LENGTH is used for "arr.length" */
3107
3108 struct GenTreeArrLen: public GenTreeUnOp
3109 {
3110     GenTreePtr&     ArrRef() { return gtOp1; }   // the array address node
3111 private:
3112     int             gtArrLenOffset; // constant to add to "gtArrRef" to get the address of the array length.
3113
3114 public:
3115     inline int      ArrLenOffset() {
3116         return gtArrLenOffset;
3117     }
3118
3119     GenTreeArrLen(var_types type, GenTreePtr arrRef, int lenOffset) : 
3120         GenTreeUnOp(GT_ARR_LENGTH, type, arrRef), 
3121         gtArrLenOffset(lenOffset)
3122         {}
3123
3124 #if DEBUGGABLE_GENTREE
3125     GenTreeArrLen() : GenTreeUnOp() {}
3126 #endif
3127 };
3128
3129 // This takes:
3130 // - a comparison value (generally an array length),
3131 // - an index value, and
3132 // - the label to jump to if the index is out of range.
3133 // - the "kind" of the throw block to branch to on failure
3134 // It generates no result.
3135
3136 struct GenTreeBoundsChk: public GenTree
3137 {
3138     GenTreePtr              gtArrLen;       // An expression for the length of the array being indexed.
3139     GenTreePtr              gtIndex;        // The index expression.
3140
3141     GenTreePtr              gtIndRngFailBB; // Label to jump to for array-index-out-of-range
3142     SpecialCodeKind         gtThrowKind;    // Kind of throw block to branch to on failure
3143
3144     /* Only out-of-ranges at same stack depth can jump to the same label (finding return address is easier)
3145        For delayed calling of fgSetRngChkTarget() so that the
3146        optimizer has a chance of eliminating some of the rng checks */
3147     unsigned        gtStkDepth;
3148
3149     GenTreeBoundsChk(genTreeOps oper, var_types type, GenTreePtr arrLen, GenTreePtr index, SpecialCodeKind kind) : 
3150         GenTree(oper, type), 
3151         gtArrLen(arrLen), gtIndex(index), 
3152         gtIndRngFailBB(NULL), 
3153         gtThrowKind(kind),
3154         gtStkDepth(0)
3155         {
3156             // Effects flags propagate upwards.
3157             gtFlags |= (arrLen->gtFlags & GTF_ALL_EFFECT);
3158             gtFlags |= GTF_EXCEPT;
3159         }
3160 #if DEBUGGABLE_GENTREE
3161     GenTreeBoundsChk() : GenTree() {}
3162 #endif
3163
3164     // If the gtArrLen is really an array length, returns array reference, else "NULL".
3165     GenTreePtr GetArray()
3166     {
3167         if (gtArrLen->OperGet() == GT_ARR_LENGTH)
3168         {
3169             return gtArrLen->gtArrLen.ArrRef();
3170         }
3171         else
3172         {
3173             return NULL;
3174         }
3175     }
3176 };
3177
3178 // gtArrElem -- general array element (GT_ARR_ELEM), for non "SZ_ARRAYS"
3179 //              -- multidimensional arrays, or 1-d arrays with non-zero lower bounds.
3180
3181 struct GenTreeArrElem: public GenTree
3182 {
3183     GenTreePtr      gtArrObj;
3184
3185     #define         GT_ARR_MAX_RANK 3
3186     GenTreePtr      gtArrInds[GT_ARR_MAX_RANK]; // Indices
3187     unsigned char   gtArrRank;                  // Rank of the array
3188
3189     unsigned char   gtArrElemSize;              // !!! Caution, this is an "unsigned char", it is used only
3190                                                 // on the optimization path of array intrisics.
3191                                                 // It stores the size of array elements WHEN it can fit
3192                                                 // into an "unsigned char".
3193                                                 // This has caused VSW 571394.
3194     var_types       gtArrElemType;              // The array element type
3195
3196     // Requires that "inds" is a pointer to an array of "rank" GenTreePtrs for the indices.
3197     GenTreeArrElem(var_types type, GenTreePtr arr, unsigned char rank, unsigned char elemSize, var_types elemType, GenTreePtr* inds) : 
3198         GenTree(GT_ARR_ELEM, type), 
3199         gtArrObj(arr), gtArrRank(rank), gtArrElemSize(elemSize), gtArrElemType(elemType)
3200         {
3201             for (unsigned char i = 0; i < rank; i++) gtArrInds[i] = inds[i];
3202             gtFlags |= GTF_EXCEPT;
3203         }
3204 #if DEBUGGABLE_GENTREE
3205     GenTreeArrElem() : GenTree() {}
3206 #endif
3207 };
3208
3209 //--------------------------------------------
3210 // 
3211 // GenTreeArrIndex (gtArrIndex): Expression to bounds-check the index for one dimension of a
3212 //    multi-dimensional or non-zero-based array., and compute the effective index
3213 //    (i.e. subtracting the lower bound).
3214 //
3215 // Notes:
3216 //    This node is similar in some ways to GenTreeBoundsChk, which ONLY performs the check.
3217 //    The reason that this node incorporates the check into the effective index computation is
3218 //    to avoid duplicating the codegen, as the effective index is required to compute the
3219 //    offset anyway.
3220 //    TODO-CQ: Enable optimization of the lower bound and length by replacing this:
3221 //                /--*  <arrObj>
3222 //                +--*  <index0>
3223 //             +--* ArrIndex[i, ]
3224 //    with something like:
3225 //                   /--*  <arrObj>
3226 //                /--*  ArrLowerBound[i, ]
3227 //                |  /--*  <arrObj>
3228 //                +--*  ArrLen[i, ]    (either generalize GT_ARR_LENGTH or add a new node)
3229 //                +--*  <index0>
3230 //             +--* ArrIndex[i, ]
3231 //    Which could, for example, be optimized to the following when known to be within bounds:
3232 //                /--*  TempForLowerBoundDim0
3233 //                +--*  <index0>
3234 //             +--* - (GT_SUB)
3235 //
3236 struct GenTreeArrIndex: public GenTreeOp
3237 {
3238     // The array object - may be any expression producing an Array reference, but is likely to be a lclVar.
3239     GenTreePtr&     ArrObj()    { return gtOp1; }
3240     // The index expression - may be any integral expression.
3241     GenTreePtr&     IndexExpr() { return gtOp2; }
3242     unsigned char   gtCurrDim;      // The current dimension
3243     unsigned char   gtArrRank;      // Rank of the array
3244     var_types       gtArrElemType;  // The array element type
3245
3246     GenTreeArrIndex(var_types type, GenTreePtr arrObj, GenTreePtr indexExpr,
3247                   unsigned char currDim, unsigned char arrRank, var_types elemType) :
3248         GenTreeOp(GT_ARR_INDEX, type, arrObj, indexExpr),
3249                   gtCurrDim(currDim), gtArrRank(arrRank), gtArrElemType(elemType)
3250     {
3251         gtFlags |= GTF_EXCEPT;
3252     }
3253 #if DEBUGGABLE_GENTREE
3254 protected:
3255     friend GenTree;
3256     // Used only for GenTree::GetVtableForOper()
3257     GenTreeArrIndex() : GenTreeOp() {}
3258 #endif
3259 };
3260
3261 // Represents either an InitBlk, InitObj, CpBlk or CpObj 
3262 // MSIL OpCode.
3263 struct GenTreeBlkOp : public GenTreeOp
3264 {
3265 public:
3266     // The destination for the CpBlk/CpObj/InitBlk/InitObj to copy bits to
3267     GenTreePtr Dest()         { 
3268                                 assert(gtOp1->gtOper == GT_LIST);
3269                                 return gtOp1->gtOp.gtOp1;
3270                               }
3271
3272     // True if this BlkOpNode is a volatile memory operation.
3273     bool IsVolatile() const { return (gtFlags & GTF_BLK_VOLATILE) != 0; }
3274
3275     // Instruction selection: during codegen time, what code sequence we will be using
3276     // to encode this operation.
3277     enum
3278     {
3279         BlkOpKindInvalid,
3280         BlkOpKindHelper,
3281         BlkOpKindRepInstr,
3282         BlkOpKindUnroll,
3283     } gtBlkOpKind;
3284
3285     bool gtBlkOpGcUnsafe; 
3286
3287     GenTreeBlkOp(genTreeOps oper) :
3288         GenTreeOp(oper, TYP_VOID DEBUGARG(true)),
3289             gtBlkOpKind(BlkOpKindInvalid),
3290             gtBlkOpGcUnsafe(false)
3291     {
3292         assert(OperIsBlkOp(oper));
3293     }
3294
3295 #if DEBUGGABLE_GENTREE
3296 protected:
3297     friend GenTree;
3298     GenTreeBlkOp() : GenTreeOp(){}
3299 #endif // DEBUGGABLE_GENTREE
3300 };
3301
3302 // gtObj  -- 'object' (GT_OBJ). */
3303
3304 struct GenTreeObj: public GenTreeUnOp
3305 {
3306     // The address of the block.
3307     GenTreePtr&     Addr()          { return gtOp1; }
3308
3309     CORINFO_CLASS_HANDLE gtClass;   // the class of the object
3310
3311     GenTreeObj(var_types type, GenTreePtr addr, CORINFO_CLASS_HANDLE cls) : 
3312         GenTreeUnOp(GT_OBJ, type, addr),
3313         gtClass(cls)
3314         {
3315             // By default, an OBJ is assumed to be a global reference.
3316             gtFlags |= GTF_GLOB_REF;
3317         }
3318
3319 #if DEBUGGABLE_GENTREE
3320     GenTreeObj() : GenTreeUnOp() {}
3321 #endif
3322 };
3323
3324 // Represents a CpObj MSIL Node.
3325 struct GenTreeCpObj : public GenTreeBlkOp
3326 {
3327 public:
3328     // The source for the CpBlk/CpObj to copy bits from
3329     GenTreePtr Source()       {
3330         assert(gtOper == GT_COPYOBJ && gtOp1->gtOper == GT_LIST);
3331         return gtOp1->gtOp.gtOp2;
3332     }
3333
3334     // In the case of CopyObj, this is the class token that represents the type that is being copied.
3335     GenTreePtr ClsTok() { return gtOp2; }
3336
3337     // If non-null, this array represents the gc-layout of the class that is being copied
3338     // with CpObj.
3339     BYTE*       gtGcPtrs;
3340
3341     // If non-zero, this is the number of slots in the class layout that 
3342     // contain gc-pointers.
3343     unsigned    gtGcPtrCount;
3344
3345     // If non-zero, the number of pointer-sized slots that constitutes the class token in CpObj.
3346     unsigned    gtSlots;
3347
3348     GenTreeCpObj(unsigned gcPtrCount, unsigned gtSlots, BYTE* gtGcPtrs) :
3349         GenTreeBlkOp(GT_COPYOBJ),
3350         gtGcPtrs(gtGcPtrs),
3351         gtGcPtrCount(gcPtrCount),
3352         gtSlots(gtSlots){ }
3353
3354 #if DEBUGGABLE_GENTREE
3355 protected:
3356     friend GenTree;
3357     GenTreeCpObj() : GenTreeBlkOp(),
3358         gtGcPtrs(nullptr),
3359         gtGcPtrCount(0),
3360         gtSlots(0) {}
3361 #endif // DEBUGGABLE_GENTREE
3362 };
3363
3364 // Represents either an InitBlk or InitObj MSIL OpCode.
3365 struct GenTreeInitBlk : public GenTreeBlkOp
3366 {
3367 public:
3368
3369     // The value used to fill the destination buffer.
3370     GenTreePtr InitVal() { assert(gtOp1->gtOper == GT_LIST);
3371                            return gtOp1->gtOp.gtOp2; }
3372
3373     // The size of the buffer to be copied.
3374     GenTreePtr Size()    { return gtOp2; }
3375
3376     GenTreeInitBlk() : GenTreeBlkOp(GT_INITBLK){}
3377
3378 #if DEBUGGABLE_GENTREE
3379 protected:
3380     friend GenTree;
3381 #endif // DEBUGGABLE_GENTREE
3382 };
3383
3384 // Represents a CpBlk or CpObj with no GC-pointers MSIL OpCode.
3385 struct GenTreeCpBlk : public GenTreeBlkOp
3386 {
3387 public:
3388
3389     // The value used to fill the destination buffer.
3390     // The source for the CpBlk/CpObj to copy bits from
3391     GenTreePtr Source() { assert(gtOp1->gtOper == GT_LIST);
3392                           return gtOp1->gtOp.gtOp2; }
3393
3394     // The size of the buffer to be copied.
3395     GenTreePtr Size()   { return gtOp2; }
3396
3397     GenTreeCpBlk() : GenTreeBlkOp(GT_COPYBLK){}
3398
3399 #if DEBUGGABLE_GENTREE
3400 protected:
3401     friend GenTree;
3402 #endif // DEBUGGABLE_GENTREE
3403 };
3404
3405 //--------------------------------------------
3406 // 
3407 // GenTreeArrOffset (gtArrOffset): Expression to compute the accumulated offset for the address
3408 //    of an element of a multi-dimensional or non-zero-based array.
3409 //
3410 // Notes:
3411 //    The result of this expression is (gtOffset * dimSize) + gtIndex
3412 //    where dimSize is the length/stride/size of the dimension, and is obtained from gtArrObj.
3413 //    This node is generated in conjunction with the GenTreeArrIndex node, which computes the
3414 //    effective index for a single dimension.  The sub-trees can be separately optimized, e.g.
3415 //    within a loop body where the expression for the 0th dimension may be invariant.
3416 //
3417 //    Here is an example of how the tree might look for a two-dimension array reference:
3418 //                /--*  const 0
3419 //                |  /--* <arrObj>
3420 //                |  +--* <index0>
3421 //                +--* ArrIndex[i, ]
3422 //                +--*  <arrObj>
3423 //             /--| arrOffs[i, ]
3424 //             |  +--*  <arrObj>
3425 //             |  +--*  <index1>
3426 //             +--* ArrIndex[*,j]
3427 //             +--*  <arrObj>
3428 //          /--| arrOffs[*,j]
3429 //    TODO-CQ: see comment on GenTreeArrIndex for how its representation may change.  When that
3430 //    is done, we will also want to replace the <arrObj> argument to arrOffs with the
3431 //    ArrLen as for GenTreeArrIndex.
3432 //
3433 struct GenTreeArrOffs: public GenTree
3434 {
3435     GenTreePtr      gtOffset;       // The accumulated offset for lower dimensions - must be TYP_I_IMPL, and
3436                                     // will either be a CSE temp, the constant 0, or another GenTreeArrOffs node.
3437     GenTreePtr      gtIndex;        // The effective index for the current dimension - must be non-negative
3438                                     // and can be any expression (though it is likely to be either a GenTreeArrIndex,
3439                                     // node, a lclVar, or a constant).
3440     GenTreePtr      gtArrObj;       // The array object - may be any expression producing an Array reference,
3441                                     // but is likely to be a lclVar.
3442     unsigned char   gtCurrDim;      // The current dimension
3443     unsigned char   gtArrRank;      // Rank of the array
3444     var_types       gtArrElemType;  // The array element type
3445
3446     GenTreeArrOffs(var_types type, GenTreePtr offset, GenTreePtr index, GenTreePtr arrObj,
3447                    unsigned char currDim, unsigned char rank, var_types elemType) : 
3448         GenTree(GT_ARR_OFFSET, type), gtOffset(offset), gtIndex(index), gtArrObj(arrObj),
3449                 gtCurrDim(currDim), gtArrRank(rank), gtArrElemType(elemType)
3450     {
3451         assert(index->gtFlags & GTF_EXCEPT);
3452         gtFlags |= GTF_EXCEPT;
3453     }
3454 #if DEBUGGABLE_GENTREE
3455     GenTreeArrOffs() : GenTree() {}
3456 #endif
3457 };
3458
3459 /* gtAddrMode -- Target-specific canonicalized addressing expression (GT_LEA) */
3460
3461 struct GenTreeAddrMode: public GenTreeOp
3462 {
3463     // Address is Base + Index*Scale + Offset.
3464     // These are the legal patterns:
3465     //
3466     //      Base                                // Base != nullptr && Index == nullptr && Scale == 0 && Offset == 0
3467     //      Base + Index*Scale                  // Base != nullptr && Index != nullptr && Scale != 0 && Offset == 0
3468     //      Base + Offset                       // Base != nullptr && Index == nullptr && Scale == 0 && Offset != 0
3469     //      Base + Index*Scale + Offset         // Base != nullptr && Index != nullptr && Scale != 0 && Offset != 0
3470     //             Index*Scale                  // Base == nullptr && Index != nullptr && Scale >  1 && Offset == 0
3471     //             Index*Scale + Offset         // Base == nullptr && Index != nullptr && Scale >  1 && Offset != 0
3472     //                           Offset         // Base == nullptr && Index == nullptr && Scale == 0 && Offset != 0
3473     //
3474     // So, for example:
3475     //      1. Base + Index is legal with Scale==1
3476     //      2. If Index is null, Scale should be zero (or unintialized / unused)
3477     //      3. If Scale==1, then we should have "Base" instead of "Index*Scale", and "Base + Offset" instead of "Index*Scale + Offset".
3478
3479     // First operand is base address/pointer
3480     bool            HasBase() const     { return gtOp1 != nullptr; }
3481     GenTreePtr&     Base()              { return gtOp1; }
3482
3483     // Second operand is scaled index value
3484     bool            HasIndex() const    { return gtOp2 != nullptr; }
3485     GenTreePtr&     Index()             { return gtOp2; }
3486
3487     unsigned        gtScale;        // The scale factor
3488     unsigned        gtOffset;       // The offset to add
3489
3490     GenTreeAddrMode(var_types type, GenTreePtr base, GenTreePtr index,
3491                     unsigned scale, unsigned offset) : 
3492         GenTreeOp(GT_LEA, type, base, index )
3493     {
3494         gtScale = scale;
3495         gtOffset = offset;
3496     }
3497 #if DEBUGGABLE_GENTREE
3498 protected:
3499     friend GenTree;
3500     // Used only for GenTree::GetVtableForOper()
3501     GenTreeAddrMode() : GenTreeOp() {}
3502 #endif
3503 };
3504
3505 // Indir is just an op, no additional data, but some additional abstractions
3506 struct GenTreeIndir: public GenTreeOp
3507 {
3508     // like an assign, op1 is the destination
3509     GenTreePtr&     Addr()      { return gtOp1; }
3510
3511     // these methods provide an interface to the indirection node which 
3512     bool            HasBase();
3513     bool            HasIndex();
3514     GenTree*        Base(); 
3515     GenTree*        Index(); 
3516     unsigned        Scale();
3517     size_t          Offset();
3518
3519     GenTreeIndir(genTreeOps oper, var_types type, GenTree *addr, GenTree *data) : 
3520     GenTreeOp(oper, type, addr, data)
3521     {
3522     }
3523
3524 #if DEBUGGABLE_GENTREE
3525 protected:
3526     friend GenTree;
3527     // Used only for GenTree::GetVtableForOper()
3528     GenTreeIndir() : GenTreeOp() {}
3529 #endif
3530 };
3531
3532 // Read-modify-write status of a RMW memory op rooted at a storeInd 
3533 enum  RMWStatus {    
3534     STOREIND_RMW_STATUS_UNKNOWN,  // RMW status of storeInd unknown
3535                                   // Default status unless modified by IsRMWMemOpRootedAtStoreInd()
3536
3537     // One of these denote storeind is a RMW memory operation.
3538     STOREIND_RMW_DST_IS_OP1,       // StoreInd is known to be a RMW memory op and dst candidate is op1
3539     STOREIND_RMW_DST_IS_OP2,       // StoreInd is known to be a RMW memory op and dst candidate is op2
3540
3541     // One of these denote the reason for storeind is marked as non-RMW operation
3542     STOREIND_RMW_UNSUPPORTED_ADDR, // Addr mode is not yet supported for RMW memory
3543     STOREIND_RMW_UNSUPPORTED_OPER, // Operation is not supported for RMW memory
3544     STOREIND_RMW_UNSUPPORTED_TYPE, // Type is not supported for RMW memory
3545     STOREIND_RMW_INDIR_UNEQUAL     // Indir to read value is not equivalent to indir that writes the value
3546 };
3547
3548 // StoreInd is just a BinOp, with additional RMW status
3549 struct GenTreeStoreInd: public GenTreeIndir
3550 {
3551 #if !CPU_LOAD_STORE_ARCH
3552     // The below flag is set and used during lowering
3553     RMWStatus  gtRMWStatus;
3554
3555     bool  IsRMWStatusUnknown() { return gtRMWStatus == STOREIND_RMW_STATUS_UNKNOWN; }
3556     bool  IsNonRMWMemoryOp() {
3557         return gtRMWStatus == STOREIND_RMW_UNSUPPORTED_ADDR ||
3558                gtRMWStatus == STOREIND_RMW_UNSUPPORTED_OPER ||
3559                gtRMWStatus == STOREIND_RMW_UNSUPPORTED_TYPE ||
3560                gtRMWStatus == STOREIND_RMW_INDIR_UNEQUAL;
3561     }
3562     bool  IsRMWMemoryOp() { return gtRMWStatus == STOREIND_RMW_DST_IS_OP1 || gtRMWStatus == STOREIND_RMW_DST_IS_OP2; }
3563     bool  IsRMWDstOp1() { return gtRMWStatus == STOREIND_RMW_DST_IS_OP1; }
3564     bool  IsRMWDstOp2() { return gtRMWStatus == STOREIND_RMW_DST_IS_OP2; }
3565 #endif //!CPU_LOAD_STORE_ARCH
3566
3567     RMWStatus GetRMWStatus() { 
3568 #if !CPU_LOAD_STORE_ARCH
3569         return gtRMWStatus; 
3570 #else
3571         return STOREIND_RMW_STATUS_UNKNOWN;
3572 #endif
3573     }
3574
3575     void SetRMWStatusDefault() 
3576     {
3577 #if !CPU_LOAD_STORE_ARCH
3578         gtRMWStatus = STOREIND_RMW_STATUS_UNKNOWN;
3579 #endif
3580     }
3581
3582     void SetRMWStatus(RMWStatus status)
3583     {
3584 #if !CPU_LOAD_STORE_ARCH
3585         gtRMWStatus = status;
3586 #endif
3587     }
3588
3589     GenTreePtr&     Data()      { return gtOp2; }
3590
3591     GenTreeStoreInd(var_types type, GenTree *destPtr, GenTree *data) : 
3592     GenTreeIndir(GT_STOREIND, type, destPtr, data)
3593     {
3594         SetRMWStatusDefault();
3595     }
3596
3597 #if DEBUGGABLE_GENTREE
3598 protected:
3599     friend GenTree;
3600     // Used only for GenTree::GetVtableForOper()
3601     GenTreeStoreInd() : GenTreeIndir() { SetRMWStatusDefault(); }
3602 #endif
3603 };
3604
3605
3606 /* gtRetExp -- Place holder for the return expression from an inline candidate (GT_RET_EXPR) */
3607
3608 struct GenTreeRetExpr: public GenTree
3609 {
3610     GenTreePtr      gtInlineCandidate;
3611
3612     CORINFO_CLASS_HANDLE gtRetClsHnd;
3613
3614     GenTreeRetExpr(var_types type) : 
3615         GenTree(GT_RET_EXPR, type) 
3616         {}
3617 #if DEBUGGABLE_GENTREE
3618     GenTreeRetExpr() : GenTree() {}
3619 #endif
3620 };
3621
3622
3623 /* gtStmt   -- 'statement expr' (GT_STMT) */
3624
3625 class InlineContext;
3626
3627 struct GenTreeStmt: public GenTree
3628 {
3629     GenTreePtr      gtStmtExpr;      // root of the expression tree
3630     GenTreePtr      gtStmtList;      // first node (for forward walks)
3631     InlineContext*  gtInlineContext; // The inline context for this statement.
3632   
3633 #if defined(DEBUGGING_SUPPORT) || defined(DEBUG)
3634     IL_OFFSETX      gtStmtILoffsx;   // instr offset (if available)
3635 #endif
3636
3637 #ifdef DEBUG
3638     IL_OFFSET       gtStmtLastILoffs;// instr offset at end of stmt
3639 #endif
3640
3641     bool            gtStmtIsTopLevel()
3642     {
3643         return (gtFlags & GTF_STMT_TOP_LEVEL) != 0;
3644     }
3645
3646     bool            gtStmtIsEmbedded()
3647     {
3648         return !gtStmtIsTopLevel();
3649     }
3650
3651     // Return the next statement, if it is embedded, otherwise nullptr
3652     GenTreeStmt*    gtStmtNextIfEmbedded()
3653     {
3654         GenTree* nextStmt = gtNext;
3655         if (nextStmt != nullptr && nextStmt->gtStmt.gtStmtIsEmbedded())
3656         {
3657             return nextStmt->AsStmt();
3658         }
3659         else
3660         {
3661             return nullptr;
3662         }
3663     }
3664
3665     GenTree*    gtStmtNextTopLevelStmt()
3666     {
3667         GenTree* nextStmt = gtNext;
3668         while (nextStmt != nullptr && nextStmt->gtStmt.gtStmtIsEmbedded())
3669         {
3670             nextStmt = nextStmt->gtNext;
3671         }
3672         return nextStmt;
3673     }
3674
3675     __declspec(property(get=getNextStmt))
3676     GenTreeStmt* gtNextStmt;
3677
3678     __declspec(property(get=getPrevStmt))
3679     GenTreeStmt* gtPrevStmt;
3680
3681     GenTreeStmt* getNextStmt() 
3682     {
3683         if (gtNext == nullptr)
3684             return nullptr;
3685         else
3686             return gtNext->AsStmt();
3687     }
3688
3689     GenTreeStmt* getPrevStmt() 
3690     {
3691         if (gtPrev == nullptr)
3692             return nullptr;
3693         else
3694             return gtPrev->AsStmt();
3695     }
3696
3697     GenTreeStmt(GenTreePtr expr, IL_OFFSETX offset)
3698         : GenTree(GT_STMT, TYP_VOID)
3699         , gtStmtExpr(expr)
3700         , gtStmtList(nullptr)
3701         , gtInlineContext(nullptr)
3702 #if defined(DEBUGGING_SUPPORT) || defined(DEBUG)
3703         , gtStmtILoffsx(offset)
3704 #endif
3705 #ifdef DEBUG
3706         , gtStmtLastILoffs(BAD_IL_OFFSET)
3707 #endif
3708     {
3709         // Statements can't have statements as part of their expression tree.
3710         assert(expr->gtOper != GT_STMT);
3711
3712         gtFlags |= GTF_STMT_TOP_LEVEL;
3713
3714         // Set the statement to have the same costs as the top node of the tree.
3715         // This is used long before costs have been assigned, so we need to copy
3716         // the raw costs.
3717         CopyRawCosts(expr);
3718     }
3719
3720 #if DEBUGGABLE_GENTREE
3721     GenTreeStmt() : GenTree(GT_STMT, TYP_VOID) {}
3722 #endif
3723 };
3724
3725
3726
3727
3728 /*  NOTE: Any tree nodes that are larger than 8 bytes (two ints or
3729     pointers) must be flagged as 'large' in GenTree::InitNodeSize().
3730  */
3731
3732                 
3733 /* gtClsVar -- 'static data member' (GT_CLS_VAR) */
3734
3735 struct GenTreeClsVar: public GenTree
3736 {
3737     CORINFO_FIELD_HANDLE    gtClsVarHnd;
3738     FieldSeqNode*           gtFieldSeq;
3739
3740     GenTreeClsVar(var_types type, CORINFO_FIELD_HANDLE clsVarHnd, FieldSeqNode* fldSeq) : 
3741         GenTree(GT_CLS_VAR, type), 
3742         gtClsVarHnd(clsVarHnd),
3743         gtFieldSeq(fldSeq)
3744         {
3745             gtFlags |= GTF_GLOB_REF;
3746         }
3747 #if DEBUGGABLE_GENTREE
3748     GenTreeClsVar() : GenTree() {}
3749 #endif
3750 };
3751
3752 /* gtArgPlace -- 'register argument placeholder' (GT_ARGPLACE) */
3753
3754 struct GenTreeArgPlace: public GenTree
3755 {
3756     CORINFO_CLASS_HANDLE    gtArgPlaceClsHnd;    // Needed when we have a TYP_STRUCT argument
3757
3758     GenTreeArgPlace(var_types type, CORINFO_CLASS_HANDLE clsHnd) : 
3759         GenTree(GT_ARGPLACE, type), 
3760         gtArgPlaceClsHnd(clsHnd) 
3761         {}
3762 #if DEBUGGABLE_GENTREE
3763     GenTreeArgPlace() : GenTree() {}
3764 #endif
3765 };
3766
3767 /* gtLabel  -- code label target    (GT_LABEL) */
3768
3769 struct GenTreeLabel: public GenTree
3770 {
3771     BasicBlock* gtLabBB;
3772
3773     GenTreeLabel(BasicBlock* bb) : 
3774         GenTree(GT_LABEL, TYP_VOID), 
3775         gtLabBB(bb) 
3776         {}
3777 #if DEBUGGABLE_GENTREE
3778     GenTreeLabel() : GenTree() {}
3779 #endif
3780 };
3781
3782 /* gtPhiArg -- phi node rhs argument, var = phi(phiarg, phiarg, phiarg...); GT_PHI_ARG */
3783 struct GenTreePhiArg: public GenTreeLclVarCommon
3784 {
3785     BasicBlock  *   gtPredBB;
3786
3787     GenTreePhiArg(var_types type, unsigned lclNum, unsigned snum, BasicBlock* block)
3788         : GenTreeLclVarCommon(GT_PHI_ARG, type, lclNum)
3789         , gtPredBB(block)
3790     { 
3791         SetSsaNum(snum);
3792     }
3793
3794 #if DEBUGGABLE_GENTREE
3795     GenTreePhiArg() : GenTreeLclVarCommon() {}
3796 #endif
3797 };
3798
3799 /* gtPutArgStk -- Argument passed on stack */
3800
3801 struct GenTreePutArgStk: public GenTreeUnOp
3802 {
3803     unsigned gtSlotNum;        // Slot number of the argument to be passed on stack
3804
3805 #if FEATURE_FASTTAILCALL
3806     bool putInIncomingArgArea;    // Whether this arg needs to be placed in incoming arg area.
3807                                   // By default this is false and will be placed in out-going arg area.
3808                                   // Fast tail calls set this to true.
3809                                   // In future if we need to add more such bool fields consider bit fields.
3810
3811     GenTreePutArgStk(
3812             genTreeOps oper,
3813             var_types type,
3814             unsigned slotNum
3815             FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(unsigned numSlots)
3816             FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(bool isStruct),
3817             bool _putInIncomingArgArea = false
3818             DEBUGARG(GenTreePtr callNode = NULL)
3819             DEBUGARG(bool largeNode = false))
3820         : 
3821         GenTreeUnOp(oper, type DEBUGARG(largeNode)),
3822         gtSlotNum(slotNum),
3823         putInIncomingArgArea(_putInIncomingArgArea)
3824 #ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
3825         , gtPutArgStkKind(PutArgStkKindInvalid),
3826         gtNumSlots(numSlots),
3827         gtIsStruct(isStruct),
3828         gtNumberReferenceSlots(0),
3829         gtGcPtrs(nullptr)
3830 #endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
3831     {
3832 #ifdef DEBUG
3833         gtCall = callNode;
3834 #endif
3835     }
3836
3837
3838     GenTreePutArgStk(
3839             genTreeOps oper,
3840             var_types type,
3841             GenTreePtr op1,
3842             unsigned slotNum
3843             FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(unsigned numSlots)
3844             FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(bool isStruct),
3845             bool _putInIncomingArgArea = false
3846             DEBUGARG(GenTreePtr callNode = NULL)
3847             DEBUGARG(bool largeNode = false))
3848         :
3849         GenTreeUnOp(oper, type, op1 DEBUGARG(largeNode)), 
3850         gtSlotNum(slotNum),
3851         putInIncomingArgArea(_putInIncomingArgArea)
3852 #ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
3853         , gtPutArgStkKind(PutArgStkKindInvalid),
3854         gtNumSlots(numSlots),
3855         gtIsStruct(isStruct),
3856         gtNumberReferenceSlots(0),
3857         gtGcPtrs(nullptr)
3858 #endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
3859     {
3860 #ifdef DEBUG
3861         gtCall = callNode;
3862 #endif
3863     }
3864
3865 #else  // !FEATURE_FASTTAILCALL
3866
3867     GenTreePutArgStk(
3868             genTreeOps oper,
3869             var_types type,
3870             unsigned slotNum
3871             FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(unsigned numSlots)
3872             FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(bool isStruct)
3873             DEBUGARG(GenTreePtr callNode = NULL)
3874             DEBUGARG(bool largeNode = false))
3875         :
3876         GenTreeUnOp(oper, type DEBUGARG(largeNode)),
3877         gtSlotNum(slotNum)
3878 #ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
3879         , gtPutArgStkKind(PutArgStkKindInvalid),
3880         gtNumSlots(numSlots),
3881         gtIsStruct(isStruct),
3882         gtNumberReferenceSlots(0),
3883         gtGcPtrs(nullptr)
3884 #endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
3885     {
3886 #ifdef DEBUG
3887         gtCall = callNode;
3888 #endif
3889     }
3890
3891
3892     GenTreePutArgStk(
3893             genTreeOps oper,
3894             var_types type,
3895             GenTreePtr op1,
3896             unsigned slotNum
3897             FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(unsigned numSlots)
3898             FEATURE_UNIX_AMD64_STRUCT_PASSING_ONLY_ARG(bool isStruct)
3899             DEBUGARG(GenTreePtr callNode = NULL)
3900             DEBUGARG(bool largeNode = false))
3901         :
3902         GenTreeUnOp(oper, type, op1 DEBUGARG(largeNode)), 
3903         gtSlotNum(slotNum)
3904 #ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
3905         , gtPutArgStkKind(PutArgStkKindInvalid),
3906         gtNumSlots(numSlots),
3907         gtIsStruct(isStruct),
3908         gtNumberReferenceSlots(0),
3909         gtGcPtrs(nullptr)
3910 #endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
3911     {
3912 #ifdef DEBUG
3913         gtCall = callNode;
3914 #endif
3915     }
3916 #endif // FEATURE_FASTTAILCALL
3917
3918     unsigned getArgOffset() { return gtSlotNum * TARGET_POINTER_SIZE; }
3919
3920 #ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
3921     unsigned getArgSize() { return gtNumSlots * TARGET_POINTER_SIZE; }
3922 #endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
3923
3924 #ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
3925     //------------------------------------------------------------------------
3926     // setGcPointers: Sets the number of references and the layout of the struct object returned by the VM.
3927     //
3928     // Arguments:
3929     //    numPointers - Number of pointer references.
3930     //    pointers    - layout of the struct (with pointers marked.)
3931     //
3932     // Return Value:
3933     //    None
3934     //
3935     // Notes:
3936     //    This data is used in the codegen for GT_PUTARG_STK to decide how to copy the struct to the stack by value.
3937     //    If no pointer references are used, block copying instructions are used.
3938     //    Otherwise the pointer reference slots are copied atomically in a way that gcinfo is emitted.
3939     //    Any non pointer references between the pointer reference slots are copied in block fashion.
3940     //
3941     void setGcPointers(unsigned numPointers, BYTE* pointers)
3942     {
3943         gtNumberReferenceSlots = numPointers;
3944         gtGcPtrs = pointers;
3945     }
3946 #endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
3947
3948 #ifdef DEBUG
3949     GenTreePtr      gtCall;                // the call node to which this argument belongs
3950 #endif
3951
3952 #ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
3953     // Instruction selection: during codegen time, what code sequence we will be using
3954     // to encode this operation.
3955
3956     enum PutArgStkKind : __int8
3957     {
3958         PutArgStkKindInvalid,
3959         PutArgStkKindRepInstr,
3960         PutArgStkKindUnroll,
3961     };
3962
3963     PutArgStkKind gtPutArgStkKind;
3964
3965     unsigned gtNumSlots;              // Number of slots for the argument to be passed on stack
3966     bool     gtIsStruct;              // This stack arg is a struct.
3967     unsigned gtNumberReferenceSlots;  // Number of reference slots.
3968     BYTE*    gtGcPtrs;                // gcPointers
3969 #endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
3970
3971 #if DEBUGGABLE_GENTREE
3972     GenTreePutArgStk() : GenTreeUnOp() {}
3973 #endif
3974 };
3975
3976 // Represents GT_COPY or GT_RELOAD node
3977 struct GenTreeCopyOrReload : public GenTreeUnOp
3978 {
3979     // State required to support copy/reload of a multi-reg call node.
3980     // First register is is always given by gtRegNum.
3981     //
3982 #if FEATURE_MULTIREG_RET
3983     regNumber gtOtherRegs[MAX_RET_REG_COUNT - 1];
3984 #endif
3985
3986     //----------------------------------------------------------
3987     // ClearOtherRegs: set gtOtherRegs to REG_NA.
3988     //
3989     // Arguments:
3990     //    None
3991     //
3992     // Return Value:
3993     //    None
3994     //
3995     void ClearOtherRegs()
3996     {
3997 #if FEATURE_MULTIREG_RET
3998         for (unsigned i = 0; i < MAX_RET_REG_COUNT - 1; ++i)
3999         {
4000             gtOtherRegs[i] = REG_NA;
4001         }
4002 #endif
4003     }
4004
4005     //-----------------------------------------------------------
4006     // GetRegNumByIdx: Get regNumber of ith position.
4007     //
4008     // Arguments:
4009     //    idx   -   register position.
4010     //
4011     // Return Value:
4012     //    Returns regNumber assigned to ith position.
4013     //
4014     regNumber GetRegNumByIdx(unsigned idx) const
4015     {
4016         assert(idx < MAX_RET_REG_COUNT);
4017
4018         if (idx == 0)
4019         {
4020             return gtRegNum;
4021         }
4022
4023 #if FEATURE_MULTIREG_RET
4024         return gtOtherRegs[idx - 1];
4025 #else
4026         return REG_NA;
4027 #endif
4028     }
4029
4030     //-----------------------------------------------------------
4031     // SetRegNumByIdx: Set the regNumber for ith position.
4032     //
4033     // Arguments:
4034     //    reg   -   reg number 
4035     //    idx   -   register position.
4036     //
4037     // Return Value:
4038     //    None.
4039     //
4040     void SetRegNumByIdx(regNumber reg, unsigned idx)
4041     {
4042         assert(idx < MAX_RET_REG_COUNT);
4043
4044         if (idx == 0)
4045         {
4046             gtRegNum = reg;
4047         }
4048 #if FEATURE_MULTIREG_RET
4049         else
4050         {
4051             gtOtherRegs[idx - 1] = reg;
4052             assert(gtOtherRegs[idx - 1] == reg);
4053         }
4054 #else
4055         else
4056         {
4057             unreached();
4058         }
4059 #endif
4060     }
4061
4062     //----------------------------------------------------------------------------
4063     // CopyOtherRegs: copy multi-reg state from the given copy/reload node to this
4064     // node.
4065     //
4066     // Arguments:
4067     //    from  -  GenTree node from which to copy multi-reg state
4068     //
4069     // Return Value:
4070     //    None
4071     //
4072     // TODO-ARM: Implement this routine for Arm64 and Arm32
4073     // TODO-X86: Implement this routine for x86
4074     void CopyOtherRegs(GenTreeCopyOrReload* from)
4075     {
4076         assert(OperGet() == from->OperGet());
4077
4078 #ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
4079         for (unsigned i = 0; i < MAX_RET_REG_COUNT - 1; ++i)
4080         {
4081             gtOtherRegs[i] = from->gtOtherRegs[i];
4082         }
4083 #endif
4084     }
4085
4086     GenTreeCopyOrReload(genTreeOps oper,
4087         var_types type,
4088         GenTree* op1) : GenTreeUnOp(oper, type, op1)
4089     {
4090         gtRegNum = REG_NA;
4091         ClearOtherRegs();
4092     }
4093
4094 #if DEBUGGABLE_GENTREE
4095     GenTreeCopyOrReload() : GenTreeUnOp() {}
4096 #endif
4097 };
4098
4099 //------------------------------------------------------------------------
4100 // Deferred inline functions of GenTree -- these need the subtypes above to
4101 // be defined already.
4102 //------------------------------------------------------------------------
4103
4104 //------------------------------------------------------------------------
4105 // IsFPZero: Checks whether this is a floating point constant with value 0.0
4106 //
4107 // Return Value:
4108 //    Returns true iff the tree is an GT_CNS_DBL, with value of 0.0.
4109
4110 inline bool GenTree::IsFPZero()
4111 {
4112     if ((gtOper == GT_CNS_DBL) && (gtDblCon.gtDconVal == 0.0))
4113         return true;
4114     return false;
4115 }
4116
4117 //------------------------------------------------------------------------
4118 // IsIntegralConst: Checks whether this is a constant node with the given value
4119 //
4120 // Arguments:
4121 //    constVal - the value of interest
4122 //
4123 // Return Value:
4124 //    Returns true iff the tree is an integral constant opcode, with
4125 //    the given value.
4126 //
4127 // Notes:
4128 //    Like gtIconVal, the argument is of ssize_t, so cannot check for
4129 //    long constants in a target-independent way.
4130
4131 inline bool GenTree::IsIntegralConst(ssize_t constVal)
4132
4133 {
4134     if ((gtOper == GT_CNS_INT) && (gtIntConCommon.IconValue() == constVal))
4135         return true;
4136
4137     if ((gtOper == GT_CNS_LNG) && (gtIntConCommon.LngValue() == constVal))
4138         return true;
4139
4140     return false;
4141 }
4142
4143 inline bool GenTree::IsBoxedValue()
4144 {
4145     assert(gtOper != GT_BOX || gtBox.BoxOp() != NULL);
4146     return (gtOper == GT_BOX) && (gtFlags & GTF_BOX_VALUE);
4147 }
4148
4149 inline GenTreePtr GenTree::MoveNext()
4150 {
4151     assert(IsList());
4152     return gtOp.gtOp2;
4153 }
4154
4155 #ifdef DEBUG
4156 //------------------------------------------------------------------------
4157 // IsListForMultiRegArg: Given an GenTree node that represents an argument
4158 //                       enforce (or don't enforce) the following invariant.
4159 //
4160 // For LEGACY_BACKEND or architectures that don't support MultiReg args
4161 // we don't allow a GT_LIST at all.
4162 //
4163 // Currently for AMD64 UNIX we allow a limited case where a GT_LIST is 
4164 // allowed but every element must be a GT_LCL_FLD.
4165 //
4166 // For the future targets that allow for Multireg args (and this includes
4167 //  the current ARM64 target) we allow a GT_LIST of arbitrary nodes, these
4168 //  would typically start out as GT_LCL_VARs or GT_LCL_FLDS or GT_INDs, 
4169 //  but could be changed into constants or GT_COMMA trees by the later 
4170 //  optimization phases.
4171 // 
4172 // Arguments:
4173 //    instance method for a GenTree node
4174 //
4175 // Return values:
4176 //    true:      the GenTree node is accepted as a valid argument
4177 //    false:     the GenTree node is not accepted as a valid argumeny
4178 //
4179 inline bool GenTree::IsListForMultiRegArg()
4180 {
4181     if (!IsList())
4182     {
4183         // We don't have a GT_LIST, so just return true.
4184         return true;
4185     }
4186     else  // We do have a GT_LIST
4187     {
4188 #if defined(LEGACY_BACKEND) || !FEATURE_MULTIREG_ARGS
4189
4190         // Not allowed to have a GT_LIST for an argument 
4191         // unless we have a RyuJIT backend and FEATURE_MULTIREG_ARGS
4192
4193         return false;
4194
4195 #else  // we have RyuJIT backend and FEATURE_MULTIREG_ARGS
4196
4197 #ifdef FEATURE_UNIX_AMD64_STRUCT_PASSING
4198         // For UNIX ABI we currently only allow a GT_LIST of GT_LCL_FLDs nodes 
4199         GenTree* gtListPtr = this;
4200         while (gtListPtr != nullptr) 
4201         {
4202             // ToDo: fix UNIX_AMD64 so that we do not generate this kind of a List
4203             //  Note the list as currently created is malformed, as the last entry is a nullptr
4204             if (gtListPtr->Current() == nullptr)
4205                 break;
4206
4207             // Only a list of GT_LCL_FLDs is allowed
4208             if (gtListPtr->Current()->OperGet() != GT_LCL_FLD)
4209             {
4210                 return false;
4211             }
4212             gtListPtr = gtListPtr->MoveNext();
4213         }
4214 #endif  // FEATURE_UNIX_AMD64_STRUCT_PASSING
4215
4216         // Note that for non-UNIX ABI the GT_LIST may contain any node
4217         //
4218         // We allow this GT_LIST as an argument 
4219         return true;
4220
4221 #endif  // RyuJIT backend and FEATURE_MULTIREG_ARGS
4222     }
4223 }
4224 #endif // DEBUG
4225
4226 inline GenTreePtr GenTree::Current()
4227 {
4228     assert(IsList());
4229     return gtOp.gtOp1;
4230 }
4231
4232 inline GenTreePtr *GenTree::pCurrent()
4233 {
4234     assert(IsList());
4235     return &(gtOp.gtOp1);
4236 }
4237
4238 inline GenTreePtr      GenTree::gtGetOp1() 
4239 {
4240     return gtOp.gtOp1;
4241 }
4242
4243 #ifdef DEBUG
4244 /* static */
4245 inline bool GenTree::RequiresNonNullOp2(genTreeOps oper)
4246 {
4247     switch (oper)
4248     {
4249     case GT_ADD:
4250     case GT_SUB:
4251     case GT_MUL:
4252     case GT_DIV:
4253     case GT_MOD:
4254     case GT_UDIV:
4255     case GT_UMOD:
4256     case GT_OR:
4257     case GT_XOR:
4258     case GT_AND:
4259     case GT_LSH:
4260     case GT_RSH:
4261     case GT_RSZ:
4262     case GT_ROL:
4263     case GT_ROR:
4264     case GT_INDEX:
4265     case GT_ASG:
4266     case GT_ASG_ADD:
4267     case GT_ASG_SUB:
4268     case GT_ASG_MUL:
4269     case GT_ASG_DIV:
4270     case GT_ASG_MOD:
4271     case GT_ASG_UDIV:
4272     case GT_ASG_UMOD:
4273     case GT_ASG_OR:
4274     case GT_ASG_XOR:
4275     case GT_ASG_AND:
4276     case GT_ASG_LSH:
4277     case GT_ASG_RSH:
4278     case GT_ASG_RSZ:
4279     case GT_EQ:
4280     case GT_NE:
4281     case GT_LT:
4282     case GT_LE:
4283     case GT_GE:
4284     case GT_GT:
4285     case GT_COMMA:
4286     case GT_QMARK:
4287     case GT_COLON:
4288     case GT_MKREFANY:
4289     case GT_INITBLK:
4290     case GT_COPYBLK:
4291         return true;
4292     default:
4293         return false;
4294     }
4295 }
4296 #endif // DEBUG
4297
4298 inline GenTreePtr      GenTree::gtGetOp2() 
4299 {
4300     /* gtOp.gtOp2 is only valid for GTK_BINOP nodes. */
4301
4302     GenTreePtr op2 = OperIsBinary() ? gtOp.gtOp2 : nullptr;
4303
4304     // This documents the genTreeOps for which gtOp.gtOp2 cannot be nullptr.
4305     // This helps prefix in its analyis of code which calls gtGetOp2()
4306
4307     assert((op2 != nullptr) || !RequiresNonNullOp2(gtOper));
4308
4309     return op2;
4310 }
4311
4312 inline GenTreePtr      GenTree::gtEffectiveVal(bool commaOnly)
4313 {
4314     switch (gtOper)
4315     {
4316     case GT_COMMA:
4317         return gtOp.gtOp2->gtEffectiveVal(commaOnly);
4318
4319     case GT_NOP:
4320         if (!commaOnly && gtOp.gtOp1 != NULL) 
4321             return gtOp.gtOp1->gtEffectiveVal();
4322         break;
4323
4324     default:
4325         break;
4326     }       
4327
4328     return this;
4329 }
4330
4331 inline GenTree*         GenTree::gtSkipReloadOrCopy()
4332 {
4333     // There can be only one reload or copy (we can't have a reload/copy of a reload/copy)
4334     if (gtOper == GT_RELOAD || gtOper == GT_COPY)
4335     {
4336         assert(gtGetOp1()->OperGet() != GT_RELOAD && gtGetOp1()->OperGet() != GT_COPY);
4337         return gtGetOp1();
4338     }
4339     return this;
4340 }
4341
4342 //-----------------------------------------------------------------------------------
4343 // IsMultiRegCall: whether a call node returning its value in more than one register
4344 //
4345 // Arguments:
4346 //     None
4347 //
4348 // Return Value:
4349 //     Returns true if this GenTree is a multi register returning call 
4350 inline bool  GenTree::IsMultiRegCall() const
4351 {
4352     if (this->IsCall())
4353     {
4354         // We cannot use AsCall() as it is not declared const
4355         const GenTreeCall* call = reinterpret_cast<const GenTreeCall *>(this);
4356         return call->HasMultiRegRetVal();
4357     }
4358
4359     return false;
4360 }
4361
4362 //-------------------------------------------------------------------------
4363 // IsCopyOrReload: whether this is a GT_COPY or GT_RELOAD node.
4364 //
4365 // Arguments:
4366 //     None
4367 //
4368 // Return Value:
4369 //     Returns true if this GenTree is a copy or reload node.
4370 inline bool GenTree::IsCopyOrReload() const
4371 {
4372     return (gtOper == GT_COPY || gtOper == GT_RELOAD);
4373 }
4374
4375 //-----------------------------------------------------------------------------------
4376 // IsCopyOrReloadOfMultiRegCall: whether this is a GT_COPY or GT_RELOAD of a multi-reg
4377 // call node.
4378 //
4379 // Arguments:
4380 //     None
4381 //
4382 // Return Value:
4383 //     Returns true if this GenTree is a copy or reload of multi-reg call node.
4384 inline bool GenTree::IsCopyOrReloadOfMultiRegCall() const
4385 {
4386     if (IsCopyOrReload())
4387     {
4388         GenTree* t = const_cast<GenTree*>(this);
4389         return t->gtGetOp1()->IsMultiRegCall();
4390     }
4391
4392     return false;
4393 }
4394
4395 inline bool GenTree::IsCnsIntOrI() const
4396 {
4397     return (gtOper == GT_CNS_INT);
4398 }
4399
4400 inline bool GenTree::IsIntegralConst() const
4401 {
4402 #ifdef _TARGET_64BIT_
4403     return IsCnsIntOrI();
4404 #else // !_TARGET_64BIT_
4405     return ((gtOper == GT_CNS_INT) || (gtOper == GT_CNS_LNG));
4406 #endif // !_TARGET_64BIT_
4407 }
4408
4409 inline bool GenTree::IsIntCnsFitsInI32()
4410 {
4411 #ifdef _TARGET_64BIT_
4412     return IsCnsIntOrI() && ((int)gtIntConCommon.IconValue() == gtIntConCommon.IconValue());
4413 #else // !_TARGET_64BIT_
4414     return IsCnsIntOrI();
4415 #endif // !_TARGET_64BIT_
4416 }
4417
4418 inline bool GenTree::IsCnsFltOrDbl() const
4419 {
4420     return OperGet() == GT_CNS_DBL;
4421 }
4422
4423 inline bool GenTree::IsCnsNonZeroFltOrDbl()
4424 {
4425     if (OperGet() == GT_CNS_DBL)
4426     {
4427         double constValue = gtDblCon.gtDconVal;
4428         return *(__int64*)&constValue != 0;
4429     }
4430
4431     return false;
4432 }
4433
4434 inline bool GenTree::IsHelperCall() { return OperGet() == GT_CALL && gtCall.gtCallType == CT_HELPER; }
4435
4436 inline var_types GenTree::CastFromType() { return this->gtCast.CastOp()->TypeGet(); }
4437 inline var_types& GenTree::CastToType()  { return this->gtCast.gtCastType; }
4438
4439
4440 /*****************************************************************************/
4441
4442 #ifndef _HOST_64BIT_
4443 #include <poppack.h>
4444 #endif
4445
4446 /*****************************************************************************/
4447
4448 #if     SMALL_TREE_NODES
4449
4450 // In debug, on some platforms (e.g., when LATE_DISASM is defined), GenTreeIntCon is bigger than GenTreeLclFld.
4451 const
4452 size_t              TREE_NODE_SZ_SMALL = max(sizeof(GenTreeIntCon), sizeof(GenTreeLclFld));
4453
4454 #endif // SMALL_TREE_NODES
4455
4456 const
4457 size_t              TREE_NODE_SZ_LARGE = sizeof(GenTreeCall);
4458
4459 /*****************************************************************************
4460  * Types returned by GenTree::lvaLclVarRefs()
4461  */
4462
4463 enum varRefKinds
4464 {
4465     VR_INVARIANT  = 0x00,      // an invariant value
4466     VR_NONE       = 0x00,
4467     VR_IND_REF    = 0x01,      // an object reference
4468     VR_IND_SCL    = 0x02,      // a non-object reference
4469     VR_GLB_VAR    = 0x04,      // a global (clsVar)
4470 };
4471 // Add a temp define to avoid merge conflict.
4472 #define VR_IND_PTR VR_IND_REF
4473
4474 /*****************************************************************************/
4475 #endif  // !GENTREE_H
4476 /*****************************************************************************/
4477