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