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