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