Merge pull request #12878 from hseok-oh/ryujit/struct_promote1
[platform/upstream/coreclr.git] / src / jit / lsra.cpp
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 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8
9                  Linear Scan Register Allocation
10
11                          a.k.a. LSRA
12
13   Preconditions
14     - All register requirements are expressed in the code stream, either as destination
15       registers of tree nodes, or as internal registers.  These requirements are
16       expressed in the TreeNodeInfo (gtLsraInfo) on each node, which includes:
17       - The number of register sources and destinations.
18       - The register restrictions (candidates) of the target register, both from itself,
19         as producer of the value (dstCandidates), and from its consuming node (srcCandidates).
20         Note that the srcCandidates field of TreeNodeInfo refers to the destination register
21         (not any of its sources).
22       - The number (internalCount) of registers required, and their register restrictions (internalCandidates).
23         These are neither inputs nor outputs of the node, but used in the sequence of code generated for the tree.
24     "Internal registers" are registers used during the code sequence generated for the node.
25     The register lifetimes must obey the following lifetime model:
26     - First, any internal registers are defined.
27     - Next, any source registers are used (and are then freed if they are last use and are not identified as
28       "delayRegFree").
29     - Next, the internal registers are used (and are then freed).
30     - Next, any registers in the kill set for the instruction are killed.
31     - Next, the destination register(s) are defined (multiple destination registers are only supported on ARM)
32     - Finally, any "delayRegFree" source registers are freed.
33   There are several things to note about this order:
34     - The internal registers will never overlap any use, but they may overlap a destination register.
35     - Internal registers are never live beyond the node.
36     - The "delayRegFree" annotation is used for instructions that are only available in a Read-Modify-Write form.
37       That is, the destination register is one of the sources.  In this case, we must not use the same register for
38       the non-RMW operand as for the destination.
39
40   Overview (doLinearScan):
41     - Walk all blocks, building intervals and RefPositions (buildIntervals)
42     - Allocate registers (allocateRegisters)
43     - Annotate nodes with register assignments (resolveRegisters)
44     - Add move nodes as needed to resolve conflicting register
45       assignments across non-adjacent edges. (resolveEdges, called from resolveRegisters)
46
47   Postconditions:
48
49     Tree nodes (GenTree):
50     - GenTree::gtRegNum (and gtRegPair for ARM) is annotated with the register
51       assignment for a node. If the node does not require a register, it is
52       annotated as such (for single registers, gtRegNum = REG_NA; for register
53       pair type, gtRegPair = REG_PAIR_NONE). For a variable definition or interior
54       tree node (an "implicit" definition), this is the register to put the result.
55       For an expression use, this is the place to find the value that has previously
56       been computed.
57       - In most cases, this register must satisfy the constraints specified by the TreeNodeInfo.
58       - In some cases, this is difficult:
59         - If a lclVar node currently lives in some register, it may not be desirable to move it
60           (i.e. its current location may be desirable for future uses, e.g. if it's a callee save register,
61           but needs to be in a specific arg register for a call).
62         - In other cases there may be conflicts on the restrictions placed by the defining node and the node which
63           consumes it
64       - If such a node is constrained to a single fixed register (e.g. an arg register, or a return from a call),
65         then LSRA is free to annotate the node with a different register.  The code generator must issue the appropriate
66         move.
67       - However, if such a node is constrained to a set of registers, and its current location does not satisfy that
68         requirement, LSRA must insert a GT_COPY node between the node and its parent.  The gtRegNum on the GT_COPY node
69         must satisfy the register requirement of the parent.
70     - GenTree::gtRsvdRegs has a set of registers used for internal temps.
71     - A tree node is marked GTF_SPILL if the tree node must be spilled by the code generator after it has been
72       evaluated.
73       - LSRA currently does not set GTF_SPILLED on such nodes, because it caused problems in the old code generator.
74         In the new backend perhaps this should change (see also the note below under CodeGen).
75     - A tree node is marked GTF_SPILLED if it is a lclVar that must be reloaded prior to use.
76       - The register (gtRegNum) on the node indicates the register to which it must be reloaded.
77       - For lclVar nodes, since the uses and defs are distinct tree nodes, it is always possible to annotate the node
78         with the register to which the variable must be reloaded.
79       - For other nodes, since they represent both the def and use, if the value must be reloaded to a different
80         register, LSRA must insert a GT_RELOAD node in order to specify the register to which it should be reloaded.
81
82     Local variable table (LclVarDsc):
83     - LclVarDsc::lvRegister is set to true if a local variable has the
84       same register assignment for its entire lifetime.
85     - LclVarDsc::lvRegNum / lvOtherReg: these are initialized to their
86       first value at the end of LSRA (it looks like lvOtherReg isn't?
87       This is probably a bug (ARM)). Codegen will set them to their current value
88       as it processes the trees, since a variable can (now) be assigned different
89       registers over its lifetimes.
90
91 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
92 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
93 */
94
95 #include "jitpch.h"
96 #ifdef _MSC_VER
97 #pragma hdrstop
98 #endif
99
100 #ifndef LEGACY_BACKEND // This file is ONLY used for the RyuJIT backend that uses the linear scan register allocator
101
102 #include "lsra.h"
103
104 #ifdef DEBUG
105 const char* LinearScan::resolveTypeName[] = {"Split", "Join", "Critical", "SharedCritical"};
106 #endif // DEBUG
107
108 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
109 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
110 XX                                                                           XX
111 XX                    Small Helper functions                                 XX
112 XX                                                                           XX
113 XX                                                                           XX
114 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
115 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
116 */
117
118 //--------------------------------------------------------------
119 // lsraAssignRegToTree: Assign the given reg to tree node.
120 //
121 // Arguments:
122 //    tree    -    Gentree node
123 //    reg     -    register to be assigned
124 //    regIdx  -    register idx, if tree is a multi-reg call node.
125 //                 regIdx will be zero for single-reg result producing tree nodes.
126 //
127 // Return Value:
128 //    None
129 //
130 void lsraAssignRegToTree(GenTreePtr tree, regNumber reg, unsigned regIdx)
131 {
132     if (regIdx == 0)
133     {
134         tree->gtRegNum = reg;
135     }
136 #if defined(_TARGET_ARM_)
137     else if (tree->OperGet() == GT_MUL_LONG || tree->OperGet() == GT_PUTARG_REG)
138     {
139         assert(regIdx == 1);
140         GenTreeMultiRegOp* mul = tree->AsMultiRegOp();
141         mul->gtOtherReg        = reg;
142     }
143     else if (tree->OperGet() == GT_COPY)
144     {
145         assert(regIdx == 1);
146         GenTreeCopyOrReload* copy = tree->AsCopyOrReload();
147         copy->gtOtherRegs[0]      = (regNumberSmall)reg;
148     }
149     else if (tree->OperGet() == GT_PUTARG_SPLIT)
150     {
151         GenTreePutArgSplit* putArg = tree->AsPutArgSplit();
152         putArg->SetRegNumByIdx(reg, regIdx);
153     }
154 #endif // _TARGET_ARM_
155     else
156     {
157         assert(tree->IsMultiRegCall());
158         GenTreeCall* call = tree->AsCall();
159         call->SetRegNumByIdx(reg, regIdx);
160     }
161 }
162
163 //-------------------------------------------------------------
164 // getWeight: Returns the weight of the RefPosition.
165 //
166 // Arguments:
167 //    refPos   -   ref position
168 //
169 // Returns:
170 //    Weight of ref position.
171 unsigned LinearScan::getWeight(RefPosition* refPos)
172 {
173     unsigned   weight;
174     GenTreePtr treeNode = refPos->treeNode;
175
176     if (treeNode != nullptr)
177     {
178         if (isCandidateLocalRef(treeNode))
179         {
180             // Tracked locals: use weighted ref cnt as the weight of the
181             // ref position.
182             GenTreeLclVarCommon* lclCommon = treeNode->AsLclVarCommon();
183             LclVarDsc*           varDsc    = &(compiler->lvaTable[lclCommon->gtLclNum]);
184             weight                         = varDsc->lvRefCntWtd;
185         }
186         else
187         {
188             // Non-candidate local ref or non-lcl tree node.
189             // These are considered to have two references in the basic block:
190             // a def and a use and hence weighted ref count is 2 times
191             // the basic block weight in which they appear.
192             weight = 2 * this->blockInfo[refPos->bbNum].weight;
193         }
194     }
195     else
196     {
197         // Non-tree node ref positions.  These will have a single
198         // reference in the basic block and hence their weighted
199         // refcount is equal to the block weight in which they
200         // appear.
201         weight = this->blockInfo[refPos->bbNum].weight;
202     }
203
204     return weight;
205 }
206
207 // allRegs represents a set of registers that can
208 // be used to allocate the specified type in any point
209 // in time (more of a 'bank' of registers).
210 regMaskTP LinearScan::allRegs(RegisterType rt)
211 {
212     if (rt == TYP_FLOAT)
213     {
214         return availableFloatRegs;
215     }
216     else if (rt == TYP_DOUBLE)
217     {
218         return availableDoubleRegs;
219 #ifdef FEATURE_SIMD
220         // TODO-Cleanup: Add an RBM_ALLSIMD
221     }
222     else if (varTypeIsSIMD(rt))
223     {
224         return availableDoubleRegs;
225 #endif // FEATURE_SIMD
226     }
227     else
228     {
229         return availableIntRegs;
230     }
231 }
232
233 //--------------------------------------------------------------------------
234 // allMultiRegCallNodeRegs: represents a set of registers that can be used
235 // to allocate a multi-reg call node.
236 //
237 // Arguments:
238 //    call   -  Multi-reg call node
239 //
240 // Return Value:
241 //    Mask representing the set of available registers for multi-reg call
242 //    node.
243 //
244 // Note:
245 // Multi-reg call node available regs = Bitwise-OR(allregs(GetReturnRegType(i)))
246 // for all i=0..RetRegCount-1.
247 regMaskTP LinearScan::allMultiRegCallNodeRegs(GenTreeCall* call)
248 {
249     assert(call->HasMultiRegRetVal());
250
251     ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc();
252     regMaskTP       resultMask  = allRegs(retTypeDesc->GetReturnRegType(0));
253
254     unsigned count = retTypeDesc->GetReturnRegCount();
255     for (unsigned i = 1; i < count; ++i)
256     {
257         resultMask |= allRegs(retTypeDesc->GetReturnRegType(i));
258     }
259
260     return resultMask;
261 }
262
263 //--------------------------------------------------------------------------
264 // allRegs: returns the set of registers that can accomodate the type of
265 // given node.
266 //
267 // Arguments:
268 //    tree   -  GenTree node
269 //
270 // Return Value:
271 //    Mask representing the set of available registers for given tree
272 //
273 // Note: In case of multi-reg call node, the full set of registers must be
274 // determined by looking at types of individual return register types.
275 // In this case, the registers may include registers from different register
276 // sets and will not be limited to the actual ABI return registers.
277 regMaskTP LinearScan::allRegs(GenTree* tree)
278 {
279     regMaskTP resultMask;
280
281     // In case of multi-reg calls, allRegs is defined as
282     // Bitwise-Or(allRegs(GetReturnRegType(i)) for i=0..ReturnRegCount-1
283     if (tree->IsMultiRegCall())
284     {
285         resultMask = allMultiRegCallNodeRegs(tree->AsCall());
286     }
287     else
288     {
289         resultMask = allRegs(tree->TypeGet());
290     }
291
292     return resultMask;
293 }
294
295 regMaskTP LinearScan::allSIMDRegs()
296 {
297     return availableFloatRegs;
298 }
299
300 //------------------------------------------------------------------------
301 // internalFloatRegCandidates: Return the set of registers that are appropriate
302 //                             for use as internal float registers.
303 //
304 // Return Value:
305 //    The set of registers (as a regMaskTP).
306 //
307 // Notes:
308 //    compFloatingPointUsed is only required to be set if it is possible that we
309 //    will use floating point callee-save registers.
310 //    It is unlikely, if an internal register is the only use of floating point,
311 //    that it will select a callee-save register.  But to be safe, we restrict
312 //    the set of candidates if compFloatingPointUsed is not already set.
313
314 regMaskTP LinearScan::internalFloatRegCandidates()
315 {
316     if (compiler->compFloatingPointUsed)
317     {
318         return allRegs(TYP_FLOAT);
319     }
320     else
321     {
322         return RBM_FLT_CALLEE_TRASH;
323     }
324 }
325
326 /*****************************************************************************
327  * Register types
328  *****************************************************************************/
329 template <class T>
330 RegisterType regType(T type)
331 {
332 #ifdef FEATURE_SIMD
333     if (varTypeIsSIMD(type))
334     {
335         return FloatRegisterType;
336     }
337 #endif // FEATURE_SIMD
338     return varTypeIsFloating(TypeGet(type)) ? FloatRegisterType : IntRegisterType;
339 }
340
341 bool useFloatReg(var_types type)
342 {
343     return (regType(type) == FloatRegisterType);
344 }
345
346 bool registerTypesEquivalent(RegisterType a, RegisterType b)
347 {
348     return varTypeIsIntegralOrI(a) == varTypeIsIntegralOrI(b);
349 }
350
351 bool isSingleRegister(regMaskTP regMask)
352 {
353     return (regMask != RBM_NONE && genMaxOneBit(regMask));
354 }
355
356 /*****************************************************************************
357  * Inline functions for RegRecord
358  *****************************************************************************/
359
360 bool RegRecord::isFree()
361 {
362     return ((assignedInterval == nullptr || !assignedInterval->isActive) && !isBusyUntilNextKill);
363 }
364
365 /*****************************************************************************
366  * Inline functions for LinearScan
367  *****************************************************************************/
368 RegRecord* LinearScan::getRegisterRecord(regNumber regNum)
369 {
370     return &physRegs[regNum];
371 }
372
373 #ifdef DEBUG
374
375 //----------------------------------------------------------------------------
376 // getConstrainedRegMask: Returns new regMask which is the intersection of
377 // regMaskActual and regMaskConstraint if the new regMask has at least
378 // minRegCount registers, otherwise returns regMaskActual.
379 //
380 // Arguments:
381 //     regMaskActual      -  regMask that needs to be constrained
382 //     regMaskConstraint  -  regMask constraint that needs to be
383 //                           applied to regMaskActual
384 //     minRegCount        -  Minimum number of regs that should be
385 //                           be present in new regMask.
386 //
387 // Return Value:
388 //     New regMask that has minRegCount registers after instersection.
389 //     Otherwise returns regMaskActual.
390 regMaskTP LinearScan::getConstrainedRegMask(regMaskTP regMaskActual, regMaskTP regMaskConstraint, unsigned minRegCount)
391 {
392     regMaskTP newMask = regMaskActual & regMaskConstraint;
393     if (genCountBits(newMask) >= minRegCount)
394     {
395         return newMask;
396     }
397
398     return regMaskActual;
399 }
400
401 //------------------------------------------------------------------------
402 // stressLimitRegs: Given a set of registers, expressed as a register mask, reduce
403 //            them based on the current stress options.
404 //
405 // Arguments:
406 //    mask      - The current mask of register candidates for a node
407 //
408 // Return Value:
409 //    A possibly-modified mask, based on the value of COMPlus_JitStressRegs.
410 //
411 // Notes:
412 //    This is the method used to implement the stress options that limit
413 //    the set of registers considered for allocation.
414
415 regMaskTP LinearScan::stressLimitRegs(RefPosition* refPosition, regMaskTP mask)
416 {
417     if (getStressLimitRegs() != LSRA_LIMIT_NONE)
418     {
419         // The refPosition could be null, for example when called
420         // by getTempRegForResolution().
421         int minRegCount = (refPosition != nullptr) ? refPosition->minRegCandidateCount : 1;
422
423         switch (getStressLimitRegs())
424         {
425             case LSRA_LIMIT_CALLEE:
426                 if (!compiler->opts.compDbgEnC)
427                 {
428                     mask = getConstrainedRegMask(mask, RBM_CALLEE_SAVED, minRegCount);
429                 }
430                 break;
431
432             case LSRA_LIMIT_CALLER:
433             {
434                 mask = getConstrainedRegMask(mask, RBM_CALLEE_TRASH, minRegCount);
435             }
436             break;
437
438             case LSRA_LIMIT_SMALL_SET:
439                 if ((mask & LsraLimitSmallIntSet) != RBM_NONE)
440                 {
441                     mask = getConstrainedRegMask(mask, LsraLimitSmallIntSet, minRegCount);
442                 }
443                 else if ((mask & LsraLimitSmallFPSet) != RBM_NONE)
444                 {
445                     mask = getConstrainedRegMask(mask, LsraLimitSmallFPSet, minRegCount);
446                 }
447                 break;
448
449             default:
450                 unreached();
451         }
452
453         if (refPosition != nullptr && refPosition->isFixedRegRef)
454         {
455             mask |= refPosition->registerAssignment;
456         }
457     }
458
459     return mask;
460 }
461 #endif // DEBUG
462
463 // TODO-Cleanup: Consider adding an overload that takes a varDsc, and can appropriately
464 // set such fields as isStructField
465
466 Interval* LinearScan::newInterval(RegisterType theRegisterType)
467 {
468     intervals.emplace_back(theRegisterType, allRegs(theRegisterType));
469     Interval* newInt = &intervals.back();
470
471 #ifdef DEBUG
472     newInt->intervalIndex = static_cast<unsigned>(intervals.size() - 1);
473 #endif // DEBUG
474
475     DBEXEC(VERBOSE, newInt->dump());
476     return newInt;
477 }
478
479 RefPosition* LinearScan::newRefPositionRaw(LsraLocation nodeLocation, GenTree* treeNode, RefType refType)
480 {
481     refPositions.emplace_back(curBBNum, nodeLocation, treeNode, refType);
482     RefPosition* newRP = &refPositions.back();
483 #ifdef DEBUG
484     newRP->rpNum = static_cast<unsigned>(refPositions.size() - 1);
485 #endif // DEBUG
486     return newRP;
487 }
488
489 //------------------------------------------------------------------------
490 // resolveConflictingDefAndUse: Resolve the situation where we have conflicting def and use
491 //    register requirements on a single-def, single-use interval.
492 //
493 // Arguments:
494 //    defRefPosition - The interval definition
495 //    useRefPosition - The (sole) interval use
496 //
497 // Return Value:
498 //    None.
499 //
500 // Assumptions:
501 //    The two RefPositions are for the same interval, which is a tree-temp.
502 //
503 // Notes:
504 //    We require some special handling for the case where the use is a "delayRegFree" case of a fixedReg.
505 //    In that case, if we change the registerAssignment on the useRefPosition, we will lose the fact that,
506 //    even if we assign a different register (and rely on codegen to do the copy), that fixedReg also needs
507 //    to remain busy until the Def register has been allocated.  In that case, we don't allow Case 1 or Case 4
508 //    below.
509 //    Here are the cases we consider (in this order):
510 //    1. If The defRefPosition specifies a single register, and there are no conflicting
511 //       FixedReg uses of it between the def and use, we use that register, and the code generator
512 //       will insert the copy.  Note that it cannot be in use because there is a FixedRegRef for the def.
513 //    2. If the useRefPosition specifies a single register, and it is not in use, and there are no
514 //       conflicting FixedReg uses of it between the def and use, we use that register, and the code generator
515 //       will insert the copy.
516 //    3. If the defRefPosition specifies a single register (but there are conflicts, as determined
517 //       in 1.), and there are no conflicts with the useRefPosition register (if it's a single register),
518 ///      we set the register requirements on the defRefPosition to the use registers, and the
519 //       code generator will insert a copy on the def.  We can't rely on the code generator to put a copy
520 //       on the use if it has multiple possible candidates, as it won't know which one has been allocated.
521 //    4. If the useRefPosition specifies a single register, and there are no conflicts with the register
522 //       on the defRefPosition, we leave the register requirements on the defRefPosition as-is, and set
523 //       the useRefPosition to the def registers, for similar reasons to case #3.
524 //    5. If both the defRefPosition and the useRefPosition specify single registers, but both have conflicts,
525 //       We set the candiates on defRefPosition to be all regs of the appropriate type, and since they are
526 //       single registers, codegen can insert the copy.
527 //    6. Finally, if the RefPositions specify disjoint subsets of the registers (or the use is fixed but
528 //       has a conflict), we must insert a copy.  The copy will be inserted before the use if the
529 //       use is not fixed (in the fixed case, the code generator will insert the use).
530 //
531 // TODO-CQ: We get bad register allocation in case #3 in the situation where no register is
532 // available for the lifetime.  We end up allocating a register that must be spilled, and it probably
533 // won't be the register that is actually defined by the target instruction.  So, we have to copy it
534 // and THEN spill it.  In this case, we should be using the def requirement.  But we need to change
535 // the interface to this method a bit to make that work (e.g. returning a candidate set to use, but
536 // leaving the registerAssignment as-is on the def, so that if we find that we need to spill anyway
537 // we can use the fixed-reg on the def.
538 //
539
540 void LinearScan::resolveConflictingDefAndUse(Interval* interval, RefPosition* defRefPosition)
541 {
542     assert(!interval->isLocalVar);
543
544     RefPosition* useRefPosition   = defRefPosition->nextRefPosition;
545     regMaskTP    defRegAssignment = defRefPosition->registerAssignment;
546     regMaskTP    useRegAssignment = useRefPosition->registerAssignment;
547     RegRecord*   defRegRecord     = nullptr;
548     RegRecord*   useRegRecord     = nullptr;
549     regNumber    defReg           = REG_NA;
550     regNumber    useReg           = REG_NA;
551     bool         defRegConflict   = false;
552     bool         useRegConflict   = false;
553
554     // If the useRefPosition is a "delayRegFree", we can't change the registerAssignment
555     // on it, or we will fail to ensure that the fixedReg is busy at the time the target
556     // (of the node that uses this interval) is allocated.
557     bool canChangeUseAssignment = !useRefPosition->isFixedRegRef || !useRefPosition->delayRegFree;
558
559     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CONFLICT));
560     if (!canChangeUseAssignment)
561     {
562         INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_FIXED_DELAY_USE));
563     }
564     if (defRefPosition->isFixedRegRef)
565     {
566         defReg       = defRefPosition->assignedReg();
567         defRegRecord = getRegisterRecord(defReg);
568         if (canChangeUseAssignment)
569         {
570             RefPosition* currFixedRegRefPosition = defRegRecord->recentRefPosition;
571             assert(currFixedRegRefPosition != nullptr &&
572                    currFixedRegRefPosition->nodeLocation == defRefPosition->nodeLocation);
573
574             if (currFixedRegRefPosition->nextRefPosition == nullptr ||
575                 currFixedRegRefPosition->nextRefPosition->nodeLocation > useRefPosition->getRefEndLocation())
576             {
577                 // This is case #1.  Use the defRegAssignment
578                 INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CASE1));
579                 useRefPosition->registerAssignment = defRegAssignment;
580                 return;
581             }
582             else
583             {
584                 defRegConflict = true;
585             }
586         }
587     }
588     if (useRefPosition->isFixedRegRef)
589     {
590         useReg                               = useRefPosition->assignedReg();
591         useRegRecord                         = getRegisterRecord(useReg);
592         RefPosition* currFixedRegRefPosition = useRegRecord->recentRefPosition;
593
594         // We know that useRefPosition is a fixed use, so the nextRefPosition must not be null.
595         RefPosition* nextFixedRegRefPosition = useRegRecord->getNextRefPosition();
596         assert(nextFixedRegRefPosition != nullptr &&
597                nextFixedRegRefPosition->nodeLocation <= useRefPosition->nodeLocation);
598
599         // First, check to see if there are any conflicting FixedReg references between the def and use.
600         if (nextFixedRegRefPosition->nodeLocation == useRefPosition->nodeLocation)
601         {
602             // OK, no conflicting FixedReg references.
603             // Now, check to see whether it is currently in use.
604             if (useRegRecord->assignedInterval != nullptr)
605             {
606                 RefPosition* possiblyConflictingRef         = useRegRecord->assignedInterval->recentRefPosition;
607                 LsraLocation possiblyConflictingRefLocation = possiblyConflictingRef->getRefEndLocation();
608                 if (possiblyConflictingRefLocation >= defRefPosition->nodeLocation)
609                 {
610                     useRegConflict = true;
611                 }
612             }
613             if (!useRegConflict)
614             {
615                 // This is case #2.  Use the useRegAssignment
616                 INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CASE2));
617                 defRefPosition->registerAssignment = useRegAssignment;
618                 return;
619             }
620         }
621         else
622         {
623             useRegConflict = true;
624         }
625     }
626     if (defRegRecord != nullptr && !useRegConflict)
627     {
628         // This is case #3.
629         INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CASE3));
630         defRefPosition->registerAssignment = useRegAssignment;
631         return;
632     }
633     if (useRegRecord != nullptr && !defRegConflict && canChangeUseAssignment)
634     {
635         // This is case #4.
636         INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CASE4));
637         useRefPosition->registerAssignment = defRegAssignment;
638         return;
639     }
640     if (defRegRecord != nullptr && useRegRecord != nullptr)
641     {
642         // This is case #5.
643         INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CASE5));
644         RegisterType regType = interval->registerType;
645         assert((getRegisterType(interval, defRefPosition) == regType) &&
646                (getRegisterType(interval, useRefPosition) == regType));
647         regMaskTP candidates               = allRegs(regType);
648         defRefPosition->registerAssignment = candidates;
649         return;
650     }
651     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CASE6));
652     return;
653 }
654
655 //------------------------------------------------------------------------
656 // conflictingFixedRegReference: Determine whether the current RegRecord has a
657 //                               fixed register use that conflicts with 'refPosition'
658 //
659 // Arguments:
660 //    refPosition - The RefPosition of interest
661 //
662 // Return Value:
663 //    Returns true iff the given RefPosition is NOT a fixed use of this register,
664 //    AND either:
665 //    - there is a RefPosition on this RegRecord at the nodeLocation of the given RefPosition, or
666 //    - the given RefPosition has a delayRegFree, and there is a RefPosition on this RegRecord at
667 //      the nodeLocation just past the given RefPosition.
668 //
669 // Assumptions:
670 //    'refPosition is non-null.
671
672 bool RegRecord::conflictingFixedRegReference(RefPosition* refPosition)
673 {
674     // Is this a fixed reference of this register?  If so, there is no conflict.
675     if (refPosition->isFixedRefOfRegMask(genRegMask(regNum)))
676     {
677         return false;
678     }
679     // Otherwise, check for conflicts.
680     // There is a conflict if:
681     // 1. There is a recent RefPosition on this RegRecord that is at this location,
682     //    except in the case where it is a special "putarg" that is associated with this interval, OR
683     // 2. There is an upcoming RefPosition at this location, or at the next location
684     //    if refPosition is a delayed use (i.e. must be kept live through the next/def location).
685
686     LsraLocation refLocation = refPosition->nodeLocation;
687     if (recentRefPosition != nullptr && recentRefPosition->refType != RefTypeKill &&
688         recentRefPosition->nodeLocation == refLocation &&
689         (!isBusyUntilNextKill || assignedInterval != refPosition->getInterval()))
690     {
691         return true;
692     }
693     LsraLocation nextPhysRefLocation = getNextRefLocation();
694     if (nextPhysRefLocation == refLocation || (refPosition->delayRegFree && nextPhysRefLocation == (refLocation + 1)))
695     {
696         return true;
697     }
698     return false;
699 }
700
701 void LinearScan::applyCalleeSaveHeuristics(RefPosition* rp)
702 {
703 #ifdef _TARGET_AMD64_
704     if (compiler->opts.compDbgEnC)
705     {
706         // We only use RSI and RDI for EnC code, so we don't want to favor callee-save regs.
707         return;
708     }
709 #endif // _TARGET_AMD64_
710
711     Interval* theInterval = rp->getInterval();
712
713 #ifdef DEBUG
714     regMaskTP calleeSaveMask = calleeSaveRegs(getRegisterType(theInterval, rp));
715     if (doReverseCallerCallee())
716     {
717         rp->registerAssignment =
718             getConstrainedRegMask(rp->registerAssignment, calleeSaveMask, rp->minRegCandidateCount);
719     }
720     else
721 #endif // DEBUG
722     {
723         // Set preferences so that this register set will be preferred for earlier refs
724         theInterval->updateRegisterPreferences(rp->registerAssignment);
725     }
726 }
727
728 void LinearScan::associateRefPosWithInterval(RefPosition* rp)
729 {
730     Referenceable* theReferent = rp->referent;
731
732     if (theReferent != nullptr)
733     {
734         // All RefPositions except the dummy ones at the beginning of blocks
735
736         if (rp->isIntervalRef())
737         {
738             Interval* theInterval = rp->getInterval();
739
740             applyCalleeSaveHeuristics(rp);
741
742             if (theInterval->isLocalVar)
743             {
744                 if (RefTypeIsUse(rp->refType))
745                 {
746                     RefPosition* const prevRP = theInterval->recentRefPosition;
747                     if ((prevRP != nullptr) && (prevRP->bbNum == rp->bbNum))
748                     {
749                         prevRP->lastUse = false;
750                     }
751                 }
752
753                 rp->lastUse = (rp->refType != RefTypeExpUse) && (rp->refType != RefTypeParamDef) &&
754                               (rp->refType != RefTypeZeroInit) && !extendLifetimes();
755             }
756             else if (rp->refType == RefTypeUse)
757             {
758                 // Ensure that we have consistent def/use on SDSU temps.
759                 // However, there are a couple of cases where this may over-constrain allocation:
760                 // 1. In the case of a non-commutative rmw def (in which the rmw source must be delay-free), or
761                 // 2. In the case where the defining node requires a temp distinct from the target (also a
762                 //    delay-free case).
763                 // In those cases, if we propagate a single-register restriction from the consumer to the producer
764                 // the delayed uses will not see a fixed reference in the PhysReg at that position, and may
765                 // incorrectly allocate that register.
766                 // TODO-CQ: This means that we may often require a copy at the use of this node's result.
767                 // This case could be moved to BuildRefPositionsForNode, at the point where the def RefPosition is
768                 // created, causing a RefTypeFixedRef to be added at that location. This, however, results in
769                 // more PhysReg RefPositions (a throughput impact), and a large number of diffs that require
770                 // further analysis to determine benefit.
771                 // See Issue #11274.
772                 RefPosition* prevRefPosition = theInterval->recentRefPosition;
773                 assert(prevRefPosition != nullptr && theInterval->firstRefPosition == prevRefPosition);
774                 // All defs must have a valid treeNode, but we check it below to be conservative.
775                 assert(prevRefPosition->treeNode != nullptr);
776                 regMaskTP prevAssignment = prevRefPosition->registerAssignment;
777                 regMaskTP newAssignment  = (prevAssignment & rp->registerAssignment);
778                 if (newAssignment != RBM_NONE)
779                 {
780                     if (!isSingleRegister(newAssignment) ||
781                         (!theInterval->hasNonCommutativeRMWDef && (prevRefPosition->treeNode != nullptr) &&
782                          !prevRefPosition->treeNode->gtLsraInfo.isInternalRegDelayFree))
783                     {
784                         prevRefPosition->registerAssignment = newAssignment;
785                     }
786                 }
787                 else
788                 {
789                     theInterval->hasConflictingDefUse = true;
790                 }
791
792                 rp->lastUse = true;
793             }
794         }
795
796         RefPosition* prevRP = theReferent->recentRefPosition;
797         if (prevRP != nullptr)
798         {
799             prevRP->nextRefPosition = rp;
800         }
801         else
802         {
803             theReferent->firstRefPosition = rp;
804         }
805         theReferent->recentRefPosition = rp;
806         theReferent->lastRefPosition   = rp;
807     }
808     else
809     {
810         assert((rp->refType == RefTypeBB) || (rp->refType == RefTypeKillGCRefs));
811     }
812 }
813
814 //---------------------------------------------------------------------------
815 // newRefPosition: allocate and initialize a new RefPosition.
816 //
817 // Arguments:
818 //     reg             -  reg number that identifies RegRecord to be associated
819 //                        with this RefPosition
820 //     theLocation     -  LSRA location of RefPosition
821 //     theRefType      -  RefPosition type
822 //     theTreeNode     -  GenTree node for which this RefPosition is created
823 //     mask            -  Set of valid registers for this RefPosition
824 //     multiRegIdx     -  register position if this RefPosition corresponds to a
825 //                        multi-reg call node.
826 //
827 // Return Value:
828 //     a new RefPosition
829 //
830 RefPosition* LinearScan::newRefPosition(
831     regNumber reg, LsraLocation theLocation, RefType theRefType, GenTree* theTreeNode, regMaskTP mask)
832 {
833     RefPosition* newRP = newRefPositionRaw(theLocation, theTreeNode, theRefType);
834
835     newRP->setReg(getRegisterRecord(reg));
836     newRP->registerAssignment = mask;
837
838     newRP->setMultiRegIdx(0);
839     newRP->setAllocateIfProfitable(false);
840
841     associateRefPosWithInterval(newRP);
842
843     DBEXEC(VERBOSE, newRP->dump());
844     return newRP;
845 }
846
847 //---------------------------------------------------------------------------
848 // newRefPosition: allocate and initialize a new RefPosition.
849 //
850 // Arguments:
851 //     theInterval     -  interval to which RefPosition is associated with.
852 //     theLocation     -  LSRA location of RefPosition
853 //     theRefType      -  RefPosition type
854 //     theTreeNode     -  GenTree node for which this RefPosition is created
855 //     mask            -  Set of valid registers for this RefPosition
856 //     multiRegIdx     -  register position if this RefPosition corresponds to a
857 //                        multi-reg call node.
858 //     minRegCount     -  Minimum number registers that needs to be ensured while
859 //                        constraining candidates for this ref position under
860 //                        LSRA stress. This is a DEBUG only arg.
861 //
862 // Return Value:
863 //     a new RefPosition
864 //
865 RefPosition* LinearScan::newRefPosition(Interval*    theInterval,
866                                         LsraLocation theLocation,
867                                         RefType      theRefType,
868                                         GenTree*     theTreeNode,
869                                         regMaskTP    mask,
870                                         unsigned     multiRegIdx /* = 0 */
871                                         DEBUGARG(unsigned minRegCandidateCount /* = 1 */))
872 {
873 #ifdef DEBUG
874     if (theInterval != nullptr && regType(theInterval->registerType) == FloatRegisterType)
875     {
876         // In the case we're using floating point registers we must make sure
877         // this flag was set previously in the compiler since this will mandate
878         // whether LSRA will take into consideration FP reg killsets.
879         assert(compiler->compFloatingPointUsed || ((mask & RBM_FLT_CALLEE_SAVED) == 0));
880     }
881 #endif // DEBUG
882
883     // If this reference is constrained to a single register (and it's not a dummy
884     // or Kill reftype already), add a RefTypeFixedReg at this location so that its
885     // availability can be more accurately determined
886
887     bool isFixedRegister = isSingleRegister(mask);
888     bool insertFixedRef  = false;
889     if (isFixedRegister)
890     {
891         // Insert a RefTypeFixedReg for any normal def or use (not ParamDef or BB)
892         if (theRefType == RefTypeUse || theRefType == RefTypeDef)
893         {
894             insertFixedRef = true;
895         }
896     }
897
898     if (insertFixedRef)
899     {
900         regNumber    physicalReg = genRegNumFromMask(mask);
901         RefPosition* pos         = newRefPosition(physicalReg, theLocation, RefTypeFixedReg, nullptr, mask);
902         assert(theInterval != nullptr);
903         assert((allRegs(theInterval->registerType) & mask) != 0);
904     }
905
906     RefPosition* newRP = newRefPositionRaw(theLocation, theTreeNode, theRefType);
907
908     newRP->setInterval(theInterval);
909
910     // Spill info
911     newRP->isFixedRegRef = isFixedRegister;
912
913 #ifndef _TARGET_AMD64_
914     // We don't need this for AMD because the PInvoke method epilog code is explicit
915     // at register allocation time.
916     if (theInterval != nullptr && theInterval->isLocalVar && compiler->info.compCallUnmanaged &&
917         theInterval->varNum == compiler->genReturnLocal)
918     {
919         mask &= ~(RBM_PINVOKE_TCB | RBM_PINVOKE_FRAME);
920         noway_assert(mask != RBM_NONE);
921     }
922 #endif // !_TARGET_AMD64_
923     newRP->registerAssignment = mask;
924
925     newRP->setMultiRegIdx(multiRegIdx);
926     newRP->setAllocateIfProfitable(false);
927
928 #ifdef DEBUG
929     newRP->minRegCandidateCount = minRegCandidateCount;
930 #endif // DEBUG
931
932     associateRefPosWithInterval(newRP);
933
934     DBEXEC(VERBOSE, newRP->dump());
935     return newRP;
936 }
937
938 /*****************************************************************************
939  * Inline functions for Interval
940  *****************************************************************************/
941 RefPosition* Referenceable::getNextRefPosition()
942 {
943     if (recentRefPosition == nullptr)
944     {
945         return firstRefPosition;
946     }
947     else
948     {
949         return recentRefPosition->nextRefPosition;
950     }
951 }
952
953 LsraLocation Referenceable::getNextRefLocation()
954 {
955     RefPosition* nextRefPosition = getNextRefPosition();
956     if (nextRefPosition == nullptr)
957     {
958         return MaxLocation;
959     }
960     else
961     {
962         return nextRefPosition->nodeLocation;
963     }
964 }
965
966 // Iterate through all the registers of the given type
967 class RegisterIterator
968 {
969     friend class Registers;
970
971 public:
972     RegisterIterator(RegisterType type) : regType(type)
973     {
974         if (useFloatReg(regType))
975         {
976             currentRegNum = REG_FP_FIRST;
977         }
978         else
979         {
980             currentRegNum = REG_INT_FIRST;
981         }
982     }
983
984 protected:
985     static RegisterIterator Begin(RegisterType regType)
986     {
987         return RegisterIterator(regType);
988     }
989     static RegisterIterator End(RegisterType regType)
990     {
991         RegisterIterator endIter = RegisterIterator(regType);
992         // This assumes only integer and floating point register types
993         // if we target a processor with additional register types,
994         // this would have to change
995         if (useFloatReg(regType))
996         {
997             // This just happens to work for both double & float
998             endIter.currentRegNum = REG_NEXT(REG_FP_LAST);
999         }
1000         else
1001         {
1002             endIter.currentRegNum = REG_NEXT(REG_INT_LAST);
1003         }
1004         return endIter;
1005     }
1006
1007 public:
1008     void operator++(int dummy) // int dummy is c++ for "this is postfix ++"
1009     {
1010         currentRegNum = REG_NEXT(currentRegNum);
1011 #ifdef _TARGET_ARM_
1012         if (regType == TYP_DOUBLE)
1013             currentRegNum = REG_NEXT(currentRegNum);
1014 #endif
1015     }
1016     void operator++() // prefix operator++
1017     {
1018         currentRegNum = REG_NEXT(currentRegNum);
1019 #ifdef _TARGET_ARM_
1020         if (regType == TYP_DOUBLE)
1021             currentRegNum = REG_NEXT(currentRegNum);
1022 #endif
1023     }
1024     regNumber operator*()
1025     {
1026         return currentRegNum;
1027     }
1028     bool operator!=(const RegisterIterator& other)
1029     {
1030         return other.currentRegNum != currentRegNum;
1031     }
1032
1033 private:
1034     regNumber    currentRegNum;
1035     RegisterType regType;
1036 };
1037
1038 class Registers
1039 {
1040 public:
1041     friend class RegisterIterator;
1042     RegisterType type;
1043     Registers(RegisterType t)
1044     {
1045         type = t;
1046     }
1047     RegisterIterator begin()
1048     {
1049         return RegisterIterator::Begin(type);
1050     }
1051     RegisterIterator end()
1052     {
1053         return RegisterIterator::End(type);
1054     }
1055 };
1056
1057 #ifdef DEBUG
1058 void LinearScan::dumpVarToRegMap(VarToRegMap map)
1059 {
1060     bool anyPrinted = false;
1061     for (unsigned varIndex = 0; varIndex < compiler->lvaTrackedCount; varIndex++)
1062     {
1063         unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
1064         if (map[varIndex] != REG_STK)
1065         {
1066             printf("V%02u=%s ", varNum, getRegName(map[varIndex]));
1067             anyPrinted = true;
1068         }
1069     }
1070     if (!anyPrinted)
1071     {
1072         printf("none");
1073     }
1074     printf("\n");
1075 }
1076
1077 void LinearScan::dumpInVarToRegMap(BasicBlock* block)
1078 {
1079     printf("Var=Reg beg of BB%02u: ", block->bbNum);
1080     VarToRegMap map = getInVarToRegMap(block->bbNum);
1081     dumpVarToRegMap(map);
1082 }
1083
1084 void LinearScan::dumpOutVarToRegMap(BasicBlock* block)
1085 {
1086     printf("Var=Reg end of BB%02u: ", block->bbNum);
1087     VarToRegMap map = getOutVarToRegMap(block->bbNum);
1088     dumpVarToRegMap(map);
1089 }
1090
1091 #endif // DEBUG
1092
1093 LinearScanInterface* getLinearScanAllocator(Compiler* comp)
1094 {
1095     return new (comp, CMK_LSRA) LinearScan(comp);
1096 }
1097
1098 //------------------------------------------------------------------------
1099 // LSRA constructor
1100 //
1101 // Arguments:
1102 //    theCompiler
1103 //
1104 // Notes:
1105 //    The constructor takes care of initializing the data structures that are used
1106 //    during Lowering, including (in DEBUG) getting the stress environment variables,
1107 //    as they may affect the block ordering.
1108
1109 LinearScan::LinearScan(Compiler* theCompiler)
1110     : compiler(theCompiler)
1111 #if MEASURE_MEM_ALLOC
1112     , lsraIAllocator(nullptr)
1113 #endif // MEASURE_MEM_ALLOC
1114     , intervals(LinearScanMemoryAllocatorInterval(theCompiler))
1115     , refPositions(LinearScanMemoryAllocatorRefPosition(theCompiler))
1116 {
1117 #ifdef DEBUG
1118     maxNodeLocation   = 0;
1119     activeRefPosition = nullptr;
1120
1121     // Get the value of the environment variable that controls stress for register allocation
1122     lsraStressMask = JitConfig.JitStressRegs();
1123 #if 0
1124 #ifdef DEBUG
1125     if (lsraStressMask != 0)
1126     {
1127         // The code in this #if can be used to debug JitStressRegs issues according to
1128         // method hash.  To use, simply set environment variables JitStressRegsHashLo and JitStressRegsHashHi
1129         unsigned methHash = compiler->info.compMethodHash();
1130         char* lostr = getenv("JitStressRegsHashLo");
1131         unsigned methHashLo = 0;
1132         bool dump = false;
1133         if (lostr != nullptr)
1134         {
1135             sscanf_s(lostr, "%x", &methHashLo);
1136             dump = true;
1137         }
1138         char* histr = getenv("JitStressRegsHashHi");
1139         unsigned methHashHi = UINT32_MAX;
1140         if (histr != nullptr)
1141         {
1142             sscanf_s(histr, "%x", &methHashHi);
1143             dump = true;
1144         }
1145         if (methHash < methHashLo || methHash > methHashHi)
1146         {
1147             lsraStressMask = 0;
1148         }
1149         else if (dump == true)
1150         {
1151             printf("JitStressRegs = %x for method %s, hash = 0x%x.\n",
1152                    lsraStressMask, compiler->info.compFullName, compiler->info.compMethodHash());
1153             printf("");         // in our logic this causes a flush
1154         }
1155     }
1156 #endif // DEBUG
1157 #endif
1158
1159     dumpTerse = (JitConfig.JitDumpTerseLsra() != 0);
1160 #endif // DEBUG
1161
1162     enregisterLocalVars = ((compiler->opts.compFlags & CLFLG_REGVAR) != 0) && compiler->lvaTrackedCount > 0;
1163     availableIntRegs    = (RBM_ALLINT & ~compiler->codeGen->regSet.rsMaskResvd);
1164
1165 #if ETW_EBP_FRAMED
1166     availableIntRegs &= ~RBM_FPBASE;
1167 #endif // ETW_EBP_FRAMED
1168
1169     availableFloatRegs  = RBM_ALLFLOAT;
1170     availableDoubleRegs = RBM_ALLDOUBLE;
1171
1172 #ifdef _TARGET_AMD64_
1173     if (compiler->opts.compDbgEnC)
1174     {
1175         // On x64 when the EnC option is set, we always save exactly RBP, RSI and RDI.
1176         // RBP is not available to the register allocator, so RSI and RDI are the only
1177         // callee-save registers available.
1178         availableIntRegs &= ~RBM_CALLEE_SAVED | RBM_RSI | RBM_RDI;
1179         availableFloatRegs &= ~RBM_CALLEE_SAVED;
1180         availableDoubleRegs &= ~RBM_CALLEE_SAVED;
1181     }
1182 #endif // _TARGET_AMD64_
1183     compiler->rpFrameType           = FT_NOT_SET;
1184     compiler->rpMustCreateEBPCalled = false;
1185
1186     compiler->codeGen->intRegState.rsIsFloat   = false;
1187     compiler->codeGen->floatRegState.rsIsFloat = true;
1188
1189     // Block sequencing (the order in which we schedule).
1190     // Note that we don't initialize the bbVisitedSet until we do the first traversal
1191     // (currently during Lowering's second phase, where it sets the TreeNodeInfo).
1192     // This is so that any blocks that are added during the first phase of Lowering
1193     // are accounted for (and we don't have BasicBlockEpoch issues).
1194     blockSequencingDone   = false;
1195     blockSequence         = nullptr;
1196     blockSequenceWorkList = nullptr;
1197     curBBSeqNum           = 0;
1198     bbSeqCount            = 0;
1199
1200     // Information about each block, including predecessor blocks used for variable locations at block entry.
1201     blockInfo = nullptr;
1202
1203     // Populate the register mask table.
1204     // The first two masks in the table are allint/allfloat
1205     // The next N are the masks for each single register.
1206     // After that are the dynamically added ones.
1207     regMaskTable               = new (compiler, CMK_LSRA) regMaskTP[numMasks];
1208     regMaskTable[ALLINT_IDX]   = allRegs(TYP_INT);
1209     regMaskTable[ALLFLOAT_IDX] = allRegs(TYP_DOUBLE);
1210
1211     regNumber reg;
1212     for (reg = REG_FIRST; reg < REG_COUNT; reg = REG_NEXT(reg))
1213     {
1214         regMaskTable[FIRST_SINGLE_REG_IDX + reg - REG_FIRST] = (reg == REG_STK) ? RBM_NONE : genRegMask(reg);
1215     }
1216     nextFreeMask = FIRST_SINGLE_REG_IDX + REG_COUNT;
1217     noway_assert(nextFreeMask <= numMasks);
1218 }
1219
1220 // Return the reg mask corresponding to the given index.
1221 regMaskTP LinearScan::GetRegMaskForIndex(RegMaskIndex index)
1222 {
1223     assert(index < numMasks);
1224     assert(index < nextFreeMask);
1225     return regMaskTable[index];
1226 }
1227
1228 // Given a reg mask, return the index it corresponds to. If it is not a 'well known' reg mask,
1229 // add it at the end. This method has linear behavior in the worst cases but that is fairly rare.
1230 // Most methods never use any but the well-known masks, and when they do use more
1231 // it is only one or two more.
1232 LinearScan::RegMaskIndex LinearScan::GetIndexForRegMask(regMaskTP mask)
1233 {
1234     RegMaskIndex result;
1235     if (isSingleRegister(mask))
1236     {
1237         result = genRegNumFromMask(mask) + FIRST_SINGLE_REG_IDX;
1238     }
1239     else if (mask == allRegs(TYP_INT))
1240     {
1241         result = ALLINT_IDX;
1242     }
1243     else if (mask == allRegs(TYP_DOUBLE))
1244     {
1245         result = ALLFLOAT_IDX;
1246     }
1247     else
1248     {
1249         for (int i = FIRST_SINGLE_REG_IDX + REG_COUNT; i < nextFreeMask; i++)
1250         {
1251             if (regMaskTable[i] == mask)
1252             {
1253                 return i;
1254             }
1255         }
1256
1257         // We only allocate a fixed number of masks. Since we don't reallocate, we will throw a
1258         // noway_assert if we exceed this limit.
1259         noway_assert(nextFreeMask < numMasks);
1260
1261         regMaskTable[nextFreeMask] = mask;
1262         result                     = nextFreeMask;
1263         nextFreeMask++;
1264     }
1265     assert(mask == regMaskTable[result]);
1266     return result;
1267 }
1268
1269 // We've decided that we can't use a register during register allocation (probably FPBASE),
1270 // but we've already added it to the register masks. Go through the masks and remove it.
1271 void LinearScan::RemoveRegisterFromMasks(regNumber reg)
1272 {
1273     JITDUMP("Removing register %s from LSRA register masks\n", getRegName(reg));
1274
1275     regMaskTP mask = ~genRegMask(reg);
1276     for (int i = 0; i < nextFreeMask; i++)
1277     {
1278         regMaskTable[i] &= mask;
1279     }
1280
1281     JITDUMP("After removing register:\n");
1282     DBEXEC(VERBOSE, dspRegisterMaskTable());
1283 }
1284
1285 #ifdef DEBUG
1286 void LinearScan::dspRegisterMaskTable()
1287 {
1288     printf("LSRA register masks. Total allocated: %d, total used: %d\n", numMasks, nextFreeMask);
1289     for (int i = 0; i < nextFreeMask; i++)
1290     {
1291         printf("%2u: ", i);
1292         dspRegMask(regMaskTable[i]);
1293         printf("\n");
1294     }
1295 }
1296 #endif // DEBUG
1297
1298 //------------------------------------------------------------------------
1299 // getNextCandidateFromWorkList: Get the next candidate for block sequencing
1300 //
1301 // Arguments:
1302 //    None.
1303 //
1304 // Return Value:
1305 //    The next block to be placed in the sequence.
1306 //
1307 // Notes:
1308 //    This method currently always returns the next block in the list, and relies on having
1309 //    blocks added to the list only when they are "ready", and on the
1310 //    addToBlockSequenceWorkList() method to insert them in the proper order.
1311 //    However, a block may be in the list and already selected, if it was subsequently
1312 //    encountered as both a flow and layout successor of the most recently selected
1313 //    block.
1314
1315 BasicBlock* LinearScan::getNextCandidateFromWorkList()
1316 {
1317     BasicBlockList* nextWorkList = nullptr;
1318     for (BasicBlockList* workList = blockSequenceWorkList; workList != nullptr; workList = nextWorkList)
1319     {
1320         nextWorkList          = workList->next;
1321         BasicBlock* candBlock = workList->block;
1322         removeFromBlockSequenceWorkList(workList, nullptr);
1323         if (!isBlockVisited(candBlock))
1324         {
1325             return candBlock;
1326         }
1327     }
1328     return nullptr;
1329 }
1330
1331 //------------------------------------------------------------------------
1332 // setBlockSequence:Determine the block order for register allocation.
1333 //
1334 // Arguments:
1335 //    None
1336 //
1337 // Return Value:
1338 //    None
1339 //
1340 // Notes:
1341 //    On return, the blockSequence array contains the blocks, in the order in which they
1342 //    will be allocated.
1343 //    This method clears the bbVisitedSet on LinearScan, and when it returns the set
1344 //    contains all the bbNums for the block.
1345 //    This requires a traversal of the BasicBlocks, and could potentially be
1346 //    combined with the first traversal (currently the one in Lowering that sets the
1347 //    TreeNodeInfo).
1348
1349 void LinearScan::setBlockSequence()
1350 {
1351     // Reset the "visited" flag on each block.
1352     compiler->EnsureBasicBlockEpoch();
1353     bbVisitedSet = BlockSetOps::MakeEmpty(compiler);
1354     BlockSet readySet(BlockSetOps::MakeEmpty(compiler));
1355     BlockSet predSet(BlockSetOps::MakeEmpty(compiler));
1356
1357     assert(blockSequence == nullptr && bbSeqCount == 0);
1358     blockSequence            = new (compiler, CMK_LSRA) BasicBlock*[compiler->fgBBcount];
1359     bbNumMaxBeforeResolution = compiler->fgBBNumMax;
1360     blockInfo                = new (compiler, CMK_LSRA) LsraBlockInfo[bbNumMaxBeforeResolution + 1];
1361
1362     assert(blockSequenceWorkList == nullptr);
1363
1364     bool addedInternalBlocks = false;
1365     verifiedAllBBs           = false;
1366     hasCriticalEdges         = false;
1367     BasicBlock* nextBlock;
1368     for (BasicBlock* block = compiler->fgFirstBB; block != nullptr; block = nextBlock)
1369     {
1370         blockSequence[bbSeqCount] = block;
1371         markBlockVisited(block);
1372         bbSeqCount++;
1373         nextBlock = nullptr;
1374
1375         // Initialize the blockInfo.
1376         // predBBNum will be set later.  0 is never used as a bbNum.
1377         blockInfo[block->bbNum].predBBNum = 0;
1378         // We check for critical edges below, but initialize to false.
1379         blockInfo[block->bbNum].hasCriticalInEdge  = false;
1380         blockInfo[block->bbNum].hasCriticalOutEdge = false;
1381         blockInfo[block->bbNum].weight             = block->bbWeight;
1382
1383 #if TRACK_LSRA_STATS
1384         blockInfo[block->bbNum].spillCount         = 0;
1385         blockInfo[block->bbNum].copyRegCount       = 0;
1386         blockInfo[block->bbNum].resolutionMovCount = 0;
1387         blockInfo[block->bbNum].splitEdgeCount     = 0;
1388 #endif // TRACK_LSRA_STATS
1389
1390         if (block->GetUniquePred(compiler) == nullptr)
1391         {
1392             for (flowList* pred = block->bbPreds; pred != nullptr; pred = pred->flNext)
1393             {
1394                 BasicBlock* predBlock = pred->flBlock;
1395                 if (predBlock->NumSucc(compiler) > 1)
1396                 {
1397                     blockInfo[block->bbNum].hasCriticalInEdge = true;
1398                     hasCriticalEdges                          = true;
1399                     break;
1400                 }
1401                 else if (predBlock->bbJumpKind == BBJ_SWITCH)
1402                 {
1403                     assert(!"Switch with single successor");
1404                 }
1405             }
1406         }
1407
1408         // Determine which block to schedule next.
1409
1410         // First, update the NORMAL successors of the current block, adding them to the worklist
1411         // according to the desired order.  We will handle the EH successors below.
1412         bool checkForCriticalOutEdge = (block->NumSucc(compiler) > 1);
1413         if (!checkForCriticalOutEdge && block->bbJumpKind == BBJ_SWITCH)
1414         {
1415             assert(!"Switch with single successor");
1416         }
1417
1418         const unsigned numSuccs = block->NumSucc(compiler);
1419         for (unsigned succIndex = 0; succIndex < numSuccs; succIndex++)
1420         {
1421             BasicBlock* succ = block->GetSucc(succIndex, compiler);
1422             if (checkForCriticalOutEdge && succ->GetUniquePred(compiler) == nullptr)
1423             {
1424                 blockInfo[block->bbNum].hasCriticalOutEdge = true;
1425                 hasCriticalEdges                           = true;
1426                 // We can stop checking now.
1427                 checkForCriticalOutEdge = false;
1428             }
1429
1430             if (isTraversalLayoutOrder() || isBlockVisited(succ))
1431             {
1432                 continue;
1433             }
1434
1435             // We've now seen a predecessor, so add it to the work list and the "readySet".
1436             // It will be inserted in the worklist according to the specified traversal order
1437             // (i.e. pred-first or random, since layout order is handled above).
1438             if (!BlockSetOps::IsMember(compiler, readySet, succ->bbNum))
1439             {
1440                 addToBlockSequenceWorkList(readySet, succ, predSet);
1441                 BlockSetOps::AddElemD(compiler, readySet, succ->bbNum);
1442             }
1443         }
1444
1445         // For layout order, simply use bbNext
1446         if (isTraversalLayoutOrder())
1447         {
1448             nextBlock = block->bbNext;
1449             continue;
1450         }
1451
1452         while (nextBlock == nullptr)
1453         {
1454             nextBlock = getNextCandidateFromWorkList();
1455
1456             // TODO-Throughput: We would like to bypass this traversal if we know we've handled all
1457             // the blocks - but fgBBcount does not appear to be updated when blocks are removed.
1458             if (nextBlock == nullptr /* && bbSeqCount != compiler->fgBBcount*/ && !verifiedAllBBs)
1459             {
1460                 // If we don't encounter all blocks by traversing the regular sucessor links, do a full
1461                 // traversal of all the blocks, and add them in layout order.
1462                 // This may include:
1463                 //   - internal-only blocks (in the fgAddCodeList) which may not be in the flow graph
1464                 //     (these are not even in the bbNext links).
1465                 //   - blocks that have become unreachable due to optimizations, but that are strongly
1466                 //     connected (these are not removed)
1467                 //   - EH blocks
1468
1469                 for (Compiler::AddCodeDsc* desc = compiler->fgAddCodeList; desc != nullptr; desc = desc->acdNext)
1470                 {
1471                     if (!isBlockVisited(block))
1472                     {
1473                         addToBlockSequenceWorkList(readySet, block, predSet);
1474                         BlockSetOps::AddElemD(compiler, readySet, block->bbNum);
1475                     }
1476                 }
1477
1478                 for (BasicBlock* block = compiler->fgFirstBB; block; block = block->bbNext)
1479                 {
1480                     if (!isBlockVisited(block))
1481                     {
1482                         addToBlockSequenceWorkList(readySet, block, predSet);
1483                         BlockSetOps::AddElemD(compiler, readySet, block->bbNum);
1484                     }
1485                 }
1486                 verifiedAllBBs = true;
1487             }
1488             else
1489             {
1490                 break;
1491             }
1492         }
1493     }
1494     blockSequencingDone = true;
1495
1496 #ifdef DEBUG
1497     // Make sure that we've visited all the blocks.
1498     for (BasicBlock* block = compiler->fgFirstBB; block != nullptr; block = block->bbNext)
1499     {
1500         assert(isBlockVisited(block));
1501     }
1502
1503     JITDUMP("LSRA Block Sequence: ");
1504     int i = 1;
1505     for (BasicBlock *block = startBlockSequence(); block != nullptr; ++i, block = moveToNextBlock())
1506     {
1507         JITDUMP("BB%02u", block->bbNum);
1508
1509         if (block->isMaxBBWeight())
1510         {
1511             JITDUMP("(MAX) ");
1512         }
1513         else
1514         {
1515             JITDUMP("(%6s) ", refCntWtd2str(block->getBBWeight(compiler)));
1516         }
1517
1518         if (i % 10 == 0)
1519         {
1520             JITDUMP("\n                     ");
1521         }
1522     }
1523     JITDUMP("\n\n");
1524 #endif
1525 }
1526
1527 //------------------------------------------------------------------------
1528 // compareBlocksForSequencing: Compare two basic blocks for sequencing order.
1529 //
1530 // Arguments:
1531 //    block1            - the first block for comparison
1532 //    block2            - the second block for comparison
1533 //    useBlockWeights   - whether to use block weights for comparison
1534 //
1535 // Return Value:
1536 //    -1 if block1 is preferred.
1537 //     0 if the blocks are equivalent.
1538 //     1 if block2 is preferred.
1539 //
1540 // Notes:
1541 //    See addToBlockSequenceWorkList.
1542 int LinearScan::compareBlocksForSequencing(BasicBlock* block1, BasicBlock* block2, bool useBlockWeights)
1543 {
1544     if (useBlockWeights)
1545     {
1546         unsigned weight1 = block1->getBBWeight(compiler);
1547         unsigned weight2 = block2->getBBWeight(compiler);
1548
1549         if (weight1 > weight2)
1550         {
1551             return -1;
1552         }
1553         else if (weight1 < weight2)
1554         {
1555             return 1;
1556         }
1557     }
1558
1559     // If weights are the same prefer LOWER bbnum
1560     if (block1->bbNum < block2->bbNum)
1561     {
1562         return -1;
1563     }
1564     else if (block1->bbNum == block2->bbNum)
1565     {
1566         return 0;
1567     }
1568     else
1569     {
1570         return 1;
1571     }
1572 }
1573
1574 //------------------------------------------------------------------------
1575 // addToBlockSequenceWorkList: Add a BasicBlock to the work list for sequencing.
1576 //
1577 // Arguments:
1578 //    sequencedBlockSet - the set of blocks that are already sequenced
1579 //    block             - the new block to be added
1580 //    predSet           - the buffer to save predecessors set. A block set allocated by the caller used here as a
1581 //    temporary block set for constructing a predecessor set. Allocated by the caller to avoid reallocating a new block
1582 //    set with every call to this function
1583 //
1584 // Return Value:
1585 //    None.
1586 //
1587 // Notes:
1588 //    The first block in the list will be the next one to be sequenced, as soon
1589 //    as we encounter a block whose successors have all been sequenced, in pred-first
1590 //    order, or the very next block if we are traversing in random order (once implemented).
1591 //    This method uses a comparison method to determine the order in which to place
1592 //    the blocks in the list.  This method queries whether all predecessors of the
1593 //    block are sequenced at the time it is added to the list and if so uses block weights
1594 //    for inserting the block.  A block is never inserted ahead of its predecessors.
1595 //    A block at the time of insertion may not have all its predecessors sequenced, in
1596 //    which case it will be sequenced based on its block number. Once a block is inserted,
1597 //    its priority\order will not be changed later once its remaining predecessors are
1598 //    sequenced.  This would mean that work list may not be sorted entirely based on
1599 //    block weights alone.
1600 //
1601 //    Note also that, when random traversal order is implemented, this method
1602 //    should insert the blocks into the list in random order, so that we can always
1603 //    simply select the first block in the list.
1604 void LinearScan::addToBlockSequenceWorkList(BlockSet sequencedBlockSet, BasicBlock* block, BlockSet& predSet)
1605 {
1606     // The block that is being added is not already sequenced
1607     assert(!BlockSetOps::IsMember(compiler, sequencedBlockSet, block->bbNum));
1608
1609     // Get predSet of block
1610     BlockSetOps::ClearD(compiler, predSet);
1611     flowList* pred;
1612     for (pred = block->bbPreds; pred != nullptr; pred = pred->flNext)
1613     {
1614         BlockSetOps::AddElemD(compiler, predSet, pred->flBlock->bbNum);
1615     }
1616
1617     // If either a rarely run block or all its preds are already sequenced, use block's weight to sequence
1618     bool useBlockWeight = block->isRunRarely() || BlockSetOps::IsSubset(compiler, sequencedBlockSet, predSet);
1619
1620     BasicBlockList* prevNode = nullptr;
1621     BasicBlockList* nextNode = blockSequenceWorkList;
1622
1623     while (nextNode != nullptr)
1624     {
1625         int seqResult;
1626
1627         if (nextNode->block->isRunRarely())
1628         {
1629             // If the block that is yet to be sequenced is a rarely run block, always use block weights for sequencing
1630             seqResult = compareBlocksForSequencing(nextNode->block, block, true);
1631         }
1632         else if (BlockSetOps::IsMember(compiler, predSet, nextNode->block->bbNum))
1633         {
1634             // always prefer unsequenced pred blocks
1635             seqResult = -1;
1636         }
1637         else
1638         {
1639             seqResult = compareBlocksForSequencing(nextNode->block, block, useBlockWeight);
1640         }
1641
1642         if (seqResult > 0)
1643         {
1644             break;
1645         }
1646
1647         prevNode = nextNode;
1648         nextNode = nextNode->next;
1649     }
1650
1651     BasicBlockList* newListNode = new (compiler, CMK_LSRA) BasicBlockList(block, nextNode);
1652     if (prevNode == nullptr)
1653     {
1654         blockSequenceWorkList = newListNode;
1655     }
1656     else
1657     {
1658         prevNode->next = newListNode;
1659     }
1660 }
1661
1662 void LinearScan::removeFromBlockSequenceWorkList(BasicBlockList* listNode, BasicBlockList* prevNode)
1663 {
1664     if (listNode == blockSequenceWorkList)
1665     {
1666         assert(prevNode == nullptr);
1667         blockSequenceWorkList = listNode->next;
1668     }
1669     else
1670     {
1671         assert(prevNode != nullptr && prevNode->next == listNode);
1672         prevNode->next = listNode->next;
1673     }
1674     // TODO-Cleanup: consider merging Compiler::BlockListNode and BasicBlockList
1675     // compiler->FreeBlockListNode(listNode);
1676 }
1677
1678 // Initialize the block order for allocation (called each time a new traversal begins).
1679 BasicBlock* LinearScan::startBlockSequence()
1680 {
1681     if (!blockSequencingDone)
1682     {
1683         setBlockSequence();
1684     }
1685     BasicBlock* curBB = compiler->fgFirstBB;
1686     curBBSeqNum       = 0;
1687     curBBNum          = curBB->bbNum;
1688     clearVisitedBlocks();
1689     assert(blockSequence[0] == compiler->fgFirstBB);
1690     markBlockVisited(curBB);
1691     return curBB;
1692 }
1693
1694 //------------------------------------------------------------------------
1695 // moveToNextBlock: Move to the next block in order for allocation or resolution.
1696 //
1697 // Arguments:
1698 //    None
1699 //
1700 // Return Value:
1701 //    The next block.
1702 //
1703 // Notes:
1704 //    This method is used when the next block is actually going to be handled.
1705 //    It changes curBBNum.
1706
1707 BasicBlock* LinearScan::moveToNextBlock()
1708 {
1709     BasicBlock* nextBlock = getNextBlock();
1710     curBBSeqNum++;
1711     if (nextBlock != nullptr)
1712     {
1713         curBBNum = nextBlock->bbNum;
1714     }
1715     return nextBlock;
1716 }
1717
1718 //------------------------------------------------------------------------
1719 // getNextBlock: Get the next block in order for allocation or resolution.
1720 //
1721 // Arguments:
1722 //    None
1723 //
1724 // Return Value:
1725 //    The next block.
1726 //
1727 // Notes:
1728 //    This method does not actually change the current block - it is used simply
1729 //    to determine which block will be next.
1730
1731 BasicBlock* LinearScan::getNextBlock()
1732 {
1733     assert(blockSequencingDone);
1734     unsigned int nextBBSeqNum = curBBSeqNum + 1;
1735     if (nextBBSeqNum < bbSeqCount)
1736     {
1737         return blockSequence[nextBBSeqNum];
1738     }
1739     return nullptr;
1740 }
1741
1742 //------------------------------------------------------------------------
1743 // doLinearScan: The main method for register allocation.
1744 //
1745 // Arguments:
1746 //    None
1747 //
1748 // Return Value:
1749 //    None.
1750 //
1751 // Assumptions:
1752 //    Lowering must have set the NodeInfo (gtLsraInfo) on each node to communicate
1753 //    the register requirements.
1754
1755 void LinearScan::doLinearScan()
1756 {
1757     unsigned lsraBlockEpoch = compiler->GetCurBasicBlockEpoch();
1758
1759     splitBBNumToTargetBBNumMap = nullptr;
1760
1761     // This is complicated by the fact that physical registers have refs associated
1762     // with locations where they are killed (e.g. calls), but we don't want to
1763     // count these as being touched.
1764
1765     compiler->codeGen->regSet.rsClearRegsModified();
1766
1767     initMaxSpill();
1768     buildIntervals();
1769     DBEXEC(VERBOSE, TupleStyleDump(LSRA_DUMP_REFPOS));
1770     compiler->EndPhase(PHASE_LINEAR_SCAN_BUILD);
1771
1772     DBEXEC(VERBOSE, lsraDumpIntervals("after buildIntervals"));
1773
1774     clearVisitedBlocks();
1775     initVarRegMaps();
1776     allocateRegisters();
1777     compiler->EndPhase(PHASE_LINEAR_SCAN_ALLOC);
1778     resolveRegisters();
1779     compiler->EndPhase(PHASE_LINEAR_SCAN_RESOLVE);
1780
1781 #if TRACK_LSRA_STATS
1782     if ((JitConfig.DisplayLsraStats() != 0)
1783 #ifdef DEBUG
1784         || VERBOSE
1785 #endif
1786         )
1787     {
1788         dumpLsraStats(jitstdout);
1789     }
1790 #endif // TRACK_LSRA_STATS
1791
1792     DBEXEC(VERBOSE, TupleStyleDump(LSRA_DUMP_POST));
1793
1794     compiler->compLSRADone = true;
1795     noway_assert(lsraBlockEpoch = compiler->GetCurBasicBlockEpoch());
1796 }
1797
1798 //------------------------------------------------------------------------
1799 // recordVarLocationsAtStartOfBB: Update live-in LclVarDscs with the appropriate
1800 //    register location at the start of a block, during codegen.
1801 //
1802 // Arguments:
1803 //    bb - the block for which code is about to be generated.
1804 //
1805 // Return Value:
1806 //    None.
1807 //
1808 // Assumptions:
1809 //    CodeGen will take care of updating the reg masks and the current var liveness,
1810 //    after calling this method.
1811 //    This is because we need to kill off the dead registers before setting the newly live ones.
1812
1813 void LinearScan::recordVarLocationsAtStartOfBB(BasicBlock* bb)
1814 {
1815     if (!enregisterLocalVars)
1816     {
1817         return;
1818     }
1819     JITDUMP("Recording Var Locations at start of BB%02u\n", bb->bbNum);
1820     VarToRegMap map   = getInVarToRegMap(bb->bbNum);
1821     unsigned    count = 0;
1822
1823     VarSetOps::AssignNoCopy(compiler, currentLiveVars,
1824                             VarSetOps::Intersection(compiler, registerCandidateVars, bb->bbLiveIn));
1825     VarSetOps::Iter iter(compiler, currentLiveVars);
1826     unsigned        varIndex = 0;
1827     while (iter.NextElem(&varIndex))
1828     {
1829         unsigned   varNum = compiler->lvaTrackedToVarNum[varIndex];
1830         LclVarDsc* varDsc = &(compiler->lvaTable[varNum]);
1831         regNumber  regNum = getVarReg(map, varIndex);
1832
1833         regNumber oldRegNum = varDsc->lvRegNum;
1834         regNumber newRegNum = regNum;
1835
1836         if (oldRegNum != newRegNum)
1837         {
1838             JITDUMP("  V%02u(%s->%s)", varNum, compiler->compRegVarName(oldRegNum),
1839                     compiler->compRegVarName(newRegNum));
1840             varDsc->lvRegNum = newRegNum;
1841             count++;
1842         }
1843         else if (newRegNum != REG_STK)
1844         {
1845             JITDUMP("  V%02u(%s)", varNum, compiler->compRegVarName(newRegNum));
1846             count++;
1847         }
1848     }
1849
1850     if (count == 0)
1851     {
1852         JITDUMP("  <none>\n");
1853     }
1854
1855     JITDUMP("\n");
1856 }
1857
1858 void Interval::setLocalNumber(Compiler* compiler, unsigned lclNum, LinearScan* linScan)
1859 {
1860     LclVarDsc* varDsc = &compiler->lvaTable[lclNum];
1861     assert(varDsc->lvTracked);
1862     assert(varDsc->lvVarIndex < compiler->lvaTrackedCount);
1863
1864     linScan->localVarIntervals[varDsc->lvVarIndex] = this;
1865
1866     assert(linScan->getIntervalForLocalVar(varDsc->lvVarIndex) == this);
1867     this->isLocalVar = true;
1868     this->varNum     = lclNum;
1869 }
1870
1871 // identify the candidates which we are not going to enregister due to
1872 // being used in EH in a way we don't want to deal with
1873 // this logic cloned from fgInterBlockLocalVarLiveness
1874 void LinearScan::identifyCandidatesExceptionDataflow()
1875 {
1876     VARSET_TP   exceptVars(VarSetOps::MakeEmpty(compiler));
1877     VARSET_TP   filterVars(VarSetOps::MakeEmpty(compiler));
1878     VARSET_TP   finallyVars(VarSetOps::MakeEmpty(compiler));
1879     BasicBlock* block;
1880
1881     foreach_block(compiler, block)
1882     {
1883         if (block->bbCatchTyp != BBCT_NONE)
1884         {
1885             // live on entry to handler
1886             VarSetOps::UnionD(compiler, exceptVars, block->bbLiveIn);
1887         }
1888
1889         if (block->bbJumpKind == BBJ_EHFILTERRET)
1890         {
1891             // live on exit from filter
1892             VarSetOps::UnionD(compiler, filterVars, block->bbLiveOut);
1893         }
1894         else if (block->bbJumpKind == BBJ_EHFINALLYRET)
1895         {
1896             // live on exit from finally
1897             VarSetOps::UnionD(compiler, finallyVars, block->bbLiveOut);
1898         }
1899 #if FEATURE_EH_FUNCLETS
1900         // Funclets are called and returned from, as such we can only count on the frame
1901         // pointer being restored, and thus everything live in or live out must be on the
1902         // stack
1903         if (block->bbFlags & BBF_FUNCLET_BEG)
1904         {
1905             VarSetOps::UnionD(compiler, exceptVars, block->bbLiveIn);
1906         }
1907         if ((block->bbJumpKind == BBJ_EHFINALLYRET) || (block->bbJumpKind == BBJ_EHFILTERRET) ||
1908             (block->bbJumpKind == BBJ_EHCATCHRET))
1909         {
1910             VarSetOps::UnionD(compiler, exceptVars, block->bbLiveOut);
1911         }
1912 #endif // FEATURE_EH_FUNCLETS
1913     }
1914
1915     // slam them all together (there was really no need to use more than 2 bitvectors here)
1916     VarSetOps::UnionD(compiler, exceptVars, filterVars);
1917     VarSetOps::UnionD(compiler, exceptVars, finallyVars);
1918
1919     /* Mark all pointer variables live on exit from a 'finally'
1920         block as either volatile for non-GC ref types or as
1921         'explicitly initialized' (volatile and must-init) for GC-ref types */
1922
1923     VarSetOps::Iter iter(compiler, exceptVars);
1924     unsigned        varIndex = 0;
1925     while (iter.NextElem(&varIndex))
1926     {
1927         unsigned   varNum = compiler->lvaTrackedToVarNum[varIndex];
1928         LclVarDsc* varDsc = compiler->lvaTable + varNum;
1929
1930         compiler->lvaSetVarDoNotEnregister(varNum DEBUGARG(Compiler::DNER_LiveInOutOfHandler));
1931
1932         if (varTypeIsGC(varDsc))
1933         {
1934             if (VarSetOps::IsMember(compiler, finallyVars, varIndex) && !varDsc->lvIsParam)
1935             {
1936                 varDsc->lvMustInit = true;
1937             }
1938         }
1939     }
1940 }
1941
1942 bool LinearScan::isRegCandidate(LclVarDsc* varDsc)
1943 {
1944     // We shouldn't be called if opt settings do not permit register variables.
1945     assert((compiler->opts.compFlags & CLFLG_REGVAR) != 0);
1946
1947     if (!varDsc->lvTracked)
1948     {
1949         return false;
1950     }
1951
1952 #if !defined(_TARGET_64BIT_)
1953     if (varDsc->lvType == TYP_LONG)
1954     {
1955         // Long variables should not be register candidates.
1956         // Lowering will have split any candidate lclVars into lo/hi vars.
1957         return false;
1958     }
1959 #endif // !defined(_TARGET_64BIT)
1960
1961     // If we have JMP, reg args must be put on the stack
1962
1963     if (compiler->compJmpOpUsed && varDsc->lvIsRegArg)
1964     {
1965         return false;
1966     }
1967
1968     // Don't allocate registers for dependently promoted struct fields
1969     if (compiler->lvaIsFieldOfDependentlyPromotedStruct(varDsc))
1970     {
1971         return false;
1972     }
1973     return true;
1974 }
1975
1976 // Identify locals & compiler temps that are register candidates
1977 // TODO-Cleanup: This was cloned from Compiler::lvaSortByRefCount() in lclvars.cpp in order
1978 // to avoid perturbation, but should be merged.
1979
1980 void LinearScan::identifyCandidates()
1981 {
1982     if (enregisterLocalVars)
1983     {
1984         // Initialize the set of lclVars that are candidates for register allocation.
1985         VarSetOps::AssignNoCopy(compiler, registerCandidateVars, VarSetOps::MakeEmpty(compiler));
1986
1987         // Initialize the sets of lclVars that are used to determine whether, and for which lclVars,
1988         // we need to perform resolution across basic blocks.
1989         // Note that we can't do this in the constructor because the number of tracked lclVars may
1990         // change between the constructor and the actual allocation.
1991         VarSetOps::AssignNoCopy(compiler, resolutionCandidateVars, VarSetOps::MakeEmpty(compiler));
1992         VarSetOps::AssignNoCopy(compiler, splitOrSpilledVars, VarSetOps::MakeEmpty(compiler));
1993
1994         // We set enregisterLocalVars to true only if there are tracked lclVars
1995         assert(compiler->lvaCount != 0);
1996     }
1997     else if (compiler->lvaCount == 0)
1998     {
1999         // Nothing to do. Note that even if enregisterLocalVars is false, we still need to set the
2000         // lvLRACandidate field on all the lclVars to false if we have any.
2001         return;
2002     }
2003
2004     if (compiler->compHndBBtabCount > 0)
2005     {
2006         identifyCandidatesExceptionDataflow();
2007     }
2008
2009     unsigned   lclNum;
2010     LclVarDsc* varDsc;
2011
2012     // While we build intervals for the candidate lclVars, we will determine the floating point
2013     // lclVars, if any, to consider for callee-save register preferencing.
2014     // We maintain two sets of FP vars - those that meet the first threshold of weighted ref Count,
2015     // and those that meet the second.
2016     // The first threshold is used for methods that are heuristically deemed either to have light
2017     // fp usage, or other factors that encourage conservative use of callee-save registers, such
2018     // as multiple exits (where there might be an early exit that woudl be excessively penalized by
2019     // lots of prolog/epilog saves & restores).
2020     // The second threshold is used where there are factors deemed to make it more likely that fp
2021     // fp callee save registers will be needed, such as loops or many fp vars.
2022     // We keep two sets of vars, since we collect some of the information to determine which set to
2023     // use as we iterate over the vars.
2024     // When we are generating AVX code on non-Unix (FEATURE_PARTIAL_SIMD_CALLEE_SAVE), we maintain an
2025     // additional set of LargeVectorType vars, and there is a separate threshold defined for those.
2026     // It is assumed that if we encounter these, that we should consider this a "high use" scenario,
2027     // so we don't maintain two sets of these vars.
2028     // This is defined as thresholdLargeVectorRefCntWtd, as we are likely to use the same mechanism
2029     // for vectors on Arm64, though the actual value may differ.
2030
2031     unsigned int floatVarCount        = 0;
2032     unsigned int thresholdFPRefCntWtd = 4 * BB_UNITY_WEIGHT;
2033     unsigned int maybeFPRefCntWtd     = 2 * BB_UNITY_WEIGHT;
2034     VARSET_TP    fpMaybeCandidateVars(VarSetOps::UninitVal());
2035 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
2036     unsigned int largeVectorVarCount           = 0;
2037     unsigned int thresholdLargeVectorRefCntWtd = 4 * BB_UNITY_WEIGHT;
2038 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
2039     if (enregisterLocalVars)
2040     {
2041         VarSetOps::AssignNoCopy(compiler, fpCalleeSaveCandidateVars, VarSetOps::MakeEmpty(compiler));
2042         VarSetOps::AssignNoCopy(compiler, fpMaybeCandidateVars, VarSetOps::MakeEmpty(compiler));
2043 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
2044         VarSetOps::AssignNoCopy(compiler, largeVectorVars, VarSetOps::MakeEmpty(compiler));
2045         VarSetOps::AssignNoCopy(compiler, largeVectorCalleeSaveCandidateVars, VarSetOps::MakeEmpty(compiler));
2046 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
2047     }
2048 #if DOUBLE_ALIGN
2049     unsigned refCntStk       = 0;
2050     unsigned refCntReg       = 0;
2051     unsigned refCntWtdReg    = 0;
2052     unsigned refCntStkParam  = 0; // sum of     ref counts for all stack based parameters
2053     unsigned refCntWtdStkDbl = 0; // sum of wtd ref counts for stack based doubles
2054     doDoubleAlign            = false;
2055     bool checkDoubleAlign    = true;
2056     if (compiler->codeGen->isFramePointerRequired() || compiler->opts.MinOpts())
2057     {
2058         checkDoubleAlign = false;
2059     }
2060     else
2061     {
2062         switch (compiler->getCanDoubleAlign())
2063         {
2064             case MUST_DOUBLE_ALIGN:
2065                 doDoubleAlign    = true;
2066                 checkDoubleAlign = false;
2067                 break;
2068             case CAN_DOUBLE_ALIGN:
2069                 break;
2070             case CANT_DOUBLE_ALIGN:
2071                 doDoubleAlign    = false;
2072                 checkDoubleAlign = false;
2073                 break;
2074             default:
2075                 unreached();
2076         }
2077     }
2078 #endif // DOUBLE_ALIGN
2079
2080     // Check whether register variables are permitted.
2081     if (!enregisterLocalVars)
2082     {
2083         localVarIntervals = nullptr;
2084     }
2085     else if (compiler->lvaTrackedCount > 0)
2086     {
2087         // initialize mapping from tracked local to interval
2088         localVarIntervals = new (compiler, CMK_LSRA) Interval*[compiler->lvaTrackedCount];
2089     }
2090
2091     INTRACK_STATS(regCandidateVarCount = 0);
2092     for (lclNum = 0, varDsc = compiler->lvaTable; lclNum < compiler->lvaCount; lclNum++, varDsc++)
2093     {
2094         // Initialize all variables to REG_STK
2095         varDsc->lvRegNum = REG_STK;
2096 #ifndef _TARGET_64BIT_
2097         varDsc->lvOtherReg = REG_STK;
2098 #endif // _TARGET_64BIT_
2099
2100         if (!enregisterLocalVars)
2101         {
2102             varDsc->lvLRACandidate = false;
2103             continue;
2104         }
2105
2106 #if DOUBLE_ALIGN
2107         if (checkDoubleAlign)
2108         {
2109             if (varDsc->lvIsParam && !varDsc->lvIsRegArg)
2110             {
2111                 refCntStkParam += varDsc->lvRefCnt;
2112             }
2113             else if (!isRegCandidate(varDsc) || varDsc->lvDoNotEnregister)
2114             {
2115                 refCntStk += varDsc->lvRefCnt;
2116                 if ((varDsc->lvType == TYP_DOUBLE) ||
2117                     ((varTypeIsStruct(varDsc) && varDsc->lvStructDoubleAlign &&
2118                       (compiler->lvaGetPromotionType(varDsc) != Compiler::PROMOTION_TYPE_INDEPENDENT))))
2119                 {
2120                     refCntWtdStkDbl += varDsc->lvRefCntWtd;
2121                 }
2122             }
2123             else
2124             {
2125                 refCntReg += varDsc->lvRefCnt;
2126                 refCntWtdReg += varDsc->lvRefCntWtd;
2127             }
2128         }
2129 #endif // DOUBLE_ALIGN
2130
2131         /* Track all locals that can be enregistered */
2132
2133         if (!isRegCandidate(varDsc))
2134         {
2135             varDsc->lvLRACandidate = 0;
2136             if (varDsc->lvTracked)
2137             {
2138                 localVarIntervals[varDsc->lvVarIndex] = nullptr;
2139             }
2140             continue;
2141         }
2142
2143         assert(varDsc->lvTracked);
2144
2145         varDsc->lvLRACandidate = 1;
2146
2147         // Start with lvRegister as false - set it true only if the variable gets
2148         // the same register assignment throughout
2149         varDsc->lvRegister = false;
2150
2151         /* If the ref count is zero */
2152         if (varDsc->lvRefCnt == 0)
2153         {
2154             /* Zero ref count, make this untracked */
2155             varDsc->lvRefCntWtd    = 0;
2156             varDsc->lvLRACandidate = 0;
2157         }
2158
2159         // Variables that are address-exposed are never enregistered, or tracked.
2160         // A struct may be promoted, and a struct that fits in a register may be fully enregistered.
2161         // Pinned variables may not be tracked (a condition of the GCInfo representation)
2162         // or enregistered, on x86 -- it is believed that we can enregister pinned (more properly, "pinning")
2163         // references when using the general GC encoding.
2164
2165         if (varDsc->lvAddrExposed || !varTypeIsEnregisterableStruct(varDsc))
2166         {
2167             varDsc->lvLRACandidate = 0;
2168 #ifdef DEBUG
2169             Compiler::DoNotEnregisterReason dner = Compiler::DNER_AddrExposed;
2170             if (!varDsc->lvAddrExposed)
2171             {
2172                 dner = Compiler::DNER_IsStruct;
2173             }
2174 #endif // DEBUG
2175             compiler->lvaSetVarDoNotEnregister(lclNum DEBUGARG(dner));
2176         }
2177         else if (varDsc->lvPinned)
2178         {
2179             varDsc->lvTracked = 0;
2180 #ifdef JIT32_GCENCODER
2181             compiler->lvaSetVarDoNotEnregister(lclNum DEBUGARG(Compiler::DNER_PinningRef));
2182 #endif // JIT32_GCENCODER
2183         }
2184
2185         //  Are we not optimizing and we have exception handlers?
2186         //   if so mark all args and locals as volatile, so that they
2187         //   won't ever get enregistered.
2188         //
2189         if (compiler->opts.MinOpts() && compiler->compHndBBtabCount > 0)
2190         {
2191             compiler->lvaSetVarDoNotEnregister(lclNum DEBUGARG(Compiler::DNER_LiveInOutOfHandler));
2192         }
2193
2194         if (varDsc->lvDoNotEnregister)
2195         {
2196             varDsc->lvLRACandidate                = 0;
2197             localVarIntervals[varDsc->lvVarIndex] = nullptr;
2198             continue;
2199         }
2200
2201         var_types type = genActualType(varDsc->TypeGet());
2202
2203         switch (type)
2204         {
2205 #if CPU_HAS_FP_SUPPORT
2206             case TYP_FLOAT:
2207             case TYP_DOUBLE:
2208                 if (compiler->opts.compDbgCode)
2209                 {
2210                     varDsc->lvLRACandidate = 0;
2211                 }
2212 #ifdef ARM_SOFTFP
2213                 if (varDsc->lvIsParam && varDsc->lvIsRegArg)
2214                 {
2215                     type = (type == TYP_DOUBLE) ? TYP_LONG : TYP_INT;
2216                 }
2217 #endif // ARM_SOFTFP
2218                 break;
2219 #endif // CPU_HAS_FP_SUPPORT
2220
2221             case TYP_INT:
2222             case TYP_LONG:
2223             case TYP_REF:
2224             case TYP_BYREF:
2225                 break;
2226
2227 #ifdef FEATURE_SIMD
2228             case TYP_SIMD12:
2229             case TYP_SIMD16:
2230             case TYP_SIMD32:
2231                 if (varDsc->lvPromoted)
2232                 {
2233                     varDsc->lvLRACandidate = 0;
2234                 }
2235                 break;
2236
2237             // TODO-1stClassStructs: Move TYP_SIMD8 up with the other SIMD types, after handling the param issue
2238             // (passing & returning as TYP_LONG).
2239             case TYP_SIMD8:
2240 #endif // FEATURE_SIMD
2241
2242             case TYP_STRUCT:
2243             {
2244                 varDsc->lvLRACandidate = 0;
2245             }
2246             break;
2247
2248             case TYP_UNDEF:
2249             case TYP_UNKNOWN:
2250                 noway_assert(!"lvType not set correctly");
2251                 varDsc->lvType = TYP_INT;
2252
2253                 __fallthrough;
2254
2255             default:
2256                 varDsc->lvLRACandidate = 0;
2257         }
2258
2259         if (varDsc->lvLRACandidate)
2260         {
2261             Interval* newInt = newInterval(type);
2262             newInt->setLocalNumber(compiler, lclNum, this);
2263             VarSetOps::AddElemD(compiler, registerCandidateVars, varDsc->lvVarIndex);
2264
2265             // we will set this later when we have determined liveness
2266             varDsc->lvMustInit = false;
2267
2268             if (varDsc->lvIsStructField)
2269             {
2270                 newInt->isStructField = true;
2271             }
2272
2273             INTRACK_STATS(regCandidateVarCount++);
2274
2275             // We maintain two sets of FP vars - those that meet the first threshold of weighted ref Count,
2276             // and those that meet the second (see the definitions of thresholdFPRefCntWtd and maybeFPRefCntWtd
2277             // above).
2278             CLANG_FORMAT_COMMENT_ANCHOR;
2279
2280 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
2281             // Additionally, when we are generating AVX on non-UNIX amd64, we keep a separate set of the LargeVectorType
2282             // vars.
2283             if (varDsc->lvType == LargeVectorType)
2284             {
2285                 largeVectorVarCount++;
2286                 VarSetOps::AddElemD(compiler, largeVectorVars, varDsc->lvVarIndex);
2287                 unsigned refCntWtd = varDsc->lvRefCntWtd;
2288                 if (refCntWtd >= thresholdLargeVectorRefCntWtd)
2289                 {
2290                     VarSetOps::AddElemD(compiler, largeVectorCalleeSaveCandidateVars, varDsc->lvVarIndex);
2291                 }
2292             }
2293             else
2294 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
2295                 if (regType(type) == FloatRegisterType)
2296             {
2297                 floatVarCount++;
2298                 unsigned refCntWtd = varDsc->lvRefCntWtd;
2299                 if (varDsc->lvIsRegArg)
2300                 {
2301                     // Don't count the initial reference for register params.  In those cases,
2302                     // using a callee-save causes an extra copy.
2303                     refCntWtd -= BB_UNITY_WEIGHT;
2304                 }
2305                 if (refCntWtd >= thresholdFPRefCntWtd)
2306                 {
2307                     VarSetOps::AddElemD(compiler, fpCalleeSaveCandidateVars, varDsc->lvVarIndex);
2308                 }
2309                 else if (refCntWtd >= maybeFPRefCntWtd)
2310                 {
2311                     VarSetOps::AddElemD(compiler, fpMaybeCandidateVars, varDsc->lvVarIndex);
2312                 }
2313             }
2314         }
2315         else
2316         {
2317             localVarIntervals[varDsc->lvVarIndex] = nullptr;
2318         }
2319     }
2320
2321 #if DOUBLE_ALIGN
2322     if (checkDoubleAlign)
2323     {
2324         // TODO-CQ: Fine-tune this:
2325         // In the legacy reg predictor, this runs after allocation, and then demotes any lclVars
2326         // allocated to the frame pointer, which is probably the wrong order.
2327         // However, because it runs after allocation, it can determine the impact of demoting
2328         // the lclVars allocated to the frame pointer.
2329         // => Here, estimate of the EBP refCnt and weighted refCnt is a wild guess.
2330         //
2331         unsigned refCntEBP    = refCntReg / 8;
2332         unsigned refCntWtdEBP = refCntWtdReg / 8;
2333
2334         doDoubleAlign =
2335             compiler->shouldDoubleAlign(refCntStk, refCntEBP, refCntWtdEBP, refCntStkParam, refCntWtdStkDbl);
2336     }
2337 #endif // DOUBLE_ALIGN
2338
2339     // The factors we consider to determine which set of fp vars to use as candidates for callee save
2340     // registers current include the number of fp vars, whether there are loops, and whether there are
2341     // multiple exits.  These have been selected somewhat empirically, but there is probably room for
2342     // more tuning.
2343     CLANG_FORMAT_COMMENT_ANCHOR;
2344
2345 #ifdef DEBUG
2346     if (VERBOSE)
2347     {
2348         printf("\nFP callee save candidate vars: ");
2349         if (enregisterLocalVars && !VarSetOps::IsEmpty(compiler, fpCalleeSaveCandidateVars))
2350         {
2351             dumpConvertedVarSet(compiler, fpCalleeSaveCandidateVars);
2352             printf("\n");
2353         }
2354         else
2355         {
2356             printf("None\n\n");
2357         }
2358     }
2359 #endif
2360
2361     JITDUMP("floatVarCount = %d; hasLoops = %d, singleExit = %d\n", floatVarCount, compiler->fgHasLoops,
2362             (compiler->fgReturnBlocks == nullptr || compiler->fgReturnBlocks->next == nullptr));
2363
2364     // Determine whether to use the 2nd, more aggressive, threshold for fp callee saves.
2365     if (floatVarCount > 6 && compiler->fgHasLoops &&
2366         (compiler->fgReturnBlocks == nullptr || compiler->fgReturnBlocks->next == nullptr))
2367     {
2368         assert(enregisterLocalVars);
2369 #ifdef DEBUG
2370         if (VERBOSE)
2371         {
2372             printf("Adding additional fp callee save candidates: \n");
2373             if (!VarSetOps::IsEmpty(compiler, fpMaybeCandidateVars))
2374             {
2375                 dumpConvertedVarSet(compiler, fpMaybeCandidateVars);
2376                 printf("\n");
2377             }
2378             else
2379             {
2380                 printf("None\n\n");
2381             }
2382         }
2383 #endif
2384         VarSetOps::UnionD(compiler, fpCalleeSaveCandidateVars, fpMaybeCandidateVars);
2385     }
2386
2387 #ifdef _TARGET_ARM_
2388 #ifdef DEBUG
2389     if (VERBOSE)
2390     {
2391         // Frame layout is only pre-computed for ARM
2392         printf("\nlvaTable after IdentifyCandidates\n");
2393         compiler->lvaTableDump();
2394     }
2395 #endif // DEBUG
2396 #endif // _TARGET_ARM_
2397 }
2398
2399 // TODO-Throughput: This mapping can surely be more efficiently done
2400 void LinearScan::initVarRegMaps()
2401 {
2402     if (!enregisterLocalVars)
2403     {
2404         inVarToRegMaps  = nullptr;
2405         outVarToRegMaps = nullptr;
2406         return;
2407     }
2408     assert(compiler->lvaTrackedFixed); // We should have already set this to prevent us from adding any new tracked
2409                                        // variables.
2410
2411     // The compiler memory allocator requires that the allocation be an
2412     // even multiple of int-sized objects
2413     unsigned int varCount = compiler->lvaTrackedCount;
2414     regMapCount           = (unsigned int)roundUp(varCount, sizeof(int));
2415
2416     // Not sure why blocks aren't numbered from zero, but they don't appear to be.
2417     // So, if we want to index by bbNum we have to know the maximum value.
2418     unsigned int bbCount = compiler->fgBBNumMax + 1;
2419
2420     inVarToRegMaps  = new (compiler, CMK_LSRA) regNumberSmall*[bbCount];
2421     outVarToRegMaps = new (compiler, CMK_LSRA) regNumberSmall*[bbCount];
2422
2423     if (varCount > 0)
2424     {
2425         // This VarToRegMap is used during the resolution of critical edges.
2426         sharedCriticalVarToRegMap = new (compiler, CMK_LSRA) regNumberSmall[regMapCount];
2427
2428         for (unsigned int i = 0; i < bbCount; i++)
2429         {
2430             VarToRegMap inVarToRegMap  = new (compiler, CMK_LSRA) regNumberSmall[regMapCount];
2431             VarToRegMap outVarToRegMap = new (compiler, CMK_LSRA) regNumberSmall[regMapCount];
2432
2433             for (unsigned int j = 0; j < regMapCount; j++)
2434             {
2435                 inVarToRegMap[j]  = REG_STK;
2436                 outVarToRegMap[j] = REG_STK;
2437             }
2438             inVarToRegMaps[i]  = inVarToRegMap;
2439             outVarToRegMaps[i] = outVarToRegMap;
2440         }
2441     }
2442     else
2443     {
2444         sharedCriticalVarToRegMap = nullptr;
2445         for (unsigned int i = 0; i < bbCount; i++)
2446         {
2447             inVarToRegMaps[i]  = nullptr;
2448             outVarToRegMaps[i] = nullptr;
2449         }
2450     }
2451 }
2452
2453 void LinearScan::setInVarRegForBB(unsigned int bbNum, unsigned int varNum, regNumber reg)
2454 {
2455     assert(enregisterLocalVars);
2456     assert(reg < UCHAR_MAX && varNum < compiler->lvaCount);
2457     inVarToRegMaps[bbNum][compiler->lvaTable[varNum].lvVarIndex] = (regNumberSmall)reg;
2458 }
2459
2460 void LinearScan::setOutVarRegForBB(unsigned int bbNum, unsigned int varNum, regNumber reg)
2461 {
2462     assert(enregisterLocalVars);
2463     assert(reg < UCHAR_MAX && varNum < compiler->lvaCount);
2464     outVarToRegMaps[bbNum][compiler->lvaTable[varNum].lvVarIndex] = (regNumberSmall)reg;
2465 }
2466
2467 LinearScan::SplitEdgeInfo LinearScan::getSplitEdgeInfo(unsigned int bbNum)
2468 {
2469     assert(enregisterLocalVars);
2470     SplitEdgeInfo splitEdgeInfo;
2471     assert(bbNum <= compiler->fgBBNumMax);
2472     assert(bbNum > bbNumMaxBeforeResolution);
2473     assert(splitBBNumToTargetBBNumMap != nullptr);
2474     splitBBNumToTargetBBNumMap->Lookup(bbNum, &splitEdgeInfo);
2475     assert(splitEdgeInfo.toBBNum <= bbNumMaxBeforeResolution);
2476     assert(splitEdgeInfo.fromBBNum <= bbNumMaxBeforeResolution);
2477     return splitEdgeInfo;
2478 }
2479
2480 VarToRegMap LinearScan::getInVarToRegMap(unsigned int bbNum)
2481 {
2482     assert(enregisterLocalVars);
2483     assert(bbNum <= compiler->fgBBNumMax);
2484     // For the blocks inserted to split critical edges, the inVarToRegMap is
2485     // equal to the outVarToRegMap at the "from" block.
2486     if (bbNum > bbNumMaxBeforeResolution)
2487     {
2488         SplitEdgeInfo splitEdgeInfo = getSplitEdgeInfo(bbNum);
2489         unsigned      fromBBNum     = splitEdgeInfo.fromBBNum;
2490         if (fromBBNum == 0)
2491         {
2492             assert(splitEdgeInfo.toBBNum != 0);
2493             return inVarToRegMaps[splitEdgeInfo.toBBNum];
2494         }
2495         else
2496         {
2497             return outVarToRegMaps[fromBBNum];
2498         }
2499     }
2500
2501     return inVarToRegMaps[bbNum];
2502 }
2503
2504 VarToRegMap LinearScan::getOutVarToRegMap(unsigned int bbNum)
2505 {
2506     assert(enregisterLocalVars);
2507     assert(bbNum <= compiler->fgBBNumMax);
2508     // For the blocks inserted to split critical edges, the outVarToRegMap is
2509     // equal to the inVarToRegMap at the target.
2510     if (bbNum > bbNumMaxBeforeResolution)
2511     {
2512         // If this is an empty block, its in and out maps are both the same.
2513         // We identify this case by setting fromBBNum or toBBNum to 0, and using only the other.
2514         SplitEdgeInfo splitEdgeInfo = getSplitEdgeInfo(bbNum);
2515         unsigned      toBBNum       = splitEdgeInfo.toBBNum;
2516         if (toBBNum == 0)
2517         {
2518             assert(splitEdgeInfo.fromBBNum != 0);
2519             return outVarToRegMaps[splitEdgeInfo.fromBBNum];
2520         }
2521         else
2522         {
2523             return inVarToRegMaps[toBBNum];
2524         }
2525     }
2526     return outVarToRegMaps[bbNum];
2527 }
2528
2529 //------------------------------------------------------------------------
2530 // setVarReg: Set the register associated with a variable in the given 'bbVarToRegMap'.
2531 //
2532 // Arguments:
2533 //    bbVarToRegMap   - the map of interest
2534 //    trackedVarIndex - the lvVarIndex for the variable
2535 //    reg             - the register to which it is being mapped
2536 //
2537 // Return Value:
2538 //    None
2539 //
2540 void LinearScan::setVarReg(VarToRegMap bbVarToRegMap, unsigned int trackedVarIndex, regNumber reg)
2541 {
2542     assert(trackedVarIndex < compiler->lvaTrackedCount);
2543     regNumberSmall regSmall = (regNumberSmall)reg;
2544     assert((regNumber)regSmall == reg);
2545     bbVarToRegMap[trackedVarIndex] = regSmall;
2546 }
2547
2548 //------------------------------------------------------------------------
2549 // getVarReg: Get the register associated with a variable in the given 'bbVarToRegMap'.
2550 //
2551 // Arguments:
2552 //    bbVarToRegMap   - the map of interest
2553 //    trackedVarIndex - the lvVarIndex for the variable
2554 //
2555 // Return Value:
2556 //    The register to which 'trackedVarIndex' is mapped
2557 //
2558 regNumber LinearScan::getVarReg(VarToRegMap bbVarToRegMap, unsigned int trackedVarIndex)
2559 {
2560     assert(enregisterLocalVars);
2561     assert(trackedVarIndex < compiler->lvaTrackedCount);
2562     return (regNumber)bbVarToRegMap[trackedVarIndex];
2563 }
2564
2565 // Initialize the incoming VarToRegMap to the given map values (generally a predecessor of
2566 // the block)
2567 VarToRegMap LinearScan::setInVarToRegMap(unsigned int bbNum, VarToRegMap srcVarToRegMap)
2568 {
2569     assert(enregisterLocalVars);
2570     VarToRegMap inVarToRegMap = inVarToRegMaps[bbNum];
2571     memcpy(inVarToRegMap, srcVarToRegMap, (regMapCount * sizeof(regNumber)));
2572     return inVarToRegMap;
2573 }
2574
2575 // given a tree node
2576 RefType refTypeForLocalRefNode(GenTree* node)
2577 {
2578     assert(node->IsLocal());
2579
2580     // We don't support updates
2581     assert((node->gtFlags & GTF_VAR_USEASG) == 0);
2582
2583     if (node->gtFlags & GTF_VAR_DEF)
2584     {
2585         return RefTypeDef;
2586     }
2587     else
2588     {
2589         return RefTypeUse;
2590     }
2591 }
2592
2593 //------------------------------------------------------------------------
2594 // checkLastUses: Check correctness of last use flags
2595 //
2596 // Arguments:
2597 //    The block for which we are checking last uses.
2598 //
2599 // Notes:
2600 //    This does a backward walk of the RefPositions, starting from the liveOut set.
2601 //    This method was previously used to set the last uses, which were computed by
2602 //    liveness, but were not create in some cases of multiple lclVar references in the
2603 //    same tree. However, now that last uses are computed as RefPositions are created,
2604 //    that is no longer necessary, and this method is simply retained as a check.
2605 //    The exception to the check-only behavior is when LSRA_EXTEND_LIFETIMES if set via
2606 //    COMPlus_JitStressRegs. In that case, this method is required, because even though
2607 //    the RefPositions will not be marked lastUse in that case, we still need to correclty
2608 //    mark the last uses on the tree nodes, which is done by this method.
2609 //
2610 #ifdef DEBUG
2611 void LinearScan::checkLastUses(BasicBlock* block)
2612 {
2613     if (VERBOSE)
2614     {
2615         JITDUMP("\n\nCHECKING LAST USES for block %u, liveout=", block->bbNum);
2616         dumpConvertedVarSet(compiler, block->bbLiveOut);
2617         JITDUMP("\n==============================\n");
2618     }
2619
2620     unsigned keepAliveVarNum = BAD_VAR_NUM;
2621     if (compiler->lvaKeepAliveAndReportThis())
2622     {
2623         keepAliveVarNum = compiler->info.compThisArg;
2624         assert(compiler->info.compIsStatic == false);
2625     }
2626
2627     // find which uses are lastUses
2628
2629     // Work backwards starting with live out.
2630     // 'computedLive' is updated to include any exposed use (including those in this
2631     // block that we've already seen).  When we encounter a use, if it's
2632     // not in that set, then it's a last use.
2633
2634     VARSET_TP computedLive(VarSetOps::MakeCopy(compiler, block->bbLiveOut));
2635
2636     bool foundDiff          = false;
2637     auto currentRefPosition = refPositions.rbegin();
2638     while (currentRefPosition->refType != RefTypeBB)
2639     {
2640         // We should never see ParamDefs or ZeroInits within a basic block.
2641         assert(currentRefPosition->refType != RefTypeParamDef && currentRefPosition->refType != RefTypeZeroInit);
2642         if (currentRefPosition->isIntervalRef() && currentRefPosition->getInterval()->isLocalVar)
2643         {
2644             unsigned varNum   = currentRefPosition->getInterval()->varNum;
2645             unsigned varIndex = currentRefPosition->getInterval()->getVarIndex(compiler);
2646
2647             LsraLocation loc = currentRefPosition->nodeLocation;
2648
2649             // We should always have a tree node for a localVar, except for the "special" RefPositions.
2650             GenTreePtr tree = currentRefPosition->treeNode;
2651             assert(tree != nullptr || currentRefPosition->refType == RefTypeExpUse ||
2652                    currentRefPosition->refType == RefTypeDummyDef);
2653
2654             if (!VarSetOps::IsMember(compiler, computedLive, varIndex) && varNum != keepAliveVarNum)
2655             {
2656                 // There was no exposed use, so this is a "last use" (and we mark it thus even if it's a def)
2657
2658                 if (extendLifetimes())
2659                 {
2660                     // NOTE: this is a bit of a hack. When extending lifetimes, the "last use" bit will be clear.
2661                     // This bit, however, would normally be used during resolveLocalRef to set the value of
2662                     // GTF_VAR_DEATH on the node for a ref position. If this bit is not set correctly even when
2663                     // extending lifetimes, the code generator will assert as it expects to have accurate last
2664                     // use information. To avoid these asserts, set the GTF_VAR_DEATH bit here.
2665                     // Note also that extendLifetimes() is an LSRA stress mode, so it will only be true for
2666                     // Checked or Debug builds, for which this method will be executed.
2667                     if (tree != nullptr)
2668                     {
2669                         tree->gtFlags |= GTF_VAR_DEATH;
2670                     }
2671                 }
2672                 else if (!currentRefPosition->lastUse)
2673                 {
2674                     JITDUMP("missing expected last use of V%02u @%u\n", compiler->lvaTrackedToVarNum[varIndex], loc);
2675                     foundDiff = true;
2676                 }
2677                 VarSetOps::AddElemD(compiler, computedLive, varIndex);
2678             }
2679             else if (currentRefPosition->lastUse)
2680             {
2681                 JITDUMP("unexpected last use of V%02u @%u\n", compiler->lvaTrackedToVarNum[varIndex], loc);
2682                 foundDiff = true;
2683             }
2684             else if (extendLifetimes() && tree != nullptr)
2685             {
2686                 // NOTE: see the comment above re: the extendLifetimes hack.
2687                 tree->gtFlags &= ~GTF_VAR_DEATH;
2688             }
2689
2690             if (currentRefPosition->refType == RefTypeDef || currentRefPosition->refType == RefTypeDummyDef)
2691             {
2692                 VarSetOps::RemoveElemD(compiler, computedLive, varIndex);
2693             }
2694         }
2695
2696         assert(currentRefPosition != refPositions.rend());
2697         ++currentRefPosition;
2698     }
2699
2700     VARSET_TP liveInNotComputedLive(VarSetOps::Diff(compiler, block->bbLiveIn, computedLive));
2701
2702     VarSetOps::Iter liveInNotComputedLiveIter(compiler, liveInNotComputedLive);
2703     unsigned        liveInNotComputedLiveIndex = 0;
2704     while (liveInNotComputedLiveIter.NextElem(&liveInNotComputedLiveIndex))
2705     {
2706         unsigned varNum = compiler->lvaTrackedToVarNum[liveInNotComputedLiveIndex];
2707         if (compiler->lvaTable[varNum].lvLRACandidate)
2708         {
2709             JITDUMP("BB%02u: V%02u is in LiveIn set, but not computed live.\n", block->bbNum, varNum);
2710             foundDiff = true;
2711         }
2712     }
2713
2714     VarSetOps::DiffD(compiler, computedLive, block->bbLiveIn);
2715     const VARSET_TP& computedLiveNotLiveIn(computedLive); // reuse the buffer.
2716     VarSetOps::Iter  computedLiveNotLiveInIter(compiler, computedLiveNotLiveIn);
2717     unsigned         computedLiveNotLiveInIndex = 0;
2718     while (computedLiveNotLiveInIter.NextElem(&computedLiveNotLiveInIndex))
2719     {
2720         unsigned varNum = compiler->lvaTrackedToVarNum[computedLiveNotLiveInIndex];
2721         if (compiler->lvaTable[varNum].lvLRACandidate)
2722         {
2723             JITDUMP("BB%02u: V%02u is computed live, but not in LiveIn set.\n", block->bbNum, varNum);
2724             foundDiff = true;
2725         }
2726     }
2727
2728     assert(!foundDiff);
2729 }
2730 #endif // DEBUG
2731
2732 void LinearScan::addRefsForPhysRegMask(regMaskTP mask, LsraLocation currentLoc, RefType refType, bool isLastUse)
2733 {
2734     for (regNumber reg = REG_FIRST; mask; reg = REG_NEXT(reg), mask >>= 1)
2735     {
2736         if (mask & 1)
2737         {
2738             // This assumes that these are all "special" RefTypes that
2739             // don't need to be recorded on the tree (hence treeNode is nullptr)
2740             RefPosition* pos = newRefPosition(reg, currentLoc, refType, nullptr,
2741                                               genRegMask(reg)); // This MUST occupy the physical register (obviously)
2742
2743             if (isLastUse)
2744             {
2745                 pos->lastUse = true;
2746             }
2747         }
2748     }
2749 }
2750
2751 //------------------------------------------------------------------------
2752 // getKillSetForNode:   Return the registers killed by the given tree node.
2753 //
2754 // Arguments:
2755 //    compiler   - the compiler context to use
2756 //    tree       - the tree for which the kill set is needed.
2757 //
2758 // Return Value:    a register mask of the registers killed
2759 //
2760 regMaskTP LinearScan::getKillSetForNode(GenTree* tree)
2761 {
2762     regMaskTP killMask = RBM_NONE;
2763     switch (tree->OperGet())
2764     {
2765 #ifdef _TARGET_XARCH_
2766         case GT_MUL:
2767             // We use the 128-bit multiply when performing an overflow checking unsigned multiply
2768             //
2769             if (((tree->gtFlags & GTF_UNSIGNED) != 0) && tree->gtOverflowEx())
2770             {
2771                 // Both RAX and RDX are killed by the operation
2772                 killMask = RBM_RAX | RBM_RDX;
2773             }
2774             break;
2775
2776         case GT_MULHI:
2777 #if defined(_TARGET_X86_) && !defined(LEGACY_BACKEND)
2778         case GT_MUL_LONG:
2779 #endif
2780             killMask = RBM_RAX | RBM_RDX;
2781             break;
2782
2783         case GT_MOD:
2784         case GT_DIV:
2785         case GT_UMOD:
2786         case GT_UDIV:
2787             if (!varTypeIsFloating(tree->TypeGet()))
2788             {
2789                 // RDX needs to be killed early, because it must not be used as a source register
2790                 // (unlike most cases, where the kill happens AFTER the uses).  So for this kill,
2791                 // we add the RefPosition at the tree loc (where the uses are located) instead of the
2792                 // usual kill location which is the same as the defs at tree loc+1.
2793                 // Note that we don't have to add interference for the live vars, because that
2794                 // will be done below, and is not sensitive to the precise location.
2795                 LsraLocation currentLoc = tree->gtLsraInfo.loc;
2796                 assert(currentLoc != 0);
2797                 addRefsForPhysRegMask(RBM_RDX, currentLoc, RefTypeKill, true);
2798                 // Both RAX and RDX are killed by the operation
2799                 killMask = RBM_RAX | RBM_RDX;
2800             }
2801             break;
2802 #endif // _TARGET_XARCH_
2803
2804         case GT_STORE_OBJ:
2805             if (tree->OperIsCopyBlkOp())
2806             {
2807                 assert(tree->AsObj()->gtGcPtrCount != 0);
2808                 killMask = compiler->compHelperCallKillSet(CORINFO_HELP_ASSIGN_BYREF);
2809                 break;
2810             }
2811             __fallthrough;
2812
2813         case GT_STORE_BLK:
2814         case GT_STORE_DYN_BLK:
2815         {
2816             GenTreeBlk* blkNode   = tree->AsBlk();
2817             bool        isCopyBlk = varTypeIsStruct(blkNode->Data());
2818             switch (blkNode->gtBlkOpKind)
2819             {
2820                 case GenTreeBlk::BlkOpKindHelper:
2821                     if (isCopyBlk)
2822                     {
2823                         killMask = compiler->compHelperCallKillSet(CORINFO_HELP_MEMCPY);
2824                     }
2825                     else
2826                     {
2827                         killMask = compiler->compHelperCallKillSet(CORINFO_HELP_MEMSET);
2828                     }
2829                     break;
2830
2831 #ifdef _TARGET_XARCH_
2832                 case GenTreeBlk::BlkOpKindRepInstr:
2833                     if (isCopyBlk)
2834                     {
2835                         // rep movs kills RCX, RDI and RSI
2836                         killMask = RBM_RCX | RBM_RDI | RBM_RSI;
2837                     }
2838                     else
2839                     {
2840                         // rep stos kills RCX and RDI.
2841                         // (Note that the Data() node, if not constant, will be assigned to
2842                         // RCX, but it's find that this kills it, as the value is not available
2843                         // after this node in any case.)
2844                         killMask = RBM_RDI | RBM_RCX;
2845                     }
2846                     break;
2847 #else
2848                 case GenTreeBlk::BlkOpKindRepInstr:
2849 #endif
2850                 case GenTreeBlk::BlkOpKindUnroll:
2851                 case GenTreeBlk::BlkOpKindInvalid:
2852                     // for these 'gtBlkOpKind' kinds, we leave 'killMask' = RBM_NONE
2853                     break;
2854             }
2855         }
2856         break;
2857
2858         case GT_RETURNTRAP:
2859             killMask = compiler->compHelperCallKillSet(CORINFO_HELP_STOP_FOR_GC);
2860             break;
2861         case GT_CALL:
2862 #ifdef _TARGET_X86_
2863             if (compiler->compFloatingPointUsed)
2864             {
2865                 if (tree->TypeGet() == TYP_DOUBLE)
2866                 {
2867                     needDoubleTmpForFPCall = true;
2868                 }
2869                 else if (tree->TypeGet() == TYP_FLOAT)
2870                 {
2871                     needFloatTmpForFPCall = true;
2872                 }
2873             }
2874 #endif // _TARGET_X86_
2875 #if defined(_TARGET_X86_) || defined(_TARGET_ARM_)
2876             if (tree->IsHelperCall())
2877             {
2878                 GenTreeCall*    call     = tree->AsCall();
2879                 CorInfoHelpFunc helpFunc = compiler->eeGetHelperNum(call->gtCallMethHnd);
2880                 killMask                 = compiler->compHelperCallKillSet(helpFunc);
2881             }
2882             else
2883 #endif // defined(_TARGET_X86_) || defined(_TARGET_ARM_)
2884             {
2885                 // if there is no FP used, we can ignore the FP kills
2886                 if (compiler->compFloatingPointUsed)
2887                 {
2888                     killMask = RBM_CALLEE_TRASH;
2889                 }
2890                 else
2891                 {
2892                     killMask = RBM_INT_CALLEE_TRASH;
2893                 }
2894 #ifdef _TARGET_ARM_
2895                 if (tree->AsCall()->IsVirtualStub())
2896                 {
2897                     killMask |= compiler->virtualStubParamInfo->GetRegMask();
2898                 }
2899 #else // !_TARGET_ARM_
2900             // Verify that the special virtual stub call registers are in the kill mask.
2901             // We don't just add them unconditionally to the killMask because for most architectures
2902             // they are already in the RBM_CALLEE_TRASH set,
2903             // and we don't want to introduce extra checks and calls in this hot function.
2904             assert(!tree->AsCall()->IsVirtualStub() || ((killMask & compiler->virtualStubParamInfo->GetRegMask()) ==
2905                                                         compiler->virtualStubParamInfo->GetRegMask()));
2906 #endif
2907             }
2908             break;
2909         case GT_STOREIND:
2910             if (compiler->codeGen->gcInfo.gcIsWriteBarrierAsgNode(tree))
2911             {
2912                 killMask = RBM_CALLEE_TRASH_NOGC;
2913             }
2914             break;
2915
2916 #if defined(PROFILING_SUPPORTED)
2917         // If this method requires profiler ELT hook then mark these nodes as killing
2918         // callee trash registers (excluding RAX and XMM0). The reason for this is that
2919         // profiler callback would trash these registers. See vm\amd64\asmhelpers.asm for
2920         // more details.
2921         case GT_RETURN:
2922             if (compiler->compIsProfilerHookNeeded())
2923             {
2924                 killMask = compiler->compHelperCallKillSet(CORINFO_HELP_PROF_FCN_LEAVE);
2925             }
2926             break;
2927
2928         case GT_PROF_HOOK:
2929             if (compiler->compIsProfilerHookNeeded())
2930             {
2931                 killMask = compiler->compHelperCallKillSet(CORINFO_HELP_PROF_FCN_TAILCALL);
2932             }
2933             break;
2934 #endif // PROFILING_SUPPORTED
2935
2936         default:
2937             // for all other 'tree->OperGet()' kinds, leave 'killMask' = RBM_NONE
2938             break;
2939     }
2940     return killMask;
2941 }
2942
2943 //------------------------------------------------------------------------
2944 // buildKillPositionsForNode:
2945 // Given some tree node add refpositions for all the registers this node kills
2946 //
2947 // Arguments:
2948 //    tree       - the tree for which kill positions should be generated
2949 //    currentLoc - the location at which the kills should be added
2950 //
2951 // Return Value:
2952 //    true       - kills were inserted
2953 //    false      - no kills were inserted
2954 //
2955 // Notes:
2956 //    The return value is needed because if we have any kills, we need to make sure that
2957 //    all defs are located AFTER the kills.  On the other hand, if there aren't kills,
2958 //    the multiple defs for a regPair are in different locations.
2959 //    If we generate any kills, we will mark all currentLiveVars as being preferenced
2960 //    to avoid the killed registers.  This is somewhat conservative.
2961
2962 bool LinearScan::buildKillPositionsForNode(GenTree* tree, LsraLocation currentLoc)
2963 {
2964     regMaskTP killMask   = getKillSetForNode(tree);
2965     bool      isCallKill = ((killMask == RBM_INT_CALLEE_TRASH) || (killMask == RBM_CALLEE_TRASH));
2966     if (killMask != RBM_NONE)
2967     {
2968         // The killMask identifies a set of registers that will be used during codegen.
2969         // Mark these as modified here, so when we do final frame layout, we'll know about
2970         // all these registers. This is especially important if killMask contains
2971         // callee-saved registers, which affect the frame size since we need to save/restore them.
2972         // In the case where we have a copyBlk with GC pointers, can need to call the
2973         // CORINFO_HELP_ASSIGN_BYREF helper, which kills callee-saved RSI and RDI, if
2974         // LSRA doesn't assign RSI/RDI, they wouldn't get marked as modified until codegen,
2975         // which is too late.
2976         compiler->codeGen->regSet.rsSetRegsModified(killMask DEBUGARG(dumpTerse));
2977
2978         addRefsForPhysRegMask(killMask, currentLoc, RefTypeKill, true);
2979
2980         // TODO-CQ: It appears to be valuable for both fp and int registers to avoid killing the callee
2981         // save regs on infrequently exectued paths.  However, it results in a large number of asmDiffs,
2982         // many of which appear to be regressions (because there is more spill on the infrequently path),
2983         // but are not really because the frequent path becomes smaller.  Validating these diffs will need
2984         // to be done before making this change.
2985         // if (!blockSequence[curBBSeqNum]->isRunRarely())
2986         if (enregisterLocalVars)
2987         {
2988             VarSetOps::Iter iter(compiler, currentLiveVars);
2989             unsigned        varIndex = 0;
2990             while (iter.NextElem(&varIndex))
2991             {
2992                 unsigned   varNum = compiler->lvaTrackedToVarNum[varIndex];
2993                 LclVarDsc* varDsc = compiler->lvaTable + varNum;
2994 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
2995                 if (varDsc->lvType == LargeVectorType)
2996                 {
2997                     if (!VarSetOps::IsMember(compiler, largeVectorCalleeSaveCandidateVars, varIndex))
2998                     {
2999                         continue;
3000                     }
3001                 }
3002                 else
3003 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
3004                     if (varTypeIsFloating(varDsc) &&
3005                         !VarSetOps::IsMember(compiler, fpCalleeSaveCandidateVars, varIndex))
3006                 {
3007                     continue;
3008                 }
3009                 Interval* interval = getIntervalForLocalVar(varIndex);
3010                 if (isCallKill)
3011                 {
3012                     interval->preferCalleeSave = true;
3013                 }
3014                 regMaskTP newPreferences = allRegs(interval->registerType) & (~killMask);
3015
3016                 if (newPreferences != RBM_NONE)
3017                 {
3018                     interval->updateRegisterPreferences(newPreferences);
3019                 }
3020                 else
3021                 {
3022                     // If there are no callee-saved registers, the call could kill all the registers.
3023                     // This is a valid state, so in that case assert should not trigger. The RA will spill in order to
3024                     // free a register later.
3025                     assert(compiler->opts.compDbgEnC || (calleeSaveRegs(varDsc->lvType)) == RBM_NONE);
3026                 }
3027             }
3028         }
3029
3030         if (tree->IsCall() && (tree->gtFlags & GTF_CALL_UNMANAGED) != 0)
3031         {
3032             RefPosition* pos = newRefPosition((Interval*)nullptr, currentLoc, RefTypeKillGCRefs, tree,
3033                                               (allRegs(TYP_REF) & ~RBM_ARG_REGS));
3034         }
3035         return true;
3036     }
3037
3038     return false;
3039 }
3040
3041 //----------------------------------------------------------------------------
3042 // defineNewInternalTemp: Defines a ref position for an internal temp.
3043 //
3044 // Arguments:
3045 //     tree                  -   Gentree node requiring an internal register
3046 //     regType               -   Register type
3047 //     currentLoc            -   Location of the temp Def position
3048 //     regMask               -   register mask of candidates for temp
3049 //     minRegCandidateCount  -   Minimum registers to be ensured in candidate
3050 //                               set under LSRA stress mode.  This is a
3051 //                               DEBUG only arg.
3052 RefPosition* LinearScan::defineNewInternalTemp(GenTree*     tree,
3053                                                RegisterType regType,
3054                                                LsraLocation currentLoc,
3055                                                regMaskTP regMask DEBUGARG(unsigned minRegCandidateCount))
3056 {
3057     Interval* current   = newInterval(regType);
3058     current->isInternal = true;
3059     return newRefPosition(current, currentLoc, RefTypeDef, tree, regMask, 0 DEBUG_ARG(minRegCandidateCount));
3060 }
3061
3062 //------------------------------------------------------------------------
3063 // buildInternalRegisterDefsForNode - build Def positions for internal
3064 // registers required for tree node.
3065 //
3066 // Arguments:
3067 //   tree                  -   Gentree node that needs internal registers
3068 //   currentLoc            -   Location at which Def positions need to be defined
3069 //   temps                 -   in-out array which is populated with ref positions
3070 //                             created for Def of internal registers
3071 //   minRegCandidateCount  -   Minimum registers to be ensured in candidate
3072 //                             set of ref positions under LSRA stress.  This is
3073 //                             a DEBUG only arg.
3074 //
3075 // Returns:
3076 //   The total number of Def positions created for internal registers of tree node.
3077 int LinearScan::buildInternalRegisterDefsForNode(GenTree*     tree,
3078                                                  LsraLocation currentLoc,
3079                                                  RefPosition* temps[] // populates
3080                                                  DEBUGARG(unsigned minRegCandidateCount))
3081 {
3082     int       count;
3083     int       internalIntCount = tree->gtLsraInfo.internalIntCount;
3084     regMaskTP internalCands    = tree->gtLsraInfo.getInternalCandidates(this);
3085
3086     // If the number of internal integer registers required is the same as the number of candidate integer registers in
3087     // the candidate set, then they must be handled as fixed registers.
3088     // (E.g. for the integer registers that floating point arguments must be copied into for a varargs call.)
3089     bool      fixedRegs             = false;
3090     regMaskTP internalIntCandidates = (internalCands & allRegs(TYP_INT));
3091     if (((int)genCountBits(internalIntCandidates)) == internalIntCount)
3092     {
3093         fixedRegs = true;
3094     }
3095
3096     for (count = 0; count < internalIntCount; count++)
3097     {
3098         regMaskTP internalIntCands = (internalCands & allRegs(TYP_INT));
3099         if (fixedRegs)
3100         {
3101             internalIntCands = genFindLowestBit(internalIntCands);
3102             internalCands &= ~internalIntCands;
3103         }
3104         temps[count] =
3105             defineNewInternalTemp(tree, IntRegisterType, currentLoc, internalIntCands DEBUG_ARG(minRegCandidateCount));
3106     }
3107
3108     int internalFloatCount = tree->gtLsraInfo.internalFloatCount;
3109     for (int i = 0; i < internalFloatCount; i++)
3110     {
3111         regMaskTP internalFPCands = (internalCands & internalFloatRegCandidates());
3112         temps[count++] =
3113             defineNewInternalTemp(tree, FloatRegisterType, currentLoc, internalFPCands DEBUG_ARG(minRegCandidateCount));
3114     }
3115
3116     assert(count < MaxInternalRegisters);
3117     assert(count == (internalIntCount + internalFloatCount));
3118     return count;
3119 }
3120
3121 //------------------------------------------------------------------------
3122 // buildInternalRegisterUsesForNode - adds Use positions for internal
3123 // registers required for tree node.
3124 //
3125 // Arguments:
3126 //   tree                  -   Gentree node that needs internal registers
3127 //   currentLoc            -   Location at which Use positions need to be defined
3128 //   defs                  -   int array containing Def positions of internal
3129 //                             registers.
3130 //   total                 -   Total number of Def positions in 'defs' array.
3131 //   minRegCandidateCount  -   Minimum registers to be ensured in candidate
3132 //                             set of ref positions under LSRA stress.  This is
3133 //                             a DEBUG only arg.
3134 //
3135 // Returns:
3136 //   Void.
3137 void LinearScan::buildInternalRegisterUsesForNode(GenTree*     tree,
3138                                                   LsraLocation currentLoc,
3139                                                   RefPosition* defs[],
3140                                                   int total DEBUGARG(unsigned minRegCandidateCount))
3141 {
3142     assert(total < MaxInternalRegisters);
3143
3144     // defs[] has been populated by buildInternalRegisterDefsForNode
3145     // now just add uses to the defs previously added.
3146     for (int i = 0; i < total; i++)
3147     {
3148         RefPosition* prevRefPosition = defs[i];
3149         assert(prevRefPosition != nullptr);
3150         regMaskTP mask = prevRefPosition->registerAssignment;
3151         if (prevRefPosition->isPhysRegRef)
3152         {
3153             newRefPosition(defs[i]->getReg()->regNum, currentLoc, RefTypeUse, tree, mask);
3154         }
3155         else
3156         {
3157             RefPosition* newest = newRefPosition(defs[i]->getInterval(), currentLoc, RefTypeUse, tree, mask,
3158                                                  0 DEBUG_ARG(minRegCandidateCount));
3159
3160             if (tree->gtLsraInfo.isInternalRegDelayFree)
3161             {
3162                 newest->delayRegFree = true;
3163             }
3164         }
3165     }
3166 }
3167
3168 regMaskTP LinearScan::getUseCandidates(GenTree* useNode)
3169 {
3170     TreeNodeInfo info = useNode->gtLsraInfo;
3171     return info.getSrcCandidates(this);
3172 }
3173
3174 regMaskTP LinearScan::getDefCandidates(GenTree* tree)
3175 {
3176     TreeNodeInfo info = tree->gtLsraInfo;
3177     return info.getDstCandidates(this);
3178 }
3179
3180 RegisterType LinearScan::getDefType(GenTree* tree)
3181 {
3182     return tree->TypeGet();
3183 }
3184
3185 //------------------------------------------------------------------------
3186 // LocationInfoListNode: used to store a single `LocationInfo` value for a
3187 //                       node during `buildIntervals`.
3188 //
3189 // This is the node type for `LocationInfoList` below.
3190 //
3191 class LocationInfoListNode final : public LocationInfo
3192 {
3193     friend class LocationInfoList;
3194     friend class LocationInfoListNodePool;
3195
3196     LocationInfoListNode* m_next; // The next node in the list
3197
3198 public:
3199     LocationInfoListNode(LsraLocation l, Interval* i, GenTree* t, unsigned regIdx = 0) : LocationInfo(l, i, t, regIdx)
3200     {
3201     }
3202
3203     //------------------------------------------------------------------------
3204     // LocationInfoListNode::Next: Returns the next node in the list.
3205     LocationInfoListNode* Next() const
3206     {
3207         return m_next;
3208     }
3209 };
3210
3211 //------------------------------------------------------------------------
3212 // LocationInfoList: used to store a list of `LocationInfo` values for a
3213 //                   node during `buildIntervals`.
3214 //
3215 // Given an IR node that either directly defines N registers or that is a
3216 // contained node with uses that define a total of N registers, that node
3217 // will map to N `LocationInfo` values. These values are stored as a
3218 // linked list of `LocationInfoListNode` values.
3219 //
3220 class LocationInfoList final
3221 {
3222     friend class LocationInfoListNodePool;
3223
3224     LocationInfoListNode* m_head; // The head of the list
3225     LocationInfoListNode* m_tail; // The tail of the list
3226
3227 public:
3228     LocationInfoList() : m_head(nullptr), m_tail(nullptr)
3229     {
3230     }
3231
3232     LocationInfoList(LocationInfoListNode* node) : m_head(node), m_tail(node)
3233     {
3234         assert(m_head->m_next == nullptr);
3235     }
3236
3237     //------------------------------------------------------------------------
3238     // LocationInfoList::IsEmpty: Returns true if the list is empty.
3239     //
3240     bool IsEmpty() const
3241     {
3242         return m_head == nullptr;
3243     }
3244
3245     //------------------------------------------------------------------------
3246     // LocationInfoList::Begin: Returns the first node in the list.
3247     //
3248     LocationInfoListNode* Begin() const
3249     {
3250         return m_head;
3251     }
3252
3253     //------------------------------------------------------------------------
3254     // LocationInfoList::End: Returns the position after the last node in the
3255     //                        list. The returned value is suitable for use as
3256     //                        a sentinel for iteration.
3257     //
3258     LocationInfoListNode* End() const
3259     {
3260         return nullptr;
3261     }
3262
3263     //------------------------------------------------------------------------
3264     // LocationInfoList::Append: Appends a node to the list.
3265     //
3266     // Arguments:
3267     //    node - The node to append. Must not be part of an existing list.
3268     //
3269     void Append(LocationInfoListNode* node)
3270     {
3271         assert(node->m_next == nullptr);
3272
3273         if (m_tail == nullptr)
3274         {
3275             assert(m_head == nullptr);
3276             m_head = node;
3277         }
3278         else
3279         {
3280             m_tail->m_next = node;
3281         }
3282
3283         m_tail = node;
3284     }
3285
3286     //------------------------------------------------------------------------
3287     // LocationInfoList::Append: Appends another list to this list.
3288     //
3289     // Arguments:
3290     //    other - The list to append.
3291     //
3292     void Append(LocationInfoList other)
3293     {
3294         if (m_tail == nullptr)
3295         {
3296             assert(m_head == nullptr);
3297             m_head = other.m_head;
3298         }
3299         else
3300         {
3301             m_tail->m_next = other.m_head;
3302         }
3303
3304         m_tail = other.m_tail;
3305     }
3306 };
3307
3308 //------------------------------------------------------------------------
3309 // LocationInfoListNodePool: manages a pool of `LocationInfoListNode`
3310 //                           values to decrease overall memory usage
3311 //                           during `buildIntervals`.
3312 //
3313 // `buildIntervals` involves creating a list of location info values per
3314 // node that either directly produces a set of registers or that is a
3315 // contained node with register-producing sources. However, these lists
3316 // are short-lived: they are destroyed once the use of the corresponding
3317 // node is processed. As such, there is typically only a small number of
3318 // `LocationInfoListNode` values in use at any given time. Pooling these
3319 // values avoids otherwise frequent allocations.
3320 class LocationInfoListNodePool final
3321 {
3322     LocationInfoListNode* m_freeList;
3323     Compiler*             m_compiler;
3324
3325 public:
3326     //------------------------------------------------------------------------
3327     // LocationInfoListNodePool::LocationInfoListNodePool:
3328     //    Creates a pool of `LocationInfoListNode` values.
3329     //
3330     // Arguments:
3331     //    compiler    - The compiler context.
3332     //    preallocate - The number of nodes to preallocate.
3333     //
3334     LocationInfoListNodePool(Compiler* compiler, unsigned preallocate = 0) : m_compiler(compiler)
3335     {
3336         if (preallocate > 0)
3337         {
3338             size_t preallocateSize   = sizeof(LocationInfoListNode) * preallocate;
3339             auto*  preallocatedNodes = reinterpret_cast<LocationInfoListNode*>(compiler->compGetMem(preallocateSize));
3340
3341             LocationInfoListNode* head = preallocatedNodes;
3342             head->m_next               = nullptr;
3343
3344             for (unsigned i = 1; i < preallocate; i++)
3345             {
3346                 LocationInfoListNode* node = &preallocatedNodes[i];
3347                 node->m_next               = head;
3348                 head                       = node;
3349             }
3350
3351             m_freeList = head;
3352         }
3353     }
3354
3355     //------------------------------------------------------------------------
3356     // LocationInfoListNodePool::GetNode: Fetches an unused node from the
3357     //                                    pool.
3358     //
3359     // Arguments:
3360     //    l -    - The `LsraLocation` for the `LocationInfo` value.
3361     //    i      - The interval for the `LocationInfo` value.
3362     //    t      - The IR node for the `LocationInfo` value
3363     //    regIdx - The register index for the `LocationInfo` value.
3364     //
3365     // Returns:
3366     //    A pooled or newly-allocated `LocationInfoListNode`, depending on the
3367     //    contents of the pool.
3368     LocationInfoListNode* GetNode(LsraLocation l, Interval* i, GenTree* t, unsigned regIdx = 0)
3369     {
3370         LocationInfoListNode* head = m_freeList;
3371         if (head == nullptr)
3372         {
3373             head = reinterpret_cast<LocationInfoListNode*>(m_compiler->compGetMem(sizeof(LocationInfoListNode)));
3374         }
3375         else
3376         {
3377             m_freeList = head->m_next;
3378         }
3379
3380         head->loc         = l;
3381         head->interval    = i;
3382         head->treeNode    = t;
3383         head->multiRegIdx = regIdx;
3384         head->m_next      = nullptr;
3385
3386         return head;
3387     }
3388
3389     //------------------------------------------------------------------------
3390     // LocationInfoListNodePool::ReturnNodes: Returns a list of nodes to the
3391     //                                        pool.
3392     //
3393     // Arguments:
3394     //    list - The list to return.
3395     //
3396     void ReturnNodes(LocationInfoList& list)
3397     {
3398         assert(list.m_head != nullptr);
3399         assert(list.m_tail != nullptr);
3400
3401         LocationInfoListNode* head = m_freeList;
3402         list.m_tail->m_next        = head;
3403         m_freeList                 = list.m_head;
3404     }
3405 };
3406
3407 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
3408 VARSET_VALRET_TP
3409 LinearScan::buildUpperVectorSaveRefPositions(GenTree* tree, LsraLocation currentLoc)
3410 {
3411     assert(enregisterLocalVars);
3412     VARSET_TP liveLargeVectors(VarSetOps::MakeEmpty(compiler));
3413     regMaskTP fpCalleeKillSet = RBM_NONE;
3414     if (!VarSetOps::IsEmpty(compiler, largeVectorVars))
3415     {
3416         // We actually need to find any calls that kill the upper-half of the callee-save vector registers.
3417         // But we will use as a proxy any node that kills floating point registers.
3418         // (Note that some calls are masquerading as other nodes at this point so we can't just check for calls.)
3419         fpCalleeKillSet = getKillSetForNode(tree);
3420         if ((fpCalleeKillSet & RBM_FLT_CALLEE_TRASH) != RBM_NONE)
3421         {
3422             VarSetOps::AssignNoCopy(compiler, liveLargeVectors,
3423                                     VarSetOps::Intersection(compiler, currentLiveVars, largeVectorVars));
3424             VarSetOps::Iter iter(compiler, liveLargeVectors);
3425             unsigned        varIndex = 0;
3426             while (iter.NextElem(&varIndex))
3427             {
3428                 Interval* varInterval    = getIntervalForLocalVar(varIndex);
3429                 Interval* tempInterval   = newInterval(LargeVectorType);
3430                 tempInterval->isInternal = true;
3431                 RefPosition* pos =
3432                     newRefPosition(tempInterval, currentLoc, RefTypeUpperVectorSaveDef, tree, RBM_FLT_CALLEE_SAVED);
3433                 // We are going to save the existing relatedInterval of varInterval on tempInterval, so that we can set
3434                 // the tempInterval as the relatedInterval of varInterval, so that we can build the corresponding
3435                 // RefTypeUpperVectorSaveUse RefPosition.  We will then restore the relatedInterval onto varInterval,
3436                 // and set varInterval as the relatedInterval of tempInterval.
3437                 tempInterval->relatedInterval = varInterval->relatedInterval;
3438                 varInterval->relatedInterval  = tempInterval;
3439             }
3440         }
3441     }
3442     return liveLargeVectors;
3443 }
3444
3445 void LinearScan::buildUpperVectorRestoreRefPositions(GenTree*         tree,
3446                                                      LsraLocation     currentLoc,
3447                                                      VARSET_VALARG_TP liveLargeVectors)
3448 {
3449     assert(enregisterLocalVars);
3450     if (!VarSetOps::IsEmpty(compiler, liveLargeVectors))
3451     {
3452         VarSetOps::Iter iter(compiler, liveLargeVectors);
3453         unsigned        varIndex = 0;
3454         while (iter.NextElem(&varIndex))
3455         {
3456             Interval* varInterval  = getIntervalForLocalVar(varIndex);
3457             Interval* tempInterval = varInterval->relatedInterval;
3458             assert(tempInterval->isInternal == true);
3459             RefPosition* pos =
3460                 newRefPosition(tempInterval, currentLoc, RefTypeUpperVectorSaveUse, tree, RBM_FLT_CALLEE_SAVED);
3461             // Restore the relatedInterval onto varInterval, and set varInterval as the relatedInterval
3462             // of tempInterval.
3463             varInterval->relatedInterval  = tempInterval->relatedInterval;
3464             tempInterval->relatedInterval = varInterval;
3465         }
3466     }
3467 }
3468 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
3469
3470 #ifdef DEBUG
3471 //------------------------------------------------------------------------
3472 // ComputeOperandDstCount: computes the number of registers defined by a
3473 //                         node.
3474 //
3475 // For most nodes, this is simple:
3476 // - Nodes that do not produce values (e.g. stores and other void-typed
3477 //   nodes) and nodes that immediately use the registers they define
3478 //   produce no registers
3479 // - Nodes that are marked as defining N registers define N registers.
3480 //
3481 // For contained nodes, however, things are more complicated: for purposes
3482 // of bookkeeping, a contained node is treated as producing the transitive
3483 // closure of the registers produced by its sources.
3484 //
3485 // Arguments:
3486 //    operand - The operand for which to compute a register count.
3487 //
3488 // Returns:
3489 //    The number of registers defined by `operand`.
3490 //
3491 static int ComputeOperandDstCount(GenTree* operand)
3492 {
3493     TreeNodeInfo& operandInfo = operand->gtLsraInfo;
3494
3495     if (operandInfo.isLocalDefUse)
3496     {
3497         // Operands that define an unused value do not produce any registers.
3498         return 0;
3499     }
3500     else if (operandInfo.dstCount != 0)
3501     {
3502         // Operands that have a specified number of destination registers consume all of their operands
3503         // and therefore produce exactly that number of registers.
3504         return operandInfo.dstCount;
3505     }
3506     else if (operandInfo.srcCount != 0)
3507     {
3508         // If an operand has no destination registers but does have source registers, it must be a store
3509         // or a compare.
3510         assert(operand->OperIsStore() || operand->OperIsBlkOp() || operand->OperIsPutArgStk() ||
3511                operand->OperIsCompare() || operand->OperIs(GT_CMP) || operand->IsSIMDEqualityOrInequality());
3512         return 0;
3513     }
3514     else if (!operand->OperIsFieldListHead() && (operand->OperIsStore() || operand->TypeGet() == TYP_VOID))
3515     {
3516         // Stores and void-typed operands may be encountered when processing call nodes, which contain
3517         // pointers to argument setup stores.
3518         return 0;
3519     }
3520     else
3521     {
3522         // If a field list or non-void-typed operand is not an unused value and does not have source registers,
3523         // that argument is contained within its parent and produces `sum(operand_dst_count)` registers.
3524         int dstCount = 0;
3525         for (GenTree* op : operand->Operands())
3526         {
3527             dstCount += ComputeOperandDstCount(op);
3528         }
3529
3530         return dstCount;
3531     }
3532 }
3533
3534 //------------------------------------------------------------------------
3535 // ComputeAvailableSrcCount: computes the number of registers available as
3536 //                           sources for a node.
3537 //
3538 // This is simply the sum of the number of registers produced by each
3539 // operand to the node.
3540 //
3541 // Arguments:
3542 //    node - The node for which to compute a source count.
3543 //
3544 // Retures:
3545 //    The number of registers available as sources for `node`.
3546 //
3547 static int ComputeAvailableSrcCount(GenTree* node)
3548 {
3549     int numSources = 0;
3550     for (GenTree* operand : node->Operands())
3551     {
3552         numSources += ComputeOperandDstCount(operand);
3553     }
3554
3555     return numSources;
3556 }
3557 #endif // DEBUG
3558
3559 static GenTree* GetFirstOperand(GenTree* node)
3560 {
3561     GenTree* firstOperand = nullptr;
3562     node->VisitOperands([&firstOperand](GenTree* operand) -> GenTree::VisitResult {
3563         firstOperand = operand;
3564         return GenTree::VisitResult::Abort;
3565     });
3566     return firstOperand;
3567 }
3568
3569 void LinearScan::buildRefPositionsForNode(GenTree*                  tree,
3570                                           BasicBlock*               block,
3571                                           LocationInfoListNodePool& listNodePool,
3572                                           HashTableBase<GenTree*, LocationInfoList>& operandToLocationInfoMap,
3573                                           LsraLocation currentLoc)
3574 {
3575 #ifdef _TARGET_ARM_
3576     assert(!isRegPairType(tree->TypeGet()));
3577 #endif // _TARGET_ARM_
3578
3579     // The LIR traversal doesn't visit GT_LIST or GT_ARGPLACE nodes.
3580     // GT_CLS_VAR nodes should have been eliminated by rationalizer.
3581     assert(tree->OperGet() != GT_ARGPLACE);
3582     assert(tree->OperGet() != GT_LIST);
3583     assert(tree->OperGet() != GT_CLS_VAR);
3584
3585     // The LIR traversal visits only the first node in a GT_FIELD_LIST.
3586     assert((tree->OperGet() != GT_FIELD_LIST) || tree->AsFieldList()->IsFieldListHead());
3587
3588     // The set of internal temporary registers used by this node are stored in the
3589     // gtRsvdRegs register mask. Clear it out.
3590     tree->gtRsvdRegs = RBM_NONE;
3591
3592     TreeNodeInfo info = tree->gtLsraInfo;
3593     assert(info.IsValid(this));
3594     int consume = info.srcCount;
3595     int produce = info.dstCount;
3596
3597 #ifdef DEBUG
3598     if (VERBOSE)
3599     {
3600         lsraDispNode(tree, LSRA_DUMP_REFPOS, (produce != 0));
3601         JITDUMP("\n");
3602         if (tree->isContained())
3603         {
3604             JITDUMP("Contained\n");
3605         }
3606         else if (tree->OperIs(GT_LCL_VAR, GT_LCL_FLD) && info.isLocalDefUse)
3607         {
3608             JITDUMP("Unused\n");
3609         }
3610         else
3611         {
3612             JITDUMP("  consume=%d produce=%d\n", consume, produce);
3613         }
3614
3615         if (consume != 0)
3616         {
3617             JITDUMP("at start of tree, map contains: { ");
3618             bool first = true;
3619             for (auto kvp : operandToLocationInfoMap)
3620             {
3621                 GenTree*         node    = kvp.Key();
3622                 LocationInfoList defList = kvp.Value();
3623
3624                 JITDUMP("%sN%03u. %s -> (", first ? "" : "; ", node->gtSeqNum, GenTree::OpName(node->OperGet()));
3625                 for (LocationInfoListNode *def = defList.Begin(), *end = defList.End(); def != end; def = def->Next())
3626                 {
3627                     JITDUMP("%s%d.N%03u", def == defList.Begin() ? "" : ", ", def->loc, def->treeNode->gtSeqNum);
3628                 }
3629                 JITDUMP(")");
3630
3631                 first = false;
3632             }
3633             JITDUMP(" }\n");
3634         }
3635     }
3636 #endif // DEBUG
3637
3638     assert(((consume == 0) && (produce == 0)) || (ComputeAvailableSrcCount(tree) == consume));
3639
3640     if (tree->OperIs(GT_LCL_VAR, GT_LCL_FLD))
3641     {
3642         LclVarDsc* const varDsc = &compiler->lvaTable[tree->AsLclVarCommon()->gtLclNum];
3643         if (isCandidateVar(varDsc))
3644         {
3645             assert(consume == 0);
3646
3647             // We handle tracked variables differently from non-tracked ones.  If it is tracked,
3648             // we simply add a use or def of the tracked variable.  Otherwise, for a use we need
3649             // to actually add the appropriate references for loading or storing the variable.
3650             //
3651             // It won't actually get used or defined until the appropriate ancestor tree node
3652             // is processed, unless this is marked "isLocalDefUse" because it is a stack-based argument
3653             // to a call
3654
3655             assert(varDsc->lvTracked);
3656             unsigned varIndex = varDsc->lvVarIndex;
3657
3658             // We have only approximate last-use information at this point.  This is because the
3659             // execution order doesn't actually reflect the true order in which the localVars
3660             // are referenced - but the order of the RefPositions will, so we recompute it after
3661             // RefPositions are built.
3662             // Use the old value for setting currentLiveVars - note that we do this with the
3663             // not-quite-correct setting of lastUse.  However, this is OK because
3664             // 1) this is only for preferencing, which doesn't require strict correctness, and
3665             // 2) the cases where these out-of-order uses occur should not overlap a kill.
3666             // TODO-Throughput: clean this up once we have the execution order correct.  At that point
3667             // we can update currentLiveVars at the same place that we create the RefPosition.
3668             if ((tree->gtFlags & GTF_VAR_DEATH) != 0)
3669             {
3670                 VarSetOps::RemoveElemD(compiler, currentLiveVars, varIndex);
3671             }
3672
3673             if (!info.isLocalDefUse && !tree->isContained())
3674             {
3675                 assert(produce != 0);
3676
3677                 LocationInfoList list(listNodePool.GetNode(currentLoc, getIntervalForLocalVar(varIndex), tree));
3678                 bool             added = operandToLocationInfoMap.AddOrUpdate(tree, list);
3679                 assert(added);
3680
3681                 tree->gtLsraInfo.definesAnyRegisters = true;
3682             }
3683             return;
3684         }
3685     }
3686
3687     if (tree->isContained())
3688     {
3689         assert(!info.isLocalDefUse);
3690         assert(consume == 0);
3691         assert(produce == 0);
3692         assert(info.internalIntCount == 0);
3693         assert(info.internalFloatCount == 0);
3694
3695         // Contained nodes map to the concatenated lists of their operands.
3696         LocationInfoList locationInfoList;
3697         tree->VisitOperands([&](GenTree* op) -> GenTree::VisitResult {
3698             if (!op->gtLsraInfo.definesAnyRegisters)
3699             {
3700                 assert(ComputeOperandDstCount(op) == 0);
3701                 return GenTree::VisitResult::Continue;
3702             }
3703
3704             LocationInfoList operandList;
3705             bool             removed = operandToLocationInfoMap.TryRemove(op, &operandList);
3706             assert(removed);
3707
3708             locationInfoList.Append(operandList);
3709             return GenTree::VisitResult::Continue;
3710         });
3711
3712         if (!locationInfoList.IsEmpty())
3713         {
3714             bool added = operandToLocationInfoMap.AddOrUpdate(tree, locationInfoList);
3715             assert(added);
3716             tree->gtLsraInfo.definesAnyRegisters = true;
3717         }
3718         JITDUMP("\n");
3719         return;
3720     }
3721
3722     // Handle the case of local variable assignment
3723     Interval* varDefInterval = nullptr;
3724     RefType   defRefType     = RefTypeDef;
3725
3726     GenTree* defNode = tree;
3727
3728     // noAdd means the node creates a def but for purposes of map
3729     // management do not add it because data is not flowing up the
3730     // tree but over (as in ASG nodes)
3731
3732     bool         noAdd   = info.isLocalDefUse;
3733     RefPosition* prevPos = nullptr;
3734
3735     bool isSpecialPutArg = false;
3736
3737     assert(!tree->OperIsAssignment());
3738     if (tree->OperIsLocalStore())
3739     {
3740         GenTreeLclVarCommon* const store = tree->AsLclVarCommon();
3741         assert((consume > 1) || (regType(store->gtOp1->TypeGet()) == regType(store->TypeGet())));
3742
3743         LclVarDsc* varDsc = &compiler->lvaTable[store->gtLclNum];
3744         if (isCandidateVar(varDsc))
3745         {
3746             // We always push the tracked lclVar intervals
3747             assert(varDsc->lvTracked);
3748             unsigned varIndex = varDsc->lvVarIndex;
3749             varDefInterval    = getIntervalForLocalVar(varIndex);
3750             defRefType        = refTypeForLocalRefNode(tree);
3751             defNode           = tree;
3752             if (produce == 0)
3753             {
3754                 produce = 1;
3755                 noAdd   = true;
3756             }
3757
3758             assert(consume <= MAX_RET_REG_COUNT);
3759             if (consume == 1)
3760             {
3761                 // Get the location info for the register defined by the first operand.
3762                 LocationInfoList operandDefs;
3763                 bool             found = operandToLocationInfoMap.TryGetValue(GetFirstOperand(tree), &operandDefs);
3764                 assert(found);
3765
3766                 // Since we only expect to consume one register, we should only have a single register to
3767                 // consume.
3768                 assert(operandDefs.Begin()->Next() == operandDefs.End());
3769
3770                 LocationInfo& operandInfo = *static_cast<LocationInfo*>(operandDefs.Begin());
3771
3772                 Interval* srcInterval = operandInfo.interval;
3773                 if (srcInterval->relatedInterval == nullptr)
3774                 {
3775                     // Preference the source to the dest, unless this is a non-last-use localVar.
3776                     // Note that the last-use info is not correct, but it is a better approximation than preferencing
3777                     // the source to the dest, if the source's lifetime extends beyond the dest.
3778                     if (!srcInterval->isLocalVar || (operandInfo.treeNode->gtFlags & GTF_VAR_DEATH) != 0)
3779                     {
3780                         srcInterval->assignRelatedInterval(varDefInterval);
3781                     }
3782                 }
3783                 else if (!srcInterval->isLocalVar)
3784                 {
3785                     // Preference the source to dest, if src is not a local var.
3786                     srcInterval->assignRelatedInterval(varDefInterval);
3787                 }
3788             }
3789
3790             if ((tree->gtFlags & GTF_VAR_DEATH) == 0)
3791             {
3792                 VarSetOps::AddElemD(compiler, currentLiveVars, varIndex);
3793             }
3794         }
3795         else if (store->gtOp1->OperIs(GT_BITCAST))
3796         {
3797             store->gtType = store->gtOp1->gtType = store->gtOp1->AsUnOp()->gtOp1->TypeGet();
3798
3799             // Get the location info for the register defined by the first operand.
3800             LocationInfoList operandDefs;
3801             bool             found = operandToLocationInfoMap.TryGetValue(GetFirstOperand(store), &operandDefs);
3802             assert(found);
3803
3804             // Since we only expect to consume one register, we should only have a single register to consume.
3805             assert(operandDefs.Begin()->Next() == operandDefs.End());
3806
3807             LocationInfo& operandInfo = *static_cast<LocationInfo*>(operandDefs.Begin());
3808
3809             Interval* srcInterval     = operandInfo.interval;
3810             srcInterval->registerType = regType(store->TypeGet());
3811
3812             RefPosition* srcDefPosition = srcInterval->firstRefPosition;
3813             assert(srcDefPosition != nullptr);
3814             assert(srcDefPosition->refType == RefTypeDef);
3815             assert(srcDefPosition->treeNode == store->gtOp1);
3816
3817             srcDefPosition->registerAssignment = allRegs(store->TypeGet());
3818             store->gtOp1->gtLsraInfo.setSrcCandidates(this, allRegs(store->TypeGet()));
3819         }
3820     }
3821     else if (noAdd && produce == 0)
3822     {
3823         // This is the case for dead nodes that occur after
3824         // tree rationalization
3825         // TODO-Cleanup: Identify and remove these dead nodes prior to register allocation.
3826         if (tree->IsMultiRegCall())
3827         {
3828             // In case of multi-reg call node, produce = number of return registers
3829             produce = tree->AsCall()->GetReturnTypeDesc()->GetReturnRegCount();
3830         }
3831         else
3832         {
3833             produce = 1;
3834         }
3835     }
3836
3837     Interval* prefSrcInterval = nullptr;
3838
3839     // If this is a binary operator that will be encoded with 2 operand fields
3840     // (i.e. the target is read-modify-write), preference the dst to op1.
3841
3842     bool hasDelayFreeSrc = tree->gtLsraInfo.hasDelayFreeSrc;
3843
3844 #if defined(DEBUG) && defined(_TARGET_X86_)
3845     // On x86, `LSRA_LIMIT_CALLER` is too restrictive to allow the use of special put args: this stress mode
3846     // leaves only three registers allocatable--eax, ecx, and edx--of which the latter two are also used for the
3847     // first two integral arguments to a call. This can leave us with too few registers to succesfully allocate in
3848     // situations like the following:
3849     //
3850     //     t1026 =    lclVar    ref    V52 tmp35        u:3 REG NA <l:$3a1, c:$98d>
3851     //
3852     //             /--*  t1026  ref
3853     //     t1352 = *  putarg_reg ref    REG NA
3854     //
3855     //      t342 =    lclVar    int    V14 loc6         u:4 REG NA $50c
3856     //
3857     //      t343 =    const     int    1 REG NA $41
3858     //
3859     //             /--*  t342   int
3860     //             +--*  t343   int
3861     //      t344 = *  +         int    REG NA $495
3862     //
3863     //      t345 =    lclVar    int    V04 arg4         u:2 REG NA $100
3864     //
3865     //             /--*  t344   int
3866     //             +--*  t345   int
3867     //      t346 = *  %         int    REG NA $496
3868     //
3869     //             /--*  t346   int
3870     //     t1353 = *  putarg_reg int    REG NA
3871     //
3872     //     t1354 =    lclVar    ref    V52 tmp35         (last use) REG NA
3873     //
3874     //             /--*  t1354  ref
3875     //     t1355 = *  lea(b+0)  byref  REG NA
3876     //
3877     // Here, the first `putarg_reg` would normally be considered a special put arg, which would remove `ecx` from the
3878     // set of allocatable registers, leaving only `eax` and `edx`. The allocator will then fail to allocate a register
3879     // for the def of `t345` if arg4 is not a register candidate: the corresponding ref position will be constrained to
3880     // { `ecx`, `ebx`, `esi`, `edi` }, which `LSRA_LIMIT_CALLER` will further constrain to `ecx`, which will not be
3881     // available due to the special put arg.
3882     const bool supportsSpecialPutArg = getStressLimitRegs() != LSRA_LIMIT_CALLER;
3883 #else
3884     const bool supportsSpecialPutArg = true;
3885 #endif
3886
3887     if (supportsSpecialPutArg && tree->OperGet() == GT_PUTARG_REG && isCandidateLocalRef(tree->gtGetOp1()) &&
3888         (tree->gtGetOp1()->gtFlags & GTF_VAR_DEATH) == 0)
3889     {
3890         // This is the case for a "pass-through" copy of a lclVar.  In the case where it is a non-last-use,
3891         // we don't want the def of the copy to kill the lclVar register, if it is assigned the same register
3892         // (which is actually what we hope will happen).
3893         JITDUMP("Setting putarg_reg as a pass-through of a non-last use lclVar\n");
3894
3895         // Get the register information for the first operand of the node.
3896         LocationInfoList operandDefs;
3897         bool             found = operandToLocationInfoMap.TryGetValue(GetFirstOperand(tree), &operandDefs);
3898         assert(found);
3899
3900         // Preference the destination to the interval of the first register defined by the first operand.
3901         Interval* srcInterval = operandDefs.Begin()->interval;
3902         assert(srcInterval->isLocalVar);
3903         prefSrcInterval = srcInterval;
3904         isSpecialPutArg = true;
3905     }
3906
3907     RefPosition* internalRefs[MaxInternalRegisters];
3908
3909 #ifdef DEBUG
3910     // Number of registers required for tree node is the sum of
3911     // consume + produce + internalCount.  This is the minimum
3912     // set of registers that needs to be ensured in candidate
3913     // set of ref positions created.
3914     unsigned minRegCount = consume + produce + info.internalIntCount + info.internalFloatCount;
3915 #endif // DEBUG
3916
3917     // make intervals for all the 'internal' register requirements for this node
3918     // where internal means additional registers required temporarily
3919     int internalCount = buildInternalRegisterDefsForNode(tree, currentLoc, internalRefs DEBUG_ARG(minRegCount));
3920
3921     // pop all ref'd tree temps
3922     tree->VisitOperands([&](GenTree* operand) -> GenTree::VisitResult {
3923         // Skip operands that do not define any registers, whether directly or indirectly.
3924         if (!operand->gtLsraInfo.definesAnyRegisters)
3925         {
3926             return GenTree::VisitResult::Continue;
3927         }
3928
3929         // Remove the list of registers defined by the current operand from the map. Note that this
3930         // is only correct because tree nodes are singly-used: if this property ever changes (e.g.
3931         // if tree nodes are eventually allowed to be multiply-used), then the removal is only
3932         // correct at the last use.
3933         LocationInfoList operandDefs;
3934         bool             removed = operandToLocationInfoMap.TryRemove(operand, &operandDefs);
3935         assert(removed);
3936         assert(!operandDefs.IsEmpty());
3937
3938         LocationInfoListNode* const operandDefsEnd = operandDefs.End();
3939         for (LocationInfoListNode* operandDefsIterator = operandDefs.Begin(); operandDefsIterator != operandDefsEnd;
3940              operandDefsIterator                       = operandDefsIterator->Next())
3941         {
3942             LocationInfo& locInfo = *static_cast<LocationInfo*>(operandDefsIterator);
3943
3944             // for interstitial tree temps, a use is always last and end; this is set by default in newRefPosition
3945             GenTree* const useNode = locInfo.treeNode;
3946             assert(useNode != nullptr);
3947
3948             Interval* const i = locInfo.interval;
3949             if (useNode->gtLsraInfo.isTgtPref)
3950             {
3951                 prefSrcInterval = i;
3952             }
3953
3954             const bool delayRegFree = (hasDelayFreeSrc && useNode->gtLsraInfo.isDelayFree);
3955
3956 #ifdef DEBUG
3957             // If delayRegFree, then Use will interfere with the destination of
3958             // the consuming node.  Therefore, we also need add the kill set of
3959             // consuming node to minRegCount.
3960             //
3961             // For example consider the following IR on x86, where v01 and v02
3962             // are method args coming in ecx and edx respectively.
3963             //   GT_DIV(v01, v02)
3964             //
3965             // For GT_DIV minRegCount will be 3 without adding kill set
3966             // of GT_DIV node.
3967             //
3968             // Assume further JitStressRegs=2, which would constrain
3969             // candidates to callee trashable regs { eax, ecx, edx } on
3970             // use positions of v01 and v02.  LSRA allocates ecx for v01.
3971             // Use position of v02 cannot be allocated a regs since it
3972             // is marked delay-reg free and {eax,edx} are getting killed
3973             // before the def of GT_DIV.  For this reason, minRegCount
3974             // for Use position of v02 also needs to take into account
3975             // of kill set of its consuming node.
3976             unsigned minRegCountForUsePos = minRegCount;
3977             if (delayRegFree)
3978             {
3979                 regMaskTP killMask = getKillSetForNode(tree);
3980                 if (killMask != RBM_NONE)
3981                 {
3982                     minRegCountForUsePos += genCountBits(killMask);
3983                 }
3984             }
3985 #endif // DEBUG
3986
3987             regMaskTP candidates = getUseCandidates(useNode);
3988             assert((candidates & allRegs(i->registerType)) != 0);
3989
3990             // For non-localVar uses we record nothing, as nothing needs to be written back to the tree.
3991             GenTree* const refPosNode = i->isLocalVar ? useNode : nullptr;
3992             RefPosition*   pos        = newRefPosition(i, currentLoc, RefTypeUse, refPosNode, candidates,
3993                                               locInfo.multiRegIdx DEBUG_ARG(minRegCountForUsePos));
3994
3995             if (delayRegFree)
3996             {
3997                 pos->delayRegFree = true;
3998             }
3999
4000             if (useNode->IsRegOptional())
4001             {
4002                 pos->setAllocateIfProfitable(true);
4003             }
4004         }
4005
4006         listNodePool.ReturnNodes(operandDefs);
4007
4008         return GenTree::VisitResult::Continue;
4009     });
4010
4011     buildInternalRegisterUsesForNode(tree, currentLoc, internalRefs, internalCount DEBUG_ARG(minRegCount));
4012
4013     RegisterType registerType  = getDefType(tree);
4014     regMaskTP    candidates    = getDefCandidates(tree);
4015     regMaskTP    useCandidates = getUseCandidates(tree);
4016
4017 #ifdef DEBUG
4018     if (VERBOSE && produce)
4019     {
4020         printf("Def candidates ");
4021         dumpRegMask(candidates);
4022         printf(", Use candidates ");
4023         dumpRegMask(useCandidates);
4024         printf("\n");
4025     }
4026 #endif // DEBUG
4027
4028 #if defined(_TARGET_AMD64_)
4029     // Multi-reg call node is the only node that could produce multi-reg value
4030     assert(produce <= 1 || (tree->IsMultiRegCall() && produce == MAX_RET_REG_COUNT));
4031 #endif // _TARGET_xxx_
4032
4033     // Add kill positions before adding def positions
4034     buildKillPositionsForNode(tree, currentLoc + 1);
4035
4036 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
4037     VARSET_TP liveLargeVectors(VarSetOps::UninitVal());
4038     if (enregisterLocalVars && (RBM_FLT_CALLEE_SAVED != RBM_NONE))
4039     {
4040         // Build RefPositions for saving any live large vectors.
4041         // This must be done after the kills, so that we know which large vectors are still live.
4042         VarSetOps::AssignNoCopy(compiler, liveLargeVectors, buildUpperVectorSaveRefPositions(tree, currentLoc + 1));
4043     }
4044 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
4045
4046     ReturnTypeDesc* retTypeDesc    = nullptr;
4047     bool            isMultiRegCall = tree->IsMultiRegCall();
4048     if (isMultiRegCall)
4049     {
4050         retTypeDesc = tree->AsCall()->GetReturnTypeDesc();
4051         assert((int)genCountBits(candidates) == produce);
4052         assert(candidates == retTypeDesc->GetABIReturnRegs());
4053     }
4054
4055     // push defs
4056     LocationInfoList locationInfoList;
4057     LsraLocation     defLocation = currentLoc + 1;
4058 #ifdef ARM_SOFTFP
4059     regMaskTP remainingUseCandidates = useCandidates;
4060 #endif
4061     for (int i = 0; i < produce; i++)
4062     {
4063         regMaskTP currCandidates = candidates;
4064         Interval* interval       = varDefInterval;
4065
4066         // In case of multi-reg call node, registerType is given by
4067         // the type of ith position return register.
4068         if (isMultiRegCall)
4069         {
4070             registerType   = retTypeDesc->GetReturnRegType((unsigned)i);
4071             currCandidates = genRegMask(retTypeDesc->GetABIReturnReg(i));
4072             useCandidates  = allRegs(registerType);
4073         }
4074
4075 #ifdef _TARGET_ARM_
4076         if (tree->OperIsPutArgSplit())
4077         {
4078             // get i-th candidate
4079             currCandidates = genFindLowestReg(candidates);
4080             candidates &= ~currCandidates;
4081         }
4082 #ifdef ARM_SOFTFP
4083         // If oper is GT_PUTARG_REG, set bits in useCandidates must be in sequential order.
4084         else if (tree->OperGet() == GT_PUTARG_REG || tree->OperGet() == GT_COPY)
4085         {
4086             useCandidates = genFindLowestReg(remainingUseCandidates);
4087             remainingUseCandidates &= ~useCandidates;
4088         }
4089 #endif // ARM_SOFTFP
4090 #endif // _TARGET_ARM_
4091
4092         if (interval == nullptr)
4093         {
4094             // Make a new interval
4095             interval = newInterval(registerType);
4096             if (hasDelayFreeSrc)
4097             {
4098                 interval->hasNonCommutativeRMWDef = true;
4099             }
4100             else if (tree->OperIsConst())
4101             {
4102                 assert(!tree->IsReuseRegVal());
4103                 interval->isConstant = true;
4104             }
4105
4106             if ((currCandidates & useCandidates) != RBM_NONE)
4107             {
4108                 interval->updateRegisterPreferences(currCandidates & useCandidates);
4109             }
4110
4111             if (isSpecialPutArg)
4112             {
4113                 interval->isSpecialPutArg = true;
4114             }
4115         }
4116         else
4117         {
4118             assert(registerTypesEquivalent(interval->registerType, registerType));
4119         }
4120
4121         if (prefSrcInterval != nullptr)
4122         {
4123             interval->assignRelatedIntervalIfUnassigned(prefSrcInterval);
4124         }
4125
4126         // for assignments, we want to create a refposition for the def
4127         // but not push it
4128         if (!noAdd)
4129         {
4130             locationInfoList.Append(listNodePool.GetNode(defLocation, interval, tree, (unsigned)i));
4131         }
4132
4133         RefPosition* pos = newRefPosition(interval, defLocation, defRefType, defNode, currCandidates,
4134                                           (unsigned)i DEBUG_ARG(minRegCount));
4135         if (info.isLocalDefUse)
4136         {
4137             pos->isLocalDefUse = true;
4138             pos->lastUse       = true;
4139         }
4140         interval->updateRegisterPreferences(currCandidates);
4141         interval->updateRegisterPreferences(useCandidates);
4142     }
4143
4144 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
4145     // SaveDef position must be at the same location as Def position of call node.
4146     if (enregisterLocalVars)
4147     {
4148         buildUpperVectorRestoreRefPositions(tree, defLocation, liveLargeVectors);
4149     }
4150 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
4151
4152     if (!locationInfoList.IsEmpty())
4153     {
4154         bool added = operandToLocationInfoMap.AddOrUpdate(tree, locationInfoList);
4155         assert(added);
4156         tree->gtLsraInfo.definesAnyRegisters = true;
4157     }
4158     JITDUMP("\n");
4159 }
4160
4161 // make an interval for each physical register
4162 void LinearScan::buildPhysRegRecords()
4163 {
4164     RegisterType regType = IntRegisterType;
4165     for (regNumber reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
4166     {
4167         RegRecord* curr = &physRegs[reg];
4168         curr->init(reg);
4169     }
4170 }
4171
4172 BasicBlock* getNonEmptyBlock(BasicBlock* block)
4173 {
4174     while (block != nullptr && block->bbTreeList == nullptr)
4175     {
4176         BasicBlock* nextBlock = block->bbNext;
4177         // Note that here we use the version of NumSucc that does not take a compiler.
4178         // That way this doesn't have to take a compiler, or be an instance method, e.g. of LinearScan.
4179         // If we have an empty block, it must have jump type BBJ_NONE or BBJ_ALWAYS, in which
4180         // case we don't need the version that takes a compiler.
4181         assert(block->NumSucc() == 1 && ((block->bbJumpKind == BBJ_ALWAYS) || (block->bbJumpKind == BBJ_NONE)));
4182         // sometimes the first block is empty and ends with an uncond branch
4183         // assert( block->GetSucc(0) == nextBlock);
4184         block = nextBlock;
4185     }
4186     assert(block != nullptr && block->bbTreeList != nullptr);
4187     return block;
4188 }
4189
4190 //------------------------------------------------------------------------
4191 // insertZeroInitRefPositions: Handle lclVars that are live-in to the first block
4192 //
4193 // Notes:
4194 //    Prior to calling this method, 'currentLiveVars' must be set to the set of register
4195 //    candidate variables that are liveIn to the first block.
4196 //    For each register candidate that is live-in to the first block:
4197 //    - If it is a GC ref, or if compInitMem is set, a ZeroInit RefPosition will be created.
4198 //    - Otherwise, it will be marked as spilled, since it will not be assigned a register
4199 //      on entry and will be loaded from memory on the undefined path.
4200 //      Note that, when the compInitMem option is not set, we may encounter these on
4201 //      paths that are protected by the same condition as an earlier def. However, since
4202 //      we don't do the analysis to determine this - and couldn't rely on always identifying
4203 //      such cases even if we tried - we must conservatively treat the undefined path as
4204 //      being possible. This is a relatively rare case, so the introduced conservatism is
4205 //      not expected to warrant the analysis required to determine the best placement of
4206 //      an initialization.
4207 //
4208 void LinearScan::insertZeroInitRefPositions()
4209 {
4210     assert(enregisterLocalVars);
4211 #ifdef DEBUG
4212     VARSET_TP expectedLiveVars(VarSetOps::Intersection(compiler, registerCandidateVars, compiler->fgFirstBB->bbLiveIn));
4213     assert(VarSetOps::Equal(compiler, currentLiveVars, expectedLiveVars));
4214 #endif //  DEBUG
4215
4216     // insert defs for this, then a block boundary
4217
4218     VarSetOps::Iter iter(compiler, currentLiveVars);
4219     unsigned        varIndex = 0;
4220     while (iter.NextElem(&varIndex))
4221     {
4222         unsigned   varNum = compiler->lvaTrackedToVarNum[varIndex];
4223         LclVarDsc* varDsc = compiler->lvaTable + varNum;
4224         if (!varDsc->lvIsParam && isCandidateVar(varDsc))
4225         {
4226             JITDUMP("V%02u was live in to first block:", varNum);
4227             Interval* interval = getIntervalForLocalVar(varIndex);
4228             if (compiler->info.compInitMem || varTypeIsGC(varDsc->TypeGet()))
4229             {
4230                 JITDUMP(" creating ZeroInit\n");
4231                 GenTree*     firstNode = getNonEmptyBlock(compiler->fgFirstBB)->firstNode();
4232                 RefPosition* pos =
4233                     newRefPosition(interval, MinLocation, RefTypeZeroInit, firstNode, allRegs(interval->registerType));
4234                 varDsc->lvMustInit = true;
4235             }
4236             else
4237             {
4238                 setIntervalAsSpilled(interval);
4239                 JITDUMP(" marking as spilled\n");
4240             }
4241         }
4242     }
4243 }
4244
4245 #if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
4246 // -----------------------------------------------------------------------
4247 // Sets the register state for an argument of type STRUCT for System V systems.
4248 //     See Compiler::raUpdateRegStateForArg(RegState *regState, LclVarDsc *argDsc) in regalloc.cpp
4249 //         for how state for argument is updated for unix non-structs and Windows AMD64 structs.
4250 void LinearScan::unixAmd64UpdateRegStateForArg(LclVarDsc* argDsc)
4251 {
4252     assert(varTypeIsStruct(argDsc));
4253     RegState* intRegState   = &compiler->codeGen->intRegState;
4254     RegState* floatRegState = &compiler->codeGen->floatRegState;
4255
4256     if ((argDsc->lvArgReg != REG_STK) && (argDsc->lvArgReg != REG_NA))
4257     {
4258         if (genRegMask(argDsc->lvArgReg) & (RBM_ALLFLOAT))
4259         {
4260             assert(genRegMask(argDsc->lvArgReg) & (RBM_FLTARG_REGS));
4261             floatRegState->rsCalleeRegArgMaskLiveIn |= genRegMask(argDsc->lvArgReg);
4262         }
4263         else
4264         {
4265             assert(genRegMask(argDsc->lvArgReg) & (RBM_ARG_REGS));
4266             intRegState->rsCalleeRegArgMaskLiveIn |= genRegMask(argDsc->lvArgReg);
4267         }
4268     }
4269
4270     if ((argDsc->lvOtherArgReg != REG_STK) && (argDsc->lvOtherArgReg != REG_NA))
4271     {
4272         if (genRegMask(argDsc->lvOtherArgReg) & (RBM_ALLFLOAT))
4273         {
4274             assert(genRegMask(argDsc->lvOtherArgReg) & (RBM_FLTARG_REGS));
4275             floatRegState->rsCalleeRegArgMaskLiveIn |= genRegMask(argDsc->lvOtherArgReg);
4276         }
4277         else
4278         {
4279             assert(genRegMask(argDsc->lvOtherArgReg) & (RBM_ARG_REGS));
4280             intRegState->rsCalleeRegArgMaskLiveIn |= genRegMask(argDsc->lvOtherArgReg);
4281         }
4282     }
4283 }
4284
4285 #endif // defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
4286
4287 //------------------------------------------------------------------------
4288 // updateRegStateForArg: Updates rsCalleeRegArgMaskLiveIn for the appropriate
4289 //    regState (either compiler->intRegState or compiler->floatRegState),
4290 //    with the lvArgReg on "argDsc"
4291 //
4292 // Arguments:
4293 //    argDsc - the argument for which the state is to be updated.
4294 //
4295 // Return Value: None
4296 //
4297 // Assumptions:
4298 //    The argument is live on entry to the function
4299 //    (or is untracked and therefore assumed live)
4300 //
4301 // Notes:
4302 //    This relies on a method in regAlloc.cpp that is shared between LSRA
4303 //    and regAlloc.  It is further abstracted here because regState is updated
4304 //    separately for tracked and untracked variables in LSRA.
4305 //
4306 void LinearScan::updateRegStateForArg(LclVarDsc* argDsc)
4307 {
4308 #if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
4309     // For System V AMD64 calls the argDsc can have 2 registers (for structs.)
4310     // Handle them here.
4311     if (varTypeIsStruct(argDsc))
4312     {
4313         unixAmd64UpdateRegStateForArg(argDsc);
4314     }
4315     else
4316 #endif // defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
4317     {
4318         RegState* intRegState   = &compiler->codeGen->intRegState;
4319         RegState* floatRegState = &compiler->codeGen->floatRegState;
4320         // In the case of AMD64 we'll still use the floating point registers
4321         // to model the register usage for argument on vararg calls, so
4322         // we will ignore the varargs condition to determine whether we use
4323         // XMM registers or not for setting up the call.
4324         bool isFloat = (isFloatRegType(argDsc->lvType)
4325 #ifndef _TARGET_AMD64_
4326                         && !compiler->info.compIsVarArgs
4327 #endif
4328                         && !compiler->opts.compUseSoftFP);
4329
4330         if (argDsc->lvIsHfaRegArg())
4331         {
4332             isFloat = true;
4333         }
4334
4335         if (isFloat)
4336         {
4337             JITDUMP("Float arg V%02u in reg %s\n", (argDsc - compiler->lvaTable), getRegName(argDsc->lvArgReg));
4338             compiler->raUpdateRegStateForArg(floatRegState, argDsc);
4339         }
4340         else
4341         {
4342             JITDUMP("Int arg V%02u in reg %s\n", (argDsc - compiler->lvaTable), getRegName(argDsc->lvArgReg));
4343 #if FEATURE_MULTIREG_ARGS
4344             if (argDsc->lvOtherArgReg != REG_NA)
4345             {
4346                 JITDUMP("(second half) in reg %s\n", getRegName(argDsc->lvOtherArgReg));
4347             }
4348 #endif // FEATURE_MULTIREG_ARGS
4349             compiler->raUpdateRegStateForArg(intRegState, argDsc);
4350         }
4351     }
4352 }
4353
4354 //------------------------------------------------------------------------
4355 // findPredBlockForLiveIn: Determine which block should be used for the register locations of the live-in variables.
4356 //
4357 // Arguments:
4358 //    block                 - The block for which we're selecting a predecesor.
4359 //    prevBlock             - The previous block in in allocation order.
4360 //    pPredBlockIsAllocated - A debug-only argument that indicates whether any of the predecessors have been seen
4361 //                            in allocation order.
4362 //
4363 // Return Value:
4364 //    The selected predecessor.
4365 //
4366 // Assumptions:
4367 //    in DEBUG, caller initializes *pPredBlockIsAllocated to false, and it will be set to true if the block
4368 //    returned is in fact a predecessor.
4369 //
4370 // Notes:
4371 //    This will select a predecessor based on the heuristics obtained by getLsraBlockBoundaryLocations(), which can be
4372 //    one of:
4373 //      LSRA_BLOCK_BOUNDARY_PRED    - Use the register locations of a predecessor block (default)
4374 //      LSRA_BLOCK_BOUNDARY_LAYOUT  - Use the register locations of the previous block in layout order.
4375 //                                    This is the only case where this actually returns a different block.
4376 //      LSRA_BLOCK_BOUNDARY_ROTATE  - Rotate the register locations from a predecessor.
4377 //                                    For this case, the block returned is the same as for LSRA_BLOCK_BOUNDARY_PRED, but
4378 //                                    the register locations will be "rotated" to stress the resolution and allocation
4379 //                                    code.
4380
4381 BasicBlock* LinearScan::findPredBlockForLiveIn(BasicBlock* block,
4382                                                BasicBlock* prevBlock DEBUGARG(bool* pPredBlockIsAllocated))
4383 {
4384     BasicBlock* predBlock = nullptr;
4385 #ifdef DEBUG
4386     assert(*pPredBlockIsAllocated == false);
4387     if (getLsraBlockBoundaryLocations() == LSRA_BLOCK_BOUNDARY_LAYOUT)
4388     {
4389         if (prevBlock != nullptr)
4390         {
4391             predBlock = prevBlock;
4392         }
4393     }
4394     else
4395 #endif // DEBUG
4396         if (block != compiler->fgFirstBB)
4397     {
4398         predBlock = block->GetUniquePred(compiler);
4399         if (predBlock != nullptr)
4400         {
4401             if (isBlockVisited(predBlock))
4402             {
4403                 if (predBlock->bbJumpKind == BBJ_COND)
4404                 {
4405                     // Special handling to improve matching on backedges.
4406                     BasicBlock* otherBlock = (block == predBlock->bbNext) ? predBlock->bbJumpDest : predBlock->bbNext;
4407                     noway_assert(otherBlock != nullptr);
4408                     if (isBlockVisited(otherBlock))
4409                     {
4410                         // This is the case when we have a conditional branch where one target has already
4411                         // been visited.  It would be best to use the same incoming regs as that block,
4412                         // so that we have less likelihood of having to move registers.
4413                         // For example, in determining the block to use for the starting register locations for
4414                         // "block" in the following example, we'd like to use the same predecessor for "block"
4415                         // as for "otherBlock", so that both successors of predBlock have the same locations, reducing
4416                         // the likelihood of needing a split block on a backedge:
4417                         //
4418                         //   otherPred
4419                         //       |
4420                         //   otherBlock <-+
4421                         //     . . .      |
4422                         //                |
4423                         //   predBlock----+
4424                         //       |
4425                         //     block
4426                         //
4427                         for (flowList* pred = otherBlock->bbPreds; pred != nullptr; pred = pred->flNext)
4428                         {
4429                             BasicBlock* otherPred = pred->flBlock;
4430                             if (otherPred->bbNum == blockInfo[otherBlock->bbNum].predBBNum)
4431                             {
4432                                 predBlock = otherPred;
4433                                 break;
4434                             }
4435                         }
4436                     }
4437                 }
4438             }
4439             else
4440             {
4441                 predBlock = nullptr;
4442             }
4443         }
4444         else
4445         {
4446             for (flowList* pred = block->bbPreds; pred != nullptr; pred = pred->flNext)
4447             {
4448                 BasicBlock* candidatePredBlock = pred->flBlock;
4449                 if (isBlockVisited(candidatePredBlock))
4450                 {
4451                     if (predBlock == nullptr || predBlock->bbWeight < candidatePredBlock->bbWeight)
4452                     {
4453                         predBlock = candidatePredBlock;
4454                         INDEBUG(*pPredBlockIsAllocated = true;)
4455                     }
4456                 }
4457             }
4458         }
4459         if (predBlock == nullptr)
4460         {
4461             predBlock = prevBlock;
4462             assert(predBlock != nullptr);
4463             JITDUMP("\n\nNo allocated predecessor; ");
4464         }
4465     }
4466     return predBlock;
4467 }
4468
4469 void LinearScan::buildIntervals()
4470 {
4471     BasicBlock* block;
4472
4473     // start numbering at 1; 0 is the entry
4474     LsraLocation currentLoc = 1;
4475
4476     JITDUMP("\nbuildIntervals ========\n");
4477
4478     // Now build (empty) records for all of the physical registers
4479     buildPhysRegRecords();
4480
4481 #ifdef DEBUG
4482     if (VERBOSE)
4483     {
4484         printf("\n-----------------\n");
4485         printf("LIVENESS:\n");
4486         printf("-----------------\n");
4487         foreach_block(compiler, block)
4488         {
4489             printf("BB%02u use def in out\n", block->bbNum);
4490             dumpConvertedVarSet(compiler, block->bbVarUse);
4491             printf("\n");
4492             dumpConvertedVarSet(compiler, block->bbVarDef);
4493             printf("\n");
4494             dumpConvertedVarSet(compiler, block->bbLiveIn);
4495             printf("\n");
4496             dumpConvertedVarSet(compiler, block->bbLiveOut);
4497             printf("\n");
4498         }
4499     }
4500 #endif // DEBUG
4501
4502 #if DOUBLE_ALIGN
4503     // We will determine whether we should double align the frame during
4504     // identifyCandidates(), but we initially assume that we will not.
4505     doDoubleAlign = false;
4506 #endif
4507
4508     identifyCandidates();
4509
4510     // Figure out if we're going to use a frame pointer. We need to do this before building
4511     // the ref positions, because those objects will embed the frame register in various register masks
4512     // if the frame pointer is not reserved. If we decide to have a frame pointer, setFrameType() will
4513     // remove the frame pointer from the masks.
4514     setFrameType();
4515
4516     DBEXEC(VERBOSE, TupleStyleDump(LSRA_DUMP_PRE));
4517
4518     // second part:
4519     JITDUMP("\nbuildIntervals second part ========\n");
4520     currentLoc = 0;
4521
4522     // Next, create ParamDef RefPositions for all the tracked parameters,
4523     // in order of their varIndex
4524
4525     LclVarDsc*   argDsc;
4526     unsigned int lclNum;
4527
4528     RegState* intRegState                   = &compiler->codeGen->intRegState;
4529     RegState* floatRegState                 = &compiler->codeGen->floatRegState;
4530     intRegState->rsCalleeRegArgMaskLiveIn   = RBM_NONE;
4531     floatRegState->rsCalleeRegArgMaskLiveIn = RBM_NONE;
4532
4533     for (unsigned int varIndex = 0; varIndex < compiler->lvaTrackedCount; varIndex++)
4534     {
4535         lclNum = compiler->lvaTrackedToVarNum[varIndex];
4536         argDsc = &(compiler->lvaTable[lclNum]);
4537
4538         if (!argDsc->lvIsParam)
4539         {
4540             continue;
4541         }
4542
4543         // Only reserve a register if the argument is actually used.
4544         // Is it dead on entry? If compJmpOpUsed is true, then the arguments
4545         // have to be kept alive, so we have to consider it as live on entry.
4546         // Use lvRefCnt instead of checking bbLiveIn because if it's volatile we
4547         // won't have done dataflow on it, but it needs to be marked as live-in so
4548         // it will get saved in the prolog.
4549         if (!compiler->compJmpOpUsed && argDsc->lvRefCnt == 0 && !compiler->opts.compDbgCode)
4550         {
4551             continue;
4552         }
4553
4554         if (argDsc->lvIsRegArg)
4555         {
4556             updateRegStateForArg(argDsc);
4557         }
4558
4559         if (isCandidateVar(argDsc))
4560         {
4561             Interval* interval = getIntervalForLocalVar(varIndex);
4562             regMaskTP mask     = allRegs(TypeGet(argDsc));
4563             if (argDsc->lvIsRegArg)
4564             {
4565                 // Set this interval as currently assigned to that register
4566                 regNumber inArgReg = argDsc->lvArgReg;
4567                 assert(inArgReg < REG_COUNT);
4568                 mask = genRegMask(inArgReg);
4569                 assignPhysReg(inArgReg, interval);
4570             }
4571             RefPosition* pos = newRefPosition(interval, MinLocation, RefTypeParamDef, nullptr, mask);
4572         }
4573         else if (varTypeIsStruct(argDsc->lvType))
4574         {
4575             for (unsigned fieldVarNum = argDsc->lvFieldLclStart;
4576                  fieldVarNum < argDsc->lvFieldLclStart + argDsc->lvFieldCnt; ++fieldVarNum)
4577             {
4578                 LclVarDsc* fieldVarDsc = &(compiler->lvaTable[fieldVarNum]);
4579                 if (fieldVarDsc->lvLRACandidate)
4580                 {
4581                     assert(fieldVarDsc->lvTracked);
4582                     Interval*    interval = getIntervalForLocalVar(fieldVarDsc->lvVarIndex);
4583                     RefPosition* pos =
4584                         newRefPosition(interval, MinLocation, RefTypeParamDef, nullptr, allRegs(TypeGet(fieldVarDsc)));
4585                 }
4586             }
4587         }
4588         else
4589         {
4590             // We can overwrite the register (i.e. codegen saves it on entry)
4591             assert(argDsc->lvRefCnt == 0 || !argDsc->lvIsRegArg || argDsc->lvDoNotEnregister ||
4592                    !argDsc->lvLRACandidate || (varTypeIsFloating(argDsc->TypeGet()) && compiler->opts.compDbgCode));
4593         }
4594     }
4595
4596     // Now set up the reg state for the non-tracked args
4597     // (We do this here because we want to generate the ParamDef RefPositions in tracked
4598     // order, so that loop doesn't hit the non-tracked args)
4599
4600     for (unsigned argNum = 0; argNum < compiler->info.compArgsCount; argNum++, argDsc++)
4601     {
4602         argDsc = &(compiler->lvaTable[argNum]);
4603
4604         if (argDsc->lvPromotedStruct())
4605         {
4606             noway_assert(argDsc->lvFieldCnt == 1); // We only handle one field here
4607
4608             unsigned fieldVarNum = argDsc->lvFieldLclStart;
4609             argDsc               = &(compiler->lvaTable[fieldVarNum]);
4610         }
4611         noway_assert(argDsc->lvIsParam);
4612         if (!argDsc->lvTracked && argDsc->lvIsRegArg)
4613         {
4614             updateRegStateForArg(argDsc);
4615         }
4616     }
4617
4618     // If there is a secret stub param, it is also live in
4619     if (compiler->info.compPublishStubParam)
4620     {
4621         intRegState->rsCalleeRegArgMaskLiveIn |= RBM_SECRET_STUB_PARAM;
4622     }
4623
4624     LocationInfoListNodePool listNodePool(compiler, 8);
4625     SmallHashTable<GenTree*, LocationInfoList, 32> operandToLocationInfoMap(compiler);
4626
4627     BasicBlock* predBlock = nullptr;
4628     BasicBlock* prevBlock = nullptr;
4629
4630     // Initialize currentLiveVars to the empty set.  We will set it to the current
4631     // live-in at the entry to each block (this will include the incoming args on
4632     // the first block).
4633     VarSetOps::AssignNoCopy(compiler, currentLiveVars, VarSetOps::MakeEmpty(compiler));
4634
4635     for (block = startBlockSequence(); block != nullptr; block = moveToNextBlock())
4636     {
4637         JITDUMP("\nNEW BLOCK BB%02u\n", block->bbNum);
4638
4639         bool predBlockIsAllocated = false;
4640         predBlock                 = findPredBlockForLiveIn(block, prevBlock DEBUGARG(&predBlockIsAllocated));
4641         if (predBlock)
4642         {
4643             JITDUMP("\n\nSetting BB%02u as the predecessor for determining incoming variable registers of BB%02u\n",
4644                     block->bbNum, predBlock->bbNum);
4645             assert(predBlock->bbNum <= bbNumMaxBeforeResolution);
4646             blockInfo[block->bbNum].predBBNum = predBlock->bbNum;
4647         }
4648
4649         if (enregisterLocalVars)
4650         {
4651             VarSetOps::AssignNoCopy(compiler, currentLiveVars,
4652                                     VarSetOps::Intersection(compiler, registerCandidateVars, block->bbLiveIn));
4653
4654             if (block == compiler->fgFirstBB)
4655             {
4656                 insertZeroInitRefPositions();
4657             }
4658
4659             // Any lclVars live-in to a block are resolution candidates.
4660             VarSetOps::UnionD(compiler, resolutionCandidateVars, currentLiveVars);
4661
4662             // Determine if we need any DummyDefs.
4663             // We need DummyDefs for cases where "predBlock" isn't really a predecessor.
4664             // Note that it's possible to have uses of unitialized variables, in which case even the first
4665             // block may require DummyDefs, which we are not currently adding - this means that these variables
4666             // will always be considered to be in memory on entry (and reloaded when the use is encountered).
4667             // TODO-CQ: Consider how best to tune this.  Currently, if we create DummyDefs for uninitialized
4668             // variables (which may actually be initialized along the dynamically executed paths, but not
4669             // on all static paths), we wind up with excessive liveranges for some of these variables.
4670             VARSET_TP newLiveIn(VarSetOps::MakeCopy(compiler, currentLiveVars));
4671             if (predBlock)
4672             {
4673                 // Compute set difference: newLiveIn = currentLiveVars - predBlock->bbLiveOut
4674                 VarSetOps::DiffD(compiler, newLiveIn, predBlock->bbLiveOut);
4675             }
4676             bool needsDummyDefs = (!VarSetOps::IsEmpty(compiler, newLiveIn) && block != compiler->fgFirstBB);
4677
4678             // Create dummy def RefPositions
4679
4680             if (needsDummyDefs)
4681             {
4682                 // If we are using locations from a predecessor, we should never require DummyDefs.
4683                 assert(!predBlockIsAllocated);
4684
4685                 JITDUMP("Creating dummy definitions\n");
4686                 VarSetOps::Iter iter(compiler, newLiveIn);
4687                 unsigned        varIndex = 0;
4688                 while (iter.NextElem(&varIndex))
4689                 {
4690                     unsigned   varNum = compiler->lvaTrackedToVarNum[varIndex];
4691                     LclVarDsc* varDsc = compiler->lvaTable + varNum;
4692                     // Add a dummyDef for any candidate vars that are in the "newLiveIn" set.
4693                     // If this is the entry block, don't add any incoming parameters (they're handled with ParamDefs).
4694                     if (isCandidateVar(varDsc) && (predBlock != nullptr || !varDsc->lvIsParam))
4695                     {
4696                         Interval*    interval = getIntervalForLocalVar(varIndex);
4697                         RefPosition* pos      = newRefPosition(interval, currentLoc, RefTypeDummyDef, nullptr,
4698                                                           allRegs(interval->registerType));
4699                     }
4700                 }
4701                 JITDUMP("Finished creating dummy definitions\n\n");
4702             }
4703         }
4704
4705         // Add a dummy RefPosition to mark the block boundary.
4706         // Note that we do this AFTER adding the exposed uses above, because the
4707         // register positions for those exposed uses need to be recorded at
4708         // this point.
4709
4710         RefPosition* pos = newRefPosition((Interval*)nullptr, currentLoc, RefTypeBB, nullptr, RBM_NONE);
4711         JITDUMP("\n");
4712
4713         LIR::Range& blockRange = LIR::AsRange(block);
4714         for (GenTree* node : blockRange.NonPhiNodes())
4715         {
4716             assert(node->gtLsraInfo.loc >= currentLoc);
4717             assert(!node->IsValue() || ((node->gtLIRFlags & LIR::Flags::IsUnusedValue) == 0) ||
4718                    node->gtLsraInfo.isLocalDefUse);
4719
4720             currentLoc = node->gtLsraInfo.loc;
4721             buildRefPositionsForNode(node, block, listNodePool, operandToLocationInfoMap, currentLoc);
4722
4723 #ifdef DEBUG
4724             if (currentLoc > maxNodeLocation)
4725             {
4726                 maxNodeLocation = currentLoc;
4727             }
4728 #endif // DEBUG
4729         }
4730
4731         // Increment the LsraLocation at this point, so that the dummy RefPositions
4732         // will not have the same LsraLocation as any "real" RefPosition.
4733         currentLoc += 2;
4734
4735         // Note: the visited set is cleared in LinearScan::doLinearScan()
4736         markBlockVisited(block);
4737
4738         if (enregisterLocalVars)
4739         {
4740             // Insert exposed uses for a lclVar that is live-out of 'block' but not live-in to the
4741             // next block, or any unvisited successors.
4742             // This will address lclVars that are live on a backedge, as well as those that are kept
4743             // live at a GT_JMP.
4744             //
4745             // Blocks ending with "jmp method" are marked as BBJ_HAS_JMP,
4746             // and jmp call is represented using GT_JMP node which is a leaf node.
4747             // Liveness phase keeps all the arguments of the method live till the end of
4748             // block by adding them to liveout set of the block containing GT_JMP.
4749             //
4750             // The target of a GT_JMP implicitly uses all the current method arguments, however
4751             // there are no actual references to them.  This can cause LSRA to assert, because
4752             // the variables are live but it sees no references.  In order to correctly model the
4753             // liveness of these arguments, we add dummy exposed uses, in the same manner as for
4754             // backward branches.  This will happen automatically via expUseSet.
4755             //
4756             // Note that a block ending with GT_JMP has no successors and hence the variables
4757             // for which dummy use ref positions are added are arguments of the method.
4758
4759             VARSET_TP expUseSet(VarSetOps::MakeCopy(compiler, block->bbLiveOut));
4760             VarSetOps::IntersectionD(compiler, expUseSet, registerCandidateVars);
4761             BasicBlock* nextBlock = getNextBlock();
4762             if (nextBlock != nullptr)
4763             {
4764                 VarSetOps::DiffD(compiler, expUseSet, nextBlock->bbLiveIn);
4765             }
4766             for (BasicBlock* succ : block->GetAllSuccs(compiler))
4767             {
4768                 if (VarSetOps::IsEmpty(compiler, expUseSet))
4769                 {
4770                     break;
4771                 }
4772
4773                 if (isBlockVisited(succ))
4774                 {
4775                     continue;
4776                 }
4777                 VarSetOps::DiffD(compiler, expUseSet, succ->bbLiveIn);
4778             }
4779
4780             if (!VarSetOps::IsEmpty(compiler, expUseSet))
4781             {
4782                 JITDUMP("Exposed uses:");
4783                 VarSetOps::Iter iter(compiler, expUseSet);
4784                 unsigned        varIndex = 0;
4785                 while (iter.NextElem(&varIndex))
4786                 {
4787                     unsigned   varNum = compiler->lvaTrackedToVarNum[varIndex];
4788                     LclVarDsc* varDsc = compiler->lvaTable + varNum;
4789                     assert(isCandidateVar(varDsc));
4790                     Interval*    interval = getIntervalForLocalVar(varIndex);
4791                     RefPosition* pos =
4792                         newRefPosition(interval, currentLoc, RefTypeExpUse, nullptr, allRegs(interval->registerType));
4793                     JITDUMP(" V%02u", varNum);
4794                 }
4795                 JITDUMP("\n");
4796             }
4797
4798             // Clear the "last use" flag on any vars that are live-out from this block.
4799             {
4800                 VarSetOps::Iter iter(compiler, block->bbLiveOut);
4801                 unsigned        varIndex = 0;
4802                 while (iter.NextElem(&varIndex))
4803                 {
4804                     unsigned         varNum = compiler->lvaTrackedToVarNum[varIndex];
4805                     LclVarDsc* const varDsc = &compiler->lvaTable[varNum];
4806                     if (isCandidateVar(varDsc))
4807                     {
4808                         RefPosition* const lastRP = getIntervalForLocalVar(varIndex)->lastRefPosition;
4809                         if ((lastRP != nullptr) && (lastRP->bbNum == block->bbNum))
4810                         {
4811                             lastRP->lastUse = false;
4812                         }
4813                     }
4814                 }
4815             }
4816
4817 #ifdef DEBUG
4818             checkLastUses(block);
4819
4820             if (VERBOSE)
4821             {
4822                 printf("use: ");
4823                 dumpConvertedVarSet(compiler, block->bbVarUse);
4824                 printf("\ndef: ");
4825                 dumpConvertedVarSet(compiler, block->bbVarDef);
4826                 printf("\n");
4827             }
4828 #endif // DEBUG
4829         }
4830
4831         prevBlock = block;
4832     }
4833
4834     if (enregisterLocalVars)
4835     {
4836         if (compiler->lvaKeepAliveAndReportThis())
4837         {
4838             // If we need to KeepAliveAndReportThis, add a dummy exposed use of it at the end
4839             unsigned keepAliveVarNum = compiler->info.compThisArg;
4840             assert(compiler->info.compIsStatic == false);
4841             LclVarDsc* varDsc = compiler->lvaTable + keepAliveVarNum;
4842             if (isCandidateVar(varDsc))
4843             {
4844                 JITDUMP("Adding exposed use of this, for lvaKeepAliveAndReportThis\n");
4845                 Interval*    interval = getIntervalForLocalVar(varDsc->lvVarIndex);
4846                 RefPosition* pos =
4847                     newRefPosition(interval, currentLoc, RefTypeExpUse, nullptr, allRegs(interval->registerType));
4848             }
4849         }
4850
4851 #ifdef DEBUG
4852         if (getLsraExtendLifeTimes())
4853         {
4854             LclVarDsc* varDsc;
4855             for (lclNum = 0, varDsc = compiler->lvaTable; lclNum < compiler->lvaCount; lclNum++, varDsc++)
4856             {
4857                 if (varDsc->lvLRACandidate)
4858                 {
4859                     JITDUMP("Adding exposed use of V%02u for LsraExtendLifetimes\n", lclNum);
4860                     Interval*    interval = getIntervalForLocalVar(varDsc->lvVarIndex);
4861                     RefPosition* pos =
4862                         newRefPosition(interval, currentLoc, RefTypeExpUse, nullptr, allRegs(interval->registerType));
4863                 }
4864             }
4865         }
4866 #endif // DEBUG
4867     }
4868
4869     // If the last block has successors, create a RefTypeBB to record
4870     // what's live
4871
4872     if (prevBlock->NumSucc(compiler) > 0)
4873     {
4874         RefPosition* pos = newRefPosition((Interval*)nullptr, currentLoc, RefTypeBB, nullptr, RBM_NONE);
4875     }
4876
4877 #ifdef DEBUG
4878     // Make sure we don't have any blocks that were not visited
4879     foreach_block(compiler, block)
4880     {
4881         assert(isBlockVisited(block));
4882     }
4883
4884     if (VERBOSE)
4885     {
4886         lsraDumpIntervals("BEFORE VALIDATING INTERVALS");
4887         dumpRefPositions("BEFORE VALIDATING INTERVALS");
4888         validateIntervals();
4889     }
4890 #endif // DEBUG
4891 }
4892
4893 #ifdef DEBUG
4894 void LinearScan::dumpVarRefPositions(const char* title)
4895 {
4896     if (enregisterLocalVars)
4897     {
4898         printf("\nVAR REFPOSITIONS %s\n", title);
4899
4900         for (unsigned i = 0; i < compiler->lvaCount; i++)
4901         {
4902             printf("--- V%02u\n", i);
4903
4904             LclVarDsc* varDsc = compiler->lvaTable + i;
4905             if (varDsc->lvIsRegCandidate())
4906             {
4907                 Interval* interval = getIntervalForLocalVar(varDsc->lvVarIndex);
4908                 for (RefPosition* ref = interval->firstRefPosition; ref != nullptr; ref = ref->nextRefPosition)
4909                 {
4910                     ref->dump();
4911                 }
4912             }
4913         }
4914         printf("\n");
4915     }
4916 }
4917
4918 void LinearScan::validateIntervals()
4919 {
4920     if (enregisterLocalVars)
4921     {
4922         for (unsigned i = 0; i < compiler->lvaTrackedCount; i++)
4923         {
4924             if (!compiler->lvaTable[compiler->lvaTrackedToVarNum[i]].lvLRACandidate)
4925             {
4926                 continue;
4927             }
4928             Interval* interval = getIntervalForLocalVar(i);
4929
4930             bool defined = false;
4931             printf("-----------------\n");
4932             for (RefPosition* ref = interval->firstRefPosition; ref != nullptr; ref = ref->nextRefPosition)
4933             {
4934                 ref->dump();
4935                 RefType refType = ref->refType;
4936                 if (!defined && RefTypeIsUse(refType))
4937                 {
4938                     if (compiler->info.compMethodName != nullptr)
4939                     {
4940                         printf("%s: ", compiler->info.compMethodName);
4941                     }
4942                     printf("LocalVar V%02u: undefined use at %u\n", interval->varNum, ref->nodeLocation);
4943                 }
4944                 // Note that there can be multiple last uses if they are on disjoint paths,
4945                 // so we can't really check the lastUse flag
4946                 if (ref->lastUse)
4947                 {
4948                     defined = false;
4949                 }
4950                 if (RefTypeIsDef(refType))
4951                 {
4952                     defined = true;
4953                 }
4954             }
4955         }
4956     }
4957 }
4958 #endif // DEBUG
4959
4960 // Set the default rpFrameType based upon codeGen->isFramePointerRequired()
4961 // This was lifted from the register predictor
4962 //
4963 void LinearScan::setFrameType()
4964 {
4965     FrameType frameType = FT_NOT_SET;
4966 #if DOUBLE_ALIGN
4967     compiler->codeGen->setDoubleAlign(false);
4968     if (doDoubleAlign)
4969     {
4970         frameType = FT_DOUBLE_ALIGN_FRAME;
4971         compiler->codeGen->setDoubleAlign(true);
4972     }
4973     else
4974 #endif // DOUBLE_ALIGN
4975         if (compiler->codeGen->isFramePointerRequired())
4976     {
4977         frameType = FT_EBP_FRAME;
4978     }
4979     else
4980     {
4981         if (compiler->rpMustCreateEBPCalled == false)
4982         {
4983 #ifdef DEBUG
4984             const char* reason;
4985 #endif // DEBUG
4986             compiler->rpMustCreateEBPCalled = true;
4987             if (compiler->rpMustCreateEBPFrame(INDEBUG(&reason)))
4988             {
4989                 JITDUMP("; Decided to create an EBP based frame for ETW stackwalking (%s)\n", reason);
4990                 compiler->codeGen->setFrameRequired(true);
4991             }
4992         }
4993
4994         if (compiler->codeGen->isFrameRequired())
4995         {
4996             frameType = FT_EBP_FRAME;
4997         }
4998         else
4999         {
5000             frameType = FT_ESP_FRAME;
5001         }
5002     }
5003
5004     switch (frameType)
5005     {
5006         case FT_ESP_FRAME:
5007             noway_assert(!compiler->codeGen->isFramePointerRequired());
5008             noway_assert(!compiler->codeGen->isFrameRequired());
5009             compiler->codeGen->setFramePointerUsed(false);
5010             break;
5011         case FT_EBP_FRAME:
5012             compiler->codeGen->setFramePointerUsed(true);
5013             break;
5014 #if DOUBLE_ALIGN
5015         case FT_DOUBLE_ALIGN_FRAME:
5016             noway_assert(!compiler->codeGen->isFramePointerRequired());
5017             compiler->codeGen->setFramePointerUsed(false);
5018             break;
5019 #endif // DOUBLE_ALIGN
5020         default:
5021             noway_assert(!"rpFrameType not set correctly!");
5022             break;
5023     }
5024
5025     // If we are using FPBASE as the frame register, we cannot also use it for
5026     // a local var. Note that we may have already added it to the register masks,
5027     // which are computed when the LinearScan class constructor is created, and
5028     // used during lowering. Luckily, the TreeNodeInfo only stores an index to
5029     // the masks stored in the LinearScan class, so we only need to walk the
5030     // unique masks and remove FPBASE.
5031     if (frameType == FT_EBP_FRAME)
5032     {
5033         if ((availableIntRegs & RBM_FPBASE) != 0)
5034         {
5035             RemoveRegisterFromMasks(REG_FPBASE);
5036
5037             // We know that we're already in "read mode" for availableIntRegs. However,
5038             // we need to remove the FPBASE register, so subsequent users (like callers
5039             // to allRegs()) get the right thing. The RemoveRegisterFromMasks() code
5040             // fixes up everything that already took a dependency on the value that was
5041             // previously read, so this completes the picture.
5042             availableIntRegs.OverrideAssign(availableIntRegs & ~RBM_FPBASE);
5043         }
5044     }
5045
5046     compiler->rpFrameType = frameType;
5047 }
5048
5049 // Is the copyReg/moveReg given by this RefPosition still busy at the
5050 // given location?
5051 bool copyOrMoveRegInUse(RefPosition* ref, LsraLocation loc)
5052 {
5053     assert(ref->copyReg || ref->moveReg);
5054     if (ref->getRefEndLocation() >= loc)
5055     {
5056         return true;
5057     }
5058     Interval*    interval = ref->getInterval();
5059     RefPosition* nextRef  = interval->getNextRefPosition();
5060     if (nextRef != nullptr && nextRef->treeNode == ref->treeNode && nextRef->getRefEndLocation() >= loc)
5061     {
5062         return true;
5063     }
5064     return false;
5065 }
5066
5067 // Determine whether the register represented by "physRegRecord" is available at least
5068 // at the "currentLoc", and if so, return the next location at which it is in use in
5069 // "nextRefLocationPtr"
5070 //
5071 bool LinearScan::registerIsAvailable(RegRecord*    physRegRecord,
5072                                      LsraLocation  currentLoc,
5073                                      LsraLocation* nextRefLocationPtr,
5074                                      RegisterType  regType)
5075 {
5076     *nextRefLocationPtr          = MaxLocation;
5077     LsraLocation nextRefLocation = MaxLocation;
5078     regMaskTP    regMask         = genRegMask(physRegRecord->regNum);
5079     if (physRegRecord->isBusyUntilNextKill)
5080     {
5081         return false;
5082     }
5083
5084     RefPosition* nextPhysReference = physRegRecord->getNextRefPosition();
5085     if (nextPhysReference != nullptr)
5086     {
5087         nextRefLocation = nextPhysReference->nodeLocation;
5088         // if (nextPhysReference->refType == RefTypeFixedReg) nextRefLocation--;
5089     }
5090     else if (!physRegRecord->isCalleeSave)
5091     {
5092         nextRefLocation = MaxLocation - 1;
5093     }
5094
5095     Interval* assignedInterval = physRegRecord->assignedInterval;
5096
5097     if (assignedInterval != nullptr)
5098     {
5099         RefPosition* recentReference = assignedInterval->recentRefPosition;
5100
5101         // The only case where we have an assignedInterval, but recentReference is null
5102         // is where this interval is live at procedure entry (i.e. an arg register), in which
5103         // case it's still live and its assigned register is not available
5104         // (Note that the ParamDef will be recorded as a recentReference when we encounter
5105         // it, but we will be allocating registers, potentially to other incoming parameters,
5106         // as we process the ParamDefs.)
5107
5108         if (recentReference == nullptr)
5109         {
5110             return false;
5111         }
5112
5113         // Is this a copyReg/moveReg?  It is if the register assignment doesn't match.
5114         // (the recentReference may not be a copyReg/moveReg, because we could have seen another
5115         // reference since the copyReg/moveReg)
5116
5117         if (!assignedInterval->isAssignedTo(physRegRecord->regNum))
5118         {
5119             // Don't reassign it if it's still in use
5120             if ((recentReference->copyReg || recentReference->moveReg) &&
5121                 copyOrMoveRegInUse(recentReference, currentLoc))
5122             {
5123                 return false;
5124             }
5125         }
5126         else if (!assignedInterval->isActive && assignedInterval->isConstant)
5127         {
5128             // Treat this as unassigned, i.e. do nothing.
5129             // TODO-CQ: Consider adjusting the heuristics (probably in the caller of this method)
5130             // to avoid reusing these registers.
5131         }
5132         // If this interval isn't active, it's available if it isn't referenced
5133         // at this location (or the previous location, if the recent RefPosition
5134         // is a delayRegFree).
5135         else if (!assignedInterval->isActive &&
5136                  (recentReference->refType == RefTypeExpUse || recentReference->getRefEndLocation() < currentLoc))
5137         {
5138             // This interval must have a next reference (otherwise it wouldn't be assigned to this register)
5139             RefPosition* nextReference = recentReference->nextRefPosition;
5140             if (nextReference != nullptr)
5141             {
5142                 if (nextReference->nodeLocation < nextRefLocation)
5143                 {
5144                     nextRefLocation = nextReference->nodeLocation;
5145                 }
5146             }
5147             else
5148             {
5149                 assert(recentReference->copyReg && recentReference->registerAssignment != regMask);
5150             }
5151         }
5152         else
5153         {
5154             return false;
5155         }
5156     }
5157     if (nextRefLocation < *nextRefLocationPtr)
5158     {
5159         *nextRefLocationPtr = nextRefLocation;
5160     }
5161
5162 #ifdef _TARGET_ARM_
5163     if (regType == TYP_DOUBLE)
5164     {
5165         // Recurse, but check the other half this time (TYP_FLOAT)
5166         if (!registerIsAvailable(getRegisterRecord(REG_NEXT(physRegRecord->regNum)), currentLoc, nextRefLocationPtr,
5167                                  TYP_FLOAT))
5168             return false;
5169         nextRefLocation = *nextRefLocationPtr;
5170     }
5171 #endif // _TARGET_ARM_
5172
5173     return (nextRefLocation >= currentLoc);
5174 }
5175
5176 //------------------------------------------------------------------------
5177 // getRegisterType: Get the RegisterType to use for the given RefPosition
5178 //
5179 // Arguments:
5180 //    currentInterval: The interval for the current allocation
5181 //    refPosition:     The RefPosition of the current Interval for which a register is being allocated
5182 //
5183 // Return Value:
5184 //    The RegisterType that should be allocated for this RefPosition
5185 //
5186 // Notes:
5187 //    This will nearly always be identical to the registerType of the interval, except in the case
5188 //    of SIMD types of 8 bytes (currently only Vector2) when they are passed and returned in integer
5189 //    registers, or copied to a return temp.
5190 //    This method need only be called in situations where we may be dealing with the register requirements
5191 //    of a RefTypeUse RefPosition (i.e. not when we are only looking at the type of an interval, nor when
5192 //    we are interested in the "defining" type of the interval).  This is because the situation of interest
5193 //    only happens at the use (where it must be copied to an integer register).
5194
5195 RegisterType LinearScan::getRegisterType(Interval* currentInterval, RefPosition* refPosition)
5196 {
5197     assert(refPosition->getInterval() == currentInterval);
5198     RegisterType regType    = currentInterval->registerType;
5199     regMaskTP    candidates = refPosition->registerAssignment;
5200
5201     assert((candidates & allRegs(regType)) != RBM_NONE);
5202     return regType;
5203 }
5204
5205 //------------------------------------------------------------------------
5206 // tryAllocateFreeReg: Find a free register that satisfies the requirements for refPosition,
5207 //                     and takes into account the preferences for the given Interval
5208 //
5209 // Arguments:
5210 //    currentInterval: The interval for the current allocation
5211 //    refPosition:     The RefPosition of the current Interval for which a register is being allocated
5212 //
5213 // Return Value:
5214 //    The regNumber, if any, allocated to the RefPositon.  Returns REG_NA if no free register is found.
5215 //
5216 // Notes:
5217 //    TODO-CQ: Consider whether we need to use a different order for tree temps than for vars, as
5218 //    reg predict does
5219
5220 static const regNumber lsraRegOrder[]      = {REG_VAR_ORDER};
5221 const unsigned         lsraRegOrderSize    = ArrLen(lsraRegOrder);
5222 static const regNumber lsraRegOrderFlt[]   = {REG_VAR_ORDER_FLT};
5223 const unsigned         lsraRegOrderFltSize = ArrLen(lsraRegOrderFlt);
5224
5225 regNumber LinearScan::tryAllocateFreeReg(Interval* currentInterval, RefPosition* refPosition)
5226 {
5227     regNumber foundReg = REG_NA;
5228
5229     RegisterType     regType = getRegisterType(currentInterval, refPosition);
5230     const regNumber* regOrder;
5231     unsigned         regOrderSize;
5232     if (useFloatReg(regType))
5233     {
5234         regOrder     = lsraRegOrderFlt;
5235         regOrderSize = lsraRegOrderFltSize;
5236     }
5237     else
5238     {
5239         regOrder     = lsraRegOrder;
5240         regOrderSize = lsraRegOrderSize;
5241     }
5242
5243     LsraLocation currentLocation = refPosition->nodeLocation;
5244     RefPosition* nextRefPos      = refPosition->nextRefPosition;
5245     LsraLocation nextLocation    = (nextRefPos == nullptr) ? currentLocation : nextRefPos->nodeLocation;
5246     regMaskTP    candidates      = refPosition->registerAssignment;
5247     regMaskTP    preferences     = currentInterval->registerPreferences;
5248
5249     if (RefTypeIsDef(refPosition->refType))
5250     {
5251         if (currentInterval->hasConflictingDefUse)
5252         {
5253             resolveConflictingDefAndUse(currentInterval, refPosition);
5254             candidates = refPosition->registerAssignment;
5255         }
5256         // Otherwise, check for the case of a fixed-reg def of a reg that will be killed before the
5257         // use, or interferes at the point of use (which shouldn't happen, but Lower doesn't mark
5258         // the contained nodes as interfering).
5259         // Note that we may have a ParamDef RefPosition that is marked isFixedRegRef, but which
5260         // has had its registerAssignment changed to no longer be a single register.
5261         else if (refPosition->isFixedRegRef && nextRefPos != nullptr && RefTypeIsUse(nextRefPos->refType) &&
5262                  !nextRefPos->isFixedRegRef && genMaxOneBit(refPosition->registerAssignment))
5263         {
5264             regNumber  defReg       = refPosition->assignedReg();
5265             RegRecord* defRegRecord = getRegisterRecord(defReg);
5266
5267             RefPosition* currFixedRegRefPosition = defRegRecord->recentRefPosition;
5268             assert(currFixedRegRefPosition != nullptr &&
5269                    currFixedRegRefPosition->nodeLocation == refPosition->nodeLocation);
5270
5271             // If there is another fixed reference to this register before the use, change the candidates
5272             // on this RefPosition to include that of nextRefPos.
5273             if (currFixedRegRefPosition->nextRefPosition != nullptr &&
5274                 currFixedRegRefPosition->nextRefPosition->nodeLocation <= nextRefPos->getRefEndLocation())
5275             {
5276                 candidates |= nextRefPos->registerAssignment;
5277                 if (preferences == refPosition->registerAssignment)
5278                 {
5279                     preferences = candidates;
5280                 }
5281             }
5282         }
5283     }
5284
5285     preferences &= candidates;
5286     if (preferences == RBM_NONE)
5287     {
5288         preferences = candidates;
5289     }
5290     regMaskTP relatedPreferences = RBM_NONE;
5291
5292 #ifdef DEBUG
5293     candidates = stressLimitRegs(refPosition, candidates);
5294 #endif
5295     bool mustAssignARegister = true;
5296     assert(candidates != RBM_NONE);
5297
5298     // If the related interval has no further references, it is possible that it is a source of the
5299     // node that produces this interval.  However, we don't want to use the relatedInterval for preferencing
5300     // if its next reference is not a new definition (as it either is or will become live).
5301     Interval* relatedInterval = currentInterval->relatedInterval;
5302     if (relatedInterval != nullptr)
5303     {
5304         RefPosition* nextRelatedRefPosition = relatedInterval->getNextRefPosition();
5305         if (nextRelatedRefPosition != nullptr)
5306         {
5307             // Don't use the relatedInterval for preferencing if its next reference is not a new definition.
5308             if (!RefTypeIsDef(nextRelatedRefPosition->refType))
5309             {
5310                 relatedInterval = nullptr;
5311             }
5312             // Is the relatedInterval simply a copy to another relatedInterval?
5313             else if ((relatedInterval->relatedInterval != nullptr) &&
5314                      (nextRelatedRefPosition->nextRefPosition != nullptr) &&
5315                      (nextRelatedRefPosition->nextRefPosition->nextRefPosition == nullptr) &&
5316                      (nextRelatedRefPosition->nextRefPosition->nodeLocation <
5317                       relatedInterval->relatedInterval->getNextRefLocation()))
5318             {
5319                 // The current relatedInterval has only two remaining RefPositions, both of which
5320                 // occur prior to the next RefPosition for its relatedInterval.
5321                 // It is likely a copy.
5322                 relatedInterval = relatedInterval->relatedInterval;
5323             }
5324         }
5325     }
5326
5327     if (relatedInterval != nullptr)
5328     {
5329         // If the related interval already has an assigned register, then use that
5330         // as the related preference.  We'll take the related
5331         // interval preferences into account in the loop over all the registers.
5332
5333         if (relatedInterval->assignedReg != nullptr)
5334         {
5335             relatedPreferences = genRegMask(relatedInterval->assignedReg->regNum);
5336         }
5337         else
5338         {
5339             relatedPreferences = relatedInterval->registerPreferences;
5340         }
5341     }
5342
5343     bool preferCalleeSave = currentInterval->preferCalleeSave;
5344
5345     // For floating point, we want to be less aggressive about using callee-save registers.
5346     // So in that case, we just need to ensure that the current RefPosition is covered.
5347     RefPosition* rangeEndRefPosition;
5348     RefPosition* lastRefPosition = currentInterval->lastRefPosition;
5349     if (useFloatReg(currentInterval->registerType))
5350     {
5351         rangeEndRefPosition = refPosition;
5352     }
5353     else
5354     {
5355         rangeEndRefPosition = currentInterval->lastRefPosition;
5356         // If we have a relatedInterval that is not currently occupying a register,
5357         // and whose lifetime begins after this one ends,
5358         // we want to try to select a register that will cover its lifetime.
5359         if ((relatedInterval != nullptr) && (relatedInterval->assignedReg == nullptr) &&
5360             (relatedInterval->getNextRefLocation() >= rangeEndRefPosition->nodeLocation))
5361         {
5362             lastRefPosition  = relatedInterval->lastRefPosition;
5363             preferCalleeSave = relatedInterval->preferCalleeSave;
5364         }
5365     }
5366
5367     // If this has a delayed use (due to being used in a rmw position of a
5368     // non-commutative operator), its endLocation is delayed until the "def"
5369     // position, which is one location past the use (getRefEndLocation() takes care of this).
5370     LsraLocation rangeEndLocation = rangeEndRefPosition->getRefEndLocation();
5371     LsraLocation lastLocation     = lastRefPosition->getRefEndLocation();
5372     regNumber    prevReg          = REG_NA;
5373
5374     if (currentInterval->assignedReg)
5375     {
5376         bool useAssignedReg = false;
5377         // This was an interval that was previously allocated to the given
5378         // physical register, and we should try to allocate it to that register
5379         // again, if possible and reasonable.
5380         // Use it preemptively (i.e. before checking other available regs)
5381         // only if it is preferred and available.
5382
5383         RegRecord* regRec    = currentInterval->assignedReg;
5384         prevReg              = regRec->regNum;
5385         regMaskTP prevRegBit = genRegMask(prevReg);
5386
5387         // Is it in the preferred set of regs?
5388         if ((prevRegBit & preferences) != RBM_NONE)
5389         {
5390             // Is it currently available?
5391             LsraLocation nextPhysRefLoc;
5392             if (registerIsAvailable(regRec, currentLocation, &nextPhysRefLoc, currentInterval->registerType))
5393             {
5394                 // If the register is next referenced at this location, only use it if
5395                 // this has a fixed reg requirement (i.e. this is the reference that caused
5396                 // the FixedReg ref to be created)
5397
5398                 if (!regRec->conflictingFixedRegReference(refPosition))
5399                 {
5400                     useAssignedReg = true;
5401                 }
5402             }
5403         }
5404         if (useAssignedReg)
5405         {
5406             regNumber foundReg = prevReg;
5407             assignPhysReg(regRec, currentInterval);
5408             refPosition->registerAssignment = genRegMask(foundReg);
5409             return foundReg;
5410         }
5411         else
5412         {
5413             // Don't keep trying to allocate to this register
5414             currentInterval->assignedReg = nullptr;
5415         }
5416     }
5417
5418     RegRecord* availablePhysRegInterval = nullptr;
5419     Interval*  intervalToUnassign       = nullptr;
5420
5421     // Each register will receive a score which is the sum of the scoring criteria below.
5422     // These were selected on the assumption that they will have an impact on the "goodness"
5423     // of a register selection, and have been tuned to a certain extent by observing the impact
5424     // of the ordering on asmDiffs.  However, there is probably much more room for tuning,
5425     // and perhaps additional criteria.
5426     //
5427     // These are FLAGS (bits) so that we can easily order them and add them together.
5428     // If the scores are equal, but one covers more of the current interval's range,
5429     // then it wins.  Otherwise, the one encountered earlier in the regOrder wins.
5430
5431     enum RegisterScore
5432     {
5433         VALUE_AVAILABLE = 0x40, // It is a constant value that is already in an acceptable register.
5434         COVERS          = 0x20, // It is in the interval's preference set and it covers the entire lifetime.
5435         OWN_PREFERENCE  = 0x10, // It is in the preference set of this interval.
5436         COVERS_RELATED  = 0x08, // It is in the preference set of the related interval and covers the entire lifetime.
5437         RELATED_PREFERENCE = 0x04, // It is in the preference set of the related interval.
5438         CALLER_CALLEE      = 0x02, // It is in the right "set" for the interval (caller or callee-save).
5439         UNASSIGNED         = 0x01, // It is not currently assigned to an inactive interval.
5440     };
5441
5442     int bestScore = 0;
5443
5444     // Compute the best possible score so we can stop looping early if we find it.
5445     // TODO-Throughput: At some point we may want to short-circuit the computation of each score, but
5446     // probably not until we've tuned the order of these criteria.  At that point,
5447     // we'll need to avoid the short-circuit if we've got a stress option to reverse
5448     // the selection.
5449     int bestPossibleScore = COVERS + UNASSIGNED + OWN_PREFERENCE + CALLER_CALLEE;
5450     if (relatedPreferences != RBM_NONE)
5451     {
5452         bestPossibleScore |= RELATED_PREFERENCE + COVERS_RELATED;
5453     }
5454
5455     LsraLocation bestLocation = MinLocation;
5456
5457     // In non-debug builds, this will simply get optimized away
5458     bool reverseSelect = false;
5459 #ifdef DEBUG
5460     reverseSelect = doReverseSelect();
5461 #endif // DEBUG
5462
5463     // An optimization for the common case where there is only one candidate -
5464     // avoid looping over all the other registers
5465
5466     regNumber singleReg = REG_NA;
5467
5468     if (genMaxOneBit(candidates))
5469     {
5470         regOrderSize = 1;
5471         singleReg    = genRegNumFromMask(candidates);
5472         regOrder     = &singleReg;
5473     }
5474
5475     for (unsigned i = 0; i < regOrderSize && (candidates != RBM_NONE); i++)
5476     {
5477         regNumber regNum       = regOrder[i];
5478         regMaskTP candidateBit = genRegMask(regNum);
5479
5480         if (!(candidates & candidateBit))
5481         {
5482             continue;
5483         }
5484
5485         candidates &= ~candidateBit;
5486
5487         RegRecord* physRegRecord = getRegisterRecord(regNum);
5488
5489         int          score               = 0;
5490         LsraLocation nextPhysRefLocation = MaxLocation;
5491
5492         // By chance, is this register already holding this interval, as a copyReg or having
5493         // been restored as inactive after a kill?
5494         if (physRegRecord->assignedInterval == currentInterval)
5495         {
5496             availablePhysRegInterval = physRegRecord;
5497             intervalToUnassign       = nullptr;
5498             break;
5499         }
5500
5501         // Find the next RefPosition of the physical register
5502         if (!registerIsAvailable(physRegRecord, currentLocation, &nextPhysRefLocation, regType))
5503         {
5504             continue;
5505         }
5506
5507         // If the register is next referenced at this location, only use it if
5508         // this has a fixed reg requirement (i.e. this is the reference that caused
5509         // the FixedReg ref to be created)
5510
5511         if (physRegRecord->conflictingFixedRegReference(refPosition))
5512         {
5513             continue;
5514         }
5515
5516         // If this is a definition of a constant interval, check to see if its value is already in this register.
5517         if (currentInterval->isConstant && RefTypeIsDef(refPosition->refType) &&
5518             (physRegRecord->assignedInterval != nullptr) && physRegRecord->assignedInterval->isConstant)
5519         {
5520             noway_assert(refPosition->treeNode != nullptr);
5521             GenTree* otherTreeNode = physRegRecord->assignedInterval->firstRefPosition->treeNode;
5522             noway_assert(otherTreeNode != nullptr);
5523
5524             if (refPosition->treeNode->OperGet() == otherTreeNode->OperGet())
5525             {
5526                 switch (otherTreeNode->OperGet())
5527                 {
5528                     case GT_CNS_INT:
5529                         if ((refPosition->treeNode->AsIntCon()->IconValue() ==
5530                              otherTreeNode->AsIntCon()->IconValue()) &&
5531                             (varTypeGCtype(refPosition->treeNode) == varTypeGCtype(otherTreeNode)))
5532                         {
5533 #ifdef _TARGET_64BIT_
5534                             // If the constant is negative, only reuse registers of the same type.
5535                             // This is because, on a 64-bit system, we do not sign-extend immediates in registers to
5536                             // 64-bits unless they are actually longs, as this requires a longer instruction.
5537                             // This doesn't apply to a 32-bit system, on which long values occupy multiple registers.
5538                             // (We could sign-extend, but we would have to always sign-extend, because if we reuse more
5539                             // than once, we won't have access to the instruction that originally defines the constant).
5540                             if ((refPosition->treeNode->TypeGet() == otherTreeNode->TypeGet()) ||
5541                                 (refPosition->treeNode->AsIntCon()->IconValue() >= 0))
5542 #endif // _TARGET_64BIT_
5543                             {
5544                                 score |= VALUE_AVAILABLE;
5545                             }
5546                         }
5547                         break;
5548                     case GT_CNS_DBL:
5549                     {
5550                         // For floating point constants, the values must be identical, not simply compare
5551                         // equal.  So we compare the bits.
5552                         if (refPosition->treeNode->AsDblCon()->isBitwiseEqual(otherTreeNode->AsDblCon()) &&
5553                             (refPosition->treeNode->TypeGet() == otherTreeNode->TypeGet()))
5554                         {
5555                             score |= VALUE_AVAILABLE;
5556                         }
5557                         break;
5558                     }
5559                     default:
5560                         // for all other 'otherTreeNode->OperGet()' kinds, we leave 'score' unchanged
5561                         break;
5562                 }
5563             }
5564         }
5565
5566         // If the nextPhysRefLocation is a fixedRef for the rangeEndRefPosition, increment it so that
5567         // we don't think it isn't covering the live range.
5568         // This doesn't handle the case where earlier RefPositions for this Interval are also
5569         // FixedRefs of this regNum, but at least those are only interesting in the case where those
5570         // are "local last uses" of the Interval - otherwise the liveRange would interfere with the reg.
5571         if (nextPhysRefLocation == rangeEndLocation && rangeEndRefPosition->isFixedRefOfReg(regNum))
5572         {
5573             INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_INCREMENT_RANGE_END, currentInterval, regNum));
5574             nextPhysRefLocation++;
5575         }
5576
5577         if ((candidateBit & preferences) != RBM_NONE)
5578         {
5579             score |= OWN_PREFERENCE;
5580             if (nextPhysRefLocation > rangeEndLocation)
5581             {
5582                 score |= COVERS;
5583             }
5584         }
5585         if (relatedInterval != nullptr && (candidateBit & relatedPreferences) != RBM_NONE)
5586         {
5587             score |= RELATED_PREFERENCE;
5588             if (nextPhysRefLocation > relatedInterval->lastRefPosition->nodeLocation)
5589             {
5590                 score |= COVERS_RELATED;
5591             }
5592         }
5593
5594         // If we had a fixed-reg def of a reg that will be killed before the use, prefer it to any other registers
5595         // with the same score.  (Note that we haven't changed the original registerAssignment on the RefPosition).
5596         // Overload the RELATED_PREFERENCE value.
5597         else if (candidateBit == refPosition->registerAssignment)
5598         {
5599             score |= RELATED_PREFERENCE;
5600         }
5601
5602         if ((preferCalleeSave && physRegRecord->isCalleeSave) || (!preferCalleeSave && !physRegRecord->isCalleeSave))
5603         {
5604             score |= CALLER_CALLEE;
5605         }
5606
5607         // The register is considered unassigned if it has no assignedInterval, OR
5608         // if its next reference is beyond the range of this interval.
5609         if (physRegRecord->assignedInterval == nullptr ||
5610             physRegRecord->assignedInterval->getNextRefLocation() > lastLocation)
5611         {
5612             score |= UNASSIGNED;
5613         }
5614
5615         bool foundBetterCandidate = false;
5616
5617         if (score > bestScore)
5618         {
5619             foundBetterCandidate = true;
5620         }
5621         else if (score == bestScore)
5622         {
5623             // Prefer a register that covers the range.
5624             if (bestLocation <= lastLocation)
5625             {
5626                 if (nextPhysRefLocation > bestLocation)
5627                 {
5628                     foundBetterCandidate = true;
5629                 }
5630             }
5631             // If both cover the range, prefer a register that is killed sooner (leaving the longer range register
5632             // available). If both cover the range and also getting killed at the same location, prefer the one which
5633             // is same as previous assignment.
5634             else if (nextPhysRefLocation > lastLocation)
5635             {
5636                 if (nextPhysRefLocation < bestLocation)
5637                 {
5638                     foundBetterCandidate = true;
5639                 }
5640                 else if (nextPhysRefLocation == bestLocation && prevReg == regNum)
5641                 {
5642                     foundBetterCandidate = true;
5643                 }
5644             }
5645         }
5646
5647 #ifdef DEBUG
5648         if (doReverseSelect() && bestScore != 0)
5649         {
5650             foundBetterCandidate = !foundBetterCandidate;
5651         }
5652 #endif // DEBUG
5653
5654         if (foundBetterCandidate)
5655         {
5656             bestLocation             = nextPhysRefLocation;
5657             availablePhysRegInterval = physRegRecord;
5658             intervalToUnassign       = physRegRecord->assignedInterval;
5659             bestScore                = score;
5660         }
5661
5662         // there is no way we can get a better score so break out
5663         if (!reverseSelect && score == bestPossibleScore && bestLocation == rangeEndLocation + 1)
5664         {
5665             break;
5666         }
5667     }
5668
5669     if (availablePhysRegInterval != nullptr)
5670     {
5671         if (intervalToUnassign != nullptr)
5672         {
5673             RegRecord* physRegToUnassign = availablePhysRegInterval;
5674 #ifdef _TARGET_ARM_
5675             // We should unassign a double register if availablePhysRegInterval is part of the double register
5676             if (availablePhysRegInterval->assignedInterval->registerType == TYP_DOUBLE &&
5677                 !genIsValidDoubleReg(availablePhysRegInterval->regNum))
5678                 physRegToUnassign = findAnotherHalfRegRec(availablePhysRegInterval);
5679 #endif
5680             unassignPhysReg(physRegToUnassign, intervalToUnassign->recentRefPosition);
5681             if (bestScore & VALUE_AVAILABLE)
5682             {
5683                 assert(intervalToUnassign->isConstant);
5684                 refPosition->treeNode->SetReuseRegVal();
5685             }
5686             // If we considered this "unassigned" because this interval's lifetime ends before
5687             // the next ref, remember it.
5688             else if ((bestScore & UNASSIGNED) != 0 && intervalToUnassign != nullptr)
5689             {
5690                 updatePreviousInterval(physRegToUnassign, intervalToUnassign, intervalToUnassign->registerType);
5691             }
5692         }
5693         else
5694         {
5695             assert((bestScore & VALUE_AVAILABLE) == 0);
5696         }
5697         assignPhysReg(availablePhysRegInterval, currentInterval);
5698         foundReg                        = availablePhysRegInterval->regNum;
5699         regMaskTP foundRegMask          = genRegMask(foundReg);
5700         refPosition->registerAssignment = foundRegMask;
5701         if (relatedInterval != nullptr)
5702         {
5703             relatedInterval->updateRegisterPreferences(foundRegMask);
5704         }
5705     }
5706
5707     return foundReg;
5708 }
5709
5710 //------------------------------------------------------------------------
5711 // allocateBusyReg: Find a busy register that satisfies the requirements for refPosition,
5712 //                  and that can be spilled.
5713 //
5714 // Arguments:
5715 //    current               The interval for the current allocation
5716 //    refPosition           The RefPosition of the current Interval for which a register is being allocated
5717 //    allocateIfProfitable  If true, a reg may not be allocated if all other ref positions currently
5718 //                          occupying registers are more important than the 'refPosition'.
5719 //
5720 // Return Value:
5721 //    The regNumber allocated to the RefPositon.  Returns REG_NA if no free register is found.
5722 //
5723 // Note:  Currently this routine uses weight and farthest distance of next reference
5724 // to select a ref position for spilling.
5725 // a) if allocateIfProfitable = false
5726 //        The ref position chosen for spilling will be the lowest weight
5727 //        of all and if there is is more than one ref position with the
5728 //        same lowest weight, among them choses the one with farthest
5729 //        distance to its next reference.
5730 //
5731 // b) if allocateIfProfitable = true
5732 //        The ref position chosen for spilling will not only be lowest weight
5733 //        of all but also has a weight lower than 'refPosition'.  If there is
5734 //        no such ref position, reg will not be allocated.
5735 regNumber LinearScan::allocateBusyReg(Interval* current, RefPosition* refPosition, bool allocateIfProfitable)
5736 {
5737     regNumber foundReg = REG_NA;
5738
5739     RegisterType regType     = getRegisterType(current, refPosition);
5740     regMaskTP    candidates  = refPosition->registerAssignment;
5741     regMaskTP    preferences = (current->registerPreferences & candidates);
5742     if (preferences == RBM_NONE)
5743     {
5744         preferences = candidates;
5745     }
5746     if (candidates == RBM_NONE)
5747     {
5748         // This assumes only integer and floating point register types
5749         // if we target a processor with additional register types,
5750         // this would have to change
5751         candidates = allRegs(regType);
5752     }
5753
5754 #ifdef DEBUG
5755     candidates = stressLimitRegs(refPosition, candidates);
5756 #endif // DEBUG
5757
5758     // TODO-CQ: Determine whether/how to take preferences into account in addition to
5759     // prefering the one with the furthest ref position when considering
5760     // a candidate to spill
5761     RegRecord*   farthestRefPhysRegRecord = nullptr;
5762     LsraLocation farthestLocation         = MinLocation;
5763     LsraLocation refLocation              = refPosition->nodeLocation;
5764     unsigned     farthestRefPosWeight;
5765     if (allocateIfProfitable)
5766     {
5767         // If allocating a reg is optional, we will consider those ref positions
5768         // whose weight is less than 'refPosition' for spilling.
5769         farthestRefPosWeight = getWeight(refPosition);
5770     }
5771     else
5772     {
5773         // If allocating a reg is a must, we start off with max weight so
5774         // that the first spill candidate will be selected based on
5775         // farthest distance alone.  Since we start off with farthestLocation
5776         // initialized to MinLocation, the first available ref position
5777         // will be selected as spill candidate and its weight as the
5778         // fathestRefPosWeight.
5779         farthestRefPosWeight = BB_MAX_WEIGHT;
5780     }
5781
5782     for (regNumber regNum : Registers(regType))
5783     {
5784         regMaskTP candidateBit = genRegMask(regNum);
5785         if (!(candidates & candidateBit))
5786         {
5787             continue;
5788         }
5789         RegRecord* physRegRecord = getRegisterRecord(regNum);
5790
5791         if (physRegRecord->isBusyUntilNextKill)
5792         {
5793             continue;
5794         }
5795         Interval* assignedInterval = physRegRecord->assignedInterval;
5796
5797         // If there is a fixed reference at the same location (and it's not due to this reference),
5798         // don't use it.
5799
5800         if (physRegRecord->conflictingFixedRegReference(refPosition))
5801         {
5802             assert(candidates != candidateBit);
5803             continue;
5804         }
5805
5806         LsraLocation physRegNextLocation = MaxLocation;
5807         if (refPosition->isFixedRefOfRegMask(candidateBit))
5808         {
5809             // Either there is a fixed reference due to this node, or one associated with a
5810             // fixed use fed by a def at this node.
5811             // In either case, we must use this register as it's the only candidate
5812             // TODO-CQ: At the time we allocate a register to a fixed-reg def, if it's not going
5813             // to remain live until the use, we should set the candidates to allRegs(regType)
5814             // to avoid a spill - codegen can then insert the copy.
5815             assert(candidates == candidateBit);
5816
5817             // If a refPosition has a fixed reg as its candidate and is also marked
5818             // as allocateIfProfitable, we should allocate fixed reg only if the
5819             // weight of this ref position is greater than the weight of the ref
5820             // position to which fixed reg is assigned.  Such a case would arise
5821             // on x86 under LSRA stress.
5822             if (!allocateIfProfitable)
5823             {
5824                 physRegNextLocation  = MaxLocation;
5825                 farthestRefPosWeight = BB_MAX_WEIGHT;
5826             }
5827         }
5828         else
5829         {
5830             physRegNextLocation = physRegRecord->getNextRefLocation();
5831
5832             // If refPosition requires a fixed register, we should reject all others.
5833             // Otherwise, we will still evaluate all phyRegs though their next location is
5834             // not better than farthestLocation found so far.
5835             //
5836             // TODO: this method should be using an approach similar to tryAllocateFreeReg()
5837             // where it uses a regOrder array to avoid iterating over any but the single
5838             // fixed candidate.
5839             if (refPosition->isFixedRegRef && physRegNextLocation < farthestLocation)
5840             {
5841                 continue;
5842             }
5843         }
5844
5845         // If this register is not assigned to an interval, either
5846         // - it has a FixedReg reference at the current location that is not this reference, OR
5847         // - this is the special case of a fixed loReg, where this interval has a use at the same location
5848         // In either case, we cannot use it
5849
5850         if (assignedInterval == nullptr)
5851         {
5852             RefPosition* nextPhysRegPosition = physRegRecord->getNextRefPosition();
5853
5854 #ifndef _TARGET_ARM64_
5855             // TODO-Cleanup: Revisit this after Issue #3524 is complete
5856             // On ARM64 the nodeLocation is not always == refLocation, Disabling this assert for now.
5857             assert(nextPhysRegPosition->nodeLocation == refLocation && candidateBit != candidates);
5858 #endif
5859             continue;
5860         }
5861
5862         RefPosition* recentAssignedRef = assignedInterval->recentRefPosition;
5863
5864         if (!assignedInterval->isActive)
5865         {
5866             // The assigned interval has a reference at this location - otherwise, we would have found
5867             // this in tryAllocateFreeReg().
5868             // Note that we may or may not have actually handled the reference yet, so it could either
5869             // be recentAssigedRef, or the next reference.
5870             assert(recentAssignedRef != nullptr);
5871             if (recentAssignedRef->nodeLocation != refLocation)
5872             {
5873                 if (recentAssignedRef->nodeLocation + 1 == refLocation)
5874                 {
5875                     assert(recentAssignedRef->delayRegFree);
5876                 }
5877                 else
5878                 {
5879                     RefPosition* nextAssignedRef = recentAssignedRef->nextRefPosition;
5880                     assert(nextAssignedRef != nullptr);
5881                     assert(nextAssignedRef->nodeLocation == refLocation ||
5882                            (nextAssignedRef->nodeLocation + 1 == refLocation && nextAssignedRef->delayRegFree));
5883                 }
5884             }
5885             continue;
5886         }
5887
5888         // If we have a recentAssignedRef, check that it is going to be OK to spill it
5889         //
5890         // TODO-Review: Under what conditions recentAssginedRef would be null?
5891         unsigned recentAssignedRefWeight = BB_ZERO_WEIGHT;
5892         if (recentAssignedRef != nullptr)
5893         {
5894             if (recentAssignedRef->nodeLocation == refLocation)
5895             {
5896                 // We can't spill a register that's being used at the current location
5897                 RefPosition* physRegRef = physRegRecord->recentRefPosition;
5898                 continue;
5899             }
5900
5901             // If the current position has the candidate register marked to be delayed,
5902             // check if the previous location is using this register, if that's the case we have to skip
5903             // since we can't spill this register.
5904             if (recentAssignedRef->delayRegFree && (refLocation == recentAssignedRef->nodeLocation + 1))
5905             {
5906                 continue;
5907             }
5908
5909             // We don't prefer to spill a register if the weight of recentAssignedRef > weight
5910             // of the spill candidate found so far.  We would consider spilling a greater weight
5911             // ref position only if the refPosition being allocated must need a reg.
5912             recentAssignedRefWeight = getWeight(recentAssignedRef);
5913             if (recentAssignedRefWeight > farthestRefPosWeight)
5914             {
5915                 continue;
5916             }
5917         }
5918
5919         RefPosition* nextRefPosition = assignedInterval->getNextRefPosition();
5920         LsraLocation nextLocation    = assignedInterval->getNextRefLocation();
5921
5922         // We should never spill a register that's occupied by an Interval with its next use at the current location.
5923         // Normally this won't occur (unless we actually had more uses in a single node than there are registers),
5924         // because we'll always find something with a later nextLocation, but it can happen in stress when
5925         // we have LSRA_SELECT_NEAREST.
5926         if ((nextLocation == refLocation) && !refPosition->isFixedRegRef && nextRefPosition->RequiresRegister())
5927         {
5928             continue;
5929         }
5930
5931         if (nextLocation > physRegNextLocation)
5932         {
5933             nextLocation = physRegNextLocation;
5934         }
5935
5936         bool isBetterLocation;
5937
5938 #ifdef DEBUG
5939         if (doSelectNearest() && farthestRefPhysRegRecord != nullptr)
5940         {
5941             isBetterLocation = (nextLocation <= farthestLocation);
5942         }
5943         else
5944 #endif
5945             // This if-stmt is associated with the above else
5946             if (recentAssignedRefWeight < farthestRefPosWeight)
5947         {
5948             isBetterLocation = true;
5949         }
5950         else
5951         {
5952             // This would mean the weight of spill ref position we found so far is equal
5953             // to the weight of the ref position that is being evaluated.  In this case
5954             // we prefer to spill ref position whose distance to its next reference is
5955             // the farthest.
5956             assert(recentAssignedRefWeight == farthestRefPosWeight);
5957
5958             // If allocateIfProfitable=true, the first spill candidate selected
5959             // will be based on weight alone. After we have found a spill
5960             // candidate whose weight is less than the 'refPosition', we will
5961             // consider farthest distance when there is a tie in weights.
5962             // This is to ensure that we don't spill a ref position whose
5963             // weight is equal to weight of 'refPosition'.
5964             if (allocateIfProfitable && farthestRefPhysRegRecord == nullptr)
5965             {
5966                 isBetterLocation = false;
5967             }
5968             else
5969             {
5970                 isBetterLocation = (nextLocation > farthestLocation);
5971
5972                 if (nextLocation > farthestLocation)
5973                 {
5974                     isBetterLocation = true;
5975                 }
5976                 else if (nextLocation == farthestLocation)
5977                 {
5978                     // Both weight and distance are equal.
5979                     // Prefer that ref position which is marked both reload and
5980                     // allocate if profitable.  These ref positions don't need
5981                     // need to be spilled as they are already in memory and
5982                     // codegen considers them as contained memory operands.
5983                     isBetterLocation = (recentAssignedRef != nullptr) && recentAssignedRef->reload &&
5984                                        recentAssignedRef->AllocateIfProfitable();
5985                 }
5986                 else
5987                 {
5988                     isBetterLocation = false;
5989                 }
5990             }
5991         }
5992
5993         if (isBetterLocation)
5994         {
5995             farthestLocation         = nextLocation;
5996             farthestRefPhysRegRecord = physRegRecord;
5997             farthestRefPosWeight     = recentAssignedRefWeight;
5998         }
5999     }
6000
6001 #if DEBUG
6002     if (allocateIfProfitable)
6003     {
6004         // There may not be a spill candidate or if one is found
6005         // its weight must be less than the weight of 'refPosition'
6006         assert((farthestRefPhysRegRecord == nullptr) || (farthestRefPosWeight < getWeight(refPosition)));
6007     }
6008     else
6009     {
6010         // Must have found a spill candidate.
6011         assert(farthestRefPhysRegRecord != nullptr);
6012         if ((farthestLocation == refLocation) && !refPosition->isFixedRegRef)
6013         {
6014             Interval*    assignedInterval = farthestRefPhysRegRecord->assignedInterval;
6015             RefPosition* nextRefPosition  = assignedInterval->getNextRefPosition();
6016             assert(!nextRefPosition->RequiresRegister());
6017         }
6018         else
6019         {
6020             assert(farthestLocation > refLocation || refPosition->isFixedRegRef);
6021         }
6022     }
6023 #endif
6024
6025     if (farthestRefPhysRegRecord != nullptr)
6026     {
6027         foundReg = farthestRefPhysRegRecord->regNum;
6028         unassignPhysReg(farthestRefPhysRegRecord, farthestRefPhysRegRecord->assignedInterval->recentRefPosition);
6029         assignPhysReg(farthestRefPhysRegRecord, current);
6030         refPosition->registerAssignment = genRegMask(foundReg);
6031     }
6032     else
6033     {
6034         foundReg                        = REG_NA;
6035         refPosition->registerAssignment = RBM_NONE;
6036     }
6037
6038     return foundReg;
6039 }
6040
6041 // Grab a register to use to copy and then immediately use.
6042 // This is called only for localVar intervals that already have a register
6043 // assignment that is not compatible with the current RefPosition.
6044 // This is not like regular assignment, because we don't want to change
6045 // any preferences or existing register assignments.
6046 // Prefer a free register that's got the earliest next use.
6047 // Otherwise, spill something with the farthest next use
6048 //
6049 regNumber LinearScan::assignCopyReg(RefPosition* refPosition)
6050 {
6051     Interval* currentInterval = refPosition->getInterval();
6052     assert(currentInterval != nullptr);
6053     assert(currentInterval->isActive);
6054
6055     bool         foundFreeReg = false;
6056     RegRecord*   bestPhysReg  = nullptr;
6057     LsraLocation bestLocation = MinLocation;
6058     regMaskTP    candidates   = refPosition->registerAssignment;
6059
6060     // Save the relatedInterval, if any, so that it doesn't get modified during allocation.
6061     Interval* savedRelatedInterval   = currentInterval->relatedInterval;
6062     currentInterval->relatedInterval = nullptr;
6063
6064     // We don't want really want to change the default assignment,
6065     // so 1) pretend this isn't active, and 2) remember the old reg
6066     regNumber  oldPhysReg   = currentInterval->physReg;
6067     RegRecord* oldRegRecord = currentInterval->assignedReg;
6068     assert(oldRegRecord->regNum == oldPhysReg);
6069     currentInterval->isActive = false;
6070
6071     regNumber allocatedReg = tryAllocateFreeReg(currentInterval, refPosition);
6072     if (allocatedReg == REG_NA)
6073     {
6074         allocatedReg = allocateBusyReg(currentInterval, refPosition, false);
6075     }
6076
6077     // Now restore the old info
6078     currentInterval->relatedInterval = savedRelatedInterval;
6079     currentInterval->physReg         = oldPhysReg;
6080     currentInterval->assignedReg     = oldRegRecord;
6081     currentInterval->isActive        = true;
6082
6083     refPosition->copyReg = true;
6084     return allocatedReg;
6085 }
6086
6087 // Check if the interval is already assigned and if it is then unassign the physical record
6088 // then set the assignedInterval to 'interval'
6089 //
6090 void LinearScan::checkAndAssignInterval(RegRecord* regRec, Interval* interval)
6091 {
6092     if (regRec->assignedInterval != nullptr && regRec->assignedInterval != interval)
6093     {
6094         // This is allocated to another interval.  Either it is inactive, or it was allocated as a
6095         // copyReg and is therefore not the "assignedReg" of the other interval.  In the latter case,
6096         // we simply unassign it - in the former case we need to set the physReg on the interval to
6097         // REG_NA to indicate that it is no longer in that register.
6098         // The lack of checking for this case resulted in an assert in the retail version of System.dll,
6099         // in method SerialStream.GetDcbFlag.
6100         // Note that we can't check for the copyReg case, because we may have seen a more recent
6101         // RefPosition for the Interval that was NOT a copyReg.
6102         if (regRec->assignedInterval->assignedReg == regRec)
6103         {
6104             assert(regRec->assignedInterval->isActive == false);
6105             regRec->assignedInterval->physReg = REG_NA;
6106         }
6107         unassignPhysReg(regRec->regNum);
6108     }
6109
6110     updateAssignedInterval(regRec, interval, interval->registerType);
6111 }
6112
6113 // Assign the given physical register interval to the given interval
6114 void LinearScan::assignPhysReg(RegRecord* regRec, Interval* interval)
6115 {
6116     regMaskTP assignedRegMask = genRegMask(regRec->regNum);
6117     compiler->codeGen->regSet.rsSetRegsModified(assignedRegMask DEBUGARG(dumpTerse));
6118
6119     checkAndAssignInterval(regRec, interval);
6120     interval->assignedReg = regRec;
6121
6122     interval->physReg  = regRec->regNum;
6123     interval->isActive = true;
6124     if (interval->isLocalVar)
6125     {
6126         // Prefer this register for future references
6127         interval->updateRegisterPreferences(assignedRegMask);
6128     }
6129 }
6130
6131 //------------------------------------------------------------------------
6132 // setIntervalAsSplit: Set this Interval as being split
6133 //
6134 // Arguments:
6135 //    interval - The Interval which is being split
6136 //
6137 // Return Value:
6138 //    None.
6139 //
6140 // Notes:
6141 //    The given Interval will be marked as split, and it will be added to the
6142 //    set of splitOrSpilledVars.
6143 //
6144 // Assumptions:
6145 //    "interval" must be a lclVar interval, as tree temps are never split.
6146 //    This is asserted in the call to getVarIndex().
6147 //
6148 void LinearScan::setIntervalAsSplit(Interval* interval)
6149 {
6150     if (interval->isLocalVar)
6151     {
6152         unsigned varIndex = interval->getVarIndex(compiler);
6153         if (!interval->isSplit)
6154         {
6155             VarSetOps::AddElemD(compiler, splitOrSpilledVars, varIndex);
6156         }
6157         else
6158         {
6159             assert(VarSetOps::IsMember(compiler, splitOrSpilledVars, varIndex));
6160         }
6161     }
6162     interval->isSplit = true;
6163 }
6164
6165 //------------------------------------------------------------------------
6166 // setIntervalAsSpilled: Set this Interval as being spilled
6167 //
6168 // Arguments:
6169 //    interval - The Interval which is being spilled
6170 //
6171 // Return Value:
6172 //    None.
6173 //
6174 // Notes:
6175 //    The given Interval will be marked as spilled, and it will be added
6176 //    to the set of splitOrSpilledVars.
6177 //
6178 void LinearScan::setIntervalAsSpilled(Interval* interval)
6179 {
6180     if (interval->isLocalVar)
6181     {
6182         unsigned varIndex = interval->getVarIndex(compiler);
6183         if (!interval->isSpilled)
6184         {
6185             VarSetOps::AddElemD(compiler, splitOrSpilledVars, varIndex);
6186         }
6187         else
6188         {
6189             assert(VarSetOps::IsMember(compiler, splitOrSpilledVars, varIndex));
6190         }
6191     }
6192     interval->isSpilled = true;
6193 }
6194
6195 //------------------------------------------------------------------------
6196 // spill: Spill this Interval between "fromRefPosition" and "toRefPosition"
6197 //
6198 // Arguments:
6199 //    fromRefPosition - The RefPosition at which the Interval is to be spilled
6200 //    toRefPosition   - The RefPosition at which it must be reloaded
6201 //
6202 // Return Value:
6203 //    None.
6204 //
6205 // Assumptions:
6206 //    fromRefPosition and toRefPosition must not be null
6207 //
6208 void LinearScan::spillInterval(Interval* interval, RefPosition* fromRefPosition, RefPosition* toRefPosition)
6209 {
6210     assert(fromRefPosition != nullptr && toRefPosition != nullptr);
6211     assert(fromRefPosition->getInterval() == interval && toRefPosition->getInterval() == interval);
6212     assert(fromRefPosition->nextRefPosition == toRefPosition);
6213
6214     if (!fromRefPosition->lastUse)
6215     {
6216         // If not allocated a register, Lcl var def/use ref positions even if reg optional
6217         // should be marked as spillAfter.
6218         if (!fromRefPosition->RequiresRegister() && !(interval->isLocalVar && fromRefPosition->IsActualRef()))
6219         {
6220             fromRefPosition->registerAssignment = RBM_NONE;
6221         }
6222         else
6223         {
6224             fromRefPosition->spillAfter = true;
6225         }
6226     }
6227     assert(toRefPosition != nullptr);
6228
6229 #ifdef DEBUG
6230     if (VERBOSE)
6231     {
6232         dumpLsraAllocationEvent(LSRA_EVENT_SPILL, interval);
6233     }
6234 #endif // DEBUG
6235
6236     INTRACK_STATS(updateLsraStat(LSRA_STAT_SPILL, fromRefPosition->bbNum));
6237
6238     interval->isActive = false;
6239     setIntervalAsSpilled(interval);
6240
6241     // If fromRefPosition occurs before the beginning of this block, mark this as living in the stack
6242     // on entry to this block.
6243     if (fromRefPosition->nodeLocation <= curBBStartLocation)
6244     {
6245         // This must be a lclVar interval
6246         assert(interval->isLocalVar);
6247         setInVarRegForBB(curBBNum, interval->varNum, REG_STK);
6248     }
6249 }
6250
6251 //------------------------------------------------------------------------
6252 // unassignPhysRegNoSpill: Unassign the given physical register record from
6253 //                         an active interval, without spilling.
6254 //
6255 // Arguments:
6256 //    regRec           - the RegRecord to be unasssigned
6257 //
6258 // Return Value:
6259 //    None.
6260 //
6261 // Assumptions:
6262 //    The assignedInterval must not be null, and must be active.
6263 //
6264 // Notes:
6265 //    This method is used to unassign a register when an interval needs to be moved to a
6266 //    different register, but not (yet) spilled.
6267
6268 void LinearScan::unassignPhysRegNoSpill(RegRecord* regRec)
6269 {
6270     Interval* assignedInterval = regRec->assignedInterval;
6271     assert(assignedInterval != nullptr && assignedInterval->isActive);
6272     assignedInterval->isActive = false;
6273     unassignPhysReg(regRec, nullptr);
6274     assignedInterval->isActive = true;
6275 }
6276
6277 //------------------------------------------------------------------------
6278 // checkAndClearInterval: Clear the assignedInterval for the given
6279 //                        physical register record
6280 //
6281 // Arguments:
6282 //    regRec           - the physical RegRecord to be unasssigned
6283 //    spillRefPosition - The RefPosition at which the assignedInterval is to be spilled
6284 //                       or nullptr if we aren't spilling
6285 //
6286 // Return Value:
6287 //    None.
6288 //
6289 // Assumptions:
6290 //    see unassignPhysReg
6291 //
6292 void LinearScan::checkAndClearInterval(RegRecord* regRec, RefPosition* spillRefPosition)
6293 {
6294     Interval* assignedInterval = regRec->assignedInterval;
6295     assert(assignedInterval != nullptr);
6296     regNumber thisRegNum = regRec->regNum;
6297
6298     if (spillRefPosition == nullptr)
6299     {
6300         // Note that we can't assert  for the copyReg case
6301         //
6302         if (assignedInterval->physReg == thisRegNum)
6303         {
6304             assert(assignedInterval->isActive == false);
6305         }
6306     }
6307     else
6308     {
6309         assert(spillRefPosition->getInterval() == assignedInterval);
6310     }
6311
6312     updateAssignedInterval(regRec, nullptr, assignedInterval->registerType);
6313 }
6314
6315 //------------------------------------------------------------------------
6316 // unassignPhysReg: Unassign the given physical register record, and spill the
6317 //                  assignedInterval at the given spillRefPosition, if any.
6318 //
6319 // Arguments:
6320 //    regRec           - the RegRecord to be unasssigned
6321 //    spillRefPosition - The RefPosition at which the assignedInterval is to be spilled
6322 //
6323 // Return Value:
6324 //    None.
6325 //
6326 // Assumptions:
6327 //    The assignedInterval must not be null.
6328 //    If spillRefPosition is null, the assignedInterval must be inactive, or not currently
6329 //    assigned to this register (e.g. this is a copyReg for that Interval).
6330 //    Otherwise, spillRefPosition must be associated with the assignedInterval.
6331 //
6332 void LinearScan::unassignPhysReg(RegRecord* regRec, RefPosition* spillRefPosition)
6333 {
6334     Interval* assignedInterval = regRec->assignedInterval;
6335     assert(assignedInterval != nullptr);
6336
6337     regNumber thisRegNum = regRec->regNum;
6338
6339 #ifdef _TARGET_ARM_
6340     regNumber  nextRegNum = REG_NA;
6341     RegRecord* nextRegRec = nullptr;
6342
6343     // Prepare second half RegRecord of a double register for TYP_DOUBLE
6344     if (assignedInterval->registerType == TYP_DOUBLE)
6345     {
6346         assert(isFloatRegType(regRec->registerType));
6347         assert(genIsValidDoubleReg(regRec->regNum));
6348
6349         nextRegNum = REG_NEXT(regRec->regNum);
6350         nextRegRec = getRegisterRecord(nextRegNum);
6351
6352         // Both two RegRecords should have been assigned to the same interval.
6353         assert(assignedInterval == nextRegRec->assignedInterval);
6354     }
6355 #endif // _TARGET_ARM_
6356
6357     checkAndClearInterval(regRec, spillRefPosition);
6358
6359 #ifdef _TARGET_ARM_
6360     if (assignedInterval->registerType == TYP_DOUBLE)
6361     {
6362         // Both two RegRecords should have been unassigned together.
6363         assert(regRec->assignedInterval == nullptr);
6364         assert(nextRegRec->assignedInterval == nullptr);
6365     }
6366 #endif // _TARGET_ARM_
6367
6368 #ifdef DEBUG
6369     if (VERBOSE && !dumpTerse)
6370     {
6371         printf("unassigning %s: ", getRegName(regRec->regNum));
6372         assignedInterval->dump();
6373         printf("\n");
6374     }
6375 #endif // DEBUG
6376
6377     RefPosition* nextRefPosition = nullptr;
6378     if (spillRefPosition != nullptr)
6379     {
6380         nextRefPosition = spillRefPosition->nextRefPosition;
6381     }
6382
6383     if (assignedInterval->physReg != REG_NA && assignedInterval->physReg != thisRegNum)
6384     {
6385         // This must have been a temporary copy reg, but we can't assert that because there
6386         // may have been intervening RefPositions that were not copyRegs.
6387
6388         // reg->assignedInterval has already been set to nullptr by checkAndClearInterval()
6389         assert(regRec->assignedInterval == nullptr);
6390         return;
6391     }
6392
6393     regNumber victimAssignedReg = assignedInterval->physReg;
6394     assignedInterval->physReg   = REG_NA;
6395
6396     bool spill = assignedInterval->isActive && nextRefPosition != nullptr;
6397     if (spill)
6398     {
6399         // If this is an active interval, it must have a recentRefPosition,
6400         // otherwise it would not be active
6401         assert(spillRefPosition != nullptr);
6402
6403 #if 0
6404         // TODO-CQ: Enable this and insert an explicit GT_COPY (otherwise there's no way to communicate
6405         // to codegen that we want the copyReg to be the new home location).
6406         // If the last reference was a copyReg, and we're spilling the register
6407         // it was copied from, then make the copyReg the new primary location
6408         // if possible
6409         if (spillRefPosition->copyReg)
6410         {
6411             regNumber copyFromRegNum = victimAssignedReg;
6412             regNumber copyRegNum = genRegNumFromMask(spillRefPosition->registerAssignment);
6413             if (copyFromRegNum == thisRegNum &&
6414                 getRegisterRecord(copyRegNum)->assignedInterval == assignedInterval)
6415             {
6416                 assert(copyRegNum != thisRegNum);
6417                 assignedInterval->physReg = copyRegNum;
6418                 assignedInterval->assignedReg = this->getRegisterRecord(copyRegNum);
6419                 return;
6420             }
6421         }
6422 #endif // 0
6423 #ifdef DEBUG
6424         // With JitStressRegs == 0x80 (LSRA_EXTEND_LIFETIMES), we may have a RefPosition
6425         // that is not marked lastUse even though the treeNode is a lastUse.  In that case
6426         // we must not mark it for spill because the register will have been immediately freed
6427         // after use.  While we could conceivably add special handling for this case in codegen,
6428         // it would be messy and undesirably cause the "bleeding" of LSRA stress modes outside
6429         // of LSRA.
6430         if (extendLifetimes() && assignedInterval->isLocalVar && RefTypeIsUse(spillRefPosition->refType) &&
6431             spillRefPosition->treeNode != nullptr && (spillRefPosition->treeNode->gtFlags & GTF_VAR_DEATH) != 0)
6432         {
6433             dumpLsraAllocationEvent(LSRA_EVENT_SPILL_EXTENDED_LIFETIME, assignedInterval);
6434             assignedInterval->isActive = false;
6435             spill                      = false;
6436             // If the spillRefPosition occurs before the beginning of this block, it will have
6437             // been marked as living in this register on entry to this block, but we now need
6438             // to mark this as living on the stack.
6439             if (spillRefPosition->nodeLocation <= curBBStartLocation)
6440             {
6441                 setInVarRegForBB(curBBNum, assignedInterval->varNum, REG_STK);
6442                 if (spillRefPosition->nextRefPosition != nullptr)
6443                 {
6444                     setIntervalAsSpilled(assignedInterval);
6445                 }
6446             }
6447             else
6448             {
6449                 // Otherwise, we need to mark spillRefPosition as lastUse, or the interval
6450                 // will remain active beyond its allocated range during the resolution phase.
6451                 spillRefPosition->lastUse = true;
6452             }
6453         }
6454         else
6455 #endif // DEBUG
6456         {
6457             spillInterval(assignedInterval, spillRefPosition, nextRefPosition);
6458         }
6459     }
6460     // Maintain the association with the interval, if it has more references.
6461     // Or, if we "remembered" an interval assigned to this register, restore it.
6462     if (nextRefPosition != nullptr)
6463     {
6464         assignedInterval->assignedReg = regRec;
6465     }
6466     else if (canRestorePreviousInterval(regRec, assignedInterval))
6467     {
6468         regRec->assignedInterval = regRec->previousInterval;
6469         regRec->previousInterval = nullptr;
6470
6471 #ifdef _TARGET_ARM_
6472         // Note:
6473         //   We can not use updateAssignedInterval() and updatePreviousInterval() here,
6474         //   because regRec may not be a even-numbered float register.
6475
6476         // Update second half RegRecord of a double register for TYP_DOUBLE
6477         if (regRec->assignedInterval->registerType == TYP_DOUBLE)
6478         {
6479             RegRecord* anotherHalfRegRec = findAnotherHalfRegRec(regRec);
6480
6481             anotherHalfRegRec->assignedInterval = regRec->assignedInterval;
6482             anotherHalfRegRec->previousInterval = nullptr;
6483         }
6484 #endif // _TARGET_ARM_
6485
6486 #ifdef DEBUG
6487         if (spill)
6488         {
6489             dumpLsraAllocationEvent(LSRA_EVENT_RESTORE_PREVIOUS_INTERVAL_AFTER_SPILL, regRec->assignedInterval,
6490                                     thisRegNum);
6491         }
6492         else
6493         {
6494             dumpLsraAllocationEvent(LSRA_EVENT_RESTORE_PREVIOUS_INTERVAL, regRec->assignedInterval, thisRegNum);
6495         }
6496 #endif // DEBUG
6497     }
6498     else
6499     {
6500         updateAssignedInterval(regRec, nullptr, assignedInterval->registerType);
6501         updatePreviousInterval(regRec, nullptr, assignedInterval->registerType);
6502     }
6503 }
6504
6505 //------------------------------------------------------------------------
6506 // spillGCRefs: Spill any GC-type intervals that are currently in registers.a
6507 //
6508 // Arguments:
6509 //    killRefPosition - The RefPosition for the kill
6510 //
6511 // Return Value:
6512 //    None.
6513 //
6514 void LinearScan::spillGCRefs(RefPosition* killRefPosition)
6515 {
6516     // For each physical register that can hold a GC type,
6517     // if it is occupied by an interval of a GC type, spill that interval.
6518     regMaskTP candidateRegs = killRefPosition->registerAssignment;
6519     while (candidateRegs != RBM_NONE)
6520     {
6521         regMaskTP nextRegBit = genFindLowestBit(candidateRegs);
6522         candidateRegs &= ~nextRegBit;
6523         regNumber  nextReg          = genRegNumFromMask(nextRegBit);
6524         RegRecord* regRecord        = getRegisterRecord(nextReg);
6525         Interval*  assignedInterval = regRecord->assignedInterval;
6526         if (assignedInterval == nullptr || (assignedInterval->isActive == false) ||
6527             !varTypeIsGC(assignedInterval->registerType))
6528         {
6529             continue;
6530         }
6531         unassignPhysReg(regRecord, assignedInterval->recentRefPosition);
6532     }
6533     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DONE_KILL_GC_REFS, nullptr, REG_NA, nullptr));
6534 }
6535
6536 //------------------------------------------------------------------------
6537 // processBlockEndAllocation: Update var locations after 'currentBlock' has been allocated
6538 //
6539 // Arguments:
6540 //    currentBlock - the BasicBlock we have just finished allocating registers for
6541 //
6542 // Return Value:
6543 //    None
6544 //
6545 // Notes:
6546 //    Calls processBlockEndLocations() to set the outVarToRegMap, then gets the next block,
6547 //    and sets the inVarToRegMap appropriately.
6548
6549 void LinearScan::processBlockEndAllocation(BasicBlock* currentBlock)
6550 {
6551     assert(currentBlock != nullptr);
6552     if (enregisterLocalVars)
6553     {
6554         processBlockEndLocations(currentBlock);
6555     }
6556     markBlockVisited(currentBlock);
6557
6558     // Get the next block to allocate.
6559     // When the last block in the method has successors, there will be a final "RefTypeBB" to
6560     // ensure that we get the varToRegMap set appropriately, but in that case we don't need
6561     // to worry about "nextBlock".
6562     BasicBlock* nextBlock = getNextBlock();
6563     if (nextBlock != nullptr)
6564     {
6565         processBlockStartLocations(nextBlock, true);
6566     }
6567 }
6568
6569 //------------------------------------------------------------------------
6570 // rotateBlockStartLocation: When in the LSRA_BLOCK_BOUNDARY_ROTATE stress mode, attempt to
6571 //                           "rotate" the register assignment for a localVar to the next higher
6572 //                           register that is available.
6573 //
6574 // Arguments:
6575 //    interval      - the Interval for the variable whose register is getting rotated
6576 //    targetReg     - its register assignment from the predecessor block being used for live-in
6577 //    availableRegs - registers available for use
6578 //
6579 // Return Value:
6580 //    The new register to use.
6581
6582 #ifdef DEBUG
6583 regNumber LinearScan::rotateBlockStartLocation(Interval* interval, regNumber targetReg, regMaskTP availableRegs)
6584 {
6585     if (targetReg != REG_STK && getLsraBlockBoundaryLocations() == LSRA_BLOCK_BOUNDARY_ROTATE)
6586     {
6587         // If we're rotating the register locations at block boundaries, try to use
6588         // the next higher register number of the appropriate register type.
6589         regMaskTP candidateRegs = allRegs(interval->registerType) & availableRegs;
6590         regNumber firstReg      = REG_NA;
6591         regNumber newReg        = REG_NA;
6592         while (candidateRegs != RBM_NONE)
6593         {
6594             regMaskTP nextRegBit = genFindLowestBit(candidateRegs);
6595             candidateRegs &= ~nextRegBit;
6596             regNumber nextReg = genRegNumFromMask(nextRegBit);
6597             if (nextReg > targetReg)
6598             {
6599                 newReg = nextReg;
6600                 break;
6601             }
6602             else if (firstReg == REG_NA)
6603             {
6604                 firstReg = nextReg;
6605             }
6606         }
6607         if (newReg == REG_NA)
6608         {
6609             assert(firstReg != REG_NA);
6610             newReg = firstReg;
6611         }
6612         targetReg = newReg;
6613     }
6614     return targetReg;
6615 }
6616 #endif // DEBUG
6617
6618 #ifdef _TARGET_ARM_
6619 //--------------------------------------------------------------------------------------
6620 // isSecondHalfReg: Test if recRec is second half of double register
6621 //                  which is assigned to an interval.
6622 //
6623 // Arguments:
6624 //    regRec - a register to be tested
6625 //    interval - an interval which is assigned to some register
6626 //
6627 // Assumptions:
6628 //    None
6629 //
6630 // Return Value:
6631 //    True only if regRec is second half of assignedReg in interval
6632 //
6633 bool LinearScan::isSecondHalfReg(RegRecord* regRec, Interval* interval)
6634 {
6635     RegRecord* assignedReg = interval->assignedReg;
6636
6637     if (assignedReg != nullptr && interval->registerType == TYP_DOUBLE)
6638     {
6639         // interval should have been allocated to a valid double register
6640         assert(genIsValidDoubleReg(assignedReg->regNum));
6641
6642         // Find a second half RegRecord of double register
6643         regNumber firstRegNum  = assignedReg->regNum;
6644         regNumber secondRegNum = REG_NEXT(firstRegNum);
6645
6646         assert(genIsValidFloatReg(secondRegNum) && !genIsValidDoubleReg(secondRegNum));
6647
6648         RegRecord* secondRegRec = getRegisterRecord(secondRegNum);
6649
6650         return secondRegRec == regRec;
6651     }
6652
6653     return false;
6654 }
6655
6656 //------------------------------------------------------------------------------------------
6657 // findAnotherHalfRegRec: Find another half RegRecord which forms same ARM32 double register
6658 //
6659 // Arguments:
6660 //    regRec - A float RegRecord
6661 //
6662 // Assumptions:
6663 //    None
6664 //
6665 // Return Value:
6666 //    A RegRecord which forms same double register with regRec
6667 //
6668 RegRecord* LinearScan::findAnotherHalfRegRec(RegRecord* regRec)
6669 {
6670     regNumber  anotherHalfRegNum;
6671     RegRecord* anotherHalfRegRec;
6672
6673     assert(genIsValidFloatReg(regRec->regNum));
6674
6675     // Find another half register for TYP_DOUBLE interval,
6676     // following same logic in canRestorePreviousInterval().
6677     if (genIsValidDoubleReg(regRec->regNum))
6678     {
6679         anotherHalfRegNum = REG_NEXT(regRec->regNum);
6680         assert(!genIsValidDoubleReg(anotherHalfRegNum));
6681     }
6682     else
6683     {
6684         anotherHalfRegNum = REG_PREV(regRec->regNum);
6685         assert(genIsValidDoubleReg(anotherHalfRegNum));
6686     }
6687     anotherHalfRegRec = getRegisterRecord(anotherHalfRegNum);
6688
6689     return anotherHalfRegRec;
6690 }
6691 #endif
6692
6693 //--------------------------------------------------------------------------------------
6694 // canRestorePreviousInterval: Test if we can restore previous interval
6695 //
6696 // Arguments:
6697 //    regRec - a register which contains previous interval to be restored
6698 //    assignedInterval - an interval just unassigned
6699 //
6700 // Assumptions:
6701 //    None
6702 //
6703 // Return Value:
6704 //    True only if previous interval of regRec can be restored
6705 //
6706 bool LinearScan::canRestorePreviousInterval(RegRecord* regRec, Interval* assignedInterval)
6707 {
6708     bool retVal =
6709         (regRec->previousInterval != nullptr && regRec->previousInterval != assignedInterval &&
6710          regRec->previousInterval->assignedReg == regRec && regRec->previousInterval->getNextRefPosition() != nullptr);
6711
6712 #ifdef _TARGET_ARM_
6713     if (retVal && regRec->previousInterval->registerType == TYP_DOUBLE)
6714     {
6715         RegRecord* anotherHalfRegRec = findAnotherHalfRegRec(regRec);
6716
6717         retVal = retVal && anotherHalfRegRec->assignedInterval == nullptr;
6718     }
6719 #endif
6720
6721     return retVal;
6722 }
6723
6724 bool LinearScan::isAssignedToInterval(Interval* interval, RegRecord* regRec)
6725 {
6726     bool isAssigned = (interval->assignedReg == regRec);
6727 #ifdef _TARGET_ARM_
6728     isAssigned |= isSecondHalfReg(regRec, interval);
6729 #endif
6730     return isAssigned;
6731 }
6732
6733 //------------------------------------------------------------------------
6734 // processBlockStartLocations: Update var locations on entry to 'currentBlock' and clear constant
6735 //                             registers.
6736 //
6737 // Arguments:
6738 //    currentBlock   - the BasicBlock we are about to allocate registers for
6739 //    allocationPass - true if we are currently allocating registers (versus writing them back)
6740 //
6741 // Return Value:
6742 //    None
6743 //
6744 // Notes:
6745 //    During the allocation pass, we use the outVarToRegMap of the selected predecessor to
6746 //    determine the lclVar locations for the inVarToRegMap.
6747 //    During the resolution (write-back) pass, we only modify the inVarToRegMap in cases where
6748 //    a lclVar was spilled after the block had been completed.
6749 void LinearScan::processBlockStartLocations(BasicBlock* currentBlock, bool allocationPass)
6750 {
6751     // If we have no register candidates we should only call this method during allocation.
6752
6753     assert(enregisterLocalVars || allocationPass);
6754
6755     if (!enregisterLocalVars)
6756     {
6757         // Just clear any constant registers and return.
6758         for (regNumber reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
6759         {
6760             RegRecord* physRegRecord    = getRegisterRecord(reg);
6761             Interval*  assignedInterval = physRegRecord->assignedInterval;
6762
6763             if (assignedInterval != nullptr)
6764             {
6765                 assert(assignedInterval->isConstant);
6766                 physRegRecord->assignedInterval = nullptr;
6767             }
6768         }
6769         INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_START_BB, nullptr, REG_NA, currentBlock));
6770         return;
6771     }
6772
6773     unsigned    predBBNum         = blockInfo[currentBlock->bbNum].predBBNum;
6774     VarToRegMap predVarToRegMap   = getOutVarToRegMap(predBBNum);
6775     VarToRegMap inVarToRegMap     = getInVarToRegMap(currentBlock->bbNum);
6776     bool        hasCriticalInEdge = blockInfo[currentBlock->bbNum].hasCriticalInEdge;
6777
6778     VarSetOps::AssignNoCopy(compiler, currentLiveVars,
6779                             VarSetOps::Intersection(compiler, registerCandidateVars, currentBlock->bbLiveIn));
6780 #ifdef DEBUG
6781     if (getLsraExtendLifeTimes())
6782     {
6783         VarSetOps::AssignNoCopy(compiler, currentLiveVars, registerCandidateVars);
6784     }
6785     // If we are rotating register assignments at block boundaries, we want to make the
6786     // inactive registers available for the rotation.
6787     regMaskTP inactiveRegs = RBM_NONE;
6788 #endif // DEBUG
6789     regMaskTP       liveRegs = RBM_NONE;
6790     VarSetOps::Iter iter(compiler, currentLiveVars);
6791     unsigned        varIndex = 0;
6792     while (iter.NextElem(&varIndex))
6793     {
6794         unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
6795         if (!compiler->lvaTable[varNum].lvLRACandidate)
6796         {
6797             continue;
6798         }
6799         regNumber    targetReg;
6800         Interval*    interval        = getIntervalForLocalVar(varIndex);
6801         RefPosition* nextRefPosition = interval->getNextRefPosition();
6802         assert(nextRefPosition != nullptr);
6803
6804         if (allocationPass)
6805         {
6806             targetReg = getVarReg(predVarToRegMap, varIndex);
6807 #ifdef DEBUG
6808             regNumber newTargetReg = rotateBlockStartLocation(interval, targetReg, (~liveRegs | inactiveRegs));
6809             if (newTargetReg != targetReg)
6810             {
6811                 targetReg = newTargetReg;
6812                 setIntervalAsSplit(interval);
6813             }
6814 #endif // DEBUG
6815             setVarReg(inVarToRegMap, varIndex, targetReg);
6816         }
6817         else // !allocationPass (i.e. resolution/write-back pass)
6818         {
6819             targetReg = getVarReg(inVarToRegMap, varIndex);
6820             // There are four cases that we need to consider during the resolution pass:
6821             // 1. This variable had a register allocated initially, and it was not spilled in the RefPosition
6822             //    that feeds this block.  In this case, both targetReg and predVarToRegMap[varIndex] will be targetReg.
6823             // 2. This variable had not been spilled prior to the end of predBB, but was later spilled, so
6824             //    predVarToRegMap[varIndex] will be REG_STK, but targetReg is its former allocated value.
6825             //    In this case, we will normally change it to REG_STK.  We will update its "spilled" status when we
6826             //    encounter it in resolveLocalRef().
6827             // 2a. If the next RefPosition is marked as a copyReg, we need to retain the allocated register.  This is
6828             //     because the copyReg RefPosition will not have recorded the "home" register, yet downstream
6829             //     RefPositions rely on the correct "home" register.
6830             // 3. This variable was spilled before we reached the end of predBB.  In this case, both targetReg and
6831             //    predVarToRegMap[varIndex] will be REG_STK, and the next RefPosition will have been marked
6832             //    as reload during allocation time if necessary (note that by the time we actually reach the next
6833             //    RefPosition, we may be using a different predecessor, at which it is still in a register).
6834             // 4. This variable was spilled during the allocation of this block, so targetReg is REG_STK
6835             //    (because we set inVarToRegMap at the time we spilled it), but predVarToRegMap[varIndex]
6836             //    is not REG_STK.  We retain the REG_STK value in the inVarToRegMap.
6837             if (targetReg != REG_STK)
6838             {
6839                 if (getVarReg(predVarToRegMap, varIndex) != REG_STK)
6840                 {
6841                     // Case #1 above.
6842                     assert(getVarReg(predVarToRegMap, varIndex) == targetReg ||
6843                            getLsraBlockBoundaryLocations() == LSRA_BLOCK_BOUNDARY_ROTATE);
6844                 }
6845                 else if (!nextRefPosition->copyReg)
6846                 {
6847                     // case #2 above.
6848                     setVarReg(inVarToRegMap, varIndex, REG_STK);
6849                     targetReg = REG_STK;
6850                 }
6851                 // Else case 2a. - retain targetReg.
6852             }
6853             // Else case #3 or #4, we retain targetReg and nothing further to do or assert.
6854         }
6855         if (interval->physReg == targetReg)
6856         {
6857             if (interval->isActive)
6858             {
6859                 assert(targetReg != REG_STK);
6860                 assert(interval->assignedReg != nullptr && interval->assignedReg->regNum == targetReg &&
6861                        interval->assignedReg->assignedInterval == interval);
6862                 liveRegs |= genRegMask(targetReg);
6863                 continue;
6864             }
6865         }
6866         else if (interval->physReg != REG_NA)
6867         {
6868             // This can happen if we are using the locations from a basic block other than the
6869             // immediately preceding one - where the variable was in a different location.
6870             if (targetReg != REG_STK)
6871             {
6872                 // Unassign it from the register (it will get a new register below).
6873                 if (interval->assignedReg != nullptr && interval->assignedReg->assignedInterval == interval)
6874                 {
6875                     interval->isActive = false;
6876                     unassignPhysReg(getRegisterRecord(interval->physReg), nullptr);
6877                 }
6878                 else
6879                 {
6880                     // This interval was live in this register the last time we saw a reference to it,
6881                     // but has since been displaced.
6882                     interval->physReg = REG_NA;
6883                 }
6884             }
6885             else if (allocationPass)
6886             {
6887                 // Keep the register assignment - if another var has it, it will get unassigned.
6888                 // Otherwise, resolution will fix it up later, and it will be more
6889                 // likely to match other assignments this way.
6890                 interval->isActive = true;
6891                 liveRegs |= genRegMask(interval->physReg);
6892                 INDEBUG(inactiveRegs |= genRegMask(interval->physReg));
6893                 setVarReg(inVarToRegMap, varIndex, interval->physReg);
6894             }
6895             else
6896             {
6897                 interval->physReg = REG_NA;
6898             }
6899         }
6900         if (targetReg != REG_STK)
6901         {
6902             RegRecord* targetRegRecord = getRegisterRecord(targetReg);
6903             liveRegs |= genRegMask(targetReg);
6904             if (!interval->isActive)
6905             {
6906                 interval->isActive    = true;
6907                 interval->physReg     = targetReg;
6908                 interval->assignedReg = targetRegRecord;
6909             }
6910             Interval* assignedInterval = targetRegRecord->assignedInterval;
6911             if (assignedInterval != interval)
6912             {
6913                 // Is there another interval currently assigned to this register?  If so unassign it.
6914                 if (assignedInterval != nullptr)
6915                 {
6916                     if (isAssignedToInterval(assignedInterval, targetRegRecord))
6917                     {
6918                         regNumber assignedRegNum = assignedInterval->assignedReg->regNum;
6919
6920                         // If the interval is active, it will be set to active when we reach its new
6921                         // register assignment (which we must not yet have done, or it wouldn't still be
6922                         // assigned to this register).
6923                         assignedInterval->isActive = false;
6924                         unassignPhysReg(assignedInterval->assignedReg, nullptr);
6925                         if (allocationPass && assignedInterval->isLocalVar &&
6926                             inVarToRegMap[assignedInterval->getVarIndex(compiler)] == assignedRegNum)
6927                         {
6928                             inVarToRegMap[assignedInterval->getVarIndex(compiler)] = REG_STK;
6929                         }
6930                     }
6931                     else
6932                     {
6933                         // This interval is no longer assigned to this register.
6934                         updateAssignedInterval(targetRegRecord, nullptr, assignedInterval->registerType);
6935                     }
6936                 }
6937                 assignPhysReg(targetRegRecord, interval);
6938             }
6939             if (interval->recentRefPosition != nullptr && !interval->recentRefPosition->copyReg &&
6940                 interval->recentRefPosition->registerAssignment != genRegMask(targetReg))
6941             {
6942                 interval->getNextRefPosition()->outOfOrder = true;
6943             }
6944         }
6945     }
6946
6947     // Unassign any registers that are no longer live.
6948     for (regNumber reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
6949     {
6950         if ((liveRegs & genRegMask(reg)) == 0)
6951         {
6952             RegRecord* physRegRecord    = getRegisterRecord(reg);
6953             Interval*  assignedInterval = physRegRecord->assignedInterval;
6954
6955             if (assignedInterval != nullptr)
6956             {
6957                 assert(assignedInterval->isLocalVar || assignedInterval->isConstant);
6958
6959                 if (!assignedInterval->isConstant && assignedInterval->assignedReg == physRegRecord)
6960                 {
6961                     assignedInterval->isActive = false;
6962                     if (assignedInterval->getNextRefPosition() == nullptr)
6963                     {
6964                         unassignPhysReg(physRegRecord, nullptr);
6965                     }
6966                     inVarToRegMap[assignedInterval->getVarIndex(compiler)] = REG_STK;
6967                 }
6968                 else
6969                 {
6970                     // This interval may still be active, but was in another register in an
6971                     // intervening block.
6972                     updateAssignedInterval(physRegRecord, nullptr, assignedInterval->registerType);
6973                 }
6974
6975 #ifdef _TARGET_ARM_
6976                 if (assignedInterval->registerType == TYP_DOUBLE)
6977                 {
6978                     // Skip next float register, because we already addressed a double register
6979                     assert(genIsValidDoubleReg(reg));
6980                     reg = REG_NEXT(reg);
6981                 }
6982 #endif // _TARGET_ARM_
6983             }
6984         }
6985 #ifdef _TARGET_ARM_
6986         else
6987         {
6988             RegRecord* physRegRecord    = getRegisterRecord(reg);
6989             Interval*  assignedInterval = physRegRecord->assignedInterval;
6990
6991             if (assignedInterval != nullptr && assignedInterval->registerType == TYP_DOUBLE)
6992             {
6993                 // Skip next float register, because we already addressed a double register
6994                 assert(genIsValidDoubleReg(reg));
6995                 reg = REG_NEXT(reg);
6996             }
6997         }
6998 #endif // _TARGET_ARM_
6999     }
7000     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_START_BB, nullptr, REG_NA, currentBlock));
7001 }
7002
7003 //------------------------------------------------------------------------
7004 // processBlockEndLocations: Record the variables occupying registers after completing the current block.
7005 //
7006 // Arguments:
7007 //    currentBlock - the block we have just completed.
7008 //
7009 // Return Value:
7010 //    None
7011 //
7012 // Notes:
7013 //    This must be called both during the allocation and resolution (write-back) phases.
7014 //    This is because we need to have the outVarToRegMap locations in order to set the locations
7015 //    at successor blocks during allocation time, but if lclVars are spilled after a block has been
7016 //    completed, we need to record the REG_STK location for those variables at resolution time.
7017
7018 void LinearScan::processBlockEndLocations(BasicBlock* currentBlock)
7019 {
7020     assert(currentBlock != nullptr && currentBlock->bbNum == curBBNum);
7021     VarToRegMap outVarToRegMap = getOutVarToRegMap(curBBNum);
7022
7023     VarSetOps::AssignNoCopy(compiler, currentLiveVars,
7024                             VarSetOps::Intersection(compiler, registerCandidateVars, currentBlock->bbLiveOut));
7025 #ifdef DEBUG
7026     if (getLsraExtendLifeTimes())
7027     {
7028         VarSetOps::Assign(compiler, currentLiveVars, registerCandidateVars);
7029     }
7030 #endif // DEBUG
7031     regMaskTP       liveRegs = RBM_NONE;
7032     VarSetOps::Iter iter(compiler, currentLiveVars);
7033     unsigned        varIndex = 0;
7034     while (iter.NextElem(&varIndex))
7035     {
7036         Interval* interval = getIntervalForLocalVar(varIndex);
7037         if (interval->isActive)
7038         {
7039             assert(interval->physReg != REG_NA && interval->physReg != REG_STK);
7040             setVarReg(outVarToRegMap, varIndex, interval->physReg);
7041         }
7042         else
7043         {
7044             outVarToRegMap[varIndex] = REG_STK;
7045         }
7046     }
7047     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_END_BB));
7048 }
7049
7050 #ifdef DEBUG
7051 void LinearScan::dumpRefPositions(const char* str)
7052 {
7053     printf("------------\n");
7054     printf("REFPOSITIONS %s: \n", str);
7055     printf("------------\n");
7056     for (auto& refPos : refPositions)
7057     {
7058         refPos.dump();
7059     }
7060 }
7061 #endif // DEBUG
7062
7063 bool LinearScan::registerIsFree(regNumber regNum, RegisterType regType)
7064 {
7065     RegRecord* physRegRecord = getRegisterRecord(regNum);
7066
7067     bool isFree = physRegRecord->isFree();
7068
7069 #ifdef _TARGET_ARM_
7070     if (isFree && regType == TYP_DOUBLE)
7071     {
7072         isFree = getRegisterRecord(REG_NEXT(regNum))->isFree();
7073     }
7074 #endif // _TARGET_ARM_
7075
7076     return isFree;
7077 }
7078
7079 //------------------------------------------------------------------------
7080 // LinearScan::freeRegister: Make a register available for use
7081 //
7082 // Arguments:
7083 //    physRegRecord - the RegRecord for the register to be freed.
7084 //
7085 // Return Value:
7086 //    None.
7087 //
7088 // Assumptions:
7089 //    None.
7090 //    It may be that the RegRecord has already been freed, e.g. due to a kill,
7091 //    in which case this method has no effect.
7092 //
7093 // Notes:
7094 //    If there is currently an Interval assigned to this register, and it has
7095 //    more references (i.e. this is a local last-use, but more uses and/or
7096 //    defs remain), it will remain assigned to the physRegRecord.  However, since
7097 //    it is marked inactive, the register will be available, albeit less desirable
7098 //    to allocate.
7099 void LinearScan::freeRegister(RegRecord* physRegRecord)
7100 {
7101     Interval* assignedInterval = physRegRecord->assignedInterval;
7102     // It may have already been freed by a "Kill"
7103     if (assignedInterval != nullptr)
7104     {
7105         assignedInterval->isActive = false;
7106         // If this is a constant node, that we may encounter again (e.g. constant),
7107         // don't unassign it until we need the register.
7108         if (!assignedInterval->isConstant)
7109         {
7110             RefPosition* nextRefPosition = assignedInterval->getNextRefPosition();
7111             // Unassign the register only if there are no more RefPositions, or the next
7112             // one is a def.  Note that the latter condition doesn't actually ensure that
7113             // there aren't subsequent uses that could be reached by a def in the assigned
7114             // register, but is merely a heuristic to avoid tying up the register (or using
7115             // it when it's non-optimal).  A better alternative would be to use SSA, so that
7116             // we wouldn't unnecessarily link separate live ranges to the same register.
7117             if (nextRefPosition == nullptr || RefTypeIsDef(nextRefPosition->refType))
7118             {
7119 #ifdef _TARGET_ARM_
7120                 assert((assignedInterval->registerType != TYP_DOUBLE) || genIsValidDoubleReg(physRegRecord->regNum));
7121 #endif // _TARGET_ARM_
7122                 unassignPhysReg(physRegRecord, nullptr);
7123             }
7124         }
7125     }
7126 }
7127
7128 void LinearScan::freeRegisters(regMaskTP regsToFree)
7129 {
7130     if (regsToFree == RBM_NONE)
7131     {
7132         return;
7133     }
7134
7135     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_FREE_REGS));
7136     while (regsToFree != RBM_NONE)
7137     {
7138         regMaskTP nextRegBit = genFindLowestBit(regsToFree);
7139         regsToFree &= ~nextRegBit;
7140         regNumber nextReg = genRegNumFromMask(nextRegBit);
7141         freeRegister(getRegisterRecord(nextReg));
7142     }
7143 }
7144
7145 // Actual register allocation, accomplished by iterating over all of the previously
7146 // constructed Intervals
7147 // Loosely based on raAssignVars()
7148 //
7149 void LinearScan::allocateRegisters()
7150 {
7151     JITDUMP("*************** In LinearScan::allocateRegisters()\n");
7152     DBEXEC(VERBOSE, lsraDumpIntervals("before allocateRegisters"));
7153
7154     // at start, nothing is active except for register args
7155     for (auto& interval : intervals)
7156     {
7157         Interval* currentInterval          = &interval;
7158         currentInterval->recentRefPosition = nullptr;
7159         currentInterval->isActive          = false;
7160         if (currentInterval->isLocalVar)
7161         {
7162             LclVarDsc* varDsc = currentInterval->getLocalVar(compiler);
7163             if (varDsc->lvIsRegArg && currentInterval->firstRefPosition != nullptr)
7164             {
7165                 currentInterval->isActive = true;
7166             }
7167         }
7168     }
7169
7170     for (regNumber reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
7171     {
7172         getRegisterRecord(reg)->recentRefPosition = nullptr;
7173         getRegisterRecord(reg)->isActive          = false;
7174     }
7175
7176 #ifdef DEBUG
7177     regNumber lastAllocatedReg = REG_NA;
7178     if (VERBOSE)
7179     {
7180         dumpRefPositions("BEFORE ALLOCATION");
7181         dumpVarRefPositions("BEFORE ALLOCATION");
7182
7183         printf("\n\nAllocating Registers\n"
7184                "--------------------\n");
7185         if (dumpTerse)
7186         {
7187             dumpRegRecordHeader();
7188             // Now print an empty indent
7189             printf(indentFormat, "");
7190         }
7191     }
7192 #endif // DEBUG
7193
7194     BasicBlock* currentBlock = nullptr;
7195
7196     LsraLocation prevLocation    = MinLocation;
7197     regMaskTP    regsToFree      = RBM_NONE;
7198     regMaskTP    delayRegsToFree = RBM_NONE;
7199
7200     // This is the most recent RefPosition for which a register was allocated
7201     // - currently only used for DEBUG but maintained in non-debug, for clarity of code
7202     //   (and will be optimized away because in non-debug spillAlways() unconditionally returns false)
7203     RefPosition* lastAllocatedRefPosition = nullptr;
7204
7205     bool handledBlockEnd = false;
7206
7207     for (auto& refPosition : refPositions)
7208     {
7209         RefPosition* currentRefPosition = &refPosition;
7210
7211 #ifdef DEBUG
7212         // Set the activeRefPosition to null until we're done with any boundary handling.
7213         activeRefPosition = nullptr;
7214         if (VERBOSE)
7215         {
7216             if (dumpTerse)
7217             {
7218                 // We're really dumping the RegRecords "after" the previous RefPosition, but it's more convenient
7219                 // to do this here, since there are a number of "continue"s in this loop.
7220                 dumpRegRecords();
7221             }
7222             else
7223             {
7224                 printf("\n");
7225             }
7226         }
7227 #endif // DEBUG
7228
7229         // This is the previousRefPosition of the current Referent, if any
7230         RefPosition* previousRefPosition = nullptr;
7231
7232         Interval*      currentInterval = nullptr;
7233         Referenceable* currentReferent = nullptr;
7234         bool           isInternalRef   = false;
7235         RefType        refType         = currentRefPosition->refType;
7236
7237         currentReferent = currentRefPosition->referent;
7238
7239         if (spillAlways() && lastAllocatedRefPosition != nullptr && !lastAllocatedRefPosition->isPhysRegRef &&
7240             !lastAllocatedRefPosition->getInterval()->isInternal &&
7241             (RefTypeIsDef(lastAllocatedRefPosition->refType) || lastAllocatedRefPosition->getInterval()->isLocalVar))
7242         {
7243             assert(lastAllocatedRefPosition->registerAssignment != RBM_NONE);
7244             RegRecord* regRecord = lastAllocatedRefPosition->getInterval()->assignedReg;
7245             unassignPhysReg(regRecord, lastAllocatedRefPosition);
7246             // Now set lastAllocatedRefPosition to null, so that we don't try to spill it again
7247             lastAllocatedRefPosition = nullptr;
7248         }
7249
7250         // We wait to free any registers until we've completed all the
7251         // uses for the current node.
7252         // This avoids reusing registers too soon.
7253         // We free before the last true def (after all the uses & internal
7254         // registers), and then again at the beginning of the next node.
7255         // This is made easier by assigning two LsraLocations per node - one
7256         // for all the uses, internal registers & all but the last def, and
7257         // another for the final def (if any).
7258
7259         LsraLocation currentLocation = currentRefPosition->nodeLocation;
7260
7261         if ((regsToFree | delayRegsToFree) != RBM_NONE)
7262         {
7263             bool doFreeRegs = false;
7264             // Free at a new location, or at a basic block boundary
7265             if (currentLocation > prevLocation || refType == RefTypeBB)
7266             {
7267                 doFreeRegs = true;
7268             }
7269
7270             if (doFreeRegs)
7271             {
7272                 freeRegisters(regsToFree);
7273                 regsToFree      = delayRegsToFree;
7274                 delayRegsToFree = RBM_NONE;
7275             }
7276         }
7277         prevLocation = currentLocation;
7278
7279         // get previous refposition, then current refpos is the new previous
7280         if (currentReferent != nullptr)
7281         {
7282             previousRefPosition                = currentReferent->recentRefPosition;
7283             currentReferent->recentRefPosition = currentRefPosition;
7284         }
7285         else
7286         {
7287             assert((refType == RefTypeBB) || (refType == RefTypeKillGCRefs));
7288         }
7289
7290         // For the purposes of register resolution, we handle the DummyDefs before
7291         // the block boundary - so the RefTypeBB is after all the DummyDefs.
7292         // However, for the purposes of allocation, we want to handle the block
7293         // boundary first, so that we can free any registers occupied by lclVars
7294         // that aren't live in the next block and make them available for the
7295         // DummyDefs.
7296
7297         if (!handledBlockEnd && (refType == RefTypeBB || refType == RefTypeDummyDef))
7298         {
7299             // Free any delayed regs (now in regsToFree) before processing the block boundary
7300             freeRegisters(regsToFree);
7301             regsToFree         = RBM_NONE;
7302             handledBlockEnd    = true;
7303             curBBStartLocation = currentRefPosition->nodeLocation;
7304             if (currentBlock == nullptr)
7305             {
7306                 currentBlock = startBlockSequence();
7307             }
7308             else
7309             {
7310                 processBlockEndAllocation(currentBlock);
7311                 currentBlock = moveToNextBlock();
7312             }
7313 #ifdef DEBUG
7314             if (VERBOSE && currentBlock != nullptr && !dumpTerse)
7315             {
7316                 currentBlock->dspBlockHeader(compiler);
7317                 printf("\n");
7318             }
7319 #endif // DEBUG
7320         }
7321
7322 #ifdef DEBUG
7323         activeRefPosition = currentRefPosition;
7324         if (VERBOSE)
7325         {
7326             if (dumpTerse)
7327             {
7328                 dumpRefPositionShort(currentRefPosition, currentBlock);
7329             }
7330             else
7331             {
7332                 currentRefPosition->dump();
7333             }
7334         }
7335 #endif // DEBUG
7336
7337         if (refType == RefTypeBB)
7338         {
7339             handledBlockEnd = false;
7340             continue;
7341         }
7342
7343         if (refType == RefTypeKillGCRefs)
7344         {
7345             spillGCRefs(currentRefPosition);
7346             continue;
7347         }
7348
7349         // If this is a FixedReg, disassociate any inactive constant interval from this register.
7350         // Otherwise, do nothing.
7351         if (refType == RefTypeFixedReg)
7352         {
7353             RegRecord* regRecord        = currentRefPosition->getReg();
7354             Interval*  assignedInterval = regRecord->assignedInterval;
7355
7356             if (assignedInterval != nullptr && !assignedInterval->isActive && assignedInterval->isConstant)
7357             {
7358                 regRecord->assignedInterval = nullptr;
7359
7360 #ifdef _TARGET_ARM_
7361                 // Update overlapping floating point register for TYP_DOUBLE
7362                 if (assignedInterval->registerType == TYP_DOUBLE)
7363                 {
7364                     regRecord        = getRegisterRecord(REG_NEXT(regRecord->regNum));
7365                     assignedInterval = regRecord->assignedInterval;
7366
7367                     assert(assignedInterval != nullptr && !assignedInterval->isActive && assignedInterval->isConstant);
7368                     regRecord->assignedInterval = nullptr;
7369                 }
7370 #endif
7371             }
7372             INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_FIXED_REG, nullptr, currentRefPosition->assignedReg()));
7373             continue;
7374         }
7375
7376         // If this is an exposed use, do nothing - this is merely a placeholder to attempt to
7377         // ensure that a register is allocated for the full lifetime.  The resolution logic
7378         // will take care of moving to the appropriate register if needed.
7379
7380         if (refType == RefTypeExpUse)
7381         {
7382             INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_EXP_USE));
7383             continue;
7384         }
7385
7386         regNumber assignedRegister = REG_NA;
7387
7388         if (currentRefPosition->isIntervalRef())
7389         {
7390             currentInterval  = currentRefPosition->getInterval();
7391             assignedRegister = currentInterval->physReg;
7392 #if DEBUG
7393             if (VERBOSE && !dumpTerse)
7394             {
7395                 currentInterval->dump();
7396             }
7397 #endif // DEBUG
7398
7399             // Identify the special cases where we decide up-front not to allocate
7400             bool allocate = true;
7401             bool didDump  = false;
7402
7403             if (refType == RefTypeParamDef || refType == RefTypeZeroInit)
7404             {
7405                 // For a ParamDef with a weighted refCount less than unity, don't enregister it at entry.
7406                 // TODO-CQ: Consider doing this only for stack parameters, since otherwise we may be needlessly
7407                 // inserting a store.
7408                 LclVarDsc* varDsc = currentInterval->getLocalVar(compiler);
7409                 assert(varDsc != nullptr);
7410                 if (refType == RefTypeParamDef && varDsc->lvRefCntWtd <= BB_UNITY_WEIGHT)
7411                 {
7412                     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_NO_ENTRY_REG_ALLOCATED, currentInterval));
7413                     didDump  = true;
7414                     allocate = false;
7415                     setIntervalAsSpilled(currentInterval);
7416                 }
7417                 // If it has no actual references, mark it as "lastUse"; since they're not actually part
7418                 // of any flow they won't have been marked during dataflow.  Otherwise, if we allocate a
7419                 // register we won't unassign it.
7420                 else if (currentRefPosition->nextRefPosition == nullptr)
7421                 {
7422                     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_ZERO_REF, currentInterval));
7423                     currentRefPosition->lastUse = true;
7424                 }
7425             }
7426 #ifdef FEATURE_SIMD
7427             else if (refType == RefTypeUpperVectorSaveDef || refType == RefTypeUpperVectorSaveUse)
7428             {
7429                 Interval* lclVarInterval = currentInterval->relatedInterval;
7430                 if (lclVarInterval->physReg == REG_NA)
7431                 {
7432                     allocate = false;
7433                 }
7434             }
7435 #endif // FEATURE_SIMD
7436
7437             if (allocate == false)
7438             {
7439                 if (assignedRegister != REG_NA)
7440                 {
7441                     unassignPhysReg(getRegisterRecord(assignedRegister), currentRefPosition);
7442                 }
7443                 else if (!didDump)
7444                 {
7445                     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_NO_REG_ALLOCATED, currentInterval));
7446                     didDump = true;
7447                 }
7448                 currentRefPosition->registerAssignment = RBM_NONE;
7449                 continue;
7450             }
7451
7452             if (currentInterval->isSpecialPutArg)
7453             {
7454                 assert(!currentInterval->isLocalVar);
7455                 Interval* srcInterval = currentInterval->relatedInterval;
7456                 assert(srcInterval->isLocalVar);
7457                 if (refType == RefTypeDef)
7458                 {
7459                     assert(srcInterval->recentRefPosition->nodeLocation == currentLocation - 1);
7460                     RegRecord* physRegRecord = srcInterval->assignedReg;
7461
7462                     // For a putarg_reg to be special, its next use location has to be the same
7463                     // as fixed reg's next kill location. Otherwise, if source lcl var's next use
7464                     // is after the kill of fixed reg but before putarg_reg's next use, fixed reg's
7465                     // kill would lead to spill of source but not the putarg_reg if it were treated
7466                     // as special.
7467                     if (srcInterval->isActive &&
7468                         genRegMask(srcInterval->physReg) == currentRefPosition->registerAssignment &&
7469                         currentInterval->getNextRefLocation() == physRegRecord->getNextRefLocation())
7470                     {
7471                         assert(physRegRecord->regNum == srcInterval->physReg);
7472
7473                         // Special putarg_reg acts as a pass-thru since both source lcl var
7474                         // and putarg_reg have the same register allocated.  Physical reg
7475                         // record of reg continue to point to source lcl var's interval
7476                         // instead of to putarg_reg's interval.  So if a spill of reg
7477                         // allocated to source lcl var happens, to reallocate to another
7478                         // tree node, before its use at call node it will lead to spill of
7479                         // lcl var instead of putarg_reg since physical reg record is pointing
7480                         // to lcl var's interval. As a result, arg reg would get trashed leading
7481                         // to bad codegen. The assumption here is that source lcl var of a
7482                         // special putarg_reg doesn't get spilled and re-allocated prior to
7483                         // its use at the call node.  This is ensured by marking physical reg
7484                         // record as busy until next kill.
7485                         physRegRecord->isBusyUntilNextKill = true;
7486                     }
7487                     else
7488                     {
7489                         currentInterval->isSpecialPutArg = false;
7490                     }
7491                 }
7492                 // If this is still a SpecialPutArg, continue;
7493                 if (currentInterval->isSpecialPutArg)
7494                 {
7495                     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_SPECIAL_PUTARG, currentInterval,
7496                                                     currentRefPosition->assignedReg()));
7497                     continue;
7498                 }
7499             }
7500
7501             if (assignedRegister == REG_NA && RefTypeIsUse(refType))
7502             {
7503                 currentRefPosition->reload = true;
7504                 INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_RELOAD, currentInterval, assignedRegister));
7505             }
7506         }
7507
7508         regMaskTP assignedRegBit = RBM_NONE;
7509         bool      isInRegister   = false;
7510         if (assignedRegister != REG_NA)
7511         {
7512             isInRegister   = true;
7513             assignedRegBit = genRegMask(assignedRegister);
7514             if (!currentInterval->isActive)
7515             {
7516                 // If this is a use, it must have started the block on the stack, but the register
7517                 // was available for use so we kept the association.
7518                 if (RefTypeIsUse(refType))
7519                 {
7520                     assert(enregisterLocalVars);
7521                     assert(inVarToRegMaps[curBBNum][currentInterval->getVarIndex(compiler)] == REG_STK &&
7522                            previousRefPosition->nodeLocation <= curBBStartLocation);
7523                     isInRegister = false;
7524                 }
7525                 else
7526                 {
7527                     currentInterval->isActive = true;
7528                 }
7529             }
7530             assert(currentInterval->assignedReg != nullptr &&
7531                    currentInterval->assignedReg->regNum == assignedRegister &&
7532                    currentInterval->assignedReg->assignedInterval == currentInterval);
7533         }
7534
7535         // If this is a physical register, we unconditionally assign it to itself!
7536         if (currentRefPosition->isPhysRegRef)
7537         {
7538             RegRecord* currentReg       = currentRefPosition->getReg();
7539             Interval*  assignedInterval = currentReg->assignedInterval;
7540
7541             if (assignedInterval != nullptr)
7542             {
7543                 unassignPhysReg(currentReg, assignedInterval->recentRefPosition);
7544             }
7545             currentReg->isActive = true;
7546             assignedRegister     = currentReg->regNum;
7547             assignedRegBit       = genRegMask(assignedRegister);
7548             if (refType == RefTypeKill)
7549             {
7550                 currentReg->isBusyUntilNextKill = false;
7551             }
7552         }
7553         else if (previousRefPosition != nullptr)
7554         {
7555             assert(previousRefPosition->nextRefPosition == currentRefPosition);
7556             assert(assignedRegister == REG_NA || assignedRegBit == previousRefPosition->registerAssignment ||
7557                    currentRefPosition->outOfOrder || previousRefPosition->copyReg ||
7558                    previousRefPosition->refType == RefTypeExpUse || currentRefPosition->refType == RefTypeDummyDef);
7559         }
7560         else if (assignedRegister != REG_NA)
7561         {
7562             // Handle the case where this is a preassigned register (i.e. parameter).
7563             // We don't want to actually use the preassigned register if it's not
7564             // going to cover the lifetime - but we had to preallocate it to ensure
7565             // that it remained live.
7566             // TODO-CQ: At some point we may want to refine the analysis here, in case
7567             // it might be beneficial to keep it in this reg for PART of the lifetime
7568             if (currentInterval->isLocalVar)
7569             {
7570                 regMaskTP preferences        = currentInterval->registerPreferences;
7571                 bool      keepAssignment     = true;
7572                 bool      matchesPreferences = (preferences & genRegMask(assignedRegister)) != RBM_NONE;
7573
7574                 // Will the assigned register cover the lifetime?  If not, does it at least
7575                 // meet the preferences for the next RefPosition?
7576                 RegRecord*   physRegRecord     = getRegisterRecord(currentInterval->physReg);
7577                 RefPosition* nextPhysRegRefPos = physRegRecord->getNextRefPosition();
7578                 if (nextPhysRegRefPos != nullptr &&
7579                     nextPhysRegRefPos->nodeLocation <= currentInterval->lastRefPosition->nodeLocation)
7580                 {
7581                     // Check to see if the existing assignment matches the preferences (e.g. callee save registers)
7582                     // and ensure that the next use of this localVar does not occur after the nextPhysRegRefPos
7583                     // There must be a next RefPosition, because we know that the Interval extends beyond the
7584                     // nextPhysRegRefPos.
7585                     RefPosition* nextLclVarRefPos = currentRefPosition->nextRefPosition;
7586                     assert(nextLclVarRefPos != nullptr);
7587                     if (!matchesPreferences || nextPhysRegRefPos->nodeLocation < nextLclVarRefPos->nodeLocation ||
7588                         physRegRecord->conflictingFixedRegReference(nextLclVarRefPos))
7589                     {
7590                         keepAssignment = false;
7591                     }
7592                 }
7593                 else if (refType == RefTypeParamDef && !matchesPreferences)
7594                 {
7595                     // Don't use the register, even if available, if it doesn't match the preferences.
7596                     // Note that this case is only for ParamDefs, for which we haven't yet taken preferences
7597                     // into account (we've just automatically got the initial location).  In other cases,
7598                     // we would already have put it in a preferenced register, if it was available.
7599                     // TODO-CQ: Consider expanding this to check availability - that would duplicate
7600                     // code here, but otherwise we may wind up in this register anyway.
7601                     keepAssignment = false;
7602                 }
7603
7604                 if (keepAssignment == false)
7605                 {
7606                     currentRefPosition->registerAssignment = allRegs(currentInterval->registerType);
7607                     unassignPhysRegNoSpill(physRegRecord);
7608
7609                     // If the preferences are currently set to just this register, reset them to allRegs
7610                     // of the appropriate type (just as we just reset the registerAssignment for this
7611                     // RefPosition.
7612                     // Otherwise, simply remove this register from the preferences, if it's there.
7613
7614                     if (currentInterval->registerPreferences == assignedRegBit)
7615                     {
7616                         currentInterval->registerPreferences = currentRefPosition->registerAssignment;
7617                     }
7618                     else
7619                     {
7620                         currentInterval->registerPreferences &= ~assignedRegBit;
7621                     }
7622
7623                     assignedRegister = REG_NA;
7624                     assignedRegBit   = RBM_NONE;
7625                 }
7626             }
7627         }
7628
7629         if (assignedRegister != REG_NA)
7630         {
7631             // If there is a conflicting fixed reference, insert a copy.
7632             RegRecord* physRegRecord = getRegisterRecord(assignedRegister);
7633             if (physRegRecord->conflictingFixedRegReference(currentRefPosition))
7634             {
7635                 // We may have already reassigned the register to the conflicting reference.
7636                 // If not, we need to unassign this interval.
7637                 if (physRegRecord->assignedInterval == currentInterval)
7638                 {
7639                     unassignPhysRegNoSpill(physRegRecord);
7640                 }
7641                 currentRefPosition->moveReg = true;
7642                 assignedRegister            = REG_NA;
7643                 setIntervalAsSplit(currentInterval);
7644                 INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_MOVE_REG, currentInterval, assignedRegister));
7645             }
7646             else if ((genRegMask(assignedRegister) & currentRefPosition->registerAssignment) != 0)
7647             {
7648                 currentRefPosition->registerAssignment = assignedRegBit;
7649                 if (!currentReferent->isActive)
7650                 {
7651                     // If we've got an exposed use at the top of a block, the
7652                     // interval might not have been active.  Otherwise if it's a use,
7653                     // the interval must be active.
7654                     if (refType == RefTypeDummyDef)
7655                     {
7656                         currentReferent->isActive = true;
7657                         assert(getRegisterRecord(assignedRegister)->assignedInterval == currentInterval);
7658                     }
7659                     else
7660                     {
7661                         currentRefPosition->reload = true;
7662                     }
7663                 }
7664                 INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_KEPT_ALLOCATION, currentInterval, assignedRegister));
7665             }
7666             else
7667             {
7668                 assert(currentInterval != nullptr);
7669
7670                 // It's already in a register, but not one we need.
7671                 if (!RefTypeIsDef(currentRefPosition->refType))
7672                 {
7673                     regNumber copyReg = assignCopyReg(currentRefPosition);
7674                     assert(copyReg != REG_NA);
7675                     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_COPY_REG, currentInterval, copyReg));
7676                     lastAllocatedRefPosition = currentRefPosition;
7677                     if (currentRefPosition->lastUse)
7678                     {
7679                         if (currentRefPosition->delayRegFree)
7680                         {
7681                             INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_LAST_USE_DELAYED, currentInterval,
7682                                                             assignedRegister));
7683                             delayRegsToFree |= (genRegMask(assignedRegister) | currentRefPosition->registerAssignment);
7684                         }
7685                         else
7686                         {
7687                             INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_LAST_USE, currentInterval, assignedRegister));
7688                             regsToFree |= (genRegMask(assignedRegister) | currentRefPosition->registerAssignment);
7689                         }
7690                     }
7691                     // If this is a tree temp (non-localVar) interval, we will need an explicit move.
7692                     if (!currentInterval->isLocalVar)
7693                     {
7694                         currentRefPosition->moveReg = true;
7695                         currentRefPosition->copyReg = false;
7696                     }
7697                     continue;
7698                 }
7699                 else
7700                 {
7701                     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_NEEDS_NEW_REG, nullptr, assignedRegister));
7702                     regsToFree |= genRegMask(assignedRegister);
7703                     // We want a new register, but we don't want this to be considered a spill.
7704                     assignedRegister = REG_NA;
7705                     if (physRegRecord->assignedInterval == currentInterval)
7706                     {
7707                         unassignPhysRegNoSpill(physRegRecord);
7708                     }
7709                 }
7710             }
7711         }
7712
7713         if (assignedRegister == REG_NA)
7714         {
7715             bool allocateReg = true;
7716
7717             if (currentRefPosition->AllocateIfProfitable())
7718             {
7719                 // We can avoid allocating a register if it is a the last use requiring a reload.
7720                 if (currentRefPosition->lastUse && currentRefPosition->reload)
7721                 {
7722                     allocateReg = false;
7723                 }
7724
7725 #ifdef DEBUG
7726                 // Under stress mode, don't attempt to allocate a reg to
7727                 // reg optional ref position.
7728                 if (allocateReg && regOptionalNoAlloc())
7729                 {
7730                     allocateReg = false;
7731                 }
7732 #endif
7733             }
7734
7735             if (allocateReg)
7736             {
7737                 // Try to allocate a register
7738                 assignedRegister = tryAllocateFreeReg(currentInterval, currentRefPosition);
7739             }
7740
7741             // If no register was found, and if the currentRefPosition must have a register,
7742             // then find a register to spill
7743             if (assignedRegister == REG_NA)
7744             {
7745 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
7746                 if (refType == RefTypeUpperVectorSaveDef)
7747                 {
7748                     // TODO-CQ: Determine whether copying to two integer callee-save registers would be profitable.
7749
7750                     // SaveDef position occurs after the Use of args and at the same location as Kill/Def
7751                     // positions of a call node.  But SaveDef position cannot use any of the arg regs as
7752                     // they are needed for call node.
7753                     currentRefPosition->registerAssignment =
7754                         (allRegs(TYP_FLOAT) & RBM_FLT_CALLEE_TRASH & ~RBM_FLTARG_REGS);
7755                     assignedRegister = tryAllocateFreeReg(currentInterval, currentRefPosition);
7756
7757                     // There MUST be caller-save registers available, because they have all just been killed.
7758                     // Amd64 Windows: xmm4-xmm5 are guaranteed to be available as xmm0-xmm3 are used for passing args.
7759                     // Amd64 Unix: xmm8-xmm15 are guaranteed to be avilable as xmm0-xmm7 are used for passing args.
7760                     // X86 RyuJIT Windows: xmm4-xmm7 are guanrateed to be available.
7761                     assert(assignedRegister != REG_NA);
7762
7763                     // Now, spill it.
7764                     // Note:
7765                     //   i) The reason we have to spill is that SaveDef position is allocated after the Kill positions
7766                     //      of the call node are processed.  Since callee-trash registers are killed by call node
7767                     //      we explicity spill and unassign the register.
7768                     //  ii) These will look a bit backward in the dump, but it's a pain to dump the alloc before the
7769                     //  spill).
7770                     unassignPhysReg(getRegisterRecord(assignedRegister), currentRefPosition);
7771                     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_ALLOC_REG, currentInterval, assignedRegister));
7772
7773                     // Now set assignedRegister to REG_NA again so that we don't re-activate it.
7774                     assignedRegister = REG_NA;
7775                 }
7776                 else
7777 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
7778                     if (currentRefPosition->RequiresRegister() || currentRefPosition->AllocateIfProfitable())
7779                 {
7780                     if (allocateReg)
7781                     {
7782                         assignedRegister = allocateBusyReg(currentInterval, currentRefPosition,
7783                                                            currentRefPosition->AllocateIfProfitable());
7784                     }
7785
7786                     if (assignedRegister != REG_NA)
7787                     {
7788                         INDEBUG(
7789                             dumpLsraAllocationEvent(LSRA_EVENT_ALLOC_SPILLED_REG, currentInterval, assignedRegister));
7790                     }
7791                     else
7792                     {
7793                         // This can happen only for those ref positions that are to be allocated
7794                         // only if profitable.
7795                         noway_assert(currentRefPosition->AllocateIfProfitable());
7796
7797                         currentRefPosition->registerAssignment = RBM_NONE;
7798                         currentRefPosition->reload             = false;
7799                         setIntervalAsSpilled(currentInterval);
7800
7801                         INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_NO_REG_ALLOCATED, currentInterval));
7802                     }
7803                 }
7804                 else
7805                 {
7806                     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_NO_REG_ALLOCATED, currentInterval));
7807                     currentRefPosition->registerAssignment = RBM_NONE;
7808                     currentInterval->isActive              = false;
7809                     setIntervalAsSpilled(currentInterval);
7810                 }
7811             }
7812 #ifdef DEBUG
7813             else
7814             {
7815                 if (VERBOSE)
7816                 {
7817                     if (currentInterval->isConstant && (currentRefPosition->treeNode != nullptr) &&
7818                         currentRefPosition->treeNode->IsReuseRegVal())
7819                     {
7820                         dumpLsraAllocationEvent(LSRA_EVENT_REUSE_REG, nullptr, assignedRegister, currentBlock);
7821                     }
7822                     else
7823                     {
7824                         dumpLsraAllocationEvent(LSRA_EVENT_ALLOC_REG, nullptr, assignedRegister, currentBlock);
7825                     }
7826                 }
7827             }
7828 #endif // DEBUG
7829
7830             if (refType == RefTypeDummyDef && assignedRegister != REG_NA)
7831             {
7832                 setInVarRegForBB(curBBNum, currentInterval->varNum, assignedRegister);
7833             }
7834
7835             // If we allocated a register, and this is a use of a spilled value,
7836             // it should have been marked for reload above.
7837             if (assignedRegister != REG_NA && RefTypeIsUse(refType) && !isInRegister)
7838             {
7839                 assert(currentRefPosition->reload);
7840             }
7841         }
7842
7843         // If we allocated a register, record it
7844         if (currentInterval != nullptr && assignedRegister != REG_NA)
7845         {
7846             assignedRegBit                         = genRegMask(assignedRegister);
7847             currentRefPosition->registerAssignment = assignedRegBit;
7848             currentInterval->physReg               = assignedRegister;
7849             regsToFree &= ~assignedRegBit; // we'll set it again later if it's dead
7850
7851             // If this interval is dead, free the register.
7852             // The interval could be dead if this is a user variable, or if the
7853             // node is being evaluated for side effects, or a call whose result
7854             // is not used, etc.
7855             if (currentRefPosition->lastUse || currentRefPosition->nextRefPosition == nullptr)
7856             {
7857                 assert(currentRefPosition->isIntervalRef());
7858
7859                 if (refType != RefTypeExpUse && currentRefPosition->nextRefPosition == nullptr)
7860                 {
7861                     if (currentRefPosition->delayRegFree)
7862                     {
7863                         delayRegsToFree |= assignedRegBit;
7864
7865                         INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_LAST_USE_DELAYED));
7866                     }
7867                     else
7868                     {
7869                         regsToFree |= assignedRegBit;
7870
7871                         INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_LAST_USE));
7872                     }
7873                 }
7874                 else
7875                 {
7876                     currentInterval->isActive = false;
7877                 }
7878             }
7879
7880             lastAllocatedRefPosition = currentRefPosition;
7881         }
7882     }
7883
7884     // Free registers to clear associated intervals for resolution phase
7885     CLANG_FORMAT_COMMENT_ANCHOR;
7886
7887 #ifdef DEBUG
7888     if (getLsraExtendLifeTimes())
7889     {
7890         // If we have extended lifetimes, we need to make sure all the registers are freed.
7891         for (int regNumIndex = 0; regNumIndex <= REG_FP_LAST; regNumIndex++)
7892         {
7893             RegRecord& regRecord = physRegs[regNumIndex];
7894             Interval*  interval  = regRecord.assignedInterval;
7895             if (interval != nullptr)
7896             {
7897                 interval->isActive = false;
7898                 unassignPhysReg(&regRecord, nullptr);
7899             }
7900         }
7901     }
7902     else
7903 #endif // DEBUG
7904     {
7905         freeRegisters(regsToFree | delayRegsToFree);
7906     }
7907
7908 #ifdef DEBUG
7909     if (VERBOSE)
7910     {
7911         if (dumpTerse)
7912         {
7913             // Dump the RegRecords after the last RefPosition is handled.
7914             dumpRegRecords();
7915             printf("\n");
7916         }
7917
7918         dumpRefPositions("AFTER ALLOCATION");
7919         dumpVarRefPositions("AFTER ALLOCATION");
7920
7921         // Dump the intervals that remain active
7922         printf("Active intervals at end of allocation:\n");
7923
7924         // We COULD just reuse the intervalIter from above, but ArrayListIterator doesn't
7925         // provide a Reset function (!) - we'll probably replace this so don't bother
7926         // adding it
7927
7928         for (auto& interval : intervals)
7929         {
7930             if (interval.isActive)
7931             {
7932                 printf("Active ");
7933                 interval.dump();
7934             }
7935         }
7936
7937         printf("\n");
7938     }
7939 #endif // DEBUG
7940 }
7941
7942 //-----------------------------------------------------------------------------
7943 // updateAssignedInterval: Update assigned interval of register.
7944 //
7945 // Arguments:
7946 //    reg      -    register to be updated
7947 //    interval -    interval to be assigned
7948 //    regType  -    regsiter type
7949 //
7950 // Return Value:
7951 //    None
7952 //
7953 // Assumptions:
7954 //    For ARM32, when "regType" is TYP_DOUBLE, "reg" should be a even-numbered
7955 //    float register, i.e. lower half of double register.
7956 //
7957 // Note:
7958 //    For ARM32, two float registers consisting a double register are updated
7959 //    together when "regType" is TYP_DOUBLE.
7960 //
7961 void LinearScan::updateAssignedInterval(RegRecord* reg, Interval* interval, RegisterType regType)
7962 {
7963     reg->assignedInterval = interval;
7964
7965 #ifdef _TARGET_ARM_
7966     // Update overlapping floating point register for TYP_DOUBLE
7967     if (regType == TYP_DOUBLE)
7968     {
7969         assert(genIsValidDoubleReg(reg->regNum));
7970
7971         RegRecord* anotherHalfReg = findAnotherHalfRegRec(reg);
7972
7973         anotherHalfReg->assignedInterval = interval;
7974     }
7975 #endif
7976 }
7977
7978 //-----------------------------------------------------------------------------
7979 // updatePreviousInterval: Update previous interval of register.
7980 //
7981 // Arguments:
7982 //    reg      -    register to be updated
7983 //    interval -    interval to be assigned
7984 //    regType  -    regsiter type
7985 //
7986 // Return Value:
7987 //    None
7988 //
7989 // Assumptions:
7990 //    For ARM32, when "regType" is TYP_DOUBLE, "reg" should be a even-numbered
7991 //    float register, i.e. lower half of double register.
7992 //
7993 // Note:
7994 //    For ARM32, two float registers consisting a double register are updated
7995 //    together when "regType" is TYP_DOUBLE.
7996 //
7997 void LinearScan::updatePreviousInterval(RegRecord* reg, Interval* interval, RegisterType regType)
7998 {
7999     reg->previousInterval = interval;
8000
8001 #ifdef _TARGET_ARM_
8002     // Update overlapping floating point register for TYP_DOUBLE
8003     if (regType == TYP_DOUBLE)
8004     {
8005         assert(genIsValidDoubleReg(reg->regNum));
8006
8007         RegRecord* anotherHalfReg = findAnotherHalfRegRec(reg);
8008
8009         anotherHalfReg->previousInterval = interval;
8010     }
8011 #endif
8012 }
8013
8014 // LinearScan::resolveLocalRef
8015 // Description:
8016 //      Update the graph for a local reference.
8017 //      Also, track the register (if any) that is currently occupied.
8018 // Arguments:
8019 //      treeNode: The lclVar that's being resolved
8020 //      currentRefPosition: the RefPosition associated with the treeNode
8021 //
8022 // Details:
8023 // This method is called for each local reference, during the resolveRegisters
8024 // phase of LSRA.  It is responsible for keeping the following in sync:
8025 //   - varDsc->lvRegNum (and lvOtherReg) contain the unique register location.
8026 //     If it is not in the same register through its lifetime, it is set to REG_STK.
8027 //   - interval->physReg is set to the assigned register
8028 //     (i.e. at the code location which is currently being handled by resolveRegisters())
8029 //     - interval->isActive is true iff the interval is live and occupying a register
8030 //     - interval->isSpilled should have already been set to true if the interval is EVER spilled
8031 //     - interval->isSplit is set to true if the interval does not occupy the same
8032 //       register throughout the method
8033 //   - RegRecord->assignedInterval points to the interval which currently occupies
8034 //     the register
8035 //   - For each lclVar node:
8036 //     - gtRegNum/gtRegPair is set to the currently allocated register(s).
8037 //     - GTF_SPILLED is set on a use if it must be reloaded prior to use.
8038 //     - GTF_SPILL is set if it must be spilled after use.
8039 //
8040 // A copyReg is an ugly case where the variable must be in a specific (fixed) register,
8041 // but it currently resides elsewhere.  The register allocator must track the use of the
8042 // fixed register, but it marks the lclVar node with the register it currently lives in
8043 // and the code generator does the necessary move.
8044 //
8045 // Before beginning, the varDsc for each parameter must be set to its initial location.
8046 //
8047 // NICE: Consider tracking whether an Interval is always in the same location (register/stack)
8048 // in which case it will require no resolution.
8049 //
8050 void LinearScan::resolveLocalRef(BasicBlock* block, GenTreePtr treeNode, RefPosition* currentRefPosition)
8051 {
8052     assert((block == nullptr) == (treeNode == nullptr));
8053     assert(enregisterLocalVars);
8054
8055     // Is this a tracked local?  Or just a register allocated for loading
8056     // a non-tracked one?
8057     Interval* interval = currentRefPosition->getInterval();
8058     if (!interval->isLocalVar)
8059     {
8060         return;
8061     }
8062     interval->recentRefPosition = currentRefPosition;
8063     LclVarDsc* varDsc           = interval->getLocalVar(compiler);
8064
8065     // NOTE: we set the GTF_VAR_DEATH flag here unless we are extending lifetimes, in which case we write
8066     // this bit in checkLastUses. This is a bit of a hack, but is necessary because codegen requires
8067     // accurate last use info that is not reflected in the lastUse bit on ref positions when we are extending
8068     // lifetimes. See also the comments in checkLastUses.
8069     if ((treeNode != nullptr) && !extendLifetimes())
8070     {
8071         if (currentRefPosition->lastUse)
8072         {
8073             treeNode->gtFlags |= GTF_VAR_DEATH;
8074         }
8075         else
8076         {
8077             treeNode->gtFlags &= ~GTF_VAR_DEATH;
8078         }
8079     }
8080
8081     if (currentRefPosition->registerAssignment == RBM_NONE)
8082     {
8083         assert(!currentRefPosition->RequiresRegister());
8084         assert(interval->isSpilled);
8085
8086         varDsc->lvRegNum = REG_STK;
8087         if (interval->assignedReg != nullptr && interval->assignedReg->assignedInterval == interval)
8088         {
8089             updateAssignedInterval(interval->assignedReg, nullptr, interval->registerType);
8090         }
8091         interval->assignedReg = nullptr;
8092         interval->physReg     = REG_NA;
8093         if (treeNode != nullptr)
8094         {
8095             treeNode->SetContained();
8096         }
8097
8098         return;
8099     }
8100
8101     // In most cases, assigned and home registers will be the same
8102     // The exception is the copyReg case, where we've assigned a register
8103     // for a specific purpose, but will be keeping the register assignment
8104     regNumber assignedReg = currentRefPosition->assignedReg();
8105     regNumber homeReg     = assignedReg;
8106
8107     // Undo any previous association with a physical register, UNLESS this
8108     // is a copyReg
8109     if (!currentRefPosition->copyReg)
8110     {
8111         regNumber oldAssignedReg = interval->physReg;
8112         if (oldAssignedReg != REG_NA && assignedReg != oldAssignedReg)
8113         {
8114             RegRecord* oldRegRecord = getRegisterRecord(oldAssignedReg);
8115             if (oldRegRecord->assignedInterval == interval)
8116             {
8117                 updateAssignedInterval(oldRegRecord, nullptr, interval->registerType);
8118             }
8119         }
8120     }
8121
8122     if (currentRefPosition->refType == RefTypeUse && !currentRefPosition->reload)
8123     {
8124         // Was this spilled after our predecessor was scheduled?
8125         if (interval->physReg == REG_NA)
8126         {
8127             assert(inVarToRegMaps[curBBNum][varDsc->lvVarIndex] == REG_STK);
8128             currentRefPosition->reload = true;
8129         }
8130     }
8131
8132     bool reload     = currentRefPosition->reload;
8133     bool spillAfter = currentRefPosition->spillAfter;
8134
8135     // In the reload case we either:
8136     // - Set the register to REG_STK if it will be referenced only from the home location, or
8137     // - Set the register to the assigned register and set GTF_SPILLED if it must be loaded into a register.
8138     if (reload)
8139     {
8140         assert(currentRefPosition->refType != RefTypeDef);
8141         assert(interval->isSpilled);
8142         varDsc->lvRegNum = REG_STK;
8143         if (!spillAfter)
8144         {
8145             interval->physReg = assignedReg;
8146         }
8147
8148         // If there is no treeNode, this must be a RefTypeExpUse, in
8149         // which case we did the reload already
8150         if (treeNode != nullptr)
8151         {
8152             treeNode->gtFlags |= GTF_SPILLED;
8153             if (spillAfter)
8154             {
8155                 if (currentRefPosition->AllocateIfProfitable())
8156                 {
8157                     // This is a use of lclVar that is flagged as reg-optional
8158                     // by lower/codegen and marked for both reload and spillAfter.
8159                     // In this case we can avoid unnecessary reload and spill
8160                     // by setting reg on lclVar to REG_STK and reg on tree node
8161                     // to REG_NA.  Codegen will generate the code by considering
8162                     // it as a contained memory operand.
8163                     //
8164                     // Note that varDsc->lvRegNum is already to REG_STK above.
8165                     interval->physReg  = REG_NA;
8166                     treeNode->gtRegNum = REG_NA;
8167                     treeNode->gtFlags &= ~GTF_SPILLED;
8168                     treeNode->SetContained();
8169                 }
8170                 else
8171                 {
8172                     treeNode->gtFlags |= GTF_SPILL;
8173                 }
8174             }
8175         }
8176         else
8177         {
8178             assert(currentRefPosition->refType == RefTypeExpUse);
8179         }
8180     }
8181     else if (spillAfter && !RefTypeIsUse(currentRefPosition->refType))
8182     {
8183         // In the case of a pure def, don't bother spilling - just assign it to the
8184         // stack.  However, we need to remember that it was spilled.
8185
8186         assert(interval->isSpilled);
8187         varDsc->lvRegNum  = REG_STK;
8188         interval->physReg = REG_NA;
8189         if (treeNode != nullptr)
8190         {
8191             treeNode->gtRegNum = REG_NA;
8192         }
8193     }
8194     else
8195     {
8196         // Not reload and Not pure-def that's spillAfter
8197
8198         if (currentRefPosition->copyReg || currentRefPosition->moveReg)
8199         {
8200             // For a copyReg or moveReg, we have two cases:
8201             //  - In the first case, we have a fixedReg - i.e. a register which the code
8202             //    generator is constrained to use.
8203             //    The code generator will generate the appropriate move to meet the requirement.
8204             //  - In the second case, we were forced to use a different register because of
8205             //    interference (or JitStressRegs).
8206             //    In this case, we generate a GT_COPY.
8207             // In either case, we annotate the treeNode with the register in which the value
8208             // currently lives.  For moveReg, the homeReg is the new register (as assigned above).
8209             // But for copyReg, the homeReg remains unchanged.
8210
8211             assert(treeNode != nullptr);
8212             treeNode->gtRegNum = interval->physReg;
8213
8214             if (currentRefPosition->copyReg)
8215             {
8216                 homeReg = interval->physReg;
8217             }
8218             else
8219             {
8220                 assert(interval->isSplit);
8221                 interval->physReg = assignedReg;
8222             }
8223
8224             if (!currentRefPosition->isFixedRegRef || currentRefPosition->moveReg)
8225             {
8226                 // This is the second case, where we need to generate a copy
8227                 insertCopyOrReload(block, treeNode, currentRefPosition->getMultiRegIdx(), currentRefPosition);
8228             }
8229         }
8230         else
8231         {
8232             interval->physReg = assignedReg;
8233
8234             if (!interval->isSpilled && !interval->isSplit)
8235             {
8236                 if (varDsc->lvRegNum != REG_STK)
8237                 {
8238                     // If the register assignments don't match, then this interval is split.
8239                     if (varDsc->lvRegNum != assignedReg)
8240                     {
8241                         setIntervalAsSplit(interval);
8242                         varDsc->lvRegNum = REG_STK;
8243                     }
8244                 }
8245                 else
8246                 {
8247                     varDsc->lvRegNum = assignedReg;
8248                 }
8249             }
8250         }
8251         if (spillAfter)
8252         {
8253             if (treeNode != nullptr)
8254             {
8255                 treeNode->gtFlags |= GTF_SPILL;
8256             }
8257             assert(interval->isSpilled);
8258             interval->physReg = REG_NA;
8259             varDsc->lvRegNum  = REG_STK;
8260         }
8261     }
8262
8263     // Update the physRegRecord for the register, so that we know what vars are in
8264     // regs at the block boundaries
8265     RegRecord* physRegRecord = getRegisterRecord(homeReg);
8266     if (spillAfter || currentRefPosition->lastUse)
8267     {
8268         interval->isActive    = false;
8269         interval->assignedReg = nullptr;
8270         interval->physReg     = REG_NA;
8271
8272         updateAssignedInterval(physRegRecord, nullptr, interval->registerType);
8273     }
8274     else
8275     {
8276         interval->isActive    = true;
8277         interval->assignedReg = physRegRecord;
8278
8279         updateAssignedInterval(physRegRecord, interval, interval->registerType);
8280     }
8281 }
8282
8283 void LinearScan::writeRegisters(RefPosition* currentRefPosition, GenTree* tree)
8284 {
8285     lsraAssignRegToTree(tree, currentRefPosition->assignedReg(), currentRefPosition->getMultiRegIdx());
8286 }
8287
8288 //------------------------------------------------------------------------
8289 // insertCopyOrReload: Insert a copy in the case where a tree node value must be moved
8290 //   to a different register at the point of use (GT_COPY), or it is reloaded to a different register
8291 //   than the one it was spilled from (GT_RELOAD).
8292 //
8293 // Arguments:
8294 //    block             - basic block in which GT_COPY/GT_RELOAD is inserted.
8295 //    tree              - This is the node to copy or reload.
8296 //                        Insert copy or reload node between this node and its parent.
8297 //    multiRegIdx       - register position of tree node for which copy or reload is needed.
8298 //    refPosition       - The RefPosition at which copy or reload will take place.
8299 //
8300 // Notes:
8301 //    The GT_COPY or GT_RELOAD will be inserted in the proper spot in execution order where the reload is to occur.
8302 //
8303 // For example, for this tree (numbers are execution order, lower is earlier and higher is later):
8304 //
8305 //                                   +---------+----------+
8306 //                                   |       GT_ADD (3)   |
8307 //                                   +---------+----------+
8308 //                                             |
8309 //                                           /   \
8310 //                                         /       \
8311 //                                       /           \
8312 //                   +-------------------+           +----------------------+
8313 //                   |         x (1)     | "tree"    |         y (2)        |
8314 //                   +-------------------+           +----------------------+
8315 //
8316 // generate this tree:
8317 //
8318 //                                   +---------+----------+
8319 //                                   |       GT_ADD (4)   |
8320 //                                   +---------+----------+
8321 //                                             |
8322 //                                           /   \
8323 //                                         /       \
8324 //                                       /           \
8325 //                   +-------------------+           +----------------------+
8326 //                   |  GT_RELOAD (3)    |           |         y (2)        |
8327 //                   +-------------------+           +----------------------+
8328 //                             |
8329 //                   +-------------------+
8330 //                   |         x (1)     | "tree"
8331 //                   +-------------------+
8332 //
8333 // Note in particular that the GT_RELOAD node gets inserted in execution order immediately before the parent of "tree",
8334 // which seems a bit weird since normally a node's parent (in this case, the parent of "x", GT_RELOAD in the "after"
8335 // picture) immediately follows all of its children (that is, normally the execution ordering is postorder).
8336 // The ordering must be this weird "out of normal order" way because the "x" node is being spilled, probably
8337 // because the expression in the tree represented above by "y" has high register requirements. We don't want
8338 // to reload immediately, of course. So we put GT_RELOAD where the reload should actually happen.
8339 //
8340 // Note that GT_RELOAD is required when we reload to a different register than the one we spilled to. It can also be
8341 // used if we reload to the same register. Normally, though, in that case we just mark the node with GTF_SPILLED,
8342 // and the unspilling code automatically reuses the same register, and does the reload when it notices that flag
8343 // when considering a node's operands.
8344 //
8345 void LinearScan::insertCopyOrReload(BasicBlock* block, GenTreePtr tree, unsigned multiRegIdx, RefPosition* refPosition)
8346 {
8347     LIR::Range& blockRange = LIR::AsRange(block);
8348
8349     LIR::Use treeUse;
8350     bool     foundUse = blockRange.TryGetUse(tree, &treeUse);
8351     assert(foundUse);
8352
8353     GenTree* parent = treeUse.User();
8354
8355     genTreeOps oper;
8356     if (refPosition->reload)
8357     {
8358         oper = GT_RELOAD;
8359     }
8360     else
8361     {
8362         oper = GT_COPY;
8363
8364 #if TRACK_LSRA_STATS
8365         updateLsraStat(LSRA_STAT_COPY_REG, block->bbNum);
8366 #endif
8367     }
8368
8369     // If the parent is a reload/copy node, then tree must be a multi-reg call node
8370     // that has already had one of its registers spilled. This is Because multi-reg
8371     // call node is the only node whose RefTypeDef positions get independently
8372     // spilled or reloaded.  It is possible that one of its RefTypeDef position got
8373     // spilled and the next use of it requires it to be in a different register.
8374     //
8375     // In this case set the ith position reg of reload/copy node to the reg allocated
8376     // for copy/reload refPosition.  Essentially a copy/reload node will have a reg
8377     // for each multi-reg position of its child. If there is a valid reg in ith
8378     // position of GT_COPY or GT_RELOAD node then the corresponding result of its
8379     // child needs to be copied or reloaded to that reg.
8380     if (parent->IsCopyOrReload())
8381     {
8382         noway_assert(parent->OperGet() == oper);
8383         noway_assert(tree->IsMultiRegCall());
8384         GenTreeCall*         call         = tree->AsCall();
8385         GenTreeCopyOrReload* copyOrReload = parent->AsCopyOrReload();
8386         noway_assert(copyOrReload->GetRegNumByIdx(multiRegIdx) == REG_NA);
8387         copyOrReload->SetRegNumByIdx(refPosition->assignedReg(), multiRegIdx);
8388     }
8389     else
8390     {
8391         // Create the new node, with "tree" as its only child.
8392         var_types treeType = tree->TypeGet();
8393
8394         GenTreeCopyOrReload* newNode = new (compiler, oper) GenTreeCopyOrReload(oper, treeType, tree);
8395         assert(refPosition->registerAssignment != RBM_NONE);
8396         newNode->SetRegNumByIdx(refPosition->assignedReg(), multiRegIdx);
8397         newNode->gtLsraInfo.isLsraAdded   = true;
8398         newNode->gtLsraInfo.isLocalDefUse = false;
8399         if (refPosition->copyReg)
8400         {
8401             // This is a TEMPORARY copy
8402             assert(isCandidateLocalRef(tree));
8403             newNode->gtFlags |= GTF_VAR_DEATH;
8404         }
8405
8406         // Insert the copy/reload after the spilled node and replace the use of the original node with a use
8407         // of the copy/reload.
8408         blockRange.InsertAfter(tree, newNode);
8409         treeUse.ReplaceWith(compiler, newNode);
8410     }
8411 }
8412
8413 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
8414 //------------------------------------------------------------------------
8415 // insertUpperVectorSaveAndReload: Insert code to save and restore the upper half of a vector that lives
8416 //                                 in a callee-save register at the point of a kill (the upper half is
8417 //                                 not preserved).
8418 //
8419 // Arguments:
8420 //    tree              - This is the node around which we will insert the Save & Reload.
8421 //                        It will be a call or some node that turns into a call.
8422 //    refPosition       - The RefTypeUpperVectorSaveDef RefPosition.
8423 //
8424 void LinearScan::insertUpperVectorSaveAndReload(GenTreePtr tree, RefPosition* refPosition, BasicBlock* block)
8425 {
8426     Interval* lclVarInterval = refPosition->getInterval()->relatedInterval;
8427     assert(lclVarInterval->isLocalVar == true);
8428     LclVarDsc* varDsc = compiler->lvaTable + lclVarInterval->varNum;
8429     assert(varDsc->lvType == LargeVectorType);
8430     regNumber lclVarReg = lclVarInterval->physReg;
8431     if (lclVarReg == REG_NA)
8432     {
8433         return;
8434     }
8435
8436     assert((genRegMask(lclVarReg) & RBM_FLT_CALLEE_SAVED) != RBM_NONE);
8437
8438     regNumber spillReg   = refPosition->assignedReg();
8439     bool      spillToMem = refPosition->spillAfter;
8440
8441     LIR::Range& blockRange = LIR::AsRange(block);
8442
8443     // First, insert the save before the call.
8444
8445     GenTreePtr saveLcl                = compiler->gtNewLclvNode(lclVarInterval->varNum, LargeVectorType);
8446     saveLcl->gtLsraInfo.isLsraAdded   = true;
8447     saveLcl->gtRegNum                 = lclVarReg;
8448     saveLcl->gtLsraInfo.isLocalDefUse = false;
8449
8450     GenTreeSIMD* simdNode =
8451         new (compiler, GT_SIMD) GenTreeSIMD(LargeVectorSaveType, saveLcl, nullptr, SIMDIntrinsicUpperSave,
8452                                             varDsc->lvBaseType, genTypeSize(LargeVectorType));
8453     simdNode->gtLsraInfo.isLsraAdded = true;
8454     simdNode->gtRegNum               = spillReg;
8455     if (spillToMem)
8456     {
8457         simdNode->gtFlags |= GTF_SPILL;
8458     }
8459
8460     blockRange.InsertBefore(tree, LIR::SeqTree(compiler, simdNode));
8461
8462     // Now insert the restore after the call.
8463
8464     GenTreePtr restoreLcl                = compiler->gtNewLclvNode(lclVarInterval->varNum, LargeVectorType);
8465     restoreLcl->gtLsraInfo.isLsraAdded   = true;
8466     restoreLcl->gtRegNum                 = lclVarReg;
8467     restoreLcl->gtLsraInfo.isLocalDefUse = false;
8468
8469     simdNode = new (compiler, GT_SIMD)
8470         GenTreeSIMD(LargeVectorType, restoreLcl, nullptr, SIMDIntrinsicUpperRestore, varDsc->lvBaseType, 32);
8471     simdNode->gtLsraInfo.isLsraAdded = true;
8472     simdNode->gtRegNum               = spillReg;
8473     if (spillToMem)
8474     {
8475         simdNode->gtFlags |= GTF_SPILLED;
8476     }
8477
8478     blockRange.InsertAfter(tree, LIR::SeqTree(compiler, simdNode));
8479 }
8480 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
8481
8482 //------------------------------------------------------------------------
8483 // initMaxSpill: Initializes the LinearScan members used to track the max number
8484 //               of concurrent spills.  This is needed so that we can set the
8485 //               fields in Compiler, so that the code generator, in turn can
8486 //               allocate the right number of spill locations.
8487 //
8488 // Arguments:
8489 //    None.
8490 //
8491 // Return Value:
8492 //    None.
8493 //
8494 // Assumptions:
8495 //    This is called before any calls to updateMaxSpill().
8496
8497 void LinearScan::initMaxSpill()
8498 {
8499     needDoubleTmpForFPCall = false;
8500     needFloatTmpForFPCall  = false;
8501     for (int i = 0; i < TYP_COUNT; i++)
8502     {
8503         maxSpill[i]     = 0;
8504         currentSpill[i] = 0;
8505     }
8506 }
8507
8508 //------------------------------------------------------------------------
8509 // recordMaxSpill: Sets the fields in Compiler for the max number of concurrent spills.
8510 //                 (See the comment on initMaxSpill.)
8511 //
8512 // Arguments:
8513 //    None.
8514 //
8515 // Return Value:
8516 //    None.
8517 //
8518 // Assumptions:
8519 //    This is called after updateMaxSpill() has been called for all "real"
8520 //    RefPositions.
8521
8522 void LinearScan::recordMaxSpill()
8523 {
8524     // Note: due to the temp normalization process (see tmpNormalizeType)
8525     // only a few types should actually be seen here.
8526     JITDUMP("Recording the maximum number of concurrent spills:\n");
8527 #ifdef _TARGET_X86_
8528     var_types returnType = compiler->tmpNormalizeType(compiler->info.compRetType);
8529     if (needDoubleTmpForFPCall || (returnType == TYP_DOUBLE))
8530     {
8531         JITDUMP("Adding a spill temp for moving a double call/return value between xmm reg and x87 stack.\n");
8532         maxSpill[TYP_DOUBLE] += 1;
8533     }
8534     if (needFloatTmpForFPCall || (returnType == TYP_FLOAT))
8535     {
8536         JITDUMP("Adding a spill temp for moving a float call/return value between xmm reg and x87 stack.\n");
8537         maxSpill[TYP_FLOAT] += 1;
8538     }
8539 #endif // _TARGET_X86_
8540     for (int i = 0; i < TYP_COUNT; i++)
8541     {
8542         if (var_types(i) != compiler->tmpNormalizeType(var_types(i)))
8543         {
8544             // Only normalized types should have anything in the maxSpill array.
8545             // We assume here that if type 'i' does not normalize to itself, then
8546             // nothing else normalizes to 'i', either.
8547             assert(maxSpill[i] == 0);
8548         }
8549         if (maxSpill[i] != 0)
8550         {
8551             JITDUMP("  %s: %d\n", varTypeName(var_types(i)), maxSpill[i]);
8552             compiler->tmpPreAllocateTemps(var_types(i), maxSpill[i]);
8553         }
8554     }
8555     JITDUMP("\n");
8556 }
8557
8558 //------------------------------------------------------------------------
8559 // updateMaxSpill: Update the maximum number of concurrent spills
8560 //
8561 // Arguments:
8562 //    refPosition - the current RefPosition being handled
8563 //
8564 // Return Value:
8565 //    None.
8566 //
8567 // Assumptions:
8568 //    The RefPosition has an associated interval (getInterval() will
8569 //    otherwise assert).
8570 //
8571 // Notes:
8572 //    This is called for each "real" RefPosition during the writeback
8573 //    phase of LSRA.  It keeps track of how many concurrently-live
8574 //    spills there are, and the largest number seen so far.
8575
8576 void LinearScan::updateMaxSpill(RefPosition* refPosition)
8577 {
8578     RefType refType = refPosition->refType;
8579
8580     if (refPosition->spillAfter || refPosition->reload ||
8581         (refPosition->AllocateIfProfitable() && refPosition->assignedReg() == REG_NA))
8582     {
8583         Interval* interval = refPosition->getInterval();
8584         if (!interval->isLocalVar)
8585         {
8586             // The tmp allocation logic 'normalizes' types to a small number of
8587             // types that need distinct stack locations from each other.
8588             // Those types are currently gc refs, byrefs, <= 4 byte non-GC items,
8589             // 8-byte non-GC items, and 16-byte or 32-byte SIMD vectors.
8590             // LSRA is agnostic to those choices but needs
8591             // to know what they are here.
8592             var_types typ;
8593
8594 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
8595             if ((refType == RefTypeUpperVectorSaveDef) || (refType == RefTypeUpperVectorSaveUse))
8596             {
8597                 typ = LargeVectorSaveType;
8598             }
8599             else
8600 #endif // !FEATURE_PARTIAL_SIMD_CALLEE_SAVE
8601             {
8602                 GenTreePtr treeNode = refPosition->treeNode;
8603                 if (treeNode == nullptr)
8604                 {
8605                     assert(RefTypeIsUse(refType));
8606                     treeNode = interval->firstRefPosition->treeNode;
8607                 }
8608                 assert(treeNode != nullptr);
8609
8610                 // In case of multi-reg call nodes, we need to use the type
8611                 // of the return register given by multiRegIdx of the refposition.
8612                 if (treeNode->IsMultiRegCall())
8613                 {
8614                     ReturnTypeDesc* retTypeDesc = treeNode->AsCall()->GetReturnTypeDesc();
8615                     typ                         = retTypeDesc->GetReturnRegType(refPosition->getMultiRegIdx());
8616                 }
8617                 else
8618                 {
8619                     typ = treeNode->TypeGet();
8620                 }
8621                 typ = compiler->tmpNormalizeType(typ);
8622             }
8623
8624             if (refPosition->spillAfter && !refPosition->reload)
8625             {
8626                 currentSpill[typ]++;
8627                 if (currentSpill[typ] > maxSpill[typ])
8628                 {
8629                     maxSpill[typ] = currentSpill[typ];
8630                 }
8631             }
8632             else if (refPosition->reload)
8633             {
8634                 assert(currentSpill[typ] > 0);
8635                 currentSpill[typ]--;
8636             }
8637             else if (refPosition->AllocateIfProfitable() && refPosition->assignedReg() == REG_NA)
8638             {
8639                 // A spill temp not getting reloaded into a reg because it is
8640                 // marked as allocate if profitable and getting used from its
8641                 // memory location.  To properly account max spill for typ we
8642                 // decrement spill count.
8643                 assert(RefTypeIsUse(refType));
8644                 assert(currentSpill[typ] > 0);
8645                 currentSpill[typ]--;
8646             }
8647             JITDUMP("  Max spill for %s is %d\n", varTypeName(typ), maxSpill[typ]);
8648         }
8649     }
8650 }
8651
8652 // This is the final phase of register allocation.  It writes the register assignments to
8653 // the tree, and performs resolution across joins and backedges.
8654 //
8655 void LinearScan::resolveRegisters()
8656 {
8657     // Iterate over the tree and the RefPositions in lockstep
8658     //  - annotate the tree with register assignments by setting gtRegNum or gtRegPair (for longs)
8659     //    on the tree node
8660     //  - track globally-live var locations
8661     //  - add resolution points at split/merge/critical points as needed
8662
8663     // Need to use the same traversal order as the one that assigns the location numbers.
8664
8665     // Dummy RefPositions have been added at any split, join or critical edge, at the
8666     // point where resolution may be required.  These are located:
8667     //  - for a split, at the top of the non-adjacent block
8668     //  - for a join, at the bottom of the non-adjacent joining block
8669     //  - for a critical edge, at the top of the target block of each critical
8670     //    edge.
8671     // Note that a target block may have multiple incoming critical or split edges
8672     //
8673     // These RefPositions record the expected location of the Interval at that point.
8674     // At each branch, we identify the location of each liveOut interval, and check
8675     // against the RefPositions at the target.
8676
8677     BasicBlock*  block;
8678     LsraLocation currentLocation = MinLocation;
8679
8680     // Clear register assignments - these will be reestablished as lclVar defs (including RefTypeParamDefs)
8681     // are encountered.
8682     if (enregisterLocalVars)
8683     {
8684         for (regNumber reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
8685         {
8686             RegRecord* physRegRecord    = getRegisterRecord(reg);
8687             Interval*  assignedInterval = physRegRecord->assignedInterval;
8688             if (assignedInterval != nullptr)
8689             {
8690                 assignedInterval->assignedReg = nullptr;
8691                 assignedInterval->physReg     = REG_NA;
8692             }
8693             physRegRecord->assignedInterval  = nullptr;
8694             physRegRecord->recentRefPosition = nullptr;
8695         }
8696
8697         // Clear "recentRefPosition" for lclVar intervals
8698         for (unsigned varIndex = 0; varIndex < compiler->lvaTrackedCount; varIndex++)
8699         {
8700             if (localVarIntervals[varIndex] != nullptr)
8701             {
8702                 localVarIntervals[varIndex]->recentRefPosition = nullptr;
8703                 localVarIntervals[varIndex]->isActive          = false;
8704             }
8705             else
8706             {
8707                 assert(compiler->lvaTable[compiler->lvaTrackedToVarNum[varIndex]].lvLRACandidate == false);
8708             }
8709         }
8710     }
8711
8712     // handle incoming arguments and special temps
8713     auto currentRefPosition = refPositions.begin();
8714
8715     if (enregisterLocalVars)
8716     {
8717         VarToRegMap entryVarToRegMap = inVarToRegMaps[compiler->fgFirstBB->bbNum];
8718         while (currentRefPosition != refPositions.end() &&
8719                (currentRefPosition->refType == RefTypeParamDef || currentRefPosition->refType == RefTypeZeroInit))
8720         {
8721             Interval* interval = currentRefPosition->getInterval();
8722             assert(interval != nullptr && interval->isLocalVar);
8723             resolveLocalRef(nullptr, nullptr, currentRefPosition);
8724             regNumber reg      = REG_STK;
8725             int       varIndex = interval->getVarIndex(compiler);
8726
8727             if (!currentRefPosition->spillAfter && currentRefPosition->registerAssignment != RBM_NONE)
8728             {
8729                 reg = currentRefPosition->assignedReg();
8730             }
8731             else
8732             {
8733                 reg                = REG_STK;
8734                 interval->isActive = false;
8735             }
8736             setVarReg(entryVarToRegMap, varIndex, reg);
8737             ++currentRefPosition;
8738         }
8739     }
8740     else
8741     {
8742         assert(currentRefPosition == refPositions.end() ||
8743                (currentRefPosition->refType != RefTypeParamDef && currentRefPosition->refType != RefTypeZeroInit));
8744     }
8745
8746     BasicBlock* insertionBlock = compiler->fgFirstBB;
8747     GenTreePtr  insertionPoint = LIR::AsRange(insertionBlock).FirstNonPhiNode();
8748
8749     // write back assignments
8750     for (block = startBlockSequence(); block != nullptr; block = moveToNextBlock())
8751     {
8752         assert(curBBNum == block->bbNum);
8753
8754         if (enregisterLocalVars)
8755         {
8756             // Record the var locations at the start of this block.
8757             // (If it's fgFirstBB, we've already done that above, see entryVarToRegMap)
8758
8759             curBBStartLocation = currentRefPosition->nodeLocation;
8760             if (block != compiler->fgFirstBB)
8761             {
8762                 processBlockStartLocations(block, false);
8763             }
8764
8765             // Handle the DummyDefs, updating the incoming var location.
8766             for (; currentRefPosition != refPositions.end() && currentRefPosition->refType == RefTypeDummyDef;
8767                  ++currentRefPosition)
8768             {
8769                 assert(currentRefPosition->isIntervalRef());
8770                 // Don't mark dummy defs as reload
8771                 currentRefPosition->reload = false;
8772                 resolveLocalRef(nullptr, nullptr, currentRefPosition);
8773                 regNumber reg;
8774                 if (currentRefPosition->registerAssignment != RBM_NONE)
8775                 {
8776                     reg = currentRefPosition->assignedReg();
8777                 }
8778                 else
8779                 {
8780                     reg                                         = REG_STK;
8781                     currentRefPosition->getInterval()->isActive = false;
8782                 }
8783                 setInVarRegForBB(curBBNum, currentRefPosition->getInterval()->varNum, reg);
8784             }
8785         }
8786
8787         // The next RefPosition should be for the block.  Move past it.
8788         assert(currentRefPosition != refPositions.end());
8789         assert(currentRefPosition->refType == RefTypeBB);
8790         ++currentRefPosition;
8791
8792         // Handle the RefPositions for the block
8793         for (; currentRefPosition != refPositions.end() && currentRefPosition->refType != RefTypeBB &&
8794                currentRefPosition->refType != RefTypeDummyDef;
8795              ++currentRefPosition)
8796         {
8797             currentLocation = currentRefPosition->nodeLocation;
8798
8799             // Ensure that the spill & copy info is valid.
8800             // First, if it's reload, it must not be copyReg or moveReg
8801             assert(!currentRefPosition->reload || (!currentRefPosition->copyReg && !currentRefPosition->moveReg));
8802             // If it's copyReg it must not be moveReg, and vice-versa
8803             assert(!currentRefPosition->copyReg || !currentRefPosition->moveReg);
8804
8805             switch (currentRefPosition->refType)
8806             {
8807 #ifdef FEATURE_SIMD
8808                 case RefTypeUpperVectorSaveUse:
8809                 case RefTypeUpperVectorSaveDef:
8810 #endif // FEATURE_SIMD
8811                 case RefTypeUse:
8812                 case RefTypeDef:
8813                     // These are the ones we're interested in
8814                     break;
8815                 case RefTypeKill:
8816                 case RefTypeFixedReg:
8817                     // These require no handling at resolution time
8818                     assert(currentRefPosition->referent != nullptr);
8819                     currentRefPosition->referent->recentRefPosition = currentRefPosition;
8820                     continue;
8821                 case RefTypeExpUse:
8822                     // Ignore the ExpUse cases - a RefTypeExpUse would only exist if the
8823                     // variable is dead at the entry to the next block.  So we'll mark
8824                     // it as in its current location and resolution will take care of any
8825                     // mismatch.
8826                     assert(getNextBlock() == nullptr ||
8827                            !VarSetOps::IsMember(compiler, getNextBlock()->bbLiveIn,
8828                                                 currentRefPosition->getInterval()->getVarIndex(compiler)));
8829                     currentRefPosition->referent->recentRefPosition = currentRefPosition;
8830                     continue;
8831                 case RefTypeKillGCRefs:
8832                     // No action to take at resolution time, and no interval to update recentRefPosition for.
8833                     continue;
8834                 case RefTypeDummyDef:
8835                 case RefTypeParamDef:
8836                 case RefTypeZeroInit:
8837                 // Should have handled all of these already
8838                 default:
8839                     unreached();
8840                     break;
8841             }
8842             updateMaxSpill(currentRefPosition);
8843             GenTree* treeNode = currentRefPosition->treeNode;
8844
8845 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
8846             if (currentRefPosition->refType == RefTypeUpperVectorSaveDef)
8847             {
8848                 // The treeNode must be a call, and this must be a RefPosition for a LargeVectorType LocalVar.
8849                 // If the LocalVar is in a callee-save register, we are going to spill its upper half around the call.
8850                 // If we have allocated a register to spill it to, we will use that; otherwise, we will spill it
8851                 // to the stack.  We can use as a temp register any non-arg caller-save register.
8852                 noway_assert(treeNode != nullptr);
8853                 currentRefPosition->referent->recentRefPosition = currentRefPosition;
8854                 insertUpperVectorSaveAndReload(treeNode, currentRefPosition, block);
8855             }
8856             else if (currentRefPosition->refType == RefTypeUpperVectorSaveUse)
8857             {
8858                 continue;
8859             }
8860 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
8861
8862             // Most uses won't actually need to be recorded (they're on the def).
8863             // In those cases, treeNode will be nullptr.
8864             if (treeNode == nullptr)
8865             {
8866                 // This is either a use, a dead def, or a field of a struct
8867                 Interval* interval = currentRefPosition->getInterval();
8868                 assert(currentRefPosition->refType == RefTypeUse ||
8869                        currentRefPosition->registerAssignment == RBM_NONE || interval->isStructField);
8870
8871                 // TODO-Review: Need to handle the case where any of the struct fields
8872                 // are reloaded/spilled at this use
8873                 assert(!interval->isStructField ||
8874                        (currentRefPosition->reload == false && currentRefPosition->spillAfter == false));
8875
8876                 if (interval->isLocalVar && !interval->isStructField)
8877                 {
8878                     LclVarDsc* varDsc = interval->getLocalVar(compiler);
8879
8880                     // This must be a dead definition.  We need to mark the lclVar
8881                     // so that it's not considered a candidate for lvRegister, as
8882                     // this dead def will have to go to the stack.
8883                     assert(currentRefPosition->refType == RefTypeDef);
8884                     varDsc->lvRegNum = REG_STK;
8885                 }
8886                 continue;
8887             }
8888
8889             LsraLocation loc = treeNode->gtLsraInfo.loc;
8890             assert(treeNode->IsLocal() || currentLocation == loc || currentLocation == loc + 1);
8891
8892             if (currentRefPosition->isIntervalRef() && currentRefPosition->getInterval()->isInternal)
8893             {
8894                 treeNode->gtRsvdRegs |= currentRefPosition->registerAssignment;
8895             }
8896             else
8897             {
8898                 writeRegisters(currentRefPosition, treeNode);
8899
8900                 if (treeNode->IsLocal() && currentRefPosition->getInterval()->isLocalVar)
8901                 {
8902                     resolveLocalRef(block, treeNode, currentRefPosition);
8903                 }
8904
8905                 // Mark spill locations on temps
8906                 // (local vars are handled in resolveLocalRef, above)
8907                 // Note that the tree node will be changed from GTF_SPILL to GTF_SPILLED
8908                 // in codegen, taking care of the "reload" case for temps
8909                 else if (currentRefPosition->spillAfter || (currentRefPosition->nextRefPosition != nullptr &&
8910                                                             currentRefPosition->nextRefPosition->moveReg))
8911                 {
8912                     if (treeNode != nullptr && currentRefPosition->isIntervalRef())
8913                     {
8914                         if (currentRefPosition->spillAfter)
8915                         {
8916                             treeNode->gtFlags |= GTF_SPILL;
8917
8918                             // If this is a constant interval that is reusing a pre-existing value, we actually need
8919                             // to generate the value at this point in order to spill it.
8920                             if (treeNode->IsReuseRegVal())
8921                             {
8922                                 treeNode->ResetReuseRegVal();
8923                             }
8924
8925                             // In case of multi-reg call node, also set spill flag on the
8926                             // register specified by multi-reg index of current RefPosition.
8927                             // Note that the spill flag on treeNode indicates that one or
8928                             // more its allocated registers are in that state.
8929                             if (treeNode->IsMultiRegCall())
8930                             {
8931                                 GenTreeCall* call = treeNode->AsCall();
8932                                 call->SetRegSpillFlagByIdx(GTF_SPILL, currentRefPosition->getMultiRegIdx());
8933                             }
8934 #ifdef _TARGET_ARM_
8935                             else if (treeNode->OperIsPutArgSplit())
8936                             {
8937                                 GenTreePutArgSplit* splitArg = treeNode->AsPutArgSplit();
8938                                 splitArg->SetRegSpillFlagByIdx(GTF_SPILL, currentRefPosition->getMultiRegIdx());
8939                             }
8940 #endif
8941                         }
8942
8943                         // If the value is reloaded or moved to a different register, we need to insert
8944                         // a node to hold the register to which it should be reloaded
8945                         RefPosition* nextRefPosition = currentRefPosition->nextRefPosition;
8946                         assert(nextRefPosition != nullptr);
8947                         if (INDEBUG(alwaysInsertReload() ||)
8948                                 nextRefPosition->assignedReg() != currentRefPosition->assignedReg())
8949                         {
8950                             if (nextRefPosition->assignedReg() != REG_NA)
8951                             {
8952                                 insertCopyOrReload(block, treeNode, currentRefPosition->getMultiRegIdx(),
8953                                                    nextRefPosition);
8954                             }
8955                             else
8956                             {
8957                                 assert(nextRefPosition->AllocateIfProfitable());
8958
8959                                 // In case of tree temps, if def is spilled and use didn't
8960                                 // get a register, set a flag on tree node to be treated as
8961                                 // contained at the point of its use.
8962                                 if (currentRefPosition->spillAfter && currentRefPosition->refType == RefTypeDef &&
8963                                     nextRefPosition->refType == RefTypeUse)
8964                                 {
8965                                     assert(nextRefPosition->treeNode == nullptr);
8966                                     treeNode->gtFlags |= GTF_NOREG_AT_USE;
8967                                 }
8968                             }
8969                         }
8970                     }
8971
8972                     // We should never have to "spill after" a temp use, since
8973                     // they're single use
8974                     else
8975                     {
8976                         unreached();
8977                     }
8978                 }
8979             }
8980         }
8981
8982         if (enregisterLocalVars)
8983         {
8984             processBlockEndLocations(block);
8985         }
8986     }
8987
8988     if (enregisterLocalVars)
8989     {
8990 #ifdef DEBUG
8991         if (VERBOSE)
8992         {
8993             printf("-----------------------\n");
8994             printf("RESOLVING BB BOUNDARIES\n");
8995             printf("-----------------------\n");
8996
8997             printf("Resolution Candidates: ");
8998             dumpConvertedVarSet(compiler, resolutionCandidateVars);
8999             printf("\n");
9000             printf("Has %sCritical Edges\n\n", hasCriticalEdges ? "" : "No");
9001
9002             printf("Prior to Resolution\n");
9003             foreach_block(compiler, block)
9004             {
9005                 printf("\nBB%02u use def in out\n", block->bbNum);
9006                 dumpConvertedVarSet(compiler, block->bbVarUse);
9007                 printf("\n");
9008                 dumpConvertedVarSet(compiler, block->bbVarDef);
9009                 printf("\n");
9010                 dumpConvertedVarSet(compiler, block->bbLiveIn);
9011                 printf("\n");
9012                 dumpConvertedVarSet(compiler, block->bbLiveOut);
9013                 printf("\n");
9014
9015                 dumpInVarToRegMap(block);
9016                 dumpOutVarToRegMap(block);
9017             }
9018
9019             printf("\n\n");
9020         }
9021 #endif // DEBUG
9022
9023         resolveEdges();
9024
9025         // Verify register assignments on variables
9026         unsigned   lclNum;
9027         LclVarDsc* varDsc;
9028         for (lclNum = 0, varDsc = compiler->lvaTable; lclNum < compiler->lvaCount; lclNum++, varDsc++)
9029         {
9030             if (!isCandidateVar(varDsc))
9031             {
9032                 varDsc->lvRegNum = REG_STK;
9033             }
9034             else
9035             {
9036                 Interval* interval = getIntervalForLocalVar(varDsc->lvVarIndex);
9037
9038                 // Determine initial position for parameters
9039
9040                 if (varDsc->lvIsParam)
9041                 {
9042                     regMaskTP initialRegMask = interval->firstRefPosition->registerAssignment;
9043                     regNumber initialReg     = (initialRegMask == RBM_NONE || interval->firstRefPosition->spillAfter)
9044                                                ? REG_STK
9045                                                : genRegNumFromMask(initialRegMask);
9046                     regNumber sourceReg = (varDsc->lvIsRegArg) ? varDsc->lvArgReg : REG_STK;
9047
9048 #ifdef _TARGET_ARM_
9049                     if (varTypeIsMultiReg(varDsc))
9050                     {
9051                         // TODO-ARM-NYI: Map the hi/lo intervals back to lvRegNum and lvOtherReg (these should NYI
9052                         // before this)
9053                         assert(!"Multi-reg types not yet supported");
9054                     }
9055                     else
9056 #endif // _TARGET_ARM_
9057                     {
9058                         varDsc->lvArgInitReg = initialReg;
9059                         JITDUMP("  Set V%02u argument initial register to %s\n", lclNum, getRegName(initialReg));
9060                     }
9061
9062                     // Stack args that are part of dependently-promoted structs should never be register candidates (see
9063                     // LinearScan::isRegCandidate).
9064                     assert(varDsc->lvIsRegArg || !compiler->lvaIsFieldOfDependentlyPromotedStruct(varDsc));
9065                 }
9066
9067                 // If lvRegNum is REG_STK, that means that either no register
9068                 // was assigned, or (more likely) that the same register was not
9069                 // used for all references.  In that case, codegen gets the register
9070                 // from the tree node.
9071                 if (varDsc->lvRegNum == REG_STK || interval->isSpilled || interval->isSplit)
9072                 {
9073                     // For codegen purposes, we'll set lvRegNum to whatever register
9074                     // it's currently in as we go.
9075                     // However, we never mark an interval as lvRegister if it has either been spilled
9076                     // or split.
9077                     varDsc->lvRegister = false;
9078
9079                     // Skip any dead defs or exposed uses
9080                     // (first use exposed will only occur when there is no explicit initialization)
9081                     RefPosition* firstRefPosition = interval->firstRefPosition;
9082                     while ((firstRefPosition != nullptr) && (firstRefPosition->refType == RefTypeExpUse))
9083                     {
9084                         firstRefPosition = firstRefPosition->nextRefPosition;
9085                     }
9086                     if (firstRefPosition == nullptr)
9087                     {
9088                         // Dead interval
9089                         varDsc->lvLRACandidate = false;
9090                         if (varDsc->lvRefCnt == 0)
9091                         {
9092                             varDsc->lvOnFrame = false;
9093                         }
9094                         else
9095                         {
9096                             // We may encounter cases where a lclVar actually has no references, but
9097                             // a non-zero refCnt.  For safety (in case this is some "hidden" lclVar that we're
9098                             // not correctly recognizing), we'll mark those as needing a stack location.
9099                             // TODO-Cleanup: Make this an assert if/when we correct the refCnt
9100                             // updating.
9101                             varDsc->lvOnFrame = true;
9102                         }
9103                     }
9104                     else
9105                     {
9106                         // If the interval was not spilled, it doesn't need a stack location.
9107                         if (!interval->isSpilled)
9108                         {
9109                             varDsc->lvOnFrame = false;
9110                         }
9111                         if (firstRefPosition->registerAssignment == RBM_NONE || firstRefPosition->spillAfter)
9112                         {
9113                             // Either this RefPosition is spilled, or regOptional or it is not a "real" def or use
9114                             assert(
9115                                 firstRefPosition->spillAfter || firstRefPosition->AllocateIfProfitable() ||
9116                                 (firstRefPosition->refType != RefTypeDef && firstRefPosition->refType != RefTypeUse));
9117                             varDsc->lvRegNum = REG_STK;
9118                         }
9119                         else
9120                         {
9121                             varDsc->lvRegNum = firstRefPosition->assignedReg();
9122                         }
9123                     }
9124                 }
9125                 else
9126                 {
9127                     {
9128                         varDsc->lvRegister = true;
9129                         varDsc->lvOnFrame  = false;
9130                     }
9131 #ifdef DEBUG
9132                     regMaskTP registerAssignment = genRegMask(varDsc->lvRegNum);
9133                     assert(!interval->isSpilled && !interval->isSplit);
9134                     RefPosition* refPosition = interval->firstRefPosition;
9135                     assert(refPosition != nullptr);
9136
9137                     while (refPosition != nullptr)
9138                     {
9139                         // All RefPositions must match, except for dead definitions,
9140                         // copyReg/moveReg and RefTypeExpUse positions
9141                         if (refPosition->registerAssignment != RBM_NONE && !refPosition->copyReg &&
9142                             !refPosition->moveReg && refPosition->refType != RefTypeExpUse)
9143                         {
9144                             assert(refPosition->registerAssignment == registerAssignment);
9145                         }
9146                         refPosition = refPosition->nextRefPosition;
9147                     }
9148 #endif // DEBUG
9149                 }
9150             }
9151         }
9152     }
9153
9154 #ifdef DEBUG
9155     if (VERBOSE)
9156     {
9157         printf("Trees after linear scan register allocator (LSRA)\n");
9158         compiler->fgDispBasicBlocks(true);
9159     }
9160
9161     verifyFinalAllocation();
9162 #endif // DEBUG
9163
9164     compiler->raMarkStkVars();
9165     recordMaxSpill();
9166
9167     // TODO-CQ: Review this comment and address as needed.
9168     // Change all unused promoted non-argument struct locals to a non-GC type (in this case TYP_INT)
9169     // so that the gc tracking logic and lvMustInit logic will ignore them.
9170     // Extract the code that does this from raAssignVars, and call it here.
9171     // PRECONDITIONS: Ensure that lvPromoted is set on promoted structs, if and
9172     // only if it is promoted on all paths.
9173     // Call might be something like:
9174     // compiler->BashUnusedStructLocals();
9175 }
9176
9177 //
9178 //------------------------------------------------------------------------
9179 // insertMove: Insert a move of a lclVar with the given lclNum into the given block.
9180 //
9181 // Arguments:
9182 //    block          - the BasicBlock into which the move will be inserted.
9183 //    insertionPoint - the instruction before which to insert the move
9184 //    lclNum         - the lclNum of the var to be moved
9185 //    fromReg        - the register from which the var is moving
9186 //    toReg          - the register to which the var is moving
9187 //
9188 // Return Value:
9189 //    None.
9190 //
9191 // Notes:
9192 //    If insertionPoint is non-NULL, insert before that instruction;
9193 //    otherwise, insert "near" the end (prior to the branch, if any).
9194 //    If fromReg or toReg is REG_STK, then move from/to memory, respectively.
9195
9196 void LinearScan::insertMove(
9197     BasicBlock* block, GenTreePtr insertionPoint, unsigned lclNum, regNumber fromReg, regNumber toReg)
9198 {
9199     LclVarDsc* varDsc = compiler->lvaTable + lclNum;
9200     // the lclVar must be a register candidate
9201     assert(isRegCandidate(varDsc));
9202     // One or both MUST be a register
9203     assert(fromReg != REG_STK || toReg != REG_STK);
9204     // They must not be the same register.
9205     assert(fromReg != toReg);
9206
9207     // This var can't be marked lvRegister now
9208     varDsc->lvRegNum = REG_STK;
9209
9210     GenTreePtr src              = compiler->gtNewLclvNode(lclNum, varDsc->TypeGet());
9211     src->gtLsraInfo.isLsraAdded = true;
9212
9213     // There are three cases we need to handle:
9214     // - We are loading a lclVar from the stack.
9215     // - We are storing a lclVar to the stack.
9216     // - We are copying a lclVar between registers.
9217     //
9218     // In the first and second cases, the lclVar node will be marked with GTF_SPILLED and GTF_SPILL, respectively.
9219     // It is up to the code generator to ensure that any necessary normalization is done when loading or storing the
9220     // lclVar's value.
9221     //
9222     // In the third case, we generate GT_COPY(GT_LCL_VAR) and type each node with the normalized type of the lclVar.
9223     // This is safe because a lclVar is always normalized once it is in a register.
9224
9225     GenTree* dst = src;
9226     if (fromReg == REG_STK)
9227     {
9228         src->gtFlags |= GTF_SPILLED;
9229         src->gtRegNum = toReg;
9230     }
9231     else if (toReg == REG_STK)
9232     {
9233         src->gtFlags |= GTF_SPILL;
9234         src->gtRegNum = fromReg;
9235     }
9236     else
9237     {
9238         var_types movType = genActualType(varDsc->TypeGet());
9239         src->gtType       = movType;
9240
9241         dst = new (compiler, GT_COPY) GenTreeCopyOrReload(GT_COPY, movType, src);
9242         // This is the new home of the lclVar - indicate that by clearing the GTF_VAR_DEATH flag.
9243         // Note that if src is itself a lastUse, this will have no effect.
9244         dst->gtFlags &= ~(GTF_VAR_DEATH);
9245         src->gtRegNum                 = fromReg;
9246         dst->gtRegNum                 = toReg;
9247         src->gtLsraInfo.isLocalDefUse = false;
9248         dst->gtLsraInfo.isLsraAdded   = true;
9249     }
9250     dst->gtLsraInfo.isLocalDefUse = true;
9251
9252     LIR::Range  treeRange  = LIR::SeqTree(compiler, dst);
9253     LIR::Range& blockRange = LIR::AsRange(block);
9254
9255     if (insertionPoint != nullptr)
9256     {
9257         blockRange.InsertBefore(insertionPoint, std::move(treeRange));
9258     }
9259     else
9260     {
9261         // Put the copy at the bottom
9262         // If there's a branch, make an embedded statement that executes just prior to the branch
9263         if (block->bbJumpKind == BBJ_COND || block->bbJumpKind == BBJ_SWITCH)
9264         {
9265             noway_assert(!blockRange.IsEmpty());
9266
9267             GenTree* branch = blockRange.LastNode();
9268             assert(branch->OperIsConditionalJump() || branch->OperGet() == GT_SWITCH_TABLE ||
9269                    branch->OperGet() == GT_SWITCH);
9270
9271             blockRange.InsertBefore(branch, std::move(treeRange));
9272         }
9273         else
9274         {
9275             assert(block->bbJumpKind == BBJ_NONE || block->bbJumpKind == BBJ_ALWAYS);
9276             blockRange.InsertAtEnd(std::move(treeRange));
9277         }
9278     }
9279 }
9280
9281 void LinearScan::insertSwap(
9282     BasicBlock* block, GenTreePtr insertionPoint, unsigned lclNum1, regNumber reg1, unsigned lclNum2, regNumber reg2)
9283 {
9284 #ifdef DEBUG
9285     if (VERBOSE)
9286     {
9287         const char* insertionPointString = "top";
9288         if (insertionPoint == nullptr)
9289         {
9290             insertionPointString = "bottom";
9291         }
9292         printf("   BB%02u %s: swap V%02u in %s with V%02u in %s\n", block->bbNum, insertionPointString, lclNum1,
9293                getRegName(reg1), lclNum2, getRegName(reg2));
9294     }
9295 #endif // DEBUG
9296
9297     LclVarDsc* varDsc1 = compiler->lvaTable + lclNum1;
9298     LclVarDsc* varDsc2 = compiler->lvaTable + lclNum2;
9299     assert(reg1 != REG_STK && reg1 != REG_NA && reg2 != REG_STK && reg2 != REG_NA);
9300
9301     GenTreePtr lcl1                = compiler->gtNewLclvNode(lclNum1, varDsc1->TypeGet());
9302     lcl1->gtLsraInfo.isLsraAdded   = true;
9303     lcl1->gtLsraInfo.isLocalDefUse = false;
9304     lcl1->gtRegNum                 = reg1;
9305
9306     GenTreePtr lcl2                = compiler->gtNewLclvNode(lclNum2, varDsc2->TypeGet());
9307     lcl2->gtLsraInfo.isLsraAdded   = true;
9308     lcl2->gtLsraInfo.isLocalDefUse = false;
9309     lcl2->gtRegNum                 = reg2;
9310
9311     GenTreePtr swap                = compiler->gtNewOperNode(GT_SWAP, TYP_VOID, lcl1, lcl2);
9312     swap->gtLsraInfo.isLsraAdded   = true;
9313     swap->gtLsraInfo.isLocalDefUse = false;
9314     swap->gtRegNum                 = REG_NA;
9315
9316     lcl1->gtNext = lcl2;
9317     lcl2->gtPrev = lcl1;
9318     lcl2->gtNext = swap;
9319     swap->gtPrev = lcl2;
9320
9321     LIR::Range  swapRange  = LIR::SeqTree(compiler, swap);
9322     LIR::Range& blockRange = LIR::AsRange(block);
9323
9324     if (insertionPoint != nullptr)
9325     {
9326         blockRange.InsertBefore(insertionPoint, std::move(swapRange));
9327     }
9328     else
9329     {
9330         // Put the copy at the bottom
9331         // If there's a branch, make an embedded statement that executes just prior to the branch
9332         if (block->bbJumpKind == BBJ_COND || block->bbJumpKind == BBJ_SWITCH)
9333         {
9334             noway_assert(!blockRange.IsEmpty());
9335
9336             GenTree* branch = blockRange.LastNode();
9337             assert(branch->OperIsConditionalJump() || branch->OperGet() == GT_SWITCH_TABLE ||
9338                    branch->OperGet() == GT_SWITCH);
9339
9340             blockRange.InsertBefore(branch, std::move(swapRange));
9341         }
9342         else
9343         {
9344             assert(block->bbJumpKind == BBJ_NONE || block->bbJumpKind == BBJ_ALWAYS);
9345             blockRange.InsertAtEnd(std::move(swapRange));
9346         }
9347     }
9348 }
9349
9350 //------------------------------------------------------------------------
9351 // getTempRegForResolution: Get a free register to use for resolution code.
9352 //
9353 // Arguments:
9354 //    fromBlock - The "from" block on the edge being resolved.
9355 //    toBlock   - The "to"block on the edge
9356 //    type      - the type of register required
9357 //
9358 // Return Value:
9359 //    Returns a register that is free on the given edge, or REG_NA if none is available.
9360 //
9361 // Notes:
9362 //    It is up to the caller to check the return value, and to determine whether a register is
9363 //    available, and to handle that case appropriately.
9364 //    It is also up to the caller to cache the return value, as this is not cheap to compute.
9365
9366 regNumber LinearScan::getTempRegForResolution(BasicBlock* fromBlock, BasicBlock* toBlock, var_types type)
9367 {
9368     // TODO-Throughput: This would be much more efficient if we add RegToVarMaps instead of VarToRegMaps
9369     // and they would be more space-efficient as well.
9370     VarToRegMap fromVarToRegMap = getOutVarToRegMap(fromBlock->bbNum);
9371     VarToRegMap toVarToRegMap   = getInVarToRegMap(toBlock->bbNum);
9372
9373     regMaskTP freeRegs = allRegs(type);
9374 #ifdef DEBUG
9375     if (getStressLimitRegs() == LSRA_LIMIT_SMALL_SET)
9376     {
9377         return REG_NA;
9378     }
9379 #endif // DEBUG
9380     INDEBUG(freeRegs = stressLimitRegs(nullptr, freeRegs));
9381
9382     // We are only interested in the variables that are live-in to the "to" block.
9383     VarSetOps::Iter iter(compiler, toBlock->bbLiveIn);
9384     unsigned        varIndex = 0;
9385     while (iter.NextElem(&varIndex) && freeRegs != RBM_NONE)
9386     {
9387         regNumber fromReg = getVarReg(fromVarToRegMap, varIndex);
9388         regNumber toReg   = getVarReg(toVarToRegMap, varIndex);
9389         assert(fromReg != REG_NA && toReg != REG_NA);
9390         if (fromReg != REG_STK)
9391         {
9392             freeRegs &= ~genRegMask(fromReg);
9393         }
9394         if (toReg != REG_STK)
9395         {
9396             freeRegs &= ~genRegMask(toReg);
9397         }
9398     }
9399     if (freeRegs == RBM_NONE)
9400     {
9401         return REG_NA;
9402     }
9403     else
9404     {
9405         regNumber tempReg = genRegNumFromMask(genFindLowestBit(freeRegs));
9406         return tempReg;
9407     }
9408 }
9409
9410 //------------------------------------------------------------------------
9411 // addResolution: Add a resolution move of the given interval
9412 //
9413 // Arguments:
9414 //    block          - the BasicBlock into which the move will be inserted.
9415 //    insertionPoint - the instruction before which to insert the move
9416 //    interval       - the interval of the var to be moved
9417 //    toReg          - the register to which the var is moving
9418 //    fromReg        - the register from which the var is moving
9419 //
9420 // Return Value:
9421 //    None.
9422 //
9423 // Notes:
9424 //    For joins, we insert at the bottom (indicated by an insertionPoint
9425 //    of nullptr), while for splits we insert at the top.
9426 //    This is because for joins 'block' is a pred of the join, while for splits it is a succ.
9427 //    For critical edges, this function may be called twice - once to move from
9428 //    the source (fromReg), if any, to the stack, in which case toReg will be
9429 //    REG_STK, and we insert at the bottom (leave insertionPoint as nullptr).
9430 //    The next time, we want to move from the stack to the destination (toReg),
9431 //    in which case fromReg will be REG_STK, and we insert at the top.
9432
9433 void LinearScan::addResolution(
9434     BasicBlock* block, GenTreePtr insertionPoint, Interval* interval, regNumber toReg, regNumber fromReg)
9435 {
9436 #ifdef DEBUG
9437     const char* insertionPointString = "top";
9438 #endif // DEBUG
9439     if (insertionPoint == nullptr)
9440     {
9441 #ifdef DEBUG
9442         insertionPointString = "bottom";
9443 #endif // DEBUG
9444     }
9445
9446     JITDUMP("   BB%02u %s: move V%02u from ", block->bbNum, insertionPointString, interval->varNum);
9447     JITDUMP("%s to %s", getRegName(fromReg), getRegName(toReg));
9448
9449     insertMove(block, insertionPoint, interval->varNum, fromReg, toReg);
9450     if (fromReg == REG_STK || toReg == REG_STK)
9451     {
9452         assert(interval->isSpilled);
9453     }
9454     else
9455     {
9456         // We should have already marked this as spilled or split.
9457         assert((interval->isSpilled) || (interval->isSplit));
9458     }
9459
9460     INTRACK_STATS(updateLsraStat(LSRA_STAT_RESOLUTION_MOV, block->bbNum));
9461 }
9462
9463 //------------------------------------------------------------------------
9464 // handleOutgoingCriticalEdges: Performs the necessary resolution on all critical edges that feed out of 'block'
9465 //
9466 // Arguments:
9467 //    block     - the block with outgoing critical edges.
9468 //
9469 // Return Value:
9470 //    None..
9471 //
9472 // Notes:
9473 //    For all outgoing critical edges (i.e. any successor of this block which is
9474 //    a join edge), if there are any conflicts, split the edge by adding a new block,
9475 //    and generate the resolution code into that block.
9476
9477 void LinearScan::handleOutgoingCriticalEdges(BasicBlock* block)
9478 {
9479     VARSET_TP outResolutionSet(VarSetOps::Intersection(compiler, block->bbLiveOut, resolutionCandidateVars));
9480     if (VarSetOps::IsEmpty(compiler, outResolutionSet))
9481     {
9482         return;
9483     }
9484     VARSET_TP sameResolutionSet(VarSetOps::MakeEmpty(compiler));
9485     VARSET_TP sameLivePathsSet(VarSetOps::MakeEmpty(compiler));
9486     VARSET_TP singleTargetSet(VarSetOps::MakeEmpty(compiler));
9487     VARSET_TP diffResolutionSet(VarSetOps::MakeEmpty(compiler));
9488
9489     // Get the outVarToRegMap for this block
9490     VarToRegMap outVarToRegMap = getOutVarToRegMap(block->bbNum);
9491     unsigned    succCount      = block->NumSucc(compiler);
9492     assert(succCount > 1);
9493     VarToRegMap firstSuccInVarToRegMap = nullptr;
9494     BasicBlock* firstSucc              = nullptr;
9495
9496     // First, determine the live regs at the end of this block so that we know what regs are
9497     // available to copy into.
9498     // Note that for this purpose we use the full live-out set, because we must ensure that
9499     // even the registers that remain the same across the edge are preserved correctly.
9500     regMaskTP       liveOutRegs = RBM_NONE;
9501     VarSetOps::Iter liveOutIter(compiler, block->bbLiveOut);
9502     unsigned        liveOutVarIndex = 0;
9503     while (liveOutIter.NextElem(&liveOutVarIndex))
9504     {
9505         regNumber fromReg = getVarReg(outVarToRegMap, liveOutVarIndex);
9506         if (fromReg != REG_STK)
9507         {
9508             liveOutRegs |= genRegMask(fromReg);
9509         }
9510     }
9511
9512     // Next, if this blocks ends with a switch table, we have to make sure not to copy
9513     // into the registers that it uses.
9514     regMaskTP switchRegs = RBM_NONE;
9515     if (block->bbJumpKind == BBJ_SWITCH)
9516     {
9517         // At this point, Lowering has transformed any non-switch-table blocks into
9518         // cascading ifs.
9519         GenTree* switchTable = LIR::AsRange(block).LastNode();
9520         assert(switchTable != nullptr && switchTable->OperGet() == GT_SWITCH_TABLE);
9521
9522         switchRegs   = switchTable->gtRsvdRegs;
9523         GenTree* op1 = switchTable->gtGetOp1();
9524         GenTree* op2 = switchTable->gtGetOp2();
9525         noway_assert(op1 != nullptr && op2 != nullptr);
9526         assert(op1->gtRegNum != REG_NA && op2->gtRegNum != REG_NA);
9527         switchRegs |= genRegMask(op1->gtRegNum);
9528         switchRegs |= genRegMask(op2->gtRegNum);
9529     }
9530
9531     VarToRegMap sameVarToRegMap = sharedCriticalVarToRegMap;
9532     regMaskTP   sameWriteRegs   = RBM_NONE;
9533     regMaskTP   diffReadRegs    = RBM_NONE;
9534
9535     // For each var that may require resolution, classify them as:
9536     // - in the same register at the end of this block and at each target (no resolution needed)
9537     // - in different registers at different targets (resolve separately):
9538     //     diffResolutionSet
9539     // - in the same register at each target at which it's live, but different from the end of
9540     //   this block.  We may be able to resolve these as if it is "join", but only if they do not
9541     //   write to any registers that are read by those in the diffResolutionSet:
9542     //     sameResolutionSet
9543
9544     VarSetOps::Iter outResolutionSetIter(compiler, outResolutionSet);
9545     unsigned        outResolutionSetVarIndex = 0;
9546     while (outResolutionSetIter.NextElem(&outResolutionSetVarIndex))
9547     {
9548         regNumber fromReg             = getVarReg(outVarToRegMap, outResolutionSetVarIndex);
9549         bool      isMatch             = true;
9550         bool      isSame              = false;
9551         bool      maybeSingleTarget   = false;
9552         bool      maybeSameLivePaths  = false;
9553         bool      liveOnlyAtSplitEdge = true;
9554         regNumber sameToReg           = REG_NA;
9555         for (unsigned succIndex = 0; succIndex < succCount; succIndex++)
9556         {
9557             BasicBlock* succBlock = block->GetSucc(succIndex, compiler);
9558             if (!VarSetOps::IsMember(compiler, succBlock->bbLiveIn, outResolutionSetVarIndex))
9559             {
9560                 maybeSameLivePaths = true;
9561                 continue;
9562             }
9563             else if (liveOnlyAtSplitEdge)
9564             {
9565                 // Is the var live only at those target blocks which are connected by a split edge to this block
9566                 liveOnlyAtSplitEdge = ((succBlock->bbPreds->flNext == nullptr) && (succBlock != compiler->fgFirstBB));
9567             }
9568
9569             regNumber toReg = getVarReg(getInVarToRegMap(succBlock->bbNum), outResolutionSetVarIndex);
9570             if (sameToReg == REG_NA)
9571             {
9572                 sameToReg = toReg;
9573                 continue;
9574             }
9575             if (toReg == sameToReg)
9576             {
9577                 continue;
9578             }
9579             sameToReg = REG_NA;
9580             break;
9581         }
9582
9583         // Check for the cases where we can't write to a register.
9584         // We only need to check for these cases if sameToReg is an actual register (not REG_STK).
9585         if (sameToReg != REG_NA && sameToReg != REG_STK)
9586         {
9587             // If there's a path on which this var isn't live, it may use the original value in sameToReg.
9588             // In this case, sameToReg will be in the liveOutRegs of this block.
9589             // Similarly, if sameToReg is in sameWriteRegs, it has already been used (i.e. for a lclVar that's
9590             // live only at another target), and we can't copy another lclVar into that reg in this block.
9591             regMaskTP sameToRegMask = genRegMask(sameToReg);
9592             if (maybeSameLivePaths &&
9593                 (((sameToRegMask & liveOutRegs) != RBM_NONE) || ((sameToRegMask & sameWriteRegs) != RBM_NONE)))
9594             {
9595                 sameToReg = REG_NA;
9596             }
9597             // If this register is used by a switch table at the end of the block, we can't do the copy
9598             // in this block (since we can't insert it after the switch).
9599             if ((sameToRegMask & switchRegs) != RBM_NONE)
9600             {
9601                 sameToReg = REG_NA;
9602             }
9603
9604             // If the var is live only at those blocks connected by a split edge and not live-in at some of the
9605             // target blocks, we will resolve it the same way as if it were in diffResolutionSet and resolution
9606             // will be deferred to the handling of split edges, which means copy will only be at those target(s).
9607             //
9608             // Another way to achieve similar resolution for vars live only at split edges is by removing them
9609             // from consideration up-front but it requires that we traverse those edges anyway to account for
9610             // the registers that must note be overwritten.
9611             if (liveOnlyAtSplitEdge && maybeSameLivePaths)
9612             {
9613                 sameToReg = REG_NA;
9614             }
9615         }
9616
9617         if (sameToReg == REG_NA)
9618         {
9619             VarSetOps::AddElemD(compiler, diffResolutionSet, outResolutionSetVarIndex);
9620             if (fromReg != REG_STK)
9621             {
9622                 diffReadRegs |= genRegMask(fromReg);
9623             }
9624         }
9625         else if (sameToReg != fromReg)
9626         {
9627             VarSetOps::AddElemD(compiler, sameResolutionSet, outResolutionSetVarIndex);
9628             setVarReg(sameVarToRegMap, outResolutionSetVarIndex, sameToReg);
9629             if (sameToReg != REG_STK)
9630             {
9631                 sameWriteRegs |= genRegMask(sameToReg);
9632             }
9633         }
9634     }
9635
9636     if (!VarSetOps::IsEmpty(compiler, sameResolutionSet))
9637     {
9638         if ((sameWriteRegs & diffReadRegs) != RBM_NONE)
9639         {
9640             // We cannot split the "same" and "diff" regs if the "same" set writes registers
9641             // that must be read by the "diff" set.  (Note that when these are done as a "batch"
9642             // we carefully order them to ensure all the input regs are read before they are
9643             // overwritten.)
9644             VarSetOps::UnionD(compiler, diffResolutionSet, sameResolutionSet);
9645             VarSetOps::ClearD(compiler, sameResolutionSet);
9646         }
9647         else
9648         {
9649             // For any vars in the sameResolutionSet, we can simply add the move at the end of "block".
9650             resolveEdge(block, nullptr, ResolveSharedCritical, sameResolutionSet);
9651         }
9652     }
9653     if (!VarSetOps::IsEmpty(compiler, diffResolutionSet))
9654     {
9655         for (unsigned succIndex = 0; succIndex < succCount; succIndex++)
9656         {
9657             BasicBlock* succBlock = block->GetSucc(succIndex, compiler);
9658
9659             // Any "diffResolutionSet" resolution for a block with no other predecessors will be handled later
9660             // as split resolution.
9661             if ((succBlock->bbPreds->flNext == nullptr) && (succBlock != compiler->fgFirstBB))
9662             {
9663                 continue;
9664             }
9665
9666             // Now collect the resolution set for just this edge, if any.
9667             // Check only the vars in diffResolutionSet that are live-in to this successor.
9668             bool        needsResolution   = false;
9669             VarToRegMap succInVarToRegMap = getInVarToRegMap(succBlock->bbNum);
9670             VARSET_TP   edgeResolutionSet(VarSetOps::Intersection(compiler, diffResolutionSet, succBlock->bbLiveIn));
9671             VarSetOps::Iter iter(compiler, edgeResolutionSet);
9672             unsigned        varIndex = 0;
9673             while (iter.NextElem(&varIndex))
9674             {
9675                 regNumber fromReg = getVarReg(outVarToRegMap, varIndex);
9676                 regNumber toReg   = getVarReg(succInVarToRegMap, varIndex);
9677
9678                 if (fromReg == toReg)
9679                 {
9680                     VarSetOps::RemoveElemD(compiler, edgeResolutionSet, varIndex);
9681                 }
9682             }
9683             if (!VarSetOps::IsEmpty(compiler, edgeResolutionSet))
9684             {
9685                 resolveEdge(block, succBlock, ResolveCritical, edgeResolutionSet);
9686             }
9687         }
9688     }
9689 }
9690
9691 //------------------------------------------------------------------------
9692 // resolveEdges: Perform resolution across basic block edges
9693 //
9694 // Arguments:
9695 //    None.
9696 //
9697 // Return Value:
9698 //    None.
9699 //
9700 // Notes:
9701 //    Traverse the basic blocks.
9702 //    - If this block has a single predecessor that is not the immediately
9703 //      preceding block, perform any needed 'split' resolution at the beginning of this block
9704 //    - Otherwise if this block has critical incoming edges, handle them.
9705 //    - If this block has a single successor that has multiple predecesors, perform any needed
9706 //      'join' resolution at the end of this block.
9707 //    Note that a block may have both 'split' or 'critical' incoming edge(s) and 'join' outgoing
9708 //    edges.
9709
9710 void LinearScan::resolveEdges()
9711 {
9712     JITDUMP("RESOLVING EDGES\n");
9713
9714     // The resolutionCandidateVars set was initialized with all the lclVars that are live-in to
9715     // any block. We now intersect that set with any lclVars that ever spilled or split.
9716     // If there are no candidates for resoultion, simply return.
9717
9718     VarSetOps::IntersectionD(compiler, resolutionCandidateVars, splitOrSpilledVars);
9719     if (VarSetOps::IsEmpty(compiler, resolutionCandidateVars))
9720     {
9721         return;
9722     }
9723
9724     BasicBlock *block, *prevBlock = nullptr;
9725
9726     // Handle all the critical edges first.
9727     // We will try to avoid resolution across critical edges in cases where all the critical-edge
9728     // targets of a block have the same home.  We will then split the edges only for the
9729     // remaining mismatches.  We visit the out-edges, as that allows us to share the moves that are
9730     // common among allt he targets.
9731
9732     if (hasCriticalEdges)
9733     {
9734         foreach_block(compiler, block)
9735         {
9736             if (block->bbNum > bbNumMaxBeforeResolution)
9737             {
9738                 // This is a new block added during resolution - we don't need to visit these now.
9739                 continue;
9740             }
9741             if (blockInfo[block->bbNum].hasCriticalOutEdge)
9742             {
9743                 handleOutgoingCriticalEdges(block);
9744             }
9745             prevBlock = block;
9746         }
9747     }
9748
9749     prevBlock = nullptr;
9750     foreach_block(compiler, block)
9751     {
9752         if (block->bbNum > bbNumMaxBeforeResolution)
9753         {
9754             // This is a new block added during resolution - we don't need to visit these now.
9755             continue;
9756         }
9757
9758         unsigned    succCount       = block->NumSucc(compiler);
9759         flowList*   preds           = block->bbPreds;
9760         BasicBlock* uniquePredBlock = block->GetUniquePred(compiler);
9761
9762         // First, if this block has a single predecessor,
9763         // we may need resolution at the beginning of this block.
9764         // This may be true even if it's the block we used for starting locations,
9765         // if a variable was spilled.
9766         VARSET_TP inResolutionSet(VarSetOps::Intersection(compiler, block->bbLiveIn, resolutionCandidateVars));
9767         if (!VarSetOps::IsEmpty(compiler, inResolutionSet))
9768         {
9769             if (uniquePredBlock != nullptr)
9770             {
9771                 // We may have split edges during critical edge resolution, and in the process split
9772                 // a non-critical edge as well.
9773                 // It is unlikely that we would ever have more than one of these in sequence (indeed,
9774                 // I don't think it's possible), but there's no need to assume that it can't.
9775                 while (uniquePredBlock->bbNum > bbNumMaxBeforeResolution)
9776                 {
9777                     uniquePredBlock = uniquePredBlock->GetUniquePred(compiler);
9778                     noway_assert(uniquePredBlock != nullptr);
9779                 }
9780                 resolveEdge(uniquePredBlock, block, ResolveSplit, inResolutionSet);
9781             }
9782         }
9783
9784         // Finally, if this block has a single successor:
9785         //  - and that has at least one other predecessor (otherwise we will do the resolution at the
9786         //    top of the successor),
9787         //  - and that is not the target of a critical edge (otherwise we've already handled it)
9788         // we may need resolution at the end of this block.
9789
9790         if (succCount == 1)
9791         {
9792             BasicBlock* succBlock = block->GetSucc(0, compiler);
9793             if (succBlock->GetUniquePred(compiler) == nullptr)
9794             {
9795                 VARSET_TP outResolutionSet(
9796                     VarSetOps::Intersection(compiler, succBlock->bbLiveIn, resolutionCandidateVars));
9797                 if (!VarSetOps::IsEmpty(compiler, outResolutionSet))
9798                 {
9799                     resolveEdge(block, succBlock, ResolveJoin, outResolutionSet);
9800                 }
9801             }
9802         }
9803     }
9804
9805     // Now, fixup the mapping for any blocks that were adding for edge splitting.
9806     // See the comment prior to the call to fgSplitEdge() in resolveEdge().
9807     // Note that we could fold this loop in with the checking code below, but that
9808     // would only improve the debug case, and would clutter up the code somewhat.
9809     if (compiler->fgBBNumMax > bbNumMaxBeforeResolution)
9810     {
9811         foreach_block(compiler, block)
9812         {
9813             if (block->bbNum > bbNumMaxBeforeResolution)
9814             {
9815                 // There may be multiple blocks inserted when we split.  But we must always have exactly
9816                 // one path (i.e. all blocks must be single-successor and single-predecessor),
9817                 // and only one block along the path may be non-empty.
9818                 // Note that we may have a newly-inserted block that is empty, but which connects
9819                 // two non-resolution blocks. This happens when an edge is split that requires it.
9820
9821                 BasicBlock* succBlock = block;
9822                 do
9823                 {
9824                     succBlock = succBlock->GetUniqueSucc();
9825                     noway_assert(succBlock != nullptr);
9826                 } while ((succBlock->bbNum > bbNumMaxBeforeResolution) && succBlock->isEmpty());
9827
9828                 BasicBlock* predBlock = block;
9829                 do
9830                 {
9831                     predBlock = predBlock->GetUniquePred(compiler);
9832                     noway_assert(predBlock != nullptr);
9833                 } while ((predBlock->bbNum > bbNumMaxBeforeResolution) && predBlock->isEmpty());
9834
9835                 unsigned succBBNum = succBlock->bbNum;
9836                 unsigned predBBNum = predBlock->bbNum;
9837                 if (block->isEmpty())
9838                 {
9839                     // For the case of the empty block, find the non-resolution block (succ or pred).
9840                     if (predBBNum > bbNumMaxBeforeResolution)
9841                     {
9842                         assert(succBBNum <= bbNumMaxBeforeResolution);
9843                         predBBNum = 0;
9844                     }
9845                     else
9846                     {
9847                         succBBNum = 0;
9848                     }
9849                 }
9850                 else
9851                 {
9852                     assert((succBBNum <= bbNumMaxBeforeResolution) && (predBBNum <= bbNumMaxBeforeResolution));
9853                 }
9854                 SplitEdgeInfo info = {predBBNum, succBBNum};
9855                 getSplitBBNumToTargetBBNumMap()->Set(block->bbNum, info);
9856             }
9857         }
9858     }
9859
9860 #ifdef DEBUG
9861     // Make sure the varToRegMaps match up on all edges.
9862     bool foundMismatch = false;
9863     foreach_block(compiler, block)
9864     {
9865         if (block->isEmpty() && block->bbNum > bbNumMaxBeforeResolution)
9866         {
9867             continue;
9868         }
9869         VarToRegMap toVarToRegMap = getInVarToRegMap(block->bbNum);
9870         for (flowList* pred = block->bbPreds; pred != nullptr; pred = pred->flNext)
9871         {
9872             BasicBlock*     predBlock       = pred->flBlock;
9873             VarToRegMap     fromVarToRegMap = getOutVarToRegMap(predBlock->bbNum);
9874             VarSetOps::Iter iter(compiler, block->bbLiveIn);
9875             unsigned        varIndex = 0;
9876             while (iter.NextElem(&varIndex))
9877             {
9878                 regNumber fromReg = getVarReg(fromVarToRegMap, varIndex);
9879                 regNumber toReg   = getVarReg(toVarToRegMap, varIndex);
9880                 if (fromReg != toReg)
9881                 {
9882                     if (!foundMismatch)
9883                     {
9884                         foundMismatch = true;
9885                         printf("Found mismatched var locations after resolution!\n");
9886                     }
9887                     unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
9888                     printf(" V%02u: BB%02u to BB%02u: %s to %s\n", varNum, predBlock->bbNum, block->bbNum,
9889                            getRegName(fromReg), getRegName(toReg));
9890                 }
9891             }
9892         }
9893     }
9894     assert(!foundMismatch);
9895 #endif
9896     JITDUMP("\n");
9897 }
9898
9899 //------------------------------------------------------------------------
9900 // resolveEdge: Perform the specified type of resolution between two blocks.
9901 //
9902 // Arguments:
9903 //    fromBlock     - the block from which the edge originates
9904 //    toBlock       - the block at which the edge terminates
9905 //    resolveType   - the type of resolution to be performed
9906 //    liveSet       - the set of tracked lclVar indices which may require resolution
9907 //
9908 // Return Value:
9909 //    None.
9910 //
9911 // Assumptions:
9912 //    The caller must have performed the analysis to determine the type of the edge.
9913 //
9914 // Notes:
9915 //    This method emits the correctly ordered moves necessary to place variables in the
9916 //    correct registers across a Split, Join or Critical edge.
9917 //    In order to avoid overwriting register values before they have been moved to their
9918 //    new home (register/stack), it first does the register-to-stack moves (to free those
9919 //    registers), then the register to register moves, ensuring that the target register
9920 //    is free before the move, and then finally the stack to register moves.
9921
9922 void LinearScan::resolveEdge(BasicBlock*      fromBlock,
9923                              BasicBlock*      toBlock,
9924                              ResolveType      resolveType,
9925                              VARSET_VALARG_TP liveSet)
9926 {
9927     VarToRegMap fromVarToRegMap = getOutVarToRegMap(fromBlock->bbNum);
9928     VarToRegMap toVarToRegMap;
9929     if (resolveType == ResolveSharedCritical)
9930     {
9931         toVarToRegMap = sharedCriticalVarToRegMap;
9932     }
9933     else
9934     {
9935         toVarToRegMap = getInVarToRegMap(toBlock->bbNum);
9936     }
9937
9938     // The block to which we add the resolution moves depends on the resolveType
9939     BasicBlock* block;
9940     switch (resolveType)
9941     {
9942         case ResolveJoin:
9943         case ResolveSharedCritical:
9944             block = fromBlock;
9945             break;
9946         case ResolveSplit:
9947             block = toBlock;
9948             break;
9949         case ResolveCritical:
9950             // fgSplitEdge may add one or two BasicBlocks.  It returns the block that splits
9951             // the edge from 'fromBlock' and 'toBlock', but if it inserts that block right after
9952             // a block with a fall-through it will have to create another block to handle that edge.
9953             // These new blocks can be mapped to existing blocks in order to correctly handle
9954             // the calls to recordVarLocationsAtStartOfBB() from codegen.  That mapping is handled
9955             // in resolveEdges(), after all the edge resolution has been done (by calling this
9956             // method for each edge).
9957             block = compiler->fgSplitEdge(fromBlock, toBlock);
9958
9959             // Split edges are counted against fromBlock.
9960             INTRACK_STATS(updateLsraStat(LSRA_STAT_SPLIT_EDGE, fromBlock->bbNum));
9961             break;
9962         default:
9963             unreached();
9964             break;
9965     }
9966
9967 #ifndef _TARGET_XARCH_
9968     // We record tempregs for beginning and end of each block.
9969     // For amd64/x86 we only need a tempReg for float - we'll use xchg for int.
9970     // TODO-Throughput: It would be better to determine the tempRegs on demand, but the code below
9971     // modifies the varToRegMaps so we don't have all the correct registers at the time
9972     // we need to get the tempReg.
9973     regNumber tempRegInt =
9974         (resolveType == ResolveSharedCritical) ? REG_NA : getTempRegForResolution(fromBlock, toBlock, TYP_INT);
9975 #endif // !_TARGET_XARCH_
9976     regNumber tempRegFlt = REG_NA;
9977     if ((compiler->compFloatingPointUsed) && (resolveType != ResolveSharedCritical))
9978     {
9979
9980 #ifdef _TARGET_ARM_
9981         // Let's try to reserve a double register for TYP_FLOAT and TYP_DOUBLE
9982         tempRegFlt = getTempRegForResolution(fromBlock, toBlock, TYP_DOUBLE);
9983         if (tempRegFlt == REG_NA)
9984         {
9985             // If fails, try to reserve a float register for TYP_FLOAT
9986             tempRegFlt = getTempRegForResolution(fromBlock, toBlock, TYP_FLOAT);
9987         }
9988 #else
9989         tempRegFlt                   = getTempRegForResolution(fromBlock, toBlock, TYP_FLOAT);
9990 #endif
9991     }
9992
9993     regMaskTP targetRegsToDo      = RBM_NONE;
9994     regMaskTP targetRegsReady     = RBM_NONE;
9995     regMaskTP targetRegsFromStack = RBM_NONE;
9996
9997     // The following arrays capture the location of the registers as they are moved:
9998     // - location[reg] gives the current location of the var that was originally in 'reg'.
9999     //   (Note that a var may be moved more than once.)
10000     // - source[reg] gives the original location of the var that needs to be moved to 'reg'.
10001     // For example, if a var is in rax and needs to be moved to rsi, then we would start with:
10002     //   location[rax] == rax
10003     //   source[rsi] == rax     -- this doesn't change
10004     // Then, if for some reason we need to move it temporary to rbx, we would have:
10005     //   location[rax] == rbx
10006     // Once we have completed the move, we will have:
10007     //   location[rax] == REG_NA
10008     // This indicates that the var originally in rax is now in its target register.
10009
10010     regNumberSmall location[REG_COUNT];
10011     C_ASSERT(sizeof(char) == sizeof(regNumberSmall)); // for memset to work
10012     memset(location, REG_NA, REG_COUNT);
10013     regNumberSmall source[REG_COUNT];
10014     memset(source, REG_NA, REG_COUNT);
10015
10016     // What interval is this register associated with?
10017     // (associated with incoming reg)
10018     Interval* sourceIntervals[REG_COUNT];
10019     memset(&sourceIntervals, 0, sizeof(sourceIntervals));
10020
10021     // Intervals for vars that need to be loaded from the stack
10022     Interval* stackToRegIntervals[REG_COUNT];
10023     memset(&stackToRegIntervals, 0, sizeof(stackToRegIntervals));
10024
10025     // Get the starting insertion point for the "to" resolution
10026     GenTreePtr insertionPoint = nullptr;
10027     if (resolveType == ResolveSplit || resolveType == ResolveCritical)
10028     {
10029         insertionPoint = LIR::AsRange(block).FirstNonPhiNode();
10030     }
10031
10032     // First:
10033     //   - Perform all moves from reg to stack (no ordering needed on these)
10034     //   - For reg to reg moves, record the current location, associating their
10035     //     source location with the target register they need to go into
10036     //   - For stack to reg moves (done last, no ordering needed between them)
10037     //     record the interval associated with the target reg
10038     // TODO-Throughput: We should be looping over the liveIn and liveOut registers, since
10039     // that will scale better than the live variables
10040
10041     VarSetOps::Iter iter(compiler, liveSet);
10042     unsigned        varIndex = 0;
10043     while (iter.NextElem(&varIndex))
10044     {
10045         regNumber fromReg = getVarReg(fromVarToRegMap, varIndex);
10046         regNumber toReg   = getVarReg(toVarToRegMap, varIndex);
10047         if (fromReg == toReg)
10048         {
10049             continue;
10050         }
10051
10052         // For Critical edges, the location will not change on either side of the edge,
10053         // since we'll add a new block to do the move.
10054         if (resolveType == ResolveSplit)
10055         {
10056             setVarReg(toVarToRegMap, varIndex, fromReg);
10057         }
10058         else if (resolveType == ResolveJoin || resolveType == ResolveSharedCritical)
10059         {
10060             setVarReg(fromVarToRegMap, varIndex, toReg);
10061         }
10062
10063         assert(fromReg < UCHAR_MAX && toReg < UCHAR_MAX);
10064
10065         Interval* interval = getIntervalForLocalVar(varIndex);
10066
10067         if (fromReg == REG_STK)
10068         {
10069             stackToRegIntervals[toReg] = interval;
10070             targetRegsFromStack |= genRegMask(toReg);
10071         }
10072         else if (toReg == REG_STK)
10073         {
10074             // Do the reg to stack moves now
10075             addResolution(block, insertionPoint, interval, REG_STK, fromReg);
10076             JITDUMP(" (%s)\n", resolveTypeName[resolveType]);
10077         }
10078         else
10079         {
10080             location[fromReg]        = (regNumberSmall)fromReg;
10081             source[toReg]            = (regNumberSmall)fromReg;
10082             sourceIntervals[fromReg] = interval;
10083             targetRegsToDo |= genRegMask(toReg);
10084         }
10085     }
10086
10087     // REGISTER to REGISTER MOVES
10088
10089     // First, find all the ones that are ready to move now
10090     regMaskTP targetCandidates = targetRegsToDo;
10091     while (targetCandidates != RBM_NONE)
10092     {
10093         regMaskTP targetRegMask = genFindLowestBit(targetCandidates);
10094         targetCandidates &= ~targetRegMask;
10095         regNumber targetReg = genRegNumFromMask(targetRegMask);
10096         if (location[targetReg] == REG_NA)
10097         {
10098             targetRegsReady |= targetRegMask;
10099         }
10100     }
10101
10102     // Perform reg to reg moves
10103     while (targetRegsToDo != RBM_NONE)
10104     {
10105         while (targetRegsReady != RBM_NONE)
10106         {
10107             regMaskTP targetRegMask = genFindLowestBit(targetRegsReady);
10108             targetRegsToDo &= ~targetRegMask;
10109             targetRegsReady &= ~targetRegMask;
10110             regNumber targetReg = genRegNumFromMask(targetRegMask);
10111             assert(location[targetReg] != targetReg);
10112             regNumber sourceReg = (regNumber)source[targetReg];
10113             regNumber fromReg   = (regNumber)location[sourceReg];
10114             assert(fromReg < UCHAR_MAX && sourceReg < UCHAR_MAX);
10115             Interval* interval = sourceIntervals[sourceReg];
10116             assert(interval != nullptr);
10117             addResolution(block, insertionPoint, interval, targetReg, fromReg);
10118             JITDUMP(" (%s)\n", resolveTypeName[resolveType]);
10119             sourceIntervals[sourceReg] = nullptr;
10120             location[sourceReg]        = REG_NA;
10121
10122             // Do we have a free targetReg?
10123             if (fromReg == sourceReg && source[fromReg] != REG_NA)
10124             {
10125                 regMaskTP fromRegMask = genRegMask(fromReg);
10126                 targetRegsReady |= fromRegMask;
10127             }
10128         }
10129         if (targetRegsToDo != RBM_NONE)
10130         {
10131             regMaskTP targetRegMask = genFindLowestBit(targetRegsToDo);
10132             regNumber targetReg     = genRegNumFromMask(targetRegMask);
10133
10134             // Is it already there due to other moves?
10135             // If not, move it to the temp reg, OR swap it with another register
10136             regNumber sourceReg = (regNumber)source[targetReg];
10137             regNumber fromReg   = (regNumber)location[sourceReg];
10138             if (targetReg == fromReg)
10139             {
10140                 targetRegsToDo &= ~targetRegMask;
10141             }
10142             else
10143             {
10144                 regNumber tempReg = REG_NA;
10145                 bool      useSwap = false;
10146                 if (emitter::isFloatReg(targetReg))
10147                 {
10148 #ifdef _TARGET_ARM_
10149                     if (sourceIntervals[fromReg]->registerType == TYP_DOUBLE)
10150                     {
10151                         // ARM32 requires a double temp register for TYP_DOUBLE.
10152                         // We tried to reserve a double temp register first, but sometimes we can't.
10153                         tempReg = genIsValidDoubleReg(tempRegFlt) ? tempRegFlt : REG_NA;
10154                     }
10155                     else
10156 #endif // _TARGET_ARM_
10157                         tempReg = tempRegFlt;
10158                 }
10159 #ifdef _TARGET_XARCH_
10160                 else
10161                 {
10162                     useSwap = true;
10163                 }
10164 #else // !_TARGET_XARCH_
10165
10166                 else
10167                 {
10168                     tempReg = tempRegInt;
10169                 }
10170
10171 #endif // !_TARGET_XARCH_
10172                 if (useSwap || tempReg == REG_NA)
10173                 {
10174                     // First, we have to figure out the destination register for what's currently in fromReg,
10175                     // so that we can find its sourceInterval.
10176                     regNumber otherTargetReg = REG_NA;
10177
10178                     // By chance, is fromReg going where it belongs?
10179                     if (location[source[fromReg]] == targetReg)
10180                     {
10181                         otherTargetReg = fromReg;
10182                         // If we can swap, we will be done with otherTargetReg as well.
10183                         // Otherwise, we'll spill it to the stack and reload it later.
10184                         if (useSwap)
10185                         {
10186                             regMaskTP fromRegMask = genRegMask(fromReg);
10187                             targetRegsToDo &= ~fromRegMask;
10188                         }
10189                     }
10190                     else
10191                     {
10192                         // Look at the remaining registers from targetRegsToDo (which we expect to be relatively
10193                         // small at this point) to find out what's currently in targetReg.
10194                         regMaskTP mask = targetRegsToDo;
10195                         while (mask != RBM_NONE && otherTargetReg == REG_NA)
10196                         {
10197                             regMaskTP nextRegMask = genFindLowestBit(mask);
10198                             regNumber nextReg     = genRegNumFromMask(nextRegMask);
10199                             mask &= ~nextRegMask;
10200                             if (location[source[nextReg]] == targetReg)
10201                             {
10202                                 otherTargetReg = nextReg;
10203                             }
10204                         }
10205                     }
10206                     assert(otherTargetReg != REG_NA);
10207
10208                     if (useSwap)
10209                     {
10210                         // Generate a "swap" of fromReg and targetReg
10211                         insertSwap(block, insertionPoint, sourceIntervals[source[otherTargetReg]]->varNum, targetReg,
10212                                    sourceIntervals[sourceReg]->varNum, fromReg);
10213                         location[sourceReg]              = REG_NA;
10214                         location[source[otherTargetReg]] = (regNumberSmall)fromReg;
10215
10216                         INTRACK_STATS(updateLsraStat(LSRA_STAT_RESOLUTION_MOV, block->bbNum));
10217                     }
10218                     else
10219                     {
10220                         // Spill "targetReg" to the stack and add its eventual target (otherTargetReg)
10221                         // to "targetRegsFromStack", which will be handled below.
10222                         // NOTE: This condition is very rare.  Setting COMPlus_JitStressRegs=0x203
10223                         // has been known to trigger it in JIT SH.
10224
10225                         // First, spill "otherInterval" from targetReg to the stack.
10226                         Interval* otherInterval = sourceIntervals[source[otherTargetReg]];
10227                         setIntervalAsSpilled(otherInterval);
10228                         addResolution(block, insertionPoint, otherInterval, REG_STK, targetReg);
10229                         JITDUMP(" (%s)\n", resolveTypeName[resolveType]);
10230                         location[source[otherTargetReg]] = REG_STK;
10231
10232                         // Now, move the interval that is going to targetReg, and add its "fromReg" to
10233                         // "targetRegsReady".
10234                         addResolution(block, insertionPoint, sourceIntervals[sourceReg], targetReg, fromReg);
10235                         JITDUMP(" (%s)\n", resolveTypeName[resolveType]);
10236                         location[sourceReg] = REG_NA;
10237                         targetRegsReady |= genRegMask(fromReg);
10238                     }
10239                     targetRegsToDo &= ~targetRegMask;
10240                 }
10241                 else
10242                 {
10243                     compiler->codeGen->regSet.rsSetRegsModified(genRegMask(tempReg) DEBUGARG(dumpTerse));
10244                     assert(sourceIntervals[targetReg] != nullptr);
10245                     addResolution(block, insertionPoint, sourceIntervals[targetReg], tempReg, targetReg);
10246                     JITDUMP(" (%s)\n", resolveTypeName[resolveType]);
10247                     location[targetReg] = (regNumberSmall)tempReg;
10248                     targetRegsReady |= targetRegMask;
10249                 }
10250             }
10251         }
10252     }
10253
10254     // Finally, perform stack to reg moves
10255     // All the target regs will be empty at this point
10256     while (targetRegsFromStack != RBM_NONE)
10257     {
10258         regMaskTP targetRegMask = genFindLowestBit(targetRegsFromStack);
10259         targetRegsFromStack &= ~targetRegMask;
10260         regNumber targetReg = genRegNumFromMask(targetRegMask);
10261
10262         Interval* interval = stackToRegIntervals[targetReg];
10263         assert(interval != nullptr);
10264
10265         addResolution(block, insertionPoint, interval, targetReg, REG_STK);
10266         JITDUMP(" (%s)\n", resolveTypeName[resolveType]);
10267     }
10268 }
10269
10270 void TreeNodeInfo::Initialize(LinearScan* lsra, GenTree* node, LsraLocation location)
10271 {
10272     regMaskTP dstCandidates;
10273
10274     // if there is a reg indicated on the tree node, use that for dstCandidates
10275     // the exception is the NOP, which sometimes show up around late args.
10276     // TODO-Cleanup: get rid of those NOPs.
10277     if (node->gtRegNum == REG_NA || node->gtOper == GT_NOP)
10278     {
10279 #ifdef ARM_SOFTFP
10280         if (node->OperGet() == GT_PUTARG_REG)
10281         {
10282             dstCandidates = lsra->allRegs(TYP_INT);
10283         }
10284         else
10285 #endif
10286         {
10287             dstCandidates = lsra->allRegs(node->TypeGet());
10288         }
10289     }
10290     else
10291     {
10292         dstCandidates = genRegMask(node->gtRegNum);
10293     }
10294
10295     internalIntCount    = 0;
10296     internalFloatCount  = 0;
10297     isLocalDefUse       = false;
10298     isLsraAdded         = false;
10299     definesAnyRegisters = false;
10300
10301     setDstCandidates(lsra, dstCandidates);
10302     srcCandsIndex = dstCandsIndex;
10303
10304     setInternalCandidates(lsra, lsra->allRegs(TYP_INT));
10305
10306     loc = location;
10307 #ifdef DEBUG
10308     isInitialized = true;
10309 #endif
10310
10311     assert(IsValid(lsra));
10312 }
10313
10314 regMaskTP TreeNodeInfo::getSrcCandidates(LinearScan* lsra)
10315 {
10316     return lsra->GetRegMaskForIndex(srcCandsIndex);
10317 }
10318
10319 void TreeNodeInfo::setSrcCandidates(LinearScan* lsra, regMaskTP mask)
10320 {
10321     LinearScan::RegMaskIndex i = lsra->GetIndexForRegMask(mask);
10322     assert(FitsIn<unsigned char>(i));
10323     srcCandsIndex = (unsigned char)i;
10324 }
10325
10326 regMaskTP TreeNodeInfo::getDstCandidates(LinearScan* lsra)
10327 {
10328     return lsra->GetRegMaskForIndex(dstCandsIndex);
10329 }
10330
10331 void TreeNodeInfo::setDstCandidates(LinearScan* lsra, regMaskTP mask)
10332 {
10333     LinearScan::RegMaskIndex i = lsra->GetIndexForRegMask(mask);
10334     assert(FitsIn<unsigned char>(i));
10335     dstCandsIndex = (unsigned char)i;
10336 }
10337
10338 regMaskTP TreeNodeInfo::getInternalCandidates(LinearScan* lsra)
10339 {
10340     return lsra->GetRegMaskForIndex(internalCandsIndex);
10341 }
10342
10343 void TreeNodeInfo::setInternalCandidates(LinearScan* lsra, regMaskTP mask)
10344 {
10345     LinearScan::RegMaskIndex i = lsra->GetIndexForRegMask(mask);
10346     assert(FitsIn<unsigned char>(i));
10347     internalCandsIndex = (unsigned char)i;
10348 }
10349
10350 void TreeNodeInfo::addInternalCandidates(LinearScan* lsra, regMaskTP mask)
10351 {
10352     LinearScan::RegMaskIndex i = lsra->GetIndexForRegMask(lsra->GetRegMaskForIndex(internalCandsIndex) | mask);
10353     assert(FitsIn<unsigned char>(i));
10354     internalCandsIndex = (unsigned char)i;
10355 }
10356
10357 #if TRACK_LSRA_STATS
10358 // ----------------------------------------------------------
10359 // updateLsraStat: Increment LSRA stat counter.
10360 //
10361 // Arguments:
10362 //    stat      -   LSRA stat enum
10363 //    bbNum     -   Basic block to which LSRA stat needs to be
10364 //                  associated with.
10365 //
10366 void LinearScan::updateLsraStat(LsraStat stat, unsigned bbNum)
10367 {
10368     if (bbNum > bbNumMaxBeforeResolution)
10369     {
10370         // This is a newly created basic block as part of resolution.
10371         // These blocks contain resolution moves that are already accounted.
10372         return;
10373     }
10374
10375     switch (stat)
10376     {
10377         case LSRA_STAT_SPILL:
10378             ++(blockInfo[bbNum].spillCount);
10379             break;
10380
10381         case LSRA_STAT_COPY_REG:
10382             ++(blockInfo[bbNum].copyRegCount);
10383             break;
10384
10385         case LSRA_STAT_RESOLUTION_MOV:
10386             ++(blockInfo[bbNum].resolutionMovCount);
10387             break;
10388
10389         case LSRA_STAT_SPLIT_EDGE:
10390             ++(blockInfo[bbNum].splitEdgeCount);
10391             break;
10392
10393         default:
10394             break;
10395     }
10396 }
10397
10398 // -----------------------------------------------------------
10399 // dumpLsraStats - dumps Lsra stats to given file.
10400 //
10401 // Arguments:
10402 //    file    -  file to which stats are to be written.
10403 //
10404 void LinearScan::dumpLsraStats(FILE* file)
10405 {
10406     unsigned sumSpillCount         = 0;
10407     unsigned sumCopyRegCount       = 0;
10408     unsigned sumResolutionMovCount = 0;
10409     unsigned sumSplitEdgeCount     = 0;
10410     UINT64   wtdSpillCount         = 0;
10411     UINT64   wtdCopyRegCount       = 0;
10412     UINT64   wtdResolutionMovCount = 0;
10413
10414     fprintf(file, "----------\n");
10415     fprintf(file, "LSRA Stats");
10416 #ifdef DEBUG
10417     if (!VERBOSE)
10418     {
10419         fprintf(file, " : %s\n", compiler->info.compFullName);
10420     }
10421     else
10422     {
10423         // In verbose mode no need to print full name
10424         // while printing lsra stats.
10425         fprintf(file, "\n");
10426     }
10427 #else
10428     fprintf(file, " : %s\n", compiler->eeGetMethodFullName(compiler->info.compCompHnd));
10429 #endif
10430
10431     fprintf(file, "----------\n");
10432
10433     for (BasicBlock* block = compiler->fgFirstBB; block != nullptr; block = block->bbNext)
10434     {
10435         if (block->bbNum > bbNumMaxBeforeResolution)
10436         {
10437             continue;
10438         }
10439
10440         unsigned spillCount         = blockInfo[block->bbNum].spillCount;
10441         unsigned copyRegCount       = blockInfo[block->bbNum].copyRegCount;
10442         unsigned resolutionMovCount = blockInfo[block->bbNum].resolutionMovCount;
10443         unsigned splitEdgeCount     = blockInfo[block->bbNum].splitEdgeCount;
10444
10445         if (spillCount != 0 || copyRegCount != 0 || resolutionMovCount != 0 || splitEdgeCount != 0)
10446         {
10447             fprintf(file, "BB%02u [%8d]: ", block->bbNum, block->bbWeight);
10448             fprintf(file, "SpillCount = %d, ResolutionMovs = %d, SplitEdges = %d, CopyReg = %d\n", spillCount,
10449                     resolutionMovCount, splitEdgeCount, copyRegCount);
10450         }
10451
10452         sumSpillCount += spillCount;
10453         sumCopyRegCount += copyRegCount;
10454         sumResolutionMovCount += resolutionMovCount;
10455         sumSplitEdgeCount += splitEdgeCount;
10456
10457         wtdSpillCount += (UINT64)spillCount * block->bbWeight;
10458         wtdCopyRegCount += (UINT64)copyRegCount * block->bbWeight;
10459         wtdResolutionMovCount += (UINT64)resolutionMovCount * block->bbWeight;
10460     }
10461
10462     fprintf(file, "Total Tracked Vars:  %d\n", compiler->lvaTrackedCount);
10463     fprintf(file, "Total Reg Cand Vars: %d\n", regCandidateVarCount);
10464     fprintf(file, "Total number of Intervals: %d\n", static_cast<unsigned>(intervals.size() - 1));
10465     fprintf(file, "Total number of RefPositions: %d\n", static_cast<unsigned>(refPositions.size() - 1));
10466     fprintf(file, "Total Spill Count: %d    Weighted: %I64u\n", sumSpillCount, wtdSpillCount);
10467     fprintf(file, "Total CopyReg Count: %d   Weighted: %I64u\n", sumCopyRegCount, wtdCopyRegCount);
10468     fprintf(file, "Total ResolutionMov Count: %d    Weighted: %I64u\n", sumResolutionMovCount, wtdResolutionMovCount);
10469     fprintf(file, "Total number of split edges: %d\n", sumSplitEdgeCount);
10470
10471     // compute total number of spill temps created
10472     unsigned numSpillTemps = 0;
10473     for (int i = 0; i < TYP_COUNT; i++)
10474     {
10475         numSpillTemps += maxSpill[i];
10476     }
10477     fprintf(file, "Total Number of spill temps created: %d\n\n", numSpillTemps);
10478 }
10479 #endif // TRACK_LSRA_STATS
10480
10481 #ifdef DEBUG
10482 void dumpRegMask(regMaskTP regs)
10483 {
10484     if (regs == RBM_ALLINT)
10485     {
10486         printf("[allInt]");
10487     }
10488     else if (regs == (RBM_ALLINT & ~RBM_FPBASE))
10489     {
10490         printf("[allIntButFP]");
10491     }
10492     else if (regs == RBM_ALLFLOAT)
10493     {
10494         printf("[allFloat]");
10495     }
10496     else if (regs == RBM_ALLDOUBLE)
10497     {
10498         printf("[allDouble]");
10499     }
10500     else
10501     {
10502         dspRegMask(regs);
10503     }
10504 }
10505
10506 static const char* getRefTypeName(RefType refType)
10507 {
10508     switch (refType)
10509     {
10510 #define DEF_REFTYPE(memberName, memberValue, shortName)                                                                \
10511     case memberName:                                                                                                   \
10512         return #memberName;
10513 #include "lsra_reftypes.h"
10514 #undef DEF_REFTYPE
10515         default:
10516             return nullptr;
10517     }
10518 }
10519
10520 static const char* getRefTypeShortName(RefType refType)
10521 {
10522     switch (refType)
10523     {
10524 #define DEF_REFTYPE(memberName, memberValue, shortName)                                                                \
10525     case memberName:                                                                                                   \
10526         return shortName;
10527 #include "lsra_reftypes.h"
10528 #undef DEF_REFTYPE
10529         default:
10530             return nullptr;
10531     }
10532 }
10533
10534 void RefPosition::dump()
10535 {
10536     printf("<RefPosition #%-3u @%-3u", rpNum, nodeLocation);
10537
10538     if (nextRefPosition)
10539     {
10540         printf(" ->#%-3u", nextRefPosition->rpNum);
10541     }
10542
10543     printf(" %s ", getRefTypeName(refType));
10544
10545     if (this->isPhysRegRef)
10546     {
10547         this->getReg()->tinyDump();
10548     }
10549     else if (getInterval())
10550     {
10551         this->getInterval()->tinyDump();
10552     }
10553
10554     if (this->treeNode)
10555     {
10556         printf("%s ", treeNode->OpName(treeNode->OperGet()));
10557     }
10558     printf("BB%02u ", this->bbNum);
10559
10560     printf("regmask=");
10561     dumpRegMask(registerAssignment);
10562
10563     if (this->lastUse)
10564     {
10565         printf(" last");
10566     }
10567     if (this->reload)
10568     {
10569         printf(" reload");
10570     }
10571     if (this->spillAfter)
10572     {
10573         printf(" spillAfter");
10574     }
10575     if (this->moveReg)
10576     {
10577         printf(" move");
10578     }
10579     if (this->copyReg)
10580     {
10581         printf(" copy");
10582     }
10583     if (this->isFixedRegRef)
10584     {
10585         printf(" fixed");
10586     }
10587     if (this->isLocalDefUse)
10588     {
10589         printf(" local");
10590     }
10591     if (this->delayRegFree)
10592     {
10593         printf(" delay");
10594     }
10595     if (this->outOfOrder)
10596     {
10597         printf(" outOfOrder");
10598     }
10599
10600     if (this->AllocateIfProfitable())
10601     {
10602         printf(" regOptional");
10603     }
10604     printf(">\n");
10605 }
10606
10607 void RegRecord::dump()
10608 {
10609     tinyDump();
10610 }
10611
10612 void Interval::dump()
10613 {
10614     printf("Interval %2u:", intervalIndex);
10615
10616     if (isLocalVar)
10617     {
10618         printf(" (V%02u)", varNum);
10619     }
10620     if (isInternal)
10621     {
10622         printf(" (INTERNAL)");
10623     }
10624     if (isSpilled)
10625     {
10626         printf(" (SPILLED)");
10627     }
10628     if (isSplit)
10629     {
10630         printf(" (SPLIT)");
10631     }
10632     if (isStructField)
10633     {
10634         printf(" (struct)");
10635     }
10636     if (isSpecialPutArg)
10637     {
10638         printf(" (specialPutArg)");
10639     }
10640     if (isConstant)
10641     {
10642         printf(" (constant)");
10643     }
10644
10645     printf(" RefPositions {");
10646     for (RefPosition* refPosition = this->firstRefPosition; refPosition != nullptr;
10647          refPosition              = refPosition->nextRefPosition)
10648     {
10649         printf("#%u@%u", refPosition->rpNum, refPosition->nodeLocation);
10650         if (refPosition->nextRefPosition)
10651         {
10652             printf(" ");
10653         }
10654     }
10655     printf("}");
10656
10657     // this is not used (yet?)
10658     // printf(" SpillOffset %d", this->spillOffset);
10659
10660     printf(" physReg:%s", getRegName(physReg));
10661
10662     printf(" Preferences=");
10663     dumpRegMask(this->registerPreferences);
10664
10665     if (relatedInterval)
10666     {
10667         printf(" RelatedInterval ");
10668         relatedInterval->microDump();
10669         printf("[%p]", dspPtr(relatedInterval));
10670     }
10671
10672     printf("\n");
10673 }
10674
10675 // print out very concise representation
10676 void Interval::tinyDump()
10677 {
10678     printf("<Ivl:%u", intervalIndex);
10679     if (isLocalVar)
10680     {
10681         printf(" V%02u", varNum);
10682     }
10683     if (isInternal)
10684     {
10685         printf(" internal");
10686     }
10687     printf("> ");
10688 }
10689
10690 // print out extremely concise representation
10691 void Interval::microDump()
10692 {
10693     char intervalTypeChar = 'I';
10694     if (isInternal)
10695     {
10696         intervalTypeChar = 'T';
10697     }
10698     else if (isLocalVar)
10699     {
10700         intervalTypeChar = 'L';
10701     }
10702
10703     printf("<%c%u>", intervalTypeChar, intervalIndex);
10704 }
10705
10706 void RegRecord::tinyDump()
10707 {
10708     printf("<Reg:%-3s> ", getRegName(regNum));
10709 }
10710
10711 void TreeNodeInfo::dump(LinearScan* lsra)
10712 {
10713     printf("<TreeNodeInfo @ %2u %d=%d %di %df", loc, dstCount, srcCount, internalIntCount, internalFloatCount);
10714     printf(" src=");
10715     dumpRegMask(getSrcCandidates(lsra));
10716     printf(" int=");
10717     dumpRegMask(getInternalCandidates(lsra));
10718     printf(" dst=");
10719     dumpRegMask(getDstCandidates(lsra));
10720     if (isLocalDefUse)
10721     {
10722         printf(" L");
10723     }
10724     if (isInitialized)
10725     {
10726         printf(" I");
10727     }
10728     if (isLsraAdded)
10729     {
10730         printf(" A");
10731     }
10732     if (isDelayFree)
10733     {
10734         printf(" D");
10735     }
10736     if (isTgtPref)
10737     {
10738         printf(" P");
10739     }
10740     if (regOptional)
10741     {
10742         printf(" O");
10743     }
10744     if (isInternalRegDelayFree)
10745     {
10746         printf(" ID");
10747     }
10748     printf(">\n");
10749 }
10750
10751 void LinearScan::lsraDumpIntervals(const char* msg)
10752 {
10753     Interval* interval;
10754
10755     printf("\nLinear scan intervals %s:\n", msg);
10756     for (auto& interval : intervals)
10757     {
10758         // only dump something if it has references
10759         // if (interval->firstRefPosition)
10760         interval.dump();
10761     }
10762
10763     printf("\n");
10764 }
10765
10766 // Dumps a tree node as a destination or source operand, with the style
10767 // of dump dependent on the mode
10768 void LinearScan::lsraGetOperandString(GenTreePtr        tree,
10769                                       LsraTupleDumpMode mode,
10770                                       char*             operandString,
10771                                       unsigned          operandStringLength)
10772 {
10773     const char* lastUseChar = "";
10774     if ((tree->gtFlags & GTF_VAR_DEATH) != 0)
10775     {
10776         lastUseChar = "*";
10777     }
10778     switch (mode)
10779     {
10780         case LinearScan::LSRA_DUMP_PRE:
10781             _snprintf_s(operandString, operandStringLength, operandStringLength, "t%d%s", tree->gtTreeID, lastUseChar);
10782             break;
10783         case LinearScan::LSRA_DUMP_REFPOS:
10784             _snprintf_s(operandString, operandStringLength, operandStringLength, "t%d%s", tree->gtTreeID, lastUseChar);
10785             break;
10786         case LinearScan::LSRA_DUMP_POST:
10787         {
10788             Compiler* compiler = JitTls::GetCompiler();
10789
10790             if (!tree->gtHasReg())
10791             {
10792                 _snprintf_s(operandString, operandStringLength, operandStringLength, "STK%s", lastUseChar);
10793             }
10794             else
10795             {
10796                 _snprintf_s(operandString, operandStringLength, operandStringLength, "%s%s",
10797                             getRegName(tree->gtRegNum, useFloatReg(tree->TypeGet())), lastUseChar);
10798             }
10799         }
10800         break;
10801         default:
10802             printf("ERROR: INVALID TUPLE DUMP MODE\n");
10803             break;
10804     }
10805 }
10806 void LinearScan::lsraDispNode(GenTreePtr tree, LsraTupleDumpMode mode, bool hasDest)
10807 {
10808     Compiler*      compiler            = JitTls::GetCompiler();
10809     const unsigned operandStringLength = 16;
10810     char           operandString[operandStringLength];
10811     const char*    emptyDestOperand = "               ";
10812     char           spillChar        = ' ';
10813
10814     if (mode == LinearScan::LSRA_DUMP_POST)
10815     {
10816         if ((tree->gtFlags & GTF_SPILL) != 0)
10817         {
10818             spillChar = 'S';
10819         }
10820         if (!hasDest && tree->gtHasReg())
10821         {
10822             // A node can define a register, but not produce a value for a parent to consume,
10823             // i.e. in the "localDefUse" case.
10824             // There used to be an assert here that we wouldn't spill such a node.
10825             // However, we can have unused lclVars that wind up being the node at which
10826             // it is spilled. This probably indicates a bug, but we don't realy want to
10827             // assert during a dump.
10828             if (spillChar == 'S')
10829             {
10830                 spillChar = '$';
10831             }
10832             else
10833             {
10834                 spillChar = '*';
10835             }
10836             hasDest = true;
10837         }
10838     }
10839     printf("%c N%03u. ", spillChar, tree->gtSeqNum);
10840
10841     LclVarDsc* varDsc = nullptr;
10842     unsigned   varNum = UINT_MAX;
10843     if (tree->IsLocal())
10844     {
10845         varNum = tree->gtLclVarCommon.gtLclNum;
10846         varDsc = &(compiler->lvaTable[varNum]);
10847         if (varDsc->lvLRACandidate)
10848         {
10849             hasDest = false;
10850         }
10851     }
10852     if (hasDest)
10853     {
10854         if (mode == LinearScan::LSRA_DUMP_POST && tree->gtFlags & GTF_SPILLED)
10855         {
10856             assert(tree->gtHasReg());
10857         }
10858         lsraGetOperandString(tree, mode, operandString, operandStringLength);
10859         printf("%-15s =", operandString);
10860     }
10861     else
10862     {
10863         printf("%-15s  ", emptyDestOperand);
10864     }
10865     if (varDsc != nullptr)
10866     {
10867         if (varDsc->lvLRACandidate)
10868         {
10869             if (mode == LSRA_DUMP_REFPOS)
10870             {
10871                 printf("  V%02u(L%d)", varNum, getIntervalForLocalVar(varDsc->lvVarIndex)->intervalIndex);
10872             }
10873             else
10874             {
10875                 lsraGetOperandString(tree, mode, operandString, operandStringLength);
10876                 printf("  V%02u(%s)", varNum, operandString);
10877                 if (mode == LinearScan::LSRA_DUMP_POST && tree->gtFlags & GTF_SPILLED)
10878                 {
10879                     printf("R");
10880                 }
10881             }
10882         }
10883         else
10884         {
10885             printf("  V%02u MEM", varNum);
10886         }
10887     }
10888     else if (tree->OperIsAssignment())
10889     {
10890         assert(!tree->gtHasReg());
10891         printf("  asg%s  ", GenTree::OpName(tree->OperGet()));
10892     }
10893     else
10894     {
10895         compiler->gtDispNodeName(tree);
10896         if (tree->OperKind() & GTK_LEAF)
10897         {
10898             compiler->gtDispLeaf(tree, nullptr);
10899         }
10900     }
10901 }
10902
10903 //------------------------------------------------------------------------
10904 // ComputeOperandDstCount: computes the number of registers defined by a
10905 //                         node.
10906 //
10907 // For most nodes, this is simple:
10908 // - Nodes that do not produce values (e.g. stores and other void-typed
10909 //   nodes) and nodes that immediately use the registers they define
10910 //   produce no registers
10911 // - Nodes that are marked as defining N registers define N registers.
10912 //
10913 // For contained nodes, however, things are more complicated: for purposes
10914 // of bookkeeping, a contained node is treated as producing the transitive
10915 // closure of the registers produced by its sources.
10916 //
10917 // Arguments:
10918 //    operand - The operand for which to compute a register count.
10919 //
10920 // Returns:
10921 //    The number of registers defined by `operand`.
10922 //
10923 void LinearScan::DumpOperandDefs(
10924     GenTree* operand, bool& first, LsraTupleDumpMode mode, char* operandString, const unsigned operandStringLength)
10925 {
10926     assert(operand != nullptr);
10927     assert(operandString != nullptr);
10928
10929     if (ComputeOperandDstCount(operand) == 0)
10930     {
10931         return;
10932     }
10933
10934     if (operand->gtLsraInfo.dstCount != 0)
10935     {
10936         // This operand directly produces registers; print it.
10937         for (int i = 0; i < operand->gtLsraInfo.dstCount; i++)
10938         {
10939             if (!first)
10940             {
10941                 printf(",");
10942             }
10943
10944             lsraGetOperandString(operand, mode, operandString, operandStringLength);
10945             printf("%s", operandString);
10946
10947             first = false;
10948         }
10949     }
10950     else
10951     {
10952         // This is a contained node. Dump the defs produced by its operands.
10953         for (GenTree* op : operand->Operands())
10954         {
10955             DumpOperandDefs(op, first, mode, operandString, operandStringLength);
10956         }
10957     }
10958 }
10959
10960 void LinearScan::TupleStyleDump(LsraTupleDumpMode mode)
10961 {
10962     BasicBlock*    block;
10963     LsraLocation   currentLoc          = 1; // 0 is the entry
10964     const unsigned operandStringLength = 16;
10965     char           operandString[operandStringLength];
10966
10967     // currentRefPosition is not used for LSRA_DUMP_PRE
10968     // We keep separate iterators for defs, so that we can print them
10969     // on the lhs of the dump
10970     auto currentRefPosition = refPositions.begin();
10971
10972     switch (mode)
10973     {
10974         case LSRA_DUMP_PRE:
10975             printf("TUPLE STYLE DUMP BEFORE LSRA\n");
10976             break;
10977         case LSRA_DUMP_REFPOS:
10978             printf("TUPLE STYLE DUMP WITH REF POSITIONS\n");
10979             break;
10980         case LSRA_DUMP_POST:
10981             printf("TUPLE STYLE DUMP WITH REGISTER ASSIGNMENTS\n");
10982             break;
10983         default:
10984             printf("ERROR: INVALID TUPLE DUMP MODE\n");
10985             return;
10986     }
10987
10988     if (mode != LSRA_DUMP_PRE)
10989     {
10990         printf("Incoming Parameters: ");
10991         for (; currentRefPosition != refPositions.end() && currentRefPosition->refType != RefTypeBB;
10992              ++currentRefPosition)
10993         {
10994             Interval* interval = currentRefPosition->getInterval();
10995             assert(interval != nullptr && interval->isLocalVar);
10996             printf(" V%02d", interval->varNum);
10997             if (mode == LSRA_DUMP_POST)
10998             {
10999                 regNumber reg;
11000                 if (currentRefPosition->registerAssignment == RBM_NONE)
11001                 {
11002                     reg = REG_STK;
11003                 }
11004                 else
11005                 {
11006                     reg = currentRefPosition->assignedReg();
11007                 }
11008                 LclVarDsc* varDsc = &(compiler->lvaTable[interval->varNum]);
11009                 printf("(");
11010                 regNumber assignedReg = varDsc->lvRegNum;
11011                 regNumber argReg      = (varDsc->lvIsRegArg) ? varDsc->lvArgReg : REG_STK;
11012
11013                 assert(reg == assignedReg || varDsc->lvRegister == false);
11014                 if (reg != argReg)
11015                 {
11016                     printf(getRegName(argReg, isFloatRegType(interval->registerType)));
11017                     printf("=>");
11018                 }
11019                 printf("%s)", getRegName(reg, isFloatRegType(interval->registerType)));
11020             }
11021         }
11022         printf("\n");
11023     }
11024
11025     for (block = startBlockSequence(); block != nullptr; block = moveToNextBlock())
11026     {
11027         currentLoc += 2;
11028
11029         if (mode == LSRA_DUMP_REFPOS)
11030         {
11031             bool printedBlockHeader = false;
11032             // We should find the boundary RefPositions in the order of exposed uses, dummy defs, and the blocks
11033             for (; currentRefPosition != refPositions.end() &&
11034                    (currentRefPosition->refType == RefTypeExpUse || currentRefPosition->refType == RefTypeDummyDef ||
11035                     (currentRefPosition->refType == RefTypeBB && !printedBlockHeader));
11036                  ++currentRefPosition)
11037             {
11038                 Interval* interval = nullptr;
11039                 if (currentRefPosition->isIntervalRef())
11040                 {
11041                     interval = currentRefPosition->getInterval();
11042                 }
11043                 switch (currentRefPosition->refType)
11044                 {
11045                     case RefTypeExpUse:
11046                         assert(interval != nullptr);
11047                         assert(interval->isLocalVar);
11048                         printf("  Exposed use of V%02u at #%d\n", interval->varNum, currentRefPosition->rpNum);
11049                         break;
11050                     case RefTypeDummyDef:
11051                         assert(interval != nullptr);
11052                         assert(interval->isLocalVar);
11053                         printf("  Dummy def of V%02u at #%d\n", interval->varNum, currentRefPosition->rpNum);
11054                         break;
11055                     case RefTypeBB:
11056                         block->dspBlockHeader(compiler);
11057                         printedBlockHeader = true;
11058                         printf("=====\n");
11059                         break;
11060                     default:
11061                         printf("Unexpected RefPosition type at #%d\n", currentRefPosition->rpNum);
11062                         break;
11063                 }
11064             }
11065         }
11066         else
11067         {
11068             block->dspBlockHeader(compiler);
11069             printf("=====\n");
11070         }
11071         if (enregisterLocalVars && mode == LSRA_DUMP_POST && block != compiler->fgFirstBB &&
11072             block->bbNum <= bbNumMaxBeforeResolution)
11073         {
11074             printf("Predecessor for variable locations: BB%02u\n", blockInfo[block->bbNum].predBBNum);
11075             dumpInVarToRegMap(block);
11076         }
11077         if (block->bbNum > bbNumMaxBeforeResolution)
11078         {
11079             SplitEdgeInfo splitEdgeInfo;
11080             splitBBNumToTargetBBNumMap->Lookup(block->bbNum, &splitEdgeInfo);
11081             assert(splitEdgeInfo.toBBNum <= bbNumMaxBeforeResolution);
11082             assert(splitEdgeInfo.fromBBNum <= bbNumMaxBeforeResolution);
11083             printf("New block introduced for resolution from BB%02u to BB%02u\n", splitEdgeInfo.fromBBNum,
11084                    splitEdgeInfo.toBBNum);
11085         }
11086
11087         for (GenTree* node : LIR::AsRange(block).NonPhiNodes())
11088         {
11089             GenTree* tree = node;
11090
11091             genTreeOps    oper = tree->OperGet();
11092             TreeNodeInfo& info = tree->gtLsraInfo;
11093             if (tree->gtLsraInfo.isLsraAdded)
11094             {
11095                 // This must be one of the nodes that we add during LSRA
11096
11097                 if (oper == GT_LCL_VAR)
11098                 {
11099                     info.srcCount = 0;
11100                     info.dstCount = 1;
11101                 }
11102                 else if (oper == GT_RELOAD || oper == GT_COPY)
11103                 {
11104                     info.srcCount = 1;
11105                     info.dstCount = 1;
11106                 }
11107 #ifdef FEATURE_SIMD
11108                 else if (oper == GT_SIMD)
11109                 {
11110                     if (tree->gtSIMD.gtSIMDIntrinsicID == SIMDIntrinsicUpperSave)
11111                     {
11112                         info.srcCount = 1;
11113                         info.dstCount = 1;
11114                     }
11115                     else
11116                     {
11117                         assert(tree->gtSIMD.gtSIMDIntrinsicID == SIMDIntrinsicUpperRestore);
11118                         info.srcCount = 2;
11119                         info.dstCount = 0;
11120                     }
11121                 }
11122 #endif // FEATURE_SIMD
11123                 else
11124                 {
11125                     assert(oper == GT_SWAP);
11126                     info.srcCount = 2;
11127                     info.dstCount = 0;
11128                 }
11129                 info.internalIntCount   = 0;
11130                 info.internalFloatCount = 0;
11131             }
11132
11133             int       consume   = info.srcCount;
11134             int       produce   = info.dstCount;
11135             regMaskTP killMask  = RBM_NONE;
11136             regMaskTP fixedMask = RBM_NONE;
11137
11138             lsraDispNode(tree, mode, produce != 0 && mode != LSRA_DUMP_REFPOS);
11139
11140             if (mode != LSRA_DUMP_REFPOS)
11141             {
11142                 if (consume > 0)
11143                 {
11144                     printf("; ");
11145
11146                     bool first = true;
11147                     for (GenTree* operand : tree->Operands())
11148                     {
11149                         DumpOperandDefs(operand, first, mode, operandString, operandStringLength);
11150                     }
11151                 }
11152             }
11153             else
11154             {
11155                 // Print each RefPosition on a new line, but
11156                 // printing all the kills for each node on a single line
11157                 // and combining the fixed regs with their associated def or use
11158                 bool         killPrinted        = false;
11159                 RefPosition* lastFixedRegRefPos = nullptr;
11160                 for (; currentRefPosition != refPositions.end() &&
11161                        (currentRefPosition->refType == RefTypeUse || currentRefPosition->refType == RefTypeFixedReg ||
11162                         currentRefPosition->refType == RefTypeKill || currentRefPosition->refType == RefTypeDef) &&
11163                        (currentRefPosition->nodeLocation == tree->gtSeqNum ||
11164                         currentRefPosition->nodeLocation == tree->gtSeqNum + 1);
11165                      ++currentRefPosition)
11166                 {
11167                     Interval* interval = nullptr;
11168                     if (currentRefPosition->isIntervalRef())
11169                     {
11170                         interval = currentRefPosition->getInterval();
11171                     }
11172                     switch (currentRefPosition->refType)
11173                     {
11174                         case RefTypeUse:
11175                             if (currentRefPosition->isPhysRegRef)
11176                             {
11177                                 printf("\n                               Use:R%d(#%d)",
11178                                        currentRefPosition->getReg()->regNum, currentRefPosition->rpNum);
11179                             }
11180                             else
11181                             {
11182                                 assert(interval != nullptr);
11183                                 printf("\n                               Use:");
11184                                 interval->microDump();
11185                                 printf("(#%d)", currentRefPosition->rpNum);
11186                                 if (currentRefPosition->isFixedRegRef)
11187                                 {
11188                                     assert(genMaxOneBit(currentRefPosition->registerAssignment));
11189                                     assert(lastFixedRegRefPos != nullptr);
11190                                     printf(" Fixed:%s(#%d)", getRegName(currentRefPosition->assignedReg(),
11191                                                                         isFloatRegType(interval->registerType)),
11192                                            lastFixedRegRefPos->rpNum);
11193                                     lastFixedRegRefPos = nullptr;
11194                                 }
11195                                 if (currentRefPosition->isLocalDefUse)
11196                                 {
11197                                     printf(" LocalDefUse");
11198                                 }
11199                                 if (currentRefPosition->lastUse)
11200                                 {
11201                                     printf(" *");
11202                                 }
11203                             }
11204                             break;
11205                         case RefTypeDef:
11206                         {
11207                             // Print each def on a new line
11208                             assert(interval != nullptr);
11209                             printf("\n        Def:");
11210                             interval->microDump();
11211                             printf("(#%d)", currentRefPosition->rpNum);
11212                             if (currentRefPosition->isFixedRegRef)
11213                             {
11214                                 assert(genMaxOneBit(currentRefPosition->registerAssignment));
11215                                 printf(" %s", getRegName(currentRefPosition->assignedReg(),
11216                                                          isFloatRegType(interval->registerType)));
11217                             }
11218                             if (currentRefPosition->isLocalDefUse)
11219                             {
11220                                 printf(" LocalDefUse");
11221                             }
11222                             if (currentRefPosition->lastUse)
11223                             {
11224                                 printf(" *");
11225                             }
11226                             if (interval->relatedInterval != nullptr)
11227                             {
11228                                 printf(" Pref:");
11229                                 interval->relatedInterval->microDump();
11230                             }
11231                         }
11232                         break;
11233                         case RefTypeKill:
11234                             if (!killPrinted)
11235                             {
11236                                 printf("\n        Kill: ");
11237                                 killPrinted = true;
11238                             }
11239                             printf(getRegName(currentRefPosition->assignedReg(),
11240                                               isFloatRegType(currentRefPosition->getReg()->registerType)));
11241                             printf(" ");
11242                             break;
11243                         case RefTypeFixedReg:
11244                             lastFixedRegRefPos = currentRefPosition;
11245                             break;
11246                         default:
11247                             printf("Unexpected RefPosition type at #%d\n", currentRefPosition->rpNum);
11248                             break;
11249                     }
11250                 }
11251             }
11252             printf("\n");
11253             if (info.internalIntCount != 0 && mode != LSRA_DUMP_REFPOS)
11254             {
11255                 printf("\tinternal (%d):\t", info.internalIntCount);
11256                 if (mode == LSRA_DUMP_POST)
11257                 {
11258                     dumpRegMask(tree->gtRsvdRegs);
11259                 }
11260                 else if ((info.getInternalCandidates(this) & allRegs(TYP_INT)) != allRegs(TYP_INT))
11261                 {
11262                     dumpRegMask(info.getInternalCandidates(this) & allRegs(TYP_INT));
11263                 }
11264                 printf("\n");
11265             }
11266             if (info.internalFloatCount != 0 && mode != LSRA_DUMP_REFPOS)
11267             {
11268                 printf("\tinternal (%d):\t", info.internalFloatCount);
11269                 if (mode == LSRA_DUMP_POST)
11270                 {
11271                     dumpRegMask(tree->gtRsvdRegs);
11272                 }
11273                 else if ((info.getInternalCandidates(this) & allRegs(TYP_INT)) != allRegs(TYP_INT))
11274                 {
11275                     dumpRegMask(info.getInternalCandidates(this) & allRegs(TYP_INT));
11276                 }
11277                 printf("\n");
11278             }
11279         }
11280         if (enregisterLocalVars && mode == LSRA_DUMP_POST)
11281         {
11282             dumpOutVarToRegMap(block);
11283         }
11284         printf("\n");
11285     }
11286     printf("\n\n");
11287 }
11288
11289 void LinearScan::dumpLsraAllocationEvent(LsraDumpEvent event,
11290                                          Interval*     interval,
11291                                          regNumber     reg,
11292                                          BasicBlock*   currentBlock)
11293 {
11294     if (!(VERBOSE))
11295     {
11296         return;
11297     }
11298     switch (event)
11299     {
11300         // Conflicting def/use
11301         case LSRA_EVENT_DEFUSE_CONFLICT:
11302             if (!dumpTerse)
11303             {
11304                 printf("  Def and Use have conflicting register requirements:");
11305             }
11306             else
11307             {
11308                 printf("DUconflict ");
11309                 dumpRegRecords();
11310             }
11311             break;
11312         case LSRA_EVENT_DEFUSE_FIXED_DELAY_USE:
11313             if (!dumpTerse)
11314             {
11315                 printf(" Can't change useAssignment ");
11316             }
11317             break;
11318         case LSRA_EVENT_DEFUSE_CASE1:
11319             if (!dumpTerse)
11320             {
11321                 printf(" case #1, use the defRegAssignment\n");
11322             }
11323             else
11324             {
11325                 printf(indentFormat, " case #1 use defRegAssignment");
11326                 dumpRegRecords();
11327                 dumpEmptyRefPosition();
11328             }
11329             break;
11330         case LSRA_EVENT_DEFUSE_CASE2:
11331             if (!dumpTerse)
11332             {
11333                 printf(" case #2, use the useRegAssignment\n");
11334             }
11335             else
11336             {
11337                 printf(indentFormat, " case #2 use useRegAssignment");
11338                 dumpRegRecords();
11339                 dumpEmptyRefPosition();
11340             }
11341             break;
11342         case LSRA_EVENT_DEFUSE_CASE3:
11343             if (!dumpTerse)
11344             {
11345                 printf(" case #3, change the defRegAssignment to the use regs\n");
11346             }
11347             else
11348             {
11349                 printf(indentFormat, " case #3 use useRegAssignment");
11350                 dumpRegRecords();
11351                 dumpEmptyRefPosition();
11352             }
11353             break;
11354         case LSRA_EVENT_DEFUSE_CASE4:
11355             if (!dumpTerse)
11356             {
11357                 printf(" case #4, change the useRegAssignment to the def regs\n");
11358             }
11359             else
11360             {
11361                 printf(indentFormat, " case #4 use defRegAssignment");
11362                 dumpRegRecords();
11363                 dumpEmptyRefPosition();
11364             }
11365             break;
11366         case LSRA_EVENT_DEFUSE_CASE5:
11367             if (!dumpTerse)
11368             {
11369                 printf(" case #5, Conflicting Def and Use single-register requirements require copies - set def to all "
11370                        "regs of the appropriate type\n");
11371             }
11372             else
11373             {
11374                 printf(indentFormat, " case #5 set def to all regs");
11375                 dumpRegRecords();
11376                 dumpEmptyRefPosition();
11377             }
11378             break;
11379         case LSRA_EVENT_DEFUSE_CASE6:
11380             if (!dumpTerse)
11381             {
11382                 printf(" case #6, Conflicting Def and Use register requirements require a copy\n");
11383             }
11384             else
11385             {
11386                 printf(indentFormat, " case #6 need a copy");
11387                 dumpRegRecords();
11388                 dumpEmptyRefPosition();
11389             }
11390             break;
11391
11392         case LSRA_EVENT_SPILL:
11393             if (!dumpTerse)
11394             {
11395                 printf("Spilled:\n");
11396                 interval->dump();
11397             }
11398             else
11399             {
11400                 assert(interval != nullptr && interval->assignedReg != nullptr);
11401                 printf("Spill %-4s ", getRegName(interval->assignedReg->regNum));
11402                 dumpRegRecords();
11403                 dumpEmptyRefPosition();
11404             }
11405             break;
11406         case LSRA_EVENT_SPILL_EXTENDED_LIFETIME:
11407             if (!dumpTerse)
11408             {
11409                 printf("  Spilled extended lifetime var V%02u at last use; not marked for actual spill.",
11410                        interval->intervalIndex);
11411             }
11412             break;
11413
11414         // Restoring the previous register
11415         case LSRA_EVENT_RESTORE_PREVIOUS_INTERVAL_AFTER_SPILL:
11416             assert(interval != nullptr);
11417             if (!dumpTerse)
11418             {
11419                 printf("  Assign register %s to previous interval Ivl:%d after spill\n", getRegName(reg),
11420                        interval->intervalIndex);
11421             }
11422             else
11423             {
11424                 // If we spilled, then the dump is already pre-indented, but we need to pre-indent for the subsequent
11425                 // allocation
11426                 // with a dumpEmptyRefPosition().
11427                 printf("SRstr %-4s ", getRegName(reg));
11428                 dumpRegRecords();
11429                 dumpEmptyRefPosition();
11430             }
11431             break;
11432         case LSRA_EVENT_RESTORE_PREVIOUS_INTERVAL:
11433             assert(interval != nullptr);
11434             if (!dumpTerse)
11435             {
11436                 printf("  Assign register %s to previous interval Ivl:%d\n", getRegName(reg), interval->intervalIndex);
11437             }
11438             else
11439             {
11440                 if (activeRefPosition == nullptr)
11441                 {
11442                     printf(emptyRefPositionFormat, "");
11443                 }
11444                 printf("Restr %-4s ", getRegName(reg));
11445                 dumpRegRecords();
11446                 if (activeRefPosition != nullptr)
11447                 {
11448                     printf(emptyRefPositionFormat, "");
11449                 }
11450             }
11451             break;
11452
11453         // Done with GC Kills
11454         case LSRA_EVENT_DONE_KILL_GC_REFS:
11455             printf("DoneKillGC ");
11456             break;
11457
11458         // Block boundaries
11459         case LSRA_EVENT_START_BB:
11460             assert(currentBlock != nullptr);
11461             if (!dumpTerse)
11462             {
11463                 printf("\n\n  Live Vars(Regs) at start of BB%02u (from pred BB%02u):", currentBlock->bbNum,
11464                        blockInfo[currentBlock->bbNum].predBBNum);
11465                 dumpVarToRegMap(inVarToRegMaps[currentBlock->bbNum]);
11466             }
11467             break;
11468         case LSRA_EVENT_END_BB:
11469             if (!dumpTerse)
11470             {
11471                 printf("\n\n  Live Vars(Regs) after BB%02u:", currentBlock->bbNum);
11472                 dumpVarToRegMap(outVarToRegMaps[currentBlock->bbNum]);
11473             }
11474             break;
11475
11476         case LSRA_EVENT_FREE_REGS:
11477             if (!dumpTerse)
11478             {
11479                 printf("Freeing registers:\n");
11480             }
11481             break;
11482
11483         // Characteristics of the current RefPosition
11484         case LSRA_EVENT_INCREMENT_RANGE_END:
11485             if (!dumpTerse)
11486             {
11487                 printf("  Incrementing nextPhysRegLocation for %s\n", getRegName(reg));
11488             }
11489             // else ???
11490             break;
11491         case LSRA_EVENT_LAST_USE:
11492             if (!dumpTerse)
11493             {
11494                 printf("    Last use, marked to be freed\n");
11495             }
11496             break;
11497         case LSRA_EVENT_LAST_USE_DELAYED:
11498             if (!dumpTerse)
11499             {
11500                 printf("    Last use, marked to be freed (delayed)\n");
11501             }
11502             break;
11503         case LSRA_EVENT_NEEDS_NEW_REG:
11504             if (!dumpTerse)
11505             {
11506                 printf("    Needs new register; mark %s to be freed\n", getRegName(reg));
11507             }
11508             else
11509             {
11510                 printf("Free  %-4s ", getRegName(reg));
11511                 dumpRegRecords();
11512                 dumpEmptyRefPosition();
11513             }
11514             break;
11515
11516         // Allocation decisions
11517         case LSRA_EVENT_FIXED_REG:
11518         case LSRA_EVENT_EXP_USE:
11519             if (!dumpTerse)
11520             {
11521                 printf("No allocation\n");
11522             }
11523             else
11524             {
11525                 printf("Keep  %-4s ", getRegName(reg));
11526             }
11527             break;
11528         case LSRA_EVENT_ZERO_REF:
11529             assert(interval != nullptr && interval->isLocalVar);
11530             if (!dumpTerse)
11531             {
11532                 printf("Marking V%02u as last use there are no actual references\n", interval->varNum);
11533             }
11534             else
11535             {
11536                 printf("NoRef      ");
11537                 dumpRegRecords();
11538                 dumpEmptyRefPosition();
11539             }
11540             break;
11541         case LSRA_EVENT_KEPT_ALLOCATION:
11542             if (!dumpTerse)
11543             {
11544                 printf("already allocated %4s\n", getRegName(reg));
11545             }
11546             else
11547             {
11548                 printf("Keep  %-4s ", getRegName(reg));
11549             }
11550             break;
11551         case LSRA_EVENT_COPY_REG:
11552             assert(interval != nullptr && interval->recentRefPosition != nullptr);
11553             if (!dumpTerse)
11554             {
11555                 printf("allocated %s as copyReg\n\n", getRegName(reg));
11556             }
11557             else
11558             {
11559                 printf("Copy  %-4s ", getRegName(reg));
11560             }
11561             break;
11562         case LSRA_EVENT_MOVE_REG:
11563             assert(interval != nullptr && interval->recentRefPosition != nullptr);
11564             if (!dumpTerse)
11565             {
11566                 printf("  needs a new register; marked as moveReg\n");
11567             }
11568             else
11569             {
11570                 printf("Move  %-4s ", getRegName(reg));
11571                 dumpRegRecords();
11572                 dumpEmptyRefPosition();
11573             }
11574             break;
11575         case LSRA_EVENT_ALLOC_REG:
11576             if (!dumpTerse)
11577             {
11578                 printf("allocated %s\n", getRegName(reg));
11579             }
11580             else
11581             {
11582                 printf("Alloc %-4s ", getRegName(reg));
11583             }
11584             break;
11585         case LSRA_EVENT_REUSE_REG:
11586             if (!dumpTerse)
11587             {
11588                 printf("reused constant in %s\n", getRegName(reg));
11589             }
11590             else
11591             {
11592                 printf("Reuse %-4s ", getRegName(reg));
11593             }
11594             break;
11595         case LSRA_EVENT_ALLOC_SPILLED_REG:
11596             if (!dumpTerse)
11597             {
11598                 printf("allocated spilled register %s\n", getRegName(reg));
11599             }
11600             else
11601             {
11602                 printf("Steal %-4s ", getRegName(reg));
11603             }
11604             break;
11605         case LSRA_EVENT_NO_ENTRY_REG_ALLOCATED:
11606             assert(interval != nullptr && interval->isLocalVar);
11607             if (!dumpTerse)
11608             {
11609                 printf("Not allocating an entry register for V%02u due to low ref count\n", interval->varNum);
11610             }
11611             else
11612             {
11613                 printf("LoRef      ");
11614             }
11615             break;
11616         case LSRA_EVENT_NO_REG_ALLOCATED:
11617             if (!dumpTerse)
11618             {
11619                 printf("no register allocated\n");
11620             }
11621             else
11622             {
11623                 printf("NoReg      ");
11624             }
11625             break;
11626         case LSRA_EVENT_RELOAD:
11627             if (!dumpTerse)
11628             {
11629                 printf("    Marked for reload\n");
11630             }
11631             else
11632             {
11633                 printf("ReLod %-4s ", getRegName(reg));
11634                 dumpRegRecords();
11635                 dumpEmptyRefPosition();
11636             }
11637             break;
11638         case LSRA_EVENT_SPECIAL_PUTARG:
11639             if (!dumpTerse)
11640             {
11641                 printf("    Special case of putArg - using lclVar that's in the expected reg\n");
11642             }
11643             else
11644             {
11645                 printf("PtArg %-4s ", getRegName(reg));
11646             }
11647             break;
11648         default:
11649             break;
11650     }
11651 }
11652
11653 //------------------------------------------------------------------------
11654 // dumpRegRecordHeader: Dump the header for a column-based dump of the register state.
11655 //
11656 // Arguments:
11657 //    None.
11658 //
11659 // Return Value:
11660 //    None.
11661 //
11662 // Assumptions:
11663 //    Reg names fit in 4 characters (minimum width of the columns)
11664 //
11665 // Notes:
11666 //    In order to make the table as dense as possible (for ease of reading the dumps),
11667 //    we determine the minimum regColumnWidth width required to represent:
11668 //      regs, by name (e.g. eax or xmm0) - this is fixed at 4 characters.
11669 //      intervals, as Vnn for lclVar intervals, or as I<num> for other intervals.
11670 //    The table is indented by the amount needed for dumpRefPositionShort, which is
11671 //    captured in shortRefPositionDumpWidth.
11672 //
11673 void LinearScan::dumpRegRecordHeader()
11674 {
11675     printf("The following table has one or more rows for each RefPosition that is handled during allocation.\n"
11676            "The first column provides the basic information about the RefPosition, with its type (e.g. Def,\n"
11677            "Use, Fixd) followed by a '*' if it is a last use, and a 'D' if it is delayRegFree, and then the\n"
11678            "action taken during allocation (e.g. Alloc a new register, or Keep an existing one).\n"
11679            "The subsequent columns show the Interval occupying each register, if any, followed by 'a' if it is\n"
11680            "active, and 'i'if it is inactive.  Columns are only printed up to the last modifed register, which\n"
11681            "may increase during allocation, in which case additional columns will appear.  Registers which are\n"
11682            "not marked modified have ---- in their column.\n\n");
11683
11684     // First, determine the width of each register column (which holds a reg name in the
11685     // header, and an interval name in each subsequent row).
11686     int intervalNumberWidth = (int)log10((double)intervals.size()) + 1;
11687     // The regColumnWidth includes the identifying character (I or V) and an 'i' or 'a' (inactive or active)
11688     regColumnWidth = intervalNumberWidth + 2;
11689     if (regColumnWidth < 4)
11690     {
11691         regColumnWidth = 4;
11692     }
11693     sprintf_s(intervalNameFormat, MAX_FORMAT_CHARS, "%%c%%-%dd", regColumnWidth - 2);
11694     sprintf_s(regNameFormat, MAX_FORMAT_CHARS, "%%-%ds", regColumnWidth);
11695
11696     // Next, determine the width of the short RefPosition (see dumpRefPositionShort()).
11697     // This is in the form:
11698     // nnn.#mmm NAME TYPEld
11699     // Where:
11700     //    nnn is the Location, right-justified to the width needed for the highest location.
11701     //    mmm is the RefPosition rpNum, left-justified to the width needed for the highest rpNum.
11702     //    NAME is dumped by dumpReferentName(), and is "regColumnWidth".
11703     //    TYPE is RefTypeNameShort, and is 4 characters
11704     //    l is either '*' (if a last use) or ' ' (otherwise)
11705     //    d is either 'D' (if a delayed use) or ' ' (otherwise)
11706
11707     maxNodeLocation = (maxNodeLocation == 0)
11708                           ? 1
11709                           : maxNodeLocation; // corner case of a method with an infinite loop without any gentree nodes
11710     assert(maxNodeLocation >= 1);
11711     assert(refPositions.size() >= 1);
11712     int nodeLocationWidth         = (int)log10((double)maxNodeLocation) + 1;
11713     int refPositionWidth          = (int)log10((double)refPositions.size()) + 1;
11714     int refTypeInfoWidth          = 4 /*TYPE*/ + 2 /* last-use and delayed */ + 1 /* space */;
11715     int locationAndRPNumWidth     = nodeLocationWidth + 2 /* .# */ + refPositionWidth + 1 /* space */;
11716     int shortRefPositionDumpWidth = locationAndRPNumWidth + regColumnWidth + 1 /* space */ + refTypeInfoWidth;
11717     sprintf_s(shortRefPositionFormat, MAX_FORMAT_CHARS, "%%%dd.#%%-%dd ", nodeLocationWidth, refPositionWidth);
11718     sprintf_s(emptyRefPositionFormat, MAX_FORMAT_CHARS, "%%-%ds", shortRefPositionDumpWidth);
11719
11720     // The width of the "allocation info"
11721     //  - a 5-character allocation decision
11722     //  - a space
11723     //  - a 4-character register
11724     //  - a space
11725     int allocationInfoWidth = 5 + 1 + 4 + 1;
11726
11727     // Next, determine the width of the legend for each row.  This includes:
11728     //  - a short RefPosition dump (shortRefPositionDumpWidth), which includes a space
11729     //  - the allocation info (allocationInfoWidth), which also includes a space
11730
11731     regTableIndent = shortRefPositionDumpWidth + allocationInfoWidth;
11732
11733     // BBnn printed left-justified in the NAME Typeld and allocationInfo space.
11734     int bbDumpWidth = regColumnWidth + 1 + refTypeInfoWidth + allocationInfoWidth;
11735     int bbNumWidth  = (int)log10((double)compiler->fgBBNumMax) + 1;
11736     // In the unlikely event that BB numbers overflow the space, we'll simply omit the predBB
11737     int predBBNumDumpSpace = regTableIndent - locationAndRPNumWidth - bbNumWidth - 9; // 'BB' + ' PredBB'
11738     if (predBBNumDumpSpace < bbNumWidth)
11739     {
11740         sprintf_s(bbRefPosFormat, MAX_LEGEND_FORMAT_CHARS, "BB%%-%dd", shortRefPositionDumpWidth - 2);
11741     }
11742     else
11743     {
11744         sprintf_s(bbRefPosFormat, MAX_LEGEND_FORMAT_CHARS, "BB%%-%dd PredBB%%-%dd", bbNumWidth, predBBNumDumpSpace);
11745     }
11746
11747     if (compiler->shouldDumpASCIITrees())
11748     {
11749         columnSeparator = "|";
11750         line            = "-";
11751         leftBox         = "+";
11752         middleBox       = "+";
11753         rightBox        = "+";
11754     }
11755     else
11756     {
11757         columnSeparator = "\xe2\x94\x82";
11758         line            = "\xe2\x94\x80";
11759         leftBox         = "\xe2\x94\x9c";
11760         middleBox       = "\xe2\x94\xbc";
11761         rightBox        = "\xe2\x94\xa4";
11762     }
11763     sprintf_s(indentFormat, MAX_FORMAT_CHARS, "%%-%ds", regTableIndent);
11764
11765     // Now, set up the legend format for the RefPosition info
11766     sprintf_s(legendFormat, MAX_LEGEND_FORMAT_CHARS, "%%-%d.%ds%%-%d.%ds%%-%ds%%s", nodeLocationWidth + 1,
11767               nodeLocationWidth + 1, refPositionWidth + 2, refPositionWidth + 2, regColumnWidth + 1);
11768
11769     // Finally, print a "title row" including the legend and the reg names
11770     dumpRegRecordTitle();
11771 }
11772
11773 int LinearScan::getLastUsedRegNumIndex()
11774 {
11775     int       lastUsedRegNumIndex = 0;
11776     regMaskTP usedRegsMask        = compiler->codeGen->regSet.rsGetModifiedRegsMask();
11777     int       lastRegNumIndex     = compiler->compFloatingPointUsed ? REG_FP_LAST : REG_INT_LAST;
11778     for (int regNumIndex = 0; regNumIndex <= lastRegNumIndex; regNumIndex++)
11779     {
11780         if ((usedRegsMask & genRegMask((regNumber)regNumIndex)) != 0)
11781         {
11782             lastUsedRegNumIndex = regNumIndex;
11783         }
11784     }
11785     return lastUsedRegNumIndex;
11786 }
11787
11788 void LinearScan::dumpRegRecordTitleLines()
11789 {
11790     for (int i = 0; i < regTableIndent; i++)
11791     {
11792         printf("%s", line);
11793     }
11794     int lastUsedRegNumIndex = getLastUsedRegNumIndex();
11795     for (int regNumIndex = 0; regNumIndex <= lastUsedRegNumIndex; regNumIndex++)
11796     {
11797         printf("%s", middleBox);
11798         for (int i = 0; i < regColumnWidth; i++)
11799         {
11800             printf("%s", line);
11801         }
11802     }
11803     printf("%s\n", rightBox);
11804 }
11805 void LinearScan::dumpRegRecordTitle()
11806 {
11807     dumpRegRecordTitleLines();
11808
11809     // Print out the legend for the RefPosition info
11810     printf(legendFormat, "Loc ", "RP# ", "Name ", "Type  Action Reg  ");
11811
11812     // Print out the register name column headers
11813     char columnFormatArray[MAX_FORMAT_CHARS];
11814     sprintf_s(columnFormatArray, MAX_FORMAT_CHARS, "%s%%-%d.%ds", columnSeparator, regColumnWidth, regColumnWidth);
11815     int lastUsedRegNumIndex = getLastUsedRegNumIndex();
11816     for (int regNumIndex = 0; regNumIndex <= lastUsedRegNumIndex; regNumIndex++)
11817     {
11818         regNumber   regNum  = (regNumber)regNumIndex;
11819         const char* regName = getRegName(regNum);
11820         printf(columnFormatArray, regName);
11821     }
11822     printf("%s\n", columnSeparator);
11823
11824     rowCountSinceLastTitle = 0;
11825
11826     dumpRegRecordTitleLines();
11827 }
11828
11829 void LinearScan::dumpRegRecords()
11830 {
11831     static char columnFormatArray[18];
11832     int         lastUsedRegNumIndex = getLastUsedRegNumIndex();
11833     regMaskTP   usedRegsMask        = compiler->codeGen->regSet.rsGetModifiedRegsMask();
11834
11835     for (int regNumIndex = 0; regNumIndex <= lastUsedRegNumIndex; regNumIndex++)
11836     {
11837         printf("%s", columnSeparator);
11838         RegRecord& regRecord = physRegs[regNumIndex];
11839         Interval*  interval  = regRecord.assignedInterval;
11840         if (interval != nullptr)
11841         {
11842             dumpIntervalName(interval);
11843             char activeChar = interval->isActive ? 'a' : 'i';
11844             printf("%c", activeChar);
11845         }
11846         else if (regRecord.isBusyUntilNextKill)
11847         {
11848             printf(columnFormatArray, "Busy");
11849         }
11850         else if ((usedRegsMask & genRegMask((regNumber)regNumIndex)) == 0)
11851         {
11852             sprintf_s(columnFormatArray, MAX_FORMAT_CHARS, "%%-%ds", regColumnWidth);
11853             printf(columnFormatArray, "----");
11854         }
11855         else
11856         {
11857             sprintf_s(columnFormatArray, MAX_FORMAT_CHARS, "%%-%ds", regColumnWidth);
11858             printf(columnFormatArray, "");
11859         }
11860     }
11861     printf("%s\n", columnSeparator);
11862
11863     if (rowCountSinceLastTitle > MAX_ROWS_BETWEEN_TITLES)
11864     {
11865         dumpRegRecordTitle();
11866     }
11867     rowCountSinceLastTitle++;
11868 }
11869
11870 void LinearScan::dumpIntervalName(Interval* interval)
11871 {
11872     if (interval->isLocalVar)
11873     {
11874         printf(intervalNameFormat, 'V', interval->varNum);
11875     }
11876     else if (interval->isConstant)
11877     {
11878         printf(intervalNameFormat, 'C', interval->intervalIndex);
11879     }
11880     else
11881     {
11882         printf(intervalNameFormat, 'I', interval->intervalIndex);
11883     }
11884 }
11885
11886 void LinearScan::dumpEmptyRefPosition()
11887 {
11888     printf(emptyRefPositionFormat, "");
11889 }
11890
11891 // Note that the size of this dump is computed in dumpRegRecordHeader().
11892 //
11893 void LinearScan::dumpRefPositionShort(RefPosition* refPosition, BasicBlock* currentBlock)
11894 {
11895     BasicBlock* block = currentBlock;
11896     if (refPosition->refType == RefTypeBB)
11897     {
11898         // Always print a title row before a RefTypeBB (except for the first, because we
11899         // will already have printed it before the parameters)
11900         if (refPosition->refType == RefTypeBB && block != compiler->fgFirstBB && block != nullptr)
11901         {
11902             dumpRegRecordTitle();
11903         }
11904     }
11905     printf(shortRefPositionFormat, refPosition->nodeLocation, refPosition->rpNum);
11906     if (refPosition->refType == RefTypeBB)
11907     {
11908         if (block == nullptr)
11909         {
11910             printf(regNameFormat, "END");
11911             printf("               ");
11912             printf(regNameFormat, "");
11913         }
11914         else
11915         {
11916             printf(bbRefPosFormat, block->bbNum, block == compiler->fgFirstBB ? 0 : blockInfo[block->bbNum].predBBNum);
11917         }
11918     }
11919     else if (refPosition->isIntervalRef())
11920     {
11921         Interval* interval = refPosition->getInterval();
11922         dumpIntervalName(interval);
11923         char lastUseChar = ' ';
11924         char delayChar   = ' ';
11925         if (refPosition->lastUse)
11926         {
11927             lastUseChar = '*';
11928             if (refPosition->delayRegFree)
11929             {
11930                 delayChar = 'D';
11931             }
11932         }
11933         printf("  %s%c%c ", getRefTypeShortName(refPosition->refType), lastUseChar, delayChar);
11934     }
11935     else if (refPosition->isPhysRegRef)
11936     {
11937         RegRecord* regRecord = refPosition->getReg();
11938         printf(regNameFormat, getRegName(regRecord->regNum));
11939         printf(" %s   ", getRefTypeShortName(refPosition->refType));
11940     }
11941     else
11942     {
11943         assert(refPosition->refType == RefTypeKillGCRefs);
11944         // There's no interval or reg name associated with this.
11945         printf(regNameFormat, "   ");
11946         printf(" %s   ", getRefTypeShortName(refPosition->refType));
11947     }
11948 }
11949
11950 //------------------------------------------------------------------------
11951 // LinearScan::IsResolutionMove:
11952 //     Returns true if the given node is a move inserted by LSRA
11953 //     resolution.
11954 //
11955 // Arguments:
11956 //     node - the node to check.
11957 //
11958 bool LinearScan::IsResolutionMove(GenTree* node)
11959 {
11960     if (!node->gtLsraInfo.isLsraAdded)
11961     {
11962         return false;
11963     }
11964
11965     switch (node->OperGet())
11966     {
11967         case GT_LCL_VAR:
11968         case GT_COPY:
11969             return node->gtLsraInfo.isLocalDefUse;
11970
11971         case GT_SWAP:
11972             return true;
11973
11974         default:
11975             return false;
11976     }
11977 }
11978
11979 //------------------------------------------------------------------------
11980 // LinearScan::IsResolutionNode:
11981 //     Returns true if the given node is either a move inserted by LSRA
11982 //     resolution or an operand to such a move.
11983 //
11984 // Arguments:
11985 //     containingRange - the range that contains the node to check.
11986 //     node - the node to check.
11987 //
11988 bool LinearScan::IsResolutionNode(LIR::Range& containingRange, GenTree* node)
11989 {
11990     for (;;)
11991     {
11992         if (IsResolutionMove(node))
11993         {
11994             return true;
11995         }
11996
11997         if (!node->gtLsraInfo.isLsraAdded || (node->OperGet() != GT_LCL_VAR))
11998         {
11999             return false;
12000         }
12001
12002         LIR::Use use;
12003         bool     foundUse = containingRange.TryGetUse(node, &use);
12004         assert(foundUse);
12005
12006         node = use.User();
12007     }
12008 }
12009
12010 //------------------------------------------------------------------------
12011 // verifyFinalAllocation: Traverse the RefPositions and verify various invariants.
12012 //
12013 // Arguments:
12014 //    None.
12015 //
12016 // Return Value:
12017 //    None.
12018 //
12019 // Notes:
12020 //    If verbose is set, this will also dump a table of the final allocations.
12021 void LinearScan::verifyFinalAllocation()
12022 {
12023     if (VERBOSE)
12024     {
12025         printf("\nFinal allocation\n");
12026     }
12027
12028     // Clear register assignments.
12029     for (regNumber reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
12030     {
12031         RegRecord* physRegRecord        = getRegisterRecord(reg);
12032         physRegRecord->assignedInterval = nullptr;
12033     }
12034
12035     for (auto& interval : intervals)
12036     {
12037         interval.assignedReg = nullptr;
12038         interval.physReg     = REG_NA;
12039     }
12040
12041     DBEXEC(VERBOSE, dumpRegRecordTitle());
12042
12043     BasicBlock*  currentBlock                = nullptr;
12044     GenTree*     firstBlockEndResolutionNode = nullptr;
12045     regMaskTP    regsToFree                  = RBM_NONE;
12046     regMaskTP    delayRegsToFree             = RBM_NONE;
12047     LsraLocation currentLocation             = MinLocation;
12048     for (auto& refPosition : refPositions)
12049     {
12050         RefPosition* currentRefPosition = &refPosition;
12051         Interval*    interval           = nullptr;
12052         RegRecord*   regRecord          = nullptr;
12053         regNumber    regNum             = REG_NA;
12054         if (currentRefPosition->refType == RefTypeBB)
12055         {
12056             regsToFree |= delayRegsToFree;
12057             delayRegsToFree = RBM_NONE;
12058             // For BB RefPositions, wait until we dump the "end of block" info before dumping the basic RefPosition
12059             // info.
12060         }
12061         else
12062         {
12063             // For other RefPosition types, we can dump the basic RefPosition info now.
12064             DBEXEC(VERBOSE, dumpRefPositionShort(currentRefPosition, currentBlock));
12065
12066             if (currentRefPosition->isPhysRegRef)
12067             {
12068                 regRecord                    = currentRefPosition->getReg();
12069                 regRecord->recentRefPosition = currentRefPosition;
12070                 regNum                       = regRecord->regNum;
12071             }
12072             else if (currentRefPosition->isIntervalRef())
12073             {
12074                 interval                    = currentRefPosition->getInterval();
12075                 interval->recentRefPosition = currentRefPosition;
12076                 if (currentRefPosition->registerAssignment != RBM_NONE)
12077                 {
12078                     if (!genMaxOneBit(currentRefPosition->registerAssignment))
12079                     {
12080                         assert(currentRefPosition->refType == RefTypeExpUse ||
12081                                currentRefPosition->refType == RefTypeDummyDef);
12082                     }
12083                     else
12084                     {
12085                         regNum    = currentRefPosition->assignedReg();
12086                         regRecord = getRegisterRecord(regNum);
12087                     }
12088                 }
12089             }
12090         }
12091
12092         LsraLocation newLocation = currentRefPosition->nodeLocation;
12093
12094         if (newLocation > currentLocation)
12095         {
12096             // Free Registers.
12097             // We could use the freeRegisters() method, but we'd have to carefully manage the active intervals.
12098             for (regNumber reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
12099             {
12100                 regMaskTP regMask = genRegMask(reg);
12101                 if ((regsToFree & regMask) != RBM_NONE)
12102                 {
12103                     RegRecord* physRegRecord        = getRegisterRecord(reg);
12104                     physRegRecord->assignedInterval = nullptr;
12105                 }
12106             }
12107             regsToFree = delayRegsToFree;
12108             regsToFree = RBM_NONE;
12109         }
12110         currentLocation = newLocation;
12111
12112         switch (currentRefPosition->refType)
12113         {
12114             case RefTypeBB:
12115             {
12116                 if (currentBlock == nullptr)
12117                 {
12118                     currentBlock = startBlockSequence();
12119                 }
12120                 else
12121                 {
12122                     // Verify the resolution moves at the end of the previous block.
12123                     for (GenTree* node = firstBlockEndResolutionNode; node != nullptr; node = node->gtNext)
12124                     {
12125                         assert(enregisterLocalVars);
12126                         // Only verify nodes that are actually moves; don't bother with the nodes that are
12127                         // operands to moves.
12128                         if (IsResolutionMove(node))
12129                         {
12130                             verifyResolutionMove(node, currentLocation);
12131                         }
12132                     }
12133
12134                     // Validate the locations at the end of the previous block.
12135                     if (enregisterLocalVars)
12136                     {
12137                         VarToRegMap     outVarToRegMap = outVarToRegMaps[currentBlock->bbNum];
12138                         VarSetOps::Iter iter(compiler, currentBlock->bbLiveOut);
12139                         unsigned        varIndex = 0;
12140                         while (iter.NextElem(&varIndex))
12141                         {
12142                             if (localVarIntervals[varIndex] == nullptr)
12143                             {
12144                                 assert(!compiler->lvaTable[compiler->lvaTrackedToVarNum[varIndex]].lvLRACandidate);
12145                                 continue;
12146                             }
12147                             regNumber regNum = getVarReg(outVarToRegMap, varIndex);
12148                             interval         = getIntervalForLocalVar(varIndex);
12149                             assert(interval->physReg == regNum || (interval->physReg == REG_NA && regNum == REG_STK));
12150                             interval->physReg     = REG_NA;
12151                             interval->assignedReg = nullptr;
12152                             interval->isActive    = false;
12153                         }
12154                     }
12155
12156                     // Clear register assignments.
12157                     for (regNumber reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
12158                     {
12159                         RegRecord* physRegRecord        = getRegisterRecord(reg);
12160                         physRegRecord->assignedInterval = nullptr;
12161                     }
12162
12163                     // Now, record the locations at the beginning of this block.
12164                     currentBlock = moveToNextBlock();
12165                 }
12166
12167                 if (currentBlock != nullptr)
12168                 {
12169                     if (enregisterLocalVars)
12170                     {
12171                         VarToRegMap     inVarToRegMap = inVarToRegMaps[currentBlock->bbNum];
12172                         VarSetOps::Iter iter(compiler, currentBlock->bbLiveIn);
12173                         unsigned        varIndex = 0;
12174                         while (iter.NextElem(&varIndex))
12175                         {
12176                             if (localVarIntervals[varIndex] == nullptr)
12177                             {
12178                                 assert(!compiler->lvaTable[compiler->lvaTrackedToVarNum[varIndex]].lvLRACandidate);
12179                                 continue;
12180                             }
12181                             regNumber regNum                  = getVarReg(inVarToRegMap, varIndex);
12182                             interval                          = getIntervalForLocalVar(varIndex);
12183                             interval->physReg                 = regNum;
12184                             interval->assignedReg             = &(physRegs[regNum]);
12185                             interval->isActive                = true;
12186                             physRegs[regNum].assignedInterval = interval;
12187                         }
12188                     }
12189
12190                     if (VERBOSE)
12191                     {
12192                         dumpRefPositionShort(currentRefPosition, currentBlock);
12193                         dumpRegRecords();
12194                     }
12195
12196                     // Finally, handle the resolution moves, if any, at the beginning of the next block.
12197                     firstBlockEndResolutionNode = nullptr;
12198                     bool foundNonResolutionNode = false;
12199
12200                     LIR::Range& currentBlockRange = LIR::AsRange(currentBlock);
12201                     for (GenTree* node : currentBlockRange.NonPhiNodes())
12202                     {
12203                         if (IsResolutionNode(currentBlockRange, node))
12204                         {
12205                             assert(enregisterLocalVars);
12206                             if (foundNonResolutionNode)
12207                             {
12208                                 firstBlockEndResolutionNode = node;
12209                                 break;
12210                             }
12211                             else if (IsResolutionMove(node))
12212                             {
12213                                 // Only verify nodes that are actually moves; don't bother with the nodes that are
12214                                 // operands to moves.
12215                                 verifyResolutionMove(node, currentLocation);
12216                             }
12217                         }
12218                         else
12219                         {
12220                             foundNonResolutionNode = true;
12221                         }
12222                     }
12223                 }
12224             }
12225
12226             break;
12227
12228             case RefTypeKill:
12229                 assert(regRecord != nullptr);
12230                 assert(regRecord->assignedInterval == nullptr);
12231                 dumpLsraAllocationEvent(LSRA_EVENT_KEPT_ALLOCATION, nullptr, regRecord->regNum, currentBlock);
12232                 break;
12233             case RefTypeFixedReg:
12234                 assert(regRecord != nullptr);
12235                 dumpLsraAllocationEvent(LSRA_EVENT_KEPT_ALLOCATION, nullptr, regRecord->regNum, currentBlock);
12236                 break;
12237
12238             case RefTypeUpperVectorSaveDef:
12239             case RefTypeUpperVectorSaveUse:
12240             case RefTypeDef:
12241             case RefTypeUse:
12242             case RefTypeParamDef:
12243             case RefTypeZeroInit:
12244                 assert(interval != nullptr);
12245
12246                 if (interval->isSpecialPutArg)
12247                 {
12248                     dumpLsraAllocationEvent(LSRA_EVENT_SPECIAL_PUTARG, interval, regNum);
12249                     break;
12250                 }
12251                 if (currentRefPosition->reload)
12252                 {
12253                     interval->isActive = true;
12254                     assert(regNum != REG_NA);
12255                     interval->physReg           = regNum;
12256                     interval->assignedReg       = regRecord;
12257                     regRecord->assignedInterval = interval;
12258                     dumpLsraAllocationEvent(LSRA_EVENT_RELOAD, nullptr, regRecord->regNum, currentBlock);
12259                 }
12260                 if (regNum == REG_NA)
12261                 {
12262                     dumpLsraAllocationEvent(LSRA_EVENT_NO_REG_ALLOCATED, interval);
12263                 }
12264                 else if (RefTypeIsDef(currentRefPosition->refType))
12265                 {
12266                     interval->isActive = true;
12267                     if (VERBOSE)
12268                     {
12269                         if (interval->isConstant && (currentRefPosition->treeNode != nullptr) &&
12270                             currentRefPosition->treeNode->IsReuseRegVal())
12271                         {
12272                             dumpLsraAllocationEvent(LSRA_EVENT_REUSE_REG, nullptr, regRecord->regNum, currentBlock);
12273                         }
12274                         else
12275                         {
12276                             dumpLsraAllocationEvent(LSRA_EVENT_ALLOC_REG, nullptr, regRecord->regNum, currentBlock);
12277                         }
12278                     }
12279                 }
12280                 else if (currentRefPosition->copyReg)
12281                 {
12282                     dumpLsraAllocationEvent(LSRA_EVENT_COPY_REG, interval, regRecord->regNum, currentBlock);
12283                 }
12284                 else if (currentRefPosition->moveReg)
12285                 {
12286                     assert(interval->assignedReg != nullptr);
12287                     interval->assignedReg->assignedInterval = nullptr;
12288                     interval->physReg                       = regNum;
12289                     interval->assignedReg                   = regRecord;
12290                     regRecord->assignedInterval             = interval;
12291                     if (VERBOSE)
12292                     {
12293                         printf("Move  %-4s ", getRegName(regRecord->regNum));
12294                     }
12295                 }
12296                 else
12297                 {
12298                     dumpLsraAllocationEvent(LSRA_EVENT_KEPT_ALLOCATION, nullptr, regRecord->regNum, currentBlock);
12299                 }
12300                 if (currentRefPosition->lastUse || currentRefPosition->spillAfter)
12301                 {
12302                     interval->isActive = false;
12303                 }
12304                 if (regNum != REG_NA)
12305                 {
12306                     if (currentRefPosition->spillAfter)
12307                     {
12308                         if (VERBOSE)
12309                         {
12310                             // If refPos is marked as copyReg, then the reg that is spilled
12311                             // is the homeReg of the interval not the reg currently assigned
12312                             // to refPos.
12313                             regNumber spillReg = regNum;
12314                             if (currentRefPosition->copyReg)
12315                             {
12316                                 assert(interval != nullptr);
12317                                 spillReg = interval->physReg;
12318                             }
12319                             dumpRegRecords();
12320                             dumpEmptyRefPosition();
12321                             printf("Spill %-4s ", getRegName(spillReg));
12322                         }
12323                     }
12324                     else if (currentRefPosition->copyReg)
12325                     {
12326                         regRecord->assignedInterval = interval;
12327                     }
12328                     else
12329                     {
12330                         interval->physReg           = regNum;
12331                         interval->assignedReg       = regRecord;
12332                         regRecord->assignedInterval = interval;
12333                     }
12334                 }
12335                 break;
12336             case RefTypeKillGCRefs:
12337                 // No action to take.
12338                 // However, we will assert that, at resolution time, no registers contain GC refs.
12339                 {
12340                     DBEXEC(VERBOSE, printf("           "));
12341                     regMaskTP candidateRegs = currentRefPosition->registerAssignment;
12342                     while (candidateRegs != RBM_NONE)
12343                     {
12344                         regMaskTP nextRegBit = genFindLowestBit(candidateRegs);
12345                         candidateRegs &= ~nextRegBit;
12346                         regNumber  nextReg          = genRegNumFromMask(nextRegBit);
12347                         RegRecord* regRecord        = getRegisterRecord(nextReg);
12348                         Interval*  assignedInterval = regRecord->assignedInterval;
12349                         assert(assignedInterval == nullptr || !varTypeIsGC(assignedInterval->registerType));
12350                     }
12351                 }
12352                 break;
12353
12354             case RefTypeExpUse:
12355             case RefTypeDummyDef:
12356                 // Do nothing; these will be handled by the RefTypeBB.
12357                 DBEXEC(VERBOSE, printf("           "));
12358                 break;
12359
12360             case RefTypeInvalid:
12361                 // for these 'currentRefPosition->refType' values, No action to take
12362                 break;
12363         }
12364
12365         if (currentRefPosition->refType != RefTypeBB)
12366         {
12367             DBEXEC(VERBOSE, dumpRegRecords());
12368             if (interval != nullptr)
12369             {
12370                 if (currentRefPosition->copyReg)
12371                 {
12372                     assert(interval->physReg != regNum);
12373                     regRecord->assignedInterval = nullptr;
12374                     assert(interval->assignedReg != nullptr);
12375                     regRecord = interval->assignedReg;
12376                 }
12377                 if (currentRefPosition->spillAfter || currentRefPosition->lastUse)
12378                 {
12379                     interval->physReg     = REG_NA;
12380                     interval->assignedReg = nullptr;
12381
12382                     // regRegcord could be null if the RefPosition does not require a register.
12383                     if (regRecord != nullptr)
12384                     {
12385                         regRecord->assignedInterval = nullptr;
12386                     }
12387                     else
12388                     {
12389                         assert(!currentRefPosition->RequiresRegister());
12390                     }
12391                 }
12392             }
12393         }
12394     }
12395
12396     // Now, verify the resolution blocks.
12397     // Currently these are nearly always at the end of the method, but that may not alwyas be the case.
12398     // So, we'll go through all the BBs looking for blocks whose bbNum is greater than bbNumMaxBeforeResolution.
12399     for (BasicBlock* currentBlock = compiler->fgFirstBB; currentBlock != nullptr; currentBlock = currentBlock->bbNext)
12400     {
12401         if (currentBlock->bbNum > bbNumMaxBeforeResolution)
12402         {
12403             // If we haven't enregistered an lclVars, we have no resolution blocks.
12404             assert(enregisterLocalVars);
12405
12406             if (VERBOSE)
12407             {
12408                 dumpRegRecordTitle();
12409                 printf(shortRefPositionFormat, 0, 0);
12410                 assert(currentBlock->bbPreds != nullptr && currentBlock->bbPreds->flBlock != nullptr);
12411                 printf(bbRefPosFormat, currentBlock->bbNum, currentBlock->bbPreds->flBlock->bbNum);
12412                 dumpRegRecords();
12413             }
12414
12415             // Clear register assignments.
12416             for (regNumber reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
12417             {
12418                 RegRecord* physRegRecord        = getRegisterRecord(reg);
12419                 physRegRecord->assignedInterval = nullptr;
12420             }
12421
12422             // Set the incoming register assignments
12423             VarToRegMap     inVarToRegMap = getInVarToRegMap(currentBlock->bbNum);
12424             VarSetOps::Iter iter(compiler, currentBlock->bbLiveIn);
12425             unsigned        varIndex = 0;
12426             while (iter.NextElem(&varIndex))
12427             {
12428                 if (localVarIntervals[varIndex] == nullptr)
12429                 {
12430                     assert(!compiler->lvaTable[compiler->lvaTrackedToVarNum[varIndex]].lvLRACandidate);
12431                     continue;
12432                 }
12433                 regNumber regNum                  = getVarReg(inVarToRegMap, varIndex);
12434                 Interval* interval                = getIntervalForLocalVar(varIndex);
12435                 interval->physReg                 = regNum;
12436                 interval->assignedReg             = &(physRegs[regNum]);
12437                 interval->isActive                = true;
12438                 physRegs[regNum].assignedInterval = interval;
12439             }
12440
12441             // Verify the moves in this block
12442             LIR::Range& currentBlockRange = LIR::AsRange(currentBlock);
12443             for (GenTree* node : currentBlockRange.NonPhiNodes())
12444             {
12445                 assert(IsResolutionNode(currentBlockRange, node));
12446                 if (IsResolutionMove(node))
12447                 {
12448                     // Only verify nodes that are actually moves; don't bother with the nodes that are
12449                     // operands to moves.
12450                     verifyResolutionMove(node, currentLocation);
12451                 }
12452             }
12453
12454             // Verify the outgoing register assignments
12455             {
12456                 VarToRegMap     outVarToRegMap = getOutVarToRegMap(currentBlock->bbNum);
12457                 VarSetOps::Iter iter(compiler, currentBlock->bbLiveOut);
12458                 unsigned        varIndex = 0;
12459                 while (iter.NextElem(&varIndex))
12460                 {
12461                     if (localVarIntervals[varIndex] == nullptr)
12462                     {
12463                         assert(!compiler->lvaTable[compiler->lvaTrackedToVarNum[varIndex]].lvLRACandidate);
12464                         continue;
12465                     }
12466                     regNumber regNum   = getVarReg(outVarToRegMap, varIndex);
12467                     Interval* interval = getIntervalForLocalVar(varIndex);
12468                     assert(interval->physReg == regNum || (interval->physReg == REG_NA && regNum == REG_STK));
12469                     interval->physReg     = REG_NA;
12470                     interval->assignedReg = nullptr;
12471                     interval->isActive    = false;
12472                 }
12473             }
12474         }
12475     }
12476
12477     DBEXEC(VERBOSE, printf("\n"));
12478 }
12479
12480 //------------------------------------------------------------------------
12481 // verifyResolutionMove: Verify a resolution statement.  Called by verifyFinalAllocation()
12482 //
12483 // Arguments:
12484 //    resolutionMove    - A GenTree* that must be a resolution move.
12485 //    currentLocation   - The LsraLocation of the most recent RefPosition that has been verified.
12486 //
12487 // Return Value:
12488 //    None.
12489 //
12490 // Notes:
12491 //    If verbose is set, this will also dump the moves into the table of final allocations.
12492 void LinearScan::verifyResolutionMove(GenTree* resolutionMove, LsraLocation currentLocation)
12493 {
12494     GenTree* dst = resolutionMove;
12495     assert(IsResolutionMove(dst));
12496
12497     if (dst->OperGet() == GT_SWAP)
12498     {
12499         GenTreeLclVarCommon* left          = dst->gtGetOp1()->AsLclVarCommon();
12500         GenTreeLclVarCommon* right         = dst->gtGetOp2()->AsLclVarCommon();
12501         regNumber            leftRegNum    = left->gtRegNum;
12502         regNumber            rightRegNum   = right->gtRegNum;
12503         LclVarDsc*           leftVarDsc    = compiler->lvaTable + left->gtLclNum;
12504         LclVarDsc*           rightVarDsc   = compiler->lvaTable + right->gtLclNum;
12505         Interval*            leftInterval  = getIntervalForLocalVar(leftVarDsc->lvVarIndex);
12506         Interval*            rightInterval = getIntervalForLocalVar(rightVarDsc->lvVarIndex);
12507         assert(leftInterval->physReg == leftRegNum && rightInterval->physReg == rightRegNum);
12508         leftInterval->physReg                  = rightRegNum;
12509         rightInterval->physReg                 = leftRegNum;
12510         leftInterval->assignedReg              = &physRegs[rightRegNum];
12511         rightInterval->assignedReg             = &physRegs[leftRegNum];
12512         physRegs[rightRegNum].assignedInterval = leftInterval;
12513         physRegs[leftRegNum].assignedInterval  = rightInterval;
12514         if (VERBOSE)
12515         {
12516             printf(shortRefPositionFormat, currentLocation, 0);
12517             dumpIntervalName(leftInterval);
12518             printf("  Swap   ");
12519             printf("      %-4s ", getRegName(rightRegNum));
12520             dumpRegRecords();
12521             printf(shortRefPositionFormat, currentLocation, 0);
12522             dumpIntervalName(rightInterval);
12523             printf("  \"      ");
12524             printf("      %-4s ", getRegName(leftRegNum));
12525             dumpRegRecords();
12526         }
12527         return;
12528     }
12529     regNumber            dstRegNum = dst->gtRegNum;
12530     regNumber            srcRegNum;
12531     GenTreeLclVarCommon* lcl;
12532     if (dst->OperGet() == GT_COPY)
12533     {
12534         lcl       = dst->gtGetOp1()->AsLclVarCommon();
12535         srcRegNum = lcl->gtRegNum;
12536     }
12537     else
12538     {
12539         lcl = dst->AsLclVarCommon();
12540         if ((lcl->gtFlags & GTF_SPILLED) != 0)
12541         {
12542             srcRegNum = REG_STK;
12543         }
12544         else
12545         {
12546             assert((lcl->gtFlags & GTF_SPILL) != 0);
12547             srcRegNum = dstRegNum;
12548             dstRegNum = REG_STK;
12549         }
12550     }
12551
12552     Interval* interval = getIntervalForLocalVarNode(lcl);
12553     assert(interval->physReg == srcRegNum || (srcRegNum == REG_STK && interval->physReg == REG_NA));
12554     if (srcRegNum != REG_STK)
12555     {
12556         physRegs[srcRegNum].assignedInterval = nullptr;
12557     }
12558     if (dstRegNum != REG_STK)
12559     {
12560         interval->physReg                    = dstRegNum;
12561         interval->assignedReg                = &(physRegs[dstRegNum]);
12562         physRegs[dstRegNum].assignedInterval = interval;
12563         interval->isActive                   = true;
12564     }
12565     else
12566     {
12567         interval->physReg     = REG_NA;
12568         interval->assignedReg = nullptr;
12569         interval->isActive    = false;
12570     }
12571     if (VERBOSE)
12572     {
12573         printf(shortRefPositionFormat, currentLocation, 0);
12574         dumpIntervalName(interval);
12575         printf("  Move   ");
12576         printf("      %-4s ", getRegName(dstRegNum));
12577         dumpRegRecords();
12578     }
12579 }
12580 #endif // DEBUG
12581
12582 #endif // !LEGACY_BACKEND