Fix reading Time zone rules using Julian days (#17672)
[platform/upstream/coreclr.git] / src / jit / compiler.hpp
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                    Inline functions                                       XX
9 XX                                                                           XX
10 XX                                                                           XX
11 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
12 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
13 */
14
15 #ifndef _COMPILER_HPP_
16 #define _COMPILER_HPP_
17
18 #include "emit.h" // for emitter::emitAddLabel
19
20 #include "bitvec.h"
21
22 #include "compilerbitsettraits.hpp"
23
24 /*
25 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
26 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
27 XX                                                                           XX
28 XX  Miscellaneous utility functions. Some of these are defined in Utils.cpp  XX
29 XX                                                                           XX
30 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
31 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
32 */
33
34 /*****************************************************************************/
35 /*****************************************************************************/
36
37 inline bool getInlinePInvokeEnabled()
38 {
39 #ifdef DEBUG
40     return JitConfig.JitPInvokeEnabled() && !JitConfig.StressCOMCall();
41 #else
42     return true;
43 #endif
44 }
45
46 inline bool getInlinePInvokeCheckEnabled()
47 {
48 #ifdef DEBUG
49     return JitConfig.JitPInvokeCheckEnabled() != 0;
50 #else
51     return false;
52 #endif
53 }
54
55 // Enforce float narrowing for buggy compilers (notably preWhidbey VC)
56 inline float forceCastToFloat(double d)
57 {
58     Volatile<float> f = (float)d;
59     return f;
60 }
61
62 // Enforce UInt32 narrowing for buggy compilers (notably Whidbey Beta 2 LKG)
63 inline UINT32 forceCastToUInt32(double d)
64 {
65     Volatile<UINT32> u = (UINT32)d;
66     return u;
67 }
68
69 enum RoundLevel
70 {
71     ROUND_NEVER     = 0, // Never round
72     ROUND_CMP_CONST = 1, // Round values compared against constants
73     ROUND_CMP       = 2, // Round comparands and return values
74     ROUND_ALWAYS    = 3, // Round always
75
76     COUNT_ROUND_LEVEL,
77     DEFAULT_ROUND_LEVEL = ROUND_NEVER
78 };
79
80 inline RoundLevel getRoundFloatLevel()
81 {
82 #ifdef DEBUG
83     return (RoundLevel)JitConfig.JitRoundFloat();
84 #else
85     return DEFAULT_ROUND_LEVEL;
86 #endif
87 }
88
89 /*****************************************************************************/
90 /*****************************************************************************
91  *
92  *  Return the lowest bit that is set
93  */
94
95 template <typename T>
96 inline T genFindLowestBit(T value)
97 {
98     return (value & (0 - value));
99 }
100
101 /*****************************************************************************/
102 /*****************************************************************************
103  *
104  *  Return the highest bit that is set (that is, a mask that includes just the highest bit).
105  *  TODO-ARM64-Throughput: we should convert these to use the _BitScanReverse() / _BitScanReverse64()
106  *  compiler intrinsics, but our CRT header file intrin.h doesn't define these for ARM64 yet.
107  */
108
109 inline unsigned int genFindHighestBit(unsigned int mask)
110 {
111     assert(mask != 0);
112     unsigned int bit = 1U << ((sizeof(unsigned int) * 8) - 1); // start looking at the top
113     while ((bit & mask) == 0)
114     {
115         bit >>= 1;
116     }
117     return bit;
118 }
119
120 inline unsigned __int64 genFindHighestBit(unsigned __int64 mask)
121 {
122     assert(mask != 0);
123     unsigned __int64 bit = 1ULL << ((sizeof(unsigned __int64) * 8) - 1); // start looking at the top
124     while ((bit & mask) == 0)
125     {
126         bit >>= 1;
127     }
128     return bit;
129 }
130
131 #if 0
132 // TODO-ARM64-Cleanup: These should probably be the implementation, when intrin.h is updated for ARM64
133 inline
134 unsigned int genFindHighestBit(unsigned int mask)
135 {
136     assert(mask != 0);
137     unsigned int index;
138     _BitScanReverse(&index, mask);
139     return 1L << index;
140 }
141
142 inline
143 unsigned __int64 genFindHighestBit(unsigned __int64 mask)
144 {
145     assert(mask != 0);
146     unsigned int index;
147     _BitScanReverse64(&index, mask);
148     return 1LL << index;
149 }
150 #endif // 0
151
152 /*****************************************************************************
153 *
154 *  Return true if the given 64-bit value has exactly zero or one bits set.
155 */
156
157 template <typename T>
158 inline BOOL genMaxOneBit(T value)
159 {
160     return (value & (value - 1)) == 0;
161 }
162
163 /*****************************************************************************
164 *
165 *  Return true if the given 32-bit value has exactly zero or one bits set.
166 */
167
168 inline BOOL genMaxOneBit(unsigned value)
169 {
170     return (value & (value - 1)) == 0;
171 }
172
173 /*****************************************************************************
174 *
175 *  Return true if the given 64-bit value has exactly one bit set.
176 */
177
178 template <typename T>
179 inline bool genExactlyOneBit(T value)
180 {
181     return ((value != 0) && genMaxOneBit(value));
182 }
183
184 /*****************************************************************************
185 *
186 *  Return true if the given 32-bit value has exactly zero or one bits set.
187 */
188
189 inline bool genExactlyOneBit(unsigned value)
190 {
191     return ((value != 0) && genMaxOneBit(value));
192 }
193
194 /*****************************************************************************
195  *
196  *  Given a value that has exactly one bit set, return the position of that
197  *  bit, in other words return the logarithm in base 2 of the given value.
198  */
199 inline unsigned genLog2(unsigned value)
200 {
201     return BitPosition(value);
202 }
203
204 // Given an unsigned 64-bit value, returns the lower 32-bits in unsigned format
205 //
206 inline unsigned ulo32(unsigned __int64 value)
207 {
208     return static_cast<unsigned>(value);
209 }
210
211 // Given an unsigned 64-bit value, returns the upper 32-bits in unsigned format
212 //
213 inline unsigned uhi32(unsigned __int64 value)
214 {
215     return static_cast<unsigned>(value >> 32);
216 }
217
218 /*****************************************************************************
219  *
220  *  Given a value that has exactly one bit set, return the position of that
221  *  bit, in other words return the logarithm in base 2 of the given value.
222  */
223
224 inline unsigned genLog2(unsigned __int64 value)
225 {
226     unsigned lo32 = ulo32(value);
227     unsigned hi32 = uhi32(value);
228
229     if (lo32 != 0)
230     {
231         assert(hi32 == 0);
232         return genLog2(lo32);
233     }
234     else
235     {
236         return genLog2(hi32) + 32;
237     }
238 }
239
240 /*****************************************************************************
241  *
242  *  Return the lowest bit that is set in the given register mask.
243  */
244
245 inline regMaskTP genFindLowestReg(regMaskTP value)
246 {
247     return (regMaskTP)genFindLowestBit(value);
248 }
249
250 /*****************************************************************************
251  *
252  *  A rather simple routine that counts the number of bits in a given number.
253  */
254
255 template <typename T>
256 inline unsigned genCountBits(T bits)
257 {
258     unsigned cnt = 0;
259
260     while (bits)
261     {
262         cnt++;
263         bits -= genFindLowestBit(bits);
264     }
265
266     return cnt;
267 }
268
269 /*****************************************************************************
270  *
271  *  Given 3 masks value, end, start, returns the bits of value between start
272  *  and end (exclusive).
273  *
274  *  value[bitNum(end) - 1, bitNum(start) + 1]
275  */
276
277 inline unsigned __int64 BitsBetween(unsigned __int64 value, unsigned __int64 end, unsigned __int64 start)
278 {
279     assert(start != 0);
280     assert(start < end);
281     assert((start & (start - 1)) == 0);
282     assert((end & (end - 1)) == 0);
283
284     return value & ~((start - 1) | start) & // Ones to the left of set bit in the start mask.
285            (end - 1);                       // Ones to the right of set bit in the end mask.
286 }
287
288 /*****************************************************************************/
289
290 inline bool jitIsScaleIndexMul(size_t val)
291 {
292     switch (val)
293     {
294         case 1:
295         case 2:
296         case 4:
297         case 8:
298             return true;
299
300         default:
301             return false;
302     }
303 }
304
305 // Returns "tree" iff "val" is a valid addressing mode scale shift amount on
306 // the target architecture.
307 inline bool jitIsScaleIndexShift(ssize_t val)
308 {
309     // It happens that this is the right test for all our current targets: x86, x64 and ARM.
310     // This test would become target-dependent if we added a new target with a different constraint.
311     return 0 < val && val < 4;
312 }
313
314 /*****************************************************************************
315  * Returns true if value is between [start..end).
316  * The comparison is inclusive of start, exclusive of end.
317  */
318
319 /* static */
320 inline bool Compiler::jitIsBetween(unsigned value, unsigned start, unsigned end)
321 {
322     return start <= value && value < end;
323 }
324
325 /*****************************************************************************
326  * Returns true if value is between [start..end].
327  * The comparison is inclusive of both start and end.
328  */
329
330 /* static */
331 inline bool Compiler::jitIsBetweenInclusive(unsigned value, unsigned start, unsigned end)
332 {
333     return start <= value && value <= end;
334 }
335
336 /******************************************************************************************
337  * Return the EH descriptor for the given region index.
338  */
339 inline EHblkDsc* Compiler::ehGetDsc(unsigned regionIndex)
340 {
341     assert(regionIndex < compHndBBtabCount);
342     return &compHndBBtab[regionIndex];
343 }
344
345 /******************************************************************************************
346  * Return the EH descriptor index of the enclosing try, for the given region index.
347  */
348 inline unsigned Compiler::ehGetEnclosingTryIndex(unsigned regionIndex)
349 {
350     return ehGetDsc(regionIndex)->ebdEnclosingTryIndex;
351 }
352
353 /******************************************************************************************
354  * Return the EH descriptor index of the enclosing handler, for the given region index.
355  */
356 inline unsigned Compiler::ehGetEnclosingHndIndex(unsigned regionIndex)
357 {
358     return ehGetDsc(regionIndex)->ebdEnclosingHndIndex;
359 }
360
361 /******************************************************************************************
362  * Return the EH index given a region descriptor.
363  */
364 inline unsigned Compiler::ehGetIndex(EHblkDsc* ehDsc)
365 {
366     assert(compHndBBtab <= ehDsc && ehDsc < compHndBBtab + compHndBBtabCount);
367     return (unsigned)(ehDsc - compHndBBtab);
368 }
369
370 /******************************************************************************************
371  * Return the EH descriptor for the most nested 'try' region this BasicBlock is a member of
372  * (or nullptr if this block is not in a 'try' region).
373  */
374 inline EHblkDsc* Compiler::ehGetBlockTryDsc(BasicBlock* block)
375 {
376     if (!block->hasTryIndex())
377     {
378         return nullptr;
379     }
380
381     return ehGetDsc(block->getTryIndex());
382 }
383
384 /******************************************************************************************
385  * Return the EH descriptor for the most nested filter or handler region this BasicBlock is a member of
386  * (or nullptr if this block is not in a filter or handler region).
387  */
388 inline EHblkDsc* Compiler::ehGetBlockHndDsc(BasicBlock* block)
389 {
390     if (!block->hasHndIndex())
391     {
392         return nullptr;
393     }
394
395     return ehGetDsc(block->getHndIndex());
396 }
397
398 #if FEATURE_EH_FUNCLETS
399
400 /*****************************************************************************
401  *  Get the FuncInfoDsc for the funclet we are currently generating code for.
402  *  This is only valid during codegen.
403  *
404  */
405 inline FuncInfoDsc* Compiler::funCurrentFunc()
406 {
407     return funGetFunc(compCurrFuncIdx);
408 }
409
410 /*****************************************************************************
411  *  Change which funclet we are currently generating code for.
412  *  This is only valid after funclets are created.
413  *
414  */
415 inline void Compiler::funSetCurrentFunc(unsigned funcIdx)
416 {
417     assert(fgFuncletsCreated);
418     assert(FitsIn<unsigned short>(funcIdx));
419     noway_assert(funcIdx < compFuncInfoCount);
420     compCurrFuncIdx = (unsigned short)funcIdx;
421 }
422
423 /*****************************************************************************
424  *  Get the FuncInfoDsc for the given funclet.
425  *  This is only valid after funclets are created.
426  *
427  */
428 inline FuncInfoDsc* Compiler::funGetFunc(unsigned funcIdx)
429 {
430     assert(fgFuncletsCreated);
431     assert(funcIdx < compFuncInfoCount);
432     return &compFuncInfos[funcIdx];
433 }
434
435 /*****************************************************************************
436  *  Get the funcIdx for the EH funclet that begins with block.
437  *  This is only valid after funclets are created.
438  *  It is only valid for blocks marked with BBF_FUNCLET_BEG because
439  *  otherwise we would have to do a more expensive check to determine
440  *  if this should return the filter funclet or the filter handler funclet.
441  *
442  */
443 inline unsigned Compiler::funGetFuncIdx(BasicBlock* block)
444 {
445     assert(fgFuncletsCreated);
446     assert(block->bbFlags & BBF_FUNCLET_BEG);
447
448     EHblkDsc*    eh      = ehGetDsc(block->getHndIndex());
449     unsigned int funcIdx = eh->ebdFuncIndex;
450     if (eh->ebdHndBeg != block)
451     {
452         // If this is a filter EH clause, but we want the funclet
453         // for the filter (not the filter handler), it is the previous one
454         noway_assert(eh->HasFilter());
455         noway_assert(eh->ebdFilter == block);
456         assert(funGetFunc(funcIdx)->funKind == FUNC_HANDLER);
457         assert(funGetFunc(funcIdx)->funEHIndex == funGetFunc(funcIdx - 1)->funEHIndex);
458         assert(funGetFunc(funcIdx - 1)->funKind == FUNC_FILTER);
459         funcIdx--;
460     }
461
462     return funcIdx;
463 }
464
465 #else // !FEATURE_EH_FUNCLETS
466
467 /*****************************************************************************
468  *  Get the FuncInfoDsc for the funclet we are currently generating code for.
469  *  This is only valid during codegen.  For non-funclet platforms, this is
470  *  always the root function.
471  *
472  */
473 inline FuncInfoDsc* Compiler::funCurrentFunc()
474 {
475     return &compFuncInfoRoot;
476 }
477
478 /*****************************************************************************
479  *  Change which funclet we are currently generating code for.
480  *  This is only valid after funclets are created.
481  *
482  */
483 inline void Compiler::funSetCurrentFunc(unsigned funcIdx)
484 {
485     assert(funcIdx == 0);
486 }
487
488 /*****************************************************************************
489  *  Get the FuncInfoDsc for the givven funclet.
490  *  This is only valid after funclets are created.
491  *
492  */
493 inline FuncInfoDsc* Compiler::funGetFunc(unsigned funcIdx)
494 {
495     assert(funcIdx == 0);
496     return &compFuncInfoRoot;
497 }
498
499 /*****************************************************************************
500  *  No funclets, so always 0.
501  *
502  */
503 inline unsigned Compiler::funGetFuncIdx(BasicBlock* block)
504 {
505     return 0;
506 }
507
508 #endif // !FEATURE_EH_FUNCLETS
509
510 //------------------------------------------------------------------------------
511 // genRegNumFromMask : Maps a single register mask to a register number.
512 //
513 // Arguments:
514 //    mask - the register mask
515 //
516 // Return Value:
517 //    The number of the register contained in the mask.
518 //
519 // Assumptions:
520 //    The mask contains one and only one register.
521
522 inline regNumber genRegNumFromMask(regMaskTP mask)
523 {
524     assert(mask != 0); // Must have one bit set, so can't have a mask of zero
525
526     /* Convert the mask to a register number */
527
528     regNumber regNum = (regNumber)genLog2(mask);
529
530     /* Make sure we got it right */
531
532     assert(genRegMask(regNum) == mask);
533
534     return regNum;
535 }
536
537 //------------------------------------------------------------------------------
538 // genSmallTypeCanRepresentValue: Checks if a value can be represented by a given small type.
539 //
540 // Arguments:
541 //    value - the value to check
542 //    type  - the type
543 //
544 // Return Value:
545 //    True if the value is representable, false otherwise.
546
547 inline bool genSmallTypeCanRepresentValue(var_types type, ssize_t value)
548 {
549     switch (type)
550     {
551         case TYP_UBYTE:
552         case TYP_BOOL:
553             return FitsIn<UINT8>(value);
554         case TYP_BYTE:
555             return FitsIn<INT8>(value);
556         case TYP_USHORT:
557             return FitsIn<UINT16>(value);
558         case TYP_SHORT:
559             return FitsIn<INT16>(value);
560         default:
561             unreached();
562     }
563 }
564
565 /*****************************************************************************
566  *
567  *  Return the size in bytes of the given type.
568  */
569
570 extern const BYTE genTypeSizes[TYP_COUNT];
571
572 template <class T>
573 inline unsigned genTypeSize(T type)
574 {
575     assert((unsigned)TypeGet(type) < _countof(genTypeSizes));
576
577     return genTypeSizes[TypeGet(type)];
578 }
579
580 /*****************************************************************************
581  *
582  *  Return the "stack slot count" of the given type.
583  *      returns 1 for 32-bit types and 2 for 64-bit types.
584  */
585
586 extern const BYTE genTypeStSzs[TYP_COUNT];
587
588 inline unsigned genTypeStSz(var_types type)
589 {
590     assert((unsigned)type < _countof(genTypeStSzs));
591
592     return genTypeStSzs[type];
593 }
594
595 /*****************************************************************************
596  *
597  *  Return the number of registers required to hold a value of the given type.
598  */
599
600 /*****************************************************************************
601  *
602  *  The following function maps a 'precise' type to an actual type as seen
603  *  by the VM (for example, 'byte' maps to 'int').
604  */
605
606 extern const BYTE genActualTypes[TYP_COUNT];
607
608 inline var_types genActualType(var_types type)
609 {
610     /* Spot check to make certain the table is in synch with the enum */
611
612     assert(genActualTypes[TYP_DOUBLE] == TYP_DOUBLE);
613     assert(genActualTypes[TYP_REF] == TYP_REF);
614
615     assert((unsigned)type < sizeof(genActualTypes));
616     return (var_types)genActualTypes[type];
617 }
618
619 /*****************************************************************************/
620
621 inline var_types genUnsignedType(var_types type)
622 {
623     /* Force signed types into corresponding unsigned type */
624
625     switch (type)
626     {
627         case TYP_BYTE:
628             type = TYP_UBYTE;
629             break;
630         case TYP_SHORT:
631             type = TYP_USHORT;
632             break;
633         case TYP_INT:
634             type = TYP_UINT;
635             break;
636         case TYP_LONG:
637             type = TYP_ULONG;
638             break;
639         default:
640             break;
641     }
642
643     return type;
644 }
645
646 /*****************************************************************************/
647
648 inline var_types genSignedType(var_types type)
649 {
650     /* Force non-small unsigned type into corresponding signed type */
651     /* Note that we leave the small types alone */
652
653     switch (type)
654     {
655         case TYP_UINT:
656             type = TYP_INT;
657             break;
658         case TYP_ULONG:
659             type = TYP_LONG;
660             break;
661         default:
662             break;
663     }
664
665     return type;
666 }
667
668 /*****************************************************************************
669  *  Can this type be passed as a parameter in a register?
670  */
671
672 inline bool isRegParamType(var_types type)
673 {
674 #if defined(_TARGET_X86_)
675     return (type <= TYP_INT || type == TYP_REF || type == TYP_BYREF);
676 #else  // !_TARGET_X86_
677     return true;
678 #endif // !_TARGET_X86_
679 }
680
681 #if defined(_TARGET_AMD64_) || defined(_TARGET_ARM64_)
682 /*****************************************************************************/
683 // Returns true if 'type' is a struct that can be enregistered for call args
684 //                         or can be returned by value in multiple registers.
685 //              if 'type' is not a struct the return value will be false.
686 //
687 // Arguments:
688 //    type      - the basic jit var_type for the item being queried
689 //    typeClass - the handle for the struct when 'type' is TYP_STRUCT
690 //    typeSize  - Out param (if non-null) is updated with the size of 'type'.
691 //    forReturn - this is true when we asking about a GT_RETURN context;
692 //                this is false when we are asking about an argument context
693 //
694 inline bool Compiler::VarTypeIsMultiByteAndCanEnreg(var_types            type,
695                                                     CORINFO_CLASS_HANDLE typeClass,
696                                                     unsigned*            typeSize,
697                                                     bool                 forReturn)
698 {
699     bool     result = false;
700     unsigned size   = 0;
701
702     if (varTypeIsStruct(type))
703     {
704         size = info.compCompHnd->getClassSize(typeClass);
705         if (forReturn)
706         {
707             structPassingKind howToReturnStruct;
708             type = getReturnTypeForStruct(typeClass, &howToReturnStruct, size);
709         }
710         else
711         {
712             structPassingKind howToPassStruct;
713             type = getArgTypeForStruct(typeClass, &howToPassStruct, size);
714         }
715         if (type != TYP_UNKNOWN)
716         {
717             result = true;
718         }
719     }
720     else
721     {
722         size = genTypeSize(type);
723     }
724
725     if (typeSize != nullptr)
726     {
727         *typeSize = size;
728     }
729
730     return result;
731 }
732 #endif //_TARGET_AMD64_ || _TARGET_ARM64_
733
734 /*****************************************************************************/
735
736 #ifdef DEBUG
737
738 inline const char* varTypeGCstring(var_types type)
739 {
740     switch (type)
741     {
742         case TYP_REF:
743             return "gcr";
744         case TYP_BYREF:
745             return "byr";
746         default:
747             return "non";
748     }
749 }
750
751 #endif
752
753 /*****************************************************************************/
754
755 const char* varTypeName(var_types);
756
757 /*****************************************************************************
758  *
759  *  Helpers to pull big-endian values out of a byte stream.
760  */
761
762 inline unsigned genGetU1(const BYTE* addr)
763 {
764     return addr[0];
765 }
766
767 inline signed genGetI1(const BYTE* addr)
768 {
769     return (signed char)addr[0];
770 }
771
772 inline unsigned genGetU2(const BYTE* addr)
773 {
774     return (addr[0] << 8) | addr[1];
775 }
776
777 inline signed genGetI2(const BYTE* addr)
778 {
779     return (signed short)((addr[0] << 8) | addr[1]);
780 }
781
782 inline unsigned genGetU4(const BYTE* addr)
783 {
784     return (addr[0] << 24) | (addr[1] << 16) | (addr[2] << 8) | addr[3];
785 }
786
787 /*****************************************************************************/
788 //  Helpers to pull little-endian values out of a byte stream.
789
790 inline unsigned __int8 getU1LittleEndian(const BYTE* ptr)
791 {
792     return *(UNALIGNED unsigned __int8*)ptr;
793 }
794
795 inline unsigned __int16 getU2LittleEndian(const BYTE* ptr)
796 {
797     return GET_UNALIGNED_VAL16(ptr);
798 }
799
800 inline unsigned __int32 getU4LittleEndian(const BYTE* ptr)
801 {
802     return GET_UNALIGNED_VAL32(ptr);
803 }
804
805 inline signed __int8 getI1LittleEndian(const BYTE* ptr)
806 {
807     return *(UNALIGNED signed __int8*)ptr;
808 }
809
810 inline signed __int16 getI2LittleEndian(const BYTE* ptr)
811 {
812     return GET_UNALIGNED_VAL16(ptr);
813 }
814
815 inline signed __int32 getI4LittleEndian(const BYTE* ptr)
816 {
817     return GET_UNALIGNED_VAL32(ptr);
818 }
819
820 inline signed __int64 getI8LittleEndian(const BYTE* ptr)
821 {
822     return GET_UNALIGNED_VAL64(ptr);
823 }
824
825 inline float getR4LittleEndian(const BYTE* ptr)
826 {
827     __int32 val = getI4LittleEndian(ptr);
828     return *(float*)&val;
829 }
830
831 inline double getR8LittleEndian(const BYTE* ptr)
832 {
833     __int64 val = getI8LittleEndian(ptr);
834     return *(double*)&val;
835 }
836
837 /*****************************************************************************
838  *
839  *  Return the normalized index to use in the EXPSET_TP for the CSE with
840  *  the given CSE index.
841  *  Each GenTree has the following field:
842  *    signed char       gtCSEnum;        // 0 or the CSE index (negated if def)
843  *  So zero is reserved to mean this node is not a CSE
844  *  and postive values indicate CSE uses and negative values indicate CSE defs.
845  *  The caller of this method must pass a non-zero postive value.
846  *  This precondition is checked by the assert on the first line of this method.
847  */
848
849 inline unsigned int genCSEnum2bit(unsigned index)
850 {
851     assert((index > 0) && (index <= EXPSET_SZ));
852
853     return (index - 1);
854 }
855
856 #ifdef DEBUG
857 const char* genES2str(BitVecTraits* traits, EXPSET_TP set);
858 const char* refCntWtd2str(unsigned refCntWtd);
859 #endif
860
861 /*
862 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
863 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
864 XX                          GenTree                                          XX
865 XX                      Inline functions                                     XX
866 XX                                                                           XX
867 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
868 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
869 */
870
871 void* GenTree::operator new(size_t sz, Compiler* comp, genTreeOps oper)
872 {
873 #if SMALL_TREE_NODES
874     size_t size = GenTree::s_gtNodeSizes[oper];
875 #else
876     size_t   size    = TREE_NODE_SZ_LARGE;
877 #endif
878
879 #if MEASURE_NODE_SIZE
880     genNodeSizeStats.genTreeNodeCnt += 1;
881     genNodeSizeStats.genTreeNodeSize += size;
882     genNodeSizeStats.genTreeNodeActualSize += sz;
883
884     genNodeSizeStatsPerFunc.genTreeNodeCnt += 1;
885     genNodeSizeStatsPerFunc.genTreeNodeSize += size;
886     genNodeSizeStatsPerFunc.genTreeNodeActualSize += sz;
887 #endif // MEASURE_NODE_SIZE
888
889     assert(size >= sz);
890     return comp->compGetMem(size, CMK_ASTNode);
891 }
892
893 // GenTree constructor
894 inline GenTree::GenTree(genTreeOps oper, var_types type DEBUGARG(bool largeNode))
895 {
896     gtOper     = oper;
897     gtType     = type;
898     gtFlags    = 0;
899     gtLIRFlags = 0;
900 #ifdef DEBUG
901     gtDebugFlags = 0;
902 #endif // DEBUG
903 #ifdef LEGACY_BACKEND
904     gtUsedRegs = 0;
905 #endif // LEGACY_BACKEND
906 #if FEATURE_ANYCSE
907     gtCSEnum = NO_CSE;
908 #endif // FEATURE_ANYCSE
909 #if ASSERTION_PROP
910     ClearAssertion();
911 #endif
912
913 #if FEATURE_STACK_FP_X87
914     gtFPlvl = 0;
915 #endif
916
917     gtNext   = nullptr;
918     gtPrev   = nullptr;
919     gtRegNum = REG_NA;
920     INDEBUG(gtRegTag = GT_REGTAG_NONE;)
921
922     INDEBUG(gtCostsInitialized = false;)
923
924 #ifdef DEBUG
925 #if SMALL_TREE_NODES
926     size_t size = GenTree::s_gtNodeSizes[oper];
927     if (size == TREE_NODE_SZ_SMALL && !largeNode)
928     {
929         gtDebugFlags |= GTF_DEBUG_NODE_SMALL;
930     }
931     else if (size == TREE_NODE_SZ_LARGE || largeNode)
932     {
933         gtDebugFlags |= GTF_DEBUG_NODE_LARGE;
934     }
935     else
936     {
937         assert(!"bogus node size");
938     }
939 #endif
940 #endif
941
942 #if COUNT_AST_OPERS
943     InterlockedIncrement(&s_gtNodeCounts[oper]);
944 #endif
945
946 #ifdef DEBUG
947     gtSeqNum = 0;
948     gtTreeID = JitTls::GetCompiler()->compGenTreeID++;
949     gtVNPair.SetBoth(ValueNumStore::NoVN);
950     gtRegTag   = GT_REGTAG_NONE;
951     gtOperSave = GT_NONE;
952 #endif
953 }
954
955 /*****************************************************************************/
956
957 inline GenTreeStmt* Compiler::gtNewStmt(GenTree* expr, IL_OFFSETX offset)
958 {
959     /* NOTE - GT_STMT is now a small node in retail */
960
961     GenTreeStmt* stmt = new (this, GT_STMT) GenTreeStmt(expr, offset);
962
963     return stmt;
964 }
965
966 /*****************************************************************************/
967
968 inline GenTree* Compiler::gtNewOperNode(genTreeOps oper, var_types type, GenTree* op1, bool doSimplifications)
969 {
970     assert((GenTree::OperKind(oper) & (GTK_UNOP | GTK_BINOP)) != 0);
971     assert((GenTree::OperKind(oper) & GTK_EXOP) ==
972            0); // Can't use this to construct any types that extend unary/binary operator.
973     assert(op1 != nullptr || oper == GT_PHI || oper == GT_RETFILT || oper == GT_NOP ||
974            (oper == GT_RETURN && type == TYP_VOID));
975
976     if (doSimplifications)
977     {
978         // We do some simplifications here.
979         // If this gets to be too many, try a switch...
980         // TODO-Cleanup: With the factoring out of array bounds checks, it should not be the
981         // case that we need to check for the array index case here, but without this check
982         // we get failures (see for example jit\Directed\Languages\Python\test_methods_d.exe)
983         if (oper == GT_IND)
984         {
985             // IND(ADDR(IND(x)) == IND(x)
986             if (op1->gtOper == GT_ADDR)
987             {
988                 if (op1->gtOp.gtOp1->gtOper == GT_IND && (op1->gtOp.gtOp1->gtFlags & GTF_IND_ARR_INDEX) == 0)
989                 {
990                     op1 = op1->gtOp.gtOp1->gtOp.gtOp1;
991                 }
992             }
993         }
994         else if (oper == GT_ADDR)
995         {
996             // if "x" is not an array index, ADDR(IND(x)) == x
997             if (op1->gtOper == GT_IND && (op1->gtFlags & GTF_IND_ARR_INDEX) == 0)
998             {
999                 return op1->gtOp.gtOp1;
1000             }
1001         }
1002     }
1003
1004     GenTree* node = new (this, oper) GenTreeOp(oper, type, op1, nullptr);
1005
1006     //
1007     // the GT_ADDR of a Local Variable implies GTF_ADDR_ONSTACK
1008     //
1009     if ((oper == GT_ADDR) && (op1->OperGet() == GT_LCL_VAR))
1010     {
1011         node->gtFlags |= GTF_ADDR_ONSTACK;
1012     }
1013
1014     return node;
1015 }
1016
1017 // Returns an opcode that is of the largest node size in use.
1018 inline genTreeOps LargeOpOpcode()
1019 {
1020 #if SMALL_TREE_NODES
1021     // Allocate a large node
1022     assert(GenTree::s_gtNodeSizes[GT_CALL] == TREE_NODE_SZ_LARGE);
1023 #endif
1024     return GT_CALL;
1025 }
1026
1027 /******************************************************************************
1028  *
1029  * Use to create nodes which may later be morphed to another (big) operator
1030  */
1031
1032 inline GenTree* Compiler::gtNewLargeOperNode(genTreeOps oper, var_types type, GenTree* op1, GenTree* op2)
1033 {
1034     assert((GenTree::OperKind(oper) & (GTK_UNOP | GTK_BINOP)) != 0);
1035     assert((GenTree::OperKind(oper) & GTK_EXOP) ==
1036            0); // Can't use this to construct any types that extend unary/binary operator.
1037 #if SMALL_TREE_NODES
1038     // Allocate a large node
1039
1040     assert(GenTree::s_gtNodeSizes[oper] == TREE_NODE_SZ_SMALL);
1041
1042     GenTree* node = new (this, LargeOpOpcode()) GenTreeOp(oper, type, op1, op2 DEBUGARG(/*largeNode*/ true));
1043 #else
1044     GenTree* node    = new (this, oper) GenTreeOp(oper, type, op1, op2);
1045 #endif
1046
1047     return node;
1048 }
1049
1050 /*****************************************************************************
1051  *
1052  *  allocates a integer constant entry that represents a handle (something
1053  *  that may need to be fixed up).
1054  */
1055
1056 inline GenTree* Compiler::gtNewIconHandleNode(size_t value, unsigned flags, FieldSeqNode* fields)
1057 {
1058     GenTree* node;
1059     assert((flags & (GTF_ICON_HDL_MASK | GTF_ICON_FIELD_OFF)) != 0);
1060
1061     // Interpret "fields == NULL" as "not a field."
1062     if (fields == nullptr)
1063     {
1064         fields = FieldSeqStore::NotAField();
1065     }
1066
1067 #if defined(LATE_DISASM)
1068     node = new (this, LargeOpOpcode()) GenTreeIntCon(TYP_I_IMPL, value, fields DEBUGARG(/*largeNode*/ true));
1069 #else
1070     node             = new (this, GT_CNS_INT) GenTreeIntCon(TYP_I_IMPL, value, fields);
1071 #endif
1072     node->gtFlags |= flags;
1073     return node;
1074 }
1075
1076 /*****************************************************************************
1077  *
1078  *  It may not be allowed to embed HANDLEs directly into the JITed code (for eg,
1079  *  as arguments to JIT helpers). Get a corresponding value that can be embedded.
1080  *  These are versions for each specific type of HANDLE
1081  */
1082
1083 inline GenTree* Compiler::gtNewIconEmbScpHndNode(CORINFO_MODULE_HANDLE scpHnd)
1084 {
1085     void *embedScpHnd, *pEmbedScpHnd;
1086
1087     embedScpHnd = (void*)info.compCompHnd->embedModuleHandle(scpHnd, &pEmbedScpHnd);
1088
1089     assert((!embedScpHnd) != (!pEmbedScpHnd));
1090
1091     return gtNewIconEmbHndNode(embedScpHnd, pEmbedScpHnd, GTF_ICON_SCOPE_HDL, scpHnd);
1092 }
1093
1094 //-----------------------------------------------------------------------------
1095
1096 inline GenTree* Compiler::gtNewIconEmbClsHndNode(CORINFO_CLASS_HANDLE clsHnd)
1097 {
1098     void *embedClsHnd, *pEmbedClsHnd;
1099
1100     embedClsHnd = (void*)info.compCompHnd->embedClassHandle(clsHnd, &pEmbedClsHnd);
1101
1102     assert((!embedClsHnd) != (!pEmbedClsHnd));
1103
1104     return gtNewIconEmbHndNode(embedClsHnd, pEmbedClsHnd, GTF_ICON_CLASS_HDL, clsHnd);
1105 }
1106
1107 //-----------------------------------------------------------------------------
1108
1109 inline GenTree* Compiler::gtNewIconEmbMethHndNode(CORINFO_METHOD_HANDLE methHnd)
1110 {
1111     void *embedMethHnd, *pEmbedMethHnd;
1112
1113     embedMethHnd = (void*)info.compCompHnd->embedMethodHandle(methHnd, &pEmbedMethHnd);
1114
1115     assert((!embedMethHnd) != (!pEmbedMethHnd));
1116
1117     return gtNewIconEmbHndNode(embedMethHnd, pEmbedMethHnd, GTF_ICON_METHOD_HDL, methHnd);
1118 }
1119
1120 //-----------------------------------------------------------------------------
1121
1122 inline GenTree* Compiler::gtNewIconEmbFldHndNode(CORINFO_FIELD_HANDLE fldHnd)
1123 {
1124     void *embedFldHnd, *pEmbedFldHnd;
1125
1126     embedFldHnd = (void*)info.compCompHnd->embedFieldHandle(fldHnd, &pEmbedFldHnd);
1127
1128     assert((!embedFldHnd) != (!pEmbedFldHnd));
1129
1130     return gtNewIconEmbHndNode(embedFldHnd, pEmbedFldHnd, GTF_ICON_FIELD_HDL, fldHnd);
1131 }
1132
1133 /*****************************************************************************/
1134
1135 //------------------------------------------------------------------------------
1136 // gtNewHelperCallNode : Helper to create a call helper node.
1137 //
1138 //
1139 // Arguments:
1140 //    helper    - Call helper
1141 //    type      - Type of the node
1142 //    args      - Call args
1143 //
1144 // Return Value:
1145 //    New CT_HELPER node
1146
1147 inline GenTreeCall* Compiler::gtNewHelperCallNode(unsigned helper, var_types type, GenTreeArgList* args)
1148 {
1149     unsigned     flags  = s_helperCallProperties.NoThrow((CorInfoHelpFunc)helper) ? 0 : GTF_EXCEPT;
1150     GenTreeCall* result = gtNewCallNode(CT_HELPER, eeFindHelper(helper), type, args);
1151     result->gtFlags |= flags;
1152
1153 #if DEBUG
1154     // Helper calls are never candidates.
1155
1156     result->gtInlineObservation = InlineObservation::CALLSITE_IS_CALL_TO_HELPER;
1157 #endif
1158
1159     return result;
1160 }
1161
1162 //------------------------------------------------------------------------
1163 // gtNewAllocObjNode: A little helper to create an object allocation node.
1164 //
1165 // Arguments:
1166 //    helper           - Value returned by ICorJitInfo::getNewHelper
1167 //    clsHnd           - Corresponding class handle
1168 //    type             - Tree return type (e.g. TYP_REF)
1169 //    op1              - Node containing an address of VtablePtr
1170 //
1171 // Return Value:
1172 //    Returns GT_ALLOCOBJ node that will be later morphed into an
1173 //    allocation helper call or local variable allocation on the stack.
1174 inline GenTree* Compiler::gtNewAllocObjNode(unsigned int         helper,
1175                                             CORINFO_CLASS_HANDLE clsHnd,
1176                                             var_types            type,
1177                                             GenTree*             op1)
1178 {
1179     GenTree* node = new (this, GT_ALLOCOBJ) GenTreeAllocObj(type, helper, clsHnd, op1);
1180     return node;
1181 }
1182
1183 //------------------------------------------------------------------------
1184 // gtNewRuntimeLookup: Helper to create a runtime lookup node
1185 //
1186 // Arguments:
1187 //    hnd - generic handle being looked up
1188 //    hndTyp - type of the generic handle
1189 //    tree - tree for the lookup
1190 //
1191 // Return Value:
1192 //    New GenTreeRuntimeLookup node.
1193 inline GenTree* Compiler::gtNewRuntimeLookup(CORINFO_GENERIC_HANDLE hnd, CorInfoGenericHandleType hndTyp, GenTree* tree)
1194 {
1195     assert(tree != nullptr);
1196     GenTree* node = new (this, GT_RUNTIMELOOKUP) GenTreeRuntimeLookup(hnd, hndTyp, tree);
1197     return node;
1198 }
1199
1200 /*****************************************************************************/
1201
1202 inline GenTree* Compiler::gtNewCodeRef(BasicBlock* block)
1203 {
1204     GenTree* node = new (this, GT_LABEL) GenTreeLabel(block);
1205     return node;
1206 }
1207
1208 /*****************************************************************************
1209  *
1210  *  A little helper to create a data member reference node.
1211  */
1212
1213 inline GenTree* Compiler::gtNewFieldRef(
1214     var_types typ, CORINFO_FIELD_HANDLE fldHnd, GenTree* obj, DWORD offset, bool nullcheck)
1215 {
1216 #if SMALL_TREE_NODES
1217     /* 'GT_FIELD' nodes may later get transformed into 'GT_IND' */
1218
1219     assert(GenTree::s_gtNodeSizes[GT_IND] <= GenTree::s_gtNodeSizes[GT_FIELD]);
1220     GenTree* tree = new (this, GT_FIELD) GenTreeField(typ);
1221 #else
1222     GenTree*    tree = new (this, GT_FIELD) GenTreeField(typ);
1223 #endif
1224     tree->gtField.gtFldObj    = obj;
1225     tree->gtField.gtFldHnd    = fldHnd;
1226     tree->gtField.gtFldOffset = offset;
1227
1228 #ifdef FEATURE_READYTORUN_COMPILER
1229     tree->gtField.gtFieldLookup.addr = nullptr;
1230 #endif
1231
1232     if (nullcheck)
1233     {
1234         tree->gtFlags |= GTF_FLD_NULLCHECK;
1235     }
1236
1237     // If "obj" is the address of a local, note that a field of that struct local has been accessed.
1238     if (obj != nullptr && obj->OperGet() == GT_ADDR && varTypeIsStruct(obj->gtOp.gtOp1) &&
1239         obj->gtOp.gtOp1->OperGet() == GT_LCL_VAR)
1240     {
1241         unsigned lclNum                  = obj->gtOp.gtOp1->gtLclVarCommon.gtLclNum;
1242         lvaTable[lclNum].lvFieldAccessed = 1;
1243 #if defined(_TARGET_AMD64_) || defined(_TARGET_ARM64_)
1244         // These structs are passed by reference; we should probably be able to treat these
1245         // as non-global refs, but downstream logic expects these to be marked this way.
1246         if (lvaTable[lclNum].lvIsParam)
1247         {
1248             tree->gtFlags |= GTF_GLOB_REF;
1249         }
1250 #endif // defined(_TARGET_AMD64_) || defined(_TARGET_ARM64_)
1251     }
1252     else
1253     {
1254         tree->gtFlags |= GTF_GLOB_REF;
1255     }
1256
1257     return tree;
1258 }
1259
1260 /*****************************************************************************
1261  *
1262  *  A little helper to create an array index node.
1263  */
1264
1265 inline GenTree* Compiler::gtNewIndexRef(var_types typ, GenTree* arrayOp, GenTree* indexOp)
1266 {
1267     GenTreeIndex* gtIndx = new (this, GT_INDEX) GenTreeIndex(typ, arrayOp, indexOp, genTypeSize(typ));
1268
1269     return gtIndx;
1270 }
1271
1272 //------------------------------------------------------------------------------
1273 // gtNewArrLen : Helper to create an array length node.
1274 //
1275 //
1276 // Arguments:
1277 //    typ      -  Type of the node
1278 //    arrayOp  -  Array node
1279 //    lenOffset - Offset of the length field
1280 //
1281 // Return Value:
1282 //    New GT_ARR_LENGTH node
1283
1284 inline GenTreeArrLen* Compiler::gtNewArrLen(var_types typ, GenTree* arrayOp, int lenOffset)
1285 {
1286     GenTreeArrLen* arrLen = new (this, GT_ARR_LENGTH) GenTreeArrLen(typ, arrayOp, lenOffset);
1287     static_assert_no_msg(GTF_ARRLEN_NONFAULTING == GTF_IND_NONFAULTING);
1288     arrLen->SetIndirExceptionFlags(this);
1289     return arrLen;
1290 }
1291
1292 //------------------------------------------------------------------------------
1293 // gtNewIndir : Helper to create an indirection node.
1294 //
1295 // Arguments:
1296 //    typ   -  Type of the node
1297 //    addr  -  Address of the indirection
1298 //
1299 // Return Value:
1300 //    New GT_IND node
1301
1302 inline GenTree* Compiler::gtNewIndir(var_types typ, GenTree* addr)
1303 {
1304     GenTree* indir = gtNewOperNode(GT_IND, typ, addr);
1305     indir->SetIndirExceptionFlags(this);
1306     return indir;
1307 }
1308
1309 /*****************************************************************************
1310  *
1311  *  Create (and check for) a "nothing" node, i.e. a node that doesn't produce
1312  *  any code. We currently use a "nop" node of type void for this purpose.
1313  */
1314
1315 inline GenTree* Compiler::gtNewNothingNode()
1316 {
1317     return new (this, GT_NOP) GenTreeOp(GT_NOP, TYP_VOID);
1318 }
1319 /*****************************************************************************/
1320
1321 inline bool GenTree::IsNothingNode() const
1322 {
1323     return (gtOper == GT_NOP && gtType == TYP_VOID);
1324 }
1325
1326 /*****************************************************************************
1327  *
1328  *  Change the given node to a NOP - May be later changed to a GT_COMMA
1329  *
1330  *****************************************************************************/
1331
1332 inline void GenTree::gtBashToNOP()
1333 {
1334     ChangeOper(GT_NOP);
1335
1336     gtType     = TYP_VOID;
1337     gtOp.gtOp1 = gtOp.gtOp2 = nullptr;
1338
1339     gtFlags &= ~(GTF_ALL_EFFECT | GTF_REVERSE_OPS);
1340 }
1341
1342 // return new arg placeholder node.  Does not do anything but has a type associated
1343 // with it so we can keep track of register arguments in lists associated w/ call nodes
1344
1345 inline GenTree* Compiler::gtNewArgPlaceHolderNode(var_types type, CORINFO_CLASS_HANDLE clsHnd)
1346 {
1347     GenTree* node = new (this, GT_ARGPLACE) GenTreeArgPlace(type, clsHnd);
1348     return node;
1349 }
1350
1351 /*****************************************************************************/
1352
1353 inline GenTree* Compiler::gtUnusedValNode(GenTree* expr)
1354 {
1355     return gtNewOperNode(GT_COMMA, TYP_VOID, expr, gtNewNothingNode());
1356 }
1357
1358 /*****************************************************************************
1359  *
1360  * A wrapper for gtSetEvalOrder and gtComputeFPlvls
1361  * Necessary because the FP levels may need to be re-computed if we reverse
1362  * operands
1363  */
1364
1365 inline void Compiler::gtSetStmtInfo(GenTree* stmt)
1366 {
1367     assert(stmt->gtOper == GT_STMT);
1368     GenTree* expr = stmt->gtStmt.gtStmtExpr;
1369
1370 #if FEATURE_STACK_FP_X87
1371     /* We will try to compute the FP stack level at each node */
1372     codeGen->genResetFPstkLevel();
1373
1374     /* Sometimes we need to redo the FP level computation */
1375     gtFPstLvlRedo = false;
1376 #endif // FEATURE_STACK_FP_X87
1377
1378 #ifdef DEBUG
1379     if (verbose && 0)
1380     {
1381         gtDispTree(stmt);
1382     }
1383 #endif
1384
1385     /* Recursively process the expression */
1386
1387     gtSetEvalOrder(expr);
1388
1389     // Set the statement to have the same costs as the top node of the tree.
1390     stmt->CopyCosts(expr);
1391
1392 #if FEATURE_STACK_FP_X87
1393     /* Unused float values leave one operand on the stack */
1394     assert(codeGen->genGetFPstkLevel() == 0 || codeGen->genGetFPstkLevel() == 1);
1395
1396     /* Do we need to recompute FP stack levels? */
1397
1398     if (gtFPstLvlRedo)
1399     {
1400         codeGen->genResetFPstkLevel();
1401         gtComputeFPlvls(expr);
1402         assert(codeGen->genGetFPstkLevel() == 0 || codeGen->genGetFPstkLevel() == 1);
1403     }
1404 #endif // FEATURE_STACK_FP_X87
1405 }
1406
1407 #if FEATURE_STACK_FP_X87
1408 inline unsigned Compiler::gtSetEvalOrderAndRestoreFPstkLevel(GenTree* tree)
1409 {
1410     unsigned FPlvlSave     = codeGen->genFPstkLevel;
1411     unsigned result        = gtSetEvalOrder(tree);
1412     codeGen->genFPstkLevel = FPlvlSave;
1413
1414     return result;
1415 }
1416 #else  // !FEATURE_STACK_FP_X87
1417 inline unsigned Compiler::gtSetEvalOrderAndRestoreFPstkLevel(GenTree* tree)
1418 {
1419     return gtSetEvalOrder(tree);
1420 }
1421 #endif // FEATURE_STACK_FP_X87
1422
1423 /*****************************************************************************/
1424 #if SMALL_TREE_NODES
1425 /*****************************************************************************/
1426
1427 inline void GenTree::SetOper(genTreeOps oper, ValueNumberUpdate vnUpdate)
1428 {
1429     assert(((gtDebugFlags & GTF_DEBUG_NODE_SMALL) != 0) != ((gtDebugFlags & GTF_DEBUG_NODE_LARGE) != 0));
1430
1431     /* Make sure the node isn't too small for the new operator */
1432
1433     assert(GenTree::s_gtNodeSizes[gtOper] == TREE_NODE_SZ_SMALL ||
1434            GenTree::s_gtNodeSizes[gtOper] == TREE_NODE_SZ_LARGE);
1435
1436     assert(GenTree::s_gtNodeSizes[oper] == TREE_NODE_SZ_SMALL || GenTree::s_gtNodeSizes[oper] == TREE_NODE_SZ_LARGE);
1437     assert(GenTree::s_gtNodeSizes[oper] == TREE_NODE_SZ_SMALL || (gtDebugFlags & GTF_DEBUG_NODE_LARGE));
1438
1439 #if defined(_HOST_64BIT_) && !defined(_TARGET_64BIT_)
1440     if (gtOper == GT_CNS_LNG && oper == GT_CNS_INT)
1441     {
1442         // When casting from LONG to INT, we need to force cast of the value,
1443         // if the host architecture represents INT and LONG with the same data size.
1444         gtLngCon.gtLconVal = (INT64)(INT32)gtLngCon.gtLconVal;
1445     }
1446 #endif // defined(_HOST_64BIT_) && !defined(_TARGET_64BIT_)
1447
1448     SetOperRaw(oper);
1449
1450 #ifdef DEBUG
1451     // Maintain the invariant that unary operators always have NULL gtOp2.
1452     // If we ever start explicitly allocating GenTreeUnOp nodes, we wouldn't be
1453     // able to do that (but if we did, we'd have to have a check in gtOp -- perhaps
1454     // a gtUnOp...)
1455     if (OperKind(oper) == GTK_UNOP)
1456     {
1457         gtOp.gtOp2 = nullptr;
1458     }
1459 #endif // DEBUG
1460
1461 #if DEBUGGABLE_GENTREE
1462     // Until we eliminate SetOper/ChangeOper, we also change the vtable of the node, so that
1463     // it shows up correctly in the debugger.
1464     SetVtableForOper(oper);
1465 #endif // DEBUGGABLE_GENTREE
1466
1467     if (oper == GT_CNS_INT)
1468     {
1469         gtIntCon.gtFieldSeq = nullptr;
1470     }
1471
1472 #if !defined(LEGACY_BACKEND) && defined(_TARGET_ARM_)
1473     if (oper == GT_MUL_LONG)
1474     {
1475         // We sometimes bash GT_MUL to GT_MUL_LONG, which converts it from GenTreeOp to GenTreeMultiRegOp.
1476         gtMultiRegOp.gtOtherReg = REG_NA;
1477         gtMultiRegOp.ClearOtherRegFlags();
1478     }
1479 #endif
1480
1481     if (vnUpdate == CLEAR_VN)
1482     {
1483         // Clear the ValueNum field as well.
1484         gtVNPair.SetBoth(ValueNumStore::NoVN);
1485     }
1486 }
1487
1488 inline GenTreeCast* Compiler::gtNewCastNode(var_types typ, GenTree* op1, bool fromUnsigned, var_types castType)
1489 {
1490     GenTreeCast* res = new (this, GT_CAST) GenTreeCast(typ, op1, fromUnsigned, castType);
1491     return res;
1492 }
1493
1494 inline GenTreeCast* Compiler::gtNewCastNodeL(var_types typ, GenTree* op1, bool fromUnsigned, var_types castType)
1495 {
1496     /* Some casts get transformed into 'GT_CALL' or 'GT_IND' nodes */
1497
1498     assert(GenTree::s_gtNodeSizes[GT_CALL] >= GenTree::s_gtNodeSizes[GT_CAST]);
1499     assert(GenTree::s_gtNodeSizes[GT_CALL] >= GenTree::s_gtNodeSizes[GT_IND]);
1500
1501     /* Make a big node first and then change it to be GT_CAST */
1502
1503     GenTreeCast* res =
1504         new (this, LargeOpOpcode()) GenTreeCast(typ, op1, fromUnsigned, castType DEBUGARG(/*largeNode*/ true));
1505     return res;
1506 }
1507
1508 /*****************************************************************************/
1509 #else // SMALL_TREE_NODES
1510 /*****************************************************************************/
1511
1512 inline void GenTree::InitNodeSize()
1513 {
1514 }
1515
1516 inline void GenTree::SetOper(genTreeOps oper, ValueNumberUpdate vnUpdate)
1517 {
1518     SetOperRaw(oper);
1519
1520     if (vnUpdate == CLEAR_VN)
1521     {
1522         // Clear the ValueNum field.
1523         gtVNPair.SetBoth(ValueNumStore::NoVN);
1524     }
1525 }
1526
1527 inline void GenTree::ReplaceWith(GenTree* src)
1528 {
1529     RecordOperBashing(OperGet(), src->OperGet()); // nop unless NODEBASH_STATS is enabled
1530     *this    = *src;
1531 #ifdef DEBUG
1532     gtSeqNum = 0;
1533 #endif
1534 }
1535
1536 inline GenTree* Compiler::gtNewCastNode(var_types typ, GenTree* op1, var_types castType)
1537 {
1538     GenTree* tree           = gtNewOperNode(GT_CAST, typ, op1);
1539     tree->gtCast.gtCastType = castType;
1540 }
1541
1542 inline GenTree* Compiler::gtNewCastNodeL(var_types typ, GenTree* op1, var_types castType)
1543 {
1544     return gtNewCastNode(typ, op1, castType);
1545 }
1546
1547 /*****************************************************************************/
1548 #endif // SMALL_TREE_NODES
1549 /*****************************************************************************/
1550
1551 /*****************************************************************************/
1552
1553 inline void GenTree::SetOperRaw(genTreeOps oper)
1554 {
1555     // Please do not do anything here other than assign to gtOper (debug-only
1556     // code is OK, but should be kept to a minimum).
1557     RecordOperBashing(OperGet(), oper); // nop unless NODEBASH_STATS is enabled
1558     gtOper = oper;
1559 }
1560
1561 inline void GenTree::SetOperResetFlags(genTreeOps oper)
1562 {
1563     SetOper(oper);
1564     gtFlags &= GTF_NODE_MASK;
1565 }
1566
1567 inline void GenTree::ChangeOperConst(genTreeOps oper)
1568 {
1569 #ifdef _TARGET_64BIT_
1570     assert(oper != GT_CNS_LNG); // We should never see a GT_CNS_LNG for a 64-bit target!
1571 #endif
1572     assert(OperIsConst(oper)); // use ChangeOper() instead
1573     SetOperResetFlags(oper);
1574     // Some constant subtypes have additional fields that must be initialized.
1575     if (oper == GT_CNS_INT)
1576     {
1577         gtIntCon.gtFieldSeq = FieldSeqStore::NotAField();
1578     }
1579 }
1580
1581 inline void GenTree::ChangeOper(genTreeOps oper, ValueNumberUpdate vnUpdate)
1582 {
1583     assert(!OperIsConst(oper)); // use ChangeOperLeaf() instead
1584
1585     unsigned mask = GTF_COMMON_MASK;
1586     if (this->OperIsIndirOrArrLength() && OperIsIndirOrArrLength(oper))
1587     {
1588         mask |= GTF_IND_NONFAULTING;
1589     }
1590     SetOper(oper, vnUpdate);
1591     gtFlags &= mask;
1592
1593     // Do "oper"-specific initializations...
1594     switch (oper)
1595     {
1596         case GT_LCL_FLD:
1597             gtLclFld.gtLclOffs  = 0;
1598             gtLclFld.gtFieldSeq = FieldSeqStore::NotAField();
1599             break;
1600         default:
1601             break;
1602     }
1603 }
1604
1605 inline void GenTree::ChangeOperUnchecked(genTreeOps oper)
1606 {
1607     unsigned mask = GTF_COMMON_MASK;
1608     if (this->OperIsIndirOrArrLength() && OperIsIndirOrArrLength(oper))
1609     {
1610         mask |= GTF_IND_NONFAULTING;
1611     }
1612     SetOperRaw(oper); // Trust the caller and don't use SetOper()
1613     gtFlags &= mask;
1614 }
1615
1616 /*****************************************************************************
1617  * Returns true if the node is &var (created by ldarga and ldloca)
1618  */
1619
1620 inline bool GenTree::IsVarAddr() const
1621 {
1622     if (gtOper == GT_ADDR)
1623     {
1624         if (gtFlags & GTF_ADDR_ONSTACK)
1625         {
1626             assert((gtType == TYP_BYREF) || (gtType == TYP_I_IMPL));
1627             return true;
1628         }
1629     }
1630     return false;
1631 }
1632
1633 /*****************************************************************************
1634  *
1635  * Returns true if the node is of the "ovf" variety, for example, add.ovf.i1.
1636  * + gtOverflow() can only be called for valid operators (that is, we know it is one
1637  *   of the operators which may have GTF_OVERFLOW set).
1638  * + gtOverflowEx() is more expensive, and should be called only if gtOper may be
1639  *   an operator for which GTF_OVERFLOW is invalid.
1640  */
1641
1642 inline bool GenTree::gtOverflow() const
1643 {
1644     assert(OperMayOverflow());
1645
1646     if ((gtFlags & GTF_OVERFLOW) != 0)
1647     {
1648         assert(varTypeIsIntegral(TypeGet()));
1649
1650         return true;
1651     }
1652     else
1653     {
1654         return false;
1655     }
1656 }
1657
1658 inline bool GenTree::gtOverflowEx() const
1659 {
1660     return OperMayOverflow() && gtOverflow();
1661 }
1662
1663 /*
1664 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1665 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1666 XX                          LclVarsInfo                                      XX
1667 XX                      Inline functions                                     XX
1668 XX                                                                           XX
1669 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1670 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1671 */
1672
1673 inline bool Compiler::lvaHaveManyLocals() const
1674 {
1675     return (lvaCount >= lclMAX_TRACKED);
1676 }
1677
1678 /*****************************************************************************
1679  *
1680  *  Allocate a temporary variable or a set of temp variables.
1681  */
1682
1683 inline unsigned Compiler::lvaGrabTemp(bool shortLifetime DEBUGARG(const char* reason))
1684 {
1685     if (compIsForInlining())
1686     {
1687         // Grab the temp using Inliner's Compiler instance.
1688         Compiler* pComp = impInlineInfo->InlinerCompiler; // The Compiler instance for the caller (i.e. the inliner)
1689
1690         if (pComp->lvaHaveManyLocals())
1691         {
1692             // Don't create more LclVar with inlining
1693             compInlineResult->NoteFatal(InlineObservation::CALLSITE_TOO_MANY_LOCALS);
1694         }
1695
1696         unsigned tmpNum = pComp->lvaGrabTemp(shortLifetime DEBUGARG(reason));
1697         lvaTable        = pComp->lvaTable;
1698         lvaCount        = pComp->lvaCount;
1699         lvaTableCnt     = pComp->lvaTableCnt;
1700         return tmpNum;
1701     }
1702
1703     // You cannot allocate more space after frame layout!
1704     noway_assert(lvaDoneFrameLayout < Compiler::TENTATIVE_FRAME_LAYOUT);
1705
1706     /* Check if the lvaTable has to be grown */
1707     if (lvaCount + 1 > lvaTableCnt)
1708     {
1709         unsigned newLvaTableCnt = lvaCount + (lvaCount / 2) + 1;
1710
1711         // Check for overflow
1712         if (newLvaTableCnt <= lvaCount)
1713         {
1714             IMPL_LIMITATION("too many locals");
1715         }
1716
1717         // Note: compGetMemArray might throw.
1718         LclVarDsc* newLvaTable = (LclVarDsc*)compGetMemArray(newLvaTableCnt, sizeof(*lvaTable), CMK_LvaTable);
1719
1720         memcpy(newLvaTable, lvaTable, lvaCount * sizeof(*lvaTable));
1721         memset(newLvaTable + lvaCount, 0, (newLvaTableCnt - lvaCount) * sizeof(*lvaTable));
1722
1723         for (unsigned i = lvaCount; i < newLvaTableCnt; i++)
1724         {
1725             new (&newLvaTable[i], jitstd::placement_t()) LclVarDsc(this); // call the constructor.
1726         }
1727
1728 #ifdef DEBUG
1729         // Fill the old table with junks. So to detect the un-intended use.
1730         memset(lvaTable, JitConfig.JitDefaultFill(), lvaCount * sizeof(*lvaTable));
1731 #endif
1732
1733         lvaTableCnt = newLvaTableCnt;
1734         lvaTable    = newLvaTable;
1735     }
1736
1737     lvaTable[lvaCount].lvType    = TYP_UNDEF; // Initialize lvType, lvIsTemp and lvOnFrame
1738     lvaTable[lvaCount].lvIsTemp  = shortLifetime;
1739     lvaTable[lvaCount].lvOnFrame = true;
1740
1741     unsigned tempNum = lvaCount;
1742
1743     lvaCount++;
1744
1745 #ifdef DEBUG
1746     if (verbose)
1747     {
1748         printf("\nlvaGrabTemp returning %d (", tempNum);
1749         gtDispLclVar(tempNum, false);
1750         printf(")%s called for %s.\n", shortLifetime ? "" : " (a long lifetime temp)", reason);
1751     }
1752 #endif // DEBUG
1753
1754     return tempNum;
1755 }
1756
1757 inline unsigned Compiler::lvaGrabTemps(unsigned cnt DEBUGARG(const char* reason))
1758 {
1759     if (compIsForInlining())
1760     {
1761         // Grab the temps using Inliner's Compiler instance.
1762         unsigned tmpNum = impInlineInfo->InlinerCompiler->lvaGrabTemps(cnt DEBUGARG(reason));
1763
1764         lvaTable    = impInlineInfo->InlinerCompiler->lvaTable;
1765         lvaCount    = impInlineInfo->InlinerCompiler->lvaCount;
1766         lvaTableCnt = impInlineInfo->InlinerCompiler->lvaTableCnt;
1767         return tmpNum;
1768     }
1769
1770 #ifdef DEBUG
1771     if (verbose)
1772     {
1773         printf("\nlvaGrabTemps(%d) returning %d..%d (long lifetime temps) called for %s", cnt, lvaCount,
1774                lvaCount + cnt - 1, reason);
1775     }
1776 #endif
1777
1778     // You cannot allocate more space after frame layout!
1779     noway_assert(lvaDoneFrameLayout < Compiler::TENTATIVE_FRAME_LAYOUT);
1780
1781     /* Check if the lvaTable has to be grown */
1782     if (lvaCount + cnt > lvaTableCnt)
1783     {
1784         unsigned newLvaTableCnt = lvaCount + max(lvaCount / 2 + 1, cnt);
1785
1786         // Check for overflow
1787         if (newLvaTableCnt <= lvaCount)
1788         {
1789             IMPL_LIMITATION("too many locals");
1790         }
1791
1792         // Note: compGetMemArray might throw.
1793         LclVarDsc* newLvaTable = (LclVarDsc*)compGetMemArray(newLvaTableCnt, sizeof(*lvaTable), CMK_LvaTable);
1794
1795         memcpy(newLvaTable, lvaTable, lvaCount * sizeof(*lvaTable));
1796         memset(newLvaTable + lvaCount, 0, (newLvaTableCnt - lvaCount) * sizeof(*lvaTable));
1797         for (unsigned i = lvaCount; i < newLvaTableCnt; i++)
1798         {
1799             new (&newLvaTable[i], jitstd::placement_t()) LclVarDsc(this); // call the constructor.
1800         }
1801
1802 #ifdef DEBUG
1803         // Fill the old table with junks. So to detect the un-intended use.
1804         memset(lvaTable, JitConfig.JitDefaultFill(), lvaCount * sizeof(*lvaTable));
1805 #endif
1806
1807         lvaTableCnt = newLvaTableCnt;
1808         lvaTable    = newLvaTable;
1809     }
1810
1811     unsigned tempNum = lvaCount;
1812
1813     while (cnt--)
1814     {
1815         lvaTable[lvaCount].lvType    = TYP_UNDEF; // Initialize lvType, lvIsTemp and lvOnFrame
1816         lvaTable[lvaCount].lvIsTemp  = false;
1817         lvaTable[lvaCount].lvOnFrame = true;
1818         lvaCount++;
1819     }
1820
1821     return tempNum;
1822 }
1823
1824 /*****************************************************************************
1825  *
1826  *  Allocate a temporary variable which is implicitly used by code-gen
1827  *  There will be no explicit references to the temp, and so it needs to
1828  *  be forced to be kept alive, and not be optimized away.
1829  */
1830
1831 inline unsigned Compiler::lvaGrabTempWithImplicitUse(bool shortLifetime DEBUGARG(const char* reason))
1832 {
1833     if (compIsForInlining())
1834     {
1835         // Grab the temp using Inliner's Compiler instance.
1836         unsigned tmpNum = impInlineInfo->InlinerCompiler->lvaGrabTempWithImplicitUse(shortLifetime DEBUGARG(reason));
1837
1838         lvaTable    = impInlineInfo->InlinerCompiler->lvaTable;
1839         lvaCount    = impInlineInfo->InlinerCompiler->lvaCount;
1840         lvaTableCnt = impInlineInfo->InlinerCompiler->lvaTableCnt;
1841         return tmpNum;
1842     }
1843
1844     unsigned lclNum = lvaGrabTemp(shortLifetime DEBUGARG(reason));
1845
1846     LclVarDsc* varDsc = &lvaTable[lclNum];
1847
1848     // This will prevent it from being optimized away
1849     // TODO-CQ: We shouldn't have to go as far as to declare these
1850     // address-exposed -- DoNotEnregister should suffice?
1851     lvaSetVarAddrExposed(lclNum);
1852
1853     // We need lvRefCnt to be non-zero to prevent various asserts from firing.
1854     varDsc->lvRefCnt    = 1;
1855     varDsc->lvRefCntWtd = BB_UNITY_WEIGHT;
1856
1857     return lclNum;
1858 }
1859
1860 /*****************************************************************************
1861  *
1862  *  If lvaTrackedFixed is false then set the lvaSortAgain flag
1863  *   (this allows us to grow the number of tracked variables)
1864  *   and zero lvRefCntWtd when lvRefCnt is zero
1865  */
1866
1867 inline void LclVarDsc::lvaResetSortAgainFlag(Compiler* comp)
1868 {
1869     if (!comp->lvaTrackedFixed)
1870     {
1871         /* Flag this change, set lvaSortAgain to true */
1872         comp->lvaSortAgain = true;
1873     }
1874     /* Set weighted ref count to zero if  ref count is zero */
1875     if (lvRefCnt == 0)
1876     {
1877         lvRefCntWtd = 0;
1878     }
1879 }
1880
1881 /*****************************************************************************
1882  *
1883  *  Decrement the ref counts for a local variable
1884  */
1885
1886 inline void LclVarDsc::decRefCnts(BasicBlock::weight_t weight, Compiler* comp, bool propagate)
1887 {
1888     /* Decrement lvRefCnt and lvRefCntWtd */
1889     Compiler::lvaPromotionType promotionType = DUMMY_INIT(Compiler::PROMOTION_TYPE_NONE);
1890     if (varTypeIsStruct(lvType))
1891     {
1892         promotionType = comp->lvaGetPromotionType(this);
1893     }
1894
1895     //
1896     // Decrement counts on the local itself.
1897     //
1898     if (lvType != TYP_STRUCT || promotionType != Compiler::PROMOTION_TYPE_INDEPENDENT)
1899     {
1900         assert(lvRefCnt); // Can't decrement below zero
1901
1902         // TODO: Well, the assert above could be bogus.
1903         // If lvRefCnt has overflowed before, then might drop to 0.
1904         // Therefore we do need the following check to keep lvRefCnt from underflow:
1905         if (lvRefCnt > 0)
1906         {
1907             //
1908             // Decrement lvRefCnt
1909             //
1910             lvRefCnt--;
1911
1912             //
1913             // Decrement lvRefCntWtd
1914             //
1915             if (weight != 0)
1916             {
1917                 if (lvIsTemp && (weight * 2 > weight))
1918                 {
1919                     weight *= 2;
1920                 }
1921
1922                 if (lvRefCntWtd <= weight)
1923                 { // Can't go below zero
1924                     lvRefCntWtd = 0;
1925                 }
1926                 else
1927                 {
1928                     lvRefCntWtd -= weight;
1929                 }
1930             }
1931         }
1932     }
1933
1934     if (varTypeIsStruct(lvType) && propagate)
1935     {
1936         // For promoted struct locals, decrement lvRefCnt on its field locals as well.
1937         if (promotionType == Compiler::PROMOTION_TYPE_INDEPENDENT ||
1938             promotionType == Compiler::PROMOTION_TYPE_DEPENDENT)
1939         {
1940             for (unsigned i = lvFieldLclStart; i < lvFieldLclStart + lvFieldCnt; ++i)
1941             {
1942                 comp->lvaTable[i].decRefCnts(comp->lvaMarkRefsWeight, comp, false); // Don't propagate
1943             }
1944         }
1945     }
1946
1947     if (lvIsStructField && propagate)
1948     {
1949         // Depending on the promotion type, decrement the ref count for the parent struct as well.
1950         promotionType           = comp->lvaGetParentPromotionType(this);
1951         LclVarDsc* parentvarDsc = &comp->lvaTable[lvParentLcl];
1952         assert(!parentvarDsc->lvRegStruct);
1953         if (promotionType == Compiler::PROMOTION_TYPE_DEPENDENT)
1954         {
1955             parentvarDsc->decRefCnts(comp->lvaMarkRefsWeight, comp, false); // Don't propagate
1956         }
1957     }
1958
1959     lvaResetSortAgainFlag(comp);
1960
1961 #ifdef DEBUG
1962     if (comp->verbose)
1963     {
1964         unsigned varNum = (unsigned)(this - comp->lvaTable);
1965         assert(&comp->lvaTable[varNum] == this);
1966         printf("New refCnts for V%02u: refCnt = %2u, refCntWtd = %s\n", varNum, lvRefCnt, refCntWtd2str(lvRefCntWtd));
1967     }
1968 #endif
1969 }
1970
1971 /*****************************************************************************
1972  *
1973  *  Increment the ref counts for a local variable
1974  */
1975
1976 inline void LclVarDsc::incRefCnts(BasicBlock::weight_t weight, Compiler* comp, bool propagate)
1977 {
1978     Compiler::lvaPromotionType promotionType = DUMMY_INIT(Compiler::PROMOTION_TYPE_NONE);
1979     if (varTypeIsStruct(lvType))
1980     {
1981         promotionType = comp->lvaGetPromotionType(this);
1982     }
1983
1984     //
1985     // Increment counts on the local itself.
1986     //
1987     if (lvType != TYP_STRUCT || promotionType != Compiler::PROMOTION_TYPE_INDEPENDENT)
1988     {
1989         //
1990         // Increment lvRefCnt
1991         //
1992         int newRefCnt = lvRefCnt + 1;
1993         if (newRefCnt == (unsigned short)newRefCnt) // lvRefCnt is an "unsigned short". Don't overflow it.
1994         {
1995             lvRefCnt = (unsigned short)newRefCnt;
1996         }
1997
1998         // This fires when an uninitialize value for 'weight' is used (see lvaMarkRefsWeight)
1999         assert(weight != 0xdddddddd);
2000         //
2001         // Increment lvRefCntWtd
2002         //
2003         if (weight != 0)
2004         {
2005             // We double the weight of internal temps
2006             //
2007             if (lvIsTemp && (weight * 2 > weight))
2008             {
2009                 weight *= 2;
2010             }
2011
2012             unsigned newWeight = lvRefCntWtd + weight;
2013             if (newWeight >= lvRefCntWtd)
2014             { // lvRefCntWtd is an "unsigned".  Don't overflow it
2015                 lvRefCntWtd = newWeight;
2016             }
2017             else
2018             { // On overflow we assign ULONG_MAX
2019                 lvRefCntWtd = ULONG_MAX;
2020             }
2021         }
2022     }
2023
2024     if (varTypeIsStruct(lvType) && propagate)
2025     {
2026         // For promoted struct locals, increment lvRefCnt on its field locals as well.
2027         if (promotionType == Compiler::PROMOTION_TYPE_INDEPENDENT ||
2028             promotionType == Compiler::PROMOTION_TYPE_DEPENDENT)
2029         {
2030             for (unsigned i = lvFieldLclStart; i < lvFieldLclStart + lvFieldCnt; ++i)
2031             {
2032                 comp->lvaTable[i].incRefCnts(comp->lvaMarkRefsWeight, comp, false); // Don't propagate
2033             }
2034         }
2035     }
2036
2037     if (lvIsStructField && propagate)
2038     {
2039         // Depending on the promotion type, increment the ref count for the parent struct as well.
2040         promotionType           = comp->lvaGetParentPromotionType(this);
2041         LclVarDsc* parentvarDsc = &comp->lvaTable[lvParentLcl];
2042         assert(!parentvarDsc->lvRegStruct);
2043         if (promotionType == Compiler::PROMOTION_TYPE_DEPENDENT)
2044         {
2045             parentvarDsc->incRefCnts(comp->lvaMarkRefsWeight, comp, false); // Don't propagate
2046         }
2047     }
2048
2049     lvaResetSortAgainFlag(comp);
2050
2051 #ifdef DEBUG
2052     if (comp->verbose)
2053     {
2054         unsigned varNum = (unsigned)(this - comp->lvaTable);
2055         assert(&comp->lvaTable[varNum] == this);
2056         printf("New refCnts for V%02u: refCnt = %2u, refCntWtd = %s\n", varNum, lvRefCnt, refCntWtd2str(lvRefCntWtd));
2057     }
2058 #endif
2059 }
2060
2061 /*****************************************************************************
2062  *
2063  *  Set the lvPrefReg field to reg
2064  */
2065
2066 inline void LclVarDsc::setPrefReg(regNumber regNum, Compiler* comp)
2067 {
2068     regMaskTP regMask;
2069     if (isFloatRegType(TypeGet()))
2070     {
2071         // Check for FP struct-promoted field being passed in integer register
2072         //
2073         if (!genIsValidFloatReg(regNum))
2074         {
2075             return;
2076         }
2077         regMask = genRegMaskFloat(regNum, TypeGet());
2078     }
2079     else
2080     {
2081         regMask = genRegMask(regNum);
2082     }
2083
2084 #ifdef _TARGET_ARM_
2085     // Don't set a preferred register for a TYP_STRUCT that takes more than one register slot
2086     if ((TypeGet() == TYP_STRUCT) && (lvSize() > REGSIZE_BYTES))
2087         return;
2088 #endif
2089
2090     /* Only interested if we have a new register bit set */
2091     if (lvPrefReg & regMask)
2092     {
2093         return;
2094     }
2095
2096 #ifdef DEBUG
2097     if (comp->verbose)
2098     {
2099         if (lvPrefReg)
2100         {
2101             printf("Change preferred register for V%02u from ", this - comp->lvaTable);
2102             dspRegMask(lvPrefReg);
2103         }
2104         else
2105         {
2106             printf("Set preferred register for V%02u", this - comp->lvaTable);
2107         }
2108         printf(" to ");
2109         dspRegMask(regMask);
2110         printf("\n");
2111     }
2112 #endif
2113
2114     /* Overwrite the lvPrefReg field */
2115
2116     lvPrefReg = (regMaskSmall)regMask;
2117
2118 #ifdef LEGACY_BACKEND
2119     // This is specific to the classic register allocator.
2120     // While walking the trees during reg predict we set the lvPrefReg mask
2121     // and then re-sort the 'tracked' variable when the lvPrefReg mask changes.
2122     if (lvTracked)
2123     {
2124         /* Flag this change, set lvaSortAgain to true */
2125         comp->lvaSortAgain = true;
2126     }
2127 #endif // LEGACY_BACKEND
2128 }
2129
2130 /*****************************************************************************
2131  *
2132  *  Add regMask to the lvPrefReg field
2133  */
2134
2135 inline void LclVarDsc::addPrefReg(regMaskTP regMask, Compiler* comp)
2136 {
2137     assert(regMask != RBM_NONE);
2138
2139 #ifdef _TARGET_ARM_
2140     // Don't set a preferred register for a TYP_STRUCT that takes more than one register slot
2141     if ((lvType == TYP_STRUCT) && (lvSize() > REGSIZE_BYTES))
2142         return;
2143 #endif
2144
2145     /* Only interested if we have a new register bit set */
2146     if (lvPrefReg & regMask)
2147     {
2148         return;
2149     }
2150
2151 #ifdef DEBUG
2152     if (comp->verbose)
2153     {
2154         if (lvPrefReg)
2155         {
2156             printf("Additional preferred register for V%02u from ", this - comp->lvaTable);
2157             dspRegMask(lvPrefReg);
2158         }
2159         else
2160         {
2161             printf("Set preferred register for V%02u", this - comp->lvaTable);
2162         }
2163         printf(" to ");
2164         dspRegMask(lvPrefReg | regMask);
2165         printf("\n");
2166     }
2167 #endif
2168
2169     /* Update the lvPrefReg field */
2170
2171     lvPrefReg |= regMask;
2172
2173 #ifdef LEGACY_BACKEND
2174     // This is specific to the classic register allocator
2175     // While walking the trees during reg predict we set the lvPrefReg mask
2176     // and then resort the 'tracked' variable when the lvPrefReg mask changes
2177     if (lvTracked)
2178     {
2179         /* Flag this change, set lvaSortAgain to true */
2180         comp->lvaSortAgain = true;
2181     }
2182 #endif // LEGACY_BACKEND
2183 }
2184
2185 /*****************************************************************************
2186  *
2187  *  The following returns the mask of all tracked locals
2188  *  referenced in a statement.
2189  */
2190
2191 inline VARSET_VALRET_TP Compiler::lvaStmtLclMask(GenTree* stmt)
2192 {
2193     GenTree*   tree;
2194     unsigned   varNum;
2195     LclVarDsc* varDsc;
2196     VARSET_TP  lclMask(VarSetOps::MakeEmpty(this));
2197
2198     assert(stmt->gtOper == GT_STMT);
2199     assert(fgStmtListThreaded);
2200
2201     for (tree = stmt->gtStmt.gtStmtList; tree; tree = tree->gtNext)
2202     {
2203         if (tree->gtOper != GT_LCL_VAR)
2204         {
2205             continue;
2206         }
2207
2208         varNum = tree->gtLclVarCommon.gtLclNum;
2209         assert(varNum < lvaCount);
2210         varDsc = lvaTable + varNum;
2211
2212         if (!varDsc->lvTracked)
2213         {
2214             continue;
2215         }
2216
2217         VarSetOps::UnionD(this, lclMask, VarSetOps::MakeSingleton(this, varDsc->lvVarIndex));
2218     }
2219
2220     return lclMask;
2221 }
2222
2223 /*****************************************************************************
2224  * Returns true if the lvType is a TYP_REF or a TYP_BYREF.
2225  * When the lvType is a TYP_STRUCT it searches the GC layout
2226  * of the struct and returns true iff it contains a GC ref.
2227  */
2228
2229 inline bool Compiler::lvaTypeIsGC(unsigned varNum)
2230 {
2231     if (lvaTable[varNum].TypeGet() == TYP_STRUCT)
2232     {
2233         assert(lvaTable[varNum].lvGcLayout != nullptr); // bits are intialized
2234         return (lvaTable[varNum].lvStructGcCount != 0);
2235     }
2236     return (varTypeIsGC(lvaTable[varNum].TypeGet()));
2237 }
2238
2239 /*****************************************************************************
2240  Is this a synchronized instance method? If so, we will need to report "this"
2241  in the GC information, so that the EE can release the object lock
2242  in case of an exception
2243
2244  We also need to report "this" and keep it alive for all shared generic
2245  code that gets the actual generic context from the "this" pointer and
2246  has exception handlers.
2247
2248  For example, if List<T>::m() is shared between T = object and T = string,
2249  then inside m() an exception handler "catch E<T>" needs to be able to fetch
2250  the 'this' pointer to find out what 'T' is in order to tell if we
2251  should catch the exception or not.
2252  */
2253
2254 inline bool Compiler::lvaKeepAliveAndReportThis()
2255 {
2256     if (info.compIsStatic || lvaTable[0].TypeGet() != TYP_REF)
2257     {
2258         return false;
2259     }
2260
2261     const bool genericsContextIsThis = (info.compMethodInfo->options & CORINFO_GENERICS_CTXT_FROM_THIS) != 0;
2262
2263 #ifdef JIT32_GCENCODER
2264
2265     if (info.compFlags & CORINFO_FLG_SYNCH)
2266         return true;
2267
2268     if (genericsContextIsThis)
2269     {
2270         // TODO: Check if any of the exception clauses are
2271         // typed using a generic type. Else, we do not need to report this.
2272         if (info.compXcptnsCount > 0)
2273             return true;
2274
2275         if (opts.compDbgCode)
2276             return true;
2277
2278         if (lvaGenericsContextUseCount > 0)
2279         {
2280             JITDUMP("Reporting this as generic context: %u refs\n", lvaGenericsContextUseCount);
2281             return true;
2282         }
2283     }
2284 #else // !JIT32_GCENCODER
2285     // If the generics context is the this pointer we need to report it if either
2286     // the VM requires us to keep the generics context alive or it is used in a look-up.
2287     // We keep it alive in the lookup scenario, even when the VM didn't ask us to,
2288     // because collectible types need the generics context when gc-ing.
2289     if (genericsContextIsThis)
2290     {
2291         const bool isUsed   = lvaGenericsContextUseCount > 0;
2292         const bool mustKeep = (info.compMethodInfo->options & CORINFO_GENERICS_CTXT_KEEP_ALIVE) != 0;
2293
2294         if (isUsed || mustKeep)
2295         {
2296             JITDUMP("Reporting this as generic context: %u refs%s\n", lvaGenericsContextUseCount,
2297                     mustKeep ? ", must keep" : "");
2298
2299             return true;
2300         }
2301     }
2302 #endif
2303
2304     return false;
2305 }
2306
2307 /*****************************************************************************
2308   Similar to lvaKeepAliveAndReportThis
2309  */
2310
2311 inline bool Compiler::lvaReportParamTypeArg()
2312 {
2313     if (info.compMethodInfo->options & (CORINFO_GENERICS_CTXT_FROM_METHODDESC | CORINFO_GENERICS_CTXT_FROM_METHODTABLE))
2314     {
2315         assert(info.compTypeCtxtArg != -1);
2316
2317         // If the VM requires us to keep the generics context alive and report it (for example, if any catch
2318         // clause catches a type that uses a generic parameter of this method) this flag will be set.
2319         if (info.compMethodInfo->options & CORINFO_GENERICS_CTXT_KEEP_ALIVE)
2320         {
2321             return true;
2322         }
2323
2324         // Otherwise, if an exact type parameter is needed in the body, report the generics context.
2325         // We do this because collectible types needs the generics context when gc-ing.
2326         if (lvaGenericsContextUseCount > 0)
2327         {
2328             return true;
2329         }
2330     }
2331
2332     // Otherwise, we don't need to report it -- the generics context parameter is unused.
2333     return false;
2334 }
2335
2336 //*****************************************************************************
2337
2338 inline int Compiler::lvaCachedGenericContextArgOffset()
2339 {
2340     assert(lvaDoneFrameLayout == FINAL_FRAME_LAYOUT);
2341
2342     return lvaCachedGenericContextArgOffs;
2343 }
2344
2345 /*****************************************************************************
2346  *
2347  *  Return the stack framed offset of the given variable; set *FPbased to
2348  *  true if the variable is addressed off of FP, false if it's addressed
2349  *  off of SP. Note that 'varNum' can be a negated spill-temporary var index.
2350  *
2351  *  mustBeFPBased - strong about whether the base reg is FP. But it is also
2352  *  strong about not being FPBased after FINAL_FRAME_LAYOUT. i.e.,
2353  *  it enforces SP based.
2354  *
2355  *  addrModeOffset - is the addressing mode offset, for example: v02 + 0x10
2356  *  So, V02 itself is at offset sp + 0x10 and then addrModeOffset is what gets
2357  *  added beyond that.
2358  */
2359
2360 inline
2361 #ifdef _TARGET_ARM_
2362     int
2363     Compiler::lvaFrameAddress(int varNum, bool mustBeFPBased, regNumber* pBaseReg, int addrModeOffset)
2364 #else
2365     int
2366     Compiler::lvaFrameAddress(int varNum, bool* pFPbased)
2367 #endif
2368 {
2369     assert(lvaDoneFrameLayout != NO_FRAME_LAYOUT);
2370
2371     int       offset;
2372     bool      FPbased;
2373     bool      fConservative = false;
2374     var_types type          = TYP_UNDEF;
2375     if (varNum >= 0)
2376     {
2377         LclVarDsc* varDsc;
2378
2379         assert((unsigned)varNum < lvaCount);
2380         varDsc               = lvaTable + varNum;
2381         type                 = varDsc->TypeGet();
2382         bool isPrespilledArg = false;
2383 #if defined(_TARGET_ARM_) && defined(PROFILING_SUPPORTED)
2384         isPrespilledArg = varDsc->lvIsParam && compIsProfilerHookNeeded() &&
2385                           lvaIsPreSpilled(varNum, codeGen->regSet.rsMaskPreSpillRegs(false));
2386 #endif
2387
2388         // If we have finished with register allocation, and this isn't a stack-based local,
2389         // check that this has a valid stack location.
2390         if (lvaDoneFrameLayout > REGALLOC_FRAME_LAYOUT && !varDsc->lvOnFrame)
2391         {
2392 #ifdef _TARGET_AMD64_
2393 #ifndef FEATURE_UNIX_AMD64_STRUCT_PASSING
2394             // On amd64, every param has a stack location, except on Unix-like systems.
2395             assert(varDsc->lvIsParam);
2396 #endif // FEATURE_UNIX_AMD64_STRUCT_PASSING
2397 #elif !defined(LEGACY_BACKEND)
2398             // For !LEGACY_BACKEND on other targets, a stack parameter that is enregistered or prespilled
2399             // for profiling on ARM will have a stack location.
2400             assert((varDsc->lvIsParam && !varDsc->lvIsRegArg) || isPrespilledArg);
2401 #else  // !(_TARGET_AMD64 || defined(LEGACY_BACKEND))
2402             // Otherwise, we only have a valid stack location for:
2403             // A parameter that was passed on the stack, being homed into its register home,
2404             // or a prespilled argument on arm under profiler.
2405             assert((varDsc->lvIsParam && !varDsc->lvIsRegArg && varDsc->lvRegister) || isPrespilledArg);
2406 #endif // !(_TARGET_AMD64 || defined(LEGACY_BACKEND))
2407         }
2408
2409         FPbased = varDsc->lvFramePointerBased;
2410
2411 #ifdef DEBUG
2412 #if FEATURE_FIXED_OUT_ARGS
2413         if ((unsigned)varNum == lvaOutgoingArgSpaceVar)
2414         {
2415             assert(FPbased == false);
2416         }
2417         else
2418 #endif
2419         {
2420 #if DOUBLE_ALIGN
2421             assert(FPbased == (isFramePointerUsed() || (genDoubleAlign() && varDsc->lvIsParam && !varDsc->lvIsRegArg)));
2422 #else
2423 #ifdef _TARGET_X86_
2424             assert(FPbased == isFramePointerUsed());
2425 #endif
2426 #endif
2427         }
2428 #endif // DEBUG
2429
2430         offset = varDsc->lvStkOffs;
2431     }
2432     else // Its a spill-temp
2433     {
2434         FPbased = isFramePointerUsed();
2435         if (lvaDoneFrameLayout == Compiler::FINAL_FRAME_LAYOUT)
2436         {
2437             TempDsc* tmpDsc = tmpFindNum(varNum);
2438 #ifndef LEGACY_BACKEND
2439             // The temp might be in use, since this might be during code generation.
2440             if (tmpDsc == nullptr)
2441             {
2442                 tmpDsc = tmpFindNum(varNum, Compiler::TEMP_USAGE_USED);
2443             }
2444 #endif // !LEGACY_BACKEND
2445             assert(tmpDsc != nullptr);
2446             offset = tmpDsc->tdTempOffs();
2447             type   = tmpDsc->tdTempType();
2448         }
2449         else
2450         {
2451             // This value is an estimate until we calculate the
2452             // offset after the final frame layout
2453             // ---------------------------------------------------
2454             //   :                         :
2455             //   +-------------------------+ base --+
2456             //   | LR, ++N for ARM         |        |   frameBaseOffset (= N)
2457             //   +-------------------------+        |
2458             //   | R11, ++N for ARM        | <---FP |
2459             //   +-------------------------+      --+
2460             //   | compCalleeRegsPushed - N|        |   lclFrameOffset
2461             //   +-------------------------+      --+
2462             //   | lclVars                 |        |
2463             //   +-------------------------+        |
2464             //   | tmp[MAX_SPILL_TEMP]     |        |
2465             //   | tmp[1]                  |        |
2466             //   | tmp[0]                  |        |   compLclFrameSize
2467             //   +-------------------------+        |
2468             //   | outgoingArgSpaceSize    |        |
2469             //   +-------------------------+      --+
2470             //   |                         | <---SP
2471             //   :                         :
2472             // ---------------------------------------------------
2473
2474             type          = compFloatingPointUsed ? TYP_FLOAT : TYP_INT;
2475             fConservative = true;
2476             if (!FPbased)
2477             {
2478                 // Worst case stack based offset.
2479                 CLANG_FORMAT_COMMENT_ANCHOR;
2480 #if FEATURE_FIXED_OUT_ARGS
2481                 int outGoingArgSpaceSize = lvaOutgoingArgSpaceSize;
2482 #else
2483                 int outGoingArgSpaceSize = 0;
2484 #endif
2485                 offset = outGoingArgSpaceSize + max(-varNum * TARGET_POINTER_SIZE, (int)lvaGetMaxSpillTempSize());
2486             }
2487             else
2488             {
2489                 // Worst case FP based offset.
2490                 CLANG_FORMAT_COMMENT_ANCHOR;
2491
2492 #ifdef _TARGET_ARM_
2493                 offset = codeGen->genCallerSPtoInitialSPdelta() - codeGen->genCallerSPtoFPdelta();
2494 #else
2495                 offset                   = -(codeGen->genTotalFrameSize());
2496 #endif
2497             }
2498         }
2499     }
2500
2501 #ifdef _TARGET_ARM_
2502     if (FPbased)
2503     {
2504         if (mustBeFPBased)
2505         {
2506             *pBaseReg = REG_FPBASE;
2507         }
2508         // Change the FP-based addressing to the SP-based addressing when possible because
2509         // it generates smaller code on ARM. See frame picture above for the math.
2510         else
2511         {
2512             // If it is the final frame layout phase, we don't have a choice, we should stick
2513             // to either FP based or SP based that we decided in the earlier phase. Because
2514             // we have already selected the instruction. Min-opts will have R10 enabled, so just
2515             // use that.
2516
2517             int spOffset       = fConservative ? compLclFrameSize : offset + codeGen->genSPtoFPdelta();
2518             int actualOffset   = (spOffset + addrModeOffset);
2519             int ldrEncodeLimit = (varTypeIsFloating(type) ? 0x3FC : 0xFFC);
2520             // Use ldr sp imm encoding.
2521             if (lvaDoneFrameLayout == FINAL_FRAME_LAYOUT || opts.MinOpts() || (actualOffset <= ldrEncodeLimit))
2522             {
2523                 offset    = spOffset;
2524                 *pBaseReg = compLocallocUsed ? REG_SAVED_LOCALLOC_SP : REG_SPBASE;
2525             }
2526             // Use ldr +/-imm8 encoding.
2527             else if (offset >= -0x7C && offset <= ldrEncodeLimit)
2528             {
2529                 *pBaseReg = REG_FPBASE;
2530             }
2531             // Use a single movw. prefer locals.
2532             else if (actualOffset <= 0xFFFC) // Fix 383910 ARM ILGEN
2533             {
2534                 offset    = spOffset;
2535                 *pBaseReg = compLocallocUsed ? REG_SAVED_LOCALLOC_SP : REG_SPBASE;
2536             }
2537             // Use movw, movt.
2538             else
2539             {
2540                 *pBaseReg = REG_FPBASE;
2541             }
2542         }
2543     }
2544     else
2545     {
2546         *pBaseReg = REG_SPBASE;
2547     }
2548 #else
2549     *pFPbased                            = FPbased;
2550 #endif
2551
2552     return offset;
2553 }
2554
2555 inline bool Compiler::lvaIsParameter(unsigned varNum)
2556 {
2557     LclVarDsc* varDsc;
2558
2559     assert(varNum < lvaCount);
2560     varDsc = lvaTable + varNum;
2561
2562     return varDsc->lvIsParam;
2563 }
2564
2565 inline bool Compiler::lvaIsRegArgument(unsigned varNum)
2566 {
2567     LclVarDsc* varDsc;
2568
2569     assert(varNum < lvaCount);
2570     varDsc = lvaTable + varNum;
2571
2572     return varDsc->lvIsRegArg;
2573 }
2574
2575 inline BOOL Compiler::lvaIsOriginalThisArg(unsigned varNum)
2576 {
2577     assert(varNum < lvaCount);
2578
2579     BOOL isOriginalThisArg = (varNum == info.compThisArg) && (info.compIsStatic == false);
2580
2581 #ifdef DEBUG
2582     if (isOriginalThisArg)
2583     {
2584         LclVarDsc* varDsc = lvaTable + varNum;
2585         // Should never write to or take the address of the original 'this' arg
2586         CLANG_FORMAT_COMMENT_ANCHOR;
2587
2588 #ifndef JIT32_GCENCODER
2589         // With the general encoder/decoder, when the original 'this' arg is needed as a generics context param, we
2590         // copy to a new local, and mark the original as DoNotEnregister, to
2591         // ensure that it is stack-allocated.  It should not be the case that the original one can be modified -- it
2592         // should not be written to, or address-exposed.
2593         assert(!varDsc->lvHasILStoreOp &&
2594                (!varDsc->lvAddrExposed || ((info.compMethodInfo->options & CORINFO_GENERICS_CTXT_FROM_THIS) != 0)));
2595 #else
2596         assert(!varDsc->lvHasILStoreOp && !varDsc->lvAddrExposed);
2597 #endif
2598     }
2599 #endif
2600
2601     return isOriginalThisArg;
2602 }
2603
2604 inline BOOL Compiler::lvaIsOriginalThisReadOnly()
2605 {
2606     return lvaArg0Var == info.compThisArg;
2607 }
2608
2609 /*****************************************************************************
2610  *
2611  *  The following is used to detect the cases where the same local variable#
2612  *  is used both as a long/double value and a 32-bit value and/or both as an
2613  *  integer/address and a float value.
2614  */
2615
2616 /* static */ inline unsigned Compiler::lvaTypeRefMask(var_types type)
2617 {
2618     const static BYTE lvaTypeRefMasks[] = {
2619 #define DEF_TP(tn, nm, jitType, verType, sz, sze, asze, st, al, tf, howUsed) howUsed,
2620 #include "typelist.h"
2621 #undef DEF_TP
2622     };
2623
2624     assert((unsigned)type < sizeof(lvaTypeRefMasks));
2625     assert(lvaTypeRefMasks[type] != 0);
2626
2627     return lvaTypeRefMasks[type];
2628 }
2629
2630 /*****************************************************************************
2631  *
2632  *  The following is used to detect the cases where the same local variable#
2633  *  is used both as a long/double value and a 32-bit value and/or both as an
2634  *  integer/address and a float value.
2635  */
2636
2637 inline var_types Compiler::lvaGetActualType(unsigned lclNum)
2638 {
2639     return genActualType(lvaGetRealType(lclNum));
2640 }
2641
2642 inline var_types Compiler::lvaGetRealType(unsigned lclNum)
2643 {
2644     return lvaTable[lclNum].TypeGet();
2645 }
2646
2647 /*
2648 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2649 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2650 XX                          Importer                                         XX
2651 XX                      Inline functions                                     XX
2652 XX                                                                           XX
2653 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2654 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2655 */
2656
2657 inline unsigned Compiler::compMapILargNum(unsigned ILargNum)
2658 {
2659     assert(ILargNum < info.compILargsCount || tiVerificationNeeded);
2660
2661     // Note that this works because if compRetBuffArg/compTypeCtxtArg/lvVarargsHandleArg are not present
2662     // they will be BAD_VAR_NUM (MAX_UINT), which is larger than any variable number.
2663     if (ILargNum >= info.compRetBuffArg)
2664     {
2665         ILargNum++;
2666         assert(ILargNum < info.compLocalsCount || tiVerificationNeeded); // compLocals count already adjusted.
2667     }
2668
2669     if (ILargNum >= (unsigned)info.compTypeCtxtArg)
2670     {
2671         ILargNum++;
2672         assert(ILargNum < info.compLocalsCount || tiVerificationNeeded); // compLocals count already adjusted.
2673     }
2674
2675     if (ILargNum >= (unsigned)lvaVarargsHandleArg)
2676     {
2677         ILargNum++;
2678         assert(ILargNum < info.compLocalsCount || tiVerificationNeeded); // compLocals count already adjusted.
2679     }
2680
2681     assert(ILargNum < info.compArgsCount || tiVerificationNeeded);
2682     return (ILargNum);
2683 }
2684
2685 // For ARM varargs, all arguments go in integer registers, so swizzle the type
2686 inline var_types Compiler::mangleVarArgsType(var_types type)
2687 {
2688 #ifdef _TARGET_ARMARCH_
2689     if (info.compIsVarArgs || opts.compUseSoftFP)
2690     {
2691         switch (type)
2692         {
2693             case TYP_FLOAT:
2694                 return TYP_INT;
2695             case TYP_DOUBLE:
2696                 return TYP_LONG;
2697             default:
2698                 break;
2699         }
2700     }
2701 #endif // _TARGET_ARMARCH_
2702     return type;
2703 }
2704
2705 // For CORECLR there is no vararg on System V systems.
2706 #if FEATURE_VARARG
2707 inline regNumber Compiler::getCallArgIntRegister(regNumber floatReg)
2708 {
2709 #ifdef _TARGET_AMD64_
2710     switch (floatReg)
2711     {
2712         case REG_XMM0:
2713             return REG_RCX;
2714         case REG_XMM1:
2715             return REG_RDX;
2716         case REG_XMM2:
2717             return REG_R8;
2718         case REG_XMM3:
2719             return REG_R9;
2720         default:
2721             unreached();
2722     }
2723 #else  // !_TARGET_AMD64_
2724     // How will float args be passed for RyuJIT/x86?
2725     NYI("getCallArgIntRegister for RyuJIT/x86");
2726     return REG_NA;
2727 #endif // !_TARGET_AMD64_
2728 }
2729
2730 inline regNumber Compiler::getCallArgFloatRegister(regNumber intReg)
2731 {
2732 #ifdef _TARGET_AMD64_
2733     switch (intReg)
2734     {
2735         case REG_RCX:
2736             return REG_XMM0;
2737         case REG_RDX:
2738             return REG_XMM1;
2739         case REG_R8:
2740             return REG_XMM2;
2741         case REG_R9:
2742             return REG_XMM3;
2743         default:
2744             unreached();
2745     }
2746 #else  // !_TARGET_AMD64_
2747     // How will float args be passed for RyuJIT/x86?
2748     NYI("getCallArgFloatRegister for RyuJIT/x86");
2749     return REG_NA;
2750 #endif // !_TARGET_AMD64_
2751 }
2752 #endif // FEATURE_VARARG
2753
2754 /*
2755 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2756 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2757 XX                     Register Allocator                                    XX
2758 XX                      Inline functions                                     XX
2759 XX                                                                           XX
2760 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2761 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2762 */
2763
2764 /*****************************************************************************/
2765
2766 inline bool rpCanAsgOperWithoutReg(GenTree* op, bool lclvar)
2767 {
2768     var_types type;
2769
2770     switch (op->OperGet())
2771     {
2772         case GT_CNS_LNG:
2773         case GT_CNS_INT:
2774             return true;
2775         case GT_LCL_VAR:
2776             type = genActualType(op->TypeGet());
2777             if (lclvar && ((type == TYP_INT) || (type == TYP_REF) || (type == TYP_BYREF)))
2778             {
2779                 return true;
2780             }
2781             break;
2782         default:
2783             break;
2784     }
2785
2786     return false;
2787 }
2788
2789 /*
2790 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2791 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2792 XX                                                                           XX
2793 XX                       FlowGraph                                           XX
2794 XX                      Inline functions                                     XX
2795 XX                                                                           XX
2796 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2797 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
2798 */
2799
2800 inline bool Compiler::compCanEncodePtrArgCntMax()
2801 {
2802 #ifdef JIT32_GCENCODER
2803     // DDB 204533:
2804     // The GC encoding for fully interruptible methods does not
2805     // support more than 1023 pushed arguments, so we have to
2806     // use a partially interruptible GC info/encoding.
2807     //
2808     return (fgPtrArgCntMax < MAX_PTRARG_OFS);
2809 #else // JIT32_GCENCODER
2810     return true;
2811 #endif
2812 }
2813
2814 /*****************************************************************************
2815  *
2816  *  Call the given function pointer for all nodes in the tree. The 'visitor'
2817  *  fn should return one of the following values:
2818  *
2819  *  WALK_ABORT          stop walking and return immediately
2820  *  WALK_CONTINUE       continue walking
2821  *  WALK_SKIP_SUBTREES  don't walk any subtrees of the node just visited
2822  *
2823  *  computeStack - true if we want to make stack visible to callback function
2824  */
2825
2826 inline Compiler::fgWalkResult Compiler::fgWalkTreePre(
2827     GenTree** pTree, fgWalkPreFn* visitor, void* callBackData, bool lclVarsOnly, bool computeStack)
2828
2829 {
2830     fgWalkData walkData;
2831
2832     walkData.compiler      = this;
2833     walkData.wtprVisitorFn = visitor;
2834     walkData.pCallbackData = callBackData;
2835     walkData.parent        = nullptr;
2836     walkData.wtprLclsOnly  = lclVarsOnly;
2837 #ifdef DEBUG
2838     walkData.printModified = false;
2839 #endif
2840
2841     fgWalkResult result;
2842     if (lclVarsOnly && computeStack)
2843     {
2844         GenericTreeWalker<true, true, false, true, true> walker(&walkData);
2845         result = walker.WalkTree(pTree, nullptr);
2846     }
2847     else if (lclVarsOnly)
2848     {
2849         GenericTreeWalker<false, true, false, true, true> walker(&walkData);
2850         result = walker.WalkTree(pTree, nullptr);
2851     }
2852     else if (computeStack)
2853     {
2854         GenericTreeWalker<true, true, false, false, true> walker(&walkData);
2855         result = walker.WalkTree(pTree, nullptr);
2856     }
2857     else
2858     {
2859         GenericTreeWalker<false, true, false, false, true> walker(&walkData);
2860         result = walker.WalkTree(pTree, nullptr);
2861     }
2862
2863 #ifdef DEBUG
2864     if (verbose && walkData.printModified)
2865     {
2866         gtDispTree(*pTree);
2867     }
2868 #endif
2869
2870     return result;
2871 }
2872
2873 /*****************************************************************************
2874  *
2875  *  Same as above, except the tree walk is performed in a depth-first fashion,
2876  *  The 'visitor' fn should return one of the following values:
2877  *
2878  *  WALK_ABORT          stop walking and return immediately
2879  *  WALK_CONTINUE       continue walking
2880  *
2881  *  computeStack - true if we want to make stack visible to callback function
2882  */
2883
2884 inline Compiler::fgWalkResult Compiler::fgWalkTreePost(GenTree**     pTree,
2885                                                        fgWalkPostFn* visitor,
2886                                                        void*         callBackData,
2887                                                        bool          computeStack)
2888 {
2889     fgWalkData walkData;
2890
2891     walkData.compiler      = this;
2892     walkData.wtpoVisitorFn = visitor;
2893     walkData.pCallbackData = callBackData;
2894     walkData.parent        = nullptr;
2895
2896     fgWalkResult result;
2897     if (computeStack)
2898     {
2899         GenericTreeWalker<true, false, true, false, true> walker(&walkData);
2900         result = walker.WalkTree(pTree, nullptr);
2901     }
2902     else
2903     {
2904         GenericTreeWalker<false, false, true, false, true> walker(&walkData);
2905         result = walker.WalkTree(pTree, nullptr);
2906     }
2907
2908     assert(result == WALK_CONTINUE || result == WALK_ABORT);
2909
2910     return result;
2911 }
2912
2913 /*****************************************************************************
2914  *
2915  *  Call the given function pointer for all nodes in the tree. The 'visitor'
2916  *  fn should return one of the following values:
2917  *
2918  *  WALK_ABORT          stop walking and return immediately
2919  *  WALK_CONTINUE       continue walking
2920  *  WALK_SKIP_SUBTREES  don't walk any subtrees of the node just visited
2921  */
2922
2923 inline Compiler::fgWalkResult Compiler::fgWalkTree(GenTree**    pTree,
2924                                                    fgWalkPreFn* preVisitor,
2925                                                    fgWalkPreFn* postVisitor,
2926                                                    void*        callBackData)
2927
2928 {
2929     fgWalkData walkData;
2930
2931     walkData.compiler      = this;
2932     walkData.wtprVisitorFn = preVisitor;
2933     walkData.wtpoVisitorFn = postVisitor;
2934     walkData.pCallbackData = callBackData;
2935     walkData.parent        = nullptr;
2936     walkData.wtprLclsOnly  = false;
2937 #ifdef DEBUG
2938     walkData.printModified = false;
2939 #endif
2940
2941     fgWalkResult result;
2942
2943     assert(preVisitor || postVisitor);
2944
2945     if (preVisitor && postVisitor)
2946     {
2947         GenericTreeWalker<true, true, true, false, true> walker(&walkData);
2948         result = walker.WalkTree(pTree, nullptr);
2949     }
2950     else if (preVisitor)
2951     {
2952         GenericTreeWalker<true, true, false, false, true> walker(&walkData);
2953         result = walker.WalkTree(pTree, nullptr);
2954     }
2955     else
2956     {
2957         GenericTreeWalker<true, false, true, false, true> walker(&walkData);
2958         result = walker.WalkTree(pTree, nullptr);
2959     }
2960
2961 #ifdef DEBUG
2962     if (verbose && walkData.printModified)
2963     {
2964         gtDispTree(*pTree);
2965     }
2966 #endif
2967
2968     return result;
2969 }
2970
2971 /*****************************************************************************
2972  *
2973  * Has this block been added to throw an inlined exception
2974  * Returns true if the block was added to throw one of:
2975  *    range-check exception
2976  *    argument exception (used by feature SIMD)
2977  *    argument range-check exception (used by feature SIMD)
2978  *    divide by zero exception  (Not used on X86/X64)
2979  *    null reference exception (Not currently used)
2980  *    overflow exception
2981  */
2982
2983 inline bool Compiler::fgIsThrowHlpBlk(BasicBlock* block)
2984 {
2985     if (!fgIsCodeAdded())
2986     {
2987         return false;
2988     }
2989
2990     if (!(block->bbFlags & BBF_INTERNAL) || block->bbJumpKind != BBJ_THROW)
2991     {
2992         return false;
2993     }
2994
2995     GenTree* call = block->lastNode();
2996
2997 #ifdef DEBUG
2998     if (block->IsLIR())
2999     {
3000         LIR::Range& blockRange = LIR::AsRange(block);
3001         for (LIR::Range::ReverseIterator node = blockRange.rbegin(), end = blockRange.rend(); node != end; ++node)
3002         {
3003             if (node->OperGet() == GT_CALL)
3004             {
3005                 assert(*node == call);
3006                 assert(node == blockRange.rbegin());
3007                 break;
3008             }
3009         }
3010     }
3011 #endif
3012
3013     if (!call || (call->gtOper != GT_CALL))
3014     {
3015         return false;
3016     }
3017
3018     if (!((call->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_RNGCHKFAIL)) ||
3019           (call->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_THROWDIVZERO)) ||
3020           (call->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_THROWNULLREF)) ||
3021           (call->gtCall.gtCallMethHnd == eeFindHelper(CORINFO_HELP_OVERFLOW))))
3022     {
3023         return false;
3024     }
3025
3026     // We can get to this point for blocks that we didn't create as throw helper blocks
3027     // under stress, with crazy flow graph optimizations. So, walk the fgAddCodeList
3028     // for the final determination.
3029
3030     for (AddCodeDsc* add = fgAddCodeList; add; add = add->acdNext)
3031     {
3032         if (block == add->acdDstBlk)
3033         {
3034             return add->acdKind == SCK_RNGCHK_FAIL || add->acdKind == SCK_DIV_BY_ZERO || add->acdKind == SCK_OVERFLOW ||
3035                    add->acdKind == SCK_ARG_EXCPN || add->acdKind == SCK_ARG_RNG_EXCPN;
3036         }
3037     }
3038
3039     // We couldn't find it in the fgAddCodeList
3040     return false;
3041 }
3042
3043 #if !FEATURE_FIXED_OUT_ARGS
3044
3045 /*****************************************************************************
3046  *
3047  *  Return the stackLevel of the inserted block that throws exception
3048  *  (by calling the EE helper).
3049  */
3050
3051 inline unsigned Compiler::fgThrowHlpBlkStkLevel(BasicBlock* block)
3052 {
3053     for (AddCodeDsc* add = fgAddCodeList; add; add = add->acdNext)
3054     {
3055         if (block == add->acdDstBlk)
3056         {
3057             // Compute assert cond separately as assert macro cannot have conditional compilation directives.
3058             bool cond =
3059                 (add->acdKind == SCK_RNGCHK_FAIL || add->acdKind == SCK_DIV_BY_ZERO || add->acdKind == SCK_OVERFLOW ||
3060                  add->acdKind == SCK_ARG_EXCPN || add->acdKind == SCK_ARG_RNG_EXCPN);
3061             assert(cond);
3062
3063             // TODO: bbTgtStkDepth is DEBUG-only.
3064             // Should we use it regularly and avoid this search.
3065             assert(block->bbTgtStkDepth == add->acdStkLvl);
3066             return add->acdStkLvl;
3067         }
3068     }
3069
3070     noway_assert(!"fgThrowHlpBlkStkLevel should only be called if fgIsThrowHlpBlk() is true, but we can't find the "
3071                   "block in the fgAddCodeList list");
3072
3073     /* We couldn't find the basic block: it must not have been a throw helper block */
3074
3075     return 0;
3076 }
3077
3078 #endif // !FEATURE_FIXED_OUT_ARGS
3079
3080 /*
3081     Small inline function to change a given block to a throw block.
3082
3083 */
3084 inline void Compiler::fgConvertBBToThrowBB(BasicBlock* block)
3085 {
3086     // If we're converting a BBJ_CALLFINALLY block to a BBJ_THROW block,
3087     // then mark the subsequent BBJ_ALWAYS block as unreferenced.
3088     if (block->isBBCallAlwaysPair())
3089     {
3090         BasicBlock* leaveBlk = block->bbNext;
3091         noway_assert(leaveBlk->bbJumpKind == BBJ_ALWAYS);
3092
3093         leaveBlk->bbFlags &= ~BBF_DONT_REMOVE;
3094         leaveBlk->bbRefs  = 0;
3095         leaveBlk->bbPreds = nullptr;
3096
3097 #if FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
3098         // This function (fgConvertBBToThrowBB) can be called before the predecessor lists are created (e.g., in
3099         // fgMorph). The fgClearFinallyTargetBit() function to update the BBF_FINALLY_TARGET bit depends on these
3100         // predecessor lists. If there are no predecessor lists, we immediately clear all BBF_FINALLY_TARGET bits
3101         // (to allow subsequent dead code elimination to delete such blocks without asserts), and set a flag to
3102         // recompute them later, before they are required.
3103         if (fgComputePredsDone)
3104         {
3105             fgClearFinallyTargetBit(leaveBlk->bbJumpDest);
3106         }
3107         else
3108         {
3109             fgClearAllFinallyTargetBits();
3110             fgNeedToAddFinallyTargetBits = true;
3111         }
3112 #endif // FEATURE_EH_FUNCLETS && defined(_TARGET_ARM_)
3113     }
3114
3115     block->bbJumpKind = BBJ_THROW;
3116     block->bbSetRunRarely(); // any block with a throw is rare
3117 }
3118
3119 /*****************************************************************************
3120  *
3121  *  Return true if we've added any new basic blocks.
3122  */
3123
3124 inline bool Compiler::fgIsCodeAdded()
3125 {
3126     return fgAddCodeModf;
3127 }
3128
3129 /*****************************************************************************
3130   Is the offset too big?
3131 */
3132 inline bool Compiler::fgIsBigOffset(size_t offset)
3133 {
3134     return (offset > compMaxUncheckedOffsetForNullObject);
3135 }
3136
3137 #if defined(LEGACY_BACKEND)
3138
3139 /***********************************************************************************
3140 *
3141 *  Returns true if back-end will do other than integer division which currently occurs only
3142 *  if "divisor" is a positive integer constant and a power of 2 other than 1 and INT_MIN
3143 */
3144
3145 inline bool Compiler::fgIsSignedDivOptimizable(GenTree* divisor)
3146 {
3147     if (!opts.MinOpts() && divisor->IsCnsIntOrI())
3148     {
3149         ssize_t ival = divisor->gtIntConCommon.IconValue();
3150
3151         /* Is the divisor a power of 2 (excluding INT_MIN) ?.
3152            The intent of the third condition below is to exclude INT_MIN on a 64-bit platform
3153            and during codegen we need to encode ival-1 within 32 bits.  If ival were INT_MIN
3154            then ival-1 would cause underflow.
3155
3156            Note that we could put #ifdef around the third check so that it is applied only on
3157            64-bit platforms but the below is a more generic way to express it as it is a no-op
3158            on 32-bit platforms.
3159          */
3160         return (ival > 0 && genMaxOneBit(ival) && ((ssize_t)(int)ival == ival));
3161     }
3162
3163     return false;
3164 }
3165
3166 /************************************************************************************
3167 *
3168 *  Returns true if back-end will do other than integer division which currently occurs
3169 * if "divisor" is an unsigned integer constant and a power of 2 other than 1 and zero.
3170 */
3171
3172 inline bool Compiler::fgIsUnsignedDivOptimizable(GenTree* divisor)
3173 {
3174     if (!opts.MinOpts() && divisor->IsCnsIntOrI())
3175     {
3176         size_t ival = divisor->gtIntCon.gtIconVal;
3177
3178         /* Is the divisor a power of 2 ? */
3179         return ival && genMaxOneBit(ival);
3180     }
3181
3182     return false;
3183 }
3184
3185 /*****************************************************************************
3186 *
3187 *  Returns true if back-end will do other than integer division which currently occurs
3188 *  if "divisor" is a positive integer constant and a power of 2 other than zero
3189 */
3190
3191 inline bool Compiler::fgIsSignedModOptimizable(GenTree* divisor)
3192 {
3193     if (!opts.MinOpts() && divisor->IsCnsIntOrI())
3194     {
3195         size_t ival = divisor->gtIntCon.gtIconVal;
3196
3197         /* Is the divisor a power of 2  ? */
3198         return ssize_t(ival) > 0 && genMaxOneBit(ival);
3199     }
3200
3201     return false;
3202 }
3203
3204 /*****************************************************************************
3205 *
3206 *  Returns true if back-end will do other than integer division which currently occurs
3207 *  if "divisor" is a positive integer constant and a power of 2 other than zero
3208 */
3209
3210 inline bool Compiler::fgIsUnsignedModOptimizable(GenTree* divisor)
3211 {
3212     if (!opts.MinOpts() && divisor->IsCnsIntOrI())
3213     {
3214         size_t ival = divisor->gtIntCon.gtIconVal;
3215
3216         /* Is the divisor a power of 2  ? */
3217         return ival != 0 && ival == (unsigned)genFindLowestBit(ival);
3218     }
3219
3220     return false;
3221 }
3222
3223 #endif // LEGACY_BACKEND
3224
3225 /*
3226 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3227 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3228 XX                          TempsInfo                                        XX
3229 XX                      Inline functions                                     XX
3230 XX                                                                           XX
3231 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3232 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3233 */
3234
3235 /*****************************************************************************/
3236
3237 /* static */ inline unsigned Compiler::tmpSlot(unsigned size)
3238 {
3239     noway_assert(size >= sizeof(int));
3240     noway_assert(size <= TEMP_MAX_SIZE);
3241     assert((size % sizeof(int)) == 0);
3242
3243     assert(size < UINT32_MAX);
3244     return size / sizeof(int) - 1;
3245 }
3246
3247 /*****************************************************************************
3248  *
3249  *  Finish allocating temps - should be called each time after a pass is made
3250  *  over a function body.
3251  */
3252
3253 inline void Compiler::tmpEnd()
3254 {
3255 #ifdef DEBUG
3256     if (verbose && (tmpCount > 0))
3257     {
3258         printf("%d tmps used\n", tmpCount);
3259     }
3260 #endif // DEBUG
3261 }
3262
3263 /*****************************************************************************
3264  *
3265  *  Shuts down the temp-tracking code. Should be called once per function
3266  *  compiled.
3267  */
3268
3269 inline void Compiler::tmpDone()
3270 {
3271 #ifdef DEBUG
3272     unsigned count;
3273     TempDsc* temp;
3274
3275     assert(tmpAllFree());
3276     for (temp = tmpListBeg(), count = temp ? 1 : 0; temp; temp = tmpListNxt(temp), count += temp ? 1 : 0)
3277     {
3278         assert(temp->tdLegalOffset());
3279     }
3280
3281     // Make sure that all the temps were released
3282     assert(count == tmpCount);
3283     assert(tmpGetCount == 0);
3284 #endif // DEBUG
3285 }
3286
3287 #ifdef DEBUG
3288 inline bool Compiler::shouldUseVerboseTrees()
3289 {
3290     return (JitConfig.JitDumpVerboseTrees() == 1);
3291 }
3292
3293 inline bool Compiler::shouldUseVerboseSsa()
3294 {
3295     return (JitConfig.JitDumpVerboseSsa() == 1);
3296 }
3297
3298 //------------------------------------------------------------------------
3299 // shouldDumpASCIITrees: Should we use only ASCII characters for tree dumps?
3300 //
3301 // Notes:
3302 //    This is set to default to 1 in clrConfigValues.h
3303
3304 inline bool Compiler::shouldDumpASCIITrees()
3305 {
3306     return (JitConfig.JitDumpASCII() == 1);
3307 }
3308
3309 /*****************************************************************************
3310  *  Should we enable JitStress mode?
3311  *   0:   No stress
3312  *   !=2: Vary stress. Performance will be slightly/moderately degraded
3313  *   2:   Check-all stress. Performance will be REALLY horrible
3314  */
3315
3316 inline DWORD getJitStressLevel()
3317 {
3318     return JitConfig.JitStress();
3319 }
3320
3321 /*****************************************************************************
3322  *  Should we do the strict check for non-virtual call to the virtual method?
3323  */
3324
3325 inline DWORD StrictCheckForNonVirtualCallToVirtualMethod()
3326 {
3327     return JitConfig.JitStrictCheckForNonVirtualCallToVirtualMethod() == 1;
3328 }
3329
3330 #endif // DEBUG
3331
3332 /*****************************************************************************/
3333 /* Map a register argument number ("RegArgNum") to a register number ("RegNum").
3334  * A RegArgNum is in this range:
3335  *      [0, MAX_REG_ARG)        -- for integer registers
3336  *      [0, MAX_FLOAT_REG_ARG)  -- for floating point registers
3337  * Note that RegArgNum's are overlapping for integer and floating-point registers,
3338  * while RegNum's are not (for ARM anyway, though for x86, it might be different).
3339  * If we have a fixed return buffer register and are given it's index
3340  * we return the fixed return buffer register
3341  */
3342
3343 inline regNumber genMapIntRegArgNumToRegNum(unsigned argNum)
3344 {
3345     if (hasFixedRetBuffReg() && (argNum == theFixedRetBuffArgNum()))
3346     {
3347         return theFixedRetBuffReg();
3348     }
3349
3350     assert(argNum < ArrLen(intArgRegs));
3351
3352     return intArgRegs[argNum];
3353 }
3354
3355 inline regNumber genMapFloatRegArgNumToRegNum(unsigned argNum)
3356 {
3357 #ifndef _TARGET_X86_
3358     assert(argNum < ArrLen(fltArgRegs));
3359
3360     return fltArgRegs[argNum];
3361 #else
3362     assert(!"no x86 float arg regs\n");
3363     return REG_NA;
3364 #endif
3365 }
3366
3367 __forceinline regNumber genMapRegArgNumToRegNum(unsigned argNum, var_types type)
3368 {
3369     if (varTypeIsFloating(type))
3370     {
3371         return genMapFloatRegArgNumToRegNum(argNum);
3372     }
3373     else
3374     {
3375         return genMapIntRegArgNumToRegNum(argNum);
3376     }
3377 }
3378
3379 /*****************************************************************************/
3380 /* Map a register argument number ("RegArgNum") to a register mask of the associated register.
3381  * Note that for floating-pointer registers, only the low register for a register pair
3382  * (for a double on ARM) is returned.
3383  */
3384
3385 inline regMaskTP genMapIntRegArgNumToRegMask(unsigned argNum)
3386 {
3387     assert(argNum < ArrLen(intArgMasks));
3388
3389     return intArgMasks[argNum];
3390 }
3391
3392 inline regMaskTP genMapFloatRegArgNumToRegMask(unsigned argNum)
3393 {
3394 #ifndef _TARGET_X86_
3395     assert(argNum < ArrLen(fltArgMasks));
3396
3397     return fltArgMasks[argNum];
3398 #else
3399     assert(!"no x86 float arg regs\n");
3400     return RBM_NONE;
3401 #endif
3402 }
3403
3404 __forceinline regMaskTP genMapArgNumToRegMask(unsigned argNum, var_types type)
3405 {
3406     regMaskTP result;
3407     if (varTypeIsFloating(type))
3408     {
3409         result = genMapFloatRegArgNumToRegMask(argNum);
3410 #ifdef _TARGET_ARM_
3411         if (type == TYP_DOUBLE)
3412         {
3413             assert((result & RBM_DBL_REGS) != 0);
3414             result |= (result << 1);
3415         }
3416 #endif
3417     }
3418     else
3419     {
3420         result = genMapIntRegArgNumToRegMask(argNum);
3421     }
3422     return result;
3423 }
3424
3425 /*****************************************************************************/
3426 /* Map a register number ("RegNum") to a register argument number ("RegArgNum")
3427  * If we have a fixed return buffer register we return theFixedRetBuffArgNum
3428  */
3429
3430 inline unsigned genMapIntRegNumToRegArgNum(regNumber regNum)
3431 {
3432     assert(genRegMask(regNum) & fullIntArgRegMask());
3433
3434     switch (regNum)
3435     {
3436         case REG_ARG_0:
3437             return 0;
3438 #if MAX_REG_ARG >= 2
3439         case REG_ARG_1:
3440             return 1;
3441 #if MAX_REG_ARG >= 3
3442         case REG_ARG_2:
3443             return 2;
3444 #if MAX_REG_ARG >= 4
3445         case REG_ARG_3:
3446             return 3;
3447 #if MAX_REG_ARG >= 5
3448         case REG_ARG_4:
3449             return 4;
3450 #if MAX_REG_ARG >= 6
3451         case REG_ARG_5:
3452             return 5;
3453 #if MAX_REG_ARG >= 7
3454         case REG_ARG_6:
3455             return 6;
3456 #if MAX_REG_ARG >= 8
3457         case REG_ARG_7:
3458             return 7;
3459 #endif
3460 #endif
3461 #endif
3462 #endif
3463 #endif
3464 #endif
3465 #endif
3466         default:
3467             // Check for the Arm64 fixed return buffer argument register
3468             if (hasFixedRetBuffReg() && (regNum == theFixedRetBuffReg()))
3469             {
3470                 return theFixedRetBuffArgNum();
3471             }
3472             else
3473             {
3474                 assert(!"invalid register arg register");
3475                 return BAD_VAR_NUM;
3476             }
3477     }
3478 }
3479
3480 inline unsigned genMapFloatRegNumToRegArgNum(regNumber regNum)
3481 {
3482     assert(genRegMask(regNum) & RBM_FLTARG_REGS);
3483
3484 #ifdef _TARGET_ARM_
3485     return regNum - REG_F0;
3486 #elif defined(_TARGET_ARM64_)
3487     return regNum - REG_V0;
3488 #elif defined(UNIX_AMD64_ABI)
3489     return regNum - REG_FLTARG_0;
3490 #else
3491
3492 #if MAX_FLOAT_REG_ARG >= 1
3493     switch (regNum)
3494     {
3495         case REG_FLTARG_0:
3496             return 0;
3497 #if MAX_REG_ARG >= 2
3498         case REG_FLTARG_1:
3499             return 1;
3500 #if MAX_REG_ARG >= 3
3501         case REG_FLTARG_2:
3502             return 2;
3503 #if MAX_REG_ARG >= 4
3504         case REG_FLTARG_3:
3505             return 3;
3506 #if MAX_REG_ARG >= 5
3507         case REG_FLTARG_4:
3508             return 4;
3509 #endif
3510 #endif
3511 #endif
3512 #endif
3513         default:
3514             assert(!"invalid register arg register");
3515             return BAD_VAR_NUM;
3516     }
3517 #else
3518     assert(!"flt reg args not allowed");
3519     return BAD_VAR_NUM;
3520 #endif
3521 #endif // !arm
3522 }
3523
3524 inline unsigned genMapRegNumToRegArgNum(regNumber regNum, var_types type)
3525 {
3526     if (varTypeIsFloating(type))
3527     {
3528         return genMapFloatRegNumToRegArgNum(regNum);
3529     }
3530     else
3531     {
3532         return genMapIntRegNumToRegArgNum(regNum);
3533     }
3534 }
3535
3536 /*****************************************************************************/
3537 /* Return a register mask with the first 'numRegs' argument registers set.
3538  */
3539
3540 inline regMaskTP genIntAllRegArgMask(unsigned numRegs)
3541 {
3542     assert(numRegs <= MAX_REG_ARG);
3543
3544     regMaskTP result = RBM_NONE;
3545     for (unsigned i = 0; i < numRegs; i++)
3546     {
3547         result |= intArgMasks[i];
3548     }
3549     return result;
3550 }
3551
3552 #if !FEATURE_STACK_FP_X87
3553
3554 inline regMaskTP genFltAllRegArgMask(unsigned numRegs)
3555 {
3556     assert(numRegs <= MAX_FLOAT_REG_ARG);
3557
3558     regMaskTP result = RBM_NONE;
3559     for (unsigned i = 0; i < numRegs; i++)
3560     {
3561         result |= fltArgMasks[i];
3562     }
3563     return result;
3564 }
3565
3566 #endif // !FEATURE_STACK_FP_X87
3567
3568 /*
3569 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3570 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3571 XX                          Liveness                                         XX
3572 XX                      Inline functions                                     XX
3573 XX                                                                           XX
3574 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3575 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3576 */
3577
3578 /*****************************************************************************
3579  *
3580  *  Update the current set of live variables based on the life set recorded
3581  *  in the given expression tree node.
3582  */
3583
3584 template <bool ForCodeGen>
3585 inline void Compiler::compUpdateLife(GenTree* tree)
3586 {
3587     // TODO-Cleanup: We shouldn't really be calling this more than once
3588     if (tree == compCurLifeTree)
3589     {
3590         return;
3591     }
3592
3593     if (!tree->OperIsNonPhiLocal() && fgIsIndirOfAddrOfLocal(tree) == nullptr)
3594     {
3595         return;
3596     }
3597
3598     compUpdateLifeVar<ForCodeGen>(tree);
3599 }
3600
3601 template <bool ForCodeGen>
3602 inline void Compiler::compUpdateLife(VARSET_VALARG_TP newLife)
3603 {
3604     if (!VarSetOps::Equal(this, compCurLife, newLife))
3605     {
3606         compChangeLife<ForCodeGen>(newLife);
3607     }
3608 #ifdef DEBUG
3609     else
3610     {
3611         if (verbose)
3612         {
3613             printf("Liveness not changing: %s ", VarSetOps::ToString(this, compCurLife));
3614             dumpConvertedVarSet(this, compCurLife);
3615             printf("\n");
3616         }
3617     }
3618 #endif // DEBUG
3619 }
3620
3621 /*****************************************************************************
3622  *
3623  *  We stash cookies in basic blocks for the code emitter; this call retrieves
3624  *  the cookie associated with the given basic block.
3625  */
3626
3627 inline void* emitCodeGetCookie(BasicBlock* block)
3628 {
3629     assert(block);
3630     return block->bbEmitCookie;
3631 }
3632
3633 /*
3634 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3635 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3636 XX                          Optimizer                                        XX
3637 XX                      Inline functions                                     XX
3638 XX                                                                           XX
3639 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3640 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
3641 */
3642
3643 #if LOCAL_ASSERTION_PROP
3644
3645 /*****************************************************************************
3646  *
3647  *  The following resets the value assignment table
3648  *  used only during local assertion prop
3649  */
3650
3651 inline void Compiler::optAssertionReset(AssertionIndex limit)
3652 {
3653     PREFAST_ASSUME(optAssertionCount <= optMaxAssertionCount);
3654
3655     while (optAssertionCount > limit)
3656     {
3657         AssertionIndex index        = optAssertionCount;
3658         AssertionDsc*  curAssertion = optGetAssertion(index);
3659         optAssertionCount--;
3660         unsigned lclNum = curAssertion->op1.lcl.lclNum;
3661         assert(lclNum < lvaTableCnt);
3662         BitVecOps::RemoveElemD(apTraits, GetAssertionDep(lclNum), index - 1);
3663
3664         //
3665         // Find the Copy assertions
3666         //
3667         if ((curAssertion->assertionKind == OAK_EQUAL) && (curAssertion->op1.kind == O1K_LCLVAR) &&
3668             (curAssertion->op2.kind == O2K_LCLVAR_COPY))
3669         {
3670             //
3671             //  op2.lcl.lclNum no longer depends upon this assertion
3672             //
3673             lclNum = curAssertion->op2.lcl.lclNum;
3674             BitVecOps::RemoveElemD(apTraits, GetAssertionDep(lclNum), index - 1);
3675         }
3676     }
3677     while (optAssertionCount < limit)
3678     {
3679         AssertionIndex index        = ++optAssertionCount;
3680         AssertionDsc*  curAssertion = optGetAssertion(index);
3681         unsigned       lclNum       = curAssertion->op1.lcl.lclNum;
3682         BitVecOps::AddElemD(apTraits, GetAssertionDep(lclNum), index - 1);
3683
3684         //
3685         // Check for Copy assertions
3686         //
3687         if ((curAssertion->assertionKind == OAK_EQUAL) && (curAssertion->op1.kind == O1K_LCLVAR) &&
3688             (curAssertion->op2.kind == O2K_LCLVAR_COPY))
3689         {
3690             //
3691             //  op2.lcl.lclNum now depends upon this assertion
3692             //
3693             lclNum = curAssertion->op2.lcl.lclNum;
3694             BitVecOps::AddElemD(apTraits, GetAssertionDep(lclNum), index - 1);
3695         }
3696     }
3697 }
3698
3699 /*****************************************************************************
3700  *
3701  *  The following removes the i-th entry in the value assignment table
3702  *  used only during local assertion prop
3703  */
3704
3705 inline void Compiler::optAssertionRemove(AssertionIndex index)
3706 {
3707     assert(index > 0);
3708     assert(index <= optAssertionCount);
3709     PREFAST_ASSUME(optAssertionCount <= optMaxAssertionCount);
3710
3711     AssertionDsc* curAssertion = optGetAssertion(index);
3712
3713     //  Two cases to consider if (index == optAssertionCount) then the last
3714     //  entry in the table is to be removed and that happens automatically when
3715     //  optAssertionCount is decremented and we can just clear the optAssertionDep bits
3716     //  The other case is when index < optAssertionCount and here we overwrite the
3717     //  index-th entry in the table with the data found at the end of the table
3718     //  Since we are reordering the rable the optAssertionDep bits need to be recreated
3719     //  using optAssertionReset(0) and optAssertionReset(newAssertionCount) will
3720     //  correctly update the optAssertionDep bits
3721     //
3722     if (index == optAssertionCount)
3723     {
3724         unsigned lclNum = curAssertion->op1.lcl.lclNum;
3725         BitVecOps::RemoveElemD(apTraits, GetAssertionDep(lclNum), index - 1);
3726
3727         //
3728         // Check for Copy assertions
3729         //
3730         if ((curAssertion->assertionKind == OAK_EQUAL) && (curAssertion->op1.kind == O1K_LCLVAR) &&
3731             (curAssertion->op2.kind == O2K_LCLVAR_COPY))
3732         {
3733             //
3734             //  op2.lcl.lclNum no longer depends upon this assertion
3735             //
3736             lclNum = curAssertion->op2.lcl.lclNum;
3737             BitVecOps::RemoveElemD(apTraits, GetAssertionDep(lclNum), index - 1);
3738         }
3739
3740         optAssertionCount--;
3741     }
3742     else
3743     {
3744         AssertionDsc*  lastAssertion     = optGetAssertion(optAssertionCount);
3745         AssertionIndex newAssertionCount = optAssertionCount - 1;
3746
3747         optAssertionReset(0); // This make optAssertionCount equal 0
3748
3749         memcpy(curAssertion,  // the entry to be removed
3750                lastAssertion, // last entry in the table
3751                sizeof(AssertionDsc));
3752
3753         optAssertionReset(newAssertionCount);
3754     }
3755 }
3756 #endif // LOCAL_ASSERTION_PROP
3757
3758 inline void Compiler::LoopDsc::AddModifiedField(Compiler* comp, CORINFO_FIELD_HANDLE fldHnd)
3759 {
3760     if (lpFieldsModified == nullptr)
3761     {
3762         lpFieldsModified =
3763             new (comp->getAllocatorLoopHoist()) Compiler::LoopDsc::FieldHandleSet(comp->getAllocatorLoopHoist());
3764     }
3765     lpFieldsModified->Set(fldHnd, true);
3766 }
3767
3768 inline void Compiler::LoopDsc::AddModifiedElemType(Compiler* comp, CORINFO_CLASS_HANDLE structHnd)
3769 {
3770     if (lpArrayElemTypesModified == nullptr)
3771     {
3772         lpArrayElemTypesModified =
3773             new (comp->getAllocatorLoopHoist()) Compiler::LoopDsc::ClassHandleSet(comp->getAllocatorLoopHoist());
3774     }
3775     lpArrayElemTypesModified->Set(structHnd, true);
3776 }
3777
3778 inline void Compiler::LoopDsc::VERIFY_lpIterTree()
3779 {
3780 #ifdef DEBUG
3781     assert(lpFlags & LPFLG_ITER);
3782
3783     // iterTree should be "lcl <op>= const"
3784
3785     assert(lpIterTree);
3786
3787     assert(lpIterTree->OperIsAssignment());
3788
3789     if (lpIterTree->OperGet() == GT_ASG)
3790     {
3791         GenTree* lhs = lpIterTree->gtOp.gtOp1;
3792         GenTree* rhs = lpIterTree->gtOp.gtOp2;
3793         assert(lhs->OperGet() == GT_LCL_VAR);
3794
3795         switch (rhs->gtOper)
3796         {
3797             case GT_ADD:
3798             case GT_SUB:
3799             case GT_MUL:
3800             case GT_RSH:
3801             case GT_LSH:
3802                 break;
3803             default:
3804                 assert(!"Unknown operator for loop increment");
3805         }
3806         assert(rhs->gtOp.gtOp1->OperGet() == GT_LCL_VAR);
3807         assert(rhs->gtOp.gtOp1->AsLclVarCommon()->GetLclNum() == lhs->AsLclVarCommon()->GetLclNum());
3808         assert(rhs->gtOp.gtOp2->OperGet() == GT_CNS_INT);
3809     }
3810     else
3811     {
3812         assert(lpIterTree->gtOp.gtOp1->OperGet() == GT_LCL_VAR);
3813         assert(lpIterTree->gtOp.gtOp2->OperGet() == GT_CNS_INT);
3814     }
3815 #endif
3816 }
3817
3818 //-----------------------------------------------------------------------------
3819
3820 inline unsigned Compiler::LoopDsc::lpIterVar()
3821 {
3822     VERIFY_lpIterTree();
3823     return lpIterTree->gtOp.gtOp1->gtLclVarCommon.gtLclNum;
3824 }
3825
3826 //-----------------------------------------------------------------------------
3827
3828 inline int Compiler::LoopDsc::lpIterConst()
3829 {
3830     VERIFY_lpIterTree();
3831     if (lpIterTree->OperGet() == GT_ASG)
3832     {
3833         GenTree* rhs = lpIterTree->gtOp.gtOp2;
3834         return (int)rhs->gtOp.gtOp2->gtIntCon.gtIconVal;
3835     }
3836     else
3837     {
3838         return (int)lpIterTree->gtOp.gtOp2->gtIntCon.gtIconVal;
3839     }
3840 }
3841
3842 //-----------------------------------------------------------------------------
3843
3844 inline genTreeOps Compiler::LoopDsc::lpIterOper()
3845 {
3846     VERIFY_lpIterTree();
3847     if (lpIterTree->OperGet() == GT_ASG)
3848     {
3849         GenTree* rhs = lpIterTree->gtOp.gtOp2;
3850         return rhs->OperGet();
3851     }
3852     else
3853     {
3854         return lpIterTree->OperGet();
3855     }
3856 }
3857
3858 inline var_types Compiler::LoopDsc::lpIterOperType()
3859 {
3860     VERIFY_lpIterTree();
3861
3862     var_types type = lpIterTree->TypeGet();
3863     assert(genActualType(type) == TYP_INT);
3864
3865     if ((lpIterTree->gtFlags & GTF_UNSIGNED) && type == TYP_INT)
3866     {
3867         type = TYP_UINT;
3868     }
3869
3870     return type;
3871 }
3872
3873 inline void Compiler::LoopDsc::VERIFY_lpTestTree()
3874 {
3875 #ifdef DEBUG
3876     assert(lpFlags & LPFLG_ITER);
3877     assert(lpTestTree);
3878
3879     genTreeOps oper = lpTestTree->OperGet();
3880     assert(GenTree::OperIsCompare(oper));
3881
3882     GenTree* iterator = nullptr;
3883     GenTree* limit    = nullptr;
3884     if ((lpTestTree->gtOp.gtOp2->gtOper == GT_LCL_VAR) && (lpTestTree->gtOp.gtOp2->gtFlags & GTF_VAR_ITERATOR) != 0)
3885     {
3886         iterator = lpTestTree->gtOp.gtOp2;
3887         limit    = lpTestTree->gtOp.gtOp1;
3888     }
3889     else if ((lpTestTree->gtOp.gtOp1->gtOper == GT_LCL_VAR) &&
3890              (lpTestTree->gtOp.gtOp1->gtFlags & GTF_VAR_ITERATOR) != 0)
3891     {
3892         iterator = lpTestTree->gtOp.gtOp1;
3893         limit    = lpTestTree->gtOp.gtOp2;
3894     }
3895     else
3896     {
3897         // one of the nodes has to be the iterator
3898         assert(false);
3899     }
3900
3901     if (lpFlags & LPFLG_CONST_LIMIT)
3902     {
3903         assert(limit->OperIsConst());
3904     }
3905     if (lpFlags & LPFLG_VAR_LIMIT)
3906     {
3907         assert(limit->OperGet() == GT_LCL_VAR);
3908     }
3909     if (lpFlags & LPFLG_ARRLEN_LIMIT)
3910     {
3911         assert(limit->OperGet() == GT_ARR_LENGTH);
3912     }
3913 #endif
3914 }
3915
3916 //-----------------------------------------------------------------------------
3917
3918 inline bool Compiler::LoopDsc::lpIsReversed()
3919 {
3920     VERIFY_lpTestTree();
3921     return ((lpTestTree->gtOp.gtOp2->gtOper == GT_LCL_VAR) &&
3922             (lpTestTree->gtOp.gtOp2->gtFlags & GTF_VAR_ITERATOR) != 0);
3923 }
3924
3925 //-----------------------------------------------------------------------------
3926
3927 inline genTreeOps Compiler::LoopDsc::lpTestOper()
3928 {
3929     VERIFY_lpTestTree();
3930     genTreeOps op = lpTestTree->OperGet();
3931     return lpIsReversed() ? GenTree::SwapRelop(op) : op;
3932 }
3933
3934 //-----------------------------------------------------------------------------
3935
3936 inline GenTree* Compiler::LoopDsc::lpIterator()
3937 {
3938     VERIFY_lpTestTree();
3939
3940     return lpIsReversed() ? lpTestTree->gtOp.gtOp2 : lpTestTree->gtOp.gtOp1;
3941 }
3942
3943 //-----------------------------------------------------------------------------
3944
3945 inline GenTree* Compiler::LoopDsc::lpLimit()
3946 {
3947     VERIFY_lpTestTree();
3948
3949     return lpIsReversed() ? lpTestTree->gtOp.gtOp1 : lpTestTree->gtOp.gtOp2;
3950 }
3951
3952 //-----------------------------------------------------------------------------
3953
3954 inline int Compiler::LoopDsc::lpConstLimit()
3955 {
3956     VERIFY_lpTestTree();
3957     assert(lpFlags & LPFLG_CONST_LIMIT);
3958
3959     GenTree* limit = lpLimit();
3960     assert(limit->OperIsConst());
3961     return (int)limit->gtIntCon.gtIconVal;
3962 }
3963
3964 //-----------------------------------------------------------------------------
3965
3966 inline unsigned Compiler::LoopDsc::lpVarLimit()
3967 {
3968     VERIFY_lpTestTree();
3969     assert(lpFlags & LPFLG_VAR_LIMIT);
3970
3971     GenTree* limit = lpLimit();
3972     assert(limit->OperGet() == GT_LCL_VAR);
3973     return limit->gtLclVarCommon.gtLclNum;
3974 }
3975
3976 //-----------------------------------------------------------------------------
3977
3978 inline bool Compiler::LoopDsc::lpArrLenLimit(Compiler* comp, ArrIndex* index)
3979 {
3980     VERIFY_lpTestTree();
3981     assert(lpFlags & LPFLG_ARRLEN_LIMIT);
3982
3983     GenTree* limit = lpLimit();
3984     assert(limit->OperGet() == GT_ARR_LENGTH);
3985
3986     // Check if we have a.length or a[i][j].length
3987     if (limit->gtArrLen.ArrRef()->gtOper == GT_LCL_VAR)
3988     {
3989         index->arrLcl = limit->gtArrLen.ArrRef()->gtLclVarCommon.gtLclNum;
3990         index->rank   = 0;
3991         return true;
3992     }
3993     // We have a[i].length, extract a[i] pattern.
3994     else if (limit->gtArrLen.ArrRef()->gtOper == GT_COMMA)
3995     {
3996         return comp->optReconstructArrIndex(limit->gtArrLen.ArrRef(), index, BAD_VAR_NUM);
3997     }
3998     return false;
3999 }
4000
4001 /*****************************************************************************
4002  *  Is "var" assigned in the loop "lnum" ?
4003  */
4004
4005 inline bool Compiler::optIsVarAssgLoop(unsigned lnum, unsigned var)
4006 {
4007     assert(lnum < optLoopCount);
4008     if (var < lclMAX_ALLSET_TRACKED)
4009     {
4010         ALLVARSET_TP vs(AllVarSetOps::MakeSingleton(this, var));
4011         return optIsSetAssgLoop(lnum, vs) != 0;
4012     }
4013     else
4014     {
4015         return optIsVarAssigned(optLoopTable[lnum].lpHead->bbNext, optLoopTable[lnum].lpBottom, nullptr, var);
4016     }
4017 }
4018
4019 /*****************************************************************************
4020  * If the tree is a tracked local variable, return its LclVarDsc ptr.
4021  */
4022
4023 inline LclVarDsc* Compiler::optIsTrackedLocal(GenTree* tree)
4024 {
4025     LclVarDsc* varDsc;
4026     unsigned   lclNum;
4027
4028     if (tree->gtOper != GT_LCL_VAR)
4029     {
4030         return nullptr;
4031     }
4032
4033     lclNum = tree->gtLclVarCommon.gtLclNum;
4034
4035     assert(lclNum < lvaCount);
4036     varDsc = lvaTable + lclNum;
4037
4038     /* if variable not tracked, return NULL */
4039     if (!varDsc->lvTracked)
4040     {
4041         return nullptr;
4042     }
4043
4044     return varDsc;
4045 }
4046
4047 /*
4048 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
4049 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
4050 XX                                                                           XX
4051 XX                Optimization activation rules                              XX
4052 XX                                                                           XX
4053 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
4054 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
4055 */
4056
4057 // are we compiling for fast code, or are we compiling for blended code and
4058 // inside a loop?
4059 // We return true for BLENDED_CODE if the Block executes more than BB_LOOP_WEIGHT/2
4060 inline bool Compiler::optFastCodeOrBlendedLoop(BasicBlock::weight_t bbWeight)
4061 {
4062     return (compCodeOpt() == FAST_CODE) ||
4063            ((compCodeOpt() == BLENDED_CODE) && (bbWeight > (BB_LOOP_WEIGHT / 2 * BB_UNITY_WEIGHT)));
4064 }
4065
4066 // are we running on a Intel Pentium 4?
4067 inline bool Compiler::optPentium4(void)
4068 {
4069     return (info.genCPU == CPU_X86_PENTIUM_4);
4070 }
4071
4072 // should we use add/sub instead of inc/dec? (faster on P4, but increases size)
4073 inline bool Compiler::optAvoidIncDec(BasicBlock::weight_t bbWeight)
4074 {
4075     return optPentium4() && optFastCodeOrBlendedLoop(bbWeight);
4076 }
4077
4078 // should we try to replace integer multiplication with lea/add/shift sequences?
4079 inline bool Compiler::optAvoidIntMult(void)
4080 {
4081     return (compCodeOpt() != SMALL_CODE);
4082 }
4083
4084 /*
4085 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
4086 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
4087 XX                          EEInterface                                      XX
4088 XX                      Inline functions                                     XX
4089 XX                                                                           XX
4090 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
4091 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
4092 */
4093
4094 extern var_types JITtype2varType(CorInfoType type);
4095
4096 #include "ee_il_dll.hpp"
4097
4098 inline CORINFO_METHOD_HANDLE Compiler::eeFindHelper(unsigned helper)
4099 {
4100     assert(helper < CORINFO_HELP_COUNT);
4101
4102     /* Helpers are marked by the fact that they are odd numbers
4103      * force this to be an odd number (will shift it back to extract) */
4104
4105     return ((CORINFO_METHOD_HANDLE)(size_t)((helper << 2) + 1));
4106 }
4107
4108 inline CorInfoHelpFunc Compiler::eeGetHelperNum(CORINFO_METHOD_HANDLE method)
4109 {
4110     // Helpers are marked by the fact that they are odd numbers
4111     if (!(((size_t)method) & 1))
4112     {
4113         return (CORINFO_HELP_UNDEF);
4114     }
4115     return ((CorInfoHelpFunc)(((size_t)method) >> 2));
4116 }
4117
4118 inline Compiler::fgWalkResult Compiler::CountSharedStaticHelper(GenTree** pTree, fgWalkData* data)
4119 {
4120     if (Compiler::IsSharedStaticHelper(*pTree))
4121     {
4122         int* pCount = (int*)data->pCallbackData;
4123         (*pCount)++;
4124     }
4125
4126     return WALK_CONTINUE;
4127 }
4128
4129 //  TODO-Cleanup: Replace calls to IsSharedStaticHelper with new HelperCallProperties
4130 //
4131
4132 inline bool Compiler::IsSharedStaticHelper(GenTree* tree)
4133 {
4134     if (tree->gtOper != GT_CALL || tree->gtCall.gtCallType != CT_HELPER)
4135     {
4136         return false;
4137     }
4138
4139     CorInfoHelpFunc helper = eeGetHelperNum(tree->gtCall.gtCallMethHnd);
4140
4141     bool result1 =
4142         // More helpers being added to IsSharedStaticHelper (that have similar behaviors but are not true
4143         // ShareStaticHelperts)
4144         helper == CORINFO_HELP_STRCNS || helper == CORINFO_HELP_BOX ||
4145
4146         // helpers being added to IsSharedStaticHelper
4147         helper == CORINFO_HELP_GETSTATICFIELDADDR_CONTEXT || helper == CORINFO_HELP_GETSTATICFIELDADDR_TLS ||
4148         helper == CORINFO_HELP_GETGENERICS_GCSTATIC_BASE || helper == CORINFO_HELP_GETGENERICS_NONGCSTATIC_BASE ||
4149         helper == CORINFO_HELP_GETGENERICS_GCTHREADSTATIC_BASE ||
4150         helper == CORINFO_HELP_GETGENERICS_NONGCTHREADSTATIC_BASE ||
4151
4152         helper == CORINFO_HELP_GETSHARED_GCSTATIC_BASE || helper == CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE ||
4153         helper == CORINFO_HELP_GETSHARED_GCSTATIC_BASE_NOCTOR ||
4154         helper == CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE_NOCTOR ||
4155         helper == CORINFO_HELP_GETSHARED_GCSTATIC_BASE_DYNAMICCLASS ||
4156         helper == CORINFO_HELP_GETSHARED_NONGCSTATIC_BASE_DYNAMICCLASS ||
4157         helper == CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE ||
4158         helper == CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE ||
4159         helper == CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_NOCTOR ||
4160         helper == CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_NOCTOR ||
4161         helper == CORINFO_HELP_GETSHARED_GCTHREADSTATIC_BASE_DYNAMICCLASS ||
4162         helper == CORINFO_HELP_GETSHARED_NONGCTHREADSTATIC_BASE_DYNAMICCLASS ||
4163 #ifdef FEATURE_READYTORUN_COMPILER
4164         helper == CORINFO_HELP_READYTORUN_STATIC_BASE || helper == CORINFO_HELP_READYTORUN_GENERIC_STATIC_BASE ||
4165 #endif
4166         helper == CORINFO_HELP_CLASSINIT_SHARED_DYNAMICCLASS;
4167 #if 0
4168     // See above TODO-Cleanup
4169     bool result2 = s_helperCallProperties.IsPure(helper) && s_helperCallProperties.NonNullReturn(helper);
4170     assert (result1 == result2);
4171 #endif
4172     return result1;
4173 }
4174
4175 inline bool Compiler::IsTreeAlwaysHoistable(GenTree* tree)
4176 {
4177     if (IsSharedStaticHelper(tree))
4178     {
4179         return (GTF_CALL_HOISTABLE & tree->gtFlags) ? true : false;
4180     }
4181     else
4182     {
4183         return false;
4184     }
4185 }
4186
4187 inline bool Compiler::IsGcSafePoint(GenTree* tree)
4188 {
4189     if (tree->IsCall())
4190     {
4191         GenTreeCall* call = tree->AsCall();
4192         if (!call->IsFastTailCall())
4193         {
4194             if (call->gtCallType == CT_INDIRECT)
4195             {
4196                 return true;
4197             }
4198             else if (call->gtCallType == CT_USER_FUNC)
4199             {
4200                 if ((call->gtCallMoreFlags & GTF_CALL_M_NOGCCHECK) == 0)
4201                 {
4202                     return true;
4203                 }
4204             }
4205             // otherwise we have a CT_HELPER
4206         }
4207     }
4208
4209     return false;
4210 }
4211
4212 //
4213 // Note that we want to have two special FIELD_HANDLES that will both
4214 // be considered non-Data Offset handles
4215 //
4216 // The special values that we use are FLD_GLOBAL_DS and FLD_GLOBAL_FS
4217 //
4218
4219 inline bool jitStaticFldIsGlobAddr(CORINFO_FIELD_HANDLE fldHnd)
4220 {
4221     return (fldHnd == FLD_GLOBAL_DS || fldHnd == FLD_GLOBAL_FS);
4222 }
4223
4224 #if defined(DEBUG) || defined(FEATURE_JIT_METHOD_PERF) || defined(FEATURE_SIMD) || defined(FEATURE_TRACELOGGING)
4225
4226 inline bool Compiler::eeIsNativeMethod(CORINFO_METHOD_HANDLE method)
4227 {
4228     return ((((size_t)method) & 0x2) == 0x2);
4229 }
4230
4231 inline CORINFO_METHOD_HANDLE Compiler::eeGetMethodHandleForNative(CORINFO_METHOD_HANDLE method)
4232 {
4233     assert((((size_t)method) & 0x3) == 0x2);
4234     return (CORINFO_METHOD_HANDLE)(((size_t)method) & ~0x3);
4235 }
4236 #endif
4237
4238 inline CORINFO_METHOD_HANDLE Compiler::eeMarkNativeTarget(CORINFO_METHOD_HANDLE method)
4239 {
4240     assert((((size_t)method) & 0x3) == 0);
4241     if (method == nullptr)
4242     {
4243         return method;
4244     }
4245     else
4246     {
4247         return (CORINFO_METHOD_HANDLE)(((size_t)method) | 0x2);
4248     }
4249 }
4250
4251 /*
4252 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
4253 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
4254 XX                          Compiler                                         XX
4255 XX                      Inline functions                                     XX
4256 XX                                                                           XX
4257 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
4258 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
4259 */
4260
4261 #ifndef DEBUG
4262 inline bool Compiler::compStressCompile(compStressArea stressArea, unsigned weightPercentage)
4263 {
4264     return false;
4265 }
4266 #endif
4267
4268 inline ArenaAllocator* Compiler::compGetAllocator()
4269 {
4270     return compAllocator;
4271 }
4272
4273 /*****************************************************************************
4274  *
4275  *  Allocate memory from the no-release allocator. All such memory will be
4276  *  freed up simulataneously at the end of the procedure
4277  */
4278
4279 #ifndef DEBUG
4280
4281 inline void* Compiler::compGetMem(size_t sz, CompMemKind cmk)
4282 {
4283     assert(sz);
4284
4285 #if MEASURE_MEM_ALLOC
4286     genMemStats.AddAlloc(sz, cmk);
4287 #endif
4288
4289     return compAllocator->allocateMemory(sz);
4290 }
4291
4292 #endif
4293
4294 // Wrapper for Compiler::compGetMem that can be forward-declared for use in template
4295 // types which Compiler depends on but which need to allocate heap memory.
4296 inline void* compGetMem(Compiler* comp, size_t sz)
4297 {
4298     return comp->compGetMem(sz);
4299 }
4300
4301 /*****************************************************************************
4302  *
4303  * A common memory allocation for arrays of structures involves the
4304  * multiplication of the number of elements with the size of each element.
4305  * If this computation overflows, then the memory allocation might succeed,
4306  * but not allocate sufficient memory for all the elements.  This can cause
4307  * us to overwrite the allocation, and AV or worse, corrupt memory.
4308  *
4309  * This method checks for overflow, and succeeds only when it detects
4310  * that there's no overflow.  It should be cheap, because when inlined with
4311  * a constant elemSize, the division should be done in compile time, and so
4312  * at run time we simply have a check of numElem against some number (this
4313  * is why we __forceinline).
4314  */
4315
4316 #define MAX_MEMORY_PER_ALLOCATION (512 * 1024 * 1024)
4317
4318 __forceinline void* Compiler::compGetMemArray(size_t numElem, size_t elemSize, CompMemKind cmk)
4319 {
4320     if (numElem > (MAX_MEMORY_PER_ALLOCATION / elemSize))
4321     {
4322         NOMEM();
4323     }
4324
4325     return compGetMem(numElem * elemSize, cmk);
4326 }
4327
4328 /******************************************************************************
4329  *
4330  *  Roundup the allocated size so that if this memory block is aligned,
4331  *  then the next block allocated too will be aligned.
4332  *  The JIT will always try to keep all the blocks aligned.
4333  */
4334
4335 inline void Compiler::compFreeMem(void* ptr)
4336 {
4337 }
4338
4339 inline bool Compiler::compIsProfilerHookNeeded()
4340 {
4341 #ifdef PROFILING_SUPPORTED
4342     return compProfilerHookNeeded
4343            // IL stubs are excluded by VM and we need to do the same even running
4344            // under a complus env hook to generate profiler hooks
4345            || (opts.compJitELTHookEnabled && !opts.jitFlags->IsSet(JitFlags::JIT_FLAG_IL_STUB));
4346 #else  // !PROFILING_SUPPORTED
4347     return false;
4348 #endif // !PROFILING_SUPPORTED
4349 }
4350
4351 /*****************************************************************************
4352  *
4353  *  Check for the special case where the object is the constant 0.
4354  *  As we can't even fold the tree (null+fldOffs), we are left with
4355  *  op1 and op2 both being a constant. This causes lots of problems.
4356  *  We simply grab a temp and assign 0 to it and use it in place of the NULL.
4357  */
4358
4359 inline GenTree* Compiler::impCheckForNullPointer(GenTree* obj)
4360 {
4361     /* If it is not a GC type, we will be able to fold it.
4362        So don't need to do anything */
4363
4364     if (!varTypeIsGC(obj->TypeGet()))
4365     {
4366         return obj;
4367     }
4368
4369     if (obj->gtOper == GT_CNS_INT)
4370     {
4371         assert(obj->gtType == TYP_REF || obj->gtType == TYP_BYREF);
4372
4373         // We can see non-zero byrefs for RVA statics.
4374         if (obj->gtIntCon.gtIconVal != 0)
4375         {
4376             assert(obj->gtType == TYP_BYREF);
4377             return obj;
4378         }
4379
4380         unsigned tmp = lvaGrabTemp(true DEBUGARG("CheckForNullPointer"));
4381
4382         // We don't need to spill while appending as we are only assigning
4383         // NULL to a freshly-grabbed temp.
4384
4385         impAssignTempGen(tmp, obj, (unsigned)CHECK_SPILL_NONE);
4386
4387         obj = gtNewLclvNode(tmp, obj->gtType);
4388     }
4389
4390     return obj;
4391 }
4392
4393 /*****************************************************************************
4394  *
4395  *  Check for the special case where the object is the methods original 'this' pointer.
4396  *  Note that, the original 'this' pointer is always local var 0 for non-static method,
4397  *  even if we might have created the copy of 'this' pointer in lvaArg0Var.
4398  */
4399
4400 inline bool Compiler::impIsThis(GenTree* obj)
4401 {
4402     if (compIsForInlining())
4403     {
4404         return impInlineInfo->InlinerCompiler->impIsThis(obj);
4405     }
4406     else
4407     {
4408         return ((obj != nullptr) && (obj->gtOper == GT_LCL_VAR) && lvaIsOriginalThisArg(obj->gtLclVarCommon.gtLclNum));
4409     }
4410 }
4411
4412 /*****************************************************************************
4413  *
4414  *  Check to see if the delegate is created using "LDFTN <TOK>" or not.
4415  */
4416
4417 inline bool Compiler::impIsLDFTN_TOKEN(const BYTE* delegateCreateStart, const BYTE* newobjCodeAddr)
4418 {
4419     assert(newobjCodeAddr[0] == CEE_NEWOBJ);
4420     return (newobjCodeAddr - delegateCreateStart == 6 && // LDFTN <TOK> takes 6 bytes
4421             delegateCreateStart[0] == CEE_PREFIX1 && delegateCreateStart[1] == (CEE_LDFTN & 0xFF));
4422 }
4423
4424 /*****************************************************************************
4425  *
4426  *  Check to see if the delegate is created using "DUP LDVIRTFTN <TOK>" or not.
4427  */
4428
4429 inline bool Compiler::impIsDUP_LDVIRTFTN_TOKEN(const BYTE* delegateCreateStart, const BYTE* newobjCodeAddr)
4430 {
4431     assert(newobjCodeAddr[0] == CEE_NEWOBJ);
4432     return (newobjCodeAddr - delegateCreateStart == 7 && // DUP LDVIRTFTN <TOK> takes 6 bytes
4433             delegateCreateStart[0] == CEE_DUP && delegateCreateStart[1] == CEE_PREFIX1 &&
4434             delegateCreateStart[2] == (CEE_LDVIRTFTN & 0xFF));
4435 }
4436 /*****************************************************************************
4437  *
4438  * Returns true if the compiler instance is created for import only (verification).
4439  */
4440
4441 inline bool Compiler::compIsForImportOnly()
4442 {
4443     return opts.jitFlags->IsSet(JitFlags::JIT_FLAG_IMPORT_ONLY);
4444 }
4445
4446 /*****************************************************************************
4447  *
4448  *  Returns true if the compiler instance is created for inlining.
4449  */
4450
4451 inline bool Compiler::compIsForInlining()
4452 {
4453     return (impInlineInfo != nullptr);
4454 }
4455
4456 /*****************************************************************************
4457  *
4458  *  Check the inline result field in the compiler to see if inlining failed or not.
4459  */
4460
4461 inline bool Compiler::compDonotInline()
4462 {
4463     if (compIsForInlining())
4464     {
4465         assert(compInlineResult != nullptr);
4466         return compInlineResult->IsFailure();
4467     }
4468     else
4469     {
4470         return false;
4471     }
4472 }
4473
4474 inline bool Compiler::impIsPrimitive(CorInfoType jitType)
4475 {
4476     return ((CORINFO_TYPE_BOOL <= jitType && jitType <= CORINFO_TYPE_DOUBLE) || jitType == CORINFO_TYPE_PTR);
4477 }
4478
4479 /*****************************************************************************
4480  *
4481  *  Get the promotion type of a struct local.
4482  */
4483
4484 inline Compiler::lvaPromotionType Compiler::lvaGetPromotionType(const LclVarDsc* varDsc)
4485 {
4486     assert(!varDsc->lvPromoted || varTypeIsPromotable(varDsc) || varDsc->lvUnusedStruct);
4487
4488     if (!varDsc->lvPromoted)
4489     {
4490         // no struct promotion for this LclVar
4491         return PROMOTION_TYPE_NONE;
4492     }
4493     if (varDsc->lvDoNotEnregister)
4494     {
4495         // The struct is not enregistered
4496         return PROMOTION_TYPE_DEPENDENT;
4497     }
4498     if (!varDsc->lvIsParam)
4499     {
4500         // The struct is a register candidate
4501         return PROMOTION_TYPE_INDEPENDENT;
4502     }
4503
4504     // Has struct promotion for arguments been disabled using COMPlus_JitNoStructPromotion=2
4505     if (fgNoStructParamPromotion)
4506     {
4507         // The struct parameter is not enregistered
4508         return PROMOTION_TYPE_DEPENDENT;
4509     }
4510
4511     // We have a parameter that could be enregistered
4512     CLANG_FORMAT_COMMENT_ANCHOR;
4513
4514 #if defined(_TARGET_AMD64_) || defined(_TARGET_ARM64_)
4515
4516     // The struct parameter is a register candidate
4517     return PROMOTION_TYPE_INDEPENDENT;
4518 #else
4519     // The struct parameter is not enregistered
4520     return PROMOTION_TYPE_DEPENDENT;
4521 #endif
4522 }
4523
4524 /*****************************************************************************
4525  *
4526  *  Get the promotion type of a struct local.
4527  */
4528
4529 inline Compiler::lvaPromotionType Compiler::lvaGetPromotionType(unsigned varNum)
4530 {
4531     assert(varNum < lvaCount);
4532     return lvaGetPromotionType(&lvaTable[varNum]);
4533 }
4534
4535 /*****************************************************************************
4536  *
4537  *  Given a field local, get the promotion type of its parent struct local.
4538  */
4539
4540 inline Compiler::lvaPromotionType Compiler::lvaGetParentPromotionType(const LclVarDsc* varDsc)
4541 {
4542     assert(varDsc->lvIsStructField);
4543     assert(varDsc->lvParentLcl < lvaCount);
4544
4545     lvaPromotionType promotionType = lvaGetPromotionType(varDsc->lvParentLcl);
4546     assert(promotionType != PROMOTION_TYPE_NONE);
4547     return promotionType;
4548 }
4549
4550 /*****************************************************************************
4551  *
4552  *  Given a field local, get the promotion type of its parent struct local.
4553  */
4554
4555 inline Compiler::lvaPromotionType Compiler::lvaGetParentPromotionType(unsigned varNum)
4556 {
4557     assert(varNum < lvaCount);
4558     return lvaGetParentPromotionType(&lvaTable[varNum]);
4559 }
4560
4561 /*****************************************************************************
4562  *
4563  *  Return true if the local is a field local of a promoted struct of type PROMOTION_TYPE_DEPENDENT.
4564  *  Return false otherwise.
4565  */
4566
4567 inline bool Compiler::lvaIsFieldOfDependentlyPromotedStruct(const LclVarDsc* varDsc)
4568 {
4569     if (!varDsc->lvIsStructField)
4570     {
4571         return false;
4572     }
4573
4574     lvaPromotionType promotionType = lvaGetParentPromotionType(varDsc);
4575     if (promotionType == PROMOTION_TYPE_DEPENDENT)
4576     {
4577         return true;
4578     }
4579
4580     assert(promotionType == PROMOTION_TYPE_INDEPENDENT);
4581     return false;
4582 }
4583
4584 //------------------------------------------------------------------------
4585 // lvaIsGCTracked: Determine whether this var should be reported
4586 //    as tracked for GC purposes.
4587 //
4588 // Arguments:
4589 //    varDsc - the LclVarDsc for the var in question.
4590 //
4591 // Return Value:
4592 //    Returns true if the variable should be reported as tracked in the GC info.
4593 //
4594 // Notes:
4595 //    This never returns true for struct variables, even if they are tracked.
4596 //    This is because struct variables are never tracked as a whole for GC purposes.
4597 //    It is up to the caller to ensure that the fields of struct variables are
4598 //    correctly tracked.
4599 //    On Amd64, we never GC-track fields of dependently promoted structs, even
4600 //    though they may be tracked for optimization purposes.
4601 //    It seems that on x86 and arm, we simply don't track these
4602 //    fields, though I have not verified that.  I attempted to make these GC-tracked,
4603 //    but there was too much logic that depends on these being untracked, so changing
4604 //    this would require non-trivial effort.
4605
4606 inline bool Compiler::lvaIsGCTracked(const LclVarDsc* varDsc)
4607 {
4608     if (varDsc->lvTracked && (varDsc->lvType == TYP_REF || varDsc->lvType == TYP_BYREF))
4609     {
4610         // Stack parameters are always untracked w.r.t. GC reportings
4611         const bool isStackParam = varDsc->lvIsParam && !varDsc->lvIsRegArg;
4612 #ifdef _TARGET_AMD64_
4613         return !isStackParam && !lvaIsFieldOfDependentlyPromotedStruct(varDsc);
4614 #else  // !_TARGET_AMD64_
4615         return !isStackParam;
4616 #endif // !_TARGET_AMD64_
4617     }
4618     else
4619     {
4620         return false;
4621     }
4622 }
4623
4624 inline void Compiler::EndPhase(Phases phase)
4625 {
4626 #if defined(FEATURE_JIT_METHOD_PERF)
4627     if (pCompJitTimer != nullptr)
4628     {
4629         pCompJitTimer->EndPhase(this, phase);
4630     }
4631 #endif
4632 #if DUMP_FLOWGRAPHS
4633     fgDumpFlowGraph(phase);
4634 #endif // DUMP_FLOWGRAPHS
4635     previousCompletedPhase = phase;
4636 #ifdef DEBUG
4637     if (dumpIR)
4638     {
4639         if ((*dumpIRPhase == L'*') || (wcscmp(dumpIRPhase, PhaseShortNames[phase]) == 0))
4640         {
4641             printf("\n");
4642             printf("IR after %s (switch: %ls)\n", PhaseEnums[phase], PhaseShortNames[phase]);
4643             printf("\n");
4644
4645             if (dumpIRLinear)
4646             {
4647                 dFuncIR();
4648             }
4649             else if (dumpIRTrees)
4650             {
4651                 dTrees();
4652             }
4653
4654             // If we are just dumping a single method and we have a request to exit
4655             // after dumping, do so now.
4656
4657             if (dumpIRExit && ((*dumpIRPhase != L'*') || (phase == PHASE_EMIT_GCEH)))
4658             {
4659                 exit(0);
4660             }
4661         }
4662     }
4663 #endif
4664 }
4665
4666 /*****************************************************************************/
4667 #if MEASURE_CLRAPI_CALLS
4668
4669 inline void Compiler::CLRApiCallEnter(unsigned apix)
4670 {
4671     if (pCompJitTimer != nullptr)
4672     {
4673         pCompJitTimer->CLRApiCallEnter(apix);
4674     }
4675 }
4676 inline void Compiler::CLRApiCallLeave(unsigned apix)
4677 {
4678     if (pCompJitTimer != nullptr)
4679     {
4680         pCompJitTimer->CLRApiCallLeave(apix);
4681     }
4682 }
4683
4684 inline void Compiler::CLR_API_Enter(API_ICorJitInfo_Names ename)
4685 {
4686     CLRApiCallEnter(ename);
4687 }
4688
4689 inline void Compiler::CLR_API_Leave(API_ICorJitInfo_Names ename)
4690 {
4691     CLRApiCallLeave(ename);
4692 }
4693
4694 #endif // MEASURE_CLRAPI_CALLS
4695
4696 //------------------------------------------------------------------------------
4697 // fgStructTempNeedsExplicitZeroInit : Check whether temp struct needs
4698 //                                     explicit zero initialization in this basic block.
4699 //
4700 // Arguments:
4701 //    varDsc -           struct local var description
4702 //    block  -           basic block to check
4703 //
4704 // Returns:
4705 //             true if the struct temp needs explicit zero-initialization in this basic block;
4706 //             false otherwise
4707 //
4708 // Notes:
4709 //     Structs with GC pointer fields are fully zero-initialized in the prolog if compInitMem is true.
4710 //     Therefore, we don't need to insert zero-initialization if this block is not in a loop.
4711
4712 bool Compiler::fgStructTempNeedsExplicitZeroInit(LclVarDsc* varDsc, BasicBlock* block)
4713 {
4714     bool containsGCPtr = (varDsc->lvStructGcCount > 0);
4715     return (!containsGCPtr || !info.compInitMem || ((block->bbFlags & BBF_BACKWARD_JUMP) != 0));
4716 }
4717
4718 /*****************************************************************************/
4719 bool Compiler::fgExcludeFromSsa(unsigned lclNum)
4720 {
4721     if (opts.MinOpts())
4722     {
4723         return true; // If we're doing MinOpts, no SSA vars.
4724     }
4725
4726     LclVarDsc* varDsc = &lvaTable[lclNum];
4727
4728     if (varDsc->lvAddrExposed)
4729     {
4730         return true; // We exclude address-exposed variables.
4731     }
4732     if (!varDsc->lvTracked)
4733     {
4734         return true; // SSA is only done for tracked variables
4735     }
4736     // lvPromoted structs are never tracked...
4737     assert(!varDsc->lvPromoted);
4738
4739     if (varDsc->lvOverlappingFields)
4740     {
4741         return true; // Don't use SSA on structs that have overlapping fields
4742     }
4743
4744     if (varDsc->lvIsStructField && (lvaGetParentPromotionType(lclNum) != PROMOTION_TYPE_INDEPENDENT))
4745     {
4746         // SSA must exclude struct fields that are not independent
4747         // - because we don't model the struct assignment properly when multiple fields can be assigned by one struct
4748         //   assignment.
4749         // - SSA doesn't allow a single node to contain multiple SSA definitions.
4750         // - and PROMOTION_TYPE_DEPENDEDNT fields  are never candidates for a register.
4751         //
4752         // Example mscorlib method: CompatibilitySwitches:IsCompatibilitySwitchSet
4753         //
4754         return true;
4755     }
4756     // otherwise this variable is *not* excluded for SSA
4757     return false;
4758 }
4759
4760 /*****************************************************************************/
4761 ValueNum Compiler::GetUseAsgDefVNOrTreeVN(GenTree* op)
4762 {
4763     if (op->gtFlags & GTF_VAR_USEASG)
4764     {
4765         unsigned lclNum = op->AsLclVarCommon()->GetLclNum();
4766         unsigned ssaNum = GetSsaNumForLocalVarDef(op);
4767         return lvaTable[lclNum].GetPerSsaData(ssaNum)->m_vnPair.GetConservative();
4768     }
4769     else
4770     {
4771         return op->gtVNPair.GetConservative();
4772     }
4773 }
4774
4775 /*****************************************************************************/
4776 unsigned Compiler::GetSsaNumForLocalVarDef(GenTree* lcl)
4777 {
4778     // Address-taken variables don't have SSA numbers.
4779     if (fgExcludeFromSsa(lcl->AsLclVarCommon()->gtLclNum))
4780     {
4781         return SsaConfig::RESERVED_SSA_NUM;
4782     }
4783
4784     if (lcl->gtFlags & GTF_VAR_USEASG)
4785     {
4786         // It's an "lcl op= rhs" assignment.  "lcl" is both used and defined here;
4787         // we've chosen in this case to annotate "lcl" with the SSA number (and VN) of the use,
4788         // and to store the SSA number of the def in a side table.
4789         unsigned ssaNum;
4790         // In case of a remorph (fgMorph) in CSE/AssertionProp after SSA phase, there
4791         // wouldn't be an entry for the USEASG portion of the indir addr, return
4792         // reserved.
4793         if (!GetOpAsgnVarDefSsaNums()->Lookup(lcl, &ssaNum))
4794         {
4795             return SsaConfig::RESERVED_SSA_NUM;
4796         }
4797         return ssaNum;
4798     }
4799     else
4800     {
4801         return lcl->AsLclVarCommon()->gtSsaNum;
4802     }
4803 }
4804
4805 template <typename TVisitor>
4806 void GenTree::VisitOperands(TVisitor visitor)
4807 {
4808     switch (OperGet())
4809     {
4810         // Leaf nodes
4811         case GT_LCL_VAR:
4812         case GT_LCL_FLD:
4813         case GT_LCL_VAR_ADDR:
4814         case GT_LCL_FLD_ADDR:
4815         case GT_CATCH_ARG:
4816         case GT_LABEL:
4817         case GT_FTN_ADDR:
4818         case GT_RET_EXPR:
4819         case GT_CNS_INT:
4820         case GT_CNS_LNG:
4821         case GT_CNS_DBL:
4822         case GT_CNS_STR:
4823         case GT_MEMORYBARRIER:
4824         case GT_JMP:
4825         case GT_JCC:
4826         case GT_SETCC:
4827         case GT_NO_OP:
4828         case GT_START_NONGC:
4829         case GT_PROF_HOOK:
4830 #if !FEATURE_EH_FUNCLETS
4831         case GT_END_LFIN:
4832 #endif // !FEATURE_EH_FUNCLETS
4833         case GT_PHI_ARG:
4834 #ifndef LEGACY_BACKEND
4835         case GT_JMPTABLE:
4836 #endif // LEGACY_BACKEND
4837         case GT_REG_VAR:
4838         case GT_CLS_VAR:
4839         case GT_CLS_VAR_ADDR:
4840         case GT_ARGPLACE:
4841         case GT_PHYSREG:
4842         case GT_EMITNOP:
4843         case GT_PINVOKE_PROLOG:
4844         case GT_PINVOKE_EPILOG:
4845         case GT_IL_OFFSET:
4846             return;
4847
4848         // Unary operators with an optional operand
4849         case GT_NOP:
4850         case GT_RETURN:
4851         case GT_RETFILT:
4852             if (this->AsUnOp()->gtOp1 == nullptr)
4853             {
4854                 return;
4855             }
4856             __fallthrough;
4857
4858         // Standard unary operators
4859         case GT_STORE_LCL_VAR:
4860         case GT_STORE_LCL_FLD:
4861         case GT_NOT:
4862         case GT_NEG:
4863         case GT_COPY:
4864         case GT_RELOAD:
4865         case GT_ARR_LENGTH:
4866         case GT_CAST:
4867         case GT_BITCAST:
4868         case GT_CKFINITE:
4869         case GT_LCLHEAP:
4870         case GT_ADDR:
4871         case GT_IND:
4872         case GT_OBJ:
4873         case GT_BLK:
4874         case GT_BOX:
4875         case GT_ALLOCOBJ:
4876         case GT_INIT_VAL:
4877         case GT_JTRUE:
4878         case GT_SWITCH:
4879         case GT_NULLCHECK:
4880         case GT_PUTARG_REG:
4881         case GT_PUTARG_STK:
4882 #if defined(_TARGET_ARM_) && !defined(LEGACY_BACKEND)
4883         case GT_PUTARG_SPLIT:
4884 #endif
4885         case GT_RETURNTRAP:
4886             visitor(this->AsUnOp()->gtOp1);
4887             return;
4888
4889         // Variadic nodes
4890         case GT_PHI:
4891             assert(this->AsUnOp()->gtOp1 != nullptr);
4892             this->AsUnOp()->gtOp1->VisitListOperands(visitor);
4893             return;
4894
4895         case GT_FIELD_LIST:
4896             VisitListOperands(visitor);
4897             return;
4898
4899 #ifdef FEATURE_SIMD
4900         case GT_SIMD:
4901             if (this->AsSIMD()->gtSIMDIntrinsicID == SIMDIntrinsicInitN)
4902             {
4903                 assert(this->AsSIMD()->gtOp1 != nullptr);
4904                 this->AsSIMD()->gtOp1->VisitListOperands(visitor);
4905             }
4906             else
4907             {
4908                 VisitBinOpOperands<TVisitor>(visitor);
4909             }
4910             return;
4911 #endif // FEATURE_SIMD
4912
4913 #ifdef FEATURE_HW_INTRINSICS
4914         case GT_HWIntrinsic:
4915             if ((this->AsHWIntrinsic()->gtOp1 != nullptr) && this->AsHWIntrinsic()->gtOp1->OperIsList())
4916             {
4917                 this->AsHWIntrinsic()->gtOp1->VisitListOperands(visitor);
4918             }
4919             else
4920             {
4921                 VisitBinOpOperands<TVisitor>(visitor);
4922             }
4923             return;
4924 #endif // FEATURE_HW_INTRINSICS
4925
4926         // Special nodes
4927         case GT_CMPXCHG:
4928         {
4929             GenTreeCmpXchg* const cmpXchg = this->AsCmpXchg();
4930             if (visitor(cmpXchg->gtOpLocation) == VisitResult::Abort)
4931             {
4932                 return;
4933             }
4934             if (visitor(cmpXchg->gtOpValue) == VisitResult::Abort)
4935             {
4936                 return;
4937             }
4938             visitor(cmpXchg->gtOpComparand);
4939             return;
4940         }
4941
4942         case GT_ARR_BOUNDS_CHECK:
4943 #ifdef FEATURE_SIMD
4944         case GT_SIMD_CHK:
4945 #endif // FEATURE_SIMD
4946 #ifdef FEATURE_HW_INTRINSICS
4947         case GT_HW_INTRINSIC_CHK:
4948 #endif // FEATURE_HW_INTRINSICS
4949         {
4950             GenTreeBoundsChk* const boundsChk = this->AsBoundsChk();
4951             if (visitor(boundsChk->gtIndex) == VisitResult::Abort)
4952             {
4953                 return;
4954             }
4955             visitor(boundsChk->gtArrLen);
4956             return;
4957         }
4958
4959         case GT_FIELD:
4960             if (this->AsField()->gtFldObj != nullptr)
4961             {
4962                 visitor(this->AsField()->gtFldObj);
4963             }
4964             return;
4965
4966         case GT_STMT:
4967             if (this->AsStmt()->gtStmtExpr != nullptr)
4968             {
4969                 visitor(this->AsStmt()->gtStmtExpr);
4970             }
4971             return;
4972
4973         case GT_ARR_ELEM:
4974         {
4975             GenTreeArrElem* const arrElem = this->AsArrElem();
4976             if (visitor(arrElem->gtArrObj) == VisitResult::Abort)
4977             {
4978                 return;
4979             }
4980             for (unsigned i = 0; i < arrElem->gtArrRank; i++)
4981             {
4982                 if (visitor(arrElem->gtArrInds[i]) == VisitResult::Abort)
4983                 {
4984                     return;
4985                 }
4986             }
4987             return;
4988         }
4989
4990         case GT_ARR_OFFSET:
4991         {
4992             GenTreeArrOffs* const arrOffs = this->AsArrOffs();
4993             if (visitor(arrOffs->gtOffset) == VisitResult::Abort)
4994             {
4995                 return;
4996             }
4997             if (visitor(arrOffs->gtIndex) == VisitResult::Abort)
4998             {
4999                 return;
5000             }
5001             visitor(arrOffs->gtArrObj);
5002             return;
5003         }
5004
5005         case GT_DYN_BLK:
5006         {
5007             GenTreeDynBlk* const dynBlock = this->AsDynBlk();
5008             if (visitor(dynBlock->gtOp1) == VisitResult::Abort)
5009             {
5010                 return;
5011             }
5012             visitor(dynBlock->gtDynamicSize);
5013             return;
5014         }
5015
5016         case GT_STORE_DYN_BLK:
5017         {
5018             GenTreeDynBlk* const dynBlock = this->AsDynBlk();
5019             if (visitor(dynBlock->gtOp1) == VisitResult::Abort)
5020             {
5021                 return;
5022             }
5023             if (visitor(dynBlock->gtOp2) == VisitResult::Abort)
5024             {
5025                 return;
5026             }
5027             visitor(dynBlock->gtDynamicSize);
5028             return;
5029         }
5030
5031         case GT_CALL:
5032         {
5033             GenTreeCall* const call = this->AsCall();
5034             if ((call->gtCallObjp != nullptr) && (visitor(call->gtCallObjp) == VisitResult::Abort))
5035             {
5036                 return;
5037             }
5038             if ((call->gtCallArgs != nullptr) && (call->gtCallArgs->VisitListOperands(visitor) == VisitResult::Abort))
5039             {
5040                 return;
5041             }
5042             if ((call->gtCallLateArgs != nullptr) &&
5043                 (call->gtCallLateArgs->VisitListOperands(visitor)) == VisitResult::Abort)
5044             {
5045                 return;
5046             }
5047             if (call->gtCallType == CT_INDIRECT)
5048             {
5049                 if ((call->gtCallCookie != nullptr) && (visitor(call->gtCallCookie) == VisitResult::Abort))
5050                 {
5051                     return;
5052                 }
5053                 if ((call->gtCallAddr != nullptr) && (visitor(call->gtCallAddr) == VisitResult::Abort))
5054                 {
5055                     return;
5056                 }
5057             }
5058             if ((call->gtControlExpr != nullptr))
5059             {
5060                 visitor(call->gtControlExpr);
5061             }
5062             return;
5063         }
5064
5065         // Binary nodes
5066         default:
5067             assert(this->OperIsBinary());
5068             VisitBinOpOperands<TVisitor>(visitor);
5069             return;
5070     }
5071 }
5072
5073 template <typename TVisitor>
5074 GenTree::VisitResult GenTree::VisitListOperands(TVisitor visitor)
5075 {
5076     for (GenTreeArgList* node = this->AsArgList(); node != nullptr; node = node->Rest())
5077     {
5078         if (visitor(node->gtOp1) == VisitResult::Abort)
5079         {
5080             return VisitResult::Abort;
5081         }
5082     }
5083
5084     return VisitResult::Continue;
5085 }
5086
5087 template <typename TVisitor>
5088 void GenTree::VisitBinOpOperands(TVisitor visitor)
5089 {
5090     assert(this->OperIsBinary());
5091
5092     GenTreeOp* const op = this->AsOp();
5093
5094     GenTree* const op1 = op->gtOp1;
5095     if ((op1 != nullptr) && (visitor(op1) == VisitResult::Abort))
5096     {
5097         return;
5098     }
5099
5100     GenTree* const op2 = op->gtOp2;
5101     if (op2 != nullptr)
5102     {
5103         visitor(op2);
5104     }
5105 }
5106
5107 /*****************************************************************************
5108  *  operator new
5109  *
5110  *  Note that compGetMem is an arena allocator that returns memory that is
5111  *  not zero-initialized and can contain data from a prior allocation lifetime.
5112  */
5113
5114 inline void* __cdecl operator new(size_t sz, Compiler* context, CompMemKind cmk)
5115 {
5116     return context->compGetMem(sz, cmk);
5117 }
5118
5119 inline void* __cdecl operator new[](size_t sz, Compiler* context, CompMemKind cmk)
5120 {
5121     return context->compGetMem(sz, cmk);
5122 }
5123
5124 inline void* __cdecl operator new(size_t sz, void* p, const jitstd::placement_t& /* syntax_difference */)
5125 {
5126     return p;
5127 }
5128
5129 /*****************************************************************************/
5130
5131 #ifdef DEBUG
5132
5133 inline void printRegMask(regMaskTP mask)
5134 {
5135     printf(REG_MASK_ALL_FMT, mask);
5136 }
5137
5138 inline char* regMaskToString(regMaskTP mask, Compiler* context)
5139 {
5140     const size_t cchRegMask = 24;
5141     char*        regmask    = new (context, CMK_Unknown) char[cchRegMask];
5142
5143     sprintf_s(regmask, cchRegMask, REG_MASK_ALL_FMT, mask);
5144
5145     return regmask;
5146 }
5147
5148 inline void printRegMaskInt(regMaskTP mask)
5149 {
5150     printf(REG_MASK_INT_FMT, (mask & RBM_ALLINT));
5151 }
5152
5153 inline char* regMaskIntToString(regMaskTP mask, Compiler* context)
5154 {
5155     const size_t cchRegMask = 24;
5156     char*        regmask    = new (context, CMK_Unknown) char[cchRegMask];
5157
5158     sprintf_s(regmask, cchRegMask, REG_MASK_INT_FMT, (mask & RBM_ALLINT));
5159
5160     return regmask;
5161 }
5162
5163 #endif // DEBUG
5164
5165 inline static bool StructHasOverlappingFields(DWORD attribs)
5166 {
5167     return ((attribs & CORINFO_FLG_OVERLAPPING_FIELDS) != 0);
5168 }
5169
5170 inline static bool StructHasCustomLayout(DWORD attribs)
5171 {
5172     return ((attribs & CORINFO_FLG_CUSTOMLAYOUT) != 0);
5173 }
5174
5175 /*****************************************************************************
5176  * This node should not be referenced by anyone now. Set its values to garbage
5177  * to catch extra references
5178  */
5179
5180 inline void DEBUG_DESTROY_NODE(GenTree* tree)
5181 {
5182 #ifdef DEBUG
5183     // printf("DEBUG_DESTROY_NODE for [0x%08x]\n", tree);
5184
5185     // Save gtOper in case we want to find out what this node was
5186     tree->gtOperSave = tree->gtOper;
5187
5188     tree->gtType = TYP_UNDEF;
5189     tree->gtFlags |= 0xFFFFFFFF & ~GTF_NODE_MASK;
5190     if (tree->OperIsSimple())
5191     {
5192         tree->gtOp.gtOp1 = tree->gtOp.gtOp2 = nullptr;
5193     }
5194     // Must do this last, because the "gtOp" check above will fail otherwise.
5195     // Don't call SetOper, because GT_COUNT is not a valid value
5196     tree->gtOper = GT_COUNT;
5197 #endif
5198 }
5199
5200 /*****************************************************************************/
5201 #endif //_COMPILER_HPP_
5202 /*****************************************************************************/