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