Merge pull request #21864 from fiigii/fixscalarmem
[platform/upstream/coreclr.git] / src / jit / compiler.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                           Compiler                                        XX
9 XX                                                                           XX
10 XX  Represents the method data we are currently JIT-compiling.               XX
11 XX  An instance of this class is created for every method we JIT.            XX
12 XX  This contains all the info needed for the method. So allocating a        XX
13 XX  a new instance per method makes it thread-safe.                          XX
14 XX  It should be used to do all the memory management for the compiler run.  XX
15 XX                                                                           XX
16 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
17 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
18 */
19
20 /*****************************************************************************/
21 #ifndef _COMPILER_H_
22 #define _COMPILER_H_
23 /*****************************************************************************/
24
25 #include "jit.h"
26 #include "opcode.h"
27 #include "varset.h"
28 #include "jitstd.h"
29 #include "jithashtable.h"
30 #include "gentree.h"
31 #include "lir.h"
32 #include "block.h"
33 #include "inline.h"
34 #include "jiteh.h"
35 #include "instr.h"
36 #include "regalloc.h"
37 #include "sm.h"
38 #include "cycletimer.h"
39 #include "blockset.h"
40 #include "arraystack.h"
41 #include "hashbv.h"
42 #include "jitexpandarray.h"
43 #include "tinyarray.h"
44 #include "valuenum.h"
45 #include "reglist.h"
46 #include "jittelemetry.h"
47 #include "namedintrinsiclist.h"
48 #ifdef LATE_DISASM
49 #include "disasm.h"
50 #endif
51
52 #include "codegeninterface.h"
53 #include "regset.h"
54 #include "jitgcinfo.h"
55
56 #if DUMP_GC_TABLES && defined(JIT32_GCENCODER)
57 #include "gcdump.h"
58 #endif
59
60 #include "emit.h"
61
62 #include "hwintrinsic.h"
63 #include "simd.h"
64
65 // This is only used locally in the JIT to indicate that
66 // a verification block should be inserted
67 #define SEH_VERIFICATION_EXCEPTION 0xe0564552 // VER
68
69 /*****************************************************************************
70  *                  Forward declarations
71  */
72
73 struct InfoHdr;            // defined in GCInfo.h
74 struct escapeMapping_t;    // defined in flowgraph.cpp
75 class emitter;             // defined in emit.h
76 struct ShadowParamVarInfo; // defined in GSChecks.cpp
77 struct InitVarDscInfo;     // defined in register_arg_convention.h
78 class FgStack;             // defined in flowgraph.cpp
79 #if FEATURE_ANYCSE
80 class CSE_DataFlow; // defined in OptCSE.cpp
81 #endif
82 #ifdef DEBUG
83 struct IndentStack;
84 #endif
85
86 class Lowering; // defined in lower.h
87
88 // The following are defined in this file, Compiler.h
89
90 class Compiler;
91
92 /*****************************************************************************
93  *                  Unwind info
94  */
95
96 #include "unwind.h"
97
98 /*****************************************************************************/
99
100 //
101 // Declare global operator new overloads that use the compiler's arena allocator
102 //
103
104 // I wanted to make the second argument optional, with default = CMK_Unknown, but that
105 // caused these to be ambiguous with the global placement new operators.
106 void* __cdecl operator new(size_t n, Compiler* context, CompMemKind cmk);
107 void* __cdecl operator new[](size_t n, Compiler* context, CompMemKind cmk);
108 void* __cdecl operator new(size_t n, void* p, const jitstd::placement_t& syntax_difference);
109
110 // Requires the definitions of "operator new" so including "LoopCloning.h" after the definitions.
111 #include "loopcloning.h"
112
113 /*****************************************************************************/
114
115 /* This is included here and not earlier as it needs the definition of "CSE"
116  * which is defined in the section above */
117
118 /*****************************************************************************/
119
120 unsigned genLog2(unsigned value);
121 unsigned genLog2(unsigned __int64 value);
122
123 var_types genActualType(var_types type);
124 var_types genUnsignedType(var_types type);
125 var_types genSignedType(var_types type);
126
127 unsigned ReinterpretHexAsDecimal(unsigned);
128
129 /*****************************************************************************/
130
131 const unsigned FLG_CCTOR = (CORINFO_FLG_CONSTRUCTOR | CORINFO_FLG_STATIC);
132
133 #ifdef DEBUG
134 const int BAD_STK_OFFS = 0xBAADF00D; // for LclVarDsc::lvStkOffs
135 #endif
136
137 // The following holds the Local var info (scope information)
138 typedef const char* VarName; // Actual ASCII string
139 struct VarScopeDsc
140 {
141     IL_OFFSET vsdLifeBeg; // instr offset of beg of life
142     IL_OFFSET vsdLifeEnd; // instr offset of end of life
143     unsigned  vsdVarNum;  // (remapped) LclVarDsc number
144
145 #ifdef DEBUG
146     VarName vsdName; // name of the var
147 #endif
148
149     unsigned vsdLVnum; // 'which' in eeGetLVinfo().
150                        // Also, it is the index of this entry in the info.compVarScopes array,
151                        // which is useful since the array is also accessed via the
152                        // compEnterScopeList and compExitScopeList sorted arrays.
153 };
154
155 // This is the location of a SSA definition.
156 struct DefLoc
157 {
158     BasicBlock* m_blk;
159     GenTree*    m_tree;
160
161     DefLoc() : m_blk(nullptr), m_tree(nullptr)
162     {
163     }
164
165     DefLoc(BasicBlock* block, GenTree* tree) : m_blk(block), m_tree(tree)
166     {
167     }
168 };
169
170 // This class stores information associated with a LclVar SSA definition.
171 class LclSsaVarDsc
172 {
173 public:
174     LclSsaVarDsc()
175     {
176     }
177
178     LclSsaVarDsc(BasicBlock* block, GenTree* tree) : m_defLoc(block, tree)
179     {
180     }
181
182     ValueNumPair m_vnPair;
183     DefLoc       m_defLoc;
184 };
185
186 // This class stores information associated with a memory SSA definition.
187 class SsaMemDef
188 {
189 public:
190     ValueNumPair m_vnPair;
191 };
192
193 //------------------------------------------------------------------------
194 // SsaDefArray: A resizable array of SSA definitions.
195 //
196 // Unlike an ordinary resizable array implementation, this allows only element
197 // addition (by calling AllocSsaNum) and has special handling for RESERVED_SSA_NUM
198 // (basically it's a 1-based array). The array doesn't impose any particular
199 // requirements on the elements it stores and AllocSsaNum forwards its arguments
200 // to the array element constructor, this way the array supports both LclSsaVarDsc
201 // and SsaMemDef elements.
202 //
203 template <typename T>
204 class SsaDefArray
205 {
206     T*       m_array;
207     unsigned m_arraySize;
208     unsigned m_count;
209
210     static_assert_no_msg(SsaConfig::RESERVED_SSA_NUM == 0);
211     static_assert_no_msg(SsaConfig::FIRST_SSA_NUM == 1);
212
213     // Get the minimum valid SSA number.
214     unsigned GetMinSsaNum() const
215     {
216         return SsaConfig::FIRST_SSA_NUM;
217     }
218
219     // Increase (double) the size of the array.
220     void GrowArray(CompAllocator alloc)
221     {
222         unsigned oldSize = m_arraySize;
223         unsigned newSize = max(2, oldSize * 2);
224
225         T* newArray = alloc.allocate<T>(newSize);
226
227         for (unsigned i = 0; i < oldSize; i++)
228         {
229             newArray[i] = m_array[i];
230         }
231
232         m_array     = newArray;
233         m_arraySize = newSize;
234     }
235
236 public:
237     // Construct an empty SsaDefArray.
238     SsaDefArray() : m_array(nullptr), m_arraySize(0), m_count(0)
239     {
240     }
241
242     // Reset the array (used only if the SSA form is reconstructed).
243     void Reset()
244     {
245         m_count = 0;
246     }
247
248     // Allocate a new SSA number (starting with SsaConfig::FIRST_SSA_NUM).
249     template <class... Args>
250     unsigned AllocSsaNum(CompAllocator alloc, Args&&... args)
251     {
252         if (m_count == m_arraySize)
253         {
254             GrowArray(alloc);
255         }
256
257         unsigned ssaNum    = GetMinSsaNum() + m_count;
258         m_array[m_count++] = T(jitstd::forward<Args>(args)...);
259
260         // Ensure that the first SSA number we allocate is SsaConfig::FIRST_SSA_NUM
261         assert((ssaNum == SsaConfig::FIRST_SSA_NUM) || (m_count > 1));
262
263         return ssaNum;
264     }
265
266     // Get the number of SSA definitions in the array.
267     unsigned GetCount() const
268     {
269         return m_count;
270     }
271
272     // Get a pointer to the SSA definition at the specified index.
273     T* GetSsaDefByIndex(unsigned index)
274     {
275         assert(index < m_count);
276         return &m_array[index];
277     }
278
279     // Check if the specified SSA number is valid.
280     bool IsValidSsaNum(unsigned ssaNum) const
281     {
282         return (GetMinSsaNum() <= ssaNum) && (ssaNum < (GetMinSsaNum() + m_count));
283     }
284
285     // Get a pointer to the SSA definition associated with the specified SSA number.
286     T* GetSsaDef(unsigned ssaNum)
287     {
288         assert(ssaNum != SsaConfig::RESERVED_SSA_NUM);
289         return GetSsaDefByIndex(ssaNum - GetMinSsaNum());
290     }
291 };
292
293 enum RefCountState
294 {
295     RCS_INVALID, // not valid to get/set ref counts
296     RCS_EARLY,   // early counts for struct promotion and struct passing
297     RCS_NORMAL,  // normal ref counts (from lvaMarkRefs onward)
298 };
299
300 class LclVarDsc
301 {
302 public:
303     // The constructor. Most things can just be zero'ed.
304     //
305     // Initialize the ArgRegs to REG_STK.
306     // Morph will update if this local is passed in a register.
307     LclVarDsc()
308         : _lvArgReg(REG_STK)
309         ,
310 #if FEATURE_MULTIREG_ARGS
311         _lvOtherArgReg(REG_STK)
312         ,
313 #endif // FEATURE_MULTIREG_ARGS
314 #if ASSERTION_PROP
315         lvRefBlks(BlockSetOps::UninitVal())
316         ,
317 #endif // ASSERTION_PROP
318         lvPerSsaData()
319     {
320     }
321
322     // note this only packs because var_types is a typedef of unsigned char
323     var_types lvType : 5; // TYP_INT/LONG/FLOAT/DOUBLE/REF
324
325     unsigned char lvIsParam : 1;           // is this a parameter?
326     unsigned char lvIsRegArg : 1;          // is this a register argument?
327     unsigned char lvFramePointerBased : 1; // 0 = off of REG_SPBASE (e.g., ESP), 1 = off of REG_FPBASE (e.g., EBP)
328
329     unsigned char lvStructGcCount : 3; // if struct, how many GC pointer (stop counting at 7). The only use of values >1
330                                        // is to help determine whether to use block init in the prolog.
331     unsigned char lvOnFrame : 1;       // (part of) the variable lives on the frame
332     unsigned char lvRegister : 1;      // assigned to live in a register? For RyuJIT backend, this is only set if the
333                                        // variable is in the same register for the entire function.
334     unsigned char lvTracked : 1;       // is this a tracked variable?
335     bool          lvTrackedNonStruct()
336     {
337         return lvTracked && lvType != TYP_STRUCT;
338     }
339     unsigned char lvPinned : 1; // is this a pinned variable?
340
341     unsigned char lvMustInit : 1;    // must be initialized
342     unsigned char lvAddrExposed : 1; // The address of this variable is "exposed" -- passed as an argument, stored in a
343                                      // global location, etc.
344                                      // We cannot reason reliably about the value of the variable.
345     unsigned char lvDoNotEnregister : 1; // Do not enregister this variable.
346     unsigned char lvFieldAccessed : 1;   // The var is a struct local, and a field of the variable is accessed.  Affects
347                                          // struct promotion.
348
349     unsigned char lvInSsa : 1; // The variable is in SSA form (set by SsaBuilder)
350
351 #ifdef DEBUG
352     // These further document the reasons for setting "lvDoNotEnregister".  (Note that "lvAddrExposed" is one of the
353     // reasons;
354     // also, lvType == TYP_STRUCT prevents enregistration.  At least one of the reasons should be true.
355     unsigned char lvVMNeedsStackAddr : 1; // The VM may have access to a stack-relative address of the variable, and
356                                           // read/write its value.
357     unsigned char lvLiveInOutOfHndlr : 1; // The variable was live in or out of an exception handler, and this required
358                                           // the variable to be
359                                           // in the stack (at least at those boundaries.)
360     unsigned char lvLclFieldExpr : 1;     // The variable is not a struct, but was accessed like one (e.g., reading a
361                                           // particular byte from an int).
362     unsigned char lvLclBlockOpAddr : 1;   // The variable was written to via a block operation that took its address.
363     unsigned char lvLiveAcrossUCall : 1;  // The variable is live across an unmanaged call.
364 #endif
365     unsigned char lvIsCSE : 1;       // Indicates if this LclVar is a CSE variable.
366     unsigned char lvHasLdAddrOp : 1; // has ldloca or ldarga opcode on this local.
367     unsigned char lvStackByref : 1;  // This is a compiler temporary of TYP_BYREF that is known to point into our local
368                                      // stack frame.
369
370     unsigned char lvHasILStoreOp : 1;         // there is at least one STLOC or STARG on this local
371     unsigned char lvHasMultipleILStoreOp : 1; // there is more than one STLOC on this local
372
373     unsigned char lvIsTemp : 1; // Short-lifetime compiler temp (if lvIsParam is false), or implicit byref parameter
374                                 // (if lvIsParam is true)
375 #if OPT_BOOL_OPS
376     unsigned char lvIsBoolean : 1; // set if variable is boolean
377 #endif
378     unsigned char lvSingleDef : 1; // variable has a single def
379                                    // before lvaMarkLocalVars: identifies ref type locals that can get type updates
380                                    // after lvaMarkLocalVars: identifies locals that are suitable for optAddCopies
381
382 #if ASSERTION_PROP
383     unsigned char lvDisqualify : 1;   // variable is no longer OK for add copy optimization
384     unsigned char lvVolatileHint : 1; // hint for AssertionProp
385 #endif
386
387 #ifndef _TARGET_64BIT_
388     unsigned char lvStructDoubleAlign : 1; // Must we double align this struct?
389 #endif                                     // !_TARGET_64BIT_
390 #ifdef _TARGET_64BIT_
391     unsigned char lvQuirkToLong : 1; // Quirk to allocate this LclVar as a 64-bit long
392 #endif
393 #ifdef DEBUG
394     unsigned char lvKeepType : 1;       // Don't change the type of this variable
395     unsigned char lvNoLclFldStress : 1; // Can't apply local field stress on this one
396 #endif
397     unsigned char lvIsPtr : 1; // Might this be used in an address computation? (used by buffer overflow security
398                                // checks)
399     unsigned char lvIsUnsafeBuffer : 1; // Does this contain an unsafe buffer requiring buffer overflow security checks?
400     unsigned char lvPromoted : 1; // True when this local is a promoted struct, a normed struct, or a "split" long on a
401                                   // 32-bit target.  For implicit byref parameters, this gets hijacked between
402                                   // fgRetypeImplicitByRefArgs and fgMarkDemotedImplicitByRefArgs to indicate whether
403                                   // references to the arg are being rewritten as references to a promoted shadow local.
404     unsigned char lvIsStructField : 1;     // Is this local var a field of a promoted struct local?
405     unsigned char lvOverlappingFields : 1; // True when we have a struct with possibly overlapping fields
406     unsigned char lvContainsHoles : 1;     // True when we have a promoted struct that contains holes
407     unsigned char lvCustomLayout : 1;      // True when this struct has "CustomLayout"
408
409     unsigned char lvIsMultiRegArg : 1; // true if this is a multireg LclVar struct used in an argument context
410     unsigned char lvIsMultiRegRet : 1; // true if this is a multireg LclVar struct assigned from a multireg call
411
412 #ifdef FEATURE_HFA
413     unsigned char _lvIsHfa : 1;          // Is this a struct variable who's class handle is an HFA type
414     unsigned char _lvIsHfaRegArg : 1;    // Is this a HFA argument variable?    // TODO-CLEANUP: Remove this and replace
415                                          // with (lvIsRegArg && lvIsHfa())
416     unsigned char _lvHfaTypeIsFloat : 1; // Is the HFA type float or double?
417 #endif                                   // FEATURE_HFA
418
419 #ifdef DEBUG
420     // TODO-Cleanup: See the note on lvSize() - this flag is only in use by asserts that are checking for struct
421     // types, and is needed because of cases where TYP_STRUCT is bashed to an integral type.
422     // Consider cleaning this up so this workaround is not required.
423     unsigned char lvUnusedStruct : 1; // All references to this promoted struct are through its field locals.
424                                       // I.e. there is no longer any reference to the struct directly.
425                                       // In this case we can simply remove this struct local.
426 #endif
427
428     unsigned char lvLRACandidate : 1; // Tracked for linear scan register allocation purposes
429
430 #ifdef FEATURE_SIMD
431     // Note that both SIMD vector args and locals are marked as lvSIMDType = true, but the
432     // type of an arg node is TYP_BYREF and a local node is TYP_SIMD*.
433     unsigned char lvSIMDType : 1;            // This is a SIMD struct
434     unsigned char lvUsedInSIMDIntrinsic : 1; // This tells lclvar is used for simd intrinsic
435     var_types     lvBaseType : 5;            // Note: this only packs because var_types is a typedef of unsigned char
436 #endif                                       // FEATURE_SIMD
437     unsigned char lvRegStruct : 1;           // This is a reg-sized non-field-addressed struct.
438
439     unsigned char lvClassIsExact : 1; // lvClassHandle is the exact type
440
441 #ifdef DEBUG
442     unsigned char lvClassInfoUpdated : 1; // true if this var has updated class handle or exactness
443 #endif
444
445     unsigned char lvImplicitlyReferenced : 1; // true if there are non-IR references to this local (prolog, epilog, gc,
446                                               // eh)
447
448     union {
449         unsigned lvFieldLclStart; // The index of the local var representing the first field in the promoted struct
450                                   // local.  For implicit byref parameters, this gets hijacked between
451                                   // fgRetypeImplicitByRefArgs and fgMarkDemotedImplicitByRefArgs to point to the
452                                   // struct local created to model the parameter's struct promotion, if any.
453         unsigned lvParentLcl; // The index of the local var representing the parent (i.e. the promoted struct local).
454                               // Valid on promoted struct local fields.
455     };
456
457     unsigned char lvFieldCnt; //  Number of fields in the promoted VarDsc.
458     unsigned char lvFldOffset;
459     unsigned char lvFldOrdinal;
460
461 #if FEATURE_MULTIREG_ARGS
462     regNumber lvRegNumForSlot(unsigned slotNum)
463     {
464         if (slotNum == 0)
465         {
466             return lvArgReg;
467         }
468         else if (slotNum == 1)
469         {
470             return lvOtherArgReg;
471         }
472         else
473         {
474             assert(false && "Invalid slotNum!");
475         }
476
477         unreached();
478     }
479 #endif // FEATURE_MULTIREG_ARGS
480
481     bool lvIsHfa() const
482     {
483 #ifdef FEATURE_HFA
484         return _lvIsHfa;
485 #else
486         return false;
487 #endif
488     }
489
490     void lvSetIsHfa()
491     {
492 #ifdef FEATURE_HFA
493         _lvIsHfa = true;
494 #endif
495     }
496
497     bool lvIsHfaRegArg() const
498     {
499 #ifdef FEATURE_HFA
500         return _lvIsHfaRegArg;
501 #else
502         return false;
503 #endif
504     }
505
506     void lvSetIsHfaRegArg(bool value = true)
507     {
508 #ifdef FEATURE_HFA
509         _lvIsHfaRegArg = value;
510 #endif
511     }
512
513     bool lvHfaTypeIsFloat() const
514     {
515 #ifdef FEATURE_HFA
516         return _lvHfaTypeIsFloat;
517 #else
518         return false;
519 #endif
520     }
521
522     void lvSetHfaTypeIsFloat(bool value)
523     {
524 #ifdef FEATURE_HFA
525         _lvHfaTypeIsFloat = value;
526 #endif
527     }
528
529     // on Arm64 - Returns 1-4 indicating the number of register slots used by the HFA
530     // on Arm32 - Returns the total number of single FP register slots used by the HFA, max is 8
531     //
532     unsigned lvHfaSlots() const
533     {
534         assert(lvIsHfa());
535         assert(varTypeIsStruct(lvType));
536 #ifdef _TARGET_ARM_
537         return lvExactSize / sizeof(float);
538 #else  //  _TARGET_ARM64_
539         if (lvHfaTypeIsFloat())
540         {
541             return lvExactSize / sizeof(float);
542         }
543         else
544         {
545             return lvExactSize / sizeof(double);
546         }
547 #endif //  _TARGET_ARM64_
548     }
549
550     // lvIsMultiRegArgOrRet()
551     //     returns true if this is a multireg LclVar struct used in an argument context
552     //               or if this is a multireg LclVar struct assigned from a multireg call
553     bool lvIsMultiRegArgOrRet()
554     {
555         return lvIsMultiRegArg || lvIsMultiRegRet;
556     }
557
558 private:
559     regNumberSmall _lvRegNum; // Used to store the register this variable is in (or, the low register of a
560                               // register pair). It is set during codegen any time the
561                               // variable is enregistered (lvRegister is only set
562                               // to non-zero if the variable gets the same register assignment for its entire
563                               // lifetime).
564 #if !defined(_TARGET_64BIT_)
565     regNumberSmall _lvOtherReg; // Used for "upper half" of long var.
566 #endif                          // !defined(_TARGET_64BIT_)
567
568     regNumberSmall _lvArgReg; // The register in which this argument is passed.
569
570 #if FEATURE_MULTIREG_ARGS
571     regNumberSmall _lvOtherArgReg; // Used for the second part of the struct passed in a register.
572                                    // Note this is defined but not used by ARM32
573 #endif                             // FEATURE_MULTIREG_ARGS
574
575     regNumberSmall _lvArgInitReg; // the register into which the argument is moved at entry
576
577 public:
578     // The register number is stored in a small format (8 bits), but the getters return and the setters take
579     // a full-size (unsigned) format, to localize the casts here.
580
581     /////////////////////
582
583     __declspec(property(get = GetRegNum, put = SetRegNum)) regNumber lvRegNum;
584
585     regNumber GetRegNum() const
586     {
587         return (regNumber)_lvRegNum;
588     }
589
590     void SetRegNum(regNumber reg)
591     {
592         _lvRegNum = (regNumberSmall)reg;
593         assert(_lvRegNum == reg);
594     }
595
596 /////////////////////
597
598 #if defined(_TARGET_64BIT_)
599     __declspec(property(get = GetOtherReg, put = SetOtherReg)) regNumber lvOtherReg;
600
601     regNumber GetOtherReg() const
602     {
603         assert(!"shouldn't get here"); // can't use "unreached();" because it's NORETURN, which causes C4072
604                                        // "unreachable code" warnings
605         return REG_NA;
606     }
607
608     void SetOtherReg(regNumber reg)
609     {
610         assert(!"shouldn't get here"); // can't use "unreached();" because it's NORETURN, which causes C4072
611                                        // "unreachable code" warnings
612     }
613 #else  // !_TARGET_64BIT_
614     __declspec(property(get = GetOtherReg, put = SetOtherReg)) regNumber lvOtherReg;
615
616     regNumber GetOtherReg() const
617     {
618         return (regNumber)_lvOtherReg;
619     }
620
621     void SetOtherReg(regNumber reg)
622     {
623         _lvOtherReg = (regNumberSmall)reg;
624         assert(_lvOtherReg == reg);
625     }
626 #endif // !_TARGET_64BIT_
627
628     /////////////////////
629
630     __declspec(property(get = GetArgReg, put = SetArgReg)) regNumber lvArgReg;
631
632     regNumber GetArgReg() const
633     {
634         return (regNumber)_lvArgReg;
635     }
636
637     void SetArgReg(regNumber reg)
638     {
639         _lvArgReg = (regNumberSmall)reg;
640         assert(_lvArgReg == reg);
641     }
642
643 #if FEATURE_MULTIREG_ARGS
644     __declspec(property(get = GetOtherArgReg, put = SetOtherArgReg)) regNumber lvOtherArgReg;
645
646     regNumber GetOtherArgReg() const
647     {
648         return (regNumber)_lvOtherArgReg;
649     }
650
651     void SetOtherArgReg(regNumber reg)
652     {
653         _lvOtherArgReg = (regNumberSmall)reg;
654         assert(_lvOtherArgReg == reg);
655     }
656 #endif // FEATURE_MULTIREG_ARGS
657
658 #ifdef FEATURE_SIMD
659     // Is this is a SIMD struct?
660     bool lvIsSIMDType() const
661     {
662         return lvSIMDType;
663     }
664
665     // Is this is a SIMD struct which is used for SIMD intrinsic?
666     bool lvIsUsedInSIMDIntrinsic() const
667     {
668         return lvUsedInSIMDIntrinsic;
669     }
670 #else
671     // If feature_simd not enabled, return false
672     bool lvIsSIMDType() const
673     {
674         return false;
675     }
676     bool lvIsUsedInSIMDIntrinsic() const
677     {
678         return false;
679     }
680 #endif
681
682     /////////////////////
683
684     __declspec(property(get = GetArgInitReg, put = SetArgInitReg)) regNumber lvArgInitReg;
685
686     regNumber GetArgInitReg() const
687     {
688         return (regNumber)_lvArgInitReg;
689     }
690
691     void SetArgInitReg(regNumber reg)
692     {
693         _lvArgInitReg = (regNumberSmall)reg;
694         assert(_lvArgInitReg == reg);
695     }
696
697     /////////////////////
698
699     bool lvIsRegCandidate() const
700     {
701         return lvLRACandidate != 0;
702     }
703
704     bool lvIsInReg() const
705     {
706         return lvIsRegCandidate() && (lvRegNum != REG_STK);
707     }
708
709     regMaskTP lvRegMask() const
710     {
711         regMaskTP regMask = RBM_NONE;
712         if (varTypeIsFloating(TypeGet()))
713         {
714             if (lvRegNum != REG_STK)
715             {
716                 regMask = genRegMaskFloat(lvRegNum, TypeGet());
717             }
718         }
719         else
720         {
721             if (lvRegNum != REG_STK)
722             {
723                 regMask = genRegMask(lvRegNum);
724             }
725         }
726         return regMask;
727     }
728
729     unsigned short lvVarIndex; // variable tracking index
730
731 private:
732     unsigned short m_lvRefCnt; // unweighted (real) reference count.  For implicit by reference
733                                // parameters, this gets hijacked from fgMarkImplicitByRefArgs
734                                // through fgMarkDemotedImplicitByRefArgs, to provide a static
735                                // appearance count (computed during address-exposed analysis)
736                                // that fgMakeOutgoingStructArgCopy consults during global morph
737                                // to determine if eliding its copy is legal.
738
739     BasicBlock::weight_t m_lvRefCntWtd; // weighted reference count
740
741 public:
742     unsigned short lvRefCnt(RefCountState state = RCS_NORMAL) const;
743     void incLvRefCnt(unsigned short delta, RefCountState state = RCS_NORMAL);
744     void setLvRefCnt(unsigned short newValue, RefCountState state = RCS_NORMAL);
745
746     BasicBlock::weight_t lvRefCntWtd(RefCountState state = RCS_NORMAL) const;
747     void incLvRefCntWtd(BasicBlock::weight_t delta, RefCountState state = RCS_NORMAL);
748     void setLvRefCntWtd(BasicBlock::weight_t newValue, RefCountState state = RCS_NORMAL);
749
750     int      lvStkOffs;   // stack offset of home
751     unsigned lvExactSize; // (exact) size of the type in bytes
752
753     // Is this a promoted struct?
754     // This method returns true only for structs (including SIMD structs), not for
755     // locals that are split on a 32-bit target.
756     // It is only necessary to use this:
757     //   1) if only structs are wanted, and
758     //   2) if Lowering has already been done.
759     // Otherwise lvPromoted is valid.
760     bool lvPromotedStruct()
761     {
762 #if !defined(_TARGET_64BIT_)
763         return (lvPromoted && !varTypeIsLong(lvType));
764 #else  // defined(_TARGET_64BIT_)
765         return lvPromoted;
766 #endif // defined(_TARGET_64BIT_)
767     }
768
769     unsigned lvSize() const // Size needed for storage representation. Only used for structs or TYP_BLK.
770     {
771         // TODO-Review: Sometimes we get called on ARM with HFA struct variables that have been promoted,
772         // where the struct itself is no longer used because all access is via its member fields.
773         // When that happens, the struct is marked as unused and its type has been changed to
774         // TYP_INT (to keep the GC tracking code from looking at it).
775         // See Compiler::raAssignVars() for details. For example:
776         //      N002 (  4,  3) [00EA067C] -------------               return    struct $346
777         //      N001 (  3,  2) [00EA0628] -------------                  lclVar    struct(U) V03 loc2
778         //                                                                        float  V03.f1 (offs=0x00) -> V12 tmp7
779         //                                                                        f8 (last use) (last use) $345
780         // Here, the "struct(U)" shows that the "V03 loc2" variable is unused. Not shown is that V03
781         // is now TYP_INT in the local variable table. It's not really unused, because it's in the tree.
782
783         assert(varTypeIsStruct(lvType) || (lvType == TYP_BLK) || (lvPromoted && lvUnusedStruct));
784
785 #if defined(FEATURE_SIMD) && !defined(_TARGET_64BIT_)
786         // For 32-bit architectures, we make local variable SIMD12 types 16 bytes instead of just 12. We can't do
787         // this for arguments, which must be passed according the defined ABI. We don't want to do this for
788         // dependently promoted struct fields, but we don't know that here. See lvaMapSimd12ToSimd16().
789         // (Note that for 64-bits, we are already rounding up to 16.)
790         if ((lvType == TYP_SIMD12) && !lvIsParam)
791         {
792             assert(lvExactSize == 12);
793             return 16;
794         }
795 #endif // defined(FEATURE_SIMD) && !defined(_TARGET_64BIT_)
796
797         return roundUp(lvExactSize, TARGET_POINTER_SIZE);
798     }
799
800     size_t lvArgStackSize() const;
801
802     unsigned lvSlotNum; // original slot # (if remapped)
803
804     typeInfo lvVerTypeInfo; // type info needed for verification
805
806     CORINFO_CLASS_HANDLE lvClassHnd; // class handle for the local, or null if not known
807
808     CORINFO_FIELD_HANDLE lvFieldHnd; // field handle for promoted struct fields
809
810     BYTE* lvGcLayout; // GC layout info for structs
811
812 #if ASSERTION_PROP
813     BlockSet lvRefBlks;          // Set of blocks that contain refs
814     GenTree* lvDefStmt;          // Pointer to the statement with the single definition
815     void     lvaDisqualifyVar(); // Call to disqualify a local variable from use in optAddCopies
816 #endif
817     var_types TypeGet() const
818     {
819         return (var_types)lvType;
820     }
821     bool lvStackAligned() const
822     {
823         assert(lvIsStructField);
824         return ((lvFldOffset % TARGET_POINTER_SIZE) == 0);
825     }
826     bool lvNormalizeOnLoad() const
827     {
828         return varTypeIsSmall(TypeGet()) &&
829                // lvIsStructField is treated the same as the aliased local, see fgDoNormalizeOnStore.
830                (lvIsParam || lvAddrExposed || lvIsStructField);
831     }
832
833     bool lvNormalizeOnStore()
834     {
835         return varTypeIsSmall(TypeGet()) &&
836                // lvIsStructField is treated the same as the aliased local, see fgDoNormalizeOnStore.
837                !(lvIsParam || lvAddrExposed || lvIsStructField);
838     }
839
840     void incRefCnts(BasicBlock::weight_t weight,
841                     Compiler*            pComp,
842                     RefCountState        state     = RCS_NORMAL,
843                     bool                 propagate = true);
844     bool IsFloatRegType() const
845     {
846         return isFloatRegType(lvType) || lvIsHfaRegArg();
847     }
848     var_types GetHfaType() const
849     {
850         return lvIsHfa() ? (lvHfaTypeIsFloat() ? TYP_FLOAT : TYP_DOUBLE) : TYP_UNDEF;
851     }
852     void SetHfaType(var_types type)
853     {
854         assert(varTypeIsFloating(type));
855         lvSetHfaTypeIsFloat(type == TYP_FLOAT);
856     }
857
858     var_types lvaArgType();
859
860     SsaDefArray<LclSsaVarDsc> lvPerSsaData;
861
862     // Returns the address of the per-Ssa data for the given ssaNum (which is required
863     // not to be the SsaConfig::RESERVED_SSA_NUM, which indicates that the variable is
864     // not an SSA variable).
865     LclSsaVarDsc* GetPerSsaData(unsigned ssaNum)
866     {
867         return lvPerSsaData.GetSsaDef(ssaNum);
868     }
869
870 #ifdef DEBUG
871 public:
872     const char* lvReason;
873
874     void PrintVarReg() const
875     {
876         printf("%s", getRegName(lvRegNum));
877     }
878 #endif // DEBUG
879
880 }; // class LclVarDsc
881
882 /*
883 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
884 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
885 XX                                                                           XX
886 XX                           TempsInfo                                       XX
887 XX                                                                           XX
888 XX  The temporary lclVars allocated by the compiler for code generation      XX
889 XX                                                                           XX
890 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
891 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
892 */
893
894 /*****************************************************************************
895  *
896  *  The following keeps track of temporaries allocated in the stack frame
897  *  during code-generation (after register allocation). These spill-temps are
898  *  only used if we run out of registers while evaluating a tree.
899  *
900  *  These are different from the more common temps allocated by lvaGrabTemp().
901  */
902
903 class TempDsc
904 {
905 public:
906     TempDsc* tdNext;
907
908 private:
909     int tdOffs;
910 #ifdef DEBUG
911     static const int BAD_TEMP_OFFSET = 0xDDDDDDDD; // used as a sentinel "bad value" for tdOffs in DEBUG
912 #endif                                             // DEBUG
913
914     int       tdNum;
915     BYTE      tdSize;
916     var_types tdType;
917
918 public:
919     TempDsc(int _tdNum, unsigned _tdSize, var_types _tdType) : tdNum(_tdNum), tdSize((BYTE)_tdSize), tdType(_tdType)
920     {
921 #ifdef DEBUG
922         assert(tdNum <
923                0); // temps must have a negative number (so they have a different number from all local variables)
924         tdOffs = BAD_TEMP_OFFSET;
925 #endif // DEBUG
926         if (tdNum != _tdNum)
927         {
928             IMPL_LIMITATION("too many spill temps");
929         }
930     }
931
932 #ifdef DEBUG
933     bool tdLegalOffset() const
934     {
935         return tdOffs != BAD_TEMP_OFFSET;
936     }
937 #endif // DEBUG
938
939     int tdTempOffs() const
940     {
941         assert(tdLegalOffset());
942         return tdOffs;
943     }
944     void tdSetTempOffs(int offs)
945     {
946         tdOffs = offs;
947         assert(tdLegalOffset());
948     }
949     void tdAdjustTempOffs(int offs)
950     {
951         tdOffs += offs;
952         assert(tdLegalOffset());
953     }
954
955     int tdTempNum() const
956     {
957         assert(tdNum < 0);
958         return tdNum;
959     }
960     unsigned tdTempSize() const
961     {
962         return tdSize;
963     }
964     var_types tdTempType() const
965     {
966         return tdType;
967     }
968 };
969
970 // interface to hide linearscan implementation from rest of compiler
971 class LinearScanInterface
972 {
973 public:
974     virtual void doLinearScan()                                = 0;
975     virtual void recordVarLocationsAtStartOfBB(BasicBlock* bb) = 0;
976     virtual bool willEnregisterLocalVars() const               = 0;
977 };
978
979 LinearScanInterface* getLinearScanAllocator(Compiler* comp);
980
981 // Information about arrays: their element type and size, and the offset of the first element.
982 // We label GT_IND's that are array indices with GTF_IND_ARR_INDEX, and, for such nodes,
983 // associate an array info via the map retrieved by GetArrayInfoMap().  This information is used,
984 // for example, in value numbering of array index expressions.
985 struct ArrayInfo
986 {
987     var_types            m_elemType;
988     CORINFO_CLASS_HANDLE m_elemStructType;
989     unsigned             m_elemSize;
990     unsigned             m_elemOffset;
991
992     ArrayInfo() : m_elemType(TYP_UNDEF), m_elemStructType(nullptr), m_elemSize(0), m_elemOffset(0)
993     {
994     }
995
996     ArrayInfo(var_types elemType, unsigned elemSize, unsigned elemOffset, CORINFO_CLASS_HANDLE elemStructType)
997         : m_elemType(elemType), m_elemStructType(elemStructType), m_elemSize(elemSize), m_elemOffset(elemOffset)
998     {
999     }
1000 };
1001
1002 // This enumeration names the phases into which we divide compilation.  The phases should completely
1003 // partition a compilation.
1004 enum Phases
1005 {
1006 #define CompPhaseNameMacro(enum_nm, string_nm, short_nm, hasChildren, parent, measureIR) enum_nm,
1007 #include "compphases.h"
1008     PHASE_NUMBER_OF
1009 };
1010
1011 extern const char*   PhaseNames[];
1012 extern const char*   PhaseEnums[];
1013 extern const LPCWSTR PhaseShortNames[];
1014
1015 // The following enum provides a simple 1:1 mapping to CLR API's
1016 enum API_ICorJitInfo_Names
1017 {
1018 #define DEF_CLR_API(name) API_##name,
1019 #include "ICorJitInfo_API_names.h"
1020     API_COUNT
1021 };
1022
1023 //---------------------------------------------------------------
1024 // Compilation time.
1025 //
1026
1027 // A "CompTimeInfo" is a structure for tracking the compilation time of one or more methods.
1028 // We divide a compilation into a sequence of contiguous phases, and track the total (per-thread) cycles
1029 // of the compilation, as well as the cycles for each phase.  We also track the number of bytecodes.
1030 // If there is a failure in reading a timer at any point, the "CompTimeInfo" becomes invalid, as indicated
1031 // by "m_timerFailure" being true.
1032 // If FEATURE_JIT_METHOD_PERF is not set, we define a minimal form of this, enough to let other code compile.
1033 struct CompTimeInfo
1034 {
1035 #ifdef FEATURE_JIT_METHOD_PERF
1036     // The string names of the phases.
1037     static const char* PhaseNames[];
1038
1039     static bool PhaseHasChildren[];
1040     static int  PhaseParent[];
1041     static bool PhaseReportsIRSize[];
1042
1043     unsigned         m_byteCodeBytes;
1044     unsigned __int64 m_totalCycles;
1045     unsigned __int64 m_invokesByPhase[PHASE_NUMBER_OF];
1046     unsigned __int64 m_cyclesByPhase[PHASE_NUMBER_OF];
1047 #if MEASURE_CLRAPI_CALLS
1048     unsigned __int64 m_CLRinvokesByPhase[PHASE_NUMBER_OF];
1049     unsigned __int64 m_CLRcyclesByPhase[PHASE_NUMBER_OF];
1050 #endif
1051
1052     unsigned m_nodeCountAfterPhase[PHASE_NUMBER_OF];
1053
1054     // For better documentation, we call EndPhase on
1055     // non-leaf phases.  We should also call EndPhase on the
1056     // last leaf subphase; obviously, the elapsed cycles between the EndPhase
1057     // for the last leaf subphase and the EndPhase for an ancestor should be very small.
1058     // We add all such "redundant end phase" intervals to this variable below; we print
1059     // it out in a report, so we can verify that it is, indeed, very small.  If it ever
1060     // isn't, this means that we're doing something significant between the end of the last
1061     // declared subphase and the end of its parent.
1062     unsigned __int64 m_parentPhaseEndSlop;
1063     bool             m_timerFailure;
1064
1065 #if MEASURE_CLRAPI_CALLS
1066     // The following measures the time spent inside each individual CLR API call.
1067     unsigned         m_allClrAPIcalls;
1068     unsigned         m_perClrAPIcalls[API_ICorJitInfo_Names::API_COUNT];
1069     unsigned __int64 m_allClrAPIcycles;
1070     unsigned __int64 m_perClrAPIcycles[API_ICorJitInfo_Names::API_COUNT];
1071     unsigned __int32 m_maxClrAPIcycles[API_ICorJitInfo_Names::API_COUNT];
1072 #endif // MEASURE_CLRAPI_CALLS
1073
1074     CompTimeInfo(unsigned byteCodeBytes);
1075 #endif
1076 };
1077
1078 #ifdef FEATURE_JIT_METHOD_PERF
1079
1080 #if MEASURE_CLRAPI_CALLS
1081 struct WrapICorJitInfo;
1082 #endif
1083
1084 // This class summarizes the JIT time information over the course of a run: the number of methods compiled,
1085 // and the total and maximum timings.  (These are instances of the "CompTimeInfo" type described above).
1086 // The operation of adding a single method's timing to the summary may be performed concurrently by several
1087 // threads, so it is protected by a lock.
1088 // This class is intended to be used as a singleton type, with only a single instance.
1089 class CompTimeSummaryInfo
1090 {
1091     // This lock protects the fields of all CompTimeSummaryInfo(s) (of which we expect there to be one).
1092     static CritSecObject s_compTimeSummaryLock;
1093
1094     int          m_numMethods;
1095     int          m_totMethods;
1096     CompTimeInfo m_total;
1097     CompTimeInfo m_maximum;
1098
1099     int          m_numFilteredMethods;
1100     CompTimeInfo m_filtered;
1101
1102     // This can use what ever data you want to determine if the value to be added
1103     // belongs in the filtered section (it's always included in the unfiltered section)
1104     bool IncludedInFilteredData(CompTimeInfo& info);
1105
1106 public:
1107     // This is the unique CompTimeSummaryInfo object for this instance of the runtime.
1108     static CompTimeSummaryInfo s_compTimeSummary;
1109
1110     CompTimeSummaryInfo()
1111         : m_numMethods(0), m_totMethods(0), m_total(0), m_maximum(0), m_numFilteredMethods(0), m_filtered(0)
1112     {
1113     }
1114
1115     // Assumes that "info" is a completed CompTimeInfo for a compilation; adds it to the summary.
1116     // This is thread safe.
1117     void AddInfo(CompTimeInfo& info, bool includePhases);
1118
1119     // Print the summary information to "f".
1120     // This is not thread-safe; assumed to be called by only one thread.
1121     void Print(FILE* f);
1122 };
1123
1124 // A JitTimer encapsulates a CompTimeInfo for a single compilation. It also tracks the start of compilation,
1125 // and when the current phase started.  This is intended to be part of a Compilation object.  This is
1126 // disabled (FEATURE_JIT_METHOD_PERF not defined) when FEATURE_CORECLR is set, or on non-windows platforms.
1127 //
1128 class JitTimer
1129 {
1130     unsigned __int64 m_start;         // Start of the compilation.
1131     unsigned __int64 m_curPhaseStart; // Start of the current phase.
1132 #if MEASURE_CLRAPI_CALLS
1133     unsigned __int64 m_CLRcallStart;   // Start of the current CLR API call (if any).
1134     unsigned __int64 m_CLRcallInvokes; // CLR API invokes under current outer so far
1135     unsigned __int64 m_CLRcallCycles;  // CLR API  cycles under current outer so far.
1136     int              m_CLRcallAPInum;  // The enum/index of the current CLR API call (or -1).
1137     static double    s_cyclesPerSec;   // Cached for speedier measurements
1138 #endif
1139 #ifdef DEBUG
1140     Phases m_lastPhase; // The last phase that was completed (or (Phases)-1 to start).
1141 #endif
1142     CompTimeInfo m_info; // The CompTimeInfo for this compilation.
1143
1144     static CritSecObject s_csvLock; // Lock to protect the time log file.
1145     void PrintCsvMethodStats(Compiler* comp);
1146
1147 private:
1148     void* operator new(size_t);
1149     void* operator new[](size_t);
1150     void operator delete(void*);
1151     void operator delete[](void*);
1152
1153 public:
1154     // Initialized the timer instance
1155     JitTimer(unsigned byteCodeSize);
1156
1157     static JitTimer* Create(Compiler* comp, unsigned byteCodeSize)
1158     {
1159         return ::new (comp, CMK_Unknown) JitTimer(byteCodeSize);
1160     }
1161
1162     static void PrintCsvHeader();
1163
1164     // Ends the current phase (argument is for a redundant check).
1165     void EndPhase(Compiler* compiler, Phases phase);
1166
1167 #if MEASURE_CLRAPI_CALLS
1168     // Start and end a timed CLR API call.
1169     void CLRApiCallEnter(unsigned apix);
1170     void CLRApiCallLeave(unsigned apix);
1171 #endif // MEASURE_CLRAPI_CALLS
1172
1173     // Completes the timing of the current method, which is assumed to have "byteCodeBytes" bytes of bytecode,
1174     // and adds it to "sum".
1175     void Terminate(Compiler* comp, CompTimeSummaryInfo& sum, bool includePhases);
1176
1177     // Attempts to query the cycle counter of the current thread.  If successful, returns "true" and sets
1178     // *cycles to the cycle counter value.  Otherwise, returns false and sets the "m_timerFailure" flag of
1179     // "m_info" to true.
1180     bool GetThreadCycles(unsigned __int64* cycles)
1181     {
1182         bool res = CycleTimer::GetThreadCyclesS(cycles);
1183         if (!res)
1184         {
1185             m_info.m_timerFailure = true;
1186         }
1187         return res;
1188     }
1189 };
1190 #endif // FEATURE_JIT_METHOD_PERF
1191
1192 //------------------- Function/Funclet info -------------------------------
1193 enum FuncKind : BYTE
1194 {
1195     FUNC_ROOT,    // The main/root function (always id==0)
1196     FUNC_HANDLER, // a funclet associated with an EH handler (finally, fault, catch, filter handler)
1197     FUNC_FILTER,  // a funclet associated with an EH filter
1198     FUNC_COUNT
1199 };
1200
1201 class emitLocation;
1202
1203 struct FuncInfoDsc
1204 {
1205     FuncKind       funKind;
1206     BYTE           funFlags;   // Currently unused, just here for padding
1207     unsigned short funEHIndex; // index, into the ebd table, of innermost EH clause corresponding to this
1208                                // funclet. It is only valid if funKind field indicates this is a
1209                                // EH-related funclet: FUNC_HANDLER or FUNC_FILTER
1210
1211 #if defined(_TARGET_AMD64_)
1212
1213     // TODO-AMD64-Throughput: make the AMD64 info more like the ARM info to avoid having this large static array.
1214     emitLocation* startLoc;
1215     emitLocation* endLoc;
1216     emitLocation* coldStartLoc; // locations for the cold section, if there is one.
1217     emitLocation* coldEndLoc;
1218     UNWIND_INFO   unwindHeader;
1219     // Maximum of 255 UNWIND_CODE 'nodes' and then the unwind header. If there are an odd
1220     // number of codes, the VM or Zapper will 4-byte align the whole thing.
1221     BYTE     unwindCodes[offsetof(UNWIND_INFO, UnwindCode) + (0xFF * sizeof(UNWIND_CODE))];
1222     unsigned unwindCodeSlot;
1223
1224 #elif defined(_TARGET_X86_)
1225
1226 #if defined(_TARGET_UNIX_)
1227     emitLocation* startLoc;
1228     emitLocation* endLoc;
1229     emitLocation* coldStartLoc; // locations for the cold section, if there is one.
1230     emitLocation* coldEndLoc;
1231 #endif // _TARGET_UNIX_
1232
1233 #elif defined(_TARGET_ARMARCH_)
1234
1235     UnwindInfo  uwi;     // Unwind information for this function/funclet's hot  section
1236     UnwindInfo* uwiCold; // Unwind information for this function/funclet's cold section
1237                          //   Note: we only have a pointer here instead of the actual object,
1238                          //   to save memory in the JIT case (compared to the NGEN case),
1239                          //   where we don't have any cold section.
1240                          //   Note 2: we currently don't support hot/cold splitting in functions
1241                          //   with EH, so uwiCold will be NULL for all funclets.
1242
1243 #if defined(_TARGET_UNIX_)
1244     emitLocation* startLoc;
1245     emitLocation* endLoc;
1246     emitLocation* coldStartLoc; // locations for the cold section, if there is one.
1247     emitLocation* coldEndLoc;
1248 #endif // _TARGET_UNIX_
1249
1250 #endif // _TARGET_ARMARCH_
1251
1252 #if defined(_TARGET_UNIX_)
1253     jitstd::vector<CFI_CODE>* cfiCodes;
1254 #endif // _TARGET_UNIX_
1255
1256     // Eventually we may want to move rsModifiedRegsMask, lvaOutgoingArgSize, and anything else
1257     // that isn't shared between the main function body and funclets.
1258 };
1259
1260 struct fgArgTabEntry
1261 {
1262     GenTree* node;   // Initially points at the Op1 field of 'parent', but if the argument is replaced with an GT_ASG or
1263                      // placeholder it will point at the actual argument in the gtCallLateArgs list.
1264     GenTree* parent; // Points at the GT_LIST node in the gtCallArgs for this argument
1265
1266     unsigned argNum; // The original argument number, also specifies the required argument evaluation order from the IL
1267
1268 private:
1269     regNumberSmall regNums[MAX_ARG_REG_COUNT]; // The registers to use when passing this argument, set to REG_STK for
1270                                                // arguments passed on the stack
1271 public:
1272     unsigned numRegs; // Count of number of registers that this argument uses.
1273                       // Note that on ARM, if we have a double hfa, this reflects the number
1274                       // of DOUBLE registers.
1275
1276     // A slot is a pointer sized region in the OutArg area.
1277     unsigned slotNum;  // When an argument is passed in the OutArg area this is the slot number in the OutArg area
1278     unsigned numSlots; // Count of number of slots that this argument uses
1279
1280     unsigned alignment; // 1 or 2 (slots/registers)
1281 private:
1282     unsigned _lateArgInx; // index into gtCallLateArgs list; UINT_MAX if this is not a late arg.
1283 public:
1284     unsigned tmpNum; // the LclVar number if we had to force evaluation of this arg
1285
1286     var_types argType; // The type used to pass this argument. This is generally the original argument type, but when a
1287                        // struct is passed as a scalar type, this is that type.
1288                        // Note that if a struct is passed by reference, this will still be the struct type.
1289
1290     bool needTmp : 1;       // True when we force this argument's evaluation into a temp LclVar
1291     bool needPlace : 1;     // True when we must replace this argument with a placeholder node
1292     bool isTmp : 1;         // True when we setup a temp LclVar for this argument due to size issues with the struct
1293     bool processed : 1;     // True when we have decided the evaluation order for this argument in the gtCallLateArgs
1294     bool isBackFilled : 1;  // True when the argument fills a register slot skipped due to alignment requirements of
1295                             // previous arguments.
1296     bool isNonStandard : 1; // True if it is an arg that is passed in a reg other than a standard arg reg, or is forced
1297                             // to be on the stack despite its arg list position.
1298     bool isStruct : 1;      // True if this is a struct arg
1299     bool _isVararg : 1;     // True if the argument is in a vararg context.
1300     bool passedByRef : 1;   // True iff the argument is passed by reference.
1301 #ifdef FEATURE_ARG_SPLIT
1302     bool _isSplit : 1; // True when this argument is split between the registers and OutArg area
1303 #endif                 // FEATURE_ARG_SPLIT
1304 #ifdef FEATURE_HFA
1305     bool _isHfaArg : 1;    // True when the argument is an HFA type.
1306     bool _isDoubleHfa : 1; // True when the argument is an HFA, with an element type of DOUBLE.
1307 #endif
1308
1309     bool isLateArg()
1310     {
1311         bool isLate = (_lateArgInx != UINT_MAX);
1312         return isLate;
1313     }
1314
1315     __declspec(property(get = getLateArgInx, put = setLateArgInx)) unsigned lateArgInx;
1316     unsigned getLateArgInx()
1317     {
1318         assert(isLateArg());
1319         return _lateArgInx;
1320     }
1321     void setLateArgInx(unsigned inx)
1322     {
1323         _lateArgInx = inx;
1324     }
1325     __declspec(property(get = getRegNum)) regNumber regNum;
1326     regNumber getRegNum()
1327     {
1328         return (regNumber)regNums[0];
1329     }
1330     __declspec(property(get = getOtherRegNum)) regNumber otherRegNum;
1331     regNumber getOtherRegNum()
1332     {
1333         return (regNumber)regNums[1];
1334     }
1335
1336 #if defined(UNIX_AMD64_ABI)
1337     SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR structDesc;
1338 #endif
1339
1340     void setRegNum(unsigned int i, regNumber regNum)
1341     {
1342         assert(i < MAX_ARG_REG_COUNT);
1343         regNums[i] = (regNumberSmall)regNum;
1344     }
1345     regNumber getRegNum(unsigned int i)
1346     {
1347         assert(i < MAX_ARG_REG_COUNT);
1348         return (regNumber)regNums[i];
1349     }
1350
1351     __declspec(property(get = getIsSplit, put = setIsSplit)) bool isSplit;
1352     bool getIsSplit()
1353     {
1354 #ifdef FEATURE_ARG_SPLIT
1355         return _isSplit;
1356 #else // FEATURE_ARG_SPLIT
1357         return false;
1358 #endif
1359     }
1360     void setIsSplit(bool value)
1361     {
1362 #ifdef FEATURE_ARG_SPLIT
1363         _isSplit = value;
1364 #endif
1365     }
1366
1367     __declspec(property(get = getIsVararg, put = setIsVararg)) bool isVararg;
1368     bool getIsVararg()
1369     {
1370 #ifdef FEATURE_VARARG
1371         return _isVararg;
1372 #else
1373         return false;
1374 #endif
1375     }
1376     void setIsVararg(bool value)
1377     {
1378 #ifdef FEATURE_VARARG
1379         _isVararg = value;
1380 #endif // FEATURE_VARARG
1381     }
1382
1383     __declspec(property(get = getIsHfaArg)) bool isHfaArg;
1384     bool getIsHfaArg()
1385     {
1386 #ifdef FEATURE_HFA
1387         return _isHfaArg;
1388 #else
1389         return false;
1390 #endif
1391     }
1392
1393     __declspec(property(get = getIsHfaRegArg)) bool isHfaRegArg;
1394     bool getIsHfaRegArg()
1395     {
1396 #ifdef FEATURE_HFA
1397         return _isHfaArg && isPassedInRegisters();
1398 #else
1399         return false;
1400 #endif
1401     }
1402
1403     __declspec(property(get = getHfaType)) var_types hfaType;
1404     var_types getHfaType()
1405     {
1406 #ifdef FEATURE_HFA
1407         return _isHfaArg ? (_isDoubleHfa ? TYP_DOUBLE : TYP_FLOAT) : TYP_UNDEF;
1408 #else
1409         return TYP_UNDEF;
1410 #endif
1411     }
1412
1413     void setHfaType(var_types type, unsigned hfaSlots)
1414     {
1415 #ifdef FEATURE_HFA
1416         if (type != TYP_UNDEF)
1417         {
1418             // We must already have set the passing mode.
1419             assert(numRegs != 0 || numSlots != 0);
1420             // We originally set numRegs according to the size of the struct, but if the size of the
1421             // hfaType is not the same as the pointer size, we need to correct it.
1422             // Note that hfaSlots is the number of registers we will use. For ARM, that is twice
1423             // the number of "double registers".
1424             unsigned numHfaRegs = hfaSlots;
1425             if (isPassedInRegisters())
1426             {
1427 #ifdef _TARGET_ARM_
1428                 if (type == TYP_DOUBLE)
1429                 {
1430                     // Must be an even number of registers.
1431                     assert((numRegs & 1) == 0);
1432                     numHfaRegs = hfaSlots / 2;
1433                 }
1434 #endif // _TARGET_ARM_
1435                 if (_isHfaArg)
1436                 {
1437                     // This should already be set correctly.
1438                     assert(numRegs == numHfaRegs);
1439                     assert(_isDoubleHfa == (type == TYP_DOUBLE));
1440                 }
1441                 else
1442                 {
1443                     numRegs = numHfaRegs;
1444                 }
1445             }
1446             _isDoubleHfa = (type == TYP_DOUBLE);
1447             _isHfaArg    = true;
1448         }
1449 #endif // FEATURE_HFA
1450     }
1451
1452 #ifdef _TARGET_ARM_
1453     void SetIsBackFilled(bool backFilled)
1454     {
1455         isBackFilled = backFilled;
1456     }
1457
1458     bool IsBackFilled() const
1459     {
1460         return isBackFilled;
1461     }
1462 #else  // !_TARGET_ARM_
1463     void SetIsBackFilled(bool backFilled)
1464     {
1465     }
1466
1467     bool IsBackFilled() const
1468     {
1469         return false;
1470     }
1471 #endif // !_TARGET_ARM_
1472
1473     bool isPassedInRegisters()
1474     {
1475         return !isSplit && (numRegs != 0);
1476     }
1477
1478     bool isPassedInFloatRegisters()
1479     {
1480 #ifdef _TARGET_X86
1481         return false;
1482 #else
1483         return isValidFloatArgReg(regNum);
1484 #endif
1485     }
1486
1487     bool isSingleRegOrSlot()
1488     {
1489         return !isSplit && ((numRegs == 1) || (numSlots == 1));
1490     }
1491
1492     // Returns the number of "slots" used, where for this purpose a
1493     // register counts as a slot.
1494     unsigned getSlotCount()
1495     {
1496         if (isBackFilled)
1497         {
1498             assert(isPassedInRegisters());
1499             assert(numRegs == 1);
1500         }
1501         else if (regNum == REG_STK)
1502         {
1503             assert(!isPassedInRegisters());
1504             assert(numRegs == 0);
1505         }
1506         else
1507         {
1508             assert(numRegs > 0);
1509         }
1510         return numSlots + numRegs;
1511     }
1512
1513     // Returns the size as a multiple of pointer-size.
1514     // For targets without HFAs, this is the same as getSlotCount().
1515     unsigned getSize()
1516     {
1517         unsigned size = getSlotCount();
1518 #ifdef FEATURE_HFA
1519 #ifdef _TARGET_ARM_
1520         // We counted the number of regs, but if they are DOUBLE hfa regs we have to double the size.
1521         if (isHfaRegArg && (hfaType == TYP_DOUBLE))
1522         {
1523             assert(!isSplit);
1524             size <<= 1;
1525         }
1526 #elif defined(_TARGET_ARM64_)
1527         // We counted the number of regs, but if they are FLOAT hfa regs we have to halve the size.
1528         if (isHfaRegArg && (hfaType == TYP_FLOAT))
1529         {
1530             // Round up in case of odd HFA count.
1531             size = (size + 1) >> 1;
1532         }
1533 #endif // _TARGET_ARM64_
1534 #endif
1535         return size;
1536     }
1537
1538     // Set the register numbers for a multireg argument.
1539     // There's nothing to do on x64/Ux because the structDesc has already been used to set the
1540     // register numbers.
1541     void SetMultiRegNums()
1542     {
1543 #if FEATURE_MULTIREG_ARGS && !defined(UNIX_AMD64_ABI)
1544         if (numRegs == 1)
1545         {
1546             return;
1547         }
1548
1549         regNumber argReg = getRegNum(0);
1550 #ifdef _TARGET_ARM_
1551         unsigned int regSize = (hfaType == TYP_DOUBLE) ? 2 : 1;
1552 #else
1553         unsigned int regSize = 1;
1554 #endif
1555         for (unsigned int regIndex = 1; regIndex < numRegs; regIndex++)
1556         {
1557             argReg = (regNumber)(argReg + regSize);
1558             setRegNum(regIndex, argReg);
1559         }
1560 #endif // FEATURE_MULTIREG_ARGS && !defined(UNIX_AMD64_ABI)
1561     }
1562
1563     // Check that the value of 'isStruct' is consistent.
1564     // A struct arg must be one of the following:
1565     // - A node of struct type,
1566     // - A GT_FIELD_LIST, or
1567     // - A node of a scalar type, passed in a single register or slot
1568     //   (or two slots in the case of a struct pass on the stack as TYP_DOUBLE).
1569     //
1570     void checkIsStruct()
1571     {
1572         if (isStruct)
1573         {
1574             if (!varTypeIsStruct(node) && !node->OperIs(GT_FIELD_LIST))
1575             {
1576                 // This is the case where we are passing a struct as a primitive type.
1577                 // On most targets, this is always a single register or slot.
1578                 // However, on ARM this could be two slots if it is TYP_DOUBLE.
1579                 bool isPassedAsPrimitiveType = ((numRegs == 1) || ((numRegs == 0) && (numSlots == 1)));
1580 #ifdef _TARGET_ARM_
1581                 if (!isPassedAsPrimitiveType)
1582                 {
1583                     if (node->TypeGet() == TYP_DOUBLE && numRegs == 0 && (numSlots == 2))
1584                     {
1585                         isPassedAsPrimitiveType = true;
1586                     }
1587                 }
1588 #endif // _TARGET_ARM_
1589                 assert(isPassedAsPrimitiveType);
1590             }
1591         }
1592         else
1593         {
1594             assert(!varTypeIsStruct(node));
1595         }
1596     }
1597
1598 #ifdef DEBUG
1599     void Dump();
1600 #endif
1601 };
1602
1603 //-------------------------------------------------------------------------
1604 //
1605 //  The class fgArgInfo is used to handle the arguments
1606 //  when morphing a GT_CALL node.
1607 //
1608
1609 class fgArgInfo
1610 {
1611     Compiler*    compiler;    // Back pointer to the compiler instance so that we can allocate memory
1612     GenTreeCall* callTree;    // Back pointer to the GT_CALL node for this fgArgInfo
1613     unsigned     argCount;    // Updatable arg count value
1614     unsigned     nextSlotNum; // Updatable slot count value
1615     unsigned     stkLevel;    // Stack depth when we make this call (for x86)
1616
1617 #if defined(UNIX_X86_ABI)
1618     bool     alignmentDone; // Updateable flag, set to 'true' after we've done any required alignment.
1619     unsigned stkSizeBytes;  // Size of stack used by this call, in bytes. Calculated during fgMorphArgs().
1620     unsigned padStkAlign;   // Stack alignment in bytes required before arguments are pushed for this call.
1621                             // Computed dynamically during codegen, based on stkSizeBytes and the current
1622                             // stack level (genStackLevel) when the first stack adjustment is made for
1623                             // this call.
1624 #endif
1625
1626 #if FEATURE_FIXED_OUT_ARGS
1627     unsigned outArgSize; // Size of the out arg area for the call, will be at least MIN_ARG_AREA_FOR_CALL
1628 #endif
1629
1630     unsigned        argTableSize; // size of argTable array (equal to the argCount when done with fgMorphArgs)
1631     bool            hasRegArgs;   // true if we have one or more register arguments
1632     bool            hasStackArgs; // true if we have one or more stack arguments
1633     bool            argsComplete; // marker for state
1634     bool            argsSorted;   // marker for state
1635     fgArgTabEntry** argTable;     // variable sized array of per argument descrption: (i.e. argTable[argTableSize])
1636
1637 private:
1638     void AddArg(fgArgTabEntry* curArgTabEntry);
1639
1640 public:
1641     fgArgInfo(Compiler* comp, GenTreeCall* call, unsigned argCount);
1642     fgArgInfo(GenTreeCall* newCall, GenTreeCall* oldCall);
1643
1644     fgArgTabEntry* AddRegArg(unsigned  argNum,
1645                              GenTree*  node,
1646                              GenTree*  parent,
1647                              regNumber regNum,
1648                              unsigned  numRegs,
1649                              unsigned  alignment,
1650                              bool      isStruct,
1651                              bool      isVararg = false);
1652
1653 #ifdef UNIX_AMD64_ABI
1654     fgArgTabEntry* AddRegArg(unsigned                                                         argNum,
1655                              GenTree*                                                         node,
1656                              GenTree*                                                         parent,
1657                              regNumber                                                        regNum,
1658                              unsigned                                                         numRegs,
1659                              unsigned                                                         alignment,
1660                              const bool                                                       isStruct,
1661                              const bool                                                       isVararg,
1662                              const regNumber                                                  otherRegNum,
1663                              const SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* const structDescPtr = nullptr);
1664 #endif // UNIX_AMD64_ABI
1665
1666     fgArgTabEntry* AddStkArg(unsigned argNum,
1667                              GenTree* node,
1668                              GenTree* parent,
1669                              unsigned numSlots,
1670                              unsigned alignment,
1671                              bool     isStruct,
1672                              bool     isVararg = false);
1673
1674     void RemorphReset();
1675     void UpdateRegArg(fgArgTabEntry* argEntry, GenTree* node, bool reMorphing);
1676     void UpdateStkArg(fgArgTabEntry* argEntry, GenTree* node, bool reMorphing);
1677
1678     void SplitArg(unsigned argNum, unsigned numRegs, unsigned numSlots);
1679
1680     void EvalToTmp(fgArgTabEntry* curArgTabEntry, unsigned tmpNum, GenTree* newNode);
1681
1682     void ArgsComplete();
1683
1684     void SortArgs();
1685
1686     void EvalArgsToTemps();
1687
1688     unsigned ArgCount()
1689     {
1690         return argCount;
1691     }
1692     fgArgTabEntry** ArgTable()
1693     {
1694         return argTable;
1695     }
1696     unsigned GetNextSlotNum()
1697     {
1698         return nextSlotNum;
1699     }
1700     bool HasRegArgs()
1701     {
1702         return hasRegArgs;
1703     }
1704     bool HasStackArgs()
1705     {
1706         return hasStackArgs;
1707     }
1708     bool AreArgsComplete() const
1709     {
1710         return argsComplete;
1711     }
1712 #if FEATURE_FIXED_OUT_ARGS
1713     unsigned GetOutArgSize() const
1714     {
1715         return outArgSize;
1716     }
1717     void SetOutArgSize(unsigned newVal)
1718     {
1719         outArgSize = newVal;
1720     }
1721 #endif // FEATURE_FIXED_OUT_ARGS
1722
1723 #if defined(UNIX_X86_ABI)
1724     void ComputeStackAlignment(unsigned curStackLevelInBytes)
1725     {
1726         padStkAlign = AlignmentPad(curStackLevelInBytes, STACK_ALIGN);
1727     }
1728
1729     unsigned GetStkAlign()
1730     {
1731         return padStkAlign;
1732     }
1733
1734     void SetStkSizeBytes(unsigned newStkSizeBytes)
1735     {
1736         stkSizeBytes = newStkSizeBytes;
1737     }
1738
1739     unsigned GetStkSizeBytes() const
1740     {
1741         return stkSizeBytes;
1742     }
1743
1744     bool IsStkAlignmentDone() const
1745     {
1746         return alignmentDone;
1747     }
1748
1749     void SetStkAlignmentDone()
1750     {
1751         alignmentDone = true;
1752     }
1753 #endif // defined(UNIX_X86_ABI)
1754
1755     // Get the fgArgTabEntry for the arg at position argNum.
1756     fgArgTabEntry* GetArgEntry(unsigned argNum, bool reMorphing = true)
1757     {
1758         fgArgTabEntry* curArgTabEntry = nullptr;
1759
1760         if (!reMorphing)
1761         {
1762             // The arg table has not yet been sorted.
1763             curArgTabEntry = argTable[argNum];
1764             assert(curArgTabEntry->argNum == argNum);
1765             return curArgTabEntry;
1766         }
1767
1768         for (unsigned i = 0; i < argCount; i++)
1769         {
1770             curArgTabEntry = argTable[i];
1771             if (curArgTabEntry->argNum == argNum)
1772             {
1773                 return curArgTabEntry;
1774             }
1775         }
1776         noway_assert(!"GetArgEntry: argNum not found");
1777         return nullptr;
1778     }
1779
1780     // Get the node for the arg at position argIndex.
1781     // Caller must ensure that this index is a valid arg index.
1782     GenTree* GetArgNode(unsigned argIndex)
1783     {
1784         return GetArgEntry(argIndex)->node;
1785     }
1786
1787     void Dump(Compiler* compiler);
1788 };
1789
1790 #ifdef DEBUG
1791 // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1792 // We have the ability to mark source expressions with "Test Labels."
1793 // These drive assertions within the JIT, or internal JIT testing.  For example, we could label expressions
1794 // that should be CSE defs, and other expressions that should uses of those defs, with a shared label.
1795
1796 enum TestLabel // This must be kept identical to System.Runtime.CompilerServices.JitTestLabel.TestLabel.
1797 {
1798     TL_SsaName,
1799     TL_VN,        // Defines a "VN equivalence class".  (For full VN, including exceptions thrown).
1800     TL_VNNorm,    // Like above, but uses the non-exceptional value of the expression.
1801     TL_CSE_Def,   //  This must be identified in the JIT as a CSE def
1802     TL_CSE_Use,   //  This must be identified in the JIT as a CSE use
1803     TL_LoopHoist, // Expression must (or must not) be hoisted out of the loop.
1804 };
1805
1806 struct TestLabelAndNum
1807 {
1808     TestLabel m_tl;
1809     ssize_t   m_num;
1810
1811     TestLabelAndNum() : m_tl(TestLabel(0)), m_num(0)
1812     {
1813     }
1814 };
1815
1816 typedef JitHashTable<GenTree*, JitPtrKeyFuncs<GenTree>, TestLabelAndNum> NodeToTestDataMap;
1817
1818 // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1819 #endif // DEBUG
1820
1821 /*
1822 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1823 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1824 XX                                                                           XX
1825 XX   The big guy. The sections are currently organized as :                  XX
1826 XX                                                                           XX
1827 XX    o  GenTree and BasicBlock                                              XX
1828 XX    o  LclVarsInfo                                                         XX
1829 XX    o  Importer                                                            XX
1830 XX    o  FlowGraph                                                           XX
1831 XX    o  Optimizer                                                           XX
1832 XX    o  RegAlloc                                                            XX
1833 XX    o  EEInterface                                                         XX
1834 XX    o  TempsInfo                                                           XX
1835 XX    o  RegSet                                                              XX
1836 XX    o  GCInfo                                                              XX
1837 XX    o  Instruction                                                         XX
1838 XX    o  ScopeInfo                                                           XX
1839 XX    o  PrologScopeInfo                                                     XX
1840 XX    o  CodeGenerator                                                       XX
1841 XX    o  UnwindInfo                                                          XX
1842 XX    o  Compiler                                                            XX
1843 XX    o  typeInfo                                                            XX
1844 XX                                                                           XX
1845 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1846 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1847 */
1848
1849 struct HWIntrinsicInfo;
1850
1851 class Compiler
1852 {
1853     friend class emitter;
1854     friend class UnwindInfo;
1855     friend class UnwindFragmentInfo;
1856     friend class UnwindEpilogInfo;
1857     friend class JitTimer;
1858     friend class LinearScan;
1859     friend class fgArgInfo;
1860     friend class Rationalizer;
1861     friend class Phase;
1862     friend class Lowering;
1863     friend class CSE_DataFlow;
1864     friend class CSE_Heuristic;
1865     friend class CodeGenInterface;
1866     friend class CodeGen;
1867     friend class LclVarDsc;
1868     friend class TempDsc;
1869     friend class LIR;
1870     friend class ObjectAllocator;
1871     friend class LocalAddressVisitor;
1872     friend struct GenTree;
1873
1874 #ifdef FEATURE_HW_INTRINSICS
1875     friend struct HWIntrinsicInfo;
1876 #endif // FEATURE_HW_INTRINSICS
1877
1878 #ifndef _TARGET_64BIT_
1879     friend class DecomposeLongs;
1880 #endif // !_TARGET_64BIT_
1881
1882     /*
1883     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1884     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1885     XX                                                                           XX
1886     XX  Misc structs definitions                                                 XX
1887     XX                                                                           XX
1888     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1889     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1890     */
1891
1892 public:
1893     hashBvGlobalData hbvGlobalData; // Used by the hashBv bitvector package.
1894
1895 #ifdef DEBUG
1896     bool    verbose;
1897     bool    dumpIR;
1898     bool    dumpIRNodes;
1899     bool    dumpIRTypes;
1900     bool    dumpIRKinds;
1901     bool    dumpIRLocals;
1902     bool    dumpIRRegs;
1903     bool    dumpIRSsa;
1904     bool    dumpIRValnums;
1905     bool    dumpIRCosts;
1906     bool    dumpIRFlags;
1907     bool    dumpIRNoLists;
1908     bool    dumpIRNoLeafs;
1909     bool    dumpIRNoStmts;
1910     bool    dumpIRTrees;
1911     bool    dumpIRLinear;
1912     bool    dumpIRDataflow;
1913     bool    dumpIRBlockHeaders;
1914     bool    dumpIRExit;
1915     LPCWSTR dumpIRPhase;
1916     LPCWSTR dumpIRFormat;
1917     bool    verboseTrees;
1918     bool    shouldUseVerboseTrees();
1919     bool    asciiTrees; // If true, dump trees using only ASCII characters
1920     bool    shouldDumpASCIITrees();
1921     bool    verboseSsa; // If true, produce especially verbose dump output in SSA construction.
1922     bool    shouldUseVerboseSsa();
1923     bool    treesBeforeAfterMorph; // If true, print trees before/after morphing (paired by an intra-compilation id:
1924     int     morphNum; // This counts the the trees that have been morphed, allowing us to label each uniquely.
1925
1926     const char* VarNameToStr(VarName name)
1927     {
1928         return name;
1929     }
1930
1931     DWORD expensiveDebugCheckLevel;
1932 #endif
1933
1934 #if FEATURE_MULTIREG_RET
1935     GenTree* impAssignMultiRegTypeToVar(GenTree* op, CORINFO_CLASS_HANDLE hClass);
1936 #endif // FEATURE_MULTIREG_RET
1937
1938     GenTree* impAssignSmallStructTypeToVar(GenTree* op, CORINFO_CLASS_HANDLE hClass);
1939
1940 #ifdef ARM_SOFTFP
1941     bool isSingleFloat32Struct(CORINFO_CLASS_HANDLE hClass);
1942 #endif // ARM_SOFTFP
1943
1944     //-------------------------------------------------------------------------
1945     // Functions to handle homogeneous floating-point aggregates (HFAs) in ARM.
1946     // HFAs are one to four element structs where each element is the same
1947     // type, either all float or all double. They are treated specially
1948     // in the ARM Procedure Call Standard, specifically, they are passed in
1949     // floating-point registers instead of the general purpose registers.
1950     //
1951
1952     bool IsHfa(CORINFO_CLASS_HANDLE hClass);
1953     bool IsHfa(GenTree* tree);
1954
1955     var_types GetHfaType(GenTree* tree);
1956     unsigned GetHfaCount(GenTree* tree);
1957
1958     var_types GetHfaType(CORINFO_CLASS_HANDLE hClass);
1959     unsigned GetHfaCount(CORINFO_CLASS_HANDLE hClass);
1960
1961     bool IsMultiRegReturnedType(CORINFO_CLASS_HANDLE hClass);
1962
1963     //-------------------------------------------------------------------------
1964     // The following is used for validating format of EH table
1965     //
1966
1967     struct EHNodeDsc;
1968     typedef struct EHNodeDsc* pEHNodeDsc;
1969
1970     EHNodeDsc* ehnTree; // root of the tree comprising the EHnodes.
1971     EHNodeDsc* ehnNext; // root of the tree comprising the EHnodes.
1972
1973     struct EHNodeDsc
1974     {
1975         enum EHBlockType
1976         {
1977             TryNode,
1978             FilterNode,
1979             HandlerNode,
1980             FinallyNode,
1981             FaultNode
1982         };
1983
1984         EHBlockType ehnBlockType;   // kind of EH block
1985         IL_OFFSET   ehnStartOffset; // IL offset of start of the EH block
1986         IL_OFFSET ehnEndOffset; // IL offset past end of the EH block. (TODO: looks like verInsertEhNode() sets this to
1987                                 // the last IL offset, not "one past the last one", i.e., the range Start to End is
1988                                 // inclusive).
1989         pEHNodeDsc ehnNext;     // next (non-nested) block in sequential order
1990         pEHNodeDsc ehnChild;    // leftmost nested block
1991         union {
1992             pEHNodeDsc ehnTryNode;     // for filters and handlers, the corresponding try node
1993             pEHNodeDsc ehnHandlerNode; // for a try node, the corresponding handler node
1994         };
1995         pEHNodeDsc ehnFilterNode; // if this is a try node and has a filter, otherwise 0
1996         pEHNodeDsc ehnEquivalent; // if blockType=tryNode, start offset and end offset is same,
1997
1998         void ehnSetTryNodeType()
1999         {
2000             ehnBlockType = TryNode;
2001         }
2002         void ehnSetFilterNodeType()
2003         {
2004             ehnBlockType = FilterNode;
2005         }
2006         void ehnSetHandlerNodeType()
2007         {
2008             ehnBlockType = HandlerNode;
2009         }
2010         void ehnSetFinallyNodeType()
2011         {
2012             ehnBlockType = FinallyNode;
2013         }
2014         void ehnSetFaultNodeType()
2015         {
2016             ehnBlockType = FaultNode;
2017         }
2018
2019         BOOL ehnIsTryBlock()
2020         {
2021             return ehnBlockType == TryNode;
2022         }
2023         BOOL ehnIsFilterBlock()
2024         {
2025             return ehnBlockType == FilterNode;
2026         }
2027         BOOL ehnIsHandlerBlock()
2028         {
2029             return ehnBlockType == HandlerNode;
2030         }
2031         BOOL ehnIsFinallyBlock()
2032         {
2033             return ehnBlockType == FinallyNode;
2034         }
2035         BOOL ehnIsFaultBlock()
2036         {
2037             return ehnBlockType == FaultNode;
2038         }
2039
2040         // returns true if there is any overlap between the two nodes
2041         static BOOL ehnIsOverlap(pEHNodeDsc node1, pEHNodeDsc node2)
2042         {
2043             if (node1->ehnStartOffset < node2->ehnStartOffset)
2044             {
2045                 return (node1->ehnEndOffset >= node2->ehnStartOffset);
2046             }
2047             else
2048             {
2049                 return (node1->ehnStartOffset <= node2->ehnEndOffset);
2050             }
2051         }
2052
2053         // fails with BADCODE if inner is not completely nested inside outer
2054         static BOOL ehnIsNested(pEHNodeDsc inner, pEHNodeDsc outer)
2055         {
2056             return ((inner->ehnStartOffset >= outer->ehnStartOffset) && (inner->ehnEndOffset <= outer->ehnEndOffset));
2057         }
2058     };
2059
2060 //-------------------------------------------------------------------------
2061 // Exception handling functions
2062 //
2063
2064 #if !FEATURE_EH_FUNCLETS
2065
2066     bool ehNeedsShadowSPslots()
2067     {
2068         return (info.compXcptnsCount || opts.compDbgEnC);
2069     }
2070
2071     // 0 for methods with no EH
2072     // 1 for methods with non-nested EH, or where only the try blocks are nested
2073     // 2 for a method with a catch within a catch
2074     // etc.
2075     unsigned ehMaxHndNestingCount;
2076
2077 #endif // !FEATURE_EH_FUNCLETS
2078
2079     static bool jitIsBetween(unsigned value, unsigned start, unsigned end);
2080     static bool jitIsBetweenInclusive(unsigned value, unsigned start, unsigned end);
2081
2082     bool bbInCatchHandlerILRange(BasicBlock* blk);
2083     bool bbInFilterILRange(BasicBlock* blk);
2084     bool bbInTryRegions(unsigned regionIndex, BasicBlock* blk);
2085     bool bbInExnFlowRegions(unsigned regionIndex, BasicBlock* blk);
2086     bool bbInHandlerRegions(unsigned regionIndex, BasicBlock* blk);
2087     bool bbInCatchHandlerRegions(BasicBlock* tryBlk, BasicBlock* hndBlk);
2088     unsigned short bbFindInnermostCommonTryRegion(BasicBlock* bbOne, BasicBlock* bbTwo);
2089
2090     unsigned short bbFindInnermostTryRegionContainingHandlerRegion(unsigned handlerIndex);
2091     unsigned short bbFindInnermostHandlerRegionContainingTryRegion(unsigned tryIndex);
2092
2093     // Returns true if "block" is the start of a try region.
2094     bool bbIsTryBeg(BasicBlock* block);
2095
2096     // Returns true if "block" is the start of a handler or filter region.
2097     bool bbIsHandlerBeg(BasicBlock* block);
2098
2099     // Returns true iff "block" is where control flows if an exception is raised in the
2100     // try region, and sets "*regionIndex" to the index of the try for the handler.
2101     // Differs from "IsHandlerBeg" in the case of filters, where this is true for the first
2102     // block of the filter, but not for the filter's handler.
2103     bool bbIsExFlowBlock(BasicBlock* block, unsigned* regionIndex);
2104
2105     bool ehHasCallableHandlers();
2106
2107     // Return the EH descriptor for the given region index.
2108     EHblkDsc* ehGetDsc(unsigned regionIndex);
2109
2110     // Return the EH index given a region descriptor.
2111     unsigned ehGetIndex(EHblkDsc* ehDsc);
2112
2113     // Return the EH descriptor index of the enclosing try, for the given region index.
2114     unsigned ehGetEnclosingTryIndex(unsigned regionIndex);
2115
2116     // Return the EH descriptor index of the enclosing handler, for the given region index.
2117     unsigned ehGetEnclosingHndIndex(unsigned regionIndex);
2118
2119     // Return the EH descriptor for the most nested 'try' region this BasicBlock is a member of (or nullptr if this
2120     // block is not in a 'try' region).
2121     EHblkDsc* ehGetBlockTryDsc(BasicBlock* block);
2122
2123     // Return the EH descriptor for the most nested filter or handler region this BasicBlock is a member of (or nullptr
2124     // if this block is not in a filter or handler region).
2125     EHblkDsc* ehGetBlockHndDsc(BasicBlock* block);
2126
2127     // Return the EH descriptor for the most nested region that may handle exceptions raised in this BasicBlock (or
2128     // nullptr if this block's exceptions propagate to caller).
2129     EHblkDsc* ehGetBlockExnFlowDsc(BasicBlock* block);
2130
2131     EHblkDsc* ehIsBlockTryLast(BasicBlock* block);
2132     EHblkDsc* ehIsBlockHndLast(BasicBlock* block);
2133     bool ehIsBlockEHLast(BasicBlock* block);
2134
2135     bool ehBlockHasExnFlowDsc(BasicBlock* block);
2136
2137     // Return the region index of the most nested EH region this block is in.
2138     unsigned ehGetMostNestedRegionIndex(BasicBlock* block, bool* inTryRegion);
2139
2140     // Find the true enclosing try index, ignoring 'mutual protect' try. Uses IL ranges to check.
2141     unsigned ehTrueEnclosingTryIndexIL(unsigned regionIndex);
2142
2143     // Return the index of the most nested enclosing region for a particular EH region. Returns NO_ENCLOSING_INDEX
2144     // if there is no enclosing region. If the returned index is not NO_ENCLOSING_INDEX, then '*inTryRegion'
2145     // is set to 'true' if the enclosing region is a 'try', or 'false' if the enclosing region is a handler.
2146     // (It can never be a filter.)
2147     unsigned ehGetEnclosingRegionIndex(unsigned regionIndex, bool* inTryRegion);
2148
2149     // A block has been deleted. Update the EH table appropriately.
2150     void ehUpdateForDeletedBlock(BasicBlock* block);
2151
2152     // Determine whether a block can be deleted while preserving the EH normalization rules.
2153     bool ehCanDeleteEmptyBlock(BasicBlock* block);
2154
2155     // Update the 'last' pointers in the EH table to reflect new or deleted blocks in an EH region.
2156     void ehUpdateLastBlocks(BasicBlock* oldLast, BasicBlock* newLast);
2157
2158     // For a finally handler, find the region index that the BBJ_CALLFINALLY lives in that calls the handler,
2159     // or NO_ENCLOSING_INDEX if the BBJ_CALLFINALLY lives in the main function body. Normally, the index
2160     // is the same index as the handler (and the BBJ_CALLFINALLY lives in the 'try' region), but for AMD64 the
2161     // BBJ_CALLFINALLY lives in the enclosing try or handler region, whichever is more nested, or the main function
2162     // body. If the returned index is not NO_ENCLOSING_INDEX, then '*inTryRegion' is set to 'true' if the
2163     // BBJ_CALLFINALLY lives in the returned index's 'try' region, or 'false' if lives in the handler region. (It never
2164     // lives in a filter.)
2165     unsigned ehGetCallFinallyRegionIndex(unsigned finallyIndex, bool* inTryRegion);
2166
2167     // Find the range of basic blocks in which all BBJ_CALLFINALLY will be found that target the 'finallyIndex' region's
2168     // handler. Set begBlk to the first block, and endBlk to the block after the last block of the range
2169     // (nullptr if the last block is the last block in the program).
2170     // Precondition: 'finallyIndex' is the EH region of a try/finally clause.
2171     void ehGetCallFinallyBlockRange(unsigned finallyIndex, BasicBlock** begBlk, BasicBlock** endBlk);
2172
2173 #ifdef DEBUG
2174     // Given a BBJ_CALLFINALLY block and the EH region index of the finally it is calling, return
2175     // 'true' if the BBJ_CALLFINALLY is in the correct EH region.
2176     bool ehCallFinallyInCorrectRegion(BasicBlock* blockCallFinally, unsigned finallyIndex);
2177 #endif // DEBUG
2178
2179 #if FEATURE_EH_FUNCLETS
2180     // Do we need a PSPSym in the main function? For codegen purposes, we only need one
2181     // if there is a filter that protects a region with a nested EH clause (such as a
2182     // try/catch nested in the 'try' body of a try/filter/filter-handler). See
2183     // genFuncletProlog() for more details. However, the VM seems to use it for more
2184     // purposes, maybe including debugging. Until we are sure otherwise, always create
2185     // a PSPSym for functions with any EH.
2186     bool ehNeedsPSPSym() const
2187     {
2188 #ifdef _TARGET_X86_
2189         return false;
2190 #else  // _TARGET_X86_
2191         return compHndBBtabCount > 0;
2192 #endif // _TARGET_X86_
2193     }
2194
2195     bool     ehAnyFunclets();  // Are there any funclets in this function?
2196     unsigned ehFuncletCount(); // Return the count of funclets in the function
2197
2198     unsigned bbThrowIndex(BasicBlock* blk); // Get the index to use as the cache key for sharing throw blocks
2199 #else                                       // !FEATURE_EH_FUNCLETS
2200     bool ehAnyFunclets()
2201     {
2202         return false;
2203     }
2204     unsigned ehFuncletCount()
2205     {
2206         return 0;
2207     }
2208
2209     unsigned bbThrowIndex(BasicBlock* blk)
2210     {
2211         return blk->bbTryIndex;
2212     } // Get the index to use as the cache key for sharing throw blocks
2213 #endif                                      // !FEATURE_EH_FUNCLETS
2214
2215     // Returns a flowList representing the "EH predecessors" of "blk".  These are the normal predecessors of
2216     // "blk", plus one special case: if "blk" is the first block of a handler, considers the predecessor(s) of the first
2217     // first block of the corresponding try region to be "EH predecessors".  (If there is a single such predecessor,
2218     // for example, we want to consider that the immediate dominator of the catch clause start block, so it's
2219     // convenient to also consider it a predecessor.)
2220     flowList* BlockPredsWithEH(BasicBlock* blk);
2221
2222     // This table is useful for memoization of the method above.
2223     typedef JitHashTable<BasicBlock*, JitPtrKeyFuncs<BasicBlock>, flowList*> BlockToFlowListMap;
2224     BlockToFlowListMap* m_blockToEHPreds;
2225     BlockToFlowListMap* GetBlockToEHPreds()
2226     {
2227         if (m_blockToEHPreds == nullptr)
2228         {
2229             m_blockToEHPreds = new (getAllocator()) BlockToFlowListMap(getAllocator());
2230         }
2231         return m_blockToEHPreds;
2232     }
2233
2234     void* ehEmitCookie(BasicBlock* block);
2235     UNATIVE_OFFSET ehCodeOffset(BasicBlock* block);
2236
2237     EHblkDsc* ehInitHndRange(BasicBlock* src, IL_OFFSET* hndBeg, IL_OFFSET* hndEnd, bool* inFilter);
2238
2239     EHblkDsc* ehInitTryRange(BasicBlock* src, IL_OFFSET* tryBeg, IL_OFFSET* tryEnd);
2240
2241     EHblkDsc* ehInitHndBlockRange(BasicBlock* blk, BasicBlock** hndBeg, BasicBlock** hndLast, bool* inFilter);
2242
2243     EHblkDsc* ehInitTryBlockRange(BasicBlock* blk, BasicBlock** tryBeg, BasicBlock** tryLast);
2244
2245     void fgSetTryEnd(EHblkDsc* handlerTab, BasicBlock* newTryLast);
2246
2247     void fgSetHndEnd(EHblkDsc* handlerTab, BasicBlock* newHndLast);
2248
2249     void fgSkipRmvdBlocks(EHblkDsc* handlerTab);
2250
2251     void fgAllocEHTable();
2252
2253     void fgRemoveEHTableEntry(unsigned XTnum);
2254
2255 #if FEATURE_EH_FUNCLETS
2256
2257     EHblkDsc* fgAddEHTableEntry(unsigned XTnum);
2258
2259 #endif // FEATURE_EH_FUNCLETS
2260
2261 #if !FEATURE_EH
2262     void fgRemoveEH();
2263 #endif // !FEATURE_EH
2264
2265     void fgSortEHTable();
2266
2267     // Causes the EH table to obey some well-formedness conditions, by inserting
2268     // empty BB's when necessary:
2269     //   * No block is both the first block of a handler and the first block of a try.
2270     //   * No block is the first block of multiple 'try' regions.
2271     //   * No block is the last block of multiple EH regions.
2272     void fgNormalizeEH();
2273     bool fgNormalizeEHCase1();
2274     bool fgNormalizeEHCase2();
2275     bool fgNormalizeEHCase3();
2276
2277 #ifdef DEBUG
2278     void dispIncomingEHClause(unsigned num, const CORINFO_EH_CLAUSE& clause);
2279     void dispOutgoingEHClause(unsigned num, const CORINFO_EH_CLAUSE& clause);
2280     void fgVerifyHandlerTab();
2281     void fgDispHandlerTab();
2282 #endif // DEBUG
2283
2284     bool fgNeedToSortEHTable;
2285
2286     void verInitEHTree(unsigned numEHClauses);
2287     void verInsertEhNode(CORINFO_EH_CLAUSE* clause, EHblkDsc* handlerTab);
2288     void verInsertEhNodeInTree(EHNodeDsc** ppRoot, EHNodeDsc* node);
2289     void verInsertEhNodeParent(EHNodeDsc** ppRoot, EHNodeDsc* node);
2290     void verCheckNestingLevel(EHNodeDsc* initRoot);
2291
2292     /*
2293     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2294     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2295     XX                                                                           XX
2296     XX                        GenTree and BasicBlock                             XX
2297     XX                                                                           XX
2298     XX  Functions to allocate and display the GenTrees and BasicBlocks           XX
2299     XX                                                                           XX
2300     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2301     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2302     */
2303
2304     // Functions to create nodes
2305     GenTreeStmt* gtNewStmt(GenTree* expr = nullptr, IL_OFFSETX offset = BAD_IL_OFFSET);
2306
2307     // For unary opers.
2308     GenTree* gtNewOperNode(genTreeOps oper, var_types type, GenTree* op1, bool doSimplifications = TRUE);
2309
2310     // For binary opers.
2311     GenTree* gtNewOperNode(genTreeOps oper, var_types type, GenTree* op1, GenTree* op2);
2312
2313     GenTree* gtNewQmarkNode(var_types type, GenTree* cond, GenTree* colon);
2314
2315     GenTree* gtNewLargeOperNode(genTreeOps oper,
2316                                 var_types  type = TYP_I_IMPL,
2317                                 GenTree*   op1  = nullptr,
2318                                 GenTree*   op2  = nullptr);
2319
2320     GenTreeIntCon* gtNewIconNode(ssize_t value, var_types type = TYP_INT);
2321
2322     GenTree* gtNewPhysRegNode(regNumber reg, var_types type);
2323
2324     GenTree* gtNewJmpTableNode();
2325
2326     GenTree* gtNewIndOfIconHandleNode(var_types indType, size_t value, unsigned iconFlags, bool isInvariant);
2327
2328     GenTree* gtNewIconHandleNode(size_t value, unsigned flags, FieldSeqNode* fields = nullptr);
2329
2330     unsigned gtTokenToIconFlags(unsigned token);
2331
2332     GenTree* gtNewIconEmbHndNode(void* value, void* pValue, unsigned flags, void* compileTimeHandle);
2333
2334     GenTree* gtNewIconEmbScpHndNode(CORINFO_MODULE_HANDLE scpHnd);
2335     GenTree* gtNewIconEmbClsHndNode(CORINFO_CLASS_HANDLE clsHnd);
2336     GenTree* gtNewIconEmbMethHndNode(CORINFO_METHOD_HANDLE methHnd);
2337     GenTree* gtNewIconEmbFldHndNode(CORINFO_FIELD_HANDLE fldHnd);
2338
2339     GenTree* gtNewStringLiteralNode(InfoAccessType iat, void* pValue);
2340
2341     GenTree* gtNewLconNode(__int64 value);
2342
2343     GenTree* gtNewDconNode(double value);
2344
2345     GenTree* gtNewSconNode(int CPX, CORINFO_MODULE_HANDLE scpHandle);
2346
2347     GenTree* gtNewZeroConNode(var_types type);
2348
2349     GenTree* gtNewOneConNode(var_types type);
2350
2351 #ifdef FEATURE_SIMD
2352     GenTree* gtNewSIMDVectorZero(var_types simdType, var_types baseType, unsigned size);
2353     GenTree* gtNewSIMDVectorOne(var_types simdType, var_types baseType, unsigned size);
2354 #endif
2355
2356     GenTree* gtNewBlkOpNode(GenTree* dst, GenTree* srcOrFillVal, unsigned size, bool isVolatile, bool isCopyBlock);
2357
2358     GenTree* gtNewPutArgReg(var_types type, GenTree* arg, regNumber argReg);
2359
2360     GenTree* gtNewBitCastNode(var_types type, GenTree* arg);
2361
2362 protected:
2363     void gtBlockOpInit(GenTree* result, GenTree* dst, GenTree* srcOrFillVal, bool isVolatile);
2364
2365 public:
2366     GenTree* gtNewObjNode(CORINFO_CLASS_HANDLE structHnd, GenTree* addr);
2367     void gtSetObjGcInfo(GenTreeObj* objNode);
2368     GenTree* gtNewStructVal(CORINFO_CLASS_HANDLE structHnd, GenTree* addr);
2369     GenTree* gtNewBlockVal(GenTree* addr, unsigned size);
2370
2371     GenTree* gtNewCpObjNode(GenTree* dst, GenTree* src, CORINFO_CLASS_HANDLE structHnd, bool isVolatile);
2372
2373     GenTreeArgList* gtNewListNode(GenTree* op1, GenTreeArgList* op2);
2374
2375     GenTreeCall* gtNewCallNode(gtCallTypes           callType,
2376                                CORINFO_METHOD_HANDLE handle,
2377                                var_types             type,
2378                                GenTreeArgList*       args,
2379                                IL_OFFSETX            ilOffset = BAD_IL_OFFSET);
2380
2381     GenTreeCall* gtNewIndCallNode(GenTree*        addr,
2382                                   var_types       type,
2383                                   GenTreeArgList* args,
2384                                   IL_OFFSETX      ilOffset = BAD_IL_OFFSET);
2385
2386     GenTreeCall* gtNewHelperCallNode(unsigned helper, var_types type, GenTreeArgList* args = nullptr);
2387
2388     GenTree* gtNewLclvNode(unsigned lnum, var_types type DEBUGARG(IL_OFFSETX ILoffs = BAD_IL_OFFSET));
2389     GenTree* gtNewLclLNode(unsigned lnum, var_types type DEBUGARG(IL_OFFSETX ILoffs = BAD_IL_OFFSET));
2390
2391 #ifdef FEATURE_SIMD
2392     GenTreeSIMD* gtNewSIMDNode(
2393         var_types type, GenTree* op1, SIMDIntrinsicID simdIntrinsicID, var_types baseType, unsigned size);
2394     GenTreeSIMD* gtNewSIMDNode(
2395         var_types type, GenTree* op1, GenTree* op2, SIMDIntrinsicID simdIntrinsicID, var_types baseType, unsigned size);
2396     void SetOpLclRelatedToSIMDIntrinsic(GenTree* op);
2397 #endif
2398
2399 #ifdef FEATURE_HW_INTRINSICS
2400     GenTreeHWIntrinsic* gtNewSimdHWIntrinsicNode(var_types      type,
2401                                                  NamedIntrinsic hwIntrinsicID,
2402                                                  var_types      baseType,
2403                                                  unsigned       size);
2404     GenTreeHWIntrinsic* gtNewSimdHWIntrinsicNode(
2405         var_types type, GenTree* op1, NamedIntrinsic hwIntrinsicID, var_types baseType, unsigned size);
2406     GenTreeHWIntrinsic* gtNewSimdHWIntrinsicNode(
2407         var_types type, GenTree* op1, GenTree* op2, NamedIntrinsic hwIntrinsicID, var_types baseType, unsigned size);
2408     GenTreeHWIntrinsic* gtNewSimdHWIntrinsicNode(var_types      type,
2409                                                  GenTree*       op1,
2410                                                  GenTree*       op2,
2411                                                  GenTree*       op3,
2412                                                  NamedIntrinsic hwIntrinsicID,
2413                                                  var_types      baseType,
2414                                                  unsigned       size);
2415     GenTreeHWIntrinsic* gtNewSimdHWIntrinsicNode(var_types      type,
2416                                                  GenTree*       op1,
2417                                                  GenTree*       op2,
2418                                                  GenTree*       op3,
2419                                                  GenTree*       op4,
2420                                                  NamedIntrinsic hwIntrinsicID,
2421                                                  var_types      baseType,
2422                                                  unsigned       size);
2423     GenTreeHWIntrinsic* gtNewScalarHWIntrinsicNode(var_types type, GenTree* op1, NamedIntrinsic hwIntrinsicID);
2424     GenTreeHWIntrinsic* gtNewScalarHWIntrinsicNode(var_types      type,
2425                                                    GenTree*       op1,
2426                                                    GenTree*       op2,
2427                                                    NamedIntrinsic hwIntrinsicID);
2428     GenTreeHWIntrinsic* gtNewScalarHWIntrinsicNode(
2429         var_types type, GenTree* op1, GenTree* op2, GenTree* op3, NamedIntrinsic hwIntrinsicID);
2430     GenTree* gtNewMustThrowException(unsigned helper, var_types type, CORINFO_CLASS_HANDLE clsHnd);
2431     CORINFO_CLASS_HANDLE gtGetStructHandleForHWSIMD(var_types simdType, var_types simdBaseType);
2432 #endif // FEATURE_HW_INTRINSICS
2433
2434     GenTreeLclFld* gtNewLclFldNode(unsigned lnum, var_types type, unsigned offset);
2435     GenTree* gtNewInlineCandidateReturnExpr(GenTree* inlineCandidate, var_types type);
2436
2437     GenTree* gtNewFieldRef(var_types typ, CORINFO_FIELD_HANDLE fldHnd, GenTree* obj = nullptr, DWORD offset = 0);
2438
2439     GenTree* gtNewIndexRef(var_types typ, GenTree* arrayOp, GenTree* indexOp);
2440
2441     GenTreeArrLen* gtNewArrLen(var_types typ, GenTree* arrayOp, int lenOffset);
2442
2443     GenTree* gtNewIndir(var_types typ, GenTree* addr);
2444
2445     GenTreeArgList* gtNewArgList(GenTree* op);
2446     GenTreeArgList* gtNewArgList(GenTree* op1, GenTree* op2);
2447     GenTreeArgList* gtNewArgList(GenTree* op1, GenTree* op2, GenTree* op3);
2448     GenTreeArgList* gtNewArgList(GenTree* op1, GenTree* op2, GenTree* op3, GenTree* op4);
2449
2450     static fgArgTabEntry* gtArgEntryByArgNum(GenTreeCall* call, unsigned argNum);
2451     static fgArgTabEntry* gtArgEntryByNode(GenTreeCall* call, GenTree* node);
2452     fgArgTabEntry* gtArgEntryByLateArgIndex(GenTreeCall* call, unsigned lateArgInx);
2453     static GenTree* gtArgNodeByLateArgInx(GenTreeCall* call, unsigned lateArgInx);
2454     bool gtArgIsThisPtr(fgArgTabEntry* argEntry);
2455
2456     GenTree* gtNewAssignNode(GenTree* dst, GenTree* src);
2457
2458     GenTree* gtNewTempAssign(unsigned    tmp,
2459                              GenTree*    val,
2460                              GenTree**   pAfterStmt = nullptr,
2461                              IL_OFFSETX  ilOffset   = BAD_IL_OFFSET,
2462                              BasicBlock* block      = nullptr);
2463
2464     GenTree* gtNewRefCOMfield(GenTree*                objPtr,
2465                               CORINFO_RESOLVED_TOKEN* pResolvedToken,
2466                               CORINFO_ACCESS_FLAGS    access,
2467                               CORINFO_FIELD_INFO*     pFieldInfo,
2468                               var_types               lclTyp,
2469                               CORINFO_CLASS_HANDLE    structType,
2470                               GenTree*                assg);
2471
2472     GenTree* gtNewNothingNode();
2473
2474     GenTree* gtNewArgPlaceHolderNode(var_types type, CORINFO_CLASS_HANDLE clsHnd);
2475
2476     GenTree* gtUnusedValNode(GenTree* expr);
2477
2478     GenTreeCast* gtNewCastNode(var_types typ, GenTree* op1, bool fromUnsigned, var_types castType);
2479
2480     GenTreeCast* gtNewCastNodeL(var_types typ, GenTree* op1, bool fromUnsigned, var_types castType);
2481
2482     GenTreeAllocObj* gtNewAllocObjNode(
2483         unsigned int helper, bool helperHasSideEffects, CORINFO_CLASS_HANDLE clsHnd, var_types type, GenTree* op1);
2484
2485     GenTreeAllocObj* gtNewAllocObjNode(CORINFO_RESOLVED_TOKEN* pResolvedToken, BOOL useParent);
2486
2487     GenTree* gtNewRuntimeLookup(CORINFO_GENERIC_HANDLE hnd, CorInfoGenericHandleType hndTyp, GenTree* lookupTree);
2488
2489     //------------------------------------------------------------------------
2490     // Other GenTree functions
2491
2492     GenTree* gtClone(GenTree* tree, bool complexOK = false);
2493
2494     // If `tree` is a lclVar with lclNum `varNum`, return an IntCns with value `varVal`; otherwise,
2495     // create a copy of `tree`, adding specified flags, replacing uses of lclVar `deepVarNum` with
2496     // IntCnses with value `deepVarVal`.
2497     GenTree* gtCloneExpr(
2498         GenTree* tree, unsigned addFlags, unsigned varNum, int varVal, unsigned deepVarNum, int deepVarVal);
2499
2500     // Create a copy of `tree`, optionally adding specifed flags, and optionally mapping uses of local
2501     // `varNum` to int constants with value `varVal`.
2502     GenTree* gtCloneExpr(GenTree* tree, unsigned addFlags = 0, unsigned varNum = BAD_VAR_NUM, int varVal = 0)
2503     {
2504         return gtCloneExpr(tree, addFlags, varNum, varVal, varNum, varVal);
2505     }
2506
2507     // Internal helper for cloning a call
2508     GenTreeCall* gtCloneExprCallHelper(GenTreeCall* call,
2509                                        unsigned     addFlags   = 0,
2510                                        unsigned     deepVarNum = BAD_VAR_NUM,
2511                                        int          deepVarVal = 0);
2512
2513     // Create copy of an inline or guarded devirtualization candidate tree.
2514     GenTreeCall* gtCloneCandidateCall(GenTreeCall* call);
2515
2516     GenTree* gtReplaceTree(GenTree* stmt, GenTree* tree, GenTree* replacementTree);
2517
2518     void gtUpdateSideEffects(GenTree* stmt, GenTree* tree);
2519
2520     void gtUpdateTreeAncestorsSideEffects(GenTree* tree);
2521
2522     void gtUpdateStmtSideEffects(GenTree* stmt);
2523
2524     void gtUpdateNodeSideEffects(GenTree* tree);
2525
2526     void gtUpdateNodeOperSideEffects(GenTree* tree);
2527
2528     // Returns "true" iff the complexity (not formally defined, but first interpretation
2529     // is #of nodes in subtree) of "tree" is greater than "limit".
2530     // (This is somewhat redundant with the "gtCostEx/gtCostSz" fields, but can be used
2531     // before they have been set.)
2532     bool gtComplexityExceeds(GenTree** tree, unsigned limit);
2533
2534     bool gtCompareTree(GenTree* op1, GenTree* op2);
2535
2536     GenTree* gtReverseCond(GenTree* tree);
2537
2538     bool gtHasRef(GenTree* tree, ssize_t lclNum, bool defOnly);
2539
2540     bool gtHasLocalsWithAddrOp(GenTree* tree);
2541
2542     unsigned gtSetListOrder(GenTree* list, bool regs, bool isListCallArgs);
2543
2544     void gtWalkOp(GenTree** op1, GenTree** op2, GenTree* base, bool constOnly);
2545
2546 #ifdef DEBUG
2547     unsigned gtHashValue(GenTree* tree);
2548
2549     GenTree* gtWalkOpEffectiveVal(GenTree* op);
2550 #endif
2551
2552     void gtPrepareCost(GenTree* tree);
2553     bool gtIsLikelyRegVar(GenTree* tree);
2554
2555     // Returns true iff the secondNode can be swapped with firstNode.
2556     bool gtCanSwapOrder(GenTree* firstNode, GenTree* secondNode);
2557
2558     unsigned gtSetEvalOrder(GenTree* tree);
2559
2560     void gtSetStmtInfo(GenTree* stmt);
2561
2562     // Returns "true" iff "node" has any of the side effects in "flags".
2563     bool gtNodeHasSideEffects(GenTree* node, unsigned flags);
2564
2565     // Returns "true" iff "tree" or its (transitive) children have any of the side effects in "flags".
2566     bool gtTreeHasSideEffects(GenTree* tree, unsigned flags);
2567
2568     // Appends 'expr' in front of 'list'
2569     //    'list' will typically start off as 'nullptr'
2570     //    when 'list' is non-null a GT_COMMA node is used to insert 'expr'
2571     GenTree* gtBuildCommaList(GenTree* list, GenTree* expr);
2572
2573     void gtExtractSideEffList(GenTree*  expr,
2574                               GenTree** pList,
2575                               unsigned  flags      = GTF_SIDE_EFFECT,
2576                               bool      ignoreRoot = false);
2577
2578     GenTree* gtGetThisArg(GenTreeCall* call);
2579
2580     // Static fields of struct types (and sometimes the types that those are reduced to) are represented by having the
2581     // static field contain an object pointer to the boxed struct.  This simplifies the GC implementation...but
2582     // complicates the JIT somewhat.  This predicate returns "true" iff a node with type "fieldNodeType", representing
2583     // the given "fldHnd", is such an object pointer.
2584     bool gtIsStaticFieldPtrToBoxedStruct(var_types fieldNodeType, CORINFO_FIELD_HANDLE fldHnd);
2585
2586     // Return true if call is a recursive call; return false otherwise.
2587     // Note when inlining, this looks for calls back to the root method.
2588     bool gtIsRecursiveCall(GenTreeCall* call)
2589     {
2590         return gtIsRecursiveCall(call->gtCallMethHnd);
2591     }
2592
2593     bool gtIsRecursiveCall(CORINFO_METHOD_HANDLE callMethodHandle)
2594     {
2595         return (callMethodHandle == impInlineRoot()->info.compMethodHnd);
2596     }
2597
2598     //-------------------------------------------------------------------------
2599
2600     GenTree* gtFoldExpr(GenTree* tree);
2601     GenTree*
2602 #ifdef __clang__
2603         // TODO-Amd64-Unix: Remove this when the clang optimizer is fixed and/or the method implementation is
2604         // refactored in a simpler code. This is a workaround for a bug in the clang-3.5 optimizer. The issue is that in
2605         // release build the optimizer is mistyping (or just wrongly decides to use 32 bit operation for a corner case
2606         // of MIN_LONG) the args of the (ltemp / lval2) to int (it does a 32 bit div operation instead of 64 bit) - see
2607         // the implementation of the method in gentree.cpp. For the case of lval1 and lval2 equal to MIN_LONG
2608         // (0x8000000000000000) this results in raising a SIGFPE. The method implementation is rather complex. Disable
2609         // optimizations for now.
2610         __attribute__((optnone))
2611 #endif // __clang__
2612         gtFoldExprConst(GenTree* tree);
2613     GenTree* gtFoldExprSpecial(GenTree* tree);
2614     GenTree* gtFoldExprCompare(GenTree* tree);
2615     GenTree* gtCreateHandleCompare(genTreeOps             oper,
2616                                    GenTree*               op1,
2617                                    GenTree*               op2,
2618                                    CorInfoInlineTypeCheck typeCheckInliningResult);
2619     GenTree* gtFoldExprCall(GenTreeCall* call);
2620     GenTree* gtFoldTypeCompare(GenTree* tree);
2621     GenTree* gtFoldTypeEqualityCall(CorInfoIntrinsics methodID, GenTree* op1, GenTree* op2);
2622
2623     // Options to control behavior of gtTryRemoveBoxUpstreamEffects
2624     enum BoxRemovalOptions
2625     {
2626         BR_REMOVE_AND_NARROW, // remove effects, minimize remaining work, return possibly narrowed source tree
2627         BR_REMOVE_AND_NARROW_WANT_TYPE_HANDLE, // remove effects and minimize remaining work, return type handle tree
2628         BR_REMOVE_BUT_NOT_NARROW,              // remove effects, return original source tree
2629         BR_DONT_REMOVE,                        // check if removal is possible, return copy source tree
2630         BR_DONT_REMOVE_WANT_TYPE_HANDLE,       // check if removal is possible, return type handle tree
2631         BR_MAKE_LOCAL_COPY                     // revise box to copy to temp local and return local's address
2632     };
2633
2634     GenTree* gtTryRemoveBoxUpstreamEffects(GenTree* tree, BoxRemovalOptions options = BR_REMOVE_AND_NARROW);
2635     GenTree* gtOptimizeEnumHasFlag(GenTree* thisOp, GenTree* flagOp);
2636
2637     //-------------------------------------------------------------------------
2638     // Get the handle, if any.
2639     CORINFO_CLASS_HANDLE gtGetStructHandleIfPresent(GenTree* tree);
2640     // Get the handle, and assert if not found.
2641     CORINFO_CLASS_HANDLE gtGetStructHandle(GenTree* tree);
2642     // Get the handle for a ref type.
2643     CORINFO_CLASS_HANDLE gtGetClassHandle(GenTree* tree, bool* pIsExact, bool* pIsNonNull);
2644     // Get the class handle for an helper call
2645     CORINFO_CLASS_HANDLE gtGetHelperCallClassHandle(GenTreeCall* call, bool* pIsExact, bool* pIsNonNull);
2646     // Get the element handle for an array of ref type.
2647     CORINFO_CLASS_HANDLE gtGetArrayElementClassHandle(GenTree* array);
2648     // Get a class handle from a helper call argument
2649     CORINFO_CLASS_HANDLE gtGetHelperArgClassHandle(GenTree*  array,
2650                                                    unsigned* runtimeLookupCount = nullptr,
2651                                                    GenTree** handleTree         = nullptr);
2652     // Get the class handle for a field
2653     CORINFO_CLASS_HANDLE gtGetFieldClassHandle(CORINFO_FIELD_HANDLE fieldHnd, bool* pIsExact, bool* pIsNonNull);
2654     // Check if this tree is a gc static base helper call
2655     bool gtIsStaticGCBaseHelperCall(GenTree* tree);
2656
2657 //-------------------------------------------------------------------------
2658 // Functions to display the trees
2659
2660 #ifdef DEBUG
2661     void gtDispNode(GenTree* tree, IndentStack* indentStack, __in_z const char* msg, bool isLIR);
2662
2663     void gtDispVN(GenTree* tree);
2664     void gtDispConst(GenTree* tree);
2665     void gtDispLeaf(GenTree* tree, IndentStack* indentStack);
2666     void gtDispNodeName(GenTree* tree);
2667     void gtDispRegVal(GenTree* tree);
2668
2669     enum IndentInfo
2670     {
2671         IINone,
2672         IIArc,
2673         IIArcTop,
2674         IIArcBottom,
2675         IIEmbedded,
2676         IIError,
2677         IndentInfoCount
2678     };
2679     void gtDispChild(GenTree*             child,
2680                      IndentStack*         indentStack,
2681                      IndentInfo           arcType,
2682                      __in_opt const char* msg     = nullptr,
2683                      bool                 topOnly = false);
2684     void gtDispTree(GenTree*             tree,
2685                     IndentStack*         indentStack = nullptr,
2686                     __in_opt const char* msg         = nullptr,
2687                     bool                 topOnly     = false,
2688                     bool                 isLIR       = false);
2689     void gtGetLclVarNameInfo(unsigned lclNum, const char** ilKindOut, const char** ilNameOut, unsigned* ilNumOut);
2690     int gtGetLclVarName(unsigned lclNum, char* buf, unsigned buf_remaining);
2691     char* gtGetLclVarName(unsigned lclNum);
2692     void gtDispLclVar(unsigned varNum, bool padForBiggestDisp = true);
2693     void gtDispTreeList(GenTree* tree, IndentStack* indentStack = nullptr);
2694     void gtGetArgMsg(GenTreeCall* call, GenTree* arg, unsigned argNum, int listCount, char* bufp, unsigned bufLength);
2695     void gtGetLateArgMsg(GenTreeCall* call, GenTree* arg, int argNum, int listCount, char* bufp, unsigned bufLength);
2696     void gtDispArgList(GenTreeCall* call, IndentStack* indentStack);
2697     void gtDispFieldSeq(FieldSeqNode* pfsn);
2698
2699     void gtDispRange(LIR::ReadOnlyRange const& range);
2700
2701     void gtDispTreeRange(LIR::Range& containingRange, GenTree* tree);
2702
2703     void gtDispLIRNode(GenTree* node, const char* prefixMsg = nullptr);
2704 #endif
2705
2706     // For tree walks
2707
2708     enum fgWalkResult
2709     {
2710         WALK_CONTINUE,
2711         WALK_SKIP_SUBTREES,
2712         WALK_ABORT
2713     };
2714     struct fgWalkData;
2715     typedef fgWalkResult(fgWalkPreFn)(GenTree** pTree, fgWalkData* data);
2716     typedef fgWalkResult(fgWalkPostFn)(GenTree** pTree, fgWalkData* data);
2717
2718 #ifdef DEBUG
2719     static fgWalkPreFn gtAssertColonCond;
2720 #endif
2721     static fgWalkPreFn gtMarkColonCond;
2722     static fgWalkPreFn gtClearColonCond;
2723
2724     GenTree** gtFindLink(GenTree* stmt, GenTree* node);
2725     bool gtHasCatchArg(GenTree* tree);
2726
2727     typedef ArrayStack<GenTree*> GenTreeStack;
2728
2729     static bool gtHasCallOnStack(GenTreeStack* parentStack);
2730
2731 //=========================================================================
2732 // BasicBlock functions
2733 #ifdef DEBUG
2734     // This is a debug flag we will use to assert when creating block during codegen
2735     // as this interferes with procedure splitting. If you know what you're doing, set
2736     // it to true before creating the block. (DEBUG only)
2737     bool fgSafeBasicBlockCreation;
2738 #endif
2739
2740     BasicBlock* bbNewBasicBlock(BBjumpKinds jumpKind);
2741
2742     /*
2743     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2744     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2745     XX                                                                           XX
2746     XX                           LclVarsInfo                                     XX
2747     XX                                                                           XX
2748     XX   The variables to be used by the code generator.                         XX
2749     XX                                                                           XX
2750     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2751     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2752     */
2753
2754     //
2755     // For both PROMOTION_TYPE_NONE and PROMOTION_TYPE_DEPENDENT the struct will
2756     // be placed in the stack frame and it's fields must be laid out sequentially.
2757     //
2758     // For PROMOTION_TYPE_INDEPENDENT each of the struct's fields is replaced by
2759     //  a local variable that can be enregistered or placed in the stack frame.
2760     //  The fields do not need to be laid out sequentially
2761     //
2762     enum lvaPromotionType
2763     {
2764         PROMOTION_TYPE_NONE,        // The struct local is not promoted
2765         PROMOTION_TYPE_INDEPENDENT, // The struct local is promoted,
2766                                     //   and its field locals are independent of its parent struct local.
2767         PROMOTION_TYPE_DEPENDENT    // The struct local is promoted,
2768                                     //   but its field locals depend on its parent struct local.
2769     };
2770
2771     static int __cdecl RefCntCmp(const void* op1, const void* op2);
2772     static int __cdecl WtdRefCntCmp(const void* op1, const void* op2);
2773
2774     /*****************************************************************************/
2775
2776     enum FrameLayoutState
2777     {
2778         NO_FRAME_LAYOUT,
2779         INITIAL_FRAME_LAYOUT,
2780         PRE_REGALLOC_FRAME_LAYOUT,
2781         REGALLOC_FRAME_LAYOUT,
2782         TENTATIVE_FRAME_LAYOUT,
2783         FINAL_FRAME_LAYOUT
2784     };
2785
2786 public:
2787     RefCountState lvaRefCountState; // Current local ref count state
2788
2789     bool lvaLocalVarRefCounted() const
2790     {
2791         return lvaRefCountState == RCS_NORMAL;
2792     }
2793
2794     bool     lvaTrackedFixed; // true: We cannot add new 'tracked' variable
2795     unsigned lvaCount;        // total number of locals
2796
2797     unsigned   lvaRefCount; // total number of references to locals
2798     LclVarDsc* lvaTable;    // variable descriptor table
2799     unsigned   lvaTableCnt; // lvaTable size (>= lvaCount)
2800
2801     LclVarDsc** lvaRefSorted; // table sorted by refcount
2802
2803     unsigned short lvaTrackedCount;       // actual # of locals being tracked
2804     unsigned lvaTrackedCountInSizeTUnits; // min # of size_t's sufficient to hold a bit for all the locals being tracked
2805
2806 #ifdef DEBUG
2807     VARSET_TP lvaTrackedVars; // set of tracked variables
2808 #endif
2809 #ifndef _TARGET_64BIT_
2810     VARSET_TP lvaLongVars; // set of long (64-bit) variables
2811 #endif
2812     VARSET_TP lvaFloatVars; // set of floating-point (32-bit and 64-bit) variables
2813
2814     unsigned lvaCurEpoch; // VarSets are relative to a specific set of tracked var indices.
2815                           // It that changes, this changes.  VarSets from different epochs
2816                           // cannot be meaningfully combined.
2817
2818     unsigned GetCurLVEpoch()
2819     {
2820         return lvaCurEpoch;
2821     }
2822
2823     // reverse map of tracked number to var number
2824     unsigned* lvaTrackedToVarNum;
2825
2826 #if DOUBLE_ALIGN
2827 #ifdef DEBUG
2828     // # of procs compiled a with double-aligned stack
2829     static unsigned s_lvaDoubleAlignedProcsCount;
2830 #endif
2831 #endif
2832
2833     // Getters and setters for address-exposed and do-not-enregister local var properties.
2834     bool lvaVarAddrExposed(unsigned varNum);
2835     void lvaSetVarAddrExposed(unsigned varNum);
2836     bool lvaVarDoNotEnregister(unsigned varNum);
2837 #ifdef DEBUG
2838     // Reasons why we can't enregister.  Some of these correspond to debug properties of local vars.
2839     enum DoNotEnregisterReason
2840     {
2841         DNER_AddrExposed,
2842         DNER_IsStruct,
2843         DNER_LocalField,
2844         DNER_VMNeedsStackAddr,
2845         DNER_LiveInOutOfHandler,
2846         DNER_LiveAcrossUnmanagedCall,
2847         DNER_BlockOp,     // Is read or written via a block operation that explicitly takes the address.
2848         DNER_IsStructArg, // Is a struct passed as an argument in a way that requires a stack location.
2849         DNER_DepField,    // It is a field of a dependently promoted struct
2850         DNER_NoRegVars,   // opts.compFlags & CLFLG_REGVAR is not set
2851         DNER_MinOptsGC,   // It is a GC Ref and we are compiling MinOpts
2852 #if !defined(_TARGET_64BIT_)
2853         DNER_LongParamField, // It is a decomposed field of a long parameter.
2854 #endif
2855 #ifdef JIT32_GCENCODER
2856         DNER_PinningRef,
2857 #endif
2858     };
2859 #endif
2860     void lvaSetVarDoNotEnregister(unsigned varNum DEBUGARG(DoNotEnregisterReason reason));
2861
2862     unsigned lvaVarargsHandleArg;
2863 #ifdef _TARGET_X86_
2864     unsigned lvaVarargsBaseOfStkArgs; // Pointer (computed based on incoming varargs handle) to the start of the stack
2865                                       // arguments
2866 #endif                                // _TARGET_X86_
2867
2868     unsigned lvaInlinedPInvokeFrameVar; // variable representing the InlinedCallFrame
2869     unsigned lvaReversePInvokeFrameVar; // variable representing the reverse PInvoke frame
2870 #if FEATURE_FIXED_OUT_ARGS
2871     unsigned lvaPInvokeFrameRegSaveVar; // variable representing the RegSave for PInvoke inlining.
2872 #endif
2873     unsigned lvaMonAcquired; // boolean variable introduced into in synchronized methods
2874                              // that tracks whether the lock has been taken
2875
2876     unsigned lvaArg0Var; // The lclNum of arg0. Normally this will be info.compThisArg.
2877                          // However, if there is a "ldarga 0" or "starg 0" in the IL,
2878                          // we will redirect all "ldarg(a) 0" and "starg 0" to this temp.
2879
2880     unsigned lvaInlineeReturnSpillTemp; // The temp to spill the non-VOID return expression
2881                                         // in case there are multiple BBJ_RETURN blocks in the inlinee
2882                                         // or if the inlinee has GC ref locals.
2883
2884 #if FEATURE_FIXED_OUT_ARGS
2885     unsigned            lvaOutgoingArgSpaceVar;  // dummy TYP_LCLBLK var for fixed outgoing argument space
2886     PhasedVar<unsigned> lvaOutgoingArgSpaceSize; // size of fixed outgoing argument space
2887 #endif                                           // FEATURE_FIXED_OUT_ARGS
2888
2889 #ifdef _TARGET_ARM_
2890     // On architectures whose ABIs allow structs to be passed in registers, struct promotion will sometimes
2891     // require us to "rematerialize" a struct from it's separate constituent field variables.  Packing several sub-word
2892     // field variables into an argument register is a hard problem.  It's easier to reserve a word of memory into which
2893     // such field can be copied, after which the assembled memory word can be read into the register.  We will allocate
2894     // this variable to be this scratch word whenever struct promotion occurs.
2895     unsigned lvaPromotedStructAssemblyScratchVar;
2896 #endif // _TARGET_ARM_
2897
2898 #if defined(DEBUG) && defined(_TARGET_XARCH_)
2899
2900     unsigned lvaReturnSpCheck; // Stores SP to confirm it is not corrupted on return.
2901
2902 #endif // defined(DEBUG) && defined(_TARGET_XARCH_)
2903
2904 #if defined(DEBUG) && defined(_TARGET_X86_)
2905
2906     unsigned lvaCallSpCheck; // Stores SP to confirm it is not corrupted after every call.
2907
2908 #endif // defined(DEBUG) && defined(_TARGET_X86_)
2909
2910     unsigned lvaGenericsContextUseCount;
2911
2912     bool lvaKeepAliveAndReportThis(); // Synchronized instance method of a reference type, or
2913                                       // CORINFO_GENERICS_CTXT_FROM_THIS?
2914     bool lvaReportParamTypeArg();     // Exceptions and CORINFO_GENERICS_CTXT_FROM_PARAMTYPEARG?
2915
2916 //-------------------------------------------------------------------------
2917 // All these frame offsets are inter-related and must be kept in sync
2918
2919 #if !FEATURE_EH_FUNCLETS
2920     // This is used for the callable handlers
2921     unsigned lvaShadowSPslotsVar; // TYP_BLK variable for all the shadow SP slots
2922 #endif                            // FEATURE_EH_FUNCLETS
2923
2924     int lvaCachedGenericContextArgOffs;
2925     int lvaCachedGenericContextArgOffset(); // For CORINFO_CALLCONV_PARAMTYPE and if generic context is passed as
2926                                             // THIS pointer
2927
2928 #ifdef JIT32_GCENCODER
2929
2930     unsigned lvaLocAllocSPvar; // variable which stores the value of ESP after the the last alloca/localloc
2931
2932 #endif // JIT32_GCENCODER
2933
2934     unsigned lvaNewObjArrayArgs; // variable with arguments for new MD array helper
2935
2936     // TODO-Review: Prior to reg predict we reserve 24 bytes for Spill temps.
2937     //              after the reg predict we will use a computed maxTmpSize
2938     //              which is based upon the number of spill temps predicted by reg predict
2939     //              All this is necessary because if we under-estimate the size of the spill
2940     //              temps we could fail when encoding instructions that reference stack offsets for ARM.
2941     //
2942     // Pre codegen max spill temp size.
2943     static const unsigned MAX_SPILL_TEMP_SIZE = 24;
2944
2945     //-------------------------------------------------------------------------
2946
2947     unsigned lvaGetMaxSpillTempSize();
2948 #ifdef _TARGET_ARM_
2949     bool lvaIsPreSpilled(unsigned lclNum, regMaskTP preSpillMask);
2950 #endif // _TARGET_ARM_
2951     void lvaAssignFrameOffsets(FrameLayoutState curState);
2952     void lvaFixVirtualFrameOffsets();
2953     void lvaUpdateArgsWithInitialReg();
2954     void lvaAssignVirtualFrameOffsetsToArgs();
2955 #ifdef UNIX_AMD64_ABI
2956     int lvaAssignVirtualFrameOffsetToArg(unsigned lclNum, unsigned argSize, int argOffs, int* callerArgOffset);
2957 #else  // !UNIX_AMD64_ABI
2958     int lvaAssignVirtualFrameOffsetToArg(unsigned lclNum, unsigned argSize, int argOffs);
2959 #endif // !UNIX_AMD64_ABI
2960     void lvaAssignVirtualFrameOffsetsToLocals();
2961     int lvaAllocLocalAndSetVirtualOffset(unsigned lclNum, unsigned size, int stkOffs);
2962 #ifdef _TARGET_AMD64_
2963     // Returns true if compCalleeRegsPushed (including RBP if used as frame pointer) is even.
2964     bool lvaIsCalleeSavedIntRegCountEven();
2965 #endif
2966     void lvaAlignFrame();
2967     void lvaAssignFrameOffsetsToPromotedStructs();
2968     int lvaAllocateTemps(int stkOffs, bool mustDoubleAlign);
2969
2970 #ifdef DEBUG
2971     void lvaDumpRegLocation(unsigned lclNum);
2972     void lvaDumpFrameLocation(unsigned lclNum);
2973     void lvaDumpEntry(unsigned lclNum, FrameLayoutState curState, size_t refCntWtdWidth = 6);
2974     void lvaTableDump(FrameLayoutState curState = NO_FRAME_LAYOUT); // NO_FRAME_LAYOUT means use the current frame
2975                                                                     // layout state defined by lvaDoneFrameLayout
2976 #endif
2977
2978 // Limit frames size to 1GB. The maximum is 2GB in theory - make it intentionally smaller
2979 // to avoid bugs from borderline cases.
2980 #define MAX_FrameSize 0x3FFFFFFF
2981     void lvaIncrementFrameSize(unsigned size);
2982
2983     unsigned lvaFrameSize(FrameLayoutState curState);
2984
2985     // Returns the caller-SP-relative offset for the SP/FP relative offset determined by FP based.
2986     int lvaToCallerSPRelativeOffset(int offs, bool isFpBased);
2987
2988     // Returns the caller-SP-relative offset for the local variable "varNum."
2989     int lvaGetCallerSPRelativeOffset(unsigned varNum);
2990
2991     // Returns the SP-relative offset for the local variable "varNum". Illegal to ask this for functions with localloc.
2992     int lvaGetSPRelativeOffset(unsigned varNum);
2993
2994     int lvaToInitialSPRelativeOffset(unsigned offset, bool isFpBased);
2995     int lvaGetInitialSPRelativeOffset(unsigned varNum);
2996
2997     //------------------------ For splitting types ----------------------------
2998
2999     void lvaInitTypeRef();
3000
3001     void lvaInitArgs(InitVarDscInfo* varDscInfo);
3002     void lvaInitThisPtr(InitVarDscInfo* varDscInfo);
3003     void lvaInitRetBuffArg(InitVarDscInfo* varDscInfo);
3004     void lvaInitUserArgs(InitVarDscInfo* varDscInfo);
3005     void lvaInitGenericsCtxt(InitVarDscInfo* varDscInfo);
3006     void lvaInitVarArgsHandle(InitVarDscInfo* varDscInfo);
3007
3008     void lvaInitVarDsc(LclVarDsc*              varDsc,
3009                        unsigned                varNum,
3010                        CorInfoType             corInfoType,
3011                        CORINFO_CLASS_HANDLE    typeHnd,
3012                        CORINFO_ARG_LIST_HANDLE varList,
3013                        CORINFO_SIG_INFO*       varSig);
3014
3015     static unsigned lvaTypeRefMask(var_types type);
3016
3017     var_types lvaGetActualType(unsigned lclNum);
3018     var_types lvaGetRealType(unsigned lclNum);
3019
3020     //-------------------------------------------------------------------------
3021
3022     void lvaInit();
3023
3024     LclVarDsc* lvaGetDesc(unsigned lclNum)
3025     {
3026         assert(lclNum < lvaCount);
3027         return &lvaTable[lclNum];
3028     }
3029
3030     LclVarDsc* lvaGetDesc(GenTreeLclVarCommon* lclVar)
3031     {
3032         assert(lclVar->GetLclNum() < lvaCount);
3033         return &lvaTable[lclVar->GetLclNum()];
3034     }
3035
3036     unsigned lvaLclSize(unsigned varNum);
3037     unsigned lvaLclExactSize(unsigned varNum);
3038
3039     bool lvaHaveManyLocals() const;
3040
3041     unsigned lvaGrabTemp(bool shortLifetime DEBUGARG(const char* reason));
3042     unsigned lvaGrabTemps(unsigned cnt DEBUGARG(const char* reason));
3043     unsigned lvaGrabTempWithImplicitUse(bool shortLifetime DEBUGARG(const char* reason));
3044
3045     void lvaSortOnly();
3046     void lvaSortByRefCount();
3047     void lvaDumpRefCounts();
3048
3049     void lvaMarkLocalVars(); // Local variable ref-counting
3050     void lvaComputeRefCounts(bool isRecompute, bool setSlotNumbers);
3051     void lvaMarkLocalVars(BasicBlock* block, bool isRecompute);
3052
3053     void lvaAllocOutgoingArgSpaceVar(); // Set up lvaOutgoingArgSpaceVar
3054
3055     VARSET_VALRET_TP lvaStmtLclMask(GenTree* stmt);
3056
3057 #ifdef DEBUG
3058     struct lvaStressLclFldArgs
3059     {
3060         Compiler* m_pCompiler;
3061         bool      m_bFirstPass;
3062     };
3063
3064     static fgWalkPreFn lvaStressLclFldCB;
3065     void               lvaStressLclFld();
3066
3067     void lvaDispVarSet(VARSET_VALARG_TP set, VARSET_VALARG_TP allVars);
3068     void lvaDispVarSet(VARSET_VALARG_TP set);
3069
3070 #endif
3071
3072 #ifdef _TARGET_ARM_
3073     int lvaFrameAddress(int varNum, bool mustBeFPBased, regNumber* pBaseReg, int addrModeOffset, bool isFloatUsage);
3074 #else
3075     int lvaFrameAddress(int varNum, bool* pFPbased);
3076 #endif
3077
3078     bool lvaIsParameter(unsigned varNum);
3079     bool lvaIsRegArgument(unsigned varNum);
3080     BOOL lvaIsOriginalThisArg(unsigned varNum); // Is this varNum the original this argument?
3081     BOOL lvaIsOriginalThisReadOnly();           // return TRUE if there is no place in the code
3082                                                 // that writes to arg0
3083
3084     // Struct parameters that are passed by reference are marked as both lvIsParam and lvIsTemp
3085     // (this is an overload of lvIsTemp because there are no temp parameters).
3086     // For x64 this is 3, 5, 6, 7, >8 byte structs that are passed by reference.
3087     // For ARM64, this is structs larger than 16 bytes that are passed by reference.
3088     bool lvaIsImplicitByRefLocal(unsigned varNum)
3089     {
3090 #if defined(_TARGET_AMD64_) || defined(_TARGET_ARM64_)
3091         LclVarDsc* varDsc = &(lvaTable[varNum]);
3092         if (varDsc->lvIsParam && varDsc->lvIsTemp)
3093         {
3094             assert(varTypeIsStruct(varDsc) || (varDsc->lvType == TYP_BYREF));
3095             return true;
3096         }
3097 #endif // defined(_TARGET_AMD64_) || defined(_TARGET_ARM64_)
3098         return false;
3099     }
3100
3101     // Returns true if this local var is a multireg struct
3102     bool lvaIsMultiregStruct(LclVarDsc* varDsc, bool isVararg);
3103
3104     // If the local is a TYP_STRUCT, get/set a class handle describing it
3105     CORINFO_CLASS_HANDLE lvaGetStruct(unsigned varNum);
3106     void lvaSetStruct(unsigned varNum, CORINFO_CLASS_HANDLE typeHnd, bool unsafeValueClsCheck, bool setTypeInfo = true);
3107     void lvaSetStructUsedAsVarArg(unsigned varNum);
3108
3109     // If the local is TYP_REF, set or update the associated class information.
3110     void lvaSetClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool isExact = false);
3111     void lvaSetClass(unsigned varNum, GenTree* tree, CORINFO_CLASS_HANDLE stackHandle = nullptr);
3112     void lvaUpdateClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool isExact = false);
3113     void lvaUpdateClass(unsigned varNum, GenTree* tree, CORINFO_CLASS_HANDLE stackHandle = nullptr);
3114
3115 #define MAX_NumOfFieldsInPromotableStruct 4 // Maximum number of fields in promotable struct
3116
3117     // Info about struct type fields.
3118     struct lvaStructFieldInfo
3119     {
3120         CORINFO_FIELD_HANDLE fldHnd;
3121         unsigned char        fldOffset;
3122         unsigned char        fldOrdinal;
3123         var_types            fldType;
3124         unsigned             fldSize;
3125         CORINFO_CLASS_HANDLE fldTypeHnd;
3126
3127         lvaStructFieldInfo()
3128             : fldHnd(nullptr), fldOffset(0), fldOrdinal(0), fldType(TYP_UNDEF), fldSize(0), fldTypeHnd(nullptr)
3129         {
3130         }
3131     };
3132
3133     // Info about a struct type, instances of which may be candidates for promotion.
3134     struct lvaStructPromotionInfo
3135     {
3136         CORINFO_CLASS_HANDLE typeHnd;
3137         bool                 canPromote;
3138         bool                 containsHoles;
3139         bool                 customLayout;
3140         bool                 fieldsSorted;
3141         unsigned char        fieldCnt;
3142         lvaStructFieldInfo   fields[MAX_NumOfFieldsInPromotableStruct];
3143
3144         lvaStructPromotionInfo(CORINFO_CLASS_HANDLE typeHnd = nullptr)
3145             : typeHnd(typeHnd)
3146             , canPromote(false)
3147             , containsHoles(false)
3148             , customLayout(false)
3149             , fieldsSorted(false)
3150             , fieldCnt(0)
3151         {
3152         }
3153     };
3154
3155     static int __cdecl lvaFieldOffsetCmp(const void* field1, const void* field2);
3156
3157     // This class is responsible for checking validity and profitability of struct promotion.
3158     // If it is both legal and profitable, then TryPromoteStructVar promotes the struct and initializes
3159     // nessesary information for fgMorphStructField to use.
3160     class StructPromotionHelper
3161     {
3162     public:
3163         StructPromotionHelper(Compiler* compiler);
3164
3165         bool CanPromoteStructType(CORINFO_CLASS_HANDLE typeHnd);
3166         bool TryPromoteStructVar(unsigned lclNum);
3167
3168 #ifdef DEBUG
3169         void CheckRetypedAsScalar(CORINFO_FIELD_HANDLE fieldHnd, var_types requestedType);
3170 #endif // DEBUG
3171
3172 #ifdef _TARGET_ARM_
3173         bool GetRequiresScratchVar();
3174 #endif // _TARGET_ARM_
3175
3176     private:
3177         bool CanPromoteStructVar(unsigned lclNum);
3178         bool ShouldPromoteStructVar(unsigned lclNum);
3179         void PromoteStructVar(unsigned lclNum);
3180         void SortStructFields();
3181
3182         lvaStructFieldInfo GetFieldInfo(CORINFO_FIELD_HANDLE fieldHnd, BYTE ordinal);
3183         bool TryPromoteStructField(lvaStructFieldInfo& outerFieldInfo);
3184
3185     private:
3186         Compiler*              compiler;
3187         lvaStructPromotionInfo structPromotionInfo;
3188
3189 #ifdef _TARGET_ARM_
3190         bool requiresScratchVar;
3191 #endif // _TARGET_ARM_
3192
3193 #ifdef DEBUG
3194         typedef JitHashTable<CORINFO_FIELD_HANDLE, JitPtrKeyFuncs<CORINFO_FIELD_STRUCT_>, var_types>
3195                                  RetypedAsScalarFieldsMap;
3196         RetypedAsScalarFieldsMap retypedFieldsMap;
3197 #endif // DEBUG
3198     };
3199
3200     StructPromotionHelper* structPromotionHelper;
3201
3202 #if !defined(_TARGET_64BIT_)
3203     void lvaPromoteLongVars();
3204 #endif // !defined(_TARGET_64BIT_)
3205     unsigned lvaGetFieldLocal(const LclVarDsc* varDsc, unsigned int fldOffset);
3206     lvaPromotionType lvaGetPromotionType(const LclVarDsc* varDsc);
3207     lvaPromotionType lvaGetPromotionType(unsigned varNum);
3208     lvaPromotionType lvaGetParentPromotionType(const LclVarDsc* varDsc);
3209     lvaPromotionType lvaGetParentPromotionType(unsigned varNum);
3210     bool lvaIsFieldOfDependentlyPromotedStruct(const LclVarDsc* varDsc);
3211     bool lvaIsGCTracked(const LclVarDsc* varDsc);
3212
3213 #if defined(FEATURE_SIMD)
3214     bool lvaMapSimd12ToSimd16(const LclVarDsc* varDsc)
3215     {
3216         assert(varDsc->lvType == TYP_SIMD12);
3217         assert(varDsc->lvExactSize == 12);
3218
3219 #if defined(_TARGET_64BIT_)
3220         assert(varDsc->lvSize() == 16);
3221 #endif // defined(_TARGET_64BIT_)
3222
3223         // We make local variable SIMD12 types 16 bytes instead of just 12. lvSize()
3224         // already does this calculation. However, we also need to prevent mapping types if the var is a
3225         // dependently promoted struct field, which must remain its exact size within its parent struct.
3226         // However, we don't know this until late, so we may have already pretended the field is bigger
3227         // before that.
3228         if ((varDsc->lvSize() == 16) && !lvaIsFieldOfDependentlyPromotedStruct(varDsc))
3229         {
3230             return true;
3231         }
3232         else
3233         {
3234             return false;
3235         }
3236     }
3237 #endif // defined(FEATURE_SIMD)
3238
3239     BYTE* lvaGetGcLayout(unsigned varNum);
3240     bool lvaTypeIsGC(unsigned varNum);
3241     unsigned lvaGSSecurityCookie; // LclVar number
3242     bool     lvaTempsHaveLargerOffsetThanVars();
3243
3244     // Returns "true" iff local variable "lclNum" is in SSA form.
3245     bool lvaInSsa(unsigned lclNum)
3246     {
3247         assert(lclNum < lvaCount);
3248         return lvaTable[lclNum].lvInSsa;
3249     }
3250
3251     unsigned lvaSecurityObject;  // variable representing the security object on the stack
3252     unsigned lvaStubArgumentVar; // variable representing the secret stub argument coming in EAX
3253
3254 #if FEATURE_EH_FUNCLETS
3255     unsigned lvaPSPSym; // variable representing the PSPSym
3256 #endif
3257
3258     InlineInfo*     impInlineInfo;
3259     InlineStrategy* m_inlineStrategy;
3260
3261     // The Compiler* that is the root of the inlining tree of which "this" is a member.
3262     Compiler* impInlineRoot();
3263
3264 #if defined(DEBUG) || defined(INLINE_DATA)
3265     unsigned __int64 getInlineCycleCount()
3266     {
3267         return m_compCycles;
3268     }
3269 #endif // defined(DEBUG) || defined(INLINE_DATA)
3270
3271     bool fgNoStructPromotion;      // Set to TRUE to turn off struct promotion for this method.
3272     bool fgNoStructParamPromotion; // Set to TRUE to turn off struct promotion for parameters this method.
3273
3274     //=========================================================================
3275     //                          PROTECTED
3276     //=========================================================================
3277
3278 protected:
3279     //---------------- Local variable ref-counting ----------------------------
3280
3281     void lvaMarkLclRefs(GenTree* tree, BasicBlock* block, GenTreeStmt* stmt, bool isRecompute);
3282     bool IsDominatedByExceptionalEntry(BasicBlock* block);
3283     void SetVolatileHint(LclVarDsc* varDsc);
3284
3285     // Keeps the mapping from SSA #'s to VN's for the implicit memory variables.
3286     SsaDefArray<SsaMemDef> lvMemoryPerSsaData;
3287
3288 public:
3289     // Returns the address of the per-Ssa data for memory at the given ssaNum (which is required
3290     // not to be the SsaConfig::RESERVED_SSA_NUM, which indicates that the variable is
3291     // not an SSA variable).
3292     SsaMemDef* GetMemoryPerSsaData(unsigned ssaNum)
3293     {
3294         return lvMemoryPerSsaData.GetSsaDef(ssaNum);
3295     }
3296
3297     /*
3298     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3299     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3300     XX                                                                           XX
3301     XX                           Importer                                        XX
3302     XX                                                                           XX
3303     XX   Imports the given method and converts it to semantic trees              XX
3304     XX                                                                           XX
3305     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3306     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3307     */
3308
3309 public:
3310     void impInit();
3311
3312     void impImport(BasicBlock* method);
3313
3314     CORINFO_CLASS_HANDLE impGetRefAnyClass();
3315     CORINFO_CLASS_HANDLE impGetRuntimeArgumentHandle();
3316     CORINFO_CLASS_HANDLE impGetTypeHandleClass();
3317     CORINFO_CLASS_HANDLE impGetStringClass();
3318     CORINFO_CLASS_HANDLE impGetObjectClass();
3319
3320     // Returns underlying type of handles returned by ldtoken instruction
3321     var_types GetRuntimeHandleUnderlyingType()
3322     {
3323         // RuntimeTypeHandle is backed by raw pointer on CoreRT and by object reference on other runtimes
3324         return IsTargetAbi(CORINFO_CORERT_ABI) ? TYP_I_IMPL : TYP_REF;
3325     }
3326
3327     void impDevirtualizeCall(GenTreeCall*            call,
3328                              CORINFO_METHOD_HANDLE*  method,
3329                              unsigned*               methodFlags,
3330                              CORINFO_CONTEXT_HANDLE* contextHandle,
3331                              CORINFO_CONTEXT_HANDLE* exactContextHandle,
3332                              bool                    isLateDevirtualization);
3333
3334     //=========================================================================
3335     //                          PROTECTED
3336     //=========================================================================
3337
3338 protected:
3339     //-------------------- Stack manipulation ---------------------------------
3340
3341     unsigned impStkSize; // Size of the full stack
3342
3343 #define SMALL_STACK_SIZE 16 // number of elements in impSmallStack
3344
3345     struct SavedStack // used to save/restore stack contents.
3346     {
3347         unsigned    ssDepth; // number of values on stack
3348         StackEntry* ssTrees; // saved tree values
3349     };
3350
3351     bool impIsPrimitive(CorInfoType type);
3352     bool impILConsumesAddr(const BYTE* codeAddr, CORINFO_METHOD_HANDLE fncHandle, CORINFO_MODULE_HANDLE scpHandle);
3353
3354     void impResolveToken(const BYTE* addr, CORINFO_RESOLVED_TOKEN* pResolvedToken, CorInfoTokenKind kind);
3355
3356     void impPushOnStack(GenTree* tree, typeInfo ti);
3357     void        impPushNullObjRefOnStack();
3358     StackEntry  impPopStack();
3359     StackEntry& impStackTop(unsigned n = 0);
3360     unsigned impStackHeight();
3361
3362     void impSaveStackState(SavedStack* savePtr, bool copy);
3363     void impRestoreStackState(SavedStack* savePtr);
3364
3365     GenTree* impImportLdvirtftn(GenTree* thisPtr, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_CALL_INFO* pCallInfo);
3366
3367     void impImportAndPushBox(CORINFO_RESOLVED_TOKEN* pResolvedToken);
3368
3369     void impImportNewObjArray(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_CALL_INFO* pCallInfo);
3370
3371     bool impCanPInvokeInline();
3372     bool impCanPInvokeInlineCallSite(BasicBlock* block);
3373     void impCheckForPInvokeCall(
3374         GenTreeCall* call, CORINFO_METHOD_HANDLE methHnd, CORINFO_SIG_INFO* sig, unsigned mflags, BasicBlock* block);
3375     GenTreeCall* impImportIndirectCall(CORINFO_SIG_INFO* sig, IL_OFFSETX ilOffset = BAD_IL_OFFSET);
3376     void impPopArgsForUnmanagedCall(GenTree* call, CORINFO_SIG_INFO* sig);
3377
3378     void impInsertHelperCall(CORINFO_HELPER_DESC* helperCall);
3379     void impHandleAccessAllowed(CorInfoIsAccessAllowedResult result, CORINFO_HELPER_DESC* helperCall);
3380     void impHandleAccessAllowedInternal(CorInfoIsAccessAllowedResult result, CORINFO_HELPER_DESC* helperCall);
3381
3382     var_types impImportCall(OPCODE                  opcode,
3383                             CORINFO_RESOLVED_TOKEN* pResolvedToken,
3384                             CORINFO_RESOLVED_TOKEN* pConstrainedResolvedToken, // Is this a "constrained." call on a
3385                                                                                // type parameter?
3386                             GenTree*           newobjThis,
3387                             int                prefixFlags,
3388                             CORINFO_CALL_INFO* callInfo,
3389                             IL_OFFSET          rawILOffset);
3390
3391     CORINFO_CLASS_HANDLE impGetSpecialIntrinsicExactReturnType(CORINFO_METHOD_HANDLE specialIntrinsicHandle);
3392
3393     bool impMethodInfo_hasRetBuffArg(CORINFO_METHOD_INFO* methInfo);
3394
3395     GenTree* impFixupCallStructReturn(GenTreeCall* call, CORINFO_CLASS_HANDLE retClsHnd);
3396
3397     GenTree* impFixupStructReturnType(GenTree* op, CORINFO_CLASS_HANDLE retClsHnd);
3398
3399 #ifdef DEBUG
3400     var_types impImportJitTestLabelMark(int numArgs);
3401 #endif // DEBUG
3402
3403     GenTree* impInitClass(CORINFO_RESOLVED_TOKEN* pResolvedToken);
3404
3405     GenTree* impImportStaticReadOnlyField(void* fldAddr, var_types lclTyp);
3406
3407     GenTree* impImportStaticFieldAccess(CORINFO_RESOLVED_TOKEN* pResolvedToken,
3408                                         CORINFO_ACCESS_FLAGS    access,
3409                                         CORINFO_FIELD_INFO*     pFieldInfo,
3410                                         var_types               lclTyp);
3411
3412     static void impBashVarAddrsToI(GenTree* tree1, GenTree* tree2 = nullptr);
3413
3414     GenTree* impImplicitIorI4Cast(GenTree* tree, var_types dstTyp);
3415
3416     GenTree* impImplicitR4orR8Cast(GenTree* tree, var_types dstTyp);
3417
3418     void impImportLeave(BasicBlock* block);
3419     void impResetLeaveBlock(BasicBlock* block, unsigned jmpAddr);
3420     GenTree* impIntrinsic(GenTree*                newobjThis,
3421                           CORINFO_CLASS_HANDLE    clsHnd,
3422                           CORINFO_METHOD_HANDLE   method,
3423                           CORINFO_SIG_INFO*       sig,
3424                           unsigned                methodFlags,
3425                           int                     memberRef,
3426                           bool                    readonlyCall,
3427                           bool                    tailCall,
3428                           CORINFO_RESOLVED_TOKEN* pContstrainedResolvedToken,
3429                           CORINFO_THIS_TRANSFORM  constraintCallThisTransform,
3430                           CorInfoIntrinsics*      pIntrinsicID,
3431                           bool*                   isSpecialIntrinsic = nullptr);
3432     GenTree* impMathIntrinsic(CORINFO_METHOD_HANDLE method,
3433                               CORINFO_SIG_INFO*     sig,
3434                               var_types             callType,
3435                               CorInfoIntrinsics     intrinsicID,
3436                               bool                  tailCall);
3437     NamedIntrinsic lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method);
3438
3439 #ifdef FEATURE_HW_INTRINSICS
3440     GenTree* impBaseIntrinsic(NamedIntrinsic        intrinsic,
3441                               CORINFO_CLASS_HANDLE  clsHnd,
3442                               CORINFO_METHOD_HANDLE method,
3443                               CORINFO_SIG_INFO*     sig);
3444     GenTree* impHWIntrinsic(NamedIntrinsic        intrinsic,
3445                             CORINFO_METHOD_HANDLE method,
3446                             CORINFO_SIG_INFO*     sig,
3447                             bool                  mustExpand);
3448     GenTree* impUnsupportedHWIntrinsic(unsigned              helper,
3449                                        CORINFO_METHOD_HANDLE method,
3450                                        CORINFO_SIG_INFO*     sig,
3451                                        bool                  mustExpand);
3452
3453 protected:
3454     bool compSupportsHWIntrinsic(InstructionSet isa);
3455
3456 #ifdef _TARGET_XARCH_
3457     GenTree* impSSEIntrinsic(NamedIntrinsic        intrinsic,
3458                              CORINFO_METHOD_HANDLE method,
3459                              CORINFO_SIG_INFO*     sig,
3460                              bool                  mustExpand);
3461     GenTree* impSSE2Intrinsic(NamedIntrinsic        intrinsic,
3462                               CORINFO_METHOD_HANDLE method,
3463                               CORINFO_SIG_INFO*     sig,
3464                               bool                  mustExpand);
3465     GenTree* impSSE42Intrinsic(NamedIntrinsic        intrinsic,
3466                                CORINFO_METHOD_HANDLE method,
3467                                CORINFO_SIG_INFO*     sig,
3468                                bool                  mustExpand);
3469     GenTree* impAvxOrAvx2Intrinsic(NamedIntrinsic        intrinsic,
3470                                    CORINFO_METHOD_HANDLE method,
3471                                    CORINFO_SIG_INFO*     sig,
3472                                    bool                  mustExpand);
3473     GenTree* impAESIntrinsic(NamedIntrinsic        intrinsic,
3474                              CORINFO_METHOD_HANDLE method,
3475                              CORINFO_SIG_INFO*     sig,
3476                              bool                  mustExpand);
3477     GenTree* impBMI1OrBMI2Intrinsic(NamedIntrinsic        intrinsic,
3478                                     CORINFO_METHOD_HANDLE method,
3479                                     CORINFO_SIG_INFO*     sig,
3480                                     bool                  mustExpand);
3481     GenTree* impFMAIntrinsic(NamedIntrinsic        intrinsic,
3482                              CORINFO_METHOD_HANDLE method,
3483                              CORINFO_SIG_INFO*     sig,
3484                              bool                  mustExpand);
3485     GenTree* impLZCNTIntrinsic(NamedIntrinsic        intrinsic,
3486                                CORINFO_METHOD_HANDLE method,
3487                                CORINFO_SIG_INFO*     sig,
3488                                bool                  mustExpand);
3489     GenTree* impPCLMULQDQIntrinsic(NamedIntrinsic        intrinsic,
3490                                    CORINFO_METHOD_HANDLE method,
3491                                    CORINFO_SIG_INFO*     sig,
3492                                    bool                  mustExpand);
3493     GenTree* impPOPCNTIntrinsic(NamedIntrinsic        intrinsic,
3494                                 CORINFO_METHOD_HANDLE method,
3495                                 CORINFO_SIG_INFO*     sig,
3496                                 bool                  mustExpand);
3497
3498 protected:
3499     GenTree* getArgForHWIntrinsic(var_types argType, CORINFO_CLASS_HANDLE argClass);
3500     GenTree* impNonConstFallback(NamedIntrinsic intrinsic, var_types simdType, var_types baseType);
3501     GenTree* addRangeCheckIfNeeded(NamedIntrinsic intrinsic, GenTree* lastOp, bool mustExpand);
3502 #endif // _TARGET_XARCH_
3503 #ifdef _TARGET_ARM64_
3504     InstructionSet lookupHWIntrinsicISA(const char* className);
3505     NamedIntrinsic lookupHWIntrinsic(const char* className, const char* methodName);
3506     bool impCheckImmediate(GenTree* immediateOp, unsigned int max);
3507 #endif // _TARGET_ARM64_
3508 #endif // FEATURE_HW_INTRINSICS
3509     GenTree* impArrayAccessIntrinsic(CORINFO_CLASS_HANDLE clsHnd,
3510                                      CORINFO_SIG_INFO*    sig,
3511                                      int                  memberRef,
3512                                      bool                 readonlyCall,
3513                                      CorInfoIntrinsics    intrinsicID);
3514     GenTree* impInitializeArrayIntrinsic(CORINFO_SIG_INFO* sig);
3515
3516     GenTree* impMethodPointer(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_CALL_INFO* pCallInfo);
3517
3518     GenTree* impTransformThis(GenTree*                thisPtr,
3519                               CORINFO_RESOLVED_TOKEN* pConstrainedResolvedToken,
3520                               CORINFO_THIS_TRANSFORM  transform);
3521
3522     //----------------- Manipulating the trees and stmts ----------------------
3523
3524     GenTree* impTreeList; // Trees for the BB being imported
3525     GenTree* impTreeLast; // The last tree for the current BB
3526
3527 public:
3528     enum
3529     {
3530         CHECK_SPILL_ALL  = -1,
3531         CHECK_SPILL_NONE = -2
3532     };
3533
3534     void impBeginTreeList();
3535     void impEndTreeList(BasicBlock* block, GenTree* firstStmt, GenTree* lastStmt);
3536     void impEndTreeList(BasicBlock* block);
3537     void impAppendStmtCheck(GenTree* stmt, unsigned chkLevel);
3538     void impAppendStmt(GenTree* stmt, unsigned chkLevel);
3539     void impInsertStmtBefore(GenTree* stmt, GenTree* stmtBefore);
3540     GenTree* impAppendTree(GenTree* tree, unsigned chkLevel, IL_OFFSETX offset);
3541     void impInsertTreeBefore(GenTree* tree, IL_OFFSETX offset, GenTree* stmtBefore);
3542     void impAssignTempGen(unsigned    tmp,
3543                           GenTree*    val,
3544                           unsigned    curLevel,
3545                           GenTree**   pAfterStmt = nullptr,
3546                           IL_OFFSETX  ilOffset   = BAD_IL_OFFSET,
3547                           BasicBlock* block      = nullptr);
3548     void impAssignTempGen(unsigned             tmpNum,
3549                           GenTree*             val,
3550                           CORINFO_CLASS_HANDLE structHnd,
3551                           unsigned             curLevel,
3552                           GenTree**            pAfterStmt = nullptr,
3553                           IL_OFFSETX           ilOffset   = BAD_IL_OFFSET,
3554                           BasicBlock*          block      = nullptr);
3555     GenTree* impCloneExpr(GenTree*             tree,
3556                           GenTree**            clone,
3557                           CORINFO_CLASS_HANDLE structHnd,
3558                           unsigned             curLevel,
3559                           GenTree** pAfterStmt DEBUGARG(const char* reason));
3560     GenTree* impAssignStruct(GenTree*             dest,
3561                              GenTree*             src,
3562                              CORINFO_CLASS_HANDLE structHnd,
3563                              unsigned             curLevel,
3564                              GenTree**            pAfterStmt = nullptr,
3565                              IL_OFFSETX           ilOffset   = BAD_IL_OFFSET,
3566                              BasicBlock*          block      = nullptr);
3567     GenTree* impAssignStructPtr(GenTree*             dest,
3568                                 GenTree*             src,
3569                                 CORINFO_CLASS_HANDLE structHnd,
3570                                 unsigned             curLevel,
3571                                 GenTree**            pAfterStmt = nullptr,
3572                                 IL_OFFSETX           ilOffset   = BAD_IL_OFFSET,
3573                                 BasicBlock*          block      = nullptr);
3574
3575     GenTree* impGetStructAddr(GenTree* structVal, CORINFO_CLASS_HANDLE structHnd, unsigned curLevel, bool willDeref);
3576
3577     var_types impNormStructType(CORINFO_CLASS_HANDLE structHnd,
3578                                 BYTE*                gcLayout     = nullptr,
3579                                 unsigned*            numGCVars    = nullptr,
3580                                 var_types*           simdBaseType = nullptr);
3581
3582     GenTree* impNormStructVal(GenTree*             structVal,
3583                               CORINFO_CLASS_HANDLE structHnd,
3584                               unsigned             curLevel,
3585                               bool                 forceNormalization = false);
3586
3587     GenTree* impTokenToHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken,
3588                               BOOL*                   pRuntimeLookup    = nullptr,
3589                               BOOL                    mustRestoreHandle = FALSE,
3590                               BOOL                    importParent      = FALSE);
3591
3592     GenTree* impParentClassTokenToHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken,
3593                                          BOOL*                   pRuntimeLookup    = nullptr,
3594                                          BOOL                    mustRestoreHandle = FALSE)
3595     {
3596         return impTokenToHandle(pResolvedToken, pRuntimeLookup, mustRestoreHandle, TRUE);
3597     }
3598
3599     GenTree* impLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedToken,
3600                              CORINFO_LOOKUP*         pLookup,
3601                              unsigned                flags,
3602                              void*                   compileTimeHandle);
3603
3604     GenTree* getRuntimeContextTree(CORINFO_RUNTIME_LOOKUP_KIND kind);
3605
3606     GenTree* impRuntimeLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedToken,
3607                                     CORINFO_LOOKUP*         pLookup,
3608                                     void*                   compileTimeHandle);
3609
3610     GenTree* impReadyToRunLookupToTree(CORINFO_CONST_LOOKUP* pLookup, unsigned flags, void* compileTimeHandle);
3611
3612     GenTreeCall* impReadyToRunHelperToTree(CORINFO_RESOLVED_TOKEN* pResolvedToken,
3613                                            CorInfoHelpFunc         helper,
3614                                            var_types               type,
3615                                            GenTreeArgList*         arg                = nullptr,
3616                                            CORINFO_LOOKUP_KIND*    pGenericLookupKind = nullptr);
3617
3618     GenTree* impCastClassOrIsInstToTree(GenTree*                op1,
3619                                         GenTree*                op2,
3620                                         CORINFO_RESOLVED_TOKEN* pResolvedToken,
3621                                         bool                    isCastClass);
3622
3623     GenTree* impOptimizeCastClassOrIsInst(GenTree* op1, CORINFO_RESOLVED_TOKEN* pResolvedToken, bool isCastClass);
3624
3625     bool VarTypeIsMultiByteAndCanEnreg(
3626         var_types type, CORINFO_CLASS_HANDLE typeClass, unsigned* typeSize, bool forReturn, bool isVarArg);
3627
3628     bool IsIntrinsicImplementedByUserCall(CorInfoIntrinsics intrinsicId);
3629     bool IsTargetIntrinsic(CorInfoIntrinsics intrinsicId);
3630     bool IsMathIntrinsic(CorInfoIntrinsics intrinsicId);
3631     bool IsMathIntrinsic(GenTree* tree);
3632
3633 private:
3634     //----------------- Importing the method ----------------------------------
3635
3636     CORINFO_CONTEXT_HANDLE impTokenLookupContextHandle; // The context used for looking up tokens.
3637
3638 #ifdef DEBUG
3639     unsigned    impCurOpcOffs;
3640     const char* impCurOpcName;
3641     bool        impNestedStackSpill;
3642
3643     // For displaying instrs with generated native code (-n:B)
3644     GenTree* impLastILoffsStmt; // oldest stmt added for which we did not gtStmtLastILoffs
3645     void     impNoteLastILoffs();
3646 #endif
3647
3648     /* IL offset of the stmt currently being imported. It gets set to
3649        BAD_IL_OFFSET after it has been set in the appended trees. Then it gets
3650        updated at IL offsets for which we have to report mapping info.
3651        It also includes flag bits, so use jitGetILoffs()
3652        to get the actual IL offset value.
3653     */
3654
3655     IL_OFFSETX impCurStmtOffs;
3656     void impCurStmtOffsSet(IL_OFFSET offs);
3657
3658     void impNoteBranchOffs();
3659
3660     unsigned impInitBlockLineInfo();
3661
3662     GenTree* impCheckForNullPointer(GenTree* obj);
3663     bool impIsThis(GenTree* obj);
3664     bool impIsLDFTN_TOKEN(const BYTE* delegateCreateStart, const BYTE* newobjCodeAddr);
3665     bool impIsDUP_LDVIRTFTN_TOKEN(const BYTE* delegateCreateStart, const BYTE* newobjCodeAddr);
3666     bool impIsAnySTLOC(OPCODE opcode)
3667     {
3668         return ((opcode == CEE_STLOC) || (opcode == CEE_STLOC_S) ||
3669                 ((opcode >= CEE_STLOC_0) && (opcode <= CEE_STLOC_3)));
3670     }
3671
3672     GenTreeArgList* impPopList(unsigned count, CORINFO_SIG_INFO* sig, GenTreeArgList* prefixTree = nullptr);
3673
3674     GenTreeArgList* impPopRevList(unsigned count, CORINFO_SIG_INFO* sig, unsigned skipReverseCount = 0);
3675
3676     /*
3677      * Get current IL offset with stack-empty info incoporated
3678      */
3679     IL_OFFSETX impCurILOffset(IL_OFFSET offs, bool callInstruction = false);
3680
3681     //---------------- Spilling the importer stack ----------------------------
3682
3683     // The maximum number of bytes of IL processed without clean stack state.
3684     // It allows to limit the maximum tree size and depth.
3685     static const unsigned MAX_TREE_SIZE = 200;
3686     bool impCanSpillNow(OPCODE prevOpcode);
3687
3688     struct PendingDsc
3689     {
3690         PendingDsc*   pdNext;
3691         BasicBlock*   pdBB;
3692         SavedStack    pdSavedStack;
3693         ThisInitState pdThisPtrInit;
3694     };
3695
3696     PendingDsc* impPendingList; // list of BBs currently waiting to be imported.
3697     PendingDsc* impPendingFree; // Freed up dscs that can be reused
3698
3699     // We keep a byte-per-block map (dynamically extended) in the top-level Compiler object of a compilation.
3700     JitExpandArray<BYTE> impPendingBlockMembers;
3701
3702     // Return the byte for "b" (allocating/extending impPendingBlockMembers if necessary.)
3703     // Operates on the map in the top-level ancestor.
3704     BYTE impGetPendingBlockMember(BasicBlock* blk)
3705     {
3706         return impInlineRoot()->impPendingBlockMembers.Get(blk->bbInd());
3707     }
3708
3709     // Set the byte for "b" to "val" (allocating/extending impPendingBlockMembers if necessary.)
3710     // Operates on the map in the top-level ancestor.
3711     void impSetPendingBlockMember(BasicBlock* blk, BYTE val)
3712     {
3713         impInlineRoot()->impPendingBlockMembers.Set(blk->bbInd(), val);
3714     }
3715
3716     bool impCanReimport;
3717
3718     bool impSpillStackEntry(unsigned level,
3719                             unsigned varNum
3720 #ifdef DEBUG
3721                             ,
3722                             bool        bAssertOnRecursion,
3723                             const char* reason
3724 #endif
3725                             );
3726
3727     void impSpillStackEnsure(bool spillLeaves = false);
3728     void impEvalSideEffects();
3729     void impSpillSpecialSideEff();
3730     void impSpillSideEffects(bool spillGlobEffects, unsigned chkLevel DEBUGARG(const char* reason));
3731     void               impSpillValueClasses();
3732     void               impSpillEvalStack();
3733     static fgWalkPreFn impFindValueClasses;
3734     void impSpillLclRefs(ssize_t lclNum);
3735
3736     BasicBlock* impPushCatchArgOnStack(BasicBlock* hndBlk, CORINFO_CLASS_HANDLE clsHnd, bool isSingleBlockFilter);
3737
3738     void impImportBlockCode(BasicBlock* block);
3739
3740     void impReimportMarkBlock(BasicBlock* block);
3741     void impReimportMarkSuccessors(BasicBlock* block);
3742
3743     void impVerifyEHBlock(BasicBlock* block, bool isTryStart);
3744
3745     void impImportBlockPending(BasicBlock* block);
3746
3747     // Similar to impImportBlockPending, but assumes that block has already been imported once and is being
3748     // reimported for some reason.  It specifically does *not* look at verCurrentState to set the EntryState
3749     // for the block, but instead, just re-uses the block's existing EntryState.
3750     void impReimportBlockPending(BasicBlock* block);
3751
3752     var_types impGetByRefResultType(genTreeOps oper, bool fUnsigned, GenTree** pOp1, GenTree** pOp2);
3753
3754     void impImportBlock(BasicBlock* block);
3755
3756     // Assumes that "block" is a basic block that completes with a non-empty stack. We will assign the values
3757     // on the stack to local variables (the "spill temp" variables). The successor blocks will assume that
3758     // its incoming stack contents are in those locals. This requires "block" and its successors to agree on
3759     // the variables that will be used -- and for all the predecessors of those successors, and the
3760     // successors of those predecessors, etc. Call such a set of blocks closed under alternating
3761     // successor/predecessor edges a "spill clique." A block is a "predecessor" or "successor" member of the
3762     // clique (or, conceivably, both). Each block has a specified sequence of incoming and outgoing spill
3763     // temps. If "block" already has its outgoing spill temps assigned (they are always a contiguous series
3764     // of local variable numbers, so we represent them with the base local variable number), returns that.
3765     // Otherwise, picks a set of spill temps, and propagates this choice to all blocks in the spill clique of
3766     // which "block" is a member (asserting, in debug mode, that no block in this clique had its spill temps
3767     // chosen already. More precisely, that the incoming or outgoing spill temps are not chosen, depending
3768     // on which kind of member of the clique the block is).
3769     unsigned impGetSpillTmpBase(BasicBlock* block);
3770
3771     // Assumes that "block" is a basic block that completes with a non-empty stack. We have previously
3772     // assigned the values on the stack to local variables (the "spill temp" variables). The successor blocks
3773     // will assume that its incoming stack contents are in those locals. This requires "block" and its
3774     // successors to agree on the variables and their types that will be used.  The CLI spec allows implicit
3775     // conversions between 'int' and 'native int' or 'float' and 'double' stack types. So one predecessor can
3776     // push an int and another can push a native int.  For 64-bit we have chosen to implement this by typing
3777     // the "spill temp" as native int, and then importing (or re-importing as needed) so that all the
3778     // predecessors in the "spill clique" push a native int (sign-extending if needed), and all the
3779     // successors receive a native int. Similarly float and double are unified to double.
3780     // This routine is called after a type-mismatch is detected, and it will walk the spill clique to mark
3781     // blocks for re-importation as appropriate (both successors, so they get the right incoming type, and
3782     // predecessors, so they insert an upcast if needed).
3783     void impReimportSpillClique(BasicBlock* block);
3784
3785     // When we compute a "spill clique" (see above) these byte-maps are allocated to have a byte per basic
3786     // block, and represent the predecessor and successor members of the clique currently being computed.
3787     // *** Access to these will need to be locked in a parallel compiler.
3788     JitExpandArray<BYTE> impSpillCliquePredMembers;
3789     JitExpandArray<BYTE> impSpillCliqueSuccMembers;
3790
3791     enum SpillCliqueDir
3792     {
3793         SpillCliquePred,
3794         SpillCliqueSucc
3795     };
3796
3797     // Abstract class for receiving a callback while walking a spill clique
3798     class SpillCliqueWalker
3799     {
3800     public:
3801         virtual void Visit(SpillCliqueDir predOrSucc, BasicBlock* blk) = 0;
3802     };
3803
3804     // This class is used for setting the bbStkTempsIn and bbStkTempsOut on the blocks within a spill clique
3805     class SetSpillTempsBase : public SpillCliqueWalker
3806     {
3807         unsigned m_baseTmp;
3808
3809     public:
3810         SetSpillTempsBase(unsigned baseTmp) : m_baseTmp(baseTmp)
3811         {
3812         }
3813         virtual void Visit(SpillCliqueDir predOrSucc, BasicBlock* blk);
3814     };
3815
3816     // This class is used for implementing impReimportSpillClique part on each block within the spill clique
3817     class ReimportSpillClique : public SpillCliqueWalker
3818     {
3819         Compiler* m_pComp;
3820
3821     public:
3822         ReimportSpillClique(Compiler* pComp) : m_pComp(pComp)
3823         {
3824         }
3825         virtual void Visit(SpillCliqueDir predOrSucc, BasicBlock* blk);
3826     };
3827
3828     // This is the heart of the algorithm for walking spill cliques. It invokes callback->Visit for each
3829     // predecessor or successor within the spill clique
3830     void impWalkSpillCliqueFromPred(BasicBlock* pred, SpillCliqueWalker* callback);
3831
3832     // For a BasicBlock that has already been imported, the EntryState has an array of GenTrees for the
3833     // incoming locals. This walks that list an resets the types of the GenTrees to match the types of
3834     // the VarDscs. They get out of sync when we have int/native int issues (see impReimportSpillClique).
3835     void impRetypeEntryStateTemps(BasicBlock* blk);
3836
3837     BYTE impSpillCliqueGetMember(SpillCliqueDir predOrSucc, BasicBlock* blk);
3838     void impSpillCliqueSetMember(SpillCliqueDir predOrSucc, BasicBlock* blk, BYTE val);
3839
3840     void impPushVar(GenTree* op, typeInfo tiRetVal);
3841     void impLoadVar(unsigned lclNum, IL_OFFSET offset, typeInfo tiRetVal);
3842     void impLoadVar(unsigned lclNum, IL_OFFSET offset)
3843     {
3844         impLoadVar(lclNum, offset, lvaTable[lclNum].lvVerTypeInfo);
3845     }
3846     void impLoadArg(unsigned ilArgNum, IL_OFFSET offset);
3847     void impLoadLoc(unsigned ilLclNum, IL_OFFSET offset);
3848     bool impReturnInstruction(BasicBlock* block, int prefixFlags, OPCODE& opcode);
3849
3850 #ifdef _TARGET_ARM_
3851     void impMarkLclDstNotPromotable(unsigned tmpNum, GenTree* op, CORINFO_CLASS_HANDLE hClass);
3852 #endif
3853
3854     // A free list of linked list nodes used to represent to-do stacks of basic blocks.
3855     struct BlockListNode
3856     {
3857         BasicBlock*    m_blk;
3858         BlockListNode* m_next;
3859         BlockListNode(BasicBlock* blk, BlockListNode* next = nullptr) : m_blk(blk), m_next(next)
3860         {
3861         }
3862         void* operator new(size_t sz, Compiler* comp);
3863     };
3864     BlockListNode* impBlockListNodeFreeList;
3865
3866     void FreeBlockListNode(BlockListNode* node);
3867
3868     bool impIsValueType(typeInfo* pTypeInfo);
3869     var_types mangleVarArgsType(var_types type);
3870
3871 #if FEATURE_VARARG
3872     regNumber getCallArgIntRegister(regNumber floatReg);
3873     regNumber getCallArgFloatRegister(regNumber intReg);
3874 #endif // FEATURE_VARARG
3875
3876 #if defined(DEBUG)
3877     static unsigned jitTotalMethodCompiled;
3878 #endif
3879
3880 #ifdef DEBUG
3881     static LONG jitNestingLevel;
3882 #endif // DEBUG
3883
3884     static BOOL impIsAddressInLocal(GenTree* tree, GenTree** lclVarTreeOut);
3885
3886     void impMakeDiscretionaryInlineObservations(InlineInfo* pInlineInfo, InlineResult* inlineResult);
3887
3888     // STATIC inlining decision based on the IL code.
3889     void impCanInlineIL(CORINFO_METHOD_HANDLE fncHandle,
3890                         CORINFO_METHOD_INFO*  methInfo,
3891                         bool                  forceInline,
3892                         InlineResult*         inlineResult);
3893
3894     void impCheckCanInline(GenTreeCall*           call,
3895                            CORINFO_METHOD_HANDLE  fncHandle,
3896                            unsigned               methAttr,
3897                            CORINFO_CONTEXT_HANDLE exactContextHnd,
3898                            InlineCandidateInfo**  ppInlineCandidateInfo,
3899                            InlineResult*          inlineResult);
3900
3901     void impInlineRecordArgInfo(InlineInfo*   pInlineInfo,
3902                                 GenTree*      curArgVal,
3903                                 unsigned      argNum,
3904                                 InlineResult* inlineResult);
3905
3906     void impInlineInitVars(InlineInfo* pInlineInfo);
3907
3908     unsigned impInlineFetchLocal(unsigned lclNum DEBUGARG(const char* reason));
3909
3910     GenTree* impInlineFetchArg(unsigned lclNum, InlArgInfo* inlArgInfo, InlLclVarInfo* lclTypeInfo);
3911
3912     BOOL impInlineIsThis(GenTree* tree, InlArgInfo* inlArgInfo);
3913
3914     BOOL impInlineIsGuaranteedThisDerefBeforeAnySideEffects(GenTree*    additionalTreesToBeEvaluatedBefore,
3915                                                             GenTree*    variableBeingDereferenced,
3916                                                             InlArgInfo* inlArgInfo);
3917
3918     void impMarkInlineCandidate(GenTree*               call,
3919                                 CORINFO_CONTEXT_HANDLE exactContextHnd,
3920                                 bool                   exactContextNeedsRuntimeLookup,
3921                                 CORINFO_CALL_INFO*     callInfo);
3922
3923     void impMarkInlineCandidateHelper(GenTreeCall*           call,
3924                                       CORINFO_CONTEXT_HANDLE exactContextHnd,
3925                                       bool                   exactContextNeedsRuntimeLookup,
3926                                       CORINFO_CALL_INFO*     callInfo);
3927
3928     bool impTailCallRetTypeCompatible(var_types            callerRetType,
3929                                       CORINFO_CLASS_HANDLE callerRetTypeClass,
3930                                       var_types            calleeRetType,
3931                                       CORINFO_CLASS_HANDLE calleeRetTypeClass);
3932
3933     bool impIsTailCallILPattern(bool        tailPrefixed,
3934                                 OPCODE      curOpcode,
3935                                 const BYTE* codeAddrOfNextOpcode,
3936                                 const BYTE* codeEnd,
3937                                 bool        isRecursive,
3938                                 bool*       IsCallPopRet = nullptr);
3939
3940     bool impIsImplicitTailCallCandidate(
3941         OPCODE curOpcode, const BYTE* codeAddrOfNextOpcode, const BYTE* codeEnd, int prefixFlags, bool isRecursive);
3942
3943     CORINFO_RESOLVED_TOKEN* impAllocateToken(CORINFO_RESOLVED_TOKEN token);
3944
3945     /*
3946     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3947     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3948     XX                                                                           XX
3949     XX                           FlowGraph                                       XX
3950     XX                                                                           XX
3951     XX   Info about the basic-blocks, their contents and the flow analysis       XX
3952     XX                                                                           XX
3953     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3954     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3955     */
3956
3957 public:
3958     BasicBlock* fgFirstBB;        // Beginning of the basic block list
3959     BasicBlock* fgLastBB;         // End of the basic block list
3960     BasicBlock* fgFirstColdBlock; // First block to be placed in the cold section
3961 #if FEATURE_EH_FUNCLETS
3962     BasicBlock* fgFirstFuncletBB; // First block of outlined funclets (to allow block insertion before the funclets)
3963 #endif
3964     BasicBlock* fgFirstBBScratch;   // Block inserted for initialization stuff. Is nullptr if no such block has been
3965                                     // created.
3966     BasicBlockList* fgReturnBlocks; // list of BBJ_RETURN blocks
3967     unsigned        fgEdgeCount;    // # of control flow edges between the BBs
3968     unsigned        fgBBcount;      // # of BBs in the method
3969 #ifdef DEBUG
3970     unsigned fgBBcountAtCodegen; // # of BBs in the method at the start of codegen
3971 #endif
3972     unsigned     fgBBNumMax;       // The max bbNum that has been assigned to basic blocks
3973     unsigned     fgDomBBcount;     // # of BBs for which we have dominator and reachability information
3974     BasicBlock** fgBBInvPostOrder; // The flow graph stored in an array sorted in topological order, needed to compute
3975                                    // dominance. Indexed by block number. Size: fgBBNumMax + 1.
3976
3977     // After the dominance tree is computed, we cache a DFS preorder number and DFS postorder number to compute
3978     // dominance queries in O(1). fgDomTreePreOrder and fgDomTreePostOrder are arrays giving the block's preorder and
3979     // postorder number, respectively. The arrays are indexed by basic block number. (Note that blocks are numbered
3980     // starting from one. Thus, we always waste element zero. This makes debugging easier and makes the code less likely
3981     // to suffer from bugs stemming from forgetting to add or subtract one from the block number to form an array
3982     // index). The arrays are of size fgBBNumMax + 1.
3983     unsigned* fgDomTreePreOrder;
3984     unsigned* fgDomTreePostOrder;
3985
3986     bool fgBBVarSetsInited;
3987
3988     // Allocate array like T* a = new T[fgBBNumMax + 1];
3989     // Using helper so we don't keep forgetting +1.
3990     template <typename T>
3991     T* fgAllocateTypeForEachBlk(CompMemKind cmk = CMK_Unknown)
3992     {
3993         return getAllocator(cmk).allocate<T>(fgBBNumMax + 1);
3994     }
3995
3996     // BlockSets are relative to a specific set of BasicBlock numbers. If that changes
3997     // (if the blocks are renumbered), this changes. BlockSets from different epochs
3998     // cannot be meaningfully combined. Note that new blocks can be created with higher
3999     // block numbers without changing the basic block epoch. These blocks *cannot*
4000     // participate in a block set until the blocks are all renumbered, causing the epoch
4001     // to change. This is useful if continuing to use previous block sets is valuable.
4002     // If the epoch is zero, then it is uninitialized, and block sets can't be used.
4003     unsigned fgCurBBEpoch;
4004
4005     unsigned GetCurBasicBlockEpoch()
4006     {
4007         return fgCurBBEpoch;
4008     }
4009
4010     // The number of basic blocks in the current epoch. When the blocks are renumbered,
4011     // this is fgBBcount. As blocks are added, fgBBcount increases, fgCurBBEpochSize remains
4012     // the same, until a new BasicBlock epoch is created, such as when the blocks are all renumbered.
4013     unsigned fgCurBBEpochSize;
4014
4015     // The number of "size_t" elements required to hold a bitset large enough for fgCurBBEpochSize
4016     // bits. This is precomputed to avoid doing math every time BasicBlockBitSetTraits::GetArrSize() is called.
4017     unsigned fgBBSetCountInSizeTUnits;
4018
4019     void NewBasicBlockEpoch()
4020     {
4021         INDEBUG(unsigned oldEpochArrSize = fgBBSetCountInSizeTUnits);
4022
4023         // We have a new epoch. Compute and cache the size needed for new BlockSets.
4024         fgCurBBEpoch++;
4025         fgCurBBEpochSize = fgBBNumMax + 1;
4026         fgBBSetCountInSizeTUnits =
4027             roundUp(fgCurBBEpochSize, (unsigned)(sizeof(size_t) * 8)) / unsigned(sizeof(size_t) * 8);
4028
4029 #ifdef DEBUG
4030         // All BlockSet objects are now invalid!
4031         fgReachabilitySetsValid = false; // the bbReach sets are now invalid!
4032         fgEnterBlksSetValid     = false; // the fgEnterBlks set is now invalid!
4033
4034         if (verbose)
4035         {
4036             unsigned epochArrSize = BasicBlockBitSetTraits::GetArrSize(this, sizeof(size_t));
4037             printf("\nNew BlockSet epoch %d, # of blocks (including unused BB00): %u, bitset array size: %u (%s)",
4038                    fgCurBBEpoch, fgCurBBEpochSize, epochArrSize, (epochArrSize <= 1) ? "short" : "long");
4039             if ((fgCurBBEpoch != 1) && ((oldEpochArrSize <= 1) != (epochArrSize <= 1)))
4040             {
4041                 // If we're not just establishing the first epoch, and the epoch array size has changed such that we're
4042                 // going to change our bitset representation from short (just a size_t bitset) to long (a pointer to an
4043                 // array of size_t bitsets), then print that out.
4044                 printf("; NOTE: BlockSet size was previously %s!", (oldEpochArrSize <= 1) ? "short" : "long");
4045             }
4046             printf("\n");
4047         }
4048 #endif // DEBUG
4049     }
4050
4051     void EnsureBasicBlockEpoch()
4052     {
4053         if (fgCurBBEpochSize != fgBBNumMax + 1)
4054         {
4055             NewBasicBlockEpoch();
4056         }
4057     }
4058
4059     BasicBlock* fgNewBasicBlock(BBjumpKinds jumpKind);
4060     void fgEnsureFirstBBisScratch();
4061     bool fgFirstBBisScratch();
4062     bool fgBBisScratch(BasicBlock* block);
4063
4064     void fgExtendEHRegionBefore(BasicBlock* block);
4065     void fgExtendEHRegionAfter(BasicBlock* block);
4066
4067     BasicBlock* fgNewBBbefore(BBjumpKinds jumpKind, BasicBlock* block, bool extendRegion);
4068
4069     BasicBlock* fgNewBBafter(BBjumpKinds jumpKind, BasicBlock* block, bool extendRegion);
4070
4071     BasicBlock* fgNewBBinRegion(BBjumpKinds jumpKind,
4072                                 unsigned    tryIndex,
4073                                 unsigned    hndIndex,
4074                                 BasicBlock* nearBlk,
4075                                 bool        putInFilter = false,
4076                                 bool        runRarely   = false,
4077                                 bool        insertAtEnd = false);
4078
4079     BasicBlock* fgNewBBinRegion(BBjumpKinds jumpKind,
4080                                 BasicBlock* srcBlk,
4081                                 bool        runRarely   = false,
4082                                 bool        insertAtEnd = false);
4083
4084     BasicBlock* fgNewBBinRegion(BBjumpKinds jumpKind);
4085
4086     BasicBlock* fgNewBBinRegionWorker(BBjumpKinds jumpKind,
4087                                       BasicBlock* afterBlk,
4088                                       unsigned    xcptnIndex,
4089                                       bool        putInTryRegion);
4090
4091     void fgInsertBBbefore(BasicBlock* insertBeforeBlk, BasicBlock* newBlk);
4092     void fgInsertBBafter(BasicBlock* insertAfterBlk, BasicBlock* newBlk);
4093     void fgUnlinkBlock(BasicBlock* block);
4094
4095     unsigned fgMeasureIR();
4096
4097     bool fgModified;         // True if the flow graph has been modified recently
4098     bool fgComputePredsDone; // Have we computed the bbPreds list
4099     bool fgCheapPredsValid;  // Is the bbCheapPreds list valid?
4100     bool fgDomsComputed;     // Have we computed the dominator sets?
4101     bool fgOptimizedFinally; // Did we optimize any try-finallys?
4102
4103     bool fgHasSwitch; // any BBJ_SWITCH jumps?
4104
4105     BlockSet fgEnterBlks; // Set of blocks which have a special transfer of control; the "entry" blocks plus EH handler
4106                           // begin blocks.
4107
4108 #ifdef DEBUG
4109     bool fgReachabilitySetsValid; // Are the bbReach sets valid?
4110     bool fgEnterBlksSetValid;     // Is the fgEnterBlks set valid?
4111 #endif                            // DEBUG
4112
4113     bool fgRemoveRestOfBlock; // true if we know that we will throw
4114     bool fgStmtRemoved;       // true if we remove statements -> need new DFA
4115
4116     // There are two modes for ordering of the trees.
4117     //  - In FGOrderTree, the dominant ordering is the tree order, and the nodes contained in
4118     //    each tree and sub-tree are contiguous, and can be traversed (in gtNext/gtPrev order)
4119     //    by traversing the tree according to the order of the operands.
4120     //  - In FGOrderLinear, the dominant ordering is the linear order.
4121
4122     enum FlowGraphOrder
4123     {
4124         FGOrderTree,
4125         FGOrderLinear
4126     };
4127     FlowGraphOrder fgOrder;
4128
4129     // The following are boolean flags that keep track of the state of internal data structures
4130
4131     bool                 fgStmtListThreaded;       // true if the node list is now threaded
4132     bool                 fgCanRelocateEHRegions;   // true if we are allowed to relocate the EH regions
4133     bool                 fgEdgeWeightsComputed;    // true after we have called fgComputeEdgeWeights
4134     bool                 fgHaveValidEdgeWeights;   // true if we were successful in computing all of the edge weights
4135     bool                 fgSlopUsedInEdgeWeights;  // true if their was some slop used when computing the edge weights
4136     bool                 fgRangeUsedInEdgeWeights; // true if some of the edgeWeight are expressed in Min..Max form
4137     bool                 fgNeedsUpdateFlowGraph;   // true if we need to run fgUpdateFlowGraph
4138     BasicBlock::weight_t fgCalledCount;            // count of the number of times this method was called
4139                                                    // This is derived from the profile data
4140                                                    // or is BB_UNITY_WEIGHT when we don't have profile data
4141
4142 #if FEATURE_EH_FUNCLETS
4143     bool fgFuncletsCreated; // true if the funclet creation phase has been run
4144 #endif                      // FEATURE_EH_FUNCLETS
4145
4146     bool fgGlobalMorph; // indicates if we are during the global morphing phase
4147                         // since fgMorphTree can be called from several places
4148
4149     bool     impBoxTempInUse; // the temp below is valid and available
4150     unsigned impBoxTemp;      // a temporary that is used for boxing
4151
4152 #ifdef DEBUG
4153     bool jitFallbackCompile; // Are we doing a fallback compile? That is, have we executed a NO_WAY assert,
4154                              //   and we are trying to compile again in a "safer", minopts mode?
4155 #endif
4156
4157 #if defined(DEBUG)
4158     unsigned impInlinedCodeSize;
4159 #endif
4160
4161     //-------------------------------------------------------------------------
4162
4163     void fgInit();
4164
4165     void fgImport();
4166
4167     void fgTransformIndirectCalls();
4168
4169     void fgInline();
4170
4171     void fgRemoveEmptyTry();
4172
4173     void fgRemoveEmptyFinally();
4174
4175     void fgMergeFinallyChains();
4176
4177     void fgCloneFinally();
4178
4179     void fgCleanupContinuation(BasicBlock* continuation);
4180
4181     void fgUpdateFinallyTargetFlags();
4182
4183     void fgClearAllFinallyTargetBits();
4184
4185     void fgAddFinallyTargetFlags();
4186
4187 #if FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
4188     // Sometimes we need to defer updating the BBF_FINALLY_TARGET bit. fgNeedToAddFinallyTargetBits signals
4189     // when this is necessary.
4190     bool fgNeedToAddFinallyTargetBits;
4191 #endif // FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
4192
4193     bool fgRetargetBranchesToCanonicalCallFinally(BasicBlock*      block,
4194                                                   BasicBlock*      handler,
4195                                                   BlockToBlockMap& continuationMap);
4196
4197     GenTree* fgGetCritSectOfStaticMethod();
4198
4199 #if FEATURE_EH_FUNCLETS
4200
4201     void fgAddSyncMethodEnterExit();
4202
4203     GenTree* fgCreateMonitorTree(unsigned lvaMonitorBool, unsigned lvaThisVar, BasicBlock* block, bool enter);
4204
4205     void fgConvertSyncReturnToLeave(BasicBlock* block);
4206
4207 #endif // FEATURE_EH_FUNCLETS
4208
4209     void fgAddReversePInvokeEnterExit();
4210
4211     bool fgMoreThanOneReturnBlock();
4212
4213     // The number of separate return points in the method.
4214     unsigned fgReturnCount;
4215
4216     void fgAddInternal();
4217
4218     bool fgFoldConditional(BasicBlock* block);
4219
4220     void fgMorphStmts(BasicBlock* block, bool* lnot, bool* loadw);
4221     void fgMorphBlocks();
4222
4223     bool fgMorphBlockStmt(BasicBlock* block, GenTreeStmt* stmt DEBUGARG(const char* msg));
4224
4225     void fgSetOptions();
4226
4227 #ifdef DEBUG
4228     static fgWalkPreFn fgAssertNoQmark;
4229     void fgPreExpandQmarkChecks(GenTree* expr);
4230     void        fgPostExpandQmarkChecks();
4231     static void fgCheckQmarkAllowedForm(GenTree* tree);
4232 #endif
4233
4234     IL_OFFSET fgFindBlockILOffset(BasicBlock* block);
4235
4236     BasicBlock* fgSplitBlockAtBeginning(BasicBlock* curr);
4237     BasicBlock* fgSplitBlockAtEnd(BasicBlock* curr);
4238     BasicBlock* fgSplitBlockAfterStatement(BasicBlock* curr, GenTree* stmt);
4239     BasicBlock* fgSplitBlockAfterNode(BasicBlock* curr, GenTree* node); // for LIR
4240     BasicBlock* fgSplitEdge(BasicBlock* curr, BasicBlock* succ);
4241
4242     GenTreeStmt* fgNewStmtFromTree(GenTree* tree, BasicBlock* block, IL_OFFSETX offs);
4243     GenTreeStmt* fgNewStmtFromTree(GenTree* tree);
4244     GenTreeStmt* fgNewStmtFromTree(GenTree* tree, BasicBlock* block);
4245     GenTreeStmt* fgNewStmtFromTree(GenTree* tree, IL_OFFSETX offs);
4246
4247     GenTree* fgGetTopLevelQmark(GenTree* expr, GenTree** ppDst = nullptr);
4248     void fgExpandQmarkForCastInstOf(BasicBlock* block, GenTree* stmt);
4249     void fgExpandQmarkStmt(BasicBlock* block, GenTree* expr);
4250     void fgExpandQmarkNodes();
4251
4252     void fgMorph();
4253
4254     // Do "simple lowering."  This functionality is (conceptually) part of "general"
4255     // lowering that is distributed between fgMorph and the lowering phase of LSRA.
4256     void fgSimpleLowering();
4257
4258     GenTree* fgInitThisClass();
4259
4260     GenTreeCall* fgGetStaticsCCtorHelper(CORINFO_CLASS_HANDLE cls, CorInfoHelpFunc helper);
4261
4262     GenTreeCall* fgGetSharedCCtor(CORINFO_CLASS_HANDLE cls);
4263
4264     bool backendRequiresLocalVarLifetimes()
4265     {
4266         return !opts.MinOpts() || m_pLinearScan->willEnregisterLocalVars();
4267     }
4268
4269     void fgLocalVarLiveness();
4270
4271     void fgLocalVarLivenessInit();
4272
4273     void fgPerNodeLocalVarLiveness(GenTree* node);
4274     void fgPerBlockLocalVarLiveness();
4275
4276     VARSET_VALRET_TP fgGetHandlerLiveVars(BasicBlock* block);
4277
4278     void fgLiveVarAnalysis(bool updateInternalOnly = false);
4279
4280     void fgComputeLifeCall(VARSET_TP& life, GenTreeCall* call);
4281
4282     void fgComputeLifeTrackedLocalUse(VARSET_TP& life, LclVarDsc& varDsc, GenTreeLclVarCommon* node);
4283     bool fgComputeLifeTrackedLocalDef(VARSET_TP&           life,
4284                                       VARSET_VALARG_TP     keepAliveVars,
4285                                       LclVarDsc&           varDsc,
4286                                       GenTreeLclVarCommon* node);
4287     void fgComputeLifeUntrackedLocal(VARSET_TP&           life,
4288                                      VARSET_VALARG_TP     keepAliveVars,
4289                                      LclVarDsc&           varDsc,
4290                                      GenTreeLclVarCommon* lclVarNode);
4291     bool fgComputeLifeLocal(VARSET_TP& life, VARSET_VALARG_TP keepAliveVars, GenTree* lclVarNode);
4292
4293     void fgComputeLife(VARSET_TP&       life,
4294                        GenTree*         startNode,
4295                        GenTree*         endNode,
4296                        VARSET_VALARG_TP volatileVars,
4297                        bool* pStmtInfoDirty DEBUGARG(bool* treeModf));
4298
4299     void fgComputeLifeLIR(VARSET_TP& life, BasicBlock* block, VARSET_VALARG_TP volatileVars);
4300
4301     bool fgRemoveDeadStore(GenTree**        pTree,
4302                            LclVarDsc*       varDsc,
4303                            VARSET_VALARG_TP life,
4304                            bool*            doAgain,
4305                            bool* pStmtInfoDirty DEBUGARG(bool* treeModf));
4306
4307     // For updating liveset during traversal AFTER fgComputeLife has completed
4308     VARSET_VALRET_TP fgGetVarBits(GenTree* tree);
4309     VARSET_VALRET_TP fgUpdateLiveSet(VARSET_VALARG_TP liveSet, GenTree* tree);
4310
4311     // Returns the set of live variables after endTree,
4312     // assuming that liveSet is the set of live variables BEFORE tree.
4313     // Requires that fgComputeLife has completed, and that tree is in the same
4314     // statement as endTree, and that it comes before endTree in execution order
4315
4316     VARSET_VALRET_TP fgUpdateLiveSet(VARSET_VALARG_TP liveSet, GenTree* tree, GenTree* endTree)
4317     {
4318         VARSET_TP newLiveSet(VarSetOps::MakeCopy(this, liveSet));
4319         while (tree != nullptr && tree != endTree->gtNext)
4320         {
4321             VarSetOps::AssignNoCopy(this, newLiveSet, fgUpdateLiveSet(newLiveSet, tree));
4322             tree = tree->gtNext;
4323         }
4324         assert(tree == endTree->gtNext);
4325         return newLiveSet;
4326     }
4327
4328     void fgInterBlockLocalVarLiveness();
4329
4330     // The presence of a partial definition presents some difficulties for SSA: this is both a use of some SSA name
4331     // of "x", and a def of a new SSA name for "x".  The tree only has one local variable for "x", so it has to choose
4332     // whether to treat that as the use or def.  It chooses the "use", and thus the old SSA name.  This map allows us
4333     // to record/recover the "def" SSA number, given the lcl var node for "x" in such a tree.
4334     typedef JitHashTable<GenTree*, JitPtrKeyFuncs<GenTree>, unsigned> NodeToUnsignedMap;
4335     NodeToUnsignedMap* m_opAsgnVarDefSsaNums;
4336     NodeToUnsignedMap* GetOpAsgnVarDefSsaNums()
4337     {
4338         if (m_opAsgnVarDefSsaNums == nullptr)
4339         {
4340             m_opAsgnVarDefSsaNums = new (getAllocator()) NodeToUnsignedMap(getAllocator());
4341         }
4342         return m_opAsgnVarDefSsaNums;
4343     }
4344
4345     // Requires value numbering phase to have completed. Returns the value number ("gtVN") of the
4346     // "tree," EXCEPT in the case of GTF_VAR_USEASG, because the tree node's gtVN member is the
4347     // "use" VN. Performs a lookup into the map of (use asg tree -> def VN.) to return the "def's"
4348     // VN.
4349     inline ValueNum GetUseAsgDefVNOrTreeVN(GenTree* tree);
4350
4351     // Requires that "lcl" has the GTF_VAR_DEF flag set.  Returns the SSA number of "lcl".
4352     // Except: assumes that lcl is a def, and if it is
4353     // a partial def (GTF_VAR_USEASG), looks up and returns the SSA number for the "def",
4354     // rather than the "use" SSA number recorded in the tree "lcl".
4355     inline unsigned GetSsaNumForLocalVarDef(GenTree* lcl);
4356
4357     // Performs SSA conversion.
4358     void fgSsaBuild();
4359
4360     // Reset any data structures to the state expected by "fgSsaBuild", so it can be run again.
4361     void fgResetForSsa();
4362
4363     unsigned fgSsaPassesCompleted; // Number of times fgSsaBuild has been run.
4364
4365     // Returns "true" if a struct temp of the given type requires needs zero init in this block
4366     inline bool fgStructTempNeedsExplicitZeroInit(LclVarDsc* varDsc, BasicBlock* block);
4367
4368     // The value numbers for this compilation.
4369     ValueNumStore* vnStore;
4370
4371 public:
4372     ValueNumStore* GetValueNumStore()
4373     {
4374         return vnStore;
4375     }
4376
4377     // Do value numbering (assign a value number to each
4378     // tree node).
4379     void fgValueNumber();
4380
4381     // Computes new GcHeap VN via the assignment H[elemTypeEq][arrVN][inx][fldSeq] = rhsVN.
4382     // Assumes that "elemTypeEq" is the (equivalence class rep) of the array element type.
4383     // The 'indType' is the indirection type of the lhs of the assignment and will typically
4384     // match the element type of the array or fldSeq.  When this type doesn't match
4385     // or if the fldSeq is 'NotAField' we invalidate the array contents H[elemTypeEq][arrVN]
4386     //
4387     ValueNum fgValueNumberArrIndexAssign(CORINFO_CLASS_HANDLE elemTypeEq,
4388                                          ValueNum             arrVN,
4389                                          ValueNum             inxVN,
4390                                          FieldSeqNode*        fldSeq,
4391                                          ValueNum             rhsVN,
4392                                          var_types            indType);
4393
4394     // Requires that "tree" is a GT_IND marked as an array index, and that its address argument
4395     // has been parsed to yield the other input arguments.  If evaluation of the address
4396     // can raise exceptions, those should be captured in the exception set "excVN."
4397     // Assumes that "elemTypeEq" is the (equivalence class rep) of the array element type.
4398     // Marks "tree" with the VN for H[elemTypeEq][arrVN][inx][fldSeq] (for the liberal VN; a new unique
4399     // VN for the conservative VN.)  Also marks the tree's argument as the address of an array element.
4400     // The type tree->TypeGet() will typically match the element type of the array or fldSeq.
4401     // When this type doesn't match or if the fldSeq is 'NotAField' we return a new unique VN
4402     //
4403     ValueNum fgValueNumberArrIndexVal(GenTree*             tree,
4404                                       CORINFO_CLASS_HANDLE elemTypeEq,
4405                                       ValueNum             arrVN,
4406                                       ValueNum             inxVN,
4407                                       ValueNum             excVN,
4408                                       FieldSeqNode*        fldSeq);
4409
4410     // Requires "funcApp" to be a VNF_PtrToArrElem, and "addrXvn" to represent the exception set thrown
4411     // by evaluating the array index expression "tree".  Returns the value number resulting from
4412     // dereferencing the array in the current GcHeap state.  If "tree" is non-null, it must be the
4413     // "GT_IND" that does the dereference, and it is given the returned value number.
4414     ValueNum fgValueNumberArrIndexVal(GenTree* tree, struct VNFuncApp* funcApp, ValueNum addrXvn);
4415
4416     // Compute the value number for a byref-exposed load of the given type via the given pointerVN.
4417     ValueNum fgValueNumberByrefExposedLoad(var_types type, ValueNum pointerVN);
4418
4419     unsigned fgVNPassesCompleted; // Number of times fgValueNumber has been run.
4420
4421     // Utility functions for fgValueNumber.
4422
4423     // Perform value-numbering for the trees in "blk".
4424     void fgValueNumberBlock(BasicBlock* blk);
4425
4426     // Requires that "entryBlock" is the entry block of loop "loopNum", and that "loopNum" is the
4427     // innermost loop of which "entryBlock" is the entry.  Returns the value number that should be
4428     // assumed for the memoryKind at the start "entryBlk".
4429     ValueNum fgMemoryVNForLoopSideEffects(MemoryKind memoryKind, BasicBlock* entryBlock, unsigned loopNum);
4430
4431     // Called when an operation (performed by "tree", described by "msg") may cause the GcHeap to be mutated.
4432     // As GcHeap is a subset of ByrefExposed, this will also annotate the ByrefExposed mutation.
4433     void fgMutateGcHeap(GenTree* tree DEBUGARG(const char* msg));
4434
4435     // Called when an operation (performed by "tree", described by "msg") may cause an address-exposed local to be
4436     // mutated.
4437     void fgMutateAddressExposedLocal(GenTree* tree DEBUGARG(const char* msg));
4438
4439     // For a GC heap store at curTree, record the new curMemoryVN's and update curTree's MemorySsaMap.
4440     // As GcHeap is a subset of ByrefExposed, this will also record the ByrefExposed store.
4441     void recordGcHeapStore(GenTree* curTree, ValueNum gcHeapVN DEBUGARG(const char* msg));
4442
4443     // For a store to an address-exposed local at curTree, record the new curMemoryVN and update curTree's MemorySsaMap.
4444     void recordAddressExposedLocalStore(GenTree* curTree, ValueNum memoryVN DEBUGARG(const char* msg));
4445
4446     // Tree caused an update in the current memory VN.  If "tree" has an associated heap SSA #, record that
4447     // value in that SSA #.
4448     void fgValueNumberRecordMemorySsa(MemoryKind memoryKind, GenTree* tree);
4449
4450     // The input 'tree' is a leaf node that is a constant
4451     // Assign the proper value number to the tree
4452     void fgValueNumberTreeConst(GenTree* tree);
4453
4454     // Assumes that all inputs to "tree" have had value numbers assigned; assigns a VN to tree.
4455     // (With some exceptions: the VN of the lhs of an assignment is assigned as part of the
4456     // assignment.)
4457     void fgValueNumberTree(GenTree* tree);
4458
4459     // Does value-numbering for a block assignment.
4460     void fgValueNumberBlockAssignment(GenTree* tree);
4461
4462     // Does value-numbering for a cast tree.
4463     void fgValueNumberCastTree(GenTree* tree);
4464
4465     // Does value-numbering for an intrinsic tree.
4466     void fgValueNumberIntrinsic(GenTree* tree);
4467
4468     // Does value-numbering for a call.  We interpret some helper calls.
4469     void fgValueNumberCall(GenTreeCall* call);
4470
4471     // The VN of some nodes in "args" may have changed -- reassign VNs to the arg list nodes.
4472     void fgUpdateArgListVNs(GenTreeArgList* args);
4473
4474     // Does value-numbering for a helper "call" that has a VN function symbol "vnf".
4475     void fgValueNumberHelperCallFunc(GenTreeCall* call, VNFunc vnf, ValueNumPair vnpExc);
4476
4477     // Requires "helpCall" to be a helper call.  Assigns it a value number;
4478     // we understand the semantics of some of the calls.  Returns "true" if
4479     // the call may modify the heap (we assume arbitrary memory side effects if so).
4480     bool fgValueNumberHelperCall(GenTreeCall* helpCall);
4481
4482     // Requires that "helpFunc" is one of the pure Jit Helper methods.
4483     // Returns the corresponding VNFunc to use for value numbering
4484     VNFunc fgValueNumberJitHelperMethodVNFunc(CorInfoHelpFunc helpFunc);
4485
4486     // Adds the exception set for the current tree node which has a memory indirection operation
4487     void fgValueNumberAddExceptionSetForIndirection(GenTree* tree, GenTree* baseAddr);
4488
4489     // Adds the exception sets for the current tree node which is performing a division or modulus operation
4490     void fgValueNumberAddExceptionSetForDivision(GenTree* tree);
4491
4492     // Adds the exception set for the current tree node which is performing a overflow checking operation
4493     void fgValueNumberAddExceptionSetForOverflow(GenTree* tree);
4494
4495     // Adds the exception set for the current tree node which is performing a ckfinite operation
4496     void fgValueNumberAddExceptionSetForCkFinite(GenTree* tree);
4497
4498     // Adds the exception sets for the current tree node
4499     void fgValueNumberAddExceptionSet(GenTree* tree);
4500
4501     // These are the current value number for the memory implicit variables while
4502     // doing value numbering.  These are the value numbers under the "liberal" interpretation
4503     // of memory values; the "conservative" interpretation needs no VN, since every access of
4504     // memory yields an unknown value.
4505     ValueNum fgCurMemoryVN[MemoryKindCount];
4506
4507     // Return a "pseudo"-class handle for an array element type.  If "elemType" is TYP_STRUCT,
4508     // requires "elemStructType" to be non-null (and to have a low-order zero).  Otherwise, low order bit
4509     // is 1, and the rest is an encoding of "elemTyp".
4510     static CORINFO_CLASS_HANDLE EncodeElemType(var_types elemTyp, CORINFO_CLASS_HANDLE elemStructType)
4511     {
4512         if (elemStructType != nullptr)
4513         {
4514             assert(varTypeIsStruct(elemTyp) || elemTyp == TYP_REF || elemTyp == TYP_BYREF ||
4515                    varTypeIsIntegral(elemTyp));
4516             assert((size_t(elemStructType) & 0x1) == 0x0); // Make sure the encoding below is valid.
4517             return elemStructType;
4518         }
4519         else
4520         {
4521             assert(elemTyp != TYP_STRUCT);
4522             elemTyp = varTypeUnsignedToSigned(elemTyp);
4523             return CORINFO_CLASS_HANDLE(size_t(elemTyp) << 1 | 0x1);
4524         }
4525     }
4526     // If "clsHnd" is the result of an "EncodePrim" call, returns true and sets "*pPrimType" to the
4527     // var_types it represents.  Otherwise, returns TYP_STRUCT (on the assumption that "clsHnd" is
4528     // the struct type of the element).
4529     static var_types DecodeElemType(CORINFO_CLASS_HANDLE clsHnd)
4530     {
4531         size_t clsHndVal = size_t(clsHnd);
4532         if (clsHndVal & 0x1)
4533         {
4534             return var_types(clsHndVal >> 1);
4535         }
4536         else
4537         {
4538             return TYP_STRUCT;
4539         }
4540     }
4541
4542     // Convert a BYTE which represents the VM's CorInfoGCtype to the JIT's var_types
4543     var_types getJitGCType(BYTE gcType);
4544
4545     enum structPassingKind
4546     {
4547         SPK_Unknown,       // Invalid value, never returned
4548         SPK_PrimitiveType, // The struct is passed/returned using a primitive type.
4549         SPK_EnclosingType, // Like SPK_Primitive type, but used for return types that
4550                            //  require a primitive type temp that is larger than the struct size.
4551                            //  Currently used for structs of size 3, 5, 6, or 7 bytes.
4552         SPK_ByValue,       // The struct is passed/returned by value (using the ABI rules)
4553                            //  for ARM64 and UNIX_X64 in multiple registers. (when all of the
4554                            //   parameters registers are used, then the stack will be used)
4555                            //  for X86 passed on the stack, for ARM32 passed in registers
4556                            //   or the stack or split between registers and the stack.
4557         SPK_ByValueAsHfa,  // The struct is passed/returned as an HFA in multiple registers.
4558         SPK_ByReference
4559     }; // The struct is passed/returned by reference to a copy/buffer.
4560
4561     // Get the "primitive" type that is is used when we are given a struct of size 'structSize'.
4562     // For pointer sized structs the 'clsHnd' is used to determine if the struct contains GC ref.
4563     // A "primitive" type is one of the scalar types: byte, short, int, long, ref, float, double
4564     // If we can't or shouldn't use a "primitive" type then TYP_UNKNOWN is returned.
4565     //
4566     // isVarArg is passed for use on Windows Arm64 to change the decision returned regarding
4567     // hfa types.
4568     //
4569     var_types getPrimitiveTypeForStruct(unsigned structSize, CORINFO_CLASS_HANDLE clsHnd, bool isVarArg);
4570
4571     // Get the type that is used to pass values of the given struct type.
4572     // isVarArg is passed for use on Windows Arm64 to change the decision returned regarding
4573     // hfa types.
4574     //
4575     var_types getArgTypeForStruct(CORINFO_CLASS_HANDLE clsHnd,
4576                                   structPassingKind*   wbPassStruct,
4577                                   bool                 isVarArg,
4578                                   unsigned             structSize);
4579
4580     // Get the type that is used to return values of the given struct type.
4581     // If the size is unknown, pass 0 and it will be determined from 'clsHnd'.
4582     var_types getReturnTypeForStruct(CORINFO_CLASS_HANDLE clsHnd,
4583                                      structPassingKind*   wbPassStruct = nullptr,
4584                                      unsigned             structSize   = 0);
4585
4586 #ifdef DEBUG
4587     // Print a representation of "vnp" or "vn" on standard output.
4588     // If "level" is non-zero, we also print out a partial expansion of the value.
4589     void vnpPrint(ValueNumPair vnp, unsigned level);
4590     void vnPrint(ValueNum vn, unsigned level);
4591 #endif
4592
4593     bool fgDominate(BasicBlock* b1, BasicBlock* b2); // Return true if b1 dominates b2
4594
4595     // Dominator computation member functions
4596     // Not exposed outside Compiler
4597 protected:
4598     bool fgReachable(BasicBlock* b1, BasicBlock* b2); // Returns true if block b1 can reach block b2
4599
4600     void fgComputeDoms(); // Computes the immediate dominators for each basic block in the
4601                           // flow graph.  We first assume the fields bbIDom on each
4602                           // basic block are invalid. This computation is needed later
4603                           // by fgBuildDomTree to build the dominance tree structure.
4604                           // Based on: A Simple, Fast Dominance Algorithm
4605                           // by Keith D. Cooper, Timothy J. Harvey, and Ken Kennedy
4606
4607     void fgCompDominatedByExceptionalEntryBlocks();
4608
4609     BlockSet_ValRet_T fgGetDominatorSet(BasicBlock* block); // Returns a set of blocks that dominate the given block.
4610     // Note: this is relatively slow compared to calling fgDominate(),
4611     // especially if dealing with a single block versus block check.
4612
4613     void fgComputeReachabilitySets(); // Compute bbReach sets. (Also sets BBF_GC_SAFE_POINT flag on blocks.)
4614
4615     void fgComputeEnterBlocksSet(); // Compute the set of entry blocks, 'fgEnterBlks'.
4616
4617     bool fgRemoveUnreachableBlocks(); // Remove blocks determined to be unreachable by the bbReach sets.
4618
4619     void fgComputeReachability(); // Perform flow graph node reachability analysis.
4620
4621     BasicBlock* fgIntersectDom(BasicBlock* a, BasicBlock* b); // Intersect two immediate dominator sets.
4622
4623     void fgDfsInvPostOrder(); // In order to compute dominance using fgIntersectDom, the flow graph nodes must be
4624                               // processed in topological sort, this function takes care of that.
4625
4626     void fgDfsInvPostOrderHelper(BasicBlock* block, BlockSet& visited, unsigned* count);
4627
4628     BlockSet_ValRet_T fgDomFindStartNodes(); // Computes which basic blocks don't have incoming edges in the flow graph.
4629                                              // Returns this as a set.
4630
4631     BlockSet_ValRet_T fgDomTreeEntryNodes(BasicBlockList** domTree); // Computes which nodes in the dominance forest are
4632                                                                      // root nodes. Returns this as a set.
4633
4634 #ifdef DEBUG
4635     void fgDispDomTree(BasicBlockList** domTree); // Helper that prints out the Dominator Tree in debug builds.
4636 #endif                                            // DEBUG
4637
4638     void fgBuildDomTree(); // Once we compute all the immediate dominator sets for each node in the flow graph
4639                            // (performed by fgComputeDoms), this procedure builds the dominance tree represented
4640                            // adjacency lists.
4641
4642     // In order to speed up the queries of the form 'Does A dominates B', we can perform a DFS preorder and postorder
4643     // traversal of the dominance tree and the dominance query will become A dominates B iif preOrder(A) <= preOrder(B)
4644     // && postOrder(A) >= postOrder(B) making the computation O(1).
4645     void fgTraverseDomTree(unsigned bbNum, BasicBlockList** domTree, unsigned* preNum, unsigned* postNum);
4646
4647     // When the flow graph changes, we need to update the block numbers, predecessor lists, reachability sets, and
4648     // dominators.
4649     void fgUpdateChangedFlowGraph();
4650
4651 public:
4652     // Compute the predecessors of the blocks in the control flow graph.
4653     void fgComputePreds();
4654
4655     // Remove all predecessor information.
4656     void fgRemovePreds();
4657
4658     // Compute the cheap flow graph predecessors lists. This is used in some early phases
4659     // before the full predecessors lists are computed.
4660     void fgComputeCheapPreds();
4661
4662 private:
4663     void fgAddCheapPred(BasicBlock* block, BasicBlock* blockPred);
4664
4665     void fgRemoveCheapPred(BasicBlock* block, BasicBlock* blockPred);
4666
4667 public:
4668     enum GCPollType
4669     {
4670         GCPOLL_NONE,
4671         GCPOLL_CALL,
4672         GCPOLL_INLINE
4673     };
4674
4675     // Initialize the per-block variable sets (used for liveness analysis).
4676     void fgInitBlockVarSets();
4677
4678     // true if we've gone through and created GC Poll calls.
4679     bool fgGCPollsCreated;
4680     void fgMarkGCPollBlocks();
4681     void fgCreateGCPolls();
4682     bool fgCreateGCPoll(GCPollType pollType, BasicBlock* block);
4683
4684     // Requires that "block" is a block that returns from
4685     // a finally.  Returns the number of successors (jump targets of
4686     // of blocks in the covered "try" that did a "LEAVE".)
4687     unsigned fgNSuccsOfFinallyRet(BasicBlock* block);
4688
4689     // Requires that "block" is a block that returns (in the sense of BBJ_EHFINALLYRET) from
4690     // a finally.  Returns its "i"th successor (jump targets of
4691     // of blocks in the covered "try" that did a "LEAVE".)
4692     // Requires that "i" < fgNSuccsOfFinallyRet(block).
4693     BasicBlock* fgSuccOfFinallyRet(BasicBlock* block, unsigned i);
4694
4695 private:
4696     // Factor out common portions of the impls of the methods above.
4697     void fgSuccOfFinallyRetWork(BasicBlock* block, unsigned i, BasicBlock** bres, unsigned* nres);
4698
4699 public:
4700     // For many purposes, it is desirable to be able to enumerate the *distinct* targets of a switch statement,
4701     // skipping duplicate targets.  (E.g., in flow analyses that are only interested in the set of possible targets.)
4702     // SwitchUniqueSuccSet contains the non-duplicated switch targets.
4703     // (Code that modifies the jump table of a switch has an obligation to call Compiler::UpdateSwitchTableTarget,
4704     // which in turn will call the "UpdateTarget" method of this type if a SwitchUniqueSuccSet has already
4705     // been computed for the switch block.  If a switch block is deleted or is transformed into a non-switch,
4706     // we leave the entry associated with the block, but it will no longer be accessed.)
4707     struct SwitchUniqueSuccSet
4708     {
4709         unsigned     numDistinctSuccs; // Number of distinct targets of the switch.
4710         BasicBlock** nonDuplicates;    // Array of "numDistinctSuccs", containing all the distinct switch target
4711                                        // successors.
4712
4713         // The switch block "switchBlk" just had an entry with value "from" modified to the value "to".
4714         // Update "this" as necessary: if "from" is no longer an element of the jump table of "switchBlk",
4715         // remove it from "this", and ensure that "to" is a member.  Use "alloc" to do any required allocation.
4716         void UpdateTarget(CompAllocator alloc, BasicBlock* switchBlk, BasicBlock* from, BasicBlock* to);
4717     };
4718
4719     typedef JitHashTable<BasicBlock*, JitPtrKeyFuncs<BasicBlock>, SwitchUniqueSuccSet> BlockToSwitchDescMap;
4720
4721 private:
4722     // Maps BasicBlock*'s that end in switch statements to SwitchUniqueSuccSets that allow
4723     // iteration over only the distinct successors.
4724     BlockToSwitchDescMap* m_switchDescMap;
4725
4726 public:
4727     BlockToSwitchDescMap* GetSwitchDescMap(bool createIfNull = true)
4728     {
4729         if ((m_switchDescMap == nullptr) && createIfNull)
4730         {
4731             m_switchDescMap = new (getAllocator()) BlockToSwitchDescMap(getAllocator());
4732         }
4733         return m_switchDescMap;
4734     }
4735
4736     // Invalidate the map of unique switch block successors. For example, since the hash key of the map
4737     // depends on block numbers, we must invalidate the map when the blocks are renumbered, to ensure that
4738     // we don't accidentally look up and return the wrong switch data.
4739     void InvalidateUniqueSwitchSuccMap()
4740     {
4741         m_switchDescMap = nullptr;
4742     }
4743
4744     // Requires "switchBlock" to be a block that ends in a switch.  Returns
4745     // the corresponding SwitchUniqueSuccSet.
4746     SwitchUniqueSuccSet GetDescriptorForSwitch(BasicBlock* switchBlk);
4747
4748     // The switch block "switchBlk" just had an entry with value "from" modified to the value "to".
4749     // Update "this" as necessary: if "from" is no longer an element of the jump table of "switchBlk",
4750     // remove it from "this", and ensure that "to" is a member.
4751     void UpdateSwitchTableTarget(BasicBlock* switchBlk, BasicBlock* from, BasicBlock* to);
4752
4753     // Remove the "SwitchUniqueSuccSet" of "switchBlk" in the BlockToSwitchDescMap.
4754     void fgInvalidateSwitchDescMapEntry(BasicBlock* switchBlk);
4755
4756     BasicBlock* fgFirstBlockOfHandler(BasicBlock* block);
4757
4758     flowList* fgGetPredForBlock(BasicBlock* block, BasicBlock* blockPred);
4759
4760     flowList* fgGetPredForBlock(BasicBlock* block, BasicBlock* blockPred, flowList*** ptrToPred);
4761
4762     flowList* fgSpliceOutPred(BasicBlock* block, BasicBlock* blockPred);
4763
4764     flowList* fgRemoveRefPred(BasicBlock* block, BasicBlock* blockPred);
4765
4766     flowList* fgRemoveAllRefPreds(BasicBlock* block, BasicBlock* blockPred);
4767
4768     flowList* fgRemoveAllRefPreds(BasicBlock* block, flowList** ptrToPred);
4769
4770     void fgRemoveBlockAsPred(BasicBlock* block);
4771
4772     void fgChangeSwitchBlock(BasicBlock* oldSwitchBlock, BasicBlock* newSwitchBlock);
4773
4774     void fgReplaceSwitchJumpTarget(BasicBlock* blockSwitch, BasicBlock* newTarget, BasicBlock* oldTarget);
4775
4776     void fgReplaceJumpTarget(BasicBlock* block, BasicBlock* newTarget, BasicBlock* oldTarget);
4777
4778     void fgReplacePred(BasicBlock* block, BasicBlock* oldPred, BasicBlock* newPred);
4779
4780     flowList* fgAddRefPred(BasicBlock* block,
4781                            BasicBlock* blockPred,
4782                            flowList*   oldEdge           = nullptr,
4783                            bool        initializingPreds = false); // Only set to 'true' when we are computing preds in
4784                                                                    // fgComputePreds()
4785
4786     void fgFindBasicBlocks();
4787
4788     bool fgIsBetterFallThrough(BasicBlock* bCur, BasicBlock* bAlt);
4789
4790     bool fgCheckEHCanInsertAfterBlock(BasicBlock* blk, unsigned regionIndex, bool putInTryRegion);
4791
4792     BasicBlock* fgFindInsertPoint(unsigned    regionIndex,
4793                                   bool        putInTryRegion,
4794                                   BasicBlock* startBlk,
4795                                   BasicBlock* endBlk,
4796                                   BasicBlock* nearBlk,
4797                                   BasicBlock* jumpBlk,
4798                                   bool        runRarely);
4799
4800     unsigned fgGetNestingLevel(BasicBlock* block, unsigned* pFinallyNesting = nullptr);
4801
4802     void fgRemoveEmptyBlocks();
4803
4804     void fgRemoveStmt(BasicBlock* block, GenTree* stmt);
4805
4806     bool fgCheckRemoveStmt(BasicBlock* block, GenTree* stmt);
4807
4808     void fgCreateLoopPreHeader(unsigned lnum);
4809
4810     void fgUnreachableBlock(BasicBlock* block);
4811
4812     void fgRemoveConditionalJump(BasicBlock* block);
4813
4814     BasicBlock* fgLastBBInMainFunction();
4815
4816     BasicBlock* fgEndBBAfterMainFunction();
4817
4818     void fgUnlinkRange(BasicBlock* bBeg, BasicBlock* bEnd);
4819
4820     void fgRemoveBlock(BasicBlock* block, bool unreachable);
4821
4822     bool fgCanCompactBlocks(BasicBlock* block, BasicBlock* bNext);
4823
4824     void fgCompactBlocks(BasicBlock* block, BasicBlock* bNext);
4825
4826     void fgUpdateLoopsAfterCompacting(BasicBlock* block, BasicBlock* bNext);
4827
4828     BasicBlock* fgConnectFallThrough(BasicBlock* bSrc, BasicBlock* bDst);
4829
4830     bool fgRenumberBlocks();
4831
4832     bool fgExpandRarelyRunBlocks();
4833
4834     bool fgEhAllowsMoveBlock(BasicBlock* bBefore, BasicBlock* bAfter);
4835
4836     void fgMoveBlocksAfter(BasicBlock* bStart, BasicBlock* bEnd, BasicBlock* insertAfterBlk);
4837
4838     enum FG_RELOCATE_TYPE
4839     {
4840         FG_RELOCATE_TRY,    // relocate the 'try' region
4841         FG_RELOCATE_HANDLER // relocate the handler region (including the filter if necessary)
4842     };
4843     BasicBlock* fgRelocateEHRange(unsigned regionIndex, FG_RELOCATE_TYPE relocateType);
4844
4845 #if FEATURE_EH_FUNCLETS
4846 #if defined(_TARGET_ARM_)
4847     void fgClearFinallyTargetBit(BasicBlock* block);
4848 #endif // defined(_TARGET_ARM_)
4849     bool fgIsIntraHandlerPred(BasicBlock* predBlock, BasicBlock* block);
4850     bool fgAnyIntraHandlerPreds(BasicBlock* block);
4851     void fgInsertFuncletPrologBlock(BasicBlock* block);
4852     void fgCreateFuncletPrologBlocks();
4853     void fgCreateFunclets();
4854 #else  // !FEATURE_EH_FUNCLETS
4855     bool fgRelocateEHRegions();
4856 #endif // !FEATURE_EH_FUNCLETS
4857
4858     bool fgOptimizeUncondBranchToSimpleCond(BasicBlock* block, BasicBlock* target);
4859
4860     bool fgBlockEndFavorsTailDuplication(BasicBlock* block);
4861
4862     bool fgBlockIsGoodTailDuplicationCandidate(BasicBlock* block);
4863
4864     bool fgOptimizeEmptyBlock(BasicBlock* block);
4865
4866     bool fgOptimizeBranchToEmptyUnconditional(BasicBlock* block, BasicBlock* bDest);
4867
4868     bool fgOptimizeBranch(BasicBlock* bJump);
4869
4870     bool fgOptimizeSwitchBranches(BasicBlock* block);
4871
4872     bool fgOptimizeBranchToNext(BasicBlock* block, BasicBlock* bNext, BasicBlock* bPrev);
4873
4874     bool fgOptimizeSwitchJumps();
4875 #ifdef DEBUG
4876     void fgPrintEdgeWeights();
4877 #endif
4878     void                 fgComputeBlockAndEdgeWeights();
4879     BasicBlock::weight_t fgComputeMissingBlockWeights();
4880     void fgComputeCalledCount(BasicBlock::weight_t returnWeight);
4881     void fgComputeEdgeWeights();
4882
4883     void fgReorderBlocks();
4884
4885     void fgDetermineFirstColdBlock();
4886
4887     bool fgIsForwardBranch(BasicBlock* bJump, BasicBlock* bSrc = nullptr);
4888
4889     bool fgUpdateFlowGraph(bool doTailDup = false);
4890
4891     void fgFindOperOrder();
4892
4893     // method that returns if you should split here
4894     typedef bool(fgSplitPredicate)(GenTree* tree, GenTree* parent, fgWalkData* data);
4895
4896     void fgSetBlockOrder();
4897
4898     void fgRemoveReturnBlock(BasicBlock* block);
4899
4900     /* Helper code that has been factored out */
4901     inline void fgConvertBBToThrowBB(BasicBlock* block);
4902
4903     bool fgCastNeeded(GenTree* tree, var_types toType);
4904     GenTree* fgDoNormalizeOnStore(GenTree* tree);
4905     GenTree* fgMakeTmpArgNode(fgArgTabEntry* curArgTabEntry);
4906
4907     // The following check for loops that don't execute calls
4908     bool fgLoopCallMarked;
4909
4910     void fgLoopCallTest(BasicBlock* srcBB, BasicBlock* dstBB);
4911     void fgLoopCallMark();
4912
4913     void fgMarkLoopHead(BasicBlock* block);
4914
4915     unsigned fgGetCodeEstimate(BasicBlock* block);
4916
4917 #if DUMP_FLOWGRAPHS
4918     const char* fgProcessEscapes(const char* nameIn, escapeMapping_t* map);
4919     FILE* fgOpenFlowGraphFile(bool* wbDontClose, Phases phase, LPCWSTR type);
4920     bool fgDumpFlowGraph(Phases phase);
4921
4922 #endif // DUMP_FLOWGRAPHS
4923
4924 #ifdef DEBUG
4925     void fgDispDoms();
4926     void fgDispReach();
4927     void fgDispBBLiveness(BasicBlock* block);
4928     void fgDispBBLiveness();
4929     void fgTableDispBasicBlock(BasicBlock* block, int ibcColWidth = 0);
4930     void fgDispBasicBlocks(BasicBlock* firstBlock, BasicBlock* lastBlock, bool dumpTrees);
4931     void fgDispBasicBlocks(bool dumpTrees = false);
4932     void fgDumpStmtTree(GenTree* stmt, unsigned bbNum);
4933     void fgDumpBlock(BasicBlock* block);
4934     void fgDumpTrees(BasicBlock* firstBlock, BasicBlock* lastBlock);
4935
4936     static fgWalkPreFn fgStress64RsltMulCB;
4937     void               fgStress64RsltMul();
4938     void               fgDebugCheckUpdate();
4939     void fgDebugCheckBBlist(bool checkBBNum = false, bool checkBBRefs = true);
4940     void fgDebugCheckBlockLinks();
4941     void fgDebugCheckLinks(bool morphTrees = false);
4942     void fgDebugCheckStmtsList(BasicBlock* block, bool morphTrees);
4943     void fgDebugCheckNodeLinks(BasicBlock* block, GenTree* stmt);
4944     void fgDebugCheckNodesUniqueness();
4945
4946     void fgDebugCheckFlags(GenTree* tree);
4947     void fgDebugCheckFlagsHelper(GenTree* tree, unsigned treeFlags, unsigned chkFlags);
4948     void fgDebugCheckTryFinallyExits();
4949 #endif
4950
4951     static GenTree* fgGetFirstNode(GenTree* tree);
4952
4953     //--------------------- Walking the trees in the IR -----------------------
4954
4955     struct fgWalkData
4956     {
4957         Compiler*     compiler;
4958         fgWalkPreFn*  wtprVisitorFn;
4959         fgWalkPostFn* wtpoVisitorFn;
4960         void*         pCallbackData; // user-provided data
4961         bool          wtprLclsOnly;  // whether to only visit lclvar nodes
4962         GenTree*      parent;        // parent of current node, provided to callback
4963         GenTreeStack* parentStack;   // stack of parent nodes, if asked for
4964 #ifdef DEBUG
4965         bool printModified; // callback can use this
4966 #endif
4967     };
4968
4969     fgWalkResult fgWalkTreePre(GenTree**    pTree,
4970                                fgWalkPreFn* visitor,
4971                                void*        pCallBackData = nullptr,
4972                                bool         lclVarsOnly   = false,
4973                                bool         computeStack  = false);
4974
4975     fgWalkResult fgWalkTree(GenTree**     pTree,
4976                             fgWalkPreFn*  preVisitor,
4977                             fgWalkPostFn* postVisitor,
4978                             void*         pCallBackData = nullptr);
4979
4980     void fgWalkAllTreesPre(fgWalkPreFn* visitor, void* pCallBackData);
4981
4982     //----- Postorder
4983
4984     fgWalkResult fgWalkTreePost(GenTree**     pTree,
4985                                 fgWalkPostFn* visitor,
4986                                 void*         pCallBackData = nullptr,
4987                                 bool          computeStack  = false);
4988
4989     // An fgWalkPreFn that looks for expressions that have inline throws in
4990     // minopts mode. Basically it looks for tress with gtOverflowEx() or
4991     // GTF_IND_RNGCHK.  It returns WALK_ABORT if one is found.  It
4992     // returns WALK_SKIP_SUBTREES if GTF_EXCEPT is not set (assumes flags
4993     // properly propagated to parent trees).  It returns WALK_CONTINUE
4994     // otherwise.
4995     static fgWalkResult fgChkThrowCB(GenTree** pTree, Compiler::fgWalkData* data);
4996     static fgWalkResult fgChkLocAllocCB(GenTree** pTree, Compiler::fgWalkData* data);
4997     static fgWalkResult fgChkQmarkCB(GenTree** pTree, Compiler::fgWalkData* data);
4998
4999     /**************************************************************************
5000      *                          PROTECTED
5001      *************************************************************************/
5002
5003 protected:
5004     friend class SsaBuilder;
5005     friend struct ValueNumberState;
5006
5007     //--------------------- Detect the basic blocks ---------------------------
5008
5009     BasicBlock** fgBBs; // Table of pointers to the BBs
5010
5011     void        fgInitBBLookup();
5012     BasicBlock* fgLookupBB(unsigned addr);
5013
5014     void fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, FixedBitVect* jumpTarget);
5015
5016     void fgMarkBackwardJump(BasicBlock* startBlock, BasicBlock* endBlock);
5017
5018     void fgLinkBasicBlocks();
5019
5020     unsigned fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, FixedBitVect* jumpTarget);
5021
5022     void fgCheckBasicBlockControlFlow();
5023
5024     void fgControlFlowPermitted(BasicBlock* blkSrc,
5025                                 BasicBlock* blkDest,
5026                                 BOOL        IsLeave = false /* is the src a leave block */);
5027
5028     bool fgFlowToFirstBlockOfInnerTry(BasicBlock* blkSrc, BasicBlock* blkDest, bool sibling);
5029
5030     void fgObserveInlineConstants(OPCODE opcode, const FgStack& stack, bool isInlining);
5031
5032     void fgAdjustForAddressExposedOrWrittenThis();
5033
5034     bool                        fgProfileData_ILSizeMismatch;
5035     ICorJitInfo::ProfileBuffer* fgProfileBuffer;
5036     ULONG                       fgProfileBufferCount;
5037     ULONG                       fgNumProfileRuns;
5038
5039     unsigned fgStressBBProf()
5040     {
5041 #ifdef DEBUG
5042         unsigned result = JitConfig.JitStressBBProf();
5043         if (result == 0)
5044         {
5045             if (compStressCompile(STRESS_BB_PROFILE, 15))
5046             {
5047                 result = 1;
5048             }
5049         }
5050         return result;
5051 #else
5052         return 0;
5053 #endif
5054     }
5055
5056     bool fgHaveProfileData();
5057     bool fgGetProfileWeightForBasicBlock(IL_OFFSET offset, unsigned* weight);
5058     void fgInstrumentMethod();
5059
5060 public:
5061     // fgIsUsingProfileWeights - returns true if we have real profile data for this method
5062     //                           or if we have some fake profile data for the stress mode
5063     bool fgIsUsingProfileWeights()
5064     {
5065         return (fgHaveProfileData() || fgStressBBProf());
5066     }
5067
5068     // fgProfileRunsCount - returns total number of scenario runs for the profile data
5069     //                      or BB_UNITY_WEIGHT when we aren't using profile data.
5070     unsigned fgProfileRunsCount()
5071     {
5072         return fgIsUsingProfileWeights() ? fgNumProfileRuns : BB_UNITY_WEIGHT;
5073     }
5074
5075 //-------- Insert a statement at the start or end of a basic block --------
5076
5077 #ifdef DEBUG
5078 public:
5079     static bool fgBlockContainsStatementBounded(BasicBlock* block, GenTree* stmt, bool answerOnBoundExceeded = true);
5080 #endif
5081
5082 public:
5083     GenTreeStmt* fgInsertStmtAtEnd(BasicBlock* block, GenTree* node);
5084
5085 public: // Used by linear scan register allocation
5086     GenTreeStmt* fgInsertStmtNearEnd(BasicBlock* block, GenTree* node);
5087
5088 private:
5089     GenTree* fgInsertStmtAtBeg(BasicBlock* block, GenTree* stmt);
5090     GenTree* fgInsertStmtAfter(BasicBlock* block, GenTree* insertionPoint, GenTree* stmt);
5091
5092 public: // Used by linear scan register allocation
5093     GenTree* fgInsertStmtBefore(BasicBlock* block, GenTree* insertionPoint, GenTree* stmt);
5094
5095 private:
5096     GenTree* fgInsertStmtListAfter(BasicBlock* block, GenTree* stmtAfter, GenTree* stmtList);
5097
5098     //                  Create a new temporary variable to hold the result of *ppTree,
5099     //                  and transform the graph accordingly.
5100     GenTree* fgInsertCommaFormTemp(GenTree** ppTree, CORINFO_CLASS_HANDLE structType = nullptr);
5101     GenTree* fgMakeMultiUse(GenTree** ppTree);
5102
5103 private:
5104     //                  Recognize a bitwise rotation pattern and convert into a GT_ROL or a GT_ROR node.
5105     GenTree* fgRecognizeAndMorphBitwiseRotation(GenTree* tree);
5106     bool fgOperIsBitwiseRotationRoot(genTreeOps oper);
5107
5108     //-------- Determine the order in which the trees will be evaluated -------
5109
5110     unsigned fgTreeSeqNum;
5111     GenTree* fgTreeSeqLst;
5112     GenTree* fgTreeSeqBeg;
5113
5114     GenTree* fgSetTreeSeq(GenTree* tree, GenTree* prev = nullptr, bool isLIR = false);
5115     void fgSetTreeSeqHelper(GenTree* tree, bool isLIR);
5116     void fgSetTreeSeqFinish(GenTree* tree, bool isLIR);
5117     void fgSetStmtSeq(GenTree* tree);
5118     void fgSetBlockOrder(BasicBlock* block);
5119
5120     //------------------------- Morphing --------------------------------------
5121
5122     unsigned fgPtrArgCntMax;
5123
5124 public:
5125     //------------------------------------------------------------------------
5126     // fgGetPtrArgCntMax: Return the maximum number of pointer-sized stack arguments that calls inside this method
5127     // can push on the stack. This value is calculated during morph.
5128     //
5129     // Return Value:
5130     //    Returns fgPtrArgCntMax, that is a private field.
5131     //
5132     unsigned fgGetPtrArgCntMax() const
5133     {
5134         return fgPtrArgCntMax;
5135     }
5136
5137     //------------------------------------------------------------------------
5138     // fgSetPtrArgCntMax: Set the maximum number of pointer-sized stack arguments that calls inside this method
5139     // can push on the stack. This function is used during StackLevelSetter to fix incorrect morph calculations.
5140     //
5141     void fgSetPtrArgCntMax(unsigned argCntMax)
5142     {
5143         fgPtrArgCntMax = argCntMax;
5144     }
5145
5146     bool compCanEncodePtrArgCntMax();
5147
5148 private:
5149     hashBv* fgOutgoingArgTemps;
5150     hashBv* fgCurrentlyInUseArgTemps;
5151
5152     void fgSetRngChkTarget(GenTree* tree, bool delay = true);
5153
5154     BasicBlock* fgSetRngChkTargetInner(SpecialCodeKind kind, bool delay);
5155
5156 #if REARRANGE_ADDS
5157     void fgMoveOpsLeft(GenTree* tree);
5158 #endif
5159
5160     bool fgIsCommaThrow(GenTree* tree, bool forFolding = false);
5161
5162     bool fgIsThrow(GenTree* tree);
5163
5164     bool fgInDifferentRegions(BasicBlock* blk1, BasicBlock* blk2);
5165     bool fgIsBlockCold(BasicBlock* block);
5166
5167     GenTree* fgMorphCastIntoHelper(GenTree* tree, int helper, GenTree* oper);
5168
5169     GenTree* fgMorphIntoHelperCall(GenTree* tree, int helper, GenTreeArgList* args, bool morphArgs = true);
5170
5171     GenTree* fgMorphStackArgForVarArgs(unsigned lclNum, var_types varType, unsigned lclOffs);
5172
5173     // A "MorphAddrContext" carries information from the surrounding context.  If we are evaluating a byref address,
5174     // it is useful to know whether the address will be immediately dereferenced, or whether the address value will
5175     // be used, perhaps by passing it as an argument to a called method.  This affects how null checking is done:
5176     // for sufficiently small offsets, we can rely on OS page protection to implicitly null-check addresses that we
5177     // know will be dereferenced.  To know that reliance on implicit null checking is sound, we must further know that
5178     // all offsets between the top-level indirection and the bottom are constant, and that their sum is sufficiently
5179     // small; hence the other fields of MorphAddrContext.
5180     enum MorphAddrContextKind
5181     {
5182         MACK_Ind,
5183         MACK_Addr,
5184     };
5185     struct MorphAddrContext
5186     {
5187         MorphAddrContextKind m_kind;
5188         bool                 m_allConstantOffsets; // Valid only for "m_kind == MACK_Ind".  True iff all offsets between
5189                                                    // top-level indirection and here have been constants.
5190         size_t m_totalOffset; // Valid only for "m_kind == MACK_Ind", and if "m_allConstantOffsets" is true.
5191                               // In that case, is the sum of those constant offsets.
5192
5193         MorphAddrContext(MorphAddrContextKind kind) : m_kind(kind), m_allConstantOffsets(true), m_totalOffset(0)
5194         {
5195         }
5196     };
5197
5198     // A MACK_CopyBlock context is immutable, so we can just make one of these and share it.
5199     static MorphAddrContext s_CopyBlockMAC;
5200
5201 #ifdef FEATURE_SIMD
5202     GenTree* getSIMDStructFromField(GenTree*   tree,
5203                                     var_types* baseTypeOut,
5204                                     unsigned*  indexOut,
5205                                     unsigned*  simdSizeOut,
5206                                     bool       ignoreUsedInSIMDIntrinsic = false);
5207     GenTree* fgMorphFieldAssignToSIMDIntrinsicSet(GenTree* tree);
5208     GenTree* fgMorphFieldToSIMDIntrinsicGet(GenTree* tree);
5209     bool fgMorphCombineSIMDFieldAssignments(BasicBlock* block, GenTree* stmt);
5210     void impMarkContiguousSIMDFieldAssignments(GenTree* stmt);
5211
5212     // fgPreviousCandidateSIMDFieldAsgStmt is only used for tracking previous simd field assignment
5213     // in function: Complier::impMarkContiguousSIMDFieldAssignments.
5214     GenTree* fgPreviousCandidateSIMDFieldAsgStmt;
5215
5216 #endif // FEATURE_SIMD
5217     GenTree* fgMorphArrayIndex(GenTree* tree);
5218     GenTree* fgMorphCast(GenTree* tree);
5219     GenTree* fgUnwrapProxy(GenTree* objRef);
5220     GenTreeFieldList* fgMorphLclArgToFieldlist(GenTreeLclVarCommon* lcl);
5221     void fgInitArgInfo(GenTreeCall* call);
5222     GenTreeCall* fgMorphArgs(GenTreeCall* call);
5223     GenTreeArgList* fgMorphArgList(GenTreeArgList* args, MorphAddrContext* mac);
5224
5225     void fgMakeOutgoingStructArgCopy(GenTreeCall*         call,
5226                                      GenTree*             args,
5227                                      unsigned             argIndex,
5228                                      CORINFO_CLASS_HANDLE copyBlkClass);
5229
5230     void fgFixupStructReturn(GenTree* call);
5231     GenTree* fgMorphLocalVar(GenTree* tree, bool forceRemorph);
5232
5233 public:
5234     bool fgAddrCouldBeNull(GenTree* addr);
5235
5236 private:
5237     GenTree* fgMorphField(GenTree* tree, MorphAddrContext* mac);
5238     bool fgCanFastTailCall(GenTreeCall* call);
5239     bool fgCheckStmtAfterTailCall();
5240     void fgMorphTailCall(GenTreeCall* call, void* pfnCopyArgs);
5241     GenTree* fgGetStubAddrArg(GenTreeCall* call);
5242     void fgMorphRecursiveFastTailCallIntoLoop(BasicBlock* block, GenTreeCall* recursiveTailCall);
5243     GenTree* fgAssignRecursiveCallArgToCallerParam(GenTree*       arg,
5244                                                    fgArgTabEntry* argTabEntry,
5245                                                    BasicBlock*    block,
5246                                                    IL_OFFSETX     callILOffset,
5247                                                    GenTree*       tmpAssignmentInsertionPoint,
5248                                                    GenTree*       paramAssignmentInsertionPoint);
5249     static int fgEstimateCallStackSize(GenTreeCall* call);
5250     GenTree* fgMorphCall(GenTreeCall* call);
5251     void fgMorphCallInline(GenTreeCall* call, InlineResult* result);
5252     void fgMorphCallInlineHelper(GenTreeCall* call, InlineResult* result);
5253 #if DEBUG
5254     void fgNoteNonInlineCandidate(GenTreeStmt* stmt, GenTreeCall* call);
5255     static fgWalkPreFn fgFindNonInlineCandidate;
5256 #endif
5257     GenTree* fgOptimizeDelegateConstructor(GenTreeCall*            call,
5258                                            CORINFO_CONTEXT_HANDLE* ExactContextHnd,
5259                                            CORINFO_RESOLVED_TOKEN* ldftnToken);
5260     GenTree* fgMorphLeaf(GenTree* tree);
5261     void fgAssignSetVarDef(GenTree* tree);
5262     GenTree* fgMorphOneAsgBlockOp(GenTree* tree);
5263     GenTree* fgMorphInitBlock(GenTree* tree);
5264     GenTree* fgMorphBlkToInd(GenTreeBlk* tree, var_types type);
5265     GenTree* fgMorphGetStructAddr(GenTree** pTree, CORINFO_CLASS_HANDLE clsHnd, bool isRValue = false);
5266     GenTree* fgMorphBlkNode(GenTree* tree, bool isDest);
5267     GenTree* fgMorphBlockOperand(GenTree* tree, var_types asgType, unsigned blockWidth, bool isDest);
5268     void fgMorphUnsafeBlk(GenTreeObj* obj);
5269     GenTree* fgMorphCopyBlock(GenTree* tree);
5270     GenTree* fgMorphForRegisterFP(GenTree* tree);
5271     GenTree* fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac = nullptr);
5272     GenTree* fgMorphModToSubMulDiv(GenTreeOp* tree);
5273     GenTree* fgMorphSmpOpOptional(GenTreeOp* tree);
5274     GenTree* fgMorphRecognizeBoxNullable(GenTree* compare);
5275
5276     GenTree* fgMorphToEmulatedFP(GenTree* tree);
5277     GenTree* fgMorphConst(GenTree* tree);
5278
5279 public:
5280     GenTree* fgMorphTree(GenTree* tree, MorphAddrContext* mac = nullptr);
5281
5282 private:
5283 #if LOCAL_ASSERTION_PROP
5284     void fgKillDependentAssertionsSingle(unsigned lclNum DEBUGARG(GenTree* tree));
5285     void fgKillDependentAssertions(unsigned lclNum DEBUGARG(GenTree* tree));
5286 #endif
5287     void fgMorphTreeDone(GenTree* tree, GenTree* oldTree = nullptr DEBUGARG(int morphNum = 0));
5288
5289     GenTreeStmt* fgMorphStmt;
5290
5291     unsigned fgGetBigOffsetMorphingTemp(var_types type); // We cache one temp per type to be
5292                                                          // used when morphing big offset.
5293
5294     //----------------------- Liveness analysis -------------------------------
5295
5296     VARSET_TP fgCurUseSet; // vars used     by block (before an assignment)
5297     VARSET_TP fgCurDefSet; // vars assigned by block (before a use)
5298
5299     MemoryKindSet fgCurMemoryUse;   // True iff the current basic block uses memory.
5300     MemoryKindSet fgCurMemoryDef;   // True iff the current basic block modifies memory.
5301     MemoryKindSet fgCurMemoryHavoc; // True if  the current basic block is known to set memory to a "havoc" value.
5302
5303     bool byrefStatesMatchGcHeapStates; // True iff GcHeap and ByrefExposed memory have all the same def points.
5304
5305     void fgMarkUseDef(GenTreeLclVarCommon* tree);
5306
5307     void fgBeginScopeLife(VARSET_TP* inScope, VarScopeDsc* var);
5308     void fgEndScopeLife(VARSET_TP* inScope, VarScopeDsc* var);
5309
5310     void fgMarkInScope(BasicBlock* block, VARSET_VALARG_TP inScope);
5311     void fgUnmarkInScope(BasicBlock* block, VARSET_VALARG_TP unmarkScope);
5312
5313     void fgExtendDbgScopes();
5314     void fgExtendDbgLifetimes();
5315
5316 #ifdef DEBUG
5317     void fgDispDebugScopes();
5318 #endif // DEBUG
5319
5320     //-------------------------------------------------------------------------
5321     //
5322     //  The following keeps track of any code we've added for things like array
5323     //  range checking or explicit calls to enable GC, and so on.
5324     //
5325 public:
5326     struct AddCodeDsc
5327     {
5328         AddCodeDsc*     acdNext;
5329         BasicBlock*     acdDstBlk; // block  to  which we jump
5330         unsigned        acdData;
5331         SpecialCodeKind acdKind; // what kind of a special block is this?
5332 #if !FEATURE_FIXED_OUT_ARGS
5333         bool     acdStkLvlInit; // has acdStkLvl value been already set?
5334         unsigned acdStkLvl;
5335 #endif // !FEATURE_FIXED_OUT_ARGS
5336     };
5337
5338 private:
5339     static unsigned acdHelper(SpecialCodeKind codeKind);
5340
5341     AddCodeDsc* fgAddCodeList;
5342     bool        fgAddCodeModf;
5343     bool        fgRngChkThrowAdded;
5344     AddCodeDsc* fgExcptnTargetCache[SCK_COUNT];
5345
5346     BasicBlock* fgRngChkTarget(BasicBlock* block, SpecialCodeKind kind);
5347
5348     BasicBlock* fgAddCodeRef(BasicBlock* srcBlk, unsigned refData, SpecialCodeKind kind);
5349
5350 public:
5351     AddCodeDsc* fgFindExcptnTarget(SpecialCodeKind kind, unsigned refData);
5352
5353     bool fgUseThrowHelperBlocks();
5354
5355     AddCodeDsc* fgGetAdditionalCodeDescriptors()
5356     {
5357         return fgAddCodeList;
5358     }
5359
5360 private:
5361     bool fgIsCodeAdded();
5362
5363     bool fgIsThrowHlpBlk(BasicBlock* block);
5364
5365 #if !FEATURE_FIXED_OUT_ARGS
5366     unsigned fgThrowHlpBlkStkLevel(BasicBlock* block);
5367 #endif // !FEATURE_FIXED_OUT_ARGS
5368
5369     unsigned fgBigOffsetMorphingTemps[TYP_COUNT];
5370
5371     unsigned fgCheckInlineDepthAndRecursion(InlineInfo* inlineInfo);
5372     void fgInvokeInlineeCompiler(GenTreeCall* call, InlineResult* result);
5373     void fgInsertInlineeBlocks(InlineInfo* pInlineInfo);
5374     GenTree* fgInlinePrependStatements(InlineInfo* inlineInfo);
5375     void fgInlineAppendStatements(InlineInfo* inlineInfo, BasicBlock* block, GenTree* stmt);
5376
5377 #if FEATURE_MULTIREG_RET
5378     GenTree* fgGetStructAsStructPtr(GenTree* tree);
5379     GenTree* fgAssignStructInlineeToVar(GenTree* child, CORINFO_CLASS_HANDLE retClsHnd);
5380     void fgAttachStructInlineeToAsg(GenTree* tree, GenTree* child, CORINFO_CLASS_HANDLE retClsHnd);
5381 #endif // FEATURE_MULTIREG_RET
5382
5383     static fgWalkPreFn  fgUpdateInlineReturnExpressionPlaceHolder;
5384     static fgWalkPostFn fgLateDevirtualization;
5385
5386 #ifdef DEBUG
5387     static fgWalkPreFn fgDebugCheckInlineCandidates;
5388
5389     void               CheckNoTransformableIndirectCallsRemain();
5390     static fgWalkPreFn fgDebugCheckForTransformableIndirectCalls;
5391 #endif
5392
5393     void fgPromoteStructs();
5394     void fgMorphStructField(GenTree* tree, GenTree* parent);
5395     void fgMorphLocalField(GenTree* tree, GenTree* parent);
5396
5397     // Identify which parameters are implicit byrefs, and flag their LclVarDscs.
5398     void fgMarkImplicitByRefArgs();
5399
5400     // Change implicit byrefs' types from struct to pointer, and for any that were
5401     // promoted, create new promoted struct temps.
5402     void fgRetypeImplicitByRefArgs();
5403
5404     // Rewrite appearances of implicit byrefs (manifest the implied additional level of indirection).
5405     bool fgMorphImplicitByRefArgs(GenTree* tree);
5406     GenTree* fgMorphImplicitByRefArgs(GenTree* tree, bool isAddr);
5407
5408     // Clear up annotations for any struct promotion temps created for implicit byrefs.
5409     void fgMarkDemotedImplicitByRefArgs();
5410
5411     void fgMarkAddressExposedLocals();
5412
5413     static fgWalkPreFn  fgUpdateSideEffectsPre;
5414     static fgWalkPostFn fgUpdateSideEffectsPost;
5415
5416     // The given local variable, required to be a struct variable, is being assigned via
5417     // a "lclField", to make it masquerade as an integral type in the ABI.  Make sure that
5418     // the variable is not enregistered, and is therefore not promoted independently.
5419     void fgLclFldAssign(unsigned lclNum);
5420
5421     static fgWalkPreFn gtHasLocalsWithAddrOpCB;
5422
5423     enum TypeProducerKind
5424     {
5425         TPK_Unknown = 0, // May not be a RuntimeType
5426         TPK_Handle  = 1, // RuntimeType via handle
5427         TPK_GetType = 2, // RuntimeType via Object.get_Type()
5428         TPK_Null    = 3, // Tree value is null
5429         TPK_Other   = 4  // RuntimeType via other means
5430     };
5431
5432     TypeProducerKind gtGetTypeProducerKind(GenTree* tree);
5433     bool gtIsTypeHandleToRuntimeTypeHelper(GenTreeCall* call);
5434     bool gtIsTypeHandleToRuntimeTypeHandleHelper(GenTreeCall* call, CorInfoHelpFunc* pHelper = nullptr);
5435     bool gtIsActiveCSE_Candidate(GenTree* tree);
5436
5437 #ifdef DEBUG
5438     bool fgPrintInlinedMethods;
5439 #endif
5440
5441     bool fgIsBigOffset(size_t offset);
5442
5443     bool fgNeedReturnSpillTemp();
5444
5445     /*
5446     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
5447     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
5448     XX                                                                           XX
5449     XX                           Optimizer                                       XX
5450     XX                                                                           XX
5451     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
5452     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
5453     */
5454
5455 public:
5456     void optInit();
5457
5458     void optRemoveRangeCheck(GenTree* tree, GenTree* stmt);
5459     bool optIsRangeCheckRemovable(GenTree* tree);
5460
5461 protected:
5462     static fgWalkPreFn optValidRangeCheckIndex;
5463     static fgWalkPreFn optRemoveTreeVisitor; // Helper passed to Compiler::fgWalkAllTreesPre() to decrement the LclVar
5464                                              // usage counts
5465
5466     void optRemoveTree(GenTree* deadTree, GenTree* keepList);
5467
5468     /**************************************************************************
5469      *
5470      *************************************************************************/
5471
5472 protected:
5473     // Do hoisting for all loops.
5474     void optHoistLoopCode();
5475
5476     // To represent sets of VN's that have already been hoisted in outer loops.
5477     typedef JitHashTable<ValueNum, JitSmallPrimitiveKeyFuncs<ValueNum>, bool> VNToBoolMap;
5478     typedef VNToBoolMap VNSet;
5479
5480     struct LoopHoistContext
5481     {
5482     private:
5483         // The set of variables hoisted in the current loop (or nullptr if there are none).
5484         VNSet* m_pHoistedInCurLoop;
5485
5486     public:
5487         // Value numbers of expressions that have been hoisted in parent loops in the loop nest.
5488         VNSet m_hoistedInParentLoops;
5489         // Value numbers of expressions that have been hoisted in the current (or most recent) loop in the nest.
5490         // Previous decisions on loop-invariance of value numbers in the current loop.
5491         VNToBoolMap m_curLoopVnInvariantCache;
5492
5493         VNSet* GetHoistedInCurLoop(Compiler* comp)
5494         {
5495             if (m_pHoistedInCurLoop == nullptr)
5496             {
5497                 m_pHoistedInCurLoop = new (comp->getAllocatorLoopHoist()) VNSet(comp->getAllocatorLoopHoist());
5498             }
5499             return m_pHoistedInCurLoop;
5500         }
5501
5502         VNSet* ExtractHoistedInCurLoop()
5503         {
5504             VNSet* res          = m_pHoistedInCurLoop;
5505             m_pHoistedInCurLoop = nullptr;
5506             return res;
5507         }
5508
5509         LoopHoistContext(Compiler* comp)
5510             : m_pHoistedInCurLoop(nullptr)
5511             , m_hoistedInParentLoops(comp->getAllocatorLoopHoist())
5512             , m_curLoopVnInvariantCache(comp->getAllocatorLoopHoist())
5513         {
5514         }
5515     };
5516
5517     // Do hoisting for loop "lnum" (an index into the optLoopTable), and all loops nested within it.
5518     // Tracks the expressions that have been hoisted by containing loops by temporary recording their
5519     // value numbers in "m_hoistedInParentLoops".  This set is not modified by the call.
5520     void optHoistLoopNest(unsigned lnum, LoopHoistContext* hoistCtxt);
5521
5522     // Do hoisting for a particular loop ("lnum" is an index into the optLoopTable.)
5523     // Assumes that expressions have been hoisted in containing loops if their value numbers are in
5524     // "m_hoistedInParentLoops".
5525     //
5526     void optHoistThisLoop(unsigned lnum, LoopHoistContext* hoistCtxt);
5527
5528     // Hoist all expressions in "blk" that are invariant in loop "lnum" (an index into the optLoopTable)
5529     // outside of that loop.  Exempt expressions whose value number is in "m_hoistedInParentLoops"; add VN's of hoisted
5530     // expressions to "hoistInLoop".
5531     void optHoistLoopExprsForBlock(BasicBlock* blk, unsigned lnum, LoopHoistContext* hoistCtxt);
5532
5533     // Return true if the tree looks profitable to hoist out of loop 'lnum'.
5534     bool optIsProfitableToHoistableTree(GenTree* tree, unsigned lnum);
5535
5536     // Hoist all proper sub-expressions of "tree" (which occurs in "stmt", which occurs in "blk")
5537     // that are invariant in loop "lnum" (an index into the optLoopTable)
5538     // outside of that loop.  Exempt expressions whose value number is in "hoistedInParents"; add VN's of hoisted
5539     // expressions to "hoistInLoop".
5540     // Returns "true" iff "tree" is loop-invariant (wrt "lnum").
5541     // Assumes that the value of "*firstBlockAndBeforeSideEffect" indicates that we're in the first block, and before
5542     // any possible globally visible side effects.  Assume is called in evaluation order, and updates this.
5543     bool optHoistLoopExprsForTree(GenTree*          tree,
5544                                   unsigned          lnum,
5545                                   LoopHoistContext* hoistCtxt,
5546                                   bool*             firstBlockAndBeforeSideEffect,
5547                                   bool*             pHoistable,
5548                                   bool*             pCctorDependent);
5549
5550     // Performs the hoisting 'tree' into the PreHeader for loop 'lnum'
5551     void optHoistCandidate(GenTree* tree, unsigned lnum, LoopHoistContext* hoistCtxt);
5552
5553     // Returns true iff the ValueNum "vn" represents a value that is loop-invariant in "lnum".
5554     //   Constants and init values are always loop invariant.
5555     //   VNPhi's connect VN's to the SSA definition, so we can know if the SSA def occurs in the loop.
5556     bool optVNIsLoopInvariant(ValueNum vn, unsigned lnum, VNToBoolMap* recordedVNs);
5557
5558     // Returns "true" iff "tree" is valid at the head of loop "lnum", in the context of the hoist substitution
5559     // "subst".  If "tree" is a local SSA var, it is valid if its SSA definition occurs outside of the loop, or
5560     // if it is in the domain of "subst" (meaning that it's definition has been previously hoisted, with a "standin"
5561     // local.)  If tree is a constant, it is valid.  Otherwise, if it is an operator, it is valid iff its children are.
5562     bool optTreeIsValidAtLoopHead(GenTree* tree, unsigned lnum);
5563
5564     // If "blk" is the entry block of a natural loop, returns true and sets "*pLnum" to the index of the loop
5565     // in the loop table.
5566     bool optBlockIsLoopEntry(BasicBlock* blk, unsigned* pLnum);
5567
5568     // Records the set of "side effects" of all loops: fields (object instance and static)
5569     // written to, and SZ-array element type equivalence classes updated.
5570     void optComputeLoopSideEffects();
5571
5572 private:
5573     // Requires "lnum" to be the index of an outermost loop in the loop table.  Traverses the body of that loop,
5574     // including all nested loops, and records the set of "side effects" of the loop: fields (object instance and
5575     // static) written to, and SZ-array element type equivalence classes updated.
5576     void optComputeLoopNestSideEffects(unsigned lnum);
5577
5578     // Add the side effects of "blk" (which is required to be within a loop) to all loops of which it is a part.
5579     void optComputeLoopSideEffectsOfBlock(BasicBlock* blk);
5580
5581     // Hoist the expression "expr" out of loop "lnum".
5582     void optPerformHoistExpr(GenTree* expr, unsigned lnum);
5583
5584 public:
5585     void optOptimizeBools();
5586
5587 private:
5588     GenTree* optIsBoolCond(GenTree* condBranch, GenTree** compPtr, bool* boolPtr);
5589 #ifdef DEBUG
5590     void optOptimizeBoolsGcStress(BasicBlock* condBlock);
5591 #endif
5592 public:
5593     void optOptimizeLayout(); // Optimize the BasicBlock layout of the method
5594
5595     void optOptimizeLoops(); // for "while-do" loops duplicates simple loop conditions and transforms
5596                              // the loop into a "do-while" loop
5597                              // Also finds all natural loops and records them in the loop table
5598
5599     // Optionally clone loops in the loop table.
5600     void optCloneLoops();
5601
5602     // Clone loop "loopInd" in the loop table.
5603     void optCloneLoop(unsigned loopInd, LoopCloneContext* context);
5604
5605     // Ensure that loop "loopInd" has a unique head block.  (If the existing entry has
5606     // non-loop predecessors other than the head entry, create a new, empty block that goes (only) to the entry,
5607     // and redirects the preds of the entry to this new block.)  Sets the weight of the newly created block to
5608     // "ambientWeight".
5609     void optEnsureUniqueHead(unsigned loopInd, unsigned ambientWeight);
5610
5611     void optUnrollLoops(); // Unrolls loops (needs to have cost info)
5612
5613 protected:
5614     // This enumeration describes what is killed by a call.
5615
5616     enum callInterf
5617     {
5618         CALLINT_NONE,       // no interference                               (most helpers)
5619         CALLINT_REF_INDIRS, // kills GC ref indirections                     (SETFIELD OBJ)
5620         CALLINT_SCL_INDIRS, // kills non GC ref indirections                 (SETFIELD non-OBJ)
5621         CALLINT_ALL_INDIRS, // kills both GC ref and non GC ref indirections (SETFIELD STRUCT)
5622         CALLINT_ALL,        // kills everything                              (normal method call)
5623     };
5624
5625 public:
5626     // A "LoopDsc" describes a ("natural") loop.  We (currently) require the body of a loop to be a contiguous (in
5627     // bbNext order) sequence of basic blocks.  (At times, we may require the blocks in a loop to be "properly numbered"
5628     // in bbNext order; we use comparisons on the bbNum to decide order.)
5629     // The blocks that define the body are
5630     //   first <= top <= entry <= bottom   .
5631     // The "head" of the loop is a block outside the loop that has "entry" as a successor. We only support loops with a
5632     // single 'head' block. The meanings of these blocks are given in the definitions below. Also see the picture at
5633     // Compiler::optFindNaturalLoops().
5634     struct LoopDsc
5635     {
5636         BasicBlock* lpHead;  // HEAD of the loop (not part of the looping of the loop) -- has ENTRY as a successor.
5637         BasicBlock* lpFirst; // FIRST block (in bbNext order) reachable within this loop.  (May be part of a nested
5638                              // loop, but not the outer loop.)
5639         BasicBlock* lpTop;   // loop TOP (the back edge from lpBottom reaches here) (in most cases FIRST and TOP are the
5640                              // same)
5641         BasicBlock* lpEntry; // the ENTRY in the loop (in most cases TOP or BOTTOM)
5642         BasicBlock* lpBottom; // loop BOTTOM (from here we have a back edge to the TOP)
5643         BasicBlock* lpExit;   // if a single exit loop this is the EXIT (in most cases BOTTOM)
5644
5645         callInterf   lpAsgCall;     // "callInterf" for calls in the loop
5646         ALLVARSET_TP lpAsgVars;     // set of vars assigned within the loop (all vars, not just tracked)
5647         varRefKinds  lpAsgInds : 8; // set of inds modified within the loop
5648
5649         unsigned short lpFlags; // Mask of the LPFLG_* constants
5650
5651         unsigned char lpExitCnt; // number of exits from the loop
5652
5653         unsigned char lpParent;  // The index of the most-nested loop that completely contains this one,
5654                                  // or else BasicBlock::NOT_IN_LOOP if no such loop exists.
5655         unsigned char lpChild;   // The index of a nested loop, or else BasicBlock::NOT_IN_LOOP if no child exists.
5656                                  // (Actually, an "immediately" nested loop --
5657                                  // no other child of this loop is a parent of lpChild.)
5658         unsigned char lpSibling; // The index of another loop that is an immediate child of lpParent,
5659                                  // or else BasicBlock::NOT_IN_LOOP.  One can enumerate all the children of a loop
5660                                  // by following "lpChild" then "lpSibling" links.
5661
5662 #define LPFLG_DO_WHILE 0x0001 // it's a do-while loop (i.e ENTRY is at the TOP)
5663 #define LPFLG_ONE_EXIT 0x0002 // the loop has only one exit
5664
5665 #define LPFLG_ITER 0x0004      // for (i = icon or lclVar; test_condition(); i++)
5666 #define LPFLG_HOISTABLE 0x0008 // the loop is in a form that is suitable for hoisting expressions
5667 #define LPFLG_CONST 0x0010     // for (i=icon;i<icon;i++){ ... } - constant loop
5668
5669 #define LPFLG_VAR_INIT 0x0020   // iterator is initialized with a local var (var # found in lpVarInit)
5670 #define LPFLG_CONST_INIT 0x0040 // iterator is initialized with a constant (found in lpConstInit)
5671
5672 #define LPFLG_VAR_LIMIT 0x0100    // iterator is compared with a local var (var # found in lpVarLimit)
5673 #define LPFLG_CONST_LIMIT 0x0200  // iterator is compared with a constant (found in lpConstLimit)
5674 #define LPFLG_ARRLEN_LIMIT 0x0400 // iterator is compared with a.len or a[i].len (found in lpArrLenLimit)
5675 #define LPFLG_SIMD_LIMIT 0x0080   // iterator is compared with Vector<T>.Count (found in lpConstLimit)
5676
5677 #define LPFLG_HAS_PREHEAD 0x0800 // lpHead is known to be a preHead for this loop
5678 #define LPFLG_REMOVED 0x1000     // has been removed from the loop table (unrolled or optimized away)
5679 #define LPFLG_DONT_UNROLL 0x2000 // do not unroll this loop
5680
5681 #define LPFLG_ASGVARS_YES 0x4000 // "lpAsgVars" has been  computed
5682 #define LPFLG_ASGVARS_INC 0x8000 // "lpAsgVars" is incomplete -- vars beyond those representable in an AllVarSet
5683                                  // type are assigned to.
5684
5685         bool lpLoopHasMemoryHavoc[MemoryKindCount]; // The loop contains an operation that we assume has arbitrary
5686                                                     // memory side effects.  If this is set, the fields below
5687                                                     // may not be accurate (since they become irrelevant.)
5688         bool lpContainsCall;                        // True if executing the loop body *may* execute a call
5689
5690         VARSET_TP lpVarInOut;  // The set of variables that are IN or OUT during the execution of this loop
5691         VARSET_TP lpVarUseDef; // The set of variables that are USE or DEF during the execution of this loop
5692
5693         int lpHoistedExprCount; // The register count for the non-FP expressions from inside this loop that have been
5694                                 // hoisted
5695         int lpLoopVarCount;     // The register count for the non-FP LclVars that are read/written inside this loop
5696         int lpVarInOutCount;    // The register count for the non-FP LclVars that are alive inside or accross this loop
5697
5698         int lpHoistedFPExprCount; // The register count for the FP expressions from inside this loop that have been
5699                                   // hoisted
5700         int lpLoopVarFPCount;     // The register count for the FP LclVars that are read/written inside this loop
5701         int lpVarInOutFPCount;    // The register count for the FP LclVars that are alive inside or accross this loop
5702
5703         typedef JitHashTable<CORINFO_FIELD_HANDLE, JitPtrKeyFuncs<struct CORINFO_FIELD_STRUCT_>, bool> FieldHandleSet;
5704         FieldHandleSet* lpFieldsModified; // This has entries (mappings to "true") for all static field and object
5705                                           // instance fields modified
5706                                           // in the loop.
5707
5708         typedef JitHashTable<CORINFO_CLASS_HANDLE, JitPtrKeyFuncs<struct CORINFO_CLASS_STRUCT_>, bool> ClassHandleSet;
5709         ClassHandleSet* lpArrayElemTypesModified; // Bits set indicate the set of sz array element types such that
5710                                                   // arrays of that type are modified
5711                                                   // in the loop.
5712
5713         // Adds the variable liveness information for 'blk' to 'this' LoopDsc
5714         void AddVariableLiveness(Compiler* comp, BasicBlock* blk);
5715
5716         inline void AddModifiedField(Compiler* comp, CORINFO_FIELD_HANDLE fldHnd);
5717         // This doesn't *always* take a class handle -- it can also take primitive types, encoded as class handles
5718         // (shifted left, with a low-order bit set to distinguish.)
5719         // Use the {Encode/Decode}ElemType methods to construct/destruct these.
5720         inline void AddModifiedElemType(Compiler* comp, CORINFO_CLASS_HANDLE structHnd);
5721
5722         /* The following values are set only for iterator loops, i.e. has the flag LPFLG_ITER set */
5723
5724         GenTree*   lpIterTree;    // The "i = i <op> const" tree
5725         unsigned   lpIterVar();   // iterator variable #
5726         int        lpIterConst(); // the constant with which the iterator is incremented
5727         genTreeOps lpIterOper();  // the type of the operation on the iterator (ASG_ADD, ASG_SUB, etc.)
5728         void       VERIFY_lpIterTree();
5729
5730         var_types lpIterOperType(); // For overflow instructions
5731
5732         union {
5733             int lpConstInit; // initial constant value of iterator                           : Valid if LPFLG_CONST_INIT
5734             unsigned lpVarInit; // initial local var number to which we initialize the iterator : Valid if
5735                                 // LPFLG_VAR_INIT
5736         };
5737
5738         /* The following is for LPFLG_ITER loops only (i.e. the loop condition is "i RELOP const or var" */
5739
5740         GenTree*   lpTestTree;   // pointer to the node containing the loop test
5741         genTreeOps lpTestOper(); // the type of the comparison between the iterator and the limit (GT_LE, GT_GE, etc.)
5742         void       VERIFY_lpTestTree();
5743
5744         bool     lpIsReversed(); // true if the iterator node is the second operand in the loop condition
5745         GenTree* lpIterator();   // the iterator node in the loop test
5746         GenTree* lpLimit();      // the limit node in the loop test
5747
5748         int lpConstLimit();    // limit   constant value of iterator - loop condition is "i RELOP const" : Valid if
5749                                // LPFLG_CONST_LIMIT
5750         unsigned lpVarLimit(); // the lclVar # in the loop condition ( "i RELOP lclVar" )                : Valid if
5751                                // LPFLG_VAR_LIMIT
5752         bool lpArrLenLimit(Compiler* comp, ArrIndex* index); // The array length in the loop condition ( "i RELOP
5753                                                              // arr.len" or "i RELOP arr[i][j].len" )  : Valid if
5754                                                              // LPFLG_ARRLEN_LIMIT
5755
5756         // Returns "true" iff "*this" contains the blk.
5757         bool lpContains(BasicBlock* blk)
5758         {
5759             return lpFirst->bbNum <= blk->bbNum && blk->bbNum <= lpBottom->bbNum;
5760         }
5761         // Returns "true" iff "*this" (properly) contains the range [first, bottom] (allowing firsts
5762         // to be equal, but requiring bottoms to be different.)
5763         bool lpContains(BasicBlock* first, BasicBlock* bottom)
5764         {
5765             return lpFirst->bbNum <= first->bbNum && bottom->bbNum < lpBottom->bbNum;
5766         }
5767
5768         // Returns "true" iff "*this" (properly) contains "lp2" (allowing firsts to be equal, but requiring
5769         // bottoms to be different.)
5770         bool lpContains(const LoopDsc& lp2)
5771         {
5772             return lpContains(lp2.lpFirst, lp2.lpBottom);
5773         }
5774
5775         // Returns "true" iff "*this" is (properly) contained by the range [first, bottom]
5776         // (allowing firsts to be equal, but requiring bottoms to be different.)
5777         bool lpContainedBy(BasicBlock* first, BasicBlock* bottom)
5778         {
5779             return first->bbNum <= lpFirst->bbNum && lpBottom->bbNum < bottom->bbNum;
5780         }
5781
5782         // Returns "true" iff "*this" is (properly) contained by "lp2"
5783         // (allowing firsts to be equal, but requiring bottoms to be different.)
5784         bool lpContainedBy(const LoopDsc& lp2)
5785         {
5786             return lpContains(lp2.lpFirst, lp2.lpBottom);
5787         }
5788
5789         // Returns "true" iff "*this" is disjoint from the range [top, bottom].
5790         bool lpDisjoint(BasicBlock* first, BasicBlock* bottom)
5791         {
5792             return bottom->bbNum < lpFirst->bbNum || lpBottom->bbNum < first->bbNum;
5793         }
5794         // Returns "true" iff "*this" is disjoint from "lp2".
5795         bool lpDisjoint(const LoopDsc& lp2)
5796         {
5797             return lpDisjoint(lp2.lpFirst, lp2.lpBottom);
5798         }
5799         // Returns "true" iff the loop is well-formed (see code for defn).
5800         bool lpWellFormed()
5801         {
5802             return lpFirst->bbNum <= lpTop->bbNum && lpTop->bbNum <= lpEntry->bbNum &&
5803                    lpEntry->bbNum <= lpBottom->bbNum &&
5804                    (lpHead->bbNum < lpTop->bbNum || lpHead->bbNum > lpBottom->bbNum);
5805         }
5806     };
5807
5808 protected:
5809     bool fgMightHaveLoop(); // returns true if there are any backedges
5810     bool fgHasLoops;        // True if this method has any loops, set in fgComputeReachability
5811
5812 public:
5813     LoopDsc*      optLoopTable; // loop descriptor table
5814     unsigned char optLoopCount; // number of tracked loops
5815
5816     bool optRecordLoop(BasicBlock*   head,
5817                        BasicBlock*   first,
5818                        BasicBlock*   top,
5819                        BasicBlock*   entry,
5820                        BasicBlock*   bottom,
5821                        BasicBlock*   exit,
5822                        unsigned char exitCnt);
5823
5824 protected:
5825     unsigned optCallCount;         // number of calls made in the method
5826     unsigned optIndirectCallCount; // number of virtual, interface and indirect calls made in the method
5827     unsigned optNativeCallCount;   // number of Pinvoke/Native calls made in the method
5828     unsigned optLoopsCloned;       // number of loops cloned in the current method.
5829
5830 #ifdef DEBUG
5831     unsigned optFindLoopNumberFromBeginBlock(BasicBlock* begBlk);
5832     void optPrintLoopInfo(unsigned      loopNum,
5833                           BasicBlock*   lpHead,
5834                           BasicBlock*   lpFirst,
5835                           BasicBlock*   lpTop,
5836                           BasicBlock*   lpEntry,
5837                           BasicBlock*   lpBottom,
5838                           unsigned char lpExitCnt,
5839                           BasicBlock*   lpExit,
5840                           unsigned      parentLoop = BasicBlock::NOT_IN_LOOP);
5841     void optPrintLoopInfo(unsigned lnum);
5842     void optPrintLoopRecording(unsigned lnum);
5843
5844     void optCheckPreds();
5845 #endif
5846
5847     void optSetBlockWeights();
5848
5849     void optMarkLoopBlocks(BasicBlock* begBlk, BasicBlock* endBlk, bool excludeEndBlk);
5850
5851     void optUnmarkLoopBlocks(BasicBlock* begBlk, BasicBlock* endBlk);
5852
5853     void optUpdateLoopsBeforeRemoveBlock(BasicBlock* block, bool skipUnmarkLoop = false);
5854
5855     bool optIsLoopTestEvalIntoTemp(GenTree* test, GenTree** newTest);
5856     unsigned optIsLoopIncrTree(GenTree* incr);
5857     bool optCheckIterInLoopTest(unsigned loopInd, GenTree* test, BasicBlock* from, BasicBlock* to, unsigned iterVar);
5858     bool optComputeIterInfo(GenTree* incr, BasicBlock* from, BasicBlock* to, unsigned* pIterVar);
5859     bool optPopulateInitInfo(unsigned loopInd, GenTree* init, unsigned iterVar);
5860     bool optExtractInitTestIncr(
5861         BasicBlock* head, BasicBlock* bottom, BasicBlock* exit, GenTree** ppInit, GenTree** ppTest, GenTree** ppIncr);
5862
5863     void optFindNaturalLoops();
5864
5865     // Ensures that all the loops in the loop nest rooted at "loopInd" (an index into the loop table) are 'canonical' --
5866     // each loop has a unique "top."  Returns "true" iff the flowgraph has been modified.
5867     bool optCanonicalizeLoopNest(unsigned char loopInd);
5868
5869     // Ensures that the loop "loopInd" (an index into the loop table) is 'canonical' -- it has a unique "top,"
5870     // unshared with any other loop.  Returns "true" iff the flowgraph has been modified
5871     bool optCanonicalizeLoop(unsigned char loopInd);
5872
5873     // Requires "l1" to be a valid loop table index, and not "BasicBlock::NOT_IN_LOOP".  Requires "l2" to be
5874     // a valid loop table index, or else "BasicBlock::NOT_IN_LOOP".  Returns true
5875     // iff "l2" is not NOT_IN_LOOP, and "l1" contains "l2".
5876     bool optLoopContains(unsigned l1, unsigned l2);
5877
5878     // Requires "loopInd" to be a valid index into the loop table.
5879     // Updates the loop table by changing loop "loopInd", whose head is required
5880     // to be "from", to be "to".  Also performs this transformation for any
5881     // loop nested in "loopInd" that shares the same head as "loopInd".
5882     void optUpdateLoopHead(unsigned loopInd, BasicBlock* from, BasicBlock* to);
5883
5884     // Updates the successors of "blk": if "blk2" is a successor of "blk", and there is a mapping for "blk2->blk3" in
5885     // "redirectMap", change "blk" so that "blk3" is this successor. Note that the predecessor lists are not updated.
5886     void optRedirectBlock(BasicBlock* blk, BlockToBlockMap* redirectMap);
5887
5888     // Marks the containsCall information to "lnum" and any parent loops.
5889     void AddContainsCallAllContainingLoops(unsigned lnum);
5890     // Adds the variable liveness information from 'blk' to "lnum" and any parent loops.
5891     void AddVariableLivenessAllContainingLoops(unsigned lnum, BasicBlock* blk);
5892     // Adds "fldHnd" to the set of modified fields of "lnum" and any parent loops.
5893     void AddModifiedFieldAllContainingLoops(unsigned lnum, CORINFO_FIELD_HANDLE fldHnd);
5894     // Adds "elemType" to the set of modified array element types of "lnum" and any parent loops.
5895     void AddModifiedElemTypeAllContainingLoops(unsigned lnum, CORINFO_CLASS_HANDLE elemType);
5896
5897     // Requires that "from" and "to" have the same "bbJumpKind" (perhaps because "to" is a clone
5898     // of "from".)  Copies the jump destination from "from" to "to".
5899     void optCopyBlkDest(BasicBlock* from, BasicBlock* to);
5900
5901     // The depth of the loop described by "lnum" (an index into the loop table.) (0 == top level)
5902     unsigned optLoopDepth(unsigned lnum)
5903     {
5904         unsigned par = optLoopTable[lnum].lpParent;
5905         if (par == BasicBlock::NOT_IN_LOOP)
5906         {
5907             return 0;
5908         }
5909         else
5910         {
5911             return 1 + optLoopDepth(par);
5912         }
5913     }
5914
5915     void fgOptWhileLoop(BasicBlock* block);
5916
5917     bool optComputeLoopRep(int        constInit,
5918                            int        constLimit,
5919                            int        iterInc,
5920                            genTreeOps iterOper,
5921                            var_types  iterType,
5922                            genTreeOps testOper,
5923                            bool       unsignedTest,
5924                            bool       dupCond,
5925                            unsigned*  iterCount);
5926
5927 private:
5928     static fgWalkPreFn optIsVarAssgCB;
5929
5930 protected:
5931     bool optIsVarAssigned(BasicBlock* beg, BasicBlock* end, GenTree* skip, unsigned var);
5932
5933     bool optIsVarAssgLoop(unsigned lnum, unsigned var);
5934
5935     int optIsSetAssgLoop(unsigned lnum, ALLVARSET_VALARG_TP vars, varRefKinds inds = VR_NONE);
5936
5937     bool optNarrowTree(GenTree* tree, var_types srct, var_types dstt, ValueNumPair vnpNarrow, bool doit);
5938
5939     /**************************************************************************
5940      *                       Optimization conditions
5941      *************************************************************************/
5942
5943     bool optFastCodeOrBlendedLoop(BasicBlock::weight_t bbWeight);
5944     bool optPentium4(void);
5945     bool optAvoidIncDec(BasicBlock::weight_t bbWeight);
5946     bool optAvoidIntMult(void);
5947
5948 #if FEATURE_ANYCSE
5949
5950 protected:
5951     //  The following is the upper limit on how many expressions we'll keep track
5952     //  of for the CSE analysis.
5953     //
5954     static const unsigned MAX_CSE_CNT = EXPSET_SZ;
5955
5956     static const int MIN_CSE_COST = 2;
5957
5958     // Keeps tracked cse indices
5959     BitVecTraits* cseTraits;
5960     EXPSET_TP     cseFull;
5961
5962     /* Generic list of nodes - used by the CSE logic */
5963
5964     struct treeLst
5965     {
5966         treeLst* tlNext;
5967         GenTree* tlTree;
5968     };
5969
5970     struct treeStmtLst
5971     {
5972         treeStmtLst* tslNext;
5973         GenTree*     tslTree;  // tree node
5974         GenTree*     tslStmt;  // statement containing the tree
5975         BasicBlock*  tslBlock; // block containing the statement
5976     };
5977
5978     // The following logic keeps track of expressions via a simple hash table.
5979
5980     struct CSEdsc
5981     {
5982         CSEdsc* csdNextInBucket; // used by the hash table
5983
5984         unsigned csdHashKey; // the orginal hashkey
5985
5986         unsigned csdIndex;          // 1..optCSECandidateCount
5987         char     csdLiveAcrossCall; // 0 or 1
5988
5989         unsigned short csdDefCount; // definition   count
5990         unsigned short csdUseCount; // use          count  (excluding the implicit uses at defs)
5991
5992         unsigned csdDefWtCnt; // weighted def count
5993         unsigned csdUseWtCnt; // weighted use count  (excluding the implicit uses at defs)
5994
5995         GenTree*    csdTree;  // treenode containing the 1st occurance
5996         GenTree*    csdStmt;  // stmt containing the 1st occurance
5997         BasicBlock* csdBlock; // block containing the 1st occurance
5998
5999         treeStmtLst* csdTreeList; // list of matching tree nodes: head
6000         treeStmtLst* csdTreeLast; // list of matching tree nodes: tail
6001
6002         ValueNum defExcSetPromise; // The exception set that is now required for all defs of this CSE.
6003                                    // This will be set to NoVN if we decide to abandon this CSE
6004
6005         ValueNum defExcSetCurrent; // The set of exceptions we currently can use for CSE uses.
6006
6007         ValueNum defConservNormVN; // if all def occurrences share the same conservative normal value
6008                                    // number, this will reflect it; otherwise, NoVN.
6009     };
6010
6011     static const size_t s_optCSEhashSize;
6012     CSEdsc**            optCSEhash;
6013     CSEdsc**            optCSEtab;
6014
6015     typedef JitHashTable<GenTree*, JitPtrKeyFuncs<GenTree>, GenTree*> NodeToNodeMap;
6016
6017     NodeToNodeMap* optCseCheckedBoundMap; // Maps bound nodes to ancestor compares that should be
6018                                           // re-numbered with the bound to improve range check elimination
6019
6020     // Given a compare, look for a cse candidate checked bound feeding it and add a map entry if found.
6021     void optCseUpdateCheckedBoundMap(GenTree* compare);
6022
6023     void optCSEstop();
6024
6025     CSEdsc* optCSEfindDsc(unsigned index);
6026     bool optUnmarkCSE(GenTree* tree);
6027
6028     // user defined callback data for the tree walk function optCSE_MaskHelper()
6029     struct optCSE_MaskData
6030     {
6031         EXPSET_TP CSE_defMask;
6032         EXPSET_TP CSE_useMask;
6033     };
6034
6035     // Treewalk helper for optCSE_DefMask and optCSE_UseMask
6036     static fgWalkPreFn optCSE_MaskHelper;
6037
6038     // This function walks all the node for an given tree
6039     // and return the mask of CSE definitions and uses for the tree
6040     //
6041     void optCSE_GetMaskData(GenTree* tree, optCSE_MaskData* pMaskData);
6042
6043     // Given a binary tree node return true if it is safe to swap the order of evaluation for op1 and op2.
6044     bool optCSE_canSwap(GenTree* firstNode, GenTree* secondNode);
6045     bool optCSE_canSwap(GenTree* tree);
6046
6047     static int __cdecl optCSEcostCmpEx(const void* op1, const void* op2);
6048     static int __cdecl optCSEcostCmpSz(const void* op1, const void* op2);
6049
6050     void optCleanupCSEs();
6051
6052 #ifdef DEBUG
6053     void optEnsureClearCSEInfo();
6054 #endif // DEBUG
6055
6056 #endif // FEATURE_ANYCSE
6057
6058 #if FEATURE_VALNUM_CSE
6059     /**************************************************************************
6060      *                   Value Number based CSEs
6061      *************************************************************************/
6062
6063 public:
6064     void optOptimizeValnumCSEs();
6065
6066 protected:
6067     void     optValnumCSE_Init();
6068     unsigned optValnumCSE_Index(GenTree* tree, GenTree* stmt);
6069     unsigned optValnumCSE_Locate();
6070     void     optValnumCSE_InitDataFlow();
6071     void     optValnumCSE_DataFlow();
6072     void     optValnumCSE_Availablity();
6073     void     optValnumCSE_Heuristic();
6074
6075 #endif // FEATURE_VALNUM_CSE
6076
6077 #if FEATURE_ANYCSE
6078     bool     optDoCSE;             // True when we have found a duplicate CSE tree
6079     bool     optValnumCSE_phase;   // True when we are executing the optValnumCSE_phase
6080     unsigned optCSECandidateTotal; // Grand total of CSE candidates for both Lexical and ValNum
6081     unsigned optCSECandidateCount; // Count of CSE's candidates, reset for Lexical and ValNum CSE's
6082     unsigned optCSEstart;          // The first local variable number that is a CSE
6083     unsigned optCSEcount;          // The total count of CSE's introduced.
6084     unsigned optCSEweight;         // The weight of the current block when we are
6085                                    // scanning for CSE expressions
6086
6087     bool optIsCSEcandidate(GenTree* tree);
6088
6089     // lclNumIsTrueCSE returns true if the LclVar was introduced by the CSE phase of the compiler
6090     //
6091     bool lclNumIsTrueCSE(unsigned lclNum) const
6092     {
6093         return ((optCSEcount > 0) && (lclNum >= optCSEstart) && (lclNum < optCSEstart + optCSEcount));
6094     }
6095
6096     //  lclNumIsCSE returns true if the LclVar should be treated like a CSE with regards to constant prop.
6097     //
6098     bool lclNumIsCSE(unsigned lclNum) const
6099     {
6100         return lvaTable[lclNum].lvIsCSE;
6101     }
6102
6103 #ifdef DEBUG
6104     bool optConfigDisableCSE();
6105     bool optConfigDisableCSE2();
6106 #endif
6107     void optOptimizeCSEs();
6108
6109 #endif // FEATURE_ANYCSE
6110
6111     struct isVarAssgDsc
6112     {
6113         GenTree* ivaSkip;
6114 #ifdef DEBUG
6115         void* ivaSelf;
6116 #endif
6117         unsigned     ivaVar;            // Variable we are interested in, or -1
6118         ALLVARSET_TP ivaMaskVal;        // Set of variables assigned to.  This is a set of all vars, not tracked vars.
6119         bool         ivaMaskIncomplete; // Variables not representable in ivaMaskVal were assigned to.
6120         varRefKinds  ivaMaskInd;        // What kind of indirect assignments are there?
6121         callInterf   ivaMaskCall;       // What kind of calls are there?
6122     };
6123
6124     static callInterf optCallInterf(GenTreeCall* call);
6125
6126 public:
6127     // VN based copy propagation.
6128     typedef ArrayStack<GenTree*> GenTreePtrStack;
6129     typedef JitHashTable<unsigned, JitSmallPrimitiveKeyFuncs<unsigned>, GenTreePtrStack*> LclNumToGenTreePtrStack;
6130
6131     // Kill set to track variables with intervening definitions.
6132     VARSET_TP optCopyPropKillSet;
6133
6134     // Copy propagation functions.
6135     void optCopyProp(BasicBlock* block, GenTree* stmt, GenTree* tree, LclNumToGenTreePtrStack* curSsaName);
6136     void optBlockCopyPropPopStacks(BasicBlock* block, LclNumToGenTreePtrStack* curSsaName);
6137     void optBlockCopyProp(BasicBlock* block, LclNumToGenTreePtrStack* curSsaName);
6138     bool optIsSsaLocal(GenTree* tree);
6139     int optCopyProp_LclVarScore(LclVarDsc* lclVarDsc, LclVarDsc* copyVarDsc, bool preferOp2);
6140     void optVnCopyProp();
6141     INDEBUG(void optDumpCopyPropStack(LclNumToGenTreePtrStack* curSsaName));
6142
6143     /**************************************************************************
6144     *               Early value propagation
6145     *************************************************************************/
6146     struct SSAName
6147     {
6148         unsigned m_lvNum;
6149         unsigned m_ssaNum;
6150
6151         SSAName(unsigned lvNum, unsigned ssaNum) : m_lvNum(lvNum), m_ssaNum(ssaNum)
6152         {
6153         }
6154
6155         static unsigned GetHashCode(SSAName ssaNm)
6156         {
6157             return (ssaNm.m_lvNum << 16) | (ssaNm.m_ssaNum);
6158         }
6159
6160         static bool Equals(SSAName ssaNm1, SSAName ssaNm2)
6161         {
6162             return (ssaNm1.m_lvNum == ssaNm2.m_lvNum) && (ssaNm1.m_ssaNum == ssaNm2.m_ssaNum);
6163         }
6164     };
6165
6166 #define OMF_HAS_NEWARRAY 0x00000001      // Method contains 'new' of an array
6167 #define OMF_HAS_NEWOBJ 0x00000002        // Method contains 'new' of an object type.
6168 #define OMF_HAS_ARRAYREF 0x00000004      // Method contains array element loads or stores.
6169 #define OMF_HAS_VTABLEREF 0x00000008     // Method contains method table reference.
6170 #define OMF_HAS_NULLCHECK 0x00000010     // Method contains null check.
6171 #define OMF_HAS_FATPOINTER 0x00000020    // Method contains call, that needs fat pointer transformation.
6172 #define OMF_HAS_OBJSTACKALLOC 0x00000040 // Method contains an object allocated on the stack.
6173 #define OMF_HAS_GUARDEDDEVIRT 0x00000080 // Method contains guarded devirtualization candidate
6174
6175     bool doesMethodHaveFatPointer()
6176     {
6177         return (optMethodFlags & OMF_HAS_FATPOINTER) != 0;
6178     }
6179
6180     void setMethodHasFatPointer()
6181     {
6182         optMethodFlags |= OMF_HAS_FATPOINTER;
6183     }
6184
6185     void clearMethodHasFatPointer()
6186     {
6187         optMethodFlags &= ~OMF_HAS_FATPOINTER;
6188     }
6189
6190     void addFatPointerCandidate(GenTreeCall* call);
6191
6192     bool doesMethodHaveGuardedDevirtualization()
6193     {
6194         return (optMethodFlags & OMF_HAS_GUARDEDDEVIRT) != 0;
6195     }
6196
6197     void setMethodHasGuardedDevirtualization()
6198     {
6199         optMethodFlags |= OMF_HAS_GUARDEDDEVIRT;
6200     }
6201
6202     void clearMethodHasGuardedDevirtualization()
6203     {
6204         optMethodFlags &= ~OMF_HAS_GUARDEDDEVIRT;
6205     }
6206
6207     void addGuardedDevirtualizationCandidate(GenTreeCall*          call,
6208                                              CORINFO_METHOD_HANDLE methodHandle,
6209                                              CORINFO_CLASS_HANDLE  classHandle,
6210                                              unsigned              methodAttr,
6211                                              unsigned              classAttr);
6212
6213     unsigned optMethodFlags;
6214
6215     // Recursion bound controls how far we can go backwards tracking for a SSA value.
6216     // No throughput diff was found with backward walk bound between 3-8.
6217     static const int optEarlyPropRecurBound = 5;
6218
6219     enum class optPropKind
6220     {
6221         OPK_INVALID,
6222         OPK_ARRAYLEN,
6223         OPK_OBJ_GETTYPE,
6224         OPK_NULLCHECK
6225     };
6226
6227     bool gtIsVtableRef(GenTree* tree);
6228     GenTree* getArrayLengthFromAllocation(GenTree* tree);
6229     GenTree* getObjectHandleNodeFromAllocation(GenTree* tree);
6230     GenTree* optPropGetValueRec(unsigned lclNum, unsigned ssaNum, optPropKind valueKind, int walkDepth);
6231     GenTree* optPropGetValue(unsigned lclNum, unsigned ssaNum, optPropKind valueKind);
6232     GenTree* optEarlyPropRewriteTree(GenTree* tree);
6233     bool optDoEarlyPropForBlock(BasicBlock* block);
6234     bool optDoEarlyPropForFunc();
6235     void optEarlyProp();
6236     void optFoldNullCheck(GenTree* tree);
6237     bool optCanMoveNullCheckPastTree(GenTree* tree, bool isInsideTry);
6238
6239 #if ASSERTION_PROP
6240     /**************************************************************************
6241      *               Value/Assertion propagation
6242      *************************************************************************/
6243 public:
6244     // Data structures for assertion prop
6245     BitVecTraits* apTraits;
6246     ASSERT_TP     apFull;
6247
6248     enum optAssertionKind
6249     {
6250         OAK_INVALID,
6251         OAK_EQUAL,
6252         OAK_NOT_EQUAL,
6253         OAK_SUBRANGE,
6254         OAK_NO_THROW,
6255         OAK_COUNT
6256     };
6257
6258     enum optOp1Kind
6259     {
6260         O1K_INVALID,
6261         O1K_LCLVAR,
6262         O1K_ARR_BND,
6263         O1K_BOUND_OPER_BND,
6264         O1K_BOUND_LOOP_BND,
6265         O1K_CONSTANT_LOOP_BND,
6266         O1K_EXACT_TYPE,
6267         O1K_SUBTYPE,
6268         O1K_VALUE_NUMBER,
6269         O1K_COUNT
6270     };
6271
6272     enum optOp2Kind
6273     {
6274         O2K_INVALID,
6275         O2K_LCLVAR_COPY,
6276         O2K_IND_CNS_INT,
6277         O2K_CONST_INT,
6278         O2K_CONST_LONG,
6279         O2K_CONST_DOUBLE,
6280         O2K_ARR_LEN,
6281         O2K_SUBRANGE,
6282         O2K_COUNT
6283     };
6284     struct AssertionDsc
6285     {
6286         optAssertionKind assertionKind;
6287         struct SsaVar
6288         {
6289             unsigned lclNum; // assigned to or property of this local var number
6290             unsigned ssaNum;
6291         };
6292         struct ArrBnd
6293         {
6294             ValueNum vnIdx;
6295             ValueNum vnLen;
6296         };
6297         struct AssertionDscOp1
6298         {
6299             optOp1Kind kind; // a normal LclVar, or Exact-type or Subtype
6300             ValueNum   vn;
6301             union {
6302                 SsaVar lcl;
6303                 ArrBnd bnd;
6304             };
6305         } op1;
6306         struct AssertionDscOp2
6307         {
6308             optOp2Kind kind; // a const or copy assignment
6309             ValueNum   vn;
6310             struct IntVal
6311             {
6312                 ssize_t  iconVal;   // integer
6313                 unsigned iconFlags; // gtFlags
6314             };
6315             struct Range // integer subrange
6316             {
6317                 ssize_t loBound;
6318                 ssize_t hiBound;
6319             };
6320             union {
6321                 SsaVar  lcl;
6322                 IntVal  u1;
6323                 __int64 lconVal;
6324                 double  dconVal;
6325                 Range   u2;
6326             };
6327         } op2;
6328
6329         bool IsCheckedBoundArithBound()
6330         {
6331             return ((assertionKind == OAK_EQUAL || assertionKind == OAK_NOT_EQUAL) && op1.kind == O1K_BOUND_OPER_BND);
6332         }
6333         bool IsCheckedBoundBound()
6334         {
6335             return ((assertionKind == OAK_EQUAL || assertionKind == OAK_NOT_EQUAL) && op1.kind == O1K_BOUND_LOOP_BND);
6336         }
6337         bool IsConstantBound()
6338         {
6339             return ((assertionKind == OAK_EQUAL || assertionKind == OAK_NOT_EQUAL) &&
6340                     op1.kind == O1K_CONSTANT_LOOP_BND);
6341         }
6342         bool IsBoundsCheckNoThrow()
6343         {
6344             return ((assertionKind == OAK_NO_THROW) && (op1.kind == O1K_ARR_BND));
6345         }
6346
6347         bool IsCopyAssertion()
6348         {
6349             return ((assertionKind == OAK_EQUAL) && (op1.kind == O1K_LCLVAR) && (op2.kind == O2K_LCLVAR_COPY));
6350         }
6351
6352         static bool SameKind(AssertionDsc* a1, AssertionDsc* a2)
6353         {
6354             return a1->assertionKind == a2->assertionKind && a1->op1.kind == a2->op1.kind &&
6355                    a1->op2.kind == a2->op2.kind;
6356         }
6357
6358         static bool ComplementaryKind(optAssertionKind kind, optAssertionKind kind2)
6359         {
6360             if (kind == OAK_EQUAL)
6361             {
6362                 return kind2 == OAK_NOT_EQUAL;
6363             }
6364             else if (kind == OAK_NOT_EQUAL)
6365             {
6366                 return kind2 == OAK_EQUAL;
6367             }
6368             return false;
6369         }
6370
6371         static ssize_t GetLowerBoundForIntegralType(var_types type)
6372         {
6373             switch (type)
6374             {
6375                 case TYP_BYTE:
6376                     return SCHAR_MIN;
6377                 case TYP_SHORT:
6378                     return SHRT_MIN;
6379                 case TYP_INT:
6380                     return INT_MIN;
6381                 case TYP_BOOL:
6382                 case TYP_UBYTE:
6383                 case TYP_USHORT:
6384                 case TYP_UINT:
6385                     return 0;
6386                 default:
6387                     unreached();
6388             }
6389         }
6390         static ssize_t GetUpperBoundForIntegralType(var_types type)
6391         {
6392             switch (type)
6393             {
6394                 case TYP_BOOL:
6395                     return 1;
6396                 case TYP_BYTE:
6397                     return SCHAR_MAX;
6398                 case TYP_SHORT:
6399                     return SHRT_MAX;
6400                 case TYP_INT:
6401                     return INT_MAX;
6402                 case TYP_UBYTE:
6403                     return UCHAR_MAX;
6404                 case TYP_USHORT:
6405                     return USHRT_MAX;
6406                 case TYP_UINT:
6407                     return UINT_MAX;
6408                 default:
6409                     unreached();
6410             }
6411         }
6412
6413         bool HasSameOp1(AssertionDsc* that, bool vnBased)
6414         {
6415             if (op1.kind != that->op1.kind)
6416             {
6417                 return false;
6418             }
6419             else if (op1.kind == O1K_ARR_BND)
6420             {
6421                 assert(vnBased);
6422                 return (op1.bnd.vnIdx == that->op1.bnd.vnIdx) && (op1.bnd.vnLen == that->op1.bnd.vnLen);
6423             }
6424             else
6425             {
6426                 return ((vnBased && (op1.vn == that->op1.vn)) ||
6427                         (!vnBased && (op1.lcl.lclNum == that->op1.lcl.lclNum)));
6428             }
6429         }
6430
6431         bool HasSameOp2(AssertionDsc* that, bool vnBased)
6432         {
6433             if (op2.kind != that->op2.kind)
6434             {
6435                 return false;
6436             }
6437             switch (op2.kind)
6438             {
6439                 case O2K_IND_CNS_INT:
6440                 case O2K_CONST_INT:
6441                     return ((op2.u1.iconVal == that->op2.u1.iconVal) && (op2.u1.iconFlags == that->op2.u1.iconFlags));
6442
6443                 case O2K_CONST_LONG:
6444                     return (op2.lconVal == that->op2.lconVal);
6445
6446                 case O2K_CONST_DOUBLE:
6447                     // exact match because of positive and negative zero.
6448                     return (memcmp(&op2.dconVal, &that->op2.dconVal, sizeof(double)) == 0);
6449
6450                 case O2K_LCLVAR_COPY:
6451                 case O2K_ARR_LEN:
6452                     return (op2.lcl.lclNum == that->op2.lcl.lclNum) &&
6453                            (!vnBased || op2.lcl.ssaNum == that->op2.lcl.ssaNum);
6454
6455                 case O2K_SUBRANGE:
6456                     return ((op2.u2.loBound == that->op2.u2.loBound) && (op2.u2.hiBound == that->op2.u2.hiBound));
6457
6458                 case O2K_INVALID:
6459                     // we will return false
6460                     break;
6461
6462                 default:
6463                     assert(!"Unexpected value for op2.kind in AssertionDsc.");
6464                     break;
6465             }
6466             return false;
6467         }
6468
6469         bool Complementary(AssertionDsc* that, bool vnBased)
6470         {
6471             return ComplementaryKind(assertionKind, that->assertionKind) && HasSameOp1(that, vnBased) &&
6472                    HasSameOp2(that, vnBased);
6473         }
6474
6475         bool Equals(AssertionDsc* that, bool vnBased)
6476         {
6477             if (assertionKind != that->assertionKind)
6478             {
6479                 return false;
6480             }
6481             else if (assertionKind == OAK_NO_THROW)
6482             {
6483                 assert(op2.kind == O2K_INVALID);
6484                 return HasSameOp1(that, vnBased);
6485             }
6486             else
6487             {
6488                 return HasSameOp1(that, vnBased) && HasSameOp2(that, vnBased);
6489             }
6490         }
6491     };
6492
6493 protected:
6494     static fgWalkPreFn optAddCopiesCallback;
6495     static fgWalkPreFn optVNAssertionPropCurStmtVisitor;
6496     unsigned           optAddCopyLclNum;
6497     GenTree*           optAddCopyAsgnNode;
6498
6499     bool optLocalAssertionProp;  // indicates that we are performing local assertion prop
6500     bool optAssertionPropagated; // set to true if we modified the trees
6501     bool optAssertionPropagatedCurrentStmt;
6502 #ifdef DEBUG
6503     GenTree* optAssertionPropCurrentTree;
6504 #endif
6505     AssertionIndex*            optComplementaryAssertionMap;
6506     JitExpandArray<ASSERT_TP>* optAssertionDep; // table that holds dependent assertions (assertions
6507                                                 // using the value of a local var) for each local var
6508     AssertionDsc*  optAssertionTabPrivate;      // table that holds info about value assignments
6509     AssertionIndex optAssertionCount;           // total number of assertions in the assertion table
6510     AssertionIndex optMaxAssertionCount;
6511
6512 public:
6513     void optVnNonNullPropCurStmt(BasicBlock* block, GenTree* stmt, GenTree* tree);
6514     fgWalkResult optVNConstantPropCurStmt(BasicBlock* block, GenTree* stmt, GenTree* tree);
6515     GenTree* optVNConstantPropOnJTrue(BasicBlock* block, GenTree* stmt, GenTree* test);
6516     GenTree* optVNConstantPropOnTree(BasicBlock* block, GenTree* stmt, GenTree* tree);
6517     GenTree* optPrepareTreeForReplacement(GenTree* extractTree, GenTree* replaceTree);
6518
6519     AssertionIndex GetAssertionCount()
6520     {
6521         return optAssertionCount;
6522     }
6523     ASSERT_TP* bbJtrueAssertionOut;
6524     typedef JitHashTable<ValueNum, JitSmallPrimitiveKeyFuncs<ValueNum>, ASSERT_TP> ValueNumToAssertsMap;
6525     ValueNumToAssertsMap* optValueNumToAsserts;
6526
6527     // Assertion prop helpers.
6528     ASSERT_TP& GetAssertionDep(unsigned lclNum);
6529     AssertionDsc* optGetAssertion(AssertionIndex assertIndex);
6530     void optAssertionInit(bool isLocalProp);
6531     void optAssertionTraitsInit(AssertionIndex assertionCount);
6532 #if LOCAL_ASSERTION_PROP
6533     void optAssertionReset(AssertionIndex limit);
6534     void optAssertionRemove(AssertionIndex index);
6535 #endif
6536
6537     // Assertion prop data flow functions.
6538     void     optAssertionPropMain();
6539     GenTree* optVNAssertionPropCurStmt(BasicBlock* block, GenTree* stmt);
6540     bool optIsTreeKnownIntValue(bool vnBased, GenTree* tree, ssize_t* pConstant, unsigned* pIconFlags);
6541     ASSERT_TP* optInitAssertionDataflowFlags();
6542     ASSERT_TP* optComputeAssertionGen();
6543
6544     // Assertion Gen functions.
6545     void optAssertionGen(GenTree* tree);
6546     AssertionIndex optAssertionGenPhiDefn(GenTree* tree);
6547     AssertionInfo optCreateJTrueBoundsAssertion(GenTree* tree);
6548     AssertionInfo optAssertionGenJtrue(GenTree* tree);
6549     AssertionIndex optCreateJtrueAssertions(GenTree* op1, GenTree* op2, Compiler::optAssertionKind assertionKind);
6550     AssertionIndex optFindComplementary(AssertionIndex assertionIndex);
6551     void optMapComplementary(AssertionIndex assertionIndex, AssertionIndex index);
6552
6553     // Assertion creation functions.
6554     AssertionIndex optCreateAssertion(GenTree* op1, GenTree* op2, optAssertionKind assertionKind);
6555     AssertionIndex optCreateAssertion(GenTree*         op1,
6556                                       GenTree*         op2,
6557                                       optAssertionKind assertionKind,
6558                                       AssertionDsc*    assertion);
6559     void optCreateComplementaryAssertion(AssertionIndex assertionIndex, GenTree* op1, GenTree* op2);
6560
6561     bool optAssertionVnInvolvesNan(AssertionDsc* assertion);
6562     AssertionIndex optAddAssertion(AssertionDsc* assertion);
6563     void optAddVnAssertionMapping(ValueNum vn, AssertionIndex index);
6564 #ifdef DEBUG
6565     void optPrintVnAssertionMapping();
6566 #endif
6567     ASSERT_TP optGetVnMappedAssertions(ValueNum vn);
6568
6569     // Used for respective assertion propagations.
6570     AssertionIndex optAssertionIsSubrange(GenTree* tree, var_types toType, ASSERT_VALARG_TP assertions);
6571     AssertionIndex optAssertionIsSubtype(GenTree* tree, GenTree* methodTableArg, ASSERT_VALARG_TP assertions);
6572     AssertionIndex optAssertionIsNonNullInternal(GenTree* op, ASSERT_VALARG_TP assertions);
6573     bool optAssertionIsNonNull(GenTree*         op,
6574                                ASSERT_VALARG_TP assertions DEBUGARG(bool* pVnBased) DEBUGARG(AssertionIndex* pIndex));
6575
6576     // Used for Relop propagation.
6577     AssertionIndex optGlobalAssertionIsEqualOrNotEqual(ASSERT_VALARG_TP assertions, GenTree* op1, GenTree* op2);
6578     AssertionIndex optGlobalAssertionIsEqualOrNotEqualZero(ASSERT_VALARG_TP assertions, GenTree* op1);
6579     AssertionIndex optLocalAssertionIsEqualOrNotEqual(
6580         optOp1Kind op1Kind, unsigned lclNum, optOp2Kind op2Kind, ssize_t cnsVal, ASSERT_VALARG_TP assertions);
6581
6582     // Assertion prop for lcl var functions.
6583     bool optAssertionProp_LclVarTypeCheck(GenTree* tree, LclVarDsc* lclVarDsc, LclVarDsc* copyVarDsc);
6584     GenTree* optCopyAssertionProp(AssertionDsc* curAssertion,
6585                                   GenTree*      tree,
6586                                   GenTree* stmt DEBUGARG(AssertionIndex index));
6587     GenTree* optConstantAssertionProp(AssertionDsc* curAssertion,
6588                                       GenTree*      tree,
6589                                       GenTree* stmt DEBUGARG(AssertionIndex index));
6590
6591     // Assertion propagation functions.
6592     GenTree* optAssertionProp(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt);
6593     GenTree* optAssertionProp_LclVar(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt);
6594     GenTree* optAssertionProp_Ind(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt);
6595     GenTree* optAssertionProp_Cast(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt);
6596     GenTree* optAssertionProp_Call(ASSERT_VALARG_TP assertions, GenTreeCall* call, GenTree* stmt);
6597     GenTree* optAssertionProp_RelOp(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt);
6598     GenTree* optAssertionProp_Comma(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt);
6599     GenTree* optAssertionProp_BndsChk(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt);
6600     GenTree* optAssertionPropGlobal_RelOp(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt);
6601     GenTree* optAssertionPropLocal_RelOp(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt);
6602     GenTree* optAssertionProp_Update(GenTree* newTree, GenTree* tree, GenTree* stmt);
6603     GenTree* optNonNullAssertionProp_Call(ASSERT_VALARG_TP assertions, GenTreeCall* call, GenTree* stmt);
6604
6605     // Implied assertion functions.
6606     void optImpliedAssertions(AssertionIndex assertionIndex, ASSERT_TP& activeAssertions);
6607     void optImpliedByTypeOfAssertions(ASSERT_TP& activeAssertions);
6608     void optImpliedByCopyAssertion(AssertionDsc* copyAssertion, AssertionDsc* depAssertion, ASSERT_TP& result);
6609     void optImpliedByConstAssertion(AssertionDsc* curAssertion, ASSERT_TP& result);
6610
6611 #ifdef DEBUG
6612     void optPrintAssertion(AssertionDsc* newAssertion, AssertionIndex assertionIndex = 0);
6613     void optDebugCheckAssertion(AssertionDsc* assertion);
6614     void optDebugCheckAssertions(AssertionIndex AssertionIndex);
6615 #endif
6616     void optAddCopies();
6617 #endif // ASSERTION_PROP
6618
6619     /**************************************************************************
6620      *                          Range checks
6621      *************************************************************************/
6622
6623 public:
6624     struct LoopCloneVisitorInfo
6625     {
6626         LoopCloneContext* context;
6627         unsigned          loopNum;
6628         GenTree*          stmt;
6629         LoopCloneVisitorInfo(LoopCloneContext* context, unsigned loopNum, GenTree* stmt)
6630             : context(context), loopNum(loopNum), stmt(nullptr)
6631         {
6632         }
6633     };
6634
6635     bool optIsStackLocalInvariant(unsigned loopNum, unsigned lclNum);
6636     bool optExtractArrIndex(GenTree* tree, ArrIndex* result, unsigned lhsNum);
6637     bool optReconstructArrIndex(GenTree* tree, ArrIndex* result, unsigned lhsNum);
6638     bool optIdentifyLoopOptInfo(unsigned loopNum, LoopCloneContext* context);
6639     static fgWalkPreFn optCanOptimizeByLoopCloningVisitor;
6640     fgWalkResult optCanOptimizeByLoopCloning(GenTree* tree, LoopCloneVisitorInfo* info);
6641     void optObtainLoopCloningOpts(LoopCloneContext* context);
6642     bool optIsLoopClonable(unsigned loopInd);
6643
6644     bool optCanCloneLoops();
6645
6646 #ifdef DEBUG
6647     void optDebugLogLoopCloning(BasicBlock* block, GenTree* insertBefore);
6648 #endif
6649     void optPerformStaticOptimizations(unsigned loopNum, LoopCloneContext* context DEBUGARG(bool fastPath));
6650     bool optComputeDerefConditions(unsigned loopNum, LoopCloneContext* context);
6651     bool optDeriveLoopCloningConditions(unsigned loopNum, LoopCloneContext* context);
6652     BasicBlock* optInsertLoopChoiceConditions(LoopCloneContext* context,
6653                                               unsigned          loopNum,
6654                                               BasicBlock*       head,
6655                                               BasicBlock*       slow);
6656
6657 protected:
6658     ssize_t optGetArrayRefScaleAndIndex(GenTree* mul, GenTree** pIndex DEBUGARG(bool bRngChk));
6659
6660     bool optReachWithoutCall(BasicBlock* srcBB, BasicBlock* dstBB);
6661
6662 protected:
6663     bool optLoopsMarked;
6664
6665     /*
6666     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6667     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6668     XX                                                                           XX
6669     XX                           RegAlloc                                        XX
6670     XX                                                                           XX
6671     XX  Does the register allocation and puts the remaining lclVars on the stack XX
6672     XX                                                                           XX
6673     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6674     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6675     */
6676
6677 public:
6678     regNumber raUpdateRegStateForArg(RegState* regState, LclVarDsc* argDsc);
6679
6680     void raMarkStkVars();
6681
6682 protected:
6683     // Some things are used by both LSRA and regpredict allocators.
6684
6685     FrameType rpFrameType;
6686     bool      rpMustCreateEBPCalled; // Set to true after we have called rpMustCreateEBPFrame once
6687
6688     bool rpMustCreateEBPFrame(INDEBUG(const char** wbReason));
6689
6690 private:
6691     Lowering*            m_pLowering;   // Lowering; needed to Lower IR that's added or modified after Lowering.
6692     LinearScanInterface* m_pLinearScan; // Linear Scan allocator
6693
6694     /* raIsVarargsStackArg is called by raMaskStkVars and by
6695        lvaSortByRefCount.  It identifies the special case
6696        where a varargs function has a parameter passed on the
6697        stack, other than the special varargs handle.  Such parameters
6698        require special treatment, because they cannot be tracked
6699        by the GC (their offsets in the stack are not known
6700        at compile time).
6701     */
6702
6703     bool raIsVarargsStackArg(unsigned lclNum)
6704     {
6705 #ifdef _TARGET_X86_
6706
6707         LclVarDsc* varDsc = &lvaTable[lclNum];
6708
6709         assert(varDsc->lvIsParam);
6710
6711         return (info.compIsVarArgs && !varDsc->lvIsRegArg && (lclNum != lvaVarargsHandleArg));
6712
6713 #else // _TARGET_X86_
6714
6715         return false;
6716
6717 #endif // _TARGET_X86_
6718     }
6719
6720     /*
6721     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6722     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6723     XX                                                                           XX
6724     XX                           EEInterface                                     XX
6725     XX                                                                           XX
6726     XX   Get to the class and method info from the Execution Engine given        XX
6727     XX   tokens for the class and method                                         XX
6728     XX                                                                           XX
6729     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6730     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6731     */
6732
6733 public:
6734     /* These are the different addressing modes used to access a local var.
6735      * The JIT has to report the location of the locals back to the EE
6736      * for debugging purposes.
6737      */
6738
6739     enum siVarLocType
6740     {
6741         VLT_REG,
6742         VLT_REG_BYREF, // this type is currently only used for value types on X64
6743         VLT_REG_FP,
6744         VLT_STK,
6745         VLT_STK_BYREF, // this type is currently only used for value types on X64
6746         VLT_REG_REG,
6747         VLT_REG_STK,
6748         VLT_STK_REG,
6749         VLT_STK2,
6750         VLT_FPSTK,
6751         VLT_FIXED_VA,
6752
6753         VLT_COUNT,
6754         VLT_INVALID
6755     };
6756
6757     struct siVarLoc
6758     {
6759         siVarLocType vlType;
6760
6761         union {
6762             // VLT_REG/VLT_REG_FP -- Any pointer-sized enregistered value (TYP_INT, TYP_REF, etc)
6763             // eg. EAX
6764             // VLT_REG_BYREF -- the specified register contains the address of the variable
6765             // eg. [EAX]
6766
6767             struct
6768             {
6769                 regNumber vlrReg;
6770             } vlReg;
6771
6772             // VLT_STK       -- Any 32 bit value which is on the stack
6773             // eg. [ESP+0x20], or [EBP-0x28]
6774             // VLT_STK_BYREF -- the specified stack location contains the address of the variable
6775             // eg. mov EAX, [ESP+0x20]; [EAX]
6776
6777             struct
6778             {
6779                 regNumber     vlsBaseReg;
6780                 NATIVE_OFFSET vlsOffset;
6781             } vlStk;
6782
6783             // VLT_REG_REG -- TYP_LONG/TYP_DOUBLE with both DWords enregistered
6784             // eg. RBM_EAXEDX
6785
6786             struct
6787             {
6788                 regNumber vlrrReg1;
6789                 regNumber vlrrReg2;
6790             } vlRegReg;
6791
6792             // VLT_REG_STK -- Partly enregistered TYP_LONG/TYP_DOUBLE
6793             // eg { LowerDWord=EAX UpperDWord=[ESP+0x8] }
6794
6795             struct
6796             {
6797                 regNumber vlrsReg;
6798
6799                 struct
6800                 {
6801                     regNumber     vlrssBaseReg;
6802                     NATIVE_OFFSET vlrssOffset;
6803                 } vlrsStk;
6804             } vlRegStk;
6805
6806             // VLT_STK_REG -- Partly enregistered TYP_LONG/TYP_DOUBLE
6807             // eg { LowerDWord=[ESP+0x8] UpperDWord=EAX }
6808
6809             struct
6810             {
6811                 struct
6812                 {
6813                     regNumber     vlsrsBaseReg;
6814                     NATIVE_OFFSET vlsrsOffset;
6815                 } vlsrStk;
6816
6817                 regNumber vlsrReg;
6818             } vlStkReg;
6819
6820             // VLT_STK2 -- Any 64 bit value which is on the stack, in 2 successsive DWords
6821             // eg 2 DWords at [ESP+0x10]
6822
6823             struct
6824             {
6825                 regNumber     vls2BaseReg;
6826                 NATIVE_OFFSET vls2Offset;
6827             } vlStk2;
6828
6829             // VLT_FPSTK -- enregisterd TYP_DOUBLE (on the FP stack)
6830             // eg. ST(3). Actually it is ST("FPstkHeight - vpFpStk")
6831
6832             struct
6833             {
6834                 unsigned vlfReg;
6835             } vlFPstk;
6836
6837             // VLT_FIXED_VA -- fixed argument of a varargs function.
6838             // The argument location depends on the size of the variable
6839             // arguments (...). Inspecting the VARARGS_HANDLE indicates the
6840             // location of the first arg. This argument can then be accessed
6841             // relative to the position of the first arg
6842
6843             struct
6844             {
6845                 unsigned vlfvOffset;
6846             } vlFixedVarArg;
6847
6848             // VLT_MEMORY
6849
6850             struct
6851             {
6852                 void* rpValue; // pointer to the in-process
6853                                // location of the value.
6854             } vlMemory;
6855         };
6856
6857         // Helper functions
6858
6859         bool vlIsInReg(regNumber reg);
6860         bool vlIsOnStk(regNumber reg, signed offset);
6861     };
6862
6863     /*************************************************************************/
6864
6865 public:
6866     // Get handles
6867
6868     void eeGetCallInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
6869                        CORINFO_RESOLVED_TOKEN* pConstrainedToken,
6870                        CORINFO_CALLINFO_FLAGS  flags,
6871                        CORINFO_CALL_INFO*      pResult);
6872     inline CORINFO_CALLINFO_FLAGS addVerifyFlag(CORINFO_CALLINFO_FLAGS flags);
6873
6874     void eeGetFieldInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
6875                         CORINFO_ACCESS_FLAGS    flags,
6876                         CORINFO_FIELD_INFO*     pResult);
6877
6878     // Get the flags
6879
6880     BOOL eeIsValueClass(CORINFO_CLASS_HANDLE clsHnd);
6881
6882 #if defined(DEBUG) || defined(FEATURE_JIT_METHOD_PERF) || defined(FEATURE_SIMD) || defined(TRACK_LSRA_STATS)
6883
6884     bool IsSuperPMIException(unsigned code)
6885     {
6886         // Copied from NDP\clr\src\ToolBox\SuperPMI\SuperPMI-Shared\ErrorHandling.h
6887
6888         const unsigned EXCEPTIONCODE_DebugBreakorAV = 0xe0421000;
6889         const unsigned EXCEPTIONCODE_MC             = 0xe0422000;
6890         const unsigned EXCEPTIONCODE_LWM            = 0xe0423000;
6891         const unsigned EXCEPTIONCODE_SASM           = 0xe0424000;
6892         const unsigned EXCEPTIONCODE_SSYM           = 0xe0425000;
6893         const unsigned EXCEPTIONCODE_CALLUTILS      = 0xe0426000;
6894         const unsigned EXCEPTIONCODE_TYPEUTILS      = 0xe0427000;
6895         const unsigned EXCEPTIONCODE_ASSERT         = 0xe0440000;
6896
6897         switch (code)
6898         {
6899             case EXCEPTIONCODE_DebugBreakorAV:
6900             case EXCEPTIONCODE_MC:
6901             case EXCEPTIONCODE_LWM:
6902             case EXCEPTIONCODE_SASM:
6903             case EXCEPTIONCODE_SSYM:
6904             case EXCEPTIONCODE_CALLUTILS:
6905             case EXCEPTIONCODE_TYPEUTILS:
6906             case EXCEPTIONCODE_ASSERT:
6907                 return true;
6908             default:
6909                 return false;
6910         }
6911     }
6912
6913     const char* eeGetMethodName(CORINFO_METHOD_HANDLE hnd, const char** className);
6914     const char* eeGetMethodFullName(CORINFO_METHOD_HANDLE hnd);
6915
6916     bool eeIsNativeMethod(CORINFO_METHOD_HANDLE method);
6917     CORINFO_METHOD_HANDLE eeGetMethodHandleForNative(CORINFO_METHOD_HANDLE method);
6918 #endif
6919
6920     var_types eeGetArgType(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO* sig);
6921     var_types eeGetArgType(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO* sig, bool* isPinned);
6922     unsigned eeGetArgSize(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO* sig);
6923
6924     // VOM info, method sigs
6925
6926     void eeGetSig(unsigned               sigTok,
6927                   CORINFO_MODULE_HANDLE  scope,
6928                   CORINFO_CONTEXT_HANDLE context,
6929                   CORINFO_SIG_INFO*      retSig);
6930
6931     void eeGetCallSiteSig(unsigned               sigTok,
6932                           CORINFO_MODULE_HANDLE  scope,
6933                           CORINFO_CONTEXT_HANDLE context,
6934                           CORINFO_SIG_INFO*      retSig);
6935
6936     void eeGetMethodSig(CORINFO_METHOD_HANDLE methHnd, CORINFO_SIG_INFO* retSig, CORINFO_CLASS_HANDLE owner = nullptr);
6937
6938     // Method entry-points, instrs
6939
6940     CORINFO_METHOD_HANDLE eeMarkNativeTarget(CORINFO_METHOD_HANDLE method);
6941
6942     CORINFO_EE_INFO eeInfo;
6943     bool            eeInfoInitialized;
6944
6945     CORINFO_EE_INFO* eeGetEEInfo();
6946
6947     // Gets the offset of a SDArray's first element
6948     unsigned eeGetArrayDataOffset(var_types type);
6949     // Gets the offset of a MDArray's first element
6950     unsigned eeGetMDArrayDataOffset(var_types type, unsigned rank);
6951
6952     GenTree* eeGetPInvokeCookie(CORINFO_SIG_INFO* szMetaSig);
6953
6954     // Returns the page size for the target machine as reported by the EE.
6955     target_size_t eeGetPageSize()
6956     {
6957         return (target_size_t)eeGetEEInfo()->osPageSize;
6958     }
6959
6960     // Returns the frame size at which we will generate a loop to probe the stack.
6961     target_size_t getVeryLargeFrameSize()
6962     {
6963 #ifdef _TARGET_ARM_
6964         // The looping probe code is 40 bytes, whereas the straight-line probing for
6965         // the (0x2000..0x3000) case is 44, so use looping for anything 0x2000 bytes
6966         // or greater, to generate smaller code.
6967         return 2 * eeGetPageSize();
6968 #else
6969         return 3 * eeGetPageSize();
6970 #endif
6971     }
6972
6973     //------------------------------------------------------------------------
6974     // VirtualStubParam: virtual stub dispatch extra parameter (slot address).
6975     //
6976     // It represents Abi and target specific registers for the parameter.
6977     //
6978     class VirtualStubParamInfo
6979     {
6980     public:
6981         VirtualStubParamInfo(bool isCoreRTABI)
6982         {
6983 #if defined(_TARGET_X86_)
6984             reg     = REG_EAX;
6985             regMask = RBM_EAX;
6986 #elif defined(_TARGET_AMD64_)
6987             if (isCoreRTABI)
6988             {
6989                 reg     = REG_R10;
6990                 regMask = RBM_R10;
6991             }
6992             else
6993             {
6994                 reg     = REG_R11;
6995                 regMask = RBM_R11;
6996             }
6997 #elif defined(_TARGET_ARM_)
6998             if (isCoreRTABI)
6999             {
7000                 reg     = REG_R12;
7001                 regMask = RBM_R12;
7002             }
7003             else
7004             {
7005                 reg     = REG_R4;
7006                 regMask = RBM_R4;
7007             }
7008 #elif defined(_TARGET_ARM64_)
7009             reg     = REG_R11;
7010             regMask = RBM_R11;
7011 #else
7012 #error Unsupported or unset target architecture
7013 #endif
7014         }
7015
7016         regNumber GetReg() const
7017         {
7018             return reg;
7019         }
7020
7021         _regMask_enum GetRegMask() const
7022         {
7023             return regMask;
7024         }
7025
7026     private:
7027         regNumber     reg;
7028         _regMask_enum regMask;
7029     };
7030
7031     VirtualStubParamInfo* virtualStubParamInfo;
7032
7033     bool IsTargetAbi(CORINFO_RUNTIME_ABI abi)
7034     {
7035         return eeGetEEInfo()->targetAbi == abi;
7036     }
7037
7038     bool generateCFIUnwindCodes()
7039     {
7040 #if defined(_TARGET_UNIX_)
7041         return IsTargetAbi(CORINFO_CORERT_ABI);
7042 #else
7043         return false;
7044 #endif
7045     }
7046
7047     // Debugging support - Line number info
7048
7049     void eeGetStmtOffsets();
7050
7051     unsigned eeBoundariesCount;
7052
7053     struct boundariesDsc
7054     {
7055         UNATIVE_OFFSET nativeIP;
7056         IL_OFFSET      ilOffset;
7057         unsigned       sourceReason;
7058     } * eeBoundaries; // Boundaries to report to EE
7059     void eeSetLIcount(unsigned count);
7060     void eeSetLIinfo(unsigned which, UNATIVE_OFFSET offs, unsigned srcIP, bool stkEmpty, bool callInstruction);
7061     void eeSetLIdone();
7062
7063 #ifdef DEBUG
7064     static void eeDispILOffs(IL_OFFSET offs);
7065     static void eeDispLineInfo(const boundariesDsc* line);
7066     void eeDispLineInfos();
7067 #endif // DEBUG
7068
7069     // Debugging support - Local var info
7070
7071     void eeGetVars();
7072
7073     unsigned eeVarsCount;
7074
7075     struct VarResultInfo
7076     {
7077         UNATIVE_OFFSET startOffset;
7078         UNATIVE_OFFSET endOffset;
7079         DWORD          varNumber;
7080         siVarLoc       loc;
7081     } * eeVars;
7082     void eeSetLVcount(unsigned count);
7083     void eeSetLVinfo(unsigned        which,
7084                      UNATIVE_OFFSET  startOffs,
7085                      UNATIVE_OFFSET  length,
7086                      unsigned        varNum,
7087                      unsigned        LVnum,
7088                      VarName         namex,
7089                      bool            avail,
7090                      const siVarLoc& loc);
7091     void eeSetLVdone();
7092
7093 #ifdef DEBUG
7094     void eeDispVar(ICorDebugInfo::NativeVarInfo* var);
7095     void eeDispVars(CORINFO_METHOD_HANDLE ftn, ULONG32 cVars, ICorDebugInfo::NativeVarInfo* vars);
7096 #endif // DEBUG
7097
7098     // ICorJitInfo wrappers
7099
7100     void eeReserveUnwindInfo(BOOL isFunclet, BOOL isColdCode, ULONG unwindSize);
7101
7102     void eeAllocUnwindInfo(BYTE*          pHotCode,
7103                            BYTE*          pColdCode,
7104                            ULONG          startOffset,
7105                            ULONG          endOffset,
7106                            ULONG          unwindSize,
7107                            BYTE*          pUnwindBlock,
7108                            CorJitFuncKind funcKind);
7109
7110     void eeSetEHcount(unsigned cEH);
7111
7112     void eeSetEHinfo(unsigned EHnumber, const CORINFO_EH_CLAUSE* clause);
7113
7114     WORD eeGetRelocTypeHint(void* target);
7115
7116     // ICorStaticInfo wrapper functions
7117
7118     bool eeTryResolveToken(CORINFO_RESOLVED_TOKEN* resolvedToken);
7119
7120 #if defined(UNIX_AMD64_ABI)
7121 #ifdef DEBUG
7122     static void dumpSystemVClassificationType(SystemVClassificationType ct);
7123 #endif // DEBUG
7124
7125     void eeGetSystemVAmd64PassStructInRegisterDescriptor(
7126         /*IN*/ CORINFO_CLASS_HANDLE                                  structHnd,
7127         /*OUT*/ SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr);
7128 #endif // UNIX_AMD64_ABI
7129
7130     template <typename ParamType>
7131     bool eeRunWithErrorTrap(void (*function)(ParamType*), ParamType* param)
7132     {
7133         return eeRunWithErrorTrapImp(reinterpret_cast<void (*)(void*)>(function), reinterpret_cast<void*>(param));
7134     }
7135
7136     bool eeRunWithErrorTrapImp(void (*function)(void*), void* param);
7137
7138     // Utility functions
7139
7140     const char* eeGetFieldName(CORINFO_FIELD_HANDLE fieldHnd, const char** classNamePtr = nullptr);
7141
7142 #if defined(DEBUG)
7143     const wchar_t* eeGetCPString(size_t stringHandle);
7144 #endif
7145
7146     const char* eeGetClassName(CORINFO_CLASS_HANDLE clsHnd);
7147
7148     static CORINFO_METHOD_HANDLE eeFindHelper(unsigned helper);
7149     static CorInfoHelpFunc eeGetHelperNum(CORINFO_METHOD_HANDLE method);
7150
7151     static fgWalkPreFn CountSharedStaticHelper;
7152     static bool IsSharedStaticHelper(GenTree* tree);
7153     static bool IsTreeAlwaysHoistable(GenTree* tree);
7154     static bool IsGcSafePoint(GenTree* tree);
7155
7156     static CORINFO_FIELD_HANDLE eeFindJitDataOffs(unsigned jitDataOffs);
7157     // returns true/false if 'field' is a Jit Data offset
7158     static bool eeIsJitDataOffs(CORINFO_FIELD_HANDLE field);
7159     // returns a number < 0 if 'field' is not a Jit Data offset, otherwise the data offset (limited to 2GB)
7160     static int eeGetJitDataOffs(CORINFO_FIELD_HANDLE field);
7161
7162     /*****************************************************************************/
7163
7164     /*
7165     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7166     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7167     XX                                                                           XX
7168     XX                           CodeGenerator                                   XX
7169     XX                                                                           XX
7170     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7171     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7172     */
7173
7174 public:
7175     CodeGenInterface* codeGen;
7176
7177     //  The following holds information about instr offsets in terms of generated code.
7178
7179     struct IPmappingDsc
7180     {
7181         IPmappingDsc* ipmdNext;      // next line# record
7182         IL_OFFSETX    ipmdILoffsx;   // the instr offset
7183         emitLocation  ipmdNativeLoc; // the emitter location of the native code corresponding to the IL offset
7184         bool          ipmdIsLabel;   // Can this code be a branch label?
7185     };
7186
7187     // Record the instr offset mapping to the generated code
7188
7189     IPmappingDsc* genIPmappingList;
7190     IPmappingDsc* genIPmappingLast;
7191
7192     // Managed RetVal - A side hash table meant to record the mapping from a
7193     // GT_CALL node to its IL offset.  This info is used to emit sequence points
7194     // that can be used by debugger to determine the native offset at which the
7195     // managed RetVal will be available.
7196     //
7197     // In fact we can store IL offset in a GT_CALL node.  This was ruled out in
7198     // favor of a side table for two reasons: 1) We need IL offset for only those
7199     // GT_CALL nodes (created during importation) that correspond to an IL call and
7200     // whose return type is other than TYP_VOID. 2) GT_CALL node is a frequently used
7201     // structure and IL offset is needed only when generating debuggable code. Therefore
7202     // it is desirable to avoid memory size penalty in retail scenarios.
7203     typedef JitHashTable<GenTree*, JitPtrKeyFuncs<GenTree>, IL_OFFSETX> CallSiteILOffsetTable;
7204     CallSiteILOffsetTable* genCallSite2ILOffsetMap;
7205
7206     unsigned    genReturnLocal; // Local number for the return value when applicable.
7207     BasicBlock* genReturnBB;    // jumped to when not optimizing for speed.
7208
7209     // The following properties are part of CodeGenContext.  Getters are provided here for
7210     // convenience and backward compatibility, but the properties can only be set by invoking
7211     // the setter on CodeGenContext directly.
7212
7213     __declspec(property(get = getEmitter)) emitter* genEmitter;
7214     emitter* getEmitter()
7215     {
7216         return codeGen->getEmitter();
7217     }
7218
7219     bool isFramePointerUsed()
7220     {
7221         return codeGen->isFramePointerUsed();
7222     }
7223
7224     __declspec(property(get = getInterruptible, put = setInterruptible)) bool genInterruptible;
7225     bool getInterruptible()
7226     {
7227         return codeGen->genInterruptible;
7228     }
7229     void setInterruptible(bool value)
7230     {
7231         codeGen->setInterruptible(value);
7232     }
7233
7234 #ifdef _TARGET_ARMARCH_
7235     __declspec(property(get = getHasTailCalls, put = setHasTailCalls)) bool hasTailCalls;
7236     bool getHasTailCalls()
7237     {
7238         return codeGen->hasTailCalls;
7239     }
7240     void setHasTailCalls(bool value)
7241     {
7242         codeGen->setHasTailCalls(value);
7243     }
7244 #endif // _TARGET_ARMARCH_
7245
7246 #if DOUBLE_ALIGN
7247     const bool genDoubleAlign()
7248     {
7249         return codeGen->doDoubleAlign();
7250     }
7251     DWORD getCanDoubleAlign();
7252     bool shouldDoubleAlign(unsigned refCntStk,
7253                            unsigned refCntReg,
7254                            unsigned refCntWtdReg,
7255                            unsigned refCntStkParam,
7256                            unsigned refCntWtdStkDbl);
7257 #endif // DOUBLE_ALIGN
7258
7259     __declspec(property(get = getFullPtrRegMap, put = setFullPtrRegMap)) bool genFullPtrRegMap;
7260     bool getFullPtrRegMap()
7261     {
7262         return codeGen->genFullPtrRegMap;
7263     }
7264     void setFullPtrRegMap(bool value)
7265     {
7266         codeGen->setFullPtrRegMap(value);
7267     }
7268
7269 // Things that MAY belong either in CodeGen or CodeGenContext
7270
7271 #if FEATURE_EH_FUNCLETS
7272     FuncInfoDsc*   compFuncInfos;
7273     unsigned short compCurrFuncIdx;
7274     unsigned short compFuncInfoCount;
7275
7276     unsigned short compFuncCount()
7277     {
7278         assert(fgFuncletsCreated);
7279         return compFuncInfoCount;
7280     }
7281
7282 #else // !FEATURE_EH_FUNCLETS
7283
7284     // This is a no-op when there are no funclets!
7285     void genUpdateCurrentFunclet(BasicBlock* block)
7286     {
7287         return;
7288     }
7289
7290     FuncInfoDsc compFuncInfoRoot;
7291
7292     static const unsigned compCurrFuncIdx = 0;
7293
7294     unsigned short compFuncCount()
7295     {
7296         return 1;
7297     }
7298
7299 #endif // !FEATURE_EH_FUNCLETS
7300
7301     FuncInfoDsc* funCurrentFunc();
7302     void funSetCurrentFunc(unsigned funcIdx);
7303     FuncInfoDsc* funGetFunc(unsigned funcIdx);
7304     unsigned int funGetFuncIdx(BasicBlock* block);
7305
7306     // LIVENESS
7307
7308     VARSET_TP compCurLife;     // current live variables
7309     GenTree*  compCurLifeTree; // node after which compCurLife has been computed
7310
7311     template <bool ForCodeGen>
7312     void compChangeLife(VARSET_VALARG_TP newLife);
7313
7314     void genChangeLife(VARSET_VALARG_TP newLife)
7315     {
7316         compChangeLife</*ForCodeGen*/ true>(newLife);
7317     }
7318
7319     template <bool ForCodeGen>
7320     inline void compUpdateLife(VARSET_VALARG_TP newLife);
7321
7322     // Gets a register mask that represent the kill set for a helper call since
7323     // not all JIT Helper calls follow the standard ABI on the target architecture.
7324     regMaskTP compHelperCallKillSet(CorInfoHelpFunc helper);
7325
7326     // Gets a register mask that represent the kill set for a NoGC helper call.
7327     regMaskTP compNoGCHelperCallKillSet(CorInfoHelpFunc helper);
7328
7329 #ifdef _TARGET_ARM_
7330     // Requires that "varDsc" be a promoted struct local variable being passed as an argument, beginning at
7331     // "firstArgRegNum", which is assumed to have already been aligned to the register alignment restriction of the
7332     // struct type. Adds bits to "*pArgSkippedRegMask" for any argument registers *not* used in passing "varDsc" --
7333     // i.e., internal "holes" caused by internal alignment constraints.  For example, if the struct contained an int and
7334     // a double, and we at R0 (on ARM), then R1 would be skipped, and the bit for R1 would be added to the mask.
7335     void fgAddSkippedRegsInPromotedStructArg(LclVarDsc* varDsc, unsigned firstArgRegNum, regMaskTP* pArgSkippedRegMask);
7336 #endif // _TARGET_ARM_
7337
7338     // If "tree" is a indirection (GT_IND, or GT_OBJ) whose arg is an ADDR, whose arg is a LCL_VAR, return that LCL_VAR
7339     // node, else NULL.
7340     static GenTree* fgIsIndirOfAddrOfLocal(GenTree* tree);
7341
7342     // This map is indexed by GT_OBJ nodes that are address of promoted struct variables, which
7343     // have been annotated with the GTF_VAR_DEATH flag.  If such a node is *not* mapped in this
7344     // table, one may assume that all the (tracked) field vars die at this GT_OBJ.  Otherwise,
7345     // the node maps to a pointer to a VARSET_TP, containing set bits for each of the tracked field
7346     // vars of the promoted struct local that go dead at the given node (the set bits are the bits
7347     // for the tracked var indices of the field vars, as in a live var set).
7348     //
7349     // The map is allocated on demand so all map operations should use one of the following three
7350     // wrapper methods.
7351
7352     NodeToVarsetPtrMap* m_promotedStructDeathVars;
7353
7354     NodeToVarsetPtrMap* GetPromotedStructDeathVars()
7355     {
7356         if (m_promotedStructDeathVars == nullptr)
7357         {
7358             m_promotedStructDeathVars = new (getAllocator()) NodeToVarsetPtrMap(getAllocator());
7359         }
7360         return m_promotedStructDeathVars;
7361     }
7362
7363     void ClearPromotedStructDeathVars()
7364     {
7365         if (m_promotedStructDeathVars != nullptr)
7366         {
7367             m_promotedStructDeathVars->RemoveAll();
7368         }
7369     }
7370
7371     bool LookupPromotedStructDeathVars(GenTree* tree, VARSET_TP** bits)
7372     {
7373         bits        = nullptr;
7374         bool result = false;
7375
7376         if (m_promotedStructDeathVars != nullptr)
7377         {
7378             result = m_promotedStructDeathVars->Lookup(tree, bits);
7379         }
7380
7381         return result;
7382     }
7383
7384 /*
7385 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7386 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7387 XX                                                                           XX
7388 XX                           UnwindInfo                                      XX
7389 XX                                                                           XX
7390 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7391 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7392 */
7393
7394 #if !defined(__GNUC__)
7395 #pragma region Unwind information
7396 #endif
7397
7398 public:
7399     //
7400     // Infrastructure functions: start/stop/reserve/emit.
7401     //
7402
7403     void unwindBegProlog();
7404     void unwindEndProlog();
7405     void unwindBegEpilog();
7406     void unwindEndEpilog();
7407     void unwindReserve();
7408     void unwindEmit(void* pHotCode, void* pColdCode);
7409
7410     //
7411     // Specific unwind information functions: called by code generation to indicate a particular
7412     // prolog or epilog unwindable instruction has been generated.
7413     //
7414
7415     void unwindPush(regNumber reg);
7416     void unwindAllocStack(unsigned size);
7417     void unwindSetFrameReg(regNumber reg, unsigned offset);
7418     void unwindSaveReg(regNumber reg, unsigned offset);
7419
7420 #if defined(_TARGET_ARM_)
7421     void unwindPushMaskInt(regMaskTP mask);
7422     void unwindPushMaskFloat(regMaskTP mask);
7423     void unwindPopMaskInt(regMaskTP mask);
7424     void unwindPopMaskFloat(regMaskTP mask);
7425     void unwindBranch16();                    // The epilog terminates with a 16-bit branch (e.g., "bx lr")
7426     void unwindNop(unsigned codeSizeInBytes); // Generate unwind NOP code. 'codeSizeInBytes' is 2 or 4 bytes. Only
7427                                               // called via unwindPadding().
7428     void unwindPadding(); // Generate a sequence of unwind NOP codes representing instructions between the last
7429                           // instruction and the current location.
7430 #endif                    // _TARGET_ARM_
7431
7432 #if defined(_TARGET_ARM64_)
7433     void unwindNop();
7434     void unwindPadding(); // Generate a sequence of unwind NOP codes representing instructions between the last
7435                           // instruction and the current location.
7436     void unwindSaveReg(regNumber reg, int offset);                                // str reg, [sp, #offset]
7437     void unwindSaveRegPreindexed(regNumber reg, int offset);                      // str reg, [sp, #offset]!
7438     void unwindSaveRegPair(regNumber reg1, regNumber reg2, int offset);           // stp reg1, reg2, [sp, #offset]
7439     void unwindSaveRegPairPreindexed(regNumber reg1, regNumber reg2, int offset); // stp reg1, reg2, [sp, #offset]!
7440     void unwindSaveNext();                                                        // unwind code: save_next
7441     void unwindReturn(regNumber reg);                                             // ret lr
7442 #endif                                                                            // defined(_TARGET_ARM64_)
7443
7444     //
7445     // Private "helper" functions for the unwind implementation.
7446     //
7447
7448 private:
7449 #if FEATURE_EH_FUNCLETS
7450     void unwindGetFuncLocations(FuncInfoDsc*             func,
7451                                 bool                     getHotSectionData,
7452                                 /* OUT */ emitLocation** ppStartLoc,
7453                                 /* OUT */ emitLocation** ppEndLoc);
7454 #endif // FEATURE_EH_FUNCLETS
7455
7456     void unwindReserveFunc(FuncInfoDsc* func);
7457     void unwindEmitFunc(FuncInfoDsc* func, void* pHotCode, void* pColdCode);
7458
7459 #if defined(_TARGET_AMD64_) || (defined(_TARGET_X86_) && FEATURE_EH_FUNCLETS)
7460
7461     void unwindReserveFuncHelper(FuncInfoDsc* func, bool isHotCode);
7462     void unwindEmitFuncHelper(FuncInfoDsc* func, void* pHotCode, void* pColdCode, bool isHotCode);
7463
7464 #endif // _TARGET_AMD64_ || (_TARGET_X86_ && FEATURE_EH_FUNCLETS)
7465
7466     UNATIVE_OFFSET unwindGetCurrentOffset(FuncInfoDsc* func);
7467
7468 #if defined(_TARGET_AMD64_)
7469
7470     void unwindBegPrologWindows();
7471     void unwindPushWindows(regNumber reg);
7472     void unwindAllocStackWindows(unsigned size);
7473     void unwindSetFrameRegWindows(regNumber reg, unsigned offset);
7474     void unwindSaveRegWindows(regNumber reg, unsigned offset);
7475
7476 #ifdef UNIX_AMD64_ABI
7477     void unwindSaveRegCFI(regNumber reg, unsigned offset);
7478 #endif // UNIX_AMD64_ABI
7479 #elif defined(_TARGET_ARM_)
7480
7481     void unwindPushPopMaskInt(regMaskTP mask, bool useOpsize16);
7482     void unwindPushPopMaskFloat(regMaskTP mask);
7483
7484 #endif // _TARGET_ARM_
7485
7486 #if defined(_TARGET_UNIX_)
7487     int mapRegNumToDwarfReg(regNumber reg);
7488     void createCfiCode(FuncInfoDsc* func, UCHAR codeOffset, UCHAR opcode, USHORT dwarfReg, INT offset = 0);
7489     void unwindPushPopCFI(regNumber reg);
7490     void unwindBegPrologCFI();
7491     void unwindPushPopMaskCFI(regMaskTP regMask, bool isFloat);
7492     void unwindAllocStackCFI(unsigned size);
7493     void unwindSetFrameRegCFI(regNumber reg, unsigned offset);
7494     void unwindEmitFuncCFI(FuncInfoDsc* func, void* pHotCode, void* pColdCode);
7495 #ifdef DEBUG
7496     void DumpCfiInfo(bool                  isHotCode,
7497                      UNATIVE_OFFSET        startOffset,
7498                      UNATIVE_OFFSET        endOffset,
7499                      DWORD                 cfiCodeBytes,
7500                      const CFI_CODE* const pCfiCode);
7501 #endif
7502
7503 #endif // _TARGET_UNIX_
7504
7505 #if !defined(__GNUC__)
7506 #pragma endregion // Note: region is NOT under !defined(__GNUC__)
7507 #endif
7508
7509     /*
7510     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7511     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7512     XX                                                                           XX
7513     XX                               SIMD                                        XX
7514     XX                                                                           XX
7515     XX   Info about SIMD types, methods and the SIMD assembly (i.e. the assembly XX
7516     XX   that contains the distinguished, well-known SIMD type definitions).     XX
7517     XX                                                                           XX
7518     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7519     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7520     */
7521
7522     // Get highest available level for SIMD codegen
7523     SIMDLevel getSIMDSupportLevel()
7524     {
7525 #if defined(_TARGET_XARCH_)
7526         if (compSupports(InstructionSet_AVX2))
7527         {
7528             return SIMD_AVX2_Supported;
7529         }
7530
7531         if (compSupports(InstructionSet_SSE42))
7532         {
7533             return SIMD_SSE4_Supported;
7534         }
7535
7536         // min bar is SSE2
7537         return SIMD_SSE2_Supported;
7538 #else
7539         assert(!"Available instruction set(s) for SIMD codegen is not defined for target arch");
7540         unreached();
7541         return SIMD_Not_Supported;
7542 #endif
7543     }
7544
7545 #ifdef FEATURE_SIMD
7546
7547     // Should we support SIMD intrinsics?
7548     bool featureSIMD;
7549
7550     // Have we identified any SIMD types?
7551     // This is currently used by struct promotion to avoid getting type information for a struct
7552     // field to see if it is a SIMD type, if we haven't seen any SIMD types or operations in
7553     // the method.
7554     bool _usesSIMDTypes;
7555     bool usesSIMDTypes()
7556     {
7557         return _usesSIMDTypes;
7558     }
7559     void setUsesSIMDTypes(bool value)
7560     {
7561         _usesSIMDTypes = value;
7562     }
7563
7564     // This is a temp lclVar allocated on the stack as TYP_SIMD.  It is used to implement intrinsics
7565     // that require indexed access to the individual fields of the vector, which is not well supported
7566     // by the hardware.  It is allocated when/if such situations are encountered during Lowering.
7567     unsigned lvaSIMDInitTempVarNum;
7568
7569     struct SIMDHandlesCache
7570     {
7571         // SIMD Types
7572         CORINFO_CLASS_HANDLE SIMDFloatHandle;
7573         CORINFO_CLASS_HANDLE SIMDDoubleHandle;
7574         CORINFO_CLASS_HANDLE SIMDIntHandle;
7575         CORINFO_CLASS_HANDLE SIMDUShortHandle;
7576         CORINFO_CLASS_HANDLE SIMDUByteHandle;
7577         CORINFO_CLASS_HANDLE SIMDShortHandle;
7578         CORINFO_CLASS_HANDLE SIMDByteHandle;
7579         CORINFO_CLASS_HANDLE SIMDLongHandle;
7580         CORINFO_CLASS_HANDLE SIMDUIntHandle;
7581         CORINFO_CLASS_HANDLE SIMDULongHandle;
7582         CORINFO_CLASS_HANDLE SIMDVector2Handle;
7583         CORINFO_CLASS_HANDLE SIMDVector3Handle;
7584         CORINFO_CLASS_HANDLE SIMDVector4Handle;
7585         CORINFO_CLASS_HANDLE SIMDVectorHandle;
7586
7587 #ifdef FEATURE_HW_INTRINSICS
7588 #if defined(_TARGET_ARM64_)
7589         CORINFO_CLASS_HANDLE Vector64FloatHandle;
7590         CORINFO_CLASS_HANDLE Vector64IntHandle;
7591         CORINFO_CLASS_HANDLE Vector64UShortHandle;
7592         CORINFO_CLASS_HANDLE Vector64UByteHandle;
7593         CORINFO_CLASS_HANDLE Vector64ShortHandle;
7594         CORINFO_CLASS_HANDLE Vector64ByteHandle;
7595         CORINFO_CLASS_HANDLE Vector64UIntHandle;
7596 #endif // defined(_TARGET_ARM64_)
7597         CORINFO_CLASS_HANDLE Vector128FloatHandle;
7598         CORINFO_CLASS_HANDLE Vector128DoubleHandle;
7599         CORINFO_CLASS_HANDLE Vector128IntHandle;
7600         CORINFO_CLASS_HANDLE Vector128UShortHandle;
7601         CORINFO_CLASS_HANDLE Vector128UByteHandle;
7602         CORINFO_CLASS_HANDLE Vector128ShortHandle;
7603         CORINFO_CLASS_HANDLE Vector128ByteHandle;
7604         CORINFO_CLASS_HANDLE Vector128LongHandle;
7605         CORINFO_CLASS_HANDLE Vector128UIntHandle;
7606         CORINFO_CLASS_HANDLE Vector128ULongHandle;
7607 #if defined(_TARGET_XARCH_)
7608         CORINFO_CLASS_HANDLE Vector256FloatHandle;
7609         CORINFO_CLASS_HANDLE Vector256DoubleHandle;
7610         CORINFO_CLASS_HANDLE Vector256IntHandle;
7611         CORINFO_CLASS_HANDLE Vector256UShortHandle;
7612         CORINFO_CLASS_HANDLE Vector256UByteHandle;
7613         CORINFO_CLASS_HANDLE Vector256ShortHandle;
7614         CORINFO_CLASS_HANDLE Vector256ByteHandle;
7615         CORINFO_CLASS_HANDLE Vector256LongHandle;
7616         CORINFO_CLASS_HANDLE Vector256UIntHandle;
7617         CORINFO_CLASS_HANDLE Vector256ULongHandle;
7618 #endif // defined(_TARGET_XARCH_)
7619 #endif // FEATURE_HW_INTRINSICS
7620
7621         SIMDHandlesCache()
7622         {
7623             memset(this, 0, sizeof(*this));
7624         }
7625     };
7626
7627     SIMDHandlesCache* m_simdHandleCache;
7628
7629     // Get an appropriate "zero" for the given type and class handle.
7630     GenTree* gtGetSIMDZero(var_types simdType, var_types baseType, CORINFO_CLASS_HANDLE simdHandle);
7631
7632     // Get the handle for a SIMD type.
7633     CORINFO_CLASS_HANDLE gtGetStructHandleForSIMD(var_types simdType, var_types simdBaseType)
7634     {
7635         if (m_simdHandleCache == nullptr)
7636         {
7637             // This may happen if the JIT generates SIMD node on its own, without importing them.
7638             // Otherwise getBaseTypeAndSizeOfSIMDType should have created the cache.
7639             return NO_CLASS_HANDLE;
7640         }
7641
7642         if (simdBaseType == TYP_FLOAT)
7643         {
7644             switch (simdType)
7645             {
7646                 case TYP_SIMD8:
7647                     return m_simdHandleCache->SIMDVector2Handle;
7648                 case TYP_SIMD12:
7649                     return m_simdHandleCache->SIMDVector3Handle;
7650                 case TYP_SIMD16:
7651                     if ((getSIMDVectorType() == TYP_SIMD32) ||
7652                         (m_simdHandleCache->SIMDVector4Handle != NO_CLASS_HANDLE))
7653                     {
7654                         return m_simdHandleCache->SIMDVector4Handle;
7655                     }
7656                     break;
7657                 case TYP_SIMD32:
7658                     break;
7659                 default:
7660                     unreached();
7661             }
7662         }
7663         assert(emitTypeSize(simdType) <= maxSIMDStructBytes());
7664         switch (simdBaseType)
7665         {
7666             case TYP_FLOAT:
7667                 return m_simdHandleCache->SIMDFloatHandle;
7668             case TYP_DOUBLE:
7669                 return m_simdHandleCache->SIMDDoubleHandle;
7670             case TYP_INT:
7671                 return m_simdHandleCache->SIMDIntHandle;
7672             case TYP_USHORT:
7673                 return m_simdHandleCache->SIMDUShortHandle;
7674             case TYP_UBYTE:
7675                 return m_simdHandleCache->SIMDUByteHandle;
7676             case TYP_SHORT:
7677                 return m_simdHandleCache->SIMDShortHandle;
7678             case TYP_BYTE:
7679                 return m_simdHandleCache->SIMDByteHandle;
7680             case TYP_LONG:
7681                 return m_simdHandleCache->SIMDLongHandle;
7682             case TYP_UINT:
7683                 return m_simdHandleCache->SIMDUIntHandle;
7684             case TYP_ULONG:
7685                 return m_simdHandleCache->SIMDULongHandle;
7686             default:
7687                 assert(!"Didn't find a class handle for simdType");
7688         }
7689         return NO_CLASS_HANDLE;
7690     }
7691
7692     // Returns true if this is a SIMD type that should be considered an opaque
7693     // vector type (i.e. do not analyze or promote its fields).
7694     // Note that all but the fixed vector types are opaque, even though they may
7695     // actually be declared as having fields.
7696     bool isOpaqueSIMDType(CORINFO_CLASS_HANDLE structHandle)
7697     {
7698         return ((m_simdHandleCache != nullptr) && (structHandle != m_simdHandleCache->SIMDVector2Handle) &&
7699                 (structHandle != m_simdHandleCache->SIMDVector3Handle) &&
7700                 (structHandle != m_simdHandleCache->SIMDVector4Handle));
7701     }
7702
7703     // Returns true if the tree corresponds to a TYP_SIMD lcl var.
7704     // Note that both SIMD vector args and locals are mared as lvSIMDType = true, but
7705     // type of an arg node is TYP_BYREF and a local node is TYP_SIMD or TYP_STRUCT.
7706     bool isSIMDTypeLocal(GenTree* tree)
7707     {
7708         return tree->OperIsLocal() && lvaTable[tree->AsLclVarCommon()->gtLclNum].lvSIMDType;
7709     }
7710
7711     // Returns true if the lclVar is an opaque SIMD type.
7712     bool isOpaqueSIMDLclVar(LclVarDsc* varDsc)
7713     {
7714         if (!varDsc->lvSIMDType)
7715         {
7716             return false;
7717         }
7718         return isOpaqueSIMDType(varDsc->lvVerTypeInfo.GetClassHandle());
7719     }
7720
7721     // Returns true if the type of the tree is a byref of TYP_SIMD
7722     bool isAddrOfSIMDType(GenTree* tree)
7723     {
7724         if (tree->TypeGet() == TYP_BYREF || tree->TypeGet() == TYP_I_IMPL)
7725         {
7726             switch (tree->OperGet())
7727             {
7728                 case GT_ADDR:
7729                     return varTypeIsSIMD(tree->gtGetOp1());
7730
7731                 case GT_LCL_VAR_ADDR:
7732                     return lvaTable[tree->AsLclVarCommon()->gtLclNum].lvSIMDType;
7733
7734                 default:
7735                     return isSIMDTypeLocal(tree);
7736             }
7737         }
7738
7739         return false;
7740     }
7741
7742     static bool isRelOpSIMDIntrinsic(SIMDIntrinsicID intrinsicId)
7743     {
7744         return (intrinsicId == SIMDIntrinsicEqual || intrinsicId == SIMDIntrinsicLessThan ||
7745                 intrinsicId == SIMDIntrinsicLessThanOrEqual || intrinsicId == SIMDIntrinsicGreaterThan ||
7746                 intrinsicId == SIMDIntrinsicGreaterThanOrEqual);
7747     }
7748
7749     // Returns base type of a TYP_SIMD local.
7750     // Returns TYP_UNKNOWN if the local is not TYP_SIMD.
7751     var_types getBaseTypeOfSIMDLocal(GenTree* tree)
7752     {
7753         if (isSIMDTypeLocal(tree))
7754         {
7755             return lvaTable[tree->AsLclVarCommon()->gtLclNum].lvBaseType;
7756         }
7757
7758         return TYP_UNKNOWN;
7759     }
7760
7761     bool isSIMDClass(CORINFO_CLASS_HANDLE clsHnd)
7762     {
7763         return info.compCompHnd->isInSIMDModule(clsHnd);
7764     }
7765
7766     bool isIntrinsicType(CORINFO_CLASS_HANDLE clsHnd)
7767     {
7768         return (info.compCompHnd->getClassAttribs(clsHnd) & CORINFO_FLG_INTRINSIC_TYPE) != 0;
7769     }
7770
7771     const char* getClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, const char** namespaceName)
7772     {
7773         return info.compCompHnd->getClassNameFromMetadata(cls, namespaceName);
7774     }
7775
7776     CORINFO_CLASS_HANDLE getTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, unsigned index)
7777     {
7778         return info.compCompHnd->getTypeInstantiationArgument(cls, index);
7779     }
7780
7781     bool isSIMDClass(typeInfo* pTypeInfo)
7782     {
7783         return pTypeInfo->IsStruct() && isSIMDClass(pTypeInfo->GetClassHandleForValueClass());
7784     }
7785
7786     bool isHWSIMDClass(CORINFO_CLASS_HANDLE clsHnd)
7787     {
7788 #ifdef FEATURE_HW_INTRINSICS
7789         if (isIntrinsicType(clsHnd))
7790         {
7791             const char* namespaceName = nullptr;
7792             (void)getClassNameFromMetadata(clsHnd, &namespaceName);
7793             return strcmp(namespaceName, "System.Runtime.Intrinsics") == 0;
7794         }
7795 #endif // FEATURE_HW_INTRINSICS
7796         return false;
7797     }
7798
7799     bool isHWSIMDClass(typeInfo* pTypeInfo)
7800     {
7801 #ifdef FEATURE_HW_INTRINSICS
7802         return pTypeInfo->IsStruct() && isHWSIMDClass(pTypeInfo->GetClassHandleForValueClass());
7803 #else
7804         return false;
7805 #endif
7806     }
7807
7808     bool isSIMDorHWSIMDClass(CORINFO_CLASS_HANDLE clsHnd)
7809     {
7810         return isSIMDClass(clsHnd) || isHWSIMDClass(clsHnd);
7811     }
7812
7813     bool isSIMDorHWSIMDClass(typeInfo* pTypeInfo)
7814     {
7815         return isSIMDClass(pTypeInfo) || isHWSIMDClass(pTypeInfo);
7816     }
7817
7818     // Get the base (element) type and size in bytes for a SIMD type. Returns TYP_UNKNOWN
7819     // if it is not a SIMD type or is an unsupported base type.
7820     var_types getBaseTypeAndSizeOfSIMDType(CORINFO_CLASS_HANDLE typeHnd, unsigned* sizeBytes = nullptr);
7821
7822     var_types getBaseTypeOfSIMDType(CORINFO_CLASS_HANDLE typeHnd)
7823     {
7824         return getBaseTypeAndSizeOfSIMDType(typeHnd, nullptr);
7825     }
7826
7827     // Get SIMD Intrinsic info given the method handle.
7828     // Also sets typeHnd, argCount, baseType and sizeBytes out params.
7829     const SIMDIntrinsicInfo* getSIMDIntrinsicInfo(CORINFO_CLASS_HANDLE* typeHnd,
7830                                                   CORINFO_METHOD_HANDLE methodHnd,
7831                                                   CORINFO_SIG_INFO*     sig,
7832                                                   bool                  isNewObj,
7833                                                   unsigned*             argCount,
7834                                                   var_types*            baseType,
7835                                                   unsigned*             sizeBytes);
7836
7837     // Pops and returns GenTree node from importers type stack.
7838     // Normalizes TYP_STRUCT value in case of GT_CALL, GT_RET_EXPR and arg nodes.
7839     GenTree* impSIMDPopStack(var_types type, bool expectAddr = false, CORINFO_CLASS_HANDLE structType = nullptr);
7840
7841     // Create a GT_SIMD tree for a Get property of SIMD vector with a fixed index.
7842     GenTreeSIMD* impSIMDGetFixed(var_types simdType, var_types baseType, unsigned simdSize, int index);
7843
7844     // Creates a GT_SIMD tree for Select operation
7845     GenTree* impSIMDSelect(CORINFO_CLASS_HANDLE typeHnd,
7846                            var_types            baseType,
7847                            unsigned             simdVectorSize,
7848                            GenTree*             op1,
7849                            GenTree*             op2,
7850                            GenTree*             op3);
7851
7852     // Creates a GT_SIMD tree for Min/Max operation
7853     GenTree* impSIMDMinMax(SIMDIntrinsicID      intrinsicId,
7854                            CORINFO_CLASS_HANDLE typeHnd,
7855                            var_types            baseType,
7856                            unsigned             simdVectorSize,
7857                            GenTree*             op1,
7858                            GenTree*             op2);
7859
7860     // Transforms operands and returns the SIMD intrinsic to be applied on
7861     // transformed operands to obtain given relop result.
7862     SIMDIntrinsicID impSIMDRelOp(SIMDIntrinsicID      relOpIntrinsicId,
7863                                  CORINFO_CLASS_HANDLE typeHnd,
7864                                  unsigned             simdVectorSize,
7865                                  var_types*           baseType,
7866                                  GenTree**            op1,
7867                                  GenTree**            op2);
7868
7869     // Creates a GT_SIMD tree for Abs intrinsic.
7870     GenTree* impSIMDAbs(CORINFO_CLASS_HANDLE typeHnd, var_types baseType, unsigned simdVectorSize, GenTree* op1);
7871
7872 #if defined(_TARGET_XARCH_)
7873
7874     // Transforms operands and returns the SIMD intrinsic to be applied on
7875     // transformed operands to obtain == comparison result.
7876     SIMDIntrinsicID impSIMDLongRelOpEqual(CORINFO_CLASS_HANDLE typeHnd,
7877                                           unsigned             simdVectorSize,
7878                                           GenTree**            op1,
7879                                           GenTree**            op2);
7880
7881     // Transforms operands and returns the SIMD intrinsic to be applied on
7882     // transformed operands to obtain > comparison result.
7883     SIMDIntrinsicID impSIMDLongRelOpGreaterThan(CORINFO_CLASS_HANDLE typeHnd,
7884                                                 unsigned             simdVectorSize,
7885                                                 GenTree**            op1,
7886                                                 GenTree**            op2);
7887
7888     // Transforms operands and returns the SIMD intrinsic to be applied on
7889     // transformed operands to obtain >= comparison result.
7890     SIMDIntrinsicID impSIMDLongRelOpGreaterThanOrEqual(CORINFO_CLASS_HANDLE typeHnd,
7891                                                        unsigned             simdVectorSize,
7892                                                        GenTree**            op1,
7893                                                        GenTree**            op2);
7894
7895     // Transforms operands and returns the SIMD intrinsic to be applied on
7896     // transformed operands to obtain >= comparison result in case of int32
7897     // and small int base type vectors.
7898     SIMDIntrinsicID impSIMDIntegralRelOpGreaterThanOrEqual(
7899         CORINFO_CLASS_HANDLE typeHnd, unsigned simdVectorSize, var_types baseType, GenTree** op1, GenTree** op2);
7900
7901 #endif // defined(_TARGET_XARCH_)
7902
7903     void setLclRelatedToSIMDIntrinsic(GenTree* tree);
7904     bool areFieldsContiguous(GenTree* op1, GenTree* op2);
7905     bool areArrayElementsContiguous(GenTree* op1, GenTree* op2);
7906     bool areArgumentsContiguous(GenTree* op1, GenTree* op2);
7907     GenTree* createAddressNodeForSIMDInit(GenTree* tree, unsigned simdSize);
7908
7909     // check methodHnd to see if it is a SIMD method that is expanded as an intrinsic in the JIT.
7910     GenTree* impSIMDIntrinsic(OPCODE                opcode,
7911                               GenTree*              newobjThis,
7912                               CORINFO_CLASS_HANDLE  clsHnd,
7913                               CORINFO_METHOD_HANDLE method,
7914                               CORINFO_SIG_INFO*     sig,
7915                               unsigned              methodFlags,
7916                               int                   memberRef);
7917
7918     GenTree* getOp1ForConstructor(OPCODE opcode, GenTree* newobjThis, CORINFO_CLASS_HANDLE clsHnd);
7919
7920     // Whether SIMD vector occupies part of SIMD register.
7921     // SSE2: vector2f/3f are considered sub register SIMD types.
7922     // AVX: vector2f, 3f and 4f are all considered sub register SIMD types.
7923     bool isSubRegisterSIMDType(CORINFO_CLASS_HANDLE typeHnd)
7924     {
7925         unsigned  sizeBytes = 0;
7926         var_types baseType  = getBaseTypeAndSizeOfSIMDType(typeHnd, &sizeBytes);
7927         return (baseType == TYP_FLOAT) && (sizeBytes < getSIMDVectorRegisterByteLength());
7928     }
7929
7930     bool isSubRegisterSIMDType(GenTreeSIMD* simdNode)
7931     {
7932         return (simdNode->gtSIMDSize < getSIMDVectorRegisterByteLength());
7933     }
7934
7935     // Get the type for the hardware SIMD vector.
7936     // This is the maximum SIMD type supported for this target.
7937     var_types getSIMDVectorType()
7938     {
7939 #if defined(_TARGET_XARCH_)
7940         if (getSIMDSupportLevel() == SIMD_AVX2_Supported)
7941         {
7942             return TYP_SIMD32;
7943         }
7944         else
7945         {
7946             assert(getSIMDSupportLevel() >= SIMD_SSE2_Supported);
7947             return TYP_SIMD16;
7948         }
7949 #elif defined(_TARGET_ARM64_)
7950         return TYP_SIMD16;
7951 #else
7952         assert(!"getSIMDVectorType() unimplemented on target arch");
7953         unreached();
7954 #endif
7955     }
7956
7957     // Get the size of the SIMD type in bytes
7958     int getSIMDTypeSizeInBytes(CORINFO_CLASS_HANDLE typeHnd)
7959     {
7960         unsigned sizeBytes = 0;
7961         (void)getBaseTypeAndSizeOfSIMDType(typeHnd, &sizeBytes);
7962         return sizeBytes;
7963     }
7964
7965     // Get the the number of elements of basetype of SIMD vector given by its size and baseType
7966     static int getSIMDVectorLength(unsigned simdSize, var_types baseType);
7967
7968     // Get the the number of elements of basetype of SIMD vector given by its type handle
7969     int getSIMDVectorLength(CORINFO_CLASS_HANDLE typeHnd);
7970
7971     // Get preferred alignment of SIMD type.
7972     int getSIMDTypeAlignment(var_types simdType);
7973
7974     // Get the number of bytes in a System.Numeric.Vector<T> for the current compilation.
7975     // Note - cannot be used for System.Runtime.Intrinsic
7976     unsigned getSIMDVectorRegisterByteLength()
7977     {
7978 #if defined(_TARGET_XARCH_)
7979         if (getSIMDSupportLevel() == SIMD_AVX2_Supported)
7980         {
7981             return YMM_REGSIZE_BYTES;
7982         }
7983         else
7984         {
7985             assert(getSIMDSupportLevel() >= SIMD_SSE2_Supported);
7986             return XMM_REGSIZE_BYTES;
7987         }
7988 #elif defined(_TARGET_ARM64_)
7989         return FP_REGSIZE_BYTES;
7990 #else
7991         assert(!"getSIMDVectorRegisterByteLength() unimplemented on target arch");
7992         unreached();
7993 #endif
7994     }
7995
7996     // The minimum and maximum possible number of bytes in a SIMD vector.
7997
7998     // maxSIMDStructBytes
7999     // The minimum SIMD size supported by System.Numeric.Vectors or System.Runtime.Intrinsic
8000     // SSE:  16-byte Vector<T> and Vector128<T>
8001     // AVX:  32-byte Vector256<T> (Vector<T> is 16-byte)
8002     // AVX2: 32-byte Vector<T> and Vector256<T>
8003     unsigned int maxSIMDStructBytes()
8004     {
8005 #if defined(FEATURE_HW_INTRINSICS) && defined(_TARGET_XARCH_)
8006         if (compSupports(InstructionSet_AVX))
8007         {
8008             return YMM_REGSIZE_BYTES;
8009         }
8010         else
8011         {
8012             assert(getSIMDSupportLevel() >= SIMD_SSE2_Supported);
8013             return XMM_REGSIZE_BYTES;
8014         }
8015 #else
8016         return getSIMDVectorRegisterByteLength();
8017 #endif
8018     }
8019     unsigned int minSIMDStructBytes()
8020     {
8021         return emitTypeSize(TYP_SIMD8);
8022     }
8023
8024     // Returns the codegen type for a given SIMD size.
8025     var_types getSIMDTypeForSize(unsigned size)
8026     {
8027         var_types simdType = TYP_UNDEF;
8028         if (size == 8)
8029         {
8030             simdType = TYP_SIMD8;
8031         }
8032         else if (size == 12)
8033         {
8034             simdType = TYP_SIMD12;
8035         }
8036         else if (size == 16)
8037         {
8038             simdType = TYP_SIMD16;
8039         }
8040         else if (size == 32)
8041         {
8042             simdType = TYP_SIMD32;
8043         }
8044         else
8045         {
8046             noway_assert(!"Unexpected size for SIMD type");
8047         }
8048         return simdType;
8049     }
8050
8051     unsigned getSIMDInitTempVarNum()
8052     {
8053         if (lvaSIMDInitTempVarNum == BAD_VAR_NUM)
8054         {
8055             lvaSIMDInitTempVarNum                  = lvaGrabTempWithImplicitUse(false DEBUGARG("SIMDInitTempVar"));
8056             lvaTable[lvaSIMDInitTempVarNum].lvType = getSIMDVectorType();
8057         }
8058         return lvaSIMDInitTempVarNum;
8059     }
8060
8061 #else  // !FEATURE_SIMD
8062     bool isOpaqueSIMDLclVar(LclVarDsc* varDsc)
8063     {
8064         return false;
8065     }
8066 #endif // FEATURE_SIMD
8067
8068 public:
8069     //------------------------------------------------------------------------
8070     // largestEnregisterableStruct: The size in bytes of the largest struct that can be enregistered.
8071     //
8072     // Notes: It is not guaranteed that the struct of this size or smaller WILL be a
8073     //        candidate for enregistration.
8074
8075     unsigned largestEnregisterableStructSize()
8076     {
8077 #ifdef FEATURE_SIMD
8078         unsigned vectorRegSize = getSIMDVectorRegisterByteLength();
8079         if (vectorRegSize > TARGET_POINTER_SIZE)
8080         {
8081             return vectorRegSize;
8082         }
8083         else
8084 #endif // FEATURE_SIMD
8085         {
8086             return TARGET_POINTER_SIZE;
8087         }
8088     }
8089
8090 private:
8091     // These routines need not be enclosed under FEATURE_SIMD since lvIsSIMDType()
8092     // is defined for both FEATURE_SIMD and !FEATURE_SIMD apropriately. The use
8093     // of this routines also avoids the need of #ifdef FEATURE_SIMD specific code.
8094
8095     // Is this var is of type simd struct?
8096     bool lclVarIsSIMDType(unsigned varNum)
8097     {
8098         LclVarDsc* varDsc = lvaTable + varNum;
8099         return varDsc->lvIsSIMDType();
8100     }
8101
8102     // Is this Local node a SIMD local?
8103     bool lclVarIsSIMDType(GenTreeLclVarCommon* lclVarTree)
8104     {
8105         return lclVarIsSIMDType(lclVarTree->gtLclNum);
8106     }
8107
8108     // Returns true if the TYP_SIMD locals on stack are aligned at their
8109     // preferred byte boundary specified by getSIMDTypeAlignment().
8110     //
8111     // As per the Intel manual, the preferred alignment for AVX vectors is 32-bytes. On Amd64,
8112     // RSP/EBP is aligned at 16-bytes, therefore to align SIMD types at 32-bytes we need even
8113     // RSP/EBP to be 32-byte aligned. It is not clear whether additional stack space used in
8114     // aligning stack is worth the benefit and for now will use 16-byte alignment for AVX
8115     // 256-bit vectors with unaligned load/stores to/from memory. On x86, the stack frame
8116     // is aligned to 4 bytes. We need to extend existing support for double (8-byte) alignment
8117     // to 16 or 32 byte alignment for frames with local SIMD vars, if that is determined to be
8118     // profitable.
8119     //
8120     bool isSIMDTypeLocalAligned(unsigned varNum)
8121     {
8122 #if defined(FEATURE_SIMD) && ALIGN_SIMD_TYPES
8123         if (lclVarIsSIMDType(varNum) && lvaTable[varNum].lvType != TYP_BYREF)
8124         {
8125             bool ebpBased;
8126             int  off = lvaFrameAddress(varNum, &ebpBased);
8127             // TODO-Cleanup: Can't this use the lvExactSize on the varDsc?
8128             int  alignment = getSIMDTypeAlignment(lvaTable[varNum].lvType);
8129             bool isAligned = (alignment <= STACK_ALIGN) && ((off % alignment) == 0);
8130             return isAligned;
8131         }
8132 #endif // FEATURE_SIMD
8133
8134         return false;
8135     }
8136
8137     bool compSupports(InstructionSet isa) const
8138     {
8139 #if defined(_TARGET_XARCH_) || defined(_TARGET_ARM64_)
8140         return (opts.compSupportsISA & (1ULL << isa)) != 0;
8141 #else
8142         return false;
8143 #endif
8144     }
8145
8146     bool canUseVexEncoding() const
8147     {
8148 #ifdef _TARGET_XARCH_
8149         return compSupports(InstructionSet_AVX);
8150 #else
8151         return false;
8152 #endif
8153     }
8154
8155     /*
8156     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8157     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8158     XX                                                                           XX
8159     XX                           Compiler                                        XX
8160     XX                                                                           XX
8161     XX   Generic info about the compilation and the method being compiled.       XX
8162     XX   It is responsible for driving the other phases.                         XX
8163     XX   It is also responsible for all the memory management.                   XX
8164     XX                                                                           XX
8165     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8166     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8167     */
8168
8169 public:
8170     Compiler* InlineeCompiler; // The Compiler instance for the inlinee
8171
8172     InlineResult* compInlineResult; // The result of importing the inlinee method.
8173
8174     bool compDoAggressiveInlining; // If true, mark every method as CORINFO_FLG_FORCEINLINE
8175     bool compJmpOpUsed;            // Does the method do a JMP
8176     bool compLongUsed;             // Does the method use TYP_LONG
8177     bool compFloatingPointUsed;    // Does the method use TYP_FLOAT or TYP_DOUBLE
8178     bool compTailCallUsed;         // Does the method do a tailcall
8179     bool compLocallocUsed;         // Does the method use localloc.
8180     bool compLocallocOptimized;    // Does the method have an optimized localloc
8181     bool compQmarkUsed;            // Does the method use GT_QMARK/GT_COLON
8182     bool compQmarkRationalized;    // Is it allowed to use a GT_QMARK/GT_COLON node.
8183     bool compUnsafeCastUsed;       // Does the method use LDIND/STIND to cast between scalar/refernce types
8184
8185 // NOTE: These values are only reliable after
8186 //       the importing is completely finished.
8187
8188 #ifdef DEBUG
8189     // State information - which phases have completed?
8190     // These are kept together for easy discoverability
8191
8192     bool    bRangeAllowStress;
8193     bool    compCodeGenDone;
8194     int64_t compNumStatementLinksTraversed; // # of links traversed while doing debug checks
8195     bool    fgNormalizeEHDone;              // Has the flowgraph EH normalization phase been done?
8196     size_t  compSizeEstimate;               // The estimated size of the method as per `gtSetEvalOrder`.
8197     size_t  compCycleEstimate;              // The estimated cycle count of the method as per `gtSetEvalOrder`
8198 #endif                                      // DEBUG
8199
8200     bool fgLocalVarLivenessDone; // Note that this one is used outside of debug.
8201     bool fgLocalVarLivenessChanged;
8202 #if STACK_PROBES
8203     bool compStackProbePrologDone;
8204 #endif
8205     bool compLSRADone;
8206     bool compRationalIRForm;
8207
8208     bool compUsesThrowHelper; // There is a call to a THOROW_HELPER for the compiled method.
8209
8210     bool compGeneratingProlog;
8211     bool compGeneratingEpilog;
8212     bool compNeedsGSSecurityCookie; // There is an unsafe buffer (or localloc) on the stack.
8213                                     // Insert cookie on frame and code to check the cookie, like VC++ -GS.
8214     bool compGSReorderStackLayout;  // There is an unsafe buffer on the stack, reorder locals and make local
8215     // copies of susceptible parameters to avoid buffer overrun attacks through locals/params
8216     bool getNeedsGSSecurityCookie() const
8217     {
8218         return compNeedsGSSecurityCookie;
8219     }
8220     void setNeedsGSSecurityCookie()
8221     {
8222         compNeedsGSSecurityCookie = true;
8223     }
8224
8225     FrameLayoutState lvaDoneFrameLayout; // The highest frame layout state that we've completed. During
8226                                          // frame layout calculations, this is the level we are currently
8227                                          // computing.
8228
8229     //---------------------------- JITing options -----------------------------
8230
8231     enum codeOptimize
8232     {
8233         BLENDED_CODE,
8234         SMALL_CODE,
8235         FAST_CODE,
8236
8237         COUNT_OPT_CODE
8238     };
8239
8240     struct Options
8241     {
8242         JitFlags* jitFlags;  // all flags passed from the EE
8243         unsigned  compFlags; // method attributes
8244
8245         codeOptimize compCodeOpt; // what type of code optimizations
8246
8247         bool compUseFCOMI;
8248         bool compUseCMOV;
8249
8250 #if defined(_TARGET_XARCH_) || defined(_TARGET_ARM64_)
8251         uint64_t compSupportsISA;
8252         void setSupportedISA(InstructionSet isa)
8253         {
8254             compSupportsISA |= 1ULL << isa;
8255         }
8256 #endif
8257
8258 // optimize maximally and/or favor speed over size?
8259
8260 #define DEFAULT_MIN_OPTS_CODE_SIZE 60000
8261 #define DEFAULT_MIN_OPTS_INSTR_COUNT 20000
8262 #define DEFAULT_MIN_OPTS_BB_COUNT 2000
8263 #define DEFAULT_MIN_OPTS_LV_NUM_COUNT 2000
8264 #define DEFAULT_MIN_OPTS_LV_REF_COUNT 8000
8265
8266 // Maximun number of locals before turning off the inlining
8267 #define MAX_LV_NUM_COUNT_FOR_INLINING 512
8268
8269         bool     compMinOpts;
8270         unsigned instrCount;
8271         unsigned lvRefCount;
8272         bool     compMinOptsIsSet;
8273 #ifdef DEBUG
8274         bool compMinOptsIsUsed;
8275
8276         bool MinOpts()
8277         {
8278             assert(compMinOptsIsSet);
8279             compMinOptsIsUsed = true;
8280             return compMinOpts;
8281         }
8282         bool IsMinOptsSet()
8283         {
8284             return compMinOptsIsSet;
8285         }
8286 #else  // !DEBUG
8287         bool MinOpts()
8288         {
8289             return compMinOpts;
8290         }
8291         bool IsMinOptsSet()
8292         {
8293             return compMinOptsIsSet;
8294         }
8295 #endif // !DEBUG
8296
8297         bool OptimizationDisabled()
8298         {
8299             return MinOpts() || compDbgCode;
8300         }
8301         bool OptimizationEnabled()
8302         {
8303             return !OptimizationDisabled();
8304         }
8305
8306         void SetMinOpts(bool val)
8307         {
8308             assert(!compMinOptsIsUsed);
8309             assert(!compMinOptsIsSet || (compMinOpts == val));
8310             compMinOpts      = val;
8311             compMinOptsIsSet = true;
8312         }
8313
8314         // true if the CLFLG_* for an optimization is set.
8315         bool OptEnabled(unsigned optFlag)
8316         {
8317             return !!(compFlags & optFlag);
8318         }
8319
8320 #ifdef FEATURE_READYTORUN_COMPILER
8321         bool IsReadyToRun()
8322         {
8323             return jitFlags->IsSet(JitFlags::JIT_FLAG_READYTORUN);
8324         }
8325 #else
8326         bool IsReadyToRun()
8327         {
8328             return false;
8329         }
8330 #endif
8331
8332         // true if we should use the PINVOKE_{BEGIN,END} helpers instead of generating
8333         // PInvoke transitions inline (e.g. when targeting CoreRT).
8334         bool ShouldUsePInvokeHelpers()
8335         {
8336             return jitFlags->IsSet(JitFlags::JIT_FLAG_USE_PINVOKE_HELPERS);
8337         }
8338
8339         // true if we should use insert the REVERSE_PINVOKE_{ENTER,EXIT} helpers in the method
8340         // prolog/epilog
8341         bool IsReversePInvoke()
8342         {
8343             return jitFlags->IsSet(JitFlags::JIT_FLAG_REVERSE_PINVOKE);
8344         }
8345
8346         // true if we must generate code compatible with JIT32 quirks
8347         bool IsJit32Compat()
8348         {
8349 #if defined(_TARGET_X86_)
8350             return jitFlags->IsSet(JitFlags::JIT_FLAG_DESKTOP_QUIRKS);
8351 #else
8352             return false;
8353 #endif
8354         }
8355
8356         // true if we must generate code compatible with Jit64 quirks
8357         bool IsJit64Compat()
8358         {
8359 #if defined(_TARGET_AMD64_)
8360             return jitFlags->IsSet(JitFlags::JIT_FLAG_DESKTOP_QUIRKS);
8361 #elif !defined(FEATURE_CORECLR)
8362             return true;
8363 #else
8364             return false;
8365 #endif
8366         }
8367
8368         bool compScopeInfo; // Generate the LocalVar info ?
8369         bool compDbgCode;   // Generate debugger-friendly code?
8370         bool compDbgInfo;   // Gather debugging info?
8371         bool compDbgEnC;
8372
8373 #ifdef PROFILING_SUPPORTED
8374         bool compNoPInvokeInlineCB;
8375 #else
8376         static const bool compNoPInvokeInlineCB;
8377 #endif
8378
8379 #ifdef DEBUG
8380         bool compGcChecks; // Check arguments and return values to ensure they are sane
8381 #endif
8382
8383 #if defined(DEBUG) && defined(_TARGET_XARCH_)
8384
8385         bool compStackCheckOnRet; // Check stack pointer on return to ensure it is correct.
8386
8387 #endif // defined(DEBUG) && defined(_TARGET_XARCH_)
8388
8389 #if defined(DEBUG) && defined(_TARGET_X86_)
8390
8391         bool compStackCheckOnCall; // Check stack pointer after call to ensure it is correct. Only for x86.
8392
8393 #endif // defined(DEBUG) && defined(_TARGET_X86_)
8394
8395         bool compNeedSecurityCheck; // This flag really means where or not a security object needs
8396                                     // to be allocated on the stack.
8397                                     // It will be set to true in the following cases:
8398                                     //   1. When the method being compiled has a declarative security
8399                                     //        (i.e. when CORINFO_FLG_NOSECURITYWRAP is reset for the current method).
8400                                     //        This is also the case when we inject a prolog and epilog in the method.
8401                                     //   (or)
8402                                     //   2. When the method being compiled has imperative security (i.e. the method
8403                                     //        calls into another method that has CORINFO_FLG_SECURITYCHECK flag set).
8404                                     //   (or)
8405                                     //   3. When opts.compDbgEnC is true. (See also Compiler::compCompile).
8406                                     //
8407         // When this flag is set, jit will allocate a gc-reference local variable (lvaSecurityObject),
8408         // which gets reported as a GC root to stackwalker.
8409         // (See also ICodeManager::GetAddrOfSecurityObject.)
8410
8411         bool compReloc; // Generate relocs for pointers in code, true for all ngen/prejit codegen
8412
8413 #ifdef DEBUG
8414 #if defined(_TARGET_XARCH_)
8415         bool compEnablePCRelAddr; // Whether absolute addr be encoded as PC-rel offset by RyuJIT where possible
8416 #endif
8417 #endif // DEBUG
8418
8419 #ifdef UNIX_AMD64_ABI
8420         // This flag  is indicating if there is a need to align the frame.
8421         // On AMD64-Windows, if there are calls, 4 slots for the outgoing ars are allocated, except for
8422         // FastTailCall. This slots makes the frame size non-zero, so alignment logic will be called.
8423         // On AMD64-Unix, there are no such slots. There is a possibility to have calls in the method with frame size of
8424         // 0. The frame alignment logic won't kick in. This flags takes care of the AMD64-Unix case by remembering that
8425         // there are calls and making sure the frame alignment logic is executed.
8426         bool compNeedToAlignFrame;
8427 #endif // UNIX_AMD64_ABI
8428
8429         bool compProcedureSplitting; // Separate cold code from hot code
8430
8431         bool genFPorder; // Preserve FP order (operations are non-commutative)
8432         bool genFPopt;   // Can we do frame-pointer-omission optimization?
8433         bool altJit;     // True if we are an altjit and are compiling this method
8434
8435 #ifdef OPT_CONFIG
8436         bool optRepeat; // Repeat optimizer phases k times
8437 #endif
8438
8439 #ifdef DEBUG
8440         bool compProcedureSplittingEH; // Separate cold code from hot code for functions with EH
8441         bool dspCode;                  // Display native code generated
8442         bool dspEHTable;               // Display the EH table reported to the VM
8443         bool dspDebugInfo;             // Display the Debug info reported to the VM
8444         bool dspInstrs;                // Display the IL instructions intermixed with the native code output
8445         bool dspEmit;                  // Display emitter output
8446         bool dspLines;                 // Display source-code lines intermixed with native code output
8447         bool dmpHex;                   // Display raw bytes in hex of native code output
8448         bool varNames;                 // Display variables names in native code output
8449         bool disAsm;                   // Display native code as it is generated
8450         bool disAsmSpilled;            // Display native code when any register spilling occurs
8451         bool disDiffable;              // Makes the Disassembly code 'diff-able'
8452         bool disAsm2;                  // Display native code after it is generated using external disassembler
8453         bool dspOrder;                 // Display names of each of the methods that we ngen/jit
8454         bool dspUnwind;                // Display the unwind info output
8455         bool dspDiffable;     // Makes the Jit Dump 'diff-able' (currently uses same COMPlus_* flag as disDiffable)
8456         bool compLongAddress; // Force using large pseudo instructions for long address
8457                               // (IF_LARGEJMP/IF_LARGEADR/IF_LARGLDC)
8458         bool dspGCtbls;       // Display the GC tables
8459 #endif
8460
8461 #ifdef LATE_DISASM
8462         bool doLateDisasm; // Run the late disassembler
8463 #endif                     // LATE_DISASM
8464
8465 #if DUMP_GC_TABLES && !defined(DEBUG) && defined(JIT32_GCENCODER)
8466 // Only the JIT32_GCENCODER implements GC dumping in non-DEBUG code.
8467 #pragma message("NOTE: this non-debug build has GC ptr table dumping always enabled!")
8468         static const bool dspGCtbls = true;
8469 #endif
8470
8471         // We need stack probes to guarantee that we won't trigger a stack overflow
8472         // when calling unmanaged code until they get a chance to set up a frame, because
8473         // the EE will have no idea where it is.
8474         //
8475         // We will only be doing this currently for hosted environments. Unfortunately
8476         // we need to take care of stubs, so potentially, we will have to do the probes
8477         // for any call. We have a plan for not needing for stubs though
8478         bool compNeedStackProbes;
8479
8480 #ifdef PROFILING_SUPPORTED
8481         // Whether to emit Enter/Leave/TailCall hooks using a dummy stub (DummyProfilerELTStub()).
8482         // This option helps make the JIT behave as if it is running under a profiler.
8483         bool compJitELTHookEnabled;
8484 #endif // PROFILING_SUPPORTED
8485
8486 #if FEATURE_TAILCALL_OPT
8487         // Whether opportunistic or implicit tail call optimization is enabled.
8488         bool compTailCallOpt;
8489         // Whether optimization of transforming a recursive tail call into a loop is enabled.
8490         bool compTailCallLoopOpt;
8491 #endif
8492
8493 #ifdef ARM_SOFTFP
8494         static const bool compUseSoftFP = true;
8495 #else // !ARM_SOFTFP
8496         static const bool compUseSoftFP = false;
8497 #endif
8498
8499         GCPollType compGCPollType;
8500     } opts;
8501
8502 #ifdef ALT_JIT
8503     static bool                s_pAltJitExcludeAssembliesListInitialized;
8504     static AssemblyNamesList2* s_pAltJitExcludeAssembliesList;
8505 #endif // ALT_JIT
8506
8507 #ifdef DEBUG
8508     static bool                s_pJitDisasmIncludeAssembliesListInitialized;
8509     static AssemblyNamesList2* s_pJitDisasmIncludeAssembliesList;
8510 #endif // DEBUG
8511
8512 #ifdef DEBUG
8513 // silence warning of cast to greater size. It is easier to silence than construct code the compiler is happy with, and
8514 // it is safe in this case
8515 #pragma warning(push)
8516 #pragma warning(disable : 4312)
8517
8518     template <typename T>
8519     T dspPtr(T p)
8520     {
8521         return (p == ZERO) ? ZERO : (opts.dspDiffable ? T(0xD1FFAB1E) : p);
8522     }
8523
8524     template <typename T>
8525     T dspOffset(T o)
8526     {
8527         return (o == ZERO) ? ZERO : (opts.dspDiffable ? T(0xD1FFAB1E) : o);
8528     }
8529 #pragma warning(pop)
8530
8531     static int dspTreeID(GenTree* tree)
8532     {
8533         return tree->gtTreeID;
8534     }
8535     static void printTreeID(GenTree* tree)
8536     {
8537         if (tree == nullptr)
8538         {
8539             printf("[------]");
8540         }
8541         else
8542         {
8543             printf("[%06d]", dspTreeID(tree));
8544         }
8545     }
8546
8547 #endif // DEBUG
8548
8549 // clang-format off
8550 #define STRESS_MODES                                                                            \
8551                                                                                                 \
8552         STRESS_MODE(NONE)                                                                       \
8553                                                                                                 \
8554         /* "Variations" stress areas which we try to mix up with each other. */                 \
8555         /* These should not be exhaustively used as they might */                               \
8556         /* hide/trivialize other areas */                                                       \
8557                                                                                                 \
8558         STRESS_MODE(REGS)                                                                       \
8559         STRESS_MODE(DBL_ALN)                                                                    \
8560         STRESS_MODE(LCL_FLDS)                                                                   \
8561         STRESS_MODE(UNROLL_LOOPS)                                                               \
8562         STRESS_MODE(MAKE_CSE)                                                                   \
8563         STRESS_MODE(LEGACY_INLINE)                                                              \
8564         STRESS_MODE(CLONE_EXPR)                                                                 \
8565         STRESS_MODE(USE_FCOMI)                                                                  \
8566         STRESS_MODE(USE_CMOV)                                                                   \
8567         STRESS_MODE(FOLD)                                                                       \
8568         STRESS_MODE(BB_PROFILE)                                                                 \
8569         STRESS_MODE(OPT_BOOLS_GC)                                                               \
8570         STRESS_MODE(REMORPH_TREES)                                                              \
8571         STRESS_MODE(64RSLT_MUL)                                                                 \
8572         STRESS_MODE(DO_WHILE_LOOPS)                                                             \
8573         STRESS_MODE(MIN_OPTS)                                                                   \
8574         STRESS_MODE(REVERSE_FLAG)     /* Will set GTF_REVERSE_OPS whenever we can */            \
8575         STRESS_MODE(REVERSE_COMMA)    /* Will reverse commas created  with gtNewCommaNode */    \
8576         STRESS_MODE(TAILCALL)         /* Will make the call as a tailcall whenever legal */     \
8577         STRESS_MODE(CATCH_ARG)        /* Will spill catch arg */                                \
8578         STRESS_MODE(UNSAFE_BUFFER_CHECKS)                                                       \
8579         STRESS_MODE(NULL_OBJECT_CHECK)                                                          \
8580         STRESS_MODE(PINVOKE_RESTORE_ESP)                                                        \
8581         STRESS_MODE(RANDOM_INLINE)                                                              \
8582         STRESS_MODE(SWITCH_CMP_BR_EXPANSION)                                                    \
8583         STRESS_MODE(GENERIC_VARN)                                                               \
8584                                                                                                 \
8585         /* After COUNT_VARN, stress level 2 does all of these all the time */                   \
8586                                                                                                 \
8587         STRESS_MODE(COUNT_VARN)                                                                 \
8588                                                                                                 \
8589         /* "Check" stress areas that can be exhaustively used if we */                          \
8590         /*  dont care about performance at all */                                               \
8591                                                                                                 \
8592         STRESS_MODE(FORCE_INLINE) /* Treat every method as AggressiveInlining */                \
8593         STRESS_MODE(CHK_FLOW_UPDATE)                                                            \
8594         STRESS_MODE(EMITTER)                                                                    \
8595         STRESS_MODE(CHK_REIMPORT)                                                               \
8596         STRESS_MODE(FLATFP)                                                                     \
8597         STRESS_MODE(GENERIC_CHECK)                                                              \
8598         STRESS_MODE(COUNT)
8599
8600     enum                compStressArea
8601     {
8602 #define STRESS_MODE(mode) STRESS_##mode,
8603         STRESS_MODES
8604 #undef STRESS_MODE
8605     };
8606 // clang-format on
8607
8608 #ifdef DEBUG
8609     static const LPCWSTR s_compStressModeNames[STRESS_COUNT + 1];
8610     BYTE                 compActiveStressModes[STRESS_COUNT];
8611 #endif // DEBUG
8612
8613 #define MAX_STRESS_WEIGHT 100
8614
8615     bool compStressCompile(compStressArea stressArea, unsigned weightPercentage);
8616
8617 #ifdef DEBUG
8618
8619     bool compInlineStress()
8620     {
8621         return compStressCompile(STRESS_LEGACY_INLINE, 50);
8622     }
8623
8624     bool compRandomInlineStress()
8625     {
8626         return compStressCompile(STRESS_RANDOM_INLINE, 50);
8627     }
8628
8629 #endif // DEBUG
8630
8631     bool compTailCallStress()
8632     {
8633 #ifdef DEBUG
8634         return (JitConfig.TailcallStress() != 0 || compStressCompile(STRESS_TAILCALL, 5));
8635 #else
8636         return false;
8637 #endif
8638     }
8639
8640     codeOptimize compCodeOpt()
8641     {
8642 #if 0
8643         // Switching between size & speed has measurable throughput impact
8644         // (3.5% on NGen mscorlib when measured). It used to be enabled for
8645         // DEBUG, but should generate identical code between CHK & RET builds,
8646         // so that's not acceptable.
8647         // TODO-Throughput: Figure out what to do about size vs. speed & throughput.
8648         //                  Investigate the cause of the throughput regression.
8649
8650         return opts.compCodeOpt;
8651 #else
8652         return BLENDED_CODE;
8653 #endif
8654     }
8655
8656     //--------------------- Info about the procedure --------------------------
8657
8658     struct Info
8659     {
8660         COMP_HANDLE           compCompHnd;
8661         CORINFO_MODULE_HANDLE compScopeHnd;
8662         CORINFO_CLASS_HANDLE  compClassHnd;
8663         CORINFO_METHOD_HANDLE compMethodHnd;
8664         CORINFO_METHOD_INFO*  compMethodInfo;
8665
8666         BOOL hasCircularClassConstraints;
8667         BOOL hasCircularMethodConstraints;
8668
8669 #if defined(DEBUG) || defined(LATE_DISASM)
8670         const char* compMethodName;
8671         const char* compClassName;
8672         const char* compFullName;
8673 #endif // defined(DEBUG) || defined(LATE_DISASM)
8674
8675 #if defined(DEBUG) || defined(INLINE_DATA)
8676         // Method hash is logcally const, but computed
8677         // on first demand.
8678         mutable unsigned compMethodHashPrivate;
8679         unsigned         compMethodHash() const;
8680 #endif // defined(DEBUG) || defined(INLINE_DATA)
8681
8682 #ifdef PSEUDORANDOM_NOP_INSERTION
8683         // things for pseudorandom nop insertion
8684         unsigned  compChecksum;
8685         CLRRandom compRNG;
8686 #endif
8687
8688         // The following holds the FLG_xxxx flags for the method we're compiling.
8689         unsigned compFlags;
8690
8691         // The following holds the class attributes for the method we're compiling.
8692         unsigned compClassAttr;
8693
8694         const BYTE*    compCode;
8695         IL_OFFSET      compILCodeSize;     // The IL code size
8696         IL_OFFSET      compILImportSize;   // Estimated amount of IL actually imported
8697         UNATIVE_OFFSET compNativeCodeSize; // The native code size, after instructions are issued. This
8698                                            // is less than (compTotalHotCodeSize + compTotalColdCodeSize) only if:
8699         // (1) the code is not hot/cold split, and we issued less code than we expected, or
8700         // (2) the code is hot/cold split, and we issued less code than we expected
8701         // in the cold section (the hot section will always be padded out to compTotalHotCodeSize).
8702
8703         bool compIsStatic : 1;         // Is the method static (no 'this' pointer)?
8704         bool compIsVarArgs : 1;        // Does the method have varargs parameters?
8705         bool compIsContextful : 1;     // contextful method
8706         bool compInitMem : 1;          // Is the CORINFO_OPT_INIT_LOCALS bit set in the method info options?
8707         bool compUnwrapContextful : 1; // JIT should unwrap proxies when possible
8708         bool compProfilerCallback : 1; // JIT inserted a profiler Enter callback
8709         bool compPublishStubParam : 1; // EAX captured in prolog will be available through an instrinsic
8710         bool compRetBuffDefStack : 1;  // The ret buff argument definitely points into the stack.
8711
8712         var_types compRetType;       // Return type of the method as declared in IL
8713         var_types compRetNativeType; // Normalized return type as per target arch ABI
8714         unsigned  compILargsCount;   // Number of arguments (incl. implicit but not hidden)
8715         unsigned  compArgsCount;     // Number of arguments (incl. implicit and     hidden)
8716
8717 #if FEATURE_FASTTAILCALL
8718         size_t compArgStackSize; // Incoming argument stack size in bytes
8719 #endif                           // FEATURE_FASTTAILCALL
8720
8721         unsigned compRetBuffArg; // position of hidden return param var (0, 1) (BAD_VAR_NUM means not present);
8722         int compTypeCtxtArg; // position of hidden param for type context for generic code (CORINFO_CALLCONV_PARAMTYPE)
8723         unsigned       compThisArg; // position of implicit this pointer param (not to be confused with lvaArg0Var)
8724         unsigned       compILlocalsCount; // Number of vars : args + locals (incl. implicit but not hidden)
8725         unsigned       compLocalsCount;   // Number of vars : args + locals (incl. implicit and     hidden)
8726         unsigned       compMaxStack;
8727         UNATIVE_OFFSET compTotalHotCodeSize;  // Total number of bytes of Hot Code in the method
8728         UNATIVE_OFFSET compTotalColdCodeSize; // Total number of bytes of Cold Code in the method
8729
8730         unsigned compCallUnmanaged;   // count of unmanaged calls
8731         unsigned compLvFrameListRoot; // lclNum for the Frame root
8732         unsigned compXcptnsCount;     // Number of exception-handling clauses read in the method's IL.
8733                                       // You should generally use compHndBBtabCount instead: it is the
8734                                       // current number of EH clauses (after additions like synchronized
8735                                       // methods and funclets, and removals like unreachable code deletion).
8736
8737         bool compMatchedVM; // true if the VM is "matched": either the JIT is a cross-compiler
8738                             // and the VM expects that, or the JIT is a "self-host" compiler
8739                             // (e.g., x86 hosted targeting x86) and the VM expects that.
8740
8741         /*  The following holds IL scope information about local variables.
8742          */
8743
8744         unsigned     compVarScopesCount;
8745         VarScopeDsc* compVarScopes;
8746
8747         /* The following holds information about instr offsets for
8748          * which we need to report IP-mappings
8749          */
8750
8751         IL_OFFSET*                   compStmtOffsets; // sorted
8752         unsigned                     compStmtOffsetsCount;
8753         ICorDebugInfo::BoundaryTypes compStmtOffsetsImplicit;
8754
8755 #define CPU_X86 0x0100 // The generic X86 CPU
8756 #define CPU_X86_PENTIUM_4 0x0110
8757
8758 #define CPU_X64 0x0200       // The generic x64 CPU
8759 #define CPU_AMD_X64 0x0210   // AMD x64 CPU
8760 #define CPU_INTEL_X64 0x0240 // Intel x64 CPU
8761
8762 #define CPU_ARM 0x0300   // The generic ARM CPU
8763 #define CPU_ARM64 0x0400 // The generic ARM64 CPU
8764
8765         unsigned genCPU; // What CPU are we running on
8766     } info;
8767
8768     // Returns true if the method being compiled returns a non-void and non-struct value.
8769     // Note that lvaInitTypeRef() normalizes compRetNativeType for struct returns in a
8770     // single register as per target arch ABI (e.g on Amd64 Windows structs of size 1, 2,
8771     // 4 or 8 gets normalized to TYP_BYTE/TYP_SHORT/TYP_INT/TYP_LONG; On Arm HFA structs).
8772     // Methods returning such structs are considered to return non-struct return value and
8773     // this method returns true in that case.
8774     bool compMethodReturnsNativeScalarType()
8775     {
8776         return (info.compRetType != TYP_VOID) && !varTypeIsStruct(info.compRetNativeType);
8777     }
8778
8779     // Returns true if the method being compiled returns RetBuf addr as its return value
8780     bool compMethodReturnsRetBufAddr()
8781     {
8782         // There are cases where implicit RetBuf argument should be explicitly returned in a register.
8783         // In such cases the return type is changed to TYP_BYREF and appropriate IR is generated.
8784         // These cases are:
8785         // 1. Profiler Leave calllback expects the address of retbuf as return value for
8786         //    methods with hidden RetBuf argument.  impReturnInstruction() when profiler
8787         //    callbacks are needed creates GT_RETURN(TYP_BYREF, op1 = Addr of RetBuf) for
8788         //    methods with hidden RetBufArg.
8789         //
8790         // 2. As per the System V ABI, the address of RetBuf needs to be returned by
8791         //    methods with hidden RetBufArg in RAX. In such case GT_RETURN is of TYP_BYREF,
8792         //    returning the address of RetBuf.
8793         //
8794         // 3. Windows 64-bit native calling convention also requires the address of RetBuff
8795         //    to be returned in RAX.
8796         CLANG_FORMAT_COMMENT_ANCHOR;
8797
8798 #ifdef _TARGET_AMD64_
8799         return (info.compRetBuffArg != BAD_VAR_NUM);
8800 #else  // !_TARGET_AMD64_
8801         return (compIsProfilerHookNeeded()) && (info.compRetBuffArg != BAD_VAR_NUM);
8802 #endif // !_TARGET_AMD64_
8803     }
8804
8805     // Returns true if the method returns a value in more than one return register
8806     // TODO-ARM-Bug: Deal with multi-register genReturnLocaled structs?
8807     // TODO-ARM64: Does this apply for ARM64 too?
8808     bool compMethodReturnsMultiRegRetType()
8809     {
8810 #if FEATURE_MULTIREG_RET
8811 #if defined(_TARGET_X86_)
8812         // On x86 only 64-bit longs are returned in multiple registers
8813         return varTypeIsLong(info.compRetNativeType);
8814 #else  // targets: X64-UNIX, ARM64 or ARM32
8815         // On all other targets that support multireg return values:
8816         // Methods returning a struct in multiple registers have a return value of TYP_STRUCT.
8817         // Such method's compRetNativeType is TYP_STRUCT without a hidden RetBufArg
8818         return varTypeIsStruct(info.compRetNativeType) && (info.compRetBuffArg == BAD_VAR_NUM);
8819 #endif // TARGET_XXX
8820
8821 #else // not FEATURE_MULTIREG_RET
8822
8823         // For this architecture there are no multireg returns
8824         return false;
8825
8826 #endif // FEATURE_MULTIREG_RET
8827     }
8828
8829 #if FEATURE_MULTIREG_ARGS
8830     // Given a GenTree node of TYP_STRUCT that represents a pass by value argument
8831     // return the gcPtr layout for the pointers sized fields
8832     void getStructGcPtrsFromOp(GenTree* op, BYTE* gcPtrsOut);
8833 #endif // FEATURE_MULTIREG_ARGS
8834
8835     // Returns true if the method being compiled returns a value
8836     bool compMethodHasRetVal()
8837     {
8838         return compMethodReturnsNativeScalarType() || compMethodReturnsRetBufAddr() ||
8839                compMethodReturnsMultiRegRetType();
8840     }
8841
8842 #if defined(DEBUG)
8843
8844     void compDispLocalVars();
8845
8846 #endif // DEBUG
8847
8848 //-------------------------- Global Compiler Data ------------------------------------
8849
8850 #ifdef DEBUG
8851     static unsigned s_compMethodsCount; // to produce unique label names
8852     unsigned        compGenTreeID;
8853     unsigned        compBasicBlockID;
8854 #endif
8855
8856     BasicBlock* compCurBB;   // the current basic block in process
8857     GenTree*    compCurStmt; // the current statement in process
8858 #ifdef DEBUG
8859     unsigned compCurStmtNum; // to give all statements an increasing StmtNum when printing dumps
8860 #endif
8861
8862     //  The following is used to create the 'method JIT info' block.
8863     size_t compInfoBlkSize;
8864     BYTE*  compInfoBlkAddr;
8865
8866     EHblkDsc* compHndBBtab;           // array of EH data
8867     unsigned  compHndBBtabCount;      // element count of used elements in EH data array
8868     unsigned  compHndBBtabAllocCount; // element count of allocated elements in EH data array
8869
8870 #if defined(_TARGET_X86_)
8871
8872     //-------------------------------------------------------------------------
8873     //  Tracking of region covered by the monitor in synchronized methods
8874     void* syncStartEmitCookie; // the emitter cookie for first instruction after the call to MON_ENTER
8875     void* syncEndEmitCookie;   // the emitter cookie for first instruction after the call to MON_EXIT
8876
8877 #endif // !_TARGET_X86_
8878
8879     Phases previousCompletedPhase; // the most recently completed phase
8880
8881     //-------------------------------------------------------------------------
8882     //  The following keeps track of how many bytes of local frame space we've
8883     //  grabbed so far in the current function, and how many argument bytes we
8884     //  need to pop when we return.
8885     //
8886
8887     unsigned compLclFrameSize; // secObject+lclBlk+locals+temps
8888
8889     // Count of callee-saved regs we pushed in the prolog.
8890     // Does not include EBP for isFramePointerUsed() and double-aligned frames.
8891     // In case of Amd64 this doesn't include float regs saved on stack.
8892     unsigned compCalleeRegsPushed;
8893
8894 #if defined(_TARGET_XARCH_)
8895     // Mask of callee saved float regs on stack.
8896     regMaskTP compCalleeFPRegsSavedMask;
8897 #endif
8898 #ifdef _TARGET_AMD64_
8899 // Quirk for VS debug-launch scenario to work:
8900 // Bytes of padding between save-reg area and locals.
8901 #define VSQUIRK_STACK_PAD (2 * REGSIZE_BYTES)
8902     unsigned compVSQuirkStackPaddingNeeded;
8903     bool     compQuirkForPPPflag;
8904 #endif
8905
8906     unsigned compArgSize; // total size of arguments in bytes (including register args (lvIsRegArg))
8907
8908     unsigned compMapILargNum(unsigned ILargNum); // map accounting for hidden args
8909     unsigned compMapILvarNum(unsigned ILvarNum); // map accounting for hidden args
8910     unsigned compMap2ILvarNum(unsigned varNum);  // map accounting for hidden args
8911
8912     //-------------------------------------------------------------------------
8913
8914     static void compStartup();  // One-time initialization
8915     static void compShutdown(); // One-time finalization
8916
8917     void compInit(ArenaAllocator* pAlloc, InlineInfo* inlineInfo);
8918     void compDone();
8919
8920     static void compDisplayStaticSizes(FILE* fout);
8921
8922     //------------ Some utility functions --------------
8923
8924     void* compGetHelperFtn(CorInfoHelpFunc ftnNum,         /* IN  */
8925                            void**          ppIndirection); /* OUT */
8926
8927     // Several JIT/EE interface functions return a CorInfoType, and also return a
8928     // class handle as an out parameter if the type is a value class.  Returns the
8929     // size of the type these describe.
8930     unsigned compGetTypeSize(CorInfoType cit, CORINFO_CLASS_HANDLE clsHnd);
8931
8932 #ifdef DEBUG
8933     // Components used by the compiler may write unit test suites, and
8934     // have them run within this method.  They will be run only once per process, and only
8935     // in debug.  (Perhaps should be under the control of a COMPlus_ flag.)
8936     // These should fail by asserting.
8937     void compDoComponentUnitTestsOnce();
8938 #endif // DEBUG
8939
8940     int compCompile(CORINFO_METHOD_HANDLE methodHnd,
8941                     CORINFO_MODULE_HANDLE classPtr,
8942                     COMP_HANDLE           compHnd,
8943                     CORINFO_METHOD_INFO*  methodInfo,
8944                     void**                methodCodePtr,
8945                     ULONG*                methodCodeSize,
8946                     JitFlags*             compileFlags);
8947     void compCompileFinish();
8948     int compCompileHelper(CORINFO_MODULE_HANDLE            classPtr,
8949                           COMP_HANDLE                      compHnd,
8950                           CORINFO_METHOD_INFO*             methodInfo,
8951                           void**                           methodCodePtr,
8952                           ULONG*                           methodCodeSize,
8953                           JitFlags*                        compileFlags,
8954                           CorInfoInstantiationVerification instVerInfo);
8955
8956     ArenaAllocator* compGetArenaAllocator();
8957
8958 #if MEASURE_MEM_ALLOC
8959     static bool s_dspMemStats; // Display per-phase memory statistics for every function
8960 #endif                         // MEASURE_MEM_ALLOC
8961
8962 #if LOOP_HOIST_STATS
8963     unsigned m_loopsConsidered;
8964     bool     m_curLoopHasHoistedExpression;
8965     unsigned m_loopsWithHoistedExpressions;
8966     unsigned m_totalHoistedExpressions;
8967
8968     void AddLoopHoistStats();
8969     void PrintPerMethodLoopHoistStats();
8970
8971     static CritSecObject s_loopHoistStatsLock; // This lock protects the data structures below.
8972     static unsigned      s_loopsConsidered;
8973     static unsigned      s_loopsWithHoistedExpressions;
8974     static unsigned      s_totalHoistedExpressions;
8975
8976     static void PrintAggregateLoopHoistStats(FILE* f);
8977 #endif // LOOP_HOIST_STATS
8978
8979     bool compIsForImportOnly();
8980     bool compIsForInlining();
8981     bool compDonotInline();
8982
8983 #ifdef DEBUG
8984     unsigned char compGetJitDefaultFill(); // Get the default fill char value
8985                                            // we randomize this value when JitStress is enabled
8986
8987     const char* compLocalVarName(unsigned varNum, unsigned offs);
8988     VarName compVarName(regNumber reg, bool isFloatReg = false);
8989     const char* compRegVarName(regNumber reg, bool displayVar = false, bool isFloatReg = false);
8990     const char* compRegNameForSize(regNumber reg, size_t size);
8991     const char* compFPregVarName(unsigned fpReg, bool displayVar = false);
8992     void compDspSrcLinesByNativeIP(UNATIVE_OFFSET curIP);
8993     void compDspSrcLinesByLineNum(unsigned line, bool seek = false);
8994 #endif // DEBUG
8995
8996     //-------------------------------------------------------------------------
8997
8998     struct VarScopeListNode
8999     {
9000         VarScopeDsc*             data;
9001         VarScopeListNode*        next;
9002         static VarScopeListNode* Create(VarScopeDsc* value, CompAllocator alloc)
9003         {
9004             VarScopeListNode* node = new (alloc) VarScopeListNode;
9005             node->data             = value;
9006             node->next             = nullptr;
9007             return node;
9008         }
9009     };
9010
9011     struct VarScopeMapInfo
9012     {
9013         VarScopeListNode*       head;
9014         VarScopeListNode*       tail;
9015         static VarScopeMapInfo* Create(VarScopeListNode* node, CompAllocator alloc)
9016         {
9017             VarScopeMapInfo* info = new (alloc) VarScopeMapInfo;
9018             info->head            = node;
9019             info->tail            = node;
9020             return info;
9021         }
9022     };
9023
9024     // Max value of scope count for which we would use linear search; for larger values we would use hashtable lookup.
9025     static const unsigned MAX_LINEAR_FIND_LCL_SCOPELIST = 32;
9026
9027     typedef JitHashTable<unsigned, JitSmallPrimitiveKeyFuncs<unsigned>, VarScopeMapInfo*> VarNumToScopeDscMap;
9028
9029     // Map to keep variables' scope indexed by varNum containing it's scope dscs at the index.
9030     VarNumToScopeDscMap* compVarScopeMap;
9031
9032     VarScopeDsc* compFindLocalVar(unsigned varNum, unsigned lifeBeg, unsigned lifeEnd);
9033
9034     VarScopeDsc* compFindLocalVar(unsigned varNum, unsigned offs);
9035
9036     VarScopeDsc* compFindLocalVarLinear(unsigned varNum, unsigned offs);
9037
9038     void compInitVarScopeMap();
9039
9040     VarScopeDsc** compEnterScopeList; // List has the offsets where variables
9041                                       // enter scope, sorted by instr offset
9042     unsigned compNextEnterScope;
9043
9044     VarScopeDsc** compExitScopeList; // List has the offsets where variables
9045                                      // go out of scope, sorted by instr offset
9046     unsigned compNextExitScope;
9047
9048     void compInitScopeLists();
9049
9050     void compResetScopeLists();
9051
9052     VarScopeDsc* compGetNextEnterScope(unsigned offs, bool scan = false);
9053
9054     VarScopeDsc* compGetNextExitScope(unsigned offs, bool scan = false);
9055
9056     void compProcessScopesUntil(unsigned   offset,
9057                                 VARSET_TP* inScope,
9058                                 void (Compiler::*enterScopeFn)(VARSET_TP* inScope, VarScopeDsc*),
9059                                 void (Compiler::*exitScopeFn)(VARSET_TP* inScope, VarScopeDsc*));
9060
9061 #ifdef DEBUG
9062     void compDispScopeLists();
9063 #endif // DEBUG
9064
9065     bool compIsProfilerHookNeeded();
9066
9067     //-------------------------------------------------------------------------
9068     /*               Statistical Data Gathering                               */
9069
9070     void compJitStats(); // call this function and enable
9071                          // various ifdef's below for statistical data
9072
9073 #if CALL_ARG_STATS
9074     void        compCallArgStats();
9075     static void compDispCallArgStats(FILE* fout);
9076 #endif
9077
9078     //-------------------------------------------------------------------------
9079
9080 protected:
9081 #ifdef DEBUG
9082     bool skipMethod();
9083 #endif
9084
9085     ArenaAllocator* compArenaAllocator;
9086
9087 public:
9088     void compFunctionTraceStart();
9089     void compFunctionTraceEnd(void* methodCodePtr, ULONG methodCodeSize, bool isNYI);
9090
9091 protected:
9092     size_t compMaxUncheckedOffsetForNullObject;
9093
9094     void compInitOptions(JitFlags* compileFlags);
9095
9096     void compSetProcessor();
9097     void compInitDebuggingInfo();
9098     void compSetOptimizationLevel();
9099 #ifdef _TARGET_ARMARCH_
9100     bool compRsvdRegCheck(FrameLayoutState curState);
9101 #endif
9102     void compCompile(void** methodCodePtr, ULONG* methodCodeSize, JitFlags* compileFlags);
9103
9104     // Clear annotations produced during optimizations; to be used between iterations when repeating opts.
9105     void ResetOptAnnotations();
9106
9107     // Regenerate loop descriptors; to be used between iterations when repeating opts.
9108     void RecomputeLoopInfo();
9109
9110 #ifdef PROFILING_SUPPORTED
9111     // Data required for generating profiler Enter/Leave/TailCall hooks
9112
9113     bool  compProfilerHookNeeded; // Whether profiler Enter/Leave/TailCall hook needs to be generated for the method
9114     void* compProfilerMethHnd;    // Profiler handle of the method being compiled. Passed as param to ELT callbacks
9115     bool  compProfilerMethHndIndirected; // Whether compProfilerHandle is pointer to the handle or is an actual handle
9116 #endif
9117
9118 #ifdef _TARGET_AMD64_
9119     bool compQuirkForPPP(); // Check if this method should be Quirked for the PPP issue
9120 #endif
9121 public:
9122     // Assumes called as part of process shutdown; does any compiler-specific work associated with that.
9123     static void ProcessShutdownWork(ICorStaticInfo* statInfo);
9124
9125     CompAllocator getAllocator(CompMemKind cmk = CMK_Generic)
9126     {
9127         return CompAllocator(compArenaAllocator, cmk);
9128     }
9129
9130     CompAllocator getAllocatorGC()
9131     {
9132         return getAllocator(CMK_GC);
9133     }
9134
9135     CompAllocator getAllocatorLoopHoist()
9136     {
9137         return getAllocator(CMK_LoopHoist);
9138     }
9139
9140 #ifdef DEBUG
9141     CompAllocator getAllocatorDebugOnly()
9142     {
9143         return getAllocator(CMK_DebugOnly);
9144     }
9145 #endif // DEBUG
9146
9147     /*
9148     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9149     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9150     XX                                                                           XX
9151     XX                           typeInfo                                        XX
9152     XX                                                                           XX
9153     XX   Checks for type compatibility and merges types                          XX
9154     XX                                                                           XX
9155     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9156     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9157     */
9158
9159 public:
9160     // Set to TRUE if verification cannot be skipped for this method
9161     // If we detect unverifiable code, we will lazily check
9162     // canSkipMethodVerification() to see if verification is REALLY needed.
9163     BOOL tiVerificationNeeded;
9164
9165     // It it initially TRUE, and it gets set to FALSE if we run into unverifiable code
9166     // Note that this is valid only if tiVerificationNeeded was ever TRUE.
9167     BOOL tiIsVerifiableCode;
9168
9169     // Set to TRUE if runtime callout is needed for this method
9170     BOOL tiRuntimeCalloutNeeded;
9171
9172     // Set to TRUE if security prolog/epilog callout is needed for this method
9173     // Note: This flag is different than compNeedSecurityCheck.
9174     //     compNeedSecurityCheck means whether or not a security object needs
9175     //         to be allocated on the stack, which is currently true for EnC as well.
9176     //     tiSecurityCalloutNeeded means whether or not security callouts need
9177     //         to be inserted in the jitted code.
9178     BOOL tiSecurityCalloutNeeded;
9179
9180     // Returns TRUE if child is equal to or a subtype of parent for merge purposes
9181     // This support is necessary to suport attributes that are not described in
9182     // for example, signatures. For example, the permanent home byref (byref that
9183     // points to the gc heap), isn't a property of method signatures, therefore,
9184     // it is safe to have mismatches here (that tiCompatibleWith will not flag),
9185     // but when deciding if we need to reimport a block, we need to take these
9186     // in account
9187     BOOL tiMergeCompatibleWith(const typeInfo& pChild, const typeInfo& pParent, bool normalisedForStack) const;
9188
9189     // Returns TRUE if child is equal to or a subtype of parent.
9190     // normalisedForStack indicates that both types are normalised for the stack
9191     BOOL tiCompatibleWith(const typeInfo& pChild, const typeInfo& pParent, bool normalisedForStack) const;
9192
9193     // Merges pDest and pSrc. Returns FALSE if merge is undefined.
9194     // *pDest is modified to represent the merged type.  Sets "*changed" to true
9195     // if this changes "*pDest".
9196     BOOL tiMergeToCommonParent(typeInfo* pDest, const typeInfo* pSrc, bool* changed) const;
9197
9198 #ifdef DEBUG
9199     // <BUGNUM> VSW 471305
9200     // IJW allows assigning REF to BYREF. The following allows us to temporarily
9201     // bypass the assert check in gcMarkRegSetGCref and gcMarkRegSetByref
9202     // We use a "short" as we need to push/pop this scope.
9203     // </BUGNUM>
9204     short compRegSetCheckLevel;
9205 #endif
9206
9207     /*
9208     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9209     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9210     XX                                                                           XX
9211     XX                           IL verification stuff                           XX
9212     XX                                                                           XX
9213     XX                                                                           XX
9214     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9215     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9216     */
9217
9218 public:
9219     // The following is used to track liveness of local variables, initialization
9220     // of valueclass constructors, and type safe use of IL instructions.
9221
9222     // dynamic state info needed for verification
9223     EntryState verCurrentState;
9224
9225     // this ptr of object type .ctors are considered intited only after
9226     // the base class ctor is called, or an alternate ctor is called.
9227     // An uninited this ptr can be used to access fields, but cannot
9228     // be used to call a member function.
9229     BOOL verTrackObjCtorInitState;
9230
9231     void verInitBBEntryState(BasicBlock* block, EntryState* currentState);
9232
9233     // Requires that "tis" is not TIS_Bottom -- it's a definite init/uninit state.
9234     void verSetThisInit(BasicBlock* block, ThisInitState tis);
9235     void verInitCurrentState();
9236     void verResetCurrentState(BasicBlock* block, EntryState* currentState);
9237
9238     // Merges the current verification state into the entry state of "block", return FALSE if that merge fails,
9239     // TRUE if it succeeds.  Further sets "*changed" to true if this changes the entry state of "block".
9240     BOOL verMergeEntryStates(BasicBlock* block, bool* changed);
9241
9242     void verConvertBBToThrowVerificationException(BasicBlock* block DEBUGARG(bool logMsg));
9243     void verHandleVerificationFailure(BasicBlock* block DEBUGARG(bool logMsg));
9244     typeInfo verMakeTypeInfo(CORINFO_CLASS_HANDLE clsHnd,
9245                              bool bashStructToRef = false); // converts from jit type representation to typeInfo
9246     typeInfo verMakeTypeInfo(CorInfoType          ciType,
9247                              CORINFO_CLASS_HANDLE clsHnd); // converts from jit type representation to typeInfo
9248     BOOL verIsSDArray(typeInfo ti);
9249     typeInfo verGetArrayElemType(typeInfo ti);
9250
9251     typeInfo verParseArgSigToTypeInfo(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args);
9252     BOOL verNeedsVerification();
9253     BOOL verIsByRefLike(const typeInfo& ti);
9254     BOOL verIsSafeToReturnByRef(const typeInfo& ti);
9255
9256     // generic type variables range over types that satisfy IsBoxable
9257     BOOL verIsBoxable(const typeInfo& ti);
9258
9259     void DECLSPEC_NORETURN verRaiseVerifyException(INDEBUG(const char* reason) DEBUGARG(const char* file)
9260                                                        DEBUGARG(unsigned line));
9261     void verRaiseVerifyExceptionIfNeeded(INDEBUG(const char* reason) DEBUGARG(const char* file)
9262                                              DEBUGARG(unsigned line));
9263     bool verCheckTailCallConstraint(OPCODE                  opcode,
9264                                     CORINFO_RESOLVED_TOKEN* pResolvedToken,
9265                                     CORINFO_RESOLVED_TOKEN* pConstrainedResolvedToken, // Is this a "constrained." call
9266                                                                                        // on a type parameter?
9267                                     bool speculative // If true, won't throw if verificatoin fails. Instead it will
9268                                                      // return false to the caller.
9269                                                      // If false, it will throw.
9270                                     );
9271     bool verIsBoxedValueType(typeInfo ti);
9272
9273     void verVerifyCall(OPCODE                  opcode,
9274                        CORINFO_RESOLVED_TOKEN* pResolvedToken,
9275                        CORINFO_RESOLVED_TOKEN* pConstrainedResolvedToken,
9276                        bool                    tailCall,
9277                        bool                    readonlyCall, // is this a "readonly." call?
9278                        const BYTE*             delegateCreateStart,
9279                        const BYTE*             codeAddr,
9280                        CORINFO_CALL_INFO* callInfo DEBUGARG(const char* methodName));
9281
9282     BOOL verCheckDelegateCreation(const BYTE* delegateCreateStart, const BYTE* codeAddr, mdMemberRef& targetMemberRef);
9283
9284     typeInfo verVerifySTIND(const typeInfo& ptr, const typeInfo& value, const typeInfo& instrType);
9285     typeInfo verVerifyLDIND(const typeInfo& ptr, const typeInfo& instrType);
9286     void verVerifyField(CORINFO_RESOLVED_TOKEN*   pResolvedToken,
9287                         const CORINFO_FIELD_INFO& fieldInfo,
9288                         const typeInfo*           tiThis,
9289                         BOOL                      mutator,
9290                         BOOL                      allowPlainStructAsThis = FALSE);
9291     void verVerifyCond(const typeInfo& tiOp1, const typeInfo& tiOp2, unsigned opcode);
9292     void verVerifyThisPtrInitialised();
9293     BOOL verIsCallToInitThisPtr(CORINFO_CLASS_HANDLE context, CORINFO_CLASS_HANDLE target);
9294
9295 #ifdef DEBUG
9296
9297     // One line log function. Default level is 0. Increasing it gives you
9298     // more log information
9299
9300     // levels are currently unused: #define JITDUMP(level,...)                     ();
9301     void JitLogEE(unsigned level, const char* fmt, ...);
9302
9303     bool compDebugBreak;
9304
9305     bool compJitHaltMethod();
9306
9307 #endif
9308
9309     /*
9310     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9311     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9312     XX                                                                           XX
9313     XX                   GS Security checks for unsafe buffers                   XX
9314     XX                                                                           XX
9315     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9316     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9317     */
9318 public:
9319     struct ShadowParamVarInfo
9320     {
9321         FixedBitVect* assignGroup; // the closure set of variables whose values depend on each other
9322         unsigned      shadowCopy;  // Lcl var num, valid only if not set to NO_SHADOW_COPY
9323
9324         static bool mayNeedShadowCopy(LclVarDsc* varDsc)
9325         {
9326 #if defined(_TARGET_AMD64_)
9327             // GS cookie logic to create shadow slots, create trees to copy reg args to shadow
9328             // slots and update all trees to refer to shadow slots is done immediately after
9329             // fgMorph().  Lsra could potentially mark a param as DoNotEnregister after JIT determines
9330             // not to shadow a parameter.  Also, LSRA could potentially spill a param which is passed
9331             // in register. Therefore, conservatively all params may need a shadow copy.  Note that
9332             // GS cookie logic further checks whether the param is a ptr or an unsafe buffer before
9333             // creating a shadow slot even though this routine returns true.
9334             //
9335             // TODO-AMD64-CQ: Revisit this conservative approach as it could create more shadow slots than
9336             // required. There are two cases under which a reg arg could potentially be used from its
9337             // home location:
9338             //   a) LSRA marks it as DoNotEnregister (see LinearScan::identifyCandidates())
9339             //   b) LSRA spills it
9340             //
9341             // Possible solution to address case (a)
9342             //   - The conditions under which LSRA marks a varDsc as DoNotEnregister could be checked
9343             //     in this routine.  Note that live out of exception handler is something we may not be
9344             //     able to do it here since GS cookie logic is invoked ahead of liveness computation.
9345             //     Therefore, for methods with exception handling and need GS cookie check we might have
9346             //     to take conservative approach.
9347             //
9348             // Possible solution to address case (b)
9349             //   - Whenver a parameter passed in an argument register needs to be spilled by LSRA, we
9350             //     create a new spill temp if the method needs GS cookie check.
9351             return varDsc->lvIsParam;
9352 #else // !defined(_TARGET_AMD64_)
9353             return varDsc->lvIsParam && !varDsc->lvIsRegArg;
9354 #endif
9355         }
9356
9357 #ifdef DEBUG
9358         void Print()
9359         {
9360             printf("assignGroup [%p]; shadowCopy: [%d];\n", assignGroup, shadowCopy);
9361         }
9362 #endif
9363     };
9364
9365     GSCookie*           gsGlobalSecurityCookieAddr; // Address of global cookie for unsafe buffer checks
9366     GSCookie            gsGlobalSecurityCookieVal;  // Value of global cookie if addr is NULL
9367     ShadowParamVarInfo* gsShadowVarInfo;            // Table used by shadow param analysis code
9368
9369     void gsGSChecksInitCookie();   // Grabs cookie variable
9370     void gsCopyShadowParams();     // Identify vulnerable params and create dhadow copies
9371     bool gsFindVulnerableParams(); // Shadow param analysis code
9372     void gsParamsToShadows();      // Insert copy code and replave param uses by shadow
9373
9374     static fgWalkPreFn gsMarkPtrsAndAssignGroups; // Shadow param analysis tree-walk
9375     static fgWalkPreFn gsReplaceShadowParams;     // Shadow param replacement tree-walk
9376
9377 #define DEFAULT_MAX_INLINE_SIZE 100 // Methods with >  DEFAULT_MAX_INLINE_SIZE IL bytes will never be inlined.
9378                                     // This can be overwritten by setting complus_JITInlineSize env variable.
9379
9380 #define DEFAULT_MAX_INLINE_DEPTH 20 // Methods at more than this level deep will not be inlined
9381
9382 #define DEFAULT_MAX_LOCALLOC_TO_LOCAL_SIZE 32 // fixed locallocs of this size or smaller will convert to local buffers
9383
9384 private:
9385 #ifdef FEATURE_JIT_METHOD_PERF
9386     JitTimer*                  pCompJitTimer;         // Timer data structure (by phases) for current compilation.
9387     static CompTimeSummaryInfo s_compJitTimerSummary; // Summary of the Timer information for the whole run.
9388
9389     static LPCWSTR JitTimeLogCsv();        // Retrieve the file name for CSV from ConfigDWORD.
9390     static LPCWSTR compJitTimeLogFilename; // If a log file for JIT time is desired, filename to write it to.
9391 #endif
9392     inline void EndPhase(Phases phase); // Indicate the end of the given phase.
9393
9394 #if MEASURE_CLRAPI_CALLS
9395     // Thin wrappers that call into JitTimer (if present).
9396     inline void CLRApiCallEnter(unsigned apix);
9397     inline void CLRApiCallLeave(unsigned apix);
9398
9399 public:
9400     inline void CLR_API_Enter(API_ICorJitInfo_Names ename);
9401     inline void CLR_API_Leave(API_ICorJitInfo_Names ename);
9402
9403 private:
9404 #endif
9405
9406 #if defined(DEBUG) || defined(INLINE_DATA) || defined(FEATURE_CLRSQM)
9407     // These variables are associated with maintaining SQM data about compile time.
9408     unsigned __int64 m_compCyclesAtEndOfInlining; // The thread-virtualized cycle count at the end of the inlining phase
9409                                                   // in the current compilation.
9410     unsigned __int64 m_compCycles;                // Net cycle count for current compilation
9411     DWORD m_compTickCountAtEndOfInlining; // The result of GetTickCount() (# ms since some epoch marker) at the end of
9412                                           // the inlining phase in the current compilation.
9413 #endif                                    // defined(DEBUG) || defined(INLINE_DATA) || defined(FEATURE_CLRSQM)
9414
9415     // Records the SQM-relevant (cycles and tick count).  Should be called after inlining is complete.
9416     // (We do this after inlining because this marks the last point at which the JIT is likely to cause
9417     // type-loading and class initialization).
9418     void RecordStateAtEndOfInlining();
9419     // Assumes being called at the end of compilation.  Update the SQM state.
9420     void RecordStateAtEndOfCompilation();
9421
9422 #ifdef FEATURE_CLRSQM
9423     // Does anything SQM related necessary at process shutdown time.
9424     static void ProcessShutdownSQMWork(ICorStaticInfo* statInfo);
9425 #endif // FEATURE_CLRSQM
9426
9427 public:
9428 #if FUNC_INFO_LOGGING
9429     static LPCWSTR compJitFuncInfoFilename; // If a log file for per-function information is required, this is the
9430                                             // filename to write it to.
9431     static FILE* compJitFuncInfoFile;       // And this is the actual FILE* to write to.
9432 #endif                                      // FUNC_INFO_LOGGING
9433
9434     Compiler* prevCompiler; // Previous compiler on stack for TLS Compiler* linked list for reentrant compilers.
9435
9436     // Is the compilation in a full trust context?
9437     bool compIsFullTrust();
9438
9439 #if MEASURE_NOWAY
9440     void RecordNowayAssert(const char* filename, unsigned line, const char* condStr);
9441 #endif // MEASURE_NOWAY
9442
9443 #ifndef FEATURE_TRACELOGGING
9444     // Should we actually fire the noway assert body and the exception handler?
9445     bool compShouldThrowOnNoway();
9446 #else  // FEATURE_TRACELOGGING
9447     // Should we actually fire the noway assert body and the exception handler?
9448     bool compShouldThrowOnNoway(const char* filename, unsigned line);
9449
9450     // Telemetry instance to use per method compilation.
9451     JitTelemetry compJitTelemetry;
9452
9453     // Get common parameters that have to be logged with most telemetry data.
9454     void compGetTelemetryDefaults(const char** assemblyName,
9455                                   const char** scopeName,
9456                                   const char** methodName,
9457                                   unsigned*    methodHash);
9458 #endif // !FEATURE_TRACELOGGING
9459
9460 #ifdef DEBUG
9461 private:
9462     NodeToTestDataMap* m_nodeTestData;
9463
9464     static const unsigned FIRST_LOOP_HOIST_CSE_CLASS = 1000;
9465     unsigned              m_loopHoistCSEClass; // LoopHoist test annotations turn into CSE requirements; we
9466                                                // label them with CSE Class #'s starting at FIRST_LOOP_HOIST_CSE_CLASS.
9467                                                // Current kept in this.
9468 public:
9469     NodeToTestDataMap* GetNodeTestData()
9470     {
9471         Compiler* compRoot = impInlineRoot();
9472         if (compRoot->m_nodeTestData == nullptr)
9473         {
9474             compRoot->m_nodeTestData = new (getAllocatorDebugOnly()) NodeToTestDataMap(getAllocatorDebugOnly());
9475         }
9476         return compRoot->m_nodeTestData;
9477     }
9478
9479     typedef JitHashTable<GenTree*, JitPtrKeyFuncs<GenTree>, int> NodeToIntMap;
9480
9481     // Returns the set (i.e., the domain of the result map) of nodes that are keys in m_nodeTestData, and
9482     // currently occur in the AST graph.
9483     NodeToIntMap* FindReachableNodesInNodeTestData();
9484
9485     // Node "from" is being eliminated, and being replaced by node "to".  If "from" had any associated
9486     // test data, associate that data with "to".
9487     void TransferTestDataToNode(GenTree* from, GenTree* to);
9488
9489     // Requires that "to" is a clone of "from".  If any nodes in the "from" tree
9490     // have annotations, attach similar annotations to the corresponding nodes in "to".
9491     void CopyTestDataToCloneTree(GenTree* from, GenTree* to);
9492
9493     // These are the methods that test that the various conditions implied by the
9494     // test attributes are satisfied.
9495     void JitTestCheckSSA(); // SSA builder tests.
9496     void JitTestCheckVN();  // Value numbering tests.
9497 #endif                      // DEBUG
9498
9499     // The "FieldSeqStore", for canonicalizing field sequences.  See the definition of FieldSeqStore for
9500     // operations.
9501     FieldSeqStore* m_fieldSeqStore;
9502
9503     FieldSeqStore* GetFieldSeqStore()
9504     {
9505         Compiler* compRoot = impInlineRoot();
9506         if (compRoot->m_fieldSeqStore == nullptr)
9507         {
9508             // Create a CompAllocator that labels sub-structure with CMK_FieldSeqStore, and use that for allocation.
9509             CompAllocator ialloc(getAllocator(CMK_FieldSeqStore));
9510             compRoot->m_fieldSeqStore = new (ialloc) FieldSeqStore(ialloc);
9511         }
9512         return compRoot->m_fieldSeqStore;
9513     }
9514
9515     typedef JitHashTable<GenTree*, JitPtrKeyFuncs<GenTree>, FieldSeqNode*> NodeToFieldSeqMap;
9516
9517     // Some nodes of "TYP_BYREF" or "TYP_I_IMPL" actually represent the address of a field within a struct, but since
9518     // the offset of the field is zero, there's no "GT_ADD" node.  We normally attach a field sequence to the constant
9519     // that is added, but what do we do when that constant is zero, and is thus not present?  We use this mechanism to
9520     // attach the field sequence directly to the address node.
9521     NodeToFieldSeqMap* m_zeroOffsetFieldMap;
9522
9523     NodeToFieldSeqMap* GetZeroOffsetFieldMap()
9524     {
9525         // Don't need to worry about inlining here
9526         if (m_zeroOffsetFieldMap == nullptr)
9527         {
9528             // Create a CompAllocator that labels sub-structure with CMK_ZeroOffsetFieldMap, and use that for
9529             // allocation.
9530             CompAllocator ialloc(getAllocator(CMK_ZeroOffsetFieldMap));
9531             m_zeroOffsetFieldMap = new (ialloc) NodeToFieldSeqMap(ialloc);
9532         }
9533         return m_zeroOffsetFieldMap;
9534     }
9535
9536     // Requires that "op1" is a node of type "TYP_BYREF" or "TYP_I_IMPL".  We are dereferencing this with the fields in
9537     // "fieldSeq", whose offsets are required all to be zero.  Ensures that any field sequence annotation currently on
9538     // "op1" or its components is augmented by appending "fieldSeq".  In practice, if "op1" is a GT_LCL_FLD, it has
9539     // a field sequence as a member; otherwise, it may be the addition of an a byref and a constant, where the const
9540     // has a field sequence -- in this case "fieldSeq" is appended to that of the constant; otherwise, we
9541     // record the the field sequence using the ZeroOffsetFieldMap described above.
9542     //
9543     // One exception above is that "op1" is a node of type "TYP_REF" where "op1" is a GT_LCL_VAR.
9544     // This happens when System.Object vtable pointer is a regular field at offset 0 in System.Private.CoreLib in
9545     // CoreRT. Such case is handled same as the default case.
9546     void fgAddFieldSeqForZeroOffset(GenTree* op1, FieldSeqNode* fieldSeq);
9547
9548     typedef JitHashTable<const GenTree*, JitPtrKeyFuncs<GenTree>, ArrayInfo> NodeToArrayInfoMap;
9549     NodeToArrayInfoMap* m_arrayInfoMap;
9550
9551     NodeToArrayInfoMap* GetArrayInfoMap()
9552     {
9553         Compiler* compRoot = impInlineRoot();
9554         if (compRoot->m_arrayInfoMap == nullptr)
9555         {
9556             // Create a CompAllocator that labels sub-structure with CMK_ArrayInfoMap, and use that for allocation.
9557             CompAllocator ialloc(getAllocator(CMK_ArrayInfoMap));
9558             compRoot->m_arrayInfoMap = new (ialloc) NodeToArrayInfoMap(ialloc);
9559         }
9560         return compRoot->m_arrayInfoMap;
9561     }
9562
9563     //-----------------------------------------------------------------------------------------------------------------
9564     // Compiler::TryGetArrayInfo:
9565     //    Given an indirection node, checks to see whether or not that indirection represents an array access, and
9566     //    if so returns information about the array.
9567     //
9568     // Arguments:
9569     //    indir           - The `GT_IND` node.
9570     //    arrayInfo (out) - Information about the accessed array if this function returns true. Undefined otherwise.
9571     //
9572     // Returns:
9573     //    True if the `GT_IND` node represents an array access; false otherwise.
9574     bool TryGetArrayInfo(GenTreeIndir* indir, ArrayInfo* arrayInfo)
9575     {
9576         if ((indir->gtFlags & GTF_IND_ARR_INDEX) == 0)
9577         {
9578             return false;
9579         }
9580
9581         if (indir->gtOp1->OperIs(GT_INDEX_ADDR))
9582         {
9583             GenTreeIndexAddr* const indexAddr = indir->gtOp1->AsIndexAddr();
9584             *arrayInfo = ArrayInfo(indexAddr->gtElemType, indexAddr->gtElemSize, indexAddr->gtElemOffset,
9585                                    indexAddr->gtStructElemClass);
9586             return true;
9587         }
9588
9589         bool found = GetArrayInfoMap()->Lookup(indir, arrayInfo);
9590         assert(found);
9591         return true;
9592     }
9593
9594     NodeToUnsignedMap* m_memorySsaMap[MemoryKindCount];
9595
9596     // In some cases, we want to assign intermediate SSA #'s to memory states, and know what nodes create those memory
9597     // states. (We do this for try blocks, where, if the try block doesn't do a call that loses track of the memory
9598     // state, all the possible memory states are possible initial states of the corresponding catch block(s).)
9599     NodeToUnsignedMap* GetMemorySsaMap(MemoryKind memoryKind)
9600     {
9601         if (memoryKind == GcHeap && byrefStatesMatchGcHeapStates)
9602         {
9603             // Use the same map for GCHeap and ByrefExposed when their states match.
9604             memoryKind = ByrefExposed;
9605         }
9606
9607         assert(memoryKind < MemoryKindCount);
9608         Compiler* compRoot = impInlineRoot();
9609         if (compRoot->m_memorySsaMap[memoryKind] == nullptr)
9610         {
9611             // Create a CompAllocator that labels sub-structure with CMK_ArrayInfoMap, and use that for allocation.
9612             CompAllocator ialloc(getAllocator(CMK_ArrayInfoMap));
9613             compRoot->m_memorySsaMap[memoryKind] = new (ialloc) NodeToUnsignedMap(ialloc);
9614         }
9615         return compRoot->m_memorySsaMap[memoryKind];
9616     }
9617
9618     // The Refany type is the only struct type whose structure is implicitly assumed by IL.  We need its fields.
9619     CORINFO_CLASS_HANDLE m_refAnyClass;
9620     CORINFO_FIELD_HANDLE GetRefanyDataField()
9621     {
9622         if (m_refAnyClass == nullptr)
9623         {
9624             m_refAnyClass = info.compCompHnd->getBuiltinClass(CLASSID_TYPED_BYREF);
9625         }
9626         return info.compCompHnd->getFieldInClass(m_refAnyClass, 0);
9627     }
9628     CORINFO_FIELD_HANDLE GetRefanyTypeField()
9629     {
9630         if (m_refAnyClass == nullptr)
9631         {
9632             m_refAnyClass = info.compCompHnd->getBuiltinClass(CLASSID_TYPED_BYREF);
9633         }
9634         return info.compCompHnd->getFieldInClass(m_refAnyClass, 1);
9635     }
9636
9637 #if VARSET_COUNTOPS
9638     static BitSetSupport::BitSetOpCounter m_varsetOpCounter;
9639 #endif
9640 #if ALLVARSET_COUNTOPS
9641     static BitSetSupport::BitSetOpCounter m_allvarsetOpCounter;
9642 #endif
9643
9644     static HelperCallProperties s_helperCallProperties;
9645
9646 #ifdef UNIX_AMD64_ABI
9647     static var_types GetTypeFromClassificationAndSizes(SystemVClassificationType classType, int size);
9648     static var_types GetEightByteType(const SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR& structDesc,
9649                                       unsigned                                                   slotNum);
9650
9651     static void GetStructTypeOffset(const SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR& structDesc,
9652                                     var_types*                                                 type0,
9653                                     var_types*                                                 type1,
9654                                     unsigned __int8*                                           offset0,
9655                                     unsigned __int8*                                           offset1);
9656
9657     void GetStructTypeOffset(CORINFO_CLASS_HANDLE typeHnd,
9658                              var_types*           type0,
9659                              var_types*           type1,
9660                              unsigned __int8*     offset0,
9661                              unsigned __int8*     offset1);
9662
9663 #endif // defined(UNIX_AMD64_ABI)
9664
9665     void fgMorphMultiregStructArgs(GenTreeCall* call);
9666     GenTree* fgMorphMultiregStructArg(GenTree* arg, fgArgTabEntry* fgEntryPtr);
9667
9668     bool killGCRefs(GenTree* tree);
9669
9670 }; // end of class Compiler
9671
9672 //---------------------------------------------------------------------------------------------------------------------
9673 // GenTreeVisitor: a flexible tree walker implemented using the curiosly-recurring-template pattern.
9674 //
9675 // This class implements a configurable walker for IR trees. There are five configuration options (defaults values are
9676 // shown in parentheses):
9677 //
9678 // - ComputeStack (false): when true, the walker will push each node onto the `m_ancestors` stack. "Ancestors" is a bit
9679 //                         of a misnomer, as the first entry will always be the current node.
9680 //
9681 // - DoPreOrder (false): when true, the walker will invoke `TVisitor::PreOrderVisit` with the current node as an
9682 //                       argument before visiting the node's operands.
9683 //
9684 // - DoPostOrder (false): when true, the walker will invoke `TVisitor::PostOrderVisit` with the current node as an
9685 //                        argument after visiting the node's operands.
9686 //
9687 // - DoLclVarsOnly (false): when true, the walker will only invoke `TVisitor::PreOrderVisit` for lclVar nodes.
9688 //                          `DoPreOrder` must be true if this option is true.
9689 //
9690 // - UseExecutionOrder (false): when true, then walker will visit a node's operands in execution order (e.g. if a
9691 //                              binary operator has the `GTF_REVERSE_OPS` flag set, the second operand will be
9692 //                              visited before the first).
9693 //
9694 // At least one of `DoPreOrder` and `DoPostOrder` must be specified.
9695 //
9696 // A simple pre-order visitor might look something like the following:
9697 //
9698 //     class CountingVisitor final : public GenTreeVisitor<CountingVisitor>
9699 //     {
9700 //     public:
9701 //         enum
9702 //         {
9703 //             DoPreOrder = true
9704 //         };
9705 //
9706 //         unsigned m_count;
9707 //
9708 //         CountingVisitor(Compiler* compiler)
9709 //             : GenTreeVisitor<CountingVisitor>(compiler), m_count(0)
9710 //         {
9711 //         }
9712 //
9713 //         Compiler::fgWalkResult PreOrderVisit(GenTree* node)
9714 //         {
9715 //             m_count++;
9716 //         }
9717 //     };
9718 //
9719 // This visitor would then be used like so:
9720 //
9721 //     CountingVisitor countingVisitor(compiler);
9722 //     countingVisitor.WalkTree(root);
9723 //
9724 template <typename TVisitor>
9725 class GenTreeVisitor
9726 {
9727 protected:
9728     typedef Compiler::fgWalkResult fgWalkResult;
9729
9730     enum
9731     {
9732         ComputeStack      = false,
9733         DoPreOrder        = false,
9734         DoPostOrder       = false,
9735         DoLclVarsOnly     = false,
9736         UseExecutionOrder = false,
9737     };
9738
9739     Compiler*            m_compiler;
9740     ArrayStack<GenTree*> m_ancestors;
9741
9742     GenTreeVisitor(Compiler* compiler) : m_compiler(compiler), m_ancestors(compiler->getAllocator(CMK_ArrayStack))
9743     {
9744         assert(compiler != nullptr);
9745
9746         static_assert_no_msg(TVisitor::DoPreOrder || TVisitor::DoPostOrder);
9747         static_assert_no_msg(!TVisitor::DoLclVarsOnly || TVisitor::DoPreOrder);
9748     }
9749
9750     fgWalkResult PreOrderVisit(GenTree** use, GenTree* user)
9751     {
9752         return fgWalkResult::WALK_CONTINUE;
9753     }
9754
9755     fgWalkResult PostOrderVisit(GenTree** use, GenTree* user)
9756     {
9757         return fgWalkResult::WALK_CONTINUE;
9758     }
9759
9760 public:
9761     fgWalkResult WalkTree(GenTree** use, GenTree* user)
9762     {
9763         assert(use != nullptr);
9764
9765         GenTree* node = *use;
9766
9767         if (TVisitor::ComputeStack)
9768         {
9769             m_ancestors.Push(node);
9770         }
9771
9772         fgWalkResult result = fgWalkResult::WALK_CONTINUE;
9773         if (TVisitor::DoPreOrder && !TVisitor::DoLclVarsOnly)
9774         {
9775             result = reinterpret_cast<TVisitor*>(this)->PreOrderVisit(use, user);
9776             if (result == fgWalkResult::WALK_ABORT)
9777             {
9778                 return result;
9779             }
9780
9781             node = *use;
9782             if ((node == nullptr) || (result == fgWalkResult::WALK_SKIP_SUBTREES))
9783             {
9784                 goto DONE;
9785             }
9786         }
9787
9788         switch (node->OperGet())
9789         {
9790             // Leaf lclVars
9791             case GT_LCL_VAR:
9792             case GT_LCL_FLD:
9793             case GT_LCL_VAR_ADDR:
9794             case GT_LCL_FLD_ADDR:
9795                 if (TVisitor::DoLclVarsOnly)
9796                 {
9797                     result = reinterpret_cast<TVisitor*>(this)->PreOrderVisit(use, user);
9798                     if (result == fgWalkResult::WALK_ABORT)
9799                     {
9800                         return result;
9801                     }
9802                 }
9803                 __fallthrough;
9804
9805             // Leaf nodes
9806             case GT_CATCH_ARG:
9807             case GT_LABEL:
9808             case GT_FTN_ADDR:
9809             case GT_RET_EXPR:
9810             case GT_CNS_INT:
9811             case GT_CNS_LNG:
9812             case GT_CNS_DBL:
9813             case GT_CNS_STR:
9814             case GT_MEMORYBARRIER:
9815             case GT_JMP:
9816             case GT_JCC:
9817             case GT_SETCC:
9818             case GT_NO_OP:
9819             case GT_START_NONGC:
9820             case GT_PROF_HOOK:
9821 #if !FEATURE_EH_FUNCLETS
9822             case GT_END_LFIN:
9823 #endif // !FEATURE_EH_FUNCLETS
9824             case GT_PHI_ARG:
9825             case GT_JMPTABLE:
9826             case GT_CLS_VAR:
9827             case GT_CLS_VAR_ADDR:
9828             case GT_ARGPLACE:
9829             case GT_PHYSREG:
9830             case GT_EMITNOP:
9831             case GT_PINVOKE_PROLOG:
9832             case GT_PINVOKE_EPILOG:
9833             case GT_IL_OFFSET:
9834                 break;
9835
9836             // Lclvar unary operators
9837             case GT_STORE_LCL_VAR:
9838             case GT_STORE_LCL_FLD:
9839                 if (TVisitor::DoLclVarsOnly)
9840                 {
9841                     result = reinterpret_cast<TVisitor*>(this)->PreOrderVisit(use, user);
9842                     if (result == fgWalkResult::WALK_ABORT)
9843                     {
9844                         return result;
9845                     }
9846                 }
9847                 __fallthrough;
9848
9849             // Standard unary operators
9850             case GT_NOT:
9851             case GT_NEG:
9852             case GT_BSWAP:
9853             case GT_BSWAP16:
9854             case GT_COPY:
9855             case GT_RELOAD:
9856             case GT_ARR_LENGTH:
9857             case GT_CAST:
9858             case GT_BITCAST:
9859             case GT_CKFINITE:
9860             case GT_LCLHEAP:
9861             case GT_ADDR:
9862             case GT_IND:
9863             case GT_OBJ:
9864             case GT_BLK:
9865             case GT_BOX:
9866             case GT_ALLOCOBJ:
9867             case GT_INIT_VAL:
9868             case GT_JTRUE:
9869             case GT_SWITCH:
9870             case GT_NULLCHECK:
9871             case GT_PUTARG_REG:
9872             case GT_PUTARG_STK:
9873             case GT_RETURNTRAP:
9874             case GT_NOP:
9875             case GT_RETURN:
9876             case GT_RETFILT:
9877             case GT_PHI:
9878             case GT_RUNTIMELOOKUP:
9879             {
9880                 GenTreeUnOp* const unOp = node->AsUnOp();
9881                 if (unOp->gtOp1 != nullptr)
9882                 {
9883                     result = WalkTree(&unOp->gtOp1, unOp);
9884                     if (result == fgWalkResult::WALK_ABORT)
9885                     {
9886                         return result;
9887                     }
9888                 }
9889                 break;
9890             }
9891
9892             // Special nodes
9893             case GT_CMPXCHG:
9894             {
9895                 GenTreeCmpXchg* const cmpXchg = node->AsCmpXchg();
9896
9897                 result = WalkTree(&cmpXchg->gtOpLocation, cmpXchg);
9898                 if (result == fgWalkResult::WALK_ABORT)
9899                 {
9900                     return result;
9901                 }
9902                 result = WalkTree(&cmpXchg->gtOpValue, cmpXchg);
9903                 if (result == fgWalkResult::WALK_ABORT)
9904                 {
9905                     return result;
9906                 }
9907                 result = WalkTree(&cmpXchg->gtOpComparand, cmpXchg);
9908                 if (result == fgWalkResult::WALK_ABORT)
9909                 {
9910                     return result;
9911                 }
9912                 break;
9913             }
9914
9915             case GT_ARR_BOUNDS_CHECK:
9916 #ifdef FEATURE_SIMD
9917             case GT_SIMD_CHK:
9918 #endif // FEATURE_SIMD
9919 #ifdef FEATURE_HW_INTRINSICS
9920             case GT_HW_INTRINSIC_CHK:
9921 #endif // FEATURE_HW_INTRINSICS
9922             {
9923                 GenTreeBoundsChk* const boundsChk = node->AsBoundsChk();
9924
9925                 result = WalkTree(&boundsChk->gtIndex, boundsChk);
9926                 if (result == fgWalkResult::WALK_ABORT)
9927                 {
9928                     return result;
9929                 }
9930                 result = WalkTree(&boundsChk->gtArrLen, boundsChk);
9931                 if (result == fgWalkResult::WALK_ABORT)
9932                 {
9933                     return result;
9934                 }
9935                 break;
9936             }
9937
9938             case GT_FIELD:
9939             {
9940                 GenTreeField* const field = node->AsField();
9941
9942                 if (field->gtFldObj != nullptr)
9943                 {
9944                     result = WalkTree(&field->gtFldObj, field);
9945                     if (result == fgWalkResult::WALK_ABORT)
9946                     {
9947                         return result;
9948                     }
9949                 }
9950                 break;
9951             }
9952
9953             case GT_ARR_ELEM:
9954             {
9955                 GenTreeArrElem* const arrElem = node->AsArrElem();
9956
9957                 result = WalkTree(&arrElem->gtArrObj, arrElem);
9958                 if (result == fgWalkResult::WALK_ABORT)
9959                 {
9960                     return result;
9961                 }
9962
9963                 const unsigned rank = arrElem->gtArrRank;
9964                 for (unsigned dim = 0; dim < rank; dim++)
9965                 {
9966                     result = WalkTree(&arrElem->gtArrInds[dim], arrElem);
9967                     if (result == fgWalkResult::WALK_ABORT)
9968                     {
9969                         return result;
9970                     }
9971                 }
9972                 break;
9973             }
9974
9975             case GT_ARR_OFFSET:
9976             {
9977                 GenTreeArrOffs* const arrOffs = node->AsArrOffs();
9978
9979                 result = WalkTree(&arrOffs->gtOffset, arrOffs);
9980                 if (result == fgWalkResult::WALK_ABORT)
9981                 {
9982                     return result;
9983                 }
9984                 result = WalkTree(&arrOffs->gtIndex, arrOffs);
9985                 if (result == fgWalkResult::WALK_ABORT)
9986                 {
9987                     return result;
9988                 }
9989                 result = WalkTree(&arrOffs->gtArrObj, arrOffs);
9990                 if (result == fgWalkResult::WALK_ABORT)
9991                 {
9992                     return result;
9993                 }
9994                 break;
9995             }
9996
9997             case GT_DYN_BLK:
9998             {
9999                 GenTreeDynBlk* const dynBlock = node->AsDynBlk();
10000
10001                 GenTree** op1Use = &dynBlock->gtOp1;
10002                 GenTree** op2Use = &dynBlock->gtDynamicSize;
10003
10004                 if (TVisitor::UseExecutionOrder && dynBlock->gtEvalSizeFirst)
10005                 {
10006                     std::swap(op1Use, op2Use);
10007                 }
10008
10009                 result = WalkTree(op1Use, dynBlock);
10010                 if (result == fgWalkResult::WALK_ABORT)
10011                 {
10012                     return result;
10013                 }
10014                 result = WalkTree(op2Use, dynBlock);
10015                 if (result == fgWalkResult::WALK_ABORT)
10016                 {
10017                     return result;
10018                 }
10019                 break;
10020             }
10021
10022             case GT_STORE_DYN_BLK:
10023             {
10024                 GenTreeDynBlk* const dynBlock = node->AsDynBlk();
10025
10026                 GenTree** op1Use = &dynBlock->gtOp1;
10027                 GenTree** op2Use = &dynBlock->gtOp2;
10028                 GenTree** op3Use = &dynBlock->gtDynamicSize;
10029
10030                 if (TVisitor::UseExecutionOrder)
10031                 {
10032                     if (dynBlock->IsReverseOp())
10033                     {
10034                         std::swap(op1Use, op2Use);
10035                     }
10036                     if (dynBlock->gtEvalSizeFirst)
10037                     {
10038                         std::swap(op3Use, op2Use);
10039                         std::swap(op2Use, op1Use);
10040                     }
10041                 }
10042
10043                 result = WalkTree(op1Use, dynBlock);
10044                 if (result == fgWalkResult::WALK_ABORT)
10045                 {
10046                     return result;
10047                 }
10048                 result = WalkTree(op2Use, dynBlock);
10049                 if (result == fgWalkResult::WALK_ABORT)
10050                 {
10051                     return result;
10052                 }
10053                 result = WalkTree(op3Use, dynBlock);
10054                 if (result == fgWalkResult::WALK_ABORT)
10055                 {
10056                     return result;
10057                 }
10058                 break;
10059             }
10060
10061             case GT_CALL:
10062             {
10063                 GenTreeCall* const call = node->AsCall();
10064
10065                 if (call->gtCallObjp != nullptr)
10066                 {
10067                     result = WalkTree(&call->gtCallObjp, call);
10068                     if (result == fgWalkResult::WALK_ABORT)
10069                     {
10070                         return result;
10071                     }
10072                 }
10073
10074                 for (GenTreeArgList* args = call->gtCallArgs; args != nullptr; args = args->Rest())
10075                 {
10076                     result = WalkTree(args->pCurrent(), call);
10077                     if (result == fgWalkResult::WALK_ABORT)
10078                     {
10079                         return result;
10080                     }
10081                 }
10082
10083                 for (GenTreeArgList* args = call->gtCallLateArgs; args != nullptr; args = args->Rest())
10084                 {
10085                     result = WalkTree(args->pCurrent(), call);
10086                     if (result == fgWalkResult::WALK_ABORT)
10087                     {
10088                         return result;
10089                     }
10090                 }
10091
10092                 if (call->gtCallType == CT_INDIRECT)
10093                 {
10094                     if (call->gtCallCookie != nullptr)
10095                     {
10096                         result = WalkTree(&call->gtCallCookie, call);
10097                         if (result == fgWalkResult::WALK_ABORT)
10098                         {
10099                             return result;
10100                         }
10101                     }
10102
10103                     result = WalkTree(&call->gtCallAddr, call);
10104                     if (result == fgWalkResult::WALK_ABORT)
10105                     {
10106                         return result;
10107                     }
10108                 }
10109
10110                 if (call->gtControlExpr != nullptr)
10111                 {
10112                     result = WalkTree(&call->gtControlExpr, call);
10113                     if (result == fgWalkResult::WALK_ABORT)
10114                     {
10115                         return result;
10116                     }
10117                 }
10118
10119                 break;
10120             }
10121
10122             // Binary nodes
10123             default:
10124             {
10125                 assert(node->OperIsBinary());
10126
10127                 GenTreeOp* const op = node->AsOp();
10128
10129                 GenTree** op1Use = &op->gtOp1;
10130                 GenTree** op2Use = &op->gtOp2;
10131
10132                 if (TVisitor::UseExecutionOrder && node->IsReverseOp())
10133                 {
10134                     std::swap(op1Use, op2Use);
10135                 }
10136
10137                 if (*op1Use != nullptr)
10138                 {
10139                     result = WalkTree(op1Use, op);
10140                     if (result == fgWalkResult::WALK_ABORT)
10141                     {
10142                         return result;
10143                     }
10144                 }
10145
10146                 if (*op2Use != nullptr)
10147                 {
10148                     result = WalkTree(op2Use, op);
10149                     if (result == fgWalkResult::WALK_ABORT)
10150                     {
10151                         return result;
10152                     }
10153                 }
10154                 break;
10155             }
10156         }
10157
10158     DONE:
10159         // Finally, visit the current node
10160         if (TVisitor::DoPostOrder)
10161         {
10162             result = reinterpret_cast<TVisitor*>(this)->PostOrderVisit(use, user);
10163         }
10164
10165         if (TVisitor::ComputeStack)
10166         {
10167             m_ancestors.Pop();
10168         }
10169
10170         return result;
10171     }
10172 };
10173
10174 template <bool computeStack, bool doPreOrder, bool doPostOrder, bool doLclVarsOnly, bool useExecutionOrder>
10175 class GenericTreeWalker final
10176     : public GenTreeVisitor<GenericTreeWalker<computeStack, doPreOrder, doPostOrder, doLclVarsOnly, useExecutionOrder>>
10177 {
10178 public:
10179     enum
10180     {
10181         ComputeStack      = computeStack,
10182         DoPreOrder        = doPreOrder,
10183         DoPostOrder       = doPostOrder,
10184         DoLclVarsOnly     = doLclVarsOnly,
10185         UseExecutionOrder = useExecutionOrder,
10186     };
10187
10188 private:
10189     Compiler::fgWalkData* m_walkData;
10190
10191 public:
10192     GenericTreeWalker(Compiler::fgWalkData* walkData)
10193         : GenTreeVisitor<GenericTreeWalker<computeStack, doPreOrder, doPostOrder, doLclVarsOnly, useExecutionOrder>>(
10194               walkData->compiler)
10195         , m_walkData(walkData)
10196     {
10197         assert(walkData != nullptr);
10198
10199         if (computeStack)
10200         {
10201             walkData->parentStack = &this->m_ancestors;
10202         }
10203     }
10204
10205     Compiler::fgWalkResult PreOrderVisit(GenTree** use, GenTree* user)
10206     {
10207         m_walkData->parent = user;
10208         return m_walkData->wtprVisitorFn(use, m_walkData);
10209     }
10210
10211     Compiler::fgWalkResult PostOrderVisit(GenTree** use, GenTree* user)
10212     {
10213         m_walkData->parent = user;
10214         return m_walkData->wtpoVisitorFn(use, m_walkData);
10215     }
10216 };
10217
10218 /*
10219 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
10220 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
10221 XX                                                                           XX
10222 XX                   Miscellaneous Compiler stuff                            XX
10223 XX                                                                           XX
10224 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
10225 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
10226 */
10227
10228 // Values used to mark the types a stack slot is used for
10229
10230 const unsigned TYPE_REF_INT      = 0x01; // slot used as a 32-bit int
10231 const unsigned TYPE_REF_LNG      = 0x02; // slot used as a 64-bit long
10232 const unsigned TYPE_REF_FLT      = 0x04; // slot used as a 32-bit float
10233 const unsigned TYPE_REF_DBL      = 0x08; // slot used as a 64-bit float
10234 const unsigned TYPE_REF_PTR      = 0x10; // slot used as a 32-bit pointer
10235 const unsigned TYPE_REF_BYR      = 0x20; // slot used as a byref pointer
10236 const unsigned TYPE_REF_STC      = 0x40; // slot used as a struct
10237 const unsigned TYPE_REF_TYPEMASK = 0x7F; // bits that represent the type
10238
10239 // const unsigned TYPE_REF_ADDR_TAKEN  = 0x80; // slots address was taken
10240
10241 /*****************************************************************************
10242  *
10243  *  Variables to keep track of total code amounts.
10244  */
10245
10246 #if DISPLAY_SIZES
10247
10248 extern size_t grossVMsize;
10249 extern size_t grossNCsize;
10250 extern size_t totalNCsize;
10251
10252 extern unsigned genMethodICnt;
10253 extern unsigned genMethodNCnt;
10254 extern size_t   gcHeaderISize;
10255 extern size_t   gcPtrMapISize;
10256 extern size_t   gcHeaderNSize;
10257 extern size_t   gcPtrMapNSize;
10258
10259 #endif // DISPLAY_SIZES
10260
10261 /*****************************************************************************
10262  *
10263  *  Variables to keep track of basic block counts (more data on 1 BB methods)
10264  */
10265
10266 #if COUNT_BASIC_BLOCKS
10267 extern Histogram bbCntTable;
10268 extern Histogram bbOneBBSizeTable;
10269 #endif
10270
10271 /*****************************************************************************
10272  *
10273  *  Used by optFindNaturalLoops to gather statistical information such as
10274  *   - total number of natural loops
10275  *   - number of loops with 1, 2, ... exit conditions
10276  *   - number of loops that have an iterator (for like)
10277  *   - number of loops that have a constant iterator
10278  */
10279
10280 #if COUNT_LOOPS
10281
10282 extern unsigned totalLoopMethods;        // counts the total number of methods that have natural loops
10283 extern unsigned maxLoopsPerMethod;       // counts the maximum number of loops a method has
10284 extern unsigned totalLoopOverflows;      // # of methods that identified more loops than we can represent
10285 extern unsigned totalLoopCount;          // counts the total number of natural loops
10286 extern unsigned totalUnnatLoopCount;     // counts the total number of (not-necessarily natural) loops
10287 extern unsigned totalUnnatLoopOverflows; // # of methods that identified more unnatural loops than we can represent
10288 extern unsigned iterLoopCount;           // counts the # of loops with an iterator (for like)
10289 extern unsigned simpleTestLoopCount;     // counts the # of loops with an iterator and a simple loop condition (iter <
10290                                          // const)
10291 extern unsigned  constIterLoopCount;     // counts the # of loops with a constant iterator (for like)
10292 extern bool      hasMethodLoops;         // flag to keep track if we already counted a method as having loops
10293 extern unsigned  loopsThisMethod;        // counts the number of loops in the current method
10294 extern bool      loopOverflowThisMethod; // True if we exceeded the max # of loops in the method.
10295 extern Histogram loopCountTable;         // Histogram of loop counts
10296 extern Histogram loopExitCountTable;     // Histogram of loop exit counts
10297
10298 #endif // COUNT_LOOPS
10299
10300 /*****************************************************************************
10301  * variables to keep track of how many iterations we go in a dataflow pass
10302  */
10303
10304 #if DATAFLOW_ITER
10305
10306 extern unsigned CSEiterCount; // counts the # of iteration for the CSE dataflow
10307 extern unsigned CFiterCount;  // counts the # of iteration for the Const Folding dataflow
10308
10309 #endif // DATAFLOW_ITER
10310
10311 #if MEASURE_BLOCK_SIZE
10312 extern size_t genFlowNodeSize;
10313 extern size_t genFlowNodeCnt;
10314 #endif // MEASURE_BLOCK_SIZE
10315
10316 #if MEASURE_NODE_SIZE
10317 struct NodeSizeStats
10318 {
10319     void Init()
10320     {
10321         genTreeNodeCnt        = 0;
10322         genTreeNodeSize       = 0;
10323         genTreeNodeActualSize = 0;
10324     }
10325
10326     // Count of tree nodes allocated.
10327     unsigned __int64 genTreeNodeCnt;
10328
10329     // The size we allocate.
10330     unsigned __int64 genTreeNodeSize;
10331
10332     // The actual size of the node. Note that the actual size will likely be smaller
10333     // than the allocated size, but we sometimes use SetOper()/ChangeOper() to change
10334     // a smaller node to a larger one. TODO-Cleanup: add stats on
10335     // SetOper()/ChangeOper() usage to quantify this.
10336     unsigned __int64 genTreeNodeActualSize;
10337 };
10338 extern NodeSizeStats genNodeSizeStats;        // Total node size stats
10339 extern NodeSizeStats genNodeSizeStatsPerFunc; // Per-function node size stats
10340 extern Histogram     genTreeNcntHist;
10341 extern Histogram     genTreeNsizHist;
10342 #endif // MEASURE_NODE_SIZE
10343
10344 /*****************************************************************************
10345  *  Count fatal errors (including noway_asserts).
10346  */
10347
10348 #if MEASURE_FATAL
10349 extern unsigned fatal_badCode;
10350 extern unsigned fatal_noWay;
10351 extern unsigned fatal_NOMEM;
10352 extern unsigned fatal_noWayAssertBody;
10353 #ifdef DEBUG
10354 extern unsigned fatal_noWayAssertBodyArgs;
10355 #endif // DEBUG
10356 extern unsigned fatal_NYI;
10357 #endif // MEASURE_FATAL
10358
10359 /*****************************************************************************
10360  * Codegen
10361  */
10362
10363 #ifdef _TARGET_XARCH_
10364
10365 const instruction INS_SHIFT_LEFT_LOGICAL  = INS_shl;
10366 const instruction INS_SHIFT_RIGHT_LOGICAL = INS_shr;
10367 const instruction INS_SHIFT_RIGHT_ARITHM  = INS_sar;
10368
10369 const instruction INS_AND             = INS_and;
10370 const instruction INS_OR              = INS_or;
10371 const instruction INS_XOR             = INS_xor;
10372 const instruction INS_NEG             = INS_neg;
10373 const instruction INS_TEST            = INS_test;
10374 const instruction INS_MUL             = INS_imul;
10375 const instruction INS_SIGNED_DIVIDE   = INS_idiv;
10376 const instruction INS_UNSIGNED_DIVIDE = INS_div;
10377 const instruction INS_BREAKPOINT      = INS_int3;
10378 const instruction INS_ADDC            = INS_adc;
10379 const instruction INS_SUBC            = INS_sbb;
10380 const instruction INS_NOT             = INS_not;
10381
10382 #endif // _TARGET_XARCH_
10383
10384 #ifdef _TARGET_ARM_
10385
10386 const instruction INS_SHIFT_LEFT_LOGICAL  = INS_lsl;
10387 const instruction INS_SHIFT_RIGHT_LOGICAL = INS_lsr;
10388 const instruction INS_SHIFT_RIGHT_ARITHM  = INS_asr;
10389
10390 const instruction INS_AND             = INS_and;
10391 const instruction INS_OR              = INS_orr;
10392 const instruction INS_XOR             = INS_eor;
10393 const instruction INS_NEG             = INS_rsb;
10394 const instruction INS_TEST            = INS_tst;
10395 const instruction INS_MUL             = INS_mul;
10396 const instruction INS_MULADD          = INS_mla;
10397 const instruction INS_SIGNED_DIVIDE   = INS_sdiv;
10398 const instruction INS_UNSIGNED_DIVIDE = INS_udiv;
10399 const instruction INS_BREAKPOINT      = INS_bkpt;
10400 const instruction INS_ADDC            = INS_adc;
10401 const instruction INS_SUBC            = INS_sbc;
10402 const instruction INS_NOT             = INS_mvn;
10403
10404 const instruction INS_ABS  = INS_vabs;
10405 const instruction INS_SQRT = INS_vsqrt;
10406
10407 #endif // _TARGET_ARM_
10408
10409 #ifdef _TARGET_ARM64_
10410
10411 const instruction INS_MULADD     = INS_madd;
10412 const instruction INS_BREAKPOINT = INS_bkpt;
10413
10414 const instruction INS_ABS  = INS_fabs;
10415 const instruction INS_SQRT = INS_fsqrt;
10416
10417 #endif // _TARGET_ARM64_
10418
10419 /*****************************************************************************/
10420
10421 extern const BYTE genTypeSizes[];
10422 extern const BYTE genTypeAlignments[];
10423 extern const BYTE genTypeStSzs[];
10424 extern const BYTE genActualTypes[];
10425
10426 /*****************************************************************************/
10427
10428 // VERY_LARGE_FRAME_SIZE_REG_MASK is the set of registers we need to use for
10429 // the probing loop generated for very large stack frames (see `getVeryLargeFrameSize`).
10430
10431 #ifdef _TARGET_ARM_
10432 #define VERY_LARGE_FRAME_SIZE_REG_MASK (RBM_R4 | RBM_R5 | RBM_R6)
10433 #elif defined(_TARGET_ARM64_)
10434 #define VERY_LARGE_FRAME_SIZE_REG_MASK (RBM_R9 | RBM_R10 | RBM_R11)
10435 #endif
10436
10437 /*****************************************************************************/
10438
10439 extern BasicBlock dummyBB;
10440
10441 /*****************************************************************************/
10442 /*****************************************************************************/
10443
10444 // foreach_treenode_execution_order: An iterator that iterates through all the tree
10445 // nodes of a statement in execution order.
10446 //      __stmt: a GT_STMT type GenTree*
10447 //      __node: a GenTree*, already declared, that gets updated with each node in the statement, in execution order
10448
10449 #define foreach_treenode_execution_order(__node, __stmt)                                                               \
10450     for ((__node) = (__stmt)->gtStmt.gtStmtList; (__node); (__node) = (__node)->gtNext)
10451
10452 // foreach_block: An iterator over all blocks in the function.
10453 //    __compiler: the Compiler* object
10454 //    __block   : a BasicBlock*, already declared, that gets updated each iteration.
10455
10456 #define foreach_block(__compiler, __block)                                                                             \
10457     for ((__block) = (__compiler)->fgFirstBB; (__block); (__block) = (__block)->bbNext)
10458
10459 /*****************************************************************************/
10460 /*****************************************************************************/
10461
10462 #ifdef DEBUG
10463
10464 void dumpConvertedVarSet(Compiler* comp, VARSET_VALARG_TP vars);
10465
10466 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
10467 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
10468 XX                                                                           XX
10469 XX                          Debugging helpers                                XX
10470 XX                                                                           XX
10471 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
10472 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
10473 */
10474
10475 /*****************************************************************************/
10476 /* The following functions are intended to be called from the debugger, to dump
10477  * various data structures. The can be used in the debugger Watch or Quick Watch
10478  * windows. They are designed to be short to type and take as few arguments as
10479  * possible. The 'c' versions take a Compiler*, whereas the 'd' versions use the TlsCompiler.
10480  * See the function definition comment for more details.
10481  */
10482
10483 void cBlock(Compiler* comp, BasicBlock* block);
10484 void cBlocks(Compiler* comp);
10485 void cBlocksV(Compiler* comp);
10486 void cTree(Compiler* comp, GenTree* tree);
10487 void cTrees(Compiler* comp);
10488 void cEH(Compiler* comp);
10489 void cVar(Compiler* comp, unsigned lclNum);
10490 void cVarDsc(Compiler* comp, LclVarDsc* varDsc);
10491 void cVars(Compiler* comp);
10492 void cVarsFinal(Compiler* comp);
10493 void cBlockPreds(Compiler* comp, BasicBlock* block);
10494 void cReach(Compiler* comp);
10495 void cDoms(Compiler* comp);
10496 void cLiveness(Compiler* comp);
10497 void cCVarSet(Compiler* comp, VARSET_VALARG_TP vars);
10498
10499 void cFuncIR(Compiler* comp);
10500 void cBlockIR(Compiler* comp, BasicBlock* block);
10501 void cLoopIR(Compiler* comp, Compiler::LoopDsc* loop);
10502 void cTreeIR(Compiler* comp, GenTree* tree);
10503 int cTreeTypeIR(Compiler* comp, GenTree* tree);
10504 int cTreeKindsIR(Compiler* comp, GenTree* tree);
10505 int cTreeFlagsIR(Compiler* comp, GenTree* tree);
10506 int cOperandIR(Compiler* comp, GenTree* operand);
10507 int cLeafIR(Compiler* comp, GenTree* tree);
10508 int cIndirIR(Compiler* comp, GenTree* tree);
10509 int cListIR(Compiler* comp, GenTree* list);
10510 int cSsaNumIR(Compiler* comp, GenTree* tree);
10511 int cValNumIR(Compiler* comp, GenTree* tree);
10512 int cDependsIR(Compiler* comp, GenTree* comma, bool* first);
10513
10514 void dBlock(BasicBlock* block);
10515 void dBlocks();
10516 void dBlocksV();
10517 void dTree(GenTree* tree);
10518 void dTrees();
10519 void dEH();
10520 void dVar(unsigned lclNum);
10521 void dVarDsc(LclVarDsc* varDsc);
10522 void dVars();
10523 void dVarsFinal();
10524 void dBlockPreds(BasicBlock* block);
10525 void dReach();
10526 void dDoms();
10527 void dLiveness();
10528 void dCVarSet(VARSET_VALARG_TP vars);
10529
10530 void dRegMask(regMaskTP mask);
10531
10532 void dFuncIR();
10533 void dBlockIR(BasicBlock* block);
10534 void dTreeIR(GenTree* tree);
10535 void dLoopIR(Compiler::LoopDsc* loop);
10536 void dLoopNumIR(unsigned loopNum);
10537 int dTabStopIR(int curr, int tabstop);
10538 int dTreeTypeIR(GenTree* tree);
10539 int dTreeKindsIR(GenTree* tree);
10540 int dTreeFlagsIR(GenTree* tree);
10541 int dOperandIR(GenTree* operand);
10542 int dLeafIR(GenTree* tree);
10543 int dIndirIR(GenTree* tree);
10544 int dListIR(GenTree* list);
10545 int dSsaNumIR(GenTree* tree);
10546 int dValNumIR(GenTree* tree);
10547 int dDependsIR(GenTree* comma);
10548 void dFormatIR();
10549
10550 GenTree* dFindTree(GenTree* tree, unsigned id);
10551 GenTree* dFindTree(unsigned id);
10552 GenTreeStmt* dFindStmt(unsigned id);
10553 BasicBlock* dFindBlock(unsigned bbNum);
10554
10555 #endif // DEBUG
10556
10557 #include "compiler.hpp" // All the shared inline functions
10558
10559 /*****************************************************************************/
10560 #endif //_COMPILER_H_
10561 /*****************************************************************************/