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