Handle addressing modes for HW intrinsics (#22944)
[platform/upstream/coreclr.git] / src / jit / lsra.h
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4 /*****************************************************************************/
5
6 #ifndef _LSRA_H_
7 #define _LSRA_H_
8
9 #include "arraylist.h"
10 #include "smallhash.h"
11
12 // Minor and forward-reference types
13 class Interval;
14 class RefPosition;
15 class LinearScan;
16 class RegRecord;
17
18 template <class T>
19 class ArrayStack;
20
21 // LsraLocation tracks the linearized order of the nodes.
22 // Each node is assigned two LsraLocations - one for all the uses and all but the last
23 // def, and a second location for the last def (if any)
24
25 typedef unsigned int LsraLocation;
26 const unsigned int   MinLocation = 0;
27 const unsigned int   MaxLocation = UINT_MAX;
28 // max number of registers an operation could require internally (in addition to uses and defs)
29 const unsigned int MaxInternalRegisters = 8;
30 const unsigned int RegisterTypeCount    = 2;
31
32 /*****************************************************************************
33 * Register types
34 *****************************************************************************/
35 typedef var_types RegisterType;
36 #define IntRegisterType TYP_INT
37 #define FloatRegisterType TYP_FLOAT
38
39 //------------------------------------------------------------------------
40 // regType: Return the RegisterType to use for a given type
41 //
42 // Arguments:
43 //    type - the type of interest
44 //
45 template <class T>
46 RegisterType regType(T type)
47 {
48 #ifdef FEATURE_SIMD
49     if (varTypeIsSIMD(type))
50     {
51         return FloatRegisterType;
52     }
53 #endif // FEATURE_SIMD
54     return varTypeIsFloating(TypeGet(type)) ? FloatRegisterType : IntRegisterType;
55 }
56
57 //------------------------------------------------------------------------
58 // useFloatReg: Check if the given var_type should be allocated to a FloatRegisterType
59 //
60 inline bool useFloatReg(var_types type)
61 {
62     return (regType(type) == FloatRegisterType);
63 }
64
65 //------------------------------------------------------------------------
66 // registerTypesEquivalent: Check to see if two RegisterTypes are equivalent
67 //
68 inline bool registerTypesEquivalent(RegisterType a, RegisterType b)
69 {
70     return varTypeIsIntegralOrI(a) == varTypeIsIntegralOrI(b);
71 }
72
73 //------------------------------------------------------------------------
74 // registerTypesEquivalent: Get the set of callee-save registers of the given RegisterType
75 //
76 inline regMaskTP calleeSaveRegs(RegisterType rt)
77 {
78     return varTypeIsIntegralOrI(rt) ? RBM_INT_CALLEE_SAVED : RBM_FLT_CALLEE_SAVED;
79 }
80
81 //------------------------------------------------------------------------
82 // RefInfo: Captures the necessary information for a definition that is "in-flight"
83 //          during `buildIntervals` (i.e. a tree-node definition has been encountered,
84 //          but not its use). This includes the RefPosition and its associated
85 //          GenTree node.
86 //
87 struct RefInfo
88 {
89     RefPosition* ref;
90     GenTree*     treeNode;
91
92     RefInfo(RefPosition* r, GenTree* t) : ref(r), treeNode(t)
93     {
94     }
95
96     // default constructor for data structures
97     RefInfo()
98     {
99     }
100 };
101
102 //------------------------------------------------------------------------
103 // RefInfoListNode: used to store a single `RefInfo` value for a
104 //                  node during `buildIntervals`.
105 //
106 // This is the node type for `RefInfoList` below.
107 //
108 class RefInfoListNode final : public RefInfo
109 {
110     friend class RefInfoList;
111     friend class RefInfoListNodePool;
112
113     RefInfoListNode* m_next; // The next node in the list
114
115 public:
116     RefInfoListNode(RefPosition* r, GenTree* t) : RefInfo(r, t)
117     {
118     }
119
120     //------------------------------------------------------------------------
121     // RefInfoListNode::Next: Returns the next node in the list.
122     RefInfoListNode* Next() const
123     {
124         return m_next;
125     }
126 };
127
128 //------------------------------------------------------------------------
129 // RefInfoList: used to store a list of `RefInfo` values for a
130 //                   node during `buildIntervals`.
131 //
132 // This list of 'RefInfoListNode's contains the source nodes consumed by
133 // a node, and is created by 'BuildNode'.
134 //
135 class RefInfoList final
136 {
137     friend class RefInfoListNodePool;
138
139     RefInfoListNode* m_head; // The head of the list
140     RefInfoListNode* m_tail; // The tail of the list
141
142 public:
143     RefInfoList() : m_head(nullptr), m_tail(nullptr)
144     {
145     }
146
147     RefInfoList(RefInfoListNode* node) : m_head(node), m_tail(node)
148     {
149         assert(m_head->m_next == nullptr);
150     }
151
152     //------------------------------------------------------------------------
153     // RefInfoList::IsEmpty: Returns true if the list is empty.
154     //
155     bool IsEmpty() const
156     {
157         return m_head == nullptr;
158     }
159
160     //------------------------------------------------------------------------
161     // RefInfoList::Begin: Returns the first node in the list.
162     //
163     RefInfoListNode* Begin() const
164     {
165         return m_head;
166     }
167
168     //------------------------------------------------------------------------
169     // RefInfoList::End: Returns the position after the last node in the
170     //                        list. The returned value is suitable for use as
171     //                        a sentinel for iteration.
172     //
173     RefInfoListNode* End() const
174     {
175         return nullptr;
176     }
177
178     //------------------------------------------------------------------------
179     // RefInfoList::End: Returns the position after the last node in the
180     //                        list. The returned value is suitable for use as
181     //                        a sentinel for iteration.
182     //
183     RefInfoListNode* Last() const
184     {
185         return m_tail;
186     }
187
188     //------------------------------------------------------------------------
189     // RefInfoList::Append: Appends a node to the list.
190     //
191     // Arguments:
192     //    node - The node to append. Must not be part of an existing list.
193     //
194     void Append(RefInfoListNode* node)
195     {
196         assert(node->m_next == nullptr);
197
198         if (m_tail == nullptr)
199         {
200             assert(m_head == nullptr);
201             m_head = node;
202         }
203         else
204         {
205             m_tail->m_next = node;
206         }
207
208         m_tail = node;
209     }
210     //------------------------------------------------------------------------
211     // RefInfoList::Append: Appends another list to this list.
212     //
213     // Arguments:
214     //    other - The list to append.
215     //
216     void Append(RefInfoList other)
217     {
218         if (m_tail == nullptr)
219         {
220             assert(m_head == nullptr);
221             m_head = other.m_head;
222         }
223         else
224         {
225             m_tail->m_next = other.m_head;
226         }
227
228         m_tail = other.m_tail;
229     }
230
231     //------------------------------------------------------------------------
232     // RefInfoList::Prepend: Prepends a node to the list.
233     //
234     // Arguments:
235     //    node - The node to prepend. Must not be part of an existing list.
236     //
237     void Prepend(RefInfoListNode* node)
238     {
239         assert(node->m_next == nullptr);
240
241         if (m_head == nullptr)
242         {
243             assert(m_tail == nullptr);
244             m_tail = node;
245         }
246         else
247         {
248             node->m_next = m_head;
249         }
250
251         m_head = node;
252     }
253
254     //------------------------------------------------------------------------
255     // RefInfoList::Add: Adds a node to the list.
256     //
257     // Arguments:
258     //    node    - The node to add. Must not be part of an existing list.
259     //    prepend - True if it should be prepended (otherwise is appended)
260     //
261     void Add(RefInfoListNode* node, bool prepend)
262     {
263         if (prepend)
264         {
265             Prepend(node);
266         }
267         else
268         {
269             Append(node);
270         }
271     }
272
273     //------------------------------------------------------------------------
274     // removeListNode - retrieve the RefInfo for the given node
275     //
276     // Notes:
277     //     The BuildNode methods use this helper to retrieve the RefInfo for child nodes
278     //     from the useList being constructed.
279     //
280     RefInfoListNode* removeListNode(RefInfoListNode* listNode, RefInfoListNode* prevListNode)
281     {
282         RefInfoListNode* nextNode = listNode->Next();
283         if (prevListNode == nullptr)
284         {
285             m_head = nextNode;
286         }
287         else
288         {
289             prevListNode->m_next = nextNode;
290         }
291         if (nextNode == nullptr)
292         {
293             m_tail = prevListNode;
294         }
295         listNode->m_next = nullptr;
296         return listNode;
297     }
298
299     // removeListNode - remove the RefInfoListNode for the given GenTree node from the defList
300     RefInfoListNode* removeListNode(GenTree* node);
301     // Same as above but takes a multiRegIdx to support multi-reg nodes.
302     RefInfoListNode* removeListNode(GenTree* node, unsigned multiRegIdx);
303
304     //------------------------------------------------------------------------
305     // GetRefPosition - retrieve the RefPosition for the given node
306     //
307     // Notes:
308     //     The Build methods use this helper to retrieve the RefPosition for child nodes
309     //     from the useList being constructed. Note that, if the user knows the order of the operands,
310     //     it is expected that they should just retrieve them directly.
311
312     RefPosition* GetRefPosition(GenTree* node)
313     {
314         for (RefInfoListNode *listNode = Begin(), *end = End(); listNode != end; listNode = listNode->Next())
315         {
316             if (listNode->treeNode == node)
317             {
318                 return listNode->ref;
319             }
320         }
321         assert(!"GetRefPosition didn't find the node");
322         unreached();
323     }
324
325     //------------------------------------------------------------------------
326     // RefInfoList::GetSecond: Gets the second node in the list.
327     //
328     // Arguments:
329     //    (DEBUG ONLY) treeNode - The GenTree* we expect to be in the second node.
330     //
331     RefInfoListNode* GetSecond(INDEBUG(GenTree* treeNode))
332     {
333         noway_assert((Begin() != nullptr) && (Begin()->Next() != nullptr));
334         RefInfoListNode* second = Begin()->Next();
335         assert(second->treeNode == treeNode);
336         return second;
337     }
338
339 #ifdef DEBUG
340     // Count - return the number of nodes in the list (DEBUG only)
341     int Count()
342     {
343         int count = 0;
344         for (RefInfoListNode *listNode = Begin(), *end = End(); listNode != end; listNode = listNode->Next())
345         {
346             count++;
347         }
348         return count;
349     }
350 #endif // DEBUG
351 };
352
353 //------------------------------------------------------------------------
354 // RefInfoListNodePool: manages a pool of `RefInfoListNode`
355 //                      values to decrease overall memory usage
356 //                      during `buildIntervals`.
357 //
358 // `buildIntervals` involves creating a list of RefInfo items per
359 // node that either directly produces a set of registers or that is a
360 // contained node with register-producing sources. However, these lists
361 // are short-lived: they are destroyed once the use of the corresponding
362 // node is processed. As such, there is typically only a small number of
363 // `RefInfoListNode` values in use at any given time. Pooling these
364 // values avoids otherwise frequent allocations.
365 class RefInfoListNodePool final
366 {
367     RefInfoListNode*      m_freeList;
368     Compiler*             m_compiler;
369     static const unsigned defaultPreallocation = 8;
370
371 public:
372     RefInfoListNodePool(Compiler* compiler, unsigned preallocate = defaultPreallocation);
373     RefInfoListNode* GetNode(RefPosition* r, GenTree* t, unsigned regIdx = 0);
374     void ReturnNode(RefInfoListNode* listNode);
375 };
376
377 struct LsraBlockInfo
378 {
379     // bbNum of the predecessor to use for the register location of live-in variables.
380     // 0 for fgFirstBB.
381     unsigned int         predBBNum;
382     BasicBlock::weight_t weight;
383     bool                 hasCriticalInEdge;
384     bool                 hasCriticalOutEdge;
385
386 #if TRACK_LSRA_STATS
387     // Per block maintained LSRA statistics.
388
389     // Number of spills of local vars or tree temps in this basic block.
390     unsigned spillCount;
391
392     // Number of GT_COPY nodes inserted in this basic block while allocating regs.
393     // Note that GT_COPY nodes are also inserted as part of basic block boundary
394     // resolution, which are accounted against resolutionMovCount but not
395     // against copyRegCount.
396     unsigned copyRegCount;
397
398     // Number of resolution moves inserted in this basic block.
399     unsigned resolutionMovCount;
400
401     // Number of critical edges from this block that are split.
402     unsigned splitEdgeCount;
403 #endif // TRACK_LSRA_STATS
404 };
405
406 // This is sort of a bit mask
407 // The low order 2 bits will be 1 for defs, and 2 for uses
408 enum RefType : unsigned char
409 {
410 #define DEF_REFTYPE(memberName, memberValue, shortName) memberName = memberValue,
411 #include "lsra_reftypes.h"
412 #undef DEF_REFTYPE
413 };
414
415 // position in a block (for resolution)
416 enum BlockStartOrEnd
417 {
418     BlockPositionStart = 0,
419     BlockPositionEnd   = 1,
420     PositionCount      = 2
421 };
422
423 inline bool RefTypeIsUse(RefType refType)
424 {
425     return ((refType & RefTypeUse) == RefTypeUse);
426 }
427
428 inline bool RefTypeIsDef(RefType refType)
429 {
430     return ((refType & RefTypeDef) == RefTypeDef);
431 }
432
433 typedef regNumberSmall* VarToRegMap;
434
435 typedef jitstd::list<Interval>                      IntervalList;
436 typedef jitstd::list<RefPosition>                   RefPositionList;
437 typedef jitstd::list<RefPosition>::iterator         RefPositionIterator;
438 typedef jitstd::list<RefPosition>::reverse_iterator RefPositionReverseIterator;
439
440 class Referenceable
441 {
442 public:
443     Referenceable()
444     {
445         firstRefPosition  = nullptr;
446         recentRefPosition = nullptr;
447         lastRefPosition   = nullptr;
448         isActive          = false;
449     }
450
451     // A linked list of RefPositions.  These are only traversed in the forward
452     // direction, and are not moved, so they don't need to be doubly linked
453     // (see RefPosition).
454
455     RefPosition* firstRefPosition;
456     RefPosition* recentRefPosition;
457     RefPosition* lastRefPosition;
458
459     bool isActive;
460
461     // Get the position of the next reference which is at or greater than
462     // the current location (relies upon recentRefPosition being udpated
463     // during traversal).
464     RefPosition* getNextRefPosition();
465     LsraLocation getNextRefLocation();
466 };
467
468 class RegRecord : public Referenceable
469 {
470 public:
471     RegRecord()
472     {
473         assignedInterval    = nullptr;
474         previousInterval    = nullptr;
475         regNum              = REG_NA;
476         isCalleeSave        = false;
477         registerType        = IntRegisterType;
478         isBusyUntilNextKill = false;
479     }
480
481     void init(regNumber reg)
482     {
483 #ifdef _TARGET_ARM64_
484         // The Zero register, or the SP
485         if ((reg == REG_ZR) || (reg == REG_SP))
486         {
487             // IsGeneralRegister returns false for REG_ZR and REG_SP
488             regNum       = reg;
489             registerType = IntRegisterType;
490         }
491         else
492 #endif
493             if (emitter::isFloatReg(reg))
494         {
495             registerType = FloatRegisterType;
496         }
497         else
498         {
499             // The constructor defaults to IntRegisterType
500             assert(emitter::isGeneralRegister(reg) && registerType == IntRegisterType);
501         }
502         regNum       = reg;
503         isCalleeSave = ((RBM_CALLEE_SAVED & genRegMask(reg)) != 0);
504     }
505
506 #ifdef DEBUG
507     // print out representation
508     void dump();
509     // concise representation for embedding
510     void tinyDump();
511 #endif // DEBUG
512
513     bool isFree();
514
515     // RefPosition   * getNextRefPosition();
516     // LsraLocation    getNextRefLocation();
517
518     // DATA
519
520     // interval to which this register is currently allocated.
521     // If the interval is inactive (isActive == false) then it is not currently live,
522     // and the register call be unassigned (i.e. setting assignedInterval to nullptr)
523     // without spilling the register.
524     Interval* assignedInterval;
525     // Interval to which this register was previously allocated, and which was unassigned
526     // because it was inactive.  This register will be reassigned to this Interval when
527     // assignedInterval becomes inactive.
528     Interval* previousInterval;
529
530     regNumber    regNum;
531     bool         isCalleeSave;
532     RegisterType registerType;
533     // This register must be considered busy until the next time it is explicitly killed.
534     // This is used so that putarg_reg can avoid killing its lclVar source, while avoiding
535     // the problem with the reg becoming free if the last-use is encountered before the call.
536     bool isBusyUntilNextKill;
537
538     bool conflictingFixedRegReference(RefPosition* refPosition);
539 };
540
541 inline bool leafInRange(GenTree* leaf, int lower, int upper)
542 {
543     if (!leaf->IsIntCnsFitsInI32())
544     {
545         return false;
546     }
547     if (leaf->gtIntCon.gtIconVal < lower)
548     {
549         return false;
550     }
551     if (leaf->gtIntCon.gtIconVal > upper)
552     {
553         return false;
554     }
555
556     return true;
557 }
558
559 inline bool leafInRange(GenTree* leaf, int lower, int upper, int multiple)
560 {
561     if (!leafInRange(leaf, lower, upper))
562     {
563         return false;
564     }
565     if (leaf->gtIntCon.gtIconVal % multiple)
566     {
567         return false;
568     }
569
570     return true;
571 }
572
573 inline bool leafAddInRange(GenTree* leaf, int lower, int upper, int multiple = 1)
574 {
575     if (leaf->OperGet() != GT_ADD)
576     {
577         return false;
578     }
579     return leafInRange(leaf->gtGetOp2(), lower, upper, multiple);
580 }
581
582 inline bool isCandidateVar(LclVarDsc* varDsc)
583 {
584     return varDsc->lvLRACandidate;
585 }
586
587 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
588 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
589 XX                                                                           XX
590 XX                           LinearScan                                      XX
591 XX                                                                           XX
592 XX This is the container for the Linear Scan data structures and methods.    XX
593 XX                                                                           XX
594 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
595 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
596 */
597 // OPTION 1: The algorithm as described in "Optimized Interval Splitting in a
598 // Linear Scan Register Allocator".  It is driven by iterating over the Interval
599 // lists.  In this case, we need multiple IntervalLists, and Intervals will be
600 // moved between them so they must be easily updated.
601
602 // OPTION 2: The algorithm is driven by iterating over the RefPositions.  In this
603 // case, we only need a single IntervalList, and it won't be updated.
604 // The RefPosition must refer to its Interval, and we need to be able to traverse
605 // to the next RefPosition in code order
606 // THIS IS THE OPTION CURRENTLY BEING PURSUED
607
608 class LinearScan : public LinearScanInterface
609 {
610     friend class RefPosition;
611     friend class Interval;
612     friend class Lowering;
613
614 public:
615     // This could use further abstraction.  From Compiler we need the tree,
616     // the flowgraph and the allocator.
617     LinearScan(Compiler* theCompiler);
618
619     // This is the main driver
620     virtual void doLinearScan();
621
622     static bool isSingleRegister(regMaskTP regMask)
623     {
624         return (genExactlyOneBit(regMask));
625     }
626
627     // Initialize the block traversal for LSRA.
628     // This resets the bbVisitedSet, and on the first invocation sets the blockSequence array,
629     // which determines the order in which blocks will be allocated (currently called during Lowering).
630     BasicBlock* startBlockSequence();
631     // Move to the next block in sequence, updating the current block information.
632     BasicBlock* moveToNextBlock();
633     // Get the next block to be scheduled without changing the current block,
634     // but updating the blockSequence during the first iteration if it is not fully computed.
635     BasicBlock* getNextBlock();
636
637     // This is called during code generation to update the location of variables
638     virtual void recordVarLocationsAtStartOfBB(BasicBlock* bb);
639
640     // This does the dataflow analysis and builds the intervals
641     void buildIntervals();
642
643     // This is where the actual assignment is done
644     void allocateRegisters();
645
646     // This is the resolution phase, where cross-block mismatches are fixed up
647     void resolveRegisters();
648
649     void writeRegisters(RefPosition* currentRefPosition, GenTree* tree);
650
651     // Insert a copy in the case where a tree node value must be moved to a different
652     // register at the point of use, or it is reloaded to a different register
653     // than the one it was spilled from
654     void insertCopyOrReload(BasicBlock* block, GenTree* tree, unsigned multiRegIdx, RefPosition* refPosition);
655
656 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
657     // Insert code to save and restore the upper half of a vector that lives
658     // in a callee-save register at the point of a call (the upper half is
659     // not preserved).
660     void insertUpperVectorSaveAndReload(GenTree* tree, RefPosition* refPosition, BasicBlock* block);
661 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
662
663     // resolve along one block-block edge
664     enum ResolveType
665     {
666         ResolveSplit,
667         ResolveJoin,
668         ResolveCritical,
669         ResolveSharedCritical,
670         ResolveTypeCount
671     };
672 #ifdef DEBUG
673     static const char* resolveTypeName[ResolveTypeCount];
674 #endif
675
676     enum WhereToInsert
677     {
678         InsertAtTop,
679         InsertAtBottom
680     };
681
682 #ifdef _TARGET_ARM_
683     void addResolutionForDouble(BasicBlock*     block,
684                                 GenTree*        insertionPoint,
685                                 Interval**      sourceIntervals,
686                                 regNumberSmall* location,
687                                 regNumber       toReg,
688                                 regNumber       fromReg,
689                                 ResolveType     resolveType);
690 #endif
691     void addResolution(
692         BasicBlock* block, GenTree* insertionPoint, Interval* interval, regNumber outReg, regNumber inReg);
693
694     void handleOutgoingCriticalEdges(BasicBlock* block);
695
696     void resolveEdge(BasicBlock* fromBlock, BasicBlock* toBlock, ResolveType resolveType, VARSET_VALARG_TP liveSet);
697
698     void resolveEdges();
699
700     // Keep track of how many temp locations we'll need for spill
701     void initMaxSpill();
702     void updateMaxSpill(RefPosition* refPosition);
703     void recordMaxSpill();
704
705     // max simultaneous spill locations used of every type
706     unsigned int maxSpill[TYP_COUNT];
707     unsigned int currentSpill[TYP_COUNT];
708     bool         needFloatTmpForFPCall;
709     bool         needDoubleTmpForFPCall;
710
711 #ifdef DEBUG
712 private:
713     //------------------------------------------------------------------------
714     // Should we stress lsra? This uses the COMPlus_JitStressRegs variable.
715     //
716     // The mask bits are currently divided into fields in which each non-zero value
717     // is a distinct stress option (e.g. 0x3 is not a combination of 0x1 and 0x2).
718     // However, subject to possible constraints (to be determined), the different
719     // fields can be combined (e.g. 0x7 is a combination of 0x3 and 0x4).
720     // Note that the field values are declared in a public enum, but the actual bits are
721     // only accessed via accessors.
722
723     unsigned lsraStressMask;
724
725     // This controls the registers available for allocation
726     enum LsraStressLimitRegs{LSRA_LIMIT_NONE = 0, LSRA_LIMIT_CALLEE = 0x1, LSRA_LIMIT_CALLER = 0x2,
727                              LSRA_LIMIT_SMALL_SET = 0x3, LSRA_LIMIT_MASK = 0x3};
728
729     // When LSRA_LIMIT_SMALL_SET is specified, it is desirable to select a "mixed" set of caller- and callee-save
730     // registers, so as to get different coverage than limiting to callee or caller.
731     // At least for x86 and AMD64, and potentially other architecture that will support SIMD,
732     // we need a minimum of 5 fp regs in order to support the InitN intrinsic for Vector4.
733     // Hence the "SmallFPSet" has 5 elements.
734     CLANG_FORMAT_COMMENT_ANCHOR;
735
736 #if defined(_TARGET_AMD64_)
737 #ifdef UNIX_AMD64_ABI
738     // On System V the RDI and RSI are not callee saved. Use R12 ans R13 as callee saved registers.
739     static const regMaskTP LsraLimitSmallIntSet =
740         (RBM_EAX | RBM_ECX | RBM_EBX | RBM_ETW_FRAMED_EBP | RBM_R12 | RBM_R13);
741 #else  // !UNIX_AMD64_ABI
742     // On Windows Amd64 use the RDI and RSI as callee saved registers.
743     static const regMaskTP LsraLimitSmallIntSet =
744         (RBM_EAX | RBM_ECX | RBM_EBX | RBM_ETW_FRAMED_EBP | RBM_ESI | RBM_EDI);
745 #endif // !UNIX_AMD64_ABI
746     static const regMaskTP LsraLimitSmallFPSet = (RBM_XMM0 | RBM_XMM1 | RBM_XMM2 | RBM_XMM6 | RBM_XMM7);
747 #elif defined(_TARGET_ARM_)
748     // On ARM, we may need two registers to set up the target register for a virtual call, so we need
749     // to have at least the maximum number of arg registers, plus 2.
750     static const regMaskTP LsraLimitSmallIntSet = (RBM_R0 | RBM_R1 | RBM_R2 | RBM_R3 | RBM_R4 | RBM_R5);
751     static const regMaskTP LsraLimitSmallFPSet  = (RBM_F0 | RBM_F1 | RBM_F2 | RBM_F16 | RBM_F17);
752 #elif defined(_TARGET_ARM64_)
753     static const regMaskTP LsraLimitSmallIntSet = (RBM_R0 | RBM_R1 | RBM_R2 | RBM_R19 | RBM_R20);
754     static const regMaskTP LsraLimitSmallFPSet  = (RBM_V0 | RBM_V1 | RBM_V2 | RBM_V8 | RBM_V9);
755 #elif defined(_TARGET_X86_)
756     static const regMaskTP LsraLimitSmallIntSet = (RBM_EAX | RBM_ECX | RBM_EDI);
757     static const regMaskTP LsraLimitSmallFPSet  = (RBM_XMM0 | RBM_XMM1 | RBM_XMM2 | RBM_XMM6 | RBM_XMM7);
758 #else
759 #error Unsupported or unset target architecture
760 #endif // target
761
762     LsraStressLimitRegs getStressLimitRegs()
763     {
764         return (LsraStressLimitRegs)(lsraStressMask & LSRA_LIMIT_MASK);
765     }
766
767     regMaskTP getConstrainedRegMask(regMaskTP regMaskActual, regMaskTP regMaskConstrain, unsigned minRegCount);
768     regMaskTP stressLimitRegs(RefPosition* refPosition, regMaskTP mask);
769
770     // This controls the heuristics used to select registers
771     // These can be combined.
772     enum LsraSelect{LSRA_SELECT_DEFAULT = 0, LSRA_SELECT_REVERSE_HEURISTICS = 0x04,
773                     LSRA_SELECT_REVERSE_CALLER_CALLEE = 0x08, LSRA_SELECT_NEAREST = 0x10, LSRA_SELECT_MASK = 0x1c};
774     LsraSelect getSelectionHeuristics()
775     {
776         return (LsraSelect)(lsraStressMask & LSRA_SELECT_MASK);
777     }
778     bool doReverseSelect()
779     {
780         return ((lsraStressMask & LSRA_SELECT_REVERSE_HEURISTICS) != 0);
781     }
782     bool doReverseCallerCallee()
783     {
784         return ((lsraStressMask & LSRA_SELECT_REVERSE_CALLER_CALLEE) != 0);
785     }
786     bool doSelectNearest()
787     {
788         return ((lsraStressMask & LSRA_SELECT_NEAREST) != 0);
789     }
790
791     // This controls the order in which basic blocks are visited during allocation
792     enum LsraTraversalOrder{LSRA_TRAVERSE_LAYOUT = 0x20, LSRA_TRAVERSE_PRED_FIRST = 0x40,
793                             LSRA_TRAVERSE_RANDOM  = 0x60, // NYI
794                             LSRA_TRAVERSE_DEFAULT = LSRA_TRAVERSE_PRED_FIRST, LSRA_TRAVERSE_MASK = 0x60};
795     LsraTraversalOrder getLsraTraversalOrder()
796     {
797         if ((lsraStressMask & LSRA_TRAVERSE_MASK) == 0)
798         {
799             return LSRA_TRAVERSE_DEFAULT;
800         }
801         return (LsraTraversalOrder)(lsraStressMask & LSRA_TRAVERSE_MASK);
802     }
803     bool isTraversalLayoutOrder()
804     {
805         return getLsraTraversalOrder() == LSRA_TRAVERSE_LAYOUT;
806     }
807     bool isTraversalPredFirstOrder()
808     {
809         return getLsraTraversalOrder() == LSRA_TRAVERSE_PRED_FIRST;
810     }
811
812     // This controls whether lifetimes should be extended to the entire method.
813     // Note that this has no effect under MinOpts
814     enum LsraExtendLifetimes{LSRA_DONT_EXTEND = 0, LSRA_EXTEND_LIFETIMES = 0x80, LSRA_EXTEND_LIFETIMES_MASK = 0x80};
815     LsraExtendLifetimes getLsraExtendLifeTimes()
816     {
817         return (LsraExtendLifetimes)(lsraStressMask & LSRA_EXTEND_LIFETIMES_MASK);
818     }
819     bool extendLifetimes()
820     {
821         return getLsraExtendLifeTimes() == LSRA_EXTEND_LIFETIMES;
822     }
823
824     // This controls whether variables locations should be set to the previous block in layout order
825     // (LSRA_BLOCK_BOUNDARY_LAYOUT), or to that of the highest-weight predecessor (LSRA_BLOCK_BOUNDARY_PRED -
826     // the default), or rotated (LSRA_BLOCK_BOUNDARY_ROTATE).
827     enum LsraBlockBoundaryLocations{LSRA_BLOCK_BOUNDARY_PRED = 0, LSRA_BLOCK_BOUNDARY_LAYOUT = 0x100,
828                                     LSRA_BLOCK_BOUNDARY_ROTATE = 0x200, LSRA_BLOCK_BOUNDARY_MASK = 0x300};
829     LsraBlockBoundaryLocations getLsraBlockBoundaryLocations()
830     {
831         return (LsraBlockBoundaryLocations)(lsraStressMask & LSRA_BLOCK_BOUNDARY_MASK);
832     }
833     regNumber rotateBlockStartLocation(Interval* interval, regNumber targetReg, regMaskTP availableRegs);
834
835     // This controls whether we always insert a GT_RELOAD instruction after a spill
836     // Note that this can be combined with LSRA_SPILL_ALWAYS (or not)
837     enum LsraReload{LSRA_NO_RELOAD_IF_SAME = 0, LSRA_ALWAYS_INSERT_RELOAD = 0x400, LSRA_RELOAD_MASK = 0x400};
838     LsraReload getLsraReload()
839     {
840         return (LsraReload)(lsraStressMask & LSRA_RELOAD_MASK);
841     }
842     bool alwaysInsertReload()
843     {
844         return getLsraReload() == LSRA_ALWAYS_INSERT_RELOAD;
845     }
846
847     // This controls whether we spill everywhere
848     enum LsraSpill{LSRA_DONT_SPILL_ALWAYS = 0, LSRA_SPILL_ALWAYS = 0x800, LSRA_SPILL_MASK = 0x800};
849     LsraSpill getLsraSpill()
850     {
851         return (LsraSpill)(lsraStressMask & LSRA_SPILL_MASK);
852     }
853     bool spillAlways()
854     {
855         return getLsraSpill() == LSRA_SPILL_ALWAYS;
856     }
857
858     // This controls whether RefPositions that lower/codegen indicated as reg optional be
859     // allocated a reg at all.
860     enum LsraRegOptionalControl{LSRA_REG_OPTIONAL_DEFAULT = 0, LSRA_REG_OPTIONAL_NO_ALLOC = 0x1000,
861                                 LSRA_REG_OPTIONAL_MASK = 0x1000};
862
863     LsraRegOptionalControl getLsraRegOptionalControl()
864     {
865         return (LsraRegOptionalControl)(lsraStressMask & LSRA_REG_OPTIONAL_MASK);
866     }
867
868     bool regOptionalNoAlloc()
869     {
870         return getLsraRegOptionalControl() == LSRA_REG_OPTIONAL_NO_ALLOC;
871     }
872
873     bool candidatesAreStressLimited()
874     {
875         return ((lsraStressMask & (LSRA_LIMIT_MASK | LSRA_SELECT_MASK)) != 0);
876     }
877
878     // Dump support
879     void dumpNodeInfo(GenTree* node, regMaskTP dstCandidates, int srcCount, int dstCount);
880     void dumpDefList();
881     void lsraDumpIntervals(const char* msg);
882     void dumpRefPositions(const char* msg);
883     void dumpVarRefPositions(const char* msg);
884
885     // Checking code
886     static bool IsLsraAdded(GenTree* node)
887     {
888         return ((node->gtDebugFlags & GTF_DEBUG_NODE_LSRA_ADDED) != 0);
889     }
890     static void SetLsraAdded(GenTree* node)
891     {
892         node->gtDebugFlags |= GTF_DEBUG_NODE_LSRA_ADDED;
893     }
894     static bool IsResolutionMove(GenTree* node);
895     static bool IsResolutionNode(LIR::Range& containingRange, GenTree* node);
896
897     void verifyFinalAllocation();
898     void verifyResolutionMove(GenTree* resolutionNode, LsraLocation currentLocation);
899 #else  // !DEBUG
900     bool doSelectNearest()
901     {
902         return false;
903     }
904     bool extendLifetimes()
905     {
906         return false;
907     }
908     bool spillAlways()
909     {
910         return false;
911     }
912     // In a retail build we support only the default traversal order
913     bool isTraversalLayoutOrder()
914     {
915         return false;
916     }
917     bool isTraversalPredFirstOrder()
918     {
919         return true;
920     }
921     bool getLsraExtendLifeTimes()
922     {
923         return false;
924     }
925     static void SetLsraAdded(GenTree* node)
926     {
927         // do nothing; checked only under #DEBUG
928     }
929     bool candidatesAreStressLimited()
930     {
931         return false;
932     }
933 #endif // !DEBUG
934
935 public:
936     // Used by Lowering when considering whether to split Longs, as well as by identifyCandidates().
937     bool isRegCandidate(LclVarDsc* varDsc);
938
939     bool isContainableMemoryOp(GenTree* node);
940
941 private:
942     // Determine which locals are candidates for allocation
943     void identifyCandidates();
944
945     // determine which locals are used in EH constructs we don't want to deal with
946     void identifyCandidatesExceptionDataflow();
947
948     void buildPhysRegRecords();
949
950 #ifdef DEBUG
951     void checkLastUses(BasicBlock* block);
952     static int ComputeOperandDstCount(GenTree* operand);
953     static int ComputeAvailableSrcCount(GenTree* node);
954 #endif // DEBUG
955
956     void setFrameType();
957
958     // Update allocations at start/end of block
959     void unassignIntervalBlockStart(RegRecord* regRecord, VarToRegMap inVarToRegMap);
960     void processBlockEndAllocation(BasicBlock* current);
961
962     // Record variable locations at start/end of block
963     void processBlockStartLocations(BasicBlock* current, bool allocationPass);
964     void processBlockEndLocations(BasicBlock* current);
965
966 #ifdef _TARGET_ARM_
967     bool isSecondHalfReg(RegRecord* regRec, Interval* interval);
968     RegRecord* getSecondHalfRegRec(RegRecord* regRec);
969     RegRecord* findAnotherHalfRegRec(RegRecord* regRec);
970     bool canSpillDoubleReg(RegRecord* physRegRecord, LsraLocation refLocation, unsigned* recentAssignedRefWeight);
971     void unassignDoublePhysReg(RegRecord* doubleRegRecord);
972 #endif
973     void updateAssignedInterval(RegRecord* reg, Interval* interval, RegisterType regType);
974     void updatePreviousInterval(RegRecord* reg, Interval* interval, RegisterType regType);
975     bool canRestorePreviousInterval(RegRecord* regRec, Interval* assignedInterval);
976     bool isAssignedToInterval(Interval* interval, RegRecord* regRec);
977     bool isRefPositionActive(RefPosition* refPosition, LsraLocation refLocation);
978     bool canSpillReg(RegRecord* physRegRecord, LsraLocation refLocation, unsigned* recentAssignedRefWeight);
979     bool isRegInUse(RegRecord* regRec, RefPosition* refPosition);
980
981     // insert refpositions representing prolog zero-inits which will be added later
982     void insertZeroInitRefPositions();
983
984     // add physreg refpositions for a tree node, based on calling convention and instruction selection predictions
985     void addRefsForPhysRegMask(regMaskTP mask, LsraLocation currentLoc, RefType refType, bool isLastUse);
986
987     void resolveConflictingDefAndUse(Interval* interval, RefPosition* defRefPosition);
988
989     void buildRefPositionsForNode(GenTree* tree, BasicBlock* block, LsraLocation loc);
990
991 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
992     void buildUpperVectorSaveRefPositions(GenTree* tree, LsraLocation currentLoc, VARSET_VALARG_TP liveLargeVectors);
993     void buildUpperVectorRestoreRefPositions(GenTree* tree, LsraLocation currentLoc, VARSET_VALARG_TP liveLargeVectors);
994 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
995
996 #if defined(UNIX_AMD64_ABI)
997     // For AMD64 on SystemV machines. This method
998     // is called as replacement for raUpdateRegStateForArg
999     // that is used on Windows. On System V systems a struct can be passed
1000     // partially using registers from the 2 register files.
1001     void unixAmd64UpdateRegStateForArg(LclVarDsc* argDsc);
1002 #endif // defined(UNIX_AMD64_ABI)
1003
1004     // Update reg state for an incoming register argument
1005     void updateRegStateForArg(LclVarDsc* argDsc);
1006
1007     inline bool isCandidateLocalRef(GenTree* tree)
1008     {
1009         if (tree->IsLocal())
1010         {
1011             unsigned int lclNum = tree->gtLclVarCommon.gtLclNum;
1012             assert(lclNum < compiler->lvaCount);
1013             LclVarDsc* varDsc = compiler->lvaTable + tree->gtLclVarCommon.gtLclNum;
1014
1015             return isCandidateVar(varDsc);
1016         }
1017         return false;
1018     }
1019
1020     // Helpers for getKillSetForNode().
1021     regMaskTP getKillSetForStoreInd(GenTreeStoreInd* tree);
1022     regMaskTP getKillSetForShiftRotate(GenTreeOp* tree);
1023     regMaskTP getKillSetForMul(GenTreeOp* tree);
1024     regMaskTP getKillSetForCall(GenTreeCall* call);
1025     regMaskTP getKillSetForModDiv(GenTreeOp* tree);
1026     regMaskTP getKillSetForBlockStore(GenTreeBlk* blkNode);
1027     regMaskTP getKillSetForReturn();
1028     regMaskTP getKillSetForProfilerHook();
1029 #ifdef FEATURE_HW_INTRINSICS
1030     regMaskTP getKillSetForHWIntrinsic(GenTreeHWIntrinsic* node);
1031 #endif // FEATURE_HW_INTRINSICS
1032
1033 // Return the registers killed by the given tree node.
1034 // This is used only for an assert, and for stress, so it is only defined under DEBUG.
1035 // Otherwise, the Build methods should obtain the killMask from the appropriate method above.
1036 #ifdef DEBUG
1037     regMaskTP getKillSetForNode(GenTree* tree);
1038 #endif
1039
1040     // Given some tree node add refpositions for all the registers this node kills
1041     bool buildKillPositionsForNode(GenTree* tree, LsraLocation currentLoc, regMaskTP killMask);
1042
1043     regMaskTP allRegs(RegisterType rt);
1044     regMaskTP allByteRegs();
1045     regMaskTP allSIMDRegs();
1046     regMaskTP internalFloatRegCandidates();
1047
1048     bool registerIsFree(regNumber regNum, RegisterType regType);
1049     bool registerIsAvailable(RegRecord*    physRegRecord,
1050                              LsraLocation  currentLoc,
1051                              LsraLocation* nextRefLocationPtr,
1052                              RegisterType  regType);
1053     void freeRegister(RegRecord* physRegRecord);
1054     void freeRegisters(regMaskTP regsToFree);
1055
1056     // Get the type that this tree defines.
1057     var_types getDefType(GenTree* tree)
1058     {
1059         return tree->TypeGet();
1060     }
1061
1062     // Managing internal registers during the BuildNode process.
1063     RefPosition* defineNewInternalTemp(GenTree* tree, RegisterType regType, regMaskTP candidates);
1064     RefPosition* buildInternalIntRegisterDefForNode(GenTree* tree, regMaskTP internalCands = RBM_NONE);
1065     RefPosition* buildInternalFloatRegisterDefForNode(GenTree* tree, regMaskTP internalCands = RBM_NONE);
1066     void buildInternalRegisterUses();
1067
1068     void resolveLocalRef(BasicBlock* block, GenTree* treeNode, RefPosition* currentRefPosition);
1069
1070     void insertMove(BasicBlock* block, GenTree* insertionPoint, unsigned lclNum, regNumber inReg, regNumber outReg);
1071
1072     void insertSwap(
1073         BasicBlock* block, GenTree* insertionPoint, unsigned lclNum1, regNumber reg1, unsigned lclNum2, regNumber reg2);
1074
1075 public:
1076     // TODO-Cleanup: unused?
1077     class PhysRegIntervalIterator
1078     {
1079     public:
1080         PhysRegIntervalIterator(LinearScan* theLinearScan)
1081         {
1082             nextRegNumber = (regNumber)0;
1083             linearScan    = theLinearScan;
1084         }
1085         RegRecord* GetNext()
1086         {
1087             return &linearScan->physRegs[nextRegNumber];
1088         }
1089
1090     private:
1091         // This assumes that the physical registers are contiguous, starting
1092         // with a register number of 0
1093         regNumber   nextRegNumber;
1094         LinearScan* linearScan;
1095     };
1096
1097 private:
1098     Interval* newInterval(RegisterType regType);
1099
1100     Interval* getIntervalForLocalVar(unsigned varIndex)
1101     {
1102         assert(varIndex < compiler->lvaTrackedCount);
1103         assert(localVarIntervals[varIndex] != nullptr);
1104         return localVarIntervals[varIndex];
1105     }
1106
1107     Interval* getIntervalForLocalVarNode(GenTreeLclVarCommon* tree)
1108     {
1109         LclVarDsc* varDsc = &compiler->lvaTable[tree->gtLclNum];
1110         assert(varDsc->lvTracked);
1111         return getIntervalForLocalVar(varDsc->lvVarIndex);
1112     }
1113
1114     RegRecord* getRegisterRecord(regNumber regNum);
1115
1116     RefPosition* newRefPositionRaw(LsraLocation nodeLocation, GenTree* treeNode, RefType refType);
1117
1118     RefPosition* newRefPosition(Interval*    theInterval,
1119                                 LsraLocation theLocation,
1120                                 RefType      theRefType,
1121                                 GenTree*     theTreeNode,
1122                                 regMaskTP    mask,
1123                                 unsigned     multiRegIdx = 0);
1124
1125     // This creates a RefTypeUse at currentLoc. It sets the treeNode to nullptr if it is not a
1126     // lclVar interval.
1127     RefPosition* newUseRefPosition(Interval* theInterval,
1128                                    GenTree*  theTreeNode,
1129                                    regMaskTP mask,
1130                                    unsigned  multiRegIdx = 0);
1131
1132     RefPosition* newRefPosition(
1133         regNumber reg, LsraLocation theLocation, RefType theRefType, GenTree* theTreeNode, regMaskTP mask);
1134
1135     void applyCalleeSaveHeuristics(RefPosition* rp);
1136
1137     void checkConflictingDefUse(RefPosition* rp);
1138
1139     void associateRefPosWithInterval(RefPosition* rp);
1140
1141     unsigned getWeight(RefPosition* refPos);
1142
1143     /*****************************************************************************
1144      * Register management
1145      ****************************************************************************/
1146     RegisterType getRegisterType(Interval* currentInterval, RefPosition* refPosition);
1147     regNumber tryAllocateFreeReg(Interval* current, RefPosition* refPosition);
1148     regNumber allocateBusyReg(Interval* current, RefPosition* refPosition, bool allocateIfProfitable);
1149     regNumber assignCopyReg(RefPosition* refPosition);
1150
1151     bool isMatchingConstant(RegRecord* physRegRecord, RefPosition* refPosition);
1152     bool isSpillCandidate(Interval*     current,
1153                           RefPosition*  refPosition,
1154                           RegRecord*    physRegRecord,
1155                           LsraLocation& nextLocation);
1156     void checkAndAssignInterval(RegRecord* regRec, Interval* interval);
1157     void assignPhysReg(RegRecord* regRec, Interval* interval);
1158     void assignPhysReg(regNumber reg, Interval* interval)
1159     {
1160         assignPhysReg(getRegisterRecord(reg), interval);
1161     }
1162
1163     bool isAssigned(RegRecord* regRec ARM_ARG(RegisterType newRegType));
1164     bool isAssigned(RegRecord* regRec, LsraLocation lastLocation ARM_ARG(RegisterType newRegType));
1165     void checkAndClearInterval(RegRecord* regRec, RefPosition* spillRefPosition);
1166     void unassignPhysReg(RegRecord* regRec ARM_ARG(RegisterType newRegType));
1167     void unassignPhysReg(RegRecord* regRec, RefPosition* spillRefPosition);
1168     void unassignPhysRegNoSpill(RegRecord* reg);
1169     void unassignPhysReg(regNumber reg)
1170     {
1171         unassignPhysReg(getRegisterRecord(reg), nullptr);
1172     }
1173
1174     void setIntervalAsSpilled(Interval* interval);
1175     void setIntervalAsSplit(Interval* interval);
1176     void spillInterval(Interval* interval, RefPosition* fromRefPosition, RefPosition* toRefPosition);
1177
1178     void spillGCRefs(RefPosition* killRefPosition);
1179
1180     /*****************************************************************************
1181      * For Resolution phase
1182      ****************************************************************************/
1183     // TODO-Throughput: Consider refactoring this so that we keep a map from regs to vars for better scaling
1184     unsigned int regMapCount;
1185
1186     // When we split edges, we create new blocks, and instead of expanding the VarToRegMaps, we
1187     // rely on the property that the "in" map is the same as the "from" block of the edge, and the
1188     // "out" map is the same as the "to" block of the edge (by construction).
1189     // So, for any block whose bbNum is greater than bbNumMaxBeforeResolution, we use the
1190     // splitBBNumToTargetBBNumMap.
1191     // TODO-Throughput: We may want to look into the cost/benefit tradeoff of doing this vs. expanding
1192     // the arrays.
1193
1194     unsigned bbNumMaxBeforeResolution;
1195     struct SplitEdgeInfo
1196     {
1197         unsigned fromBBNum;
1198         unsigned toBBNum;
1199     };
1200     typedef JitHashTable<unsigned, JitSmallPrimitiveKeyFuncs<unsigned>, SplitEdgeInfo> SplitBBNumToTargetBBNumMap;
1201     SplitBBNumToTargetBBNumMap* splitBBNumToTargetBBNumMap;
1202     SplitBBNumToTargetBBNumMap* getSplitBBNumToTargetBBNumMap()
1203     {
1204         if (splitBBNumToTargetBBNumMap == nullptr)
1205         {
1206             splitBBNumToTargetBBNumMap =
1207                 new (getAllocator(compiler)) SplitBBNumToTargetBBNumMap(getAllocator(compiler));
1208         }
1209         return splitBBNumToTargetBBNumMap;
1210     }
1211     SplitEdgeInfo getSplitEdgeInfo(unsigned int bbNum);
1212
1213     void initVarRegMaps();
1214     void setInVarRegForBB(unsigned int bbNum, unsigned int varNum, regNumber reg);
1215     void setOutVarRegForBB(unsigned int bbNum, unsigned int varNum, regNumber reg);
1216     VarToRegMap getInVarToRegMap(unsigned int bbNum);
1217     VarToRegMap getOutVarToRegMap(unsigned int bbNum);
1218     void setVarReg(VarToRegMap map, unsigned int trackedVarIndex, regNumber reg);
1219     regNumber getVarReg(VarToRegMap map, unsigned int trackedVarIndex);
1220     // Initialize the incoming VarToRegMap to the given map values (generally a predecessor of
1221     // the block)
1222     VarToRegMap setInVarToRegMap(unsigned int bbNum, VarToRegMap srcVarToRegMap);
1223
1224     regNumber getTempRegForResolution(BasicBlock* fromBlock, BasicBlock* toBlock, var_types type);
1225
1226 #ifdef DEBUG
1227     void dumpVarToRegMap(VarToRegMap map);
1228     void dumpInVarToRegMap(BasicBlock* block);
1229     void dumpOutVarToRegMap(BasicBlock* block);
1230
1231     // There are three points at which a tuple-style dump is produced, and each
1232     // differs slightly:
1233     //   - In LSRA_DUMP_PRE, it does a simple dump of each node, with indications of what
1234     //     tree nodes are consumed.
1235     //   - In LSRA_DUMP_REFPOS, which is after the intervals are built, but before
1236     //     register allocation, each node is dumped, along with all of the RefPositions,
1237     //     The Intervals are identifed as Lnnn for lclVar intervals, Innn for for other
1238     //     intervals, and Tnnn for internal temps.
1239     //   - In LSRA_DUMP_POST, which is after register allocation, the registers are
1240     //     shown.
1241
1242     enum LsraTupleDumpMode{LSRA_DUMP_PRE, LSRA_DUMP_REFPOS, LSRA_DUMP_POST};
1243     void lsraGetOperandString(GenTree* tree, LsraTupleDumpMode mode, char* operandString, unsigned operandStringLength);
1244     void lsraDispNode(GenTree* tree, LsraTupleDumpMode mode, bool hasDest);
1245     void DumpOperandDefs(
1246         GenTree* operand, bool& first, LsraTupleDumpMode mode, char* operandString, const unsigned operandStringLength);
1247     void TupleStyleDump(LsraTupleDumpMode mode);
1248
1249     LsraLocation maxNodeLocation;
1250
1251     // Width of various fields - used to create a streamlined dump during allocation that shows the
1252     // state of all the registers in columns.
1253     int regColumnWidth;
1254     int regTableIndent;
1255
1256     const char* columnSeparator;
1257     const char* line;
1258     const char* leftBox;
1259     const char* middleBox;
1260     const char* rightBox;
1261
1262     static const int MAX_FORMAT_CHARS = 12;
1263     char             intervalNameFormat[MAX_FORMAT_CHARS];
1264     char             regNameFormat[MAX_FORMAT_CHARS];
1265     char             shortRefPositionFormat[MAX_FORMAT_CHARS];
1266     char             emptyRefPositionFormat[MAX_FORMAT_CHARS];
1267     char             indentFormat[MAX_FORMAT_CHARS];
1268     static const int MAX_LEGEND_FORMAT_CHARS = 25;
1269     char             bbRefPosFormat[MAX_LEGEND_FORMAT_CHARS];
1270     char             legendFormat[MAX_LEGEND_FORMAT_CHARS];
1271
1272     // How many rows have we printed since last printing a "title row"?
1273     static const int MAX_ROWS_BETWEEN_TITLES = 50;
1274     int              rowCountSinceLastTitle;
1275     // Current mask of registers being printed in the dump.
1276     regMaskTP lastDumpedRegisters;
1277     regMaskTP registersToDump;
1278     int       lastUsedRegNumIndex;
1279     bool shouldDumpReg(regNumber regNum)
1280     {
1281         return (registersToDump & genRegMask(regNum)) != 0;
1282     }
1283
1284     void dumpRegRecordHeader();
1285     void dumpRegRecordTitle();
1286     void dumpRegRecordTitleIfNeeded();
1287     void dumpRegRecordTitleLines();
1288     void dumpRegRecords();
1289     // An abbreviated RefPosition dump for printing with column-based register state
1290     void dumpRefPositionShort(RefPosition* refPosition, BasicBlock* currentBlock);
1291     // Print the number of spaces occupied by a dumpRefPositionShort()
1292     void dumpEmptyRefPosition();
1293     // A dump of Referent, in exactly regColumnWidth characters
1294     void dumpIntervalName(Interval* interval);
1295
1296     // Events during the allocation phase that cause some dump output
1297     enum LsraDumpEvent{
1298         // Conflicting def/use
1299         LSRA_EVENT_DEFUSE_CONFLICT, LSRA_EVENT_DEFUSE_FIXED_DELAY_USE, LSRA_EVENT_DEFUSE_CASE1, LSRA_EVENT_DEFUSE_CASE2,
1300         LSRA_EVENT_DEFUSE_CASE3, LSRA_EVENT_DEFUSE_CASE4, LSRA_EVENT_DEFUSE_CASE5, LSRA_EVENT_DEFUSE_CASE6,
1301
1302         // Spilling
1303         LSRA_EVENT_SPILL, LSRA_EVENT_SPILL_EXTENDED_LIFETIME, LSRA_EVENT_RESTORE_PREVIOUS_INTERVAL,
1304         LSRA_EVENT_RESTORE_PREVIOUS_INTERVAL_AFTER_SPILL, LSRA_EVENT_DONE_KILL_GC_REFS,
1305
1306         // Block boundaries
1307         LSRA_EVENT_START_BB, LSRA_EVENT_END_BB,
1308
1309         // Miscellaneous
1310         LSRA_EVENT_FREE_REGS,
1311
1312         // Characteristics of the current RefPosition
1313         LSRA_EVENT_INCREMENT_RANGE_END, // ???
1314         LSRA_EVENT_LAST_USE, LSRA_EVENT_LAST_USE_DELAYED, LSRA_EVENT_NEEDS_NEW_REG,
1315
1316         // Allocation decisions
1317         LSRA_EVENT_FIXED_REG, LSRA_EVENT_EXP_USE, LSRA_EVENT_ZERO_REF, LSRA_EVENT_NO_ENTRY_REG_ALLOCATED,
1318         LSRA_EVENT_KEPT_ALLOCATION, LSRA_EVENT_COPY_REG, LSRA_EVENT_MOVE_REG, LSRA_EVENT_ALLOC_REG,
1319         LSRA_EVENT_ALLOC_SPILLED_REG, LSRA_EVENT_NO_REG_ALLOCATED, LSRA_EVENT_RELOAD, LSRA_EVENT_SPECIAL_PUTARG,
1320         LSRA_EVENT_REUSE_REG,
1321     };
1322     void dumpLsraAllocationEvent(LsraDumpEvent event,
1323                                  Interval*     interval     = nullptr,
1324                                  regNumber     reg          = REG_NA,
1325                                  BasicBlock*   currentBlock = nullptr);
1326
1327     void validateIntervals();
1328 #endif // DEBUG
1329
1330 #if TRACK_LSRA_STATS
1331     enum LsraStat{
1332         LSRA_STAT_SPILL, LSRA_STAT_COPY_REG, LSRA_STAT_RESOLUTION_MOV, LSRA_STAT_SPLIT_EDGE,
1333     };
1334
1335     unsigned regCandidateVarCount;
1336     void updateLsraStat(LsraStat stat, unsigned currentBBNum);
1337
1338     void dumpLsraStats(FILE* file);
1339
1340 #define INTRACK_STATS(x) x
1341 #else // !TRACK_LSRA_STATS
1342 #define INTRACK_STATS(x)
1343 #endif // !TRACK_LSRA_STATS
1344
1345     Compiler* compiler;
1346
1347 private:
1348     CompAllocator getAllocator(Compiler* comp)
1349     {
1350         return comp->getAllocator(CMK_LSRA);
1351     }
1352
1353 #ifdef DEBUG
1354     // This is used for dumping
1355     RefPosition* activeRefPosition;
1356 #endif // DEBUG
1357
1358     IntervalList intervals;
1359
1360     RegRecord physRegs[REG_COUNT];
1361
1362     // Map from tracked variable index to Interval*.
1363     Interval** localVarIntervals;
1364
1365     // Set of blocks that have been visited.
1366     BlockSet bbVisitedSet;
1367     void markBlockVisited(BasicBlock* block)
1368     {
1369         BlockSetOps::AddElemD(compiler, bbVisitedSet, block->bbNum);
1370     }
1371     void clearVisitedBlocks()
1372     {
1373         BlockSetOps::ClearD(compiler, bbVisitedSet);
1374     }
1375     bool isBlockVisited(BasicBlock* block)
1376     {
1377         return BlockSetOps::IsMember(compiler, bbVisitedSet, block->bbNum);
1378     }
1379
1380 #if DOUBLE_ALIGN
1381     bool doDoubleAlign;
1382 #endif
1383
1384     // A map from bbNum to the block information used during register allocation.
1385     LsraBlockInfo* blockInfo;
1386     BasicBlock* findPredBlockForLiveIn(BasicBlock* block, BasicBlock* prevBlock DEBUGARG(bool* pPredBlockIsAllocated));
1387
1388     // The order in which the blocks will be allocated.
1389     // This is any array of BasicBlock*, in the order in which they should be traversed.
1390     BasicBlock** blockSequence;
1391     // The verifiedAllBBs flag indicates whether we have verified that all BBs have been
1392     // included in the blockSeuqence above, during setBlockSequence().
1393     bool verifiedAllBBs;
1394     void setBlockSequence();
1395     int compareBlocksForSequencing(BasicBlock* block1, BasicBlock* block2, bool useBlockWeights);
1396     BasicBlockList* blockSequenceWorkList;
1397     bool            blockSequencingDone;
1398     void addToBlockSequenceWorkList(BlockSet sequencedBlockSet, BasicBlock* block, BlockSet& predSet);
1399     void removeFromBlockSequenceWorkList(BasicBlockList* listNode, BasicBlockList* prevNode);
1400     BasicBlock* getNextCandidateFromWorkList();
1401
1402     // The bbNum of the block being currently allocated or resolved.
1403     unsigned int curBBNum;
1404     // The current location
1405     LsraLocation currentLoc;
1406     // The ordinal of the block we're on (i.e. this is the curBBSeqNum-th block we've allocated).
1407     unsigned int curBBSeqNum;
1408     // The number of blocks that we've sequenced.
1409     unsigned int bbSeqCount;
1410     // The Location of the start of the current block.
1411     LsraLocation curBBStartLocation;
1412     // True if the method contains any critical edges.
1413     bool hasCriticalEdges;
1414
1415     // True if there are any register candidate lclVars available for allocation.
1416     bool enregisterLocalVars;
1417
1418     virtual bool willEnregisterLocalVars() const
1419     {
1420         return enregisterLocalVars;
1421     }
1422
1423     // Ordered list of RefPositions
1424     RefPositionList refPositions;
1425
1426     // Per-block variable location mappings: an array indexed by block number that yields a
1427     // pointer to an array of regNumber, one per variable.
1428     VarToRegMap* inVarToRegMaps;
1429     VarToRegMap* outVarToRegMaps;
1430
1431     // A temporary VarToRegMap used during the resolution of critical edges.
1432     VarToRegMap sharedCriticalVarToRegMap;
1433
1434     PhasedVar<regMaskTP> availableIntRegs;
1435     PhasedVar<regMaskTP> availableFloatRegs;
1436     PhasedVar<regMaskTP> availableDoubleRegs;
1437
1438     // The set of all register candidates. Note that this may be a subset of tracked vars.
1439     VARSET_TP registerCandidateVars;
1440     // Current set of live register candidate vars, used during building of RefPositions to determine
1441     // whether to preference to callee-save.
1442     VARSET_TP currentLiveVars;
1443     // Set of variables that may require resolution across an edge.
1444     // This is first constructed during interval building, to contain all the lclVars that are live at BB edges.
1445     // Then, any lclVar that is always in the same register is removed from the set.
1446     VARSET_TP resolutionCandidateVars;
1447     // This set contains all the lclVars that are ever spilled or split.
1448     VARSET_TP splitOrSpilledVars;
1449     // Set of floating point variables to consider for callee-save registers.
1450     VARSET_TP fpCalleeSaveCandidateVars;
1451 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
1452 #if defined(_TARGET_AMD64_)
1453     static bool varTypeNeedsPartialCalleeSave(var_types type)
1454     {
1455         return (emitTypeSize(type) == 32);
1456     }
1457     static const var_types LargeVectorSaveType = TYP_SIMD16;
1458 #elif defined(_TARGET_ARM64_)
1459     static bool varTypeNeedsPartialCalleeSave(var_types type)
1460     {
1461         // ARM64 ABI FP Callee save registers only require Callee to save lower 8 Bytes
1462         // For SIMD types longer then 8 bytes Caller is responsible for saving and restoring Upper bytes.
1463         return (emitTypeSize(type) == 16);
1464     }
1465     static const var_types LargeVectorSaveType = TYP_DOUBLE;
1466 #else // !defined(_TARGET_AMD64_) && !defined(_TARGET_ARM64_)
1467 #error("Unknown target architecture for FEATURE_SIMD")
1468 #endif // !defined(_TARGET_AMD64_) && !defined(_TARGET_ARM64_)
1469
1470     // Set of large vector (TYP_SIMD32 on AVX) variables.
1471     VARSET_TP largeVectorVars;
1472     // Set of large vector (TYP_SIMD32 on AVX) variables to consider for callee-save registers.
1473     VARSET_TP largeVectorCalleeSaveCandidateVars;
1474 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
1475
1476     //-----------------------------------------------------------------------
1477     // Build methods
1478     //-----------------------------------------------------------------------
1479
1480     // The listNodePool is used to maintain the RefInfo for nodes that are "in flight"
1481     // i.e. whose consuming node has not yet been handled.
1482     RefInfoListNodePool listNodePool;
1483
1484     // The defList is used for the transient RefInfo that is computed by
1485     // the Build methods, and used in building RefPositions.
1486     // When Def RefPositions are built for a node, their NodeInfo is placed
1487     // in the defList. As the consuming node is handled, it moves the NodeInfo
1488     // into an ordered useList corresponding to the uses for that node.
1489     RefInfoList defList;
1490
1491     // As we build uses, we may want to preference the next definition (i.e. the register produced
1492     // by the current node) to the same register as one of its uses. This is done by setting
1493     // 'tgtPrefUse' to that RefPosition.
1494     RefPosition* tgtPrefUse  = nullptr;
1495     RefPosition* tgtPrefUse2 = nullptr;
1496
1497     // The following keep track of information about internal (temporary register) intervals
1498     // during the building of a single node.
1499     static const int MaxInternalCount = 4;
1500     RefPosition*     internalDefs[MaxInternalCount];
1501     int              internalCount = 0;
1502     bool             setInternalRegsDelayFree;
1503
1504     // When a RefTypeUse is marked as 'delayRegFree', we also want to mark the RefTypeDef
1505     // in the next Location as 'hasInterferingUses'. This is accomplished by setting this
1506     // 'pendingDelayFree' to true as they are created, and clearing it as a new node is
1507     // handled in 'BuildNode'.
1508     bool pendingDelayFree;
1509
1510     // This method clears the "build state" before starting to handle a new node.
1511     void clearBuildState()
1512     {
1513         tgtPrefUse               = nullptr;
1514         tgtPrefUse2              = nullptr;
1515         internalCount            = 0;
1516         setInternalRegsDelayFree = false;
1517         pendingDelayFree         = false;
1518     }
1519
1520     RefPosition* BuildUse(GenTree* operand, regMaskTP candidates = RBM_NONE, int multiRegIdx = 0);
1521
1522     void setDelayFree(RefPosition* use);
1523     int BuildBinaryUses(GenTreeOp* node, regMaskTP candidates = RBM_NONE);
1524 #ifdef _TARGET_XARCH_
1525     int BuildRMWUses(GenTreeOp* node, regMaskTP candidates = RBM_NONE);
1526 #endif // !_TARGET_XARCH_
1527     // This is the main entry point for building the RefPositions for a node.
1528     // These methods return the number of sources.
1529     int BuildNode(GenTree* stmt);
1530
1531     void getTgtPrefOperands(GenTreeOp* tree, bool& prefOp1, bool& prefOp2);
1532     bool supportsSpecialPutArg();
1533
1534     int BuildSimple(GenTree* tree);
1535     int BuildOperandUses(GenTree* node, regMaskTP candidates = RBM_NONE);
1536     int BuildDelayFreeUses(GenTree* node, regMaskTP candidates = RBM_NONE);
1537     int BuildIndirUses(GenTreeIndir* indirTree, regMaskTP candidates = RBM_NONE);
1538     int BuildAddrUses(GenTree* addr, regMaskTP candidates = RBM_NONE);
1539     void HandleFloatVarArgs(GenTreeCall* call, GenTree* argNode, bool* callHasFloatRegArgs);
1540     RefPosition* BuildDef(GenTree* tree, regMaskTP dstCandidates = RBM_NONE, int multiRegIdx = 0);
1541     void BuildDefs(GenTree* tree, int dstCount, regMaskTP dstCandidates = RBM_NONE);
1542     void BuildDefsWithKills(GenTree* tree, int dstCount, regMaskTP dstCandidates, regMaskTP killMask);
1543
1544     int BuildStoreLoc(GenTree* tree);
1545     int BuildReturn(GenTree* tree);
1546 #ifdef _TARGET_XARCH_
1547     // This method, unlike the others, returns the number of sources, since it may be called when
1548     // 'tree' is contained.
1549     int BuildShiftRotate(GenTree* tree);
1550 #endif // _TARGET_XARCH_
1551 #ifdef _TARGET_ARM_
1552     int BuildShiftLongCarry(GenTree* tree);
1553 #endif
1554     int BuildPutArgReg(GenTreeUnOp* node);
1555     int BuildCall(GenTreeCall* call);
1556     int BuildCmp(GenTree* tree);
1557     int BuildBlockStore(GenTreeBlk* blkNode);
1558     int BuildModDiv(GenTree* tree);
1559     int BuildIntrinsic(GenTree* tree);
1560     int BuildStoreLoc(GenTreeLclVarCommon* tree);
1561     int BuildIndir(GenTreeIndir* indirTree);
1562     int BuildGCWriteBarrier(GenTree* tree);
1563     int BuildCast(GenTreeCast* cast);
1564
1565 #if defined(_TARGET_XARCH_)
1566     // returns true if the tree can use the read-modify-write memory instruction form
1567     bool isRMWRegOper(GenTree* tree);
1568     int BuildMul(GenTree* tree);
1569     void SetContainsAVXFlags(unsigned sizeOfSIMDVector = 0);
1570     // Move the last use bit, if any, from 'fromTree' to 'toTree'; 'fromTree' must be contained.
1571     void CheckAndMoveRMWLastUse(GenTree* fromTree, GenTree* toTree)
1572     {
1573         // If 'fromTree' is not a last-use lclVar, there's nothing to do.
1574         if ((fromTree == nullptr) || !fromTree->OperIs(GT_LCL_VAR) || ((fromTree->gtFlags & GTF_VAR_DEATH) == 0))
1575         {
1576             return;
1577         }
1578         // If 'fromTree' was a lclVar, it must be contained and 'toTree' must match.
1579         if (!fromTree->isContained() || (toTree == nullptr) || !toTree->OperIs(GT_LCL_VAR) ||
1580             (toTree->AsLclVarCommon()->gtLclNum != toTree->AsLclVarCommon()->gtLclNum))
1581         {
1582             assert(!"Unmatched RMW indirections");
1583             return;
1584         }
1585         // This is probably not necessary, but keeps things consistent.
1586         fromTree->gtFlags &= ~GTF_VAR_DEATH;
1587         if (toTree != nullptr) // Just to be conservative
1588         {
1589             toTree->gtFlags |= GTF_VAR_DEATH;
1590         }
1591     }
1592 #endif // defined(_TARGET_XARCH_)
1593
1594 #ifdef FEATURE_SIMD
1595     int BuildSIMD(GenTreeSIMD* tree);
1596 #endif // FEATURE_SIMD
1597
1598 #ifdef FEATURE_HW_INTRINSICS
1599     int BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree);
1600 #endif // FEATURE_HW_INTRINSICS
1601
1602     int BuildPutArgStk(GenTreePutArgStk* argNode);
1603 #if FEATURE_ARG_SPLIT
1604     int BuildPutArgSplit(GenTreePutArgSplit* tree);
1605 #endif // FEATURE_ARG_SPLIT
1606     int BuildLclHeap(GenTree* tree);
1607 };
1608
1609 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1610 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1611 XX                                                                           XX
1612 XX                           Interval                                        XX
1613 XX                                                                           XX
1614 XX This is the fundamental data structure for linear scan register           XX
1615 XX allocation.  It represents the live range(s) for a variable or temp.      XX
1616 XX                                                                           XX
1617 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1618 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
1619 */
1620
1621 class Interval : public Referenceable
1622 {
1623 public:
1624     Interval(RegisterType registerType, regMaskTP registerPreferences)
1625         : registerPreferences(registerPreferences)
1626         , relatedInterval(nullptr)
1627         , assignedReg(nullptr)
1628         , registerType(registerType)
1629         , isLocalVar(false)
1630         , isSplit(false)
1631         , isSpilled(false)
1632         , isInternal(false)
1633         , isStructField(false)
1634         , isPromotedStruct(false)
1635         , hasConflictingDefUse(false)
1636         , hasInterferingUses(false)
1637         , isSpecialPutArg(false)
1638         , preferCalleeSave(false)
1639         , isConstant(false)
1640         , physReg(REG_COUNT)
1641 #ifdef DEBUG
1642         , intervalIndex(0)
1643 #endif
1644         , varNum(0)
1645     {
1646     }
1647
1648 #ifdef DEBUG
1649     // print out representation
1650     void dump();
1651     // concise representation for embedding
1652     void tinyDump();
1653     // extremely concise representation
1654     void microDump();
1655 #endif // DEBUG
1656
1657     void setLocalNumber(Compiler* compiler, unsigned lclNum, LinearScan* l);
1658
1659     // Fixed registers for which this Interval has a preference
1660     regMaskTP registerPreferences;
1661
1662     // The relatedInterval is:
1663     //  - for any other interval, it is the interval to which this interval
1664     //    is currently preferenced (e.g. because they are related by a copy)
1665     Interval* relatedInterval;
1666
1667     // The assignedReg is the RecRecord for the register to which this interval
1668     // has been assigned at some point - if the interval is active, this is the
1669     // register it currently occupies.
1670     RegRecord* assignedReg;
1671
1672     // DECIDE : put this in a union or do something w/ inheritance?
1673     // this is an interval for a physical register, not a allocatable entity
1674
1675     RegisterType registerType;
1676     bool         isLocalVar : 1;
1677     // Indicates whether this interval has been assigned to different registers
1678     bool isSplit : 1;
1679     // Indicates whether this interval is ever spilled
1680     bool isSpilled : 1;
1681     // indicates an interval representing the internal requirements for
1682     // generating code for a node (temp registers internal to the node)
1683     // Note that this interval may live beyond a node in the GT_ARR_LENREF/GT_IND
1684     // case (though never lives beyond a stmt)
1685     bool isInternal : 1;
1686     // true if this is a LocalVar for a struct field
1687     bool isStructField : 1;
1688     // true iff this is a GT_LDOBJ for a fully promoted (PROMOTION_TYPE_INDEPENDENT) struct
1689     bool isPromotedStruct : 1;
1690     // true if this is an SDSU interval for which the def and use have conflicting register
1691     // requirements
1692     bool hasConflictingDefUse : 1;
1693     // true if this interval's defining node has "delayRegFree" uses, either due to it being an RMW instruction,
1694     // OR because it requires an internal register that differs from the target.
1695     bool hasInterferingUses : 1;
1696
1697     // True if this interval is defined by a putArg, whose source is a non-last-use lclVar.
1698     // During allocation, this flag will be cleared if the source is not already in the required register.
1699     // Othewise, we will leave the register allocated to the lclVar, but mark the RegRecord as
1700     // isBusyUntilNextKill, so that it won't be reused if the lclVar goes dead before the call.
1701     bool isSpecialPutArg : 1;
1702
1703     // True if this interval interferes with a call.
1704     bool preferCalleeSave : 1;
1705
1706     // True if this interval is defined by a constant node that may be reused and/or may be
1707     // able to reuse a constant that's already in a register.
1708     bool isConstant : 1;
1709
1710     // The register to which it is currently assigned.
1711     regNumber physReg;
1712
1713 #ifdef DEBUG
1714     unsigned int intervalIndex;
1715 #endif // DEBUG
1716
1717     unsigned int varNum; // This is the "variable number": the index into the lvaTable array
1718
1719     LclVarDsc* getLocalVar(Compiler* comp)
1720     {
1721         assert(isLocalVar);
1722         return &(comp->lvaTable[this->varNum]);
1723     }
1724
1725     // Get the local tracked variable "index" (lvVarIndex), used in bitmasks.
1726     unsigned getVarIndex(Compiler* comp)
1727     {
1728         LclVarDsc* varDsc = getLocalVar(comp);
1729         assert(varDsc->lvTracked); // If this isn't true, we shouldn't be calling this function!
1730         return varDsc->lvVarIndex;
1731     }
1732
1733     bool isAssignedTo(regNumber regNum)
1734     {
1735         // This uses regMasks to handle the case where a double actually occupies two registers
1736         // TODO-Throughput: This could/should be done more cheaply.
1737         return (physReg != REG_NA && (genRegMask(physReg, registerType) & genRegMask(regNum)) != RBM_NONE);
1738     }
1739
1740     // Assign the related interval.
1741     void assignRelatedInterval(Interval* newRelatedInterval)
1742     {
1743 #ifdef DEBUG
1744         if (VERBOSE)
1745         {
1746             printf("Assigning related ");
1747             newRelatedInterval->microDump();
1748             printf(" to ");
1749             this->microDump();
1750             printf("\n");
1751         }
1752 #endif // DEBUG
1753         relatedInterval = newRelatedInterval;
1754     }
1755
1756     // Assign the related interval, but only if it isn't already assigned.
1757     bool assignRelatedIntervalIfUnassigned(Interval* newRelatedInterval)
1758     {
1759         if (relatedInterval == nullptr)
1760         {
1761             assignRelatedInterval(newRelatedInterval);
1762             return true;
1763         }
1764         else
1765         {
1766 #ifdef DEBUG
1767             if (VERBOSE)
1768             {
1769                 printf("Interval ");
1770                 this->microDump();
1771                 printf(" already has a related interval\n");
1772             }
1773 #endif // DEBUG
1774             return false;
1775         }
1776     }
1777
1778     // Get the current preferences for this Interval.
1779     // Note that when we have an assigned register we don't necessarily update the
1780     // registerPreferences to that register, as there may be multiple, possibly disjoint,
1781     // definitions. This method will return the current assigned register if any, or
1782     // the 'registerPreferences' otherwise.
1783     //
1784     regMaskTP getCurrentPreferences()
1785     {
1786         return (assignedReg == nullptr) ? registerPreferences : genRegMask(assignedReg->regNum);
1787     }
1788
1789     void mergeRegisterPreferences(regMaskTP preferences)
1790     {
1791         // We require registerPreferences to have been initialized.
1792         assert(registerPreferences != RBM_NONE);
1793         // It is invalid to update with empty preferences
1794         assert(preferences != RBM_NONE);
1795
1796         regMaskTP commonPreferences = (registerPreferences & preferences);
1797         if (commonPreferences != RBM_NONE)
1798         {
1799             registerPreferences = commonPreferences;
1800             return;
1801         }
1802
1803         // There are no preferences in common.
1804         // Preferences need to reflect both cases where a var must occupy a specific register,
1805         // as well as cases where a var is live when a register is killed.
1806         // In the former case, we would like to record all such registers, however we don't
1807         // really want to use any registers that will interfere.
1808         // To approximate this, we never "or" together multi-reg sets, which are generally kill sets.
1809
1810         if (!genMaxOneBit(preferences))
1811         {
1812             // The new preference value is a multi-reg set, so it's probably a kill.
1813             // Keep the new value.
1814             registerPreferences = preferences;
1815             return;
1816         }
1817
1818         if (!genMaxOneBit(registerPreferences))
1819         {
1820             // The old preference value is a multi-reg set.
1821             // Keep the existing preference set, as it probably reflects one or more kills.
1822             // It may have been a union of multiple individual registers, but we can't
1823             // distinguish that case without extra cost.
1824             return;
1825         }
1826
1827         // If we reach here, we have two disjoint single-reg sets.
1828         // Keep only the callee-save preferences, if not empty.
1829         // Otherwise, take the union of the preferences.
1830
1831         regMaskTP newPreferences = registerPreferences | preferences;
1832
1833         if (preferCalleeSave)
1834         {
1835             regMaskTP calleeSaveMask = (calleeSaveRegs(this->registerType) & (newPreferences));
1836             if (calleeSaveMask != RBM_NONE)
1837             {
1838                 newPreferences = calleeSaveMask;
1839             }
1840         }
1841         registerPreferences = newPreferences;
1842     }
1843
1844     // Update the registerPreferences on the interval.
1845     // If there are conflicting requirements on this interval, set the preferences to
1846     // the union of them.  That way maybe we'll get at least one of them.
1847     // An exception is made in the case where one of the existing or new
1848     // preferences are all callee-save, in which case we "prefer" the callee-save
1849
1850     void updateRegisterPreferences(regMaskTP preferences)
1851     {
1852         // If this interval is preferenced, that interval may have already been assigned a
1853         // register, and we want to include that in the preferences.
1854         if ((relatedInterval != nullptr) && !relatedInterval->isActive)
1855         {
1856             mergeRegisterPreferences(relatedInterval->getCurrentPreferences());
1857         }
1858
1859         // Now merge the new preferences.
1860         mergeRegisterPreferences(preferences);
1861     }
1862 };
1863
1864 class RefPosition
1865 {
1866 public:
1867     // A RefPosition refers to either an Interval or a RegRecord. 'referent' points to one
1868     // of these types. If it refers to a RegRecord, then 'isPhysRegRef' is true. If it
1869     // refers to an Interval, then 'isPhysRegRef' is false.
1870     // referent can never be null.
1871
1872     Referenceable* referent;
1873
1874     // nextRefPosition is the next in code order.
1875     // Note that in either case there is no need for these to be doubly linked, as they
1876     // are only traversed in the forward direction, and are not moved.
1877     RefPosition* nextRefPosition;
1878
1879     // The remaining fields are common to both options
1880     GenTree*     treeNode;
1881     unsigned int bbNum;
1882
1883     // Prior to the allocation pass, registerAssignment captures the valid registers
1884     // for this RefPosition. An empty set means that any register is valid.  A non-empty
1885     // set means that it must be one of the given registers (may be the full set if the
1886     // only constraint is that it must reside in SOME register)
1887     // After the allocation pass, this contains the actual assignment
1888     LsraLocation nodeLocation;
1889     regMaskTP    registerAssignment;
1890
1891     RefType refType;
1892
1893     // NOTE: C++ only packs bitfields if the base type is the same. So make all the base
1894     // NOTE: types of the logically "bool" types that follow 'unsigned char', so they match
1895     // NOTE: RefType that precedes this, and multiRegIdx can also match.
1896
1897     // Indicates whether this ref position is to be allocated a reg only if profitable. Currently these are the
1898     // ref positions that lower/codegen has indicated as reg optional and is considered a contained memory operand if
1899     // no reg is allocated.
1900     unsigned char allocRegIfProfitable : 1;
1901
1902     // Used by RefTypeDef/Use positions of a multi-reg call node.
1903     // Indicates the position of the register that this ref position refers to.
1904     // The max bits needed is based on max value of MAX_RET_REG_COUNT value
1905     // across all targets and that happens 4 on on Arm.  Hence index value
1906     // would be 0..MAX_RET_REG_COUNT-1.
1907     unsigned char multiRegIdx : 2;
1908
1909     // Last Use - this may be true for multiple RefPositions in the same Interval
1910     unsigned char lastUse : 1;
1911
1912     // Spill and Copy info
1913     //   reload indicates that the value was spilled, and must be reloaded here.
1914     //   spillAfter indicates that the value is spilled here, so a spill must be added.
1915     //   copyReg indicates that the value needs to be copied to a specific register,
1916     //      but that it will also retain its current assigned register.
1917     //   moveReg indicates that the value needs to be moved to a different register,
1918     //      and that this will be its new assigned register.
1919     // A RefPosition may have any flag individually or the following combinations:
1920     //  - reload and spillAfter (i.e. it remains in memory), but not in combination with copyReg or moveReg
1921     //    (reload cannot exist with copyReg or moveReg; it should be reloaded into the appropriate reg)
1922     //  - spillAfter and copyReg (i.e. it must be copied to a new reg for use, but is then spilled)
1923     //  - spillAfter and moveReg (i.e. it most be both spilled and moved)
1924     //    NOTE: a moveReg involves an explicit move, and would usually not be needed for a fixed Reg if it is going
1925     //    to be spilled, because the code generator will do the move to the fixed register, and doesn't need to
1926     //    record the new register location as the new "home" location of the lclVar. However, if there is a conflicting
1927     //    use at the same location (e.g. lclVar V1 is in rdx and needs to be in rcx, but V2 needs to be in rdx), then
1928     //    we need an explicit move.
1929     //  - copyReg and moveReg must not exist with each other.
1930
1931     unsigned char reload : 1;
1932     unsigned char spillAfter : 1;
1933     unsigned char copyReg : 1;
1934     unsigned char moveReg : 1; // true if this var is moved to a new register
1935
1936     unsigned char isPhysRegRef : 1; // true if 'referent' points of a RegRecord, false if it points to an Interval
1937     unsigned char isFixedRegRef : 1;
1938     unsigned char isLocalDefUse : 1;
1939
1940     // delayRegFree indicates that the register should not be freed right away, but instead wait
1941     // until the next Location after it would normally be freed.  This is used for the case of
1942     // non-commutative binary operators, where op2 must not be assigned the same register as
1943     // the target.  We do this by not freeing it until after the target has been defined.
1944     // Another option would be to actually change the Location of the op2 use until the same
1945     // Location as the def, but then it could potentially reuse a register that has been freed
1946     // from the other source(s), e.g. if it's a lastUse or spilled.
1947     unsigned char delayRegFree : 1;
1948
1949     // outOfOrder is marked on a (non-def) RefPosition that doesn't follow a definition of the
1950     // register currently assigned to the Interval.  This happens when we use the assigned
1951     // register from a predecessor that is not the most recently allocated BasicBlock.
1952     unsigned char outOfOrder : 1;
1953
1954 #ifdef DEBUG
1955     // Minimum number registers that needs to be ensured while
1956     // constraining candidates for this ref position under
1957     // LSRA stress.
1958     unsigned minRegCandidateCount;
1959
1960     // The unique RefPosition number, equal to its index in the
1961     // refPositions list. Only used for debugging dumps.
1962     unsigned rpNum;
1963 #endif // DEBUG
1964
1965     RefPosition(unsigned int bbNum, LsraLocation nodeLocation, GenTree* treeNode, RefType refType)
1966         : referent(nullptr)
1967         , nextRefPosition(nullptr)
1968         , treeNode(treeNode)
1969         , bbNum(bbNum)
1970         , nodeLocation(nodeLocation)
1971         , registerAssignment(RBM_NONE)
1972         , refType(refType)
1973         , multiRegIdx(0)
1974         , lastUse(false)
1975         , reload(false)
1976         , spillAfter(false)
1977         , copyReg(false)
1978         , moveReg(false)
1979         , isPhysRegRef(false)
1980         , isFixedRegRef(false)
1981         , isLocalDefUse(false)
1982         , delayRegFree(false)
1983         , outOfOrder(false)
1984 #ifdef DEBUG
1985         , minRegCandidateCount(1)
1986         , rpNum(0)
1987 #endif
1988     {
1989     }
1990
1991     Interval* getInterval()
1992     {
1993         assert(!isPhysRegRef);
1994         return (Interval*)referent;
1995     }
1996     void setInterval(Interval* i)
1997     {
1998         referent     = i;
1999         isPhysRegRef = false;
2000     }
2001
2002     RegRecord* getReg()
2003     {
2004         assert(isPhysRegRef);
2005         return (RegRecord*)referent;
2006     }
2007     void setReg(RegRecord* r)
2008     {
2009         referent           = r;
2010         isPhysRegRef       = true;
2011         registerAssignment = genRegMask(r->regNum);
2012     }
2013
2014     regNumber assignedReg()
2015     {
2016         if (registerAssignment == RBM_NONE)
2017         {
2018             return REG_NA;
2019         }
2020
2021         return genRegNumFromMask(registerAssignment);
2022     }
2023
2024     // Returns true if it is a reference on a gentree node.
2025     bool IsActualRef()
2026     {
2027         return (refType == RefTypeDef || refType == RefTypeUse);
2028     }
2029
2030     bool RequiresRegister()
2031     {
2032         return (IsActualRef()
2033 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
2034                 || refType == RefTypeUpperVectorSaveDef || refType == RefTypeUpperVectorSaveUse
2035 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
2036                 ) &&
2037                !AllocateIfProfitable();
2038     }
2039
2040     void setAllocateIfProfitable(bool val)
2041     {
2042         allocRegIfProfitable = val;
2043     }
2044
2045     // Returns true whether this ref position is to be allocated
2046     // a reg only if it is profitable.
2047     bool AllocateIfProfitable()
2048     {
2049         // TODO-CQ: Right now if a ref position is marked as
2050         // copyreg or movereg, then it is not treated as
2051         // 'allocate if profitable'. This is an implementation
2052         // limitation that needs to be addressed.
2053         return allocRegIfProfitable && !copyReg && !moveReg;
2054     }
2055
2056     void setMultiRegIdx(unsigned idx)
2057     {
2058         multiRegIdx = idx;
2059         assert(multiRegIdx == idx);
2060     }
2061
2062     unsigned getMultiRegIdx()
2063     {
2064         return multiRegIdx;
2065     }
2066
2067     LsraLocation getRefEndLocation()
2068     {
2069         return delayRegFree ? nodeLocation + 1 : nodeLocation;
2070     }
2071
2072     RefPosition* getRangeEndRef()
2073     {
2074         if (lastUse || nextRefPosition == nullptr)
2075         {
2076             return this;
2077         }
2078         // It would seem to make sense to only return 'nextRefPosition' if it is a lastUse,
2079         // and otherwise return `lastRefPosition', but that tends to  excessively lengthen
2080         // the range for heuristic purposes.
2081         // TODO-CQ: Look into how this might be improved .
2082         return nextRefPosition;
2083     }
2084
2085     LsraLocation getRangeEndLocation()
2086     {
2087         return getRangeEndRef()->getRefEndLocation();
2088     }
2089
2090     bool isIntervalRef()
2091     {
2092         return (!isPhysRegRef && (referent != nullptr));
2093     }
2094
2095     // isTrueDef indicates that the RefPosition is a non-update def of a non-internal
2096     // interval
2097     bool isTrueDef()
2098     {
2099         return (refType == RefTypeDef && isIntervalRef() && !getInterval()->isInternal);
2100     }
2101
2102     // isFixedRefOfRegMask indicates that the RefPosition has a fixed assignment to the register
2103     // specified by the given mask
2104     bool isFixedRefOfRegMask(regMaskTP regMask)
2105     {
2106         assert(genMaxOneBit(regMask));
2107         return (registerAssignment == regMask);
2108     }
2109
2110     // isFixedRefOfReg indicates that the RefPosition has a fixed assignment to the given register
2111     bool isFixedRefOfReg(regNumber regNum)
2112     {
2113         return (isFixedRefOfRegMask(genRegMask(regNum)));
2114     }
2115
2116 #ifdef DEBUG
2117     // operator= copies everything except 'rpNum', which must remain unique
2118     RefPosition& operator=(const RefPosition& rp)
2119     {
2120         unsigned rpNumSave = rpNum;
2121         memcpy(this, &rp, sizeof(rp));
2122         rpNum = rpNumSave;
2123         return *this;
2124     }
2125
2126     void dump();
2127 #endif // DEBUG
2128 };
2129
2130 #ifdef DEBUG
2131 void dumpRegMask(regMaskTP regs);
2132 #endif // DEBUG
2133
2134 /*****************************************************************************/
2135 #endif //_LSRA_H_
2136 /*****************************************************************************/