Merge pull request #12755 from tannergooding/classify
[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->IsUnusedValue() || node->gtLsraInfo.isLocalDefUse);
4718
4719             currentLoc = node->gtLsraInfo.loc;
4720             buildRefPositionsForNode(node, block, listNodePool, operandToLocationInfoMap, currentLoc);
4721
4722 #ifdef DEBUG
4723             if (currentLoc > maxNodeLocation)
4724             {
4725                 maxNodeLocation = currentLoc;
4726             }
4727 #endif // DEBUG
4728         }
4729
4730         // Increment the LsraLocation at this point, so that the dummy RefPositions
4731         // will not have the same LsraLocation as any "real" RefPosition.
4732         currentLoc += 2;
4733
4734         // Note: the visited set is cleared in LinearScan::doLinearScan()
4735         markBlockVisited(block);
4736
4737         if (enregisterLocalVars)
4738         {
4739             // Insert exposed uses for a lclVar that is live-out of 'block' but not live-in to the
4740             // next block, or any unvisited successors.
4741             // This will address lclVars that are live on a backedge, as well as those that are kept
4742             // live at a GT_JMP.
4743             //
4744             // Blocks ending with "jmp method" are marked as BBJ_HAS_JMP,
4745             // and jmp call is represented using GT_JMP node which is a leaf node.
4746             // Liveness phase keeps all the arguments of the method live till the end of
4747             // block by adding them to liveout set of the block containing GT_JMP.
4748             //
4749             // The target of a GT_JMP implicitly uses all the current method arguments, however
4750             // there are no actual references to them.  This can cause LSRA to assert, because
4751             // the variables are live but it sees no references.  In order to correctly model the
4752             // liveness of these arguments, we add dummy exposed uses, in the same manner as for
4753             // backward branches.  This will happen automatically via expUseSet.
4754             //
4755             // Note that a block ending with GT_JMP has no successors and hence the variables
4756             // for which dummy use ref positions are added are arguments of the method.
4757
4758             VARSET_TP expUseSet(VarSetOps::MakeCopy(compiler, block->bbLiveOut));
4759             VarSetOps::IntersectionD(compiler, expUseSet, registerCandidateVars);
4760             BasicBlock* nextBlock = getNextBlock();
4761             if (nextBlock != nullptr)
4762             {
4763                 VarSetOps::DiffD(compiler, expUseSet, nextBlock->bbLiveIn);
4764             }
4765             for (BasicBlock* succ : block->GetAllSuccs(compiler))
4766             {
4767                 if (VarSetOps::IsEmpty(compiler, expUseSet))
4768                 {
4769                     break;
4770                 }
4771
4772                 if (isBlockVisited(succ))
4773                 {
4774                     continue;
4775                 }
4776                 VarSetOps::DiffD(compiler, expUseSet, succ->bbLiveIn);
4777             }
4778
4779             if (!VarSetOps::IsEmpty(compiler, expUseSet))
4780             {
4781                 JITDUMP("Exposed uses:");
4782                 VarSetOps::Iter iter(compiler, expUseSet);
4783                 unsigned        varIndex = 0;
4784                 while (iter.NextElem(&varIndex))
4785                 {
4786                     unsigned   varNum = compiler->lvaTrackedToVarNum[varIndex];
4787                     LclVarDsc* varDsc = compiler->lvaTable + varNum;
4788                     assert(isCandidateVar(varDsc));
4789                     Interval*    interval = getIntervalForLocalVar(varIndex);
4790                     RefPosition* pos =
4791                         newRefPosition(interval, currentLoc, RefTypeExpUse, nullptr, allRegs(interval->registerType));
4792                     JITDUMP(" V%02u", varNum);
4793                 }
4794                 JITDUMP("\n");
4795             }
4796
4797             // Clear the "last use" flag on any vars that are live-out from this block.
4798             {
4799                 VarSetOps::Iter iter(compiler, block->bbLiveOut);
4800                 unsigned        varIndex = 0;
4801                 while (iter.NextElem(&varIndex))
4802                 {
4803                     unsigned         varNum = compiler->lvaTrackedToVarNum[varIndex];
4804                     LclVarDsc* const varDsc = &compiler->lvaTable[varNum];
4805                     if (isCandidateVar(varDsc))
4806                     {
4807                         RefPosition* const lastRP = getIntervalForLocalVar(varIndex)->lastRefPosition;
4808                         if ((lastRP != nullptr) && (lastRP->bbNum == block->bbNum))
4809                         {
4810                             lastRP->lastUse = false;
4811                         }
4812                     }
4813                 }
4814             }
4815
4816 #ifdef DEBUG
4817             checkLastUses(block);
4818
4819             if (VERBOSE)
4820             {
4821                 printf("use: ");
4822                 dumpConvertedVarSet(compiler, block->bbVarUse);
4823                 printf("\ndef: ");
4824                 dumpConvertedVarSet(compiler, block->bbVarDef);
4825                 printf("\n");
4826             }
4827 #endif // DEBUG
4828         }
4829
4830         prevBlock = block;
4831     }
4832
4833     if (enregisterLocalVars)
4834     {
4835         if (compiler->lvaKeepAliveAndReportThis())
4836         {
4837             // If we need to KeepAliveAndReportThis, add a dummy exposed use of it at the end
4838             unsigned keepAliveVarNum = compiler->info.compThisArg;
4839             assert(compiler->info.compIsStatic == false);
4840             LclVarDsc* varDsc = compiler->lvaTable + keepAliveVarNum;
4841             if (isCandidateVar(varDsc))
4842             {
4843                 JITDUMP("Adding exposed use of this, for lvaKeepAliveAndReportThis\n");
4844                 Interval*    interval = getIntervalForLocalVar(varDsc->lvVarIndex);
4845                 RefPosition* pos =
4846                     newRefPosition(interval, currentLoc, RefTypeExpUse, nullptr, allRegs(interval->registerType));
4847             }
4848         }
4849
4850 #ifdef DEBUG
4851         if (getLsraExtendLifeTimes())
4852         {
4853             LclVarDsc* varDsc;
4854             for (lclNum = 0, varDsc = compiler->lvaTable; lclNum < compiler->lvaCount; lclNum++, varDsc++)
4855             {
4856                 if (varDsc->lvLRACandidate)
4857                 {
4858                     JITDUMP("Adding exposed use of V%02u for LsraExtendLifetimes\n", lclNum);
4859                     Interval*    interval = getIntervalForLocalVar(varDsc->lvVarIndex);
4860                     RefPosition* pos =
4861                         newRefPosition(interval, currentLoc, RefTypeExpUse, nullptr, allRegs(interval->registerType));
4862                 }
4863             }
4864         }
4865 #endif // DEBUG
4866     }
4867
4868     // If the last block has successors, create a RefTypeBB to record
4869     // what's live
4870
4871     if (prevBlock->NumSucc(compiler) > 0)
4872     {
4873         RefPosition* pos = newRefPosition((Interval*)nullptr, currentLoc, RefTypeBB, nullptr, RBM_NONE);
4874     }
4875
4876 #ifdef DEBUG
4877     // Make sure we don't have any blocks that were not visited
4878     foreach_block(compiler, block)
4879     {
4880         assert(isBlockVisited(block));
4881     }
4882
4883     if (VERBOSE)
4884     {
4885         lsraDumpIntervals("BEFORE VALIDATING INTERVALS");
4886         dumpRefPositions("BEFORE VALIDATING INTERVALS");
4887         validateIntervals();
4888     }
4889 #endif // DEBUG
4890 }
4891
4892 #ifdef DEBUG
4893 void LinearScan::dumpVarRefPositions(const char* title)
4894 {
4895     if (enregisterLocalVars)
4896     {
4897         printf("\nVAR REFPOSITIONS %s\n", title);
4898
4899         for (unsigned i = 0; i < compiler->lvaCount; i++)
4900         {
4901             printf("--- V%02u\n", i);
4902
4903             LclVarDsc* varDsc = compiler->lvaTable + i;
4904             if (varDsc->lvIsRegCandidate())
4905             {
4906                 Interval* interval = getIntervalForLocalVar(varDsc->lvVarIndex);
4907                 for (RefPosition* ref = interval->firstRefPosition; ref != nullptr; ref = ref->nextRefPosition)
4908                 {
4909                     ref->dump();
4910                 }
4911             }
4912         }
4913         printf("\n");
4914     }
4915 }
4916
4917 void LinearScan::validateIntervals()
4918 {
4919     if (enregisterLocalVars)
4920     {
4921         for (unsigned i = 0; i < compiler->lvaTrackedCount; i++)
4922         {
4923             if (!compiler->lvaTable[compiler->lvaTrackedToVarNum[i]].lvLRACandidate)
4924             {
4925                 continue;
4926             }
4927             Interval* interval = getIntervalForLocalVar(i);
4928
4929             bool defined = false;
4930             printf("-----------------\n");
4931             for (RefPosition* ref = interval->firstRefPosition; ref != nullptr; ref = ref->nextRefPosition)
4932             {
4933                 ref->dump();
4934                 RefType refType = ref->refType;
4935                 if (!defined && RefTypeIsUse(refType))
4936                 {
4937                     if (compiler->info.compMethodName != nullptr)
4938                     {
4939                         printf("%s: ", compiler->info.compMethodName);
4940                     }
4941                     printf("LocalVar V%02u: undefined use at %u\n", interval->varNum, ref->nodeLocation);
4942                 }
4943                 // Note that there can be multiple last uses if they are on disjoint paths,
4944                 // so we can't really check the lastUse flag
4945                 if (ref->lastUse)
4946                 {
4947                     defined = false;
4948                 }
4949                 if (RefTypeIsDef(refType))
4950                 {
4951                     defined = true;
4952                 }
4953             }
4954         }
4955     }
4956 }
4957 #endif // DEBUG
4958
4959 // Set the default rpFrameType based upon codeGen->isFramePointerRequired()
4960 // This was lifted from the register predictor
4961 //
4962 void LinearScan::setFrameType()
4963 {
4964     FrameType frameType = FT_NOT_SET;
4965 #if DOUBLE_ALIGN
4966     compiler->codeGen->setDoubleAlign(false);
4967     if (doDoubleAlign)
4968     {
4969         frameType = FT_DOUBLE_ALIGN_FRAME;
4970         compiler->codeGen->setDoubleAlign(true);
4971     }
4972     else
4973 #endif // DOUBLE_ALIGN
4974         if (compiler->codeGen->isFramePointerRequired())
4975     {
4976         frameType = FT_EBP_FRAME;
4977     }
4978     else
4979     {
4980         if (compiler->rpMustCreateEBPCalled == false)
4981         {
4982 #ifdef DEBUG
4983             const char* reason;
4984 #endif // DEBUG
4985             compiler->rpMustCreateEBPCalled = true;
4986             if (compiler->rpMustCreateEBPFrame(INDEBUG(&reason)))
4987             {
4988                 JITDUMP("; Decided to create an EBP based frame for ETW stackwalking (%s)\n", reason);
4989                 compiler->codeGen->setFrameRequired(true);
4990             }
4991         }
4992
4993         if (compiler->codeGen->isFrameRequired())
4994         {
4995             frameType = FT_EBP_FRAME;
4996         }
4997         else
4998         {
4999             frameType = FT_ESP_FRAME;
5000         }
5001     }
5002
5003     switch (frameType)
5004     {
5005         case FT_ESP_FRAME:
5006             noway_assert(!compiler->codeGen->isFramePointerRequired());
5007             noway_assert(!compiler->codeGen->isFrameRequired());
5008             compiler->codeGen->setFramePointerUsed(false);
5009             break;
5010         case FT_EBP_FRAME:
5011             compiler->codeGen->setFramePointerUsed(true);
5012             break;
5013 #if DOUBLE_ALIGN
5014         case FT_DOUBLE_ALIGN_FRAME:
5015             noway_assert(!compiler->codeGen->isFramePointerRequired());
5016             compiler->codeGen->setFramePointerUsed(false);
5017             break;
5018 #endif // DOUBLE_ALIGN
5019         default:
5020             noway_assert(!"rpFrameType not set correctly!");
5021             break;
5022     }
5023
5024     // If we are using FPBASE as the frame register, we cannot also use it for
5025     // a local var. Note that we may have already added it to the register masks,
5026     // which are computed when the LinearScan class constructor is created, and
5027     // used during lowering. Luckily, the TreeNodeInfo only stores an index to
5028     // the masks stored in the LinearScan class, so we only need to walk the
5029     // unique masks and remove FPBASE.
5030     if (frameType == FT_EBP_FRAME)
5031     {
5032         if ((availableIntRegs & RBM_FPBASE) != 0)
5033         {
5034             RemoveRegisterFromMasks(REG_FPBASE);
5035
5036             // We know that we're already in "read mode" for availableIntRegs. However,
5037             // we need to remove the FPBASE register, so subsequent users (like callers
5038             // to allRegs()) get the right thing. The RemoveRegisterFromMasks() code
5039             // fixes up everything that already took a dependency on the value that was
5040             // previously read, so this completes the picture.
5041             availableIntRegs.OverrideAssign(availableIntRegs & ~RBM_FPBASE);
5042         }
5043     }
5044
5045     compiler->rpFrameType = frameType;
5046 }
5047
5048 // Is the copyReg/moveReg given by this RefPosition still busy at the
5049 // given location?
5050 bool copyOrMoveRegInUse(RefPosition* ref, LsraLocation loc)
5051 {
5052     assert(ref->copyReg || ref->moveReg);
5053     if (ref->getRefEndLocation() >= loc)
5054     {
5055         return true;
5056     }
5057     Interval*    interval = ref->getInterval();
5058     RefPosition* nextRef  = interval->getNextRefPosition();
5059     if (nextRef != nullptr && nextRef->treeNode == ref->treeNode && nextRef->getRefEndLocation() >= loc)
5060     {
5061         return true;
5062     }
5063     return false;
5064 }
5065
5066 // Determine whether the register represented by "physRegRecord" is available at least
5067 // at the "currentLoc", and if so, return the next location at which it is in use in
5068 // "nextRefLocationPtr"
5069 //
5070 bool LinearScan::registerIsAvailable(RegRecord*    physRegRecord,
5071                                      LsraLocation  currentLoc,
5072                                      LsraLocation* nextRefLocationPtr,
5073                                      RegisterType  regType)
5074 {
5075     *nextRefLocationPtr          = MaxLocation;
5076     LsraLocation nextRefLocation = MaxLocation;
5077     regMaskTP    regMask         = genRegMask(physRegRecord->regNum);
5078     if (physRegRecord->isBusyUntilNextKill)
5079     {
5080         return false;
5081     }
5082
5083     RefPosition* nextPhysReference = physRegRecord->getNextRefPosition();
5084     if (nextPhysReference != nullptr)
5085     {
5086         nextRefLocation = nextPhysReference->nodeLocation;
5087         // if (nextPhysReference->refType == RefTypeFixedReg) nextRefLocation--;
5088     }
5089     else if (!physRegRecord->isCalleeSave)
5090     {
5091         nextRefLocation = MaxLocation - 1;
5092     }
5093
5094     Interval* assignedInterval = physRegRecord->assignedInterval;
5095
5096     if (assignedInterval != nullptr)
5097     {
5098         RefPosition* recentReference = assignedInterval->recentRefPosition;
5099
5100         // The only case where we have an assignedInterval, but recentReference is null
5101         // is where this interval is live at procedure entry (i.e. an arg register), in which
5102         // case it's still live and its assigned register is not available
5103         // (Note that the ParamDef will be recorded as a recentReference when we encounter
5104         // it, but we will be allocating registers, potentially to other incoming parameters,
5105         // as we process the ParamDefs.)
5106
5107         if (recentReference == nullptr)
5108         {
5109             return false;
5110         }
5111
5112         // Is this a copyReg/moveReg?  It is if the register assignment doesn't match.
5113         // (the recentReference may not be a copyReg/moveReg, because we could have seen another
5114         // reference since the copyReg/moveReg)
5115
5116         if (!assignedInterval->isAssignedTo(physRegRecord->regNum))
5117         {
5118             // Don't reassign it if it's still in use
5119             if ((recentReference->copyReg || recentReference->moveReg) &&
5120                 copyOrMoveRegInUse(recentReference, currentLoc))
5121             {
5122                 return false;
5123             }
5124         }
5125         else if (!assignedInterval->isActive && assignedInterval->isConstant)
5126         {
5127             // Treat this as unassigned, i.e. do nothing.
5128             // TODO-CQ: Consider adjusting the heuristics (probably in the caller of this method)
5129             // to avoid reusing these registers.
5130         }
5131         // If this interval isn't active, it's available if it isn't referenced
5132         // at this location (or the previous location, if the recent RefPosition
5133         // is a delayRegFree).
5134         else if (!assignedInterval->isActive &&
5135                  (recentReference->refType == RefTypeExpUse || recentReference->getRefEndLocation() < currentLoc))
5136         {
5137             // This interval must have a next reference (otherwise it wouldn't be assigned to this register)
5138             RefPosition* nextReference = recentReference->nextRefPosition;
5139             if (nextReference != nullptr)
5140             {
5141                 if (nextReference->nodeLocation < nextRefLocation)
5142                 {
5143                     nextRefLocation = nextReference->nodeLocation;
5144                 }
5145             }
5146             else
5147             {
5148                 assert(recentReference->copyReg && recentReference->registerAssignment != regMask);
5149             }
5150         }
5151         else
5152         {
5153             return false;
5154         }
5155     }
5156     if (nextRefLocation < *nextRefLocationPtr)
5157     {
5158         *nextRefLocationPtr = nextRefLocation;
5159     }
5160
5161 #ifdef _TARGET_ARM_
5162     if (regType == TYP_DOUBLE)
5163     {
5164         // Recurse, but check the other half this time (TYP_FLOAT)
5165         if (!registerIsAvailable(getRegisterRecord(REG_NEXT(physRegRecord->regNum)), currentLoc, nextRefLocationPtr,
5166                                  TYP_FLOAT))
5167             return false;
5168         nextRefLocation = *nextRefLocationPtr;
5169     }
5170 #endif // _TARGET_ARM_
5171
5172     return (nextRefLocation >= currentLoc);
5173 }
5174
5175 //------------------------------------------------------------------------
5176 // getRegisterType: Get the RegisterType to use for the given RefPosition
5177 //
5178 // Arguments:
5179 //    currentInterval: The interval for the current allocation
5180 //    refPosition:     The RefPosition of the current Interval for which a register is being allocated
5181 //
5182 // Return Value:
5183 //    The RegisterType that should be allocated for this RefPosition
5184 //
5185 // Notes:
5186 //    This will nearly always be identical to the registerType of the interval, except in the case
5187 //    of SIMD types of 8 bytes (currently only Vector2) when they are passed and returned in integer
5188 //    registers, or copied to a return temp.
5189 //    This method need only be called in situations where we may be dealing with the register requirements
5190 //    of a RefTypeUse RefPosition (i.e. not when we are only looking at the type of an interval, nor when
5191 //    we are interested in the "defining" type of the interval).  This is because the situation of interest
5192 //    only happens at the use (where it must be copied to an integer register).
5193
5194 RegisterType LinearScan::getRegisterType(Interval* currentInterval, RefPosition* refPosition)
5195 {
5196     assert(refPosition->getInterval() == currentInterval);
5197     RegisterType regType    = currentInterval->registerType;
5198     regMaskTP    candidates = refPosition->registerAssignment;
5199
5200     assert((candidates & allRegs(regType)) != RBM_NONE);
5201     return regType;
5202 }
5203
5204 //------------------------------------------------------------------------
5205 // tryAllocateFreeReg: Find a free register that satisfies the requirements for refPosition,
5206 //                     and takes into account the preferences for the given Interval
5207 //
5208 // Arguments:
5209 //    currentInterval: The interval for the current allocation
5210 //    refPosition:     The RefPosition of the current Interval for which a register is being allocated
5211 //
5212 // Return Value:
5213 //    The regNumber, if any, allocated to the RefPositon.  Returns REG_NA if no free register is found.
5214 //
5215 // Notes:
5216 //    TODO-CQ: Consider whether we need to use a different order for tree temps than for vars, as
5217 //    reg predict does
5218
5219 static const regNumber lsraRegOrder[]      = {REG_VAR_ORDER};
5220 const unsigned         lsraRegOrderSize    = ArrLen(lsraRegOrder);
5221 static const regNumber lsraRegOrderFlt[]   = {REG_VAR_ORDER_FLT};
5222 const unsigned         lsraRegOrderFltSize = ArrLen(lsraRegOrderFlt);
5223
5224 regNumber LinearScan::tryAllocateFreeReg(Interval* currentInterval, RefPosition* refPosition)
5225 {
5226     regNumber foundReg = REG_NA;
5227
5228     RegisterType     regType = getRegisterType(currentInterval, refPosition);
5229     const regNumber* regOrder;
5230     unsigned         regOrderSize;
5231     if (useFloatReg(regType))
5232     {
5233         regOrder     = lsraRegOrderFlt;
5234         regOrderSize = lsraRegOrderFltSize;
5235     }
5236     else
5237     {
5238         regOrder     = lsraRegOrder;
5239         regOrderSize = lsraRegOrderSize;
5240     }
5241
5242     LsraLocation currentLocation = refPosition->nodeLocation;
5243     RefPosition* nextRefPos      = refPosition->nextRefPosition;
5244     LsraLocation nextLocation    = (nextRefPos == nullptr) ? currentLocation : nextRefPos->nodeLocation;
5245     regMaskTP    candidates      = refPosition->registerAssignment;
5246     regMaskTP    preferences     = currentInterval->registerPreferences;
5247
5248     if (RefTypeIsDef(refPosition->refType))
5249     {
5250         if (currentInterval->hasConflictingDefUse)
5251         {
5252             resolveConflictingDefAndUse(currentInterval, refPosition);
5253             candidates = refPosition->registerAssignment;
5254         }
5255         // Otherwise, check for the case of a fixed-reg def of a reg that will be killed before the
5256         // use, or interferes at the point of use (which shouldn't happen, but Lower doesn't mark
5257         // the contained nodes as interfering).
5258         // Note that we may have a ParamDef RefPosition that is marked isFixedRegRef, but which
5259         // has had its registerAssignment changed to no longer be a single register.
5260         else if (refPosition->isFixedRegRef && nextRefPos != nullptr && RefTypeIsUse(nextRefPos->refType) &&
5261                  !nextRefPos->isFixedRegRef && genMaxOneBit(refPosition->registerAssignment))
5262         {
5263             regNumber  defReg       = refPosition->assignedReg();
5264             RegRecord* defRegRecord = getRegisterRecord(defReg);
5265
5266             RefPosition* currFixedRegRefPosition = defRegRecord->recentRefPosition;
5267             assert(currFixedRegRefPosition != nullptr &&
5268                    currFixedRegRefPosition->nodeLocation == refPosition->nodeLocation);
5269
5270             // If there is another fixed reference to this register before the use, change the candidates
5271             // on this RefPosition to include that of nextRefPos.
5272             if (currFixedRegRefPosition->nextRefPosition != nullptr &&
5273                 currFixedRegRefPosition->nextRefPosition->nodeLocation <= nextRefPos->getRefEndLocation())
5274             {
5275                 candidates |= nextRefPos->registerAssignment;
5276                 if (preferences == refPosition->registerAssignment)
5277                 {
5278                     preferences = candidates;
5279                 }
5280             }
5281         }
5282     }
5283
5284     preferences &= candidates;
5285     if (preferences == RBM_NONE)
5286     {
5287         preferences = candidates;
5288     }
5289     regMaskTP relatedPreferences = RBM_NONE;
5290
5291 #ifdef DEBUG
5292     candidates = stressLimitRegs(refPosition, candidates);
5293 #endif
5294     bool mustAssignARegister = true;
5295     assert(candidates != RBM_NONE);
5296
5297     // If the related interval has no further references, it is possible that it is a source of the
5298     // node that produces this interval.  However, we don't want to use the relatedInterval for preferencing
5299     // if its next reference is not a new definition (as it either is or will become live).
5300     Interval* relatedInterval = currentInterval->relatedInterval;
5301     if (relatedInterval != nullptr)
5302     {
5303         RefPosition* nextRelatedRefPosition = relatedInterval->getNextRefPosition();
5304         if (nextRelatedRefPosition != nullptr)
5305         {
5306             // Don't use the relatedInterval for preferencing if its next reference is not a new definition.
5307             if (!RefTypeIsDef(nextRelatedRefPosition->refType))
5308             {
5309                 relatedInterval = nullptr;
5310             }
5311             // Is the relatedInterval simply a copy to another relatedInterval?
5312             else if ((relatedInterval->relatedInterval != nullptr) &&
5313                      (nextRelatedRefPosition->nextRefPosition != nullptr) &&
5314                      (nextRelatedRefPosition->nextRefPosition->nextRefPosition == nullptr) &&
5315                      (nextRelatedRefPosition->nextRefPosition->nodeLocation <
5316                       relatedInterval->relatedInterval->getNextRefLocation()))
5317             {
5318                 // The current relatedInterval has only two remaining RefPositions, both of which
5319                 // occur prior to the next RefPosition for its relatedInterval.
5320                 // It is likely a copy.
5321                 relatedInterval = relatedInterval->relatedInterval;
5322             }
5323         }
5324     }
5325
5326     if (relatedInterval != nullptr)
5327     {
5328         // If the related interval already has an assigned register, then use that
5329         // as the related preference.  We'll take the related
5330         // interval preferences into account in the loop over all the registers.
5331
5332         if (relatedInterval->assignedReg != nullptr)
5333         {
5334             relatedPreferences = genRegMask(relatedInterval->assignedReg->regNum);
5335         }
5336         else
5337         {
5338             relatedPreferences = relatedInterval->registerPreferences;
5339         }
5340     }
5341
5342     bool preferCalleeSave = currentInterval->preferCalleeSave;
5343
5344     // For floating point, we want to be less aggressive about using callee-save registers.
5345     // So in that case, we just need to ensure that the current RefPosition is covered.
5346     RefPosition* rangeEndRefPosition;
5347     RefPosition* lastRefPosition = currentInterval->lastRefPosition;
5348     if (useFloatReg(currentInterval->registerType))
5349     {
5350         rangeEndRefPosition = refPosition;
5351     }
5352     else
5353     {
5354         rangeEndRefPosition = currentInterval->lastRefPosition;
5355         // If we have a relatedInterval that is not currently occupying a register,
5356         // and whose lifetime begins after this one ends,
5357         // we want to try to select a register that will cover its lifetime.
5358         if ((relatedInterval != nullptr) && (relatedInterval->assignedReg == nullptr) &&
5359             (relatedInterval->getNextRefLocation() >= rangeEndRefPosition->nodeLocation))
5360         {
5361             lastRefPosition  = relatedInterval->lastRefPosition;
5362             preferCalleeSave = relatedInterval->preferCalleeSave;
5363         }
5364     }
5365
5366     // If this has a delayed use (due to being used in a rmw position of a
5367     // non-commutative operator), its endLocation is delayed until the "def"
5368     // position, which is one location past the use (getRefEndLocation() takes care of this).
5369     LsraLocation rangeEndLocation = rangeEndRefPosition->getRefEndLocation();
5370     LsraLocation lastLocation     = lastRefPosition->getRefEndLocation();
5371     regNumber    prevReg          = REG_NA;
5372
5373     if (currentInterval->assignedReg)
5374     {
5375         bool useAssignedReg = false;
5376         // This was an interval that was previously allocated to the given
5377         // physical register, and we should try to allocate it to that register
5378         // again, if possible and reasonable.
5379         // Use it preemptively (i.e. before checking other available regs)
5380         // only if it is preferred and available.
5381
5382         RegRecord* regRec    = currentInterval->assignedReg;
5383         prevReg              = regRec->regNum;
5384         regMaskTP prevRegBit = genRegMask(prevReg);
5385
5386         // Is it in the preferred set of regs?
5387         if ((prevRegBit & preferences) != RBM_NONE)
5388         {
5389             // Is it currently available?
5390             LsraLocation nextPhysRefLoc;
5391             if (registerIsAvailable(regRec, currentLocation, &nextPhysRefLoc, currentInterval->registerType))
5392             {
5393                 // If the register is next referenced at this location, only use it if
5394                 // this has a fixed reg requirement (i.e. this is the reference that caused
5395                 // the FixedReg ref to be created)
5396
5397                 if (!regRec->conflictingFixedRegReference(refPosition))
5398                 {
5399                     useAssignedReg = true;
5400                 }
5401             }
5402         }
5403         if (useAssignedReg)
5404         {
5405             regNumber foundReg = prevReg;
5406             assignPhysReg(regRec, currentInterval);
5407             refPosition->registerAssignment = genRegMask(foundReg);
5408             return foundReg;
5409         }
5410         else
5411         {
5412             // Don't keep trying to allocate to this register
5413             currentInterval->assignedReg = nullptr;
5414         }
5415     }
5416
5417     RegRecord* availablePhysRegInterval = nullptr;
5418     Interval*  intervalToUnassign       = nullptr;
5419
5420     // Each register will receive a score which is the sum of the scoring criteria below.
5421     // These were selected on the assumption that they will have an impact on the "goodness"
5422     // of a register selection, and have been tuned to a certain extent by observing the impact
5423     // of the ordering on asmDiffs.  However, there is probably much more room for tuning,
5424     // and perhaps additional criteria.
5425     //
5426     // These are FLAGS (bits) so that we can easily order them and add them together.
5427     // If the scores are equal, but one covers more of the current interval's range,
5428     // then it wins.  Otherwise, the one encountered earlier in the regOrder wins.
5429
5430     enum RegisterScore
5431     {
5432         VALUE_AVAILABLE = 0x40, // It is a constant value that is already in an acceptable register.
5433         COVERS          = 0x20, // It is in the interval's preference set and it covers the entire lifetime.
5434         OWN_PREFERENCE  = 0x10, // It is in the preference set of this interval.
5435         COVERS_RELATED  = 0x08, // It is in the preference set of the related interval and covers the entire lifetime.
5436         RELATED_PREFERENCE = 0x04, // It is in the preference set of the related interval.
5437         CALLER_CALLEE      = 0x02, // It is in the right "set" for the interval (caller or callee-save).
5438         UNASSIGNED         = 0x01, // It is not currently assigned to an inactive interval.
5439     };
5440
5441     int bestScore = 0;
5442
5443     // Compute the best possible score so we can stop looping early if we find it.
5444     // TODO-Throughput: At some point we may want to short-circuit the computation of each score, but
5445     // probably not until we've tuned the order of these criteria.  At that point,
5446     // we'll need to avoid the short-circuit if we've got a stress option to reverse
5447     // the selection.
5448     int bestPossibleScore = COVERS + UNASSIGNED + OWN_PREFERENCE + CALLER_CALLEE;
5449     if (relatedPreferences != RBM_NONE)
5450     {
5451         bestPossibleScore |= RELATED_PREFERENCE + COVERS_RELATED;
5452     }
5453
5454     LsraLocation bestLocation = MinLocation;
5455
5456     // In non-debug builds, this will simply get optimized away
5457     bool reverseSelect = false;
5458 #ifdef DEBUG
5459     reverseSelect = doReverseSelect();
5460 #endif // DEBUG
5461
5462     // An optimization for the common case where there is only one candidate -
5463     // avoid looping over all the other registers
5464
5465     regNumber singleReg = REG_NA;
5466
5467     if (genMaxOneBit(candidates))
5468     {
5469         regOrderSize = 1;
5470         singleReg    = genRegNumFromMask(candidates);
5471         regOrder     = &singleReg;
5472     }
5473
5474     for (unsigned i = 0; i < regOrderSize && (candidates != RBM_NONE); i++)
5475     {
5476         regNumber regNum       = regOrder[i];
5477         regMaskTP candidateBit = genRegMask(regNum);
5478
5479         if (!(candidates & candidateBit))
5480         {
5481             continue;
5482         }
5483
5484         candidates &= ~candidateBit;
5485
5486         RegRecord* physRegRecord = getRegisterRecord(regNum);
5487
5488         int          score               = 0;
5489         LsraLocation nextPhysRefLocation = MaxLocation;
5490
5491         // By chance, is this register already holding this interval, as a copyReg or having
5492         // been restored as inactive after a kill?
5493         if (physRegRecord->assignedInterval == currentInterval)
5494         {
5495             availablePhysRegInterval = physRegRecord;
5496             intervalToUnassign       = nullptr;
5497             break;
5498         }
5499
5500         // Find the next RefPosition of the physical register
5501         if (!registerIsAvailable(physRegRecord, currentLocation, &nextPhysRefLocation, regType))
5502         {
5503             continue;
5504         }
5505
5506         // If the register is next referenced at this location, only use it if
5507         // this has a fixed reg requirement (i.e. this is the reference that caused
5508         // the FixedReg ref to be created)
5509
5510         if (physRegRecord->conflictingFixedRegReference(refPosition))
5511         {
5512             continue;
5513         }
5514
5515         // If this is a definition of a constant interval, check to see if its value is already in this register.
5516         if (currentInterval->isConstant && RefTypeIsDef(refPosition->refType) &&
5517             (physRegRecord->assignedInterval != nullptr) && physRegRecord->assignedInterval->isConstant)
5518         {
5519             noway_assert(refPosition->treeNode != nullptr);
5520             GenTree* otherTreeNode = physRegRecord->assignedInterval->firstRefPosition->treeNode;
5521             noway_assert(otherTreeNode != nullptr);
5522
5523             if (refPosition->treeNode->OperGet() == otherTreeNode->OperGet())
5524             {
5525                 switch (otherTreeNode->OperGet())
5526                 {
5527                     case GT_CNS_INT:
5528                         if ((refPosition->treeNode->AsIntCon()->IconValue() ==
5529                              otherTreeNode->AsIntCon()->IconValue()) &&
5530                             (varTypeGCtype(refPosition->treeNode) == varTypeGCtype(otherTreeNode)))
5531                         {
5532 #ifdef _TARGET_64BIT_
5533                             // If the constant is negative, only reuse registers of the same type.
5534                             // This is because, on a 64-bit system, we do not sign-extend immediates in registers to
5535                             // 64-bits unless they are actually longs, as this requires a longer instruction.
5536                             // This doesn't apply to a 32-bit system, on which long values occupy multiple registers.
5537                             // (We could sign-extend, but we would have to always sign-extend, because if we reuse more
5538                             // than once, we won't have access to the instruction that originally defines the constant).
5539                             if ((refPosition->treeNode->TypeGet() == otherTreeNode->TypeGet()) ||
5540                                 (refPosition->treeNode->AsIntCon()->IconValue() >= 0))
5541 #endif // _TARGET_64BIT_
5542                             {
5543                                 score |= VALUE_AVAILABLE;
5544                             }
5545                         }
5546                         break;
5547                     case GT_CNS_DBL:
5548                     {
5549                         // For floating point constants, the values must be identical, not simply compare
5550                         // equal.  So we compare the bits.
5551                         if (refPosition->treeNode->AsDblCon()->isBitwiseEqual(otherTreeNode->AsDblCon()) &&
5552                             (refPosition->treeNode->TypeGet() == otherTreeNode->TypeGet()))
5553                         {
5554                             score |= VALUE_AVAILABLE;
5555                         }
5556                         break;
5557                     }
5558                     default:
5559                         // for all other 'otherTreeNode->OperGet()' kinds, we leave 'score' unchanged
5560                         break;
5561                 }
5562             }
5563         }
5564
5565         // If the nextPhysRefLocation is a fixedRef for the rangeEndRefPosition, increment it so that
5566         // we don't think it isn't covering the live range.
5567         // This doesn't handle the case where earlier RefPositions for this Interval are also
5568         // FixedRefs of this regNum, but at least those are only interesting in the case where those
5569         // are "local last uses" of the Interval - otherwise the liveRange would interfere with the reg.
5570         if (nextPhysRefLocation == rangeEndLocation && rangeEndRefPosition->isFixedRefOfReg(regNum))
5571         {
5572             INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_INCREMENT_RANGE_END, currentInterval, regNum));
5573             nextPhysRefLocation++;
5574         }
5575
5576         if ((candidateBit & preferences) != RBM_NONE)
5577         {
5578             score |= OWN_PREFERENCE;
5579             if (nextPhysRefLocation > rangeEndLocation)
5580             {
5581                 score |= COVERS;
5582             }
5583         }
5584         if (relatedInterval != nullptr && (candidateBit & relatedPreferences) != RBM_NONE)
5585         {
5586             score |= RELATED_PREFERENCE;
5587             if (nextPhysRefLocation > relatedInterval->lastRefPosition->nodeLocation)
5588             {
5589                 score |= COVERS_RELATED;
5590             }
5591         }
5592
5593         // If we had a fixed-reg def of a reg that will be killed before the use, prefer it to any other registers
5594         // with the same score.  (Note that we haven't changed the original registerAssignment on the RefPosition).
5595         // Overload the RELATED_PREFERENCE value.
5596         else if (candidateBit == refPosition->registerAssignment)
5597         {
5598             score |= RELATED_PREFERENCE;
5599         }
5600
5601         if ((preferCalleeSave && physRegRecord->isCalleeSave) || (!preferCalleeSave && !physRegRecord->isCalleeSave))
5602         {
5603             score |= CALLER_CALLEE;
5604         }
5605
5606         // The register is considered unassigned if it has no assignedInterval, OR
5607         // if its next reference is beyond the range of this interval.
5608         if (physRegRecord->assignedInterval == nullptr ||
5609             physRegRecord->assignedInterval->getNextRefLocation() > lastLocation)
5610         {
5611             score |= UNASSIGNED;
5612         }
5613
5614         bool foundBetterCandidate = false;
5615
5616         if (score > bestScore)
5617         {
5618             foundBetterCandidate = true;
5619         }
5620         else if (score == bestScore)
5621         {
5622             // Prefer a register that covers the range.
5623             if (bestLocation <= lastLocation)
5624             {
5625                 if (nextPhysRefLocation > bestLocation)
5626                 {
5627                     foundBetterCandidate = true;
5628                 }
5629             }
5630             // If both cover the range, prefer a register that is killed sooner (leaving the longer range register
5631             // available). If both cover the range and also getting killed at the same location, prefer the one which
5632             // is same as previous assignment.
5633             else if (nextPhysRefLocation > lastLocation)
5634             {
5635                 if (nextPhysRefLocation < bestLocation)
5636                 {
5637                     foundBetterCandidate = true;
5638                 }
5639                 else if (nextPhysRefLocation == bestLocation && prevReg == regNum)
5640                 {
5641                     foundBetterCandidate = true;
5642                 }
5643             }
5644         }
5645
5646 #ifdef DEBUG
5647         if (doReverseSelect() && bestScore != 0)
5648         {
5649             foundBetterCandidate = !foundBetterCandidate;
5650         }
5651 #endif // DEBUG
5652
5653         if (foundBetterCandidate)
5654         {
5655             bestLocation             = nextPhysRefLocation;
5656             availablePhysRegInterval = physRegRecord;
5657             intervalToUnassign       = physRegRecord->assignedInterval;
5658             bestScore                = score;
5659         }
5660
5661         // there is no way we can get a better score so break out
5662         if (!reverseSelect && score == bestPossibleScore && bestLocation == rangeEndLocation + 1)
5663         {
5664             break;
5665         }
5666     }
5667
5668     if (availablePhysRegInterval != nullptr)
5669     {
5670         if (intervalToUnassign != nullptr)
5671         {
5672             RegRecord* physRegToUnassign = availablePhysRegInterval;
5673 #ifdef _TARGET_ARM_
5674             // We should unassign a double register if availablePhysRegInterval is part of the double register
5675             if (availablePhysRegInterval->assignedInterval->registerType == TYP_DOUBLE &&
5676                 !genIsValidDoubleReg(availablePhysRegInterval->regNum))
5677                 physRegToUnassign = findAnotherHalfRegRec(availablePhysRegInterval);
5678 #endif
5679             unassignPhysReg(physRegToUnassign, intervalToUnassign->recentRefPosition);
5680             if (bestScore & VALUE_AVAILABLE)
5681             {
5682                 assert(intervalToUnassign->isConstant);
5683                 refPosition->treeNode->SetReuseRegVal();
5684             }
5685             // If we considered this "unassigned" because this interval's lifetime ends before
5686             // the next ref, remember it.
5687             else if ((bestScore & UNASSIGNED) != 0 && intervalToUnassign != nullptr)
5688             {
5689                 updatePreviousInterval(physRegToUnassign, intervalToUnassign, intervalToUnassign->registerType);
5690             }
5691         }
5692         else
5693         {
5694             assert((bestScore & VALUE_AVAILABLE) == 0);
5695         }
5696         assignPhysReg(availablePhysRegInterval, currentInterval);
5697         foundReg                        = availablePhysRegInterval->regNum;
5698         regMaskTP foundRegMask          = genRegMask(foundReg);
5699         refPosition->registerAssignment = foundRegMask;
5700         if (relatedInterval != nullptr)
5701         {
5702             relatedInterval->updateRegisterPreferences(foundRegMask);
5703         }
5704     }
5705
5706     return foundReg;
5707 }
5708
5709 //------------------------------------------------------------------------
5710 // allocateBusyReg: Find a busy register that satisfies the requirements for refPosition,
5711 //                  and that can be spilled.
5712 //
5713 // Arguments:
5714 //    current               The interval for the current allocation
5715 //    refPosition           The RefPosition of the current Interval for which a register is being allocated
5716 //    allocateIfProfitable  If true, a reg may not be allocated if all other ref positions currently
5717 //                          occupying registers are more important than the 'refPosition'.
5718 //
5719 // Return Value:
5720 //    The regNumber allocated to the RefPositon.  Returns REG_NA if no free register is found.
5721 //
5722 // Note:  Currently this routine uses weight and farthest distance of next reference
5723 // to select a ref position for spilling.
5724 // a) if allocateIfProfitable = false
5725 //        The ref position chosen for spilling will be the lowest weight
5726 //        of all and if there is is more than one ref position with the
5727 //        same lowest weight, among them choses the one with farthest
5728 //        distance to its next reference.
5729 //
5730 // b) if allocateIfProfitable = true
5731 //        The ref position chosen for spilling will not only be lowest weight
5732 //        of all but also has a weight lower than 'refPosition'.  If there is
5733 //        no such ref position, reg will not be allocated.
5734 regNumber LinearScan::allocateBusyReg(Interval* current, RefPosition* refPosition, bool allocateIfProfitable)
5735 {
5736     regNumber foundReg = REG_NA;
5737
5738     RegisterType regType     = getRegisterType(current, refPosition);
5739     regMaskTP    candidates  = refPosition->registerAssignment;
5740     regMaskTP    preferences = (current->registerPreferences & candidates);
5741     if (preferences == RBM_NONE)
5742     {
5743         preferences = candidates;
5744     }
5745     if (candidates == RBM_NONE)
5746     {
5747         // This assumes only integer and floating point register types
5748         // if we target a processor with additional register types,
5749         // this would have to change
5750         candidates = allRegs(regType);
5751     }
5752
5753 #ifdef DEBUG
5754     candidates = stressLimitRegs(refPosition, candidates);
5755 #endif // DEBUG
5756
5757     // TODO-CQ: Determine whether/how to take preferences into account in addition to
5758     // prefering the one with the furthest ref position when considering
5759     // a candidate to spill
5760     RegRecord*   farthestRefPhysRegRecord = nullptr;
5761     LsraLocation farthestLocation         = MinLocation;
5762     LsraLocation refLocation              = refPosition->nodeLocation;
5763     unsigned     farthestRefPosWeight;
5764     if (allocateIfProfitable)
5765     {
5766         // If allocating a reg is optional, we will consider those ref positions
5767         // whose weight is less than 'refPosition' for spilling.
5768         farthestRefPosWeight = getWeight(refPosition);
5769     }
5770     else
5771     {
5772         // If allocating a reg is a must, we start off with max weight so
5773         // that the first spill candidate will be selected based on
5774         // farthest distance alone.  Since we start off with farthestLocation
5775         // initialized to MinLocation, the first available ref position
5776         // will be selected as spill candidate and its weight as the
5777         // fathestRefPosWeight.
5778         farthestRefPosWeight = BB_MAX_WEIGHT;
5779     }
5780
5781     for (regNumber regNum : Registers(regType))
5782     {
5783         regMaskTP candidateBit = genRegMask(regNum);
5784         if (!(candidates & candidateBit))
5785         {
5786             continue;
5787         }
5788         RegRecord* physRegRecord = getRegisterRecord(regNum);
5789
5790         if (physRegRecord->isBusyUntilNextKill)
5791         {
5792             continue;
5793         }
5794         Interval* assignedInterval = physRegRecord->assignedInterval;
5795
5796         // If there is a fixed reference at the same location (and it's not due to this reference),
5797         // don't use it.
5798
5799         if (physRegRecord->conflictingFixedRegReference(refPosition))
5800         {
5801             assert(candidates != candidateBit);
5802             continue;
5803         }
5804
5805         LsraLocation physRegNextLocation = MaxLocation;
5806         if (refPosition->isFixedRefOfRegMask(candidateBit))
5807         {
5808             // Either there is a fixed reference due to this node, or one associated with a
5809             // fixed use fed by a def at this node.
5810             // In either case, we must use this register as it's the only candidate
5811             // TODO-CQ: At the time we allocate a register to a fixed-reg def, if it's not going
5812             // to remain live until the use, we should set the candidates to allRegs(regType)
5813             // to avoid a spill - codegen can then insert the copy.
5814             assert(candidates == candidateBit);
5815
5816             // If a refPosition has a fixed reg as its candidate and is also marked
5817             // as allocateIfProfitable, we should allocate fixed reg only if the
5818             // weight of this ref position is greater than the weight of the ref
5819             // position to which fixed reg is assigned.  Such a case would arise
5820             // on x86 under LSRA stress.
5821             if (!allocateIfProfitable)
5822             {
5823                 physRegNextLocation  = MaxLocation;
5824                 farthestRefPosWeight = BB_MAX_WEIGHT;
5825             }
5826         }
5827         else
5828         {
5829             physRegNextLocation = physRegRecord->getNextRefLocation();
5830
5831             // If refPosition requires a fixed register, we should reject all others.
5832             // Otherwise, we will still evaluate all phyRegs though their next location is
5833             // not better than farthestLocation found so far.
5834             //
5835             // TODO: this method should be using an approach similar to tryAllocateFreeReg()
5836             // where it uses a regOrder array to avoid iterating over any but the single
5837             // fixed candidate.
5838             if (refPosition->isFixedRegRef && physRegNextLocation < farthestLocation)
5839             {
5840                 continue;
5841             }
5842         }
5843
5844         // If this register is not assigned to an interval, either
5845         // - it has a FixedReg reference at the current location that is not this reference, OR
5846         // - this is the special case of a fixed loReg, where this interval has a use at the same location
5847         // In either case, we cannot use it
5848
5849         if (assignedInterval == nullptr)
5850         {
5851             RefPosition* nextPhysRegPosition = physRegRecord->getNextRefPosition();
5852
5853 #ifndef _TARGET_ARM64_
5854             // TODO-Cleanup: Revisit this after Issue #3524 is complete
5855             // On ARM64 the nodeLocation is not always == refLocation, Disabling this assert for now.
5856             assert(nextPhysRegPosition->nodeLocation == refLocation && candidateBit != candidates);
5857 #endif
5858             continue;
5859         }
5860
5861         RefPosition* recentAssignedRef = assignedInterval->recentRefPosition;
5862
5863         if (!assignedInterval->isActive)
5864         {
5865             // The assigned interval has a reference at this location - otherwise, we would have found
5866             // this in tryAllocateFreeReg().
5867             // Note that we may or may not have actually handled the reference yet, so it could either
5868             // be recentAssigedRef, or the next reference.
5869             assert(recentAssignedRef != nullptr);
5870             if (recentAssignedRef->nodeLocation != refLocation)
5871             {
5872                 if (recentAssignedRef->nodeLocation + 1 == refLocation)
5873                 {
5874                     assert(recentAssignedRef->delayRegFree);
5875                 }
5876                 else
5877                 {
5878                     RefPosition* nextAssignedRef = recentAssignedRef->nextRefPosition;
5879                     assert(nextAssignedRef != nullptr);
5880                     assert(nextAssignedRef->nodeLocation == refLocation ||
5881                            (nextAssignedRef->nodeLocation + 1 == refLocation && nextAssignedRef->delayRegFree));
5882                 }
5883             }
5884             continue;
5885         }
5886
5887         // If we have a recentAssignedRef, check that it is going to be OK to spill it
5888         //
5889         // TODO-Review: Under what conditions recentAssginedRef would be null?
5890         unsigned recentAssignedRefWeight = BB_ZERO_WEIGHT;
5891         if (recentAssignedRef != nullptr)
5892         {
5893             if (recentAssignedRef->nodeLocation == refLocation)
5894             {
5895                 // We can't spill a register that's being used at the current location
5896                 RefPosition* physRegRef = physRegRecord->recentRefPosition;
5897                 continue;
5898             }
5899
5900             // If the current position has the candidate register marked to be delayed,
5901             // check if the previous location is using this register, if that's the case we have to skip
5902             // since we can't spill this register.
5903             if (recentAssignedRef->delayRegFree && (refLocation == recentAssignedRef->nodeLocation + 1))
5904             {
5905                 continue;
5906             }
5907
5908             // We don't prefer to spill a register if the weight of recentAssignedRef > weight
5909             // of the spill candidate found so far.  We would consider spilling a greater weight
5910             // ref position only if the refPosition being allocated must need a reg.
5911             recentAssignedRefWeight = getWeight(recentAssignedRef);
5912             if (recentAssignedRefWeight > farthestRefPosWeight)
5913             {
5914                 continue;
5915             }
5916         }
5917
5918         RefPosition* nextRefPosition = assignedInterval->getNextRefPosition();
5919         LsraLocation nextLocation    = assignedInterval->getNextRefLocation();
5920
5921         // We should never spill a register that's occupied by an Interval with its next use at the current location.
5922         // Normally this won't occur (unless we actually had more uses in a single node than there are registers),
5923         // because we'll always find something with a later nextLocation, but it can happen in stress when
5924         // we have LSRA_SELECT_NEAREST.
5925         if ((nextLocation == refLocation) && !refPosition->isFixedRegRef && nextRefPosition->RequiresRegister())
5926         {
5927             continue;
5928         }
5929
5930         if (nextLocation > physRegNextLocation)
5931         {
5932             nextLocation = physRegNextLocation;
5933         }
5934
5935         bool isBetterLocation;
5936
5937 #ifdef DEBUG
5938         if (doSelectNearest() && farthestRefPhysRegRecord != nullptr)
5939         {
5940             isBetterLocation = (nextLocation <= farthestLocation);
5941         }
5942         else
5943 #endif
5944             // This if-stmt is associated with the above else
5945             if (recentAssignedRefWeight < farthestRefPosWeight)
5946         {
5947             isBetterLocation = true;
5948         }
5949         else
5950         {
5951             // This would mean the weight of spill ref position we found so far is equal
5952             // to the weight of the ref position that is being evaluated.  In this case
5953             // we prefer to spill ref position whose distance to its next reference is
5954             // the farthest.
5955             assert(recentAssignedRefWeight == farthestRefPosWeight);
5956
5957             // If allocateIfProfitable=true, the first spill candidate selected
5958             // will be based on weight alone. After we have found a spill
5959             // candidate whose weight is less than the 'refPosition', we will
5960             // consider farthest distance when there is a tie in weights.
5961             // This is to ensure that we don't spill a ref position whose
5962             // weight is equal to weight of 'refPosition'.
5963             if (allocateIfProfitable && farthestRefPhysRegRecord == nullptr)
5964             {
5965                 isBetterLocation = false;
5966             }
5967             else
5968             {
5969                 isBetterLocation = (nextLocation > farthestLocation);
5970
5971                 if (nextLocation > farthestLocation)
5972                 {
5973                     isBetterLocation = true;
5974                 }
5975                 else if (nextLocation == farthestLocation)
5976                 {
5977                     // Both weight and distance are equal.
5978                     // Prefer that ref position which is marked both reload and
5979                     // allocate if profitable.  These ref positions don't need
5980                     // need to be spilled as they are already in memory and
5981                     // codegen considers them as contained memory operands.
5982                     isBetterLocation = (recentAssignedRef != nullptr) && recentAssignedRef->reload &&
5983                                        recentAssignedRef->AllocateIfProfitable();
5984                 }
5985                 else
5986                 {
5987                     isBetterLocation = false;
5988                 }
5989             }
5990         }
5991
5992         if (isBetterLocation)
5993         {
5994             farthestLocation         = nextLocation;
5995             farthestRefPhysRegRecord = physRegRecord;
5996             farthestRefPosWeight     = recentAssignedRefWeight;
5997         }
5998     }
5999
6000 #if DEBUG
6001     if (allocateIfProfitable)
6002     {
6003         // There may not be a spill candidate or if one is found
6004         // its weight must be less than the weight of 'refPosition'
6005         assert((farthestRefPhysRegRecord == nullptr) || (farthestRefPosWeight < getWeight(refPosition)));
6006     }
6007     else
6008     {
6009         // Must have found a spill candidate.
6010         assert(farthestRefPhysRegRecord != nullptr);
6011         if ((farthestLocation == refLocation) && !refPosition->isFixedRegRef)
6012         {
6013             Interval*    assignedInterval = farthestRefPhysRegRecord->assignedInterval;
6014             RefPosition* nextRefPosition  = assignedInterval->getNextRefPosition();
6015             assert(!nextRefPosition->RequiresRegister());
6016         }
6017         else
6018         {
6019             assert(farthestLocation > refLocation || refPosition->isFixedRegRef);
6020         }
6021     }
6022 #endif
6023
6024     if (farthestRefPhysRegRecord != nullptr)
6025     {
6026         foundReg = farthestRefPhysRegRecord->regNum;
6027         unassignPhysReg(farthestRefPhysRegRecord, farthestRefPhysRegRecord->assignedInterval->recentRefPosition);
6028         assignPhysReg(farthestRefPhysRegRecord, current);
6029         refPosition->registerAssignment = genRegMask(foundReg);
6030     }
6031     else
6032     {
6033         foundReg                        = REG_NA;
6034         refPosition->registerAssignment = RBM_NONE;
6035     }
6036
6037     return foundReg;
6038 }
6039
6040 // Grab a register to use to copy and then immediately use.
6041 // This is called only for localVar intervals that already have a register
6042 // assignment that is not compatible with the current RefPosition.
6043 // This is not like regular assignment, because we don't want to change
6044 // any preferences or existing register assignments.
6045 // Prefer a free register that's got the earliest next use.
6046 // Otherwise, spill something with the farthest next use
6047 //
6048 regNumber LinearScan::assignCopyReg(RefPosition* refPosition)
6049 {
6050     Interval* currentInterval = refPosition->getInterval();
6051     assert(currentInterval != nullptr);
6052     assert(currentInterval->isActive);
6053
6054     bool         foundFreeReg = false;
6055     RegRecord*   bestPhysReg  = nullptr;
6056     LsraLocation bestLocation = MinLocation;
6057     regMaskTP    candidates   = refPosition->registerAssignment;
6058
6059     // Save the relatedInterval, if any, so that it doesn't get modified during allocation.
6060     Interval* savedRelatedInterval   = currentInterval->relatedInterval;
6061     currentInterval->relatedInterval = nullptr;
6062
6063     // We don't want really want to change the default assignment,
6064     // so 1) pretend this isn't active, and 2) remember the old reg
6065     regNumber  oldPhysReg   = currentInterval->physReg;
6066     RegRecord* oldRegRecord = currentInterval->assignedReg;
6067     assert(oldRegRecord->regNum == oldPhysReg);
6068     currentInterval->isActive = false;
6069
6070     regNumber allocatedReg = tryAllocateFreeReg(currentInterval, refPosition);
6071     if (allocatedReg == REG_NA)
6072     {
6073         allocatedReg = allocateBusyReg(currentInterval, refPosition, false);
6074     }
6075
6076     // Now restore the old info
6077     currentInterval->relatedInterval = savedRelatedInterval;
6078     currentInterval->physReg         = oldPhysReg;
6079     currentInterval->assignedReg     = oldRegRecord;
6080     currentInterval->isActive        = true;
6081
6082     refPosition->copyReg = true;
6083     return allocatedReg;
6084 }
6085
6086 // Check if the interval is already assigned and if it is then unassign the physical record
6087 // then set the assignedInterval to 'interval'
6088 //
6089 void LinearScan::checkAndAssignInterval(RegRecord* regRec, Interval* interval)
6090 {
6091     if (regRec->assignedInterval != nullptr && regRec->assignedInterval != interval)
6092     {
6093         // This is allocated to another interval.  Either it is inactive, or it was allocated as a
6094         // copyReg and is therefore not the "assignedReg" of the other interval.  In the latter case,
6095         // we simply unassign it - in the former case we need to set the physReg on the interval to
6096         // REG_NA to indicate that it is no longer in that register.
6097         // The lack of checking for this case resulted in an assert in the retail version of System.dll,
6098         // in method SerialStream.GetDcbFlag.
6099         // Note that we can't check for the copyReg case, because we may have seen a more recent
6100         // RefPosition for the Interval that was NOT a copyReg.
6101         if (regRec->assignedInterval->assignedReg == regRec)
6102         {
6103             assert(regRec->assignedInterval->isActive == false);
6104             regRec->assignedInterval->physReg = REG_NA;
6105         }
6106         unassignPhysReg(regRec->regNum);
6107     }
6108
6109     updateAssignedInterval(regRec, interval, interval->registerType);
6110 }
6111
6112 // Assign the given physical register interval to the given interval
6113 void LinearScan::assignPhysReg(RegRecord* regRec, Interval* interval)
6114 {
6115     regMaskTP assignedRegMask = genRegMask(regRec->regNum);
6116     compiler->codeGen->regSet.rsSetRegsModified(assignedRegMask DEBUGARG(dumpTerse));
6117
6118     checkAndAssignInterval(regRec, interval);
6119     interval->assignedReg = regRec;
6120
6121     interval->physReg  = regRec->regNum;
6122     interval->isActive = true;
6123     if (interval->isLocalVar)
6124     {
6125         // Prefer this register for future references
6126         interval->updateRegisterPreferences(assignedRegMask);
6127     }
6128 }
6129
6130 //------------------------------------------------------------------------
6131 // setIntervalAsSplit: Set this Interval as being split
6132 //
6133 // Arguments:
6134 //    interval - The Interval which is being split
6135 //
6136 // Return Value:
6137 //    None.
6138 //
6139 // Notes:
6140 //    The given Interval will be marked as split, and it will be added to the
6141 //    set of splitOrSpilledVars.
6142 //
6143 // Assumptions:
6144 //    "interval" must be a lclVar interval, as tree temps are never split.
6145 //    This is asserted in the call to getVarIndex().
6146 //
6147 void LinearScan::setIntervalAsSplit(Interval* interval)
6148 {
6149     if (interval->isLocalVar)
6150     {
6151         unsigned varIndex = interval->getVarIndex(compiler);
6152         if (!interval->isSplit)
6153         {
6154             VarSetOps::AddElemD(compiler, splitOrSpilledVars, varIndex);
6155         }
6156         else
6157         {
6158             assert(VarSetOps::IsMember(compiler, splitOrSpilledVars, varIndex));
6159         }
6160     }
6161     interval->isSplit = true;
6162 }
6163
6164 //------------------------------------------------------------------------
6165 // setIntervalAsSpilled: Set this Interval as being spilled
6166 //
6167 // Arguments:
6168 //    interval - The Interval which is being spilled
6169 //
6170 // Return Value:
6171 //    None.
6172 //
6173 // Notes:
6174 //    The given Interval will be marked as spilled, and it will be added
6175 //    to the set of splitOrSpilledVars.
6176 //
6177 void LinearScan::setIntervalAsSpilled(Interval* interval)
6178 {
6179     if (interval->isLocalVar)
6180     {
6181         unsigned varIndex = interval->getVarIndex(compiler);
6182         if (!interval->isSpilled)
6183         {
6184             VarSetOps::AddElemD(compiler, splitOrSpilledVars, varIndex);
6185         }
6186         else
6187         {
6188             assert(VarSetOps::IsMember(compiler, splitOrSpilledVars, varIndex));
6189         }
6190     }
6191     interval->isSpilled = true;
6192 }
6193
6194 //------------------------------------------------------------------------
6195 // spill: Spill this Interval between "fromRefPosition" and "toRefPosition"
6196 //
6197 // Arguments:
6198 //    fromRefPosition - The RefPosition at which the Interval is to be spilled
6199 //    toRefPosition   - The RefPosition at which it must be reloaded
6200 //
6201 // Return Value:
6202 //    None.
6203 //
6204 // Assumptions:
6205 //    fromRefPosition and toRefPosition must not be null
6206 //
6207 void LinearScan::spillInterval(Interval* interval, RefPosition* fromRefPosition, RefPosition* toRefPosition)
6208 {
6209     assert(fromRefPosition != nullptr && toRefPosition != nullptr);
6210     assert(fromRefPosition->getInterval() == interval && toRefPosition->getInterval() == interval);
6211     assert(fromRefPosition->nextRefPosition == toRefPosition);
6212
6213     if (!fromRefPosition->lastUse)
6214     {
6215         // If not allocated a register, Lcl var def/use ref positions even if reg optional
6216         // should be marked as spillAfter.
6217         if (!fromRefPosition->RequiresRegister() && !(interval->isLocalVar && fromRefPosition->IsActualRef()))
6218         {
6219             fromRefPosition->registerAssignment = RBM_NONE;
6220         }
6221         else
6222         {
6223             fromRefPosition->spillAfter = true;
6224         }
6225     }
6226     assert(toRefPosition != nullptr);
6227
6228 #ifdef DEBUG
6229     if (VERBOSE)
6230     {
6231         dumpLsraAllocationEvent(LSRA_EVENT_SPILL, interval);
6232     }
6233 #endif // DEBUG
6234
6235     INTRACK_STATS(updateLsraStat(LSRA_STAT_SPILL, fromRefPosition->bbNum));
6236
6237     interval->isActive = false;
6238     setIntervalAsSpilled(interval);
6239
6240     // If fromRefPosition occurs before the beginning of this block, mark this as living in the stack
6241     // on entry to this block.
6242     if (fromRefPosition->nodeLocation <= curBBStartLocation)
6243     {
6244         // This must be a lclVar interval
6245         assert(interval->isLocalVar);
6246         setInVarRegForBB(curBBNum, interval->varNum, REG_STK);
6247     }
6248 }
6249
6250 //------------------------------------------------------------------------
6251 // unassignPhysRegNoSpill: Unassign the given physical register record from
6252 //                         an active interval, without spilling.
6253 //
6254 // Arguments:
6255 //    regRec           - the RegRecord to be unasssigned
6256 //
6257 // Return Value:
6258 //    None.
6259 //
6260 // Assumptions:
6261 //    The assignedInterval must not be null, and must be active.
6262 //
6263 // Notes:
6264 //    This method is used to unassign a register when an interval needs to be moved to a
6265 //    different register, but not (yet) spilled.
6266
6267 void LinearScan::unassignPhysRegNoSpill(RegRecord* regRec)
6268 {
6269     Interval* assignedInterval = regRec->assignedInterval;
6270     assert(assignedInterval != nullptr && assignedInterval->isActive);
6271     assignedInterval->isActive = false;
6272     unassignPhysReg(regRec, nullptr);
6273     assignedInterval->isActive = true;
6274 }
6275
6276 //------------------------------------------------------------------------
6277 // checkAndClearInterval: Clear the assignedInterval for the given
6278 //                        physical register record
6279 //
6280 // Arguments:
6281 //    regRec           - the physical RegRecord to be unasssigned
6282 //    spillRefPosition - The RefPosition at which the assignedInterval is to be spilled
6283 //                       or nullptr if we aren't spilling
6284 //
6285 // Return Value:
6286 //    None.
6287 //
6288 // Assumptions:
6289 //    see unassignPhysReg
6290 //
6291 void LinearScan::checkAndClearInterval(RegRecord* regRec, RefPosition* spillRefPosition)
6292 {
6293     Interval* assignedInterval = regRec->assignedInterval;
6294     assert(assignedInterval != nullptr);
6295     regNumber thisRegNum = regRec->regNum;
6296
6297     if (spillRefPosition == nullptr)
6298     {
6299         // Note that we can't assert  for the copyReg case
6300         //
6301         if (assignedInterval->physReg == thisRegNum)
6302         {
6303             assert(assignedInterval->isActive == false);
6304         }
6305     }
6306     else
6307     {
6308         assert(spillRefPosition->getInterval() == assignedInterval);
6309     }
6310
6311     updateAssignedInterval(regRec, nullptr, assignedInterval->registerType);
6312 }
6313
6314 //------------------------------------------------------------------------
6315 // unassignPhysReg: Unassign the given physical register record, and spill the
6316 //                  assignedInterval at the given spillRefPosition, if any.
6317 //
6318 // Arguments:
6319 //    regRec           - the RegRecord to be unasssigned
6320 //    spillRefPosition - The RefPosition at which the assignedInterval is to be spilled
6321 //
6322 // Return Value:
6323 //    None.
6324 //
6325 // Assumptions:
6326 //    The assignedInterval must not be null.
6327 //    If spillRefPosition is null, the assignedInterval must be inactive, or not currently
6328 //    assigned to this register (e.g. this is a copyReg for that Interval).
6329 //    Otherwise, spillRefPosition must be associated with the assignedInterval.
6330 //
6331 void LinearScan::unassignPhysReg(RegRecord* regRec, RefPosition* spillRefPosition)
6332 {
6333     Interval* assignedInterval = regRec->assignedInterval;
6334     assert(assignedInterval != nullptr);
6335
6336     regNumber thisRegNum = regRec->regNum;
6337
6338 #ifdef _TARGET_ARM_
6339     regNumber  nextRegNum = REG_NA;
6340     RegRecord* nextRegRec = nullptr;
6341
6342     // Prepare second half RegRecord of a double register for TYP_DOUBLE
6343     if (assignedInterval->registerType == TYP_DOUBLE)
6344     {
6345         assert(isFloatRegType(regRec->registerType));
6346         assert(genIsValidDoubleReg(regRec->regNum));
6347
6348         nextRegNum = REG_NEXT(regRec->regNum);
6349         nextRegRec = getRegisterRecord(nextRegNum);
6350
6351         // Both two RegRecords should have been assigned to the same interval.
6352         assert(assignedInterval == nextRegRec->assignedInterval);
6353     }
6354 #endif // _TARGET_ARM_
6355
6356     checkAndClearInterval(regRec, spillRefPosition);
6357
6358 #ifdef _TARGET_ARM_
6359     if (assignedInterval->registerType == TYP_DOUBLE)
6360     {
6361         // Both two RegRecords should have been unassigned together.
6362         assert(regRec->assignedInterval == nullptr);
6363         assert(nextRegRec->assignedInterval == nullptr);
6364     }
6365 #endif // _TARGET_ARM_
6366
6367 #ifdef DEBUG
6368     if (VERBOSE && !dumpTerse)
6369     {
6370         printf("unassigning %s: ", getRegName(regRec->regNum));
6371         assignedInterval->dump();
6372         printf("\n");
6373     }
6374 #endif // DEBUG
6375
6376     RefPosition* nextRefPosition = nullptr;
6377     if (spillRefPosition != nullptr)
6378     {
6379         nextRefPosition = spillRefPosition->nextRefPosition;
6380     }
6381
6382     if (assignedInterval->physReg != REG_NA && assignedInterval->physReg != thisRegNum)
6383     {
6384         // This must have been a temporary copy reg, but we can't assert that because there
6385         // may have been intervening RefPositions that were not copyRegs.
6386
6387         // reg->assignedInterval has already been set to nullptr by checkAndClearInterval()
6388         assert(regRec->assignedInterval == nullptr);
6389         return;
6390     }
6391
6392     regNumber victimAssignedReg = assignedInterval->physReg;
6393     assignedInterval->physReg   = REG_NA;
6394
6395     bool spill = assignedInterval->isActive && nextRefPosition != nullptr;
6396     if (spill)
6397     {
6398         // If this is an active interval, it must have a recentRefPosition,
6399         // otherwise it would not be active
6400         assert(spillRefPosition != nullptr);
6401
6402 #if 0
6403         // TODO-CQ: Enable this and insert an explicit GT_COPY (otherwise there's no way to communicate
6404         // to codegen that we want the copyReg to be the new home location).
6405         // If the last reference was a copyReg, and we're spilling the register
6406         // it was copied from, then make the copyReg the new primary location
6407         // if possible
6408         if (spillRefPosition->copyReg)
6409         {
6410             regNumber copyFromRegNum = victimAssignedReg;
6411             regNumber copyRegNum = genRegNumFromMask(spillRefPosition->registerAssignment);
6412             if (copyFromRegNum == thisRegNum &&
6413                 getRegisterRecord(copyRegNum)->assignedInterval == assignedInterval)
6414             {
6415                 assert(copyRegNum != thisRegNum);
6416                 assignedInterval->physReg = copyRegNum;
6417                 assignedInterval->assignedReg = this->getRegisterRecord(copyRegNum);
6418                 return;
6419             }
6420         }
6421 #endif // 0
6422 #ifdef DEBUG
6423         // With JitStressRegs == 0x80 (LSRA_EXTEND_LIFETIMES), we may have a RefPosition
6424         // that is not marked lastUse even though the treeNode is a lastUse.  In that case
6425         // we must not mark it for spill because the register will have been immediately freed
6426         // after use.  While we could conceivably add special handling for this case in codegen,
6427         // it would be messy and undesirably cause the "bleeding" of LSRA stress modes outside
6428         // of LSRA.
6429         if (extendLifetimes() && assignedInterval->isLocalVar && RefTypeIsUse(spillRefPosition->refType) &&
6430             spillRefPosition->treeNode != nullptr && (spillRefPosition->treeNode->gtFlags & GTF_VAR_DEATH) != 0)
6431         {
6432             dumpLsraAllocationEvent(LSRA_EVENT_SPILL_EXTENDED_LIFETIME, assignedInterval);
6433             assignedInterval->isActive = false;
6434             spill                      = false;
6435             // If the spillRefPosition occurs before the beginning of this block, it will have
6436             // been marked as living in this register on entry to this block, but we now need
6437             // to mark this as living on the stack.
6438             if (spillRefPosition->nodeLocation <= curBBStartLocation)
6439             {
6440                 setInVarRegForBB(curBBNum, assignedInterval->varNum, REG_STK);
6441                 if (spillRefPosition->nextRefPosition != nullptr)
6442                 {
6443                     setIntervalAsSpilled(assignedInterval);
6444                 }
6445             }
6446             else
6447             {
6448                 // Otherwise, we need to mark spillRefPosition as lastUse, or the interval
6449                 // will remain active beyond its allocated range during the resolution phase.
6450                 spillRefPosition->lastUse = true;
6451             }
6452         }
6453         else
6454 #endif // DEBUG
6455         {
6456             spillInterval(assignedInterval, spillRefPosition, nextRefPosition);
6457         }
6458     }
6459     // Maintain the association with the interval, if it has more references.
6460     // Or, if we "remembered" an interval assigned to this register, restore it.
6461     if (nextRefPosition != nullptr)
6462     {
6463         assignedInterval->assignedReg = regRec;
6464     }
6465     else if (canRestorePreviousInterval(regRec, assignedInterval))
6466     {
6467         regRec->assignedInterval = regRec->previousInterval;
6468         regRec->previousInterval = nullptr;
6469
6470 #ifdef _TARGET_ARM_
6471         // Note:
6472         //   We can not use updateAssignedInterval() and updatePreviousInterval() here,
6473         //   because regRec may not be a even-numbered float register.
6474
6475         // Update second half RegRecord of a double register for TYP_DOUBLE
6476         if (regRec->assignedInterval->registerType == TYP_DOUBLE)
6477         {
6478             RegRecord* anotherHalfRegRec = findAnotherHalfRegRec(regRec);
6479
6480             anotherHalfRegRec->assignedInterval = regRec->assignedInterval;
6481             anotherHalfRegRec->previousInterval = nullptr;
6482         }
6483 #endif // _TARGET_ARM_
6484
6485 #ifdef DEBUG
6486         if (spill)
6487         {
6488             dumpLsraAllocationEvent(LSRA_EVENT_RESTORE_PREVIOUS_INTERVAL_AFTER_SPILL, regRec->assignedInterval,
6489                                     thisRegNum);
6490         }
6491         else
6492         {
6493             dumpLsraAllocationEvent(LSRA_EVENT_RESTORE_PREVIOUS_INTERVAL, regRec->assignedInterval, thisRegNum);
6494         }
6495 #endif // DEBUG
6496     }
6497     else
6498     {
6499         updateAssignedInterval(regRec, nullptr, assignedInterval->registerType);
6500         updatePreviousInterval(regRec, nullptr, assignedInterval->registerType);
6501     }
6502 }
6503
6504 //------------------------------------------------------------------------
6505 // spillGCRefs: Spill any GC-type intervals that are currently in registers.a
6506 //
6507 // Arguments:
6508 //    killRefPosition - The RefPosition for the kill
6509 //
6510 // Return Value:
6511 //    None.
6512 //
6513 void LinearScan::spillGCRefs(RefPosition* killRefPosition)
6514 {
6515     // For each physical register that can hold a GC type,
6516     // if it is occupied by an interval of a GC type, spill that interval.
6517     regMaskTP candidateRegs = killRefPosition->registerAssignment;
6518     while (candidateRegs != RBM_NONE)
6519     {
6520         regMaskTP nextRegBit = genFindLowestBit(candidateRegs);
6521         candidateRegs &= ~nextRegBit;
6522         regNumber  nextReg          = genRegNumFromMask(nextRegBit);
6523         RegRecord* regRecord        = getRegisterRecord(nextReg);
6524         Interval*  assignedInterval = regRecord->assignedInterval;
6525         if (assignedInterval == nullptr || (assignedInterval->isActive == false) ||
6526             !varTypeIsGC(assignedInterval->registerType))
6527         {
6528             continue;
6529         }
6530         unassignPhysReg(regRecord, assignedInterval->recentRefPosition);
6531     }
6532     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DONE_KILL_GC_REFS, nullptr, REG_NA, nullptr));
6533 }
6534
6535 //------------------------------------------------------------------------
6536 // processBlockEndAllocation: Update var locations after 'currentBlock' has been allocated
6537 //
6538 // Arguments:
6539 //    currentBlock - the BasicBlock we have just finished allocating registers for
6540 //
6541 // Return Value:
6542 //    None
6543 //
6544 // Notes:
6545 //    Calls processBlockEndLocations() to set the outVarToRegMap, then gets the next block,
6546 //    and sets the inVarToRegMap appropriately.
6547
6548 void LinearScan::processBlockEndAllocation(BasicBlock* currentBlock)
6549 {
6550     assert(currentBlock != nullptr);
6551     if (enregisterLocalVars)
6552     {
6553         processBlockEndLocations(currentBlock);
6554     }
6555     markBlockVisited(currentBlock);
6556
6557     // Get the next block to allocate.
6558     // When the last block in the method has successors, there will be a final "RefTypeBB" to
6559     // ensure that we get the varToRegMap set appropriately, but in that case we don't need
6560     // to worry about "nextBlock".
6561     BasicBlock* nextBlock = getNextBlock();
6562     if (nextBlock != nullptr)
6563     {
6564         processBlockStartLocations(nextBlock, true);
6565     }
6566 }
6567
6568 //------------------------------------------------------------------------
6569 // rotateBlockStartLocation: When in the LSRA_BLOCK_BOUNDARY_ROTATE stress mode, attempt to
6570 //                           "rotate" the register assignment for a localVar to the next higher
6571 //                           register that is available.
6572 //
6573 // Arguments:
6574 //    interval      - the Interval for the variable whose register is getting rotated
6575 //    targetReg     - its register assignment from the predecessor block being used for live-in
6576 //    availableRegs - registers available for use
6577 //
6578 // Return Value:
6579 //    The new register to use.
6580
6581 #ifdef DEBUG
6582 regNumber LinearScan::rotateBlockStartLocation(Interval* interval, regNumber targetReg, regMaskTP availableRegs)
6583 {
6584     if (targetReg != REG_STK && getLsraBlockBoundaryLocations() == LSRA_BLOCK_BOUNDARY_ROTATE)
6585     {
6586         // If we're rotating the register locations at block boundaries, try to use
6587         // the next higher register number of the appropriate register type.
6588         regMaskTP candidateRegs = allRegs(interval->registerType) & availableRegs;
6589         regNumber firstReg      = REG_NA;
6590         regNumber newReg        = REG_NA;
6591         while (candidateRegs != RBM_NONE)
6592         {
6593             regMaskTP nextRegBit = genFindLowestBit(candidateRegs);
6594             candidateRegs &= ~nextRegBit;
6595             regNumber nextReg = genRegNumFromMask(nextRegBit);
6596             if (nextReg > targetReg)
6597             {
6598                 newReg = nextReg;
6599                 break;
6600             }
6601             else if (firstReg == REG_NA)
6602             {
6603                 firstReg = nextReg;
6604             }
6605         }
6606         if (newReg == REG_NA)
6607         {
6608             assert(firstReg != REG_NA);
6609             newReg = firstReg;
6610         }
6611         targetReg = newReg;
6612     }
6613     return targetReg;
6614 }
6615 #endif // DEBUG
6616
6617 #ifdef _TARGET_ARM_
6618 //--------------------------------------------------------------------------------------
6619 // isSecondHalfReg: Test if recRec is second half of double register
6620 //                  which is assigned to an interval.
6621 //
6622 // Arguments:
6623 //    regRec - a register to be tested
6624 //    interval - an interval which is assigned to some register
6625 //
6626 // Assumptions:
6627 //    None
6628 //
6629 // Return Value:
6630 //    True only if regRec is second half of assignedReg in interval
6631 //
6632 bool LinearScan::isSecondHalfReg(RegRecord* regRec, Interval* interval)
6633 {
6634     RegRecord* assignedReg = interval->assignedReg;
6635
6636     if (assignedReg != nullptr && interval->registerType == TYP_DOUBLE)
6637     {
6638         // interval should have been allocated to a valid double register
6639         assert(genIsValidDoubleReg(assignedReg->regNum));
6640
6641         // Find a second half RegRecord of double register
6642         regNumber firstRegNum  = assignedReg->regNum;
6643         regNumber secondRegNum = REG_NEXT(firstRegNum);
6644
6645         assert(genIsValidFloatReg(secondRegNum) && !genIsValidDoubleReg(secondRegNum));
6646
6647         RegRecord* secondRegRec = getRegisterRecord(secondRegNum);
6648
6649         return secondRegRec == regRec;
6650     }
6651
6652     return false;
6653 }
6654
6655 //------------------------------------------------------------------------------------------
6656 // findAnotherHalfRegRec: Find another half RegRecord which forms same ARM32 double register
6657 //
6658 // Arguments:
6659 //    regRec - A float RegRecord
6660 //
6661 // Assumptions:
6662 //    None
6663 //
6664 // Return Value:
6665 //    A RegRecord which forms same double register with regRec
6666 //
6667 RegRecord* LinearScan::findAnotherHalfRegRec(RegRecord* regRec)
6668 {
6669     regNumber  anotherHalfRegNum;
6670     RegRecord* anotherHalfRegRec;
6671
6672     assert(genIsValidFloatReg(regRec->regNum));
6673
6674     // Find another half register for TYP_DOUBLE interval,
6675     // following same logic in canRestorePreviousInterval().
6676     if (genIsValidDoubleReg(regRec->regNum))
6677     {
6678         anotherHalfRegNum = REG_NEXT(regRec->regNum);
6679         assert(!genIsValidDoubleReg(anotherHalfRegNum));
6680     }
6681     else
6682     {
6683         anotherHalfRegNum = REG_PREV(regRec->regNum);
6684         assert(genIsValidDoubleReg(anotherHalfRegNum));
6685     }
6686     anotherHalfRegRec = getRegisterRecord(anotherHalfRegNum);
6687
6688     return anotherHalfRegRec;
6689 }
6690 #endif
6691
6692 //--------------------------------------------------------------------------------------
6693 // canRestorePreviousInterval: Test if we can restore previous interval
6694 //
6695 // Arguments:
6696 //    regRec - a register which contains previous interval to be restored
6697 //    assignedInterval - an interval just unassigned
6698 //
6699 // Assumptions:
6700 //    None
6701 //
6702 // Return Value:
6703 //    True only if previous interval of regRec can be restored
6704 //
6705 bool LinearScan::canRestorePreviousInterval(RegRecord* regRec, Interval* assignedInterval)
6706 {
6707     bool retVal =
6708         (regRec->previousInterval != nullptr && regRec->previousInterval != assignedInterval &&
6709          regRec->previousInterval->assignedReg == regRec && regRec->previousInterval->getNextRefPosition() != nullptr);
6710
6711 #ifdef _TARGET_ARM_
6712     if (retVal && regRec->previousInterval->registerType == TYP_DOUBLE)
6713     {
6714         RegRecord* anotherHalfRegRec = findAnotherHalfRegRec(regRec);
6715
6716         retVal = retVal && anotherHalfRegRec->assignedInterval == nullptr;
6717     }
6718 #endif
6719
6720     return retVal;
6721 }
6722
6723 bool LinearScan::isAssignedToInterval(Interval* interval, RegRecord* regRec)
6724 {
6725     bool isAssigned = (interval->assignedReg == regRec);
6726 #ifdef _TARGET_ARM_
6727     isAssigned |= isSecondHalfReg(regRec, interval);
6728 #endif
6729     return isAssigned;
6730 }
6731
6732 //------------------------------------------------------------------------
6733 // processBlockStartLocations: Update var locations on entry to 'currentBlock' and clear constant
6734 //                             registers.
6735 //
6736 // Arguments:
6737 //    currentBlock   - the BasicBlock we are about to allocate registers for
6738 //    allocationPass - true if we are currently allocating registers (versus writing them back)
6739 //
6740 // Return Value:
6741 //    None
6742 //
6743 // Notes:
6744 //    During the allocation pass, we use the outVarToRegMap of the selected predecessor to
6745 //    determine the lclVar locations for the inVarToRegMap.
6746 //    During the resolution (write-back) pass, we only modify the inVarToRegMap in cases where
6747 //    a lclVar was spilled after the block had been completed.
6748 void LinearScan::processBlockStartLocations(BasicBlock* currentBlock, bool allocationPass)
6749 {
6750     // If we have no register candidates we should only call this method during allocation.
6751
6752     assert(enregisterLocalVars || allocationPass);
6753
6754     if (!enregisterLocalVars)
6755     {
6756         // Just clear any constant registers and return.
6757         for (regNumber reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
6758         {
6759             RegRecord* physRegRecord    = getRegisterRecord(reg);
6760             Interval*  assignedInterval = physRegRecord->assignedInterval;
6761
6762             if (assignedInterval != nullptr)
6763             {
6764                 assert(assignedInterval->isConstant);
6765                 physRegRecord->assignedInterval = nullptr;
6766             }
6767         }
6768         INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_START_BB, nullptr, REG_NA, currentBlock));
6769         return;
6770     }
6771
6772     unsigned    predBBNum         = blockInfo[currentBlock->bbNum].predBBNum;
6773     VarToRegMap predVarToRegMap   = getOutVarToRegMap(predBBNum);
6774     VarToRegMap inVarToRegMap     = getInVarToRegMap(currentBlock->bbNum);
6775     bool        hasCriticalInEdge = blockInfo[currentBlock->bbNum].hasCriticalInEdge;
6776
6777     VarSetOps::AssignNoCopy(compiler, currentLiveVars,
6778                             VarSetOps::Intersection(compiler, registerCandidateVars, currentBlock->bbLiveIn));
6779 #ifdef DEBUG
6780     if (getLsraExtendLifeTimes())
6781     {
6782         VarSetOps::AssignNoCopy(compiler, currentLiveVars, registerCandidateVars);
6783     }
6784     // If we are rotating register assignments at block boundaries, we want to make the
6785     // inactive registers available for the rotation.
6786     regMaskTP inactiveRegs = RBM_NONE;
6787 #endif // DEBUG
6788     regMaskTP       liveRegs = RBM_NONE;
6789     VarSetOps::Iter iter(compiler, currentLiveVars);
6790     unsigned        varIndex = 0;
6791     while (iter.NextElem(&varIndex))
6792     {
6793         unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
6794         if (!compiler->lvaTable[varNum].lvLRACandidate)
6795         {
6796             continue;
6797         }
6798         regNumber    targetReg;
6799         Interval*    interval        = getIntervalForLocalVar(varIndex);
6800         RefPosition* nextRefPosition = interval->getNextRefPosition();
6801         assert(nextRefPosition != nullptr);
6802
6803         if (allocationPass)
6804         {
6805             targetReg = getVarReg(predVarToRegMap, varIndex);
6806 #ifdef DEBUG
6807             regNumber newTargetReg = rotateBlockStartLocation(interval, targetReg, (~liveRegs | inactiveRegs));
6808             if (newTargetReg != targetReg)
6809             {
6810                 targetReg = newTargetReg;
6811                 setIntervalAsSplit(interval);
6812             }
6813 #endif // DEBUG
6814             setVarReg(inVarToRegMap, varIndex, targetReg);
6815         }
6816         else // !allocationPass (i.e. resolution/write-back pass)
6817         {
6818             targetReg = getVarReg(inVarToRegMap, varIndex);
6819             // There are four cases that we need to consider during the resolution pass:
6820             // 1. This variable had a register allocated initially, and it was not spilled in the RefPosition
6821             //    that feeds this block.  In this case, both targetReg and predVarToRegMap[varIndex] will be targetReg.
6822             // 2. This variable had not been spilled prior to the end of predBB, but was later spilled, so
6823             //    predVarToRegMap[varIndex] will be REG_STK, but targetReg is its former allocated value.
6824             //    In this case, we will normally change it to REG_STK.  We will update its "spilled" status when we
6825             //    encounter it in resolveLocalRef().
6826             // 2a. If the next RefPosition is marked as a copyReg, we need to retain the allocated register.  This is
6827             //     because the copyReg RefPosition will not have recorded the "home" register, yet downstream
6828             //     RefPositions rely on the correct "home" register.
6829             // 3. This variable was spilled before we reached the end of predBB.  In this case, both targetReg and
6830             //    predVarToRegMap[varIndex] will be REG_STK, and the next RefPosition will have been marked
6831             //    as reload during allocation time if necessary (note that by the time we actually reach the next
6832             //    RefPosition, we may be using a different predecessor, at which it is still in a register).
6833             // 4. This variable was spilled during the allocation of this block, so targetReg is REG_STK
6834             //    (because we set inVarToRegMap at the time we spilled it), but predVarToRegMap[varIndex]
6835             //    is not REG_STK.  We retain the REG_STK value in the inVarToRegMap.
6836             if (targetReg != REG_STK)
6837             {
6838                 if (getVarReg(predVarToRegMap, varIndex) != REG_STK)
6839                 {
6840                     // Case #1 above.
6841                     assert(getVarReg(predVarToRegMap, varIndex) == targetReg ||
6842                            getLsraBlockBoundaryLocations() == LSRA_BLOCK_BOUNDARY_ROTATE);
6843                 }
6844                 else if (!nextRefPosition->copyReg)
6845                 {
6846                     // case #2 above.
6847                     setVarReg(inVarToRegMap, varIndex, REG_STK);
6848                     targetReg = REG_STK;
6849                 }
6850                 // Else case 2a. - retain targetReg.
6851             }
6852             // Else case #3 or #4, we retain targetReg and nothing further to do or assert.
6853         }
6854         if (interval->physReg == targetReg)
6855         {
6856             if (interval->isActive)
6857             {
6858                 assert(targetReg != REG_STK);
6859                 assert(interval->assignedReg != nullptr && interval->assignedReg->regNum == targetReg &&
6860                        interval->assignedReg->assignedInterval == interval);
6861                 liveRegs |= genRegMask(targetReg);
6862                 continue;
6863             }
6864         }
6865         else if (interval->physReg != REG_NA)
6866         {
6867             // This can happen if we are using the locations from a basic block other than the
6868             // immediately preceding one - where the variable was in a different location.
6869             if (targetReg != REG_STK)
6870             {
6871                 // Unassign it from the register (it will get a new register below).
6872                 if (interval->assignedReg != nullptr && interval->assignedReg->assignedInterval == interval)
6873                 {
6874                     interval->isActive = false;
6875                     unassignPhysReg(getRegisterRecord(interval->physReg), nullptr);
6876                 }
6877                 else
6878                 {
6879                     // This interval was live in this register the last time we saw a reference to it,
6880                     // but has since been displaced.
6881                     interval->physReg = REG_NA;
6882                 }
6883             }
6884             else if (allocationPass)
6885             {
6886                 // Keep the register assignment - if another var has it, it will get unassigned.
6887                 // Otherwise, resolution will fix it up later, and it will be more
6888                 // likely to match other assignments this way.
6889                 interval->isActive = true;
6890                 liveRegs |= genRegMask(interval->physReg);
6891                 INDEBUG(inactiveRegs |= genRegMask(interval->physReg));
6892                 setVarReg(inVarToRegMap, varIndex, interval->physReg);
6893             }
6894             else
6895             {
6896                 interval->physReg = REG_NA;
6897             }
6898         }
6899         if (targetReg != REG_STK)
6900         {
6901             RegRecord* targetRegRecord = getRegisterRecord(targetReg);
6902             liveRegs |= genRegMask(targetReg);
6903             if (!interval->isActive)
6904             {
6905                 interval->isActive    = true;
6906                 interval->physReg     = targetReg;
6907                 interval->assignedReg = targetRegRecord;
6908             }
6909             Interval* assignedInterval = targetRegRecord->assignedInterval;
6910             if (assignedInterval != interval)
6911             {
6912                 // Is there another interval currently assigned to this register?  If so unassign it.
6913                 if (assignedInterval != nullptr)
6914                 {
6915                     if (isAssignedToInterval(assignedInterval, targetRegRecord))
6916                     {
6917                         regNumber assignedRegNum = assignedInterval->assignedReg->regNum;
6918
6919                         // If the interval is active, it will be set to active when we reach its new
6920                         // register assignment (which we must not yet have done, or it wouldn't still be
6921                         // assigned to this register).
6922                         assignedInterval->isActive = false;
6923                         unassignPhysReg(assignedInterval->assignedReg, nullptr);
6924                         if (allocationPass && assignedInterval->isLocalVar &&
6925                             inVarToRegMap[assignedInterval->getVarIndex(compiler)] == assignedRegNum)
6926                         {
6927                             inVarToRegMap[assignedInterval->getVarIndex(compiler)] = REG_STK;
6928                         }
6929                     }
6930                     else
6931                     {
6932                         // This interval is no longer assigned to this register.
6933                         updateAssignedInterval(targetRegRecord, nullptr, assignedInterval->registerType);
6934                     }
6935                 }
6936                 assignPhysReg(targetRegRecord, interval);
6937             }
6938             if (interval->recentRefPosition != nullptr && !interval->recentRefPosition->copyReg &&
6939                 interval->recentRefPosition->registerAssignment != genRegMask(targetReg))
6940             {
6941                 interval->getNextRefPosition()->outOfOrder = true;
6942             }
6943         }
6944     }
6945
6946     // Unassign any registers that are no longer live.
6947     for (regNumber reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
6948     {
6949         if ((liveRegs & genRegMask(reg)) == 0)
6950         {
6951             RegRecord* physRegRecord    = getRegisterRecord(reg);
6952             Interval*  assignedInterval = physRegRecord->assignedInterval;
6953
6954             if (assignedInterval != nullptr)
6955             {
6956                 assert(assignedInterval->isLocalVar || assignedInterval->isConstant);
6957
6958                 if (!assignedInterval->isConstant && assignedInterval->assignedReg == physRegRecord)
6959                 {
6960                     assignedInterval->isActive = false;
6961                     if (assignedInterval->getNextRefPosition() == nullptr)
6962                     {
6963                         unassignPhysReg(physRegRecord, nullptr);
6964                     }
6965                     inVarToRegMap[assignedInterval->getVarIndex(compiler)] = REG_STK;
6966                 }
6967                 else
6968                 {
6969                     // This interval may still be active, but was in another register in an
6970                     // intervening block.
6971                     updateAssignedInterval(physRegRecord, nullptr, assignedInterval->registerType);
6972                 }
6973
6974 #ifdef _TARGET_ARM_
6975                 if (assignedInterval->registerType == TYP_DOUBLE)
6976                 {
6977                     // Skip next float register, because we already addressed a double register
6978                     assert(genIsValidDoubleReg(reg));
6979                     reg = REG_NEXT(reg);
6980                 }
6981 #endif // _TARGET_ARM_
6982             }
6983         }
6984 #ifdef _TARGET_ARM_
6985         else
6986         {
6987             RegRecord* physRegRecord    = getRegisterRecord(reg);
6988             Interval*  assignedInterval = physRegRecord->assignedInterval;
6989
6990             if (assignedInterval != nullptr && assignedInterval->registerType == TYP_DOUBLE)
6991             {
6992                 // Skip next float register, because we already addressed a double register
6993                 assert(genIsValidDoubleReg(reg));
6994                 reg = REG_NEXT(reg);
6995             }
6996         }
6997 #endif // _TARGET_ARM_
6998     }
6999     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_START_BB, nullptr, REG_NA, currentBlock));
7000 }
7001
7002 //------------------------------------------------------------------------
7003 // processBlockEndLocations: Record the variables occupying registers after completing the current block.
7004 //
7005 // Arguments:
7006 //    currentBlock - the block we have just completed.
7007 //
7008 // Return Value:
7009 //    None
7010 //
7011 // Notes:
7012 //    This must be called both during the allocation and resolution (write-back) phases.
7013 //    This is because we need to have the outVarToRegMap locations in order to set the locations
7014 //    at successor blocks during allocation time, but if lclVars are spilled after a block has been
7015 //    completed, we need to record the REG_STK location for those variables at resolution time.
7016
7017 void LinearScan::processBlockEndLocations(BasicBlock* currentBlock)
7018 {
7019     assert(currentBlock != nullptr && currentBlock->bbNum == curBBNum);
7020     VarToRegMap outVarToRegMap = getOutVarToRegMap(curBBNum);
7021
7022     VarSetOps::AssignNoCopy(compiler, currentLiveVars,
7023                             VarSetOps::Intersection(compiler, registerCandidateVars, currentBlock->bbLiveOut));
7024 #ifdef DEBUG
7025     if (getLsraExtendLifeTimes())
7026     {
7027         VarSetOps::Assign(compiler, currentLiveVars, registerCandidateVars);
7028     }
7029 #endif // DEBUG
7030     regMaskTP       liveRegs = RBM_NONE;
7031     VarSetOps::Iter iter(compiler, currentLiveVars);
7032     unsigned        varIndex = 0;
7033     while (iter.NextElem(&varIndex))
7034     {
7035         Interval* interval = getIntervalForLocalVar(varIndex);
7036         if (interval->isActive)
7037         {
7038             assert(interval->physReg != REG_NA && interval->physReg != REG_STK);
7039             setVarReg(outVarToRegMap, varIndex, interval->physReg);
7040         }
7041         else
7042         {
7043             outVarToRegMap[varIndex] = REG_STK;
7044         }
7045     }
7046     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_END_BB));
7047 }
7048
7049 #ifdef DEBUG
7050 void LinearScan::dumpRefPositions(const char* str)
7051 {
7052     printf("------------\n");
7053     printf("REFPOSITIONS %s: \n", str);
7054     printf("------------\n");
7055     for (auto& refPos : refPositions)
7056     {
7057         refPos.dump();
7058     }
7059 }
7060 #endif // DEBUG
7061
7062 bool LinearScan::registerIsFree(regNumber regNum, RegisterType regType)
7063 {
7064     RegRecord* physRegRecord = getRegisterRecord(regNum);
7065
7066     bool isFree = physRegRecord->isFree();
7067
7068 #ifdef _TARGET_ARM_
7069     if (isFree && regType == TYP_DOUBLE)
7070     {
7071         isFree = getRegisterRecord(REG_NEXT(regNum))->isFree();
7072     }
7073 #endif // _TARGET_ARM_
7074
7075     return isFree;
7076 }
7077
7078 //------------------------------------------------------------------------
7079 // LinearScan::freeRegister: Make a register available for use
7080 //
7081 // Arguments:
7082 //    physRegRecord - the RegRecord for the register to be freed.
7083 //
7084 // Return Value:
7085 //    None.
7086 //
7087 // Assumptions:
7088 //    None.
7089 //    It may be that the RegRecord has already been freed, e.g. due to a kill,
7090 //    in which case this method has no effect.
7091 //
7092 // Notes:
7093 //    If there is currently an Interval assigned to this register, and it has
7094 //    more references (i.e. this is a local last-use, but more uses and/or
7095 //    defs remain), it will remain assigned to the physRegRecord.  However, since
7096 //    it is marked inactive, the register will be available, albeit less desirable
7097 //    to allocate.
7098 void LinearScan::freeRegister(RegRecord* physRegRecord)
7099 {
7100     Interval* assignedInterval = physRegRecord->assignedInterval;
7101     // It may have already been freed by a "Kill"
7102     if (assignedInterval != nullptr)
7103     {
7104         assignedInterval->isActive = false;
7105         // If this is a constant node, that we may encounter again (e.g. constant),
7106         // don't unassign it until we need the register.
7107         if (!assignedInterval->isConstant)
7108         {
7109             RefPosition* nextRefPosition = assignedInterval->getNextRefPosition();
7110             // Unassign the register only if there are no more RefPositions, or the next
7111             // one is a def.  Note that the latter condition doesn't actually ensure that
7112             // there aren't subsequent uses that could be reached by a def in the assigned
7113             // register, but is merely a heuristic to avoid tying up the register (or using
7114             // it when it's non-optimal).  A better alternative would be to use SSA, so that
7115             // we wouldn't unnecessarily link separate live ranges to the same register.
7116             if (nextRefPosition == nullptr || RefTypeIsDef(nextRefPosition->refType))
7117             {
7118 #ifdef _TARGET_ARM_
7119                 assert((assignedInterval->registerType != TYP_DOUBLE) || genIsValidDoubleReg(physRegRecord->regNum));
7120 #endif // _TARGET_ARM_
7121                 unassignPhysReg(physRegRecord, nullptr);
7122             }
7123         }
7124     }
7125 }
7126
7127 void LinearScan::freeRegisters(regMaskTP regsToFree)
7128 {
7129     if (regsToFree == RBM_NONE)
7130     {
7131         return;
7132     }
7133
7134     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_FREE_REGS));
7135     while (regsToFree != RBM_NONE)
7136     {
7137         regMaskTP nextRegBit = genFindLowestBit(regsToFree);
7138         regsToFree &= ~nextRegBit;
7139         regNumber nextReg = genRegNumFromMask(nextRegBit);
7140         freeRegister(getRegisterRecord(nextReg));
7141     }
7142 }
7143
7144 // Actual register allocation, accomplished by iterating over all of the previously
7145 // constructed Intervals
7146 // Loosely based on raAssignVars()
7147 //
7148 void LinearScan::allocateRegisters()
7149 {
7150     JITDUMP("*************** In LinearScan::allocateRegisters()\n");
7151     DBEXEC(VERBOSE, lsraDumpIntervals("before allocateRegisters"));
7152
7153     // at start, nothing is active except for register args
7154     for (auto& interval : intervals)
7155     {
7156         Interval* currentInterval          = &interval;
7157         currentInterval->recentRefPosition = nullptr;
7158         currentInterval->isActive          = false;
7159         if (currentInterval->isLocalVar)
7160         {
7161             LclVarDsc* varDsc = currentInterval->getLocalVar(compiler);
7162             if (varDsc->lvIsRegArg && currentInterval->firstRefPosition != nullptr)
7163             {
7164                 currentInterval->isActive = true;
7165             }
7166         }
7167     }
7168
7169     for (regNumber reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
7170     {
7171         getRegisterRecord(reg)->recentRefPosition = nullptr;
7172         getRegisterRecord(reg)->isActive          = false;
7173     }
7174
7175 #ifdef DEBUG
7176     regNumber lastAllocatedReg = REG_NA;
7177     if (VERBOSE)
7178     {
7179         dumpRefPositions("BEFORE ALLOCATION");
7180         dumpVarRefPositions("BEFORE ALLOCATION");
7181
7182         printf("\n\nAllocating Registers\n"
7183                "--------------------\n");
7184         if (dumpTerse)
7185         {
7186             dumpRegRecordHeader();
7187             // Now print an empty indent
7188             printf(indentFormat, "");
7189         }
7190     }
7191 #endif // DEBUG
7192
7193     BasicBlock* currentBlock = nullptr;
7194
7195     LsraLocation prevLocation    = MinLocation;
7196     regMaskTP    regsToFree      = RBM_NONE;
7197     regMaskTP    delayRegsToFree = RBM_NONE;
7198
7199     // This is the most recent RefPosition for which a register was allocated
7200     // - currently only used for DEBUG but maintained in non-debug, for clarity of code
7201     //   (and will be optimized away because in non-debug spillAlways() unconditionally returns false)
7202     RefPosition* lastAllocatedRefPosition = nullptr;
7203
7204     bool handledBlockEnd = false;
7205
7206     for (auto& refPosition : refPositions)
7207     {
7208         RefPosition* currentRefPosition = &refPosition;
7209
7210 #ifdef DEBUG
7211         // Set the activeRefPosition to null until we're done with any boundary handling.
7212         activeRefPosition = nullptr;
7213         if (VERBOSE)
7214         {
7215             if (dumpTerse)
7216             {
7217                 // We're really dumping the RegRecords "after" the previous RefPosition, but it's more convenient
7218                 // to do this here, since there are a number of "continue"s in this loop.
7219                 dumpRegRecords();
7220             }
7221             else
7222             {
7223                 printf("\n");
7224             }
7225         }
7226 #endif // DEBUG
7227
7228         // This is the previousRefPosition of the current Referent, if any
7229         RefPosition* previousRefPosition = nullptr;
7230
7231         Interval*      currentInterval = nullptr;
7232         Referenceable* currentReferent = nullptr;
7233         bool           isInternalRef   = false;
7234         RefType        refType         = currentRefPosition->refType;
7235
7236         currentReferent = currentRefPosition->referent;
7237
7238         if (spillAlways() && lastAllocatedRefPosition != nullptr && !lastAllocatedRefPosition->isPhysRegRef &&
7239             !lastAllocatedRefPosition->getInterval()->isInternal &&
7240             (RefTypeIsDef(lastAllocatedRefPosition->refType) || lastAllocatedRefPosition->getInterval()->isLocalVar))
7241         {
7242             assert(lastAllocatedRefPosition->registerAssignment != RBM_NONE);
7243             RegRecord* regRecord = lastAllocatedRefPosition->getInterval()->assignedReg;
7244             unassignPhysReg(regRecord, lastAllocatedRefPosition);
7245             // Now set lastAllocatedRefPosition to null, so that we don't try to spill it again
7246             lastAllocatedRefPosition = nullptr;
7247         }
7248
7249         // We wait to free any registers until we've completed all the
7250         // uses for the current node.
7251         // This avoids reusing registers too soon.
7252         // We free before the last true def (after all the uses & internal
7253         // registers), and then again at the beginning of the next node.
7254         // This is made easier by assigning two LsraLocations per node - one
7255         // for all the uses, internal registers & all but the last def, and
7256         // another for the final def (if any).
7257
7258         LsraLocation currentLocation = currentRefPosition->nodeLocation;
7259
7260         if ((regsToFree | delayRegsToFree) != RBM_NONE)
7261         {
7262             bool doFreeRegs = false;
7263             // Free at a new location, or at a basic block boundary
7264             if (currentLocation > prevLocation || refType == RefTypeBB)
7265             {
7266                 doFreeRegs = true;
7267             }
7268
7269             if (doFreeRegs)
7270             {
7271                 freeRegisters(regsToFree);
7272                 regsToFree      = delayRegsToFree;
7273                 delayRegsToFree = RBM_NONE;
7274             }
7275         }
7276         prevLocation = currentLocation;
7277
7278         // get previous refposition, then current refpos is the new previous
7279         if (currentReferent != nullptr)
7280         {
7281             previousRefPosition                = currentReferent->recentRefPosition;
7282             currentReferent->recentRefPosition = currentRefPosition;
7283         }
7284         else
7285         {
7286             assert((refType == RefTypeBB) || (refType == RefTypeKillGCRefs));
7287         }
7288
7289         // For the purposes of register resolution, we handle the DummyDefs before
7290         // the block boundary - so the RefTypeBB is after all the DummyDefs.
7291         // However, for the purposes of allocation, we want to handle the block
7292         // boundary first, so that we can free any registers occupied by lclVars
7293         // that aren't live in the next block and make them available for the
7294         // DummyDefs.
7295
7296         if (!handledBlockEnd && (refType == RefTypeBB || refType == RefTypeDummyDef))
7297         {
7298             // Free any delayed regs (now in regsToFree) before processing the block boundary
7299             freeRegisters(regsToFree);
7300             regsToFree         = RBM_NONE;
7301             handledBlockEnd    = true;
7302             curBBStartLocation = currentRefPosition->nodeLocation;
7303             if (currentBlock == nullptr)
7304             {
7305                 currentBlock = startBlockSequence();
7306             }
7307             else
7308             {
7309                 processBlockEndAllocation(currentBlock);
7310                 currentBlock = moveToNextBlock();
7311             }
7312 #ifdef DEBUG
7313             if (VERBOSE && currentBlock != nullptr && !dumpTerse)
7314             {
7315                 currentBlock->dspBlockHeader(compiler);
7316                 printf("\n");
7317             }
7318 #endif // DEBUG
7319         }
7320
7321 #ifdef DEBUG
7322         activeRefPosition = currentRefPosition;
7323         if (VERBOSE)
7324         {
7325             if (dumpTerse)
7326             {
7327                 dumpRefPositionShort(currentRefPosition, currentBlock);
7328             }
7329             else
7330             {
7331                 currentRefPosition->dump();
7332             }
7333         }
7334 #endif // DEBUG
7335
7336         if (refType == RefTypeBB)
7337         {
7338             handledBlockEnd = false;
7339             continue;
7340         }
7341
7342         if (refType == RefTypeKillGCRefs)
7343         {
7344             spillGCRefs(currentRefPosition);
7345             continue;
7346         }
7347
7348         // If this is a FixedReg, disassociate any inactive constant interval from this register.
7349         // Otherwise, do nothing.
7350         if (refType == RefTypeFixedReg)
7351         {
7352             RegRecord* regRecord        = currentRefPosition->getReg();
7353             Interval*  assignedInterval = regRecord->assignedInterval;
7354
7355             if (assignedInterval != nullptr && !assignedInterval->isActive && assignedInterval->isConstant)
7356             {
7357                 regRecord->assignedInterval = nullptr;
7358
7359 #ifdef _TARGET_ARM_
7360                 // Update overlapping floating point register for TYP_DOUBLE
7361                 if (assignedInterval->registerType == TYP_DOUBLE)
7362                 {
7363                     regRecord        = getRegisterRecord(REG_NEXT(regRecord->regNum));
7364                     assignedInterval = regRecord->assignedInterval;
7365
7366                     assert(assignedInterval != nullptr && !assignedInterval->isActive && assignedInterval->isConstant);
7367                     regRecord->assignedInterval = nullptr;
7368                 }
7369 #endif
7370             }
7371             INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_FIXED_REG, nullptr, currentRefPosition->assignedReg()));
7372             continue;
7373         }
7374
7375         // If this is an exposed use, do nothing - this is merely a placeholder to attempt to
7376         // ensure that a register is allocated for the full lifetime.  The resolution logic
7377         // will take care of moving to the appropriate register if needed.
7378
7379         if (refType == RefTypeExpUse)
7380         {
7381             INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_EXP_USE));
7382             continue;
7383         }
7384
7385         regNumber assignedRegister = REG_NA;
7386
7387         if (currentRefPosition->isIntervalRef())
7388         {
7389             currentInterval  = currentRefPosition->getInterval();
7390             assignedRegister = currentInterval->physReg;
7391 #if DEBUG
7392             if (VERBOSE && !dumpTerse)
7393             {
7394                 currentInterval->dump();
7395             }
7396 #endif // DEBUG
7397
7398             // Identify the special cases where we decide up-front not to allocate
7399             bool allocate = true;
7400             bool didDump  = false;
7401
7402             if (refType == RefTypeParamDef || refType == RefTypeZeroInit)
7403             {
7404                 // For a ParamDef with a weighted refCount less than unity, don't enregister it at entry.
7405                 // TODO-CQ: Consider doing this only for stack parameters, since otherwise we may be needlessly
7406                 // inserting a store.
7407                 LclVarDsc* varDsc = currentInterval->getLocalVar(compiler);
7408                 assert(varDsc != nullptr);
7409                 if (refType == RefTypeParamDef && varDsc->lvRefCntWtd <= BB_UNITY_WEIGHT)
7410                 {
7411                     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_NO_ENTRY_REG_ALLOCATED, currentInterval));
7412                     didDump  = true;
7413                     allocate = false;
7414                     setIntervalAsSpilled(currentInterval);
7415                 }
7416                 // If it has no actual references, mark it as "lastUse"; since they're not actually part
7417                 // of any flow they won't have been marked during dataflow.  Otherwise, if we allocate a
7418                 // register we won't unassign it.
7419                 else if (currentRefPosition->nextRefPosition == nullptr)
7420                 {
7421                     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_ZERO_REF, currentInterval));
7422                     currentRefPosition->lastUse = true;
7423                 }
7424             }
7425 #ifdef FEATURE_SIMD
7426             else if (refType == RefTypeUpperVectorSaveDef || refType == RefTypeUpperVectorSaveUse)
7427             {
7428                 Interval* lclVarInterval = currentInterval->relatedInterval;
7429                 if (lclVarInterval->physReg == REG_NA)
7430                 {
7431                     allocate = false;
7432                 }
7433             }
7434 #endif // FEATURE_SIMD
7435
7436             if (allocate == false)
7437             {
7438                 if (assignedRegister != REG_NA)
7439                 {
7440                     unassignPhysReg(getRegisterRecord(assignedRegister), currentRefPosition);
7441                 }
7442                 else if (!didDump)
7443                 {
7444                     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_NO_REG_ALLOCATED, currentInterval));
7445                     didDump = true;
7446                 }
7447                 currentRefPosition->registerAssignment = RBM_NONE;
7448                 continue;
7449             }
7450
7451             if (currentInterval->isSpecialPutArg)
7452             {
7453                 assert(!currentInterval->isLocalVar);
7454                 Interval* srcInterval = currentInterval->relatedInterval;
7455                 assert(srcInterval->isLocalVar);
7456                 if (refType == RefTypeDef)
7457                 {
7458                     assert(srcInterval->recentRefPosition->nodeLocation == currentLocation - 1);
7459                     RegRecord* physRegRecord = srcInterval->assignedReg;
7460
7461                     // For a putarg_reg to be special, its next use location has to be the same
7462                     // as fixed reg's next kill location. Otherwise, if source lcl var's next use
7463                     // is after the kill of fixed reg but before putarg_reg's next use, fixed reg's
7464                     // kill would lead to spill of source but not the putarg_reg if it were treated
7465                     // as special.
7466                     if (srcInterval->isActive &&
7467                         genRegMask(srcInterval->physReg) == currentRefPosition->registerAssignment &&
7468                         currentInterval->getNextRefLocation() == physRegRecord->getNextRefLocation())
7469                     {
7470                         assert(physRegRecord->regNum == srcInterval->physReg);
7471
7472                         // Special putarg_reg acts as a pass-thru since both source lcl var
7473                         // and putarg_reg have the same register allocated.  Physical reg
7474                         // record of reg continue to point to source lcl var's interval
7475                         // instead of to putarg_reg's interval.  So if a spill of reg
7476                         // allocated to source lcl var happens, to reallocate to another
7477                         // tree node, before its use at call node it will lead to spill of
7478                         // lcl var instead of putarg_reg since physical reg record is pointing
7479                         // to lcl var's interval. As a result, arg reg would get trashed leading
7480                         // to bad codegen. The assumption here is that source lcl var of a
7481                         // special putarg_reg doesn't get spilled and re-allocated prior to
7482                         // its use at the call node.  This is ensured by marking physical reg
7483                         // record as busy until next kill.
7484                         physRegRecord->isBusyUntilNextKill = true;
7485                     }
7486                     else
7487                     {
7488                         currentInterval->isSpecialPutArg = false;
7489                     }
7490                 }
7491                 // If this is still a SpecialPutArg, continue;
7492                 if (currentInterval->isSpecialPutArg)
7493                 {
7494                     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_SPECIAL_PUTARG, currentInterval,
7495                                                     currentRefPosition->assignedReg()));
7496                     continue;
7497                 }
7498             }
7499
7500             if (assignedRegister == REG_NA && RefTypeIsUse(refType))
7501             {
7502                 currentRefPosition->reload = true;
7503                 INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_RELOAD, currentInterval, assignedRegister));
7504             }
7505         }
7506
7507         regMaskTP assignedRegBit = RBM_NONE;
7508         bool      isInRegister   = false;
7509         if (assignedRegister != REG_NA)
7510         {
7511             isInRegister   = true;
7512             assignedRegBit = genRegMask(assignedRegister);
7513             if (!currentInterval->isActive)
7514             {
7515                 // If this is a use, it must have started the block on the stack, but the register
7516                 // was available for use so we kept the association.
7517                 if (RefTypeIsUse(refType))
7518                 {
7519                     assert(enregisterLocalVars);
7520                     assert(inVarToRegMaps[curBBNum][currentInterval->getVarIndex(compiler)] == REG_STK &&
7521                            previousRefPosition->nodeLocation <= curBBStartLocation);
7522                     isInRegister = false;
7523                 }
7524                 else
7525                 {
7526                     currentInterval->isActive = true;
7527                 }
7528             }
7529             assert(currentInterval->assignedReg != nullptr &&
7530                    currentInterval->assignedReg->regNum == assignedRegister &&
7531                    currentInterval->assignedReg->assignedInterval == currentInterval);
7532         }
7533
7534         // If this is a physical register, we unconditionally assign it to itself!
7535         if (currentRefPosition->isPhysRegRef)
7536         {
7537             RegRecord* currentReg       = currentRefPosition->getReg();
7538             Interval*  assignedInterval = currentReg->assignedInterval;
7539
7540             if (assignedInterval != nullptr)
7541             {
7542                 unassignPhysReg(currentReg, assignedInterval->recentRefPosition);
7543             }
7544             currentReg->isActive = true;
7545             assignedRegister     = currentReg->regNum;
7546             assignedRegBit       = genRegMask(assignedRegister);
7547             if (refType == RefTypeKill)
7548             {
7549                 currentReg->isBusyUntilNextKill = false;
7550             }
7551         }
7552         else if (previousRefPosition != nullptr)
7553         {
7554             assert(previousRefPosition->nextRefPosition == currentRefPosition);
7555             assert(assignedRegister == REG_NA || assignedRegBit == previousRefPosition->registerAssignment ||
7556                    currentRefPosition->outOfOrder || previousRefPosition->copyReg ||
7557                    previousRefPosition->refType == RefTypeExpUse || currentRefPosition->refType == RefTypeDummyDef);
7558         }
7559         else if (assignedRegister != REG_NA)
7560         {
7561             // Handle the case where this is a preassigned register (i.e. parameter).
7562             // We don't want to actually use the preassigned register if it's not
7563             // going to cover the lifetime - but we had to preallocate it to ensure
7564             // that it remained live.
7565             // TODO-CQ: At some point we may want to refine the analysis here, in case
7566             // it might be beneficial to keep it in this reg for PART of the lifetime
7567             if (currentInterval->isLocalVar)
7568             {
7569                 regMaskTP preferences        = currentInterval->registerPreferences;
7570                 bool      keepAssignment     = true;
7571                 bool      matchesPreferences = (preferences & genRegMask(assignedRegister)) != RBM_NONE;
7572
7573                 // Will the assigned register cover the lifetime?  If not, does it at least
7574                 // meet the preferences for the next RefPosition?
7575                 RegRecord*   physRegRecord     = getRegisterRecord(currentInterval->physReg);
7576                 RefPosition* nextPhysRegRefPos = physRegRecord->getNextRefPosition();
7577                 if (nextPhysRegRefPos != nullptr &&
7578                     nextPhysRegRefPos->nodeLocation <= currentInterval->lastRefPosition->nodeLocation)
7579                 {
7580                     // Check to see if the existing assignment matches the preferences (e.g. callee save registers)
7581                     // and ensure that the next use of this localVar does not occur after the nextPhysRegRefPos
7582                     // There must be a next RefPosition, because we know that the Interval extends beyond the
7583                     // nextPhysRegRefPos.
7584                     RefPosition* nextLclVarRefPos = currentRefPosition->nextRefPosition;
7585                     assert(nextLclVarRefPos != nullptr);
7586                     if (!matchesPreferences || nextPhysRegRefPos->nodeLocation < nextLclVarRefPos->nodeLocation ||
7587                         physRegRecord->conflictingFixedRegReference(nextLclVarRefPos))
7588                     {
7589                         keepAssignment = false;
7590                     }
7591                 }
7592                 else if (refType == RefTypeParamDef && !matchesPreferences)
7593                 {
7594                     // Don't use the register, even if available, if it doesn't match the preferences.
7595                     // Note that this case is only for ParamDefs, for which we haven't yet taken preferences
7596                     // into account (we've just automatically got the initial location).  In other cases,
7597                     // we would already have put it in a preferenced register, if it was available.
7598                     // TODO-CQ: Consider expanding this to check availability - that would duplicate
7599                     // code here, but otherwise we may wind up in this register anyway.
7600                     keepAssignment = false;
7601                 }
7602
7603                 if (keepAssignment == false)
7604                 {
7605                     currentRefPosition->registerAssignment = allRegs(currentInterval->registerType);
7606                     unassignPhysRegNoSpill(physRegRecord);
7607
7608                     // If the preferences are currently set to just this register, reset them to allRegs
7609                     // of the appropriate type (just as we just reset the registerAssignment for this
7610                     // RefPosition.
7611                     // Otherwise, simply remove this register from the preferences, if it's there.
7612
7613                     if (currentInterval->registerPreferences == assignedRegBit)
7614                     {
7615                         currentInterval->registerPreferences = currentRefPosition->registerAssignment;
7616                     }
7617                     else
7618                     {
7619                         currentInterval->registerPreferences &= ~assignedRegBit;
7620                     }
7621
7622                     assignedRegister = REG_NA;
7623                     assignedRegBit   = RBM_NONE;
7624                 }
7625             }
7626         }
7627
7628         if (assignedRegister != REG_NA)
7629         {
7630             // If there is a conflicting fixed reference, insert a copy.
7631             RegRecord* physRegRecord = getRegisterRecord(assignedRegister);
7632             if (physRegRecord->conflictingFixedRegReference(currentRefPosition))
7633             {
7634                 // We may have already reassigned the register to the conflicting reference.
7635                 // If not, we need to unassign this interval.
7636                 if (physRegRecord->assignedInterval == currentInterval)
7637                 {
7638                     unassignPhysRegNoSpill(physRegRecord);
7639                 }
7640                 currentRefPosition->moveReg = true;
7641                 assignedRegister            = REG_NA;
7642                 setIntervalAsSplit(currentInterval);
7643                 INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_MOVE_REG, currentInterval, assignedRegister));
7644             }
7645             else if ((genRegMask(assignedRegister) & currentRefPosition->registerAssignment) != 0)
7646             {
7647                 currentRefPosition->registerAssignment = assignedRegBit;
7648                 if (!currentReferent->isActive)
7649                 {
7650                     // If we've got an exposed use at the top of a block, the
7651                     // interval might not have been active.  Otherwise if it's a use,
7652                     // the interval must be active.
7653                     if (refType == RefTypeDummyDef)
7654                     {
7655                         currentReferent->isActive = true;
7656                         assert(getRegisterRecord(assignedRegister)->assignedInterval == currentInterval);
7657                     }
7658                     else
7659                     {
7660                         currentRefPosition->reload = true;
7661                     }
7662                 }
7663                 INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_KEPT_ALLOCATION, currentInterval, assignedRegister));
7664             }
7665             else
7666             {
7667                 assert(currentInterval != nullptr);
7668
7669                 // It's already in a register, but not one we need.
7670                 if (!RefTypeIsDef(currentRefPosition->refType))
7671                 {
7672                     regNumber copyReg = assignCopyReg(currentRefPosition);
7673                     assert(copyReg != REG_NA);
7674                     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_COPY_REG, currentInterval, copyReg));
7675                     lastAllocatedRefPosition = currentRefPosition;
7676                     if (currentRefPosition->lastUse)
7677                     {
7678                         if (currentRefPosition->delayRegFree)
7679                         {
7680                             INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_LAST_USE_DELAYED, currentInterval,
7681                                                             assignedRegister));
7682                             delayRegsToFree |= (genRegMask(assignedRegister) | currentRefPosition->registerAssignment);
7683                         }
7684                         else
7685                         {
7686                             INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_LAST_USE, currentInterval, assignedRegister));
7687                             regsToFree |= (genRegMask(assignedRegister) | currentRefPosition->registerAssignment);
7688                         }
7689                     }
7690                     // If this is a tree temp (non-localVar) interval, we will need an explicit move.
7691                     if (!currentInterval->isLocalVar)
7692                     {
7693                         currentRefPosition->moveReg = true;
7694                         currentRefPosition->copyReg = false;
7695                     }
7696                     continue;
7697                 }
7698                 else
7699                 {
7700                     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_NEEDS_NEW_REG, nullptr, assignedRegister));
7701                     regsToFree |= genRegMask(assignedRegister);
7702                     // We want a new register, but we don't want this to be considered a spill.
7703                     assignedRegister = REG_NA;
7704                     if (physRegRecord->assignedInterval == currentInterval)
7705                     {
7706                         unassignPhysRegNoSpill(physRegRecord);
7707                     }
7708                 }
7709             }
7710         }
7711
7712         if (assignedRegister == REG_NA)
7713         {
7714             bool allocateReg = true;
7715
7716             if (currentRefPosition->AllocateIfProfitable())
7717             {
7718                 // We can avoid allocating a register if it is a the last use requiring a reload.
7719                 if (currentRefPosition->lastUse && currentRefPosition->reload)
7720                 {
7721                     allocateReg = false;
7722                 }
7723
7724 #ifdef DEBUG
7725                 // Under stress mode, don't attempt to allocate a reg to
7726                 // reg optional ref position.
7727                 if (allocateReg && regOptionalNoAlloc())
7728                 {
7729                     allocateReg = false;
7730                 }
7731 #endif
7732             }
7733
7734             if (allocateReg)
7735             {
7736                 // Try to allocate a register
7737                 assignedRegister = tryAllocateFreeReg(currentInterval, currentRefPosition);
7738             }
7739
7740             // If no register was found, and if the currentRefPosition must have a register,
7741             // then find a register to spill
7742             if (assignedRegister == REG_NA)
7743             {
7744 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
7745                 if (refType == RefTypeUpperVectorSaveDef)
7746                 {
7747                     // TODO-CQ: Determine whether copying to two integer callee-save registers would be profitable.
7748
7749                     // SaveDef position occurs after the Use of args and at the same location as Kill/Def
7750                     // positions of a call node.  But SaveDef position cannot use any of the arg regs as
7751                     // they are needed for call node.
7752                     currentRefPosition->registerAssignment =
7753                         (allRegs(TYP_FLOAT) & RBM_FLT_CALLEE_TRASH & ~RBM_FLTARG_REGS);
7754                     assignedRegister = tryAllocateFreeReg(currentInterval, currentRefPosition);
7755
7756                     // There MUST be caller-save registers available, because they have all just been killed.
7757                     // Amd64 Windows: xmm4-xmm5 are guaranteed to be available as xmm0-xmm3 are used for passing args.
7758                     // Amd64 Unix: xmm8-xmm15 are guaranteed to be avilable as xmm0-xmm7 are used for passing args.
7759                     // X86 RyuJIT Windows: xmm4-xmm7 are guanrateed to be available.
7760                     assert(assignedRegister != REG_NA);
7761
7762                     // Now, spill it.
7763                     // Note:
7764                     //   i) The reason we have to spill is that SaveDef position is allocated after the Kill positions
7765                     //      of the call node are processed.  Since callee-trash registers are killed by call node
7766                     //      we explicity spill and unassign the register.
7767                     //  ii) These will look a bit backward in the dump, but it's a pain to dump the alloc before the
7768                     //  spill).
7769                     unassignPhysReg(getRegisterRecord(assignedRegister), currentRefPosition);
7770                     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_ALLOC_REG, currentInterval, assignedRegister));
7771
7772                     // Now set assignedRegister to REG_NA again so that we don't re-activate it.
7773                     assignedRegister = REG_NA;
7774                 }
7775                 else
7776 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
7777                     if (currentRefPosition->RequiresRegister() || currentRefPosition->AllocateIfProfitable())
7778                 {
7779                     if (allocateReg)
7780                     {
7781                         assignedRegister = allocateBusyReg(currentInterval, currentRefPosition,
7782                                                            currentRefPosition->AllocateIfProfitable());
7783                     }
7784
7785                     if (assignedRegister != REG_NA)
7786                     {
7787                         INDEBUG(
7788                             dumpLsraAllocationEvent(LSRA_EVENT_ALLOC_SPILLED_REG, currentInterval, assignedRegister));
7789                     }
7790                     else
7791                     {
7792                         // This can happen only for those ref positions that are to be allocated
7793                         // only if profitable.
7794                         noway_assert(currentRefPosition->AllocateIfProfitable());
7795
7796                         currentRefPosition->registerAssignment = RBM_NONE;
7797                         currentRefPosition->reload             = false;
7798                         setIntervalAsSpilled(currentInterval);
7799
7800                         INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_NO_REG_ALLOCATED, currentInterval));
7801                     }
7802                 }
7803                 else
7804                 {
7805                     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_NO_REG_ALLOCATED, currentInterval));
7806                     currentRefPosition->registerAssignment = RBM_NONE;
7807                     currentInterval->isActive              = false;
7808                     setIntervalAsSpilled(currentInterval);
7809                 }
7810             }
7811 #ifdef DEBUG
7812             else
7813             {
7814                 if (VERBOSE)
7815                 {
7816                     if (currentInterval->isConstant && (currentRefPosition->treeNode != nullptr) &&
7817                         currentRefPosition->treeNode->IsReuseRegVal())
7818                     {
7819                         dumpLsraAllocationEvent(LSRA_EVENT_REUSE_REG, nullptr, assignedRegister, currentBlock);
7820                     }
7821                     else
7822                     {
7823                         dumpLsraAllocationEvent(LSRA_EVENT_ALLOC_REG, nullptr, assignedRegister, currentBlock);
7824                     }
7825                 }
7826             }
7827 #endif // DEBUG
7828
7829             if (refType == RefTypeDummyDef && assignedRegister != REG_NA)
7830             {
7831                 setInVarRegForBB(curBBNum, currentInterval->varNum, assignedRegister);
7832             }
7833
7834             // If we allocated a register, and this is a use of a spilled value,
7835             // it should have been marked for reload above.
7836             if (assignedRegister != REG_NA && RefTypeIsUse(refType) && !isInRegister)
7837             {
7838                 assert(currentRefPosition->reload);
7839             }
7840         }
7841
7842         // If we allocated a register, record it
7843         if (currentInterval != nullptr && assignedRegister != REG_NA)
7844         {
7845             assignedRegBit                         = genRegMask(assignedRegister);
7846             currentRefPosition->registerAssignment = assignedRegBit;
7847             currentInterval->physReg               = assignedRegister;
7848             regsToFree &= ~assignedRegBit; // we'll set it again later if it's dead
7849
7850             // If this interval is dead, free the register.
7851             // The interval could be dead if this is a user variable, or if the
7852             // node is being evaluated for side effects, or a call whose result
7853             // is not used, etc.
7854             if (currentRefPosition->lastUse || currentRefPosition->nextRefPosition == nullptr)
7855             {
7856                 assert(currentRefPosition->isIntervalRef());
7857
7858                 if (refType != RefTypeExpUse && currentRefPosition->nextRefPosition == nullptr)
7859                 {
7860                     if (currentRefPosition->delayRegFree)
7861                     {
7862                         delayRegsToFree |= assignedRegBit;
7863
7864                         INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_LAST_USE_DELAYED));
7865                     }
7866                     else
7867                     {
7868                         regsToFree |= assignedRegBit;
7869
7870                         INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_LAST_USE));
7871                     }
7872                 }
7873                 else
7874                 {
7875                     currentInterval->isActive = false;
7876                 }
7877             }
7878
7879             lastAllocatedRefPosition = currentRefPosition;
7880         }
7881     }
7882
7883     // Free registers to clear associated intervals for resolution phase
7884     CLANG_FORMAT_COMMENT_ANCHOR;
7885
7886 #ifdef DEBUG
7887     if (getLsraExtendLifeTimes())
7888     {
7889         // If we have extended lifetimes, we need to make sure all the registers are freed.
7890         for (int regNumIndex = 0; regNumIndex <= REG_FP_LAST; regNumIndex++)
7891         {
7892             RegRecord& regRecord = physRegs[regNumIndex];
7893             Interval*  interval  = regRecord.assignedInterval;
7894             if (interval != nullptr)
7895             {
7896                 interval->isActive = false;
7897                 unassignPhysReg(&regRecord, nullptr);
7898             }
7899         }
7900     }
7901     else
7902 #endif // DEBUG
7903     {
7904         freeRegisters(regsToFree | delayRegsToFree);
7905     }
7906
7907 #ifdef DEBUG
7908     if (VERBOSE)
7909     {
7910         if (dumpTerse)
7911         {
7912             // Dump the RegRecords after the last RefPosition is handled.
7913             dumpRegRecords();
7914             printf("\n");
7915         }
7916
7917         dumpRefPositions("AFTER ALLOCATION");
7918         dumpVarRefPositions("AFTER ALLOCATION");
7919
7920         // Dump the intervals that remain active
7921         printf("Active intervals at end of allocation:\n");
7922
7923         // We COULD just reuse the intervalIter from above, but ArrayListIterator doesn't
7924         // provide a Reset function (!) - we'll probably replace this so don't bother
7925         // adding it
7926
7927         for (auto& interval : intervals)
7928         {
7929             if (interval.isActive)
7930             {
7931                 printf("Active ");
7932                 interval.dump();
7933             }
7934         }
7935
7936         printf("\n");
7937     }
7938 #endif // DEBUG
7939 }
7940
7941 //-----------------------------------------------------------------------------
7942 // updateAssignedInterval: Update assigned interval of register.
7943 //
7944 // Arguments:
7945 //    reg      -    register to be updated
7946 //    interval -    interval to be assigned
7947 //    regType  -    regsiter type
7948 //
7949 // Return Value:
7950 //    None
7951 //
7952 // Assumptions:
7953 //    For ARM32, when "regType" is TYP_DOUBLE, "reg" should be a even-numbered
7954 //    float register, i.e. lower half of double register.
7955 //
7956 // Note:
7957 //    For ARM32, two float registers consisting a double register are updated
7958 //    together when "regType" is TYP_DOUBLE.
7959 //
7960 void LinearScan::updateAssignedInterval(RegRecord* reg, Interval* interval, RegisterType regType)
7961 {
7962     reg->assignedInterval = interval;
7963
7964 #ifdef _TARGET_ARM_
7965     // Update overlapping floating point register for TYP_DOUBLE
7966     if (regType == TYP_DOUBLE)
7967     {
7968         assert(genIsValidDoubleReg(reg->regNum));
7969
7970         RegRecord* anotherHalfReg = findAnotherHalfRegRec(reg);
7971
7972         anotherHalfReg->assignedInterval = interval;
7973     }
7974 #endif
7975 }
7976
7977 //-----------------------------------------------------------------------------
7978 // updatePreviousInterval: Update previous interval of register.
7979 //
7980 // Arguments:
7981 //    reg      -    register to be updated
7982 //    interval -    interval to be assigned
7983 //    regType  -    regsiter type
7984 //
7985 // Return Value:
7986 //    None
7987 //
7988 // Assumptions:
7989 //    For ARM32, when "regType" is TYP_DOUBLE, "reg" should be a even-numbered
7990 //    float register, i.e. lower half of double register.
7991 //
7992 // Note:
7993 //    For ARM32, two float registers consisting a double register are updated
7994 //    together when "regType" is TYP_DOUBLE.
7995 //
7996 void LinearScan::updatePreviousInterval(RegRecord* reg, Interval* interval, RegisterType regType)
7997 {
7998     reg->previousInterval = interval;
7999
8000 #ifdef _TARGET_ARM_
8001     // Update overlapping floating point register for TYP_DOUBLE
8002     if (regType == TYP_DOUBLE)
8003     {
8004         assert(genIsValidDoubleReg(reg->regNum));
8005
8006         RegRecord* anotherHalfReg = findAnotherHalfRegRec(reg);
8007
8008         anotherHalfReg->previousInterval = interval;
8009     }
8010 #endif
8011 }
8012
8013 // LinearScan::resolveLocalRef
8014 // Description:
8015 //      Update the graph for a local reference.
8016 //      Also, track the register (if any) that is currently occupied.
8017 // Arguments:
8018 //      treeNode: The lclVar that's being resolved
8019 //      currentRefPosition: the RefPosition associated with the treeNode
8020 //
8021 // Details:
8022 // This method is called for each local reference, during the resolveRegisters
8023 // phase of LSRA.  It is responsible for keeping the following in sync:
8024 //   - varDsc->lvRegNum (and lvOtherReg) contain the unique register location.
8025 //     If it is not in the same register through its lifetime, it is set to REG_STK.
8026 //   - interval->physReg is set to the assigned register
8027 //     (i.e. at the code location which is currently being handled by resolveRegisters())
8028 //     - interval->isActive is true iff the interval is live and occupying a register
8029 //     - interval->isSpilled should have already been set to true if the interval is EVER spilled
8030 //     - interval->isSplit is set to true if the interval does not occupy the same
8031 //       register throughout the method
8032 //   - RegRecord->assignedInterval points to the interval which currently occupies
8033 //     the register
8034 //   - For each lclVar node:
8035 //     - gtRegNum/gtRegPair is set to the currently allocated register(s).
8036 //     - GTF_SPILLED is set on a use if it must be reloaded prior to use.
8037 //     - GTF_SPILL is set if it must be spilled after use.
8038 //
8039 // A copyReg is an ugly case where the variable must be in a specific (fixed) register,
8040 // but it currently resides elsewhere.  The register allocator must track the use of the
8041 // fixed register, but it marks the lclVar node with the register it currently lives in
8042 // and the code generator does the necessary move.
8043 //
8044 // Before beginning, the varDsc for each parameter must be set to its initial location.
8045 //
8046 // NICE: Consider tracking whether an Interval is always in the same location (register/stack)
8047 // in which case it will require no resolution.
8048 //
8049 void LinearScan::resolveLocalRef(BasicBlock* block, GenTreePtr treeNode, RefPosition* currentRefPosition)
8050 {
8051     assert((block == nullptr) == (treeNode == nullptr));
8052     assert(enregisterLocalVars);
8053
8054     // Is this a tracked local?  Or just a register allocated for loading
8055     // a non-tracked one?
8056     Interval* interval = currentRefPosition->getInterval();
8057     if (!interval->isLocalVar)
8058     {
8059         return;
8060     }
8061     interval->recentRefPosition = currentRefPosition;
8062     LclVarDsc* varDsc           = interval->getLocalVar(compiler);
8063
8064     // NOTE: we set the GTF_VAR_DEATH flag here unless we are extending lifetimes, in which case we write
8065     // this bit in checkLastUses. This is a bit of a hack, but is necessary because codegen requires
8066     // accurate last use info that is not reflected in the lastUse bit on ref positions when we are extending
8067     // lifetimes. See also the comments in checkLastUses.
8068     if ((treeNode != nullptr) && !extendLifetimes())
8069     {
8070         if (currentRefPosition->lastUse)
8071         {
8072             treeNode->gtFlags |= GTF_VAR_DEATH;
8073         }
8074         else
8075         {
8076             treeNode->gtFlags &= ~GTF_VAR_DEATH;
8077         }
8078     }
8079
8080     if (currentRefPosition->registerAssignment == RBM_NONE)
8081     {
8082         assert(!currentRefPosition->RequiresRegister());
8083         assert(interval->isSpilled);
8084
8085         varDsc->lvRegNum = REG_STK;
8086         if (interval->assignedReg != nullptr && interval->assignedReg->assignedInterval == interval)
8087         {
8088             updateAssignedInterval(interval->assignedReg, nullptr, interval->registerType);
8089         }
8090         interval->assignedReg = nullptr;
8091         interval->physReg     = REG_NA;
8092         if (treeNode != nullptr)
8093         {
8094             treeNode->SetContained();
8095         }
8096
8097         return;
8098     }
8099
8100     // In most cases, assigned and home registers will be the same
8101     // The exception is the copyReg case, where we've assigned a register
8102     // for a specific purpose, but will be keeping the register assignment
8103     regNumber assignedReg = currentRefPosition->assignedReg();
8104     regNumber homeReg     = assignedReg;
8105
8106     // Undo any previous association with a physical register, UNLESS this
8107     // is a copyReg
8108     if (!currentRefPosition->copyReg)
8109     {
8110         regNumber oldAssignedReg = interval->physReg;
8111         if (oldAssignedReg != REG_NA && assignedReg != oldAssignedReg)
8112         {
8113             RegRecord* oldRegRecord = getRegisterRecord(oldAssignedReg);
8114             if (oldRegRecord->assignedInterval == interval)
8115             {
8116                 updateAssignedInterval(oldRegRecord, nullptr, interval->registerType);
8117             }
8118         }
8119     }
8120
8121     if (currentRefPosition->refType == RefTypeUse && !currentRefPosition->reload)
8122     {
8123         // Was this spilled after our predecessor was scheduled?
8124         if (interval->physReg == REG_NA)
8125         {
8126             assert(inVarToRegMaps[curBBNum][varDsc->lvVarIndex] == REG_STK);
8127             currentRefPosition->reload = true;
8128         }
8129     }
8130
8131     bool reload     = currentRefPosition->reload;
8132     bool spillAfter = currentRefPosition->spillAfter;
8133
8134     // In the reload case we either:
8135     // - Set the register to REG_STK if it will be referenced only from the home location, or
8136     // - Set the register to the assigned register and set GTF_SPILLED if it must be loaded into a register.
8137     if (reload)
8138     {
8139         assert(currentRefPosition->refType != RefTypeDef);
8140         assert(interval->isSpilled);
8141         varDsc->lvRegNum = REG_STK;
8142         if (!spillAfter)
8143         {
8144             interval->physReg = assignedReg;
8145         }
8146
8147         // If there is no treeNode, this must be a RefTypeExpUse, in
8148         // which case we did the reload already
8149         if (treeNode != nullptr)
8150         {
8151             treeNode->gtFlags |= GTF_SPILLED;
8152             if (spillAfter)
8153             {
8154                 if (currentRefPosition->AllocateIfProfitable())
8155                 {
8156                     // This is a use of lclVar that is flagged as reg-optional
8157                     // by lower/codegen and marked for both reload and spillAfter.
8158                     // In this case we can avoid unnecessary reload and spill
8159                     // by setting reg on lclVar to REG_STK and reg on tree node
8160                     // to REG_NA.  Codegen will generate the code by considering
8161                     // it as a contained memory operand.
8162                     //
8163                     // Note that varDsc->lvRegNum is already to REG_STK above.
8164                     interval->physReg  = REG_NA;
8165                     treeNode->gtRegNum = REG_NA;
8166                     treeNode->gtFlags &= ~GTF_SPILLED;
8167                     treeNode->SetContained();
8168                 }
8169                 else
8170                 {
8171                     treeNode->gtFlags |= GTF_SPILL;
8172                 }
8173             }
8174         }
8175         else
8176         {
8177             assert(currentRefPosition->refType == RefTypeExpUse);
8178         }
8179     }
8180     else if (spillAfter && !RefTypeIsUse(currentRefPosition->refType))
8181     {
8182         // In the case of a pure def, don't bother spilling - just assign it to the
8183         // stack.  However, we need to remember that it was spilled.
8184
8185         assert(interval->isSpilled);
8186         varDsc->lvRegNum  = REG_STK;
8187         interval->physReg = REG_NA;
8188         if (treeNode != nullptr)
8189         {
8190             treeNode->gtRegNum = REG_NA;
8191         }
8192     }
8193     else
8194     {
8195         // Not reload and Not pure-def that's spillAfter
8196
8197         if (currentRefPosition->copyReg || currentRefPosition->moveReg)
8198         {
8199             // For a copyReg or moveReg, we have two cases:
8200             //  - In the first case, we have a fixedReg - i.e. a register which the code
8201             //    generator is constrained to use.
8202             //    The code generator will generate the appropriate move to meet the requirement.
8203             //  - In the second case, we were forced to use a different register because of
8204             //    interference (or JitStressRegs).
8205             //    In this case, we generate a GT_COPY.
8206             // In either case, we annotate the treeNode with the register in which the value
8207             // currently lives.  For moveReg, the homeReg is the new register (as assigned above).
8208             // But for copyReg, the homeReg remains unchanged.
8209
8210             assert(treeNode != nullptr);
8211             treeNode->gtRegNum = interval->physReg;
8212
8213             if (currentRefPosition->copyReg)
8214             {
8215                 homeReg = interval->physReg;
8216             }
8217             else
8218             {
8219                 assert(interval->isSplit);
8220                 interval->physReg = assignedReg;
8221             }
8222
8223             if (!currentRefPosition->isFixedRegRef || currentRefPosition->moveReg)
8224             {
8225                 // This is the second case, where we need to generate a copy
8226                 insertCopyOrReload(block, treeNode, currentRefPosition->getMultiRegIdx(), currentRefPosition);
8227             }
8228         }
8229         else
8230         {
8231             interval->physReg = assignedReg;
8232
8233             if (!interval->isSpilled && !interval->isSplit)
8234             {
8235                 if (varDsc->lvRegNum != REG_STK)
8236                 {
8237                     // If the register assignments don't match, then this interval is split.
8238                     if (varDsc->lvRegNum != assignedReg)
8239                     {
8240                         setIntervalAsSplit(interval);
8241                         varDsc->lvRegNum = REG_STK;
8242                     }
8243                 }
8244                 else
8245                 {
8246                     varDsc->lvRegNum = assignedReg;
8247                 }
8248             }
8249         }
8250         if (spillAfter)
8251         {
8252             if (treeNode != nullptr)
8253             {
8254                 treeNode->gtFlags |= GTF_SPILL;
8255             }
8256             assert(interval->isSpilled);
8257             interval->physReg = REG_NA;
8258             varDsc->lvRegNum  = REG_STK;
8259         }
8260     }
8261
8262     // Update the physRegRecord for the register, so that we know what vars are in
8263     // regs at the block boundaries
8264     RegRecord* physRegRecord = getRegisterRecord(homeReg);
8265     if (spillAfter || currentRefPosition->lastUse)
8266     {
8267         interval->isActive    = false;
8268         interval->assignedReg = nullptr;
8269         interval->physReg     = REG_NA;
8270
8271         updateAssignedInterval(physRegRecord, nullptr, interval->registerType);
8272     }
8273     else
8274     {
8275         interval->isActive    = true;
8276         interval->assignedReg = physRegRecord;
8277
8278         updateAssignedInterval(physRegRecord, interval, interval->registerType);
8279     }
8280 }
8281
8282 void LinearScan::writeRegisters(RefPosition* currentRefPosition, GenTree* tree)
8283 {
8284     lsraAssignRegToTree(tree, currentRefPosition->assignedReg(), currentRefPosition->getMultiRegIdx());
8285 }
8286
8287 //------------------------------------------------------------------------
8288 // insertCopyOrReload: Insert a copy in the case where a tree node value must be moved
8289 //   to a different register at the point of use (GT_COPY), or it is reloaded to a different register
8290 //   than the one it was spilled from (GT_RELOAD).
8291 //
8292 // Arguments:
8293 //    block             - basic block in which GT_COPY/GT_RELOAD is inserted.
8294 //    tree              - This is the node to copy or reload.
8295 //                        Insert copy or reload node between this node and its parent.
8296 //    multiRegIdx       - register position of tree node for which copy or reload is needed.
8297 //    refPosition       - The RefPosition at which copy or reload will take place.
8298 //
8299 // Notes:
8300 //    The GT_COPY or GT_RELOAD will be inserted in the proper spot in execution order where the reload is to occur.
8301 //
8302 // For example, for this tree (numbers are execution order, lower is earlier and higher is later):
8303 //
8304 //                                   +---------+----------+
8305 //                                   |       GT_ADD (3)   |
8306 //                                   +---------+----------+
8307 //                                             |
8308 //                                           /   \
8309 //                                         /       \
8310 //                                       /           \
8311 //                   +-------------------+           +----------------------+
8312 //                   |         x (1)     | "tree"    |         y (2)        |
8313 //                   +-------------------+           +----------------------+
8314 //
8315 // generate this tree:
8316 //
8317 //                                   +---------+----------+
8318 //                                   |       GT_ADD (4)   |
8319 //                                   +---------+----------+
8320 //                                             |
8321 //                                           /   \
8322 //                                         /       \
8323 //                                       /           \
8324 //                   +-------------------+           +----------------------+
8325 //                   |  GT_RELOAD (3)    |           |         y (2)        |
8326 //                   +-------------------+           +----------------------+
8327 //                             |
8328 //                   +-------------------+
8329 //                   |         x (1)     | "tree"
8330 //                   +-------------------+
8331 //
8332 // Note in particular that the GT_RELOAD node gets inserted in execution order immediately before the parent of "tree",
8333 // which seems a bit weird since normally a node's parent (in this case, the parent of "x", GT_RELOAD in the "after"
8334 // picture) immediately follows all of its children (that is, normally the execution ordering is postorder).
8335 // The ordering must be this weird "out of normal order" way because the "x" node is being spilled, probably
8336 // because the expression in the tree represented above by "y" has high register requirements. We don't want
8337 // to reload immediately, of course. So we put GT_RELOAD where the reload should actually happen.
8338 //
8339 // Note that GT_RELOAD is required when we reload to a different register than the one we spilled to. It can also be
8340 // used if we reload to the same register. Normally, though, in that case we just mark the node with GTF_SPILLED,
8341 // and the unspilling code automatically reuses the same register, and does the reload when it notices that flag
8342 // when considering a node's operands.
8343 //
8344 void LinearScan::insertCopyOrReload(BasicBlock* block, GenTreePtr tree, unsigned multiRegIdx, RefPosition* refPosition)
8345 {
8346     LIR::Range& blockRange = LIR::AsRange(block);
8347
8348     LIR::Use treeUse;
8349     bool     foundUse = blockRange.TryGetUse(tree, &treeUse);
8350     assert(foundUse);
8351
8352     GenTree* parent = treeUse.User();
8353
8354     genTreeOps oper;
8355     if (refPosition->reload)
8356     {
8357         oper = GT_RELOAD;
8358     }
8359     else
8360     {
8361         oper = GT_COPY;
8362
8363 #if TRACK_LSRA_STATS
8364         updateLsraStat(LSRA_STAT_COPY_REG, block->bbNum);
8365 #endif
8366     }
8367
8368     // If the parent is a reload/copy node, then tree must be a multi-reg call node
8369     // that has already had one of its registers spilled. This is Because multi-reg
8370     // call node is the only node whose RefTypeDef positions get independently
8371     // spilled or reloaded.  It is possible that one of its RefTypeDef position got
8372     // spilled and the next use of it requires it to be in a different register.
8373     //
8374     // In this case set the ith position reg of reload/copy node to the reg allocated
8375     // for copy/reload refPosition.  Essentially a copy/reload node will have a reg
8376     // for each multi-reg position of its child. If there is a valid reg in ith
8377     // position of GT_COPY or GT_RELOAD node then the corresponding result of its
8378     // child needs to be copied or reloaded to that reg.
8379     if (parent->IsCopyOrReload())
8380     {
8381         noway_assert(parent->OperGet() == oper);
8382         noway_assert(tree->IsMultiRegCall());
8383         GenTreeCall*         call         = tree->AsCall();
8384         GenTreeCopyOrReload* copyOrReload = parent->AsCopyOrReload();
8385         noway_assert(copyOrReload->GetRegNumByIdx(multiRegIdx) == REG_NA);
8386         copyOrReload->SetRegNumByIdx(refPosition->assignedReg(), multiRegIdx);
8387     }
8388     else
8389     {
8390         // Create the new node, with "tree" as its only child.
8391         var_types treeType = tree->TypeGet();
8392
8393         GenTreeCopyOrReload* newNode = new (compiler, oper) GenTreeCopyOrReload(oper, treeType, tree);
8394         assert(refPosition->registerAssignment != RBM_NONE);
8395         newNode->SetRegNumByIdx(refPosition->assignedReg(), multiRegIdx);
8396         newNode->gtLsraInfo.isLsraAdded   = true;
8397         newNode->gtLsraInfo.isLocalDefUse = false;
8398         if (refPosition->copyReg)
8399         {
8400             // This is a TEMPORARY copy
8401             assert(isCandidateLocalRef(tree));
8402             newNode->gtFlags |= GTF_VAR_DEATH;
8403         }
8404
8405         // Insert the copy/reload after the spilled node and replace the use of the original node with a use
8406         // of the copy/reload.
8407         blockRange.InsertAfter(tree, newNode);
8408         treeUse.ReplaceWith(compiler, newNode);
8409     }
8410 }
8411
8412 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
8413 //------------------------------------------------------------------------
8414 // insertUpperVectorSaveAndReload: Insert code to save and restore the upper half of a vector that lives
8415 //                                 in a callee-save register at the point of a kill (the upper half is
8416 //                                 not preserved).
8417 //
8418 // Arguments:
8419 //    tree              - This is the node around which we will insert the Save & Reload.
8420 //                        It will be a call or some node that turns into a call.
8421 //    refPosition       - The RefTypeUpperVectorSaveDef RefPosition.
8422 //
8423 void LinearScan::insertUpperVectorSaveAndReload(GenTreePtr tree, RefPosition* refPosition, BasicBlock* block)
8424 {
8425     Interval* lclVarInterval = refPosition->getInterval()->relatedInterval;
8426     assert(lclVarInterval->isLocalVar == true);
8427     LclVarDsc* varDsc = compiler->lvaTable + lclVarInterval->varNum;
8428     assert(varDsc->lvType == LargeVectorType);
8429     regNumber lclVarReg = lclVarInterval->physReg;
8430     if (lclVarReg == REG_NA)
8431     {
8432         return;
8433     }
8434
8435     assert((genRegMask(lclVarReg) & RBM_FLT_CALLEE_SAVED) != RBM_NONE);
8436
8437     regNumber spillReg   = refPosition->assignedReg();
8438     bool      spillToMem = refPosition->spillAfter;
8439
8440     LIR::Range& blockRange = LIR::AsRange(block);
8441
8442     // First, insert the save before the call.
8443
8444     GenTreePtr saveLcl                = compiler->gtNewLclvNode(lclVarInterval->varNum, LargeVectorType);
8445     saveLcl->gtLsraInfo.isLsraAdded   = true;
8446     saveLcl->gtRegNum                 = lclVarReg;
8447     saveLcl->gtLsraInfo.isLocalDefUse = false;
8448
8449     GenTreeSIMD* simdNode =
8450         new (compiler, GT_SIMD) GenTreeSIMD(LargeVectorSaveType, saveLcl, nullptr, SIMDIntrinsicUpperSave,
8451                                             varDsc->lvBaseType, genTypeSize(LargeVectorType));
8452     simdNode->gtLsraInfo.isLsraAdded = true;
8453     simdNode->gtRegNum               = spillReg;
8454     if (spillToMem)
8455     {
8456         simdNode->gtFlags |= GTF_SPILL;
8457     }
8458
8459     blockRange.InsertBefore(tree, LIR::SeqTree(compiler, simdNode));
8460
8461     // Now insert the restore after the call.
8462
8463     GenTreePtr restoreLcl                = compiler->gtNewLclvNode(lclVarInterval->varNum, LargeVectorType);
8464     restoreLcl->gtLsraInfo.isLsraAdded   = true;
8465     restoreLcl->gtRegNum                 = lclVarReg;
8466     restoreLcl->gtLsraInfo.isLocalDefUse = false;
8467
8468     simdNode = new (compiler, GT_SIMD)
8469         GenTreeSIMD(LargeVectorType, restoreLcl, nullptr, SIMDIntrinsicUpperRestore, varDsc->lvBaseType, 32);
8470     simdNode->gtLsraInfo.isLsraAdded = true;
8471     simdNode->gtRegNum               = spillReg;
8472     if (spillToMem)
8473     {
8474         simdNode->gtFlags |= GTF_SPILLED;
8475     }
8476
8477     blockRange.InsertAfter(tree, LIR::SeqTree(compiler, simdNode));
8478 }
8479 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
8480
8481 //------------------------------------------------------------------------
8482 // initMaxSpill: Initializes the LinearScan members used to track the max number
8483 //               of concurrent spills.  This is needed so that we can set the
8484 //               fields in Compiler, so that the code generator, in turn can
8485 //               allocate the right number of spill locations.
8486 //
8487 // Arguments:
8488 //    None.
8489 //
8490 // Return Value:
8491 //    None.
8492 //
8493 // Assumptions:
8494 //    This is called before any calls to updateMaxSpill().
8495
8496 void LinearScan::initMaxSpill()
8497 {
8498     needDoubleTmpForFPCall = false;
8499     needFloatTmpForFPCall  = false;
8500     for (int i = 0; i < TYP_COUNT; i++)
8501     {
8502         maxSpill[i]     = 0;
8503         currentSpill[i] = 0;
8504     }
8505 }
8506
8507 //------------------------------------------------------------------------
8508 // recordMaxSpill: Sets the fields in Compiler for the max number of concurrent spills.
8509 //                 (See the comment on initMaxSpill.)
8510 //
8511 // Arguments:
8512 //    None.
8513 //
8514 // Return Value:
8515 //    None.
8516 //
8517 // Assumptions:
8518 //    This is called after updateMaxSpill() has been called for all "real"
8519 //    RefPositions.
8520
8521 void LinearScan::recordMaxSpill()
8522 {
8523     // Note: due to the temp normalization process (see tmpNormalizeType)
8524     // only a few types should actually be seen here.
8525     JITDUMP("Recording the maximum number of concurrent spills:\n");
8526 #ifdef _TARGET_X86_
8527     var_types returnType = compiler->tmpNormalizeType(compiler->info.compRetType);
8528     if (needDoubleTmpForFPCall || (returnType == TYP_DOUBLE))
8529     {
8530         JITDUMP("Adding a spill temp for moving a double call/return value between xmm reg and x87 stack.\n");
8531         maxSpill[TYP_DOUBLE] += 1;
8532     }
8533     if (needFloatTmpForFPCall || (returnType == TYP_FLOAT))
8534     {
8535         JITDUMP("Adding a spill temp for moving a float call/return value between xmm reg and x87 stack.\n");
8536         maxSpill[TYP_FLOAT] += 1;
8537     }
8538 #endif // _TARGET_X86_
8539     for (int i = 0; i < TYP_COUNT; i++)
8540     {
8541         if (var_types(i) != compiler->tmpNormalizeType(var_types(i)))
8542         {
8543             // Only normalized types should have anything in the maxSpill array.
8544             // We assume here that if type 'i' does not normalize to itself, then
8545             // nothing else normalizes to 'i', either.
8546             assert(maxSpill[i] == 0);
8547         }
8548         if (maxSpill[i] != 0)
8549         {
8550             JITDUMP("  %s: %d\n", varTypeName(var_types(i)), maxSpill[i]);
8551             compiler->tmpPreAllocateTemps(var_types(i), maxSpill[i]);
8552         }
8553     }
8554     JITDUMP("\n");
8555 }
8556
8557 //------------------------------------------------------------------------
8558 // updateMaxSpill: Update the maximum number of concurrent spills
8559 //
8560 // Arguments:
8561 //    refPosition - the current RefPosition being handled
8562 //
8563 // Return Value:
8564 //    None.
8565 //
8566 // Assumptions:
8567 //    The RefPosition has an associated interval (getInterval() will
8568 //    otherwise assert).
8569 //
8570 // Notes:
8571 //    This is called for each "real" RefPosition during the writeback
8572 //    phase of LSRA.  It keeps track of how many concurrently-live
8573 //    spills there are, and the largest number seen so far.
8574
8575 void LinearScan::updateMaxSpill(RefPosition* refPosition)
8576 {
8577     RefType refType = refPosition->refType;
8578
8579     if (refPosition->spillAfter || refPosition->reload ||
8580         (refPosition->AllocateIfProfitable() && refPosition->assignedReg() == REG_NA))
8581     {
8582         Interval* interval = refPosition->getInterval();
8583         if (!interval->isLocalVar)
8584         {
8585             // The tmp allocation logic 'normalizes' types to a small number of
8586             // types that need distinct stack locations from each other.
8587             // Those types are currently gc refs, byrefs, <= 4 byte non-GC items,
8588             // 8-byte non-GC items, and 16-byte or 32-byte SIMD vectors.
8589             // LSRA is agnostic to those choices but needs
8590             // to know what they are here.
8591             var_types typ;
8592
8593 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
8594             if ((refType == RefTypeUpperVectorSaveDef) || (refType == RefTypeUpperVectorSaveUse))
8595             {
8596                 typ = LargeVectorSaveType;
8597             }
8598             else
8599 #endif // !FEATURE_PARTIAL_SIMD_CALLEE_SAVE
8600             {
8601                 GenTreePtr treeNode = refPosition->treeNode;
8602                 if (treeNode == nullptr)
8603                 {
8604                     assert(RefTypeIsUse(refType));
8605                     treeNode = interval->firstRefPosition->treeNode;
8606                 }
8607                 assert(treeNode != nullptr);
8608
8609                 // In case of multi-reg call nodes, we need to use the type
8610                 // of the return register given by multiRegIdx of the refposition.
8611                 if (treeNode->IsMultiRegCall())
8612                 {
8613                     ReturnTypeDesc* retTypeDesc = treeNode->AsCall()->GetReturnTypeDesc();
8614                     typ                         = retTypeDesc->GetReturnRegType(refPosition->getMultiRegIdx());
8615                 }
8616                 else
8617                 {
8618                     typ = treeNode->TypeGet();
8619                 }
8620                 typ = compiler->tmpNormalizeType(typ);
8621             }
8622
8623             if (refPosition->spillAfter && !refPosition->reload)
8624             {
8625                 currentSpill[typ]++;
8626                 if (currentSpill[typ] > maxSpill[typ])
8627                 {
8628                     maxSpill[typ] = currentSpill[typ];
8629                 }
8630             }
8631             else if (refPosition->reload)
8632             {
8633                 assert(currentSpill[typ] > 0);
8634                 currentSpill[typ]--;
8635             }
8636             else if (refPosition->AllocateIfProfitable() && refPosition->assignedReg() == REG_NA)
8637             {
8638                 // A spill temp not getting reloaded into a reg because it is
8639                 // marked as allocate if profitable and getting used from its
8640                 // memory location.  To properly account max spill for typ we
8641                 // decrement spill count.
8642                 assert(RefTypeIsUse(refType));
8643                 assert(currentSpill[typ] > 0);
8644                 currentSpill[typ]--;
8645             }
8646             JITDUMP("  Max spill for %s is %d\n", varTypeName(typ), maxSpill[typ]);
8647         }
8648     }
8649 }
8650
8651 // This is the final phase of register allocation.  It writes the register assignments to
8652 // the tree, and performs resolution across joins and backedges.
8653 //
8654 void LinearScan::resolveRegisters()
8655 {
8656     // Iterate over the tree and the RefPositions in lockstep
8657     //  - annotate the tree with register assignments by setting gtRegNum or gtRegPair (for longs)
8658     //    on the tree node
8659     //  - track globally-live var locations
8660     //  - add resolution points at split/merge/critical points as needed
8661
8662     // Need to use the same traversal order as the one that assigns the location numbers.
8663
8664     // Dummy RefPositions have been added at any split, join or critical edge, at the
8665     // point where resolution may be required.  These are located:
8666     //  - for a split, at the top of the non-adjacent block
8667     //  - for a join, at the bottom of the non-adjacent joining block
8668     //  - for a critical edge, at the top of the target block of each critical
8669     //    edge.
8670     // Note that a target block may have multiple incoming critical or split edges
8671     //
8672     // These RefPositions record the expected location of the Interval at that point.
8673     // At each branch, we identify the location of each liveOut interval, and check
8674     // against the RefPositions at the target.
8675
8676     BasicBlock*  block;
8677     LsraLocation currentLocation = MinLocation;
8678
8679     // Clear register assignments - these will be reestablished as lclVar defs (including RefTypeParamDefs)
8680     // are encountered.
8681     if (enregisterLocalVars)
8682     {
8683         for (regNumber reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
8684         {
8685             RegRecord* physRegRecord    = getRegisterRecord(reg);
8686             Interval*  assignedInterval = physRegRecord->assignedInterval;
8687             if (assignedInterval != nullptr)
8688             {
8689                 assignedInterval->assignedReg = nullptr;
8690                 assignedInterval->physReg     = REG_NA;
8691             }
8692             physRegRecord->assignedInterval  = nullptr;
8693             physRegRecord->recentRefPosition = nullptr;
8694         }
8695
8696         // Clear "recentRefPosition" for lclVar intervals
8697         for (unsigned varIndex = 0; varIndex < compiler->lvaTrackedCount; varIndex++)
8698         {
8699             if (localVarIntervals[varIndex] != nullptr)
8700             {
8701                 localVarIntervals[varIndex]->recentRefPosition = nullptr;
8702                 localVarIntervals[varIndex]->isActive          = false;
8703             }
8704             else
8705             {
8706                 assert(compiler->lvaTable[compiler->lvaTrackedToVarNum[varIndex]].lvLRACandidate == false);
8707             }
8708         }
8709     }
8710
8711     // handle incoming arguments and special temps
8712     auto currentRefPosition = refPositions.begin();
8713
8714     if (enregisterLocalVars)
8715     {
8716         VarToRegMap entryVarToRegMap = inVarToRegMaps[compiler->fgFirstBB->bbNum];
8717         while (currentRefPosition != refPositions.end() &&
8718                (currentRefPosition->refType == RefTypeParamDef || currentRefPosition->refType == RefTypeZeroInit))
8719         {
8720             Interval* interval = currentRefPosition->getInterval();
8721             assert(interval != nullptr && interval->isLocalVar);
8722             resolveLocalRef(nullptr, nullptr, currentRefPosition);
8723             regNumber reg      = REG_STK;
8724             int       varIndex = interval->getVarIndex(compiler);
8725
8726             if (!currentRefPosition->spillAfter && currentRefPosition->registerAssignment != RBM_NONE)
8727             {
8728                 reg = currentRefPosition->assignedReg();
8729             }
8730             else
8731             {
8732                 reg                = REG_STK;
8733                 interval->isActive = false;
8734             }
8735             setVarReg(entryVarToRegMap, varIndex, reg);
8736             ++currentRefPosition;
8737         }
8738     }
8739     else
8740     {
8741         assert(currentRefPosition == refPositions.end() ||
8742                (currentRefPosition->refType != RefTypeParamDef && currentRefPosition->refType != RefTypeZeroInit));
8743     }
8744
8745     BasicBlock* insertionBlock = compiler->fgFirstBB;
8746     GenTreePtr  insertionPoint = LIR::AsRange(insertionBlock).FirstNonPhiNode();
8747
8748     // write back assignments
8749     for (block = startBlockSequence(); block != nullptr; block = moveToNextBlock())
8750     {
8751         assert(curBBNum == block->bbNum);
8752
8753         if (enregisterLocalVars)
8754         {
8755             // Record the var locations at the start of this block.
8756             // (If it's fgFirstBB, we've already done that above, see entryVarToRegMap)
8757
8758             curBBStartLocation = currentRefPosition->nodeLocation;
8759             if (block != compiler->fgFirstBB)
8760             {
8761                 processBlockStartLocations(block, false);
8762             }
8763
8764             // Handle the DummyDefs, updating the incoming var location.
8765             for (; currentRefPosition != refPositions.end() && currentRefPosition->refType == RefTypeDummyDef;
8766                  ++currentRefPosition)
8767             {
8768                 assert(currentRefPosition->isIntervalRef());
8769                 // Don't mark dummy defs as reload
8770                 currentRefPosition->reload = false;
8771                 resolveLocalRef(nullptr, nullptr, currentRefPosition);
8772                 regNumber reg;
8773                 if (currentRefPosition->registerAssignment != RBM_NONE)
8774                 {
8775                     reg = currentRefPosition->assignedReg();
8776                 }
8777                 else
8778                 {
8779                     reg                                         = REG_STK;
8780                     currentRefPosition->getInterval()->isActive = false;
8781                 }
8782                 setInVarRegForBB(curBBNum, currentRefPosition->getInterval()->varNum, reg);
8783             }
8784         }
8785
8786         // The next RefPosition should be for the block.  Move past it.
8787         assert(currentRefPosition != refPositions.end());
8788         assert(currentRefPosition->refType == RefTypeBB);
8789         ++currentRefPosition;
8790
8791         // Handle the RefPositions for the block
8792         for (; currentRefPosition != refPositions.end() && currentRefPosition->refType != RefTypeBB &&
8793                currentRefPosition->refType != RefTypeDummyDef;
8794              ++currentRefPosition)
8795         {
8796             currentLocation = currentRefPosition->nodeLocation;
8797
8798             // Ensure that the spill & copy info is valid.
8799             // First, if it's reload, it must not be copyReg or moveReg
8800             assert(!currentRefPosition->reload || (!currentRefPosition->copyReg && !currentRefPosition->moveReg));
8801             // If it's copyReg it must not be moveReg, and vice-versa
8802             assert(!currentRefPosition->copyReg || !currentRefPosition->moveReg);
8803
8804             switch (currentRefPosition->refType)
8805             {
8806 #ifdef FEATURE_SIMD
8807                 case RefTypeUpperVectorSaveUse:
8808                 case RefTypeUpperVectorSaveDef:
8809 #endif // FEATURE_SIMD
8810                 case RefTypeUse:
8811                 case RefTypeDef:
8812                     // These are the ones we're interested in
8813                     break;
8814                 case RefTypeKill:
8815                 case RefTypeFixedReg:
8816                     // These require no handling at resolution time
8817                     assert(currentRefPosition->referent != nullptr);
8818                     currentRefPosition->referent->recentRefPosition = currentRefPosition;
8819                     continue;
8820                 case RefTypeExpUse:
8821                     // Ignore the ExpUse cases - a RefTypeExpUse would only exist if the
8822                     // variable is dead at the entry to the next block.  So we'll mark
8823                     // it as in its current location and resolution will take care of any
8824                     // mismatch.
8825                     assert(getNextBlock() == nullptr ||
8826                            !VarSetOps::IsMember(compiler, getNextBlock()->bbLiveIn,
8827                                                 currentRefPosition->getInterval()->getVarIndex(compiler)));
8828                     currentRefPosition->referent->recentRefPosition = currentRefPosition;
8829                     continue;
8830                 case RefTypeKillGCRefs:
8831                     // No action to take at resolution time, and no interval to update recentRefPosition for.
8832                     continue;
8833                 case RefTypeDummyDef:
8834                 case RefTypeParamDef:
8835                 case RefTypeZeroInit:
8836                 // Should have handled all of these already
8837                 default:
8838                     unreached();
8839                     break;
8840             }
8841             updateMaxSpill(currentRefPosition);
8842             GenTree* treeNode = currentRefPosition->treeNode;
8843
8844 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
8845             if (currentRefPosition->refType == RefTypeUpperVectorSaveDef)
8846             {
8847                 // The treeNode must be a call, and this must be a RefPosition for a LargeVectorType LocalVar.
8848                 // If the LocalVar is in a callee-save register, we are going to spill its upper half around the call.
8849                 // If we have allocated a register to spill it to, we will use that; otherwise, we will spill it
8850                 // to the stack.  We can use as a temp register any non-arg caller-save register.
8851                 noway_assert(treeNode != nullptr);
8852                 currentRefPosition->referent->recentRefPosition = currentRefPosition;
8853                 insertUpperVectorSaveAndReload(treeNode, currentRefPosition, block);
8854             }
8855             else if (currentRefPosition->refType == RefTypeUpperVectorSaveUse)
8856             {
8857                 continue;
8858             }
8859 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
8860
8861             // Most uses won't actually need to be recorded (they're on the def).
8862             // In those cases, treeNode will be nullptr.
8863             if (treeNode == nullptr)
8864             {
8865                 // This is either a use, a dead def, or a field of a struct
8866                 Interval* interval = currentRefPosition->getInterval();
8867                 assert(currentRefPosition->refType == RefTypeUse ||
8868                        currentRefPosition->registerAssignment == RBM_NONE || interval->isStructField);
8869
8870                 // TODO-Review: Need to handle the case where any of the struct fields
8871                 // are reloaded/spilled at this use
8872                 assert(!interval->isStructField ||
8873                        (currentRefPosition->reload == false && currentRefPosition->spillAfter == false));
8874
8875                 if (interval->isLocalVar && !interval->isStructField)
8876                 {
8877                     LclVarDsc* varDsc = interval->getLocalVar(compiler);
8878
8879                     // This must be a dead definition.  We need to mark the lclVar
8880                     // so that it's not considered a candidate for lvRegister, as
8881                     // this dead def will have to go to the stack.
8882                     assert(currentRefPosition->refType == RefTypeDef);
8883                     varDsc->lvRegNum = REG_STK;
8884                 }
8885                 continue;
8886             }
8887
8888             LsraLocation loc = treeNode->gtLsraInfo.loc;
8889             assert(treeNode->IsLocal() || currentLocation == loc || currentLocation == loc + 1);
8890
8891             if (currentRefPosition->isIntervalRef() && currentRefPosition->getInterval()->isInternal)
8892             {
8893                 treeNode->gtRsvdRegs |= currentRefPosition->registerAssignment;
8894             }
8895             else
8896             {
8897                 writeRegisters(currentRefPosition, treeNode);
8898
8899                 if (treeNode->IsLocal() && currentRefPosition->getInterval()->isLocalVar)
8900                 {
8901                     resolveLocalRef(block, treeNode, currentRefPosition);
8902                 }
8903
8904                 // Mark spill locations on temps
8905                 // (local vars are handled in resolveLocalRef, above)
8906                 // Note that the tree node will be changed from GTF_SPILL to GTF_SPILLED
8907                 // in codegen, taking care of the "reload" case for temps
8908                 else if (currentRefPosition->spillAfter || (currentRefPosition->nextRefPosition != nullptr &&
8909                                                             currentRefPosition->nextRefPosition->moveReg))
8910                 {
8911                     if (treeNode != nullptr && currentRefPosition->isIntervalRef())
8912                     {
8913                         if (currentRefPosition->spillAfter)
8914                         {
8915                             treeNode->gtFlags |= GTF_SPILL;
8916
8917                             // If this is a constant interval that is reusing a pre-existing value, we actually need
8918                             // to generate the value at this point in order to spill it.
8919                             if (treeNode->IsReuseRegVal())
8920                             {
8921                                 treeNode->ResetReuseRegVal();
8922                             }
8923
8924                             // In case of multi-reg call node, also set spill flag on the
8925                             // register specified by multi-reg index of current RefPosition.
8926                             // Note that the spill flag on treeNode indicates that one or
8927                             // more its allocated registers are in that state.
8928                             if (treeNode->IsMultiRegCall())
8929                             {
8930                                 GenTreeCall* call = treeNode->AsCall();
8931                                 call->SetRegSpillFlagByIdx(GTF_SPILL, currentRefPosition->getMultiRegIdx());
8932                             }
8933 #ifdef _TARGET_ARM_
8934                             else if (treeNode->OperIsPutArgSplit())
8935                             {
8936                                 GenTreePutArgSplit* splitArg = treeNode->AsPutArgSplit();
8937                                 splitArg->SetRegSpillFlagByIdx(GTF_SPILL, currentRefPosition->getMultiRegIdx());
8938                             }
8939 #endif
8940                         }
8941
8942                         // If the value is reloaded or moved to a different register, we need to insert
8943                         // a node to hold the register to which it should be reloaded
8944                         RefPosition* nextRefPosition = currentRefPosition->nextRefPosition;
8945                         assert(nextRefPosition != nullptr);
8946                         if (INDEBUG(alwaysInsertReload() ||)
8947                                 nextRefPosition->assignedReg() != currentRefPosition->assignedReg())
8948                         {
8949                             if (nextRefPosition->assignedReg() != REG_NA)
8950                             {
8951                                 insertCopyOrReload(block, treeNode, currentRefPosition->getMultiRegIdx(),
8952                                                    nextRefPosition);
8953                             }
8954                             else
8955                             {
8956                                 assert(nextRefPosition->AllocateIfProfitable());
8957
8958                                 // In case of tree temps, if def is spilled and use didn't
8959                                 // get a register, set a flag on tree node to be treated as
8960                                 // contained at the point of its use.
8961                                 if (currentRefPosition->spillAfter && currentRefPosition->refType == RefTypeDef &&
8962                                     nextRefPosition->refType == RefTypeUse)
8963                                 {
8964                                     assert(nextRefPosition->treeNode == nullptr);
8965                                     treeNode->gtFlags |= GTF_NOREG_AT_USE;
8966                                 }
8967                             }
8968                         }
8969                     }
8970
8971                     // We should never have to "spill after" a temp use, since
8972                     // they're single use
8973                     else
8974                     {
8975                         unreached();
8976                     }
8977                 }
8978             }
8979         }
8980
8981         if (enregisterLocalVars)
8982         {
8983             processBlockEndLocations(block);
8984         }
8985     }
8986
8987     if (enregisterLocalVars)
8988     {
8989 #ifdef DEBUG
8990         if (VERBOSE)
8991         {
8992             printf("-----------------------\n");
8993             printf("RESOLVING BB BOUNDARIES\n");
8994             printf("-----------------------\n");
8995
8996             printf("Resolution Candidates: ");
8997             dumpConvertedVarSet(compiler, resolutionCandidateVars);
8998             printf("\n");
8999             printf("Has %sCritical Edges\n\n", hasCriticalEdges ? "" : "No");
9000
9001             printf("Prior to Resolution\n");
9002             foreach_block(compiler, block)
9003             {
9004                 printf("\nBB%02u use def in out\n", block->bbNum);
9005                 dumpConvertedVarSet(compiler, block->bbVarUse);
9006                 printf("\n");
9007                 dumpConvertedVarSet(compiler, block->bbVarDef);
9008                 printf("\n");
9009                 dumpConvertedVarSet(compiler, block->bbLiveIn);
9010                 printf("\n");
9011                 dumpConvertedVarSet(compiler, block->bbLiveOut);
9012                 printf("\n");
9013
9014                 dumpInVarToRegMap(block);
9015                 dumpOutVarToRegMap(block);
9016             }
9017
9018             printf("\n\n");
9019         }
9020 #endif // DEBUG
9021
9022         resolveEdges();
9023
9024         // Verify register assignments on variables
9025         unsigned   lclNum;
9026         LclVarDsc* varDsc;
9027         for (lclNum = 0, varDsc = compiler->lvaTable; lclNum < compiler->lvaCount; lclNum++, varDsc++)
9028         {
9029             if (!isCandidateVar(varDsc))
9030             {
9031                 varDsc->lvRegNum = REG_STK;
9032             }
9033             else
9034             {
9035                 Interval* interval = getIntervalForLocalVar(varDsc->lvVarIndex);
9036
9037                 // Determine initial position for parameters
9038
9039                 if (varDsc->lvIsParam)
9040                 {
9041                     regMaskTP initialRegMask = interval->firstRefPosition->registerAssignment;
9042                     regNumber initialReg     = (initialRegMask == RBM_NONE || interval->firstRefPosition->spillAfter)
9043                                                ? REG_STK
9044                                                : genRegNumFromMask(initialRegMask);
9045                     regNumber sourceReg = (varDsc->lvIsRegArg) ? varDsc->lvArgReg : REG_STK;
9046
9047 #ifdef _TARGET_ARM_
9048                     if (varTypeIsMultiReg(varDsc))
9049                     {
9050                         // TODO-ARM-NYI: Map the hi/lo intervals back to lvRegNum and lvOtherReg (these should NYI
9051                         // before this)
9052                         assert(!"Multi-reg types not yet supported");
9053                     }
9054                     else
9055 #endif // _TARGET_ARM_
9056                     {
9057                         varDsc->lvArgInitReg = initialReg;
9058                         JITDUMP("  Set V%02u argument initial register to %s\n", lclNum, getRegName(initialReg));
9059                     }
9060
9061                     // Stack args that are part of dependently-promoted structs should never be register candidates (see
9062                     // LinearScan::isRegCandidate).
9063                     assert(varDsc->lvIsRegArg || !compiler->lvaIsFieldOfDependentlyPromotedStruct(varDsc));
9064                 }
9065
9066                 // If lvRegNum is REG_STK, that means that either no register
9067                 // was assigned, or (more likely) that the same register was not
9068                 // used for all references.  In that case, codegen gets the register
9069                 // from the tree node.
9070                 if (varDsc->lvRegNum == REG_STK || interval->isSpilled || interval->isSplit)
9071                 {
9072                     // For codegen purposes, we'll set lvRegNum to whatever register
9073                     // it's currently in as we go.
9074                     // However, we never mark an interval as lvRegister if it has either been spilled
9075                     // or split.
9076                     varDsc->lvRegister = false;
9077
9078                     // Skip any dead defs or exposed uses
9079                     // (first use exposed will only occur when there is no explicit initialization)
9080                     RefPosition* firstRefPosition = interval->firstRefPosition;
9081                     while ((firstRefPosition != nullptr) && (firstRefPosition->refType == RefTypeExpUse))
9082                     {
9083                         firstRefPosition = firstRefPosition->nextRefPosition;
9084                     }
9085                     if (firstRefPosition == nullptr)
9086                     {
9087                         // Dead interval
9088                         varDsc->lvLRACandidate = false;
9089                         if (varDsc->lvRefCnt == 0)
9090                         {
9091                             varDsc->lvOnFrame = false;
9092                         }
9093                         else
9094                         {
9095                             // We may encounter cases where a lclVar actually has no references, but
9096                             // a non-zero refCnt.  For safety (in case this is some "hidden" lclVar that we're
9097                             // not correctly recognizing), we'll mark those as needing a stack location.
9098                             // TODO-Cleanup: Make this an assert if/when we correct the refCnt
9099                             // updating.
9100                             varDsc->lvOnFrame = true;
9101                         }
9102                     }
9103                     else
9104                     {
9105                         // If the interval was not spilled, it doesn't need a stack location.
9106                         if (!interval->isSpilled)
9107                         {
9108                             varDsc->lvOnFrame = false;
9109                         }
9110                         if (firstRefPosition->registerAssignment == RBM_NONE || firstRefPosition->spillAfter)
9111                         {
9112                             // Either this RefPosition is spilled, or regOptional or it is not a "real" def or use
9113                             assert(
9114                                 firstRefPosition->spillAfter || firstRefPosition->AllocateIfProfitable() ||
9115                                 (firstRefPosition->refType != RefTypeDef && firstRefPosition->refType != RefTypeUse));
9116                             varDsc->lvRegNum = REG_STK;
9117                         }
9118                         else
9119                         {
9120                             varDsc->lvRegNum = firstRefPosition->assignedReg();
9121                         }
9122                     }
9123                 }
9124                 else
9125                 {
9126                     {
9127                         varDsc->lvRegister = true;
9128                         varDsc->lvOnFrame  = false;
9129                     }
9130 #ifdef DEBUG
9131                     regMaskTP registerAssignment = genRegMask(varDsc->lvRegNum);
9132                     assert(!interval->isSpilled && !interval->isSplit);
9133                     RefPosition* refPosition = interval->firstRefPosition;
9134                     assert(refPosition != nullptr);
9135
9136                     while (refPosition != nullptr)
9137                     {
9138                         // All RefPositions must match, except for dead definitions,
9139                         // copyReg/moveReg and RefTypeExpUse positions
9140                         if (refPosition->registerAssignment != RBM_NONE && !refPosition->copyReg &&
9141                             !refPosition->moveReg && refPosition->refType != RefTypeExpUse)
9142                         {
9143                             assert(refPosition->registerAssignment == registerAssignment);
9144                         }
9145                         refPosition = refPosition->nextRefPosition;
9146                     }
9147 #endif // DEBUG
9148                 }
9149             }
9150         }
9151     }
9152
9153 #ifdef DEBUG
9154     if (VERBOSE)
9155     {
9156         printf("Trees after linear scan register allocator (LSRA)\n");
9157         compiler->fgDispBasicBlocks(true);
9158     }
9159
9160     verifyFinalAllocation();
9161 #endif // DEBUG
9162
9163     compiler->raMarkStkVars();
9164     recordMaxSpill();
9165
9166     // TODO-CQ: Review this comment and address as needed.
9167     // Change all unused promoted non-argument struct locals to a non-GC type (in this case TYP_INT)
9168     // so that the gc tracking logic and lvMustInit logic will ignore them.
9169     // Extract the code that does this from raAssignVars, and call it here.
9170     // PRECONDITIONS: Ensure that lvPromoted is set on promoted structs, if and
9171     // only if it is promoted on all paths.
9172     // Call might be something like:
9173     // compiler->BashUnusedStructLocals();
9174 }
9175
9176 //
9177 //------------------------------------------------------------------------
9178 // insertMove: Insert a move of a lclVar with the given lclNum into the given block.
9179 //
9180 // Arguments:
9181 //    block          - the BasicBlock into which the move will be inserted.
9182 //    insertionPoint - the instruction before which to insert the move
9183 //    lclNum         - the lclNum of the var to be moved
9184 //    fromReg        - the register from which the var is moving
9185 //    toReg          - the register to which the var is moving
9186 //
9187 // Return Value:
9188 //    None.
9189 //
9190 // Notes:
9191 //    If insertionPoint is non-NULL, insert before that instruction;
9192 //    otherwise, insert "near" the end (prior to the branch, if any).
9193 //    If fromReg or toReg is REG_STK, then move from/to memory, respectively.
9194
9195 void LinearScan::insertMove(
9196     BasicBlock* block, GenTreePtr insertionPoint, unsigned lclNum, regNumber fromReg, regNumber toReg)
9197 {
9198     LclVarDsc* varDsc = compiler->lvaTable + lclNum;
9199     // the lclVar must be a register candidate
9200     assert(isRegCandidate(varDsc));
9201     // One or both MUST be a register
9202     assert(fromReg != REG_STK || toReg != REG_STK);
9203     // They must not be the same register.
9204     assert(fromReg != toReg);
9205
9206     // This var can't be marked lvRegister now
9207     varDsc->lvRegNum = REG_STK;
9208
9209     GenTreePtr src              = compiler->gtNewLclvNode(lclNum, varDsc->TypeGet());
9210     src->gtLsraInfo.isLsraAdded = true;
9211
9212     // There are three cases we need to handle:
9213     // - We are loading a lclVar from the stack.
9214     // - We are storing a lclVar to the stack.
9215     // - We are copying a lclVar between registers.
9216     //
9217     // In the first and second cases, the lclVar node will be marked with GTF_SPILLED and GTF_SPILL, respectively.
9218     // It is up to the code generator to ensure that any necessary normalization is done when loading or storing the
9219     // lclVar's value.
9220     //
9221     // In the third case, we generate GT_COPY(GT_LCL_VAR) and type each node with the normalized type of the lclVar.
9222     // This is safe because a lclVar is always normalized once it is in a register.
9223
9224     GenTree* dst = src;
9225     if (fromReg == REG_STK)
9226     {
9227         src->gtFlags |= GTF_SPILLED;
9228         src->gtRegNum = toReg;
9229     }
9230     else if (toReg == REG_STK)
9231     {
9232         src->gtFlags |= GTF_SPILL;
9233         src->gtRegNum = fromReg;
9234     }
9235     else
9236     {
9237         var_types movType = genActualType(varDsc->TypeGet());
9238         src->gtType       = movType;
9239
9240         dst = new (compiler, GT_COPY) GenTreeCopyOrReload(GT_COPY, movType, src);
9241         // This is the new home of the lclVar - indicate that by clearing the GTF_VAR_DEATH flag.
9242         // Note that if src is itself a lastUse, this will have no effect.
9243         dst->gtFlags &= ~(GTF_VAR_DEATH);
9244         src->gtRegNum                 = fromReg;
9245         dst->gtRegNum                 = toReg;
9246         src->gtLsraInfo.isLocalDefUse = false;
9247         dst->gtLsraInfo.isLsraAdded   = true;
9248     }
9249     dst->gtLsraInfo.isLocalDefUse = true;
9250
9251     LIR::Range  treeRange  = LIR::SeqTree(compiler, dst);
9252     LIR::Range& blockRange = LIR::AsRange(block);
9253
9254     if (insertionPoint != nullptr)
9255     {
9256         blockRange.InsertBefore(insertionPoint, std::move(treeRange));
9257     }
9258     else
9259     {
9260         // Put the copy at the bottom
9261         // If there's a branch, make an embedded statement that executes just prior to the branch
9262         if (block->bbJumpKind == BBJ_COND || block->bbJumpKind == BBJ_SWITCH)
9263         {
9264             noway_assert(!blockRange.IsEmpty());
9265
9266             GenTree* branch = blockRange.LastNode();
9267             assert(branch->OperIsConditionalJump() || branch->OperGet() == GT_SWITCH_TABLE ||
9268                    branch->OperGet() == GT_SWITCH);
9269
9270             blockRange.InsertBefore(branch, std::move(treeRange));
9271         }
9272         else
9273         {
9274             assert(block->bbJumpKind == BBJ_NONE || block->bbJumpKind == BBJ_ALWAYS);
9275             blockRange.InsertAtEnd(std::move(treeRange));
9276         }
9277     }
9278 }
9279
9280 void LinearScan::insertSwap(
9281     BasicBlock* block, GenTreePtr insertionPoint, unsigned lclNum1, regNumber reg1, unsigned lclNum2, regNumber reg2)
9282 {
9283 #ifdef DEBUG
9284     if (VERBOSE)
9285     {
9286         const char* insertionPointString = "top";
9287         if (insertionPoint == nullptr)
9288         {
9289             insertionPointString = "bottom";
9290         }
9291         printf("   BB%02u %s: swap V%02u in %s with V%02u in %s\n", block->bbNum, insertionPointString, lclNum1,
9292                getRegName(reg1), lclNum2, getRegName(reg2));
9293     }
9294 #endif // DEBUG
9295
9296     LclVarDsc* varDsc1 = compiler->lvaTable + lclNum1;
9297     LclVarDsc* varDsc2 = compiler->lvaTable + lclNum2;
9298     assert(reg1 != REG_STK && reg1 != REG_NA && reg2 != REG_STK && reg2 != REG_NA);
9299
9300     GenTreePtr lcl1                = compiler->gtNewLclvNode(lclNum1, varDsc1->TypeGet());
9301     lcl1->gtLsraInfo.isLsraAdded   = true;
9302     lcl1->gtLsraInfo.isLocalDefUse = false;
9303     lcl1->gtRegNum                 = reg1;
9304
9305     GenTreePtr lcl2                = compiler->gtNewLclvNode(lclNum2, varDsc2->TypeGet());
9306     lcl2->gtLsraInfo.isLsraAdded   = true;
9307     lcl2->gtLsraInfo.isLocalDefUse = false;
9308     lcl2->gtRegNum                 = reg2;
9309
9310     GenTreePtr swap                = compiler->gtNewOperNode(GT_SWAP, TYP_VOID, lcl1, lcl2);
9311     swap->gtLsraInfo.isLsraAdded   = true;
9312     swap->gtLsraInfo.isLocalDefUse = false;
9313     swap->gtRegNum                 = REG_NA;
9314
9315     lcl1->gtNext = lcl2;
9316     lcl2->gtPrev = lcl1;
9317     lcl2->gtNext = swap;
9318     swap->gtPrev = lcl2;
9319
9320     LIR::Range  swapRange  = LIR::SeqTree(compiler, swap);
9321     LIR::Range& blockRange = LIR::AsRange(block);
9322
9323     if (insertionPoint != nullptr)
9324     {
9325         blockRange.InsertBefore(insertionPoint, std::move(swapRange));
9326     }
9327     else
9328     {
9329         // Put the copy at the bottom
9330         // If there's a branch, make an embedded statement that executes just prior to the branch
9331         if (block->bbJumpKind == BBJ_COND || block->bbJumpKind == BBJ_SWITCH)
9332         {
9333             noway_assert(!blockRange.IsEmpty());
9334
9335             GenTree* branch = blockRange.LastNode();
9336             assert(branch->OperIsConditionalJump() || branch->OperGet() == GT_SWITCH_TABLE ||
9337                    branch->OperGet() == GT_SWITCH);
9338
9339             blockRange.InsertBefore(branch, std::move(swapRange));
9340         }
9341         else
9342         {
9343             assert(block->bbJumpKind == BBJ_NONE || block->bbJumpKind == BBJ_ALWAYS);
9344             blockRange.InsertAtEnd(std::move(swapRange));
9345         }
9346     }
9347 }
9348
9349 //------------------------------------------------------------------------
9350 // getTempRegForResolution: Get a free register to use for resolution code.
9351 //
9352 // Arguments:
9353 //    fromBlock - The "from" block on the edge being resolved.
9354 //    toBlock   - The "to"block on the edge
9355 //    type      - the type of register required
9356 //
9357 // Return Value:
9358 //    Returns a register that is free on the given edge, or REG_NA if none is available.
9359 //
9360 // Notes:
9361 //    It is up to the caller to check the return value, and to determine whether a register is
9362 //    available, and to handle that case appropriately.
9363 //    It is also up to the caller to cache the return value, as this is not cheap to compute.
9364
9365 regNumber LinearScan::getTempRegForResolution(BasicBlock* fromBlock, BasicBlock* toBlock, var_types type)
9366 {
9367     // TODO-Throughput: This would be much more efficient if we add RegToVarMaps instead of VarToRegMaps
9368     // and they would be more space-efficient as well.
9369     VarToRegMap fromVarToRegMap = getOutVarToRegMap(fromBlock->bbNum);
9370     VarToRegMap toVarToRegMap   = getInVarToRegMap(toBlock->bbNum);
9371
9372     regMaskTP freeRegs = allRegs(type);
9373 #ifdef DEBUG
9374     if (getStressLimitRegs() == LSRA_LIMIT_SMALL_SET)
9375     {
9376         return REG_NA;
9377     }
9378 #endif // DEBUG
9379     INDEBUG(freeRegs = stressLimitRegs(nullptr, freeRegs));
9380
9381     // We are only interested in the variables that are live-in to the "to" block.
9382     VarSetOps::Iter iter(compiler, toBlock->bbLiveIn);
9383     unsigned        varIndex = 0;
9384     while (iter.NextElem(&varIndex) && freeRegs != RBM_NONE)
9385     {
9386         regNumber fromReg = getVarReg(fromVarToRegMap, varIndex);
9387         regNumber toReg   = getVarReg(toVarToRegMap, varIndex);
9388         assert(fromReg != REG_NA && toReg != REG_NA);
9389         if (fromReg != REG_STK)
9390         {
9391             freeRegs &= ~genRegMask(fromReg);
9392         }
9393         if (toReg != REG_STK)
9394         {
9395             freeRegs &= ~genRegMask(toReg);
9396         }
9397     }
9398     if (freeRegs == RBM_NONE)
9399     {
9400         return REG_NA;
9401     }
9402     else
9403     {
9404         regNumber tempReg = genRegNumFromMask(genFindLowestBit(freeRegs));
9405         return tempReg;
9406     }
9407 }
9408
9409 //------------------------------------------------------------------------
9410 // addResolution: Add a resolution move of the given interval
9411 //
9412 // Arguments:
9413 //    block          - the BasicBlock into which the move will be inserted.
9414 //    insertionPoint - the instruction before which to insert the move
9415 //    interval       - the interval of the var to be moved
9416 //    toReg          - the register to which the var is moving
9417 //    fromReg        - the register from which the var is moving
9418 //
9419 // Return Value:
9420 //    None.
9421 //
9422 // Notes:
9423 //    For joins, we insert at the bottom (indicated by an insertionPoint
9424 //    of nullptr), while for splits we insert at the top.
9425 //    This is because for joins 'block' is a pred of the join, while for splits it is a succ.
9426 //    For critical edges, this function may be called twice - once to move from
9427 //    the source (fromReg), if any, to the stack, in which case toReg will be
9428 //    REG_STK, and we insert at the bottom (leave insertionPoint as nullptr).
9429 //    The next time, we want to move from the stack to the destination (toReg),
9430 //    in which case fromReg will be REG_STK, and we insert at the top.
9431
9432 void LinearScan::addResolution(
9433     BasicBlock* block, GenTreePtr insertionPoint, Interval* interval, regNumber toReg, regNumber fromReg)
9434 {
9435 #ifdef DEBUG
9436     const char* insertionPointString = "top";
9437 #endif // DEBUG
9438     if (insertionPoint == nullptr)
9439     {
9440 #ifdef DEBUG
9441         insertionPointString = "bottom";
9442 #endif // DEBUG
9443     }
9444
9445     JITDUMP("   BB%02u %s: move V%02u from ", block->bbNum, insertionPointString, interval->varNum);
9446     JITDUMP("%s to %s", getRegName(fromReg), getRegName(toReg));
9447
9448     insertMove(block, insertionPoint, interval->varNum, fromReg, toReg);
9449     if (fromReg == REG_STK || toReg == REG_STK)
9450     {
9451         assert(interval->isSpilled);
9452     }
9453     else
9454     {
9455         // We should have already marked this as spilled or split.
9456         assert((interval->isSpilled) || (interval->isSplit));
9457     }
9458
9459     INTRACK_STATS(updateLsraStat(LSRA_STAT_RESOLUTION_MOV, block->bbNum));
9460 }
9461
9462 //------------------------------------------------------------------------
9463 // handleOutgoingCriticalEdges: Performs the necessary resolution on all critical edges that feed out of 'block'
9464 //
9465 // Arguments:
9466 //    block     - the block with outgoing critical edges.
9467 //
9468 // Return Value:
9469 //    None..
9470 //
9471 // Notes:
9472 //    For all outgoing critical edges (i.e. any successor of this block which is
9473 //    a join edge), if there are any conflicts, split the edge by adding a new block,
9474 //    and generate the resolution code into that block.
9475
9476 void LinearScan::handleOutgoingCriticalEdges(BasicBlock* block)
9477 {
9478     VARSET_TP outResolutionSet(VarSetOps::Intersection(compiler, block->bbLiveOut, resolutionCandidateVars));
9479     if (VarSetOps::IsEmpty(compiler, outResolutionSet))
9480     {
9481         return;
9482     }
9483     VARSET_TP sameResolutionSet(VarSetOps::MakeEmpty(compiler));
9484     VARSET_TP sameLivePathsSet(VarSetOps::MakeEmpty(compiler));
9485     VARSET_TP singleTargetSet(VarSetOps::MakeEmpty(compiler));
9486     VARSET_TP diffResolutionSet(VarSetOps::MakeEmpty(compiler));
9487
9488     // Get the outVarToRegMap for this block
9489     VarToRegMap outVarToRegMap = getOutVarToRegMap(block->bbNum);
9490     unsigned    succCount      = block->NumSucc(compiler);
9491     assert(succCount > 1);
9492     VarToRegMap firstSuccInVarToRegMap = nullptr;
9493     BasicBlock* firstSucc              = nullptr;
9494
9495     // First, determine the live regs at the end of this block so that we know what regs are
9496     // available to copy into.
9497     // Note that for this purpose we use the full live-out set, because we must ensure that
9498     // even the registers that remain the same across the edge are preserved correctly.
9499     regMaskTP       liveOutRegs = RBM_NONE;
9500     VarSetOps::Iter liveOutIter(compiler, block->bbLiveOut);
9501     unsigned        liveOutVarIndex = 0;
9502     while (liveOutIter.NextElem(&liveOutVarIndex))
9503     {
9504         regNumber fromReg = getVarReg(outVarToRegMap, liveOutVarIndex);
9505         if (fromReg != REG_STK)
9506         {
9507             liveOutRegs |= genRegMask(fromReg);
9508         }
9509     }
9510
9511     // Next, if this blocks ends with a switch table, we have to make sure not to copy
9512     // into the registers that it uses.
9513     regMaskTP switchRegs = RBM_NONE;
9514     if (block->bbJumpKind == BBJ_SWITCH)
9515     {
9516         // At this point, Lowering has transformed any non-switch-table blocks into
9517         // cascading ifs.
9518         GenTree* switchTable = LIR::AsRange(block).LastNode();
9519         assert(switchTable != nullptr && switchTable->OperGet() == GT_SWITCH_TABLE);
9520
9521         switchRegs   = switchTable->gtRsvdRegs;
9522         GenTree* op1 = switchTable->gtGetOp1();
9523         GenTree* op2 = switchTable->gtGetOp2();
9524         noway_assert(op1 != nullptr && op2 != nullptr);
9525         assert(op1->gtRegNum != REG_NA && op2->gtRegNum != REG_NA);
9526         switchRegs |= genRegMask(op1->gtRegNum);
9527         switchRegs |= genRegMask(op2->gtRegNum);
9528     }
9529
9530     VarToRegMap sameVarToRegMap = sharedCriticalVarToRegMap;
9531     regMaskTP   sameWriteRegs   = RBM_NONE;
9532     regMaskTP   diffReadRegs    = RBM_NONE;
9533
9534     // For each var that may require resolution, classify them as:
9535     // - in the same register at the end of this block and at each target (no resolution needed)
9536     // - in different registers at different targets (resolve separately):
9537     //     diffResolutionSet
9538     // - in the same register at each target at which it's live, but different from the end of
9539     //   this block.  We may be able to resolve these as if it is "join", but only if they do not
9540     //   write to any registers that are read by those in the diffResolutionSet:
9541     //     sameResolutionSet
9542
9543     VarSetOps::Iter outResolutionSetIter(compiler, outResolutionSet);
9544     unsigned        outResolutionSetVarIndex = 0;
9545     while (outResolutionSetIter.NextElem(&outResolutionSetVarIndex))
9546     {
9547         regNumber fromReg             = getVarReg(outVarToRegMap, outResolutionSetVarIndex);
9548         bool      isMatch             = true;
9549         bool      isSame              = false;
9550         bool      maybeSingleTarget   = false;
9551         bool      maybeSameLivePaths  = false;
9552         bool      liveOnlyAtSplitEdge = true;
9553         regNumber sameToReg           = REG_NA;
9554         for (unsigned succIndex = 0; succIndex < succCount; succIndex++)
9555         {
9556             BasicBlock* succBlock = block->GetSucc(succIndex, compiler);
9557             if (!VarSetOps::IsMember(compiler, succBlock->bbLiveIn, outResolutionSetVarIndex))
9558             {
9559                 maybeSameLivePaths = true;
9560                 continue;
9561             }
9562             else if (liveOnlyAtSplitEdge)
9563             {
9564                 // Is the var live only at those target blocks which are connected by a split edge to this block
9565                 liveOnlyAtSplitEdge = ((succBlock->bbPreds->flNext == nullptr) && (succBlock != compiler->fgFirstBB));
9566             }
9567
9568             regNumber toReg = getVarReg(getInVarToRegMap(succBlock->bbNum), outResolutionSetVarIndex);
9569             if (sameToReg == REG_NA)
9570             {
9571                 sameToReg = toReg;
9572                 continue;
9573             }
9574             if (toReg == sameToReg)
9575             {
9576                 continue;
9577             }
9578             sameToReg = REG_NA;
9579             break;
9580         }
9581
9582         // Check for the cases where we can't write to a register.
9583         // We only need to check for these cases if sameToReg is an actual register (not REG_STK).
9584         if (sameToReg != REG_NA && sameToReg != REG_STK)
9585         {
9586             // If there's a path on which this var isn't live, it may use the original value in sameToReg.
9587             // In this case, sameToReg will be in the liveOutRegs of this block.
9588             // Similarly, if sameToReg is in sameWriteRegs, it has already been used (i.e. for a lclVar that's
9589             // live only at another target), and we can't copy another lclVar into that reg in this block.
9590             regMaskTP sameToRegMask = genRegMask(sameToReg);
9591             if (maybeSameLivePaths &&
9592                 (((sameToRegMask & liveOutRegs) != RBM_NONE) || ((sameToRegMask & sameWriteRegs) != RBM_NONE)))
9593             {
9594                 sameToReg = REG_NA;
9595             }
9596             // If this register is used by a switch table at the end of the block, we can't do the copy
9597             // in this block (since we can't insert it after the switch).
9598             if ((sameToRegMask & switchRegs) != RBM_NONE)
9599             {
9600                 sameToReg = REG_NA;
9601             }
9602
9603             // If the var is live only at those blocks connected by a split edge and not live-in at some of the
9604             // target blocks, we will resolve it the same way as if it were in diffResolutionSet and resolution
9605             // will be deferred to the handling of split edges, which means copy will only be at those target(s).
9606             //
9607             // Another way to achieve similar resolution for vars live only at split edges is by removing them
9608             // from consideration up-front but it requires that we traverse those edges anyway to account for
9609             // the registers that must note be overwritten.
9610             if (liveOnlyAtSplitEdge && maybeSameLivePaths)
9611             {
9612                 sameToReg = REG_NA;
9613             }
9614         }
9615
9616         if (sameToReg == REG_NA)
9617         {
9618             VarSetOps::AddElemD(compiler, diffResolutionSet, outResolutionSetVarIndex);
9619             if (fromReg != REG_STK)
9620             {
9621                 diffReadRegs |= genRegMask(fromReg);
9622             }
9623         }
9624         else if (sameToReg != fromReg)
9625         {
9626             VarSetOps::AddElemD(compiler, sameResolutionSet, outResolutionSetVarIndex);
9627             setVarReg(sameVarToRegMap, outResolutionSetVarIndex, sameToReg);
9628             if (sameToReg != REG_STK)
9629             {
9630                 sameWriteRegs |= genRegMask(sameToReg);
9631             }
9632         }
9633     }
9634
9635     if (!VarSetOps::IsEmpty(compiler, sameResolutionSet))
9636     {
9637         if ((sameWriteRegs & diffReadRegs) != RBM_NONE)
9638         {
9639             // We cannot split the "same" and "diff" regs if the "same" set writes registers
9640             // that must be read by the "diff" set.  (Note that when these are done as a "batch"
9641             // we carefully order them to ensure all the input regs are read before they are
9642             // overwritten.)
9643             VarSetOps::UnionD(compiler, diffResolutionSet, sameResolutionSet);
9644             VarSetOps::ClearD(compiler, sameResolutionSet);
9645         }
9646         else
9647         {
9648             // For any vars in the sameResolutionSet, we can simply add the move at the end of "block".
9649             resolveEdge(block, nullptr, ResolveSharedCritical, sameResolutionSet);
9650         }
9651     }
9652     if (!VarSetOps::IsEmpty(compiler, diffResolutionSet))
9653     {
9654         for (unsigned succIndex = 0; succIndex < succCount; succIndex++)
9655         {
9656             BasicBlock* succBlock = block->GetSucc(succIndex, compiler);
9657
9658             // Any "diffResolutionSet" resolution for a block with no other predecessors will be handled later
9659             // as split resolution.
9660             if ((succBlock->bbPreds->flNext == nullptr) && (succBlock != compiler->fgFirstBB))
9661             {
9662                 continue;
9663             }
9664
9665             // Now collect the resolution set for just this edge, if any.
9666             // Check only the vars in diffResolutionSet that are live-in to this successor.
9667             bool        needsResolution   = false;
9668             VarToRegMap succInVarToRegMap = getInVarToRegMap(succBlock->bbNum);
9669             VARSET_TP   edgeResolutionSet(VarSetOps::Intersection(compiler, diffResolutionSet, succBlock->bbLiveIn));
9670             VarSetOps::Iter iter(compiler, edgeResolutionSet);
9671             unsigned        varIndex = 0;
9672             while (iter.NextElem(&varIndex))
9673             {
9674                 regNumber fromReg = getVarReg(outVarToRegMap, varIndex);
9675                 regNumber toReg   = getVarReg(succInVarToRegMap, varIndex);
9676
9677                 if (fromReg == toReg)
9678                 {
9679                     VarSetOps::RemoveElemD(compiler, edgeResolutionSet, varIndex);
9680                 }
9681             }
9682             if (!VarSetOps::IsEmpty(compiler, edgeResolutionSet))
9683             {
9684                 resolveEdge(block, succBlock, ResolveCritical, edgeResolutionSet);
9685             }
9686         }
9687     }
9688 }
9689
9690 //------------------------------------------------------------------------
9691 // resolveEdges: Perform resolution across basic block edges
9692 //
9693 // Arguments:
9694 //    None.
9695 //
9696 // Return Value:
9697 //    None.
9698 //
9699 // Notes:
9700 //    Traverse the basic blocks.
9701 //    - If this block has a single predecessor that is not the immediately
9702 //      preceding block, perform any needed 'split' resolution at the beginning of this block
9703 //    - Otherwise if this block has critical incoming edges, handle them.
9704 //    - If this block has a single successor that has multiple predecesors, perform any needed
9705 //      'join' resolution at the end of this block.
9706 //    Note that a block may have both 'split' or 'critical' incoming edge(s) and 'join' outgoing
9707 //    edges.
9708
9709 void LinearScan::resolveEdges()
9710 {
9711     JITDUMP("RESOLVING EDGES\n");
9712
9713     // The resolutionCandidateVars set was initialized with all the lclVars that are live-in to
9714     // any block. We now intersect that set with any lclVars that ever spilled or split.
9715     // If there are no candidates for resoultion, simply return.
9716
9717     VarSetOps::IntersectionD(compiler, resolutionCandidateVars, splitOrSpilledVars);
9718     if (VarSetOps::IsEmpty(compiler, resolutionCandidateVars))
9719     {
9720         return;
9721     }
9722
9723     BasicBlock *block, *prevBlock = nullptr;
9724
9725     // Handle all the critical edges first.
9726     // We will try to avoid resolution across critical edges in cases where all the critical-edge
9727     // targets of a block have the same home.  We will then split the edges only for the
9728     // remaining mismatches.  We visit the out-edges, as that allows us to share the moves that are
9729     // common among allt he targets.
9730
9731     if (hasCriticalEdges)
9732     {
9733         foreach_block(compiler, block)
9734         {
9735             if (block->bbNum > bbNumMaxBeforeResolution)
9736             {
9737                 // This is a new block added during resolution - we don't need to visit these now.
9738                 continue;
9739             }
9740             if (blockInfo[block->bbNum].hasCriticalOutEdge)
9741             {
9742                 handleOutgoingCriticalEdges(block);
9743             }
9744             prevBlock = block;
9745         }
9746     }
9747
9748     prevBlock = nullptr;
9749     foreach_block(compiler, block)
9750     {
9751         if (block->bbNum > bbNumMaxBeforeResolution)
9752         {
9753             // This is a new block added during resolution - we don't need to visit these now.
9754             continue;
9755         }
9756
9757         unsigned    succCount       = block->NumSucc(compiler);
9758         flowList*   preds           = block->bbPreds;
9759         BasicBlock* uniquePredBlock = block->GetUniquePred(compiler);
9760
9761         // First, if this block has a single predecessor,
9762         // we may need resolution at the beginning of this block.
9763         // This may be true even if it's the block we used for starting locations,
9764         // if a variable was spilled.
9765         VARSET_TP inResolutionSet(VarSetOps::Intersection(compiler, block->bbLiveIn, resolutionCandidateVars));
9766         if (!VarSetOps::IsEmpty(compiler, inResolutionSet))
9767         {
9768             if (uniquePredBlock != nullptr)
9769             {
9770                 // We may have split edges during critical edge resolution, and in the process split
9771                 // a non-critical edge as well.
9772                 // It is unlikely that we would ever have more than one of these in sequence (indeed,
9773                 // I don't think it's possible), but there's no need to assume that it can't.
9774                 while (uniquePredBlock->bbNum > bbNumMaxBeforeResolution)
9775                 {
9776                     uniquePredBlock = uniquePredBlock->GetUniquePred(compiler);
9777                     noway_assert(uniquePredBlock != nullptr);
9778                 }
9779                 resolveEdge(uniquePredBlock, block, ResolveSplit, inResolutionSet);
9780             }
9781         }
9782
9783         // Finally, if this block has a single successor:
9784         //  - and that has at least one other predecessor (otherwise we will do the resolution at the
9785         //    top of the successor),
9786         //  - and that is not the target of a critical edge (otherwise we've already handled it)
9787         // we may need resolution at the end of this block.
9788
9789         if (succCount == 1)
9790         {
9791             BasicBlock* succBlock = block->GetSucc(0, compiler);
9792             if (succBlock->GetUniquePred(compiler) == nullptr)
9793             {
9794                 VARSET_TP outResolutionSet(
9795                     VarSetOps::Intersection(compiler, succBlock->bbLiveIn, resolutionCandidateVars));
9796                 if (!VarSetOps::IsEmpty(compiler, outResolutionSet))
9797                 {
9798                     resolveEdge(block, succBlock, ResolveJoin, outResolutionSet);
9799                 }
9800             }
9801         }
9802     }
9803
9804     // Now, fixup the mapping for any blocks that were adding for edge splitting.
9805     // See the comment prior to the call to fgSplitEdge() in resolveEdge().
9806     // Note that we could fold this loop in with the checking code below, but that
9807     // would only improve the debug case, and would clutter up the code somewhat.
9808     if (compiler->fgBBNumMax > bbNumMaxBeforeResolution)
9809     {
9810         foreach_block(compiler, block)
9811         {
9812             if (block->bbNum > bbNumMaxBeforeResolution)
9813             {
9814                 // There may be multiple blocks inserted when we split.  But we must always have exactly
9815                 // one path (i.e. all blocks must be single-successor and single-predecessor),
9816                 // and only one block along the path may be non-empty.
9817                 // Note that we may have a newly-inserted block that is empty, but which connects
9818                 // two non-resolution blocks. This happens when an edge is split that requires it.
9819
9820                 BasicBlock* succBlock = block;
9821                 do
9822                 {
9823                     succBlock = succBlock->GetUniqueSucc();
9824                     noway_assert(succBlock != nullptr);
9825                 } while ((succBlock->bbNum > bbNumMaxBeforeResolution) && succBlock->isEmpty());
9826
9827                 BasicBlock* predBlock = block;
9828                 do
9829                 {
9830                     predBlock = predBlock->GetUniquePred(compiler);
9831                     noway_assert(predBlock != nullptr);
9832                 } while ((predBlock->bbNum > bbNumMaxBeforeResolution) && predBlock->isEmpty());
9833
9834                 unsigned succBBNum = succBlock->bbNum;
9835                 unsigned predBBNum = predBlock->bbNum;
9836                 if (block->isEmpty())
9837                 {
9838                     // For the case of the empty block, find the non-resolution block (succ or pred).
9839                     if (predBBNum > bbNumMaxBeforeResolution)
9840                     {
9841                         assert(succBBNum <= bbNumMaxBeforeResolution);
9842                         predBBNum = 0;
9843                     }
9844                     else
9845                     {
9846                         succBBNum = 0;
9847                     }
9848                 }
9849                 else
9850                 {
9851                     assert((succBBNum <= bbNumMaxBeforeResolution) && (predBBNum <= bbNumMaxBeforeResolution));
9852                 }
9853                 SplitEdgeInfo info = {predBBNum, succBBNum};
9854                 getSplitBBNumToTargetBBNumMap()->Set(block->bbNum, info);
9855             }
9856         }
9857     }
9858
9859 #ifdef DEBUG
9860     // Make sure the varToRegMaps match up on all edges.
9861     bool foundMismatch = false;
9862     foreach_block(compiler, block)
9863     {
9864         if (block->isEmpty() && block->bbNum > bbNumMaxBeforeResolution)
9865         {
9866             continue;
9867         }
9868         VarToRegMap toVarToRegMap = getInVarToRegMap(block->bbNum);
9869         for (flowList* pred = block->bbPreds; pred != nullptr; pred = pred->flNext)
9870         {
9871             BasicBlock*     predBlock       = pred->flBlock;
9872             VarToRegMap     fromVarToRegMap = getOutVarToRegMap(predBlock->bbNum);
9873             VarSetOps::Iter iter(compiler, block->bbLiveIn);
9874             unsigned        varIndex = 0;
9875             while (iter.NextElem(&varIndex))
9876             {
9877                 regNumber fromReg = getVarReg(fromVarToRegMap, varIndex);
9878                 regNumber toReg   = getVarReg(toVarToRegMap, varIndex);
9879                 if (fromReg != toReg)
9880                 {
9881                     if (!foundMismatch)
9882                     {
9883                         foundMismatch = true;
9884                         printf("Found mismatched var locations after resolution!\n");
9885                     }
9886                     unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
9887                     printf(" V%02u: BB%02u to BB%02u: %s to %s\n", varNum, predBlock->bbNum, block->bbNum,
9888                            getRegName(fromReg), getRegName(toReg));
9889                 }
9890             }
9891         }
9892     }
9893     assert(!foundMismatch);
9894 #endif
9895     JITDUMP("\n");
9896 }
9897
9898 //------------------------------------------------------------------------
9899 // resolveEdge: Perform the specified type of resolution between two blocks.
9900 //
9901 // Arguments:
9902 //    fromBlock     - the block from which the edge originates
9903 //    toBlock       - the block at which the edge terminates
9904 //    resolveType   - the type of resolution to be performed
9905 //    liveSet       - the set of tracked lclVar indices which may require resolution
9906 //
9907 // Return Value:
9908 //    None.
9909 //
9910 // Assumptions:
9911 //    The caller must have performed the analysis to determine the type of the edge.
9912 //
9913 // Notes:
9914 //    This method emits the correctly ordered moves necessary to place variables in the
9915 //    correct registers across a Split, Join or Critical edge.
9916 //    In order to avoid overwriting register values before they have been moved to their
9917 //    new home (register/stack), it first does the register-to-stack moves (to free those
9918 //    registers), then the register to register moves, ensuring that the target register
9919 //    is free before the move, and then finally the stack to register moves.
9920
9921 void LinearScan::resolveEdge(BasicBlock*      fromBlock,
9922                              BasicBlock*      toBlock,
9923                              ResolveType      resolveType,
9924                              VARSET_VALARG_TP liveSet)
9925 {
9926     VarToRegMap fromVarToRegMap = getOutVarToRegMap(fromBlock->bbNum);
9927     VarToRegMap toVarToRegMap;
9928     if (resolveType == ResolveSharedCritical)
9929     {
9930         toVarToRegMap = sharedCriticalVarToRegMap;
9931     }
9932     else
9933     {
9934         toVarToRegMap = getInVarToRegMap(toBlock->bbNum);
9935     }
9936
9937     // The block to which we add the resolution moves depends on the resolveType
9938     BasicBlock* block;
9939     switch (resolveType)
9940     {
9941         case ResolveJoin:
9942         case ResolveSharedCritical:
9943             block = fromBlock;
9944             break;
9945         case ResolveSplit:
9946             block = toBlock;
9947             break;
9948         case ResolveCritical:
9949             // fgSplitEdge may add one or two BasicBlocks.  It returns the block that splits
9950             // the edge from 'fromBlock' and 'toBlock', but if it inserts that block right after
9951             // a block with a fall-through it will have to create another block to handle that edge.
9952             // These new blocks can be mapped to existing blocks in order to correctly handle
9953             // the calls to recordVarLocationsAtStartOfBB() from codegen.  That mapping is handled
9954             // in resolveEdges(), after all the edge resolution has been done (by calling this
9955             // method for each edge).
9956             block = compiler->fgSplitEdge(fromBlock, toBlock);
9957
9958             // Split edges are counted against fromBlock.
9959             INTRACK_STATS(updateLsraStat(LSRA_STAT_SPLIT_EDGE, fromBlock->bbNum));
9960             break;
9961         default:
9962             unreached();
9963             break;
9964     }
9965
9966 #ifndef _TARGET_XARCH_
9967     // We record tempregs for beginning and end of each block.
9968     // For amd64/x86 we only need a tempReg for float - we'll use xchg for int.
9969     // TODO-Throughput: It would be better to determine the tempRegs on demand, but the code below
9970     // modifies the varToRegMaps so we don't have all the correct registers at the time
9971     // we need to get the tempReg.
9972     regNumber tempRegInt =
9973         (resolveType == ResolveSharedCritical) ? REG_NA : getTempRegForResolution(fromBlock, toBlock, TYP_INT);
9974 #endif // !_TARGET_XARCH_
9975     regNumber tempRegFlt = REG_NA;
9976     if ((compiler->compFloatingPointUsed) && (resolveType != ResolveSharedCritical))
9977     {
9978
9979 #ifdef _TARGET_ARM_
9980         // Let's try to reserve a double register for TYP_FLOAT and TYP_DOUBLE
9981         tempRegFlt = getTempRegForResolution(fromBlock, toBlock, TYP_DOUBLE);
9982         if (tempRegFlt == REG_NA)
9983         {
9984             // If fails, try to reserve a float register for TYP_FLOAT
9985             tempRegFlt = getTempRegForResolution(fromBlock, toBlock, TYP_FLOAT);
9986         }
9987 #else
9988         tempRegFlt                   = getTempRegForResolution(fromBlock, toBlock, TYP_FLOAT);
9989 #endif
9990     }
9991
9992     regMaskTP targetRegsToDo      = RBM_NONE;
9993     regMaskTP targetRegsReady     = RBM_NONE;
9994     regMaskTP targetRegsFromStack = RBM_NONE;
9995
9996     // The following arrays capture the location of the registers as they are moved:
9997     // - location[reg] gives the current location of the var that was originally in 'reg'.
9998     //   (Note that a var may be moved more than once.)
9999     // - source[reg] gives the original location of the var that needs to be moved to 'reg'.
10000     // For example, if a var is in rax and needs to be moved to rsi, then we would start with:
10001     //   location[rax] == rax
10002     //   source[rsi] == rax     -- this doesn't change
10003     // Then, if for some reason we need to move it temporary to rbx, we would have:
10004     //   location[rax] == rbx
10005     // Once we have completed the move, we will have:
10006     //   location[rax] == REG_NA
10007     // This indicates that the var originally in rax is now in its target register.
10008
10009     regNumberSmall location[REG_COUNT];
10010     C_ASSERT(sizeof(char) == sizeof(regNumberSmall)); // for memset to work
10011     memset(location, REG_NA, REG_COUNT);
10012     regNumberSmall source[REG_COUNT];
10013     memset(source, REG_NA, REG_COUNT);
10014
10015     // What interval is this register associated with?
10016     // (associated with incoming reg)
10017     Interval* sourceIntervals[REG_COUNT];
10018     memset(&sourceIntervals, 0, sizeof(sourceIntervals));
10019
10020     // Intervals for vars that need to be loaded from the stack
10021     Interval* stackToRegIntervals[REG_COUNT];
10022     memset(&stackToRegIntervals, 0, sizeof(stackToRegIntervals));
10023
10024     // Get the starting insertion point for the "to" resolution
10025     GenTreePtr insertionPoint = nullptr;
10026     if (resolveType == ResolveSplit || resolveType == ResolveCritical)
10027     {
10028         insertionPoint = LIR::AsRange(block).FirstNonPhiNode();
10029     }
10030
10031     // First:
10032     //   - Perform all moves from reg to stack (no ordering needed on these)
10033     //   - For reg to reg moves, record the current location, associating their
10034     //     source location with the target register they need to go into
10035     //   - For stack to reg moves (done last, no ordering needed between them)
10036     //     record the interval associated with the target reg
10037     // TODO-Throughput: We should be looping over the liveIn and liveOut registers, since
10038     // that will scale better than the live variables
10039
10040     VarSetOps::Iter iter(compiler, liveSet);
10041     unsigned        varIndex = 0;
10042     while (iter.NextElem(&varIndex))
10043     {
10044         regNumber fromReg = getVarReg(fromVarToRegMap, varIndex);
10045         regNumber toReg   = getVarReg(toVarToRegMap, varIndex);
10046         if (fromReg == toReg)
10047         {
10048             continue;
10049         }
10050
10051         // For Critical edges, the location will not change on either side of the edge,
10052         // since we'll add a new block to do the move.
10053         if (resolveType == ResolveSplit)
10054         {
10055             setVarReg(toVarToRegMap, varIndex, fromReg);
10056         }
10057         else if (resolveType == ResolveJoin || resolveType == ResolveSharedCritical)
10058         {
10059             setVarReg(fromVarToRegMap, varIndex, toReg);
10060         }
10061
10062         assert(fromReg < UCHAR_MAX && toReg < UCHAR_MAX);
10063
10064         Interval* interval = getIntervalForLocalVar(varIndex);
10065
10066         if (fromReg == REG_STK)
10067         {
10068             stackToRegIntervals[toReg] = interval;
10069             targetRegsFromStack |= genRegMask(toReg);
10070         }
10071         else if (toReg == REG_STK)
10072         {
10073             // Do the reg to stack moves now
10074             addResolution(block, insertionPoint, interval, REG_STK, fromReg);
10075             JITDUMP(" (%s)\n", resolveTypeName[resolveType]);
10076         }
10077         else
10078         {
10079             location[fromReg]        = (regNumberSmall)fromReg;
10080             source[toReg]            = (regNumberSmall)fromReg;
10081             sourceIntervals[fromReg] = interval;
10082             targetRegsToDo |= genRegMask(toReg);
10083         }
10084     }
10085
10086     // REGISTER to REGISTER MOVES
10087
10088     // First, find all the ones that are ready to move now
10089     regMaskTP targetCandidates = targetRegsToDo;
10090     while (targetCandidates != RBM_NONE)
10091     {
10092         regMaskTP targetRegMask = genFindLowestBit(targetCandidates);
10093         targetCandidates &= ~targetRegMask;
10094         regNumber targetReg = genRegNumFromMask(targetRegMask);
10095         if (location[targetReg] == REG_NA)
10096         {
10097             targetRegsReady |= targetRegMask;
10098         }
10099     }
10100
10101     // Perform reg to reg moves
10102     while (targetRegsToDo != RBM_NONE)
10103     {
10104         while (targetRegsReady != RBM_NONE)
10105         {
10106             regMaskTP targetRegMask = genFindLowestBit(targetRegsReady);
10107             targetRegsToDo &= ~targetRegMask;
10108             targetRegsReady &= ~targetRegMask;
10109             regNumber targetReg = genRegNumFromMask(targetRegMask);
10110             assert(location[targetReg] != targetReg);
10111             regNumber sourceReg = (regNumber)source[targetReg];
10112             regNumber fromReg   = (regNumber)location[sourceReg];
10113             assert(fromReg < UCHAR_MAX && sourceReg < UCHAR_MAX);
10114             Interval* interval = sourceIntervals[sourceReg];
10115             assert(interval != nullptr);
10116             addResolution(block, insertionPoint, interval, targetReg, fromReg);
10117             JITDUMP(" (%s)\n", resolveTypeName[resolveType]);
10118             sourceIntervals[sourceReg] = nullptr;
10119             location[sourceReg]        = REG_NA;
10120
10121             // Do we have a free targetReg?
10122             if (fromReg == sourceReg && source[fromReg] != REG_NA)
10123             {
10124                 regMaskTP fromRegMask = genRegMask(fromReg);
10125                 targetRegsReady |= fromRegMask;
10126             }
10127         }
10128         if (targetRegsToDo != RBM_NONE)
10129         {
10130             regMaskTP targetRegMask = genFindLowestBit(targetRegsToDo);
10131             regNumber targetReg     = genRegNumFromMask(targetRegMask);
10132
10133             // Is it already there due to other moves?
10134             // If not, move it to the temp reg, OR swap it with another register
10135             regNumber sourceReg = (regNumber)source[targetReg];
10136             regNumber fromReg   = (regNumber)location[sourceReg];
10137             if (targetReg == fromReg)
10138             {
10139                 targetRegsToDo &= ~targetRegMask;
10140             }
10141             else
10142             {
10143                 regNumber tempReg = REG_NA;
10144                 bool      useSwap = false;
10145                 if (emitter::isFloatReg(targetReg))
10146                 {
10147 #ifdef _TARGET_ARM_
10148                     if (sourceIntervals[fromReg]->registerType == TYP_DOUBLE)
10149                     {
10150                         // ARM32 requires a double temp register for TYP_DOUBLE.
10151                         // We tried to reserve a double temp register first, but sometimes we can't.
10152                         tempReg = genIsValidDoubleReg(tempRegFlt) ? tempRegFlt : REG_NA;
10153                     }
10154                     else
10155 #endif // _TARGET_ARM_
10156                         tempReg = tempRegFlt;
10157                 }
10158 #ifdef _TARGET_XARCH_
10159                 else
10160                 {
10161                     useSwap = true;
10162                 }
10163 #else // !_TARGET_XARCH_
10164
10165                 else
10166                 {
10167                     tempReg = tempRegInt;
10168                 }
10169
10170 #endif // !_TARGET_XARCH_
10171                 if (useSwap || tempReg == REG_NA)
10172                 {
10173                     // First, we have to figure out the destination register for what's currently in fromReg,
10174                     // so that we can find its sourceInterval.
10175                     regNumber otherTargetReg = REG_NA;
10176
10177                     // By chance, is fromReg going where it belongs?
10178                     if (location[source[fromReg]] == targetReg)
10179                     {
10180                         otherTargetReg = fromReg;
10181                         // If we can swap, we will be done with otherTargetReg as well.
10182                         // Otherwise, we'll spill it to the stack and reload it later.
10183                         if (useSwap)
10184                         {
10185                             regMaskTP fromRegMask = genRegMask(fromReg);
10186                             targetRegsToDo &= ~fromRegMask;
10187                         }
10188                     }
10189                     else
10190                     {
10191                         // Look at the remaining registers from targetRegsToDo (which we expect to be relatively
10192                         // small at this point) to find out what's currently in targetReg.
10193                         regMaskTP mask = targetRegsToDo;
10194                         while (mask != RBM_NONE && otherTargetReg == REG_NA)
10195                         {
10196                             regMaskTP nextRegMask = genFindLowestBit(mask);
10197                             regNumber nextReg     = genRegNumFromMask(nextRegMask);
10198                             mask &= ~nextRegMask;
10199                             if (location[source[nextReg]] == targetReg)
10200                             {
10201                                 otherTargetReg = nextReg;
10202                             }
10203                         }
10204                     }
10205                     assert(otherTargetReg != REG_NA);
10206
10207                     if (useSwap)
10208                     {
10209                         // Generate a "swap" of fromReg and targetReg
10210                         insertSwap(block, insertionPoint, sourceIntervals[source[otherTargetReg]]->varNum, targetReg,
10211                                    sourceIntervals[sourceReg]->varNum, fromReg);
10212                         location[sourceReg]              = REG_NA;
10213                         location[source[otherTargetReg]] = (regNumberSmall)fromReg;
10214
10215                         INTRACK_STATS(updateLsraStat(LSRA_STAT_RESOLUTION_MOV, block->bbNum));
10216                     }
10217                     else
10218                     {
10219                         // Spill "targetReg" to the stack and add its eventual target (otherTargetReg)
10220                         // to "targetRegsFromStack", which will be handled below.
10221                         // NOTE: This condition is very rare.  Setting COMPlus_JitStressRegs=0x203
10222                         // has been known to trigger it in JIT SH.
10223
10224                         // First, spill "otherInterval" from targetReg to the stack.
10225                         Interval* otherInterval = sourceIntervals[source[otherTargetReg]];
10226                         setIntervalAsSpilled(otherInterval);
10227                         addResolution(block, insertionPoint, otherInterval, REG_STK, targetReg);
10228                         JITDUMP(" (%s)\n", resolveTypeName[resolveType]);
10229                         location[source[otherTargetReg]] = REG_STK;
10230
10231                         // Now, move the interval that is going to targetReg, and add its "fromReg" to
10232                         // "targetRegsReady".
10233                         addResolution(block, insertionPoint, sourceIntervals[sourceReg], targetReg, fromReg);
10234                         JITDUMP(" (%s)\n", resolveTypeName[resolveType]);
10235                         location[sourceReg] = REG_NA;
10236                         targetRegsReady |= genRegMask(fromReg);
10237                     }
10238                     targetRegsToDo &= ~targetRegMask;
10239                 }
10240                 else
10241                 {
10242                     compiler->codeGen->regSet.rsSetRegsModified(genRegMask(tempReg) DEBUGARG(dumpTerse));
10243                     assert(sourceIntervals[targetReg] != nullptr);
10244                     addResolution(block, insertionPoint, sourceIntervals[targetReg], tempReg, targetReg);
10245                     JITDUMP(" (%s)\n", resolveTypeName[resolveType]);
10246                     location[targetReg] = (regNumberSmall)tempReg;
10247                     targetRegsReady |= targetRegMask;
10248                 }
10249             }
10250         }
10251     }
10252
10253     // Finally, perform stack to reg moves
10254     // All the target regs will be empty at this point
10255     while (targetRegsFromStack != RBM_NONE)
10256     {
10257         regMaskTP targetRegMask = genFindLowestBit(targetRegsFromStack);
10258         targetRegsFromStack &= ~targetRegMask;
10259         regNumber targetReg = genRegNumFromMask(targetRegMask);
10260
10261         Interval* interval = stackToRegIntervals[targetReg];
10262         assert(interval != nullptr);
10263
10264         addResolution(block, insertionPoint, interval, targetReg, REG_STK);
10265         JITDUMP(" (%s)\n", resolveTypeName[resolveType]);
10266     }
10267 }
10268
10269 void TreeNodeInfo::Initialize(LinearScan* lsra, GenTree* node, LsraLocation location)
10270 {
10271     regMaskTP dstCandidates;
10272
10273     // if there is a reg indicated on the tree node, use that for dstCandidates
10274     // the exception is the NOP, which sometimes show up around late args.
10275     // TODO-Cleanup: get rid of those NOPs.
10276     if (node->gtRegNum == REG_NA || node->gtOper == GT_NOP)
10277     {
10278 #ifdef ARM_SOFTFP
10279         if (node->OperGet() == GT_PUTARG_REG)
10280         {
10281             dstCandidates = lsra->allRegs(TYP_INT);
10282         }
10283         else
10284 #endif
10285         {
10286             dstCandidates = lsra->allRegs(node->TypeGet());
10287         }
10288     }
10289     else
10290     {
10291         dstCandidates = genRegMask(node->gtRegNum);
10292     }
10293
10294     internalIntCount    = 0;
10295     internalFloatCount  = 0;
10296     isLocalDefUse       = false;
10297     isLsraAdded         = false;
10298     definesAnyRegisters = false;
10299
10300     setDstCandidates(lsra, dstCandidates);
10301     srcCandsIndex = dstCandsIndex;
10302
10303     setInternalCandidates(lsra, lsra->allRegs(TYP_INT));
10304
10305     loc = location;
10306 #ifdef DEBUG
10307     isInitialized = true;
10308 #endif
10309
10310     assert(IsValid(lsra));
10311 }
10312
10313 regMaskTP TreeNodeInfo::getSrcCandidates(LinearScan* lsra)
10314 {
10315     return lsra->GetRegMaskForIndex(srcCandsIndex);
10316 }
10317
10318 void TreeNodeInfo::setSrcCandidates(LinearScan* lsra, regMaskTP mask)
10319 {
10320     LinearScan::RegMaskIndex i = lsra->GetIndexForRegMask(mask);
10321     assert(FitsIn<unsigned char>(i));
10322     srcCandsIndex = (unsigned char)i;
10323 }
10324
10325 regMaskTP TreeNodeInfo::getDstCandidates(LinearScan* lsra)
10326 {
10327     return lsra->GetRegMaskForIndex(dstCandsIndex);
10328 }
10329
10330 void TreeNodeInfo::setDstCandidates(LinearScan* lsra, regMaskTP mask)
10331 {
10332     LinearScan::RegMaskIndex i = lsra->GetIndexForRegMask(mask);
10333     assert(FitsIn<unsigned char>(i));
10334     dstCandsIndex = (unsigned char)i;
10335 }
10336
10337 regMaskTP TreeNodeInfo::getInternalCandidates(LinearScan* lsra)
10338 {
10339     return lsra->GetRegMaskForIndex(internalCandsIndex);
10340 }
10341
10342 void TreeNodeInfo::setInternalCandidates(LinearScan* lsra, regMaskTP mask)
10343 {
10344     LinearScan::RegMaskIndex i = lsra->GetIndexForRegMask(mask);
10345     assert(FitsIn<unsigned char>(i));
10346     internalCandsIndex = (unsigned char)i;
10347 }
10348
10349 void TreeNodeInfo::addInternalCandidates(LinearScan* lsra, regMaskTP mask)
10350 {
10351     LinearScan::RegMaskIndex i = lsra->GetIndexForRegMask(lsra->GetRegMaskForIndex(internalCandsIndex) | mask);
10352     assert(FitsIn<unsigned char>(i));
10353     internalCandsIndex = (unsigned char)i;
10354 }
10355
10356 #if TRACK_LSRA_STATS
10357 // ----------------------------------------------------------
10358 // updateLsraStat: Increment LSRA stat counter.
10359 //
10360 // Arguments:
10361 //    stat      -   LSRA stat enum
10362 //    bbNum     -   Basic block to which LSRA stat needs to be
10363 //                  associated with.
10364 //
10365 void LinearScan::updateLsraStat(LsraStat stat, unsigned bbNum)
10366 {
10367     if (bbNum > bbNumMaxBeforeResolution)
10368     {
10369         // This is a newly created basic block as part of resolution.
10370         // These blocks contain resolution moves that are already accounted.
10371         return;
10372     }
10373
10374     switch (stat)
10375     {
10376         case LSRA_STAT_SPILL:
10377             ++(blockInfo[bbNum].spillCount);
10378             break;
10379
10380         case LSRA_STAT_COPY_REG:
10381             ++(blockInfo[bbNum].copyRegCount);
10382             break;
10383
10384         case LSRA_STAT_RESOLUTION_MOV:
10385             ++(blockInfo[bbNum].resolutionMovCount);
10386             break;
10387
10388         case LSRA_STAT_SPLIT_EDGE:
10389             ++(blockInfo[bbNum].splitEdgeCount);
10390             break;
10391
10392         default:
10393             break;
10394     }
10395 }
10396
10397 // -----------------------------------------------------------
10398 // dumpLsraStats - dumps Lsra stats to given file.
10399 //
10400 // Arguments:
10401 //    file    -  file to which stats are to be written.
10402 //
10403 void LinearScan::dumpLsraStats(FILE* file)
10404 {
10405     unsigned sumSpillCount         = 0;
10406     unsigned sumCopyRegCount       = 0;
10407     unsigned sumResolutionMovCount = 0;
10408     unsigned sumSplitEdgeCount     = 0;
10409     UINT64   wtdSpillCount         = 0;
10410     UINT64   wtdCopyRegCount       = 0;
10411     UINT64   wtdResolutionMovCount = 0;
10412
10413     fprintf(file, "----------\n");
10414     fprintf(file, "LSRA Stats");
10415 #ifdef DEBUG
10416     if (!VERBOSE)
10417     {
10418         fprintf(file, " : %s\n", compiler->info.compFullName);
10419     }
10420     else
10421     {
10422         // In verbose mode no need to print full name
10423         // while printing lsra stats.
10424         fprintf(file, "\n");
10425     }
10426 #else
10427     fprintf(file, " : %s\n", compiler->eeGetMethodFullName(compiler->info.compCompHnd));
10428 #endif
10429
10430     fprintf(file, "----------\n");
10431
10432     for (BasicBlock* block = compiler->fgFirstBB; block != nullptr; block = block->bbNext)
10433     {
10434         if (block->bbNum > bbNumMaxBeforeResolution)
10435         {
10436             continue;
10437         }
10438
10439         unsigned spillCount         = blockInfo[block->bbNum].spillCount;
10440         unsigned copyRegCount       = blockInfo[block->bbNum].copyRegCount;
10441         unsigned resolutionMovCount = blockInfo[block->bbNum].resolutionMovCount;
10442         unsigned splitEdgeCount     = blockInfo[block->bbNum].splitEdgeCount;
10443
10444         if (spillCount != 0 || copyRegCount != 0 || resolutionMovCount != 0 || splitEdgeCount != 0)
10445         {
10446             fprintf(file, "BB%02u [%8d]: ", block->bbNum, block->bbWeight);
10447             fprintf(file, "SpillCount = %d, ResolutionMovs = %d, SplitEdges = %d, CopyReg = %d\n", spillCount,
10448                     resolutionMovCount, splitEdgeCount, copyRegCount);
10449         }
10450
10451         sumSpillCount += spillCount;
10452         sumCopyRegCount += copyRegCount;
10453         sumResolutionMovCount += resolutionMovCount;
10454         sumSplitEdgeCount += splitEdgeCount;
10455
10456         wtdSpillCount += (UINT64)spillCount * block->bbWeight;
10457         wtdCopyRegCount += (UINT64)copyRegCount * block->bbWeight;
10458         wtdResolutionMovCount += (UINT64)resolutionMovCount * block->bbWeight;
10459     }
10460
10461     fprintf(file, "Total Tracked Vars:  %d\n", compiler->lvaTrackedCount);
10462     fprintf(file, "Total Reg Cand Vars: %d\n", regCandidateVarCount);
10463     fprintf(file, "Total number of Intervals: %d\n", static_cast<unsigned>(intervals.size() - 1));
10464     fprintf(file, "Total number of RefPositions: %d\n", static_cast<unsigned>(refPositions.size() - 1));
10465     fprintf(file, "Total Spill Count: %d    Weighted: %I64u\n", sumSpillCount, wtdSpillCount);
10466     fprintf(file, "Total CopyReg Count: %d   Weighted: %I64u\n", sumCopyRegCount, wtdCopyRegCount);
10467     fprintf(file, "Total ResolutionMov Count: %d    Weighted: %I64u\n", sumResolutionMovCount, wtdResolutionMovCount);
10468     fprintf(file, "Total number of split edges: %d\n", sumSplitEdgeCount);
10469
10470     // compute total number of spill temps created
10471     unsigned numSpillTemps = 0;
10472     for (int i = 0; i < TYP_COUNT; i++)
10473     {
10474         numSpillTemps += maxSpill[i];
10475     }
10476     fprintf(file, "Total Number of spill temps created: %d\n\n", numSpillTemps);
10477 }
10478 #endif // TRACK_LSRA_STATS
10479
10480 #ifdef DEBUG
10481 void dumpRegMask(regMaskTP regs)
10482 {
10483     if (regs == RBM_ALLINT)
10484     {
10485         printf("[allInt]");
10486     }
10487     else if (regs == (RBM_ALLINT & ~RBM_FPBASE))
10488     {
10489         printf("[allIntButFP]");
10490     }
10491     else if (regs == RBM_ALLFLOAT)
10492     {
10493         printf("[allFloat]");
10494     }
10495     else if (regs == RBM_ALLDOUBLE)
10496     {
10497         printf("[allDouble]");
10498     }
10499     else
10500     {
10501         dspRegMask(regs);
10502     }
10503 }
10504
10505 static const char* getRefTypeName(RefType refType)
10506 {
10507     switch (refType)
10508     {
10509 #define DEF_REFTYPE(memberName, memberValue, shortName)                                                                \
10510     case memberName:                                                                                                   \
10511         return #memberName;
10512 #include "lsra_reftypes.h"
10513 #undef DEF_REFTYPE
10514         default:
10515             return nullptr;
10516     }
10517 }
10518
10519 static const char* getRefTypeShortName(RefType refType)
10520 {
10521     switch (refType)
10522     {
10523 #define DEF_REFTYPE(memberName, memberValue, shortName)                                                                \
10524     case memberName:                                                                                                   \
10525         return shortName;
10526 #include "lsra_reftypes.h"
10527 #undef DEF_REFTYPE
10528         default:
10529             return nullptr;
10530     }
10531 }
10532
10533 void RefPosition::dump()
10534 {
10535     printf("<RefPosition #%-3u @%-3u", rpNum, nodeLocation);
10536
10537     if (nextRefPosition)
10538     {
10539         printf(" ->#%-3u", nextRefPosition->rpNum);
10540     }
10541
10542     printf(" %s ", getRefTypeName(refType));
10543
10544     if (this->isPhysRegRef)
10545     {
10546         this->getReg()->tinyDump();
10547     }
10548     else if (getInterval())
10549     {
10550         this->getInterval()->tinyDump();
10551     }
10552
10553     if (this->treeNode)
10554     {
10555         printf("%s ", treeNode->OpName(treeNode->OperGet()));
10556     }
10557     printf("BB%02u ", this->bbNum);
10558
10559     printf("regmask=");
10560     dumpRegMask(registerAssignment);
10561
10562     if (this->lastUse)
10563     {
10564         printf(" last");
10565     }
10566     if (this->reload)
10567     {
10568         printf(" reload");
10569     }
10570     if (this->spillAfter)
10571     {
10572         printf(" spillAfter");
10573     }
10574     if (this->moveReg)
10575     {
10576         printf(" move");
10577     }
10578     if (this->copyReg)
10579     {
10580         printf(" copy");
10581     }
10582     if (this->isFixedRegRef)
10583     {
10584         printf(" fixed");
10585     }
10586     if (this->isLocalDefUse)
10587     {
10588         printf(" local");
10589     }
10590     if (this->delayRegFree)
10591     {
10592         printf(" delay");
10593     }
10594     if (this->outOfOrder)
10595     {
10596         printf(" outOfOrder");
10597     }
10598
10599     if (this->AllocateIfProfitable())
10600     {
10601         printf(" regOptional");
10602     }
10603     printf(">\n");
10604 }
10605
10606 void RegRecord::dump()
10607 {
10608     tinyDump();
10609 }
10610
10611 void Interval::dump()
10612 {
10613     printf("Interval %2u:", intervalIndex);
10614
10615     if (isLocalVar)
10616     {
10617         printf(" (V%02u)", varNum);
10618     }
10619     if (isInternal)
10620     {
10621         printf(" (INTERNAL)");
10622     }
10623     if (isSpilled)
10624     {
10625         printf(" (SPILLED)");
10626     }
10627     if (isSplit)
10628     {
10629         printf(" (SPLIT)");
10630     }
10631     if (isStructField)
10632     {
10633         printf(" (struct)");
10634     }
10635     if (isSpecialPutArg)
10636     {
10637         printf(" (specialPutArg)");
10638     }
10639     if (isConstant)
10640     {
10641         printf(" (constant)");
10642     }
10643
10644     printf(" RefPositions {");
10645     for (RefPosition* refPosition = this->firstRefPosition; refPosition != nullptr;
10646          refPosition              = refPosition->nextRefPosition)
10647     {
10648         printf("#%u@%u", refPosition->rpNum, refPosition->nodeLocation);
10649         if (refPosition->nextRefPosition)
10650         {
10651             printf(" ");
10652         }
10653     }
10654     printf("}");
10655
10656     // this is not used (yet?)
10657     // printf(" SpillOffset %d", this->spillOffset);
10658
10659     printf(" physReg:%s", getRegName(physReg));
10660
10661     printf(" Preferences=");
10662     dumpRegMask(this->registerPreferences);
10663
10664     if (relatedInterval)
10665     {
10666         printf(" RelatedInterval ");
10667         relatedInterval->microDump();
10668         printf("[%p]", dspPtr(relatedInterval));
10669     }
10670
10671     printf("\n");
10672 }
10673
10674 // print out very concise representation
10675 void Interval::tinyDump()
10676 {
10677     printf("<Ivl:%u", intervalIndex);
10678     if (isLocalVar)
10679     {
10680         printf(" V%02u", varNum);
10681     }
10682     if (isInternal)
10683     {
10684         printf(" internal");
10685     }
10686     printf("> ");
10687 }
10688
10689 // print out extremely concise representation
10690 void Interval::microDump()
10691 {
10692     char intervalTypeChar = 'I';
10693     if (isInternal)
10694     {
10695         intervalTypeChar = 'T';
10696     }
10697     else if (isLocalVar)
10698     {
10699         intervalTypeChar = 'L';
10700     }
10701
10702     printf("<%c%u>", intervalTypeChar, intervalIndex);
10703 }
10704
10705 void RegRecord::tinyDump()
10706 {
10707     printf("<Reg:%-3s> ", getRegName(regNum));
10708 }
10709
10710 void TreeNodeInfo::dump(LinearScan* lsra)
10711 {
10712     printf("<TreeNodeInfo @ %2u %d=%d %di %df", loc, dstCount, srcCount, internalIntCount, internalFloatCount);
10713     printf(" src=");
10714     dumpRegMask(getSrcCandidates(lsra));
10715     printf(" int=");
10716     dumpRegMask(getInternalCandidates(lsra));
10717     printf(" dst=");
10718     dumpRegMask(getDstCandidates(lsra));
10719     if (isLocalDefUse)
10720     {
10721         printf(" L");
10722     }
10723     if (isInitialized)
10724     {
10725         printf(" I");
10726     }
10727     if (isLsraAdded)
10728     {
10729         printf(" A");
10730     }
10731     if (isDelayFree)
10732     {
10733         printf(" D");
10734     }
10735     if (isTgtPref)
10736     {
10737         printf(" P");
10738     }
10739     if (regOptional)
10740     {
10741         printf(" O");
10742     }
10743     if (isInternalRegDelayFree)
10744     {
10745         printf(" ID");
10746     }
10747     printf(">\n");
10748 }
10749
10750 void LinearScan::lsraDumpIntervals(const char* msg)
10751 {
10752     Interval* interval;
10753
10754     printf("\nLinear scan intervals %s:\n", msg);
10755     for (auto& interval : intervals)
10756     {
10757         // only dump something if it has references
10758         // if (interval->firstRefPosition)
10759         interval.dump();
10760     }
10761
10762     printf("\n");
10763 }
10764
10765 // Dumps a tree node as a destination or source operand, with the style
10766 // of dump dependent on the mode
10767 void LinearScan::lsraGetOperandString(GenTreePtr        tree,
10768                                       LsraTupleDumpMode mode,
10769                                       char*             operandString,
10770                                       unsigned          operandStringLength)
10771 {
10772     const char* lastUseChar = "";
10773     if ((tree->gtFlags & GTF_VAR_DEATH) != 0)
10774     {
10775         lastUseChar = "*";
10776     }
10777     switch (mode)
10778     {
10779         case LinearScan::LSRA_DUMP_PRE:
10780             _snprintf_s(operandString, operandStringLength, operandStringLength, "t%d%s", tree->gtTreeID, lastUseChar);
10781             break;
10782         case LinearScan::LSRA_DUMP_REFPOS:
10783             _snprintf_s(operandString, operandStringLength, operandStringLength, "t%d%s", tree->gtTreeID, lastUseChar);
10784             break;
10785         case LinearScan::LSRA_DUMP_POST:
10786         {
10787             Compiler* compiler = JitTls::GetCompiler();
10788
10789             if (!tree->gtHasReg())
10790             {
10791                 _snprintf_s(operandString, operandStringLength, operandStringLength, "STK%s", lastUseChar);
10792             }
10793             else
10794             {
10795                 _snprintf_s(operandString, operandStringLength, operandStringLength, "%s%s",
10796                             getRegName(tree->gtRegNum, useFloatReg(tree->TypeGet())), lastUseChar);
10797             }
10798         }
10799         break;
10800         default:
10801             printf("ERROR: INVALID TUPLE DUMP MODE\n");
10802             break;
10803     }
10804 }
10805 void LinearScan::lsraDispNode(GenTreePtr tree, LsraTupleDumpMode mode, bool hasDest)
10806 {
10807     Compiler*      compiler            = JitTls::GetCompiler();
10808     const unsigned operandStringLength = 16;
10809     char           operandString[operandStringLength];
10810     const char*    emptyDestOperand = "               ";
10811     char           spillChar        = ' ';
10812
10813     if (mode == LinearScan::LSRA_DUMP_POST)
10814     {
10815         if ((tree->gtFlags & GTF_SPILL) != 0)
10816         {
10817             spillChar = 'S';
10818         }
10819         if (!hasDest && tree->gtHasReg())
10820         {
10821             // A node can define a register, but not produce a value for a parent to consume,
10822             // i.e. in the "localDefUse" case.
10823             // There used to be an assert here that we wouldn't spill such a node.
10824             // However, we can have unused lclVars that wind up being the node at which
10825             // it is spilled. This probably indicates a bug, but we don't realy want to
10826             // assert during a dump.
10827             if (spillChar == 'S')
10828             {
10829                 spillChar = '$';
10830             }
10831             else
10832             {
10833                 spillChar = '*';
10834             }
10835             hasDest = true;
10836         }
10837     }
10838     printf("%c N%03u. ", spillChar, tree->gtSeqNum);
10839
10840     LclVarDsc* varDsc = nullptr;
10841     unsigned   varNum = UINT_MAX;
10842     if (tree->IsLocal())
10843     {
10844         varNum = tree->gtLclVarCommon.gtLclNum;
10845         varDsc = &(compiler->lvaTable[varNum]);
10846         if (varDsc->lvLRACandidate)
10847         {
10848             hasDest = false;
10849         }
10850     }
10851     if (hasDest)
10852     {
10853         if (mode == LinearScan::LSRA_DUMP_POST && tree->gtFlags & GTF_SPILLED)
10854         {
10855             assert(tree->gtHasReg());
10856         }
10857         lsraGetOperandString(tree, mode, operandString, operandStringLength);
10858         printf("%-15s =", operandString);
10859     }
10860     else
10861     {
10862         printf("%-15s  ", emptyDestOperand);
10863     }
10864     if (varDsc != nullptr)
10865     {
10866         if (varDsc->lvLRACandidate)
10867         {
10868             if (mode == LSRA_DUMP_REFPOS)
10869             {
10870                 printf("  V%02u(L%d)", varNum, getIntervalForLocalVar(varDsc->lvVarIndex)->intervalIndex);
10871             }
10872             else
10873             {
10874                 lsraGetOperandString(tree, mode, operandString, operandStringLength);
10875                 printf("  V%02u(%s)", varNum, operandString);
10876                 if (mode == LinearScan::LSRA_DUMP_POST && tree->gtFlags & GTF_SPILLED)
10877                 {
10878                     printf("R");
10879                 }
10880             }
10881         }
10882         else
10883         {
10884             printf("  V%02u MEM", varNum);
10885         }
10886     }
10887     else if (tree->OperIsAssignment())
10888     {
10889         assert(!tree->gtHasReg());
10890         printf("  asg%s  ", GenTree::OpName(tree->OperGet()));
10891     }
10892     else
10893     {
10894         compiler->gtDispNodeName(tree);
10895         if (tree->OperKind() & GTK_LEAF)
10896         {
10897             compiler->gtDispLeaf(tree, nullptr);
10898         }
10899     }
10900 }
10901
10902 //------------------------------------------------------------------------
10903 // ComputeOperandDstCount: computes the number of registers defined by a
10904 //                         node.
10905 //
10906 // For most nodes, this is simple:
10907 // - Nodes that do not produce values (e.g. stores and other void-typed
10908 //   nodes) and nodes that immediately use the registers they define
10909 //   produce no registers
10910 // - Nodes that are marked as defining N registers define N registers.
10911 //
10912 // For contained nodes, however, things are more complicated: for purposes
10913 // of bookkeeping, a contained node is treated as producing the transitive
10914 // closure of the registers produced by its sources.
10915 //
10916 // Arguments:
10917 //    operand - The operand for which to compute a register count.
10918 //
10919 // Returns:
10920 //    The number of registers defined by `operand`.
10921 //
10922 void LinearScan::DumpOperandDefs(
10923     GenTree* operand, bool& first, LsraTupleDumpMode mode, char* operandString, const unsigned operandStringLength)
10924 {
10925     assert(operand != nullptr);
10926     assert(operandString != nullptr);
10927
10928     if (ComputeOperandDstCount(operand) == 0)
10929     {
10930         return;
10931     }
10932
10933     if (operand->gtLsraInfo.dstCount != 0)
10934     {
10935         // This operand directly produces registers; print it.
10936         for (int i = 0; i < operand->gtLsraInfo.dstCount; i++)
10937         {
10938             if (!first)
10939             {
10940                 printf(",");
10941             }
10942
10943             lsraGetOperandString(operand, mode, operandString, operandStringLength);
10944             printf("%s", operandString);
10945
10946             first = false;
10947         }
10948     }
10949     else
10950     {
10951         // This is a contained node. Dump the defs produced by its operands.
10952         for (GenTree* op : operand->Operands())
10953         {
10954             DumpOperandDefs(op, first, mode, operandString, operandStringLength);
10955         }
10956     }
10957 }
10958
10959 void LinearScan::TupleStyleDump(LsraTupleDumpMode mode)
10960 {
10961     BasicBlock*    block;
10962     LsraLocation   currentLoc          = 1; // 0 is the entry
10963     const unsigned operandStringLength = 16;
10964     char           operandString[operandStringLength];
10965
10966     // currentRefPosition is not used for LSRA_DUMP_PRE
10967     // We keep separate iterators for defs, so that we can print them
10968     // on the lhs of the dump
10969     auto currentRefPosition = refPositions.begin();
10970
10971     switch (mode)
10972     {
10973         case LSRA_DUMP_PRE:
10974             printf("TUPLE STYLE DUMP BEFORE LSRA\n");
10975             break;
10976         case LSRA_DUMP_REFPOS:
10977             printf("TUPLE STYLE DUMP WITH REF POSITIONS\n");
10978             break;
10979         case LSRA_DUMP_POST:
10980             printf("TUPLE STYLE DUMP WITH REGISTER ASSIGNMENTS\n");
10981             break;
10982         default:
10983             printf("ERROR: INVALID TUPLE DUMP MODE\n");
10984             return;
10985     }
10986
10987     if (mode != LSRA_DUMP_PRE)
10988     {
10989         printf("Incoming Parameters: ");
10990         for (; currentRefPosition != refPositions.end() && currentRefPosition->refType != RefTypeBB;
10991              ++currentRefPosition)
10992         {
10993             Interval* interval = currentRefPosition->getInterval();
10994             assert(interval != nullptr && interval->isLocalVar);
10995             printf(" V%02d", interval->varNum);
10996             if (mode == LSRA_DUMP_POST)
10997             {
10998                 regNumber reg;
10999                 if (currentRefPosition->registerAssignment == RBM_NONE)
11000                 {
11001                     reg = REG_STK;
11002                 }
11003                 else
11004                 {
11005                     reg = currentRefPosition->assignedReg();
11006                 }
11007                 LclVarDsc* varDsc = &(compiler->lvaTable[interval->varNum]);
11008                 printf("(");
11009                 regNumber assignedReg = varDsc->lvRegNum;
11010                 regNumber argReg      = (varDsc->lvIsRegArg) ? varDsc->lvArgReg : REG_STK;
11011
11012                 assert(reg == assignedReg || varDsc->lvRegister == false);
11013                 if (reg != argReg)
11014                 {
11015                     printf(getRegName(argReg, isFloatRegType(interval->registerType)));
11016                     printf("=>");
11017                 }
11018                 printf("%s)", getRegName(reg, isFloatRegType(interval->registerType)));
11019             }
11020         }
11021         printf("\n");
11022     }
11023
11024     for (block = startBlockSequence(); block != nullptr; block = moveToNextBlock())
11025     {
11026         currentLoc += 2;
11027
11028         if (mode == LSRA_DUMP_REFPOS)
11029         {
11030             bool printedBlockHeader = false;
11031             // We should find the boundary RefPositions in the order of exposed uses, dummy defs, and the blocks
11032             for (; currentRefPosition != refPositions.end() &&
11033                    (currentRefPosition->refType == RefTypeExpUse || currentRefPosition->refType == RefTypeDummyDef ||
11034                     (currentRefPosition->refType == RefTypeBB && !printedBlockHeader));
11035                  ++currentRefPosition)
11036             {
11037                 Interval* interval = nullptr;
11038                 if (currentRefPosition->isIntervalRef())
11039                 {
11040                     interval = currentRefPosition->getInterval();
11041                 }
11042                 switch (currentRefPosition->refType)
11043                 {
11044                     case RefTypeExpUse:
11045                         assert(interval != nullptr);
11046                         assert(interval->isLocalVar);
11047                         printf("  Exposed use of V%02u at #%d\n", interval->varNum, currentRefPosition->rpNum);
11048                         break;
11049                     case RefTypeDummyDef:
11050                         assert(interval != nullptr);
11051                         assert(interval->isLocalVar);
11052                         printf("  Dummy def of V%02u at #%d\n", interval->varNum, currentRefPosition->rpNum);
11053                         break;
11054                     case RefTypeBB:
11055                         block->dspBlockHeader(compiler);
11056                         printedBlockHeader = true;
11057                         printf("=====\n");
11058                         break;
11059                     default:
11060                         printf("Unexpected RefPosition type at #%d\n", currentRefPosition->rpNum);
11061                         break;
11062                 }
11063             }
11064         }
11065         else
11066         {
11067             block->dspBlockHeader(compiler);
11068             printf("=====\n");
11069         }
11070         if (enregisterLocalVars && mode == LSRA_DUMP_POST && block != compiler->fgFirstBB &&
11071             block->bbNum <= bbNumMaxBeforeResolution)
11072         {
11073             printf("Predecessor for variable locations: BB%02u\n", blockInfo[block->bbNum].predBBNum);
11074             dumpInVarToRegMap(block);
11075         }
11076         if (block->bbNum > bbNumMaxBeforeResolution)
11077         {
11078             SplitEdgeInfo splitEdgeInfo;
11079             splitBBNumToTargetBBNumMap->Lookup(block->bbNum, &splitEdgeInfo);
11080             assert(splitEdgeInfo.toBBNum <= bbNumMaxBeforeResolution);
11081             assert(splitEdgeInfo.fromBBNum <= bbNumMaxBeforeResolution);
11082             printf("New block introduced for resolution from BB%02u to BB%02u\n", splitEdgeInfo.fromBBNum,
11083                    splitEdgeInfo.toBBNum);
11084         }
11085
11086         for (GenTree* node : LIR::AsRange(block).NonPhiNodes())
11087         {
11088             GenTree* tree = node;
11089
11090             genTreeOps    oper = tree->OperGet();
11091             TreeNodeInfo& info = tree->gtLsraInfo;
11092             if (tree->gtLsraInfo.isLsraAdded)
11093             {
11094                 // This must be one of the nodes that we add during LSRA
11095
11096                 if (oper == GT_LCL_VAR)
11097                 {
11098                     info.srcCount = 0;
11099                     info.dstCount = 1;
11100                 }
11101                 else if (oper == GT_RELOAD || oper == GT_COPY)
11102                 {
11103                     info.srcCount = 1;
11104                     info.dstCount = 1;
11105                 }
11106 #ifdef FEATURE_SIMD
11107                 else if (oper == GT_SIMD)
11108                 {
11109                     if (tree->gtSIMD.gtSIMDIntrinsicID == SIMDIntrinsicUpperSave)
11110                     {
11111                         info.srcCount = 1;
11112                         info.dstCount = 1;
11113                     }
11114                     else
11115                     {
11116                         assert(tree->gtSIMD.gtSIMDIntrinsicID == SIMDIntrinsicUpperRestore);
11117                         info.srcCount = 2;
11118                         info.dstCount = 0;
11119                     }
11120                 }
11121 #endif // FEATURE_SIMD
11122                 else
11123                 {
11124                     assert(oper == GT_SWAP);
11125                     info.srcCount = 2;
11126                     info.dstCount = 0;
11127                 }
11128                 info.internalIntCount   = 0;
11129                 info.internalFloatCount = 0;
11130             }
11131
11132             int       consume   = info.srcCount;
11133             int       produce   = info.dstCount;
11134             regMaskTP killMask  = RBM_NONE;
11135             regMaskTP fixedMask = RBM_NONE;
11136
11137             lsraDispNode(tree, mode, produce != 0 && mode != LSRA_DUMP_REFPOS);
11138
11139             if (mode != LSRA_DUMP_REFPOS)
11140             {
11141                 if (consume > 0)
11142                 {
11143                     printf("; ");
11144
11145                     bool first = true;
11146                     for (GenTree* operand : tree->Operands())
11147                     {
11148                         DumpOperandDefs(operand, first, mode, operandString, operandStringLength);
11149                     }
11150                 }
11151             }
11152             else
11153             {
11154                 // Print each RefPosition on a new line, but
11155                 // printing all the kills for each node on a single line
11156                 // and combining the fixed regs with their associated def or use
11157                 bool         killPrinted        = false;
11158                 RefPosition* lastFixedRegRefPos = nullptr;
11159                 for (; currentRefPosition != refPositions.end() &&
11160                        (currentRefPosition->refType == RefTypeUse || currentRefPosition->refType == RefTypeFixedReg ||
11161                         currentRefPosition->refType == RefTypeKill || currentRefPosition->refType == RefTypeDef) &&
11162                        (currentRefPosition->nodeLocation == tree->gtSeqNum ||
11163                         currentRefPosition->nodeLocation == tree->gtSeqNum + 1);
11164                      ++currentRefPosition)
11165                 {
11166                     Interval* interval = nullptr;
11167                     if (currentRefPosition->isIntervalRef())
11168                     {
11169                         interval = currentRefPosition->getInterval();
11170                     }
11171                     switch (currentRefPosition->refType)
11172                     {
11173                         case RefTypeUse:
11174                             if (currentRefPosition->isPhysRegRef)
11175                             {
11176                                 printf("\n                               Use:R%d(#%d)",
11177                                        currentRefPosition->getReg()->regNum, currentRefPosition->rpNum);
11178                             }
11179                             else
11180                             {
11181                                 assert(interval != nullptr);
11182                                 printf("\n                               Use:");
11183                                 interval->microDump();
11184                                 printf("(#%d)", currentRefPosition->rpNum);
11185                                 if (currentRefPosition->isFixedRegRef)
11186                                 {
11187                                     assert(genMaxOneBit(currentRefPosition->registerAssignment));
11188                                     assert(lastFixedRegRefPos != nullptr);
11189                                     printf(" Fixed:%s(#%d)", getRegName(currentRefPosition->assignedReg(),
11190                                                                         isFloatRegType(interval->registerType)),
11191                                            lastFixedRegRefPos->rpNum);
11192                                     lastFixedRegRefPos = nullptr;
11193                                 }
11194                                 if (currentRefPosition->isLocalDefUse)
11195                                 {
11196                                     printf(" LocalDefUse");
11197                                 }
11198                                 if (currentRefPosition->lastUse)
11199                                 {
11200                                     printf(" *");
11201                                 }
11202                             }
11203                             break;
11204                         case RefTypeDef:
11205                         {
11206                             // Print each def on a new line
11207                             assert(interval != nullptr);
11208                             printf("\n        Def:");
11209                             interval->microDump();
11210                             printf("(#%d)", currentRefPosition->rpNum);
11211                             if (currentRefPosition->isFixedRegRef)
11212                             {
11213                                 assert(genMaxOneBit(currentRefPosition->registerAssignment));
11214                                 printf(" %s", getRegName(currentRefPosition->assignedReg(),
11215                                                          isFloatRegType(interval->registerType)));
11216                             }
11217                             if (currentRefPosition->isLocalDefUse)
11218                             {
11219                                 printf(" LocalDefUse");
11220                             }
11221                             if (currentRefPosition->lastUse)
11222                             {
11223                                 printf(" *");
11224                             }
11225                             if (interval->relatedInterval != nullptr)
11226                             {
11227                                 printf(" Pref:");
11228                                 interval->relatedInterval->microDump();
11229                             }
11230                         }
11231                         break;
11232                         case RefTypeKill:
11233                             if (!killPrinted)
11234                             {
11235                                 printf("\n        Kill: ");
11236                                 killPrinted = true;
11237                             }
11238                             printf(getRegName(currentRefPosition->assignedReg(),
11239                                               isFloatRegType(currentRefPosition->getReg()->registerType)));
11240                             printf(" ");
11241                             break;
11242                         case RefTypeFixedReg:
11243                             lastFixedRegRefPos = currentRefPosition;
11244                             break;
11245                         default:
11246                             printf("Unexpected RefPosition type at #%d\n", currentRefPosition->rpNum);
11247                             break;
11248                     }
11249                 }
11250             }
11251             printf("\n");
11252             if (info.internalIntCount != 0 && mode != LSRA_DUMP_REFPOS)
11253             {
11254                 printf("\tinternal (%d):\t", info.internalIntCount);
11255                 if (mode == LSRA_DUMP_POST)
11256                 {
11257                     dumpRegMask(tree->gtRsvdRegs);
11258                 }
11259                 else if ((info.getInternalCandidates(this) & allRegs(TYP_INT)) != allRegs(TYP_INT))
11260                 {
11261                     dumpRegMask(info.getInternalCandidates(this) & allRegs(TYP_INT));
11262                 }
11263                 printf("\n");
11264             }
11265             if (info.internalFloatCount != 0 && mode != LSRA_DUMP_REFPOS)
11266             {
11267                 printf("\tinternal (%d):\t", info.internalFloatCount);
11268                 if (mode == LSRA_DUMP_POST)
11269                 {
11270                     dumpRegMask(tree->gtRsvdRegs);
11271                 }
11272                 else if ((info.getInternalCandidates(this) & allRegs(TYP_INT)) != allRegs(TYP_INT))
11273                 {
11274                     dumpRegMask(info.getInternalCandidates(this) & allRegs(TYP_INT));
11275                 }
11276                 printf("\n");
11277             }
11278         }
11279         if (enregisterLocalVars && mode == LSRA_DUMP_POST)
11280         {
11281             dumpOutVarToRegMap(block);
11282         }
11283         printf("\n");
11284     }
11285     printf("\n\n");
11286 }
11287
11288 void LinearScan::dumpLsraAllocationEvent(LsraDumpEvent event,
11289                                          Interval*     interval,
11290                                          regNumber     reg,
11291                                          BasicBlock*   currentBlock)
11292 {
11293     if (!(VERBOSE))
11294     {
11295         return;
11296     }
11297     switch (event)
11298     {
11299         // Conflicting def/use
11300         case LSRA_EVENT_DEFUSE_CONFLICT:
11301             if (!dumpTerse)
11302             {
11303                 printf("  Def and Use have conflicting register requirements:");
11304             }
11305             else
11306             {
11307                 printf("DUconflict ");
11308                 dumpRegRecords();
11309             }
11310             break;
11311         case LSRA_EVENT_DEFUSE_FIXED_DELAY_USE:
11312             if (!dumpTerse)
11313             {
11314                 printf(" Can't change useAssignment ");
11315             }
11316             break;
11317         case LSRA_EVENT_DEFUSE_CASE1:
11318             if (!dumpTerse)
11319             {
11320                 printf(" case #1, use the defRegAssignment\n");
11321             }
11322             else
11323             {
11324                 printf(indentFormat, " case #1 use defRegAssignment");
11325                 dumpRegRecords();
11326                 dumpEmptyRefPosition();
11327             }
11328             break;
11329         case LSRA_EVENT_DEFUSE_CASE2:
11330             if (!dumpTerse)
11331             {
11332                 printf(" case #2, use the useRegAssignment\n");
11333             }
11334             else
11335             {
11336                 printf(indentFormat, " case #2 use useRegAssignment");
11337                 dumpRegRecords();
11338                 dumpEmptyRefPosition();
11339             }
11340             break;
11341         case LSRA_EVENT_DEFUSE_CASE3:
11342             if (!dumpTerse)
11343             {
11344                 printf(" case #3, change the defRegAssignment to the use regs\n");
11345             }
11346             else
11347             {
11348                 printf(indentFormat, " case #3 use useRegAssignment");
11349                 dumpRegRecords();
11350                 dumpEmptyRefPosition();
11351             }
11352             break;
11353         case LSRA_EVENT_DEFUSE_CASE4:
11354             if (!dumpTerse)
11355             {
11356                 printf(" case #4, change the useRegAssignment to the def regs\n");
11357             }
11358             else
11359             {
11360                 printf(indentFormat, " case #4 use defRegAssignment");
11361                 dumpRegRecords();
11362                 dumpEmptyRefPosition();
11363             }
11364             break;
11365         case LSRA_EVENT_DEFUSE_CASE5:
11366             if (!dumpTerse)
11367             {
11368                 printf(" case #5, Conflicting Def and Use single-register requirements require copies - set def to all "
11369                        "regs of the appropriate type\n");
11370             }
11371             else
11372             {
11373                 printf(indentFormat, " case #5 set def to all regs");
11374                 dumpRegRecords();
11375                 dumpEmptyRefPosition();
11376             }
11377             break;
11378         case LSRA_EVENT_DEFUSE_CASE6:
11379             if (!dumpTerse)
11380             {
11381                 printf(" case #6, Conflicting Def and Use register requirements require a copy\n");
11382             }
11383             else
11384             {
11385                 printf(indentFormat, " case #6 need a copy");
11386                 dumpRegRecords();
11387                 dumpEmptyRefPosition();
11388             }
11389             break;
11390
11391         case LSRA_EVENT_SPILL:
11392             if (!dumpTerse)
11393             {
11394                 printf("Spilled:\n");
11395                 interval->dump();
11396             }
11397             else
11398             {
11399                 assert(interval != nullptr && interval->assignedReg != nullptr);
11400                 printf("Spill %-4s ", getRegName(interval->assignedReg->regNum));
11401                 dumpRegRecords();
11402                 dumpEmptyRefPosition();
11403             }
11404             break;
11405         case LSRA_EVENT_SPILL_EXTENDED_LIFETIME:
11406             if (!dumpTerse)
11407             {
11408                 printf("  Spilled extended lifetime var V%02u at last use; not marked for actual spill.",
11409                        interval->intervalIndex);
11410             }
11411             break;
11412
11413         // Restoring the previous register
11414         case LSRA_EVENT_RESTORE_PREVIOUS_INTERVAL_AFTER_SPILL:
11415             assert(interval != nullptr);
11416             if (!dumpTerse)
11417             {
11418                 printf("  Assign register %s to previous interval Ivl:%d after spill\n", getRegName(reg),
11419                        interval->intervalIndex);
11420             }
11421             else
11422             {
11423                 // If we spilled, then the dump is already pre-indented, but we need to pre-indent for the subsequent
11424                 // allocation
11425                 // with a dumpEmptyRefPosition().
11426                 printf("SRstr %-4s ", getRegName(reg));
11427                 dumpRegRecords();
11428                 dumpEmptyRefPosition();
11429             }
11430             break;
11431         case LSRA_EVENT_RESTORE_PREVIOUS_INTERVAL:
11432             assert(interval != nullptr);
11433             if (!dumpTerse)
11434             {
11435                 printf("  Assign register %s to previous interval Ivl:%d\n", getRegName(reg), interval->intervalIndex);
11436             }
11437             else
11438             {
11439                 if (activeRefPosition == nullptr)
11440                 {
11441                     printf(emptyRefPositionFormat, "");
11442                 }
11443                 printf("Restr %-4s ", getRegName(reg));
11444                 dumpRegRecords();
11445                 if (activeRefPosition != nullptr)
11446                 {
11447                     printf(emptyRefPositionFormat, "");
11448                 }
11449             }
11450             break;
11451
11452         // Done with GC Kills
11453         case LSRA_EVENT_DONE_KILL_GC_REFS:
11454             printf("DoneKillGC ");
11455             break;
11456
11457         // Block boundaries
11458         case LSRA_EVENT_START_BB:
11459             assert(currentBlock != nullptr);
11460             if (!dumpTerse)
11461             {
11462                 printf("\n\n  Live Vars(Regs) at start of BB%02u (from pred BB%02u):", currentBlock->bbNum,
11463                        blockInfo[currentBlock->bbNum].predBBNum);
11464                 dumpVarToRegMap(inVarToRegMaps[currentBlock->bbNum]);
11465             }
11466             break;
11467         case LSRA_EVENT_END_BB:
11468             if (!dumpTerse)
11469             {
11470                 printf("\n\n  Live Vars(Regs) after BB%02u:", currentBlock->bbNum);
11471                 dumpVarToRegMap(outVarToRegMaps[currentBlock->bbNum]);
11472             }
11473             break;
11474
11475         case LSRA_EVENT_FREE_REGS:
11476             if (!dumpTerse)
11477             {
11478                 printf("Freeing registers:\n");
11479             }
11480             break;
11481
11482         // Characteristics of the current RefPosition
11483         case LSRA_EVENT_INCREMENT_RANGE_END:
11484             if (!dumpTerse)
11485             {
11486                 printf("  Incrementing nextPhysRegLocation for %s\n", getRegName(reg));
11487             }
11488             // else ???
11489             break;
11490         case LSRA_EVENT_LAST_USE:
11491             if (!dumpTerse)
11492             {
11493                 printf("    Last use, marked to be freed\n");
11494             }
11495             break;
11496         case LSRA_EVENT_LAST_USE_DELAYED:
11497             if (!dumpTerse)
11498             {
11499                 printf("    Last use, marked to be freed (delayed)\n");
11500             }
11501             break;
11502         case LSRA_EVENT_NEEDS_NEW_REG:
11503             if (!dumpTerse)
11504             {
11505                 printf("    Needs new register; mark %s to be freed\n", getRegName(reg));
11506             }
11507             else
11508             {
11509                 printf("Free  %-4s ", getRegName(reg));
11510                 dumpRegRecords();
11511                 dumpEmptyRefPosition();
11512             }
11513             break;
11514
11515         // Allocation decisions
11516         case LSRA_EVENT_FIXED_REG:
11517         case LSRA_EVENT_EXP_USE:
11518             if (!dumpTerse)
11519             {
11520                 printf("No allocation\n");
11521             }
11522             else
11523             {
11524                 printf("Keep  %-4s ", getRegName(reg));
11525             }
11526             break;
11527         case LSRA_EVENT_ZERO_REF:
11528             assert(interval != nullptr && interval->isLocalVar);
11529             if (!dumpTerse)
11530             {
11531                 printf("Marking V%02u as last use there are no actual references\n", interval->varNum);
11532             }
11533             else
11534             {
11535                 printf("NoRef      ");
11536                 dumpRegRecords();
11537                 dumpEmptyRefPosition();
11538             }
11539             break;
11540         case LSRA_EVENT_KEPT_ALLOCATION:
11541             if (!dumpTerse)
11542             {
11543                 printf("already allocated %4s\n", getRegName(reg));
11544             }
11545             else
11546             {
11547                 printf("Keep  %-4s ", getRegName(reg));
11548             }
11549             break;
11550         case LSRA_EVENT_COPY_REG:
11551             assert(interval != nullptr && interval->recentRefPosition != nullptr);
11552             if (!dumpTerse)
11553             {
11554                 printf("allocated %s as copyReg\n\n", getRegName(reg));
11555             }
11556             else
11557             {
11558                 printf("Copy  %-4s ", getRegName(reg));
11559             }
11560             break;
11561         case LSRA_EVENT_MOVE_REG:
11562             assert(interval != nullptr && interval->recentRefPosition != nullptr);
11563             if (!dumpTerse)
11564             {
11565                 printf("  needs a new register; marked as moveReg\n");
11566             }
11567             else
11568             {
11569                 printf("Move  %-4s ", getRegName(reg));
11570                 dumpRegRecords();
11571                 dumpEmptyRefPosition();
11572             }
11573             break;
11574         case LSRA_EVENT_ALLOC_REG:
11575             if (!dumpTerse)
11576             {
11577                 printf("allocated %s\n", getRegName(reg));
11578             }
11579             else
11580             {
11581                 printf("Alloc %-4s ", getRegName(reg));
11582             }
11583             break;
11584         case LSRA_EVENT_REUSE_REG:
11585             if (!dumpTerse)
11586             {
11587                 printf("reused constant in %s\n", getRegName(reg));
11588             }
11589             else
11590             {
11591                 printf("Reuse %-4s ", getRegName(reg));
11592             }
11593             break;
11594         case LSRA_EVENT_ALLOC_SPILLED_REG:
11595             if (!dumpTerse)
11596             {
11597                 printf("allocated spilled register %s\n", getRegName(reg));
11598             }
11599             else
11600             {
11601                 printf("Steal %-4s ", getRegName(reg));
11602             }
11603             break;
11604         case LSRA_EVENT_NO_ENTRY_REG_ALLOCATED:
11605             assert(interval != nullptr && interval->isLocalVar);
11606             if (!dumpTerse)
11607             {
11608                 printf("Not allocating an entry register for V%02u due to low ref count\n", interval->varNum);
11609             }
11610             else
11611             {
11612                 printf("LoRef      ");
11613             }
11614             break;
11615         case LSRA_EVENT_NO_REG_ALLOCATED:
11616             if (!dumpTerse)
11617             {
11618                 printf("no register allocated\n");
11619             }
11620             else
11621             {
11622                 printf("NoReg      ");
11623             }
11624             break;
11625         case LSRA_EVENT_RELOAD:
11626             if (!dumpTerse)
11627             {
11628                 printf("    Marked for reload\n");
11629             }
11630             else
11631             {
11632                 printf("ReLod %-4s ", getRegName(reg));
11633                 dumpRegRecords();
11634                 dumpEmptyRefPosition();
11635             }
11636             break;
11637         case LSRA_EVENT_SPECIAL_PUTARG:
11638             if (!dumpTerse)
11639             {
11640                 printf("    Special case of putArg - using lclVar that's in the expected reg\n");
11641             }
11642             else
11643             {
11644                 printf("PtArg %-4s ", getRegName(reg));
11645             }
11646             break;
11647         default:
11648             break;
11649     }
11650 }
11651
11652 //------------------------------------------------------------------------
11653 // dumpRegRecordHeader: Dump the header for a column-based dump of the register state.
11654 //
11655 // Arguments:
11656 //    None.
11657 //
11658 // Return Value:
11659 //    None.
11660 //
11661 // Assumptions:
11662 //    Reg names fit in 4 characters (minimum width of the columns)
11663 //
11664 // Notes:
11665 //    In order to make the table as dense as possible (for ease of reading the dumps),
11666 //    we determine the minimum regColumnWidth width required to represent:
11667 //      regs, by name (e.g. eax or xmm0) - this is fixed at 4 characters.
11668 //      intervals, as Vnn for lclVar intervals, or as I<num> for other intervals.
11669 //    The table is indented by the amount needed for dumpRefPositionShort, which is
11670 //    captured in shortRefPositionDumpWidth.
11671 //
11672 void LinearScan::dumpRegRecordHeader()
11673 {
11674     printf("The following table has one or more rows for each RefPosition that is handled during allocation.\n"
11675            "The first column provides the basic information about the RefPosition, with its type (e.g. Def,\n"
11676            "Use, Fixd) followed by a '*' if it is a last use, and a 'D' if it is delayRegFree, and then the\n"
11677            "action taken during allocation (e.g. Alloc a new register, or Keep an existing one).\n"
11678            "The subsequent columns show the Interval occupying each register, if any, followed by 'a' if it is\n"
11679            "active, and 'i'if it is inactive.  Columns are only printed up to the last modifed register, which\n"
11680            "may increase during allocation, in which case additional columns will appear.  Registers which are\n"
11681            "not marked modified have ---- in their column.\n\n");
11682
11683     // First, determine the width of each register column (which holds a reg name in the
11684     // header, and an interval name in each subsequent row).
11685     int intervalNumberWidth = (int)log10((double)intervals.size()) + 1;
11686     // The regColumnWidth includes the identifying character (I or V) and an 'i' or 'a' (inactive or active)
11687     regColumnWidth = intervalNumberWidth + 2;
11688     if (regColumnWidth < 4)
11689     {
11690         regColumnWidth = 4;
11691     }
11692     sprintf_s(intervalNameFormat, MAX_FORMAT_CHARS, "%%c%%-%dd", regColumnWidth - 2);
11693     sprintf_s(regNameFormat, MAX_FORMAT_CHARS, "%%-%ds", regColumnWidth);
11694
11695     // Next, determine the width of the short RefPosition (see dumpRefPositionShort()).
11696     // This is in the form:
11697     // nnn.#mmm NAME TYPEld
11698     // Where:
11699     //    nnn is the Location, right-justified to the width needed for the highest location.
11700     //    mmm is the RefPosition rpNum, left-justified to the width needed for the highest rpNum.
11701     //    NAME is dumped by dumpReferentName(), and is "regColumnWidth".
11702     //    TYPE is RefTypeNameShort, and is 4 characters
11703     //    l is either '*' (if a last use) or ' ' (otherwise)
11704     //    d is either 'D' (if a delayed use) or ' ' (otherwise)
11705
11706     maxNodeLocation = (maxNodeLocation == 0)
11707                           ? 1
11708                           : maxNodeLocation; // corner case of a method with an infinite loop without any gentree nodes
11709     assert(maxNodeLocation >= 1);
11710     assert(refPositions.size() >= 1);
11711     int nodeLocationWidth         = (int)log10((double)maxNodeLocation) + 1;
11712     int refPositionWidth          = (int)log10((double)refPositions.size()) + 1;
11713     int refTypeInfoWidth          = 4 /*TYPE*/ + 2 /* last-use and delayed */ + 1 /* space */;
11714     int locationAndRPNumWidth     = nodeLocationWidth + 2 /* .# */ + refPositionWidth + 1 /* space */;
11715     int shortRefPositionDumpWidth = locationAndRPNumWidth + regColumnWidth + 1 /* space */ + refTypeInfoWidth;
11716     sprintf_s(shortRefPositionFormat, MAX_FORMAT_CHARS, "%%%dd.#%%-%dd ", nodeLocationWidth, refPositionWidth);
11717     sprintf_s(emptyRefPositionFormat, MAX_FORMAT_CHARS, "%%-%ds", shortRefPositionDumpWidth);
11718
11719     // The width of the "allocation info"
11720     //  - a 5-character allocation decision
11721     //  - a space
11722     //  - a 4-character register
11723     //  - a space
11724     int allocationInfoWidth = 5 + 1 + 4 + 1;
11725
11726     // Next, determine the width of the legend for each row.  This includes:
11727     //  - a short RefPosition dump (shortRefPositionDumpWidth), which includes a space
11728     //  - the allocation info (allocationInfoWidth), which also includes a space
11729
11730     regTableIndent = shortRefPositionDumpWidth + allocationInfoWidth;
11731
11732     // BBnn printed left-justified in the NAME Typeld and allocationInfo space.
11733     int bbDumpWidth = regColumnWidth + 1 + refTypeInfoWidth + allocationInfoWidth;
11734     int bbNumWidth  = (int)log10((double)compiler->fgBBNumMax) + 1;
11735     // In the unlikely event that BB numbers overflow the space, we'll simply omit the predBB
11736     int predBBNumDumpSpace = regTableIndent - locationAndRPNumWidth - bbNumWidth - 9; // 'BB' + ' PredBB'
11737     if (predBBNumDumpSpace < bbNumWidth)
11738     {
11739         sprintf_s(bbRefPosFormat, MAX_LEGEND_FORMAT_CHARS, "BB%%-%dd", shortRefPositionDumpWidth - 2);
11740     }
11741     else
11742     {
11743         sprintf_s(bbRefPosFormat, MAX_LEGEND_FORMAT_CHARS, "BB%%-%dd PredBB%%-%dd", bbNumWidth, predBBNumDumpSpace);
11744     }
11745
11746     if (compiler->shouldDumpASCIITrees())
11747     {
11748         columnSeparator = "|";
11749         line            = "-";
11750         leftBox         = "+";
11751         middleBox       = "+";
11752         rightBox        = "+";
11753     }
11754     else
11755     {
11756         columnSeparator = "\xe2\x94\x82";
11757         line            = "\xe2\x94\x80";
11758         leftBox         = "\xe2\x94\x9c";
11759         middleBox       = "\xe2\x94\xbc";
11760         rightBox        = "\xe2\x94\xa4";
11761     }
11762     sprintf_s(indentFormat, MAX_FORMAT_CHARS, "%%-%ds", regTableIndent);
11763
11764     // Now, set up the legend format for the RefPosition info
11765     sprintf_s(legendFormat, MAX_LEGEND_FORMAT_CHARS, "%%-%d.%ds%%-%d.%ds%%-%ds%%s", nodeLocationWidth + 1,
11766               nodeLocationWidth + 1, refPositionWidth + 2, refPositionWidth + 2, regColumnWidth + 1);
11767
11768     // Finally, print a "title row" including the legend and the reg names
11769     dumpRegRecordTitle();
11770 }
11771
11772 int LinearScan::getLastUsedRegNumIndex()
11773 {
11774     int       lastUsedRegNumIndex = 0;
11775     regMaskTP usedRegsMask        = compiler->codeGen->regSet.rsGetModifiedRegsMask();
11776     int       lastRegNumIndex     = compiler->compFloatingPointUsed ? REG_FP_LAST : REG_INT_LAST;
11777     for (int regNumIndex = 0; regNumIndex <= lastRegNumIndex; regNumIndex++)
11778     {
11779         if ((usedRegsMask & genRegMask((regNumber)regNumIndex)) != 0)
11780         {
11781             lastUsedRegNumIndex = regNumIndex;
11782         }
11783     }
11784     return lastUsedRegNumIndex;
11785 }
11786
11787 void LinearScan::dumpRegRecordTitleLines()
11788 {
11789     for (int i = 0; i < regTableIndent; i++)
11790     {
11791         printf("%s", line);
11792     }
11793     int lastUsedRegNumIndex = getLastUsedRegNumIndex();
11794     for (int regNumIndex = 0; regNumIndex <= lastUsedRegNumIndex; regNumIndex++)
11795     {
11796         printf("%s", middleBox);
11797         for (int i = 0; i < regColumnWidth; i++)
11798         {
11799             printf("%s", line);
11800         }
11801     }
11802     printf("%s\n", rightBox);
11803 }
11804 void LinearScan::dumpRegRecordTitle()
11805 {
11806     dumpRegRecordTitleLines();
11807
11808     // Print out the legend for the RefPosition info
11809     printf(legendFormat, "Loc ", "RP# ", "Name ", "Type  Action Reg  ");
11810
11811     // Print out the register name column headers
11812     char columnFormatArray[MAX_FORMAT_CHARS];
11813     sprintf_s(columnFormatArray, MAX_FORMAT_CHARS, "%s%%-%d.%ds", columnSeparator, regColumnWidth, regColumnWidth);
11814     int lastUsedRegNumIndex = getLastUsedRegNumIndex();
11815     for (int regNumIndex = 0; regNumIndex <= lastUsedRegNumIndex; regNumIndex++)
11816     {
11817         regNumber   regNum  = (regNumber)regNumIndex;
11818         const char* regName = getRegName(regNum);
11819         printf(columnFormatArray, regName);
11820     }
11821     printf("%s\n", columnSeparator);
11822
11823     rowCountSinceLastTitle = 0;
11824
11825     dumpRegRecordTitleLines();
11826 }
11827
11828 void LinearScan::dumpRegRecords()
11829 {
11830     static char columnFormatArray[18];
11831     int         lastUsedRegNumIndex = getLastUsedRegNumIndex();
11832     regMaskTP   usedRegsMask        = compiler->codeGen->regSet.rsGetModifiedRegsMask();
11833
11834     for (int regNumIndex = 0; regNumIndex <= lastUsedRegNumIndex; regNumIndex++)
11835     {
11836         printf("%s", columnSeparator);
11837         RegRecord& regRecord = physRegs[regNumIndex];
11838         Interval*  interval  = regRecord.assignedInterval;
11839         if (interval != nullptr)
11840         {
11841             dumpIntervalName(interval);
11842             char activeChar = interval->isActive ? 'a' : 'i';
11843             printf("%c", activeChar);
11844         }
11845         else if (regRecord.isBusyUntilNextKill)
11846         {
11847             printf(columnFormatArray, "Busy");
11848         }
11849         else if ((usedRegsMask & genRegMask((regNumber)regNumIndex)) == 0)
11850         {
11851             sprintf_s(columnFormatArray, MAX_FORMAT_CHARS, "%%-%ds", regColumnWidth);
11852             printf(columnFormatArray, "----");
11853         }
11854         else
11855         {
11856             sprintf_s(columnFormatArray, MAX_FORMAT_CHARS, "%%-%ds", regColumnWidth);
11857             printf(columnFormatArray, "");
11858         }
11859     }
11860     printf("%s\n", columnSeparator);
11861
11862     if (rowCountSinceLastTitle > MAX_ROWS_BETWEEN_TITLES)
11863     {
11864         dumpRegRecordTitle();
11865     }
11866     rowCountSinceLastTitle++;
11867 }
11868
11869 void LinearScan::dumpIntervalName(Interval* interval)
11870 {
11871     if (interval->isLocalVar)
11872     {
11873         printf(intervalNameFormat, 'V', interval->varNum);
11874     }
11875     else if (interval->isConstant)
11876     {
11877         printf(intervalNameFormat, 'C', interval->intervalIndex);
11878     }
11879     else
11880     {
11881         printf(intervalNameFormat, 'I', interval->intervalIndex);
11882     }
11883 }
11884
11885 void LinearScan::dumpEmptyRefPosition()
11886 {
11887     printf(emptyRefPositionFormat, "");
11888 }
11889
11890 // Note that the size of this dump is computed in dumpRegRecordHeader().
11891 //
11892 void LinearScan::dumpRefPositionShort(RefPosition* refPosition, BasicBlock* currentBlock)
11893 {
11894     BasicBlock* block = currentBlock;
11895     if (refPosition->refType == RefTypeBB)
11896     {
11897         // Always print a title row before a RefTypeBB (except for the first, because we
11898         // will already have printed it before the parameters)
11899         if (refPosition->refType == RefTypeBB && block != compiler->fgFirstBB && block != nullptr)
11900         {
11901             dumpRegRecordTitle();
11902         }
11903     }
11904     printf(shortRefPositionFormat, refPosition->nodeLocation, refPosition->rpNum);
11905     if (refPosition->refType == RefTypeBB)
11906     {
11907         if (block == nullptr)
11908         {
11909             printf(regNameFormat, "END");
11910             printf("               ");
11911             printf(regNameFormat, "");
11912         }
11913         else
11914         {
11915             printf(bbRefPosFormat, block->bbNum, block == compiler->fgFirstBB ? 0 : blockInfo[block->bbNum].predBBNum);
11916         }
11917     }
11918     else if (refPosition->isIntervalRef())
11919     {
11920         Interval* interval = refPosition->getInterval();
11921         dumpIntervalName(interval);
11922         char lastUseChar = ' ';
11923         char delayChar   = ' ';
11924         if (refPosition->lastUse)
11925         {
11926             lastUseChar = '*';
11927             if (refPosition->delayRegFree)
11928             {
11929                 delayChar = 'D';
11930             }
11931         }
11932         printf("  %s%c%c ", getRefTypeShortName(refPosition->refType), lastUseChar, delayChar);
11933     }
11934     else if (refPosition->isPhysRegRef)
11935     {
11936         RegRecord* regRecord = refPosition->getReg();
11937         printf(regNameFormat, getRegName(regRecord->regNum));
11938         printf(" %s   ", getRefTypeShortName(refPosition->refType));
11939     }
11940     else
11941     {
11942         assert(refPosition->refType == RefTypeKillGCRefs);
11943         // There's no interval or reg name associated with this.
11944         printf(regNameFormat, "   ");
11945         printf(" %s   ", getRefTypeShortName(refPosition->refType));
11946     }
11947 }
11948
11949 //------------------------------------------------------------------------
11950 // LinearScan::IsResolutionMove:
11951 //     Returns true if the given node is a move inserted by LSRA
11952 //     resolution.
11953 //
11954 // Arguments:
11955 //     node - the node to check.
11956 //
11957 bool LinearScan::IsResolutionMove(GenTree* node)
11958 {
11959     if (!node->gtLsraInfo.isLsraAdded)
11960     {
11961         return false;
11962     }
11963
11964     switch (node->OperGet())
11965     {
11966         case GT_LCL_VAR:
11967         case GT_COPY:
11968             return node->gtLsraInfo.isLocalDefUse;
11969
11970         case GT_SWAP:
11971             return true;
11972
11973         default:
11974             return false;
11975     }
11976 }
11977
11978 //------------------------------------------------------------------------
11979 // LinearScan::IsResolutionNode:
11980 //     Returns true if the given node is either a move inserted by LSRA
11981 //     resolution or an operand to such a move.
11982 //
11983 // Arguments:
11984 //     containingRange - the range that contains the node to check.
11985 //     node - the node to check.
11986 //
11987 bool LinearScan::IsResolutionNode(LIR::Range& containingRange, GenTree* node)
11988 {
11989     for (;;)
11990     {
11991         if (IsResolutionMove(node))
11992         {
11993             return true;
11994         }
11995
11996         if (!node->gtLsraInfo.isLsraAdded || (node->OperGet() != GT_LCL_VAR))
11997         {
11998             return false;
11999         }
12000
12001         LIR::Use use;
12002         bool     foundUse = containingRange.TryGetUse(node, &use);
12003         assert(foundUse);
12004
12005         node = use.User();
12006     }
12007 }
12008
12009 //------------------------------------------------------------------------
12010 // verifyFinalAllocation: Traverse the RefPositions and verify various invariants.
12011 //
12012 // Arguments:
12013 //    None.
12014 //
12015 // Return Value:
12016 //    None.
12017 //
12018 // Notes:
12019 //    If verbose is set, this will also dump a table of the final allocations.
12020 void LinearScan::verifyFinalAllocation()
12021 {
12022     if (VERBOSE)
12023     {
12024         printf("\nFinal allocation\n");
12025     }
12026
12027     // Clear register assignments.
12028     for (regNumber reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
12029     {
12030         RegRecord* physRegRecord        = getRegisterRecord(reg);
12031         physRegRecord->assignedInterval = nullptr;
12032     }
12033
12034     for (auto& interval : intervals)
12035     {
12036         interval.assignedReg = nullptr;
12037         interval.physReg     = REG_NA;
12038     }
12039
12040     DBEXEC(VERBOSE, dumpRegRecordTitle());
12041
12042     BasicBlock*  currentBlock                = nullptr;
12043     GenTree*     firstBlockEndResolutionNode = nullptr;
12044     regMaskTP    regsToFree                  = RBM_NONE;
12045     regMaskTP    delayRegsToFree             = RBM_NONE;
12046     LsraLocation currentLocation             = MinLocation;
12047     for (auto& refPosition : refPositions)
12048     {
12049         RefPosition* currentRefPosition = &refPosition;
12050         Interval*    interval           = nullptr;
12051         RegRecord*   regRecord          = nullptr;
12052         regNumber    regNum             = REG_NA;
12053         if (currentRefPosition->refType == RefTypeBB)
12054         {
12055             regsToFree |= delayRegsToFree;
12056             delayRegsToFree = RBM_NONE;
12057             // For BB RefPositions, wait until we dump the "end of block" info before dumping the basic RefPosition
12058             // info.
12059         }
12060         else
12061         {
12062             // For other RefPosition types, we can dump the basic RefPosition info now.
12063             DBEXEC(VERBOSE, dumpRefPositionShort(currentRefPosition, currentBlock));
12064
12065             if (currentRefPosition->isPhysRegRef)
12066             {
12067                 regRecord                    = currentRefPosition->getReg();
12068                 regRecord->recentRefPosition = currentRefPosition;
12069                 regNum                       = regRecord->regNum;
12070             }
12071             else if (currentRefPosition->isIntervalRef())
12072             {
12073                 interval                    = currentRefPosition->getInterval();
12074                 interval->recentRefPosition = currentRefPosition;
12075                 if (currentRefPosition->registerAssignment != RBM_NONE)
12076                 {
12077                     if (!genMaxOneBit(currentRefPosition->registerAssignment))
12078                     {
12079                         assert(currentRefPosition->refType == RefTypeExpUse ||
12080                                currentRefPosition->refType == RefTypeDummyDef);
12081                     }
12082                     else
12083                     {
12084                         regNum    = currentRefPosition->assignedReg();
12085                         regRecord = getRegisterRecord(regNum);
12086                     }
12087                 }
12088             }
12089         }
12090
12091         LsraLocation newLocation = currentRefPosition->nodeLocation;
12092
12093         if (newLocation > currentLocation)
12094         {
12095             // Free Registers.
12096             // We could use the freeRegisters() method, but we'd have to carefully manage the active intervals.
12097             for (regNumber reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
12098             {
12099                 regMaskTP regMask = genRegMask(reg);
12100                 if ((regsToFree & regMask) != RBM_NONE)
12101                 {
12102                     RegRecord* physRegRecord        = getRegisterRecord(reg);
12103                     physRegRecord->assignedInterval = nullptr;
12104                 }
12105             }
12106             regsToFree = delayRegsToFree;
12107             regsToFree = RBM_NONE;
12108         }
12109         currentLocation = newLocation;
12110
12111         switch (currentRefPosition->refType)
12112         {
12113             case RefTypeBB:
12114             {
12115                 if (currentBlock == nullptr)
12116                 {
12117                     currentBlock = startBlockSequence();
12118                 }
12119                 else
12120                 {
12121                     // Verify the resolution moves at the end of the previous block.
12122                     for (GenTree* node = firstBlockEndResolutionNode; node != nullptr; node = node->gtNext)
12123                     {
12124                         assert(enregisterLocalVars);
12125                         // Only verify nodes that are actually moves; don't bother with the nodes that are
12126                         // operands to moves.
12127                         if (IsResolutionMove(node))
12128                         {
12129                             verifyResolutionMove(node, currentLocation);
12130                         }
12131                     }
12132
12133                     // Validate the locations at the end of the previous block.
12134                     if (enregisterLocalVars)
12135                     {
12136                         VarToRegMap     outVarToRegMap = outVarToRegMaps[currentBlock->bbNum];
12137                         VarSetOps::Iter iter(compiler, currentBlock->bbLiveOut);
12138                         unsigned        varIndex = 0;
12139                         while (iter.NextElem(&varIndex))
12140                         {
12141                             if (localVarIntervals[varIndex] == nullptr)
12142                             {
12143                                 assert(!compiler->lvaTable[compiler->lvaTrackedToVarNum[varIndex]].lvLRACandidate);
12144                                 continue;
12145                             }
12146                             regNumber regNum = getVarReg(outVarToRegMap, varIndex);
12147                             interval         = getIntervalForLocalVar(varIndex);
12148                             assert(interval->physReg == regNum || (interval->physReg == REG_NA && regNum == REG_STK));
12149                             interval->physReg     = REG_NA;
12150                             interval->assignedReg = nullptr;
12151                             interval->isActive    = false;
12152                         }
12153                     }
12154
12155                     // Clear register assignments.
12156                     for (regNumber reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
12157                     {
12158                         RegRecord* physRegRecord        = getRegisterRecord(reg);
12159                         physRegRecord->assignedInterval = nullptr;
12160                     }
12161
12162                     // Now, record the locations at the beginning of this block.
12163                     currentBlock = moveToNextBlock();
12164                 }
12165
12166                 if (currentBlock != nullptr)
12167                 {
12168                     if (enregisterLocalVars)
12169                     {
12170                         VarToRegMap     inVarToRegMap = inVarToRegMaps[currentBlock->bbNum];
12171                         VarSetOps::Iter iter(compiler, currentBlock->bbLiveIn);
12172                         unsigned        varIndex = 0;
12173                         while (iter.NextElem(&varIndex))
12174                         {
12175                             if (localVarIntervals[varIndex] == nullptr)
12176                             {
12177                                 assert(!compiler->lvaTable[compiler->lvaTrackedToVarNum[varIndex]].lvLRACandidate);
12178                                 continue;
12179                             }
12180                             regNumber regNum                  = getVarReg(inVarToRegMap, varIndex);
12181                             interval                          = getIntervalForLocalVar(varIndex);
12182                             interval->physReg                 = regNum;
12183                             interval->assignedReg             = &(physRegs[regNum]);
12184                             interval->isActive                = true;
12185                             physRegs[regNum].assignedInterval = interval;
12186                         }
12187                     }
12188
12189                     if (VERBOSE)
12190                     {
12191                         dumpRefPositionShort(currentRefPosition, currentBlock);
12192                         dumpRegRecords();
12193                     }
12194
12195                     // Finally, handle the resolution moves, if any, at the beginning of the next block.
12196                     firstBlockEndResolutionNode = nullptr;
12197                     bool foundNonResolutionNode = false;
12198
12199                     LIR::Range& currentBlockRange = LIR::AsRange(currentBlock);
12200                     for (GenTree* node : currentBlockRange.NonPhiNodes())
12201                     {
12202                         if (IsResolutionNode(currentBlockRange, node))
12203                         {
12204                             assert(enregisterLocalVars);
12205                             if (foundNonResolutionNode)
12206                             {
12207                                 firstBlockEndResolutionNode = node;
12208                                 break;
12209                             }
12210                             else if (IsResolutionMove(node))
12211                             {
12212                                 // Only verify nodes that are actually moves; don't bother with the nodes that are
12213                                 // operands to moves.
12214                                 verifyResolutionMove(node, currentLocation);
12215                             }
12216                         }
12217                         else
12218                         {
12219                             foundNonResolutionNode = true;
12220                         }
12221                     }
12222                 }
12223             }
12224
12225             break;
12226
12227             case RefTypeKill:
12228                 assert(regRecord != nullptr);
12229                 assert(regRecord->assignedInterval == nullptr);
12230                 dumpLsraAllocationEvent(LSRA_EVENT_KEPT_ALLOCATION, nullptr, regRecord->regNum, currentBlock);
12231                 break;
12232             case RefTypeFixedReg:
12233                 assert(regRecord != nullptr);
12234                 dumpLsraAllocationEvent(LSRA_EVENT_KEPT_ALLOCATION, nullptr, regRecord->regNum, currentBlock);
12235                 break;
12236
12237             case RefTypeUpperVectorSaveDef:
12238             case RefTypeUpperVectorSaveUse:
12239             case RefTypeDef:
12240             case RefTypeUse:
12241             case RefTypeParamDef:
12242             case RefTypeZeroInit:
12243                 assert(interval != nullptr);
12244
12245                 if (interval->isSpecialPutArg)
12246                 {
12247                     dumpLsraAllocationEvent(LSRA_EVENT_SPECIAL_PUTARG, interval, regNum);
12248                     break;
12249                 }
12250                 if (currentRefPosition->reload)
12251                 {
12252                     interval->isActive = true;
12253                     assert(regNum != REG_NA);
12254                     interval->physReg           = regNum;
12255                     interval->assignedReg       = regRecord;
12256                     regRecord->assignedInterval = interval;
12257                     dumpLsraAllocationEvent(LSRA_EVENT_RELOAD, nullptr, regRecord->regNum, currentBlock);
12258                 }
12259                 if (regNum == REG_NA)
12260                 {
12261                     dumpLsraAllocationEvent(LSRA_EVENT_NO_REG_ALLOCATED, interval);
12262                 }
12263                 else if (RefTypeIsDef(currentRefPosition->refType))
12264                 {
12265                     interval->isActive = true;
12266                     if (VERBOSE)
12267                     {
12268                         if (interval->isConstant && (currentRefPosition->treeNode != nullptr) &&
12269                             currentRefPosition->treeNode->IsReuseRegVal())
12270                         {
12271                             dumpLsraAllocationEvent(LSRA_EVENT_REUSE_REG, nullptr, regRecord->regNum, currentBlock);
12272                         }
12273                         else
12274                         {
12275                             dumpLsraAllocationEvent(LSRA_EVENT_ALLOC_REG, nullptr, regRecord->regNum, currentBlock);
12276                         }
12277                     }
12278                 }
12279                 else if (currentRefPosition->copyReg)
12280                 {
12281                     dumpLsraAllocationEvent(LSRA_EVENT_COPY_REG, interval, regRecord->regNum, currentBlock);
12282                 }
12283                 else if (currentRefPosition->moveReg)
12284                 {
12285                     assert(interval->assignedReg != nullptr);
12286                     interval->assignedReg->assignedInterval = nullptr;
12287                     interval->physReg                       = regNum;
12288                     interval->assignedReg                   = regRecord;
12289                     regRecord->assignedInterval             = interval;
12290                     if (VERBOSE)
12291                     {
12292                         printf("Move  %-4s ", getRegName(regRecord->regNum));
12293                     }
12294                 }
12295                 else
12296                 {
12297                     dumpLsraAllocationEvent(LSRA_EVENT_KEPT_ALLOCATION, nullptr, regRecord->regNum, currentBlock);
12298                 }
12299                 if (currentRefPosition->lastUse || currentRefPosition->spillAfter)
12300                 {
12301                     interval->isActive = false;
12302                 }
12303                 if (regNum != REG_NA)
12304                 {
12305                     if (currentRefPosition->spillAfter)
12306                     {
12307                         if (VERBOSE)
12308                         {
12309                             // If refPos is marked as copyReg, then the reg that is spilled
12310                             // is the homeReg of the interval not the reg currently assigned
12311                             // to refPos.
12312                             regNumber spillReg = regNum;
12313                             if (currentRefPosition->copyReg)
12314                             {
12315                                 assert(interval != nullptr);
12316                                 spillReg = interval->physReg;
12317                             }
12318                             dumpRegRecords();
12319                             dumpEmptyRefPosition();
12320                             printf("Spill %-4s ", getRegName(spillReg));
12321                         }
12322                     }
12323                     else if (currentRefPosition->copyReg)
12324                     {
12325                         regRecord->assignedInterval = interval;
12326                     }
12327                     else
12328                     {
12329                         interval->physReg           = regNum;
12330                         interval->assignedReg       = regRecord;
12331                         regRecord->assignedInterval = interval;
12332                     }
12333                 }
12334                 break;
12335             case RefTypeKillGCRefs:
12336                 // No action to take.
12337                 // However, we will assert that, at resolution time, no registers contain GC refs.
12338                 {
12339                     DBEXEC(VERBOSE, printf("           "));
12340                     regMaskTP candidateRegs = currentRefPosition->registerAssignment;
12341                     while (candidateRegs != RBM_NONE)
12342                     {
12343                         regMaskTP nextRegBit = genFindLowestBit(candidateRegs);
12344                         candidateRegs &= ~nextRegBit;
12345                         regNumber  nextReg          = genRegNumFromMask(nextRegBit);
12346                         RegRecord* regRecord        = getRegisterRecord(nextReg);
12347                         Interval*  assignedInterval = regRecord->assignedInterval;
12348                         assert(assignedInterval == nullptr || !varTypeIsGC(assignedInterval->registerType));
12349                     }
12350                 }
12351                 break;
12352
12353             case RefTypeExpUse:
12354             case RefTypeDummyDef:
12355                 // Do nothing; these will be handled by the RefTypeBB.
12356                 DBEXEC(VERBOSE, printf("           "));
12357                 break;
12358
12359             case RefTypeInvalid:
12360                 // for these 'currentRefPosition->refType' values, No action to take
12361                 break;
12362         }
12363
12364         if (currentRefPosition->refType != RefTypeBB)
12365         {
12366             DBEXEC(VERBOSE, dumpRegRecords());
12367             if (interval != nullptr)
12368             {
12369                 if (currentRefPosition->copyReg)
12370                 {
12371                     assert(interval->physReg != regNum);
12372                     regRecord->assignedInterval = nullptr;
12373                     assert(interval->assignedReg != nullptr);
12374                     regRecord = interval->assignedReg;
12375                 }
12376                 if (currentRefPosition->spillAfter || currentRefPosition->lastUse)
12377                 {
12378                     interval->physReg     = REG_NA;
12379                     interval->assignedReg = nullptr;
12380
12381                     // regRegcord could be null if the RefPosition does not require a register.
12382                     if (regRecord != nullptr)
12383                     {
12384                         regRecord->assignedInterval = nullptr;
12385                     }
12386                     else
12387                     {
12388                         assert(!currentRefPosition->RequiresRegister());
12389                     }
12390                 }
12391             }
12392         }
12393     }
12394
12395     // Now, verify the resolution blocks.
12396     // Currently these are nearly always at the end of the method, but that may not alwyas be the case.
12397     // So, we'll go through all the BBs looking for blocks whose bbNum is greater than bbNumMaxBeforeResolution.
12398     for (BasicBlock* currentBlock = compiler->fgFirstBB; currentBlock != nullptr; currentBlock = currentBlock->bbNext)
12399     {
12400         if (currentBlock->bbNum > bbNumMaxBeforeResolution)
12401         {
12402             // If we haven't enregistered an lclVars, we have no resolution blocks.
12403             assert(enregisterLocalVars);
12404
12405             if (VERBOSE)
12406             {
12407                 dumpRegRecordTitle();
12408                 printf(shortRefPositionFormat, 0, 0);
12409                 assert(currentBlock->bbPreds != nullptr && currentBlock->bbPreds->flBlock != nullptr);
12410                 printf(bbRefPosFormat, currentBlock->bbNum, currentBlock->bbPreds->flBlock->bbNum);
12411                 dumpRegRecords();
12412             }
12413
12414             // Clear register assignments.
12415             for (regNumber reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
12416             {
12417                 RegRecord* physRegRecord        = getRegisterRecord(reg);
12418                 physRegRecord->assignedInterval = nullptr;
12419             }
12420
12421             // Set the incoming register assignments
12422             VarToRegMap     inVarToRegMap = getInVarToRegMap(currentBlock->bbNum);
12423             VarSetOps::Iter iter(compiler, currentBlock->bbLiveIn);
12424             unsigned        varIndex = 0;
12425             while (iter.NextElem(&varIndex))
12426             {
12427                 if (localVarIntervals[varIndex] == nullptr)
12428                 {
12429                     assert(!compiler->lvaTable[compiler->lvaTrackedToVarNum[varIndex]].lvLRACandidate);
12430                     continue;
12431                 }
12432                 regNumber regNum                  = getVarReg(inVarToRegMap, varIndex);
12433                 Interval* interval                = getIntervalForLocalVar(varIndex);
12434                 interval->physReg                 = regNum;
12435                 interval->assignedReg             = &(physRegs[regNum]);
12436                 interval->isActive                = true;
12437                 physRegs[regNum].assignedInterval = interval;
12438             }
12439
12440             // Verify the moves in this block
12441             LIR::Range& currentBlockRange = LIR::AsRange(currentBlock);
12442             for (GenTree* node : currentBlockRange.NonPhiNodes())
12443             {
12444                 assert(IsResolutionNode(currentBlockRange, node));
12445                 if (IsResolutionMove(node))
12446                 {
12447                     // Only verify nodes that are actually moves; don't bother with the nodes that are
12448                     // operands to moves.
12449                     verifyResolutionMove(node, currentLocation);
12450                 }
12451             }
12452
12453             // Verify the outgoing register assignments
12454             {
12455                 VarToRegMap     outVarToRegMap = getOutVarToRegMap(currentBlock->bbNum);
12456                 VarSetOps::Iter iter(compiler, currentBlock->bbLiveOut);
12457                 unsigned        varIndex = 0;
12458                 while (iter.NextElem(&varIndex))
12459                 {
12460                     if (localVarIntervals[varIndex] == nullptr)
12461                     {
12462                         assert(!compiler->lvaTable[compiler->lvaTrackedToVarNum[varIndex]].lvLRACandidate);
12463                         continue;
12464                     }
12465                     regNumber regNum   = getVarReg(outVarToRegMap, varIndex);
12466                     Interval* interval = getIntervalForLocalVar(varIndex);
12467                     assert(interval->physReg == regNum || (interval->physReg == REG_NA && regNum == REG_STK));
12468                     interval->physReg     = REG_NA;
12469                     interval->assignedReg = nullptr;
12470                     interval->isActive    = false;
12471                 }
12472             }
12473         }
12474     }
12475
12476     DBEXEC(VERBOSE, printf("\n"));
12477 }
12478
12479 //------------------------------------------------------------------------
12480 // verifyResolutionMove: Verify a resolution statement.  Called by verifyFinalAllocation()
12481 //
12482 // Arguments:
12483 //    resolutionMove    - A GenTree* that must be a resolution move.
12484 //    currentLocation   - The LsraLocation of the most recent RefPosition that has been verified.
12485 //
12486 // Return Value:
12487 //    None.
12488 //
12489 // Notes:
12490 //    If verbose is set, this will also dump the moves into the table of final allocations.
12491 void LinearScan::verifyResolutionMove(GenTree* resolutionMove, LsraLocation currentLocation)
12492 {
12493     GenTree* dst = resolutionMove;
12494     assert(IsResolutionMove(dst));
12495
12496     if (dst->OperGet() == GT_SWAP)
12497     {
12498         GenTreeLclVarCommon* left          = dst->gtGetOp1()->AsLclVarCommon();
12499         GenTreeLclVarCommon* right         = dst->gtGetOp2()->AsLclVarCommon();
12500         regNumber            leftRegNum    = left->gtRegNum;
12501         regNumber            rightRegNum   = right->gtRegNum;
12502         LclVarDsc*           leftVarDsc    = compiler->lvaTable + left->gtLclNum;
12503         LclVarDsc*           rightVarDsc   = compiler->lvaTable + right->gtLclNum;
12504         Interval*            leftInterval  = getIntervalForLocalVar(leftVarDsc->lvVarIndex);
12505         Interval*            rightInterval = getIntervalForLocalVar(rightVarDsc->lvVarIndex);
12506         assert(leftInterval->physReg == leftRegNum && rightInterval->physReg == rightRegNum);
12507         leftInterval->physReg                  = rightRegNum;
12508         rightInterval->physReg                 = leftRegNum;
12509         leftInterval->assignedReg              = &physRegs[rightRegNum];
12510         rightInterval->assignedReg             = &physRegs[leftRegNum];
12511         physRegs[rightRegNum].assignedInterval = leftInterval;
12512         physRegs[leftRegNum].assignedInterval  = rightInterval;
12513         if (VERBOSE)
12514         {
12515             printf(shortRefPositionFormat, currentLocation, 0);
12516             dumpIntervalName(leftInterval);
12517             printf("  Swap   ");
12518             printf("      %-4s ", getRegName(rightRegNum));
12519             dumpRegRecords();
12520             printf(shortRefPositionFormat, currentLocation, 0);
12521             dumpIntervalName(rightInterval);
12522             printf("  \"      ");
12523             printf("      %-4s ", getRegName(leftRegNum));
12524             dumpRegRecords();
12525         }
12526         return;
12527     }
12528     regNumber            dstRegNum = dst->gtRegNum;
12529     regNumber            srcRegNum;
12530     GenTreeLclVarCommon* lcl;
12531     if (dst->OperGet() == GT_COPY)
12532     {
12533         lcl       = dst->gtGetOp1()->AsLclVarCommon();
12534         srcRegNum = lcl->gtRegNum;
12535     }
12536     else
12537     {
12538         lcl = dst->AsLclVarCommon();
12539         if ((lcl->gtFlags & GTF_SPILLED) != 0)
12540         {
12541             srcRegNum = REG_STK;
12542         }
12543         else
12544         {
12545             assert((lcl->gtFlags & GTF_SPILL) != 0);
12546             srcRegNum = dstRegNum;
12547             dstRegNum = REG_STK;
12548         }
12549     }
12550
12551     Interval* interval = getIntervalForLocalVarNode(lcl);
12552     assert(interval->physReg == srcRegNum || (srcRegNum == REG_STK && interval->physReg == REG_NA));
12553     if (srcRegNum != REG_STK)
12554     {
12555         physRegs[srcRegNum].assignedInterval = nullptr;
12556     }
12557     if (dstRegNum != REG_STK)
12558     {
12559         interval->physReg                    = dstRegNum;
12560         interval->assignedReg                = &(physRegs[dstRegNum]);
12561         physRegs[dstRegNum].assignedInterval = interval;
12562         interval->isActive                   = true;
12563     }
12564     else
12565     {
12566         interval->physReg     = REG_NA;
12567         interval->assignedReg = nullptr;
12568         interval->isActive    = false;
12569     }
12570     if (VERBOSE)
12571     {
12572         printf(shortRefPositionFormat, currentLocation, 0);
12573         dumpIntervalName(interval);
12574         printf("  Move   ");
12575         printf("      %-4s ", getRegName(dstRegNum));
12576         dumpRegRecords();
12577     }
12578 }
12579 #endif // DEBUG
12580
12581 #endif // !LEGACY_BACKEND