Enable the HWIntrinsic extension methods and remove the instance implementations...
[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, var_types type = TYP_DOUBLE);
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     // Given an address expression, compute its costs and addressing mode opportunities,
2559     // and mark addressing mode candidates as GTF_DONT_CSE.
2560     // TODO-Throughput - Consider actually instantiating these early, to avoid
2561     // having to re-run the algorithm that looks for them (might also improve CQ).
2562     bool gtMarkAddrMode(GenTree* addr, int* costEx, int* costSz, var_types type);
2563
2564     unsigned gtSetEvalOrder(GenTree* tree);
2565
2566     void gtSetStmtInfo(GenTree* stmt);
2567
2568     // Returns "true" iff "node" has any of the side effects in "flags".
2569     bool gtNodeHasSideEffects(GenTree* node, unsigned flags);
2570
2571     // Returns "true" iff "tree" or its (transitive) children have any of the side effects in "flags".
2572     bool gtTreeHasSideEffects(GenTree* tree, unsigned flags);
2573
2574     // Appends 'expr' in front of 'list'
2575     //    'list' will typically start off as 'nullptr'
2576     //    when 'list' is non-null a GT_COMMA node is used to insert 'expr'
2577     GenTree* gtBuildCommaList(GenTree* list, GenTree* expr);
2578
2579     void gtExtractSideEffList(GenTree*  expr,
2580                               GenTree** pList,
2581                               unsigned  flags      = GTF_SIDE_EFFECT,
2582                               bool      ignoreRoot = false);
2583
2584     GenTree* gtGetThisArg(GenTreeCall* call);
2585
2586     // Static fields of struct types (and sometimes the types that those are reduced to) are represented by having the
2587     // static field contain an object pointer to the boxed struct.  This simplifies the GC implementation...but
2588     // complicates the JIT somewhat.  This predicate returns "true" iff a node with type "fieldNodeType", representing
2589     // the given "fldHnd", is such an object pointer.
2590     bool gtIsStaticFieldPtrToBoxedStruct(var_types fieldNodeType, CORINFO_FIELD_HANDLE fldHnd);
2591
2592     // Return true if call is a recursive call; return false otherwise.
2593     // Note when inlining, this looks for calls back to the root method.
2594     bool gtIsRecursiveCall(GenTreeCall* call)
2595     {
2596         return gtIsRecursiveCall(call->gtCallMethHnd);
2597     }
2598
2599     bool gtIsRecursiveCall(CORINFO_METHOD_HANDLE callMethodHandle)
2600     {
2601         return (callMethodHandle == impInlineRoot()->info.compMethodHnd);
2602     }
2603
2604     //-------------------------------------------------------------------------
2605
2606     GenTree* gtFoldExpr(GenTree* tree);
2607     GenTree*
2608 #ifdef __clang__
2609         // TODO-Amd64-Unix: Remove this when the clang optimizer is fixed and/or the method implementation is
2610         // refactored in a simpler code. This is a workaround for a bug in the clang-3.5 optimizer. The issue is that in
2611         // release build the optimizer is mistyping (or just wrongly decides to use 32 bit operation for a corner case
2612         // of MIN_LONG) the args of the (ltemp / lval2) to int (it does a 32 bit div operation instead of 64 bit) - see
2613         // the implementation of the method in gentree.cpp. For the case of lval1 and lval2 equal to MIN_LONG
2614         // (0x8000000000000000) this results in raising a SIGFPE. The method implementation is rather complex. Disable
2615         // optimizations for now.
2616         __attribute__((optnone))
2617 #endif // __clang__
2618         gtFoldExprConst(GenTree* tree);
2619     GenTree* gtFoldExprSpecial(GenTree* tree);
2620     GenTree* gtFoldExprCompare(GenTree* tree);
2621     GenTree* gtCreateHandleCompare(genTreeOps             oper,
2622                                    GenTree*               op1,
2623                                    GenTree*               op2,
2624                                    CorInfoInlineTypeCheck typeCheckInliningResult);
2625     GenTree* gtFoldExprCall(GenTreeCall* call);
2626     GenTree* gtFoldTypeCompare(GenTree* tree);
2627     GenTree* gtFoldTypeEqualityCall(CorInfoIntrinsics methodID, GenTree* op1, GenTree* op2);
2628
2629     // Options to control behavior of gtTryRemoveBoxUpstreamEffects
2630     enum BoxRemovalOptions
2631     {
2632         BR_REMOVE_AND_NARROW, // remove effects, minimize remaining work, return possibly narrowed source tree
2633         BR_REMOVE_AND_NARROW_WANT_TYPE_HANDLE, // remove effects and minimize remaining work, return type handle tree
2634         BR_REMOVE_BUT_NOT_NARROW,              // remove effects, return original source tree
2635         BR_DONT_REMOVE,                        // check if removal is possible, return copy source tree
2636         BR_DONT_REMOVE_WANT_TYPE_HANDLE,       // check if removal is possible, return type handle tree
2637         BR_MAKE_LOCAL_COPY                     // revise box to copy to temp local and return local's address
2638     };
2639
2640     GenTree* gtTryRemoveBoxUpstreamEffects(GenTree* tree, BoxRemovalOptions options = BR_REMOVE_AND_NARROW);
2641     GenTree* gtOptimizeEnumHasFlag(GenTree* thisOp, GenTree* flagOp);
2642
2643     //-------------------------------------------------------------------------
2644     // Get the handle, if any.
2645     CORINFO_CLASS_HANDLE gtGetStructHandleIfPresent(GenTree* tree);
2646     // Get the handle, and assert if not found.
2647     CORINFO_CLASS_HANDLE gtGetStructHandle(GenTree* tree);
2648     // Get the handle for a ref type.
2649     CORINFO_CLASS_HANDLE gtGetClassHandle(GenTree* tree, bool* pIsExact, bool* pIsNonNull);
2650     // Get the class handle for an helper call
2651     CORINFO_CLASS_HANDLE gtGetHelperCallClassHandle(GenTreeCall* call, bool* pIsExact, bool* pIsNonNull);
2652     // Get the element handle for an array of ref type.
2653     CORINFO_CLASS_HANDLE gtGetArrayElementClassHandle(GenTree* array);
2654     // Get a class handle from a helper call argument
2655     CORINFO_CLASS_HANDLE gtGetHelperArgClassHandle(GenTree*  array,
2656                                                    unsigned* runtimeLookupCount = nullptr,
2657                                                    GenTree** handleTree         = nullptr);
2658     // Get the class handle for a field
2659     CORINFO_CLASS_HANDLE gtGetFieldClassHandle(CORINFO_FIELD_HANDLE fieldHnd, bool* pIsExact, bool* pIsNonNull);
2660     // Check if this tree is a gc static base helper call
2661     bool gtIsStaticGCBaseHelperCall(GenTree* tree);
2662
2663 //-------------------------------------------------------------------------
2664 // Functions to display the trees
2665
2666 #ifdef DEBUG
2667     void gtDispNode(GenTree* tree, IndentStack* indentStack, __in_z const char* msg, bool isLIR);
2668
2669     void gtDispVN(GenTree* tree);
2670     void gtDispConst(GenTree* tree);
2671     void gtDispLeaf(GenTree* tree, IndentStack* indentStack);
2672     void gtDispNodeName(GenTree* tree);
2673     void gtDispRegVal(GenTree* tree);
2674
2675     enum IndentInfo
2676     {
2677         IINone,
2678         IIArc,
2679         IIArcTop,
2680         IIArcBottom,
2681         IIEmbedded,
2682         IIError,
2683         IndentInfoCount
2684     };
2685     void gtDispChild(GenTree*             child,
2686                      IndentStack*         indentStack,
2687                      IndentInfo           arcType,
2688                      __in_opt const char* msg     = nullptr,
2689                      bool                 topOnly = false);
2690     void gtDispTree(GenTree*             tree,
2691                     IndentStack*         indentStack = nullptr,
2692                     __in_opt const char* msg         = nullptr,
2693                     bool                 topOnly     = false,
2694                     bool                 isLIR       = false);
2695     void gtGetLclVarNameInfo(unsigned lclNum, const char** ilKindOut, const char** ilNameOut, unsigned* ilNumOut);
2696     int gtGetLclVarName(unsigned lclNum, char* buf, unsigned buf_remaining);
2697     char* gtGetLclVarName(unsigned lclNum);
2698     void gtDispLclVar(unsigned varNum, bool padForBiggestDisp = true);
2699     void gtDispTreeList(GenTree* tree, IndentStack* indentStack = nullptr);
2700     void gtGetArgMsg(GenTreeCall* call, GenTree* arg, unsigned argNum, int listCount, char* bufp, unsigned bufLength);
2701     void gtGetLateArgMsg(GenTreeCall* call, GenTree* arg, int argNum, int listCount, char* bufp, unsigned bufLength);
2702     void gtDispArgList(GenTreeCall* call, IndentStack* indentStack);
2703     void gtDispFieldSeq(FieldSeqNode* pfsn);
2704
2705     void gtDispRange(LIR::ReadOnlyRange const& range);
2706
2707     void gtDispTreeRange(LIR::Range& containingRange, GenTree* tree);
2708
2709     void gtDispLIRNode(GenTree* node, const char* prefixMsg = nullptr);
2710 #endif
2711
2712     // For tree walks
2713
2714     enum fgWalkResult
2715     {
2716         WALK_CONTINUE,
2717         WALK_SKIP_SUBTREES,
2718         WALK_ABORT
2719     };
2720     struct fgWalkData;
2721     typedef fgWalkResult(fgWalkPreFn)(GenTree** pTree, fgWalkData* data);
2722     typedef fgWalkResult(fgWalkPostFn)(GenTree** pTree, fgWalkData* data);
2723
2724 #ifdef DEBUG
2725     static fgWalkPreFn gtAssertColonCond;
2726 #endif
2727     static fgWalkPreFn gtMarkColonCond;
2728     static fgWalkPreFn gtClearColonCond;
2729
2730     GenTree** gtFindLink(GenTree* stmt, GenTree* node);
2731     bool gtHasCatchArg(GenTree* tree);
2732
2733     typedef ArrayStack<GenTree*> GenTreeStack;
2734
2735     static bool gtHasCallOnStack(GenTreeStack* parentStack);
2736
2737 //=========================================================================
2738 // BasicBlock functions
2739 #ifdef DEBUG
2740     // This is a debug flag we will use to assert when creating block during codegen
2741     // as this interferes with procedure splitting. If you know what you're doing, set
2742     // it to true before creating the block. (DEBUG only)
2743     bool fgSafeBasicBlockCreation;
2744 #endif
2745
2746     BasicBlock* bbNewBasicBlock(BBjumpKinds jumpKind);
2747
2748     /*
2749     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2750     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2751     XX                                                                           XX
2752     XX                           LclVarsInfo                                     XX
2753     XX                                                                           XX
2754     XX   The variables to be used by the code generator.                         XX
2755     XX                                                                           XX
2756     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2757     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2758     */
2759
2760     //
2761     // For both PROMOTION_TYPE_NONE and PROMOTION_TYPE_DEPENDENT the struct will
2762     // be placed in the stack frame and it's fields must be laid out sequentially.
2763     //
2764     // For PROMOTION_TYPE_INDEPENDENT each of the struct's fields is replaced by
2765     //  a local variable that can be enregistered or placed in the stack frame.
2766     //  The fields do not need to be laid out sequentially
2767     //
2768     enum lvaPromotionType
2769     {
2770         PROMOTION_TYPE_NONE,        // The struct local is not promoted
2771         PROMOTION_TYPE_INDEPENDENT, // The struct local is promoted,
2772                                     //   and its field locals are independent of its parent struct local.
2773         PROMOTION_TYPE_DEPENDENT    // The struct local is promoted,
2774                                     //   but its field locals depend on its parent struct local.
2775     };
2776
2777     static int __cdecl RefCntCmp(const void* op1, const void* op2);
2778     static int __cdecl WtdRefCntCmp(const void* op1, const void* op2);
2779
2780     /*****************************************************************************/
2781
2782     enum FrameLayoutState
2783     {
2784         NO_FRAME_LAYOUT,
2785         INITIAL_FRAME_LAYOUT,
2786         PRE_REGALLOC_FRAME_LAYOUT,
2787         REGALLOC_FRAME_LAYOUT,
2788         TENTATIVE_FRAME_LAYOUT,
2789         FINAL_FRAME_LAYOUT
2790     };
2791
2792 public:
2793     RefCountState lvaRefCountState; // Current local ref count state
2794
2795     bool lvaLocalVarRefCounted() const
2796     {
2797         return lvaRefCountState == RCS_NORMAL;
2798     }
2799
2800     bool     lvaTrackedFixed; // true: We cannot add new 'tracked' variable
2801     unsigned lvaCount;        // total number of locals
2802
2803     unsigned   lvaRefCount; // total number of references to locals
2804     LclVarDsc* lvaTable;    // variable descriptor table
2805     unsigned   lvaTableCnt; // lvaTable size (>= lvaCount)
2806
2807     LclVarDsc** lvaRefSorted; // table sorted by refcount
2808
2809     unsigned short lvaTrackedCount;       // actual # of locals being tracked
2810     unsigned lvaTrackedCountInSizeTUnits; // min # of size_t's sufficient to hold a bit for all the locals being tracked
2811
2812 #ifdef DEBUG
2813     VARSET_TP lvaTrackedVars; // set of tracked variables
2814 #endif
2815 #ifndef _TARGET_64BIT_
2816     VARSET_TP lvaLongVars; // set of long (64-bit) variables
2817 #endif
2818     VARSET_TP lvaFloatVars; // set of floating-point (32-bit and 64-bit) variables
2819
2820     unsigned lvaCurEpoch; // VarSets are relative to a specific set of tracked var indices.
2821                           // It that changes, this changes.  VarSets from different epochs
2822                           // cannot be meaningfully combined.
2823
2824     unsigned GetCurLVEpoch()
2825     {
2826         return lvaCurEpoch;
2827     }
2828
2829     // reverse map of tracked number to var number
2830     unsigned* lvaTrackedToVarNum;
2831
2832 #if DOUBLE_ALIGN
2833 #ifdef DEBUG
2834     // # of procs compiled a with double-aligned stack
2835     static unsigned s_lvaDoubleAlignedProcsCount;
2836 #endif
2837 #endif
2838
2839     // Getters and setters for address-exposed and do-not-enregister local var properties.
2840     bool lvaVarAddrExposed(unsigned varNum);
2841     void lvaSetVarAddrExposed(unsigned varNum);
2842     bool lvaVarDoNotEnregister(unsigned varNum);
2843 #ifdef DEBUG
2844     // Reasons why we can't enregister.  Some of these correspond to debug properties of local vars.
2845     enum DoNotEnregisterReason
2846     {
2847         DNER_AddrExposed,
2848         DNER_IsStruct,
2849         DNER_LocalField,
2850         DNER_VMNeedsStackAddr,
2851         DNER_LiveInOutOfHandler,
2852         DNER_LiveAcrossUnmanagedCall,
2853         DNER_BlockOp,     // Is read or written via a block operation that explicitly takes the address.
2854         DNER_IsStructArg, // Is a struct passed as an argument in a way that requires a stack location.
2855         DNER_DepField,    // It is a field of a dependently promoted struct
2856         DNER_NoRegVars,   // opts.compFlags & CLFLG_REGVAR is not set
2857         DNER_MinOptsGC,   // It is a GC Ref and we are compiling MinOpts
2858 #if !defined(_TARGET_64BIT_)
2859         DNER_LongParamField, // It is a decomposed field of a long parameter.
2860 #endif
2861 #ifdef JIT32_GCENCODER
2862         DNER_PinningRef,
2863 #endif
2864     };
2865 #endif
2866     void lvaSetVarDoNotEnregister(unsigned varNum DEBUGARG(DoNotEnregisterReason reason));
2867
2868     unsigned lvaVarargsHandleArg;
2869 #ifdef _TARGET_X86_
2870     unsigned lvaVarargsBaseOfStkArgs; // Pointer (computed based on incoming varargs handle) to the start of the stack
2871                                       // arguments
2872 #endif                                // _TARGET_X86_
2873
2874     unsigned lvaInlinedPInvokeFrameVar; // variable representing the InlinedCallFrame
2875     unsigned lvaReversePInvokeFrameVar; // variable representing the reverse PInvoke frame
2876 #if FEATURE_FIXED_OUT_ARGS
2877     unsigned lvaPInvokeFrameRegSaveVar; // variable representing the RegSave for PInvoke inlining.
2878 #endif
2879     unsigned lvaMonAcquired; // boolean variable introduced into in synchronized methods
2880                              // that tracks whether the lock has been taken
2881
2882     unsigned lvaArg0Var; // The lclNum of arg0. Normally this will be info.compThisArg.
2883                          // However, if there is a "ldarga 0" or "starg 0" in the IL,
2884                          // we will redirect all "ldarg(a) 0" and "starg 0" to this temp.
2885
2886     unsigned lvaInlineeReturnSpillTemp; // The temp to spill the non-VOID return expression
2887                                         // in case there are multiple BBJ_RETURN blocks in the inlinee
2888                                         // or if the inlinee has GC ref locals.
2889
2890 #if FEATURE_FIXED_OUT_ARGS
2891     unsigned            lvaOutgoingArgSpaceVar;  // dummy TYP_LCLBLK var for fixed outgoing argument space
2892     PhasedVar<unsigned> lvaOutgoingArgSpaceSize; // size of fixed outgoing argument space
2893 #endif                                           // FEATURE_FIXED_OUT_ARGS
2894
2895 #ifdef _TARGET_ARM_
2896     // On architectures whose ABIs allow structs to be passed in registers, struct promotion will sometimes
2897     // require us to "rematerialize" a struct from it's separate constituent field variables.  Packing several sub-word
2898     // field variables into an argument register is a hard problem.  It's easier to reserve a word of memory into which
2899     // such field can be copied, after which the assembled memory word can be read into the register.  We will allocate
2900     // this variable to be this scratch word whenever struct promotion occurs.
2901     unsigned lvaPromotedStructAssemblyScratchVar;
2902 #endif // _TARGET_ARM_
2903
2904 #if defined(DEBUG) && defined(_TARGET_XARCH_)
2905
2906     unsigned lvaReturnSpCheck; // Stores SP to confirm it is not corrupted on return.
2907
2908 #endif // defined(DEBUG) && defined(_TARGET_XARCH_)
2909
2910 #if defined(DEBUG) && defined(_TARGET_X86_)
2911
2912     unsigned lvaCallSpCheck; // Stores SP to confirm it is not corrupted after every call.
2913
2914 #endif // defined(DEBUG) && defined(_TARGET_X86_)
2915
2916     unsigned lvaGenericsContextUseCount;
2917
2918     bool lvaKeepAliveAndReportThis(); // Synchronized instance method of a reference type, or
2919                                       // CORINFO_GENERICS_CTXT_FROM_THIS?
2920     bool lvaReportParamTypeArg();     // Exceptions and CORINFO_GENERICS_CTXT_FROM_PARAMTYPEARG?
2921
2922 //-------------------------------------------------------------------------
2923 // All these frame offsets are inter-related and must be kept in sync
2924
2925 #if !FEATURE_EH_FUNCLETS
2926     // This is used for the callable handlers
2927     unsigned lvaShadowSPslotsVar; // TYP_BLK variable for all the shadow SP slots
2928 #endif                            // FEATURE_EH_FUNCLETS
2929
2930     int lvaCachedGenericContextArgOffs;
2931     int lvaCachedGenericContextArgOffset(); // For CORINFO_CALLCONV_PARAMTYPE and if generic context is passed as
2932                                             // THIS pointer
2933
2934 #ifdef JIT32_GCENCODER
2935
2936     unsigned lvaLocAllocSPvar; // variable which stores the value of ESP after the the last alloca/localloc
2937
2938 #endif // JIT32_GCENCODER
2939
2940     unsigned lvaNewObjArrayArgs; // variable with arguments for new MD array helper
2941
2942     // TODO-Review: Prior to reg predict we reserve 24 bytes for Spill temps.
2943     //              after the reg predict we will use a computed maxTmpSize
2944     //              which is based upon the number of spill temps predicted by reg predict
2945     //              All this is necessary because if we under-estimate the size of the spill
2946     //              temps we could fail when encoding instructions that reference stack offsets for ARM.
2947     //
2948     // Pre codegen max spill temp size.
2949     static const unsigned MAX_SPILL_TEMP_SIZE = 24;
2950
2951     //-------------------------------------------------------------------------
2952
2953     unsigned lvaGetMaxSpillTempSize();
2954 #ifdef _TARGET_ARM_
2955     bool lvaIsPreSpilled(unsigned lclNum, regMaskTP preSpillMask);
2956 #endif // _TARGET_ARM_
2957     void lvaAssignFrameOffsets(FrameLayoutState curState);
2958     void lvaFixVirtualFrameOffsets();
2959     void lvaUpdateArgsWithInitialReg();
2960     void lvaAssignVirtualFrameOffsetsToArgs();
2961 #ifdef UNIX_AMD64_ABI
2962     int lvaAssignVirtualFrameOffsetToArg(unsigned lclNum, unsigned argSize, int argOffs, int* callerArgOffset);
2963 #else  // !UNIX_AMD64_ABI
2964     int lvaAssignVirtualFrameOffsetToArg(unsigned lclNum, unsigned argSize, int argOffs);
2965 #endif // !UNIX_AMD64_ABI
2966     void lvaAssignVirtualFrameOffsetsToLocals();
2967     int lvaAllocLocalAndSetVirtualOffset(unsigned lclNum, unsigned size, int stkOffs);
2968 #ifdef _TARGET_AMD64_
2969     // Returns true if compCalleeRegsPushed (including RBP if used as frame pointer) is even.
2970     bool lvaIsCalleeSavedIntRegCountEven();
2971 #endif
2972     void lvaAlignFrame();
2973     void lvaAssignFrameOffsetsToPromotedStructs();
2974     int lvaAllocateTemps(int stkOffs, bool mustDoubleAlign);
2975
2976 #ifdef DEBUG
2977     void lvaDumpRegLocation(unsigned lclNum);
2978     void lvaDumpFrameLocation(unsigned lclNum);
2979     void lvaDumpEntry(unsigned lclNum, FrameLayoutState curState, size_t refCntWtdWidth = 6);
2980     void lvaTableDump(FrameLayoutState curState = NO_FRAME_LAYOUT); // NO_FRAME_LAYOUT means use the current frame
2981                                                                     // layout state defined by lvaDoneFrameLayout
2982 #endif
2983
2984 // Limit frames size to 1GB. The maximum is 2GB in theory - make it intentionally smaller
2985 // to avoid bugs from borderline cases.
2986 #define MAX_FrameSize 0x3FFFFFFF
2987     void lvaIncrementFrameSize(unsigned size);
2988
2989     unsigned lvaFrameSize(FrameLayoutState curState);
2990
2991     // Returns the caller-SP-relative offset for the SP/FP relative offset determined by FP based.
2992     int lvaToCallerSPRelativeOffset(int offs, bool isFpBased);
2993
2994     // Returns the caller-SP-relative offset for the local variable "varNum."
2995     int lvaGetCallerSPRelativeOffset(unsigned varNum);
2996
2997     // Returns the SP-relative offset for the local variable "varNum". Illegal to ask this for functions with localloc.
2998     int lvaGetSPRelativeOffset(unsigned varNum);
2999
3000     int lvaToInitialSPRelativeOffset(unsigned offset, bool isFpBased);
3001     int lvaGetInitialSPRelativeOffset(unsigned varNum);
3002
3003     //------------------------ For splitting types ----------------------------
3004
3005     void lvaInitTypeRef();
3006
3007     void lvaInitArgs(InitVarDscInfo* varDscInfo);
3008     void lvaInitThisPtr(InitVarDscInfo* varDscInfo);
3009     void lvaInitRetBuffArg(InitVarDscInfo* varDscInfo);
3010     void lvaInitUserArgs(InitVarDscInfo* varDscInfo);
3011     void lvaInitGenericsCtxt(InitVarDscInfo* varDscInfo);
3012     void lvaInitVarArgsHandle(InitVarDscInfo* varDscInfo);
3013
3014     void lvaInitVarDsc(LclVarDsc*              varDsc,
3015                        unsigned                varNum,
3016                        CorInfoType             corInfoType,
3017                        CORINFO_CLASS_HANDLE    typeHnd,
3018                        CORINFO_ARG_LIST_HANDLE varList,
3019                        CORINFO_SIG_INFO*       varSig);
3020
3021     static unsigned lvaTypeRefMask(var_types type);
3022
3023     var_types lvaGetActualType(unsigned lclNum);
3024     var_types lvaGetRealType(unsigned lclNum);
3025
3026     //-------------------------------------------------------------------------
3027
3028     void lvaInit();
3029
3030     LclVarDsc* lvaGetDesc(unsigned lclNum)
3031     {
3032         assert(lclNum < lvaCount);
3033         return &lvaTable[lclNum];
3034     }
3035
3036     LclVarDsc* lvaGetDesc(GenTreeLclVarCommon* lclVar)
3037     {
3038         assert(lclVar->GetLclNum() < lvaCount);
3039         return &lvaTable[lclVar->GetLclNum()];
3040     }
3041
3042     unsigned lvaLclSize(unsigned varNum);
3043     unsigned lvaLclExactSize(unsigned varNum);
3044
3045     bool lvaHaveManyLocals() const;
3046
3047     unsigned lvaGrabTemp(bool shortLifetime DEBUGARG(const char* reason));
3048     unsigned lvaGrabTemps(unsigned cnt DEBUGARG(const char* reason));
3049     unsigned lvaGrabTempWithImplicitUse(bool shortLifetime DEBUGARG(const char* reason));
3050
3051     void lvaSortOnly();
3052     void lvaSortByRefCount();
3053     void lvaDumpRefCounts();
3054
3055     void lvaMarkLocalVars(); // Local variable ref-counting
3056     void lvaComputeRefCounts(bool isRecompute, bool setSlotNumbers);
3057     void lvaMarkLocalVars(BasicBlock* block, bool isRecompute);
3058
3059     void lvaAllocOutgoingArgSpaceVar(); // Set up lvaOutgoingArgSpaceVar
3060
3061     VARSET_VALRET_TP lvaStmtLclMask(GenTree* stmt);
3062
3063 #ifdef DEBUG
3064     struct lvaStressLclFldArgs
3065     {
3066         Compiler* m_pCompiler;
3067         bool      m_bFirstPass;
3068     };
3069
3070     static fgWalkPreFn lvaStressLclFldCB;
3071     void               lvaStressLclFld();
3072
3073     void lvaDispVarSet(VARSET_VALARG_TP set, VARSET_VALARG_TP allVars);
3074     void lvaDispVarSet(VARSET_VALARG_TP set);
3075
3076 #endif
3077
3078 #ifdef _TARGET_ARM_
3079     int lvaFrameAddress(int varNum, bool mustBeFPBased, regNumber* pBaseReg, int addrModeOffset, bool isFloatUsage);
3080 #else
3081     int lvaFrameAddress(int varNum, bool* pFPbased);
3082 #endif
3083
3084     bool lvaIsParameter(unsigned varNum);
3085     bool lvaIsRegArgument(unsigned varNum);
3086     BOOL lvaIsOriginalThisArg(unsigned varNum); // Is this varNum the original this argument?
3087     BOOL lvaIsOriginalThisReadOnly();           // return TRUE if there is no place in the code
3088                                                 // that writes to arg0
3089
3090     // Struct parameters that are passed by reference are marked as both lvIsParam and lvIsTemp
3091     // (this is an overload of lvIsTemp because there are no temp parameters).
3092     // For x64 this is 3, 5, 6, 7, >8 byte structs that are passed by reference.
3093     // For ARM64, this is structs larger than 16 bytes that are passed by reference.
3094     bool lvaIsImplicitByRefLocal(unsigned varNum)
3095     {
3096 #if defined(_TARGET_AMD64_) || defined(_TARGET_ARM64_)
3097         LclVarDsc* varDsc = &(lvaTable[varNum]);
3098         if (varDsc->lvIsParam && varDsc->lvIsTemp)
3099         {
3100             assert(varTypeIsStruct(varDsc) || (varDsc->lvType == TYP_BYREF));
3101             return true;
3102         }
3103 #endif // defined(_TARGET_AMD64_) || defined(_TARGET_ARM64_)
3104         return false;
3105     }
3106
3107     // Returns true if this local var is a multireg struct
3108     bool lvaIsMultiregStruct(LclVarDsc* varDsc, bool isVararg);
3109
3110     // If the local is a TYP_STRUCT, get/set a class handle describing it
3111     CORINFO_CLASS_HANDLE lvaGetStruct(unsigned varNum);
3112     void lvaSetStruct(unsigned varNum, CORINFO_CLASS_HANDLE typeHnd, bool unsafeValueClsCheck, bool setTypeInfo = true);
3113     void lvaSetStructUsedAsVarArg(unsigned varNum);
3114
3115     // If the local is TYP_REF, set or update the associated class information.
3116     void lvaSetClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool isExact = false);
3117     void lvaSetClass(unsigned varNum, GenTree* tree, CORINFO_CLASS_HANDLE stackHandle = nullptr);
3118     void lvaUpdateClass(unsigned varNum, CORINFO_CLASS_HANDLE clsHnd, bool isExact = false);
3119     void lvaUpdateClass(unsigned varNum, GenTree* tree, CORINFO_CLASS_HANDLE stackHandle = nullptr);
3120
3121 #define MAX_NumOfFieldsInPromotableStruct 4 // Maximum number of fields in promotable struct
3122
3123     // Info about struct type fields.
3124     struct lvaStructFieldInfo
3125     {
3126         CORINFO_FIELD_HANDLE fldHnd;
3127         unsigned char        fldOffset;
3128         unsigned char        fldOrdinal;
3129         var_types            fldType;
3130         unsigned             fldSize;
3131         CORINFO_CLASS_HANDLE fldTypeHnd;
3132
3133         lvaStructFieldInfo()
3134             : fldHnd(nullptr), fldOffset(0), fldOrdinal(0), fldType(TYP_UNDEF), fldSize(0), fldTypeHnd(nullptr)
3135         {
3136         }
3137     };
3138
3139     // Info about a struct type, instances of which may be candidates for promotion.
3140     struct lvaStructPromotionInfo
3141     {
3142         CORINFO_CLASS_HANDLE typeHnd;
3143         bool                 canPromote;
3144         bool                 containsHoles;
3145         bool                 customLayout;
3146         bool                 fieldsSorted;
3147         unsigned char        fieldCnt;
3148         lvaStructFieldInfo   fields[MAX_NumOfFieldsInPromotableStruct];
3149
3150         lvaStructPromotionInfo(CORINFO_CLASS_HANDLE typeHnd = nullptr)
3151             : typeHnd(typeHnd)
3152             , canPromote(false)
3153             , containsHoles(false)
3154             , customLayout(false)
3155             , fieldsSorted(false)
3156             , fieldCnt(0)
3157         {
3158         }
3159     };
3160
3161     static int __cdecl lvaFieldOffsetCmp(const void* field1, const void* field2);
3162
3163     // This class is responsible for checking validity and profitability of struct promotion.
3164     // If it is both legal and profitable, then TryPromoteStructVar promotes the struct and initializes
3165     // nessesary information for fgMorphStructField to use.
3166     class StructPromotionHelper
3167     {
3168     public:
3169         StructPromotionHelper(Compiler* compiler);
3170
3171         bool CanPromoteStructType(CORINFO_CLASS_HANDLE typeHnd);
3172         bool TryPromoteStructVar(unsigned lclNum);
3173
3174 #ifdef DEBUG
3175         void CheckRetypedAsScalar(CORINFO_FIELD_HANDLE fieldHnd, var_types requestedType);
3176 #endif // DEBUG
3177
3178 #ifdef _TARGET_ARM_
3179         bool GetRequiresScratchVar();
3180 #endif // _TARGET_ARM_
3181
3182     private:
3183         bool CanPromoteStructVar(unsigned lclNum);
3184         bool ShouldPromoteStructVar(unsigned lclNum);
3185         void PromoteStructVar(unsigned lclNum);
3186         void SortStructFields();
3187
3188         lvaStructFieldInfo GetFieldInfo(CORINFO_FIELD_HANDLE fieldHnd, BYTE ordinal);
3189         bool TryPromoteStructField(lvaStructFieldInfo& outerFieldInfo);
3190
3191     private:
3192         Compiler*              compiler;
3193         lvaStructPromotionInfo structPromotionInfo;
3194
3195 #ifdef _TARGET_ARM_
3196         bool requiresScratchVar;
3197 #endif // _TARGET_ARM_
3198
3199 #ifdef DEBUG
3200         typedef JitHashTable<CORINFO_FIELD_HANDLE, JitPtrKeyFuncs<CORINFO_FIELD_STRUCT_>, var_types>
3201                                  RetypedAsScalarFieldsMap;
3202         RetypedAsScalarFieldsMap retypedFieldsMap;
3203 #endif // DEBUG
3204     };
3205
3206     StructPromotionHelper* structPromotionHelper;
3207
3208 #if !defined(_TARGET_64BIT_)
3209     void lvaPromoteLongVars();
3210 #endif // !defined(_TARGET_64BIT_)
3211     unsigned lvaGetFieldLocal(const LclVarDsc* varDsc, unsigned int fldOffset);
3212     lvaPromotionType lvaGetPromotionType(const LclVarDsc* varDsc);
3213     lvaPromotionType lvaGetPromotionType(unsigned varNum);
3214     lvaPromotionType lvaGetParentPromotionType(const LclVarDsc* varDsc);
3215     lvaPromotionType lvaGetParentPromotionType(unsigned varNum);
3216     bool lvaIsFieldOfDependentlyPromotedStruct(const LclVarDsc* varDsc);
3217     bool lvaIsGCTracked(const LclVarDsc* varDsc);
3218
3219 #if defined(FEATURE_SIMD)
3220     bool lvaMapSimd12ToSimd16(const LclVarDsc* varDsc)
3221     {
3222         assert(varDsc->lvType == TYP_SIMD12);
3223         assert(varDsc->lvExactSize == 12);
3224
3225 #if defined(_TARGET_64BIT_)
3226         assert(varDsc->lvSize() == 16);
3227 #endif // defined(_TARGET_64BIT_)
3228
3229         // We make local variable SIMD12 types 16 bytes instead of just 12. lvSize()
3230         // already does this calculation. However, we also need to prevent mapping types if the var is a
3231         // dependently promoted struct field, which must remain its exact size within its parent struct.
3232         // However, we don't know this until late, so we may have already pretended the field is bigger
3233         // before that.
3234         if ((varDsc->lvSize() == 16) && !lvaIsFieldOfDependentlyPromotedStruct(varDsc))
3235         {
3236             return true;
3237         }
3238         else
3239         {
3240             return false;
3241         }
3242     }
3243 #endif // defined(FEATURE_SIMD)
3244
3245     BYTE* lvaGetGcLayout(unsigned varNum);
3246     bool lvaTypeIsGC(unsigned varNum);
3247     unsigned lvaGSSecurityCookie; // LclVar number
3248     bool     lvaTempsHaveLargerOffsetThanVars();
3249
3250     // Returns "true" iff local variable "lclNum" is in SSA form.
3251     bool lvaInSsa(unsigned lclNum)
3252     {
3253         assert(lclNum < lvaCount);
3254         return lvaTable[lclNum].lvInSsa;
3255     }
3256
3257     unsigned lvaSecurityObject;  // variable representing the security object on the stack
3258     unsigned lvaStubArgumentVar; // variable representing the secret stub argument coming in EAX
3259
3260 #if FEATURE_EH_FUNCLETS
3261     unsigned lvaPSPSym; // variable representing the PSPSym
3262 #endif
3263
3264     InlineInfo*     impInlineInfo;
3265     InlineStrategy* m_inlineStrategy;
3266
3267     // The Compiler* that is the root of the inlining tree of which "this" is a member.
3268     Compiler* impInlineRoot();
3269
3270 #if defined(DEBUG) || defined(INLINE_DATA)
3271     unsigned __int64 getInlineCycleCount()
3272     {
3273         return m_compCycles;
3274     }
3275 #endif // defined(DEBUG) || defined(INLINE_DATA)
3276
3277     bool fgNoStructPromotion;      // Set to TRUE to turn off struct promotion for this method.
3278     bool fgNoStructParamPromotion; // Set to TRUE to turn off struct promotion for parameters this method.
3279
3280     //=========================================================================
3281     //                          PROTECTED
3282     //=========================================================================
3283
3284 protected:
3285     //---------------- Local variable ref-counting ----------------------------
3286
3287     void lvaMarkLclRefs(GenTree* tree, BasicBlock* block, GenTreeStmt* stmt, bool isRecompute);
3288     bool IsDominatedByExceptionalEntry(BasicBlock* block);
3289     void SetVolatileHint(LclVarDsc* varDsc);
3290
3291     // Keeps the mapping from SSA #'s to VN's for the implicit memory variables.
3292     SsaDefArray<SsaMemDef> lvMemoryPerSsaData;
3293
3294 public:
3295     // Returns the address of the per-Ssa data for memory at the given ssaNum (which is required
3296     // not to be the SsaConfig::RESERVED_SSA_NUM, which indicates that the variable is
3297     // not an SSA variable).
3298     SsaMemDef* GetMemoryPerSsaData(unsigned ssaNum)
3299     {
3300         return lvMemoryPerSsaData.GetSsaDef(ssaNum);
3301     }
3302
3303     /*
3304     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3305     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3306     XX                                                                           XX
3307     XX                           Importer                                        XX
3308     XX                                                                           XX
3309     XX   Imports the given method and converts it to semantic trees              XX
3310     XX                                                                           XX
3311     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3312     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3313     */
3314
3315 public:
3316     void impInit();
3317
3318     void impImport(BasicBlock* method);
3319
3320     CORINFO_CLASS_HANDLE impGetRefAnyClass();
3321     CORINFO_CLASS_HANDLE impGetRuntimeArgumentHandle();
3322     CORINFO_CLASS_HANDLE impGetTypeHandleClass();
3323     CORINFO_CLASS_HANDLE impGetStringClass();
3324     CORINFO_CLASS_HANDLE impGetObjectClass();
3325
3326     // Returns underlying type of handles returned by ldtoken instruction
3327     var_types GetRuntimeHandleUnderlyingType()
3328     {
3329         // RuntimeTypeHandle is backed by raw pointer on CoreRT and by object reference on other runtimes
3330         return IsTargetAbi(CORINFO_CORERT_ABI) ? TYP_I_IMPL : TYP_REF;
3331     }
3332
3333     void impDevirtualizeCall(GenTreeCall*            call,
3334                              CORINFO_METHOD_HANDLE*  method,
3335                              unsigned*               methodFlags,
3336                              CORINFO_CONTEXT_HANDLE* contextHandle,
3337                              CORINFO_CONTEXT_HANDLE* exactContextHandle,
3338                              bool                    isLateDevirtualization,
3339                              bool                    isExplicitTailCall);
3340
3341     //=========================================================================
3342     //                          PROTECTED
3343     //=========================================================================
3344
3345 protected:
3346     //-------------------- Stack manipulation ---------------------------------
3347
3348     unsigned impStkSize; // Size of the full stack
3349
3350 #define SMALL_STACK_SIZE 16 // number of elements in impSmallStack
3351
3352     struct SavedStack // used to save/restore stack contents.
3353     {
3354         unsigned    ssDepth; // number of values on stack
3355         StackEntry* ssTrees; // saved tree values
3356     };
3357
3358     bool impIsPrimitive(CorInfoType type);
3359     bool impILConsumesAddr(const BYTE* codeAddr, CORINFO_METHOD_HANDLE fncHandle, CORINFO_MODULE_HANDLE scpHandle);
3360
3361     void impResolveToken(const BYTE* addr, CORINFO_RESOLVED_TOKEN* pResolvedToken, CorInfoTokenKind kind);
3362
3363     void impPushOnStack(GenTree* tree, typeInfo ti);
3364     void        impPushNullObjRefOnStack();
3365     StackEntry  impPopStack();
3366     StackEntry& impStackTop(unsigned n = 0);
3367     unsigned impStackHeight();
3368
3369     void impSaveStackState(SavedStack* savePtr, bool copy);
3370     void impRestoreStackState(SavedStack* savePtr);
3371
3372     GenTree* impImportLdvirtftn(GenTree* thisPtr, CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_CALL_INFO* pCallInfo);
3373
3374     void impImportAndPushBox(CORINFO_RESOLVED_TOKEN* pResolvedToken);
3375
3376     void impImportNewObjArray(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_CALL_INFO* pCallInfo);
3377
3378     bool impCanPInvokeInline();
3379     bool impCanPInvokeInlineCallSite(BasicBlock* block);
3380     void impCheckForPInvokeCall(
3381         GenTreeCall* call, CORINFO_METHOD_HANDLE methHnd, CORINFO_SIG_INFO* sig, unsigned mflags, BasicBlock* block);
3382     GenTreeCall* impImportIndirectCall(CORINFO_SIG_INFO* sig, IL_OFFSETX ilOffset = BAD_IL_OFFSET);
3383     void impPopArgsForUnmanagedCall(GenTree* call, CORINFO_SIG_INFO* sig);
3384
3385     void impInsertHelperCall(CORINFO_HELPER_DESC* helperCall);
3386     void impHandleAccessAllowed(CorInfoIsAccessAllowedResult result, CORINFO_HELPER_DESC* helperCall);
3387     void impHandleAccessAllowedInternal(CorInfoIsAccessAllowedResult result, CORINFO_HELPER_DESC* helperCall);
3388
3389     var_types impImportCall(OPCODE                  opcode,
3390                             CORINFO_RESOLVED_TOKEN* pResolvedToken,
3391                             CORINFO_RESOLVED_TOKEN* pConstrainedResolvedToken, // Is this a "constrained." call on a
3392                                                                                // type parameter?
3393                             GenTree*           newobjThis,
3394                             int                prefixFlags,
3395                             CORINFO_CALL_INFO* callInfo,
3396                             IL_OFFSET          rawILOffset);
3397
3398     CORINFO_CLASS_HANDLE impGetSpecialIntrinsicExactReturnType(CORINFO_METHOD_HANDLE specialIntrinsicHandle);
3399
3400     bool impMethodInfo_hasRetBuffArg(CORINFO_METHOD_INFO* methInfo);
3401
3402     GenTree* impFixupCallStructReturn(GenTreeCall* call, CORINFO_CLASS_HANDLE retClsHnd);
3403
3404     GenTree* impFixupStructReturnType(GenTree* op, CORINFO_CLASS_HANDLE retClsHnd);
3405
3406 #ifdef DEBUG
3407     var_types impImportJitTestLabelMark(int numArgs);
3408 #endif // DEBUG
3409
3410     GenTree* impInitClass(CORINFO_RESOLVED_TOKEN* pResolvedToken);
3411
3412     GenTree* impImportStaticReadOnlyField(void* fldAddr, var_types lclTyp);
3413
3414     GenTree* impImportStaticFieldAccess(CORINFO_RESOLVED_TOKEN* pResolvedToken,
3415                                         CORINFO_ACCESS_FLAGS    access,
3416                                         CORINFO_FIELD_INFO*     pFieldInfo,
3417                                         var_types               lclTyp);
3418
3419     static void impBashVarAddrsToI(GenTree* tree1, GenTree* tree2 = nullptr);
3420
3421     GenTree* impImplicitIorI4Cast(GenTree* tree, var_types dstTyp);
3422
3423     GenTree* impImplicitR4orR8Cast(GenTree* tree, var_types dstTyp);
3424
3425     void impImportLeave(BasicBlock* block);
3426     void impResetLeaveBlock(BasicBlock* block, unsigned jmpAddr);
3427     GenTree* impIntrinsic(GenTree*                newobjThis,
3428                           CORINFO_CLASS_HANDLE    clsHnd,
3429                           CORINFO_METHOD_HANDLE   method,
3430                           CORINFO_SIG_INFO*       sig,
3431                           unsigned                methodFlags,
3432                           int                     memberRef,
3433                           bool                    readonlyCall,
3434                           bool                    tailCall,
3435                           CORINFO_RESOLVED_TOKEN* pContstrainedResolvedToken,
3436                           CORINFO_THIS_TRANSFORM  constraintCallThisTransform,
3437                           CorInfoIntrinsics*      pIntrinsicID,
3438                           bool*                   isSpecialIntrinsic = nullptr);
3439     GenTree* impMathIntrinsic(CORINFO_METHOD_HANDLE method,
3440                               CORINFO_SIG_INFO*     sig,
3441                               var_types             callType,
3442                               CorInfoIntrinsics     intrinsicID,
3443                               bool                  tailCall);
3444     NamedIntrinsic lookupNamedIntrinsic(CORINFO_METHOD_HANDLE method);
3445
3446 #ifdef FEATURE_HW_INTRINSICS
3447     GenTree* impHWIntrinsic(NamedIntrinsic        intrinsic,
3448                             CORINFO_METHOD_HANDLE method,
3449                             CORINFO_SIG_INFO*     sig,
3450                             bool                  mustExpand);
3451     GenTree* impUnsupportedHWIntrinsic(unsigned              helper,
3452                                        CORINFO_METHOD_HANDLE method,
3453                                        CORINFO_SIG_INFO*     sig,
3454                                        bool                  mustExpand);
3455
3456 protected:
3457     bool compSupportsHWIntrinsic(InstructionSet isa);
3458
3459 #ifdef _TARGET_XARCH_
3460     GenTree* impBaseIntrinsic(NamedIntrinsic        intrinsic,
3461                               CORINFO_METHOD_HANDLE method,
3462                               CORINFO_SIG_INFO*     sig,
3463                               bool                  mustExpand);
3464     GenTree* impSSEIntrinsic(NamedIntrinsic        intrinsic,
3465                              CORINFO_METHOD_HANDLE method,
3466                              CORINFO_SIG_INFO*     sig,
3467                              bool                  mustExpand);
3468     GenTree* impSSE2Intrinsic(NamedIntrinsic        intrinsic,
3469                               CORINFO_METHOD_HANDLE method,
3470                               CORINFO_SIG_INFO*     sig,
3471                               bool                  mustExpand);
3472     GenTree* impSSE42Intrinsic(NamedIntrinsic        intrinsic,
3473                                CORINFO_METHOD_HANDLE method,
3474                                CORINFO_SIG_INFO*     sig,
3475                                bool                  mustExpand);
3476     GenTree* impAvxOrAvx2Intrinsic(NamedIntrinsic        intrinsic,
3477                                    CORINFO_METHOD_HANDLE method,
3478                                    CORINFO_SIG_INFO*     sig,
3479                                    bool                  mustExpand);
3480     GenTree* impAESIntrinsic(NamedIntrinsic        intrinsic,
3481                              CORINFO_METHOD_HANDLE method,
3482                              CORINFO_SIG_INFO*     sig,
3483                              bool                  mustExpand);
3484     GenTree* impBMI1OrBMI2Intrinsic(NamedIntrinsic        intrinsic,
3485                                     CORINFO_METHOD_HANDLE method,
3486                                     CORINFO_SIG_INFO*     sig,
3487                                     bool                  mustExpand);
3488     GenTree* impFMAIntrinsic(NamedIntrinsic        intrinsic,
3489                              CORINFO_METHOD_HANDLE method,
3490                              CORINFO_SIG_INFO*     sig,
3491                              bool                  mustExpand);
3492     GenTree* impLZCNTIntrinsic(NamedIntrinsic        intrinsic,
3493                                CORINFO_METHOD_HANDLE method,
3494                                CORINFO_SIG_INFO*     sig,
3495                                bool                  mustExpand);
3496     GenTree* impPCLMULQDQIntrinsic(NamedIntrinsic        intrinsic,
3497                                    CORINFO_METHOD_HANDLE method,
3498                                    CORINFO_SIG_INFO*     sig,
3499                                    bool                  mustExpand);
3500     GenTree* impPOPCNTIntrinsic(NamedIntrinsic        intrinsic,
3501                                 CORINFO_METHOD_HANDLE method,
3502                                 CORINFO_SIG_INFO*     sig,
3503                                 bool                  mustExpand);
3504
3505 protected:
3506     GenTree* getArgForHWIntrinsic(var_types argType, CORINFO_CLASS_HANDLE argClass);
3507     GenTree* impNonConstFallback(NamedIntrinsic intrinsic, var_types simdType, var_types baseType);
3508     GenTree* addRangeCheckIfNeeded(NamedIntrinsic intrinsic, GenTree* lastOp, bool mustExpand);
3509 #endif // _TARGET_XARCH_
3510 #ifdef _TARGET_ARM64_
3511     InstructionSet lookupHWIntrinsicISA(const char* className);
3512     NamedIntrinsic lookupHWIntrinsic(const char* className, const char* methodName);
3513     bool impCheckImmediate(GenTree* immediateOp, unsigned int max);
3514 #endif // _TARGET_ARM64_
3515 #endif // FEATURE_HW_INTRINSICS
3516     GenTree* impArrayAccessIntrinsic(CORINFO_CLASS_HANDLE clsHnd,
3517                                      CORINFO_SIG_INFO*    sig,
3518                                      int                  memberRef,
3519                                      bool                 readonlyCall,
3520                                      CorInfoIntrinsics    intrinsicID);
3521     GenTree* impInitializeArrayIntrinsic(CORINFO_SIG_INFO* sig);
3522
3523     GenTree* impMethodPointer(CORINFO_RESOLVED_TOKEN* pResolvedToken, CORINFO_CALL_INFO* pCallInfo);
3524
3525     GenTree* impTransformThis(GenTree*                thisPtr,
3526                               CORINFO_RESOLVED_TOKEN* pConstrainedResolvedToken,
3527                               CORINFO_THIS_TRANSFORM  transform);
3528
3529     //----------------- Manipulating the trees and stmts ----------------------
3530
3531     GenTree* impTreeList; // Trees for the BB being imported
3532     GenTree* impTreeLast; // The last tree for the current BB
3533
3534 public:
3535     enum
3536     {
3537         CHECK_SPILL_ALL  = -1,
3538         CHECK_SPILL_NONE = -2
3539     };
3540
3541     void impBeginTreeList();
3542     void impEndTreeList(BasicBlock* block, GenTree* firstStmt, GenTree* lastStmt);
3543     void impEndTreeList(BasicBlock* block);
3544     void impAppendStmtCheck(GenTree* stmt, unsigned chkLevel);
3545     void impAppendStmt(GenTree* stmt, unsigned chkLevel);
3546     void impInsertStmtBefore(GenTree* stmt, GenTree* stmtBefore);
3547     GenTree* impAppendTree(GenTree* tree, unsigned chkLevel, IL_OFFSETX offset);
3548     void impInsertTreeBefore(GenTree* tree, IL_OFFSETX offset, GenTree* stmtBefore);
3549     void impAssignTempGen(unsigned    tmp,
3550                           GenTree*    val,
3551                           unsigned    curLevel,
3552                           GenTree**   pAfterStmt = nullptr,
3553                           IL_OFFSETX  ilOffset   = BAD_IL_OFFSET,
3554                           BasicBlock* block      = nullptr);
3555     void impAssignTempGen(unsigned             tmpNum,
3556                           GenTree*             val,
3557                           CORINFO_CLASS_HANDLE structHnd,
3558                           unsigned             curLevel,
3559                           GenTree**            pAfterStmt = nullptr,
3560                           IL_OFFSETX           ilOffset   = BAD_IL_OFFSET,
3561                           BasicBlock*          block      = nullptr);
3562     GenTree* impCloneExpr(GenTree*             tree,
3563                           GenTree**            clone,
3564                           CORINFO_CLASS_HANDLE structHnd,
3565                           unsigned             curLevel,
3566                           GenTree** pAfterStmt DEBUGARG(const char* reason));
3567     GenTree* impAssignStruct(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     GenTree* impAssignStructPtr(GenTree*             dest,
3575                                 GenTree*             src,
3576                                 CORINFO_CLASS_HANDLE structHnd,
3577                                 unsigned             curLevel,
3578                                 GenTree**            pAfterStmt = nullptr,
3579                                 IL_OFFSETX           ilOffset   = BAD_IL_OFFSET,
3580                                 BasicBlock*          block      = nullptr);
3581
3582     GenTree* impGetStructAddr(GenTree* structVal, CORINFO_CLASS_HANDLE structHnd, unsigned curLevel, bool willDeref);
3583
3584     var_types impNormStructType(CORINFO_CLASS_HANDLE structHnd,
3585                                 BYTE*                gcLayout     = nullptr,
3586                                 unsigned*            numGCVars    = nullptr,
3587                                 var_types*           simdBaseType = nullptr);
3588
3589     GenTree* impNormStructVal(GenTree*             structVal,
3590                               CORINFO_CLASS_HANDLE structHnd,
3591                               unsigned             curLevel,
3592                               bool                 forceNormalization = false);
3593
3594     GenTree* impTokenToHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken,
3595                               BOOL*                   pRuntimeLookup    = nullptr,
3596                               BOOL                    mustRestoreHandle = FALSE,
3597                               BOOL                    importParent      = FALSE);
3598
3599     GenTree* impParentClassTokenToHandle(CORINFO_RESOLVED_TOKEN* pResolvedToken,
3600                                          BOOL*                   pRuntimeLookup    = nullptr,
3601                                          BOOL                    mustRestoreHandle = FALSE)
3602     {
3603         return impTokenToHandle(pResolvedToken, pRuntimeLookup, mustRestoreHandle, TRUE);
3604     }
3605
3606     GenTree* impLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedToken,
3607                              CORINFO_LOOKUP*         pLookup,
3608                              unsigned                flags,
3609                              void*                   compileTimeHandle);
3610
3611     GenTree* getRuntimeContextTree(CORINFO_RUNTIME_LOOKUP_KIND kind);
3612
3613     GenTree* impRuntimeLookupToTree(CORINFO_RESOLVED_TOKEN* pResolvedToken,
3614                                     CORINFO_LOOKUP*         pLookup,
3615                                     void*                   compileTimeHandle);
3616
3617     GenTree* impReadyToRunLookupToTree(CORINFO_CONST_LOOKUP* pLookup, unsigned flags, void* compileTimeHandle);
3618
3619     GenTreeCall* impReadyToRunHelperToTree(CORINFO_RESOLVED_TOKEN* pResolvedToken,
3620                                            CorInfoHelpFunc         helper,
3621                                            var_types               type,
3622                                            GenTreeArgList*         arg                = nullptr,
3623                                            CORINFO_LOOKUP_KIND*    pGenericLookupKind = nullptr);
3624
3625     GenTree* impCastClassOrIsInstToTree(GenTree*                op1,
3626                                         GenTree*                op2,
3627                                         CORINFO_RESOLVED_TOKEN* pResolvedToken,
3628                                         bool                    isCastClass);
3629
3630     GenTree* impOptimizeCastClassOrIsInst(GenTree* op1, CORINFO_RESOLVED_TOKEN* pResolvedToken, bool isCastClass);
3631
3632     bool VarTypeIsMultiByteAndCanEnreg(
3633         var_types type, CORINFO_CLASS_HANDLE typeClass, unsigned* typeSize, bool forReturn, bool isVarArg);
3634
3635     bool IsIntrinsicImplementedByUserCall(CorInfoIntrinsics intrinsicId);
3636     bool IsTargetIntrinsic(CorInfoIntrinsics intrinsicId);
3637     bool IsMathIntrinsic(CorInfoIntrinsics intrinsicId);
3638     bool IsMathIntrinsic(GenTree* tree);
3639
3640 private:
3641     //----------------- Importing the method ----------------------------------
3642
3643     CORINFO_CONTEXT_HANDLE impTokenLookupContextHandle; // The context used for looking up tokens.
3644
3645 #ifdef DEBUG
3646     unsigned    impCurOpcOffs;
3647     const char* impCurOpcName;
3648     bool        impNestedStackSpill;
3649
3650     // For displaying instrs with generated native code (-n:B)
3651     GenTree* impLastILoffsStmt; // oldest stmt added for which we did not gtStmtLastILoffs
3652     void     impNoteLastILoffs();
3653 #endif
3654
3655     /* IL offset of the stmt currently being imported. It gets set to
3656        BAD_IL_OFFSET after it has been set in the appended trees. Then it gets
3657        updated at IL offsets for which we have to report mapping info.
3658        It also includes flag bits, so use jitGetILoffs()
3659        to get the actual IL offset value.
3660     */
3661
3662     IL_OFFSETX impCurStmtOffs;
3663     void impCurStmtOffsSet(IL_OFFSET offs);
3664
3665     void impNoteBranchOffs();
3666
3667     unsigned impInitBlockLineInfo();
3668
3669     GenTree* impCheckForNullPointer(GenTree* obj);
3670     bool impIsThis(GenTree* obj);
3671     bool impIsLDFTN_TOKEN(const BYTE* delegateCreateStart, const BYTE* newobjCodeAddr);
3672     bool impIsDUP_LDVIRTFTN_TOKEN(const BYTE* delegateCreateStart, const BYTE* newobjCodeAddr);
3673     bool impIsAnySTLOC(OPCODE opcode)
3674     {
3675         return ((opcode == CEE_STLOC) || (opcode == CEE_STLOC_S) ||
3676                 ((opcode >= CEE_STLOC_0) && (opcode <= CEE_STLOC_3)));
3677     }
3678
3679     GenTreeArgList* impPopList(unsigned count, CORINFO_SIG_INFO* sig, GenTreeArgList* prefixTree = nullptr);
3680
3681     GenTreeArgList* impPopRevList(unsigned count, CORINFO_SIG_INFO* sig, unsigned skipReverseCount = 0);
3682
3683     /*
3684      * Get current IL offset with stack-empty info incoporated
3685      */
3686     IL_OFFSETX impCurILOffset(IL_OFFSET offs, bool callInstruction = false);
3687
3688     //---------------- Spilling the importer stack ----------------------------
3689
3690     // The maximum number of bytes of IL processed without clean stack state.
3691     // It allows to limit the maximum tree size and depth.
3692     static const unsigned MAX_TREE_SIZE = 200;
3693     bool impCanSpillNow(OPCODE prevOpcode);
3694
3695     struct PendingDsc
3696     {
3697         PendingDsc*   pdNext;
3698         BasicBlock*   pdBB;
3699         SavedStack    pdSavedStack;
3700         ThisInitState pdThisPtrInit;
3701     };
3702
3703     PendingDsc* impPendingList; // list of BBs currently waiting to be imported.
3704     PendingDsc* impPendingFree; // Freed up dscs that can be reused
3705
3706     // We keep a byte-per-block map (dynamically extended) in the top-level Compiler object of a compilation.
3707     JitExpandArray<BYTE> impPendingBlockMembers;
3708
3709     // Return the byte for "b" (allocating/extending impPendingBlockMembers if necessary.)
3710     // Operates on the map in the top-level ancestor.
3711     BYTE impGetPendingBlockMember(BasicBlock* blk)
3712     {
3713         return impInlineRoot()->impPendingBlockMembers.Get(blk->bbInd());
3714     }
3715
3716     // Set the byte for "b" to "val" (allocating/extending impPendingBlockMembers if necessary.)
3717     // Operates on the map in the top-level ancestor.
3718     void impSetPendingBlockMember(BasicBlock* blk, BYTE val)
3719     {
3720         impInlineRoot()->impPendingBlockMembers.Set(blk->bbInd(), val);
3721     }
3722
3723     bool impCanReimport;
3724
3725     bool impSpillStackEntry(unsigned level,
3726                             unsigned varNum
3727 #ifdef DEBUG
3728                             ,
3729                             bool        bAssertOnRecursion,
3730                             const char* reason
3731 #endif
3732                             );
3733
3734     void impSpillStackEnsure(bool spillLeaves = false);
3735     void impEvalSideEffects();
3736     void impSpillSpecialSideEff();
3737     void impSpillSideEffects(bool spillGlobEffects, unsigned chkLevel DEBUGARG(const char* reason));
3738     void               impSpillValueClasses();
3739     void               impSpillEvalStack();
3740     static fgWalkPreFn impFindValueClasses;
3741     void impSpillLclRefs(ssize_t lclNum);
3742
3743     BasicBlock* impPushCatchArgOnStack(BasicBlock* hndBlk, CORINFO_CLASS_HANDLE clsHnd, bool isSingleBlockFilter);
3744
3745     void impImportBlockCode(BasicBlock* block);
3746
3747     void impReimportMarkBlock(BasicBlock* block);
3748     void impReimportMarkSuccessors(BasicBlock* block);
3749
3750     void impVerifyEHBlock(BasicBlock* block, bool isTryStart);
3751
3752     void impImportBlockPending(BasicBlock* block);
3753
3754     // Similar to impImportBlockPending, but assumes that block has already been imported once and is being
3755     // reimported for some reason.  It specifically does *not* look at verCurrentState to set the EntryState
3756     // for the block, but instead, just re-uses the block's existing EntryState.
3757     void impReimportBlockPending(BasicBlock* block);
3758
3759     var_types impGetByRefResultType(genTreeOps oper, bool fUnsigned, GenTree** pOp1, GenTree** pOp2);
3760
3761     void impImportBlock(BasicBlock* block);
3762
3763     // Assumes that "block" is a basic block that completes with a non-empty stack. We will assign the values
3764     // on the stack to local variables (the "spill temp" variables). The successor blocks will assume that
3765     // its incoming stack contents are in those locals. This requires "block" and its successors to agree on
3766     // the variables that will be used -- and for all the predecessors of those successors, and the
3767     // successors of those predecessors, etc. Call such a set of blocks closed under alternating
3768     // successor/predecessor edges a "spill clique." A block is a "predecessor" or "successor" member of the
3769     // clique (or, conceivably, both). Each block has a specified sequence of incoming and outgoing spill
3770     // temps. If "block" already has its outgoing spill temps assigned (they are always a contiguous series
3771     // of local variable numbers, so we represent them with the base local variable number), returns that.
3772     // Otherwise, picks a set of spill temps, and propagates this choice to all blocks in the spill clique of
3773     // which "block" is a member (asserting, in debug mode, that no block in this clique had its spill temps
3774     // chosen already. More precisely, that the incoming or outgoing spill temps are not chosen, depending
3775     // on which kind of member of the clique the block is).
3776     unsigned impGetSpillTmpBase(BasicBlock* block);
3777
3778     // Assumes that "block" is a basic block that completes with a non-empty stack. We have previously
3779     // assigned the values on the stack to local variables (the "spill temp" variables). The successor blocks
3780     // will assume that its incoming stack contents are in those locals. This requires "block" and its
3781     // successors to agree on the variables and their types that will be used.  The CLI spec allows implicit
3782     // conversions between 'int' and 'native int' or 'float' and 'double' stack types. So one predecessor can
3783     // push an int and another can push a native int.  For 64-bit we have chosen to implement this by typing
3784     // the "spill temp" as native int, and then importing (or re-importing as needed) so that all the
3785     // predecessors in the "spill clique" push a native int (sign-extending if needed), and all the
3786     // successors receive a native int. Similarly float and double are unified to double.
3787     // This routine is called after a type-mismatch is detected, and it will walk the spill clique to mark
3788     // blocks for re-importation as appropriate (both successors, so they get the right incoming type, and
3789     // predecessors, so they insert an upcast if needed).
3790     void impReimportSpillClique(BasicBlock* block);
3791
3792     // When we compute a "spill clique" (see above) these byte-maps are allocated to have a byte per basic
3793     // block, and represent the predecessor and successor members of the clique currently being computed.
3794     // *** Access to these will need to be locked in a parallel compiler.
3795     JitExpandArray<BYTE> impSpillCliquePredMembers;
3796     JitExpandArray<BYTE> impSpillCliqueSuccMembers;
3797
3798     enum SpillCliqueDir
3799     {
3800         SpillCliquePred,
3801         SpillCliqueSucc
3802     };
3803
3804     // Abstract class for receiving a callback while walking a spill clique
3805     class SpillCliqueWalker
3806     {
3807     public:
3808         virtual void Visit(SpillCliqueDir predOrSucc, BasicBlock* blk) = 0;
3809     };
3810
3811     // This class is used for setting the bbStkTempsIn and bbStkTempsOut on the blocks within a spill clique
3812     class SetSpillTempsBase : public SpillCliqueWalker
3813     {
3814         unsigned m_baseTmp;
3815
3816     public:
3817         SetSpillTempsBase(unsigned baseTmp) : m_baseTmp(baseTmp)
3818         {
3819         }
3820         virtual void Visit(SpillCliqueDir predOrSucc, BasicBlock* blk);
3821     };
3822
3823     // This class is used for implementing impReimportSpillClique part on each block within the spill clique
3824     class ReimportSpillClique : public SpillCliqueWalker
3825     {
3826         Compiler* m_pComp;
3827
3828     public:
3829         ReimportSpillClique(Compiler* pComp) : m_pComp(pComp)
3830         {
3831         }
3832         virtual void Visit(SpillCliqueDir predOrSucc, BasicBlock* blk);
3833     };
3834
3835     // This is the heart of the algorithm for walking spill cliques. It invokes callback->Visit for each
3836     // predecessor or successor within the spill clique
3837     void impWalkSpillCliqueFromPred(BasicBlock* pred, SpillCliqueWalker* callback);
3838
3839     // For a BasicBlock that has already been imported, the EntryState has an array of GenTrees for the
3840     // incoming locals. This walks that list an resets the types of the GenTrees to match the types of
3841     // the VarDscs. They get out of sync when we have int/native int issues (see impReimportSpillClique).
3842     void impRetypeEntryStateTemps(BasicBlock* blk);
3843
3844     BYTE impSpillCliqueGetMember(SpillCliqueDir predOrSucc, BasicBlock* blk);
3845     void impSpillCliqueSetMember(SpillCliqueDir predOrSucc, BasicBlock* blk, BYTE val);
3846
3847     void impPushVar(GenTree* op, typeInfo tiRetVal);
3848     void impLoadVar(unsigned lclNum, IL_OFFSET offset, typeInfo tiRetVal);
3849     void impLoadVar(unsigned lclNum, IL_OFFSET offset)
3850     {
3851         impLoadVar(lclNum, offset, lvaTable[lclNum].lvVerTypeInfo);
3852     }
3853     void impLoadArg(unsigned ilArgNum, IL_OFFSET offset);
3854     void impLoadLoc(unsigned ilLclNum, IL_OFFSET offset);
3855     bool impReturnInstruction(BasicBlock* block, int prefixFlags, OPCODE& opcode);
3856
3857 #ifdef _TARGET_ARM_
3858     void impMarkLclDstNotPromotable(unsigned tmpNum, GenTree* op, CORINFO_CLASS_HANDLE hClass);
3859 #endif
3860
3861     // A free list of linked list nodes used to represent to-do stacks of basic blocks.
3862     struct BlockListNode
3863     {
3864         BasicBlock*    m_blk;
3865         BlockListNode* m_next;
3866         BlockListNode(BasicBlock* blk, BlockListNode* next = nullptr) : m_blk(blk), m_next(next)
3867         {
3868         }
3869         void* operator new(size_t sz, Compiler* comp);
3870     };
3871     BlockListNode* impBlockListNodeFreeList;
3872
3873     void FreeBlockListNode(BlockListNode* node);
3874
3875     bool impIsValueType(typeInfo* pTypeInfo);
3876     var_types mangleVarArgsType(var_types type);
3877
3878 #if FEATURE_VARARG
3879     regNumber getCallArgIntRegister(regNumber floatReg);
3880     regNumber getCallArgFloatRegister(regNumber intReg);
3881 #endif // FEATURE_VARARG
3882
3883 #if defined(DEBUG)
3884     static unsigned jitTotalMethodCompiled;
3885 #endif
3886
3887 #ifdef DEBUG
3888     static LONG jitNestingLevel;
3889 #endif // DEBUG
3890
3891     static BOOL impIsAddressInLocal(GenTree* tree, GenTree** lclVarTreeOut);
3892
3893     void impMakeDiscretionaryInlineObservations(InlineInfo* pInlineInfo, InlineResult* inlineResult);
3894
3895     // STATIC inlining decision based on the IL code.
3896     void impCanInlineIL(CORINFO_METHOD_HANDLE fncHandle,
3897                         CORINFO_METHOD_INFO*  methInfo,
3898                         bool                  forceInline,
3899                         InlineResult*         inlineResult);
3900
3901     void impCheckCanInline(GenTreeCall*           call,
3902                            CORINFO_METHOD_HANDLE  fncHandle,
3903                            unsigned               methAttr,
3904                            CORINFO_CONTEXT_HANDLE exactContextHnd,
3905                            InlineCandidateInfo**  ppInlineCandidateInfo,
3906                            InlineResult*          inlineResult);
3907
3908     void impInlineRecordArgInfo(InlineInfo*   pInlineInfo,
3909                                 GenTree*      curArgVal,
3910                                 unsigned      argNum,
3911                                 InlineResult* inlineResult);
3912
3913     void impInlineInitVars(InlineInfo* pInlineInfo);
3914
3915     unsigned impInlineFetchLocal(unsigned lclNum DEBUGARG(const char* reason));
3916
3917     GenTree* impInlineFetchArg(unsigned lclNum, InlArgInfo* inlArgInfo, InlLclVarInfo* lclTypeInfo);
3918
3919     BOOL impInlineIsThis(GenTree* tree, InlArgInfo* inlArgInfo);
3920
3921     BOOL impInlineIsGuaranteedThisDerefBeforeAnySideEffects(GenTree*    additionalTreesToBeEvaluatedBefore,
3922                                                             GenTree*    variableBeingDereferenced,
3923                                                             InlArgInfo* inlArgInfo);
3924
3925     void impMarkInlineCandidate(GenTree*               call,
3926                                 CORINFO_CONTEXT_HANDLE exactContextHnd,
3927                                 bool                   exactContextNeedsRuntimeLookup,
3928                                 CORINFO_CALL_INFO*     callInfo);
3929
3930     void impMarkInlineCandidateHelper(GenTreeCall*           call,
3931                                       CORINFO_CONTEXT_HANDLE exactContextHnd,
3932                                       bool                   exactContextNeedsRuntimeLookup,
3933                                       CORINFO_CALL_INFO*     callInfo);
3934
3935     bool impTailCallRetTypeCompatible(var_types            callerRetType,
3936                                       CORINFO_CLASS_HANDLE callerRetTypeClass,
3937                                       var_types            calleeRetType,
3938                                       CORINFO_CLASS_HANDLE calleeRetTypeClass);
3939
3940     bool impIsTailCallILPattern(bool        tailPrefixed,
3941                                 OPCODE      curOpcode,
3942                                 const BYTE* codeAddrOfNextOpcode,
3943                                 const BYTE* codeEnd,
3944                                 bool        isRecursive,
3945                                 bool*       IsCallPopRet = nullptr);
3946
3947     bool impIsImplicitTailCallCandidate(
3948         OPCODE curOpcode, const BYTE* codeAddrOfNextOpcode, const BYTE* codeEnd, int prefixFlags, bool isRecursive);
3949
3950     CORINFO_RESOLVED_TOKEN* impAllocateToken(CORINFO_RESOLVED_TOKEN token);
3951
3952     /*
3953     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3954     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3955     XX                                                                           XX
3956     XX                           FlowGraph                                       XX
3957     XX                                                                           XX
3958     XX   Info about the basic-blocks, their contents and the flow analysis       XX
3959     XX                                                                           XX
3960     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3961     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3962     */
3963
3964 public:
3965     BasicBlock* fgFirstBB;        // Beginning of the basic block list
3966     BasicBlock* fgLastBB;         // End of the basic block list
3967     BasicBlock* fgFirstColdBlock; // First block to be placed in the cold section
3968 #if FEATURE_EH_FUNCLETS
3969     BasicBlock* fgFirstFuncletBB; // First block of outlined funclets (to allow block insertion before the funclets)
3970 #endif
3971     BasicBlock* fgFirstBBScratch;   // Block inserted for initialization stuff. Is nullptr if no such block has been
3972                                     // created.
3973     BasicBlockList* fgReturnBlocks; // list of BBJ_RETURN blocks
3974     unsigned        fgEdgeCount;    // # of control flow edges between the BBs
3975     unsigned        fgBBcount;      // # of BBs in the method
3976 #ifdef DEBUG
3977     unsigned fgBBcountAtCodegen; // # of BBs in the method at the start of codegen
3978 #endif
3979     unsigned     fgBBNumMax;       // The max bbNum that has been assigned to basic blocks
3980     unsigned     fgDomBBcount;     // # of BBs for which we have dominator and reachability information
3981     BasicBlock** fgBBInvPostOrder; // The flow graph stored in an array sorted in topological order, needed to compute
3982                                    // dominance. Indexed by block number. Size: fgBBNumMax + 1.
3983
3984     // After the dominance tree is computed, we cache a DFS preorder number and DFS postorder number to compute
3985     // dominance queries in O(1). fgDomTreePreOrder and fgDomTreePostOrder are arrays giving the block's preorder and
3986     // postorder number, respectively. The arrays are indexed by basic block number. (Note that blocks are numbered
3987     // starting from one. Thus, we always waste element zero. This makes debugging easier and makes the code less likely
3988     // to suffer from bugs stemming from forgetting to add or subtract one from the block number to form an array
3989     // index). The arrays are of size fgBBNumMax + 1.
3990     unsigned* fgDomTreePreOrder;
3991     unsigned* fgDomTreePostOrder;
3992
3993     bool fgBBVarSetsInited;
3994
3995     // Allocate array like T* a = new T[fgBBNumMax + 1];
3996     // Using helper so we don't keep forgetting +1.
3997     template <typename T>
3998     T* fgAllocateTypeForEachBlk(CompMemKind cmk = CMK_Unknown)
3999     {
4000         return getAllocator(cmk).allocate<T>(fgBBNumMax + 1);
4001     }
4002
4003     // BlockSets are relative to a specific set of BasicBlock numbers. If that changes
4004     // (if the blocks are renumbered), this changes. BlockSets from different epochs
4005     // cannot be meaningfully combined. Note that new blocks can be created with higher
4006     // block numbers without changing the basic block epoch. These blocks *cannot*
4007     // participate in a block set until the blocks are all renumbered, causing the epoch
4008     // to change. This is useful if continuing to use previous block sets is valuable.
4009     // If the epoch is zero, then it is uninitialized, and block sets can't be used.
4010     unsigned fgCurBBEpoch;
4011
4012     unsigned GetCurBasicBlockEpoch()
4013     {
4014         return fgCurBBEpoch;
4015     }
4016
4017     // The number of basic blocks in the current epoch. When the blocks are renumbered,
4018     // this is fgBBcount. As blocks are added, fgBBcount increases, fgCurBBEpochSize remains
4019     // the same, until a new BasicBlock epoch is created, such as when the blocks are all renumbered.
4020     unsigned fgCurBBEpochSize;
4021
4022     // The number of "size_t" elements required to hold a bitset large enough for fgCurBBEpochSize
4023     // bits. This is precomputed to avoid doing math every time BasicBlockBitSetTraits::GetArrSize() is called.
4024     unsigned fgBBSetCountInSizeTUnits;
4025
4026     void NewBasicBlockEpoch()
4027     {
4028         INDEBUG(unsigned oldEpochArrSize = fgBBSetCountInSizeTUnits);
4029
4030         // We have a new epoch. Compute and cache the size needed for new BlockSets.
4031         fgCurBBEpoch++;
4032         fgCurBBEpochSize = fgBBNumMax + 1;
4033         fgBBSetCountInSizeTUnits =
4034             roundUp(fgCurBBEpochSize, (unsigned)(sizeof(size_t) * 8)) / unsigned(sizeof(size_t) * 8);
4035
4036 #ifdef DEBUG
4037         // All BlockSet objects are now invalid!
4038         fgReachabilitySetsValid = false; // the bbReach sets are now invalid!
4039         fgEnterBlksSetValid     = false; // the fgEnterBlks set is now invalid!
4040
4041         if (verbose)
4042         {
4043             unsigned epochArrSize = BasicBlockBitSetTraits::GetArrSize(this, sizeof(size_t));
4044             printf("\nNew BlockSet epoch %d, # of blocks (including unused BB00): %u, bitset array size: %u (%s)",
4045                    fgCurBBEpoch, fgCurBBEpochSize, epochArrSize, (epochArrSize <= 1) ? "short" : "long");
4046             if ((fgCurBBEpoch != 1) && ((oldEpochArrSize <= 1) != (epochArrSize <= 1)))
4047             {
4048                 // If we're not just establishing the first epoch, and the epoch array size has changed such that we're
4049                 // going to change our bitset representation from short (just a size_t bitset) to long (a pointer to an
4050                 // array of size_t bitsets), then print that out.
4051                 printf("; NOTE: BlockSet size was previously %s!", (oldEpochArrSize <= 1) ? "short" : "long");
4052             }
4053             printf("\n");
4054         }
4055 #endif // DEBUG
4056     }
4057
4058     void EnsureBasicBlockEpoch()
4059     {
4060         if (fgCurBBEpochSize != fgBBNumMax + 1)
4061         {
4062             NewBasicBlockEpoch();
4063         }
4064     }
4065
4066     BasicBlock* fgNewBasicBlock(BBjumpKinds jumpKind);
4067     void fgEnsureFirstBBisScratch();
4068     bool fgFirstBBisScratch();
4069     bool fgBBisScratch(BasicBlock* block);
4070
4071     void fgExtendEHRegionBefore(BasicBlock* block);
4072     void fgExtendEHRegionAfter(BasicBlock* block);
4073
4074     BasicBlock* fgNewBBbefore(BBjumpKinds jumpKind, BasicBlock* block, bool extendRegion);
4075
4076     BasicBlock* fgNewBBafter(BBjumpKinds jumpKind, BasicBlock* block, bool extendRegion);
4077
4078     BasicBlock* fgNewBBinRegion(BBjumpKinds jumpKind,
4079                                 unsigned    tryIndex,
4080                                 unsigned    hndIndex,
4081                                 BasicBlock* nearBlk,
4082                                 bool        putInFilter = false,
4083                                 bool        runRarely   = false,
4084                                 bool        insertAtEnd = false);
4085
4086     BasicBlock* fgNewBBinRegion(BBjumpKinds jumpKind,
4087                                 BasicBlock* srcBlk,
4088                                 bool        runRarely   = false,
4089                                 bool        insertAtEnd = false);
4090
4091     BasicBlock* fgNewBBinRegion(BBjumpKinds jumpKind);
4092
4093     BasicBlock* fgNewBBinRegionWorker(BBjumpKinds jumpKind,
4094                                       BasicBlock* afterBlk,
4095                                       unsigned    xcptnIndex,
4096                                       bool        putInTryRegion);
4097
4098     void fgInsertBBbefore(BasicBlock* insertBeforeBlk, BasicBlock* newBlk);
4099     void fgInsertBBafter(BasicBlock* insertAfterBlk, BasicBlock* newBlk);
4100     void fgUnlinkBlock(BasicBlock* block);
4101
4102     unsigned fgMeasureIR();
4103
4104     bool fgModified;         // True if the flow graph has been modified recently
4105     bool fgComputePredsDone; // Have we computed the bbPreds list
4106     bool fgCheapPredsValid;  // Is the bbCheapPreds list valid?
4107     bool fgDomsComputed;     // Have we computed the dominator sets?
4108     bool fgOptimizedFinally; // Did we optimize any try-finallys?
4109
4110     bool fgHasSwitch; // any BBJ_SWITCH jumps?
4111
4112     BlockSet fgEnterBlks; // Set of blocks which have a special transfer of control; the "entry" blocks plus EH handler
4113                           // begin blocks.
4114
4115 #ifdef DEBUG
4116     bool fgReachabilitySetsValid; // Are the bbReach sets valid?
4117     bool fgEnterBlksSetValid;     // Is the fgEnterBlks set valid?
4118 #endif                            // DEBUG
4119
4120     bool fgRemoveRestOfBlock; // true if we know that we will throw
4121     bool fgStmtRemoved;       // true if we remove statements -> need new DFA
4122
4123     // There are two modes for ordering of the trees.
4124     //  - In FGOrderTree, the dominant ordering is the tree order, and the nodes contained in
4125     //    each tree and sub-tree are contiguous, and can be traversed (in gtNext/gtPrev order)
4126     //    by traversing the tree according to the order of the operands.
4127     //  - In FGOrderLinear, the dominant ordering is the linear order.
4128
4129     enum FlowGraphOrder
4130     {
4131         FGOrderTree,
4132         FGOrderLinear
4133     };
4134     FlowGraphOrder fgOrder;
4135
4136     // The following are boolean flags that keep track of the state of internal data structures
4137
4138     bool                 fgStmtListThreaded;       // true if the node list is now threaded
4139     bool                 fgCanRelocateEHRegions;   // true if we are allowed to relocate the EH regions
4140     bool                 fgEdgeWeightsComputed;    // true after we have called fgComputeEdgeWeights
4141     bool                 fgHaveValidEdgeWeights;   // true if we were successful in computing all of the edge weights
4142     bool                 fgSlopUsedInEdgeWeights;  // true if their was some slop used when computing the edge weights
4143     bool                 fgRangeUsedInEdgeWeights; // true if some of the edgeWeight are expressed in Min..Max form
4144     bool                 fgNeedsUpdateFlowGraph;   // true if we need to run fgUpdateFlowGraph
4145     BasicBlock::weight_t fgCalledCount;            // count of the number of times this method was called
4146                                                    // This is derived from the profile data
4147                                                    // or is BB_UNITY_WEIGHT when we don't have profile data
4148
4149 #if FEATURE_EH_FUNCLETS
4150     bool fgFuncletsCreated; // true if the funclet creation phase has been run
4151 #endif                      // FEATURE_EH_FUNCLETS
4152
4153     bool fgGlobalMorph; // indicates if we are during the global morphing phase
4154                         // since fgMorphTree can be called from several places
4155
4156     bool     impBoxTempInUse; // the temp below is valid and available
4157     unsigned impBoxTemp;      // a temporary that is used for boxing
4158
4159 #ifdef DEBUG
4160     bool jitFallbackCompile; // Are we doing a fallback compile? That is, have we executed a NO_WAY assert,
4161                              //   and we are trying to compile again in a "safer", minopts mode?
4162 #endif
4163
4164 #if defined(DEBUG)
4165     unsigned impInlinedCodeSize;
4166 #endif
4167
4168     //-------------------------------------------------------------------------
4169
4170     void fgInit();
4171
4172     void fgImport();
4173
4174     void fgTransformIndirectCalls();
4175
4176     void fgInline();
4177
4178     void fgRemoveEmptyTry();
4179
4180     void fgRemoveEmptyFinally();
4181
4182     void fgMergeFinallyChains();
4183
4184     void fgCloneFinally();
4185
4186     void fgCleanupContinuation(BasicBlock* continuation);
4187
4188     void fgUpdateFinallyTargetFlags();
4189
4190     void fgClearAllFinallyTargetBits();
4191
4192     void fgAddFinallyTargetFlags();
4193
4194 #if FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
4195     // Sometimes we need to defer updating the BBF_FINALLY_TARGET bit. fgNeedToAddFinallyTargetBits signals
4196     // when this is necessary.
4197     bool fgNeedToAddFinallyTargetBits;
4198 #endif // FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
4199
4200     bool fgRetargetBranchesToCanonicalCallFinally(BasicBlock*      block,
4201                                                   BasicBlock*      handler,
4202                                                   BlockToBlockMap& continuationMap);
4203
4204     GenTree* fgGetCritSectOfStaticMethod();
4205
4206 #if FEATURE_EH_FUNCLETS
4207
4208     void fgAddSyncMethodEnterExit();
4209
4210     GenTree* fgCreateMonitorTree(unsigned lvaMonitorBool, unsigned lvaThisVar, BasicBlock* block, bool enter);
4211
4212     void fgConvertSyncReturnToLeave(BasicBlock* block);
4213
4214 #endif // FEATURE_EH_FUNCLETS
4215
4216     void fgAddReversePInvokeEnterExit();
4217
4218     bool fgMoreThanOneReturnBlock();
4219
4220     // The number of separate return points in the method.
4221     unsigned fgReturnCount;
4222
4223     void fgAddInternal();
4224
4225     bool fgFoldConditional(BasicBlock* block);
4226
4227     void fgMorphStmts(BasicBlock* block, bool* lnot, bool* loadw);
4228     void fgMorphBlocks();
4229
4230     bool fgMorphBlockStmt(BasicBlock* block, GenTreeStmt* stmt DEBUGARG(const char* msg));
4231
4232     void fgSetOptions();
4233
4234 #ifdef DEBUG
4235     static fgWalkPreFn fgAssertNoQmark;
4236     void fgPreExpandQmarkChecks(GenTree* expr);
4237     void        fgPostExpandQmarkChecks();
4238     static void fgCheckQmarkAllowedForm(GenTree* tree);
4239 #endif
4240
4241     IL_OFFSET fgFindBlockILOffset(BasicBlock* block);
4242
4243     BasicBlock* fgSplitBlockAtBeginning(BasicBlock* curr);
4244     BasicBlock* fgSplitBlockAtEnd(BasicBlock* curr);
4245     BasicBlock* fgSplitBlockAfterStatement(BasicBlock* curr, GenTree* stmt);
4246     BasicBlock* fgSplitBlockAfterNode(BasicBlock* curr, GenTree* node); // for LIR
4247     BasicBlock* fgSplitEdge(BasicBlock* curr, BasicBlock* succ);
4248
4249     GenTreeStmt* fgNewStmtFromTree(GenTree* tree, BasicBlock* block, IL_OFFSETX offs);
4250     GenTreeStmt* fgNewStmtFromTree(GenTree* tree);
4251     GenTreeStmt* fgNewStmtFromTree(GenTree* tree, BasicBlock* block);
4252     GenTreeStmt* fgNewStmtFromTree(GenTree* tree, IL_OFFSETX offs);
4253
4254     GenTree* fgGetTopLevelQmark(GenTree* expr, GenTree** ppDst = nullptr);
4255     void fgExpandQmarkForCastInstOf(BasicBlock* block, GenTree* stmt);
4256     void fgExpandQmarkStmt(BasicBlock* block, GenTree* expr);
4257     void fgExpandQmarkNodes();
4258
4259     void fgMorph();
4260
4261     // Do "simple lowering."  This functionality is (conceptually) part of "general"
4262     // lowering that is distributed between fgMorph and the lowering phase of LSRA.
4263     void fgSimpleLowering();
4264
4265     GenTree* fgInitThisClass();
4266
4267     GenTreeCall* fgGetStaticsCCtorHelper(CORINFO_CLASS_HANDLE cls, CorInfoHelpFunc helper);
4268
4269     GenTreeCall* fgGetSharedCCtor(CORINFO_CLASS_HANDLE cls);
4270
4271     bool backendRequiresLocalVarLifetimes()
4272     {
4273         return !opts.MinOpts() || m_pLinearScan->willEnregisterLocalVars();
4274     }
4275
4276     void fgLocalVarLiveness();
4277
4278     void fgLocalVarLivenessInit();
4279
4280     void fgPerNodeLocalVarLiveness(GenTree* node);
4281     void fgPerBlockLocalVarLiveness();
4282
4283     VARSET_VALRET_TP fgGetHandlerLiveVars(BasicBlock* block);
4284
4285     void fgLiveVarAnalysis(bool updateInternalOnly = false);
4286
4287     void fgComputeLifeCall(VARSET_TP& life, GenTreeCall* call);
4288
4289     void fgComputeLifeTrackedLocalUse(VARSET_TP& life, LclVarDsc& varDsc, GenTreeLclVarCommon* node);
4290     bool fgComputeLifeTrackedLocalDef(VARSET_TP&           life,
4291                                       VARSET_VALARG_TP     keepAliveVars,
4292                                       LclVarDsc&           varDsc,
4293                                       GenTreeLclVarCommon* node);
4294     void fgComputeLifeUntrackedLocal(VARSET_TP&           life,
4295                                      VARSET_VALARG_TP     keepAliveVars,
4296                                      LclVarDsc&           varDsc,
4297                                      GenTreeLclVarCommon* lclVarNode);
4298     bool fgComputeLifeLocal(VARSET_TP& life, VARSET_VALARG_TP keepAliveVars, GenTree* lclVarNode);
4299
4300     void fgComputeLife(VARSET_TP&       life,
4301                        GenTree*         startNode,
4302                        GenTree*         endNode,
4303                        VARSET_VALARG_TP volatileVars,
4304                        bool* pStmtInfoDirty DEBUGARG(bool* treeModf));
4305
4306     void fgComputeLifeLIR(VARSET_TP& life, BasicBlock* block, VARSET_VALARG_TP volatileVars);
4307
4308     bool fgRemoveDeadStore(GenTree**        pTree,
4309                            LclVarDsc*       varDsc,
4310                            VARSET_VALARG_TP life,
4311                            bool*            doAgain,
4312                            bool* pStmtInfoDirty DEBUGARG(bool* treeModf));
4313
4314     // For updating liveset during traversal AFTER fgComputeLife has completed
4315     VARSET_VALRET_TP fgGetVarBits(GenTree* tree);
4316     VARSET_VALRET_TP fgUpdateLiveSet(VARSET_VALARG_TP liveSet, GenTree* tree);
4317
4318     // Returns the set of live variables after endTree,
4319     // assuming that liveSet is the set of live variables BEFORE tree.
4320     // Requires that fgComputeLife has completed, and that tree is in the same
4321     // statement as endTree, and that it comes before endTree in execution order
4322
4323     VARSET_VALRET_TP fgUpdateLiveSet(VARSET_VALARG_TP liveSet, GenTree* tree, GenTree* endTree)
4324     {
4325         VARSET_TP newLiveSet(VarSetOps::MakeCopy(this, liveSet));
4326         while (tree != nullptr && tree != endTree->gtNext)
4327         {
4328             VarSetOps::AssignNoCopy(this, newLiveSet, fgUpdateLiveSet(newLiveSet, tree));
4329             tree = tree->gtNext;
4330         }
4331         assert(tree == endTree->gtNext);
4332         return newLiveSet;
4333     }
4334
4335     void fgInterBlockLocalVarLiveness();
4336
4337     // The presence of a partial definition presents some difficulties for SSA: this is both a use of some SSA name
4338     // 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
4339     // whether to treat that as the use or def.  It chooses the "use", and thus the old SSA name.  This map allows us
4340     // to record/recover the "def" SSA number, given the lcl var node for "x" in such a tree.
4341     typedef JitHashTable<GenTree*, JitPtrKeyFuncs<GenTree>, unsigned> NodeToUnsignedMap;
4342     NodeToUnsignedMap* m_opAsgnVarDefSsaNums;
4343     NodeToUnsignedMap* GetOpAsgnVarDefSsaNums()
4344     {
4345         if (m_opAsgnVarDefSsaNums == nullptr)
4346         {
4347             m_opAsgnVarDefSsaNums = new (getAllocator()) NodeToUnsignedMap(getAllocator());
4348         }
4349         return m_opAsgnVarDefSsaNums;
4350     }
4351
4352     // Requires value numbering phase to have completed. Returns the value number ("gtVN") of the
4353     // "tree," EXCEPT in the case of GTF_VAR_USEASG, because the tree node's gtVN member is the
4354     // "use" VN. Performs a lookup into the map of (use asg tree -> def VN.) to return the "def's"
4355     // VN.
4356     inline ValueNum GetUseAsgDefVNOrTreeVN(GenTree* tree);
4357
4358     // Requires that "lcl" has the GTF_VAR_DEF flag set.  Returns the SSA number of "lcl".
4359     // Except: assumes that lcl is a def, and if it is
4360     // a partial def (GTF_VAR_USEASG), looks up and returns the SSA number for the "def",
4361     // rather than the "use" SSA number recorded in the tree "lcl".
4362     inline unsigned GetSsaNumForLocalVarDef(GenTree* lcl);
4363
4364     // Performs SSA conversion.
4365     void fgSsaBuild();
4366
4367     // Reset any data structures to the state expected by "fgSsaBuild", so it can be run again.
4368     void fgResetForSsa();
4369
4370     unsigned fgSsaPassesCompleted; // Number of times fgSsaBuild has been run.
4371
4372     // Returns "true" if a struct temp of the given type requires needs zero init in this block
4373     inline bool fgStructTempNeedsExplicitZeroInit(LclVarDsc* varDsc, BasicBlock* block);
4374
4375     // The value numbers for this compilation.
4376     ValueNumStore* vnStore;
4377
4378 public:
4379     ValueNumStore* GetValueNumStore()
4380     {
4381         return vnStore;
4382     }
4383
4384     // Do value numbering (assign a value number to each
4385     // tree node).
4386     void fgValueNumber();
4387
4388     // Computes new GcHeap VN via the assignment H[elemTypeEq][arrVN][inx][fldSeq] = rhsVN.
4389     // Assumes that "elemTypeEq" is the (equivalence class rep) of the array element type.
4390     // The 'indType' is the indirection type of the lhs of the assignment and will typically
4391     // match the element type of the array or fldSeq.  When this type doesn't match
4392     // or if the fldSeq is 'NotAField' we invalidate the array contents H[elemTypeEq][arrVN]
4393     //
4394     ValueNum fgValueNumberArrIndexAssign(CORINFO_CLASS_HANDLE elemTypeEq,
4395                                          ValueNum             arrVN,
4396                                          ValueNum             inxVN,
4397                                          FieldSeqNode*        fldSeq,
4398                                          ValueNum             rhsVN,
4399                                          var_types            indType);
4400
4401     // Requires that "tree" is a GT_IND marked as an array index, and that its address argument
4402     // has been parsed to yield the other input arguments.  If evaluation of the address
4403     // can raise exceptions, those should be captured in the exception set "excVN."
4404     // Assumes that "elemTypeEq" is the (equivalence class rep) of the array element type.
4405     // Marks "tree" with the VN for H[elemTypeEq][arrVN][inx][fldSeq] (for the liberal VN; a new unique
4406     // VN for the conservative VN.)  Also marks the tree's argument as the address of an array element.
4407     // The type tree->TypeGet() will typically match the element type of the array or fldSeq.
4408     // When this type doesn't match or if the fldSeq is 'NotAField' we return a new unique VN
4409     //
4410     ValueNum fgValueNumberArrIndexVal(GenTree*             tree,
4411                                       CORINFO_CLASS_HANDLE elemTypeEq,
4412                                       ValueNum             arrVN,
4413                                       ValueNum             inxVN,
4414                                       ValueNum             excVN,
4415                                       FieldSeqNode*        fldSeq);
4416
4417     // Requires "funcApp" to be a VNF_PtrToArrElem, and "addrXvn" to represent the exception set thrown
4418     // by evaluating the array index expression "tree".  Returns the value number resulting from
4419     // dereferencing the array in the current GcHeap state.  If "tree" is non-null, it must be the
4420     // "GT_IND" that does the dereference, and it is given the returned value number.
4421     ValueNum fgValueNumberArrIndexVal(GenTree* tree, struct VNFuncApp* funcApp, ValueNum addrXvn);
4422
4423     // Compute the value number for a byref-exposed load of the given type via the given pointerVN.
4424     ValueNum fgValueNumberByrefExposedLoad(var_types type, ValueNum pointerVN);
4425
4426     unsigned fgVNPassesCompleted; // Number of times fgValueNumber has been run.
4427
4428     // Utility functions for fgValueNumber.
4429
4430     // Perform value-numbering for the trees in "blk".
4431     void fgValueNumberBlock(BasicBlock* blk);
4432
4433     // Requires that "entryBlock" is the entry block of loop "loopNum", and that "loopNum" is the
4434     // innermost loop of which "entryBlock" is the entry.  Returns the value number that should be
4435     // assumed for the memoryKind at the start "entryBlk".
4436     ValueNum fgMemoryVNForLoopSideEffects(MemoryKind memoryKind, BasicBlock* entryBlock, unsigned loopNum);
4437
4438     // Called when an operation (performed by "tree", described by "msg") may cause the GcHeap to be mutated.
4439     // As GcHeap is a subset of ByrefExposed, this will also annotate the ByrefExposed mutation.
4440     void fgMutateGcHeap(GenTree* tree DEBUGARG(const char* msg));
4441
4442     // Called when an operation (performed by "tree", described by "msg") may cause an address-exposed local to be
4443     // mutated.
4444     void fgMutateAddressExposedLocal(GenTree* tree DEBUGARG(const char* msg));
4445
4446     // For a GC heap store at curTree, record the new curMemoryVN's and update curTree's MemorySsaMap.
4447     // As GcHeap is a subset of ByrefExposed, this will also record the ByrefExposed store.
4448     void recordGcHeapStore(GenTree* curTree, ValueNum gcHeapVN DEBUGARG(const char* msg));
4449
4450     // For a store to an address-exposed local at curTree, record the new curMemoryVN and update curTree's MemorySsaMap.
4451     void recordAddressExposedLocalStore(GenTree* curTree, ValueNum memoryVN DEBUGARG(const char* msg));
4452
4453     // Tree caused an update in the current memory VN.  If "tree" has an associated heap SSA #, record that
4454     // value in that SSA #.
4455     void fgValueNumberRecordMemorySsa(MemoryKind memoryKind, GenTree* tree);
4456
4457     // The input 'tree' is a leaf node that is a constant
4458     // Assign the proper value number to the tree
4459     void fgValueNumberTreeConst(GenTree* tree);
4460
4461     // Assumes that all inputs to "tree" have had value numbers assigned; assigns a VN to tree.
4462     // (With some exceptions: the VN of the lhs of an assignment is assigned as part of the
4463     // assignment.)
4464     void fgValueNumberTree(GenTree* tree);
4465
4466     // Does value-numbering for a block assignment.
4467     void fgValueNumberBlockAssignment(GenTree* tree);
4468
4469     // Does value-numbering for a cast tree.
4470     void fgValueNumberCastTree(GenTree* tree);
4471
4472     // Does value-numbering for an intrinsic tree.
4473     void fgValueNumberIntrinsic(GenTree* tree);
4474
4475     // Does value-numbering for a call.  We interpret some helper calls.
4476     void fgValueNumberCall(GenTreeCall* call);
4477
4478     // The VN of some nodes in "args" may have changed -- reassign VNs to the arg list nodes.
4479     void fgUpdateArgListVNs(GenTreeArgList* args);
4480
4481     // Does value-numbering for a helper "call" that has a VN function symbol "vnf".
4482     void fgValueNumberHelperCallFunc(GenTreeCall* call, VNFunc vnf, ValueNumPair vnpExc);
4483
4484     // Requires "helpCall" to be a helper call.  Assigns it a value number;
4485     // we understand the semantics of some of the calls.  Returns "true" if
4486     // the call may modify the heap (we assume arbitrary memory side effects if so).
4487     bool fgValueNumberHelperCall(GenTreeCall* helpCall);
4488
4489     // Requires that "helpFunc" is one of the pure Jit Helper methods.
4490     // Returns the corresponding VNFunc to use for value numbering
4491     VNFunc fgValueNumberJitHelperMethodVNFunc(CorInfoHelpFunc helpFunc);
4492
4493     // Adds the exception set for the current tree node which has a memory indirection operation
4494     void fgValueNumberAddExceptionSetForIndirection(GenTree* tree, GenTree* baseAddr);
4495
4496     // Adds the exception sets for the current tree node which is performing a division or modulus operation
4497     void fgValueNumberAddExceptionSetForDivision(GenTree* tree);
4498
4499     // Adds the exception set for the current tree node which is performing a overflow checking operation
4500     void fgValueNumberAddExceptionSetForOverflow(GenTree* tree);
4501
4502     // Adds the exception set for the current tree node which is performing a ckfinite operation
4503     void fgValueNumberAddExceptionSetForCkFinite(GenTree* tree);
4504
4505     // Adds the exception sets for the current tree node
4506     void fgValueNumberAddExceptionSet(GenTree* tree);
4507
4508     // These are the current value number for the memory implicit variables while
4509     // doing value numbering.  These are the value numbers under the "liberal" interpretation
4510     // of memory values; the "conservative" interpretation needs no VN, since every access of
4511     // memory yields an unknown value.
4512     ValueNum fgCurMemoryVN[MemoryKindCount];
4513
4514     // Return a "pseudo"-class handle for an array element type.  If "elemType" is TYP_STRUCT,
4515     // requires "elemStructType" to be non-null (and to have a low-order zero).  Otherwise, low order bit
4516     // is 1, and the rest is an encoding of "elemTyp".
4517     static CORINFO_CLASS_HANDLE EncodeElemType(var_types elemTyp, CORINFO_CLASS_HANDLE elemStructType)
4518     {
4519         if (elemStructType != nullptr)
4520         {
4521             assert(varTypeIsStruct(elemTyp) || elemTyp == TYP_REF || elemTyp == TYP_BYREF ||
4522                    varTypeIsIntegral(elemTyp));
4523             assert((size_t(elemStructType) & 0x1) == 0x0); // Make sure the encoding below is valid.
4524             return elemStructType;
4525         }
4526         else
4527         {
4528             assert(elemTyp != TYP_STRUCT);
4529             elemTyp = varTypeUnsignedToSigned(elemTyp);
4530             return CORINFO_CLASS_HANDLE(size_t(elemTyp) << 1 | 0x1);
4531         }
4532     }
4533     // If "clsHnd" is the result of an "EncodePrim" call, returns true and sets "*pPrimType" to the
4534     // var_types it represents.  Otherwise, returns TYP_STRUCT (on the assumption that "clsHnd" is
4535     // the struct type of the element).
4536     static var_types DecodeElemType(CORINFO_CLASS_HANDLE clsHnd)
4537     {
4538         size_t clsHndVal = size_t(clsHnd);
4539         if (clsHndVal & 0x1)
4540         {
4541             return var_types(clsHndVal >> 1);
4542         }
4543         else
4544         {
4545             return TYP_STRUCT;
4546         }
4547     }
4548
4549     // Convert a BYTE which represents the VM's CorInfoGCtype to the JIT's var_types
4550     var_types getJitGCType(BYTE gcType);
4551
4552     enum structPassingKind
4553     {
4554         SPK_Unknown,       // Invalid value, never returned
4555         SPK_PrimitiveType, // The struct is passed/returned using a primitive type.
4556         SPK_EnclosingType, // Like SPK_Primitive type, but used for return types that
4557                            //  require a primitive type temp that is larger than the struct size.
4558                            //  Currently used for structs of size 3, 5, 6, or 7 bytes.
4559         SPK_ByValue,       // The struct is passed/returned by value (using the ABI rules)
4560                            //  for ARM64 and UNIX_X64 in multiple registers. (when all of the
4561                            //   parameters registers are used, then the stack will be used)
4562                            //  for X86 passed on the stack, for ARM32 passed in registers
4563                            //   or the stack or split between registers and the stack.
4564         SPK_ByValueAsHfa,  // The struct is passed/returned as an HFA in multiple registers.
4565         SPK_ByReference
4566     }; // The struct is passed/returned by reference to a copy/buffer.
4567
4568     // Get the "primitive" type that is is used when we are given a struct of size 'structSize'.
4569     // For pointer sized structs the 'clsHnd' is used to determine if the struct contains GC ref.
4570     // A "primitive" type is one of the scalar types: byte, short, int, long, ref, float, double
4571     // If we can't or shouldn't use a "primitive" type then TYP_UNKNOWN is returned.
4572     //
4573     // isVarArg is passed for use on Windows Arm64 to change the decision returned regarding
4574     // hfa types.
4575     //
4576     var_types getPrimitiveTypeForStruct(unsigned structSize, CORINFO_CLASS_HANDLE clsHnd, bool isVarArg);
4577
4578     // Get the type that is used to pass values of the given struct type.
4579     // isVarArg is passed for use on Windows Arm64 to change the decision returned regarding
4580     // hfa types.
4581     //
4582     var_types getArgTypeForStruct(CORINFO_CLASS_HANDLE clsHnd,
4583                                   structPassingKind*   wbPassStruct,
4584                                   bool                 isVarArg,
4585                                   unsigned             structSize);
4586
4587     // Get the type that is used to return values of the given struct type.
4588     // If the size is unknown, pass 0 and it will be determined from 'clsHnd'.
4589     var_types getReturnTypeForStruct(CORINFO_CLASS_HANDLE clsHnd,
4590                                      structPassingKind*   wbPassStruct = nullptr,
4591                                      unsigned             structSize   = 0);
4592
4593 #ifdef DEBUG
4594     // Print a representation of "vnp" or "vn" on standard output.
4595     // If "level" is non-zero, we also print out a partial expansion of the value.
4596     void vnpPrint(ValueNumPair vnp, unsigned level);
4597     void vnPrint(ValueNum vn, unsigned level);
4598 #endif
4599
4600     bool fgDominate(BasicBlock* b1, BasicBlock* b2); // Return true if b1 dominates b2
4601
4602     // Dominator computation member functions
4603     // Not exposed outside Compiler
4604 protected:
4605     bool fgReachable(BasicBlock* b1, BasicBlock* b2); // Returns true if block b1 can reach block b2
4606
4607     void fgComputeDoms(); // Computes the immediate dominators for each basic block in the
4608                           // flow graph.  We first assume the fields bbIDom on each
4609                           // basic block are invalid. This computation is needed later
4610                           // by fgBuildDomTree to build the dominance tree structure.
4611                           // Based on: A Simple, Fast Dominance Algorithm
4612                           // by Keith D. Cooper, Timothy J. Harvey, and Ken Kennedy
4613
4614     void fgCompDominatedByExceptionalEntryBlocks();
4615
4616     BlockSet_ValRet_T fgGetDominatorSet(BasicBlock* block); // Returns a set of blocks that dominate the given block.
4617     // Note: this is relatively slow compared to calling fgDominate(),
4618     // especially if dealing with a single block versus block check.
4619
4620     void fgComputeReachabilitySets(); // Compute bbReach sets. (Also sets BBF_GC_SAFE_POINT flag on blocks.)
4621
4622     void fgComputeEnterBlocksSet(); // Compute the set of entry blocks, 'fgEnterBlks'.
4623
4624     bool fgRemoveUnreachableBlocks(); // Remove blocks determined to be unreachable by the bbReach sets.
4625
4626     void fgComputeReachability(); // Perform flow graph node reachability analysis.
4627
4628     BasicBlock* fgIntersectDom(BasicBlock* a, BasicBlock* b); // Intersect two immediate dominator sets.
4629
4630     void fgDfsInvPostOrder(); // In order to compute dominance using fgIntersectDom, the flow graph nodes must be
4631                               // processed in topological sort, this function takes care of that.
4632
4633     void fgDfsInvPostOrderHelper(BasicBlock* block, BlockSet& visited, unsigned* count);
4634
4635     BlockSet_ValRet_T fgDomFindStartNodes(); // Computes which basic blocks don't have incoming edges in the flow graph.
4636                                              // Returns this as a set.
4637
4638     BlockSet_ValRet_T fgDomTreeEntryNodes(BasicBlockList** domTree); // Computes which nodes in the dominance forest are
4639                                                                      // root nodes. Returns this as a set.
4640
4641 #ifdef DEBUG
4642     void fgDispDomTree(BasicBlockList** domTree); // Helper that prints out the Dominator Tree in debug builds.
4643 #endif                                            // DEBUG
4644
4645     void fgBuildDomTree(); // Once we compute all the immediate dominator sets for each node in the flow graph
4646                            // (performed by fgComputeDoms), this procedure builds the dominance tree represented
4647                            // adjacency lists.
4648
4649     // In order to speed up the queries of the form 'Does A dominates B', we can perform a DFS preorder and postorder
4650     // traversal of the dominance tree and the dominance query will become A dominates B iif preOrder(A) <= preOrder(B)
4651     // && postOrder(A) >= postOrder(B) making the computation O(1).
4652     void fgTraverseDomTree(unsigned bbNum, BasicBlockList** domTree, unsigned* preNum, unsigned* postNum);
4653
4654     // When the flow graph changes, we need to update the block numbers, predecessor lists, reachability sets, and
4655     // dominators.
4656     void fgUpdateChangedFlowGraph();
4657
4658 public:
4659     // Compute the predecessors of the blocks in the control flow graph.
4660     void fgComputePreds();
4661
4662     // Remove all predecessor information.
4663     void fgRemovePreds();
4664
4665     // Compute the cheap flow graph predecessors lists. This is used in some early phases
4666     // before the full predecessors lists are computed.
4667     void fgComputeCheapPreds();
4668
4669 private:
4670     void fgAddCheapPred(BasicBlock* block, BasicBlock* blockPred);
4671
4672     void fgRemoveCheapPred(BasicBlock* block, BasicBlock* blockPred);
4673
4674 public:
4675     enum GCPollType
4676     {
4677         GCPOLL_NONE,
4678         GCPOLL_CALL,
4679         GCPOLL_INLINE
4680     };
4681
4682     // Initialize the per-block variable sets (used for liveness analysis).
4683     void fgInitBlockVarSets();
4684
4685     // true if we've gone through and created GC Poll calls.
4686     bool fgGCPollsCreated;
4687     void fgMarkGCPollBlocks();
4688     void fgCreateGCPolls();
4689     bool fgCreateGCPoll(GCPollType pollType, BasicBlock* block);
4690
4691     // Requires that "block" is a block that returns from
4692     // a finally.  Returns the number of successors (jump targets of
4693     // of blocks in the covered "try" that did a "LEAVE".)
4694     unsigned fgNSuccsOfFinallyRet(BasicBlock* block);
4695
4696     // Requires that "block" is a block that returns (in the sense of BBJ_EHFINALLYRET) from
4697     // a finally.  Returns its "i"th successor (jump targets of
4698     // of blocks in the covered "try" that did a "LEAVE".)
4699     // Requires that "i" < fgNSuccsOfFinallyRet(block).
4700     BasicBlock* fgSuccOfFinallyRet(BasicBlock* block, unsigned i);
4701
4702 private:
4703     // Factor out common portions of the impls of the methods above.
4704     void fgSuccOfFinallyRetWork(BasicBlock* block, unsigned i, BasicBlock** bres, unsigned* nres);
4705
4706 public:
4707     // For many purposes, it is desirable to be able to enumerate the *distinct* targets of a switch statement,
4708     // skipping duplicate targets.  (E.g., in flow analyses that are only interested in the set of possible targets.)
4709     // SwitchUniqueSuccSet contains the non-duplicated switch targets.
4710     // (Code that modifies the jump table of a switch has an obligation to call Compiler::UpdateSwitchTableTarget,
4711     // which in turn will call the "UpdateTarget" method of this type if a SwitchUniqueSuccSet has already
4712     // been computed for the switch block.  If a switch block is deleted or is transformed into a non-switch,
4713     // we leave the entry associated with the block, but it will no longer be accessed.)
4714     struct SwitchUniqueSuccSet
4715     {
4716         unsigned     numDistinctSuccs; // Number of distinct targets of the switch.
4717         BasicBlock** nonDuplicates;    // Array of "numDistinctSuccs", containing all the distinct switch target
4718                                        // successors.
4719
4720         // The switch block "switchBlk" just had an entry with value "from" modified to the value "to".
4721         // Update "this" as necessary: if "from" is no longer an element of the jump table of "switchBlk",
4722         // remove it from "this", and ensure that "to" is a member.  Use "alloc" to do any required allocation.
4723         void UpdateTarget(CompAllocator alloc, BasicBlock* switchBlk, BasicBlock* from, BasicBlock* to);
4724     };
4725
4726     typedef JitHashTable<BasicBlock*, JitPtrKeyFuncs<BasicBlock>, SwitchUniqueSuccSet> BlockToSwitchDescMap;
4727
4728 private:
4729     // Maps BasicBlock*'s that end in switch statements to SwitchUniqueSuccSets that allow
4730     // iteration over only the distinct successors.
4731     BlockToSwitchDescMap* m_switchDescMap;
4732
4733 public:
4734     BlockToSwitchDescMap* GetSwitchDescMap(bool createIfNull = true)
4735     {
4736         if ((m_switchDescMap == nullptr) && createIfNull)
4737         {
4738             m_switchDescMap = new (getAllocator()) BlockToSwitchDescMap(getAllocator());
4739         }
4740         return m_switchDescMap;
4741     }
4742
4743     // Invalidate the map of unique switch block successors. For example, since the hash key of the map
4744     // depends on block numbers, we must invalidate the map when the blocks are renumbered, to ensure that
4745     // we don't accidentally look up and return the wrong switch data.
4746     void InvalidateUniqueSwitchSuccMap()
4747     {
4748         m_switchDescMap = nullptr;
4749     }
4750
4751     // Requires "switchBlock" to be a block that ends in a switch.  Returns
4752     // the corresponding SwitchUniqueSuccSet.
4753     SwitchUniqueSuccSet GetDescriptorForSwitch(BasicBlock* switchBlk);
4754
4755     // The switch block "switchBlk" just had an entry with value "from" modified to the value "to".
4756     // Update "this" as necessary: if "from" is no longer an element of the jump table of "switchBlk",
4757     // remove it from "this", and ensure that "to" is a member.
4758     void UpdateSwitchTableTarget(BasicBlock* switchBlk, BasicBlock* from, BasicBlock* to);
4759
4760     // Remove the "SwitchUniqueSuccSet" of "switchBlk" in the BlockToSwitchDescMap.
4761     void fgInvalidateSwitchDescMapEntry(BasicBlock* switchBlk);
4762
4763     BasicBlock* fgFirstBlockOfHandler(BasicBlock* block);
4764
4765     flowList* fgGetPredForBlock(BasicBlock* block, BasicBlock* blockPred);
4766
4767     flowList* fgGetPredForBlock(BasicBlock* block, BasicBlock* blockPred, flowList*** ptrToPred);
4768
4769     flowList* fgSpliceOutPred(BasicBlock* block, BasicBlock* blockPred);
4770
4771     flowList* fgRemoveRefPred(BasicBlock* block, BasicBlock* blockPred);
4772
4773     flowList* fgRemoveAllRefPreds(BasicBlock* block, BasicBlock* blockPred);
4774
4775     flowList* fgRemoveAllRefPreds(BasicBlock* block, flowList** ptrToPred);
4776
4777     void fgRemoveBlockAsPred(BasicBlock* block);
4778
4779     void fgChangeSwitchBlock(BasicBlock* oldSwitchBlock, BasicBlock* newSwitchBlock);
4780
4781     void fgReplaceSwitchJumpTarget(BasicBlock* blockSwitch, BasicBlock* newTarget, BasicBlock* oldTarget);
4782
4783     void fgReplaceJumpTarget(BasicBlock* block, BasicBlock* newTarget, BasicBlock* oldTarget);
4784
4785     void fgReplacePred(BasicBlock* block, BasicBlock* oldPred, BasicBlock* newPred);
4786
4787     flowList* fgAddRefPred(BasicBlock* block,
4788                            BasicBlock* blockPred,
4789                            flowList*   oldEdge           = nullptr,
4790                            bool        initializingPreds = false); // Only set to 'true' when we are computing preds in
4791                                                                    // fgComputePreds()
4792
4793     void fgFindBasicBlocks();
4794
4795     bool fgIsBetterFallThrough(BasicBlock* bCur, BasicBlock* bAlt);
4796
4797     bool fgCheckEHCanInsertAfterBlock(BasicBlock* blk, unsigned regionIndex, bool putInTryRegion);
4798
4799     BasicBlock* fgFindInsertPoint(unsigned    regionIndex,
4800                                   bool        putInTryRegion,
4801                                   BasicBlock* startBlk,
4802                                   BasicBlock* endBlk,
4803                                   BasicBlock* nearBlk,
4804                                   BasicBlock* jumpBlk,
4805                                   bool        runRarely);
4806
4807     unsigned fgGetNestingLevel(BasicBlock* block, unsigned* pFinallyNesting = nullptr);
4808
4809     void fgRemoveEmptyBlocks();
4810
4811     void fgRemoveStmt(BasicBlock* block, GenTree* stmt);
4812
4813     bool fgCheckRemoveStmt(BasicBlock* block, GenTree* stmt);
4814
4815     void fgCreateLoopPreHeader(unsigned lnum);
4816
4817     void fgUnreachableBlock(BasicBlock* block);
4818
4819     void fgRemoveConditionalJump(BasicBlock* block);
4820
4821     BasicBlock* fgLastBBInMainFunction();
4822
4823     BasicBlock* fgEndBBAfterMainFunction();
4824
4825     void fgUnlinkRange(BasicBlock* bBeg, BasicBlock* bEnd);
4826
4827     void fgRemoveBlock(BasicBlock* block, bool unreachable);
4828
4829     bool fgCanCompactBlocks(BasicBlock* block, BasicBlock* bNext);
4830
4831     void fgCompactBlocks(BasicBlock* block, BasicBlock* bNext);
4832
4833     void fgUpdateLoopsAfterCompacting(BasicBlock* block, BasicBlock* bNext);
4834
4835     BasicBlock* fgConnectFallThrough(BasicBlock* bSrc, BasicBlock* bDst);
4836
4837     bool fgRenumberBlocks();
4838
4839     bool fgExpandRarelyRunBlocks();
4840
4841     bool fgEhAllowsMoveBlock(BasicBlock* bBefore, BasicBlock* bAfter);
4842
4843     void fgMoveBlocksAfter(BasicBlock* bStart, BasicBlock* bEnd, BasicBlock* insertAfterBlk);
4844
4845     enum FG_RELOCATE_TYPE
4846     {
4847         FG_RELOCATE_TRY,    // relocate the 'try' region
4848         FG_RELOCATE_HANDLER // relocate the handler region (including the filter if necessary)
4849     };
4850     BasicBlock* fgRelocateEHRange(unsigned regionIndex, FG_RELOCATE_TYPE relocateType);
4851
4852 #if FEATURE_EH_FUNCLETS
4853 #if defined(_TARGET_ARM_)
4854     void fgClearFinallyTargetBit(BasicBlock* block);
4855 #endif // defined(_TARGET_ARM_)
4856     bool fgIsIntraHandlerPred(BasicBlock* predBlock, BasicBlock* block);
4857     bool fgAnyIntraHandlerPreds(BasicBlock* block);
4858     void fgInsertFuncletPrologBlock(BasicBlock* block);
4859     void fgCreateFuncletPrologBlocks();
4860     void fgCreateFunclets();
4861 #else  // !FEATURE_EH_FUNCLETS
4862     bool fgRelocateEHRegions();
4863 #endif // !FEATURE_EH_FUNCLETS
4864
4865     bool fgOptimizeUncondBranchToSimpleCond(BasicBlock* block, BasicBlock* target);
4866
4867     bool fgBlockEndFavorsTailDuplication(BasicBlock* block);
4868
4869     bool fgBlockIsGoodTailDuplicationCandidate(BasicBlock* block);
4870
4871     bool fgOptimizeEmptyBlock(BasicBlock* block);
4872
4873     bool fgOptimizeBranchToEmptyUnconditional(BasicBlock* block, BasicBlock* bDest);
4874
4875     bool fgOptimizeBranch(BasicBlock* bJump);
4876
4877     bool fgOptimizeSwitchBranches(BasicBlock* block);
4878
4879     bool fgOptimizeBranchToNext(BasicBlock* block, BasicBlock* bNext, BasicBlock* bPrev);
4880
4881     bool fgOptimizeSwitchJumps();
4882 #ifdef DEBUG
4883     void fgPrintEdgeWeights();
4884 #endif
4885     void                 fgComputeBlockAndEdgeWeights();
4886     BasicBlock::weight_t fgComputeMissingBlockWeights();
4887     void fgComputeCalledCount(BasicBlock::weight_t returnWeight);
4888     void fgComputeEdgeWeights();
4889
4890     void fgReorderBlocks();
4891
4892     void fgDetermineFirstColdBlock();
4893
4894     bool fgIsForwardBranch(BasicBlock* bJump, BasicBlock* bSrc = nullptr);
4895
4896     bool fgUpdateFlowGraph(bool doTailDup = false);
4897
4898     void fgFindOperOrder();
4899
4900     // method that returns if you should split here
4901     typedef bool(fgSplitPredicate)(GenTree* tree, GenTree* parent, fgWalkData* data);
4902
4903     void fgSetBlockOrder();
4904
4905     void fgRemoveReturnBlock(BasicBlock* block);
4906
4907     /* Helper code that has been factored out */
4908     inline void fgConvertBBToThrowBB(BasicBlock* block);
4909
4910     bool fgCastNeeded(GenTree* tree, var_types toType);
4911     GenTree* fgDoNormalizeOnStore(GenTree* tree);
4912     GenTree* fgMakeTmpArgNode(fgArgTabEntry* curArgTabEntry);
4913
4914     // The following check for loops that don't execute calls
4915     bool fgLoopCallMarked;
4916
4917     void fgLoopCallTest(BasicBlock* srcBB, BasicBlock* dstBB);
4918     void fgLoopCallMark();
4919
4920     void fgMarkLoopHead(BasicBlock* block);
4921
4922     unsigned fgGetCodeEstimate(BasicBlock* block);
4923
4924 #if DUMP_FLOWGRAPHS
4925     const char* fgProcessEscapes(const char* nameIn, escapeMapping_t* map);
4926     FILE* fgOpenFlowGraphFile(bool* wbDontClose, Phases phase, LPCWSTR type);
4927     bool fgDumpFlowGraph(Phases phase);
4928
4929 #endif // DUMP_FLOWGRAPHS
4930
4931 #ifdef DEBUG
4932     void fgDispDoms();
4933     void fgDispReach();
4934     void fgDispBBLiveness(BasicBlock* block);
4935     void fgDispBBLiveness();
4936     void fgTableDispBasicBlock(BasicBlock* block, int ibcColWidth = 0);
4937     void fgDispBasicBlocks(BasicBlock* firstBlock, BasicBlock* lastBlock, bool dumpTrees);
4938     void fgDispBasicBlocks(bool dumpTrees = false);
4939     void fgDumpStmtTree(GenTree* stmt, unsigned bbNum);
4940     void fgDumpBlock(BasicBlock* block);
4941     void fgDumpTrees(BasicBlock* firstBlock, BasicBlock* lastBlock);
4942
4943     static fgWalkPreFn fgStress64RsltMulCB;
4944     void               fgStress64RsltMul();
4945     void               fgDebugCheckUpdate();
4946     void fgDebugCheckBBlist(bool checkBBNum = false, bool checkBBRefs = true);
4947     void fgDebugCheckBlockLinks();
4948     void fgDebugCheckLinks(bool morphTrees = false);
4949     void fgDebugCheckStmtsList(BasicBlock* block, bool morphTrees);
4950     void fgDebugCheckNodeLinks(BasicBlock* block, GenTree* stmt);
4951     void fgDebugCheckNodesUniqueness();
4952
4953     void fgDebugCheckFlags(GenTree* tree);
4954     void fgDebugCheckFlagsHelper(GenTree* tree, unsigned treeFlags, unsigned chkFlags);
4955     void fgDebugCheckTryFinallyExits();
4956 #endif
4957
4958     static GenTree* fgGetFirstNode(GenTree* tree);
4959
4960     //--------------------- Walking the trees in the IR -----------------------
4961
4962     struct fgWalkData
4963     {
4964         Compiler*     compiler;
4965         fgWalkPreFn*  wtprVisitorFn;
4966         fgWalkPostFn* wtpoVisitorFn;
4967         void*         pCallbackData; // user-provided data
4968         bool          wtprLclsOnly;  // whether to only visit lclvar nodes
4969         GenTree*      parent;        // parent of current node, provided to callback
4970         GenTreeStack* parentStack;   // stack of parent nodes, if asked for
4971 #ifdef DEBUG
4972         bool printModified; // callback can use this
4973 #endif
4974     };
4975
4976     fgWalkResult fgWalkTreePre(GenTree**    pTree,
4977                                fgWalkPreFn* visitor,
4978                                void*        pCallBackData = nullptr,
4979                                bool         lclVarsOnly   = false,
4980                                bool         computeStack  = false);
4981
4982     fgWalkResult fgWalkTree(GenTree**     pTree,
4983                             fgWalkPreFn*  preVisitor,
4984                             fgWalkPostFn* postVisitor,
4985                             void*         pCallBackData = nullptr);
4986
4987     void fgWalkAllTreesPre(fgWalkPreFn* visitor, void* pCallBackData);
4988
4989     //----- Postorder
4990
4991     fgWalkResult fgWalkTreePost(GenTree**     pTree,
4992                                 fgWalkPostFn* visitor,
4993                                 void*         pCallBackData = nullptr,
4994                                 bool          computeStack  = false);
4995
4996     // An fgWalkPreFn that looks for expressions that have inline throws in
4997     // minopts mode. Basically it looks for tress with gtOverflowEx() or
4998     // GTF_IND_RNGCHK.  It returns WALK_ABORT if one is found.  It
4999     // returns WALK_SKIP_SUBTREES if GTF_EXCEPT is not set (assumes flags
5000     // properly propagated to parent trees).  It returns WALK_CONTINUE
5001     // otherwise.
5002     static fgWalkResult fgChkThrowCB(GenTree** pTree, Compiler::fgWalkData* data);
5003     static fgWalkResult fgChkLocAllocCB(GenTree** pTree, Compiler::fgWalkData* data);
5004     static fgWalkResult fgChkQmarkCB(GenTree** pTree, Compiler::fgWalkData* data);
5005
5006     /**************************************************************************
5007      *                          PROTECTED
5008      *************************************************************************/
5009
5010 protected:
5011     friend class SsaBuilder;
5012     friend struct ValueNumberState;
5013
5014     //--------------------- Detect the basic blocks ---------------------------
5015
5016     BasicBlock** fgBBs; // Table of pointers to the BBs
5017
5018     void        fgInitBBLookup();
5019     BasicBlock* fgLookupBB(unsigned addr);
5020
5021     void fgFindJumpTargets(const BYTE* codeAddr, IL_OFFSET codeSize, FixedBitVect* jumpTarget);
5022
5023     void fgMarkBackwardJump(BasicBlock* startBlock, BasicBlock* endBlock);
5024
5025     void fgLinkBasicBlocks();
5026
5027     unsigned fgMakeBasicBlocks(const BYTE* codeAddr, IL_OFFSET codeSize, FixedBitVect* jumpTarget);
5028
5029     void fgCheckBasicBlockControlFlow();
5030
5031     void fgControlFlowPermitted(BasicBlock* blkSrc,
5032                                 BasicBlock* blkDest,
5033                                 BOOL        IsLeave = false /* is the src a leave block */);
5034
5035     bool fgFlowToFirstBlockOfInnerTry(BasicBlock* blkSrc, BasicBlock* blkDest, bool sibling);
5036
5037     void fgObserveInlineConstants(OPCODE opcode, const FgStack& stack, bool isInlining);
5038
5039     void fgAdjustForAddressExposedOrWrittenThis();
5040
5041     bool                        fgProfileData_ILSizeMismatch;
5042     ICorJitInfo::ProfileBuffer* fgProfileBuffer;
5043     ULONG                       fgProfileBufferCount;
5044     ULONG                       fgNumProfileRuns;
5045
5046     unsigned fgStressBBProf()
5047     {
5048 #ifdef DEBUG
5049         unsigned result = JitConfig.JitStressBBProf();
5050         if (result == 0)
5051         {
5052             if (compStressCompile(STRESS_BB_PROFILE, 15))
5053             {
5054                 result = 1;
5055             }
5056         }
5057         return result;
5058 #else
5059         return 0;
5060 #endif
5061     }
5062
5063     bool fgHaveProfileData();
5064     bool fgGetProfileWeightForBasicBlock(IL_OFFSET offset, unsigned* weight);
5065     void fgInstrumentMethod();
5066
5067 public:
5068     // fgIsUsingProfileWeights - returns true if we have real profile data for this method
5069     //                           or if we have some fake profile data for the stress mode
5070     bool fgIsUsingProfileWeights()
5071     {
5072         return (fgHaveProfileData() || fgStressBBProf());
5073     }
5074
5075     // fgProfileRunsCount - returns total number of scenario runs for the profile data
5076     //                      or BB_UNITY_WEIGHT when we aren't using profile data.
5077     unsigned fgProfileRunsCount()
5078     {
5079         return fgIsUsingProfileWeights() ? fgNumProfileRuns : BB_UNITY_WEIGHT;
5080     }
5081
5082 //-------- Insert a statement at the start or end of a basic block --------
5083
5084 #ifdef DEBUG
5085 public:
5086     static bool fgBlockContainsStatementBounded(BasicBlock* block, GenTree* stmt, bool answerOnBoundExceeded = true);
5087 #endif
5088
5089 public:
5090     GenTreeStmt* fgInsertStmtAtEnd(BasicBlock* block, GenTree* node);
5091
5092 public: // Used by linear scan register allocation
5093     GenTreeStmt* fgInsertStmtNearEnd(BasicBlock* block, GenTree* node);
5094
5095 private:
5096     GenTree* fgInsertStmtAtBeg(BasicBlock* block, GenTree* stmt);
5097     GenTree* fgInsertStmtAfter(BasicBlock* block, GenTree* insertionPoint, GenTree* stmt);
5098
5099 public: // Used by linear scan register allocation
5100     GenTree* fgInsertStmtBefore(BasicBlock* block, GenTree* insertionPoint, GenTree* stmt);
5101
5102 private:
5103     GenTree* fgInsertStmtListAfter(BasicBlock* block, GenTree* stmtAfter, GenTree* stmtList);
5104
5105     //                  Create a new temporary variable to hold the result of *ppTree,
5106     //                  and transform the graph accordingly.
5107     GenTree* fgInsertCommaFormTemp(GenTree** ppTree, CORINFO_CLASS_HANDLE structType = nullptr);
5108     GenTree* fgMakeMultiUse(GenTree** ppTree);
5109
5110 private:
5111     //                  Recognize a bitwise rotation pattern and convert into a GT_ROL or a GT_ROR node.
5112     GenTree* fgRecognizeAndMorphBitwiseRotation(GenTree* tree);
5113     bool fgOperIsBitwiseRotationRoot(genTreeOps oper);
5114
5115     //-------- Determine the order in which the trees will be evaluated -------
5116
5117     unsigned fgTreeSeqNum;
5118     GenTree* fgTreeSeqLst;
5119     GenTree* fgTreeSeqBeg;
5120
5121     GenTree* fgSetTreeSeq(GenTree* tree, GenTree* prev = nullptr, bool isLIR = false);
5122     void fgSetTreeSeqHelper(GenTree* tree, bool isLIR);
5123     void fgSetTreeSeqFinish(GenTree* tree, bool isLIR);
5124     void fgSetStmtSeq(GenTree* tree);
5125     void fgSetBlockOrder(BasicBlock* block);
5126
5127     //------------------------- Morphing --------------------------------------
5128
5129     unsigned fgPtrArgCntMax;
5130
5131 public:
5132     //------------------------------------------------------------------------
5133     // fgGetPtrArgCntMax: Return the maximum number of pointer-sized stack arguments that calls inside this method
5134     // can push on the stack. This value is calculated during morph.
5135     //
5136     // Return Value:
5137     //    Returns fgPtrArgCntMax, that is a private field.
5138     //
5139     unsigned fgGetPtrArgCntMax() const
5140     {
5141         return fgPtrArgCntMax;
5142     }
5143
5144     //------------------------------------------------------------------------
5145     // fgSetPtrArgCntMax: Set the maximum number of pointer-sized stack arguments that calls inside this method
5146     // can push on the stack. This function is used during StackLevelSetter to fix incorrect morph calculations.
5147     //
5148     void fgSetPtrArgCntMax(unsigned argCntMax)
5149     {
5150         fgPtrArgCntMax = argCntMax;
5151     }
5152
5153     bool compCanEncodePtrArgCntMax();
5154
5155 private:
5156     hashBv* fgOutgoingArgTemps;
5157     hashBv* fgCurrentlyInUseArgTemps;
5158
5159     void fgSetRngChkTarget(GenTree* tree, bool delay = true);
5160
5161     BasicBlock* fgSetRngChkTargetInner(SpecialCodeKind kind, bool delay);
5162
5163 #if REARRANGE_ADDS
5164     void fgMoveOpsLeft(GenTree* tree);
5165 #endif
5166
5167     bool fgIsCommaThrow(GenTree* tree, bool forFolding = false);
5168
5169     bool fgIsThrow(GenTree* tree);
5170
5171     bool fgInDifferentRegions(BasicBlock* blk1, BasicBlock* blk2);
5172     bool fgIsBlockCold(BasicBlock* block);
5173
5174     GenTree* fgMorphCastIntoHelper(GenTree* tree, int helper, GenTree* oper);
5175
5176     GenTree* fgMorphIntoHelperCall(GenTree* tree, int helper, GenTreeArgList* args, bool morphArgs = true);
5177
5178     GenTree* fgMorphStackArgForVarArgs(unsigned lclNum, var_types varType, unsigned lclOffs);
5179
5180     // A "MorphAddrContext" carries information from the surrounding context.  If we are evaluating a byref address,
5181     // it is useful to know whether the address will be immediately dereferenced, or whether the address value will
5182     // be used, perhaps by passing it as an argument to a called method.  This affects how null checking is done:
5183     // for sufficiently small offsets, we can rely on OS page protection to implicitly null-check addresses that we
5184     // know will be dereferenced.  To know that reliance on implicit null checking is sound, we must further know that
5185     // all offsets between the top-level indirection and the bottom are constant, and that their sum is sufficiently
5186     // small; hence the other fields of MorphAddrContext.
5187     enum MorphAddrContextKind
5188     {
5189         MACK_Ind,
5190         MACK_Addr,
5191     };
5192     struct MorphAddrContext
5193     {
5194         MorphAddrContextKind m_kind;
5195         bool                 m_allConstantOffsets; // Valid only for "m_kind == MACK_Ind".  True iff all offsets between
5196                                                    // top-level indirection and here have been constants.
5197         size_t m_totalOffset; // Valid only for "m_kind == MACK_Ind", and if "m_allConstantOffsets" is true.
5198                               // In that case, is the sum of those constant offsets.
5199
5200         MorphAddrContext(MorphAddrContextKind kind) : m_kind(kind), m_allConstantOffsets(true), m_totalOffset(0)
5201         {
5202         }
5203     };
5204
5205     // A MACK_CopyBlock context is immutable, so we can just make one of these and share it.
5206     static MorphAddrContext s_CopyBlockMAC;
5207
5208 #ifdef FEATURE_SIMD
5209     GenTree* getSIMDStructFromField(GenTree*   tree,
5210                                     var_types* baseTypeOut,
5211                                     unsigned*  indexOut,
5212                                     unsigned*  simdSizeOut,
5213                                     bool       ignoreUsedInSIMDIntrinsic = false);
5214     GenTree* fgMorphFieldAssignToSIMDIntrinsicSet(GenTree* tree);
5215     GenTree* fgMorphFieldToSIMDIntrinsicGet(GenTree* tree);
5216     bool fgMorphCombineSIMDFieldAssignments(BasicBlock* block, GenTree* stmt);
5217     void impMarkContiguousSIMDFieldAssignments(GenTree* stmt);
5218
5219     // fgPreviousCandidateSIMDFieldAsgStmt is only used for tracking previous simd field assignment
5220     // in function: Complier::impMarkContiguousSIMDFieldAssignments.
5221     GenTree* fgPreviousCandidateSIMDFieldAsgStmt;
5222
5223 #endif // FEATURE_SIMD
5224     GenTree* fgMorphArrayIndex(GenTree* tree);
5225     GenTree* fgMorphCast(GenTree* tree);
5226     GenTree* fgUnwrapProxy(GenTree* objRef);
5227     GenTreeFieldList* fgMorphLclArgToFieldlist(GenTreeLclVarCommon* lcl);
5228     void fgInitArgInfo(GenTreeCall* call);
5229     GenTreeCall* fgMorphArgs(GenTreeCall* call);
5230     GenTreeArgList* fgMorphArgList(GenTreeArgList* args, MorphAddrContext* mac);
5231
5232     void fgMakeOutgoingStructArgCopy(GenTreeCall*         call,
5233                                      GenTree*             args,
5234                                      unsigned             argIndex,
5235                                      CORINFO_CLASS_HANDLE copyBlkClass);
5236
5237     void fgFixupStructReturn(GenTree* call);
5238     GenTree* fgMorphLocalVar(GenTree* tree, bool forceRemorph);
5239
5240 public:
5241     bool fgAddrCouldBeNull(GenTree* addr);
5242
5243 private:
5244     GenTree* fgMorphField(GenTree* tree, MorphAddrContext* mac);
5245     bool fgCanFastTailCall(GenTreeCall* call);
5246     bool fgCheckStmtAfterTailCall();
5247     void fgMorphTailCall(GenTreeCall* call, void* pfnCopyArgs);
5248     GenTree* fgGetStubAddrArg(GenTreeCall* call);
5249     void fgMorphRecursiveFastTailCallIntoLoop(BasicBlock* block, GenTreeCall* recursiveTailCall);
5250     GenTree* fgAssignRecursiveCallArgToCallerParam(GenTree*       arg,
5251                                                    fgArgTabEntry* argTabEntry,
5252                                                    BasicBlock*    block,
5253                                                    IL_OFFSETX     callILOffset,
5254                                                    GenTree*       tmpAssignmentInsertionPoint,
5255                                                    GenTree*       paramAssignmentInsertionPoint);
5256     static int fgEstimateCallStackSize(GenTreeCall* call);
5257     GenTree* fgMorphCall(GenTreeCall* call);
5258     void fgMorphCallInline(GenTreeCall* call, InlineResult* result);
5259     void fgMorphCallInlineHelper(GenTreeCall* call, InlineResult* result);
5260 #if DEBUG
5261     void fgNoteNonInlineCandidate(GenTreeStmt* stmt, GenTreeCall* call);
5262     static fgWalkPreFn fgFindNonInlineCandidate;
5263 #endif
5264     GenTree* fgOptimizeDelegateConstructor(GenTreeCall*            call,
5265                                            CORINFO_CONTEXT_HANDLE* ExactContextHnd,
5266                                            CORINFO_RESOLVED_TOKEN* ldftnToken);
5267     GenTree* fgMorphLeaf(GenTree* tree);
5268     void fgAssignSetVarDef(GenTree* tree);
5269     GenTree* fgMorphOneAsgBlockOp(GenTree* tree);
5270     GenTree* fgMorphInitBlock(GenTree* tree);
5271     GenTree* fgMorphPromoteLocalInitBlock(GenTreeLclVar* destLclNode, GenTree* initVal, unsigned blockSize);
5272     GenTree* fgMorphBlkToInd(GenTreeBlk* tree, var_types type);
5273     GenTree* fgMorphGetStructAddr(GenTree** pTree, CORINFO_CLASS_HANDLE clsHnd, bool isRValue = false);
5274     GenTree* fgMorphBlkNode(GenTree* tree, bool isDest);
5275     GenTree* fgMorphBlockOperand(GenTree* tree, var_types asgType, unsigned blockWidth, bool isDest);
5276     void fgMorphUnsafeBlk(GenTreeObj* obj);
5277     GenTree* fgMorphCopyBlock(GenTree* tree);
5278     GenTree* fgMorphForRegisterFP(GenTree* tree);
5279     GenTree* fgMorphSmpOp(GenTree* tree, MorphAddrContext* mac = nullptr);
5280     GenTree* fgMorphModToSubMulDiv(GenTreeOp* tree);
5281     GenTree* fgMorphSmpOpOptional(GenTreeOp* tree);
5282     GenTree* fgMorphRecognizeBoxNullable(GenTree* compare);
5283
5284     GenTree* fgMorphToEmulatedFP(GenTree* tree);
5285     GenTree* fgMorphConst(GenTree* tree);
5286
5287 public:
5288     GenTree* fgMorphTree(GenTree* tree, MorphAddrContext* mac = nullptr);
5289
5290 private:
5291 #if LOCAL_ASSERTION_PROP
5292     void fgKillDependentAssertionsSingle(unsigned lclNum DEBUGARG(GenTree* tree));
5293     void fgKillDependentAssertions(unsigned lclNum DEBUGARG(GenTree* tree));
5294 #endif
5295     void fgMorphTreeDone(GenTree* tree, GenTree* oldTree = nullptr DEBUGARG(int morphNum = 0));
5296
5297     GenTreeStmt* fgMorphStmt;
5298
5299     unsigned fgGetBigOffsetMorphingTemp(var_types type); // We cache one temp per type to be
5300                                                          // used when morphing big offset.
5301
5302     //----------------------- Liveness analysis -------------------------------
5303
5304     VARSET_TP fgCurUseSet; // vars used     by block (before an assignment)
5305     VARSET_TP fgCurDefSet; // vars assigned by block (before a use)
5306
5307     MemoryKindSet fgCurMemoryUse;   // True iff the current basic block uses memory.
5308     MemoryKindSet fgCurMemoryDef;   // True iff the current basic block modifies memory.
5309     MemoryKindSet fgCurMemoryHavoc; // True if  the current basic block is known to set memory to a "havoc" value.
5310
5311     bool byrefStatesMatchGcHeapStates; // True iff GcHeap and ByrefExposed memory have all the same def points.
5312
5313     void fgMarkUseDef(GenTreeLclVarCommon* tree);
5314
5315     void fgBeginScopeLife(VARSET_TP* inScope, VarScopeDsc* var);
5316     void fgEndScopeLife(VARSET_TP* inScope, VarScopeDsc* var);
5317
5318     void fgMarkInScope(BasicBlock* block, VARSET_VALARG_TP inScope);
5319     void fgUnmarkInScope(BasicBlock* block, VARSET_VALARG_TP unmarkScope);
5320
5321     void fgExtendDbgScopes();
5322     void fgExtendDbgLifetimes();
5323
5324 #ifdef DEBUG
5325     void fgDispDebugScopes();
5326 #endif // DEBUG
5327
5328     //-------------------------------------------------------------------------
5329     //
5330     //  The following keeps track of any code we've added for things like array
5331     //  range checking or explicit calls to enable GC, and so on.
5332     //
5333 public:
5334     struct AddCodeDsc
5335     {
5336         AddCodeDsc*     acdNext;
5337         BasicBlock*     acdDstBlk; // block  to  which we jump
5338         unsigned        acdData;
5339         SpecialCodeKind acdKind; // what kind of a special block is this?
5340 #if !FEATURE_FIXED_OUT_ARGS
5341         bool     acdStkLvlInit; // has acdStkLvl value been already set?
5342         unsigned acdStkLvl;
5343 #endif // !FEATURE_FIXED_OUT_ARGS
5344     };
5345
5346 private:
5347     static unsigned acdHelper(SpecialCodeKind codeKind);
5348
5349     AddCodeDsc* fgAddCodeList;
5350     bool        fgAddCodeModf;
5351     bool        fgRngChkThrowAdded;
5352     AddCodeDsc* fgExcptnTargetCache[SCK_COUNT];
5353
5354     BasicBlock* fgRngChkTarget(BasicBlock* block, SpecialCodeKind kind);
5355
5356     BasicBlock* fgAddCodeRef(BasicBlock* srcBlk, unsigned refData, SpecialCodeKind kind);
5357
5358 public:
5359     AddCodeDsc* fgFindExcptnTarget(SpecialCodeKind kind, unsigned refData);
5360
5361     bool fgUseThrowHelperBlocks();
5362
5363     AddCodeDsc* fgGetAdditionalCodeDescriptors()
5364     {
5365         return fgAddCodeList;
5366     }
5367
5368 private:
5369     bool fgIsCodeAdded();
5370
5371     bool fgIsThrowHlpBlk(BasicBlock* block);
5372
5373 #if !FEATURE_FIXED_OUT_ARGS
5374     unsigned fgThrowHlpBlkStkLevel(BasicBlock* block);
5375 #endif // !FEATURE_FIXED_OUT_ARGS
5376
5377     unsigned fgBigOffsetMorphingTemps[TYP_COUNT];
5378
5379     unsigned fgCheckInlineDepthAndRecursion(InlineInfo* inlineInfo);
5380     void fgInvokeInlineeCompiler(GenTreeCall* call, InlineResult* result);
5381     void fgInsertInlineeBlocks(InlineInfo* pInlineInfo);
5382     GenTree* fgInlinePrependStatements(InlineInfo* inlineInfo);
5383     void fgInlineAppendStatements(InlineInfo* inlineInfo, BasicBlock* block, GenTree* stmt);
5384
5385 #if FEATURE_MULTIREG_RET
5386     GenTree* fgGetStructAsStructPtr(GenTree* tree);
5387     GenTree* fgAssignStructInlineeToVar(GenTree* child, CORINFO_CLASS_HANDLE retClsHnd);
5388     void fgAttachStructInlineeToAsg(GenTree* tree, GenTree* child, CORINFO_CLASS_HANDLE retClsHnd);
5389 #endif // FEATURE_MULTIREG_RET
5390
5391     static fgWalkPreFn  fgUpdateInlineReturnExpressionPlaceHolder;
5392     static fgWalkPostFn fgLateDevirtualization;
5393
5394 #ifdef DEBUG
5395     static fgWalkPreFn fgDebugCheckInlineCandidates;
5396
5397     void               CheckNoTransformableIndirectCallsRemain();
5398     static fgWalkPreFn fgDebugCheckForTransformableIndirectCalls;
5399 #endif
5400
5401     void fgPromoteStructs();
5402     void fgMorphStructField(GenTree* tree, GenTree* parent);
5403     void fgMorphLocalField(GenTree* tree, GenTree* parent);
5404
5405     // Identify which parameters are implicit byrefs, and flag their LclVarDscs.
5406     void fgMarkImplicitByRefArgs();
5407
5408     // Change implicit byrefs' types from struct to pointer, and for any that were
5409     // promoted, create new promoted struct temps.
5410     void fgRetypeImplicitByRefArgs();
5411
5412     // Rewrite appearances of implicit byrefs (manifest the implied additional level of indirection).
5413     bool fgMorphImplicitByRefArgs(GenTree* tree);
5414     GenTree* fgMorphImplicitByRefArgs(GenTree* tree, bool isAddr);
5415
5416     // Clear up annotations for any struct promotion temps created for implicit byrefs.
5417     void fgMarkDemotedImplicitByRefArgs();
5418
5419     void fgMarkAddressExposedLocals();
5420
5421     static fgWalkPreFn  fgUpdateSideEffectsPre;
5422     static fgWalkPostFn fgUpdateSideEffectsPost;
5423
5424     // The given local variable, required to be a struct variable, is being assigned via
5425     // a "lclField", to make it masquerade as an integral type in the ABI.  Make sure that
5426     // the variable is not enregistered, and is therefore not promoted independently.
5427     void fgLclFldAssign(unsigned lclNum);
5428
5429     static fgWalkPreFn gtHasLocalsWithAddrOpCB;
5430
5431     enum TypeProducerKind
5432     {
5433         TPK_Unknown = 0, // May not be a RuntimeType
5434         TPK_Handle  = 1, // RuntimeType via handle
5435         TPK_GetType = 2, // RuntimeType via Object.get_Type()
5436         TPK_Null    = 3, // Tree value is null
5437         TPK_Other   = 4  // RuntimeType via other means
5438     };
5439
5440     TypeProducerKind gtGetTypeProducerKind(GenTree* tree);
5441     bool gtIsTypeHandleToRuntimeTypeHelper(GenTreeCall* call);
5442     bool gtIsTypeHandleToRuntimeTypeHandleHelper(GenTreeCall* call, CorInfoHelpFunc* pHelper = nullptr);
5443     bool gtIsActiveCSE_Candidate(GenTree* tree);
5444
5445 #ifdef DEBUG
5446     bool fgPrintInlinedMethods;
5447 #endif
5448
5449     bool fgIsBigOffset(size_t offset);
5450
5451     bool fgNeedReturnSpillTemp();
5452
5453     /*
5454     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
5455     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
5456     XX                                                                           XX
5457     XX                           Optimizer                                       XX
5458     XX                                                                           XX
5459     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
5460     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
5461     */
5462
5463 public:
5464     void optInit();
5465
5466     void optRemoveRangeCheck(GenTree* tree, GenTree* stmt);
5467     bool optIsRangeCheckRemovable(GenTree* tree);
5468
5469 protected:
5470     static fgWalkPreFn optValidRangeCheckIndex;
5471     static fgWalkPreFn optRemoveTreeVisitor; // Helper passed to Compiler::fgWalkAllTreesPre() to decrement the LclVar
5472                                              // usage counts
5473
5474     void optRemoveTree(GenTree* deadTree, GenTree* keepList);
5475
5476     /**************************************************************************
5477      *
5478      *************************************************************************/
5479
5480 protected:
5481     // Do hoisting for all loops.
5482     void optHoistLoopCode();
5483
5484     // To represent sets of VN's that have already been hoisted in outer loops.
5485     typedef JitHashTable<ValueNum, JitSmallPrimitiveKeyFuncs<ValueNum>, bool> VNToBoolMap;
5486     typedef VNToBoolMap VNSet;
5487
5488     struct LoopHoistContext
5489     {
5490     private:
5491         // The set of variables hoisted in the current loop (or nullptr if there are none).
5492         VNSet* m_pHoistedInCurLoop;
5493
5494     public:
5495         // Value numbers of expressions that have been hoisted in parent loops in the loop nest.
5496         VNSet m_hoistedInParentLoops;
5497         // Value numbers of expressions that have been hoisted in the current (or most recent) loop in the nest.
5498         // Previous decisions on loop-invariance of value numbers in the current loop.
5499         VNToBoolMap m_curLoopVnInvariantCache;
5500
5501         VNSet* GetHoistedInCurLoop(Compiler* comp)
5502         {
5503             if (m_pHoistedInCurLoop == nullptr)
5504             {
5505                 m_pHoistedInCurLoop = new (comp->getAllocatorLoopHoist()) VNSet(comp->getAllocatorLoopHoist());
5506             }
5507             return m_pHoistedInCurLoop;
5508         }
5509
5510         VNSet* ExtractHoistedInCurLoop()
5511         {
5512             VNSet* res          = m_pHoistedInCurLoop;
5513             m_pHoistedInCurLoop = nullptr;
5514             return res;
5515         }
5516
5517         LoopHoistContext(Compiler* comp)
5518             : m_pHoistedInCurLoop(nullptr)
5519             , m_hoistedInParentLoops(comp->getAllocatorLoopHoist())
5520             , m_curLoopVnInvariantCache(comp->getAllocatorLoopHoist())
5521         {
5522         }
5523     };
5524
5525     // Do hoisting for loop "lnum" (an index into the optLoopTable), and all loops nested within it.
5526     // Tracks the expressions that have been hoisted by containing loops by temporary recording their
5527     // value numbers in "m_hoistedInParentLoops".  This set is not modified by the call.
5528     void optHoistLoopNest(unsigned lnum, LoopHoistContext* hoistCtxt);
5529
5530     // Do hoisting for a particular loop ("lnum" is an index into the optLoopTable.)
5531     // Assumes that expressions have been hoisted in containing loops if their value numbers are in
5532     // "m_hoistedInParentLoops".
5533     //
5534     void optHoistThisLoop(unsigned lnum, LoopHoistContext* hoistCtxt);
5535
5536     // Hoist all expressions in "blk" that are invariant in loop "lnum" (an index into the optLoopTable)
5537     // outside of that loop.  Exempt expressions whose value number is in "m_hoistedInParentLoops"; add VN's of hoisted
5538     // expressions to "hoistInLoop".
5539     void optHoistLoopExprsForBlock(BasicBlock* blk, unsigned lnum, LoopHoistContext* hoistCtxt);
5540
5541     // Return true if the tree looks profitable to hoist out of loop 'lnum'.
5542     bool optIsProfitableToHoistableTree(GenTree* tree, unsigned lnum);
5543
5544     // Hoist all proper sub-expressions of "tree" (which occurs in "stmt", which occurs in "blk")
5545     // that are invariant in loop "lnum" (an index into the optLoopTable)
5546     // outside of that loop.  Exempt expressions whose value number is in "hoistedInParents"; add VN's of hoisted
5547     // expressions to "hoistInLoop".
5548     // Returns "true" iff "tree" is loop-invariant (wrt "lnum").
5549     // Assumes that the value of "*firstBlockAndBeforeSideEffect" indicates that we're in the first block, and before
5550     // any possible globally visible side effects.  Assume is called in evaluation order, and updates this.
5551     bool optHoistLoopExprsForTree(GenTree*          tree,
5552                                   unsigned          lnum,
5553                                   LoopHoistContext* hoistCtxt,
5554                                   bool*             firstBlockAndBeforeSideEffect,
5555                                   bool*             pHoistable,
5556                                   bool*             pCctorDependent);
5557
5558     // Performs the hoisting 'tree' into the PreHeader for loop 'lnum'
5559     void optHoistCandidate(GenTree* tree, unsigned lnum, LoopHoistContext* hoistCtxt);
5560
5561     // Returns true iff the ValueNum "vn" represents a value that is loop-invariant in "lnum".
5562     //   Constants and init values are always loop invariant.
5563     //   VNPhi's connect VN's to the SSA definition, so we can know if the SSA def occurs in the loop.
5564     bool optVNIsLoopInvariant(ValueNum vn, unsigned lnum, VNToBoolMap* recordedVNs);
5565
5566     // Returns "true" iff "tree" is valid at the head of loop "lnum", in the context of the hoist substitution
5567     // "subst".  If "tree" is a local SSA var, it is valid if its SSA definition occurs outside of the loop, or
5568     // if it is in the domain of "subst" (meaning that it's definition has been previously hoisted, with a "standin"
5569     // local.)  If tree is a constant, it is valid.  Otherwise, if it is an operator, it is valid iff its children are.
5570     bool optTreeIsValidAtLoopHead(GenTree* tree, unsigned lnum);
5571
5572     // If "blk" is the entry block of a natural loop, returns true and sets "*pLnum" to the index of the loop
5573     // in the loop table.
5574     bool optBlockIsLoopEntry(BasicBlock* blk, unsigned* pLnum);
5575
5576     // Records the set of "side effects" of all loops: fields (object instance and static)
5577     // written to, and SZ-array element type equivalence classes updated.
5578     void optComputeLoopSideEffects();
5579
5580 private:
5581     // Requires "lnum" to be the index of an outermost loop in the loop table.  Traverses the body of that loop,
5582     // including all nested loops, and records the set of "side effects" of the loop: fields (object instance and
5583     // static) written to, and SZ-array element type equivalence classes updated.
5584     void optComputeLoopNestSideEffects(unsigned lnum);
5585
5586     // Add the side effects of "blk" (which is required to be within a loop) to all loops of which it is a part.
5587     void optComputeLoopSideEffectsOfBlock(BasicBlock* blk);
5588
5589     // Hoist the expression "expr" out of loop "lnum".
5590     void optPerformHoistExpr(GenTree* expr, unsigned lnum);
5591
5592 public:
5593     void optOptimizeBools();
5594
5595 private:
5596     GenTree* optIsBoolCond(GenTree* condBranch, GenTree** compPtr, bool* boolPtr);
5597 #ifdef DEBUG
5598     void optOptimizeBoolsGcStress(BasicBlock* condBlock);
5599 #endif
5600 public:
5601     void optOptimizeLayout(); // Optimize the BasicBlock layout of the method
5602
5603     void optOptimizeLoops(); // for "while-do" loops duplicates simple loop conditions and transforms
5604                              // the loop into a "do-while" loop
5605                              // Also finds all natural loops and records them in the loop table
5606
5607     // Optionally clone loops in the loop table.
5608     void optCloneLoops();
5609
5610     // Clone loop "loopInd" in the loop table.
5611     void optCloneLoop(unsigned loopInd, LoopCloneContext* context);
5612
5613     // Ensure that loop "loopInd" has a unique head block.  (If the existing entry has
5614     // non-loop predecessors other than the head entry, create a new, empty block that goes (only) to the entry,
5615     // and redirects the preds of the entry to this new block.)  Sets the weight of the newly created block to
5616     // "ambientWeight".
5617     void optEnsureUniqueHead(unsigned loopInd, unsigned ambientWeight);
5618
5619     void optUnrollLoops(); // Unrolls loops (needs to have cost info)
5620
5621 protected:
5622     // This enumeration describes what is killed by a call.
5623
5624     enum callInterf
5625     {
5626         CALLINT_NONE,       // no interference                               (most helpers)
5627         CALLINT_REF_INDIRS, // kills GC ref indirections                     (SETFIELD OBJ)
5628         CALLINT_SCL_INDIRS, // kills non GC ref indirections                 (SETFIELD non-OBJ)
5629         CALLINT_ALL_INDIRS, // kills both GC ref and non GC ref indirections (SETFIELD STRUCT)
5630         CALLINT_ALL,        // kills everything                              (normal method call)
5631     };
5632
5633 public:
5634     // A "LoopDsc" describes a ("natural") loop.  We (currently) require the body of a loop to be a contiguous (in
5635     // bbNext order) sequence of basic blocks.  (At times, we may require the blocks in a loop to be "properly numbered"
5636     // in bbNext order; we use comparisons on the bbNum to decide order.)
5637     // The blocks that define the body are
5638     //   first <= top <= entry <= bottom   .
5639     // The "head" of the loop is a block outside the loop that has "entry" as a successor. We only support loops with a
5640     // single 'head' block. The meanings of these blocks are given in the definitions below. Also see the picture at
5641     // Compiler::optFindNaturalLoops().
5642     struct LoopDsc
5643     {
5644         BasicBlock* lpHead;  // HEAD of the loop (not part of the looping of the loop) -- has ENTRY as a successor.
5645         BasicBlock* lpFirst; // FIRST block (in bbNext order) reachable within this loop.  (May be part of a nested
5646                              // loop, but not the outer loop.)
5647         BasicBlock* lpTop;   // loop TOP (the back edge from lpBottom reaches here) (in most cases FIRST and TOP are the
5648                              // same)
5649         BasicBlock* lpEntry; // the ENTRY in the loop (in most cases TOP or BOTTOM)
5650         BasicBlock* lpBottom; // loop BOTTOM (from here we have a back edge to the TOP)
5651         BasicBlock* lpExit;   // if a single exit loop this is the EXIT (in most cases BOTTOM)
5652
5653         callInterf   lpAsgCall;     // "callInterf" for calls in the loop
5654         ALLVARSET_TP lpAsgVars;     // set of vars assigned within the loop (all vars, not just tracked)
5655         varRefKinds  lpAsgInds : 8; // set of inds modified within the loop
5656
5657         unsigned short lpFlags; // Mask of the LPFLG_* constants
5658
5659         unsigned char lpExitCnt; // number of exits from the loop
5660
5661         unsigned char lpParent;  // The index of the most-nested loop that completely contains this one,
5662                                  // or else BasicBlock::NOT_IN_LOOP if no such loop exists.
5663         unsigned char lpChild;   // The index of a nested loop, or else BasicBlock::NOT_IN_LOOP if no child exists.
5664                                  // (Actually, an "immediately" nested loop --
5665                                  // no other child of this loop is a parent of lpChild.)
5666         unsigned char lpSibling; // The index of another loop that is an immediate child of lpParent,
5667                                  // or else BasicBlock::NOT_IN_LOOP.  One can enumerate all the children of a loop
5668                                  // by following "lpChild" then "lpSibling" links.
5669
5670 #define LPFLG_DO_WHILE 0x0001 // it's a do-while loop (i.e ENTRY is at the TOP)
5671 #define LPFLG_ONE_EXIT 0x0002 // the loop has only one exit
5672
5673 #define LPFLG_ITER 0x0004      // for (i = icon or lclVar; test_condition(); i++)
5674 #define LPFLG_HOISTABLE 0x0008 // the loop is in a form that is suitable for hoisting expressions
5675 #define LPFLG_CONST 0x0010     // for (i=icon;i<icon;i++){ ... } - constant loop
5676
5677 #define LPFLG_VAR_INIT 0x0020   // iterator is initialized with a local var (var # found in lpVarInit)
5678 #define LPFLG_CONST_INIT 0x0040 // iterator is initialized with a constant (found in lpConstInit)
5679
5680 #define LPFLG_VAR_LIMIT 0x0100    // iterator is compared with a local var (var # found in lpVarLimit)
5681 #define LPFLG_CONST_LIMIT 0x0200  // iterator is compared with a constant (found in lpConstLimit)
5682 #define LPFLG_ARRLEN_LIMIT 0x0400 // iterator is compared with a.len or a[i].len (found in lpArrLenLimit)
5683 #define LPFLG_SIMD_LIMIT 0x0080   // iterator is compared with Vector<T>.Count (found in lpConstLimit)
5684
5685 #define LPFLG_HAS_PREHEAD 0x0800 // lpHead is known to be a preHead for this loop
5686 #define LPFLG_REMOVED 0x1000     // has been removed from the loop table (unrolled or optimized away)
5687 #define LPFLG_DONT_UNROLL 0x2000 // do not unroll this loop
5688
5689 #define LPFLG_ASGVARS_YES 0x4000 // "lpAsgVars" has been  computed
5690 #define LPFLG_ASGVARS_INC 0x8000 // "lpAsgVars" is incomplete -- vars beyond those representable in an AllVarSet
5691                                  // type are assigned to.
5692
5693         bool lpLoopHasMemoryHavoc[MemoryKindCount]; // The loop contains an operation that we assume has arbitrary
5694                                                     // memory side effects.  If this is set, the fields below
5695                                                     // may not be accurate (since they become irrelevant.)
5696         bool lpContainsCall;                        // True if executing the loop body *may* execute a call
5697
5698         VARSET_TP lpVarInOut;  // The set of variables that are IN or OUT during the execution of this loop
5699         VARSET_TP lpVarUseDef; // The set of variables that are USE or DEF during the execution of this loop
5700
5701         int lpHoistedExprCount; // The register count for the non-FP expressions from inside this loop that have been
5702                                 // hoisted
5703         int lpLoopVarCount;     // The register count for the non-FP LclVars that are read/written inside this loop
5704         int lpVarInOutCount;    // The register count for the non-FP LclVars that are alive inside or accross this loop
5705
5706         int lpHoistedFPExprCount; // The register count for the FP expressions from inside this loop that have been
5707                                   // hoisted
5708         int lpLoopVarFPCount;     // The register count for the FP LclVars that are read/written inside this loop
5709         int lpVarInOutFPCount;    // The register count for the FP LclVars that are alive inside or accross this loop
5710
5711         typedef JitHashTable<CORINFO_FIELD_HANDLE, JitPtrKeyFuncs<struct CORINFO_FIELD_STRUCT_>, bool> FieldHandleSet;
5712         FieldHandleSet* lpFieldsModified; // This has entries (mappings to "true") for all static field and object
5713                                           // instance fields modified
5714                                           // in the loop.
5715
5716         typedef JitHashTable<CORINFO_CLASS_HANDLE, JitPtrKeyFuncs<struct CORINFO_CLASS_STRUCT_>, bool> ClassHandleSet;
5717         ClassHandleSet* lpArrayElemTypesModified; // Bits set indicate the set of sz array element types such that
5718                                                   // arrays of that type are modified
5719                                                   // in the loop.
5720
5721         // Adds the variable liveness information for 'blk' to 'this' LoopDsc
5722         void AddVariableLiveness(Compiler* comp, BasicBlock* blk);
5723
5724         inline void AddModifiedField(Compiler* comp, CORINFO_FIELD_HANDLE fldHnd);
5725         // This doesn't *always* take a class handle -- it can also take primitive types, encoded as class handles
5726         // (shifted left, with a low-order bit set to distinguish.)
5727         // Use the {Encode/Decode}ElemType methods to construct/destruct these.
5728         inline void AddModifiedElemType(Compiler* comp, CORINFO_CLASS_HANDLE structHnd);
5729
5730         /* The following values are set only for iterator loops, i.e. has the flag LPFLG_ITER set */
5731
5732         GenTree*   lpIterTree;    // The "i = i <op> const" tree
5733         unsigned   lpIterVar();   // iterator variable #
5734         int        lpIterConst(); // the constant with which the iterator is incremented
5735         genTreeOps lpIterOper();  // the type of the operation on the iterator (ASG_ADD, ASG_SUB, etc.)
5736         void       VERIFY_lpIterTree();
5737
5738         var_types lpIterOperType(); // For overflow instructions
5739
5740         union {
5741             int lpConstInit; // initial constant value of iterator                           : Valid if LPFLG_CONST_INIT
5742             unsigned lpVarInit; // initial local var number to which we initialize the iterator : Valid if
5743                                 // LPFLG_VAR_INIT
5744         };
5745
5746         /* The following is for LPFLG_ITER loops only (i.e. the loop condition is "i RELOP const or var" */
5747
5748         GenTree*   lpTestTree;   // pointer to the node containing the loop test
5749         genTreeOps lpTestOper(); // the type of the comparison between the iterator and the limit (GT_LE, GT_GE, etc.)
5750         void       VERIFY_lpTestTree();
5751
5752         bool     lpIsReversed(); // true if the iterator node is the second operand in the loop condition
5753         GenTree* lpIterator();   // the iterator node in the loop test
5754         GenTree* lpLimit();      // the limit node in the loop test
5755
5756         int lpConstLimit();    // limit   constant value of iterator - loop condition is "i RELOP const" : Valid if
5757                                // LPFLG_CONST_LIMIT
5758         unsigned lpVarLimit(); // the lclVar # in the loop condition ( "i RELOP lclVar" )                : Valid if
5759                                // LPFLG_VAR_LIMIT
5760         bool lpArrLenLimit(Compiler* comp, ArrIndex* index); // The array length in the loop condition ( "i RELOP
5761                                                              // arr.len" or "i RELOP arr[i][j].len" )  : Valid if
5762                                                              // LPFLG_ARRLEN_LIMIT
5763
5764         // Returns "true" iff "*this" contains the blk.
5765         bool lpContains(BasicBlock* blk)
5766         {
5767             return lpFirst->bbNum <= blk->bbNum && blk->bbNum <= lpBottom->bbNum;
5768         }
5769         // Returns "true" iff "*this" (properly) contains the range [first, bottom] (allowing firsts
5770         // to be equal, but requiring bottoms to be different.)
5771         bool lpContains(BasicBlock* first, BasicBlock* bottom)
5772         {
5773             return lpFirst->bbNum <= first->bbNum && bottom->bbNum < lpBottom->bbNum;
5774         }
5775
5776         // Returns "true" iff "*this" (properly) contains "lp2" (allowing firsts to be equal, but requiring
5777         // bottoms to be different.)
5778         bool lpContains(const LoopDsc& lp2)
5779         {
5780             return lpContains(lp2.lpFirst, lp2.lpBottom);
5781         }
5782
5783         // Returns "true" iff "*this" is (properly) contained by the range [first, bottom]
5784         // (allowing firsts to be equal, but requiring bottoms to be different.)
5785         bool lpContainedBy(BasicBlock* first, BasicBlock* bottom)
5786         {
5787             return first->bbNum <= lpFirst->bbNum && lpBottom->bbNum < bottom->bbNum;
5788         }
5789
5790         // Returns "true" iff "*this" is (properly) contained by "lp2"
5791         // (allowing firsts to be equal, but requiring bottoms to be different.)
5792         bool lpContainedBy(const LoopDsc& lp2)
5793         {
5794             return lpContains(lp2.lpFirst, lp2.lpBottom);
5795         }
5796
5797         // Returns "true" iff "*this" is disjoint from the range [top, bottom].
5798         bool lpDisjoint(BasicBlock* first, BasicBlock* bottom)
5799         {
5800             return bottom->bbNum < lpFirst->bbNum || lpBottom->bbNum < first->bbNum;
5801         }
5802         // Returns "true" iff "*this" is disjoint from "lp2".
5803         bool lpDisjoint(const LoopDsc& lp2)
5804         {
5805             return lpDisjoint(lp2.lpFirst, lp2.lpBottom);
5806         }
5807         // Returns "true" iff the loop is well-formed (see code for defn).
5808         bool lpWellFormed()
5809         {
5810             return lpFirst->bbNum <= lpTop->bbNum && lpTop->bbNum <= lpEntry->bbNum &&
5811                    lpEntry->bbNum <= lpBottom->bbNum &&
5812                    (lpHead->bbNum < lpTop->bbNum || lpHead->bbNum > lpBottom->bbNum);
5813         }
5814     };
5815
5816 protected:
5817     bool fgMightHaveLoop(); // returns true if there are any backedges
5818     bool fgHasLoops;        // True if this method has any loops, set in fgComputeReachability
5819
5820 public:
5821     LoopDsc*      optLoopTable; // loop descriptor table
5822     unsigned char optLoopCount; // number of tracked loops
5823
5824     bool optRecordLoop(BasicBlock*   head,
5825                        BasicBlock*   first,
5826                        BasicBlock*   top,
5827                        BasicBlock*   entry,
5828                        BasicBlock*   bottom,
5829                        BasicBlock*   exit,
5830                        unsigned char exitCnt);
5831
5832 protected:
5833     unsigned optCallCount;         // number of calls made in the method
5834     unsigned optIndirectCallCount; // number of virtual, interface and indirect calls made in the method
5835     unsigned optNativeCallCount;   // number of Pinvoke/Native calls made in the method
5836     unsigned optLoopsCloned;       // number of loops cloned in the current method.
5837
5838 #ifdef DEBUG
5839     unsigned optFindLoopNumberFromBeginBlock(BasicBlock* begBlk);
5840     void optPrintLoopInfo(unsigned      loopNum,
5841                           BasicBlock*   lpHead,
5842                           BasicBlock*   lpFirst,
5843                           BasicBlock*   lpTop,
5844                           BasicBlock*   lpEntry,
5845                           BasicBlock*   lpBottom,
5846                           unsigned char lpExitCnt,
5847                           BasicBlock*   lpExit,
5848                           unsigned      parentLoop = BasicBlock::NOT_IN_LOOP);
5849     void optPrintLoopInfo(unsigned lnum);
5850     void optPrintLoopRecording(unsigned lnum);
5851
5852     void optCheckPreds();
5853 #endif
5854
5855     void optSetBlockWeights();
5856
5857     void optMarkLoopBlocks(BasicBlock* begBlk, BasicBlock* endBlk, bool excludeEndBlk);
5858
5859     void optUnmarkLoopBlocks(BasicBlock* begBlk, BasicBlock* endBlk);
5860
5861     void optUpdateLoopsBeforeRemoveBlock(BasicBlock* block, bool skipUnmarkLoop = false);
5862
5863     bool optIsLoopTestEvalIntoTemp(GenTree* test, GenTree** newTest);
5864     unsigned optIsLoopIncrTree(GenTree* incr);
5865     bool optCheckIterInLoopTest(unsigned loopInd, GenTree* test, BasicBlock* from, BasicBlock* to, unsigned iterVar);
5866     bool optComputeIterInfo(GenTree* incr, BasicBlock* from, BasicBlock* to, unsigned* pIterVar);
5867     bool optPopulateInitInfo(unsigned loopInd, GenTree* init, unsigned iterVar);
5868     bool optExtractInitTestIncr(
5869         BasicBlock* head, BasicBlock* bottom, BasicBlock* exit, GenTree** ppInit, GenTree** ppTest, GenTree** ppIncr);
5870
5871     void optFindNaturalLoops();
5872
5873     // Ensures that all the loops in the loop nest rooted at "loopInd" (an index into the loop table) are 'canonical' --
5874     // each loop has a unique "top."  Returns "true" iff the flowgraph has been modified.
5875     bool optCanonicalizeLoopNest(unsigned char loopInd);
5876
5877     // Ensures that the loop "loopInd" (an index into the loop table) is 'canonical' -- it has a unique "top,"
5878     // unshared with any other loop.  Returns "true" iff the flowgraph has been modified
5879     bool optCanonicalizeLoop(unsigned char loopInd);
5880
5881     // Requires "l1" to be a valid loop table index, and not "BasicBlock::NOT_IN_LOOP".  Requires "l2" to be
5882     // a valid loop table index, or else "BasicBlock::NOT_IN_LOOP".  Returns true
5883     // iff "l2" is not NOT_IN_LOOP, and "l1" contains "l2".
5884     bool optLoopContains(unsigned l1, unsigned l2);
5885
5886     // Requires "loopInd" to be a valid index into the loop table.
5887     // Updates the loop table by changing loop "loopInd", whose head is required
5888     // to be "from", to be "to".  Also performs this transformation for any
5889     // loop nested in "loopInd" that shares the same head as "loopInd".
5890     void optUpdateLoopHead(unsigned loopInd, BasicBlock* from, BasicBlock* to);
5891
5892     // Updates the successors of "blk": if "blk2" is a successor of "blk", and there is a mapping for "blk2->blk3" in
5893     // "redirectMap", change "blk" so that "blk3" is this successor. Note that the predecessor lists are not updated.
5894     void optRedirectBlock(BasicBlock* blk, BlockToBlockMap* redirectMap);
5895
5896     // Marks the containsCall information to "lnum" and any parent loops.
5897     void AddContainsCallAllContainingLoops(unsigned lnum);
5898     // Adds the variable liveness information from 'blk' to "lnum" and any parent loops.
5899     void AddVariableLivenessAllContainingLoops(unsigned lnum, BasicBlock* blk);
5900     // Adds "fldHnd" to the set of modified fields of "lnum" and any parent loops.
5901     void AddModifiedFieldAllContainingLoops(unsigned lnum, CORINFO_FIELD_HANDLE fldHnd);
5902     // Adds "elemType" to the set of modified array element types of "lnum" and any parent loops.
5903     void AddModifiedElemTypeAllContainingLoops(unsigned lnum, CORINFO_CLASS_HANDLE elemType);
5904
5905     // Requires that "from" and "to" have the same "bbJumpKind" (perhaps because "to" is a clone
5906     // of "from".)  Copies the jump destination from "from" to "to".
5907     void optCopyBlkDest(BasicBlock* from, BasicBlock* to);
5908
5909     // The depth of the loop described by "lnum" (an index into the loop table.) (0 == top level)
5910     unsigned optLoopDepth(unsigned lnum)
5911     {
5912         unsigned par = optLoopTable[lnum].lpParent;
5913         if (par == BasicBlock::NOT_IN_LOOP)
5914         {
5915             return 0;
5916         }
5917         else
5918         {
5919             return 1 + optLoopDepth(par);
5920         }
5921     }
5922
5923     void fgOptWhileLoop(BasicBlock* block);
5924
5925     bool optComputeLoopRep(int        constInit,
5926                            int        constLimit,
5927                            int        iterInc,
5928                            genTreeOps iterOper,
5929                            var_types  iterType,
5930                            genTreeOps testOper,
5931                            bool       unsignedTest,
5932                            bool       dupCond,
5933                            unsigned*  iterCount);
5934
5935 private:
5936     static fgWalkPreFn optIsVarAssgCB;
5937
5938 protected:
5939     bool optIsVarAssigned(BasicBlock* beg, BasicBlock* end, GenTree* skip, unsigned var);
5940
5941     bool optIsVarAssgLoop(unsigned lnum, unsigned var);
5942
5943     int optIsSetAssgLoop(unsigned lnum, ALLVARSET_VALARG_TP vars, varRefKinds inds = VR_NONE);
5944
5945     bool optNarrowTree(GenTree* tree, var_types srct, var_types dstt, ValueNumPair vnpNarrow, bool doit);
5946
5947     /**************************************************************************
5948      *                       Optimization conditions
5949      *************************************************************************/
5950
5951     bool optFastCodeOrBlendedLoop(BasicBlock::weight_t bbWeight);
5952     bool optPentium4(void);
5953     bool optAvoidIncDec(BasicBlock::weight_t bbWeight);
5954     bool optAvoidIntMult(void);
5955
5956 #if FEATURE_ANYCSE
5957
5958 protected:
5959     //  The following is the upper limit on how many expressions we'll keep track
5960     //  of for the CSE analysis.
5961     //
5962     static const unsigned MAX_CSE_CNT = EXPSET_SZ;
5963
5964     static const int MIN_CSE_COST = 2;
5965
5966     // Keeps tracked cse indices
5967     BitVecTraits* cseTraits;
5968     EXPSET_TP     cseFull;
5969
5970     /* Generic list of nodes - used by the CSE logic */
5971
5972     struct treeLst
5973     {
5974         treeLst* tlNext;
5975         GenTree* tlTree;
5976     };
5977
5978     struct treeStmtLst
5979     {
5980         treeStmtLst* tslNext;
5981         GenTree*     tslTree;  // tree node
5982         GenTree*     tslStmt;  // statement containing the tree
5983         BasicBlock*  tslBlock; // block containing the statement
5984     };
5985
5986     // The following logic keeps track of expressions via a simple hash table.
5987
5988     struct CSEdsc
5989     {
5990         CSEdsc* csdNextInBucket; // used by the hash table
5991
5992         unsigned csdHashKey; // the orginal hashkey
5993
5994         unsigned csdIndex;          // 1..optCSECandidateCount
5995         char     csdLiveAcrossCall; // 0 or 1
5996
5997         unsigned short csdDefCount; // definition   count
5998         unsigned short csdUseCount; // use          count  (excluding the implicit uses at defs)
5999
6000         unsigned csdDefWtCnt; // weighted def count
6001         unsigned csdUseWtCnt; // weighted use count  (excluding the implicit uses at defs)
6002
6003         GenTree*    csdTree;  // treenode containing the 1st occurance
6004         GenTree*    csdStmt;  // stmt containing the 1st occurance
6005         BasicBlock* csdBlock; // block containing the 1st occurance
6006
6007         treeStmtLst* csdTreeList; // list of matching tree nodes: head
6008         treeStmtLst* csdTreeLast; // list of matching tree nodes: tail
6009
6010         ValueNum defExcSetPromise; // The exception set that is now required for all defs of this CSE.
6011                                    // This will be set to NoVN if we decide to abandon this CSE
6012
6013         ValueNum defExcSetCurrent; // The set of exceptions we currently can use for CSE uses.
6014
6015         ValueNum defConservNormVN; // if all def occurrences share the same conservative normal value
6016                                    // number, this will reflect it; otherwise, NoVN.
6017     };
6018
6019     static const size_t s_optCSEhashSize;
6020     CSEdsc**            optCSEhash;
6021     CSEdsc**            optCSEtab;
6022
6023     typedef JitHashTable<GenTree*, JitPtrKeyFuncs<GenTree>, GenTree*> NodeToNodeMap;
6024
6025     NodeToNodeMap* optCseCheckedBoundMap; // Maps bound nodes to ancestor compares that should be
6026                                           // re-numbered with the bound to improve range check elimination
6027
6028     // Given a compare, look for a cse candidate checked bound feeding it and add a map entry if found.
6029     void optCseUpdateCheckedBoundMap(GenTree* compare);
6030
6031     void optCSEstop();
6032
6033     CSEdsc* optCSEfindDsc(unsigned index);
6034     bool optUnmarkCSE(GenTree* tree);
6035
6036     // user defined callback data for the tree walk function optCSE_MaskHelper()
6037     struct optCSE_MaskData
6038     {
6039         EXPSET_TP CSE_defMask;
6040         EXPSET_TP CSE_useMask;
6041     };
6042
6043     // Treewalk helper for optCSE_DefMask and optCSE_UseMask
6044     static fgWalkPreFn optCSE_MaskHelper;
6045
6046     // This function walks all the node for an given tree
6047     // and return the mask of CSE definitions and uses for the tree
6048     //
6049     void optCSE_GetMaskData(GenTree* tree, optCSE_MaskData* pMaskData);
6050
6051     // Given a binary tree node return true if it is safe to swap the order of evaluation for op1 and op2.
6052     bool optCSE_canSwap(GenTree* firstNode, GenTree* secondNode);
6053     bool optCSE_canSwap(GenTree* tree);
6054
6055     static int __cdecl optCSEcostCmpEx(const void* op1, const void* op2);
6056     static int __cdecl optCSEcostCmpSz(const void* op1, const void* op2);
6057
6058     void optCleanupCSEs();
6059
6060 #ifdef DEBUG
6061     void optEnsureClearCSEInfo();
6062 #endif // DEBUG
6063
6064 #endif // FEATURE_ANYCSE
6065
6066 #if FEATURE_VALNUM_CSE
6067     /**************************************************************************
6068      *                   Value Number based CSEs
6069      *************************************************************************/
6070
6071 public:
6072     void optOptimizeValnumCSEs();
6073
6074 protected:
6075     void     optValnumCSE_Init();
6076     unsigned optValnumCSE_Index(GenTree* tree, GenTree* stmt);
6077     unsigned optValnumCSE_Locate();
6078     void     optValnumCSE_InitDataFlow();
6079     void     optValnumCSE_DataFlow();
6080     void     optValnumCSE_Availablity();
6081     void     optValnumCSE_Heuristic();
6082
6083 #endif // FEATURE_VALNUM_CSE
6084
6085 #if FEATURE_ANYCSE
6086     bool     optDoCSE;             // True when we have found a duplicate CSE tree
6087     bool     optValnumCSE_phase;   // True when we are executing the optValnumCSE_phase
6088     unsigned optCSECandidateTotal; // Grand total of CSE candidates for both Lexical and ValNum
6089     unsigned optCSECandidateCount; // Count of CSE's candidates, reset for Lexical and ValNum CSE's
6090     unsigned optCSEstart;          // The first local variable number that is a CSE
6091     unsigned optCSEcount;          // The total count of CSE's introduced.
6092     unsigned optCSEweight;         // The weight of the current block when we are
6093                                    // scanning for CSE expressions
6094
6095     bool optIsCSEcandidate(GenTree* tree);
6096
6097     // lclNumIsTrueCSE returns true if the LclVar was introduced by the CSE phase of the compiler
6098     //
6099     bool lclNumIsTrueCSE(unsigned lclNum) const
6100     {
6101         return ((optCSEcount > 0) && (lclNum >= optCSEstart) && (lclNum < optCSEstart + optCSEcount));
6102     }
6103
6104     //  lclNumIsCSE returns true if the LclVar should be treated like a CSE with regards to constant prop.
6105     //
6106     bool lclNumIsCSE(unsigned lclNum) const
6107     {
6108         return lvaTable[lclNum].lvIsCSE;
6109     }
6110
6111 #ifdef DEBUG
6112     bool optConfigDisableCSE();
6113     bool optConfigDisableCSE2();
6114 #endif
6115     void optOptimizeCSEs();
6116
6117 #endif // FEATURE_ANYCSE
6118
6119     struct isVarAssgDsc
6120     {
6121         GenTree* ivaSkip;
6122 #ifdef DEBUG
6123         void* ivaSelf;
6124 #endif
6125         unsigned     ivaVar;            // Variable we are interested in, or -1
6126         ALLVARSET_TP ivaMaskVal;        // Set of variables assigned to.  This is a set of all vars, not tracked vars.
6127         bool         ivaMaskIncomplete; // Variables not representable in ivaMaskVal were assigned to.
6128         varRefKinds  ivaMaskInd;        // What kind of indirect assignments are there?
6129         callInterf   ivaMaskCall;       // What kind of calls are there?
6130     };
6131
6132     static callInterf optCallInterf(GenTreeCall* call);
6133
6134 public:
6135     // VN based copy propagation.
6136     typedef ArrayStack<GenTree*> GenTreePtrStack;
6137     typedef JitHashTable<unsigned, JitSmallPrimitiveKeyFuncs<unsigned>, GenTreePtrStack*> LclNumToGenTreePtrStack;
6138
6139     // Kill set to track variables with intervening definitions.
6140     VARSET_TP optCopyPropKillSet;
6141
6142     // Copy propagation functions.
6143     void optCopyProp(BasicBlock* block, GenTree* stmt, GenTree* tree, LclNumToGenTreePtrStack* curSsaName);
6144     void optBlockCopyPropPopStacks(BasicBlock* block, LclNumToGenTreePtrStack* curSsaName);
6145     void optBlockCopyProp(BasicBlock* block, LclNumToGenTreePtrStack* curSsaName);
6146     bool optIsSsaLocal(GenTree* tree);
6147     int optCopyProp_LclVarScore(LclVarDsc* lclVarDsc, LclVarDsc* copyVarDsc, bool preferOp2);
6148     void optVnCopyProp();
6149     INDEBUG(void optDumpCopyPropStack(LclNumToGenTreePtrStack* curSsaName));
6150
6151     /**************************************************************************
6152     *               Early value propagation
6153     *************************************************************************/
6154     struct SSAName
6155     {
6156         unsigned m_lvNum;
6157         unsigned m_ssaNum;
6158
6159         SSAName(unsigned lvNum, unsigned ssaNum) : m_lvNum(lvNum), m_ssaNum(ssaNum)
6160         {
6161         }
6162
6163         static unsigned GetHashCode(SSAName ssaNm)
6164         {
6165             return (ssaNm.m_lvNum << 16) | (ssaNm.m_ssaNum);
6166         }
6167
6168         static bool Equals(SSAName ssaNm1, SSAName ssaNm2)
6169         {
6170             return (ssaNm1.m_lvNum == ssaNm2.m_lvNum) && (ssaNm1.m_ssaNum == ssaNm2.m_ssaNum);
6171         }
6172     };
6173
6174 #define OMF_HAS_NEWARRAY 0x00000001      // Method contains 'new' of an array
6175 #define OMF_HAS_NEWOBJ 0x00000002        // Method contains 'new' of an object type.
6176 #define OMF_HAS_ARRAYREF 0x00000004      // Method contains array element loads or stores.
6177 #define OMF_HAS_VTABLEREF 0x00000008     // Method contains method table reference.
6178 #define OMF_HAS_NULLCHECK 0x00000010     // Method contains null check.
6179 #define OMF_HAS_FATPOINTER 0x00000020    // Method contains call, that needs fat pointer transformation.
6180 #define OMF_HAS_OBJSTACKALLOC 0x00000040 // Method contains an object allocated on the stack.
6181 #define OMF_HAS_GUARDEDDEVIRT 0x00000080 // Method contains guarded devirtualization candidate
6182
6183     bool doesMethodHaveFatPointer()
6184     {
6185         return (optMethodFlags & OMF_HAS_FATPOINTER) != 0;
6186     }
6187
6188     void setMethodHasFatPointer()
6189     {
6190         optMethodFlags |= OMF_HAS_FATPOINTER;
6191     }
6192
6193     void clearMethodHasFatPointer()
6194     {
6195         optMethodFlags &= ~OMF_HAS_FATPOINTER;
6196     }
6197
6198     void addFatPointerCandidate(GenTreeCall* call);
6199
6200     bool doesMethodHaveGuardedDevirtualization()
6201     {
6202         return (optMethodFlags & OMF_HAS_GUARDEDDEVIRT) != 0;
6203     }
6204
6205     void setMethodHasGuardedDevirtualization()
6206     {
6207         optMethodFlags |= OMF_HAS_GUARDEDDEVIRT;
6208     }
6209
6210     void clearMethodHasGuardedDevirtualization()
6211     {
6212         optMethodFlags &= ~OMF_HAS_GUARDEDDEVIRT;
6213     }
6214
6215     void addGuardedDevirtualizationCandidate(GenTreeCall*          call,
6216                                              CORINFO_METHOD_HANDLE methodHandle,
6217                                              CORINFO_CLASS_HANDLE  classHandle,
6218                                              unsigned              methodAttr,
6219                                              unsigned              classAttr);
6220
6221     unsigned optMethodFlags;
6222
6223     // Recursion bound controls how far we can go backwards tracking for a SSA value.
6224     // No throughput diff was found with backward walk bound between 3-8.
6225     static const int optEarlyPropRecurBound = 5;
6226
6227     enum class optPropKind
6228     {
6229         OPK_INVALID,
6230         OPK_ARRAYLEN,
6231         OPK_OBJ_GETTYPE,
6232         OPK_NULLCHECK
6233     };
6234
6235     bool gtIsVtableRef(GenTree* tree);
6236     GenTree* getArrayLengthFromAllocation(GenTree* tree);
6237     GenTree* getObjectHandleNodeFromAllocation(GenTree* tree);
6238     GenTree* optPropGetValueRec(unsigned lclNum, unsigned ssaNum, optPropKind valueKind, int walkDepth);
6239     GenTree* optPropGetValue(unsigned lclNum, unsigned ssaNum, optPropKind valueKind);
6240     GenTree* optEarlyPropRewriteTree(GenTree* tree);
6241     bool optDoEarlyPropForBlock(BasicBlock* block);
6242     bool optDoEarlyPropForFunc();
6243     void optEarlyProp();
6244     void optFoldNullCheck(GenTree* tree);
6245     bool optCanMoveNullCheckPastTree(GenTree* tree, bool isInsideTry);
6246
6247 #if ASSERTION_PROP
6248     /**************************************************************************
6249      *               Value/Assertion propagation
6250      *************************************************************************/
6251 public:
6252     // Data structures for assertion prop
6253     BitVecTraits* apTraits;
6254     ASSERT_TP     apFull;
6255
6256     enum optAssertionKind
6257     {
6258         OAK_INVALID,
6259         OAK_EQUAL,
6260         OAK_NOT_EQUAL,
6261         OAK_SUBRANGE,
6262         OAK_NO_THROW,
6263         OAK_COUNT
6264     };
6265
6266     enum optOp1Kind
6267     {
6268         O1K_INVALID,
6269         O1K_LCLVAR,
6270         O1K_ARR_BND,
6271         O1K_BOUND_OPER_BND,
6272         O1K_BOUND_LOOP_BND,
6273         O1K_CONSTANT_LOOP_BND,
6274         O1K_EXACT_TYPE,
6275         O1K_SUBTYPE,
6276         O1K_VALUE_NUMBER,
6277         O1K_COUNT
6278     };
6279
6280     enum optOp2Kind
6281     {
6282         O2K_INVALID,
6283         O2K_LCLVAR_COPY,
6284         O2K_IND_CNS_INT,
6285         O2K_CONST_INT,
6286         O2K_CONST_LONG,
6287         O2K_CONST_DOUBLE,
6288         O2K_ARR_LEN,
6289         O2K_SUBRANGE,
6290         O2K_COUNT
6291     };
6292     struct AssertionDsc
6293     {
6294         optAssertionKind assertionKind;
6295         struct SsaVar
6296         {
6297             unsigned lclNum; // assigned to or property of this local var number
6298             unsigned ssaNum;
6299         };
6300         struct ArrBnd
6301         {
6302             ValueNum vnIdx;
6303             ValueNum vnLen;
6304         };
6305         struct AssertionDscOp1
6306         {
6307             optOp1Kind kind; // a normal LclVar, or Exact-type or Subtype
6308             ValueNum   vn;
6309             union {
6310                 SsaVar lcl;
6311                 ArrBnd bnd;
6312             };
6313         } op1;
6314         struct AssertionDscOp2
6315         {
6316             optOp2Kind kind; // a const or copy assignment
6317             ValueNum   vn;
6318             struct IntVal
6319             {
6320                 ssize_t  iconVal;   // integer
6321                 unsigned iconFlags; // gtFlags
6322             };
6323             struct Range // integer subrange
6324             {
6325                 ssize_t loBound;
6326                 ssize_t hiBound;
6327             };
6328             union {
6329                 SsaVar  lcl;
6330                 IntVal  u1;
6331                 __int64 lconVal;
6332                 double  dconVal;
6333                 Range   u2;
6334             };
6335         } op2;
6336
6337         bool IsCheckedBoundArithBound()
6338         {
6339             return ((assertionKind == OAK_EQUAL || assertionKind == OAK_NOT_EQUAL) && op1.kind == O1K_BOUND_OPER_BND);
6340         }
6341         bool IsCheckedBoundBound()
6342         {
6343             return ((assertionKind == OAK_EQUAL || assertionKind == OAK_NOT_EQUAL) && op1.kind == O1K_BOUND_LOOP_BND);
6344         }
6345         bool IsConstantBound()
6346         {
6347             return ((assertionKind == OAK_EQUAL || assertionKind == OAK_NOT_EQUAL) &&
6348                     op1.kind == O1K_CONSTANT_LOOP_BND);
6349         }
6350         bool IsBoundsCheckNoThrow()
6351         {
6352             return ((assertionKind == OAK_NO_THROW) && (op1.kind == O1K_ARR_BND));
6353         }
6354
6355         bool IsCopyAssertion()
6356         {
6357             return ((assertionKind == OAK_EQUAL) && (op1.kind == O1K_LCLVAR) && (op2.kind == O2K_LCLVAR_COPY));
6358         }
6359
6360         static bool SameKind(AssertionDsc* a1, AssertionDsc* a2)
6361         {
6362             return a1->assertionKind == a2->assertionKind && a1->op1.kind == a2->op1.kind &&
6363                    a1->op2.kind == a2->op2.kind;
6364         }
6365
6366         static bool ComplementaryKind(optAssertionKind kind, optAssertionKind kind2)
6367         {
6368             if (kind == OAK_EQUAL)
6369             {
6370                 return kind2 == OAK_NOT_EQUAL;
6371             }
6372             else if (kind == OAK_NOT_EQUAL)
6373             {
6374                 return kind2 == OAK_EQUAL;
6375             }
6376             return false;
6377         }
6378
6379         static ssize_t GetLowerBoundForIntegralType(var_types type)
6380         {
6381             switch (type)
6382             {
6383                 case TYP_BYTE:
6384                     return SCHAR_MIN;
6385                 case TYP_SHORT:
6386                     return SHRT_MIN;
6387                 case TYP_INT:
6388                     return INT_MIN;
6389                 case TYP_BOOL:
6390                 case TYP_UBYTE:
6391                 case TYP_USHORT:
6392                 case TYP_UINT:
6393                     return 0;
6394                 default:
6395                     unreached();
6396             }
6397         }
6398         static ssize_t GetUpperBoundForIntegralType(var_types type)
6399         {
6400             switch (type)
6401             {
6402                 case TYP_BOOL:
6403                     return 1;
6404                 case TYP_BYTE:
6405                     return SCHAR_MAX;
6406                 case TYP_SHORT:
6407                     return SHRT_MAX;
6408                 case TYP_INT:
6409                     return INT_MAX;
6410                 case TYP_UBYTE:
6411                     return UCHAR_MAX;
6412                 case TYP_USHORT:
6413                     return USHRT_MAX;
6414                 case TYP_UINT:
6415                     return UINT_MAX;
6416                 default:
6417                     unreached();
6418             }
6419         }
6420
6421         bool HasSameOp1(AssertionDsc* that, bool vnBased)
6422         {
6423             if (op1.kind != that->op1.kind)
6424             {
6425                 return false;
6426             }
6427             else if (op1.kind == O1K_ARR_BND)
6428             {
6429                 assert(vnBased);
6430                 return (op1.bnd.vnIdx == that->op1.bnd.vnIdx) && (op1.bnd.vnLen == that->op1.bnd.vnLen);
6431             }
6432             else
6433             {
6434                 return ((vnBased && (op1.vn == that->op1.vn)) ||
6435                         (!vnBased && (op1.lcl.lclNum == that->op1.lcl.lclNum)));
6436             }
6437         }
6438
6439         bool HasSameOp2(AssertionDsc* that, bool vnBased)
6440         {
6441             if (op2.kind != that->op2.kind)
6442             {
6443                 return false;
6444             }
6445             switch (op2.kind)
6446             {
6447                 case O2K_IND_CNS_INT:
6448                 case O2K_CONST_INT:
6449                     return ((op2.u1.iconVal == that->op2.u1.iconVal) && (op2.u1.iconFlags == that->op2.u1.iconFlags));
6450
6451                 case O2K_CONST_LONG:
6452                     return (op2.lconVal == that->op2.lconVal);
6453
6454                 case O2K_CONST_DOUBLE:
6455                     // exact match because of positive and negative zero.
6456                     return (memcmp(&op2.dconVal, &that->op2.dconVal, sizeof(double)) == 0);
6457
6458                 case O2K_LCLVAR_COPY:
6459                 case O2K_ARR_LEN:
6460                     return (op2.lcl.lclNum == that->op2.lcl.lclNum) &&
6461                            (!vnBased || op2.lcl.ssaNum == that->op2.lcl.ssaNum);
6462
6463                 case O2K_SUBRANGE:
6464                     return ((op2.u2.loBound == that->op2.u2.loBound) && (op2.u2.hiBound == that->op2.u2.hiBound));
6465
6466                 case O2K_INVALID:
6467                     // we will return false
6468                     break;
6469
6470                 default:
6471                     assert(!"Unexpected value for op2.kind in AssertionDsc.");
6472                     break;
6473             }
6474             return false;
6475         }
6476
6477         bool Complementary(AssertionDsc* that, bool vnBased)
6478         {
6479             return ComplementaryKind(assertionKind, that->assertionKind) && HasSameOp1(that, vnBased) &&
6480                    HasSameOp2(that, vnBased);
6481         }
6482
6483         bool Equals(AssertionDsc* that, bool vnBased)
6484         {
6485             if (assertionKind != that->assertionKind)
6486             {
6487                 return false;
6488             }
6489             else if (assertionKind == OAK_NO_THROW)
6490             {
6491                 assert(op2.kind == O2K_INVALID);
6492                 return HasSameOp1(that, vnBased);
6493             }
6494             else
6495             {
6496                 return HasSameOp1(that, vnBased) && HasSameOp2(that, vnBased);
6497             }
6498         }
6499     };
6500
6501 protected:
6502     static fgWalkPreFn optAddCopiesCallback;
6503     static fgWalkPreFn optVNAssertionPropCurStmtVisitor;
6504     unsigned           optAddCopyLclNum;
6505     GenTree*           optAddCopyAsgnNode;
6506
6507     bool optLocalAssertionProp;  // indicates that we are performing local assertion prop
6508     bool optAssertionPropagated; // set to true if we modified the trees
6509     bool optAssertionPropagatedCurrentStmt;
6510 #ifdef DEBUG
6511     GenTree* optAssertionPropCurrentTree;
6512 #endif
6513     AssertionIndex*            optComplementaryAssertionMap;
6514     JitExpandArray<ASSERT_TP>* optAssertionDep; // table that holds dependent assertions (assertions
6515                                                 // using the value of a local var) for each local var
6516     AssertionDsc*  optAssertionTabPrivate;      // table that holds info about value assignments
6517     AssertionIndex optAssertionCount;           // total number of assertions in the assertion table
6518     AssertionIndex optMaxAssertionCount;
6519
6520 public:
6521     void optVnNonNullPropCurStmt(BasicBlock* block, GenTree* stmt, GenTree* tree);
6522     fgWalkResult optVNConstantPropCurStmt(BasicBlock* block, GenTree* stmt, GenTree* tree);
6523     GenTree* optVNConstantPropOnJTrue(BasicBlock* block, GenTree* stmt, GenTree* test);
6524     GenTree* optVNConstantPropOnTree(BasicBlock* block, GenTree* stmt, GenTree* tree);
6525     GenTree* optPrepareTreeForReplacement(GenTree* extractTree, GenTree* replaceTree);
6526
6527     AssertionIndex GetAssertionCount()
6528     {
6529         return optAssertionCount;
6530     }
6531     ASSERT_TP* bbJtrueAssertionOut;
6532     typedef JitHashTable<ValueNum, JitSmallPrimitiveKeyFuncs<ValueNum>, ASSERT_TP> ValueNumToAssertsMap;
6533     ValueNumToAssertsMap* optValueNumToAsserts;
6534
6535     // Assertion prop helpers.
6536     ASSERT_TP& GetAssertionDep(unsigned lclNum);
6537     AssertionDsc* optGetAssertion(AssertionIndex assertIndex);
6538     void optAssertionInit(bool isLocalProp);
6539     void optAssertionTraitsInit(AssertionIndex assertionCount);
6540 #if LOCAL_ASSERTION_PROP
6541     void optAssertionReset(AssertionIndex limit);
6542     void optAssertionRemove(AssertionIndex index);
6543 #endif
6544
6545     // Assertion prop data flow functions.
6546     void     optAssertionPropMain();
6547     GenTree* optVNAssertionPropCurStmt(BasicBlock* block, GenTree* stmt);
6548     bool optIsTreeKnownIntValue(bool vnBased, GenTree* tree, ssize_t* pConstant, unsigned* pIconFlags);
6549     ASSERT_TP* optInitAssertionDataflowFlags();
6550     ASSERT_TP* optComputeAssertionGen();
6551
6552     // Assertion Gen functions.
6553     void optAssertionGen(GenTree* tree);
6554     AssertionIndex optAssertionGenPhiDefn(GenTree* tree);
6555     AssertionInfo optCreateJTrueBoundsAssertion(GenTree* tree);
6556     AssertionInfo optAssertionGenJtrue(GenTree* tree);
6557     AssertionIndex optCreateJtrueAssertions(GenTree* op1, GenTree* op2, Compiler::optAssertionKind assertionKind);
6558     AssertionIndex optFindComplementary(AssertionIndex assertionIndex);
6559     void optMapComplementary(AssertionIndex assertionIndex, AssertionIndex index);
6560
6561     // Assertion creation functions.
6562     AssertionIndex optCreateAssertion(GenTree* op1, GenTree* op2, optAssertionKind assertionKind);
6563     AssertionIndex optCreateAssertion(GenTree*         op1,
6564                                       GenTree*         op2,
6565                                       optAssertionKind assertionKind,
6566                                       AssertionDsc*    assertion);
6567     void optCreateComplementaryAssertion(AssertionIndex assertionIndex, GenTree* op1, GenTree* op2);
6568
6569     bool optAssertionVnInvolvesNan(AssertionDsc* assertion);
6570     AssertionIndex optAddAssertion(AssertionDsc* assertion);
6571     void optAddVnAssertionMapping(ValueNum vn, AssertionIndex index);
6572 #ifdef DEBUG
6573     void optPrintVnAssertionMapping();
6574 #endif
6575     ASSERT_TP optGetVnMappedAssertions(ValueNum vn);
6576
6577     // Used for respective assertion propagations.
6578     AssertionIndex optAssertionIsSubrange(GenTree* tree, var_types toType, ASSERT_VALARG_TP assertions);
6579     AssertionIndex optAssertionIsSubtype(GenTree* tree, GenTree* methodTableArg, ASSERT_VALARG_TP assertions);
6580     AssertionIndex optAssertionIsNonNullInternal(GenTree* op, ASSERT_VALARG_TP assertions);
6581     bool optAssertionIsNonNull(GenTree*         op,
6582                                ASSERT_VALARG_TP assertions DEBUGARG(bool* pVnBased) DEBUGARG(AssertionIndex* pIndex));
6583
6584     // Used for Relop propagation.
6585     AssertionIndex optGlobalAssertionIsEqualOrNotEqual(ASSERT_VALARG_TP assertions, GenTree* op1, GenTree* op2);
6586     AssertionIndex optGlobalAssertionIsEqualOrNotEqualZero(ASSERT_VALARG_TP assertions, GenTree* op1);
6587     AssertionIndex optLocalAssertionIsEqualOrNotEqual(
6588         optOp1Kind op1Kind, unsigned lclNum, optOp2Kind op2Kind, ssize_t cnsVal, ASSERT_VALARG_TP assertions);
6589
6590     // Assertion prop for lcl var functions.
6591     bool optAssertionProp_LclVarTypeCheck(GenTree* tree, LclVarDsc* lclVarDsc, LclVarDsc* copyVarDsc);
6592     GenTree* optCopyAssertionProp(AssertionDsc* curAssertion,
6593                                   GenTree*      tree,
6594                                   GenTree* stmt DEBUGARG(AssertionIndex index));
6595     GenTree* optConstantAssertionProp(AssertionDsc* curAssertion,
6596                                       GenTree*      tree,
6597                                       GenTree* stmt DEBUGARG(AssertionIndex index));
6598
6599     // Assertion propagation functions.
6600     GenTree* optAssertionProp(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt);
6601     GenTree* optAssertionProp_LclVar(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt);
6602     GenTree* optAssertionProp_Ind(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt);
6603     GenTree* optAssertionProp_Cast(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt);
6604     GenTree* optAssertionProp_Call(ASSERT_VALARG_TP assertions, GenTreeCall* call, GenTree* stmt);
6605     GenTree* optAssertionProp_RelOp(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt);
6606     GenTree* optAssertionProp_Comma(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt);
6607     GenTree* optAssertionProp_BndsChk(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt);
6608     GenTree* optAssertionPropGlobal_RelOp(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt);
6609     GenTree* optAssertionPropLocal_RelOp(ASSERT_VALARG_TP assertions, GenTree* tree, GenTree* stmt);
6610     GenTree* optAssertionProp_Update(GenTree* newTree, GenTree* tree, GenTree* stmt);
6611     GenTree* optNonNullAssertionProp_Call(ASSERT_VALARG_TP assertions, GenTreeCall* call, GenTree* stmt);
6612
6613     // Implied assertion functions.
6614     void optImpliedAssertions(AssertionIndex assertionIndex, ASSERT_TP& activeAssertions);
6615     void optImpliedByTypeOfAssertions(ASSERT_TP& activeAssertions);
6616     void optImpliedByCopyAssertion(AssertionDsc* copyAssertion, AssertionDsc* depAssertion, ASSERT_TP& result);
6617     void optImpliedByConstAssertion(AssertionDsc* curAssertion, ASSERT_TP& result);
6618
6619 #ifdef DEBUG
6620     void optPrintAssertion(AssertionDsc* newAssertion, AssertionIndex assertionIndex = 0);
6621     void optDebugCheckAssertion(AssertionDsc* assertion);
6622     void optDebugCheckAssertions(AssertionIndex AssertionIndex);
6623 #endif
6624     void optAddCopies();
6625 #endif // ASSERTION_PROP
6626
6627     /**************************************************************************
6628      *                          Range checks
6629      *************************************************************************/
6630
6631 public:
6632     struct LoopCloneVisitorInfo
6633     {
6634         LoopCloneContext* context;
6635         unsigned          loopNum;
6636         GenTree*          stmt;
6637         LoopCloneVisitorInfo(LoopCloneContext* context, unsigned loopNum, GenTree* stmt)
6638             : context(context), loopNum(loopNum), stmt(nullptr)
6639         {
6640         }
6641     };
6642
6643     bool optIsStackLocalInvariant(unsigned loopNum, unsigned lclNum);
6644     bool optExtractArrIndex(GenTree* tree, ArrIndex* result, unsigned lhsNum);
6645     bool optReconstructArrIndex(GenTree* tree, ArrIndex* result, unsigned lhsNum);
6646     bool optIdentifyLoopOptInfo(unsigned loopNum, LoopCloneContext* context);
6647     static fgWalkPreFn optCanOptimizeByLoopCloningVisitor;
6648     fgWalkResult optCanOptimizeByLoopCloning(GenTree* tree, LoopCloneVisitorInfo* info);
6649     void optObtainLoopCloningOpts(LoopCloneContext* context);
6650     bool optIsLoopClonable(unsigned loopInd);
6651
6652     bool optCanCloneLoops();
6653
6654 #ifdef DEBUG
6655     void optDebugLogLoopCloning(BasicBlock* block, GenTree* insertBefore);
6656 #endif
6657     void optPerformStaticOptimizations(unsigned loopNum, LoopCloneContext* context DEBUGARG(bool fastPath));
6658     bool optComputeDerefConditions(unsigned loopNum, LoopCloneContext* context);
6659     bool optDeriveLoopCloningConditions(unsigned loopNum, LoopCloneContext* context);
6660     BasicBlock* optInsertLoopChoiceConditions(LoopCloneContext* context,
6661                                               unsigned          loopNum,
6662                                               BasicBlock*       head,
6663                                               BasicBlock*       slow);
6664
6665 protected:
6666     ssize_t optGetArrayRefScaleAndIndex(GenTree* mul, GenTree** pIndex DEBUGARG(bool bRngChk));
6667
6668     bool optReachWithoutCall(BasicBlock* srcBB, BasicBlock* dstBB);
6669
6670 protected:
6671     bool optLoopsMarked;
6672
6673     /*
6674     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6675     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6676     XX                                                                           XX
6677     XX                           RegAlloc                                        XX
6678     XX                                                                           XX
6679     XX  Does the register allocation and puts the remaining lclVars on the stack XX
6680     XX                                                                           XX
6681     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6682     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6683     */
6684
6685 public:
6686     regNumber raUpdateRegStateForArg(RegState* regState, LclVarDsc* argDsc);
6687
6688     void raMarkStkVars();
6689
6690 protected:
6691     // Some things are used by both LSRA and regpredict allocators.
6692
6693     FrameType rpFrameType;
6694     bool      rpMustCreateEBPCalled; // Set to true after we have called rpMustCreateEBPFrame once
6695
6696     bool rpMustCreateEBPFrame(INDEBUG(const char** wbReason));
6697
6698 private:
6699     Lowering*            m_pLowering;   // Lowering; needed to Lower IR that's added or modified after Lowering.
6700     LinearScanInterface* m_pLinearScan; // Linear Scan allocator
6701
6702     /* raIsVarargsStackArg is called by raMaskStkVars and by
6703        lvaSortByRefCount.  It identifies the special case
6704        where a varargs function has a parameter passed on the
6705        stack, other than the special varargs handle.  Such parameters
6706        require special treatment, because they cannot be tracked
6707        by the GC (their offsets in the stack are not known
6708        at compile time).
6709     */
6710
6711     bool raIsVarargsStackArg(unsigned lclNum)
6712     {
6713 #ifdef _TARGET_X86_
6714
6715         LclVarDsc* varDsc = &lvaTable[lclNum];
6716
6717         assert(varDsc->lvIsParam);
6718
6719         return (info.compIsVarArgs && !varDsc->lvIsRegArg && (lclNum != lvaVarargsHandleArg));
6720
6721 #else // _TARGET_X86_
6722
6723         return false;
6724
6725 #endif // _TARGET_X86_
6726     }
6727
6728     /*
6729     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6730     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6731     XX                                                                           XX
6732     XX                           EEInterface                                     XX
6733     XX                                                                           XX
6734     XX   Get to the class and method info from the Execution Engine given        XX
6735     XX   tokens for the class and method                                         XX
6736     XX                                                                           XX
6737     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6738     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6739     */
6740
6741 public:
6742     // Get handles
6743
6744     void eeGetCallInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
6745                        CORINFO_RESOLVED_TOKEN* pConstrainedToken,
6746                        CORINFO_CALLINFO_FLAGS  flags,
6747                        CORINFO_CALL_INFO*      pResult);
6748     inline CORINFO_CALLINFO_FLAGS addVerifyFlag(CORINFO_CALLINFO_FLAGS flags);
6749
6750     void eeGetFieldInfo(CORINFO_RESOLVED_TOKEN* pResolvedToken,
6751                         CORINFO_ACCESS_FLAGS    flags,
6752                         CORINFO_FIELD_INFO*     pResult);
6753
6754     // Get the flags
6755
6756     BOOL eeIsValueClass(CORINFO_CLASS_HANDLE clsHnd);
6757
6758 #if defined(DEBUG) || defined(FEATURE_JIT_METHOD_PERF) || defined(FEATURE_SIMD) || defined(TRACK_LSRA_STATS)
6759
6760     bool IsSuperPMIException(unsigned code)
6761     {
6762         // Copied from NDP\clr\src\ToolBox\SuperPMI\SuperPMI-Shared\ErrorHandling.h
6763
6764         const unsigned EXCEPTIONCODE_DebugBreakorAV = 0xe0421000;
6765         const unsigned EXCEPTIONCODE_MC             = 0xe0422000;
6766         const unsigned EXCEPTIONCODE_LWM            = 0xe0423000;
6767         const unsigned EXCEPTIONCODE_SASM           = 0xe0424000;
6768         const unsigned EXCEPTIONCODE_SSYM           = 0xe0425000;
6769         const unsigned EXCEPTIONCODE_CALLUTILS      = 0xe0426000;
6770         const unsigned EXCEPTIONCODE_TYPEUTILS      = 0xe0427000;
6771         const unsigned EXCEPTIONCODE_ASSERT         = 0xe0440000;
6772
6773         switch (code)
6774         {
6775             case EXCEPTIONCODE_DebugBreakorAV:
6776             case EXCEPTIONCODE_MC:
6777             case EXCEPTIONCODE_LWM:
6778             case EXCEPTIONCODE_SASM:
6779             case EXCEPTIONCODE_SSYM:
6780             case EXCEPTIONCODE_CALLUTILS:
6781             case EXCEPTIONCODE_TYPEUTILS:
6782             case EXCEPTIONCODE_ASSERT:
6783                 return true;
6784             default:
6785                 return false;
6786         }
6787     }
6788
6789     const char* eeGetMethodName(CORINFO_METHOD_HANDLE hnd, const char** className);
6790     const char* eeGetMethodFullName(CORINFO_METHOD_HANDLE hnd);
6791
6792     bool eeIsNativeMethod(CORINFO_METHOD_HANDLE method);
6793     CORINFO_METHOD_HANDLE eeGetMethodHandleForNative(CORINFO_METHOD_HANDLE method);
6794 #endif
6795
6796     var_types eeGetArgType(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO* sig);
6797     var_types eeGetArgType(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO* sig, bool* isPinned);
6798     unsigned eeGetArgSize(CORINFO_ARG_LIST_HANDLE list, CORINFO_SIG_INFO* sig);
6799
6800     // VOM info, method sigs
6801
6802     void eeGetSig(unsigned               sigTok,
6803                   CORINFO_MODULE_HANDLE  scope,
6804                   CORINFO_CONTEXT_HANDLE context,
6805                   CORINFO_SIG_INFO*      retSig);
6806
6807     void eeGetCallSiteSig(unsigned               sigTok,
6808                           CORINFO_MODULE_HANDLE  scope,
6809                           CORINFO_CONTEXT_HANDLE context,
6810                           CORINFO_SIG_INFO*      retSig);
6811
6812     void eeGetMethodSig(CORINFO_METHOD_HANDLE methHnd, CORINFO_SIG_INFO* retSig, CORINFO_CLASS_HANDLE owner = nullptr);
6813
6814     // Method entry-points, instrs
6815
6816     CORINFO_METHOD_HANDLE eeMarkNativeTarget(CORINFO_METHOD_HANDLE method);
6817
6818     CORINFO_EE_INFO eeInfo;
6819     bool            eeInfoInitialized;
6820
6821     CORINFO_EE_INFO* eeGetEEInfo();
6822
6823     // Gets the offset of a SDArray's first element
6824     unsigned eeGetArrayDataOffset(var_types type);
6825     // Gets the offset of a MDArray's first element
6826     unsigned eeGetMDArrayDataOffset(var_types type, unsigned rank);
6827
6828     GenTree* eeGetPInvokeCookie(CORINFO_SIG_INFO* szMetaSig);
6829
6830     // Returns the page size for the target machine as reported by the EE.
6831     target_size_t eeGetPageSize()
6832     {
6833         return (target_size_t)eeGetEEInfo()->osPageSize;
6834     }
6835
6836     // Returns the frame size at which we will generate a loop to probe the stack.
6837     target_size_t getVeryLargeFrameSize()
6838     {
6839 #ifdef _TARGET_ARM_
6840         // The looping probe code is 40 bytes, whereas the straight-line probing for
6841         // the (0x2000..0x3000) case is 44, so use looping for anything 0x2000 bytes
6842         // or greater, to generate smaller code.
6843         return 2 * eeGetPageSize();
6844 #else
6845         return 3 * eeGetPageSize();
6846 #endif
6847     }
6848
6849     //------------------------------------------------------------------------
6850     // VirtualStubParam: virtual stub dispatch extra parameter (slot address).
6851     //
6852     // It represents Abi and target specific registers for the parameter.
6853     //
6854     class VirtualStubParamInfo
6855     {
6856     public:
6857         VirtualStubParamInfo(bool isCoreRTABI)
6858         {
6859 #if defined(_TARGET_X86_)
6860             reg     = REG_EAX;
6861             regMask = RBM_EAX;
6862 #elif defined(_TARGET_AMD64_)
6863             if (isCoreRTABI)
6864             {
6865                 reg     = REG_R10;
6866                 regMask = RBM_R10;
6867             }
6868             else
6869             {
6870                 reg     = REG_R11;
6871                 regMask = RBM_R11;
6872             }
6873 #elif defined(_TARGET_ARM_)
6874             if (isCoreRTABI)
6875             {
6876                 reg     = REG_R12;
6877                 regMask = RBM_R12;
6878             }
6879             else
6880             {
6881                 reg     = REG_R4;
6882                 regMask = RBM_R4;
6883             }
6884 #elif defined(_TARGET_ARM64_)
6885             reg     = REG_R11;
6886             regMask = RBM_R11;
6887 #else
6888 #error Unsupported or unset target architecture
6889 #endif
6890         }
6891
6892         regNumber GetReg() const
6893         {
6894             return reg;
6895         }
6896
6897         _regMask_enum GetRegMask() const
6898         {
6899             return regMask;
6900         }
6901
6902     private:
6903         regNumber     reg;
6904         _regMask_enum regMask;
6905     };
6906
6907     VirtualStubParamInfo* virtualStubParamInfo;
6908
6909     bool IsTargetAbi(CORINFO_RUNTIME_ABI abi)
6910     {
6911         return eeGetEEInfo()->targetAbi == abi;
6912     }
6913
6914     bool generateCFIUnwindCodes()
6915     {
6916 #if defined(_TARGET_UNIX_)
6917         return IsTargetAbi(CORINFO_CORERT_ABI);
6918 #else
6919         return false;
6920 #endif
6921     }
6922
6923     // Debugging support - Line number info
6924
6925     void eeGetStmtOffsets();
6926
6927     unsigned eeBoundariesCount;
6928
6929     struct boundariesDsc
6930     {
6931         UNATIVE_OFFSET nativeIP;
6932         IL_OFFSET      ilOffset;
6933         unsigned       sourceReason;
6934     } * eeBoundaries; // Boundaries to report to EE
6935     void eeSetLIcount(unsigned count);
6936     void eeSetLIinfo(unsigned which, UNATIVE_OFFSET offs, unsigned srcIP, bool stkEmpty, bool callInstruction);
6937     void eeSetLIdone();
6938
6939 #ifdef DEBUG
6940     static void eeDispILOffs(IL_OFFSET offs);
6941     static void eeDispLineInfo(const boundariesDsc* line);
6942     void eeDispLineInfos();
6943 #endif // DEBUG
6944
6945     // Debugging support - Local var info
6946
6947     void eeGetVars();
6948
6949     unsigned eeVarsCount;
6950
6951     struct VarResultInfo
6952     {
6953         UNATIVE_OFFSET             startOffset;
6954         UNATIVE_OFFSET             endOffset;
6955         DWORD                      varNumber;
6956         CodeGenInterface::siVarLoc loc;
6957     } * eeVars;
6958     void eeSetLVcount(unsigned count);
6959     void eeSetLVinfo(unsigned                          which,
6960                      UNATIVE_OFFSET                    startOffs,
6961                      UNATIVE_OFFSET                    length,
6962                      unsigned                          varNum,
6963                      unsigned                          LVnum,
6964                      VarName                           namex,
6965                      bool                              avail,
6966                      const CodeGenInterface::siVarLoc* loc);
6967     void eeSetLVdone();
6968
6969 #ifdef DEBUG
6970     void eeDispVar(ICorDebugInfo::NativeVarInfo* var);
6971     void eeDispVars(CORINFO_METHOD_HANDLE ftn, ULONG32 cVars, ICorDebugInfo::NativeVarInfo* vars);
6972 #endif // DEBUG
6973
6974     // ICorJitInfo wrappers
6975
6976     void eeReserveUnwindInfo(BOOL isFunclet, BOOL isColdCode, ULONG unwindSize);
6977
6978     void eeAllocUnwindInfo(BYTE*          pHotCode,
6979                            BYTE*          pColdCode,
6980                            ULONG          startOffset,
6981                            ULONG          endOffset,
6982                            ULONG          unwindSize,
6983                            BYTE*          pUnwindBlock,
6984                            CorJitFuncKind funcKind);
6985
6986     void eeSetEHcount(unsigned cEH);
6987
6988     void eeSetEHinfo(unsigned EHnumber, const CORINFO_EH_CLAUSE* clause);
6989
6990     WORD eeGetRelocTypeHint(void* target);
6991
6992     // ICorStaticInfo wrapper functions
6993
6994     bool eeTryResolveToken(CORINFO_RESOLVED_TOKEN* resolvedToken);
6995
6996 #if defined(UNIX_AMD64_ABI)
6997 #ifdef DEBUG
6998     static void dumpSystemVClassificationType(SystemVClassificationType ct);
6999 #endif // DEBUG
7000
7001     void eeGetSystemVAmd64PassStructInRegisterDescriptor(
7002         /*IN*/ CORINFO_CLASS_HANDLE                                  structHnd,
7003         /*OUT*/ SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR* structPassInRegDescPtr);
7004 #endif // UNIX_AMD64_ABI
7005
7006     template <typename ParamType>
7007     bool eeRunWithErrorTrap(void (*function)(ParamType*), ParamType* param)
7008     {
7009         return eeRunWithErrorTrapImp(reinterpret_cast<void (*)(void*)>(function), reinterpret_cast<void*>(param));
7010     }
7011
7012     bool eeRunWithErrorTrapImp(void (*function)(void*), void* param);
7013
7014     // Utility functions
7015
7016     const char* eeGetFieldName(CORINFO_FIELD_HANDLE fieldHnd, const char** classNamePtr = nullptr);
7017
7018 #if defined(DEBUG)
7019     const wchar_t* eeGetCPString(size_t stringHandle);
7020 #endif
7021
7022     const char* eeGetClassName(CORINFO_CLASS_HANDLE clsHnd);
7023
7024     static CORINFO_METHOD_HANDLE eeFindHelper(unsigned helper);
7025     static CorInfoHelpFunc eeGetHelperNum(CORINFO_METHOD_HANDLE method);
7026
7027     static fgWalkPreFn CountSharedStaticHelper;
7028     static bool IsSharedStaticHelper(GenTree* tree);
7029     static bool IsTreeAlwaysHoistable(GenTree* tree);
7030     static bool IsGcSafePoint(GenTree* tree);
7031
7032     static CORINFO_FIELD_HANDLE eeFindJitDataOffs(unsigned jitDataOffs);
7033     // returns true/false if 'field' is a Jit Data offset
7034     static bool eeIsJitDataOffs(CORINFO_FIELD_HANDLE field);
7035     // returns a number < 0 if 'field' is not a Jit Data offset, otherwise the data offset (limited to 2GB)
7036     static int eeGetJitDataOffs(CORINFO_FIELD_HANDLE field);
7037
7038     /*****************************************************************************/
7039
7040     /*
7041     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7042     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7043     XX                                                                           XX
7044     XX                           CodeGenerator                                   XX
7045     XX                                                                           XX
7046     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7047     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7048     */
7049
7050 public:
7051     CodeGenInterface* codeGen;
7052
7053     //  The following holds information about instr offsets in terms of generated code.
7054
7055     struct IPmappingDsc
7056     {
7057         IPmappingDsc* ipmdNext;      // next line# record
7058         IL_OFFSETX    ipmdILoffsx;   // the instr offset
7059         emitLocation  ipmdNativeLoc; // the emitter location of the native code corresponding to the IL offset
7060         bool          ipmdIsLabel;   // Can this code be a branch label?
7061     };
7062
7063     // Record the instr offset mapping to the generated code
7064
7065     IPmappingDsc* genIPmappingList;
7066     IPmappingDsc* genIPmappingLast;
7067
7068     // Managed RetVal - A side hash table meant to record the mapping from a
7069     // GT_CALL node to its IL offset.  This info is used to emit sequence points
7070     // that can be used by debugger to determine the native offset at which the
7071     // managed RetVal will be available.
7072     //
7073     // In fact we can store IL offset in a GT_CALL node.  This was ruled out in
7074     // favor of a side table for two reasons: 1) We need IL offset for only those
7075     // GT_CALL nodes (created during importation) that correspond to an IL call and
7076     // whose return type is other than TYP_VOID. 2) GT_CALL node is a frequently used
7077     // structure and IL offset is needed only when generating debuggable code. Therefore
7078     // it is desirable to avoid memory size penalty in retail scenarios.
7079     typedef JitHashTable<GenTree*, JitPtrKeyFuncs<GenTree>, IL_OFFSETX> CallSiteILOffsetTable;
7080     CallSiteILOffsetTable* genCallSite2ILOffsetMap;
7081
7082     unsigned    genReturnLocal; // Local number for the return value when applicable.
7083     BasicBlock* genReturnBB;    // jumped to when not optimizing for speed.
7084
7085     // The following properties are part of CodeGenContext.  Getters are provided here for
7086     // convenience and backward compatibility, but the properties can only be set by invoking
7087     // the setter on CodeGenContext directly.
7088
7089     __declspec(property(get = getEmitter)) emitter* genEmitter;
7090     emitter* getEmitter()
7091     {
7092         return codeGen->getEmitter();
7093     }
7094
7095     bool isFramePointerUsed() const
7096     {
7097         return codeGen->isFramePointerUsed();
7098     }
7099
7100     __declspec(property(get = getInterruptible, put = setInterruptible)) bool genInterruptible;
7101     bool getInterruptible()
7102     {
7103         return codeGen->genInterruptible;
7104     }
7105     void setInterruptible(bool value)
7106     {
7107         codeGen->setInterruptible(value);
7108     }
7109
7110 #ifdef _TARGET_ARMARCH_
7111     __declspec(property(get = getHasTailCalls, put = setHasTailCalls)) bool hasTailCalls;
7112     bool getHasTailCalls()
7113     {
7114         return codeGen->hasTailCalls;
7115     }
7116     void setHasTailCalls(bool value)
7117     {
7118         codeGen->setHasTailCalls(value);
7119     }
7120 #endif // _TARGET_ARMARCH_
7121
7122 #if DOUBLE_ALIGN
7123     const bool genDoubleAlign()
7124     {
7125         return codeGen->doDoubleAlign();
7126     }
7127     DWORD getCanDoubleAlign();
7128     bool shouldDoubleAlign(unsigned refCntStk,
7129                            unsigned refCntReg,
7130                            unsigned refCntWtdReg,
7131                            unsigned refCntStkParam,
7132                            unsigned refCntWtdStkDbl);
7133 #endif // DOUBLE_ALIGN
7134
7135     __declspec(property(get = getFullPtrRegMap, put = setFullPtrRegMap)) bool genFullPtrRegMap;
7136     bool getFullPtrRegMap()
7137     {
7138         return codeGen->genFullPtrRegMap;
7139     }
7140     void setFullPtrRegMap(bool value)
7141     {
7142         codeGen->setFullPtrRegMap(value);
7143     }
7144
7145 // Things that MAY belong either in CodeGen or CodeGenContext
7146
7147 #if FEATURE_EH_FUNCLETS
7148     FuncInfoDsc*   compFuncInfos;
7149     unsigned short compCurrFuncIdx;
7150     unsigned short compFuncInfoCount;
7151
7152     unsigned short compFuncCount()
7153     {
7154         assert(fgFuncletsCreated);
7155         return compFuncInfoCount;
7156     }
7157
7158 #else // !FEATURE_EH_FUNCLETS
7159
7160     // This is a no-op when there are no funclets!
7161     void genUpdateCurrentFunclet(BasicBlock* block)
7162     {
7163         return;
7164     }
7165
7166     FuncInfoDsc compFuncInfoRoot;
7167
7168     static const unsigned compCurrFuncIdx = 0;
7169
7170     unsigned short compFuncCount()
7171     {
7172         return 1;
7173     }
7174
7175 #endif // !FEATURE_EH_FUNCLETS
7176
7177     FuncInfoDsc* funCurrentFunc();
7178     void funSetCurrentFunc(unsigned funcIdx);
7179     FuncInfoDsc* funGetFunc(unsigned funcIdx);
7180     unsigned int funGetFuncIdx(BasicBlock* block);
7181
7182     // LIVENESS
7183
7184     VARSET_TP compCurLife;     // current live variables
7185     GenTree*  compCurLifeTree; // node after which compCurLife has been computed
7186
7187     template <bool ForCodeGen>
7188     void compChangeLife(VARSET_VALARG_TP newLife);
7189
7190     void genChangeLife(VARSET_VALARG_TP newLife)
7191     {
7192         compChangeLife</*ForCodeGen*/ true>(newLife);
7193     }
7194
7195     template <bool ForCodeGen>
7196     inline void compUpdateLife(VARSET_VALARG_TP newLife);
7197
7198     // Gets a register mask that represent the kill set for a helper call since
7199     // not all JIT Helper calls follow the standard ABI on the target architecture.
7200     regMaskTP compHelperCallKillSet(CorInfoHelpFunc helper);
7201
7202     // Gets a register mask that represent the kill set for a NoGC helper call.
7203     regMaskTP compNoGCHelperCallKillSet(CorInfoHelpFunc helper);
7204
7205 #ifdef _TARGET_ARM_
7206     // Requires that "varDsc" be a promoted struct local variable being passed as an argument, beginning at
7207     // "firstArgRegNum", which is assumed to have already been aligned to the register alignment restriction of the
7208     // struct type. Adds bits to "*pArgSkippedRegMask" for any argument registers *not* used in passing "varDsc" --
7209     // i.e., internal "holes" caused by internal alignment constraints.  For example, if the struct contained an int and
7210     // a double, and we at R0 (on ARM), then R1 would be skipped, and the bit for R1 would be added to the mask.
7211     void fgAddSkippedRegsInPromotedStructArg(LclVarDsc* varDsc, unsigned firstArgRegNum, regMaskTP* pArgSkippedRegMask);
7212 #endif // _TARGET_ARM_
7213
7214     // 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
7215     // node, else NULL.
7216     static GenTree* fgIsIndirOfAddrOfLocal(GenTree* tree);
7217
7218     // This map is indexed by GT_OBJ nodes that are address of promoted struct variables, which
7219     // have been annotated with the GTF_VAR_DEATH flag.  If such a node is *not* mapped in this
7220     // table, one may assume that all the (tracked) field vars die at this GT_OBJ.  Otherwise,
7221     // the node maps to a pointer to a VARSET_TP, containing set bits for each of the tracked field
7222     // vars of the promoted struct local that go dead at the given node (the set bits are the bits
7223     // for the tracked var indices of the field vars, as in a live var set).
7224     //
7225     // The map is allocated on demand so all map operations should use one of the following three
7226     // wrapper methods.
7227
7228     NodeToVarsetPtrMap* m_promotedStructDeathVars;
7229
7230     NodeToVarsetPtrMap* GetPromotedStructDeathVars()
7231     {
7232         if (m_promotedStructDeathVars == nullptr)
7233         {
7234             m_promotedStructDeathVars = new (getAllocator()) NodeToVarsetPtrMap(getAllocator());
7235         }
7236         return m_promotedStructDeathVars;
7237     }
7238
7239     void ClearPromotedStructDeathVars()
7240     {
7241         if (m_promotedStructDeathVars != nullptr)
7242         {
7243             m_promotedStructDeathVars->RemoveAll();
7244         }
7245     }
7246
7247     bool LookupPromotedStructDeathVars(GenTree* tree, VARSET_TP** bits)
7248     {
7249         bits        = nullptr;
7250         bool result = false;
7251
7252         if (m_promotedStructDeathVars != nullptr)
7253         {
7254             result = m_promotedStructDeathVars->Lookup(tree, bits);
7255         }
7256
7257         return result;
7258     }
7259
7260 /*
7261 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7262 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7263 XX                                                                           XX
7264 XX                           UnwindInfo                                      XX
7265 XX                                                                           XX
7266 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7267 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7268 */
7269
7270 #if !defined(__GNUC__)
7271 #pragma region Unwind information
7272 #endif
7273
7274 public:
7275     //
7276     // Infrastructure functions: start/stop/reserve/emit.
7277     //
7278
7279     void unwindBegProlog();
7280     void unwindEndProlog();
7281     void unwindBegEpilog();
7282     void unwindEndEpilog();
7283     void unwindReserve();
7284     void unwindEmit(void* pHotCode, void* pColdCode);
7285
7286     //
7287     // Specific unwind information functions: called by code generation to indicate a particular
7288     // prolog or epilog unwindable instruction has been generated.
7289     //
7290
7291     void unwindPush(regNumber reg);
7292     void unwindAllocStack(unsigned size);
7293     void unwindSetFrameReg(regNumber reg, unsigned offset);
7294     void unwindSaveReg(regNumber reg, unsigned offset);
7295
7296 #if defined(_TARGET_ARM_)
7297     void unwindPushMaskInt(regMaskTP mask);
7298     void unwindPushMaskFloat(regMaskTP mask);
7299     void unwindPopMaskInt(regMaskTP mask);
7300     void unwindPopMaskFloat(regMaskTP mask);
7301     void unwindBranch16();                    // The epilog terminates with a 16-bit branch (e.g., "bx lr")
7302     void unwindNop(unsigned codeSizeInBytes); // Generate unwind NOP code. 'codeSizeInBytes' is 2 or 4 bytes. Only
7303                                               // called via unwindPadding().
7304     void unwindPadding(); // Generate a sequence of unwind NOP codes representing instructions between the last
7305                           // instruction and the current location.
7306 #endif                    // _TARGET_ARM_
7307
7308 #if defined(_TARGET_ARM64_)
7309     void unwindNop();
7310     void unwindPadding(); // Generate a sequence of unwind NOP codes representing instructions between the last
7311                           // instruction and the current location.
7312     void unwindSaveReg(regNumber reg, int offset);                                // str reg, [sp, #offset]
7313     void unwindSaveRegPreindexed(regNumber reg, int offset);                      // str reg, [sp, #offset]!
7314     void unwindSaveRegPair(regNumber reg1, regNumber reg2, int offset);           // stp reg1, reg2, [sp, #offset]
7315     void unwindSaveRegPairPreindexed(regNumber reg1, regNumber reg2, int offset); // stp reg1, reg2, [sp, #offset]!
7316     void unwindSaveNext();                                                        // unwind code: save_next
7317     void unwindReturn(regNumber reg);                                             // ret lr
7318 #endif                                                                            // defined(_TARGET_ARM64_)
7319
7320     //
7321     // Private "helper" functions for the unwind implementation.
7322     //
7323
7324 private:
7325 #if FEATURE_EH_FUNCLETS
7326     void unwindGetFuncLocations(FuncInfoDsc*             func,
7327                                 bool                     getHotSectionData,
7328                                 /* OUT */ emitLocation** ppStartLoc,
7329                                 /* OUT */ emitLocation** ppEndLoc);
7330 #endif // FEATURE_EH_FUNCLETS
7331
7332     void unwindReserveFunc(FuncInfoDsc* func);
7333     void unwindEmitFunc(FuncInfoDsc* func, void* pHotCode, void* pColdCode);
7334
7335 #if defined(_TARGET_AMD64_) || (defined(_TARGET_X86_) && FEATURE_EH_FUNCLETS)
7336
7337     void unwindReserveFuncHelper(FuncInfoDsc* func, bool isHotCode);
7338     void unwindEmitFuncHelper(FuncInfoDsc* func, void* pHotCode, void* pColdCode, bool isHotCode);
7339
7340 #endif // _TARGET_AMD64_ || (_TARGET_X86_ && FEATURE_EH_FUNCLETS)
7341
7342     UNATIVE_OFFSET unwindGetCurrentOffset(FuncInfoDsc* func);
7343
7344 #if defined(_TARGET_AMD64_)
7345
7346     void unwindBegPrologWindows();
7347     void unwindPushWindows(regNumber reg);
7348     void unwindAllocStackWindows(unsigned size);
7349     void unwindSetFrameRegWindows(regNumber reg, unsigned offset);
7350     void unwindSaveRegWindows(regNumber reg, unsigned offset);
7351
7352 #ifdef UNIX_AMD64_ABI
7353     void unwindSaveRegCFI(regNumber reg, unsigned offset);
7354 #endif // UNIX_AMD64_ABI
7355 #elif defined(_TARGET_ARM_)
7356
7357     void unwindPushPopMaskInt(regMaskTP mask, bool useOpsize16);
7358     void unwindPushPopMaskFloat(regMaskTP mask);
7359
7360 #endif // _TARGET_ARM_
7361
7362 #if defined(_TARGET_UNIX_)
7363     int mapRegNumToDwarfReg(regNumber reg);
7364     void createCfiCode(FuncInfoDsc* func, UCHAR codeOffset, UCHAR opcode, USHORT dwarfReg, INT offset = 0);
7365     void unwindPushPopCFI(regNumber reg);
7366     void unwindBegPrologCFI();
7367     void unwindPushPopMaskCFI(regMaskTP regMask, bool isFloat);
7368     void unwindAllocStackCFI(unsigned size);
7369     void unwindSetFrameRegCFI(regNumber reg, unsigned offset);
7370     void unwindEmitFuncCFI(FuncInfoDsc* func, void* pHotCode, void* pColdCode);
7371 #ifdef DEBUG
7372     void DumpCfiInfo(bool                  isHotCode,
7373                      UNATIVE_OFFSET        startOffset,
7374                      UNATIVE_OFFSET        endOffset,
7375                      DWORD                 cfiCodeBytes,
7376                      const CFI_CODE* const pCfiCode);
7377 #endif
7378
7379 #endif // _TARGET_UNIX_
7380
7381 #if !defined(__GNUC__)
7382 #pragma endregion // Note: region is NOT under !defined(__GNUC__)
7383 #endif
7384
7385     /*
7386     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7387     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7388     XX                                                                           XX
7389     XX                               SIMD                                        XX
7390     XX                                                                           XX
7391     XX   Info about SIMD types, methods and the SIMD assembly (i.e. the assembly XX
7392     XX   that contains the distinguished, well-known SIMD type definitions).     XX
7393     XX                                                                           XX
7394     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7395     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7396     */
7397
7398     // Get highest available level for SIMD codegen
7399     SIMDLevel getSIMDSupportLevel()
7400     {
7401 #if defined(_TARGET_XARCH_)
7402         if (compSupports(InstructionSet_AVX2))
7403         {
7404             return SIMD_AVX2_Supported;
7405         }
7406
7407         if (compSupports(InstructionSet_SSE42))
7408         {
7409             return SIMD_SSE4_Supported;
7410         }
7411
7412         // min bar is SSE2
7413         return SIMD_SSE2_Supported;
7414 #else
7415         assert(!"Available instruction set(s) for SIMD codegen is not defined for target arch");
7416         unreached();
7417         return SIMD_Not_Supported;
7418 #endif
7419     }
7420
7421 #ifdef FEATURE_SIMD
7422
7423     // Should we support SIMD intrinsics?
7424     bool featureSIMD;
7425
7426     // Have we identified any SIMD types?
7427     // This is currently used by struct promotion to avoid getting type information for a struct
7428     // field to see if it is a SIMD type, if we haven't seen any SIMD types or operations in
7429     // the method.
7430     bool _usesSIMDTypes;
7431     bool usesSIMDTypes()
7432     {
7433         return _usesSIMDTypes;
7434     }
7435     void setUsesSIMDTypes(bool value)
7436     {
7437         _usesSIMDTypes = value;
7438     }
7439
7440     // This is a temp lclVar allocated on the stack as TYP_SIMD.  It is used to implement intrinsics
7441     // that require indexed access to the individual fields of the vector, which is not well supported
7442     // by the hardware.  It is allocated when/if such situations are encountered during Lowering.
7443     unsigned lvaSIMDInitTempVarNum;
7444
7445     struct SIMDHandlesCache
7446     {
7447         // SIMD Types
7448         CORINFO_CLASS_HANDLE SIMDFloatHandle;
7449         CORINFO_CLASS_HANDLE SIMDDoubleHandle;
7450         CORINFO_CLASS_HANDLE SIMDIntHandle;
7451         CORINFO_CLASS_HANDLE SIMDUShortHandle;
7452         CORINFO_CLASS_HANDLE SIMDUByteHandle;
7453         CORINFO_CLASS_HANDLE SIMDShortHandle;
7454         CORINFO_CLASS_HANDLE SIMDByteHandle;
7455         CORINFO_CLASS_HANDLE SIMDLongHandle;
7456         CORINFO_CLASS_HANDLE SIMDUIntHandle;
7457         CORINFO_CLASS_HANDLE SIMDULongHandle;
7458         CORINFO_CLASS_HANDLE SIMDVector2Handle;
7459         CORINFO_CLASS_HANDLE SIMDVector3Handle;
7460         CORINFO_CLASS_HANDLE SIMDVector4Handle;
7461         CORINFO_CLASS_HANDLE SIMDVectorHandle;
7462
7463 #ifdef FEATURE_HW_INTRINSICS
7464 #if defined(_TARGET_ARM64_)
7465         CORINFO_CLASS_HANDLE Vector64FloatHandle;
7466         CORINFO_CLASS_HANDLE Vector64IntHandle;
7467         CORINFO_CLASS_HANDLE Vector64UShortHandle;
7468         CORINFO_CLASS_HANDLE Vector64UByteHandle;
7469         CORINFO_CLASS_HANDLE Vector64ShortHandle;
7470         CORINFO_CLASS_HANDLE Vector64ByteHandle;
7471         CORINFO_CLASS_HANDLE Vector64UIntHandle;
7472 #endif // defined(_TARGET_ARM64_)
7473         CORINFO_CLASS_HANDLE Vector128FloatHandle;
7474         CORINFO_CLASS_HANDLE Vector128DoubleHandle;
7475         CORINFO_CLASS_HANDLE Vector128IntHandle;
7476         CORINFO_CLASS_HANDLE Vector128UShortHandle;
7477         CORINFO_CLASS_HANDLE Vector128UByteHandle;
7478         CORINFO_CLASS_HANDLE Vector128ShortHandle;
7479         CORINFO_CLASS_HANDLE Vector128ByteHandle;
7480         CORINFO_CLASS_HANDLE Vector128LongHandle;
7481         CORINFO_CLASS_HANDLE Vector128UIntHandle;
7482         CORINFO_CLASS_HANDLE Vector128ULongHandle;
7483 #if defined(_TARGET_XARCH_)
7484         CORINFO_CLASS_HANDLE Vector256FloatHandle;
7485         CORINFO_CLASS_HANDLE Vector256DoubleHandle;
7486         CORINFO_CLASS_HANDLE Vector256IntHandle;
7487         CORINFO_CLASS_HANDLE Vector256UShortHandle;
7488         CORINFO_CLASS_HANDLE Vector256UByteHandle;
7489         CORINFO_CLASS_HANDLE Vector256ShortHandle;
7490         CORINFO_CLASS_HANDLE Vector256ByteHandle;
7491         CORINFO_CLASS_HANDLE Vector256LongHandle;
7492         CORINFO_CLASS_HANDLE Vector256UIntHandle;
7493         CORINFO_CLASS_HANDLE Vector256ULongHandle;
7494 #endif // defined(_TARGET_XARCH_)
7495 #endif // FEATURE_HW_INTRINSICS
7496
7497         SIMDHandlesCache()
7498         {
7499             memset(this, 0, sizeof(*this));
7500         }
7501     };
7502
7503     SIMDHandlesCache* m_simdHandleCache;
7504
7505     // Get an appropriate "zero" for the given type and class handle.
7506     GenTree* gtGetSIMDZero(var_types simdType, var_types baseType, CORINFO_CLASS_HANDLE simdHandle);
7507
7508     // Get the handle for a SIMD type.
7509     CORINFO_CLASS_HANDLE gtGetStructHandleForSIMD(var_types simdType, var_types simdBaseType)
7510     {
7511         if (m_simdHandleCache == nullptr)
7512         {
7513             // This may happen if the JIT generates SIMD node on its own, without importing them.
7514             // Otherwise getBaseTypeAndSizeOfSIMDType should have created the cache.
7515             return NO_CLASS_HANDLE;
7516         }
7517
7518         if (simdBaseType == TYP_FLOAT)
7519         {
7520             switch (simdType)
7521             {
7522                 case TYP_SIMD8:
7523                     return m_simdHandleCache->SIMDVector2Handle;
7524                 case TYP_SIMD12:
7525                     return m_simdHandleCache->SIMDVector3Handle;
7526                 case TYP_SIMD16:
7527                     if ((getSIMDVectorType() == TYP_SIMD32) ||
7528                         (m_simdHandleCache->SIMDVector4Handle != NO_CLASS_HANDLE))
7529                     {
7530                         return m_simdHandleCache->SIMDVector4Handle;
7531                     }
7532                     break;
7533                 case TYP_SIMD32:
7534                     break;
7535                 default:
7536                     unreached();
7537             }
7538         }
7539         assert(emitTypeSize(simdType) <= maxSIMDStructBytes());
7540         switch (simdBaseType)
7541         {
7542             case TYP_FLOAT:
7543                 return m_simdHandleCache->SIMDFloatHandle;
7544             case TYP_DOUBLE:
7545                 return m_simdHandleCache->SIMDDoubleHandle;
7546             case TYP_INT:
7547                 return m_simdHandleCache->SIMDIntHandle;
7548             case TYP_USHORT:
7549                 return m_simdHandleCache->SIMDUShortHandle;
7550             case TYP_UBYTE:
7551                 return m_simdHandleCache->SIMDUByteHandle;
7552             case TYP_SHORT:
7553                 return m_simdHandleCache->SIMDShortHandle;
7554             case TYP_BYTE:
7555                 return m_simdHandleCache->SIMDByteHandle;
7556             case TYP_LONG:
7557                 return m_simdHandleCache->SIMDLongHandle;
7558             case TYP_UINT:
7559                 return m_simdHandleCache->SIMDUIntHandle;
7560             case TYP_ULONG:
7561                 return m_simdHandleCache->SIMDULongHandle;
7562             default:
7563                 assert(!"Didn't find a class handle for simdType");
7564         }
7565         return NO_CLASS_HANDLE;
7566     }
7567
7568     // Returns true if this is a SIMD type that should be considered an opaque
7569     // vector type (i.e. do not analyze or promote its fields).
7570     // Note that all but the fixed vector types are opaque, even though they may
7571     // actually be declared as having fields.
7572     bool isOpaqueSIMDType(CORINFO_CLASS_HANDLE structHandle)
7573     {
7574         return ((m_simdHandleCache != nullptr) && (structHandle != m_simdHandleCache->SIMDVector2Handle) &&
7575                 (structHandle != m_simdHandleCache->SIMDVector3Handle) &&
7576                 (structHandle != m_simdHandleCache->SIMDVector4Handle));
7577     }
7578
7579     // Returns true if the tree corresponds to a TYP_SIMD lcl var.
7580     // Note that both SIMD vector args and locals are mared as lvSIMDType = true, but
7581     // type of an arg node is TYP_BYREF and a local node is TYP_SIMD or TYP_STRUCT.
7582     bool isSIMDTypeLocal(GenTree* tree)
7583     {
7584         return tree->OperIsLocal() && lvaTable[tree->AsLclVarCommon()->gtLclNum].lvSIMDType;
7585     }
7586
7587     // Returns true if the lclVar is an opaque SIMD type.
7588     bool isOpaqueSIMDLclVar(LclVarDsc* varDsc)
7589     {
7590         if (!varDsc->lvSIMDType)
7591         {
7592             return false;
7593         }
7594         return isOpaqueSIMDType(varDsc->lvVerTypeInfo.GetClassHandle());
7595     }
7596
7597     // Returns true if the type of the tree is a byref of TYP_SIMD
7598     bool isAddrOfSIMDType(GenTree* tree)
7599     {
7600         if (tree->TypeGet() == TYP_BYREF || tree->TypeGet() == TYP_I_IMPL)
7601         {
7602             switch (tree->OperGet())
7603             {
7604                 case GT_ADDR:
7605                     return varTypeIsSIMD(tree->gtGetOp1());
7606
7607                 case GT_LCL_VAR_ADDR:
7608                     return lvaTable[tree->AsLclVarCommon()->gtLclNum].lvSIMDType;
7609
7610                 default:
7611                     return isSIMDTypeLocal(tree);
7612             }
7613         }
7614
7615         return false;
7616     }
7617
7618     static bool isRelOpSIMDIntrinsic(SIMDIntrinsicID intrinsicId)
7619     {
7620         return (intrinsicId == SIMDIntrinsicEqual || intrinsicId == SIMDIntrinsicLessThan ||
7621                 intrinsicId == SIMDIntrinsicLessThanOrEqual || intrinsicId == SIMDIntrinsicGreaterThan ||
7622                 intrinsicId == SIMDIntrinsicGreaterThanOrEqual);
7623     }
7624
7625     // Returns base type of a TYP_SIMD local.
7626     // Returns TYP_UNKNOWN if the local is not TYP_SIMD.
7627     var_types getBaseTypeOfSIMDLocal(GenTree* tree)
7628     {
7629         if (isSIMDTypeLocal(tree))
7630         {
7631             return lvaTable[tree->AsLclVarCommon()->gtLclNum].lvBaseType;
7632         }
7633
7634         return TYP_UNKNOWN;
7635     }
7636
7637     bool isSIMDClass(CORINFO_CLASS_HANDLE clsHnd)
7638     {
7639         return info.compCompHnd->isInSIMDModule(clsHnd);
7640     }
7641
7642     bool isIntrinsicType(CORINFO_CLASS_HANDLE clsHnd)
7643     {
7644         return (info.compCompHnd->getClassAttribs(clsHnd) & CORINFO_FLG_INTRINSIC_TYPE) != 0;
7645     }
7646
7647     const char* getClassNameFromMetadata(CORINFO_CLASS_HANDLE cls, const char** namespaceName)
7648     {
7649         return info.compCompHnd->getClassNameFromMetadata(cls, namespaceName);
7650     }
7651
7652     CORINFO_CLASS_HANDLE getTypeInstantiationArgument(CORINFO_CLASS_HANDLE cls, unsigned index)
7653     {
7654         return info.compCompHnd->getTypeInstantiationArgument(cls, index);
7655     }
7656
7657     bool isSIMDClass(typeInfo* pTypeInfo)
7658     {
7659         return pTypeInfo->IsStruct() && isSIMDClass(pTypeInfo->GetClassHandleForValueClass());
7660     }
7661
7662     bool isHWSIMDClass(CORINFO_CLASS_HANDLE clsHnd)
7663     {
7664 #ifdef FEATURE_HW_INTRINSICS
7665         if (isIntrinsicType(clsHnd))
7666         {
7667             const char* namespaceName = nullptr;
7668             (void)getClassNameFromMetadata(clsHnd, &namespaceName);
7669             return strcmp(namespaceName, "System.Runtime.Intrinsics") == 0;
7670         }
7671 #endif // FEATURE_HW_INTRINSICS
7672         return false;
7673     }
7674
7675     bool isHWSIMDClass(typeInfo* pTypeInfo)
7676     {
7677 #ifdef FEATURE_HW_INTRINSICS
7678         return pTypeInfo->IsStruct() && isHWSIMDClass(pTypeInfo->GetClassHandleForValueClass());
7679 #else
7680         return false;
7681 #endif
7682     }
7683
7684     bool isSIMDorHWSIMDClass(CORINFO_CLASS_HANDLE clsHnd)
7685     {
7686         return isSIMDClass(clsHnd) || isHWSIMDClass(clsHnd);
7687     }
7688
7689     bool isSIMDorHWSIMDClass(typeInfo* pTypeInfo)
7690     {
7691         return isSIMDClass(pTypeInfo) || isHWSIMDClass(pTypeInfo);
7692     }
7693
7694     // Get the base (element) type and size in bytes for a SIMD type. Returns TYP_UNKNOWN
7695     // if it is not a SIMD type or is an unsupported base type.
7696     var_types getBaseTypeAndSizeOfSIMDType(CORINFO_CLASS_HANDLE typeHnd, unsigned* sizeBytes = nullptr);
7697
7698     var_types getBaseTypeOfSIMDType(CORINFO_CLASS_HANDLE typeHnd)
7699     {
7700         return getBaseTypeAndSizeOfSIMDType(typeHnd, nullptr);
7701     }
7702
7703     // Get SIMD Intrinsic info given the method handle.
7704     // Also sets typeHnd, argCount, baseType and sizeBytes out params.
7705     const SIMDIntrinsicInfo* getSIMDIntrinsicInfo(CORINFO_CLASS_HANDLE* typeHnd,
7706                                                   CORINFO_METHOD_HANDLE methodHnd,
7707                                                   CORINFO_SIG_INFO*     sig,
7708                                                   bool                  isNewObj,
7709                                                   unsigned*             argCount,
7710                                                   var_types*            baseType,
7711                                                   unsigned*             sizeBytes);
7712
7713     // Pops and returns GenTree node from importers type stack.
7714     // Normalizes TYP_STRUCT value in case of GT_CALL, GT_RET_EXPR and arg nodes.
7715     GenTree* impSIMDPopStack(var_types type, bool expectAddr = false, CORINFO_CLASS_HANDLE structType = nullptr);
7716
7717     // Create a GT_SIMD tree for a Get property of SIMD vector with a fixed index.
7718     GenTreeSIMD* impSIMDGetFixed(var_types simdType, var_types baseType, unsigned simdSize, int index);
7719
7720     // Creates a GT_SIMD tree for Select operation
7721     GenTree* impSIMDSelect(CORINFO_CLASS_HANDLE typeHnd,
7722                            var_types            baseType,
7723                            unsigned             simdVectorSize,
7724                            GenTree*             op1,
7725                            GenTree*             op2,
7726                            GenTree*             op3);
7727
7728     // Creates a GT_SIMD tree for Min/Max operation
7729     GenTree* impSIMDMinMax(SIMDIntrinsicID      intrinsicId,
7730                            CORINFO_CLASS_HANDLE typeHnd,
7731                            var_types            baseType,
7732                            unsigned             simdVectorSize,
7733                            GenTree*             op1,
7734                            GenTree*             op2);
7735
7736     // Transforms operands and returns the SIMD intrinsic to be applied on
7737     // transformed operands to obtain given relop result.
7738     SIMDIntrinsicID impSIMDRelOp(SIMDIntrinsicID      relOpIntrinsicId,
7739                                  CORINFO_CLASS_HANDLE typeHnd,
7740                                  unsigned             simdVectorSize,
7741                                  var_types*           baseType,
7742                                  GenTree**            op1,
7743                                  GenTree**            op2);
7744
7745     // Creates a GT_SIMD tree for Abs intrinsic.
7746     GenTree* impSIMDAbs(CORINFO_CLASS_HANDLE typeHnd, var_types baseType, unsigned simdVectorSize, GenTree* op1);
7747
7748 #if defined(_TARGET_XARCH_)
7749
7750     // Transforms operands and returns the SIMD intrinsic to be applied on
7751     // transformed operands to obtain == comparison result.
7752     SIMDIntrinsicID impSIMDLongRelOpEqual(CORINFO_CLASS_HANDLE typeHnd,
7753                                           unsigned             simdVectorSize,
7754                                           GenTree**            op1,
7755                                           GenTree**            op2);
7756
7757     // Transforms operands and returns the SIMD intrinsic to be applied on
7758     // transformed operands to obtain > comparison result.
7759     SIMDIntrinsicID impSIMDLongRelOpGreaterThan(CORINFO_CLASS_HANDLE typeHnd,
7760                                                 unsigned             simdVectorSize,
7761                                                 GenTree**            op1,
7762                                                 GenTree**            op2);
7763
7764     // Transforms operands and returns the SIMD intrinsic to be applied on
7765     // transformed operands to obtain >= comparison result.
7766     SIMDIntrinsicID impSIMDLongRelOpGreaterThanOrEqual(CORINFO_CLASS_HANDLE typeHnd,
7767                                                        unsigned             simdVectorSize,
7768                                                        GenTree**            op1,
7769                                                        GenTree**            op2);
7770
7771     // Transforms operands and returns the SIMD intrinsic to be applied on
7772     // transformed operands to obtain >= comparison result in case of int32
7773     // and small int base type vectors.
7774     SIMDIntrinsicID impSIMDIntegralRelOpGreaterThanOrEqual(
7775         CORINFO_CLASS_HANDLE typeHnd, unsigned simdVectorSize, var_types baseType, GenTree** op1, GenTree** op2);
7776
7777 #endif // defined(_TARGET_XARCH_)
7778
7779     void setLclRelatedToSIMDIntrinsic(GenTree* tree);
7780     bool areFieldsContiguous(GenTree* op1, GenTree* op2);
7781     bool areArrayElementsContiguous(GenTree* op1, GenTree* op2);
7782     bool areArgumentsContiguous(GenTree* op1, GenTree* op2);
7783     GenTree* createAddressNodeForSIMDInit(GenTree* tree, unsigned simdSize);
7784
7785     // check methodHnd to see if it is a SIMD method that is expanded as an intrinsic in the JIT.
7786     GenTree* impSIMDIntrinsic(OPCODE                opcode,
7787                               GenTree*              newobjThis,
7788                               CORINFO_CLASS_HANDLE  clsHnd,
7789                               CORINFO_METHOD_HANDLE method,
7790                               CORINFO_SIG_INFO*     sig,
7791                               unsigned              methodFlags,
7792                               int                   memberRef);
7793
7794     GenTree* getOp1ForConstructor(OPCODE opcode, GenTree* newobjThis, CORINFO_CLASS_HANDLE clsHnd);
7795
7796     // Whether SIMD vector occupies part of SIMD register.
7797     // SSE2: vector2f/3f are considered sub register SIMD types.
7798     // AVX: vector2f, 3f and 4f are all considered sub register SIMD types.
7799     bool isSubRegisterSIMDType(CORINFO_CLASS_HANDLE typeHnd)
7800     {
7801         unsigned  sizeBytes = 0;
7802         var_types baseType  = getBaseTypeAndSizeOfSIMDType(typeHnd, &sizeBytes);
7803         return (baseType == TYP_FLOAT) && (sizeBytes < getSIMDVectorRegisterByteLength());
7804     }
7805
7806     bool isSubRegisterSIMDType(GenTreeSIMD* simdNode)
7807     {
7808         return (simdNode->gtSIMDSize < getSIMDVectorRegisterByteLength());
7809     }
7810
7811     // Get the type for the hardware SIMD vector.
7812     // This is the maximum SIMD type supported for this target.
7813     var_types getSIMDVectorType()
7814     {
7815 #if defined(_TARGET_XARCH_)
7816         if (getSIMDSupportLevel() == SIMD_AVX2_Supported)
7817         {
7818             return TYP_SIMD32;
7819         }
7820         else
7821         {
7822             assert(getSIMDSupportLevel() >= SIMD_SSE2_Supported);
7823             return TYP_SIMD16;
7824         }
7825 #elif defined(_TARGET_ARM64_)
7826         return TYP_SIMD16;
7827 #else
7828         assert(!"getSIMDVectorType() unimplemented on target arch");
7829         unreached();
7830 #endif
7831     }
7832
7833     // Get the size of the SIMD type in bytes
7834     int getSIMDTypeSizeInBytes(CORINFO_CLASS_HANDLE typeHnd)
7835     {
7836         unsigned sizeBytes = 0;
7837         (void)getBaseTypeAndSizeOfSIMDType(typeHnd, &sizeBytes);
7838         return sizeBytes;
7839     }
7840
7841     // Get the the number of elements of basetype of SIMD vector given by its size and baseType
7842     static int getSIMDVectorLength(unsigned simdSize, var_types baseType);
7843
7844     // Get the the number of elements of basetype of SIMD vector given by its type handle
7845     int getSIMDVectorLength(CORINFO_CLASS_HANDLE typeHnd);
7846
7847     // Get preferred alignment of SIMD type.
7848     int getSIMDTypeAlignment(var_types simdType);
7849
7850     // Get the number of bytes in a System.Numeric.Vector<T> for the current compilation.
7851     // Note - cannot be used for System.Runtime.Intrinsic
7852     unsigned getSIMDVectorRegisterByteLength()
7853     {
7854 #if defined(_TARGET_XARCH_)
7855         if (getSIMDSupportLevel() == SIMD_AVX2_Supported)
7856         {
7857             return YMM_REGSIZE_BYTES;
7858         }
7859         else
7860         {
7861             assert(getSIMDSupportLevel() >= SIMD_SSE2_Supported);
7862             return XMM_REGSIZE_BYTES;
7863         }
7864 #elif defined(_TARGET_ARM64_)
7865         return FP_REGSIZE_BYTES;
7866 #else
7867         assert(!"getSIMDVectorRegisterByteLength() unimplemented on target arch");
7868         unreached();
7869 #endif
7870     }
7871
7872     // The minimum and maximum possible number of bytes in a SIMD vector.
7873
7874     // maxSIMDStructBytes
7875     // The minimum SIMD size supported by System.Numeric.Vectors or System.Runtime.Intrinsic
7876     // SSE:  16-byte Vector<T> and Vector128<T>
7877     // AVX:  32-byte Vector256<T> (Vector<T> is 16-byte)
7878     // AVX2: 32-byte Vector<T> and Vector256<T>
7879     unsigned int maxSIMDStructBytes()
7880     {
7881 #if defined(FEATURE_HW_INTRINSICS) && defined(_TARGET_XARCH_)
7882         if (compSupports(InstructionSet_AVX))
7883         {
7884             return YMM_REGSIZE_BYTES;
7885         }
7886         else
7887         {
7888             assert(getSIMDSupportLevel() >= SIMD_SSE2_Supported);
7889             return XMM_REGSIZE_BYTES;
7890         }
7891 #else
7892         return getSIMDVectorRegisterByteLength();
7893 #endif
7894     }
7895     unsigned int minSIMDStructBytes()
7896     {
7897         return emitTypeSize(TYP_SIMD8);
7898     }
7899
7900     // Returns the codegen type for a given SIMD size.
7901     var_types getSIMDTypeForSize(unsigned size)
7902     {
7903         var_types simdType = TYP_UNDEF;
7904         if (size == 8)
7905         {
7906             simdType = TYP_SIMD8;
7907         }
7908         else if (size == 12)
7909         {
7910             simdType = TYP_SIMD12;
7911         }
7912         else if (size == 16)
7913         {
7914             simdType = TYP_SIMD16;
7915         }
7916         else if (size == 32)
7917         {
7918             simdType = TYP_SIMD32;
7919         }
7920         else
7921         {
7922             noway_assert(!"Unexpected size for SIMD type");
7923         }
7924         return simdType;
7925     }
7926
7927     unsigned getSIMDInitTempVarNum()
7928     {
7929         if (lvaSIMDInitTempVarNum == BAD_VAR_NUM)
7930         {
7931             lvaSIMDInitTempVarNum                  = lvaGrabTempWithImplicitUse(false DEBUGARG("SIMDInitTempVar"));
7932             lvaTable[lvaSIMDInitTempVarNum].lvType = getSIMDVectorType();
7933         }
7934         return lvaSIMDInitTempVarNum;
7935     }
7936
7937 #else  // !FEATURE_SIMD
7938     bool isOpaqueSIMDLclVar(LclVarDsc* varDsc)
7939     {
7940         return false;
7941     }
7942 #endif // FEATURE_SIMD
7943
7944 public:
7945     //------------------------------------------------------------------------
7946     // largestEnregisterableStruct: The size in bytes of the largest struct that can be enregistered.
7947     //
7948     // Notes: It is not guaranteed that the struct of this size or smaller WILL be a
7949     //        candidate for enregistration.
7950
7951     unsigned largestEnregisterableStructSize()
7952     {
7953 #ifdef FEATURE_SIMD
7954         unsigned vectorRegSize = getSIMDVectorRegisterByteLength();
7955         if (vectorRegSize > TARGET_POINTER_SIZE)
7956         {
7957             return vectorRegSize;
7958         }
7959         else
7960 #endif // FEATURE_SIMD
7961         {
7962             return TARGET_POINTER_SIZE;
7963         }
7964     }
7965
7966 private:
7967     // These routines need not be enclosed under FEATURE_SIMD since lvIsSIMDType()
7968     // is defined for both FEATURE_SIMD and !FEATURE_SIMD apropriately. The use
7969     // of this routines also avoids the need of #ifdef FEATURE_SIMD specific code.
7970
7971     // Is this var is of type simd struct?
7972     bool lclVarIsSIMDType(unsigned varNum)
7973     {
7974         LclVarDsc* varDsc = lvaTable + varNum;
7975         return varDsc->lvIsSIMDType();
7976     }
7977
7978     // Is this Local node a SIMD local?
7979     bool lclVarIsSIMDType(GenTreeLclVarCommon* lclVarTree)
7980     {
7981         return lclVarIsSIMDType(lclVarTree->gtLclNum);
7982     }
7983
7984     // Returns true if the TYP_SIMD locals on stack are aligned at their
7985     // preferred byte boundary specified by getSIMDTypeAlignment().
7986     //
7987     // As per the Intel manual, the preferred alignment for AVX vectors is 32-bytes. On Amd64,
7988     // RSP/EBP is aligned at 16-bytes, therefore to align SIMD types at 32-bytes we need even
7989     // RSP/EBP to be 32-byte aligned. It is not clear whether additional stack space used in
7990     // aligning stack is worth the benefit and for now will use 16-byte alignment for AVX
7991     // 256-bit vectors with unaligned load/stores to/from memory. On x86, the stack frame
7992     // is aligned to 4 bytes. We need to extend existing support for double (8-byte) alignment
7993     // to 16 or 32 byte alignment for frames with local SIMD vars, if that is determined to be
7994     // profitable.
7995     //
7996     bool isSIMDTypeLocalAligned(unsigned varNum)
7997     {
7998 #if defined(FEATURE_SIMD) && ALIGN_SIMD_TYPES
7999         if (lclVarIsSIMDType(varNum) && lvaTable[varNum].lvType != TYP_BYREF)
8000         {
8001             bool ebpBased;
8002             int  off = lvaFrameAddress(varNum, &ebpBased);
8003             // TODO-Cleanup: Can't this use the lvExactSize on the varDsc?
8004             int  alignment = getSIMDTypeAlignment(lvaTable[varNum].lvType);
8005             bool isAligned = (alignment <= STACK_ALIGN) && ((off % alignment) == 0);
8006             return isAligned;
8007         }
8008 #endif // FEATURE_SIMD
8009
8010         return false;
8011     }
8012
8013     bool compSupports(InstructionSet isa) const
8014     {
8015 #if defined(_TARGET_XARCH_) || defined(_TARGET_ARM64_)
8016         return (opts.compSupportsISA & (1ULL << isa)) != 0;
8017 #else
8018         return false;
8019 #endif
8020     }
8021
8022     bool canUseVexEncoding() const
8023     {
8024 #ifdef _TARGET_XARCH_
8025         return compSupports(InstructionSet_AVX);
8026 #else
8027         return false;
8028 #endif
8029     }
8030
8031     /*
8032     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8033     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8034     XX                                                                           XX
8035     XX                           Compiler                                        XX
8036     XX                                                                           XX
8037     XX   Generic info about the compilation and the method being compiled.       XX
8038     XX   It is responsible for driving the other phases.                         XX
8039     XX   It is also responsible for all the memory management.                   XX
8040     XX                                                                           XX
8041     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8042     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8043     */
8044
8045 public:
8046     Compiler* InlineeCompiler; // The Compiler instance for the inlinee
8047
8048     InlineResult* compInlineResult; // The result of importing the inlinee method.
8049
8050     bool compDoAggressiveInlining; // If true, mark every method as CORINFO_FLG_FORCEINLINE
8051     bool compJmpOpUsed;            // Does the method do a JMP
8052     bool compLongUsed;             // Does the method use TYP_LONG
8053     bool compFloatingPointUsed;    // Does the method use TYP_FLOAT or TYP_DOUBLE
8054     bool compTailCallUsed;         // Does the method do a tailcall
8055     bool compLocallocUsed;         // Does the method use localloc.
8056     bool compLocallocOptimized;    // Does the method have an optimized localloc
8057     bool compQmarkUsed;            // Does the method use GT_QMARK/GT_COLON
8058     bool compQmarkRationalized;    // Is it allowed to use a GT_QMARK/GT_COLON node.
8059     bool compUnsafeCastUsed;       // Does the method use LDIND/STIND to cast between scalar/refernce types
8060
8061 // NOTE: These values are only reliable after
8062 //       the importing is completely finished.
8063
8064 #ifdef DEBUG
8065     // State information - which phases have completed?
8066     // These are kept together for easy discoverability
8067
8068     bool    bRangeAllowStress;
8069     bool    compCodeGenDone;
8070     int64_t compNumStatementLinksTraversed; // # of links traversed while doing debug checks
8071     bool    fgNormalizeEHDone;              // Has the flowgraph EH normalization phase been done?
8072     size_t  compSizeEstimate;               // The estimated size of the method as per `gtSetEvalOrder`.
8073     size_t  compCycleEstimate;              // The estimated cycle count of the method as per `gtSetEvalOrder`
8074 #endif                                      // DEBUG
8075
8076     bool fgLocalVarLivenessDone; // Note that this one is used outside of debug.
8077     bool fgLocalVarLivenessChanged;
8078     bool compLSRADone;
8079     bool compRationalIRForm;
8080
8081     bool compUsesThrowHelper; // There is a call to a THOROW_HELPER for the compiled method.
8082
8083     bool compGeneratingProlog;
8084     bool compGeneratingEpilog;
8085     bool compNeedsGSSecurityCookie; // There is an unsafe buffer (or localloc) on the stack.
8086                                     // Insert cookie on frame and code to check the cookie, like VC++ -GS.
8087     bool compGSReorderStackLayout;  // There is an unsafe buffer on the stack, reorder locals and make local
8088     // copies of susceptible parameters to avoid buffer overrun attacks through locals/params
8089     bool getNeedsGSSecurityCookie() const
8090     {
8091         return compNeedsGSSecurityCookie;
8092     }
8093     void setNeedsGSSecurityCookie()
8094     {
8095         compNeedsGSSecurityCookie = true;
8096     }
8097
8098     FrameLayoutState lvaDoneFrameLayout; // The highest frame layout state that we've completed. During
8099                                          // frame layout calculations, this is the level we are currently
8100                                          // computing.
8101
8102     //---------------------------- JITing options -----------------------------
8103
8104     enum codeOptimize
8105     {
8106         BLENDED_CODE,
8107         SMALL_CODE,
8108         FAST_CODE,
8109
8110         COUNT_OPT_CODE
8111     };
8112
8113     struct Options
8114     {
8115         JitFlags* jitFlags;  // all flags passed from the EE
8116         unsigned  compFlags; // method attributes
8117
8118         codeOptimize compCodeOpt; // what type of code optimizations
8119
8120         bool compUseFCOMI;
8121         bool compUseCMOV;
8122
8123 #if defined(_TARGET_XARCH_) || defined(_TARGET_ARM64_)
8124         uint64_t compSupportsISA;
8125         void setSupportedISA(InstructionSet isa)
8126         {
8127             compSupportsISA |= 1ULL << isa;
8128         }
8129 #endif
8130
8131 // optimize maximally and/or favor speed over size?
8132
8133 #define DEFAULT_MIN_OPTS_CODE_SIZE 60000
8134 #define DEFAULT_MIN_OPTS_INSTR_COUNT 20000
8135 #define DEFAULT_MIN_OPTS_BB_COUNT 2000
8136 #define DEFAULT_MIN_OPTS_LV_NUM_COUNT 2000
8137 #define DEFAULT_MIN_OPTS_LV_REF_COUNT 8000
8138
8139 // Maximun number of locals before turning off the inlining
8140 #define MAX_LV_NUM_COUNT_FOR_INLINING 512
8141
8142         bool     compMinOpts;
8143         unsigned instrCount;
8144         unsigned lvRefCount;
8145         bool     compMinOptsIsSet;
8146 #ifdef DEBUG
8147         bool compMinOptsIsUsed;
8148
8149         bool MinOpts()
8150         {
8151             assert(compMinOptsIsSet);
8152             compMinOptsIsUsed = true;
8153             return compMinOpts;
8154         }
8155         bool IsMinOptsSet()
8156         {
8157             return compMinOptsIsSet;
8158         }
8159 #else  // !DEBUG
8160         bool MinOpts()
8161         {
8162             return compMinOpts;
8163         }
8164         bool IsMinOptsSet()
8165         {
8166             return compMinOptsIsSet;
8167         }
8168 #endif // !DEBUG
8169
8170         bool OptimizationDisabled()
8171         {
8172             return MinOpts() || compDbgCode;
8173         }
8174         bool OptimizationEnabled()
8175         {
8176             return !OptimizationDisabled();
8177         }
8178
8179         void SetMinOpts(bool val)
8180         {
8181             assert(!compMinOptsIsUsed);
8182             assert(!compMinOptsIsSet || (compMinOpts == val));
8183             compMinOpts      = val;
8184             compMinOptsIsSet = true;
8185         }
8186
8187         // true if the CLFLG_* for an optimization is set.
8188         bool OptEnabled(unsigned optFlag)
8189         {
8190             return !!(compFlags & optFlag);
8191         }
8192
8193 #ifdef FEATURE_READYTORUN_COMPILER
8194         bool IsReadyToRun()
8195         {
8196             return jitFlags->IsSet(JitFlags::JIT_FLAG_READYTORUN);
8197         }
8198 #else
8199         bool IsReadyToRun()
8200         {
8201             return false;
8202         }
8203 #endif
8204
8205         // true if we should use the PINVOKE_{BEGIN,END} helpers instead of generating
8206         // PInvoke transitions inline (e.g. when targeting CoreRT).
8207         bool ShouldUsePInvokeHelpers()
8208         {
8209             return jitFlags->IsSet(JitFlags::JIT_FLAG_USE_PINVOKE_HELPERS);
8210         }
8211
8212         // true if we should use insert the REVERSE_PINVOKE_{ENTER,EXIT} helpers in the method
8213         // prolog/epilog
8214         bool IsReversePInvoke()
8215         {
8216             return jitFlags->IsSet(JitFlags::JIT_FLAG_REVERSE_PINVOKE);
8217         }
8218
8219         // true if we must generate code compatible with JIT32 quirks
8220         bool IsJit32Compat()
8221         {
8222 #if defined(_TARGET_X86_)
8223             return jitFlags->IsSet(JitFlags::JIT_FLAG_DESKTOP_QUIRKS);
8224 #else
8225             return false;
8226 #endif
8227         }
8228
8229         // true if we must generate code compatible with Jit64 quirks
8230         bool IsJit64Compat()
8231         {
8232 #if defined(_TARGET_AMD64_)
8233             return jitFlags->IsSet(JitFlags::JIT_FLAG_DESKTOP_QUIRKS);
8234 #elif !defined(FEATURE_CORECLR)
8235             return true;
8236 #else
8237             return false;
8238 #endif
8239         }
8240
8241         bool compScopeInfo; // Generate the LocalVar info ?
8242         bool compDbgCode;   // Generate debugger-friendly code?
8243         bool compDbgInfo;   // Gather debugging info?
8244         bool compDbgEnC;
8245
8246 #ifdef PROFILING_SUPPORTED
8247         bool compNoPInvokeInlineCB;
8248 #else
8249         static const bool compNoPInvokeInlineCB;
8250 #endif
8251
8252 #ifdef DEBUG
8253         bool compGcChecks; // Check arguments and return values to ensure they are sane
8254 #endif
8255
8256 #if defined(DEBUG) && defined(_TARGET_XARCH_)
8257
8258         bool compStackCheckOnRet; // Check stack pointer on return to ensure it is correct.
8259
8260 #endif // defined(DEBUG) && defined(_TARGET_XARCH_)
8261
8262 #if defined(DEBUG) && defined(_TARGET_X86_)
8263
8264         bool compStackCheckOnCall; // Check stack pointer after call to ensure it is correct. Only for x86.
8265
8266 #endif // defined(DEBUG) && defined(_TARGET_X86_)
8267
8268         bool compNeedSecurityCheck; // This flag really means where or not a security object needs
8269                                     // to be allocated on the stack.
8270                                     // It will be set to true in the following cases:
8271                                     //   1. When the method being compiled has a declarative security
8272                                     //        (i.e. when CORINFO_FLG_NOSECURITYWRAP is reset for the current method).
8273                                     //        This is also the case when we inject a prolog and epilog in the method.
8274                                     //   (or)
8275                                     //   2. When the method being compiled has imperative security (i.e. the method
8276                                     //        calls into another method that has CORINFO_FLG_SECURITYCHECK flag set).
8277                                     //   (or)
8278                                     //   3. When opts.compDbgEnC is true. (See also Compiler::compCompile).
8279                                     //
8280         // When this flag is set, jit will allocate a gc-reference local variable (lvaSecurityObject),
8281         // which gets reported as a GC root to stackwalker.
8282         // (See also ICodeManager::GetAddrOfSecurityObject.)
8283
8284         bool compReloc; // Generate relocs for pointers in code, true for all ngen/prejit codegen
8285
8286 #ifdef DEBUG
8287 #if defined(_TARGET_XARCH_)
8288         bool compEnablePCRelAddr; // Whether absolute addr be encoded as PC-rel offset by RyuJIT where possible
8289 #endif
8290 #endif // DEBUG
8291
8292 #ifdef UNIX_AMD64_ABI
8293         // This flag  is indicating if there is a need to align the frame.
8294         // On AMD64-Windows, if there are calls, 4 slots for the outgoing ars are allocated, except for
8295         // FastTailCall. This slots makes the frame size non-zero, so alignment logic will be called.
8296         // On AMD64-Unix, there are no such slots. There is a possibility to have calls in the method with frame size of
8297         // 0. The frame alignment logic won't kick in. This flags takes care of the AMD64-Unix case by remembering that
8298         // there are calls and making sure the frame alignment logic is executed.
8299         bool compNeedToAlignFrame;
8300 #endif // UNIX_AMD64_ABI
8301
8302         bool compProcedureSplitting; // Separate cold code from hot code
8303
8304         bool genFPorder; // Preserve FP order (operations are non-commutative)
8305         bool genFPopt;   // Can we do frame-pointer-omission optimization?
8306         bool altJit;     // True if we are an altjit and are compiling this method
8307
8308 #ifdef OPT_CONFIG
8309         bool optRepeat; // Repeat optimizer phases k times
8310 #endif
8311
8312 #ifdef DEBUG
8313         bool compProcedureSplittingEH; // Separate cold code from hot code for functions with EH
8314         bool dspCode;                  // Display native code generated
8315         bool dspEHTable;               // Display the EH table reported to the VM
8316         bool dspDebugInfo;             // Display the Debug info reported to the VM
8317         bool dspInstrs;                // Display the IL instructions intermixed with the native code output
8318         bool dspEmit;                  // Display emitter output
8319         bool dspLines;                 // Display source-code lines intermixed with native code output
8320         bool dmpHex;                   // Display raw bytes in hex of native code output
8321         bool varNames;                 // Display variables names in native code output
8322         bool disAsm;                   // Display native code as it is generated
8323         bool disAsmSpilled;            // Display native code when any register spilling occurs
8324         bool disDiffable;              // Makes the Disassembly code 'diff-able'
8325         bool disAsm2;                  // Display native code after it is generated using external disassembler
8326         bool dspOrder;                 // Display names of each of the methods that we ngen/jit
8327         bool dspUnwind;                // Display the unwind info output
8328         bool dspDiffable;     // Makes the Jit Dump 'diff-able' (currently uses same COMPlus_* flag as disDiffable)
8329         bool compLongAddress; // Force using large pseudo instructions for long address
8330                               // (IF_LARGEJMP/IF_LARGEADR/IF_LARGLDC)
8331         bool dspGCtbls;       // Display the GC tables
8332 #endif
8333
8334 #ifdef LATE_DISASM
8335         bool doLateDisasm; // Run the late disassembler
8336 #endif                     // LATE_DISASM
8337
8338 #if DUMP_GC_TABLES && !defined(DEBUG) && defined(JIT32_GCENCODER)
8339 // Only the JIT32_GCENCODER implements GC dumping in non-DEBUG code.
8340 #pragma message("NOTE: this non-debug build has GC ptr table dumping always enabled!")
8341         static const bool dspGCtbls = true;
8342 #endif
8343
8344 #ifdef PROFILING_SUPPORTED
8345         // Whether to emit Enter/Leave/TailCall hooks using a dummy stub (DummyProfilerELTStub()).
8346         // This option helps make the JIT behave as if it is running under a profiler.
8347         bool compJitELTHookEnabled;
8348 #endif // PROFILING_SUPPORTED
8349
8350 #if FEATURE_TAILCALL_OPT
8351         // Whether opportunistic or implicit tail call optimization is enabled.
8352         bool compTailCallOpt;
8353         // Whether optimization of transforming a recursive tail call into a loop is enabled.
8354         bool compTailCallLoopOpt;
8355 #endif
8356
8357 #if defined(_TARGET_ARM64_)
8358         // Decision about whether to save FP/LR registers with callee-saved registers (see
8359         // COMPlus_JitSaveFpLrWithCalleSavedRegisters).
8360         int compJitSaveFpLrWithCalleeSavedRegisters;
8361 #endif // defined(_TARGET_ARM64_)
8362
8363 #ifdef ARM_SOFTFP
8364         static const bool compUseSoftFP = true;
8365 #else // !ARM_SOFTFP
8366         static const bool compUseSoftFP = false;
8367 #endif
8368
8369         GCPollType compGCPollType;
8370     } opts;
8371
8372 #ifdef ALT_JIT
8373     static bool                s_pAltJitExcludeAssembliesListInitialized;
8374     static AssemblyNamesList2* s_pAltJitExcludeAssembliesList;
8375 #endif // ALT_JIT
8376
8377 #ifdef DEBUG
8378     static bool                s_pJitDisasmIncludeAssembliesListInitialized;
8379     static AssemblyNamesList2* s_pJitDisasmIncludeAssembliesList;
8380
8381     static bool       s_pJitFunctionFileInitialized;
8382     static MethodSet* s_pJitMethodSet;
8383 #endif // DEBUG
8384
8385 #ifdef DEBUG
8386 // silence warning of cast to greater size. It is easier to silence than construct code the compiler is happy with, and
8387 // it is safe in this case
8388 #pragma warning(push)
8389 #pragma warning(disable : 4312)
8390
8391     template <typename T>
8392     T dspPtr(T p)
8393     {
8394         return (p == ZERO) ? ZERO : (opts.dspDiffable ? T(0xD1FFAB1E) : p);
8395     }
8396
8397     template <typename T>
8398     T dspOffset(T o)
8399     {
8400         return (o == ZERO) ? ZERO : (opts.dspDiffable ? T(0xD1FFAB1E) : o);
8401     }
8402 #pragma warning(pop)
8403
8404     static int dspTreeID(GenTree* tree)
8405     {
8406         return tree->gtTreeID;
8407     }
8408     static void printTreeID(GenTree* tree)
8409     {
8410         if (tree == nullptr)
8411         {
8412             printf("[------]");
8413         }
8414         else
8415         {
8416             printf("[%06d]", dspTreeID(tree));
8417         }
8418     }
8419
8420 #endif // DEBUG
8421
8422 // clang-format off
8423 #define STRESS_MODES                                                                            \
8424                                                                                                 \
8425         STRESS_MODE(NONE)                                                                       \
8426                                                                                                 \
8427         /* "Variations" stress areas which we try to mix up with each other. */                 \
8428         /* These should not be exhaustively used as they might */                               \
8429         /* hide/trivialize other areas */                                                       \
8430                                                                                                 \
8431         STRESS_MODE(REGS)                                                                       \
8432         STRESS_MODE(DBL_ALN)                                                                    \
8433         STRESS_MODE(LCL_FLDS)                                                                   \
8434         STRESS_MODE(UNROLL_LOOPS)                                                               \
8435         STRESS_MODE(MAKE_CSE)                                                                   \
8436         STRESS_MODE(LEGACY_INLINE)                                                              \
8437         STRESS_MODE(CLONE_EXPR)                                                                 \
8438         STRESS_MODE(USE_FCOMI)                                                                  \
8439         STRESS_MODE(USE_CMOV)                                                                   \
8440         STRESS_MODE(FOLD)                                                                       \
8441         STRESS_MODE(BB_PROFILE)                                                                 \
8442         STRESS_MODE(OPT_BOOLS_GC)                                                               \
8443         STRESS_MODE(REMORPH_TREES)                                                              \
8444         STRESS_MODE(64RSLT_MUL)                                                                 \
8445         STRESS_MODE(DO_WHILE_LOOPS)                                                             \
8446         STRESS_MODE(MIN_OPTS)                                                                   \
8447         STRESS_MODE(REVERSE_FLAG)     /* Will set GTF_REVERSE_OPS whenever we can */            \
8448         STRESS_MODE(REVERSE_COMMA)    /* Will reverse commas created  with gtNewCommaNode */    \
8449         STRESS_MODE(TAILCALL)         /* Will make the call as a tailcall whenever legal */     \
8450         STRESS_MODE(CATCH_ARG)        /* Will spill catch arg */                                \
8451         STRESS_MODE(UNSAFE_BUFFER_CHECKS)                                                       \
8452         STRESS_MODE(NULL_OBJECT_CHECK)                                                          \
8453         STRESS_MODE(PINVOKE_RESTORE_ESP)                                                        \
8454         STRESS_MODE(RANDOM_INLINE)                                                              \
8455         STRESS_MODE(SWITCH_CMP_BR_EXPANSION)                                                    \
8456         STRESS_MODE(GENERIC_VARN)                                                               \
8457                                                                                                 \
8458         /* After COUNT_VARN, stress level 2 does all of these all the time */                   \
8459                                                                                                 \
8460         STRESS_MODE(COUNT_VARN)                                                                 \
8461                                                                                                 \
8462         /* "Check" stress areas that can be exhaustively used if we */                          \
8463         /*  dont care about performance at all */                                               \
8464                                                                                                 \
8465         STRESS_MODE(FORCE_INLINE) /* Treat every method as AggressiveInlining */                \
8466         STRESS_MODE(CHK_FLOW_UPDATE)                                                            \
8467         STRESS_MODE(EMITTER)                                                                    \
8468         STRESS_MODE(CHK_REIMPORT)                                                               \
8469         STRESS_MODE(FLATFP)                                                                     \
8470         STRESS_MODE(GENERIC_CHECK)                                                              \
8471         STRESS_MODE(COUNT)
8472
8473     enum                compStressArea
8474     {
8475 #define STRESS_MODE(mode) STRESS_##mode,
8476         STRESS_MODES
8477 #undef STRESS_MODE
8478     };
8479 // clang-format on
8480
8481 #ifdef DEBUG
8482     static const LPCWSTR s_compStressModeNames[STRESS_COUNT + 1];
8483     BYTE                 compActiveStressModes[STRESS_COUNT];
8484 #endif // DEBUG
8485
8486 #define MAX_STRESS_WEIGHT 100
8487
8488     bool compStressCompile(compStressArea stressArea, unsigned weightPercentage);
8489
8490 #ifdef DEBUG
8491
8492     bool compInlineStress()
8493     {
8494         return compStressCompile(STRESS_LEGACY_INLINE, 50);
8495     }
8496
8497     bool compRandomInlineStress()
8498     {
8499         return compStressCompile(STRESS_RANDOM_INLINE, 50);
8500     }
8501
8502 #endif // DEBUG
8503
8504     bool compTailCallStress()
8505     {
8506 #ifdef DEBUG
8507         return (JitConfig.TailcallStress() != 0 || compStressCompile(STRESS_TAILCALL, 5));
8508 #else
8509         return false;
8510 #endif
8511     }
8512
8513     codeOptimize compCodeOpt()
8514     {
8515 #if 0
8516         // Switching between size & speed has measurable throughput impact
8517         // (3.5% on NGen mscorlib when measured). It used to be enabled for
8518         // DEBUG, but should generate identical code between CHK & RET builds,
8519         // so that's not acceptable.
8520         // TODO-Throughput: Figure out what to do about size vs. speed & throughput.
8521         //                  Investigate the cause of the throughput regression.
8522
8523         return opts.compCodeOpt;
8524 #else
8525         return BLENDED_CODE;
8526 #endif
8527     }
8528
8529     //--------------------- Info about the procedure --------------------------
8530
8531     struct Info
8532     {
8533         COMP_HANDLE           compCompHnd;
8534         CORINFO_MODULE_HANDLE compScopeHnd;
8535         CORINFO_CLASS_HANDLE  compClassHnd;
8536         CORINFO_METHOD_HANDLE compMethodHnd;
8537         CORINFO_METHOD_INFO*  compMethodInfo;
8538
8539         BOOL hasCircularClassConstraints;
8540         BOOL hasCircularMethodConstraints;
8541
8542 #if defined(DEBUG) || defined(LATE_DISASM)
8543         const char* compMethodName;
8544         const char* compClassName;
8545         const char* compFullName;
8546 #endif // defined(DEBUG) || defined(LATE_DISASM)
8547
8548 #if defined(DEBUG) || defined(INLINE_DATA)
8549         // Method hash is logcally const, but computed
8550         // on first demand.
8551         mutable unsigned compMethodHashPrivate;
8552         unsigned         compMethodHash() const;
8553 #endif // defined(DEBUG) || defined(INLINE_DATA)
8554
8555 #ifdef PSEUDORANDOM_NOP_INSERTION
8556         // things for pseudorandom nop insertion
8557         unsigned  compChecksum;
8558         CLRRandom compRNG;
8559 #endif
8560
8561         // The following holds the FLG_xxxx flags for the method we're compiling.
8562         unsigned compFlags;
8563
8564         // The following holds the class attributes for the method we're compiling.
8565         unsigned compClassAttr;
8566
8567         const BYTE*    compCode;
8568         IL_OFFSET      compILCodeSize;     // The IL code size
8569         IL_OFFSET      compILImportSize;   // Estimated amount of IL actually imported
8570         UNATIVE_OFFSET compNativeCodeSize; // The native code size, after instructions are issued. This
8571                                            // is less than (compTotalHotCodeSize + compTotalColdCodeSize) only if:
8572         // (1) the code is not hot/cold split, and we issued less code than we expected, or
8573         // (2) the code is hot/cold split, and we issued less code than we expected
8574         // in the cold section (the hot section will always be padded out to compTotalHotCodeSize).
8575
8576         bool compIsStatic : 1;         // Is the method static (no 'this' pointer)?
8577         bool compIsVarArgs : 1;        // Does the method have varargs parameters?
8578         bool compIsContextful : 1;     // contextful method
8579         bool compInitMem : 1;          // Is the CORINFO_OPT_INIT_LOCALS bit set in the method info options?
8580         bool compUnwrapContextful : 1; // JIT should unwrap proxies when possible
8581         bool compProfilerCallback : 1; // JIT inserted a profiler Enter callback
8582         bool compPublishStubParam : 1; // EAX captured in prolog will be available through an instrinsic
8583         bool compRetBuffDefStack : 1;  // The ret buff argument definitely points into the stack.
8584
8585         var_types compRetType;       // Return type of the method as declared in IL
8586         var_types compRetNativeType; // Normalized return type as per target arch ABI
8587         unsigned  compILargsCount;   // Number of arguments (incl. implicit but not hidden)
8588         unsigned  compArgsCount;     // Number of arguments (incl. implicit and     hidden)
8589
8590 #if FEATURE_FASTTAILCALL
8591         size_t compArgStackSize; // Incoming argument stack size in bytes
8592 #endif                           // FEATURE_FASTTAILCALL
8593
8594         unsigned compRetBuffArg; // position of hidden return param var (0, 1) (BAD_VAR_NUM means not present);
8595         int compTypeCtxtArg; // position of hidden param for type context for generic code (CORINFO_CALLCONV_PARAMTYPE)
8596         unsigned       compThisArg; // position of implicit this pointer param (not to be confused with lvaArg0Var)
8597         unsigned       compILlocalsCount; // Number of vars : args + locals (incl. implicit but not hidden)
8598         unsigned       compLocalsCount;   // Number of vars : args + locals (incl. implicit and     hidden)
8599         unsigned       compMaxStack;
8600         UNATIVE_OFFSET compTotalHotCodeSize;  // Total number of bytes of Hot Code in the method
8601         UNATIVE_OFFSET compTotalColdCodeSize; // Total number of bytes of Cold Code in the method
8602
8603         unsigned compCallUnmanaged;   // count of unmanaged calls
8604         unsigned compLvFrameListRoot; // lclNum for the Frame root
8605         unsigned compXcptnsCount;     // Number of exception-handling clauses read in the method's IL.
8606                                       // You should generally use compHndBBtabCount instead: it is the
8607                                       // current number of EH clauses (after additions like synchronized
8608                                       // methods and funclets, and removals like unreachable code deletion).
8609
8610         bool compMatchedVM; // true if the VM is "matched": either the JIT is a cross-compiler
8611                             // and the VM expects that, or the JIT is a "self-host" compiler
8612                             // (e.g., x86 hosted targeting x86) and the VM expects that.
8613
8614         /*  The following holds IL scope information about local variables.
8615          */
8616
8617         unsigned     compVarScopesCount;
8618         VarScopeDsc* compVarScopes;
8619
8620         /* The following holds information about instr offsets for
8621          * which we need to report IP-mappings
8622          */
8623
8624         IL_OFFSET*                   compStmtOffsets; // sorted
8625         unsigned                     compStmtOffsetsCount;
8626         ICorDebugInfo::BoundaryTypes compStmtOffsetsImplicit;
8627
8628 #define CPU_X86 0x0100 // The generic X86 CPU
8629 #define CPU_X86_PENTIUM_4 0x0110
8630
8631 #define CPU_X64 0x0200       // The generic x64 CPU
8632 #define CPU_AMD_X64 0x0210   // AMD x64 CPU
8633 #define CPU_INTEL_X64 0x0240 // Intel x64 CPU
8634
8635 #define CPU_ARM 0x0300   // The generic ARM CPU
8636 #define CPU_ARM64 0x0400 // The generic ARM64 CPU
8637
8638         unsigned genCPU; // What CPU are we running on
8639     } info;
8640
8641     // Returns true if the method being compiled returns a non-void and non-struct value.
8642     // Note that lvaInitTypeRef() normalizes compRetNativeType for struct returns in a
8643     // single register as per target arch ABI (e.g on Amd64 Windows structs of size 1, 2,
8644     // 4 or 8 gets normalized to TYP_BYTE/TYP_SHORT/TYP_INT/TYP_LONG; On Arm HFA structs).
8645     // Methods returning such structs are considered to return non-struct return value and
8646     // this method returns true in that case.
8647     bool compMethodReturnsNativeScalarType()
8648     {
8649         return (info.compRetType != TYP_VOID) && !varTypeIsStruct(info.compRetNativeType);
8650     }
8651
8652     // Returns true if the method being compiled returns RetBuf addr as its return value
8653     bool compMethodReturnsRetBufAddr()
8654     {
8655         // There are cases where implicit RetBuf argument should be explicitly returned in a register.
8656         // In such cases the return type is changed to TYP_BYREF and appropriate IR is generated.
8657         // These cases are:
8658         // 1. Profiler Leave calllback expects the address of retbuf as return value for
8659         //    methods with hidden RetBuf argument.  impReturnInstruction() when profiler
8660         //    callbacks are needed creates GT_RETURN(TYP_BYREF, op1 = Addr of RetBuf) for
8661         //    methods with hidden RetBufArg.
8662         //
8663         // 2. As per the System V ABI, the address of RetBuf needs to be returned by
8664         //    methods with hidden RetBufArg in RAX. In such case GT_RETURN is of TYP_BYREF,
8665         //    returning the address of RetBuf.
8666         //
8667         // 3. Windows 64-bit native calling convention also requires the address of RetBuff
8668         //    to be returned in RAX.
8669         CLANG_FORMAT_COMMENT_ANCHOR;
8670
8671 #ifdef _TARGET_AMD64_
8672         return (info.compRetBuffArg != BAD_VAR_NUM);
8673 #else  // !_TARGET_AMD64_
8674         return (compIsProfilerHookNeeded()) && (info.compRetBuffArg != BAD_VAR_NUM);
8675 #endif // !_TARGET_AMD64_
8676     }
8677
8678     // Returns true if the method returns a value in more than one return register
8679     // TODO-ARM-Bug: Deal with multi-register genReturnLocaled structs?
8680     // TODO-ARM64: Does this apply for ARM64 too?
8681     bool compMethodReturnsMultiRegRetType()
8682     {
8683 #if FEATURE_MULTIREG_RET
8684 #if defined(_TARGET_X86_)
8685         // On x86 only 64-bit longs are returned in multiple registers
8686         return varTypeIsLong(info.compRetNativeType);
8687 #else  // targets: X64-UNIX, ARM64 or ARM32
8688         // On all other targets that support multireg return values:
8689         // Methods returning a struct in multiple registers have a return value of TYP_STRUCT.
8690         // Such method's compRetNativeType is TYP_STRUCT without a hidden RetBufArg
8691         return varTypeIsStruct(info.compRetNativeType) && (info.compRetBuffArg == BAD_VAR_NUM);
8692 #endif // TARGET_XXX
8693
8694 #else // not FEATURE_MULTIREG_RET
8695
8696         // For this architecture there are no multireg returns
8697         return false;
8698
8699 #endif // FEATURE_MULTIREG_RET
8700     }
8701
8702 #if FEATURE_MULTIREG_ARGS
8703     // Given a GenTree node of TYP_STRUCT that represents a pass by value argument
8704     // return the gcPtr layout for the pointers sized fields
8705     void getStructGcPtrsFromOp(GenTree* op, BYTE* gcPtrsOut);
8706 #endif // FEATURE_MULTIREG_ARGS
8707
8708     // Returns true if the method being compiled returns a value
8709     bool compMethodHasRetVal()
8710     {
8711         return compMethodReturnsNativeScalarType() || compMethodReturnsRetBufAddr() ||
8712                compMethodReturnsMultiRegRetType();
8713     }
8714
8715 #if defined(DEBUG)
8716
8717     void compDispLocalVars();
8718
8719 #endif // DEBUG
8720
8721 //-------------------------- Global Compiler Data ------------------------------------
8722
8723 #ifdef DEBUG
8724     static unsigned s_compMethodsCount; // to produce unique label names
8725     unsigned        compGenTreeID;
8726     unsigned        compBasicBlockID;
8727 #endif
8728
8729     BasicBlock* compCurBB;   // the current basic block in process
8730     GenTree*    compCurStmt; // the current statement in process
8731 #ifdef DEBUG
8732     unsigned compCurStmtNum; // to give all statements an increasing StmtNum when printing dumps
8733 #endif
8734
8735     //  The following is used to create the 'method JIT info' block.
8736     size_t compInfoBlkSize;
8737     BYTE*  compInfoBlkAddr;
8738
8739     EHblkDsc* compHndBBtab;           // array of EH data
8740     unsigned  compHndBBtabCount;      // element count of used elements in EH data array
8741     unsigned  compHndBBtabAllocCount; // element count of allocated elements in EH data array
8742
8743 #if defined(_TARGET_X86_)
8744
8745     //-------------------------------------------------------------------------
8746     //  Tracking of region covered by the monitor in synchronized methods
8747     void* syncStartEmitCookie; // the emitter cookie for first instruction after the call to MON_ENTER
8748     void* syncEndEmitCookie;   // the emitter cookie for first instruction after the call to MON_EXIT
8749
8750 #endif // !_TARGET_X86_
8751
8752     Phases previousCompletedPhase; // the most recently completed phase
8753
8754     //-------------------------------------------------------------------------
8755     //  The following keeps track of how many bytes of local frame space we've
8756     //  grabbed so far in the current function, and how many argument bytes we
8757     //  need to pop when we return.
8758     //
8759
8760     unsigned compLclFrameSize; // secObject+lclBlk+locals+temps
8761
8762     // Count of callee-saved regs we pushed in the prolog.
8763     // Does not include EBP for isFramePointerUsed() and double-aligned frames.
8764     // In case of Amd64 this doesn't include float regs saved on stack.
8765     unsigned compCalleeRegsPushed;
8766
8767 #if defined(_TARGET_XARCH_)
8768     // Mask of callee saved float regs on stack.
8769     regMaskTP compCalleeFPRegsSavedMask;
8770 #endif
8771 #ifdef _TARGET_AMD64_
8772 // Quirk for VS debug-launch scenario to work:
8773 // Bytes of padding between save-reg area and locals.
8774 #define VSQUIRK_STACK_PAD (2 * REGSIZE_BYTES)
8775     unsigned compVSQuirkStackPaddingNeeded;
8776     bool     compQuirkForPPPflag;
8777 #endif
8778
8779     unsigned compArgSize; // total size of arguments in bytes (including register args (lvIsRegArg))
8780
8781     unsigned compMapILargNum(unsigned ILargNum); // map accounting for hidden args
8782     unsigned compMapILvarNum(unsigned ILvarNum); // map accounting for hidden args
8783     unsigned compMap2ILvarNum(unsigned varNum);  // map accounting for hidden args
8784
8785     //-------------------------------------------------------------------------
8786
8787     static void compStartup();  // One-time initialization
8788     static void compShutdown(); // One-time finalization
8789
8790     void compInit(ArenaAllocator* pAlloc, InlineInfo* inlineInfo);
8791     void compDone();
8792
8793     static void compDisplayStaticSizes(FILE* fout);
8794
8795     //------------ Some utility functions --------------
8796
8797     void* compGetHelperFtn(CorInfoHelpFunc ftnNum,         /* IN  */
8798                            void**          ppIndirection); /* OUT */
8799
8800     // Several JIT/EE interface functions return a CorInfoType, and also return a
8801     // class handle as an out parameter if the type is a value class.  Returns the
8802     // size of the type these describe.
8803     unsigned compGetTypeSize(CorInfoType cit, CORINFO_CLASS_HANDLE clsHnd);
8804
8805 #ifdef DEBUG
8806     // Components used by the compiler may write unit test suites, and
8807     // have them run within this method.  They will be run only once per process, and only
8808     // in debug.  (Perhaps should be under the control of a COMPlus_ flag.)
8809     // These should fail by asserting.
8810     void compDoComponentUnitTestsOnce();
8811 #endif // DEBUG
8812
8813     int compCompile(CORINFO_METHOD_HANDLE methodHnd,
8814                     CORINFO_MODULE_HANDLE classPtr,
8815                     COMP_HANDLE           compHnd,
8816                     CORINFO_METHOD_INFO*  methodInfo,
8817                     void**                methodCodePtr,
8818                     ULONG*                methodCodeSize,
8819                     JitFlags*             compileFlags);
8820     void compCompileFinish();
8821     int compCompileHelper(CORINFO_MODULE_HANDLE            classPtr,
8822                           COMP_HANDLE                      compHnd,
8823                           CORINFO_METHOD_INFO*             methodInfo,
8824                           void**                           methodCodePtr,
8825                           ULONG*                           methodCodeSize,
8826                           JitFlags*                        compileFlags,
8827                           CorInfoInstantiationVerification instVerInfo);
8828
8829     ArenaAllocator* compGetArenaAllocator();
8830
8831 #if MEASURE_MEM_ALLOC
8832     static bool s_dspMemStats; // Display per-phase memory statistics for every function
8833 #endif                         // MEASURE_MEM_ALLOC
8834
8835 #if LOOP_HOIST_STATS
8836     unsigned m_loopsConsidered;
8837     bool     m_curLoopHasHoistedExpression;
8838     unsigned m_loopsWithHoistedExpressions;
8839     unsigned m_totalHoistedExpressions;
8840
8841     void AddLoopHoistStats();
8842     void PrintPerMethodLoopHoistStats();
8843
8844     static CritSecObject s_loopHoistStatsLock; // This lock protects the data structures below.
8845     static unsigned      s_loopsConsidered;
8846     static unsigned      s_loopsWithHoistedExpressions;
8847     static unsigned      s_totalHoistedExpressions;
8848
8849     static void PrintAggregateLoopHoistStats(FILE* f);
8850 #endif // LOOP_HOIST_STATS
8851
8852     bool compIsForImportOnly();
8853     bool compIsForInlining();
8854     bool compDonotInline();
8855
8856 #ifdef DEBUG
8857     unsigned char compGetJitDefaultFill(); // Get the default fill char value
8858                                            // we randomize this value when JitStress is enabled
8859
8860     const char* compLocalVarName(unsigned varNum, unsigned offs);
8861     VarName compVarName(regNumber reg, bool isFloatReg = false);
8862     const char* compRegVarName(regNumber reg, bool displayVar = false, bool isFloatReg = false);
8863     const char* compRegNameForSize(regNumber reg, size_t size);
8864     const char* compFPregVarName(unsigned fpReg, bool displayVar = false);
8865     void compDspSrcLinesByNativeIP(UNATIVE_OFFSET curIP);
8866     void compDspSrcLinesByLineNum(unsigned line, bool seek = false);
8867 #endif // DEBUG
8868
8869     //-------------------------------------------------------------------------
8870
8871     struct VarScopeListNode
8872     {
8873         VarScopeDsc*             data;
8874         VarScopeListNode*        next;
8875         static VarScopeListNode* Create(VarScopeDsc* value, CompAllocator alloc)
8876         {
8877             VarScopeListNode* node = new (alloc) VarScopeListNode;
8878             node->data             = value;
8879             node->next             = nullptr;
8880             return node;
8881         }
8882     };
8883
8884     struct VarScopeMapInfo
8885     {
8886         VarScopeListNode*       head;
8887         VarScopeListNode*       tail;
8888         static VarScopeMapInfo* Create(VarScopeListNode* node, CompAllocator alloc)
8889         {
8890             VarScopeMapInfo* info = new (alloc) VarScopeMapInfo;
8891             info->head            = node;
8892             info->tail            = node;
8893             return info;
8894         }
8895     };
8896
8897     // Max value of scope count for which we would use linear search; for larger values we would use hashtable lookup.
8898     static const unsigned MAX_LINEAR_FIND_LCL_SCOPELIST = 32;
8899
8900     typedef JitHashTable<unsigned, JitSmallPrimitiveKeyFuncs<unsigned>, VarScopeMapInfo*> VarNumToScopeDscMap;
8901
8902     // Map to keep variables' scope indexed by varNum containing it's scope dscs at the index.
8903     VarNumToScopeDscMap* compVarScopeMap;
8904
8905     VarScopeDsc* compFindLocalVar(unsigned varNum, unsigned lifeBeg, unsigned lifeEnd);
8906
8907     VarScopeDsc* compFindLocalVar(unsigned varNum, unsigned offs);
8908
8909     VarScopeDsc* compFindLocalVarLinear(unsigned varNum, unsigned offs);
8910
8911     void compInitVarScopeMap();
8912
8913     VarScopeDsc** compEnterScopeList; // List has the offsets where variables
8914                                       // enter scope, sorted by instr offset
8915     unsigned compNextEnterScope;
8916
8917     VarScopeDsc** compExitScopeList; // List has the offsets where variables
8918                                      // go out of scope, sorted by instr offset
8919     unsigned compNextExitScope;
8920
8921     void compInitScopeLists();
8922
8923     void compResetScopeLists();
8924
8925     VarScopeDsc* compGetNextEnterScope(unsigned offs, bool scan = false);
8926
8927     VarScopeDsc* compGetNextExitScope(unsigned offs, bool scan = false);
8928
8929     void compProcessScopesUntil(unsigned   offset,
8930                                 VARSET_TP* inScope,
8931                                 void (Compiler::*enterScopeFn)(VARSET_TP* inScope, VarScopeDsc*),
8932                                 void (Compiler::*exitScopeFn)(VARSET_TP* inScope, VarScopeDsc*));
8933
8934 #ifdef DEBUG
8935     void compDispScopeLists();
8936 #endif // DEBUG
8937
8938     bool compIsProfilerHookNeeded();
8939
8940     //-------------------------------------------------------------------------
8941     /*               Statistical Data Gathering                               */
8942
8943     void compJitStats(); // call this function and enable
8944                          // various ifdef's below for statistical data
8945
8946 #if CALL_ARG_STATS
8947     void        compCallArgStats();
8948     static void compDispCallArgStats(FILE* fout);
8949 #endif
8950
8951     //-------------------------------------------------------------------------
8952
8953 protected:
8954 #ifdef DEBUG
8955     bool skipMethod();
8956 #endif
8957
8958     ArenaAllocator* compArenaAllocator;
8959
8960 public:
8961     void compFunctionTraceStart();
8962     void compFunctionTraceEnd(void* methodCodePtr, ULONG methodCodeSize, bool isNYI);
8963
8964 protected:
8965     size_t compMaxUncheckedOffsetForNullObject;
8966
8967     void compInitOptions(JitFlags* compileFlags);
8968
8969     void compSetProcessor();
8970     void compInitDebuggingInfo();
8971     void compSetOptimizationLevel();
8972 #ifdef _TARGET_ARMARCH_
8973     bool compRsvdRegCheck(FrameLayoutState curState);
8974 #endif
8975     void compCompile(void** methodCodePtr, ULONG* methodCodeSize, JitFlags* compileFlags);
8976
8977     // Clear annotations produced during optimizations; to be used between iterations when repeating opts.
8978     void ResetOptAnnotations();
8979
8980     // Regenerate loop descriptors; to be used between iterations when repeating opts.
8981     void RecomputeLoopInfo();
8982
8983 #ifdef PROFILING_SUPPORTED
8984     // Data required for generating profiler Enter/Leave/TailCall hooks
8985
8986     bool  compProfilerHookNeeded; // Whether profiler Enter/Leave/TailCall hook needs to be generated for the method
8987     void* compProfilerMethHnd;    // Profiler handle of the method being compiled. Passed as param to ELT callbacks
8988     bool  compProfilerMethHndIndirected; // Whether compProfilerHandle is pointer to the handle or is an actual handle
8989 #endif
8990
8991 #ifdef _TARGET_AMD64_
8992     bool compQuirkForPPP(); // Check if this method should be Quirked for the PPP issue
8993 #endif
8994 public:
8995     // Assumes called as part of process shutdown; does any compiler-specific work associated with that.
8996     static void ProcessShutdownWork(ICorStaticInfo* statInfo);
8997
8998     CompAllocator getAllocator(CompMemKind cmk = CMK_Generic)
8999     {
9000         return CompAllocator(compArenaAllocator, cmk);
9001     }
9002
9003     CompAllocator getAllocatorGC()
9004     {
9005         return getAllocator(CMK_GC);
9006     }
9007
9008     CompAllocator getAllocatorLoopHoist()
9009     {
9010         return getAllocator(CMK_LoopHoist);
9011     }
9012
9013 #ifdef DEBUG
9014     CompAllocator getAllocatorDebugOnly()
9015     {
9016         return getAllocator(CMK_DebugOnly);
9017     }
9018 #endif // DEBUG
9019
9020     /*
9021     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9022     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9023     XX                                                                           XX
9024     XX                           typeInfo                                        XX
9025     XX                                                                           XX
9026     XX   Checks for type compatibility and merges types                          XX
9027     XX                                                                           XX
9028     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9029     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9030     */
9031
9032 public:
9033     // Set to TRUE if verification cannot be skipped for this method
9034     // If we detect unverifiable code, we will lazily check
9035     // canSkipMethodVerification() to see if verification is REALLY needed.
9036     BOOL tiVerificationNeeded;
9037
9038     // It it initially TRUE, and it gets set to FALSE if we run into unverifiable code
9039     // Note that this is valid only if tiVerificationNeeded was ever TRUE.
9040     BOOL tiIsVerifiableCode;
9041
9042     // Set to TRUE if runtime callout is needed for this method
9043     BOOL tiRuntimeCalloutNeeded;
9044
9045     // Set to TRUE if security prolog/epilog callout is needed for this method
9046     // Note: This flag is different than compNeedSecurityCheck.
9047     //     compNeedSecurityCheck means whether or not a security object needs
9048     //         to be allocated on the stack, which is currently true for EnC as well.
9049     //     tiSecurityCalloutNeeded means whether or not security callouts need
9050     //         to be inserted in the jitted code.
9051     BOOL tiSecurityCalloutNeeded;
9052
9053     // Returns TRUE if child is equal to or a subtype of parent for merge purposes
9054     // This support is necessary to suport attributes that are not described in
9055     // for example, signatures. For example, the permanent home byref (byref that
9056     // points to the gc heap), isn't a property of method signatures, therefore,
9057     // it is safe to have mismatches here (that tiCompatibleWith will not flag),
9058     // but when deciding if we need to reimport a block, we need to take these
9059     // in account
9060     BOOL tiMergeCompatibleWith(const typeInfo& pChild, const typeInfo& pParent, bool normalisedForStack) const;
9061
9062     // Returns TRUE if child is equal to or a subtype of parent.
9063     // normalisedForStack indicates that both types are normalised for the stack
9064     BOOL tiCompatibleWith(const typeInfo& pChild, const typeInfo& pParent, bool normalisedForStack) const;
9065
9066     // Merges pDest and pSrc. Returns FALSE if merge is undefined.
9067     // *pDest is modified to represent the merged type.  Sets "*changed" to true
9068     // if this changes "*pDest".
9069     BOOL tiMergeToCommonParent(typeInfo* pDest, const typeInfo* pSrc, bool* changed) const;
9070
9071 #ifdef DEBUG
9072     // <BUGNUM> VSW 471305
9073     // IJW allows assigning REF to BYREF. The following allows us to temporarily
9074     // bypass the assert check in gcMarkRegSetGCref and gcMarkRegSetByref
9075     // We use a "short" as we need to push/pop this scope.
9076     // </BUGNUM>
9077     short compRegSetCheckLevel;
9078 #endif
9079
9080     /*
9081     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9082     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9083     XX                                                                           XX
9084     XX                           IL verification stuff                           XX
9085     XX                                                                           XX
9086     XX                                                                           XX
9087     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9088     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9089     */
9090
9091 public:
9092     // The following is used to track liveness of local variables, initialization
9093     // of valueclass constructors, and type safe use of IL instructions.
9094
9095     // dynamic state info needed for verification
9096     EntryState verCurrentState;
9097
9098     // this ptr of object type .ctors are considered intited only after
9099     // the base class ctor is called, or an alternate ctor is called.
9100     // An uninited this ptr can be used to access fields, but cannot
9101     // be used to call a member function.
9102     BOOL verTrackObjCtorInitState;
9103
9104     void verInitBBEntryState(BasicBlock* block, EntryState* currentState);
9105
9106     // Requires that "tis" is not TIS_Bottom -- it's a definite init/uninit state.
9107     void verSetThisInit(BasicBlock* block, ThisInitState tis);
9108     void verInitCurrentState();
9109     void verResetCurrentState(BasicBlock* block, EntryState* currentState);
9110
9111     // Merges the current verification state into the entry state of "block", return FALSE if that merge fails,
9112     // TRUE if it succeeds.  Further sets "*changed" to true if this changes the entry state of "block".
9113     BOOL verMergeEntryStates(BasicBlock* block, bool* changed);
9114
9115     void verConvertBBToThrowVerificationException(BasicBlock* block DEBUGARG(bool logMsg));
9116     void verHandleVerificationFailure(BasicBlock* block DEBUGARG(bool logMsg));
9117     typeInfo verMakeTypeInfo(CORINFO_CLASS_HANDLE clsHnd,
9118                              bool bashStructToRef = false); // converts from jit type representation to typeInfo
9119     typeInfo verMakeTypeInfo(CorInfoType          ciType,
9120                              CORINFO_CLASS_HANDLE clsHnd); // converts from jit type representation to typeInfo
9121     BOOL verIsSDArray(typeInfo ti);
9122     typeInfo verGetArrayElemType(typeInfo ti);
9123
9124     typeInfo verParseArgSigToTypeInfo(CORINFO_SIG_INFO* sig, CORINFO_ARG_LIST_HANDLE args);
9125     BOOL verNeedsVerification();
9126     BOOL verIsByRefLike(const typeInfo& ti);
9127     BOOL verIsSafeToReturnByRef(const typeInfo& ti);
9128
9129     // generic type variables range over types that satisfy IsBoxable
9130     BOOL verIsBoxable(const typeInfo& ti);
9131
9132     void DECLSPEC_NORETURN verRaiseVerifyException(INDEBUG(const char* reason) DEBUGARG(const char* file)
9133                                                        DEBUGARG(unsigned line));
9134     void verRaiseVerifyExceptionIfNeeded(INDEBUG(const char* reason) DEBUGARG(const char* file)
9135                                              DEBUGARG(unsigned line));
9136     bool verCheckTailCallConstraint(OPCODE                  opcode,
9137                                     CORINFO_RESOLVED_TOKEN* pResolvedToken,
9138                                     CORINFO_RESOLVED_TOKEN* pConstrainedResolvedToken, // Is this a "constrained." call
9139                                                                                        // on a type parameter?
9140                                     bool speculative // If true, won't throw if verificatoin fails. Instead it will
9141                                                      // return false to the caller.
9142                                                      // If false, it will throw.
9143                                     );
9144     bool verIsBoxedValueType(typeInfo ti);
9145
9146     void verVerifyCall(OPCODE                  opcode,
9147                        CORINFO_RESOLVED_TOKEN* pResolvedToken,
9148                        CORINFO_RESOLVED_TOKEN* pConstrainedResolvedToken,
9149                        bool                    tailCall,
9150                        bool                    readonlyCall, // is this a "readonly." call?
9151                        const BYTE*             delegateCreateStart,
9152                        const BYTE*             codeAddr,
9153                        CORINFO_CALL_INFO* callInfo DEBUGARG(const char* methodName));
9154
9155     BOOL verCheckDelegateCreation(const BYTE* delegateCreateStart, const BYTE* codeAddr, mdMemberRef& targetMemberRef);
9156
9157     typeInfo verVerifySTIND(const typeInfo& ptr, const typeInfo& value, const typeInfo& instrType);
9158     typeInfo verVerifyLDIND(const typeInfo& ptr, const typeInfo& instrType);
9159     void verVerifyField(CORINFO_RESOLVED_TOKEN*   pResolvedToken,
9160                         const CORINFO_FIELD_INFO& fieldInfo,
9161                         const typeInfo*           tiThis,
9162                         BOOL                      mutator,
9163                         BOOL                      allowPlainStructAsThis = FALSE);
9164     void verVerifyCond(const typeInfo& tiOp1, const typeInfo& tiOp2, unsigned opcode);
9165     void verVerifyThisPtrInitialised();
9166     BOOL verIsCallToInitThisPtr(CORINFO_CLASS_HANDLE context, CORINFO_CLASS_HANDLE target);
9167
9168 #ifdef DEBUG
9169
9170     // One line log function. Default level is 0. Increasing it gives you
9171     // more log information
9172
9173     // levels are currently unused: #define JITDUMP(level,...)                     ();
9174     void JitLogEE(unsigned level, const char* fmt, ...);
9175
9176     bool compDebugBreak;
9177
9178     bool compJitHaltMethod();
9179
9180 #endif
9181
9182     /*
9183     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9184     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9185     XX                                                                           XX
9186     XX                   GS Security checks for unsafe buffers                   XX
9187     XX                                                                           XX
9188     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9189     XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
9190     */
9191 public:
9192     struct ShadowParamVarInfo
9193     {
9194         FixedBitVect* assignGroup; // the closure set of variables whose values depend on each other
9195         unsigned      shadowCopy;  // Lcl var num, valid only if not set to NO_SHADOW_COPY
9196
9197         static bool mayNeedShadowCopy(LclVarDsc* varDsc)
9198         {
9199 #if defined(_TARGET_AMD64_)
9200             // GS cookie logic to create shadow slots, create trees to copy reg args to shadow
9201             // slots and update all trees to refer to shadow slots is done immediately after
9202             // fgMorph().  Lsra could potentially mark a param as DoNotEnregister after JIT determines
9203             // not to shadow a parameter.  Also, LSRA could potentially spill a param which is passed
9204             // in register. Therefore, conservatively all params may need a shadow copy.  Note that
9205             // GS cookie logic further checks whether the param is a ptr or an unsafe buffer before
9206             // creating a shadow slot even though this routine returns true.
9207             //
9208             // TODO-AMD64-CQ: Revisit this conservative approach as it could create more shadow slots than
9209             // required. There are two cases under which a reg arg could potentially be used from its
9210             // home location:
9211             //   a) LSRA marks it as DoNotEnregister (see LinearScan::identifyCandidates())
9212             //   b) LSRA spills it
9213             //
9214             // Possible solution to address case (a)
9215             //   - The conditions under which LSRA marks a varDsc as DoNotEnregister could be checked
9216             //     in this routine.  Note that live out of exception handler is something we may not be
9217             //     able to do it here since GS cookie logic is invoked ahead of liveness computation.
9218             //     Therefore, for methods with exception handling and need GS cookie check we might have
9219             //     to take conservative approach.
9220             //
9221             // Possible solution to address case (b)
9222             //   - Whenver a parameter passed in an argument register needs to be spilled by LSRA, we
9223             //     create a new spill temp if the method needs GS cookie check.
9224             return varDsc->lvIsParam;
9225 #else // !defined(_TARGET_AMD64_)
9226             return varDsc->lvIsParam && !varDsc->lvIsRegArg;
9227 #endif
9228         }
9229
9230 #ifdef DEBUG
9231         void Print()
9232         {
9233             printf("assignGroup [%p]; shadowCopy: [%d];\n", assignGroup, shadowCopy);
9234         }
9235 #endif
9236     };
9237
9238     GSCookie*           gsGlobalSecurityCookieAddr; // Address of global cookie for unsafe buffer checks
9239     GSCookie            gsGlobalSecurityCookieVal;  // Value of global cookie if addr is NULL
9240     ShadowParamVarInfo* gsShadowVarInfo;            // Table used by shadow param analysis code
9241
9242     void gsGSChecksInitCookie();   // Grabs cookie variable
9243     void gsCopyShadowParams();     // Identify vulnerable params and create dhadow copies
9244     bool gsFindVulnerableParams(); // Shadow param analysis code
9245     void gsParamsToShadows();      // Insert copy code and replave param uses by shadow
9246
9247     static fgWalkPreFn gsMarkPtrsAndAssignGroups; // Shadow param analysis tree-walk
9248     static fgWalkPreFn gsReplaceShadowParams;     // Shadow param replacement tree-walk
9249
9250 #define DEFAULT_MAX_INLINE_SIZE 100 // Methods with >  DEFAULT_MAX_INLINE_SIZE IL bytes will never be inlined.
9251                                     // This can be overwritten by setting complus_JITInlineSize env variable.
9252
9253 #define DEFAULT_MAX_INLINE_DEPTH 20 // Methods at more than this level deep will not be inlined
9254
9255 #define DEFAULT_MAX_LOCALLOC_TO_LOCAL_SIZE 32 // fixed locallocs of this size or smaller will convert to local buffers
9256
9257 private:
9258 #ifdef FEATURE_JIT_METHOD_PERF
9259     JitTimer*                  pCompJitTimer;         // Timer data structure (by phases) for current compilation.
9260     static CompTimeSummaryInfo s_compJitTimerSummary; // Summary of the Timer information for the whole run.
9261
9262     static LPCWSTR JitTimeLogCsv();        // Retrieve the file name for CSV from ConfigDWORD.
9263     static LPCWSTR compJitTimeLogFilename; // If a log file for JIT time is desired, filename to write it to.
9264 #endif
9265     inline void EndPhase(Phases phase); // Indicate the end of the given phase.
9266
9267 #if MEASURE_CLRAPI_CALLS
9268     // Thin wrappers that call into JitTimer (if present).
9269     inline void CLRApiCallEnter(unsigned apix);
9270     inline void CLRApiCallLeave(unsigned apix);
9271
9272 public:
9273     inline void CLR_API_Enter(API_ICorJitInfo_Names ename);
9274     inline void CLR_API_Leave(API_ICorJitInfo_Names ename);
9275
9276 private:
9277 #endif
9278
9279 #if defined(DEBUG) || defined(INLINE_DATA) || defined(FEATURE_CLRSQM)
9280     // These variables are associated with maintaining SQM data about compile time.
9281     unsigned __int64 m_compCyclesAtEndOfInlining; // The thread-virtualized cycle count at the end of the inlining phase
9282                                                   // in the current compilation.
9283     unsigned __int64 m_compCycles;                // Net cycle count for current compilation
9284     DWORD m_compTickCountAtEndOfInlining; // The result of GetTickCount() (# ms since some epoch marker) at the end of
9285                                           // the inlining phase in the current compilation.
9286 #endif                                    // defined(DEBUG) || defined(INLINE_DATA) || defined(FEATURE_CLRSQM)
9287
9288     // Records the SQM-relevant (cycles and tick count).  Should be called after inlining is complete.
9289     // (We do this after inlining because this marks the last point at which the JIT is likely to cause
9290     // type-loading and class initialization).
9291     void RecordStateAtEndOfInlining();
9292     // Assumes being called at the end of compilation.  Update the SQM state.
9293     void RecordStateAtEndOfCompilation();
9294
9295 #ifdef FEATURE_CLRSQM
9296     // Does anything SQM related necessary at process shutdown time.
9297     static void ProcessShutdownSQMWork(ICorStaticInfo* statInfo);
9298 #endif // FEATURE_CLRSQM
9299
9300 public:
9301 #if FUNC_INFO_LOGGING
9302     static LPCWSTR compJitFuncInfoFilename; // If a log file for per-function information is required, this is the
9303                                             // filename to write it to.
9304     static FILE* compJitFuncInfoFile;       // And this is the actual FILE* to write to.
9305 #endif                                      // FUNC_INFO_LOGGING
9306
9307     Compiler* prevCompiler; // Previous compiler on stack for TLS Compiler* linked list for reentrant compilers.
9308
9309     // Is the compilation in a full trust context?
9310     bool compIsFullTrust();
9311
9312 #if MEASURE_NOWAY
9313     void RecordNowayAssert(const char* filename, unsigned line, const char* condStr);
9314 #endif // MEASURE_NOWAY
9315
9316 #ifndef FEATURE_TRACELOGGING
9317     // Should we actually fire the noway assert body and the exception handler?
9318     bool compShouldThrowOnNoway();
9319 #else  // FEATURE_TRACELOGGING
9320     // Should we actually fire the noway assert body and the exception handler?
9321     bool compShouldThrowOnNoway(const char* filename, unsigned line);
9322
9323     // Telemetry instance to use per method compilation.
9324     JitTelemetry compJitTelemetry;
9325
9326     // Get common parameters that have to be logged with most telemetry data.
9327     void compGetTelemetryDefaults(const char** assemblyName,
9328                                   const char** scopeName,
9329                                   const char** methodName,
9330                                   unsigned*    methodHash);
9331 #endif // !FEATURE_TRACELOGGING
9332
9333 #ifdef DEBUG
9334 private:
9335     NodeToTestDataMap* m_nodeTestData;
9336
9337     static const unsigned FIRST_LOOP_HOIST_CSE_CLASS = 1000;
9338     unsigned              m_loopHoistCSEClass; // LoopHoist test annotations turn into CSE requirements; we
9339                                                // label them with CSE Class #'s starting at FIRST_LOOP_HOIST_CSE_CLASS.
9340                                                // Current kept in this.
9341 public:
9342     NodeToTestDataMap* GetNodeTestData()
9343     {
9344         Compiler* compRoot = impInlineRoot();
9345         if (compRoot->m_nodeTestData == nullptr)
9346         {
9347             compRoot->m_nodeTestData = new (getAllocatorDebugOnly()) NodeToTestDataMap(getAllocatorDebugOnly());
9348         }
9349         return compRoot->m_nodeTestData;
9350     }
9351
9352     typedef JitHashTable<GenTree*, JitPtrKeyFuncs<GenTree>, int> NodeToIntMap;
9353
9354     // Returns the set (i.e., the domain of the result map) of nodes that are keys in m_nodeTestData, and
9355     // currently occur in the AST graph.
9356     NodeToIntMap* FindReachableNodesInNodeTestData();
9357
9358     // Node "from" is being eliminated, and being replaced by node "to".  If "from" had any associated
9359     // test data, associate that data with "to".
9360     void TransferTestDataToNode(GenTree* from, GenTree* to);
9361
9362     // Requires that "to" is a clone of "from".  If any nodes in the "from" tree
9363     // have annotations, attach similar annotations to the corresponding nodes in "to".
9364     void CopyTestDataToCloneTree(GenTree* from, GenTree* to);
9365
9366     // These are the methods that test that the various conditions implied by the
9367     // test attributes are satisfied.
9368     void JitTestCheckSSA(); // SSA builder tests.
9369     void JitTestCheckVN();  // Value numbering tests.
9370 #endif                      // DEBUG
9371
9372     // The "FieldSeqStore", for canonicalizing field sequences.  See the definition of FieldSeqStore for
9373     // operations.
9374     FieldSeqStore* m_fieldSeqStore;
9375
9376     FieldSeqStore* GetFieldSeqStore()
9377     {
9378         Compiler* compRoot = impInlineRoot();
9379         if (compRoot->m_fieldSeqStore == nullptr)
9380         {
9381             // Create a CompAllocator that labels sub-structure with CMK_FieldSeqStore, and use that for allocation.
9382             CompAllocator ialloc(getAllocator(CMK_FieldSeqStore));
9383             compRoot->m_fieldSeqStore = new (ialloc) FieldSeqStore(ialloc);
9384         }
9385         return compRoot->m_fieldSeqStore;
9386     }
9387
9388     typedef JitHashTable<GenTree*, JitPtrKeyFuncs<GenTree>, FieldSeqNode*> NodeToFieldSeqMap;
9389
9390     // Some nodes of "TYP_BYREF" or "TYP_I_IMPL" actually represent the address of a field within a struct, but since
9391     // the offset of the field is zero, there's no "GT_ADD" node.  We normally attach a field sequence to the constant
9392     // that is added, but what do we do when that constant is zero, and is thus not present?  We use this mechanism to
9393     // attach the field sequence directly to the address node.
9394     NodeToFieldSeqMap* m_zeroOffsetFieldMap;
9395
9396     NodeToFieldSeqMap* GetZeroOffsetFieldMap()
9397     {
9398         // Don't need to worry about inlining here
9399         if (m_zeroOffsetFieldMap == nullptr)
9400         {
9401             // Create a CompAllocator that labels sub-structure with CMK_ZeroOffsetFieldMap, and use that for
9402             // allocation.
9403             CompAllocator ialloc(getAllocator(CMK_ZeroOffsetFieldMap));
9404             m_zeroOffsetFieldMap = new (ialloc) NodeToFieldSeqMap(ialloc);
9405         }
9406         return m_zeroOffsetFieldMap;
9407     }
9408
9409     // Requires that "op1" is a node of type "TYP_BYREF" or "TYP_I_IMPL".  We are dereferencing this with the fields in
9410     // "fieldSeq", whose offsets are required all to be zero.  Ensures that any field sequence annotation currently on
9411     // "op1" or its components is augmented by appending "fieldSeq".  In practice, if "op1" is a GT_LCL_FLD, it has
9412     // a field sequence as a member; otherwise, it may be the addition of an a byref and a constant, where the const
9413     // has a field sequence -- in this case "fieldSeq" is appended to that of the constant; otherwise, we
9414     // record the the field sequence using the ZeroOffsetFieldMap described above.
9415     //
9416     // One exception above is that "op1" is a node of type "TYP_REF" where "op1" is a GT_LCL_VAR.
9417     // This happens when System.Object vtable pointer is a regular field at offset 0 in System.Private.CoreLib in
9418     // CoreRT. Such case is handled same as the default case.
9419     void fgAddFieldSeqForZeroOffset(GenTree* op1, FieldSeqNode* fieldSeq);
9420
9421     typedef JitHashTable<const GenTree*, JitPtrKeyFuncs<GenTree>, ArrayInfo> NodeToArrayInfoMap;
9422     NodeToArrayInfoMap* m_arrayInfoMap;
9423
9424     NodeToArrayInfoMap* GetArrayInfoMap()
9425     {
9426         Compiler* compRoot = impInlineRoot();
9427         if (compRoot->m_arrayInfoMap == nullptr)
9428         {
9429             // Create a CompAllocator that labels sub-structure with CMK_ArrayInfoMap, and use that for allocation.
9430             CompAllocator ialloc(getAllocator(CMK_ArrayInfoMap));
9431             compRoot->m_arrayInfoMap = new (ialloc) NodeToArrayInfoMap(ialloc);
9432         }
9433         return compRoot->m_arrayInfoMap;
9434     }
9435
9436     //-----------------------------------------------------------------------------------------------------------------
9437     // Compiler::TryGetArrayInfo:
9438     //    Given an indirection node, checks to see whether or not that indirection represents an array access, and
9439     //    if so returns information about the array.
9440     //
9441     // Arguments:
9442     //    indir           - The `GT_IND` node.
9443     //    arrayInfo (out) - Information about the accessed array if this function returns true. Undefined otherwise.
9444     //
9445     // Returns:
9446     //    True if the `GT_IND` node represents an array access; false otherwise.
9447     bool TryGetArrayInfo(GenTreeIndir* indir, ArrayInfo* arrayInfo)
9448     {
9449         if ((indir->gtFlags & GTF_IND_ARR_INDEX) == 0)
9450         {
9451             return false;
9452         }
9453
9454         if (indir->gtOp1->OperIs(GT_INDEX_ADDR))
9455         {
9456             GenTreeIndexAddr* const indexAddr = indir->gtOp1->AsIndexAddr();
9457             *arrayInfo = ArrayInfo(indexAddr->gtElemType, indexAddr->gtElemSize, indexAddr->gtElemOffset,
9458                                    indexAddr->gtStructElemClass);
9459             return true;
9460         }
9461
9462         bool found = GetArrayInfoMap()->Lookup(indir, arrayInfo);
9463         assert(found);
9464         return true;
9465     }
9466
9467     NodeToUnsignedMap* m_memorySsaMap[MemoryKindCount];
9468
9469     // In some cases, we want to assign intermediate SSA #'s to memory states, and know what nodes create those memory
9470     // states. (We do this for try blocks, where, if the try block doesn't do a call that loses track of the memory
9471     // state, all the possible memory states are possible initial states of the corresponding catch block(s).)
9472     NodeToUnsignedMap* GetMemorySsaMap(MemoryKind memoryKind)
9473     {
9474         if (memoryKind == GcHeap && byrefStatesMatchGcHeapStates)
9475         {
9476             // Use the same map for GCHeap and ByrefExposed when their states match.
9477             memoryKind = ByrefExposed;
9478         }
9479
9480         assert(memoryKind < MemoryKindCount);
9481         Compiler* compRoot = impInlineRoot();
9482         if (compRoot->m_memorySsaMap[memoryKind] == nullptr)
9483         {
9484             // Create a CompAllocator that labels sub-structure with CMK_ArrayInfoMap, and use that for allocation.
9485             CompAllocator ialloc(getAllocator(CMK_ArrayInfoMap));
9486             compRoot->m_memorySsaMap[memoryKind] = new (ialloc) NodeToUnsignedMap(ialloc);
9487         }
9488         return compRoot->m_memorySsaMap[memoryKind];
9489     }
9490
9491     // The Refany type is the only struct type whose structure is implicitly assumed by IL.  We need its fields.
9492     CORINFO_CLASS_HANDLE m_refAnyClass;
9493     CORINFO_FIELD_HANDLE GetRefanyDataField()
9494     {
9495         if (m_refAnyClass == nullptr)
9496         {
9497             m_refAnyClass = info.compCompHnd->getBuiltinClass(CLASSID_TYPED_BYREF);
9498         }
9499         return info.compCompHnd->getFieldInClass(m_refAnyClass, 0);
9500     }
9501     CORINFO_FIELD_HANDLE GetRefanyTypeField()
9502     {
9503         if (m_refAnyClass == nullptr)
9504         {
9505             m_refAnyClass = info.compCompHnd->getBuiltinClass(CLASSID_TYPED_BYREF);
9506         }
9507         return info.compCompHnd->getFieldInClass(m_refAnyClass, 1);
9508     }
9509
9510 #if VARSET_COUNTOPS
9511     static BitSetSupport::BitSetOpCounter m_varsetOpCounter;
9512 #endif
9513 #if ALLVARSET_COUNTOPS
9514     static BitSetSupport::BitSetOpCounter m_allvarsetOpCounter;
9515 #endif
9516
9517     static HelperCallProperties s_helperCallProperties;
9518
9519 #ifdef UNIX_AMD64_ABI
9520     static var_types GetTypeFromClassificationAndSizes(SystemVClassificationType classType, int size);
9521     static var_types GetEightByteType(const SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR& structDesc,
9522                                       unsigned                                                   slotNum);
9523
9524     static void GetStructTypeOffset(const SYSTEMV_AMD64_CORINFO_STRUCT_REG_PASSING_DESCRIPTOR& structDesc,
9525                                     var_types*                                                 type0,
9526                                     var_types*                                                 type1,
9527                                     unsigned __int8*                                           offset0,
9528                                     unsigned __int8*                                           offset1);
9529
9530     void GetStructTypeOffset(CORINFO_CLASS_HANDLE typeHnd,
9531                              var_types*           type0,
9532                              var_types*           type1,
9533                              unsigned __int8*     offset0,
9534                              unsigned __int8*     offset1);
9535
9536 #endif // defined(UNIX_AMD64_ABI)
9537
9538     void fgMorphMultiregStructArgs(GenTreeCall* call);
9539     GenTree* fgMorphMultiregStructArg(GenTree* arg, fgArgTabEntry* fgEntryPtr);
9540
9541     bool killGCRefs(GenTree* tree);
9542
9543 }; // end of class Compiler
9544
9545 //---------------------------------------------------------------------------------------------------------------------
9546 // GenTreeVisitor: a flexible tree walker implemented using the curiosly-recurring-template pattern.
9547 //
9548 // This class implements a configurable walker for IR trees. There are five configuration options (defaults values are
9549 // shown in parentheses):
9550 //
9551 // - ComputeStack (false): when true, the walker will push each node onto the `m_ancestors` stack. "Ancestors" is a bit
9552 //                         of a misnomer, as the first entry will always be the current node.
9553 //
9554 // - DoPreOrder (false): when true, the walker will invoke `TVisitor::PreOrderVisit` with the current node as an
9555 //                       argument before visiting the node's operands.
9556 //
9557 // - DoPostOrder (false): when true, the walker will invoke `TVisitor::PostOrderVisit` with the current node as an
9558 //                        argument after visiting the node's operands.
9559 //
9560 // - DoLclVarsOnly (false): when true, the walker will only invoke `TVisitor::PreOrderVisit` for lclVar nodes.
9561 //                          `DoPreOrder` must be true if this option is true.
9562 //
9563 // - UseExecutionOrder (false): when true, then walker will visit a node's operands in execution order (e.g. if a
9564 //                              binary operator has the `GTF_REVERSE_OPS` flag set, the second operand will be
9565 //                              visited before the first).
9566 //
9567 // At least one of `DoPreOrder` and `DoPostOrder` must be specified.
9568 //
9569 // A simple pre-order visitor might look something like the following:
9570 //
9571 //     class CountingVisitor final : public GenTreeVisitor<CountingVisitor>
9572 //     {
9573 //     public:
9574 //         enum
9575 //         {
9576 //             DoPreOrder = true
9577 //         };
9578 //
9579 //         unsigned m_count;
9580 //
9581 //         CountingVisitor(Compiler* compiler)
9582 //             : GenTreeVisitor<CountingVisitor>(compiler), m_count(0)
9583 //         {
9584 //         }
9585 //
9586 //         Compiler::fgWalkResult PreOrderVisit(GenTree* node)
9587 //         {
9588 //             m_count++;
9589 //         }
9590 //     };
9591 //
9592 // This visitor would then be used like so:
9593 //
9594 //     CountingVisitor countingVisitor(compiler);
9595 //     countingVisitor.WalkTree(root);
9596 //
9597 template <typename TVisitor>
9598 class GenTreeVisitor
9599 {
9600 protected:
9601     typedef Compiler::fgWalkResult fgWalkResult;
9602
9603     enum
9604     {
9605         ComputeStack      = false,
9606         DoPreOrder        = false,
9607         DoPostOrder       = false,
9608         DoLclVarsOnly     = false,
9609         UseExecutionOrder = false,
9610     };
9611
9612     Compiler*            m_compiler;
9613     ArrayStack<GenTree*> m_ancestors;
9614
9615     GenTreeVisitor(Compiler* compiler) : m_compiler(compiler), m_ancestors(compiler->getAllocator(CMK_ArrayStack))
9616     {
9617         assert(compiler != nullptr);
9618
9619         static_assert_no_msg(TVisitor::DoPreOrder || TVisitor::DoPostOrder);
9620         static_assert_no_msg(!TVisitor::DoLclVarsOnly || TVisitor::DoPreOrder);
9621     }
9622
9623     fgWalkResult PreOrderVisit(GenTree** use, GenTree* user)
9624     {
9625         return fgWalkResult::WALK_CONTINUE;
9626     }
9627
9628     fgWalkResult PostOrderVisit(GenTree** use, GenTree* user)
9629     {
9630         return fgWalkResult::WALK_CONTINUE;
9631     }
9632
9633 public:
9634     fgWalkResult WalkTree(GenTree** use, GenTree* user)
9635     {
9636         assert(use != nullptr);
9637
9638         GenTree* node = *use;
9639
9640         if (TVisitor::ComputeStack)
9641         {
9642             m_ancestors.Push(node);
9643         }
9644
9645         fgWalkResult result = fgWalkResult::WALK_CONTINUE;
9646         if (TVisitor::DoPreOrder && !TVisitor::DoLclVarsOnly)
9647         {
9648             result = reinterpret_cast<TVisitor*>(this)->PreOrderVisit(use, user);
9649             if (result == fgWalkResult::WALK_ABORT)
9650             {
9651                 return result;
9652             }
9653
9654             node = *use;
9655             if ((node == nullptr) || (result == fgWalkResult::WALK_SKIP_SUBTREES))
9656             {
9657                 goto DONE;
9658             }
9659         }
9660
9661         switch (node->OperGet())
9662         {
9663             // Leaf lclVars
9664             case GT_LCL_VAR:
9665             case GT_LCL_FLD:
9666             case GT_LCL_VAR_ADDR:
9667             case GT_LCL_FLD_ADDR:
9668                 if (TVisitor::DoLclVarsOnly)
9669                 {
9670                     result = reinterpret_cast<TVisitor*>(this)->PreOrderVisit(use, user);
9671                     if (result == fgWalkResult::WALK_ABORT)
9672                     {
9673                         return result;
9674                     }
9675                 }
9676                 __fallthrough;
9677
9678             // Leaf nodes
9679             case GT_CATCH_ARG:
9680             case GT_LABEL:
9681             case GT_FTN_ADDR:
9682             case GT_RET_EXPR:
9683             case GT_CNS_INT:
9684             case GT_CNS_LNG:
9685             case GT_CNS_DBL:
9686             case GT_CNS_STR:
9687             case GT_MEMORYBARRIER:
9688             case GT_JMP:
9689             case GT_JCC:
9690             case GT_SETCC:
9691             case GT_NO_OP:
9692             case GT_START_NONGC:
9693             case GT_START_PREEMPTGC:
9694             case GT_PROF_HOOK:
9695 #if !FEATURE_EH_FUNCLETS
9696             case GT_END_LFIN:
9697 #endif // !FEATURE_EH_FUNCLETS
9698             case GT_PHI_ARG:
9699             case GT_JMPTABLE:
9700             case GT_CLS_VAR:
9701             case GT_CLS_VAR_ADDR:
9702             case GT_ARGPLACE:
9703             case GT_PHYSREG:
9704             case GT_EMITNOP:
9705             case GT_PINVOKE_PROLOG:
9706             case GT_PINVOKE_EPILOG:
9707             case GT_IL_OFFSET:
9708                 break;
9709
9710             // Lclvar unary operators
9711             case GT_STORE_LCL_VAR:
9712             case GT_STORE_LCL_FLD:
9713                 if (TVisitor::DoLclVarsOnly)
9714                 {
9715                     result = reinterpret_cast<TVisitor*>(this)->PreOrderVisit(use, user);
9716                     if (result == fgWalkResult::WALK_ABORT)
9717                     {
9718                         return result;
9719                     }
9720                 }
9721                 __fallthrough;
9722
9723             // Standard unary operators
9724             case GT_NOT:
9725             case GT_NEG:
9726             case GT_BSWAP:
9727             case GT_BSWAP16:
9728             case GT_COPY:
9729             case GT_RELOAD:
9730             case GT_ARR_LENGTH:
9731             case GT_CAST:
9732             case GT_BITCAST:
9733             case GT_CKFINITE:
9734             case GT_LCLHEAP:
9735             case GT_ADDR:
9736             case GT_IND:
9737             case GT_OBJ:
9738             case GT_BLK:
9739             case GT_BOX:
9740             case GT_ALLOCOBJ:
9741             case GT_INIT_VAL:
9742             case GT_JTRUE:
9743             case GT_SWITCH:
9744             case GT_NULLCHECK:
9745             case GT_PUTARG_REG:
9746             case GT_PUTARG_STK:
9747             case GT_RETURNTRAP:
9748             case GT_NOP:
9749             case GT_RETURN:
9750             case GT_RETFILT:
9751             case GT_PHI:
9752             case GT_RUNTIMELOOKUP:
9753             {
9754                 GenTreeUnOp* const unOp = node->AsUnOp();
9755                 if (unOp->gtOp1 != nullptr)
9756                 {
9757                     result = WalkTree(&unOp->gtOp1, unOp);
9758                     if (result == fgWalkResult::WALK_ABORT)
9759                     {
9760                         return result;
9761                     }
9762                 }
9763                 break;
9764             }
9765
9766             // Special nodes
9767             case GT_CMPXCHG:
9768             {
9769                 GenTreeCmpXchg* const cmpXchg = node->AsCmpXchg();
9770
9771                 result = WalkTree(&cmpXchg->gtOpLocation, cmpXchg);
9772                 if (result == fgWalkResult::WALK_ABORT)
9773                 {
9774                     return result;
9775                 }
9776                 result = WalkTree(&cmpXchg->gtOpValue, cmpXchg);
9777                 if (result == fgWalkResult::WALK_ABORT)
9778                 {
9779                     return result;
9780                 }
9781                 result = WalkTree(&cmpXchg->gtOpComparand, cmpXchg);
9782                 if (result == fgWalkResult::WALK_ABORT)
9783                 {
9784                     return result;
9785                 }
9786                 break;
9787             }
9788
9789             case GT_ARR_BOUNDS_CHECK:
9790 #ifdef FEATURE_SIMD
9791             case GT_SIMD_CHK:
9792 #endif // FEATURE_SIMD
9793 #ifdef FEATURE_HW_INTRINSICS
9794             case GT_HW_INTRINSIC_CHK:
9795 #endif // FEATURE_HW_INTRINSICS
9796             {
9797                 GenTreeBoundsChk* const boundsChk = node->AsBoundsChk();
9798
9799                 result = WalkTree(&boundsChk->gtIndex, boundsChk);
9800                 if (result == fgWalkResult::WALK_ABORT)
9801                 {
9802                     return result;
9803                 }
9804                 result = WalkTree(&boundsChk->gtArrLen, boundsChk);
9805                 if (result == fgWalkResult::WALK_ABORT)
9806                 {
9807                     return result;
9808                 }
9809                 break;
9810             }
9811
9812             case GT_FIELD:
9813             {
9814                 GenTreeField* const field = node->AsField();
9815
9816                 if (field->gtFldObj != nullptr)
9817                 {
9818                     result = WalkTree(&field->gtFldObj, field);
9819                     if (result == fgWalkResult::WALK_ABORT)
9820                     {
9821                         return result;
9822                     }
9823                 }
9824                 break;
9825             }
9826
9827             case GT_ARR_ELEM:
9828             {
9829                 GenTreeArrElem* const arrElem = node->AsArrElem();
9830
9831                 result = WalkTree(&arrElem->gtArrObj, arrElem);
9832                 if (result == fgWalkResult::WALK_ABORT)
9833                 {
9834                     return result;
9835                 }
9836
9837                 const unsigned rank = arrElem->gtArrRank;
9838                 for (unsigned dim = 0; dim < rank; dim++)
9839                 {
9840                     result = WalkTree(&arrElem->gtArrInds[dim], arrElem);
9841                     if (result == fgWalkResult::WALK_ABORT)
9842                     {
9843                         return result;
9844                     }
9845                 }
9846                 break;
9847             }
9848
9849             case GT_ARR_OFFSET:
9850             {
9851                 GenTreeArrOffs* const arrOffs = node->AsArrOffs();
9852
9853                 result = WalkTree(&arrOffs->gtOffset, arrOffs);
9854                 if (result == fgWalkResult::WALK_ABORT)
9855                 {
9856                     return result;
9857                 }
9858                 result = WalkTree(&arrOffs->gtIndex, arrOffs);
9859                 if (result == fgWalkResult::WALK_ABORT)
9860                 {
9861                     return result;
9862                 }
9863                 result = WalkTree(&arrOffs->gtArrObj, arrOffs);
9864                 if (result == fgWalkResult::WALK_ABORT)
9865                 {
9866                     return result;
9867                 }
9868                 break;
9869             }
9870
9871             case GT_DYN_BLK:
9872             {
9873                 GenTreeDynBlk* const dynBlock = node->AsDynBlk();
9874
9875                 GenTree** op1Use = &dynBlock->gtOp1;
9876                 GenTree** op2Use = &dynBlock->gtDynamicSize;
9877
9878                 if (TVisitor::UseExecutionOrder && dynBlock->gtEvalSizeFirst)
9879                 {
9880                     std::swap(op1Use, op2Use);
9881                 }
9882
9883                 result = WalkTree(op1Use, dynBlock);
9884                 if (result == fgWalkResult::WALK_ABORT)
9885                 {
9886                     return result;
9887                 }
9888                 result = WalkTree(op2Use, dynBlock);
9889                 if (result == fgWalkResult::WALK_ABORT)
9890                 {
9891                     return result;
9892                 }
9893                 break;
9894             }
9895
9896             case GT_STORE_DYN_BLK:
9897             {
9898                 GenTreeDynBlk* const dynBlock = node->AsDynBlk();
9899
9900                 GenTree** op1Use = &dynBlock->gtOp1;
9901                 GenTree** op2Use = &dynBlock->gtOp2;
9902                 GenTree** op3Use = &dynBlock->gtDynamicSize;
9903
9904                 if (TVisitor::UseExecutionOrder)
9905                 {
9906                     if (dynBlock->IsReverseOp())
9907                     {
9908                         std::swap(op1Use, op2Use);
9909                     }
9910                     if (dynBlock->gtEvalSizeFirst)
9911                     {
9912                         std::swap(op3Use, op2Use);
9913                         std::swap(op2Use, op1Use);
9914                     }
9915                 }
9916
9917                 result = WalkTree(op1Use, dynBlock);
9918                 if (result == fgWalkResult::WALK_ABORT)
9919                 {
9920                     return result;
9921                 }
9922                 result = WalkTree(op2Use, dynBlock);
9923                 if (result == fgWalkResult::WALK_ABORT)
9924                 {
9925                     return result;
9926                 }
9927                 result = WalkTree(op3Use, dynBlock);
9928                 if (result == fgWalkResult::WALK_ABORT)
9929                 {
9930                     return result;
9931                 }
9932                 break;
9933             }
9934
9935             case GT_CALL:
9936             {
9937                 GenTreeCall* const call = node->AsCall();
9938
9939                 if (call->gtCallObjp != nullptr)
9940                 {
9941                     result = WalkTree(&call->gtCallObjp, call);
9942                     if (result == fgWalkResult::WALK_ABORT)
9943                     {
9944                         return result;
9945                     }
9946                 }
9947
9948                 for (GenTreeArgList* args = call->gtCallArgs; args != nullptr; args = args->Rest())
9949                 {
9950                     result = WalkTree(args->pCurrent(), call);
9951                     if (result == fgWalkResult::WALK_ABORT)
9952                     {
9953                         return result;
9954                     }
9955                 }
9956
9957                 for (GenTreeArgList* args = call->gtCallLateArgs; args != nullptr; args = args->Rest())
9958                 {
9959                     result = WalkTree(args->pCurrent(), call);
9960                     if (result == fgWalkResult::WALK_ABORT)
9961                     {
9962                         return result;
9963                     }
9964                 }
9965
9966                 if (call->gtCallType == CT_INDIRECT)
9967                 {
9968                     if (call->gtCallCookie != nullptr)
9969                     {
9970                         result = WalkTree(&call->gtCallCookie, call);
9971                         if (result == fgWalkResult::WALK_ABORT)
9972                         {
9973                             return result;
9974                         }
9975                     }
9976
9977                     result = WalkTree(&call->gtCallAddr, call);
9978                     if (result == fgWalkResult::WALK_ABORT)
9979                     {
9980                         return result;
9981                     }
9982                 }
9983
9984                 if (call->gtControlExpr != nullptr)
9985                 {
9986                     result = WalkTree(&call->gtControlExpr, call);
9987                     if (result == fgWalkResult::WALK_ABORT)
9988                     {
9989                         return result;
9990                     }
9991                 }
9992
9993                 break;
9994             }
9995
9996             // Binary nodes
9997             default:
9998             {
9999                 assert(node->OperIsBinary());
10000
10001                 GenTreeOp* const op = node->AsOp();
10002
10003                 GenTree** op1Use = &op->gtOp1;
10004                 GenTree** op2Use = &op->gtOp2;
10005
10006                 if (TVisitor::UseExecutionOrder && node->IsReverseOp())
10007                 {
10008                     std::swap(op1Use, op2Use);
10009                 }
10010
10011                 if (*op1Use != nullptr)
10012                 {
10013                     result = WalkTree(op1Use, op);
10014                     if (result == fgWalkResult::WALK_ABORT)
10015                     {
10016                         return result;
10017                     }
10018                 }
10019
10020                 if (*op2Use != nullptr)
10021                 {
10022                     result = WalkTree(op2Use, op);
10023                     if (result == fgWalkResult::WALK_ABORT)
10024                     {
10025                         return result;
10026                     }
10027                 }
10028                 break;
10029             }
10030         }
10031
10032     DONE:
10033         // Finally, visit the current node
10034         if (TVisitor::DoPostOrder)
10035         {
10036             result = reinterpret_cast<TVisitor*>(this)->PostOrderVisit(use, user);
10037         }
10038
10039         if (TVisitor::ComputeStack)
10040         {
10041             m_ancestors.Pop();
10042         }
10043
10044         return result;
10045     }
10046 };
10047
10048 template <bool computeStack, bool doPreOrder, bool doPostOrder, bool doLclVarsOnly, bool useExecutionOrder>
10049 class GenericTreeWalker final
10050     : public GenTreeVisitor<GenericTreeWalker<computeStack, doPreOrder, doPostOrder, doLclVarsOnly, useExecutionOrder>>
10051 {
10052 public:
10053     enum
10054     {
10055         ComputeStack      = computeStack,
10056         DoPreOrder        = doPreOrder,
10057         DoPostOrder       = doPostOrder,
10058         DoLclVarsOnly     = doLclVarsOnly,
10059         UseExecutionOrder = useExecutionOrder,
10060     };
10061
10062 private:
10063     Compiler::fgWalkData* m_walkData;
10064
10065 public:
10066     GenericTreeWalker(Compiler::fgWalkData* walkData)
10067         : GenTreeVisitor<GenericTreeWalker<computeStack, doPreOrder, doPostOrder, doLclVarsOnly, useExecutionOrder>>(
10068               walkData->compiler)
10069         , m_walkData(walkData)
10070     {
10071         assert(walkData != nullptr);
10072
10073         if (computeStack)
10074         {
10075             walkData->parentStack = &this->m_ancestors;
10076         }
10077     }
10078
10079     Compiler::fgWalkResult PreOrderVisit(GenTree** use, GenTree* user)
10080     {
10081         m_walkData->parent = user;
10082         return m_walkData->wtprVisitorFn(use, m_walkData);
10083     }
10084
10085     Compiler::fgWalkResult PostOrderVisit(GenTree** use, GenTree* user)
10086     {
10087         m_walkData->parent = user;
10088         return m_walkData->wtpoVisitorFn(use, m_walkData);
10089     }
10090 };
10091
10092 /*
10093 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
10094 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
10095 XX                                                                           XX
10096 XX                   Miscellaneous Compiler stuff                            XX
10097 XX                                                                           XX
10098 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
10099 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
10100 */
10101
10102 // Values used to mark the types a stack slot is used for
10103
10104 const unsigned TYPE_REF_INT      = 0x01; // slot used as a 32-bit int
10105 const unsigned TYPE_REF_LNG      = 0x02; // slot used as a 64-bit long
10106 const unsigned TYPE_REF_FLT      = 0x04; // slot used as a 32-bit float
10107 const unsigned TYPE_REF_DBL      = 0x08; // slot used as a 64-bit float
10108 const unsigned TYPE_REF_PTR      = 0x10; // slot used as a 32-bit pointer
10109 const unsigned TYPE_REF_BYR      = 0x20; // slot used as a byref pointer
10110 const unsigned TYPE_REF_STC      = 0x40; // slot used as a struct
10111 const unsigned TYPE_REF_TYPEMASK = 0x7F; // bits that represent the type
10112
10113 // const unsigned TYPE_REF_ADDR_TAKEN  = 0x80; // slots address was taken
10114
10115 /*****************************************************************************
10116  *
10117  *  Variables to keep track of total code amounts.
10118  */
10119
10120 #if DISPLAY_SIZES
10121
10122 extern size_t grossVMsize;
10123 extern size_t grossNCsize;
10124 extern size_t totalNCsize;
10125
10126 extern unsigned genMethodICnt;
10127 extern unsigned genMethodNCnt;
10128 extern size_t   gcHeaderISize;
10129 extern size_t   gcPtrMapISize;
10130 extern size_t   gcHeaderNSize;
10131 extern size_t   gcPtrMapNSize;
10132
10133 #endif // DISPLAY_SIZES
10134
10135 /*****************************************************************************
10136  *
10137  *  Variables to keep track of basic block counts (more data on 1 BB methods)
10138  */
10139
10140 #if COUNT_BASIC_BLOCKS
10141 extern Histogram bbCntTable;
10142 extern Histogram bbOneBBSizeTable;
10143 #endif
10144
10145 /*****************************************************************************
10146  *
10147  *  Used by optFindNaturalLoops to gather statistical information such as
10148  *   - total number of natural loops
10149  *   - number of loops with 1, 2, ... exit conditions
10150  *   - number of loops that have an iterator (for like)
10151  *   - number of loops that have a constant iterator
10152  */
10153
10154 #if COUNT_LOOPS
10155
10156 extern unsigned totalLoopMethods;        // counts the total number of methods that have natural loops
10157 extern unsigned maxLoopsPerMethod;       // counts the maximum number of loops a method has
10158 extern unsigned totalLoopOverflows;      // # of methods that identified more loops than we can represent
10159 extern unsigned totalLoopCount;          // counts the total number of natural loops
10160 extern unsigned totalUnnatLoopCount;     // counts the total number of (not-necessarily natural) loops
10161 extern unsigned totalUnnatLoopOverflows; // # of methods that identified more unnatural loops than we can represent
10162 extern unsigned iterLoopCount;           // counts the # of loops with an iterator (for like)
10163 extern unsigned simpleTestLoopCount;     // counts the # of loops with an iterator and a simple loop condition (iter <
10164                                          // const)
10165 extern unsigned  constIterLoopCount;     // counts the # of loops with a constant iterator (for like)
10166 extern bool      hasMethodLoops;         // flag to keep track if we already counted a method as having loops
10167 extern unsigned  loopsThisMethod;        // counts the number of loops in the current method
10168 extern bool      loopOverflowThisMethod; // True if we exceeded the max # of loops in the method.
10169 extern Histogram loopCountTable;         // Histogram of loop counts
10170 extern Histogram loopExitCountTable;     // Histogram of loop exit counts
10171
10172 #endif // COUNT_LOOPS
10173
10174 /*****************************************************************************
10175  * variables to keep track of how many iterations we go in a dataflow pass
10176  */
10177
10178 #if DATAFLOW_ITER
10179
10180 extern unsigned CSEiterCount; // counts the # of iteration for the CSE dataflow
10181 extern unsigned CFiterCount;  // counts the # of iteration for the Const Folding dataflow
10182
10183 #endif // DATAFLOW_ITER
10184
10185 #if MEASURE_BLOCK_SIZE
10186 extern size_t genFlowNodeSize;
10187 extern size_t genFlowNodeCnt;
10188 #endif // MEASURE_BLOCK_SIZE
10189
10190 #if MEASURE_NODE_SIZE
10191 struct NodeSizeStats
10192 {
10193     void Init()
10194     {
10195         genTreeNodeCnt        = 0;
10196         genTreeNodeSize       = 0;
10197         genTreeNodeActualSize = 0;
10198     }
10199
10200     // Count of tree nodes allocated.
10201     unsigned __int64 genTreeNodeCnt;
10202
10203     // The size we allocate.
10204     unsigned __int64 genTreeNodeSize;
10205
10206     // The actual size of the node. Note that the actual size will likely be smaller
10207     // than the allocated size, but we sometimes use SetOper()/ChangeOper() to change
10208     // a smaller node to a larger one. TODO-Cleanup: add stats on
10209     // SetOper()/ChangeOper() usage to quantify this.
10210     unsigned __int64 genTreeNodeActualSize;
10211 };
10212 extern NodeSizeStats genNodeSizeStats;        // Total node size stats
10213 extern NodeSizeStats genNodeSizeStatsPerFunc; // Per-function node size stats
10214 extern Histogram     genTreeNcntHist;
10215 extern Histogram     genTreeNsizHist;
10216 #endif // MEASURE_NODE_SIZE
10217
10218 /*****************************************************************************
10219  *  Count fatal errors (including noway_asserts).
10220  */
10221
10222 #if MEASURE_FATAL
10223 extern unsigned fatal_badCode;
10224 extern unsigned fatal_noWay;
10225 extern unsigned fatal_NOMEM;
10226 extern unsigned fatal_noWayAssertBody;
10227 #ifdef DEBUG
10228 extern unsigned fatal_noWayAssertBodyArgs;
10229 #endif // DEBUG
10230 extern unsigned fatal_NYI;
10231 #endif // MEASURE_FATAL
10232
10233 /*****************************************************************************
10234  * Codegen
10235  */
10236
10237 #ifdef _TARGET_XARCH_
10238
10239 const instruction INS_SHIFT_LEFT_LOGICAL  = INS_shl;
10240 const instruction INS_SHIFT_RIGHT_LOGICAL = INS_shr;
10241 const instruction INS_SHIFT_RIGHT_ARITHM  = INS_sar;
10242
10243 const instruction INS_AND             = INS_and;
10244 const instruction INS_OR              = INS_or;
10245 const instruction INS_XOR             = INS_xor;
10246 const instruction INS_NEG             = INS_neg;
10247 const instruction INS_TEST            = INS_test;
10248 const instruction INS_MUL             = INS_imul;
10249 const instruction INS_SIGNED_DIVIDE   = INS_idiv;
10250 const instruction INS_UNSIGNED_DIVIDE = INS_div;
10251 const instruction INS_BREAKPOINT      = INS_int3;
10252 const instruction INS_ADDC            = INS_adc;
10253 const instruction INS_SUBC            = INS_sbb;
10254 const instruction INS_NOT             = INS_not;
10255
10256 #endif // _TARGET_XARCH_
10257
10258 #ifdef _TARGET_ARM_
10259
10260 const instruction INS_SHIFT_LEFT_LOGICAL  = INS_lsl;
10261 const instruction INS_SHIFT_RIGHT_LOGICAL = INS_lsr;
10262 const instruction INS_SHIFT_RIGHT_ARITHM  = INS_asr;
10263
10264 const instruction INS_AND             = INS_and;
10265 const instruction INS_OR              = INS_orr;
10266 const instruction INS_XOR             = INS_eor;
10267 const instruction INS_NEG             = INS_rsb;
10268 const instruction INS_TEST            = INS_tst;
10269 const instruction INS_MUL             = INS_mul;
10270 const instruction INS_MULADD          = INS_mla;
10271 const instruction INS_SIGNED_DIVIDE   = INS_sdiv;
10272 const instruction INS_UNSIGNED_DIVIDE = INS_udiv;
10273 const instruction INS_BREAKPOINT      = INS_bkpt;
10274 const instruction INS_ADDC            = INS_adc;
10275 const instruction INS_SUBC            = INS_sbc;
10276 const instruction INS_NOT             = INS_mvn;
10277
10278 const instruction INS_ABS  = INS_vabs;
10279 const instruction INS_SQRT = INS_vsqrt;
10280
10281 #endif // _TARGET_ARM_
10282
10283 #ifdef _TARGET_ARM64_
10284
10285 const instruction INS_MULADD     = INS_madd;
10286 const instruction INS_BREAKPOINT = INS_bkpt;
10287
10288 const instruction INS_ABS  = INS_fabs;
10289 const instruction INS_SQRT = INS_fsqrt;
10290
10291 #endif // _TARGET_ARM64_
10292
10293 /*****************************************************************************/
10294
10295 extern const BYTE genTypeSizes[];
10296 extern const BYTE genTypeAlignments[];
10297 extern const BYTE genTypeStSzs[];
10298 extern const BYTE genActualTypes[];
10299
10300 /*****************************************************************************/
10301
10302 // VERY_LARGE_FRAME_SIZE_REG_MASK is the set of registers we need to use for
10303 // the probing loop generated for very large stack frames (see `getVeryLargeFrameSize`).
10304
10305 #ifdef _TARGET_ARM_
10306 #define VERY_LARGE_FRAME_SIZE_REG_MASK (RBM_R4 | RBM_R5 | RBM_R6)
10307 #elif defined(_TARGET_ARM64_)
10308 #define VERY_LARGE_FRAME_SIZE_REG_MASK (RBM_R9 | RBM_R10 | RBM_R11)
10309 #endif
10310
10311 /*****************************************************************************/
10312
10313 extern BasicBlock dummyBB;
10314
10315 /*****************************************************************************/
10316 /*****************************************************************************/
10317
10318 // foreach_treenode_execution_order: An iterator that iterates through all the tree
10319 // nodes of a statement in execution order.
10320 //      __stmt: a GT_STMT type GenTree*
10321 //      __node: a GenTree*, already declared, that gets updated with each node in the statement, in execution order
10322
10323 #define foreach_treenode_execution_order(__node, __stmt)                                                               \
10324     for ((__node) = (__stmt)->gtStmt.gtStmtList; (__node); (__node) = (__node)->gtNext)
10325
10326 // foreach_block: An iterator over all blocks in the function.
10327 //    __compiler: the Compiler* object
10328 //    __block   : a BasicBlock*, already declared, that gets updated each iteration.
10329
10330 #define foreach_block(__compiler, __block)                                                                             \
10331     for ((__block) = (__compiler)->fgFirstBB; (__block); (__block) = (__block)->bbNext)
10332
10333 /*****************************************************************************/
10334 /*****************************************************************************/
10335
10336 #ifdef DEBUG
10337
10338 void dumpConvertedVarSet(Compiler* comp, VARSET_VALARG_TP vars);
10339
10340 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
10341 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
10342 XX                                                                           XX
10343 XX                          Debugging helpers                                XX
10344 XX                                                                           XX
10345 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
10346 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
10347 */
10348
10349 /*****************************************************************************/
10350 /* The following functions are intended to be called from the debugger, to dump
10351  * various data structures. The can be used in the debugger Watch or Quick Watch
10352  * windows. They are designed to be short to type and take as few arguments as
10353  * possible. The 'c' versions take a Compiler*, whereas the 'd' versions use the TlsCompiler.
10354  * See the function definition comment for more details.
10355  */
10356
10357 void cBlock(Compiler* comp, BasicBlock* block);
10358 void cBlocks(Compiler* comp);
10359 void cBlocksV(Compiler* comp);
10360 void cTree(Compiler* comp, GenTree* tree);
10361 void cTrees(Compiler* comp);
10362 void cEH(Compiler* comp);
10363 void cVar(Compiler* comp, unsigned lclNum);
10364 void cVarDsc(Compiler* comp, LclVarDsc* varDsc);
10365 void cVars(Compiler* comp);
10366 void cVarsFinal(Compiler* comp);
10367 void cBlockPreds(Compiler* comp, BasicBlock* block);
10368 void cReach(Compiler* comp);
10369 void cDoms(Compiler* comp);
10370 void cLiveness(Compiler* comp);
10371 void cCVarSet(Compiler* comp, VARSET_VALARG_TP vars);
10372
10373 void cFuncIR(Compiler* comp);
10374 void cBlockIR(Compiler* comp, BasicBlock* block);
10375 void cLoopIR(Compiler* comp, Compiler::LoopDsc* loop);
10376 void cTreeIR(Compiler* comp, GenTree* tree);
10377 int cTreeTypeIR(Compiler* comp, GenTree* tree);
10378 int cTreeKindsIR(Compiler* comp, GenTree* tree);
10379 int cTreeFlagsIR(Compiler* comp, GenTree* tree);
10380 int cOperandIR(Compiler* comp, GenTree* operand);
10381 int cLeafIR(Compiler* comp, GenTree* tree);
10382 int cIndirIR(Compiler* comp, GenTree* tree);
10383 int cListIR(Compiler* comp, GenTree* list);
10384 int cSsaNumIR(Compiler* comp, GenTree* tree);
10385 int cValNumIR(Compiler* comp, GenTree* tree);
10386 int cDependsIR(Compiler* comp, GenTree* comma, bool* first);
10387
10388 void dBlock(BasicBlock* block);
10389 void dBlocks();
10390 void dBlocksV();
10391 void dTree(GenTree* tree);
10392 void dTrees();
10393 void dEH();
10394 void dVar(unsigned lclNum);
10395 void dVarDsc(LclVarDsc* varDsc);
10396 void dVars();
10397 void dVarsFinal();
10398 void dBlockPreds(BasicBlock* block);
10399 void dReach();
10400 void dDoms();
10401 void dLiveness();
10402 void dCVarSet(VARSET_VALARG_TP vars);
10403
10404 void dRegMask(regMaskTP mask);
10405
10406 void dFuncIR();
10407 void dBlockIR(BasicBlock* block);
10408 void dTreeIR(GenTree* tree);
10409 void dLoopIR(Compiler::LoopDsc* loop);
10410 void dLoopNumIR(unsigned loopNum);
10411 int dTabStopIR(int curr, int tabstop);
10412 int dTreeTypeIR(GenTree* tree);
10413 int dTreeKindsIR(GenTree* tree);
10414 int dTreeFlagsIR(GenTree* tree);
10415 int dOperandIR(GenTree* operand);
10416 int dLeafIR(GenTree* tree);
10417 int dIndirIR(GenTree* tree);
10418 int dListIR(GenTree* list);
10419 int dSsaNumIR(GenTree* tree);
10420 int dValNumIR(GenTree* tree);
10421 int dDependsIR(GenTree* comma);
10422 void dFormatIR();
10423
10424 GenTree* dFindTree(GenTree* tree, unsigned id);
10425 GenTree* dFindTree(unsigned id);
10426 GenTreeStmt* dFindStmt(unsigned id);
10427 BasicBlock* dFindBlock(unsigned bbNum);
10428
10429 #endif // DEBUG
10430
10431 #include "compiler.hpp" // All the shared inline functions
10432
10433 /*****************************************************************************/
10434 #endif //_COMPILER_H_
10435 /*****************************************************************************/