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