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