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