Merge pull request #13234 from janvorli/add-rhel6-official-rid
[platform/upstream/coreclr.git] / src / jit / lsra.cpp
1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
4
5 /*
6 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
8
9                  Linear Scan Register Allocation
10
11                          a.k.a. LSRA
12
13   Preconditions
14     - All register requirements are expressed in the code stream, either as destination
15       registers of tree nodes, or as internal registers.  These requirements are
16       expressed in the TreeNodeInfo (gtLsraInfo) on each node, which includes:
17       - The number of register sources and destinations.
18       - The register restrictions (candidates) of the target register, both from itself,
19         as producer of the value (dstCandidates), and from its consuming node (srcCandidates).
20         Note that the srcCandidates field of TreeNodeInfo refers to the destination register
21         (not any of its sources).
22       - The number (internalCount) of registers required, and their register restrictions (internalCandidates).
23         These are neither inputs nor outputs of the node, but used in the sequence of code generated for the tree.
24     "Internal registers" are registers used during the code sequence generated for the node.
25     The register lifetimes must obey the following lifetime model:
26     - First, any internal registers are defined.
27     - Next, any source registers are used (and are then freed if they are last use and are not identified as
28       "delayRegFree").
29     - Next, the internal registers are used (and are then freed).
30     - Next, any registers in the kill set for the instruction are killed.
31     - Next, the destination register(s) are defined (multiple destination registers are only supported on ARM)
32     - Finally, any "delayRegFree" source registers are freed.
33   There are several things to note about this order:
34     - The internal registers will never overlap any use, but they may overlap a destination register.
35     - Internal registers are never live beyond the node.
36     - The "delayRegFree" annotation is used for instructions that are only available in a Read-Modify-Write form.
37       That is, the destination register is one of the sources.  In this case, we must not use the same register for
38       the non-RMW operand as for the destination.
39
40   Overview (doLinearScan):
41     - Walk all blocks, building intervals and RefPositions (buildIntervals)
42     - Allocate registers (allocateRegisters)
43     - Annotate nodes with register assignments (resolveRegisters)
44     - Add move nodes as needed to resolve conflicting register
45       assignments across non-adjacent edges. (resolveEdges, called from resolveRegisters)
46
47   Postconditions:
48
49     Tree nodes (GenTree):
50     - GenTree::gtRegNum (and gtRegPair for ARM) is annotated with the register
51       assignment for a node. If the node does not require a register, it is
52       annotated as such (for single registers, gtRegNum = REG_NA; for register
53       pair type, gtRegPair = REG_PAIR_NONE). For a variable definition or interior
54       tree node (an "implicit" definition), this is the register to put the result.
55       For an expression use, this is the place to find the value that has previously
56       been computed.
57       - In most cases, this register must satisfy the constraints specified by the TreeNodeInfo.
58       - In some cases, this is difficult:
59         - If a lclVar node currently lives in some register, it may not be desirable to move it
60           (i.e. its current location may be desirable for future uses, e.g. if it's a callee save register,
61           but needs to be in a specific arg register for a call).
62         - In other cases there may be conflicts on the restrictions placed by the defining node and the node which
63           consumes it
64       - If such a node is constrained to a single fixed register (e.g. an arg register, or a return from a call),
65         then LSRA is free to annotate the node with a different register.  The code generator must issue the appropriate
66         move.
67       - However, if such a node is constrained to a set of registers, and its current location does not satisfy that
68         requirement, LSRA must insert a GT_COPY node between the node and its parent.  The gtRegNum on the GT_COPY node
69         must satisfy the register requirement of the parent.
70     - GenTree::gtRsvdRegs has a set of registers used for internal temps.
71     - A tree node is marked GTF_SPILL if the tree node must be spilled by the code generator after it has been
72       evaluated.
73       - LSRA currently does not set GTF_SPILLED on such nodes, because it caused problems in the old code generator.
74         In the new backend perhaps this should change (see also the note below under CodeGen).
75     - A tree node is marked GTF_SPILLED if it is a lclVar that must be reloaded prior to use.
76       - The register (gtRegNum) on the node indicates the register to which it must be reloaded.
77       - For lclVar nodes, since the uses and defs are distinct tree nodes, it is always possible to annotate the node
78         with the register to which the variable must be reloaded.
79       - For other nodes, since they represent both the def and use, if the value must be reloaded to a different
80         register, LSRA must insert a GT_RELOAD node in order to specify the register to which it should be reloaded.
81
82     Local variable table (LclVarDsc):
83     - LclVarDsc::lvRegister is set to true if a local variable has the
84       same register assignment for its entire lifetime.
85     - LclVarDsc::lvRegNum / lvOtherReg: these are initialized to their
86       first value at the end of LSRA (it looks like lvOtherReg isn't?
87       This is probably a bug (ARM)). Codegen will set them to their current value
88       as it processes the trees, since a variable can (now) be assigned different
89       registers over its lifetimes.
90
91 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
92 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
93 */
94
95 #include "jitpch.h"
96 #ifdef _MSC_VER
97 #pragma hdrstop
98 #endif
99
100 #ifndef LEGACY_BACKEND // This file is ONLY used for the RyuJIT backend that uses the linear scan register allocator
101
102 #include "lsra.h"
103
104 #ifdef DEBUG
105 const char* LinearScan::resolveTypeName[] = {"Split", "Join", "Critical", "SharedCritical"};
106 #endif // DEBUG
107
108 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
109 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
110 XX                                                                           XX
111 XX                    Small Helper functions                                 XX
112 XX                                                                           XX
113 XX                                                                           XX
114 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
115 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
116 */
117
118 //--------------------------------------------------------------
119 // lsraAssignRegToTree: Assign the given reg to tree node.
120 //
121 // Arguments:
122 //    tree    -    Gentree node
123 //    reg     -    register to be assigned
124 //    regIdx  -    register idx, if tree is a multi-reg call node.
125 //                 regIdx will be zero for single-reg result producing tree nodes.
126 //
127 // Return Value:
128 //    None
129 //
130 void lsraAssignRegToTree(GenTreePtr tree, regNumber reg, unsigned regIdx)
131 {
132     if (regIdx == 0)
133     {
134         tree->gtRegNum = reg;
135     }
136 #if defined(_TARGET_ARM_)
137     else if (tree->OperGet() == GT_MUL_LONG || tree->OperGet() == GT_PUTARG_REG)
138     {
139         assert(regIdx == 1);
140         GenTreeMultiRegOp* mul = tree->AsMultiRegOp();
141         mul->gtOtherReg        = reg;
142     }
143     else if (tree->OperGet() == GT_COPY)
144     {
145         assert(regIdx == 1);
146         GenTreeCopyOrReload* copy = tree->AsCopyOrReload();
147         copy->gtOtherRegs[0]      = (regNumberSmall)reg;
148     }
149     else if (tree->OperGet() == GT_PUTARG_SPLIT)
150     {
151         GenTreePutArgSplit* putArg = tree->AsPutArgSplit();
152         putArg->SetRegNumByIdx(reg, regIdx);
153     }
154 #endif // _TARGET_ARM_
155     else
156     {
157         assert(tree->IsMultiRegCall());
158         GenTreeCall* call = tree->AsCall();
159         call->SetRegNumByIdx(reg, regIdx);
160     }
161 }
162
163 //-------------------------------------------------------------
164 // getWeight: Returns the weight of the RefPosition.
165 //
166 // Arguments:
167 //    refPos   -   ref position
168 //
169 // Returns:
170 //    Weight of ref position.
171 unsigned LinearScan::getWeight(RefPosition* refPos)
172 {
173     unsigned   weight;
174     GenTreePtr treeNode = refPos->treeNode;
175
176     if (treeNode != nullptr)
177     {
178         if (isCandidateLocalRef(treeNode))
179         {
180             // Tracked locals: use weighted ref cnt as the weight of the
181             // ref position.
182             GenTreeLclVarCommon* lclCommon = treeNode->AsLclVarCommon();
183             LclVarDsc*           varDsc    = &(compiler->lvaTable[lclCommon->gtLclNum]);
184             weight                         = varDsc->lvRefCntWtd;
185         }
186         else
187         {
188             // Non-candidate local ref or non-lcl tree node.
189             // These are considered to have two references in the basic block:
190             // a def and a use and hence weighted ref count is 2 times
191             // the basic block weight in which they appear.
192             weight = 2 * this->blockInfo[refPos->bbNum].weight;
193         }
194     }
195     else
196     {
197         // Non-tree node ref positions.  These will have a single
198         // reference in the basic block and hence their weighted
199         // refcount is equal to the block weight in which they
200         // appear.
201         weight = this->blockInfo[refPos->bbNum].weight;
202     }
203
204     return weight;
205 }
206
207 // allRegs represents a set of registers that can
208 // be used to allocate the specified type in any point
209 // in time (more of a 'bank' of registers).
210 regMaskTP LinearScan::allRegs(RegisterType rt)
211 {
212     if (rt == TYP_FLOAT)
213     {
214         return availableFloatRegs;
215     }
216     else if (rt == TYP_DOUBLE)
217     {
218         return availableDoubleRegs;
219 #ifdef FEATURE_SIMD
220         // TODO-Cleanup: Add an RBM_ALLSIMD
221     }
222     else if (varTypeIsSIMD(rt))
223     {
224         return availableDoubleRegs;
225 #endif // FEATURE_SIMD
226     }
227     else
228     {
229         return availableIntRegs;
230     }
231 }
232
233 //--------------------------------------------------------------------------
234 // allMultiRegCallNodeRegs: represents a set of registers that can be used
235 // to allocate a multi-reg call node.
236 //
237 // Arguments:
238 //    call   -  Multi-reg call node
239 //
240 // Return Value:
241 //    Mask representing the set of available registers for multi-reg call
242 //    node.
243 //
244 // Note:
245 // Multi-reg call node available regs = Bitwise-OR(allregs(GetReturnRegType(i)))
246 // for all i=0..RetRegCount-1.
247 regMaskTP LinearScan::allMultiRegCallNodeRegs(GenTreeCall* call)
248 {
249     assert(call->HasMultiRegRetVal());
250
251     ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc();
252     regMaskTP       resultMask  = allRegs(retTypeDesc->GetReturnRegType(0));
253
254     unsigned count = retTypeDesc->GetReturnRegCount();
255     for (unsigned i = 1; i < count; ++i)
256     {
257         resultMask |= allRegs(retTypeDesc->GetReturnRegType(i));
258     }
259
260     return resultMask;
261 }
262
263 //--------------------------------------------------------------------------
264 // allRegs: returns the set of registers that can accomodate the type of
265 // given node.
266 //
267 // Arguments:
268 //    tree   -  GenTree node
269 //
270 // Return Value:
271 //    Mask representing the set of available registers for given tree
272 //
273 // Note: In case of multi-reg call node, the full set of registers must be
274 // determined by looking at types of individual return register types.
275 // In this case, the registers may include registers from different register
276 // sets and will not be limited to the actual ABI return registers.
277 regMaskTP LinearScan::allRegs(GenTree* tree)
278 {
279     regMaskTP resultMask;
280
281     // In case of multi-reg calls, allRegs is defined as
282     // Bitwise-Or(allRegs(GetReturnRegType(i)) for i=0..ReturnRegCount-1
283     if (tree->IsMultiRegCall())
284     {
285         resultMask = allMultiRegCallNodeRegs(tree->AsCall());
286     }
287     else
288     {
289         resultMask = allRegs(tree->TypeGet());
290     }
291
292     return resultMask;
293 }
294
295 regMaskTP LinearScan::allSIMDRegs()
296 {
297     return availableFloatRegs;
298 }
299
300 //------------------------------------------------------------------------
301 // internalFloatRegCandidates: Return the set of registers that are appropriate
302 //                             for use as internal float registers.
303 //
304 // Return Value:
305 //    The set of registers (as a regMaskTP).
306 //
307 // Notes:
308 //    compFloatingPointUsed is only required to be set if it is possible that we
309 //    will use floating point callee-save registers.
310 //    It is unlikely, if an internal register is the only use of floating point,
311 //    that it will select a callee-save register.  But to be safe, we restrict
312 //    the set of candidates if compFloatingPointUsed is not already set.
313
314 regMaskTP LinearScan::internalFloatRegCandidates()
315 {
316     if (compiler->compFloatingPointUsed)
317     {
318         return allRegs(TYP_FLOAT);
319     }
320     else
321     {
322         return RBM_FLT_CALLEE_TRASH;
323     }
324 }
325
326 /*****************************************************************************
327  * Register types
328  *****************************************************************************/
329 template <class T>
330 RegisterType regType(T type)
331 {
332 #ifdef FEATURE_SIMD
333     if (varTypeIsSIMD(type))
334     {
335         return FloatRegisterType;
336     }
337 #endif // FEATURE_SIMD
338     return varTypeIsFloating(TypeGet(type)) ? FloatRegisterType : IntRegisterType;
339 }
340
341 bool useFloatReg(var_types type)
342 {
343     return (regType(type) == FloatRegisterType);
344 }
345
346 bool registerTypesEquivalent(RegisterType a, RegisterType b)
347 {
348     return varTypeIsIntegralOrI(a) == varTypeIsIntegralOrI(b);
349 }
350
351 bool isSingleRegister(regMaskTP regMask)
352 {
353     return (regMask != RBM_NONE && genMaxOneBit(regMask));
354 }
355
356 /*****************************************************************************
357  * Inline functions for RegRecord
358  *****************************************************************************/
359
360 bool RegRecord::isFree()
361 {
362     return ((assignedInterval == nullptr || !assignedInterval->isActive) && !isBusyUntilNextKill);
363 }
364
365 /*****************************************************************************
366  * Inline functions for LinearScan
367  *****************************************************************************/
368 RegRecord* LinearScan::getRegisterRecord(regNumber regNum)
369 {
370     return &physRegs[regNum];
371 }
372
373 #ifdef DEBUG
374
375 //----------------------------------------------------------------------------
376 // getConstrainedRegMask: Returns new regMask which is the intersection of
377 // regMaskActual and regMaskConstraint if the new regMask has at least
378 // minRegCount registers, otherwise returns regMaskActual.
379 //
380 // Arguments:
381 //     regMaskActual      -  regMask that needs to be constrained
382 //     regMaskConstraint  -  regMask constraint that needs to be
383 //                           applied to regMaskActual
384 //     minRegCount        -  Minimum number of regs that should be
385 //                           be present in new regMask.
386 //
387 // Return Value:
388 //     New regMask that has minRegCount registers after instersection.
389 //     Otherwise returns regMaskActual.
390 regMaskTP LinearScan::getConstrainedRegMask(regMaskTP regMaskActual, regMaskTP regMaskConstraint, unsigned minRegCount)
391 {
392     regMaskTP newMask = regMaskActual & regMaskConstraint;
393     if (genCountBits(newMask) >= minRegCount)
394     {
395         return newMask;
396     }
397
398     return regMaskActual;
399 }
400
401 //------------------------------------------------------------------------
402 // stressLimitRegs: Given a set of registers, expressed as a register mask, reduce
403 //            them based on the current stress options.
404 //
405 // Arguments:
406 //    mask      - The current mask of register candidates for a node
407 //
408 // Return Value:
409 //    A possibly-modified mask, based on the value of COMPlus_JitStressRegs.
410 //
411 // Notes:
412 //    This is the method used to implement the stress options that limit
413 //    the set of registers considered for allocation.
414
415 regMaskTP LinearScan::stressLimitRegs(RefPosition* refPosition, regMaskTP mask)
416 {
417     if (getStressLimitRegs() != LSRA_LIMIT_NONE)
418     {
419         // The refPosition could be null, for example when called
420         // by getTempRegForResolution().
421         int minRegCount = (refPosition != nullptr) ? refPosition->minRegCandidateCount : 1;
422
423         switch (getStressLimitRegs())
424         {
425             case LSRA_LIMIT_CALLEE:
426                 if (!compiler->opts.compDbgEnC)
427                 {
428                     mask = getConstrainedRegMask(mask, RBM_CALLEE_SAVED, minRegCount);
429                 }
430                 break;
431
432             case LSRA_LIMIT_CALLER:
433             {
434                 mask = getConstrainedRegMask(mask, RBM_CALLEE_TRASH, minRegCount);
435             }
436             break;
437
438             case LSRA_LIMIT_SMALL_SET:
439                 if ((mask & LsraLimitSmallIntSet) != RBM_NONE)
440                 {
441                     mask = getConstrainedRegMask(mask, LsraLimitSmallIntSet, minRegCount);
442                 }
443                 else if ((mask & LsraLimitSmallFPSet) != RBM_NONE)
444                 {
445                     mask = getConstrainedRegMask(mask, LsraLimitSmallFPSet, minRegCount);
446                 }
447                 break;
448
449             default:
450                 unreached();
451         }
452
453         if (refPosition != nullptr && refPosition->isFixedRegRef)
454         {
455             mask |= refPosition->registerAssignment;
456         }
457     }
458
459     return mask;
460 }
461 #endif // DEBUG
462
463 // TODO-Cleanup: Consider adding an overload that takes a varDsc, and can appropriately
464 // set such fields as isStructField
465
466 Interval* LinearScan::newInterval(RegisterType theRegisterType)
467 {
468     intervals.emplace_back(theRegisterType, allRegs(theRegisterType));
469     Interval* newInt = &intervals.back();
470
471 #ifdef DEBUG
472     newInt->intervalIndex = static_cast<unsigned>(intervals.size() - 1);
473 #endif // DEBUG
474
475     DBEXEC(VERBOSE, newInt->dump());
476     return newInt;
477 }
478
479 RefPosition* LinearScan::newRefPositionRaw(LsraLocation nodeLocation, GenTree* treeNode, RefType refType)
480 {
481     refPositions.emplace_back(curBBNum, nodeLocation, treeNode, refType);
482     RefPosition* newRP = &refPositions.back();
483 #ifdef DEBUG
484     newRP->rpNum = static_cast<unsigned>(refPositions.size() - 1);
485 #endif // DEBUG
486     return newRP;
487 }
488
489 //------------------------------------------------------------------------
490 // resolveConflictingDefAndUse: Resolve the situation where we have conflicting def and use
491 //    register requirements on a single-def, single-use interval.
492 //
493 // Arguments:
494 //    defRefPosition - The interval definition
495 //    useRefPosition - The (sole) interval use
496 //
497 // Return Value:
498 //    None.
499 //
500 // Assumptions:
501 //    The two RefPositions are for the same interval, which is a tree-temp.
502 //
503 // Notes:
504 //    We require some special handling for the case where the use is a "delayRegFree" case of a fixedReg.
505 //    In that case, if we change the registerAssignment on the useRefPosition, we will lose the fact that,
506 //    even if we assign a different register (and rely on codegen to do the copy), that fixedReg also needs
507 //    to remain busy until the Def register has been allocated.  In that case, we don't allow Case 1 or Case 4
508 //    below.
509 //    Here are the cases we consider (in this order):
510 //    1. If The defRefPosition specifies a single register, and there are no conflicting
511 //       FixedReg uses of it between the def and use, we use that register, and the code generator
512 //       will insert the copy.  Note that it cannot be in use because there is a FixedRegRef for the def.
513 //    2. If the useRefPosition specifies a single register, and it is not in use, and there are no
514 //       conflicting FixedReg uses of it between the def and use, we use that register, and the code generator
515 //       will insert the copy.
516 //    3. If the defRefPosition specifies a single register (but there are conflicts, as determined
517 //       in 1.), and there are no conflicts with the useRefPosition register (if it's a single register),
518 ///      we set the register requirements on the defRefPosition to the use registers, and the
519 //       code generator will insert a copy on the def.  We can't rely on the code generator to put a copy
520 //       on the use if it has multiple possible candidates, as it won't know which one has been allocated.
521 //    4. If the useRefPosition specifies a single register, and there are no conflicts with the register
522 //       on the defRefPosition, we leave the register requirements on the defRefPosition as-is, and set
523 //       the useRefPosition to the def registers, for similar reasons to case #3.
524 //    5. If both the defRefPosition and the useRefPosition specify single registers, but both have conflicts,
525 //       We set the candiates on defRefPosition to be all regs of the appropriate type, and since they are
526 //       single registers, codegen can insert the copy.
527 //    6. Finally, if the RefPositions specify disjoint subsets of the registers (or the use is fixed but
528 //       has a conflict), we must insert a copy.  The copy will be inserted before the use if the
529 //       use is not fixed (in the fixed case, the code generator will insert the use).
530 //
531 // TODO-CQ: We get bad register allocation in case #3 in the situation where no register is
532 // available for the lifetime.  We end up allocating a register that must be spilled, and it probably
533 // won't be the register that is actually defined by the target instruction.  So, we have to copy it
534 // and THEN spill it.  In this case, we should be using the def requirement.  But we need to change
535 // the interface to this method a bit to make that work (e.g. returning a candidate set to use, but
536 // leaving the registerAssignment as-is on the def, so that if we find that we need to spill anyway
537 // we can use the fixed-reg on the def.
538 //
539
540 void LinearScan::resolveConflictingDefAndUse(Interval* interval, RefPosition* defRefPosition)
541 {
542     assert(!interval->isLocalVar);
543
544     RefPosition* useRefPosition   = defRefPosition->nextRefPosition;
545     regMaskTP    defRegAssignment = defRefPosition->registerAssignment;
546     regMaskTP    useRegAssignment = useRefPosition->registerAssignment;
547     RegRecord*   defRegRecord     = nullptr;
548     RegRecord*   useRegRecord     = nullptr;
549     regNumber    defReg           = REG_NA;
550     regNumber    useReg           = REG_NA;
551     bool         defRegConflict   = false;
552     bool         useRegConflict   = false;
553
554     // If the useRefPosition is a "delayRegFree", we can't change the registerAssignment
555     // on it, or we will fail to ensure that the fixedReg is busy at the time the target
556     // (of the node that uses this interval) is allocated.
557     bool canChangeUseAssignment = !useRefPosition->isFixedRegRef || !useRefPosition->delayRegFree;
558
559     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CONFLICT));
560     if (!canChangeUseAssignment)
561     {
562         INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_FIXED_DELAY_USE));
563     }
564     if (defRefPosition->isFixedRegRef)
565     {
566         defReg       = defRefPosition->assignedReg();
567         defRegRecord = getRegisterRecord(defReg);
568         if (canChangeUseAssignment)
569         {
570             RefPosition* currFixedRegRefPosition = defRegRecord->recentRefPosition;
571             assert(currFixedRegRefPosition != nullptr &&
572                    currFixedRegRefPosition->nodeLocation == defRefPosition->nodeLocation);
573
574             if (currFixedRegRefPosition->nextRefPosition == nullptr ||
575                 currFixedRegRefPosition->nextRefPosition->nodeLocation > useRefPosition->getRefEndLocation())
576             {
577                 // This is case #1.  Use the defRegAssignment
578                 INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CASE1));
579                 useRefPosition->registerAssignment = defRegAssignment;
580                 return;
581             }
582             else
583             {
584                 defRegConflict = true;
585             }
586         }
587     }
588     if (useRefPosition->isFixedRegRef)
589     {
590         useReg                               = useRefPosition->assignedReg();
591         useRegRecord                         = getRegisterRecord(useReg);
592         RefPosition* currFixedRegRefPosition = useRegRecord->recentRefPosition;
593
594         // We know that useRefPosition is a fixed use, so the nextRefPosition must not be null.
595         RefPosition* nextFixedRegRefPosition = useRegRecord->getNextRefPosition();
596         assert(nextFixedRegRefPosition != nullptr &&
597                nextFixedRegRefPosition->nodeLocation <= useRefPosition->nodeLocation);
598
599         // First, check to see if there are any conflicting FixedReg references between the def and use.
600         if (nextFixedRegRefPosition->nodeLocation == useRefPosition->nodeLocation)
601         {
602             // OK, no conflicting FixedReg references.
603             // Now, check to see whether it is currently in use.
604             if (useRegRecord->assignedInterval != nullptr)
605             {
606                 RefPosition* possiblyConflictingRef         = useRegRecord->assignedInterval->recentRefPosition;
607                 LsraLocation possiblyConflictingRefLocation = possiblyConflictingRef->getRefEndLocation();
608                 if (possiblyConflictingRefLocation >= defRefPosition->nodeLocation)
609                 {
610                     useRegConflict = true;
611                 }
612             }
613             if (!useRegConflict)
614             {
615                 // This is case #2.  Use the useRegAssignment
616                 INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CASE2));
617                 defRefPosition->registerAssignment = useRegAssignment;
618                 return;
619             }
620         }
621         else
622         {
623             useRegConflict = true;
624         }
625     }
626     if (defRegRecord != nullptr && !useRegConflict)
627     {
628         // This is case #3.
629         INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CASE3));
630         defRefPosition->registerAssignment = useRegAssignment;
631         return;
632     }
633     if (useRegRecord != nullptr && !defRegConflict && canChangeUseAssignment)
634     {
635         // This is case #4.
636         INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CASE4));
637         useRefPosition->registerAssignment = defRegAssignment;
638         return;
639     }
640     if (defRegRecord != nullptr && useRegRecord != nullptr)
641     {
642         // This is case #5.
643         INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CASE5));
644         RegisterType regType = interval->registerType;
645         assert((getRegisterType(interval, defRefPosition) == regType) &&
646                (getRegisterType(interval, useRefPosition) == regType));
647         regMaskTP candidates               = allRegs(regType);
648         defRefPosition->registerAssignment = candidates;
649         return;
650     }
651     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CASE6));
652     return;
653 }
654
655 //------------------------------------------------------------------------
656 // conflictingFixedRegReference: Determine whether the current RegRecord has a
657 //                               fixed register use that conflicts with 'refPosition'
658 //
659 // Arguments:
660 //    refPosition - The RefPosition of interest
661 //
662 // Return Value:
663 //    Returns true iff the given RefPosition is NOT a fixed use of this register,
664 //    AND either:
665 //    - there is a RefPosition on this RegRecord at the nodeLocation of the given RefPosition, or
666 //    - the given RefPosition has a delayRegFree, and there is a RefPosition on this RegRecord at
667 //      the nodeLocation just past the given RefPosition.
668 //
669 // Assumptions:
670 //    'refPosition is non-null.
671
672 bool RegRecord::conflictingFixedRegReference(RefPosition* refPosition)
673 {
674     // Is this a fixed reference of this register?  If so, there is no conflict.
675     if (refPosition->isFixedRefOfRegMask(genRegMask(regNum)))
676     {
677         return false;
678     }
679     // Otherwise, check for conflicts.
680     // There is a conflict if:
681     // 1. There is a recent RefPosition on this RegRecord that is at this location,
682     //    except in the case where it is a special "putarg" that is associated with this interval, OR
683     // 2. There is an upcoming RefPosition at this location, or at the next location
684     //    if refPosition is a delayed use (i.e. must be kept live through the next/def location).
685
686     LsraLocation refLocation = refPosition->nodeLocation;
687     if (recentRefPosition != nullptr && recentRefPosition->refType != RefTypeKill &&
688         recentRefPosition->nodeLocation == refLocation &&
689         (!isBusyUntilNextKill || assignedInterval != refPosition->getInterval()))
690     {
691         return true;
692     }
693     LsraLocation nextPhysRefLocation = getNextRefLocation();
694     if (nextPhysRefLocation == refLocation || (refPosition->delayRegFree && nextPhysRefLocation == (refLocation + 1)))
695     {
696         return true;
697     }
698     return false;
699 }
700
701 void LinearScan::applyCalleeSaveHeuristics(RefPosition* rp)
702 {
703 #ifdef _TARGET_AMD64_
704     if (compiler->opts.compDbgEnC)
705     {
706         // We only use RSI and RDI for EnC code, so we don't want to favor callee-save regs.
707         return;
708     }
709 #endif // _TARGET_AMD64_
710
711     Interval* theInterval = rp->getInterval();
712
713 #ifdef DEBUG
714     regMaskTP calleeSaveMask = calleeSaveRegs(getRegisterType(theInterval, rp));
715     if (doReverseCallerCallee())
716     {
717         rp->registerAssignment =
718             getConstrainedRegMask(rp->registerAssignment, calleeSaveMask, rp->minRegCandidateCount);
719     }
720     else
721 #endif // DEBUG
722     {
723         // Set preferences so that this register set will be preferred for earlier refs
724         theInterval->updateRegisterPreferences(rp->registerAssignment);
725     }
726 }
727
728 void LinearScan::associateRefPosWithInterval(RefPosition* rp)
729 {
730     Referenceable* theReferent = rp->referent;
731
732     if (theReferent != nullptr)
733     {
734         // All RefPositions except the dummy ones at the beginning of blocks
735
736         if (rp->isIntervalRef())
737         {
738             Interval* theInterval = rp->getInterval();
739
740             applyCalleeSaveHeuristics(rp);
741
742             if (theInterval->isLocalVar)
743             {
744                 if (RefTypeIsUse(rp->refType))
745                 {
746                     RefPosition* const prevRP = theInterval->recentRefPosition;
747                     if ((prevRP != nullptr) && (prevRP->bbNum == rp->bbNum))
748                     {
749                         prevRP->lastUse = false;
750                     }
751                 }
752
753                 rp->lastUse = (rp->refType != RefTypeExpUse) && (rp->refType != RefTypeParamDef) &&
754                               (rp->refType != RefTypeZeroInit) && !extendLifetimes();
755             }
756             else if (rp->refType == RefTypeUse)
757             {
758                 // Ensure that we have consistent def/use on SDSU temps.
759                 // However, there are a couple of cases where this may over-constrain allocation:
760                 // 1. In the case of a non-commutative rmw def (in which the rmw source must be delay-free), or
761                 // 2. In the case where the defining node requires a temp distinct from the target (also a
762                 //    delay-free case).
763                 // In those cases, if we propagate a single-register restriction from the consumer to the producer
764                 // the delayed uses will not see a fixed reference in the PhysReg at that position, and may
765                 // incorrectly allocate that register.
766                 // TODO-CQ: This means that we may often require a copy at the use of this node's result.
767                 // This case could be moved to BuildRefPositionsForNode, at the point where the def RefPosition is
768                 // created, causing a RefTypeFixedRef to be added at that location. This, however, results in
769                 // more PhysReg RefPositions (a throughput impact), and a large number of diffs that require
770                 // further analysis to determine benefit.
771                 // See Issue #11274.
772                 RefPosition* prevRefPosition = theInterval->recentRefPosition;
773                 assert(prevRefPosition != nullptr && theInterval->firstRefPosition == prevRefPosition);
774                 // All defs must have a valid treeNode, but we check it below to be conservative.
775                 assert(prevRefPosition->treeNode != nullptr);
776                 regMaskTP prevAssignment = prevRefPosition->registerAssignment;
777                 regMaskTP newAssignment  = (prevAssignment & rp->registerAssignment);
778                 if (newAssignment != RBM_NONE)
779                 {
780                     if (!isSingleRegister(newAssignment) ||
781                         (!theInterval->hasNonCommutativeRMWDef && (prevRefPosition->treeNode != nullptr) &&
782                          !prevRefPosition->treeNode->gtLsraInfo.isInternalRegDelayFree))
783                     {
784                         prevRefPosition->registerAssignment = newAssignment;
785                     }
786                 }
787                 else
788                 {
789                     theInterval->hasConflictingDefUse = true;
790                 }
791
792                 rp->lastUse = true;
793             }
794         }
795
796         RefPosition* prevRP = theReferent->recentRefPosition;
797         if (prevRP != nullptr)
798         {
799             prevRP->nextRefPosition = rp;
800         }
801         else
802         {
803             theReferent->firstRefPosition = rp;
804         }
805         theReferent->recentRefPosition = rp;
806         theReferent->lastRefPosition   = rp;
807     }
808     else
809     {
810         assert((rp->refType == RefTypeBB) || (rp->refType == RefTypeKillGCRefs));
811     }
812 }
813
814 //---------------------------------------------------------------------------
815 // newRefPosition: allocate and initialize a new RefPosition.
816 //
817 // Arguments:
818 //     reg             -  reg number that identifies RegRecord to be associated
819 //                        with this RefPosition
820 //     theLocation     -  LSRA location of RefPosition
821 //     theRefType      -  RefPosition type
822 //     theTreeNode     -  GenTree node for which this RefPosition is created
823 //     mask            -  Set of valid registers for this RefPosition
824 //     multiRegIdx     -  register position if this RefPosition corresponds to a
825 //                        multi-reg call node.
826 //
827 // Return Value:
828 //     a new RefPosition
829 //
830 RefPosition* LinearScan::newRefPosition(
831     regNumber reg, LsraLocation theLocation, RefType theRefType, GenTree* theTreeNode, regMaskTP mask)
832 {
833     RefPosition* newRP = newRefPositionRaw(theLocation, theTreeNode, theRefType);
834
835     newRP->setReg(getRegisterRecord(reg));
836     newRP->registerAssignment = mask;
837
838     newRP->setMultiRegIdx(0);
839     newRP->setAllocateIfProfitable(false);
840
841     associateRefPosWithInterval(newRP);
842
843     DBEXEC(VERBOSE, newRP->dump());
844     return newRP;
845 }
846
847 //---------------------------------------------------------------------------
848 // newRefPosition: allocate and initialize a new RefPosition.
849 //
850 // Arguments:
851 //     theInterval     -  interval to which RefPosition is associated with.
852 //     theLocation     -  LSRA location of RefPosition
853 //     theRefType      -  RefPosition type
854 //     theTreeNode     -  GenTree node for which this RefPosition is created
855 //     mask            -  Set of valid registers for this RefPosition
856 //     multiRegIdx     -  register position if this RefPosition corresponds to a
857 //                        multi-reg call node.
858 //     minRegCount     -  Minimum number registers that needs to be ensured while
859 //                        constraining candidates for this ref position under
860 //                        LSRA stress. This is a DEBUG only arg.
861 //
862 // Return Value:
863 //     a new RefPosition
864 //
865 RefPosition* LinearScan::newRefPosition(Interval*    theInterval,
866                                         LsraLocation theLocation,
867                                         RefType      theRefType,
868                                         GenTree*     theTreeNode,
869                                         regMaskTP    mask,
870                                         unsigned     multiRegIdx /* = 0 */
871                                         DEBUGARG(unsigned minRegCandidateCount /* = 1 */))
872 {
873 #ifdef DEBUG
874     if (theInterval != nullptr && regType(theInterval->registerType) == FloatRegisterType)
875     {
876         // In the case we're using floating point registers we must make sure
877         // this flag was set previously in the compiler since this will mandate
878         // whether LSRA will take into consideration FP reg killsets.
879         assert(compiler->compFloatingPointUsed || ((mask & RBM_FLT_CALLEE_SAVED) == 0));
880     }
881 #endif // DEBUG
882
883     // If this reference is constrained to a single register (and it's not a dummy
884     // or Kill reftype already), add a RefTypeFixedReg at this location so that its
885     // availability can be more accurately determined
886
887     bool isFixedRegister = isSingleRegister(mask);
888     bool insertFixedRef  = false;
889     if (isFixedRegister)
890     {
891         // Insert a RefTypeFixedReg for any normal def or use (not ParamDef or BB)
892         if (theRefType == RefTypeUse || theRefType == RefTypeDef)
893         {
894             insertFixedRef = true;
895         }
896     }
897
898     if (insertFixedRef)
899     {
900         regNumber    physicalReg = genRegNumFromMask(mask);
901         RefPosition* pos         = newRefPosition(physicalReg, theLocation, RefTypeFixedReg, nullptr, mask);
902         assert(theInterval != nullptr);
903         assert((allRegs(theInterval->registerType) & mask) != 0);
904     }
905
906     RefPosition* newRP = newRefPositionRaw(theLocation, theTreeNode, theRefType);
907
908     newRP->setInterval(theInterval);
909
910     // Spill info
911     newRP->isFixedRegRef = isFixedRegister;
912
913 #ifndef _TARGET_AMD64_
914     // We don't need this for AMD because the PInvoke method epilog code is explicit
915     // at register allocation time.
916     if (theInterval != nullptr && theInterval->isLocalVar && compiler->info.compCallUnmanaged &&
917         theInterval->varNum == compiler->genReturnLocal)
918     {
919         mask &= ~(RBM_PINVOKE_TCB | RBM_PINVOKE_FRAME);
920         noway_assert(mask != RBM_NONE);
921     }
922 #endif // !_TARGET_AMD64_
923     newRP->registerAssignment = mask;
924
925     newRP->setMultiRegIdx(multiRegIdx);
926     newRP->setAllocateIfProfitable(false);
927
928 #ifdef DEBUG
929     newRP->minRegCandidateCount = minRegCandidateCount;
930 #endif // DEBUG
931
932     associateRefPosWithInterval(newRP);
933
934     DBEXEC(VERBOSE, newRP->dump());
935     return newRP;
936 }
937
938 /*****************************************************************************
939  * Inline functions for Interval
940  *****************************************************************************/
941 RefPosition* Referenceable::getNextRefPosition()
942 {
943     if (recentRefPosition == nullptr)
944     {
945         return firstRefPosition;
946     }
947     else
948     {
949         return recentRefPosition->nextRefPosition;
950     }
951 }
952
953 LsraLocation Referenceable::getNextRefLocation()
954 {
955     RefPosition* nextRefPosition = getNextRefPosition();
956     if (nextRefPosition == nullptr)
957     {
958         return MaxLocation;
959     }
960     else
961     {
962         return nextRefPosition->nodeLocation;
963     }
964 }
965
966 // Iterate through all the registers of the given type
967 class RegisterIterator
968 {
969     friend class Registers;
970
971 public:
972     RegisterIterator(RegisterType type) : regType(type)
973     {
974         if (useFloatReg(regType))
975         {
976             currentRegNum = REG_FP_FIRST;
977         }
978         else
979         {
980             currentRegNum = REG_INT_FIRST;
981         }
982     }
983
984 protected:
985     static RegisterIterator Begin(RegisterType regType)
986     {
987         return RegisterIterator(regType);
988     }
989     static RegisterIterator End(RegisterType regType)
990     {
991         RegisterIterator endIter = RegisterIterator(regType);
992         // This assumes only integer and floating point register types
993         // if we target a processor with additional register types,
994         // this would have to change
995         if (useFloatReg(regType))
996         {
997             // This just happens to work for both double & float
998             endIter.currentRegNum = REG_NEXT(REG_FP_LAST);
999         }
1000         else
1001         {
1002             endIter.currentRegNum = REG_NEXT(REG_INT_LAST);
1003         }
1004         return endIter;
1005     }
1006
1007 public:
1008     void operator++(int dummy) // int dummy is c++ for "this is postfix ++"
1009     {
1010         currentRegNum = REG_NEXT(currentRegNum);
1011 #ifdef _TARGET_ARM_
1012         if (regType == TYP_DOUBLE)
1013             currentRegNum = REG_NEXT(currentRegNum);
1014 #endif
1015     }
1016     void operator++() // prefix operator++
1017     {
1018         currentRegNum = REG_NEXT(currentRegNum);
1019 #ifdef _TARGET_ARM_
1020         if (regType == TYP_DOUBLE)
1021             currentRegNum = REG_NEXT(currentRegNum);
1022 #endif
1023     }
1024     regNumber operator*()
1025     {
1026         return currentRegNum;
1027     }
1028     bool operator!=(const RegisterIterator& other)
1029     {
1030         return other.currentRegNum != currentRegNum;
1031     }
1032
1033 private:
1034     regNumber    currentRegNum;
1035     RegisterType regType;
1036 };
1037
1038 class Registers
1039 {
1040 public:
1041     friend class RegisterIterator;
1042     RegisterType type;
1043     Registers(RegisterType t)
1044     {
1045         type = t;
1046     }
1047     RegisterIterator begin()
1048     {
1049         return RegisterIterator::Begin(type);
1050     }
1051     RegisterIterator end()
1052     {
1053         return RegisterIterator::End(type);
1054     }
1055 };
1056
1057 #ifdef DEBUG
1058 void LinearScan::dumpVarToRegMap(VarToRegMap map)
1059 {
1060     bool anyPrinted = false;
1061     for (unsigned varIndex = 0; varIndex < compiler->lvaTrackedCount; varIndex++)
1062     {
1063         unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
1064         if (map[varIndex] != REG_STK)
1065         {
1066             printf("V%02u=%s ", varNum, getRegName(map[varIndex]));
1067             anyPrinted = true;
1068         }
1069     }
1070     if (!anyPrinted)
1071     {
1072         printf("none");
1073     }
1074     printf("\n");
1075 }
1076
1077 void LinearScan::dumpInVarToRegMap(BasicBlock* block)
1078 {
1079     printf("Var=Reg beg of BB%02u: ", block->bbNum);
1080     VarToRegMap map = getInVarToRegMap(block->bbNum);
1081     dumpVarToRegMap(map);
1082 }
1083
1084 void LinearScan::dumpOutVarToRegMap(BasicBlock* block)
1085 {
1086     printf("Var=Reg end of BB%02u: ", block->bbNum);
1087     VarToRegMap map = getOutVarToRegMap(block->bbNum);
1088     dumpVarToRegMap(map);
1089 }
1090
1091 #endif // DEBUG
1092
1093 LinearScanInterface* getLinearScanAllocator(Compiler* comp)
1094 {
1095     return new (comp, CMK_LSRA) LinearScan(comp);
1096 }
1097
1098 //------------------------------------------------------------------------
1099 // LSRA constructor
1100 //
1101 // Arguments:
1102 //    theCompiler
1103 //
1104 // Notes:
1105 //    The constructor takes care of initializing the data structures that are used
1106 //    during Lowering, including (in DEBUG) getting the stress environment variables,
1107 //    as they may affect the block ordering.
1108
1109 LinearScan::LinearScan(Compiler* theCompiler)
1110     : compiler(theCompiler)
1111 #if MEASURE_MEM_ALLOC
1112     , lsraIAllocator(nullptr)
1113 #endif // MEASURE_MEM_ALLOC
1114     , intervals(LinearScanMemoryAllocatorInterval(theCompiler))
1115     , refPositions(LinearScanMemoryAllocatorRefPosition(theCompiler))
1116 {
1117 #ifdef DEBUG
1118     maxNodeLocation   = 0;
1119     activeRefPosition = nullptr;
1120
1121     // Get the value of the environment variable that controls stress for register allocation
1122     lsraStressMask = JitConfig.JitStressRegs();
1123 #if 0
1124 #ifdef DEBUG
1125     if (lsraStressMask != 0)
1126     {
1127         // The code in this #if can be used to debug JitStressRegs issues according to
1128         // method hash.  To use, simply set environment variables JitStressRegsHashLo and JitStressRegsHashHi
1129         unsigned methHash = compiler->info.compMethodHash();
1130         char* lostr = getenv("JitStressRegsHashLo");
1131         unsigned methHashLo = 0;
1132         bool dump = false;
1133         if (lostr != nullptr)
1134         {
1135             sscanf_s(lostr, "%x", &methHashLo);
1136             dump = true;
1137         }
1138         char* histr = getenv("JitStressRegsHashHi");
1139         unsigned methHashHi = UINT32_MAX;
1140         if (histr != nullptr)
1141         {
1142             sscanf_s(histr, "%x", &methHashHi);
1143             dump = true;
1144         }
1145         if (methHash < methHashLo || methHash > methHashHi)
1146         {
1147             lsraStressMask = 0;
1148         }
1149         else if (dump == true)
1150         {
1151             printf("JitStressRegs = %x for method %s, hash = 0x%x.\n",
1152                    lsraStressMask, compiler->info.compFullName, compiler->info.compMethodHash());
1153             printf("");         // in our logic this causes a flush
1154         }
1155     }
1156 #endif // DEBUG
1157 #endif
1158
1159     dumpTerse = (JitConfig.JitDumpTerseLsra() != 0);
1160 #endif // DEBUG
1161
1162     enregisterLocalVars = ((compiler->opts.compFlags & CLFLG_REGVAR) != 0) && compiler->lvaTrackedCount > 0;
1163     availableIntRegs    = (RBM_ALLINT & ~compiler->codeGen->regSet.rsMaskResvd);
1164
1165 #if ETW_EBP_FRAMED
1166     availableIntRegs &= ~RBM_FPBASE;
1167 #endif // ETW_EBP_FRAMED
1168
1169     availableFloatRegs  = RBM_ALLFLOAT;
1170     availableDoubleRegs = RBM_ALLDOUBLE;
1171
1172 #ifdef _TARGET_AMD64_
1173     if (compiler->opts.compDbgEnC)
1174     {
1175         // On x64 when the EnC option is set, we always save exactly RBP, RSI and RDI.
1176         // RBP is not available to the register allocator, so RSI and RDI are the only
1177         // callee-save registers available.
1178         availableIntRegs &= ~RBM_CALLEE_SAVED | RBM_RSI | RBM_RDI;
1179         availableFloatRegs &= ~RBM_CALLEE_SAVED;
1180         availableDoubleRegs &= ~RBM_CALLEE_SAVED;
1181     }
1182 #endif // _TARGET_AMD64_
1183     compiler->rpFrameType           = FT_NOT_SET;
1184     compiler->rpMustCreateEBPCalled = false;
1185
1186     compiler->codeGen->intRegState.rsIsFloat   = false;
1187     compiler->codeGen->floatRegState.rsIsFloat = true;
1188
1189     // Block sequencing (the order in which we schedule).
1190     // Note that we don't initialize the bbVisitedSet until we do the first traversal
1191     // (currently during Lowering's second phase, where it sets the TreeNodeInfo).
1192     // This is so that any blocks that are added during the first phase of Lowering
1193     // are accounted for (and we don't have BasicBlockEpoch issues).
1194     blockSequencingDone   = false;
1195     blockSequence         = nullptr;
1196     blockSequenceWorkList = nullptr;
1197     curBBSeqNum           = 0;
1198     bbSeqCount            = 0;
1199
1200     // Information about each block, including predecessor blocks used for variable locations at block entry.
1201     blockInfo = nullptr;
1202
1203     // Populate the register mask table.
1204     // The first two masks in the table are allint/allfloat
1205     // The next N are the masks for each single register.
1206     // After that are the dynamically added ones.
1207     regMaskTable               = new (compiler, CMK_LSRA) regMaskTP[numMasks];
1208     regMaskTable[ALLINT_IDX]   = allRegs(TYP_INT);
1209     regMaskTable[ALLFLOAT_IDX] = allRegs(TYP_DOUBLE);
1210
1211     regNumber reg;
1212     for (reg = REG_FIRST; reg < REG_COUNT; reg = REG_NEXT(reg))
1213     {
1214         regMaskTable[FIRST_SINGLE_REG_IDX + reg - REG_FIRST] = (reg == REG_STK) ? RBM_NONE : genRegMask(reg);
1215     }
1216     nextFreeMask = FIRST_SINGLE_REG_IDX + REG_COUNT;
1217     noway_assert(nextFreeMask <= numMasks);
1218 }
1219
1220 // Return the reg mask corresponding to the given index.
1221 regMaskTP LinearScan::GetRegMaskForIndex(RegMaskIndex index)
1222 {
1223     assert(index < numMasks);
1224     assert(index < nextFreeMask);
1225     return regMaskTable[index];
1226 }
1227
1228 // Given a reg mask, return the index it corresponds to. If it is not a 'well known' reg mask,
1229 // add it at the end. This method has linear behavior in the worst cases but that is fairly rare.
1230 // Most methods never use any but the well-known masks, and when they do use more
1231 // it is only one or two more.
1232 LinearScan::RegMaskIndex LinearScan::GetIndexForRegMask(regMaskTP mask)
1233 {
1234     RegMaskIndex result;
1235     if (isSingleRegister(mask))
1236     {
1237         result = genRegNumFromMask(mask) + FIRST_SINGLE_REG_IDX;
1238     }
1239     else if (mask == allRegs(TYP_INT))
1240     {
1241         result = ALLINT_IDX;
1242     }
1243     else if (mask == allRegs(TYP_DOUBLE))
1244     {
1245         result = ALLFLOAT_IDX;
1246     }
1247     else
1248     {
1249         for (int i = FIRST_SINGLE_REG_IDX + REG_COUNT; i < nextFreeMask; i++)
1250         {
1251             if (regMaskTable[i] == mask)
1252             {
1253                 return i;
1254             }
1255         }
1256
1257         // We only allocate a fixed number of masks. Since we don't reallocate, we will throw a
1258         // noway_assert if we exceed this limit.
1259         noway_assert(nextFreeMask < numMasks);
1260
1261         regMaskTable[nextFreeMask] = mask;
1262         result                     = nextFreeMask;
1263         nextFreeMask++;
1264     }
1265     assert(mask == regMaskTable[result]);
1266     return result;
1267 }
1268
1269 // We've decided that we can't use a register during register allocation (probably FPBASE),
1270 // but we've already added it to the register masks. Go through the masks and remove it.
1271 void LinearScan::RemoveRegisterFromMasks(regNumber reg)
1272 {
1273     JITDUMP("Removing register %s from LSRA register masks\n", getRegName(reg));
1274
1275     regMaskTP mask = ~genRegMask(reg);
1276     for (int i = 0; i < nextFreeMask; i++)
1277     {
1278         regMaskTable[i] &= mask;
1279     }
1280
1281     JITDUMP("After removing register:\n");
1282     DBEXEC(VERBOSE, dspRegisterMaskTable());
1283 }
1284
1285 #ifdef DEBUG
1286 void LinearScan::dspRegisterMaskTable()
1287 {
1288     printf("LSRA register masks. Total allocated: %d, total used: %d\n", numMasks, nextFreeMask);
1289     for (int i = 0; i < nextFreeMask; i++)
1290     {
1291         printf("%2u: ", i);
1292         dspRegMask(regMaskTable[i]);
1293         printf("\n");
1294     }
1295 }
1296 #endif // DEBUG
1297
1298 //------------------------------------------------------------------------
1299 // getNextCandidateFromWorkList: Get the next candidate for block sequencing
1300 //
1301 // Arguments:
1302 //    None.
1303 //
1304 // Return Value:
1305 //    The next block to be placed in the sequence.
1306 //
1307 // Notes:
1308 //    This method currently always returns the next block in the list, and relies on having
1309 //    blocks added to the list only when they are "ready", and on the
1310 //    addToBlockSequenceWorkList() method to insert them in the proper order.
1311 //    However, a block may be in the list and already selected, if it was subsequently
1312 //    encountered as both a flow and layout successor of the most recently selected
1313 //    block.
1314
1315 BasicBlock* LinearScan::getNextCandidateFromWorkList()
1316 {
1317     BasicBlockList* nextWorkList = nullptr;
1318     for (BasicBlockList* workList = blockSequenceWorkList; workList != nullptr; workList = nextWorkList)
1319     {
1320         nextWorkList          = workList->next;
1321         BasicBlock* candBlock = workList->block;
1322         removeFromBlockSequenceWorkList(workList, nullptr);
1323         if (!isBlockVisited(candBlock))
1324         {
1325             return candBlock;
1326         }
1327     }
1328     return nullptr;
1329 }
1330
1331 //------------------------------------------------------------------------
1332 // setBlockSequence:Determine the block order for register allocation.
1333 //
1334 // Arguments:
1335 //    None
1336 //
1337 // Return Value:
1338 //    None
1339 //
1340 // Notes:
1341 //    On return, the blockSequence array contains the blocks, in the order in which they
1342 //    will be allocated.
1343 //    This method clears the bbVisitedSet on LinearScan, and when it returns the set
1344 //    contains all the bbNums for the block.
1345 //    This requires a traversal of the BasicBlocks, and could potentially be
1346 //    combined with the first traversal (currently the one in Lowering that sets the
1347 //    TreeNodeInfo).
1348
1349 void LinearScan::setBlockSequence()
1350 {
1351     // Reset the "visited" flag on each block.
1352     compiler->EnsureBasicBlockEpoch();
1353     bbVisitedSet = BlockSetOps::MakeEmpty(compiler);
1354     BlockSet readySet(BlockSetOps::MakeEmpty(compiler));
1355     BlockSet predSet(BlockSetOps::MakeEmpty(compiler));
1356
1357     assert(blockSequence == nullptr && bbSeqCount == 0);
1358     blockSequence            = new (compiler, CMK_LSRA) BasicBlock*[compiler->fgBBcount];
1359     bbNumMaxBeforeResolution = compiler->fgBBNumMax;
1360     blockInfo                = new (compiler, CMK_LSRA) LsraBlockInfo[bbNumMaxBeforeResolution + 1];
1361
1362     assert(blockSequenceWorkList == nullptr);
1363
1364     bool addedInternalBlocks = false;
1365     verifiedAllBBs           = false;
1366     hasCriticalEdges         = false;
1367     BasicBlock* nextBlock;
1368     for (BasicBlock* block = compiler->fgFirstBB; block != nullptr; block = nextBlock)
1369     {
1370         blockSequence[bbSeqCount] = block;
1371         markBlockVisited(block);
1372         bbSeqCount++;
1373         nextBlock = nullptr;
1374
1375         // Initialize the blockInfo.
1376         // predBBNum will be set later.  0 is never used as a bbNum.
1377         blockInfo[block->bbNum].predBBNum = 0;
1378         // We check for critical edges below, but initialize to false.
1379         blockInfo[block->bbNum].hasCriticalInEdge  = false;
1380         blockInfo[block->bbNum].hasCriticalOutEdge = false;
1381         blockInfo[block->bbNum].weight             = block->bbWeight;
1382
1383 #if TRACK_LSRA_STATS
1384         blockInfo[block->bbNum].spillCount         = 0;
1385         blockInfo[block->bbNum].copyRegCount       = 0;
1386         blockInfo[block->bbNum].resolutionMovCount = 0;
1387         blockInfo[block->bbNum].splitEdgeCount     = 0;
1388 #endif // TRACK_LSRA_STATS
1389
1390         if (block->GetUniquePred(compiler) == nullptr)
1391         {
1392             for (flowList* pred = block->bbPreds; pred != nullptr; pred = pred->flNext)
1393             {
1394                 BasicBlock* predBlock = pred->flBlock;
1395                 if (predBlock->NumSucc(compiler) > 1)
1396                 {
1397                     blockInfo[block->bbNum].hasCriticalInEdge = true;
1398                     hasCriticalEdges                          = true;
1399                     break;
1400                 }
1401                 else if (predBlock->bbJumpKind == BBJ_SWITCH)
1402                 {
1403                     assert(!"Switch with single successor");
1404                 }
1405             }
1406         }
1407
1408         // Determine which block to schedule next.
1409
1410         // First, update the NORMAL successors of the current block, adding them to the worklist
1411         // according to the desired order.  We will handle the EH successors below.
1412         bool checkForCriticalOutEdge = (block->NumSucc(compiler) > 1);
1413         if (!checkForCriticalOutEdge && block->bbJumpKind == BBJ_SWITCH)
1414         {
1415             assert(!"Switch with single successor");
1416         }
1417
1418         const unsigned numSuccs = block->NumSucc(compiler);
1419         for (unsigned succIndex = 0; succIndex < numSuccs; succIndex++)
1420         {
1421             BasicBlock* succ = block->GetSucc(succIndex, compiler);
1422             if (checkForCriticalOutEdge && succ->GetUniquePred(compiler) == nullptr)
1423             {
1424                 blockInfo[block->bbNum].hasCriticalOutEdge = true;
1425                 hasCriticalEdges                           = true;
1426                 // We can stop checking now.
1427                 checkForCriticalOutEdge = false;
1428             }
1429
1430             if (isTraversalLayoutOrder() || isBlockVisited(succ))
1431             {
1432                 continue;
1433             }
1434
1435             // We've now seen a predecessor, so add it to the work list and the "readySet".
1436             // It will be inserted in the worklist according to the specified traversal order
1437             // (i.e. pred-first or random, since layout order is handled above).
1438             if (!BlockSetOps::IsMember(compiler, readySet, succ->bbNum))
1439             {
1440                 addToBlockSequenceWorkList(readySet, succ, predSet);
1441                 BlockSetOps::AddElemD(compiler, readySet, succ->bbNum);
1442             }
1443         }
1444
1445         // For layout order, simply use bbNext
1446         if (isTraversalLayoutOrder())
1447         {
1448             nextBlock = block->bbNext;
1449             continue;
1450         }
1451
1452         while (nextBlock == nullptr)
1453         {
1454             nextBlock = getNextCandidateFromWorkList();
1455
1456             // TODO-Throughput: We would like to bypass this traversal if we know we've handled all
1457             // the blocks - but fgBBcount does not appear to be updated when blocks are removed.
1458             if (nextBlock == nullptr /* && bbSeqCount != compiler->fgBBcount*/ && !verifiedAllBBs)
1459             {
1460                 // If we don't encounter all blocks by traversing the regular sucessor links, do a full
1461                 // traversal of all the blocks, and add them in layout order.
1462                 // This may include:
1463                 //   - internal-only blocks (in the fgAddCodeList) which may not be in the flow graph
1464                 //     (these are not even in the bbNext links).
1465                 //   - blocks that have become unreachable due to optimizations, but that are strongly
1466                 //     connected (these are not removed)
1467                 //   - EH blocks
1468
1469                 for (Compiler::AddCodeDsc* desc = compiler->fgAddCodeList; desc != nullptr; desc = desc->acdNext)
1470                 {
1471                     if (!isBlockVisited(block))
1472                     {
1473                         addToBlockSequenceWorkList(readySet, block, predSet);
1474                         BlockSetOps::AddElemD(compiler, readySet, block->bbNum);
1475                     }
1476                 }
1477
1478                 for (BasicBlock* block = compiler->fgFirstBB; block; block = block->bbNext)
1479                 {
1480                     if (!isBlockVisited(block))
1481                     {
1482                         addToBlockSequenceWorkList(readySet, block, predSet);
1483                         BlockSetOps::AddElemD(compiler, readySet, block->bbNum);
1484                     }
1485                 }
1486                 verifiedAllBBs = true;
1487             }
1488             else
1489             {
1490                 break;
1491             }
1492         }
1493     }
1494     blockSequencingDone = true;
1495
1496 #ifdef DEBUG
1497     // Make sure that we've visited all the blocks.
1498     for (BasicBlock* block = compiler->fgFirstBB; block != nullptr; block = block->bbNext)
1499     {
1500         assert(isBlockVisited(block));
1501     }
1502
1503     JITDUMP("LSRA Block Sequence: ");
1504     int i = 1;
1505     for (BasicBlock *block = startBlockSequence(); block != nullptr; ++i, block = moveToNextBlock())
1506     {
1507         JITDUMP("BB%02u", block->bbNum);
1508
1509         if (block->isMaxBBWeight())
1510         {
1511             JITDUMP("(MAX) ");
1512         }
1513         else
1514         {
1515             JITDUMP("(%6s) ", refCntWtd2str(block->getBBWeight(compiler)));
1516         }
1517
1518         if (i % 10 == 0)
1519         {
1520             JITDUMP("\n                     ");
1521         }
1522     }
1523     JITDUMP("\n\n");
1524 #endif
1525 }
1526
1527 //------------------------------------------------------------------------
1528 // compareBlocksForSequencing: Compare two basic blocks for sequencing order.
1529 //
1530 // Arguments:
1531 //    block1            - the first block for comparison
1532 //    block2            - the second block for comparison
1533 //    useBlockWeights   - whether to use block weights for comparison
1534 //
1535 // Return Value:
1536 //    -1 if block1 is preferred.
1537 //     0 if the blocks are equivalent.
1538 //     1 if block2 is preferred.
1539 //
1540 // Notes:
1541 //    See addToBlockSequenceWorkList.
1542 int LinearScan::compareBlocksForSequencing(BasicBlock* block1, BasicBlock* block2, bool useBlockWeights)
1543 {
1544     if (useBlockWeights)
1545     {
1546         unsigned weight1 = block1->getBBWeight(compiler);
1547         unsigned weight2 = block2->getBBWeight(compiler);
1548
1549         if (weight1 > weight2)
1550         {
1551             return -1;
1552         }
1553         else if (weight1 < weight2)
1554         {
1555             return 1;
1556         }
1557     }
1558
1559     // If weights are the same prefer LOWER bbnum
1560     if (block1->bbNum < block2->bbNum)
1561     {
1562         return -1;
1563     }
1564     else if (block1->bbNum == block2->bbNum)
1565     {
1566         return 0;
1567     }
1568     else
1569     {
1570         return 1;
1571     }
1572 }
1573
1574 //------------------------------------------------------------------------
1575 // addToBlockSequenceWorkList: Add a BasicBlock to the work list for sequencing.
1576 //
1577 // Arguments:
1578 //    sequencedBlockSet - the set of blocks that are already sequenced
1579 //    block             - the new block to be added
1580 //    predSet           - the buffer to save predecessors set. A block set allocated by the caller used here as a
1581 //    temporary block set for constructing a predecessor set. Allocated by the caller to avoid reallocating a new block
1582 //    set with every call to this function
1583 //
1584 // Return Value:
1585 //    None.
1586 //
1587 // Notes:
1588 //    The first block in the list will be the next one to be sequenced, as soon
1589 //    as we encounter a block whose successors have all been sequenced, in pred-first
1590 //    order, or the very next block if we are traversing in random order (once implemented).
1591 //    This method uses a comparison method to determine the order in which to place
1592 //    the blocks in the list.  This method queries whether all predecessors of the
1593 //    block are sequenced at the time it is added to the list and if so uses block weights
1594 //    for inserting the block.  A block is never inserted ahead of its predecessors.
1595 //    A block at the time of insertion may not have all its predecessors sequenced, in
1596 //    which case it will be sequenced based on its block number. Once a block is inserted,
1597 //    its priority\order will not be changed later once its remaining predecessors are
1598 //    sequenced.  This would mean that work list may not be sorted entirely based on
1599 //    block weights alone.
1600 //
1601 //    Note also that, when random traversal order is implemented, this method
1602 //    should insert the blocks into the list in random order, so that we can always
1603 //    simply select the first block in the list.
1604 void LinearScan::addToBlockSequenceWorkList(BlockSet sequencedBlockSet, BasicBlock* block, BlockSet& predSet)
1605 {
1606     // The block that is being added is not already sequenced
1607     assert(!BlockSetOps::IsMember(compiler, sequencedBlockSet, block->bbNum));
1608
1609     // Get predSet of block
1610     BlockSetOps::ClearD(compiler, predSet);
1611     flowList* pred;
1612     for (pred = block->bbPreds; pred != nullptr; pred = pred->flNext)
1613     {
1614         BlockSetOps::AddElemD(compiler, predSet, pred->flBlock->bbNum);
1615     }
1616
1617     // If either a rarely run block or all its preds are already sequenced, use block's weight to sequence
1618     bool useBlockWeight = block->isRunRarely() || BlockSetOps::IsSubset(compiler, sequencedBlockSet, predSet);
1619
1620     BasicBlockList* prevNode = nullptr;
1621     BasicBlockList* nextNode = blockSequenceWorkList;
1622
1623     while (nextNode != nullptr)
1624     {
1625         int seqResult;
1626
1627         if (nextNode->block->isRunRarely())
1628         {
1629             // If the block that is yet to be sequenced is a rarely run block, always use block weights for sequencing
1630             seqResult = compareBlocksForSequencing(nextNode->block, block, true);
1631         }
1632         else if (BlockSetOps::IsMember(compiler, predSet, nextNode->block->bbNum))
1633         {
1634             // always prefer unsequenced pred blocks
1635             seqResult = -1;
1636         }
1637         else
1638         {
1639             seqResult = compareBlocksForSequencing(nextNode->block, block, useBlockWeight);
1640         }
1641
1642         if (seqResult > 0)
1643         {
1644             break;
1645         }
1646
1647         prevNode = nextNode;
1648         nextNode = nextNode->next;
1649     }
1650
1651     BasicBlockList* newListNode = new (compiler, CMK_LSRA) BasicBlockList(block, nextNode);
1652     if (prevNode == nullptr)
1653     {
1654         blockSequenceWorkList = newListNode;
1655     }
1656     else
1657     {
1658         prevNode->next = newListNode;
1659     }
1660 }
1661
1662 void LinearScan::removeFromBlockSequenceWorkList(BasicBlockList* listNode, BasicBlockList* prevNode)
1663 {
1664     if (listNode == blockSequenceWorkList)
1665     {
1666         assert(prevNode == nullptr);
1667         blockSequenceWorkList = listNode->next;
1668     }
1669     else
1670     {
1671         assert(prevNode != nullptr && prevNode->next == listNode);
1672         prevNode->next = listNode->next;
1673     }
1674     // TODO-Cleanup: consider merging Compiler::BlockListNode and BasicBlockList
1675     // compiler->FreeBlockListNode(listNode);
1676 }
1677
1678 // Initialize the block order for allocation (called each time a new traversal begins).
1679 BasicBlock* LinearScan::startBlockSequence()
1680 {
1681     if (!blockSequencingDone)
1682     {
1683         setBlockSequence();
1684     }
1685     BasicBlock* curBB = compiler->fgFirstBB;
1686     curBBSeqNum       = 0;
1687     curBBNum          = curBB->bbNum;
1688     clearVisitedBlocks();
1689     assert(blockSequence[0] == compiler->fgFirstBB);
1690     markBlockVisited(curBB);
1691     return curBB;
1692 }
1693
1694 //------------------------------------------------------------------------
1695 // moveToNextBlock: Move to the next block in order for allocation or resolution.
1696 //
1697 // Arguments:
1698 //    None
1699 //
1700 // Return Value:
1701 //    The next block.
1702 //
1703 // Notes:
1704 //    This method is used when the next block is actually going to be handled.
1705 //    It changes curBBNum.
1706
1707 BasicBlock* LinearScan::moveToNextBlock()
1708 {
1709     BasicBlock* nextBlock = getNextBlock();
1710     curBBSeqNum++;
1711     if (nextBlock != nullptr)
1712     {
1713         curBBNum = nextBlock->bbNum;
1714     }
1715     return nextBlock;
1716 }
1717
1718 //------------------------------------------------------------------------
1719 // getNextBlock: Get the next block in order for allocation or resolution.
1720 //
1721 // Arguments:
1722 //    None
1723 //
1724 // Return Value:
1725 //    The next block.
1726 //
1727 // Notes:
1728 //    This method does not actually change the current block - it is used simply
1729 //    to determine which block will be next.
1730
1731 BasicBlock* LinearScan::getNextBlock()
1732 {
1733     assert(blockSequencingDone);
1734     unsigned int nextBBSeqNum = curBBSeqNum + 1;
1735     if (nextBBSeqNum < bbSeqCount)
1736     {
1737         return blockSequence[nextBBSeqNum];
1738     }
1739     return nullptr;
1740 }
1741
1742 //------------------------------------------------------------------------
1743 // doLinearScan: The main method for register allocation.
1744 //
1745 // Arguments:
1746 //    None
1747 //
1748 // Return Value:
1749 //    None.
1750 //
1751 // Assumptions:
1752 //    Lowering must have set the NodeInfo (gtLsraInfo) on each node to communicate
1753 //    the register requirements.
1754
1755 void LinearScan::doLinearScan()
1756 {
1757     unsigned lsraBlockEpoch = compiler->GetCurBasicBlockEpoch();
1758
1759     splitBBNumToTargetBBNumMap = nullptr;
1760
1761     // This is complicated by the fact that physical registers have refs associated
1762     // with locations where they are killed (e.g. calls), but we don't want to
1763     // count these as being touched.
1764
1765     compiler->codeGen->regSet.rsClearRegsModified();
1766
1767     initMaxSpill();
1768     buildIntervals();
1769     DBEXEC(VERBOSE, TupleStyleDump(LSRA_DUMP_REFPOS));
1770     compiler->EndPhase(PHASE_LINEAR_SCAN_BUILD);
1771
1772     DBEXEC(VERBOSE, lsraDumpIntervals("after buildIntervals"));
1773
1774     clearVisitedBlocks();
1775     initVarRegMaps();
1776     allocateRegisters();
1777     compiler->EndPhase(PHASE_LINEAR_SCAN_ALLOC);
1778     resolveRegisters();
1779     compiler->EndPhase(PHASE_LINEAR_SCAN_RESOLVE);
1780
1781 #if TRACK_LSRA_STATS
1782     if ((JitConfig.DisplayLsraStats() != 0)
1783 #ifdef DEBUG
1784         || VERBOSE
1785 #endif
1786         )
1787     {
1788         dumpLsraStats(jitstdout);
1789     }
1790 #endif // TRACK_LSRA_STATS
1791
1792     DBEXEC(VERBOSE, TupleStyleDump(LSRA_DUMP_POST));
1793
1794     compiler->compLSRADone = true;
1795     noway_assert(lsraBlockEpoch = compiler->GetCurBasicBlockEpoch());
1796 }
1797
1798 //------------------------------------------------------------------------
1799 // recordVarLocationsAtStartOfBB: Update live-in LclVarDscs with the appropriate
1800 //    register location at the start of a block, during codegen.
1801 //
1802 // Arguments:
1803 //    bb - the block for which code is about to be generated.
1804 //
1805 // Return Value:
1806 //    None.
1807 //
1808 // Assumptions:
1809 //    CodeGen will take care of updating the reg masks and the current var liveness,
1810 //    after calling this method.
1811 //    This is because we need to kill off the dead registers before setting the newly live ones.
1812
1813 void LinearScan::recordVarLocationsAtStartOfBB(BasicBlock* bb)
1814 {
1815     if (!enregisterLocalVars)
1816     {
1817         return;
1818     }
1819     JITDUMP("Recording Var Locations at start of BB%02u\n", bb->bbNum);
1820     VarToRegMap map   = getInVarToRegMap(bb->bbNum);
1821     unsigned    count = 0;
1822
1823     VarSetOps::AssignNoCopy(compiler, currentLiveVars,
1824                             VarSetOps::Intersection(compiler, registerCandidateVars, bb->bbLiveIn));
1825     VarSetOps::Iter iter(compiler, currentLiveVars);
1826     unsigned        varIndex = 0;
1827     while (iter.NextElem(&varIndex))
1828     {
1829         unsigned   varNum = compiler->lvaTrackedToVarNum[varIndex];
1830         LclVarDsc* varDsc = &(compiler->lvaTable[varNum]);
1831         regNumber  regNum = getVarReg(map, varIndex);
1832
1833         regNumber oldRegNum = varDsc->lvRegNum;
1834         regNumber newRegNum = regNum;
1835
1836         if (oldRegNum != newRegNum)
1837         {
1838             JITDUMP("  V%02u(%s->%s)", varNum, compiler->compRegVarName(oldRegNum),
1839                     compiler->compRegVarName(newRegNum));
1840             varDsc->lvRegNum = newRegNum;
1841             count++;
1842         }
1843         else if (newRegNum != REG_STK)
1844         {
1845             JITDUMP("  V%02u(%s)", varNum, compiler->compRegVarName(newRegNum));
1846             count++;
1847         }
1848     }
1849
1850     if (count == 0)
1851     {
1852         JITDUMP("  <none>\n");
1853     }
1854
1855     JITDUMP("\n");
1856 }
1857
1858 void Interval::setLocalNumber(Compiler* compiler, unsigned lclNum, LinearScan* linScan)
1859 {
1860     LclVarDsc* varDsc = &compiler->lvaTable[lclNum];
1861     assert(varDsc->lvTracked);
1862     assert(varDsc->lvVarIndex < compiler->lvaTrackedCount);
1863
1864     linScan->localVarIntervals[varDsc->lvVarIndex] = this;
1865
1866     assert(linScan->getIntervalForLocalVar(varDsc->lvVarIndex) == this);
1867     this->isLocalVar = true;
1868     this->varNum     = lclNum;
1869 }
1870
1871 // identify the candidates which we are not going to enregister due to
1872 // being used in EH in a way we don't want to deal with
1873 // this logic cloned from fgInterBlockLocalVarLiveness
1874 void LinearScan::identifyCandidatesExceptionDataflow()
1875 {
1876     VARSET_TP   exceptVars(VarSetOps::MakeEmpty(compiler));
1877     VARSET_TP   filterVars(VarSetOps::MakeEmpty(compiler));
1878     VARSET_TP   finallyVars(VarSetOps::MakeEmpty(compiler));
1879     BasicBlock* block;
1880
1881     foreach_block(compiler, block)
1882     {
1883         if (block->bbCatchTyp != BBCT_NONE)
1884         {
1885             // live on entry to handler
1886             VarSetOps::UnionD(compiler, exceptVars, block->bbLiveIn);
1887         }
1888
1889         if (block->bbJumpKind == BBJ_EHFILTERRET)
1890         {
1891             // live on exit from filter
1892             VarSetOps::UnionD(compiler, filterVars, block->bbLiveOut);
1893         }
1894         else if (block->bbJumpKind == BBJ_EHFINALLYRET)
1895         {
1896             // live on exit from finally
1897             VarSetOps::UnionD(compiler, finallyVars, block->bbLiveOut);
1898         }
1899 #if FEATURE_EH_FUNCLETS
1900         // Funclets are called and returned from, as such we can only count on the frame
1901         // pointer being restored, and thus everything live in or live out must be on the
1902         // stack
1903         if (block->bbFlags & BBF_FUNCLET_BEG)
1904         {
1905             VarSetOps::UnionD(compiler, exceptVars, block->bbLiveIn);
1906         }
1907         if ((block->bbJumpKind == BBJ_EHFINALLYRET) || (block->bbJumpKind == BBJ_EHFILTERRET) ||
1908             (block->bbJumpKind == BBJ_EHCATCHRET))
1909         {
1910             VarSetOps::UnionD(compiler, exceptVars, block->bbLiveOut);
1911         }
1912 #endif // FEATURE_EH_FUNCLETS
1913     }
1914
1915     // slam them all together (there was really no need to use more than 2 bitvectors here)
1916     VarSetOps::UnionD(compiler, exceptVars, filterVars);
1917     VarSetOps::UnionD(compiler, exceptVars, finallyVars);
1918
1919     /* Mark all pointer variables live on exit from a 'finally'
1920         block as either volatile for non-GC ref types or as
1921         'explicitly initialized' (volatile and must-init) for GC-ref types */
1922
1923     VarSetOps::Iter iter(compiler, exceptVars);
1924     unsigned        varIndex = 0;
1925     while (iter.NextElem(&varIndex))
1926     {
1927         unsigned   varNum = compiler->lvaTrackedToVarNum[varIndex];
1928         LclVarDsc* varDsc = compiler->lvaTable + varNum;
1929
1930         compiler->lvaSetVarDoNotEnregister(varNum DEBUGARG(Compiler::DNER_LiveInOutOfHandler));
1931
1932         if (varTypeIsGC(varDsc))
1933         {
1934             if (VarSetOps::IsMember(compiler, finallyVars, varIndex) && !varDsc->lvIsParam)
1935             {
1936                 varDsc->lvMustInit = true;
1937             }
1938         }
1939     }
1940 }
1941
1942 bool LinearScan::isRegCandidate(LclVarDsc* varDsc)
1943 {
1944     // We shouldn't be called if opt settings do not permit register variables.
1945     assert((compiler->opts.compFlags & CLFLG_REGVAR) != 0);
1946
1947     if (!varDsc->lvTracked)
1948     {
1949         return false;
1950     }
1951
1952 #if !defined(_TARGET_64BIT_)
1953     if (varDsc->lvType == TYP_LONG)
1954     {
1955         // Long variables should not be register candidates.
1956         // Lowering will have split any candidate lclVars into lo/hi vars.
1957         return false;
1958     }
1959 #endif // !defined(_TARGET_64BIT)
1960
1961     // If we have JMP, reg args must be put on the stack
1962
1963     if (compiler->compJmpOpUsed && varDsc->lvIsRegArg)
1964     {
1965         return false;
1966     }
1967
1968     // Don't allocate registers for dependently promoted struct fields
1969     if (compiler->lvaIsFieldOfDependentlyPromotedStruct(varDsc))
1970     {
1971         return false;
1972     }
1973     return true;
1974 }
1975
1976 // Identify locals & compiler temps that are register candidates
1977 // TODO-Cleanup: This was cloned from Compiler::lvaSortByRefCount() in lclvars.cpp in order
1978 // to avoid perturbation, but should be merged.
1979
1980 void LinearScan::identifyCandidates()
1981 {
1982     if (enregisterLocalVars)
1983     {
1984         // Initialize the set of lclVars that are candidates for register allocation.
1985         VarSetOps::AssignNoCopy(compiler, registerCandidateVars, VarSetOps::MakeEmpty(compiler));
1986
1987         // Initialize the sets of lclVars that are used to determine whether, and for which lclVars,
1988         // we need to perform resolution across basic blocks.
1989         // Note that we can't do this in the constructor because the number of tracked lclVars may
1990         // change between the constructor and the actual allocation.
1991         VarSetOps::AssignNoCopy(compiler, resolutionCandidateVars, VarSetOps::MakeEmpty(compiler));
1992         VarSetOps::AssignNoCopy(compiler, splitOrSpilledVars, VarSetOps::MakeEmpty(compiler));
1993
1994         // We set enregisterLocalVars to true only if there are tracked lclVars
1995         assert(compiler->lvaCount != 0);
1996     }
1997     else if (compiler->lvaCount == 0)
1998     {
1999         // Nothing to do. Note that even if enregisterLocalVars is false, we still need to set the
2000         // lvLRACandidate field on all the lclVars to false if we have any.
2001         return;
2002     }
2003
2004     if (compiler->compHndBBtabCount > 0)
2005     {
2006         identifyCandidatesExceptionDataflow();
2007     }
2008
2009     unsigned   lclNum;
2010     LclVarDsc* varDsc;
2011
2012     // While we build intervals for the candidate lclVars, we will determine the floating point
2013     // lclVars, if any, to consider for callee-save register preferencing.
2014     // We maintain two sets of FP vars - those that meet the first threshold of weighted ref Count,
2015     // and those that meet the second.
2016     // The first threshold is used for methods that are heuristically deemed either to have light
2017     // fp usage, or other factors that encourage conservative use of callee-save registers, such
2018     // as multiple exits (where there might be an early exit that woudl be excessively penalized by
2019     // lots of prolog/epilog saves & restores).
2020     // The second threshold is used where there are factors deemed to make it more likely that fp
2021     // fp callee save registers will be needed, such as loops or many fp vars.
2022     // We keep two sets of vars, since we collect some of the information to determine which set to
2023     // use as we iterate over the vars.
2024     // When we are generating AVX code on non-Unix (FEATURE_PARTIAL_SIMD_CALLEE_SAVE), we maintain an
2025     // additional set of LargeVectorType vars, and there is a separate threshold defined for those.
2026     // It is assumed that if we encounter these, that we should consider this a "high use" scenario,
2027     // so we don't maintain two sets of these vars.
2028     // This is defined as thresholdLargeVectorRefCntWtd, as we are likely to use the same mechanism
2029     // for vectors on Arm64, though the actual value may differ.
2030
2031     unsigned int floatVarCount        = 0;
2032     unsigned int thresholdFPRefCntWtd = 4 * BB_UNITY_WEIGHT;
2033     unsigned int maybeFPRefCntWtd     = 2 * BB_UNITY_WEIGHT;
2034     VARSET_TP    fpMaybeCandidateVars(VarSetOps::UninitVal());
2035 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
2036     unsigned int largeVectorVarCount           = 0;
2037     unsigned int thresholdLargeVectorRefCntWtd = 4 * BB_UNITY_WEIGHT;
2038 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
2039     if (enregisterLocalVars)
2040     {
2041         VarSetOps::AssignNoCopy(compiler, fpCalleeSaveCandidateVars, VarSetOps::MakeEmpty(compiler));
2042         VarSetOps::AssignNoCopy(compiler, fpMaybeCandidateVars, VarSetOps::MakeEmpty(compiler));
2043 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
2044         VarSetOps::AssignNoCopy(compiler, largeVectorVars, VarSetOps::MakeEmpty(compiler));
2045         VarSetOps::AssignNoCopy(compiler, largeVectorCalleeSaveCandidateVars, VarSetOps::MakeEmpty(compiler));
2046 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
2047     }
2048 #if DOUBLE_ALIGN
2049     unsigned refCntStk       = 0;
2050     unsigned refCntReg       = 0;
2051     unsigned refCntWtdReg    = 0;
2052     unsigned refCntStkParam  = 0; // sum of     ref counts for all stack based parameters
2053     unsigned refCntWtdStkDbl = 0; // sum of wtd ref counts for stack based doubles
2054     doDoubleAlign            = false;
2055     bool checkDoubleAlign    = true;
2056     if (compiler->codeGen->isFramePointerRequired() || compiler->opts.MinOpts())
2057     {
2058         checkDoubleAlign = false;
2059     }
2060     else
2061     {
2062         switch (compiler->getCanDoubleAlign())
2063         {
2064             case MUST_DOUBLE_ALIGN:
2065                 doDoubleAlign    = true;
2066                 checkDoubleAlign = false;
2067                 break;
2068             case CAN_DOUBLE_ALIGN:
2069                 break;
2070             case CANT_DOUBLE_ALIGN:
2071                 doDoubleAlign    = false;
2072                 checkDoubleAlign = false;
2073                 break;
2074             default:
2075                 unreached();
2076         }
2077     }
2078 #endif // DOUBLE_ALIGN
2079
2080     // Check whether register variables are permitted.
2081     if (!enregisterLocalVars)
2082     {
2083         localVarIntervals = nullptr;
2084     }
2085     else if (compiler->lvaTrackedCount > 0)
2086     {
2087         // initialize mapping from tracked local to interval
2088         localVarIntervals = new (compiler, CMK_LSRA) Interval*[compiler->lvaTrackedCount];
2089     }
2090
2091     INTRACK_STATS(regCandidateVarCount = 0);
2092     for (lclNum = 0, varDsc = compiler->lvaTable; lclNum < compiler->lvaCount; lclNum++, varDsc++)
2093     {
2094         // Initialize all variables to REG_STK
2095         varDsc->lvRegNum = REG_STK;
2096 #ifndef _TARGET_64BIT_
2097         varDsc->lvOtherReg = REG_STK;
2098 #endif // _TARGET_64BIT_
2099
2100         if (!enregisterLocalVars)
2101         {
2102             varDsc->lvLRACandidate = false;
2103             continue;
2104         }
2105
2106 #if DOUBLE_ALIGN
2107         if (checkDoubleAlign)
2108         {
2109             if (varDsc->lvIsParam && !varDsc->lvIsRegArg)
2110             {
2111                 refCntStkParam += varDsc->lvRefCnt;
2112             }
2113             else if (!isRegCandidate(varDsc) || varDsc->lvDoNotEnregister)
2114             {
2115                 refCntStk += varDsc->lvRefCnt;
2116                 if ((varDsc->lvType == TYP_DOUBLE) ||
2117                     ((varTypeIsStruct(varDsc) && varDsc->lvStructDoubleAlign &&
2118                       (compiler->lvaGetPromotionType(varDsc) != Compiler::PROMOTION_TYPE_INDEPENDENT))))
2119                 {
2120                     refCntWtdStkDbl += varDsc->lvRefCntWtd;
2121                 }
2122             }
2123             else
2124             {
2125                 refCntReg += varDsc->lvRefCnt;
2126                 refCntWtdReg += varDsc->lvRefCntWtd;
2127             }
2128         }
2129 #endif // DOUBLE_ALIGN
2130
2131         /* Track all locals that can be enregistered */
2132
2133         if (!isRegCandidate(varDsc))
2134         {
2135             varDsc->lvLRACandidate = 0;
2136             if (varDsc->lvTracked)
2137             {
2138                 localVarIntervals[varDsc->lvVarIndex] = nullptr;
2139             }
2140             continue;
2141         }
2142
2143         assert(varDsc->lvTracked);
2144
2145         varDsc->lvLRACandidate = 1;
2146
2147         // Start with lvRegister as false - set it true only if the variable gets
2148         // the same register assignment throughout
2149         varDsc->lvRegister = false;
2150
2151         /* If the ref count is zero */
2152         if (varDsc->lvRefCnt == 0)
2153         {
2154             /* Zero ref count, make this untracked */
2155             varDsc->lvRefCntWtd    = 0;
2156             varDsc->lvLRACandidate = 0;
2157         }
2158
2159         // Variables that are address-exposed are never enregistered, or tracked.
2160         // A struct may be promoted, and a struct that fits in a register may be fully enregistered.
2161         // Pinned variables may not be tracked (a condition of the GCInfo representation)
2162         // or enregistered, on x86 -- it is believed that we can enregister pinned (more properly, "pinning")
2163         // references when using the general GC encoding.
2164
2165         if (varDsc->lvAddrExposed || !varTypeIsEnregisterableStruct(varDsc))
2166         {
2167             varDsc->lvLRACandidate = 0;
2168 #ifdef DEBUG
2169             Compiler::DoNotEnregisterReason dner = Compiler::DNER_AddrExposed;
2170             if (!varDsc->lvAddrExposed)
2171             {
2172                 dner = Compiler::DNER_IsStruct;
2173             }
2174 #endif // DEBUG
2175             compiler->lvaSetVarDoNotEnregister(lclNum DEBUGARG(dner));
2176         }
2177         else if (varDsc->lvPinned)
2178         {
2179             varDsc->lvTracked = 0;
2180 #ifdef JIT32_GCENCODER
2181             compiler->lvaSetVarDoNotEnregister(lclNum DEBUGARG(Compiler::DNER_PinningRef));
2182 #endif // JIT32_GCENCODER
2183         }
2184
2185         //  Are we not optimizing and we have exception handlers?
2186         //   if so mark all args and locals as volatile, so that they
2187         //   won't ever get enregistered.
2188         //
2189         if (compiler->opts.MinOpts() && compiler->compHndBBtabCount > 0)
2190         {
2191             compiler->lvaSetVarDoNotEnregister(lclNum DEBUGARG(Compiler::DNER_LiveInOutOfHandler));
2192         }
2193
2194         if (varDsc->lvDoNotEnregister)
2195         {
2196             varDsc->lvLRACandidate                = 0;
2197             localVarIntervals[varDsc->lvVarIndex] = nullptr;
2198             continue;
2199         }
2200
2201         var_types type = genActualType(varDsc->TypeGet());
2202
2203         switch (type)
2204         {
2205 #if CPU_HAS_FP_SUPPORT
2206             case TYP_FLOAT:
2207             case TYP_DOUBLE:
2208                 if (compiler->opts.compDbgCode)
2209                 {
2210                     varDsc->lvLRACandidate = 0;
2211                 }
2212 #ifdef ARM_SOFTFP
2213                 if (varDsc->lvIsParam && varDsc->lvIsRegArg)
2214                 {
2215                     type = (type == TYP_DOUBLE) ? TYP_LONG : TYP_INT;
2216                 }
2217 #endif // ARM_SOFTFP
2218                 break;
2219 #endif // CPU_HAS_FP_SUPPORT
2220
2221             case TYP_INT:
2222             case TYP_LONG:
2223             case TYP_REF:
2224             case TYP_BYREF:
2225                 break;
2226
2227 #ifdef FEATURE_SIMD
2228             case TYP_SIMD12:
2229             case TYP_SIMD16:
2230             case TYP_SIMD32:
2231                 if (varDsc->lvPromoted)
2232                 {
2233                     varDsc->lvLRACandidate = 0;
2234                 }
2235                 break;
2236
2237             // TODO-1stClassStructs: Move TYP_SIMD8 up with the other SIMD types, after handling the param issue
2238             // (passing & returning as TYP_LONG).
2239             case TYP_SIMD8:
2240 #endif // FEATURE_SIMD
2241
2242             case TYP_STRUCT:
2243             {
2244                 varDsc->lvLRACandidate = 0;
2245             }
2246             break;
2247
2248             case TYP_UNDEF:
2249             case TYP_UNKNOWN:
2250                 noway_assert(!"lvType not set correctly");
2251                 varDsc->lvType = TYP_INT;
2252
2253                 __fallthrough;
2254
2255             default:
2256                 varDsc->lvLRACandidate = 0;
2257         }
2258
2259         if (varDsc->lvLRACandidate)
2260         {
2261             Interval* newInt = newInterval(type);
2262             newInt->setLocalNumber(compiler, lclNum, this);
2263             VarSetOps::AddElemD(compiler, registerCandidateVars, varDsc->lvVarIndex);
2264
2265             // we will set this later when we have determined liveness
2266             varDsc->lvMustInit = false;
2267
2268             if (varDsc->lvIsStructField)
2269             {
2270                 newInt->isStructField = true;
2271             }
2272
2273             INTRACK_STATS(regCandidateVarCount++);
2274
2275             // We maintain two sets of FP vars - those that meet the first threshold of weighted ref Count,
2276             // and those that meet the second (see the definitions of thresholdFPRefCntWtd and maybeFPRefCntWtd
2277             // above).
2278             CLANG_FORMAT_COMMENT_ANCHOR;
2279
2280 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
2281             // Additionally, when we are generating AVX on non-UNIX amd64, we keep a separate set of the LargeVectorType
2282             // vars.
2283             if (varDsc->lvType == LargeVectorType)
2284             {
2285                 largeVectorVarCount++;
2286                 VarSetOps::AddElemD(compiler, largeVectorVars, varDsc->lvVarIndex);
2287                 unsigned refCntWtd = varDsc->lvRefCntWtd;
2288                 if (refCntWtd >= thresholdLargeVectorRefCntWtd)
2289                 {
2290                     VarSetOps::AddElemD(compiler, largeVectorCalleeSaveCandidateVars, varDsc->lvVarIndex);
2291                 }
2292             }
2293             else
2294 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
2295                 if (regType(type) == FloatRegisterType)
2296             {
2297                 floatVarCount++;
2298                 unsigned refCntWtd = varDsc->lvRefCntWtd;
2299                 if (varDsc->lvIsRegArg)
2300                 {
2301                     // Don't count the initial reference for register params.  In those cases,
2302                     // using a callee-save causes an extra copy.
2303                     refCntWtd -= BB_UNITY_WEIGHT;
2304                 }
2305                 if (refCntWtd >= thresholdFPRefCntWtd)
2306                 {
2307                     VarSetOps::AddElemD(compiler, fpCalleeSaveCandidateVars, varDsc->lvVarIndex);
2308                 }
2309                 else if (refCntWtd >= maybeFPRefCntWtd)
2310                 {
2311                     VarSetOps::AddElemD(compiler, fpMaybeCandidateVars, varDsc->lvVarIndex);
2312                 }
2313             }
2314         }
2315         else
2316         {
2317             localVarIntervals[varDsc->lvVarIndex] = nullptr;
2318         }
2319     }
2320
2321 #if DOUBLE_ALIGN
2322     if (checkDoubleAlign)
2323     {
2324         // TODO-CQ: Fine-tune this:
2325         // In the legacy reg predictor, this runs after allocation, and then demotes any lclVars
2326         // allocated to the frame pointer, which is probably the wrong order.
2327         // However, because it runs after allocation, it can determine the impact of demoting
2328         // the lclVars allocated to the frame pointer.
2329         // => Here, estimate of the EBP refCnt and weighted refCnt is a wild guess.
2330         //
2331         unsigned refCntEBP    = refCntReg / 8;
2332         unsigned refCntWtdEBP = refCntWtdReg / 8;
2333
2334         doDoubleAlign =
2335             compiler->shouldDoubleAlign(refCntStk, refCntEBP, refCntWtdEBP, refCntStkParam, refCntWtdStkDbl);
2336     }
2337 #endif // DOUBLE_ALIGN
2338
2339     // The factors we consider to determine which set of fp vars to use as candidates for callee save
2340     // registers current include the number of fp vars, whether there are loops, and whether there are
2341     // multiple exits.  These have been selected somewhat empirically, but there is probably room for
2342     // more tuning.
2343     CLANG_FORMAT_COMMENT_ANCHOR;
2344
2345 #ifdef DEBUG
2346     if (VERBOSE)
2347     {
2348         printf("\nFP callee save candidate vars: ");
2349         if (enregisterLocalVars && !VarSetOps::IsEmpty(compiler, fpCalleeSaveCandidateVars))
2350         {
2351             dumpConvertedVarSet(compiler, fpCalleeSaveCandidateVars);
2352             printf("\n");
2353         }
2354         else
2355         {
2356             printf("None\n\n");
2357         }
2358     }
2359 #endif
2360
2361     JITDUMP("floatVarCount = %d; hasLoops = %d, singleExit = %d\n", floatVarCount, compiler->fgHasLoops,
2362             (compiler->fgReturnBlocks == nullptr || compiler->fgReturnBlocks->next == nullptr));
2363
2364     // Determine whether to use the 2nd, more aggressive, threshold for fp callee saves.
2365     if (floatVarCount > 6 && compiler->fgHasLoops &&
2366         (compiler->fgReturnBlocks == nullptr || compiler->fgReturnBlocks->next == nullptr))
2367     {
2368         assert(enregisterLocalVars);
2369 #ifdef DEBUG
2370         if (VERBOSE)
2371         {
2372             printf("Adding additional fp callee save candidates: \n");
2373             if (!VarSetOps::IsEmpty(compiler, fpMaybeCandidateVars))
2374             {
2375                 dumpConvertedVarSet(compiler, fpMaybeCandidateVars);
2376                 printf("\n");
2377             }
2378             else
2379             {
2380                 printf("None\n\n");
2381             }
2382         }
2383 #endif
2384         VarSetOps::UnionD(compiler, fpCalleeSaveCandidateVars, fpMaybeCandidateVars);
2385     }
2386
2387 #ifdef _TARGET_ARM_
2388 #ifdef DEBUG
2389     if (VERBOSE)
2390     {
2391         // Frame layout is only pre-computed for ARM
2392         printf("\nlvaTable after IdentifyCandidates\n");
2393         compiler->lvaTableDump();
2394     }
2395 #endif // DEBUG
2396 #endif // _TARGET_ARM_
2397 }
2398
2399 // TODO-Throughput: This mapping can surely be more efficiently done
2400 void LinearScan::initVarRegMaps()
2401 {
2402     if (!enregisterLocalVars)
2403     {
2404         inVarToRegMaps  = nullptr;
2405         outVarToRegMaps = nullptr;
2406         return;
2407     }
2408     assert(compiler->lvaTrackedFixed); // We should have already set this to prevent us from adding any new tracked
2409                                        // variables.
2410
2411     // The compiler memory allocator requires that the allocation be an
2412     // even multiple of int-sized objects
2413     unsigned int varCount = compiler->lvaTrackedCount;
2414     regMapCount           = (unsigned int)roundUp(varCount, sizeof(int));
2415
2416     // Not sure why blocks aren't numbered from zero, but they don't appear to be.
2417     // So, if we want to index by bbNum we have to know the maximum value.
2418     unsigned int bbCount = compiler->fgBBNumMax + 1;
2419
2420     inVarToRegMaps  = new (compiler, CMK_LSRA) regNumberSmall*[bbCount];
2421     outVarToRegMaps = new (compiler, CMK_LSRA) regNumberSmall*[bbCount];
2422
2423     if (varCount > 0)
2424     {
2425         // This VarToRegMap is used during the resolution of critical edges.
2426         sharedCriticalVarToRegMap = new (compiler, CMK_LSRA) regNumberSmall[regMapCount];
2427
2428         for (unsigned int i = 0; i < bbCount; i++)
2429         {
2430             VarToRegMap inVarToRegMap  = new (compiler, CMK_LSRA) regNumberSmall[regMapCount];
2431             VarToRegMap outVarToRegMap = new (compiler, CMK_LSRA) regNumberSmall[regMapCount];
2432
2433             for (unsigned int j = 0; j < regMapCount; j++)
2434             {
2435                 inVarToRegMap[j]  = REG_STK;
2436                 outVarToRegMap[j] = REG_STK;
2437             }
2438             inVarToRegMaps[i]  = inVarToRegMap;
2439             outVarToRegMaps[i] = outVarToRegMap;
2440         }
2441     }
2442     else
2443     {
2444         sharedCriticalVarToRegMap = nullptr;
2445         for (unsigned int i = 0; i < bbCount; i++)
2446         {
2447             inVarToRegMaps[i]  = nullptr;
2448             outVarToRegMaps[i] = nullptr;
2449         }
2450     }
2451 }
2452
2453 void LinearScan::setInVarRegForBB(unsigned int bbNum, unsigned int varNum, regNumber reg)
2454 {
2455     assert(enregisterLocalVars);
2456     assert(reg < UCHAR_MAX && varNum < compiler->lvaCount);
2457     inVarToRegMaps[bbNum][compiler->lvaTable[varNum].lvVarIndex] = (regNumberSmall)reg;
2458 }
2459
2460 void LinearScan::setOutVarRegForBB(unsigned int bbNum, unsigned int varNum, regNumber reg)
2461 {
2462     assert(enregisterLocalVars);
2463     assert(reg < UCHAR_MAX && varNum < compiler->lvaCount);
2464     outVarToRegMaps[bbNum][compiler->lvaTable[varNum].lvVarIndex] = (regNumberSmall)reg;
2465 }
2466
2467 LinearScan::SplitEdgeInfo LinearScan::getSplitEdgeInfo(unsigned int bbNum)
2468 {
2469     assert(enregisterLocalVars);
2470     SplitEdgeInfo splitEdgeInfo;
2471     assert(bbNum <= compiler->fgBBNumMax);
2472     assert(bbNum > bbNumMaxBeforeResolution);
2473     assert(splitBBNumToTargetBBNumMap != nullptr);
2474     splitBBNumToTargetBBNumMap->Lookup(bbNum, &splitEdgeInfo);
2475     assert(splitEdgeInfo.toBBNum <= bbNumMaxBeforeResolution);
2476     assert(splitEdgeInfo.fromBBNum <= bbNumMaxBeforeResolution);
2477     return splitEdgeInfo;
2478 }
2479
2480 VarToRegMap LinearScan::getInVarToRegMap(unsigned int bbNum)
2481 {
2482     assert(enregisterLocalVars);
2483     assert(bbNum <= compiler->fgBBNumMax);
2484     // For the blocks inserted to split critical edges, the inVarToRegMap is
2485     // equal to the outVarToRegMap at the "from" block.
2486     if (bbNum > bbNumMaxBeforeResolution)
2487     {
2488         SplitEdgeInfo splitEdgeInfo = getSplitEdgeInfo(bbNum);
2489         unsigned      fromBBNum     = splitEdgeInfo.fromBBNum;
2490         if (fromBBNum == 0)
2491         {
2492             assert(splitEdgeInfo.toBBNum != 0);
2493             return inVarToRegMaps[splitEdgeInfo.toBBNum];
2494         }
2495         else
2496         {
2497             return outVarToRegMaps[fromBBNum];
2498         }
2499     }
2500
2501     return inVarToRegMaps[bbNum];
2502 }
2503
2504 VarToRegMap LinearScan::getOutVarToRegMap(unsigned int bbNum)
2505 {
2506     assert(enregisterLocalVars);
2507     assert(bbNum <= compiler->fgBBNumMax);
2508     // For the blocks inserted to split critical edges, the outVarToRegMap is
2509     // equal to the inVarToRegMap at the target.
2510     if (bbNum > bbNumMaxBeforeResolution)
2511     {
2512         // If this is an empty block, its in and out maps are both the same.
2513         // We identify this case by setting fromBBNum or toBBNum to 0, and using only the other.
2514         SplitEdgeInfo splitEdgeInfo = getSplitEdgeInfo(bbNum);
2515         unsigned      toBBNum       = splitEdgeInfo.toBBNum;
2516         if (toBBNum == 0)
2517         {
2518             assert(splitEdgeInfo.fromBBNum != 0);
2519             return outVarToRegMaps[splitEdgeInfo.fromBBNum];
2520         }
2521         else
2522         {
2523             return inVarToRegMaps[toBBNum];
2524         }
2525     }
2526     return outVarToRegMaps[bbNum];
2527 }
2528
2529 //------------------------------------------------------------------------
2530 // setVarReg: Set the register associated with a variable in the given 'bbVarToRegMap'.
2531 //
2532 // Arguments:
2533 //    bbVarToRegMap   - the map of interest
2534 //    trackedVarIndex - the lvVarIndex for the variable
2535 //    reg             - the register to which it is being mapped
2536 //
2537 // Return Value:
2538 //    None
2539 //
2540 void LinearScan::setVarReg(VarToRegMap bbVarToRegMap, unsigned int trackedVarIndex, regNumber reg)
2541 {
2542     assert(trackedVarIndex < compiler->lvaTrackedCount);
2543     regNumberSmall regSmall = (regNumberSmall)reg;
2544     assert((regNumber)regSmall == reg);
2545     bbVarToRegMap[trackedVarIndex] = regSmall;
2546 }
2547
2548 //------------------------------------------------------------------------
2549 // getVarReg: Get the register associated with a variable in the given 'bbVarToRegMap'.
2550 //
2551 // Arguments:
2552 //    bbVarToRegMap   - the map of interest
2553 //    trackedVarIndex - the lvVarIndex for the variable
2554 //
2555 // Return Value:
2556 //    The register to which 'trackedVarIndex' is mapped
2557 //
2558 regNumber LinearScan::getVarReg(VarToRegMap bbVarToRegMap, unsigned int trackedVarIndex)
2559 {
2560     assert(enregisterLocalVars);
2561     assert(trackedVarIndex < compiler->lvaTrackedCount);
2562     return (regNumber)bbVarToRegMap[trackedVarIndex];
2563 }
2564
2565 // Initialize the incoming VarToRegMap to the given map values (generally a predecessor of
2566 // the block)
2567 VarToRegMap LinearScan::setInVarToRegMap(unsigned int bbNum, VarToRegMap srcVarToRegMap)
2568 {
2569     assert(enregisterLocalVars);
2570     VarToRegMap inVarToRegMap = inVarToRegMaps[bbNum];
2571     memcpy(inVarToRegMap, srcVarToRegMap, (regMapCount * sizeof(regNumber)));
2572     return inVarToRegMap;
2573 }
2574
2575 // given a tree node
2576 RefType refTypeForLocalRefNode(GenTree* node)
2577 {
2578     assert(node->IsLocal());
2579
2580     // We don't support updates
2581     assert((node->gtFlags & GTF_VAR_USEASG) == 0);
2582
2583     if (node->gtFlags & GTF_VAR_DEF)
2584     {
2585         return RefTypeDef;
2586     }
2587     else
2588     {
2589         return RefTypeUse;
2590     }
2591 }
2592
2593 //------------------------------------------------------------------------
2594 // checkLastUses: Check correctness of last use flags
2595 //
2596 // Arguments:
2597 //    The block for which we are checking last uses.
2598 //
2599 // Notes:
2600 //    This does a backward walk of the RefPositions, starting from the liveOut set.
2601 //    This method was previously used to set the last uses, which were computed by
2602 //    liveness, but were not create in some cases of multiple lclVar references in the
2603 //    same tree. However, now that last uses are computed as RefPositions are created,
2604 //    that is no longer necessary, and this method is simply retained as a check.
2605 //    The exception to the check-only behavior is when LSRA_EXTEND_LIFETIMES if set via
2606 //    COMPlus_JitStressRegs. In that case, this method is required, because even though
2607 //    the RefPositions will not be marked lastUse in that case, we still need to correclty
2608 //    mark the last uses on the tree nodes, which is done by this method.
2609 //
2610 #ifdef DEBUG
2611 void LinearScan::checkLastUses(BasicBlock* block)
2612 {
2613     if (VERBOSE)
2614     {
2615         JITDUMP("\n\nCHECKING LAST USES for block %u, liveout=", block->bbNum);
2616         dumpConvertedVarSet(compiler, block->bbLiveOut);
2617         JITDUMP("\n==============================\n");
2618     }
2619
2620     unsigned keepAliveVarNum = BAD_VAR_NUM;
2621     if (compiler->lvaKeepAliveAndReportThis())
2622     {
2623         keepAliveVarNum = compiler->info.compThisArg;
2624         assert(compiler->info.compIsStatic == false);
2625     }
2626
2627     // find which uses are lastUses
2628
2629     // Work backwards starting with live out.
2630     // 'computedLive' is updated to include any exposed use (including those in this
2631     // block that we've already seen).  When we encounter a use, if it's
2632     // not in that set, then it's a last use.
2633
2634     VARSET_TP computedLive(VarSetOps::MakeCopy(compiler, block->bbLiveOut));
2635
2636     bool foundDiff          = false;
2637     auto currentRefPosition = refPositions.rbegin();
2638     while (currentRefPosition->refType != RefTypeBB)
2639     {
2640         // We should never see ParamDefs or ZeroInits within a basic block.
2641         assert(currentRefPosition->refType != RefTypeParamDef && currentRefPosition->refType != RefTypeZeroInit);
2642         if (currentRefPosition->isIntervalRef() && currentRefPosition->getInterval()->isLocalVar)
2643         {
2644             unsigned varNum   = currentRefPosition->getInterval()->varNum;
2645             unsigned varIndex = currentRefPosition->getInterval()->getVarIndex(compiler);
2646
2647             LsraLocation loc = currentRefPosition->nodeLocation;
2648
2649             // We should always have a tree node for a localVar, except for the "special" RefPositions.
2650             GenTreePtr tree = currentRefPosition->treeNode;
2651             assert(tree != nullptr || currentRefPosition->refType == RefTypeExpUse ||
2652                    currentRefPosition->refType == RefTypeDummyDef);
2653
2654             if (!VarSetOps::IsMember(compiler, computedLive, varIndex) && varNum != keepAliveVarNum)
2655             {
2656                 // There was no exposed use, so this is a "last use" (and we mark it thus even if it's a def)
2657
2658                 if (extendLifetimes())
2659                 {
2660                     // NOTE: this is a bit of a hack. When extending lifetimes, the "last use" bit will be clear.
2661                     // This bit, however, would normally be used during resolveLocalRef to set the value of
2662                     // GTF_VAR_DEATH on the node for a ref position. If this bit is not set correctly even when
2663                     // extending lifetimes, the code generator will assert as it expects to have accurate last
2664                     // use information. To avoid these asserts, set the GTF_VAR_DEATH bit here.
2665                     // Note also that extendLifetimes() is an LSRA stress mode, so it will only be true for
2666                     // Checked or Debug builds, for which this method will be executed.
2667                     if (tree != nullptr)
2668                     {
2669                         tree->gtFlags |= GTF_VAR_DEATH;
2670                     }
2671                 }
2672                 else if (!currentRefPosition->lastUse)
2673                 {
2674                     JITDUMP("missing expected last use of V%02u @%u\n", compiler->lvaTrackedToVarNum[varIndex], loc);
2675                     foundDiff = true;
2676                 }
2677                 VarSetOps::AddElemD(compiler, computedLive, varIndex);
2678             }
2679             else if (currentRefPosition->lastUse)
2680             {
2681                 JITDUMP("unexpected last use of V%02u @%u\n", compiler->lvaTrackedToVarNum[varIndex], loc);
2682                 foundDiff = true;
2683             }
2684             else if (extendLifetimes() && tree != nullptr)
2685             {
2686                 // NOTE: see the comment above re: the extendLifetimes hack.
2687                 tree->gtFlags &= ~GTF_VAR_DEATH;
2688             }
2689
2690             if (currentRefPosition->refType == RefTypeDef || currentRefPosition->refType == RefTypeDummyDef)
2691             {
2692                 VarSetOps::RemoveElemD(compiler, computedLive, varIndex);
2693             }
2694         }
2695
2696         assert(currentRefPosition != refPositions.rend());
2697         ++currentRefPosition;
2698     }
2699
2700     VARSET_TP liveInNotComputedLive(VarSetOps::Diff(compiler, block->bbLiveIn, computedLive));
2701
2702     VarSetOps::Iter liveInNotComputedLiveIter(compiler, liveInNotComputedLive);
2703     unsigned        liveInNotComputedLiveIndex = 0;
2704     while (liveInNotComputedLiveIter.NextElem(&liveInNotComputedLiveIndex))
2705     {
2706         unsigned varNum = compiler->lvaTrackedToVarNum[liveInNotComputedLiveIndex];
2707         if (compiler->lvaTable[varNum].lvLRACandidate)
2708         {
2709             JITDUMP("BB%02u: V%02u is in LiveIn set, but not computed live.\n", block->bbNum, varNum);
2710             foundDiff = true;
2711         }
2712     }
2713
2714     VarSetOps::DiffD(compiler, computedLive, block->bbLiveIn);
2715     const VARSET_TP& computedLiveNotLiveIn(computedLive); // reuse the buffer.
2716     VarSetOps::Iter  computedLiveNotLiveInIter(compiler, computedLiveNotLiveIn);
2717     unsigned         computedLiveNotLiveInIndex = 0;
2718     while (computedLiveNotLiveInIter.NextElem(&computedLiveNotLiveInIndex))
2719     {
2720         unsigned varNum = compiler->lvaTrackedToVarNum[computedLiveNotLiveInIndex];
2721         if (compiler->lvaTable[varNum].lvLRACandidate)
2722         {
2723             JITDUMP("BB%02u: V%02u is computed live, but not in LiveIn set.\n", block->bbNum, varNum);
2724             foundDiff = true;
2725         }
2726     }
2727
2728     assert(!foundDiff);
2729 }
2730 #endif // DEBUG
2731
2732 void LinearScan::addRefsForPhysRegMask(regMaskTP mask, LsraLocation currentLoc, RefType refType, bool isLastUse)
2733 {
2734     for (regNumber reg = REG_FIRST; mask; reg = REG_NEXT(reg), mask >>= 1)
2735     {
2736         if (mask & 1)
2737         {
2738             // This assumes that these are all "special" RefTypes that
2739             // don't need to be recorded on the tree (hence treeNode is nullptr)
2740             RefPosition* pos = newRefPosition(reg, currentLoc, refType, nullptr,
2741                                               genRegMask(reg)); // This MUST occupy the physical register (obviously)
2742
2743             if (isLastUse)
2744             {
2745                 pos->lastUse = true;
2746             }
2747         }
2748     }
2749 }
2750
2751 //------------------------------------------------------------------------
2752 // getKillSetForNode:   Return the registers killed by the given tree node.
2753 //
2754 // Arguments:
2755 //    compiler   - the compiler context to use
2756 //    tree       - the tree for which the kill set is needed.
2757 //
2758 // Return Value:    a register mask of the registers killed
2759 //
2760 regMaskTP LinearScan::getKillSetForNode(GenTree* tree)
2761 {
2762     regMaskTP killMask = RBM_NONE;
2763     switch (tree->OperGet())
2764     {
2765 #ifdef _TARGET_XARCH_
2766         case GT_MUL:
2767             // We use the 128-bit multiply when performing an overflow checking unsigned multiply
2768             //
2769             if (((tree->gtFlags & GTF_UNSIGNED) != 0) && tree->gtOverflowEx())
2770             {
2771                 // Both RAX and RDX are killed by the operation
2772                 killMask = RBM_RAX | RBM_RDX;
2773             }
2774             break;
2775
2776         case GT_MULHI:
2777 #if defined(_TARGET_X86_) && !defined(LEGACY_BACKEND)
2778         case GT_MUL_LONG:
2779 #endif
2780             killMask = RBM_RAX | RBM_RDX;
2781             break;
2782
2783         case GT_MOD:
2784         case GT_DIV:
2785         case GT_UMOD:
2786         case GT_UDIV:
2787             if (!varTypeIsFloating(tree->TypeGet()))
2788             {
2789                 // RDX needs to be killed early, because it must not be used as a source register
2790                 // (unlike most cases, where the kill happens AFTER the uses).  So for this kill,
2791                 // we add the RefPosition at the tree loc (where the uses are located) instead of the
2792                 // usual kill location which is the same as the defs at tree loc+1.
2793                 // Note that we don't have to add interference for the live vars, because that
2794                 // will be done below, and is not sensitive to the precise location.
2795                 LsraLocation currentLoc = tree->gtLsraInfo.loc;
2796                 assert(currentLoc != 0);
2797                 addRefsForPhysRegMask(RBM_RDX, currentLoc, RefTypeKill, true);
2798                 // Both RAX and RDX are killed by the operation
2799                 killMask = RBM_RAX | RBM_RDX;
2800             }
2801             break;
2802 #endif // _TARGET_XARCH_
2803
2804         case GT_STORE_OBJ:
2805             if (tree->OperIsCopyBlkOp())
2806             {
2807                 assert(tree->AsObj()->gtGcPtrCount != 0);
2808                 killMask = compiler->compHelperCallKillSet(CORINFO_HELP_ASSIGN_BYREF);
2809                 break;
2810             }
2811             __fallthrough;
2812
2813         case GT_STORE_BLK:
2814         case GT_STORE_DYN_BLK:
2815         {
2816             GenTreeBlk* blkNode   = tree->AsBlk();
2817             bool        isCopyBlk = varTypeIsStruct(blkNode->Data());
2818             switch (blkNode->gtBlkOpKind)
2819             {
2820                 case GenTreeBlk::BlkOpKindHelper:
2821                     if (isCopyBlk)
2822                     {
2823                         killMask = compiler->compHelperCallKillSet(CORINFO_HELP_MEMCPY);
2824                     }
2825                     else
2826                     {
2827                         killMask = compiler->compHelperCallKillSet(CORINFO_HELP_MEMSET);
2828                     }
2829                     break;
2830
2831 #ifdef _TARGET_XARCH_
2832                 case GenTreeBlk::BlkOpKindRepInstr:
2833                     if (isCopyBlk)
2834                     {
2835                         // rep movs kills RCX, RDI and RSI
2836                         killMask = RBM_RCX | RBM_RDI | RBM_RSI;
2837                     }
2838                     else
2839                     {
2840                         // rep stos kills RCX and RDI.
2841                         // (Note that the Data() node, if not constant, will be assigned to
2842                         // RCX, but it's find that this kills it, as the value is not available
2843                         // after this node in any case.)
2844                         killMask = RBM_RDI | RBM_RCX;
2845                     }
2846                     break;
2847 #else
2848                 case GenTreeBlk::BlkOpKindRepInstr:
2849 #endif
2850                 case GenTreeBlk::BlkOpKindUnroll:
2851                 case GenTreeBlk::BlkOpKindInvalid:
2852                     // for these 'gtBlkOpKind' kinds, we leave 'killMask' = RBM_NONE
2853                     break;
2854             }
2855         }
2856         break;
2857
2858         case GT_RETURNTRAP:
2859             killMask = compiler->compHelperCallKillSet(CORINFO_HELP_STOP_FOR_GC);
2860             break;
2861         case GT_CALL:
2862 #ifdef _TARGET_X86_
2863             if (compiler->compFloatingPointUsed)
2864             {
2865                 if (tree->TypeGet() == TYP_DOUBLE)
2866                 {
2867                     needDoubleTmpForFPCall = true;
2868                 }
2869                 else if (tree->TypeGet() == TYP_FLOAT)
2870                 {
2871                     needFloatTmpForFPCall = true;
2872                 }
2873             }
2874 #endif // _TARGET_X86_
2875 #if defined(_TARGET_X86_) || defined(_TARGET_ARM_)
2876             if (tree->IsHelperCall())
2877             {
2878                 GenTreeCall*    call     = tree->AsCall();
2879                 CorInfoHelpFunc helpFunc = compiler->eeGetHelperNum(call->gtCallMethHnd);
2880                 killMask                 = compiler->compHelperCallKillSet(helpFunc);
2881             }
2882             else
2883 #endif // defined(_TARGET_X86_) || defined(_TARGET_ARM_)
2884             {
2885                 // if there is no FP used, we can ignore the FP kills
2886                 if (compiler->compFloatingPointUsed)
2887                 {
2888                     killMask = RBM_CALLEE_TRASH;
2889                 }
2890                 else
2891                 {
2892                     killMask = RBM_INT_CALLEE_TRASH;
2893                 }
2894 #ifdef _TARGET_ARM_
2895                 if (tree->AsCall()->IsVirtualStub())
2896                 {
2897                     killMask |= compiler->virtualStubParamInfo->GetRegMask();
2898                 }
2899 #else // !_TARGET_ARM_
2900             // Verify that the special virtual stub call registers are in the kill mask.
2901             // We don't just add them unconditionally to the killMask because for most architectures
2902             // they are already in the RBM_CALLEE_TRASH set,
2903             // and we don't want to introduce extra checks and calls in this hot function.
2904             assert(!tree->AsCall()->IsVirtualStub() || ((killMask & compiler->virtualStubParamInfo->GetRegMask()) ==
2905                                                         compiler->virtualStubParamInfo->GetRegMask()));
2906 #endif
2907             }
2908             break;
2909         case GT_STOREIND:
2910             if (compiler->codeGen->gcInfo.gcIsWriteBarrierAsgNode(tree))
2911             {
2912                 killMask = RBM_CALLEE_TRASH_NOGC;
2913             }
2914             break;
2915
2916 #if defined(PROFILING_SUPPORTED)
2917         // If this method requires profiler ELT hook then mark these nodes as killing
2918         // callee trash registers (excluding RAX and XMM0). The reason for this is that
2919         // profiler callback would trash these registers. See vm\amd64\asmhelpers.asm for
2920         // more details.
2921         case GT_RETURN:
2922             if (compiler->compIsProfilerHookNeeded())
2923             {
2924                 killMask = compiler->compHelperCallKillSet(CORINFO_HELP_PROF_FCN_LEAVE);
2925             }
2926             break;
2927
2928         case GT_PROF_HOOK:
2929             if (compiler->compIsProfilerHookNeeded())
2930             {
2931                 killMask = compiler->compHelperCallKillSet(CORINFO_HELP_PROF_FCN_TAILCALL);
2932             }
2933             break;
2934 #endif // PROFILING_SUPPORTED
2935
2936         default:
2937             // for all other 'tree->OperGet()' kinds, leave 'killMask' = RBM_NONE
2938             break;
2939     }
2940     return killMask;
2941 }
2942
2943 //------------------------------------------------------------------------
2944 // buildKillPositionsForNode:
2945 // Given some tree node add refpositions for all the registers this node kills
2946 //
2947 // Arguments:
2948 //    tree       - the tree for which kill positions should be generated
2949 //    currentLoc - the location at which the kills should be added
2950 //
2951 // Return Value:
2952 //    true       - kills were inserted
2953 //    false      - no kills were inserted
2954 //
2955 // Notes:
2956 //    The return value is needed because if we have any kills, we need to make sure that
2957 //    all defs are located AFTER the kills.  On the other hand, if there aren't kills,
2958 //    the multiple defs for a regPair are in different locations.
2959 //    If we generate any kills, we will mark all currentLiveVars as being preferenced
2960 //    to avoid the killed registers.  This is somewhat conservative.
2961
2962 bool LinearScan::buildKillPositionsForNode(GenTree* tree, LsraLocation currentLoc)
2963 {
2964     regMaskTP killMask   = getKillSetForNode(tree);
2965     bool      isCallKill = ((killMask == RBM_INT_CALLEE_TRASH) || (killMask == RBM_CALLEE_TRASH));
2966     if (killMask != RBM_NONE)
2967     {
2968         // The killMask identifies a set of registers that will be used during codegen.
2969         // Mark these as modified here, so when we do final frame layout, we'll know about
2970         // all these registers. This is especially important if killMask contains
2971         // callee-saved registers, which affect the frame size since we need to save/restore them.
2972         // In the case where we have a copyBlk with GC pointers, can need to call the
2973         // CORINFO_HELP_ASSIGN_BYREF helper, which kills callee-saved RSI and RDI, if
2974         // LSRA doesn't assign RSI/RDI, they wouldn't get marked as modified until codegen,
2975         // which is too late.
2976         compiler->codeGen->regSet.rsSetRegsModified(killMask DEBUGARG(dumpTerse));
2977
2978         addRefsForPhysRegMask(killMask, currentLoc, RefTypeKill, true);
2979
2980         // TODO-CQ: It appears to be valuable for both fp and int registers to avoid killing the callee
2981         // save regs on infrequently exectued paths.  However, it results in a large number of asmDiffs,
2982         // many of which appear to be regressions (because there is more spill on the infrequently path),
2983         // but are not really because the frequent path becomes smaller.  Validating these diffs will need
2984         // to be done before making this change.
2985         // if (!blockSequence[curBBSeqNum]->isRunRarely())
2986         if (enregisterLocalVars)
2987         {
2988             VarSetOps::Iter iter(compiler, currentLiveVars);
2989             unsigned        varIndex = 0;
2990             while (iter.NextElem(&varIndex))
2991             {
2992                 unsigned   varNum = compiler->lvaTrackedToVarNum[varIndex];
2993                 LclVarDsc* varDsc = compiler->lvaTable + varNum;
2994 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
2995                 if (varDsc->lvType == LargeVectorType)
2996                 {
2997                     if (!VarSetOps::IsMember(compiler, largeVectorCalleeSaveCandidateVars, varIndex))
2998                     {
2999                         continue;
3000                     }
3001                 }
3002                 else
3003 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
3004                     if (varTypeIsFloating(varDsc) &&
3005                         !VarSetOps::IsMember(compiler, fpCalleeSaveCandidateVars, varIndex))
3006                 {
3007                     continue;
3008                 }
3009                 Interval* interval = getIntervalForLocalVar(varIndex);
3010                 if (isCallKill)
3011                 {
3012                     interval->preferCalleeSave = true;
3013                 }
3014                 regMaskTP newPreferences = allRegs(interval->registerType) & (~killMask);
3015
3016                 if (newPreferences != RBM_NONE)
3017                 {
3018                     interval->updateRegisterPreferences(newPreferences);
3019                 }
3020                 else
3021                 {
3022                     // If there are no callee-saved registers, the call could kill all the registers.
3023                     // This is a valid state, so in that case assert should not trigger. The RA will spill in order to
3024                     // free a register later.
3025                     assert(compiler->opts.compDbgEnC || (calleeSaveRegs(varDsc->lvType)) == RBM_NONE);
3026                 }
3027             }
3028         }
3029
3030         if (tree->IsCall() && (tree->gtFlags & GTF_CALL_UNMANAGED) != 0)
3031         {
3032             RefPosition* pos = newRefPosition((Interval*)nullptr, currentLoc, RefTypeKillGCRefs, tree,
3033                                               (allRegs(TYP_REF) & ~RBM_ARG_REGS));
3034         }
3035         return true;
3036     }
3037
3038     return false;
3039 }
3040
3041 //----------------------------------------------------------------------------
3042 // defineNewInternalTemp: Defines a ref position for an internal temp.
3043 //
3044 // Arguments:
3045 //     tree                  -   Gentree node requiring an internal register
3046 //     regType               -   Register type
3047 //     currentLoc            -   Location of the temp Def position
3048 //     regMask               -   register mask of candidates for temp
3049 //     minRegCandidateCount  -   Minimum registers to be ensured in candidate
3050 //                               set under LSRA stress mode.  This is a
3051 //                               DEBUG only arg.
3052 RefPosition* LinearScan::defineNewInternalTemp(GenTree*     tree,
3053                                                RegisterType regType,
3054                                                LsraLocation currentLoc,
3055                                                regMaskTP regMask DEBUGARG(unsigned minRegCandidateCount))
3056 {
3057     Interval* current   = newInterval(regType);
3058     current->isInternal = true;
3059     return newRefPosition(current, currentLoc, RefTypeDef, tree, regMask, 0 DEBUG_ARG(minRegCandidateCount));
3060 }
3061
3062 //------------------------------------------------------------------------
3063 // buildInternalRegisterDefsForNode - build Def positions for internal
3064 // registers required for tree node.
3065 //
3066 // Arguments:
3067 //   tree                  -   Gentree node that needs internal registers
3068 //   currentLoc            -   Location at which Def positions need to be defined
3069 //   temps                 -   in-out array which is populated with ref positions
3070 //                             created for Def of internal registers
3071 //   minRegCandidateCount  -   Minimum registers to be ensured in candidate
3072 //                             set of ref positions under LSRA stress.  This is
3073 //                             a DEBUG only arg.
3074 //
3075 // Returns:
3076 //   The total number of Def positions created for internal registers of tree node.
3077 int LinearScan::buildInternalRegisterDefsForNode(GenTree*     tree,
3078                                                  LsraLocation currentLoc,
3079                                                  RefPosition* temps[] // populates
3080                                                  DEBUGARG(unsigned minRegCandidateCount))
3081 {
3082     int       count;
3083     int       internalIntCount = tree->gtLsraInfo.internalIntCount;
3084     regMaskTP internalCands    = tree->gtLsraInfo.getInternalCandidates(this);
3085
3086     // If the number of internal integer registers required is the same as the number of candidate integer registers in
3087     // the candidate set, then they must be handled as fixed registers.
3088     // (E.g. for the integer registers that floating point arguments must be copied into for a varargs call.)
3089     bool      fixedRegs             = false;
3090     regMaskTP internalIntCandidates = (internalCands & allRegs(TYP_INT));
3091     if (((int)genCountBits(internalIntCandidates)) == internalIntCount)
3092     {
3093         fixedRegs = true;
3094     }
3095
3096     for (count = 0; count < internalIntCount; count++)
3097     {
3098         regMaskTP internalIntCands = (internalCands & allRegs(TYP_INT));
3099         if (fixedRegs)
3100         {
3101             internalIntCands = genFindLowestBit(internalIntCands);
3102             internalCands &= ~internalIntCands;
3103         }
3104         temps[count] =
3105             defineNewInternalTemp(tree, IntRegisterType, currentLoc, internalIntCands DEBUG_ARG(minRegCandidateCount));
3106     }
3107
3108     int internalFloatCount = tree->gtLsraInfo.internalFloatCount;
3109     for (int i = 0; i < internalFloatCount; i++)
3110     {
3111         regMaskTP internalFPCands = (internalCands & internalFloatRegCandidates());
3112         temps[count++] =
3113             defineNewInternalTemp(tree, FloatRegisterType, currentLoc, internalFPCands DEBUG_ARG(minRegCandidateCount));
3114     }
3115
3116     assert(count < MaxInternalRegisters);
3117     assert(count == (internalIntCount + internalFloatCount));
3118     return count;
3119 }
3120
3121 //------------------------------------------------------------------------
3122 // buildInternalRegisterUsesForNode - adds Use positions for internal
3123 // registers required for tree node.
3124 //
3125 // Arguments:
3126 //   tree                  -   Gentree node that needs internal registers
3127 //   currentLoc            -   Location at which Use positions need to be defined
3128 //   defs                  -   int array containing Def positions of internal
3129 //                             registers.
3130 //   total                 -   Total number of Def positions in 'defs' array.
3131 //   minRegCandidateCount  -   Minimum registers to be ensured in candidate
3132 //                             set of ref positions under LSRA stress.  This is
3133 //                             a DEBUG only arg.
3134 //
3135 // Returns:
3136 //   Void.
3137 void LinearScan::buildInternalRegisterUsesForNode(GenTree*     tree,
3138                                                   LsraLocation currentLoc,
3139                                                   RefPosition* defs[],
3140                                                   int total DEBUGARG(unsigned minRegCandidateCount))
3141 {
3142     assert(total < MaxInternalRegisters);
3143
3144     // defs[] has been populated by buildInternalRegisterDefsForNode
3145     // now just add uses to the defs previously added.
3146     for (int i = 0; i < total; i++)
3147     {
3148         RefPosition* prevRefPosition = defs[i];
3149         assert(prevRefPosition != nullptr);
3150         regMaskTP mask = prevRefPosition->registerAssignment;
3151         if (prevRefPosition->isPhysRegRef)
3152         {
3153             newRefPosition(defs[i]->getReg()->regNum, currentLoc, RefTypeUse, tree, mask);
3154         }
3155         else
3156         {
3157             RefPosition* newest = newRefPosition(defs[i]->getInterval(), currentLoc, RefTypeUse, tree, mask,
3158                                                  0 DEBUG_ARG(minRegCandidateCount));
3159
3160             if (tree->gtLsraInfo.isInternalRegDelayFree)
3161             {
3162                 newest->delayRegFree = true;
3163             }
3164         }
3165     }
3166 }
3167
3168 regMaskTP LinearScan::getUseCandidates(GenTree* useNode)
3169 {
3170     TreeNodeInfo info = useNode->gtLsraInfo;
3171     return info.getSrcCandidates(this);
3172 }
3173
3174 regMaskTP LinearScan::getDefCandidates(GenTree* tree)
3175 {
3176     TreeNodeInfo info = tree->gtLsraInfo;
3177     return info.getDstCandidates(this);
3178 }
3179
3180 RegisterType LinearScan::getDefType(GenTree* tree)
3181 {
3182     return tree->TypeGet();
3183 }
3184
3185 //------------------------------------------------------------------------
3186 // LocationInfoListNode: used to store a single `LocationInfo` value for a
3187 //                       node during `buildIntervals`.
3188 //
3189 // This is the node type for `LocationInfoList` below.
3190 //
3191 class LocationInfoListNode final : public LocationInfo
3192 {
3193     friend class LocationInfoList;
3194     friend class LocationInfoListNodePool;
3195
3196     LocationInfoListNode* m_next; // The next node in the list
3197
3198 public:
3199     LocationInfoListNode(LsraLocation l, Interval* i, GenTree* t, unsigned regIdx = 0) : LocationInfo(l, i, t, regIdx)
3200     {
3201     }
3202
3203     //------------------------------------------------------------------------
3204     // LocationInfoListNode::Next: Returns the next node in the list.
3205     LocationInfoListNode* Next() const
3206     {
3207         return m_next;
3208     }
3209 };
3210
3211 //------------------------------------------------------------------------
3212 // LocationInfoList: used to store a list of `LocationInfo` values for a
3213 //                   node during `buildIntervals`.
3214 //
3215 // Given an IR node that either directly defines N registers or that is a
3216 // contained node with uses that define a total of N registers, that node
3217 // will map to N `LocationInfo` values. These values are stored as a
3218 // linked list of `LocationInfoListNode` values.
3219 //
3220 class LocationInfoList final
3221 {
3222     friend class LocationInfoListNodePool;
3223
3224     LocationInfoListNode* m_head; // The head of the list
3225     LocationInfoListNode* m_tail; // The tail of the list
3226
3227 public:
3228     LocationInfoList() : m_head(nullptr), m_tail(nullptr)
3229     {
3230     }
3231
3232     LocationInfoList(LocationInfoListNode* node) : m_head(node), m_tail(node)
3233     {
3234         assert(m_head->m_next == nullptr);
3235     }
3236
3237     //------------------------------------------------------------------------
3238     // LocationInfoList::IsEmpty: Returns true if the list is empty.
3239     //
3240     bool IsEmpty() const
3241     {
3242         return m_head == nullptr;
3243     }
3244
3245     //------------------------------------------------------------------------
3246     // LocationInfoList::Begin: Returns the first node in the list.
3247     //
3248     LocationInfoListNode* Begin() const
3249     {
3250         return m_head;
3251     }
3252
3253     //------------------------------------------------------------------------
3254     // LocationInfoList::End: Returns the position after the last node in the
3255     //                        list. The returned value is suitable for use as
3256     //                        a sentinel for iteration.
3257     //
3258     LocationInfoListNode* End() const
3259     {
3260         return nullptr;
3261     }
3262
3263     //------------------------------------------------------------------------
3264     // LocationInfoList::Append: Appends a node to the list.
3265     //
3266     // Arguments:
3267     //    node - The node to append. Must not be part of an existing list.
3268     //
3269     void Append(LocationInfoListNode* node)
3270     {
3271         assert(node->m_next == nullptr);
3272
3273         if (m_tail == nullptr)
3274         {
3275             assert(m_head == nullptr);
3276             m_head = node;
3277         }
3278         else
3279         {
3280             m_tail->m_next = node;
3281         }
3282
3283         m_tail = node;
3284     }
3285
3286     //------------------------------------------------------------------------
3287     // LocationInfoList::Append: Appends another list to this list.
3288     //
3289     // Arguments:
3290     //    other - The list to append.
3291     //
3292     void Append(LocationInfoList other)
3293     {
3294         if (m_tail == nullptr)
3295         {
3296             assert(m_head == nullptr);
3297             m_head = other.m_head;
3298         }
3299         else
3300         {
3301             m_tail->m_next = other.m_head;
3302         }
3303
3304         m_tail = other.m_tail;
3305     }
3306 };
3307
3308 //------------------------------------------------------------------------
3309 // LocationInfoListNodePool: manages a pool of `LocationInfoListNode`
3310 //                           values to decrease overall memory usage
3311 //                           during `buildIntervals`.
3312 //
3313 // `buildIntervals` involves creating a list of location info values per
3314 // node that either directly produces a set of registers or that is a
3315 // contained node with register-producing sources. However, these lists
3316 // are short-lived: they are destroyed once the use of the corresponding
3317 // node is processed. As such, there is typically only a small number of
3318 // `LocationInfoListNode` values in use at any given time. Pooling these
3319 // values avoids otherwise frequent allocations.
3320 class LocationInfoListNodePool final
3321 {
3322     LocationInfoListNode* m_freeList;
3323     Compiler*             m_compiler;
3324
3325 public:
3326     //------------------------------------------------------------------------
3327     // LocationInfoListNodePool::LocationInfoListNodePool:
3328     //    Creates a pool of `LocationInfoListNode` values.
3329     //
3330     // Arguments:
3331     //    compiler    - The compiler context.
3332     //    preallocate - The number of nodes to preallocate.
3333     //
3334     LocationInfoListNodePool(Compiler* compiler, unsigned preallocate = 0) : m_compiler(compiler)
3335     {
3336         if (preallocate > 0)
3337         {
3338             size_t preallocateSize   = sizeof(LocationInfoListNode) * preallocate;
3339             auto*  preallocatedNodes = reinterpret_cast<LocationInfoListNode*>(compiler->compGetMem(preallocateSize));
3340
3341             LocationInfoListNode* head = preallocatedNodes;
3342             head->m_next               = nullptr;
3343
3344             for (unsigned i = 1; i < preallocate; i++)
3345             {
3346                 LocationInfoListNode* node = &preallocatedNodes[i];
3347                 node->m_next               = head;
3348                 head                       = node;
3349             }
3350
3351             m_freeList = head;
3352         }
3353     }
3354
3355     //------------------------------------------------------------------------
3356     // LocationInfoListNodePool::GetNode: Fetches an unused node from the
3357     //                                    pool.
3358     //
3359     // Arguments:
3360     //    l -    - The `LsraLocation` for the `LocationInfo` value.
3361     //    i      - The interval for the `LocationInfo` value.
3362     //    t      - The IR node for the `LocationInfo` value
3363     //    regIdx - The register index for the `LocationInfo` value.
3364     //
3365     // Returns:
3366     //    A pooled or newly-allocated `LocationInfoListNode`, depending on the
3367     //    contents of the pool.
3368     LocationInfoListNode* GetNode(LsraLocation l, Interval* i, GenTree* t, unsigned regIdx = 0)
3369     {
3370         LocationInfoListNode* head = m_freeList;
3371         if (head == nullptr)
3372         {
3373             head = reinterpret_cast<LocationInfoListNode*>(m_compiler->compGetMem(sizeof(LocationInfoListNode)));
3374         }
3375         else
3376         {
3377             m_freeList = head->m_next;
3378         }
3379
3380         head->loc         = l;
3381         head->interval    = i;
3382         head->treeNode    = t;
3383         head->multiRegIdx = regIdx;
3384         head->m_next      = nullptr;
3385
3386         return head;
3387     }
3388
3389     //------------------------------------------------------------------------
3390     // LocationInfoListNodePool::ReturnNodes: Returns a list of nodes to the
3391     //                                        pool.
3392     //
3393     // Arguments:
3394     //    list - The list to return.
3395     //
3396     void ReturnNodes(LocationInfoList& list)
3397     {
3398         assert(list.m_head != nullptr);
3399         assert(list.m_tail != nullptr);
3400
3401         LocationInfoListNode* head = m_freeList;
3402         list.m_tail->m_next        = head;
3403         m_freeList                 = list.m_head;
3404     }
3405 };
3406
3407 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
3408 VARSET_VALRET_TP
3409 LinearScan::buildUpperVectorSaveRefPositions(GenTree* tree, LsraLocation currentLoc)
3410 {
3411     assert(enregisterLocalVars);
3412     VARSET_TP liveLargeVectors(VarSetOps::MakeEmpty(compiler));
3413     regMaskTP fpCalleeKillSet = RBM_NONE;
3414     if (!VarSetOps::IsEmpty(compiler, largeVectorVars))
3415     {
3416         // We actually need to find any calls that kill the upper-half of the callee-save vector registers.
3417         // But we will use as a proxy any node that kills floating point registers.
3418         // (Note that some calls are masquerading as other nodes at this point so we can't just check for calls.)
3419         fpCalleeKillSet = getKillSetForNode(tree);
3420         if ((fpCalleeKillSet & RBM_FLT_CALLEE_TRASH) != RBM_NONE)
3421         {
3422             VarSetOps::AssignNoCopy(compiler, liveLargeVectors,
3423                                     VarSetOps::Intersection(compiler, currentLiveVars, largeVectorVars));
3424             VarSetOps::Iter iter(compiler, liveLargeVectors);
3425             unsigned        varIndex = 0;
3426             while (iter.NextElem(&varIndex))
3427             {
3428                 Interval* varInterval    = getIntervalForLocalVar(varIndex);
3429                 Interval* tempInterval   = newInterval(LargeVectorType);
3430                 tempInterval->isInternal = true;
3431                 RefPosition* pos =
3432                     newRefPosition(tempInterval, currentLoc, RefTypeUpperVectorSaveDef, tree, RBM_FLT_CALLEE_SAVED);
3433                 // We are going to save the existing relatedInterval of varInterval on tempInterval, so that we can set
3434                 // the tempInterval as the relatedInterval of varInterval, so that we can build the corresponding
3435                 // RefTypeUpperVectorSaveUse RefPosition.  We will then restore the relatedInterval onto varInterval,
3436                 // and set varInterval as the relatedInterval of tempInterval.
3437                 tempInterval->relatedInterval = varInterval->relatedInterval;
3438                 varInterval->relatedInterval  = tempInterval;
3439             }
3440         }
3441     }
3442     return liveLargeVectors;
3443 }
3444
3445 void LinearScan::buildUpperVectorRestoreRefPositions(GenTree*         tree,
3446                                                      LsraLocation     currentLoc,
3447                                                      VARSET_VALARG_TP liveLargeVectors)
3448 {
3449     assert(enregisterLocalVars);
3450     if (!VarSetOps::IsEmpty(compiler, liveLargeVectors))
3451     {
3452         VarSetOps::Iter iter(compiler, liveLargeVectors);
3453         unsigned        varIndex = 0;
3454         while (iter.NextElem(&varIndex))
3455         {
3456             Interval* varInterval  = getIntervalForLocalVar(varIndex);
3457             Interval* tempInterval = varInterval->relatedInterval;
3458             assert(tempInterval->isInternal == true);
3459             RefPosition* pos =
3460                 newRefPosition(tempInterval, currentLoc, RefTypeUpperVectorSaveUse, tree, RBM_FLT_CALLEE_SAVED);
3461             // Restore the relatedInterval onto varInterval, and set varInterval as the relatedInterval
3462             // of tempInterval.
3463             varInterval->relatedInterval  = tempInterval->relatedInterval;
3464             tempInterval->relatedInterval = varInterval;
3465         }
3466     }
3467 }
3468 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
3469
3470 #ifdef DEBUG
3471 //------------------------------------------------------------------------
3472 // ComputeOperandDstCount: computes the number of registers defined by a
3473 //                         node.
3474 //
3475 // For most nodes, this is simple:
3476 // - Nodes that do not produce values (e.g. stores and other void-typed
3477 //   nodes) and nodes that immediately use the registers they define
3478 //   produce no registers
3479 // - Nodes that are marked as defining N registers define N registers.
3480 //
3481 // For contained nodes, however, things are more complicated: for purposes
3482 // of bookkeeping, a contained node is treated as producing the transitive
3483 // closure of the registers produced by its sources.
3484 //
3485 // Arguments:
3486 //    operand - The operand for which to compute a register count.
3487 //
3488 // Returns:
3489 //    The number of registers defined by `operand`.
3490 //
3491 static int ComputeOperandDstCount(GenTree* operand)
3492 {
3493     TreeNodeInfo& operandInfo = operand->gtLsraInfo;
3494
3495     if (operandInfo.isLocalDefUse)
3496     {
3497         // Operands that define an unused value do not produce any registers.
3498         return 0;
3499     }
3500     else if (operandInfo.dstCount != 0)
3501     {
3502         // Operands that have a specified number of destination registers consume all of their operands
3503         // and therefore produce exactly that number of registers.
3504         return operandInfo.dstCount;
3505     }
3506     else if (operandInfo.srcCount != 0)
3507     {
3508         // If an operand has no destination registers but does have source registers, it must be a store
3509         // or a compare.
3510         assert(operand->OperIsStore() || operand->OperIsBlkOp() || operand->OperIsPutArgStk() ||
3511                operand->OperIsCompare() || operand->OperIs(GT_CMP) || operand->IsSIMDEqualityOrInequality());
3512         return 0;
3513     }
3514     else if (!operand->OperIsFieldListHead() && (operand->OperIsStore() || operand->TypeGet() == TYP_VOID))
3515     {
3516         // Stores and void-typed operands may be encountered when processing call nodes, which contain
3517         // pointers to argument setup stores.
3518         return 0;
3519     }
3520     else
3521     {
3522         // If a field list or non-void-typed operand is not an unused value and does not have source registers,
3523         // that argument is contained within its parent and produces `sum(operand_dst_count)` registers.
3524         int dstCount = 0;
3525         for (GenTree* op : operand->Operands())
3526         {
3527             dstCount += ComputeOperandDstCount(op);
3528         }
3529
3530         return dstCount;
3531     }
3532 }
3533
3534 //------------------------------------------------------------------------
3535 // ComputeAvailableSrcCount: computes the number of registers available as
3536 //                           sources for a node.
3537 //
3538 // This is simply the sum of the number of registers produced by each
3539 // operand to the node.
3540 //
3541 // Arguments:
3542 //    node - The node for which to compute a source count.
3543 //
3544 // Retures:
3545 //    The number of registers available as sources for `node`.
3546 //
3547 static int ComputeAvailableSrcCount(GenTree* node)
3548 {
3549     int numSources = 0;
3550     for (GenTree* operand : node->Operands())
3551     {
3552         numSources += ComputeOperandDstCount(operand);
3553     }
3554
3555     return numSources;
3556 }
3557 #endif // DEBUG
3558
3559 static GenTree* GetFirstOperand(GenTree* node)
3560 {
3561     GenTree* firstOperand = nullptr;
3562     node->VisitOperands([&firstOperand](GenTree* operand) -> GenTree::VisitResult {
3563         firstOperand = operand;
3564         return GenTree::VisitResult::Abort;
3565     });
3566     return firstOperand;
3567 }
3568
3569 void LinearScan::buildRefPositionsForNode(GenTree*                  tree,
3570                                           BasicBlock*               block,
3571                                           LocationInfoListNodePool& listNodePool,
3572                                           HashTableBase<GenTree*, LocationInfoList>& operandToLocationInfoMap,
3573                                           LsraLocation currentLoc)
3574 {
3575 #ifdef _TARGET_ARM_
3576     assert(!isRegPairType(tree->TypeGet()));
3577 #endif // _TARGET_ARM_
3578
3579     // The LIR traversal doesn't visit GT_LIST or GT_ARGPLACE nodes.
3580     // GT_CLS_VAR nodes should have been eliminated by rationalizer.
3581     assert(tree->OperGet() != GT_ARGPLACE);
3582     assert(tree->OperGet() != GT_LIST);
3583     assert(tree->OperGet() != GT_CLS_VAR);
3584
3585     // The LIR traversal visits only the first node in a GT_FIELD_LIST.
3586     assert((tree->OperGet() != GT_FIELD_LIST) || tree->AsFieldList()->IsFieldListHead());
3587
3588     // The set of internal temporary registers used by this node are stored in the
3589     // gtRsvdRegs register mask. Clear it out.
3590     tree->gtRsvdRegs = RBM_NONE;
3591
3592     TreeNodeInfo info = tree->gtLsraInfo;
3593     assert(info.IsValid(this));
3594     int consume = info.srcCount;
3595     int produce = info.dstCount;
3596
3597 #ifdef DEBUG
3598     if (VERBOSE)
3599     {
3600         lsraDispNode(tree, LSRA_DUMP_REFPOS, (produce != 0));
3601         JITDUMP("\n");
3602         if (tree->isContained())
3603         {
3604             JITDUMP("Contained\n");
3605         }
3606         else if (tree->OperIs(GT_LCL_VAR, GT_LCL_FLD) && info.isLocalDefUse)
3607         {
3608             JITDUMP("Unused\n");
3609         }
3610         else
3611         {
3612             JITDUMP("  consume=%d produce=%d\n", consume, produce);
3613         }
3614
3615         if (consume != 0)
3616         {
3617             JITDUMP("at start of tree, map contains: { ");
3618             bool first = true;
3619             for (auto kvp : operandToLocationInfoMap)
3620             {
3621                 GenTree*         node    = kvp.Key();
3622                 LocationInfoList defList = kvp.Value();
3623
3624                 JITDUMP("%sN%03u. %s -> (", first ? "" : "; ", node->gtSeqNum, GenTree::OpName(node->OperGet()));
3625                 for (LocationInfoListNode *def = defList.Begin(), *end = defList.End(); def != end; def = def->Next())
3626                 {
3627                     JITDUMP("%s%d.N%03u", def == defList.Begin() ? "" : ", ", def->loc, def->treeNode->gtSeqNum);
3628                 }
3629                 JITDUMP(")");
3630
3631                 first = false;
3632             }
3633             JITDUMP(" }\n");
3634         }
3635     }
3636 #endif // DEBUG
3637
3638     assert(((consume == 0) && (produce == 0)) || (ComputeAvailableSrcCount(tree) == consume));
3639
3640     if (tree->OperIs(GT_LCL_VAR, GT_LCL_FLD))
3641     {
3642         LclVarDsc* const varDsc = &compiler->lvaTable[tree->AsLclVarCommon()->gtLclNum];
3643         if (isCandidateVar(varDsc))
3644         {
3645             assert(consume == 0);
3646
3647             // We handle tracked variables differently from non-tracked ones.  If it is tracked,
3648             // we simply add a use or def of the tracked variable.  Otherwise, for a use we need
3649             // to actually add the appropriate references for loading or storing the variable.
3650             //
3651             // It won't actually get used or defined until the appropriate ancestor tree node
3652             // is processed, unless this is marked "isLocalDefUse" because it is a stack-based argument
3653             // to a call
3654
3655             assert(varDsc->lvTracked);
3656             unsigned varIndex = varDsc->lvVarIndex;
3657
3658             // We have only approximate last-use information at this point.  This is because the
3659             // execution order doesn't actually reflect the true order in which the localVars
3660             // are referenced - but the order of the RefPositions will, so we recompute it after
3661             // RefPositions are built.
3662             // Use the old value for setting currentLiveVars - note that we do this with the
3663             // not-quite-correct setting of lastUse.  However, this is OK because
3664             // 1) this is only for preferencing, which doesn't require strict correctness, and
3665             // 2) the cases where these out-of-order uses occur should not overlap a kill.
3666             // TODO-Throughput: clean this up once we have the execution order correct.  At that point
3667             // we can update currentLiveVars at the same place that we create the RefPosition.
3668             if ((tree->gtFlags & GTF_VAR_DEATH) != 0)
3669             {
3670                 VarSetOps::RemoveElemD(compiler, currentLiveVars, varIndex);
3671             }
3672
3673             if (!info.isLocalDefUse && !tree->isContained())
3674             {
3675                 assert(produce != 0);
3676
3677                 LocationInfoList list(listNodePool.GetNode(currentLoc, getIntervalForLocalVar(varIndex), tree));
3678                 bool             added = operandToLocationInfoMap.AddOrUpdate(tree, list);
3679                 assert(added);
3680
3681                 tree->gtLsraInfo.definesAnyRegisters = true;
3682             }
3683             return;
3684         }
3685     }
3686
3687     if (tree->isContained())
3688     {
3689         assert(!info.isLocalDefUse);
3690         assert(consume == 0);
3691         assert(produce == 0);
3692         assert(info.internalIntCount == 0);
3693         assert(info.internalFloatCount == 0);
3694
3695         // Contained nodes map to the concatenated lists of their operands.
3696         LocationInfoList locationInfoList;
3697         tree->VisitOperands([&](GenTree* op) -> GenTree::VisitResult {
3698             if (!op->gtLsraInfo.definesAnyRegisters)
3699             {
3700                 assert(ComputeOperandDstCount(op) == 0);
3701                 return GenTree::VisitResult::Continue;
3702             }
3703
3704             LocationInfoList operandList;
3705             bool             removed = operandToLocationInfoMap.TryRemove(op, &operandList);
3706             assert(removed);
3707
3708             locationInfoList.Append(operandList);
3709             return GenTree::VisitResult::Continue;
3710         });
3711
3712         if (!locationInfoList.IsEmpty())
3713         {
3714             bool added = operandToLocationInfoMap.AddOrUpdate(tree, locationInfoList);
3715             assert(added);
3716             tree->gtLsraInfo.definesAnyRegisters = true;
3717         }
3718         JITDUMP("\n");
3719         return;
3720     }
3721
3722     // Handle the case of local variable assignment
3723     Interval* varDefInterval = nullptr;
3724     RefType   defRefType     = RefTypeDef;
3725
3726     GenTree* defNode = tree;
3727
3728     // noAdd means the node creates a def but for purposes of map
3729     // management do not add it because data is not flowing up the
3730     // tree but over (as in ASG nodes)
3731
3732     bool         noAdd   = info.isLocalDefUse;
3733     RefPosition* prevPos = nullptr;
3734
3735     bool isSpecialPutArg = false;
3736
3737     assert(!tree->OperIsAssignment());
3738     if (tree->OperIsLocalStore())
3739     {
3740         GenTreeLclVarCommon* const store = tree->AsLclVarCommon();
3741         assert((consume > 1) || (regType(store->gtOp1->TypeGet()) == regType(store->TypeGet())));
3742
3743         LclVarDsc* varDsc = &compiler->lvaTable[store->gtLclNum];
3744         if (isCandidateVar(varDsc))
3745         {
3746             // We always push the tracked lclVar intervals
3747             assert(varDsc->lvTracked);
3748             unsigned varIndex = varDsc->lvVarIndex;
3749             varDefInterval    = getIntervalForLocalVar(varIndex);
3750             defRefType        = refTypeForLocalRefNode(tree);
3751             defNode           = tree;
3752             if (produce == 0)
3753             {
3754                 produce = 1;
3755                 noAdd   = true;
3756             }
3757
3758             assert(consume <= MAX_RET_REG_COUNT);
3759             if (consume == 1)
3760             {
3761                 // Get the location info for the register defined by the first operand.
3762                 LocationInfoList operandDefs;
3763                 bool             found = operandToLocationInfoMap.TryGetValue(GetFirstOperand(tree), &operandDefs);
3764                 assert(found);
3765
3766                 // Since we only expect to consume one register, we should only have a single register to
3767                 // consume.
3768                 assert(operandDefs.Begin()->Next() == operandDefs.End());
3769
3770                 LocationInfo& operandInfo = *static_cast<LocationInfo*>(operandDefs.Begin());
3771
3772                 Interval* srcInterval = operandInfo.interval;
3773                 if (srcInterval->relatedInterval == nullptr)
3774                 {
3775                     // Preference the source to the dest, unless this is a non-last-use localVar.
3776                     // Note that the last-use info is not correct, but it is a better approximation than preferencing
3777                     // the source to the dest, if the source's lifetime extends beyond the dest.
3778                     if (!srcInterval->isLocalVar || (operandInfo.treeNode->gtFlags & GTF_VAR_DEATH) != 0)
3779                     {
3780                         srcInterval->assignRelatedInterval(varDefInterval);
3781                     }
3782                 }
3783                 else if (!srcInterval->isLocalVar)
3784                 {
3785                     // Preference the source to dest, if src is not a local var.
3786                     srcInterval->assignRelatedInterval(varDefInterval);
3787                 }
3788             }
3789
3790             if ((tree->gtFlags & GTF_VAR_DEATH) == 0)
3791             {
3792                 VarSetOps::AddElemD(compiler, currentLiveVars, varIndex);
3793             }
3794         }
3795         else if (store->gtOp1->OperIs(GT_BITCAST))
3796         {
3797             store->gtType = store->gtOp1->gtType = store->gtOp1->AsUnOp()->gtOp1->TypeGet();
3798
3799             // Get the location info for the register defined by the first operand.
3800             LocationInfoList operandDefs;
3801             bool             found = operandToLocationInfoMap.TryGetValue(GetFirstOperand(store), &operandDefs);
3802             assert(found);
3803
3804             // Since we only expect to consume one register, we should only have a single register to consume.
3805             assert(operandDefs.Begin()->Next() == operandDefs.End());
3806
3807             LocationInfo& operandInfo = *static_cast<LocationInfo*>(operandDefs.Begin());
3808
3809             Interval* srcInterval     = operandInfo.interval;
3810             srcInterval->registerType = regType(store->TypeGet());
3811
3812             RefPosition* srcDefPosition = srcInterval->firstRefPosition;
3813             assert(srcDefPosition != nullptr);
3814             assert(srcDefPosition->refType == RefTypeDef);
3815             assert(srcDefPosition->treeNode == store->gtOp1);
3816
3817             srcDefPosition->registerAssignment = allRegs(store->TypeGet());
3818             store->gtOp1->gtLsraInfo.setSrcCandidates(this, allRegs(store->TypeGet()));
3819         }
3820     }
3821     else if (noAdd && produce == 0)
3822     {
3823         // This is the case for dead nodes that occur after
3824         // tree rationalization
3825         // TODO-Cleanup: Identify and remove these dead nodes prior to register allocation.
3826         if (tree->IsMultiRegCall())
3827         {
3828             // In case of multi-reg call node, produce = number of return registers
3829             produce = tree->AsCall()->GetReturnTypeDesc()->GetReturnRegCount();
3830         }
3831         else
3832         {
3833             produce = 1;
3834         }
3835     }
3836
3837     Interval* prefSrcInterval = nullptr;
3838
3839     // If this is a binary operator that will be encoded with 2 operand fields
3840     // (i.e. the target is read-modify-write), preference the dst to op1.
3841
3842     bool hasDelayFreeSrc = tree->gtLsraInfo.hasDelayFreeSrc;
3843
3844 #if defined(DEBUG) && defined(_TARGET_X86_)
3845     // On x86, `LSRA_LIMIT_CALLER` is too restrictive to allow the use of special put args: this stress mode
3846     // leaves only three registers allocatable--eax, ecx, and edx--of which the latter two are also used for the
3847     // first two integral arguments to a call. This can leave us with too few registers to succesfully allocate in
3848     // situations like the following:
3849     //
3850     //     t1026 =    lclVar    ref    V52 tmp35        u:3 REG NA <l:$3a1, c:$98d>
3851     //
3852     //             /--*  t1026  ref
3853     //     t1352 = *  putarg_reg ref    REG NA
3854     //
3855     //      t342 =    lclVar    int    V14 loc6         u:4 REG NA $50c
3856     //
3857     //      t343 =    const     int    1 REG NA $41
3858     //
3859     //             /--*  t342   int
3860     //             +--*  t343   int
3861     //      t344 = *  +         int    REG NA $495
3862     //
3863     //      t345 =    lclVar    int    V04 arg4         u:2 REG NA $100
3864     //
3865     //             /--*  t344   int
3866     //             +--*  t345   int
3867     //      t346 = *  %         int    REG NA $496
3868     //
3869     //             /--*  t346   int
3870     //     t1353 = *  putarg_reg int    REG NA
3871     //
3872     //     t1354 =    lclVar    ref    V52 tmp35         (last use) REG NA
3873     //
3874     //             /--*  t1354  ref
3875     //     t1355 = *  lea(b+0)  byref  REG NA
3876     //
3877     // Here, the first `putarg_reg` would normally be considered a special put arg, which would remove `ecx` from the
3878     // set of allocatable registers, leaving only `eax` and `edx`. The allocator will then fail to allocate a register
3879     // for the def of `t345` if arg4 is not a register candidate: the corresponding ref position will be constrained to
3880     // { `ecx`, `ebx`, `esi`, `edi` }, which `LSRA_LIMIT_CALLER` will further constrain to `ecx`, which will not be
3881     // available due to the special put arg.
3882     const bool supportsSpecialPutArg = getStressLimitRegs() != LSRA_LIMIT_CALLER;
3883 #else
3884     const bool supportsSpecialPutArg = true;
3885 #endif
3886
3887     if (supportsSpecialPutArg && tree->OperGet() == GT_PUTARG_REG && isCandidateLocalRef(tree->gtGetOp1()) &&
3888         (tree->gtGetOp1()->gtFlags & GTF_VAR_DEATH) == 0)
3889     {
3890         // This is the case for a "pass-through" copy of a lclVar.  In the case where it is a non-last-use,
3891         // we don't want the def of the copy to kill the lclVar register, if it is assigned the same register
3892         // (which is actually what we hope will happen).
3893         JITDUMP("Setting putarg_reg as a pass-through of a non-last use lclVar\n");
3894
3895         // Get the register information for the first operand of the node.
3896         LocationInfoList operandDefs;
3897         bool             found = operandToLocationInfoMap.TryGetValue(GetFirstOperand(tree), &operandDefs);
3898         assert(found);
3899
3900         // Preference the destination to the interval of the first register defined by the first operand.
3901         Interval* srcInterval = operandDefs.Begin()->interval;
3902         assert(srcInterval->isLocalVar);
3903         prefSrcInterval = srcInterval;
3904         isSpecialPutArg = true;
3905     }
3906
3907     RefPosition* internalRefs[MaxInternalRegisters];
3908
3909 #ifdef DEBUG
3910     // Number of registers required for tree node is the sum of
3911     // consume + produce + internalCount.  This is the minimum
3912     // set of registers that needs to be ensured in candidate
3913     // set of ref positions created.
3914     unsigned minRegCount = consume + produce + info.internalIntCount + info.internalFloatCount;
3915 #endif // DEBUG
3916
3917     // make intervals for all the 'internal' register requirements for this node
3918     // where internal means additional registers required temporarily
3919     int internalCount = buildInternalRegisterDefsForNode(tree, currentLoc, internalRefs DEBUG_ARG(minRegCount));
3920
3921     // pop all ref'd tree temps
3922     tree->VisitOperands([&](GenTree* operand) -> GenTree::VisitResult {
3923         // Skip operands that do not define any registers, whether directly or indirectly.
3924         if (!operand->gtLsraInfo.definesAnyRegisters)
3925         {
3926             return GenTree::VisitResult::Continue;
3927         }
3928
3929         // Remove the list of registers defined by the current operand from the map. Note that this
3930         // is only correct because tree nodes are singly-used: if this property ever changes (e.g.
3931         // if tree nodes are eventually allowed to be multiply-used), then the removal is only
3932         // correct at the last use.
3933         LocationInfoList operandDefs;
3934         bool             removed = operandToLocationInfoMap.TryRemove(operand, &operandDefs);
3935         assert(removed);
3936         assert(!operandDefs.IsEmpty());
3937
3938         LocationInfoListNode* const operandDefsEnd = operandDefs.End();
3939         for (LocationInfoListNode* operandDefsIterator = operandDefs.Begin(); operandDefsIterator != operandDefsEnd;
3940              operandDefsIterator                       = operandDefsIterator->Next())
3941         {
3942             LocationInfo& locInfo = *static_cast<LocationInfo*>(operandDefsIterator);
3943
3944             // for interstitial tree temps, a use is always last and end; this is set by default in newRefPosition
3945             GenTree* const useNode = locInfo.treeNode;
3946             assert(useNode != nullptr);
3947
3948             Interval* const i = locInfo.interval;
3949             if (useNode->gtLsraInfo.isTgtPref)
3950             {
3951                 prefSrcInterval = i;
3952             }
3953
3954             const bool delayRegFree = (hasDelayFreeSrc && useNode->gtLsraInfo.isDelayFree);
3955
3956 #ifdef DEBUG
3957             // If delayRegFree, then Use will interfere with the destination of
3958             // the consuming node.  Therefore, we also need add the kill set of
3959             // consuming node to minRegCount.
3960             //
3961             // For example consider the following IR on x86, where v01 and v02
3962             // are method args coming in ecx and edx respectively.
3963             //   GT_DIV(v01, v02)
3964             //
3965             // For GT_DIV minRegCount will be 3 without adding kill set
3966             // of GT_DIV node.
3967             //
3968             // Assume further JitStressRegs=2, which would constrain
3969             // candidates to callee trashable regs { eax, ecx, edx } on
3970             // use positions of v01 and v02.  LSRA allocates ecx for v01.
3971             // Use position of v02 cannot be allocated a regs since it
3972             // is marked delay-reg free and {eax,edx} are getting killed
3973             // before the def of GT_DIV.  For this reason, minRegCount
3974             // for Use position of v02 also needs to take into account
3975             // of kill set of its consuming node.
3976             unsigned minRegCountForUsePos = minRegCount;
3977             if (delayRegFree)
3978             {
3979                 regMaskTP killMask = getKillSetForNode(tree);
3980                 if (killMask != RBM_NONE)
3981                 {
3982                     minRegCountForUsePos += genCountBits(killMask);
3983                 }
3984             }
3985 #endif // DEBUG
3986
3987             regMaskTP candidates = getUseCandidates(useNode);
3988 #ifdef ARM_SOFTFP
3989             // If oper is GT_PUTARG_REG, set bits in useCandidates must be in sequential order.
3990             if (useNode->OperIsMultiRegOp())
3991             {
3992                 regMaskTP candidate = genFindLowestReg(candidates);
3993                 useNode->gtLsraInfo.setSrcCandidates(this, candidates & ~candidate);
3994                 candidates = candidate;
3995             }
3996 #endif // ARM_SOFTFP
3997             assert((candidates & allRegs(i->registerType)) != 0);
3998
3999             // For non-localVar uses we record nothing, as nothing needs to be written back to the tree.
4000             GenTree* const refPosNode = i->isLocalVar ? useNode : nullptr;
4001             RefPosition*   pos        = newRefPosition(i, currentLoc, RefTypeUse, refPosNode, candidates,
4002                                               locInfo.multiRegIdx DEBUG_ARG(minRegCountForUsePos));
4003
4004             if (delayRegFree)
4005             {
4006                 pos->delayRegFree = true;
4007             }
4008
4009             if (useNode->IsRegOptional())
4010             {
4011                 pos->setAllocateIfProfitable(true);
4012             }
4013         }
4014
4015         listNodePool.ReturnNodes(operandDefs);
4016
4017         return GenTree::VisitResult::Continue;
4018     });
4019
4020     buildInternalRegisterUsesForNode(tree, currentLoc, internalRefs, internalCount DEBUG_ARG(minRegCount));
4021
4022     RegisterType registerType  = getDefType(tree);
4023     regMaskTP    candidates    = getDefCandidates(tree);
4024     regMaskTP    useCandidates = getUseCandidates(tree);
4025
4026 #ifdef DEBUG
4027     if (VERBOSE && produce)
4028     {
4029         printf("Def candidates ");
4030         dumpRegMask(candidates);
4031         printf(", Use candidates ");
4032         dumpRegMask(useCandidates);
4033         printf("\n");
4034     }
4035 #endif // DEBUG
4036
4037 #if defined(_TARGET_AMD64_)
4038     // Multi-reg call node is the only node that could produce multi-reg value
4039     assert(produce <= 1 || (tree->IsMultiRegCall() && produce == MAX_RET_REG_COUNT));
4040 #endif // _TARGET_xxx_
4041
4042     // Add kill positions before adding def positions
4043     buildKillPositionsForNode(tree, currentLoc + 1);
4044
4045 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
4046     VARSET_TP liveLargeVectors(VarSetOps::UninitVal());
4047     if (enregisterLocalVars && (RBM_FLT_CALLEE_SAVED != RBM_NONE))
4048     {
4049         // Build RefPositions for saving any live large vectors.
4050         // This must be done after the kills, so that we know which large vectors are still live.
4051         VarSetOps::AssignNoCopy(compiler, liveLargeVectors, buildUpperVectorSaveRefPositions(tree, currentLoc + 1));
4052     }
4053 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
4054
4055     ReturnTypeDesc* retTypeDesc    = nullptr;
4056     bool            isMultiRegCall = tree->IsMultiRegCall();
4057     if (isMultiRegCall)
4058     {
4059         retTypeDesc = tree->AsCall()->GetReturnTypeDesc();
4060         assert((int)genCountBits(candidates) == produce);
4061         assert(candidates == retTypeDesc->GetABIReturnRegs());
4062     }
4063
4064     // push defs
4065     LocationInfoList locationInfoList;
4066     LsraLocation     defLocation = currentLoc + 1;
4067 #ifdef ARM_SOFTFP
4068     regMaskTP remainingUseCandidates = useCandidates;
4069 #endif
4070     for (int i = 0; i < produce; i++)
4071     {
4072         regMaskTP currCandidates = candidates;
4073         Interval* interval       = varDefInterval;
4074
4075         // In case of multi-reg call node, registerType is given by
4076         // the type of ith position return register.
4077         if (isMultiRegCall)
4078         {
4079             registerType   = retTypeDesc->GetReturnRegType((unsigned)i);
4080             currCandidates = genRegMask(retTypeDesc->GetABIReturnReg(i));
4081             useCandidates  = allRegs(registerType);
4082         }
4083
4084 #ifdef _TARGET_ARM_
4085         if (tree->OperIsPutArgSplit())
4086         {
4087             // get i-th candidate
4088             currCandidates = genFindLowestReg(candidates);
4089             candidates &= ~currCandidates;
4090         }
4091 #ifdef ARM_SOFTFP
4092         // If oper is GT_PUTARG_REG, set bits in useCandidates must be in sequential order.
4093         else if (tree->OperGet() == GT_PUTARG_REG || tree->OperGet() == GT_COPY)
4094         {
4095             useCandidates = genFindLowestReg(remainingUseCandidates);
4096             remainingUseCandidates &= ~useCandidates;
4097         }
4098 #endif // ARM_SOFTFP
4099 #endif // _TARGET_ARM_
4100
4101         if (interval == nullptr)
4102         {
4103             // Make a new interval
4104             interval = newInterval(registerType);
4105             if (hasDelayFreeSrc)
4106             {
4107                 interval->hasNonCommutativeRMWDef = true;
4108             }
4109             else if (tree->OperIsConst())
4110             {
4111                 assert(!tree->IsReuseRegVal());
4112                 interval->isConstant = true;
4113             }
4114
4115             if ((currCandidates & useCandidates) != RBM_NONE)
4116             {
4117                 interval->updateRegisterPreferences(currCandidates & useCandidates);
4118             }
4119
4120             if (isSpecialPutArg)
4121             {
4122                 interval->isSpecialPutArg = true;
4123             }
4124         }
4125         else
4126         {
4127             assert(registerTypesEquivalent(interval->registerType, registerType));
4128         }
4129
4130         if (prefSrcInterval != nullptr)
4131         {
4132             interval->assignRelatedIntervalIfUnassigned(prefSrcInterval);
4133         }
4134
4135         // for assignments, we want to create a refposition for the def
4136         // but not push it
4137         if (!noAdd)
4138         {
4139             locationInfoList.Append(listNodePool.GetNode(defLocation, interval, tree, (unsigned)i));
4140         }
4141
4142         RefPosition* pos = newRefPosition(interval, defLocation, defRefType, defNode, currCandidates,
4143                                           (unsigned)i DEBUG_ARG(minRegCount));
4144         if (info.isLocalDefUse)
4145         {
4146             pos->isLocalDefUse = true;
4147             pos->lastUse       = true;
4148         }
4149         interval->updateRegisterPreferences(currCandidates);
4150         interval->updateRegisterPreferences(useCandidates);
4151     }
4152
4153 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
4154     // SaveDef position must be at the same location as Def position of call node.
4155     if (enregisterLocalVars)
4156     {
4157         buildUpperVectorRestoreRefPositions(tree, defLocation, liveLargeVectors);
4158     }
4159 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
4160
4161     if (!locationInfoList.IsEmpty())
4162     {
4163         bool added = operandToLocationInfoMap.AddOrUpdate(tree, locationInfoList);
4164         assert(added);
4165         tree->gtLsraInfo.definesAnyRegisters = true;
4166     }
4167     JITDUMP("\n");
4168 }
4169
4170 // make an interval for each physical register
4171 void LinearScan::buildPhysRegRecords()
4172 {
4173     RegisterType regType = IntRegisterType;
4174     for (regNumber reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
4175     {
4176         RegRecord* curr = &physRegs[reg];
4177         curr->init(reg);
4178     }
4179 }
4180
4181 BasicBlock* getNonEmptyBlock(BasicBlock* block)
4182 {
4183     while (block != nullptr && block->bbTreeList == nullptr)
4184     {
4185         BasicBlock* nextBlock = block->bbNext;
4186         // Note that here we use the version of NumSucc that does not take a compiler.
4187         // That way this doesn't have to take a compiler, or be an instance method, e.g. of LinearScan.
4188         // If we have an empty block, it must have jump type BBJ_NONE or BBJ_ALWAYS, in which
4189         // case we don't need the version that takes a compiler.
4190         assert(block->NumSucc() == 1 && ((block->bbJumpKind == BBJ_ALWAYS) || (block->bbJumpKind == BBJ_NONE)));
4191         // sometimes the first block is empty and ends with an uncond branch
4192         // assert( block->GetSucc(0) == nextBlock);
4193         block = nextBlock;
4194     }
4195     assert(block != nullptr && block->bbTreeList != nullptr);
4196     return block;
4197 }
4198
4199 //------------------------------------------------------------------------
4200 // insertZeroInitRefPositions: Handle lclVars that are live-in to the first block
4201 //
4202 // Notes:
4203 //    Prior to calling this method, 'currentLiveVars' must be set to the set of register
4204 //    candidate variables that are liveIn to the first block.
4205 //    For each register candidate that is live-in to the first block:
4206 //    - If it is a GC ref, or if compInitMem is set, a ZeroInit RefPosition will be created.
4207 //    - Otherwise, it will be marked as spilled, since it will not be assigned a register
4208 //      on entry and will be loaded from memory on the undefined path.
4209 //      Note that, when the compInitMem option is not set, we may encounter these on
4210 //      paths that are protected by the same condition as an earlier def. However, since
4211 //      we don't do the analysis to determine this - and couldn't rely on always identifying
4212 //      such cases even if we tried - we must conservatively treat the undefined path as
4213 //      being possible. This is a relatively rare case, so the introduced conservatism is
4214 //      not expected to warrant the analysis required to determine the best placement of
4215 //      an initialization.
4216 //
4217 void LinearScan::insertZeroInitRefPositions()
4218 {
4219     assert(enregisterLocalVars);
4220 #ifdef DEBUG
4221     VARSET_TP expectedLiveVars(VarSetOps::Intersection(compiler, registerCandidateVars, compiler->fgFirstBB->bbLiveIn));
4222     assert(VarSetOps::Equal(compiler, currentLiveVars, expectedLiveVars));
4223 #endif //  DEBUG
4224
4225     // insert defs for this, then a block boundary
4226
4227     VarSetOps::Iter iter(compiler, currentLiveVars);
4228     unsigned        varIndex = 0;
4229     while (iter.NextElem(&varIndex))
4230     {
4231         unsigned   varNum = compiler->lvaTrackedToVarNum[varIndex];
4232         LclVarDsc* varDsc = compiler->lvaTable + varNum;
4233         if (!varDsc->lvIsParam && isCandidateVar(varDsc))
4234         {
4235             JITDUMP("V%02u was live in to first block:", varNum);
4236             Interval* interval = getIntervalForLocalVar(varIndex);
4237             if (compiler->info.compInitMem || varTypeIsGC(varDsc->TypeGet()))
4238             {
4239                 JITDUMP(" creating ZeroInit\n");
4240                 GenTree*     firstNode = getNonEmptyBlock(compiler->fgFirstBB)->firstNode();
4241                 RefPosition* pos =
4242                     newRefPosition(interval, MinLocation, RefTypeZeroInit, firstNode, allRegs(interval->registerType));
4243                 varDsc->lvMustInit = true;
4244             }
4245             else
4246             {
4247                 setIntervalAsSpilled(interval);
4248                 JITDUMP(" marking as spilled\n");
4249             }
4250         }
4251     }
4252 }
4253
4254 #if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
4255 // -----------------------------------------------------------------------
4256 // Sets the register state for an argument of type STRUCT for System V systems.
4257 //     See Compiler::raUpdateRegStateForArg(RegState *regState, LclVarDsc *argDsc) in regalloc.cpp
4258 //         for how state for argument is updated for unix non-structs and Windows AMD64 structs.
4259 void LinearScan::unixAmd64UpdateRegStateForArg(LclVarDsc* argDsc)
4260 {
4261     assert(varTypeIsStruct(argDsc));
4262     RegState* intRegState   = &compiler->codeGen->intRegState;
4263     RegState* floatRegState = &compiler->codeGen->floatRegState;
4264
4265     if ((argDsc->lvArgReg != REG_STK) && (argDsc->lvArgReg != REG_NA))
4266     {
4267         if (genRegMask(argDsc->lvArgReg) & (RBM_ALLFLOAT))
4268         {
4269             assert(genRegMask(argDsc->lvArgReg) & (RBM_FLTARG_REGS));
4270             floatRegState->rsCalleeRegArgMaskLiveIn |= genRegMask(argDsc->lvArgReg);
4271         }
4272         else
4273         {
4274             assert(genRegMask(argDsc->lvArgReg) & (RBM_ARG_REGS));
4275             intRegState->rsCalleeRegArgMaskLiveIn |= genRegMask(argDsc->lvArgReg);
4276         }
4277     }
4278
4279     if ((argDsc->lvOtherArgReg != REG_STK) && (argDsc->lvOtherArgReg != REG_NA))
4280     {
4281         if (genRegMask(argDsc->lvOtherArgReg) & (RBM_ALLFLOAT))
4282         {
4283             assert(genRegMask(argDsc->lvOtherArgReg) & (RBM_FLTARG_REGS));
4284             floatRegState->rsCalleeRegArgMaskLiveIn |= genRegMask(argDsc->lvOtherArgReg);
4285         }
4286         else
4287         {
4288             assert(genRegMask(argDsc->lvOtherArgReg) & (RBM_ARG_REGS));
4289             intRegState->rsCalleeRegArgMaskLiveIn |= genRegMask(argDsc->lvOtherArgReg);
4290         }
4291     }
4292 }
4293
4294 #endif // defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
4295
4296 //------------------------------------------------------------------------
4297 // updateRegStateForArg: Updates rsCalleeRegArgMaskLiveIn for the appropriate
4298 //    regState (either compiler->intRegState or compiler->floatRegState),
4299 //    with the lvArgReg on "argDsc"
4300 //
4301 // Arguments:
4302 //    argDsc - the argument for which the state is to be updated.
4303 //
4304 // Return Value: None
4305 //
4306 // Assumptions:
4307 //    The argument is live on entry to the function
4308 //    (or is untracked and therefore assumed live)
4309 //
4310 // Notes:
4311 //    This relies on a method in regAlloc.cpp that is shared between LSRA
4312 //    and regAlloc.  It is further abstracted here because regState is updated
4313 //    separately for tracked and untracked variables in LSRA.
4314 //
4315 void LinearScan::updateRegStateForArg(LclVarDsc* argDsc)
4316 {
4317 #if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
4318     // For System V AMD64 calls the argDsc can have 2 registers (for structs.)
4319     // Handle them here.
4320     if (varTypeIsStruct(argDsc))
4321     {
4322         unixAmd64UpdateRegStateForArg(argDsc);
4323     }
4324     else
4325 #endif // defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
4326     {
4327         RegState* intRegState   = &compiler->codeGen->intRegState;
4328         RegState* floatRegState = &compiler->codeGen->floatRegState;
4329         // In the case of AMD64 we'll still use the floating point registers
4330         // to model the register usage for argument on vararg calls, so
4331         // we will ignore the varargs condition to determine whether we use
4332         // XMM registers or not for setting up the call.
4333         bool isFloat = (isFloatRegType(argDsc->lvType)
4334 #ifndef _TARGET_AMD64_
4335                         && !compiler->info.compIsVarArgs
4336 #endif
4337                         && !compiler->opts.compUseSoftFP);
4338
4339         if (argDsc->lvIsHfaRegArg())
4340         {
4341             isFloat = true;
4342         }
4343
4344         if (isFloat)
4345         {
4346             JITDUMP("Float arg V%02u in reg %s\n", (argDsc - compiler->lvaTable), getRegName(argDsc->lvArgReg));
4347             compiler->raUpdateRegStateForArg(floatRegState, argDsc);
4348         }
4349         else
4350         {
4351             JITDUMP("Int arg V%02u in reg %s\n", (argDsc - compiler->lvaTable), getRegName(argDsc->lvArgReg));
4352 #if FEATURE_MULTIREG_ARGS
4353             if (argDsc->lvOtherArgReg != REG_NA)
4354             {
4355                 JITDUMP("(second half) in reg %s\n", getRegName(argDsc->lvOtherArgReg));
4356             }
4357 #endif // FEATURE_MULTIREG_ARGS
4358             compiler->raUpdateRegStateForArg(intRegState, argDsc);
4359         }
4360     }
4361 }
4362
4363 //------------------------------------------------------------------------
4364 // findPredBlockForLiveIn: Determine which block should be used for the register locations of the live-in variables.
4365 //
4366 // Arguments:
4367 //    block                 - The block for which we're selecting a predecesor.
4368 //    prevBlock             - The previous block in in allocation order.
4369 //    pPredBlockIsAllocated - A debug-only argument that indicates whether any of the predecessors have been seen
4370 //                            in allocation order.
4371 //
4372 // Return Value:
4373 //    The selected predecessor.
4374 //
4375 // Assumptions:
4376 //    in DEBUG, caller initializes *pPredBlockIsAllocated to false, and it will be set to true if the block
4377 //    returned is in fact a predecessor.
4378 //
4379 // Notes:
4380 //    This will select a predecessor based on the heuristics obtained by getLsraBlockBoundaryLocations(), which can be
4381 //    one of:
4382 //      LSRA_BLOCK_BOUNDARY_PRED    - Use the register locations of a predecessor block (default)
4383 //      LSRA_BLOCK_BOUNDARY_LAYOUT  - Use the register locations of the previous block in layout order.
4384 //                                    This is the only case where this actually returns a different block.
4385 //      LSRA_BLOCK_BOUNDARY_ROTATE  - Rotate the register locations from a predecessor.
4386 //                                    For this case, the block returned is the same as for LSRA_BLOCK_BOUNDARY_PRED, but
4387 //                                    the register locations will be "rotated" to stress the resolution and allocation
4388 //                                    code.
4389
4390 BasicBlock* LinearScan::findPredBlockForLiveIn(BasicBlock* block,
4391                                                BasicBlock* prevBlock DEBUGARG(bool* pPredBlockIsAllocated))
4392 {
4393     BasicBlock* predBlock = nullptr;
4394 #ifdef DEBUG
4395     assert(*pPredBlockIsAllocated == false);
4396     if (getLsraBlockBoundaryLocations() == LSRA_BLOCK_BOUNDARY_LAYOUT)
4397     {
4398         if (prevBlock != nullptr)
4399         {
4400             predBlock = prevBlock;
4401         }
4402     }
4403     else
4404 #endif // DEBUG
4405         if (block != compiler->fgFirstBB)
4406     {
4407         predBlock = block->GetUniquePred(compiler);
4408         if (predBlock != nullptr)
4409         {
4410             if (isBlockVisited(predBlock))
4411             {
4412                 if (predBlock->bbJumpKind == BBJ_COND)
4413                 {
4414                     // Special handling to improve matching on backedges.
4415                     BasicBlock* otherBlock = (block == predBlock->bbNext) ? predBlock->bbJumpDest : predBlock->bbNext;
4416                     noway_assert(otherBlock != nullptr);
4417                     if (isBlockVisited(otherBlock))
4418                     {
4419                         // This is the case when we have a conditional branch where one target has already
4420                         // been visited.  It would be best to use the same incoming regs as that block,
4421                         // so that we have less likelihood of having to move registers.
4422                         // For example, in determining the block to use for the starting register locations for
4423                         // "block" in the following example, we'd like to use the same predecessor for "block"
4424                         // as for "otherBlock", so that both successors of predBlock have the same locations, reducing
4425                         // the likelihood of needing a split block on a backedge:
4426                         //
4427                         //   otherPred
4428                         //       |
4429                         //   otherBlock <-+
4430                         //     . . .      |
4431                         //                |
4432                         //   predBlock----+
4433                         //       |
4434                         //     block
4435                         //
4436                         for (flowList* pred = otherBlock->bbPreds; pred != nullptr; pred = pred->flNext)
4437                         {
4438                             BasicBlock* otherPred = pred->flBlock;
4439                             if (otherPred->bbNum == blockInfo[otherBlock->bbNum].predBBNum)
4440                             {
4441                                 predBlock = otherPred;
4442                                 break;
4443                             }
4444                         }
4445                     }
4446                 }
4447             }
4448             else
4449             {
4450                 predBlock = nullptr;
4451             }
4452         }
4453         else
4454         {
4455             for (flowList* pred = block->bbPreds; pred != nullptr; pred = pred->flNext)
4456             {
4457                 BasicBlock* candidatePredBlock = pred->flBlock;
4458                 if (isBlockVisited(candidatePredBlock))
4459                 {
4460                     if (predBlock == nullptr || predBlock->bbWeight < candidatePredBlock->bbWeight)
4461                     {
4462                         predBlock = candidatePredBlock;
4463                         INDEBUG(*pPredBlockIsAllocated = true;)
4464                     }
4465                 }
4466             }
4467         }
4468         if (predBlock == nullptr)
4469         {
4470             predBlock = prevBlock;
4471             assert(predBlock != nullptr);
4472             JITDUMP("\n\nNo allocated predecessor; ");
4473         }
4474     }
4475     return predBlock;
4476 }
4477
4478 void LinearScan::buildIntervals()
4479 {
4480     BasicBlock* block;
4481
4482     // start numbering at 1; 0 is the entry
4483     LsraLocation currentLoc = 1;
4484
4485     JITDUMP("\nbuildIntervals ========\n");
4486
4487     // Now build (empty) records for all of the physical registers
4488     buildPhysRegRecords();
4489
4490 #ifdef DEBUG
4491     if (VERBOSE)
4492     {
4493         printf("\n-----------------\n");
4494         printf("LIVENESS:\n");
4495         printf("-----------------\n");
4496         foreach_block(compiler, block)
4497         {
4498             printf("BB%02u use def in out\n", block->bbNum);
4499             dumpConvertedVarSet(compiler, block->bbVarUse);
4500             printf("\n");
4501             dumpConvertedVarSet(compiler, block->bbVarDef);
4502             printf("\n");
4503             dumpConvertedVarSet(compiler, block->bbLiveIn);
4504             printf("\n");
4505             dumpConvertedVarSet(compiler, block->bbLiveOut);
4506             printf("\n");
4507         }
4508     }
4509 #endif // DEBUG
4510
4511 #if DOUBLE_ALIGN
4512     // We will determine whether we should double align the frame during
4513     // identifyCandidates(), but we initially assume that we will not.
4514     doDoubleAlign = false;
4515 #endif
4516
4517     identifyCandidates();
4518
4519     // Figure out if we're going to use a frame pointer. We need to do this before building
4520     // the ref positions, because those objects will embed the frame register in various register masks
4521     // if the frame pointer is not reserved. If we decide to have a frame pointer, setFrameType() will
4522     // remove the frame pointer from the masks.
4523     setFrameType();
4524
4525     DBEXEC(VERBOSE, TupleStyleDump(LSRA_DUMP_PRE));
4526
4527     // second part:
4528     JITDUMP("\nbuildIntervals second part ========\n");
4529     currentLoc = 0;
4530
4531     // Next, create ParamDef RefPositions for all the tracked parameters,
4532     // in order of their varIndex
4533
4534     LclVarDsc*   argDsc;
4535     unsigned int lclNum;
4536
4537     RegState* intRegState                   = &compiler->codeGen->intRegState;
4538     RegState* floatRegState                 = &compiler->codeGen->floatRegState;
4539     intRegState->rsCalleeRegArgMaskLiveIn   = RBM_NONE;
4540     floatRegState->rsCalleeRegArgMaskLiveIn = RBM_NONE;
4541
4542     for (unsigned int varIndex = 0; varIndex < compiler->lvaTrackedCount; varIndex++)
4543     {
4544         lclNum = compiler->lvaTrackedToVarNum[varIndex];
4545         argDsc = &(compiler->lvaTable[lclNum]);
4546
4547         if (!argDsc->lvIsParam)
4548         {
4549             continue;
4550         }
4551
4552         // Only reserve a register if the argument is actually used.
4553         // Is it dead on entry? If compJmpOpUsed is true, then the arguments
4554         // have to be kept alive, so we have to consider it as live on entry.
4555         // Use lvRefCnt instead of checking bbLiveIn because if it's volatile we
4556         // won't have done dataflow on it, but it needs to be marked as live-in so
4557         // it will get saved in the prolog.
4558         if (!compiler->compJmpOpUsed && argDsc->lvRefCnt == 0 && !compiler->opts.compDbgCode)
4559         {
4560             continue;
4561         }
4562
4563         if (argDsc->lvIsRegArg)
4564         {
4565             updateRegStateForArg(argDsc);
4566         }
4567
4568         if (isCandidateVar(argDsc))
4569         {
4570             Interval* interval = getIntervalForLocalVar(varIndex);
4571             regMaskTP mask     = allRegs(TypeGet(argDsc));
4572             if (argDsc->lvIsRegArg)
4573             {
4574                 // Set this interval as currently assigned to that register
4575                 regNumber inArgReg = argDsc->lvArgReg;
4576                 assert(inArgReg < REG_COUNT);
4577                 mask = genRegMask(inArgReg);
4578                 assignPhysReg(inArgReg, interval);
4579             }
4580             RefPosition* pos = newRefPosition(interval, MinLocation, RefTypeParamDef, nullptr, mask);
4581         }
4582         else if (varTypeIsStruct(argDsc->lvType))
4583         {
4584             for (unsigned fieldVarNum = argDsc->lvFieldLclStart;
4585                  fieldVarNum < argDsc->lvFieldLclStart + argDsc->lvFieldCnt; ++fieldVarNum)
4586             {
4587                 LclVarDsc* fieldVarDsc = &(compiler->lvaTable[fieldVarNum]);
4588                 if (fieldVarDsc->lvLRACandidate)
4589                 {
4590                     assert(fieldVarDsc->lvTracked);
4591                     Interval*    interval = getIntervalForLocalVar(fieldVarDsc->lvVarIndex);
4592                     RefPosition* pos =
4593                         newRefPosition(interval, MinLocation, RefTypeParamDef, nullptr, allRegs(TypeGet(fieldVarDsc)));
4594                 }
4595             }
4596         }
4597         else
4598         {
4599             // We can overwrite the register (i.e. codegen saves it on entry)
4600             assert(argDsc->lvRefCnt == 0 || !argDsc->lvIsRegArg || argDsc->lvDoNotEnregister ||
4601                    !argDsc->lvLRACandidate || (varTypeIsFloating(argDsc->TypeGet()) && compiler->opts.compDbgCode));
4602         }
4603     }
4604
4605     // Now set up the reg state for the non-tracked args
4606     // (We do this here because we want to generate the ParamDef RefPositions in tracked
4607     // order, so that loop doesn't hit the non-tracked args)
4608
4609     for (unsigned argNum = 0; argNum < compiler->info.compArgsCount; argNum++, argDsc++)
4610     {
4611         argDsc = &(compiler->lvaTable[argNum]);
4612
4613         if (argDsc->lvPromotedStruct())
4614         {
4615             noway_assert(argDsc->lvFieldCnt == 1); // We only handle one field here
4616
4617             unsigned fieldVarNum = argDsc->lvFieldLclStart;
4618             argDsc               = &(compiler->lvaTable[fieldVarNum]);
4619         }
4620         noway_assert(argDsc->lvIsParam);
4621         if (!argDsc->lvTracked && argDsc->lvIsRegArg)
4622         {
4623             updateRegStateForArg(argDsc);
4624         }
4625     }
4626
4627     // If there is a secret stub param, it is also live in
4628     if (compiler->info.compPublishStubParam)
4629     {
4630         intRegState->rsCalleeRegArgMaskLiveIn |= RBM_SECRET_STUB_PARAM;
4631     }
4632
4633     LocationInfoListNodePool listNodePool(compiler, 8);
4634     SmallHashTable<GenTree*, LocationInfoList, 32> operandToLocationInfoMap(compiler);
4635
4636     BasicBlock* predBlock = nullptr;
4637     BasicBlock* prevBlock = nullptr;
4638
4639     // Initialize currentLiveVars to the empty set.  We will set it to the current
4640     // live-in at the entry to each block (this will include the incoming args on
4641     // the first block).
4642     VarSetOps::AssignNoCopy(compiler, currentLiveVars, VarSetOps::MakeEmpty(compiler));
4643
4644     for (block = startBlockSequence(); block != nullptr; block = moveToNextBlock())
4645     {
4646         JITDUMP("\nNEW BLOCK BB%02u\n", block->bbNum);
4647
4648         bool predBlockIsAllocated = false;
4649         predBlock                 = findPredBlockForLiveIn(block, prevBlock DEBUGARG(&predBlockIsAllocated));
4650         if (predBlock)
4651         {
4652             JITDUMP("\n\nSetting BB%02u as the predecessor for determining incoming variable registers of BB%02u\n",
4653                     block->bbNum, predBlock->bbNum);
4654             assert(predBlock->bbNum <= bbNumMaxBeforeResolution);
4655             blockInfo[block->bbNum].predBBNum = predBlock->bbNum;
4656         }
4657
4658         if (enregisterLocalVars)
4659         {
4660             VarSetOps::AssignNoCopy(compiler, currentLiveVars,
4661                                     VarSetOps::Intersection(compiler, registerCandidateVars, block->bbLiveIn));
4662
4663             if (block == compiler->fgFirstBB)
4664             {
4665                 insertZeroInitRefPositions();
4666             }
4667
4668             // Any lclVars live-in to a block are resolution candidates.
4669             VarSetOps::UnionD(compiler, resolutionCandidateVars, currentLiveVars);
4670
4671             // Determine if we need any DummyDefs.
4672             // We need DummyDefs for cases where "predBlock" isn't really a predecessor.
4673             // Note that it's possible to have uses of unitialized variables, in which case even the first
4674             // block may require DummyDefs, which we are not currently adding - this means that these variables
4675             // will always be considered to be in memory on entry (and reloaded when the use is encountered).
4676             // TODO-CQ: Consider how best to tune this.  Currently, if we create DummyDefs for uninitialized
4677             // variables (which may actually be initialized along the dynamically executed paths, but not
4678             // on all static paths), we wind up with excessive liveranges for some of these variables.
4679             VARSET_TP newLiveIn(VarSetOps::MakeCopy(compiler, currentLiveVars));
4680             if (predBlock)
4681             {
4682                 // Compute set difference: newLiveIn = currentLiveVars - predBlock->bbLiveOut
4683                 VarSetOps::DiffD(compiler, newLiveIn, predBlock->bbLiveOut);
4684             }
4685             bool needsDummyDefs = (!VarSetOps::IsEmpty(compiler, newLiveIn) && block != compiler->fgFirstBB);
4686
4687             // Create dummy def RefPositions
4688
4689             if (needsDummyDefs)
4690             {
4691                 // If we are using locations from a predecessor, we should never require DummyDefs.
4692                 assert(!predBlockIsAllocated);
4693
4694                 JITDUMP("Creating dummy definitions\n");
4695                 VarSetOps::Iter iter(compiler, newLiveIn);
4696                 unsigned        varIndex = 0;
4697                 while (iter.NextElem(&varIndex))
4698                 {
4699                     unsigned   varNum = compiler->lvaTrackedToVarNum[varIndex];
4700                     LclVarDsc* varDsc = compiler->lvaTable + varNum;
4701                     // Add a dummyDef for any candidate vars that are in the "newLiveIn" set.
4702                     // If this is the entry block, don't add any incoming parameters (they're handled with ParamDefs).
4703                     if (isCandidateVar(varDsc) && (predBlock != nullptr || !varDsc->lvIsParam))
4704                     {
4705                         Interval*    interval = getIntervalForLocalVar(varIndex);
4706                         RefPosition* pos      = newRefPosition(interval, currentLoc, RefTypeDummyDef, nullptr,
4707                                                           allRegs(interval->registerType));
4708                     }
4709                 }
4710                 JITDUMP("Finished creating dummy definitions\n\n");
4711             }
4712         }
4713
4714         // Add a dummy RefPosition to mark the block boundary.
4715         // Note that we do this AFTER adding the exposed uses above, because the
4716         // register positions for those exposed uses need to be recorded at
4717         // this point.
4718
4719         RefPosition* pos = newRefPosition((Interval*)nullptr, currentLoc, RefTypeBB, nullptr, RBM_NONE);
4720         JITDUMP("\n");
4721
4722         LIR::Range& blockRange = LIR::AsRange(block);
4723         for (GenTree* node : blockRange.NonPhiNodes())
4724         {
4725             assert(node->gtLsraInfo.loc >= currentLoc);
4726             assert(!node->IsValue() || !node->IsUnusedValue() || node->gtLsraInfo.isLocalDefUse);
4727
4728             currentLoc = node->gtLsraInfo.loc;
4729             buildRefPositionsForNode(node, block, listNodePool, operandToLocationInfoMap, currentLoc);
4730
4731 #ifdef DEBUG
4732             if (currentLoc > maxNodeLocation)
4733             {
4734                 maxNodeLocation = currentLoc;
4735             }
4736 #endif // DEBUG
4737         }
4738
4739         // Increment the LsraLocation at this point, so that the dummy RefPositions
4740         // will not have the same LsraLocation as any "real" RefPosition.
4741         currentLoc += 2;
4742
4743         // Note: the visited set is cleared in LinearScan::doLinearScan()
4744         markBlockVisited(block);
4745
4746         if (enregisterLocalVars)
4747         {
4748             // Insert exposed uses for a lclVar that is live-out of 'block' but not live-in to the
4749             // next block, or any unvisited successors.
4750             // This will address lclVars that are live on a backedge, as well as those that are kept
4751             // live at a GT_JMP.
4752             //
4753             // Blocks ending with "jmp method" are marked as BBJ_HAS_JMP,
4754             // and jmp call is represented using GT_JMP node which is a leaf node.
4755             // Liveness phase keeps all the arguments of the method live till the end of
4756             // block by adding them to liveout set of the block containing GT_JMP.
4757             //
4758             // The target of a GT_JMP implicitly uses all the current method arguments, however
4759             // there are no actual references to them.  This can cause LSRA to assert, because
4760             // the variables are live but it sees no references.  In order to correctly model the
4761             // liveness of these arguments, we add dummy exposed uses, in the same manner as for
4762             // backward branches.  This will happen automatically via expUseSet.
4763             //
4764             // Note that a block ending with GT_JMP has no successors and hence the variables
4765             // for which dummy use ref positions are added are arguments of the method.
4766
4767             VARSET_TP expUseSet(VarSetOps::MakeCopy(compiler, block->bbLiveOut));
4768             VarSetOps::IntersectionD(compiler, expUseSet, registerCandidateVars);
4769             BasicBlock* nextBlock = getNextBlock();
4770             if (nextBlock != nullptr)
4771             {
4772                 VarSetOps::DiffD(compiler, expUseSet, nextBlock->bbLiveIn);
4773             }
4774             for (BasicBlock* succ : block->GetAllSuccs(compiler))
4775             {
4776                 if (VarSetOps::IsEmpty(compiler, expUseSet))
4777                 {
4778                     break;
4779                 }
4780
4781                 if (isBlockVisited(succ))
4782                 {
4783                     continue;
4784                 }
4785                 VarSetOps::DiffD(compiler, expUseSet, succ->bbLiveIn);
4786             }
4787
4788             if (!VarSetOps::IsEmpty(compiler, expUseSet))
4789             {
4790                 JITDUMP("Exposed uses:");
4791                 VarSetOps::Iter iter(compiler, expUseSet);
4792                 unsigned        varIndex = 0;
4793                 while (iter.NextElem(&varIndex))
4794                 {
4795                     unsigned   varNum = compiler->lvaTrackedToVarNum[varIndex];
4796                     LclVarDsc* varDsc = compiler->lvaTable + varNum;
4797                     assert(isCandidateVar(varDsc));
4798                     Interval*    interval = getIntervalForLocalVar(varIndex);
4799                     RefPosition* pos =
4800                         newRefPosition(interval, currentLoc, RefTypeExpUse, nullptr, allRegs(interval->registerType));
4801                     JITDUMP(" V%02u", varNum);
4802                 }
4803                 JITDUMP("\n");
4804             }
4805
4806             // Clear the "last use" flag on any vars that are live-out from this block.
4807             {
4808                 VarSetOps::Iter iter(compiler, block->bbLiveOut);
4809                 unsigned        varIndex = 0;
4810                 while (iter.NextElem(&varIndex))
4811                 {
4812                     unsigned         varNum = compiler->lvaTrackedToVarNum[varIndex];
4813                     LclVarDsc* const varDsc = &compiler->lvaTable[varNum];
4814                     if (isCandidateVar(varDsc))
4815                     {
4816                         RefPosition* const lastRP = getIntervalForLocalVar(varIndex)->lastRefPosition;
4817                         if ((lastRP != nullptr) && (lastRP->bbNum == block->bbNum))
4818                         {
4819                             lastRP->lastUse = false;
4820                         }
4821                     }
4822                 }
4823             }
4824
4825 #ifdef DEBUG
4826             checkLastUses(block);
4827
4828             if (VERBOSE)
4829             {
4830                 printf("use: ");
4831                 dumpConvertedVarSet(compiler, block->bbVarUse);
4832                 printf("\ndef: ");
4833                 dumpConvertedVarSet(compiler, block->bbVarDef);
4834                 printf("\n");
4835             }
4836 #endif // DEBUG
4837         }
4838
4839         prevBlock = block;
4840     }
4841
4842     if (enregisterLocalVars)
4843     {
4844         if (compiler->lvaKeepAliveAndReportThis())
4845         {
4846             // If we need to KeepAliveAndReportThis, add a dummy exposed use of it at the end
4847             unsigned keepAliveVarNum = compiler->info.compThisArg;
4848             assert(compiler->info.compIsStatic == false);
4849             LclVarDsc* varDsc = compiler->lvaTable + keepAliveVarNum;
4850             if (isCandidateVar(varDsc))
4851             {
4852                 JITDUMP("Adding exposed use of this, for lvaKeepAliveAndReportThis\n");
4853                 Interval*    interval = getIntervalForLocalVar(varDsc->lvVarIndex);
4854                 RefPosition* pos =
4855                     newRefPosition(interval, currentLoc, RefTypeExpUse, nullptr, allRegs(interval->registerType));
4856             }
4857         }
4858
4859 #ifdef DEBUG
4860         if (getLsraExtendLifeTimes())
4861         {
4862             LclVarDsc* varDsc;
4863             for (lclNum = 0, varDsc = compiler->lvaTable; lclNum < compiler->lvaCount; lclNum++, varDsc++)
4864             {
4865                 if (varDsc->lvLRACandidate)
4866                 {
4867                     JITDUMP("Adding exposed use of V%02u for LsraExtendLifetimes\n", lclNum);
4868                     Interval*    interval = getIntervalForLocalVar(varDsc->lvVarIndex);
4869                     RefPosition* pos =
4870                         newRefPosition(interval, currentLoc, RefTypeExpUse, nullptr, allRegs(interval->registerType));
4871                 }
4872             }
4873         }
4874 #endif // DEBUG
4875     }
4876
4877     // If the last block has successors, create a RefTypeBB to record
4878     // what's live
4879
4880     if (prevBlock->NumSucc(compiler) > 0)
4881     {
4882         RefPosition* pos = newRefPosition((Interval*)nullptr, currentLoc, RefTypeBB, nullptr, RBM_NONE);
4883     }
4884
4885 #ifdef DEBUG
4886     // Make sure we don't have any blocks that were not visited
4887     foreach_block(compiler, block)
4888     {
4889         assert(isBlockVisited(block));
4890     }
4891
4892     if (VERBOSE)
4893     {
4894         lsraDumpIntervals("BEFORE VALIDATING INTERVALS");
4895         dumpRefPositions("BEFORE VALIDATING INTERVALS");
4896         validateIntervals();
4897     }
4898 #endif // DEBUG
4899 }
4900
4901 #ifdef DEBUG
4902 void LinearScan::dumpVarRefPositions(const char* title)
4903 {
4904     if (enregisterLocalVars)
4905     {
4906         printf("\nVAR REFPOSITIONS %s\n", title);
4907
4908         for (unsigned i = 0; i < compiler->lvaCount; i++)
4909         {
4910             printf("--- V%02u\n", i);
4911
4912             LclVarDsc* varDsc = compiler->lvaTable + i;
4913             if (varDsc->lvIsRegCandidate())
4914             {
4915                 Interval* interval = getIntervalForLocalVar(varDsc->lvVarIndex);
4916                 for (RefPosition* ref = interval->firstRefPosition; ref != nullptr; ref = ref->nextRefPosition)
4917                 {
4918                     ref->dump();
4919                 }
4920             }
4921         }
4922         printf("\n");
4923     }
4924 }
4925
4926 void LinearScan::validateIntervals()
4927 {
4928     if (enregisterLocalVars)
4929     {
4930         for (unsigned i = 0; i < compiler->lvaTrackedCount; i++)
4931         {
4932             if (!compiler->lvaTable[compiler->lvaTrackedToVarNum[i]].lvLRACandidate)
4933             {
4934                 continue;
4935             }
4936             Interval* interval = getIntervalForLocalVar(i);
4937
4938             bool defined = false;
4939             printf("-----------------\n");
4940             for (RefPosition* ref = interval->firstRefPosition; ref != nullptr; ref = ref->nextRefPosition)
4941             {
4942                 ref->dump();
4943                 RefType refType = ref->refType;
4944                 if (!defined && RefTypeIsUse(refType))
4945                 {
4946                     if (compiler->info.compMethodName != nullptr)
4947                     {
4948                         printf("%s: ", compiler->info.compMethodName);
4949                     }
4950                     printf("LocalVar V%02u: undefined use at %u\n", interval->varNum, ref->nodeLocation);
4951                 }
4952                 // Note that there can be multiple last uses if they are on disjoint paths,
4953                 // so we can't really check the lastUse flag
4954                 if (ref->lastUse)
4955                 {
4956                     defined = false;
4957                 }
4958                 if (RefTypeIsDef(refType))
4959                 {
4960                     defined = true;
4961                 }
4962             }
4963         }
4964     }
4965 }
4966 #endif // DEBUG
4967
4968 // Set the default rpFrameType based upon codeGen->isFramePointerRequired()
4969 // This was lifted from the register predictor
4970 //
4971 void LinearScan::setFrameType()
4972 {
4973     FrameType frameType = FT_NOT_SET;
4974 #if DOUBLE_ALIGN
4975     compiler->codeGen->setDoubleAlign(false);
4976     if (doDoubleAlign)
4977     {
4978         frameType = FT_DOUBLE_ALIGN_FRAME;
4979         compiler->codeGen->setDoubleAlign(true);
4980     }
4981     else
4982 #endif // DOUBLE_ALIGN
4983         if (compiler->codeGen->isFramePointerRequired())
4984     {
4985         frameType = FT_EBP_FRAME;
4986     }
4987     else
4988     {
4989         if (compiler->rpMustCreateEBPCalled == false)
4990         {
4991 #ifdef DEBUG
4992             const char* reason;
4993 #endif // DEBUG
4994             compiler->rpMustCreateEBPCalled = true;
4995             if (compiler->rpMustCreateEBPFrame(INDEBUG(&reason)))
4996             {
4997                 JITDUMP("; Decided to create an EBP based frame for ETW stackwalking (%s)\n", reason);
4998                 compiler->codeGen->setFrameRequired(true);
4999             }
5000         }
5001
5002         if (compiler->codeGen->isFrameRequired())
5003         {
5004             frameType = FT_EBP_FRAME;
5005         }
5006         else
5007         {
5008             frameType = FT_ESP_FRAME;
5009         }
5010     }
5011
5012     switch (frameType)
5013     {
5014         case FT_ESP_FRAME:
5015             noway_assert(!compiler->codeGen->isFramePointerRequired());
5016             noway_assert(!compiler->codeGen->isFrameRequired());
5017             compiler->codeGen->setFramePointerUsed(false);
5018             break;
5019         case FT_EBP_FRAME:
5020             compiler->codeGen->setFramePointerUsed(true);
5021             break;
5022 #if DOUBLE_ALIGN
5023         case FT_DOUBLE_ALIGN_FRAME:
5024             noway_assert(!compiler->codeGen->isFramePointerRequired());
5025             compiler->codeGen->setFramePointerUsed(false);
5026             break;
5027 #endif // DOUBLE_ALIGN
5028         default:
5029             noway_assert(!"rpFrameType not set correctly!");
5030             break;
5031     }
5032
5033     // If we are using FPBASE as the frame register, we cannot also use it for
5034     // a local var. Note that we may have already added it to the register masks,
5035     // which are computed when the LinearScan class constructor is created, and
5036     // used during lowering. Luckily, the TreeNodeInfo only stores an index to
5037     // the masks stored in the LinearScan class, so we only need to walk the
5038     // unique masks and remove FPBASE.
5039     if (frameType == FT_EBP_FRAME)
5040     {
5041         if ((availableIntRegs & RBM_FPBASE) != 0)
5042         {
5043             RemoveRegisterFromMasks(REG_FPBASE);
5044
5045             // We know that we're already in "read mode" for availableIntRegs. However,
5046             // we need to remove the FPBASE register, so subsequent users (like callers
5047             // to allRegs()) get the right thing. The RemoveRegisterFromMasks() code
5048             // fixes up everything that already took a dependency on the value that was
5049             // previously read, so this completes the picture.
5050             availableIntRegs.OverrideAssign(availableIntRegs & ~RBM_FPBASE);
5051         }
5052     }
5053
5054     compiler->rpFrameType = frameType;
5055 }
5056
5057 // Is the copyReg/moveReg given by this RefPosition still busy at the
5058 // given location?
5059 bool copyOrMoveRegInUse(RefPosition* ref, LsraLocation loc)
5060 {
5061     assert(ref->copyReg || ref->moveReg);
5062     if (ref->getRefEndLocation() >= loc)
5063     {
5064         return true;
5065     }
5066     Interval*    interval = ref->getInterval();
5067     RefPosition* nextRef  = interval->getNextRefPosition();
5068     if (nextRef != nullptr && nextRef->treeNode == ref->treeNode && nextRef->getRefEndLocation() >= loc)
5069     {
5070         return true;
5071     }
5072     return false;
5073 }
5074
5075 // Determine whether the register represented by "physRegRecord" is available at least
5076 // at the "currentLoc", and if so, return the next location at which it is in use in
5077 // "nextRefLocationPtr"
5078 //
5079 bool LinearScan::registerIsAvailable(RegRecord*    physRegRecord,
5080                                      LsraLocation  currentLoc,
5081                                      LsraLocation* nextRefLocationPtr,
5082                                      RegisterType  regType)
5083 {
5084     *nextRefLocationPtr          = MaxLocation;
5085     LsraLocation nextRefLocation = MaxLocation;
5086     regMaskTP    regMask         = genRegMask(physRegRecord->regNum);
5087     if (physRegRecord->isBusyUntilNextKill)
5088     {
5089         return false;
5090     }
5091
5092     RefPosition* nextPhysReference = physRegRecord->getNextRefPosition();
5093     if (nextPhysReference != nullptr)
5094     {
5095         nextRefLocation = nextPhysReference->nodeLocation;
5096         // if (nextPhysReference->refType == RefTypeFixedReg) nextRefLocation--;
5097     }
5098     else if (!physRegRecord->isCalleeSave)
5099     {
5100         nextRefLocation = MaxLocation - 1;
5101     }
5102
5103     Interval* assignedInterval = physRegRecord->assignedInterval;
5104
5105     if (assignedInterval != nullptr)
5106     {
5107         RefPosition* recentReference = assignedInterval->recentRefPosition;
5108
5109         // The only case where we have an assignedInterval, but recentReference is null
5110         // is where this interval is live at procedure entry (i.e. an arg register), in which
5111         // case it's still live and its assigned register is not available
5112         // (Note that the ParamDef will be recorded as a recentReference when we encounter
5113         // it, but we will be allocating registers, potentially to other incoming parameters,
5114         // as we process the ParamDefs.)
5115
5116         if (recentReference == nullptr)
5117         {
5118             return false;
5119         }
5120
5121         // Is this a copyReg/moveReg?  It is if the register assignment doesn't match.
5122         // (the recentReference may not be a copyReg/moveReg, because we could have seen another
5123         // reference since the copyReg/moveReg)
5124
5125         if (!assignedInterval->isAssignedTo(physRegRecord->regNum))
5126         {
5127             // Don't reassign it if it's still in use
5128             if ((recentReference->copyReg || recentReference->moveReg) &&
5129                 copyOrMoveRegInUse(recentReference, currentLoc))
5130             {
5131                 return false;
5132             }
5133         }
5134         else if (!assignedInterval->isActive && assignedInterval->isConstant)
5135         {
5136             // Treat this as unassigned, i.e. do nothing.
5137             // TODO-CQ: Consider adjusting the heuristics (probably in the caller of this method)
5138             // to avoid reusing these registers.
5139         }
5140         // If this interval isn't active, it's available if it isn't referenced
5141         // at this location (or the previous location, if the recent RefPosition
5142         // is a delayRegFree).
5143         else if (!assignedInterval->isActive &&
5144                  (recentReference->refType == RefTypeExpUse || recentReference->getRefEndLocation() < currentLoc))
5145         {
5146             // This interval must have a next reference (otherwise it wouldn't be assigned to this register)
5147             RefPosition* nextReference = recentReference->nextRefPosition;
5148             if (nextReference != nullptr)
5149             {
5150                 if (nextReference->nodeLocation < nextRefLocation)
5151                 {
5152                     nextRefLocation = nextReference->nodeLocation;
5153                 }
5154             }
5155             else
5156             {
5157                 assert(recentReference->copyReg && recentReference->registerAssignment != regMask);
5158             }
5159         }
5160         else
5161         {
5162             return false;
5163         }
5164     }
5165     if (nextRefLocation < *nextRefLocationPtr)
5166     {
5167         *nextRefLocationPtr = nextRefLocation;
5168     }
5169
5170 #ifdef _TARGET_ARM_
5171     if (regType == TYP_DOUBLE)
5172     {
5173         // Recurse, but check the other half this time (TYP_FLOAT)
5174         if (!registerIsAvailable(getRegisterRecord(REG_NEXT(physRegRecord->regNum)), currentLoc, nextRefLocationPtr,
5175                                  TYP_FLOAT))
5176             return false;
5177         nextRefLocation = *nextRefLocationPtr;
5178     }
5179 #endif // _TARGET_ARM_
5180
5181     return (nextRefLocation >= currentLoc);
5182 }
5183
5184 //------------------------------------------------------------------------
5185 // getRegisterType: Get the RegisterType to use for the given RefPosition
5186 //
5187 // Arguments:
5188 //    currentInterval: The interval for the current allocation
5189 //    refPosition:     The RefPosition of the current Interval for which a register is being allocated
5190 //
5191 // Return Value:
5192 //    The RegisterType that should be allocated for this RefPosition
5193 //
5194 // Notes:
5195 //    This will nearly always be identical to the registerType of the interval, except in the case
5196 //    of SIMD types of 8 bytes (currently only Vector2) when they are passed and returned in integer
5197 //    registers, or copied to a return temp.
5198 //    This method need only be called in situations where we may be dealing with the register requirements
5199 //    of a RefTypeUse RefPosition (i.e. not when we are only looking at the type of an interval, nor when
5200 //    we are interested in the "defining" type of the interval).  This is because the situation of interest
5201 //    only happens at the use (where it must be copied to an integer register).
5202
5203 RegisterType LinearScan::getRegisterType(Interval* currentInterval, RefPosition* refPosition)
5204 {
5205     assert(refPosition->getInterval() == currentInterval);
5206     RegisterType regType    = currentInterval->registerType;
5207     regMaskTP    candidates = refPosition->registerAssignment;
5208
5209     assert((candidates & allRegs(regType)) != RBM_NONE);
5210     return regType;
5211 }
5212
5213 //------------------------------------------------------------------------
5214 // tryAllocateFreeReg: Find a free register that satisfies the requirements for refPosition,
5215 //                     and takes into account the preferences for the given Interval
5216 //
5217 // Arguments:
5218 //    currentInterval: The interval for the current allocation
5219 //    refPosition:     The RefPosition of the current Interval for which a register is being allocated
5220 //
5221 // Return Value:
5222 //    The regNumber, if any, allocated to the RefPositon.  Returns REG_NA if no free register is found.
5223 //
5224 // Notes:
5225 //    TODO-CQ: Consider whether we need to use a different order for tree temps than for vars, as
5226 //    reg predict does
5227
5228 static const regNumber lsraRegOrder[]      = {REG_VAR_ORDER};
5229 const unsigned         lsraRegOrderSize    = ArrLen(lsraRegOrder);
5230 static const regNumber lsraRegOrderFlt[]   = {REG_VAR_ORDER_FLT};
5231 const unsigned         lsraRegOrderFltSize = ArrLen(lsraRegOrderFlt);
5232
5233 regNumber LinearScan::tryAllocateFreeReg(Interval* currentInterval, RefPosition* refPosition)
5234 {
5235     regNumber foundReg = REG_NA;
5236
5237     RegisterType     regType = getRegisterType(currentInterval, refPosition);
5238     const regNumber* regOrder;
5239     unsigned         regOrderSize;
5240     if (useFloatReg(regType))
5241     {
5242         regOrder     = lsraRegOrderFlt;
5243         regOrderSize = lsraRegOrderFltSize;
5244     }
5245     else
5246     {
5247         regOrder     = lsraRegOrder;
5248         regOrderSize = lsraRegOrderSize;
5249     }
5250
5251     LsraLocation currentLocation = refPosition->nodeLocation;
5252     RefPosition* nextRefPos      = refPosition->nextRefPosition;
5253     LsraLocation nextLocation    = (nextRefPos == nullptr) ? currentLocation : nextRefPos->nodeLocation;
5254     regMaskTP    candidates      = refPosition->registerAssignment;
5255     regMaskTP    preferences     = currentInterval->registerPreferences;
5256
5257     if (RefTypeIsDef(refPosition->refType))
5258     {
5259         if (currentInterval->hasConflictingDefUse)
5260         {
5261             resolveConflictingDefAndUse(currentInterval, refPosition);
5262             candidates = refPosition->registerAssignment;
5263         }
5264         // Otherwise, check for the case of a fixed-reg def of a reg that will be killed before the
5265         // use, or interferes at the point of use (which shouldn't happen, but Lower doesn't mark
5266         // the contained nodes as interfering).
5267         // Note that we may have a ParamDef RefPosition that is marked isFixedRegRef, but which
5268         // has had its registerAssignment changed to no longer be a single register.
5269         else if (refPosition->isFixedRegRef && nextRefPos != nullptr && RefTypeIsUse(nextRefPos->refType) &&
5270                  !nextRefPos->isFixedRegRef && genMaxOneBit(refPosition->registerAssignment))
5271         {
5272             regNumber  defReg       = refPosition->assignedReg();
5273             RegRecord* defRegRecord = getRegisterRecord(defReg);
5274
5275             RefPosition* currFixedRegRefPosition = defRegRecord->recentRefPosition;
5276             assert(currFixedRegRefPosition != nullptr &&
5277                    currFixedRegRefPosition->nodeLocation == refPosition->nodeLocation);
5278
5279             // If there is another fixed reference to this register before the use, change the candidates
5280             // on this RefPosition to include that of nextRefPos.
5281             if (currFixedRegRefPosition->nextRefPosition != nullptr &&
5282                 currFixedRegRefPosition->nextRefPosition->nodeLocation <= nextRefPos->getRefEndLocation())
5283             {
5284                 candidates |= nextRefPos->registerAssignment;
5285                 if (preferences == refPosition->registerAssignment)
5286                 {
5287                     preferences = candidates;
5288                 }
5289             }
5290         }
5291     }
5292
5293     preferences &= candidates;
5294     if (preferences == RBM_NONE)
5295     {
5296         preferences = candidates;
5297     }
5298     regMaskTP relatedPreferences = RBM_NONE;
5299
5300 #ifdef DEBUG
5301     candidates = stressLimitRegs(refPosition, candidates);
5302 #endif
5303     bool mustAssignARegister = true;
5304     assert(candidates != RBM_NONE);
5305
5306     // If the related interval has no further references, it is possible that it is a source of the
5307     // node that produces this interval.  However, we don't want to use the relatedInterval for preferencing
5308     // if its next reference is not a new definition (as it either is or will become live).
5309     Interval* relatedInterval = currentInterval->relatedInterval;
5310     if (relatedInterval != nullptr)
5311     {
5312         RefPosition* nextRelatedRefPosition = relatedInterval->getNextRefPosition();
5313         if (nextRelatedRefPosition != nullptr)
5314         {
5315             // Don't use the relatedInterval for preferencing if its next reference is not a new definition.
5316             if (!RefTypeIsDef(nextRelatedRefPosition->refType))
5317             {
5318                 relatedInterval = nullptr;
5319             }
5320             // Is the relatedInterval simply a copy to another relatedInterval?
5321             else if ((relatedInterval->relatedInterval != nullptr) &&
5322                      (nextRelatedRefPosition->nextRefPosition != nullptr) &&
5323                      (nextRelatedRefPosition->nextRefPosition->nextRefPosition == nullptr) &&
5324                      (nextRelatedRefPosition->nextRefPosition->nodeLocation <
5325                       relatedInterval->relatedInterval->getNextRefLocation()))
5326             {
5327                 // The current relatedInterval has only two remaining RefPositions, both of which
5328                 // occur prior to the next RefPosition for its relatedInterval.
5329                 // It is likely a copy.
5330                 relatedInterval = relatedInterval->relatedInterval;
5331             }
5332         }
5333     }
5334
5335     if (relatedInterval != nullptr)
5336     {
5337         // If the related interval already has an assigned register, then use that
5338         // as the related preference.  We'll take the related
5339         // interval preferences into account in the loop over all the registers.
5340
5341         if (relatedInterval->assignedReg != nullptr)
5342         {
5343             relatedPreferences = genRegMask(relatedInterval->assignedReg->regNum);
5344         }
5345         else
5346         {
5347             relatedPreferences = relatedInterval->registerPreferences;
5348         }
5349     }
5350
5351     bool preferCalleeSave = currentInterval->preferCalleeSave;
5352
5353     // For floating point, we want to be less aggressive about using callee-save registers.
5354     // So in that case, we just need to ensure that the current RefPosition is covered.
5355     RefPosition* rangeEndRefPosition;
5356     RefPosition* lastRefPosition = currentInterval->lastRefPosition;
5357     if (useFloatReg(currentInterval->registerType))
5358     {
5359         rangeEndRefPosition = refPosition;
5360     }
5361     else
5362     {
5363         rangeEndRefPosition = currentInterval->lastRefPosition;
5364         // If we have a relatedInterval that is not currently occupying a register,
5365         // and whose lifetime begins after this one ends,
5366         // we want to try to select a register that will cover its lifetime.
5367         if ((relatedInterval != nullptr) && (relatedInterval->assignedReg == nullptr) &&
5368             (relatedInterval->getNextRefLocation() >= rangeEndRefPosition->nodeLocation))
5369         {
5370             lastRefPosition  = relatedInterval->lastRefPosition;
5371             preferCalleeSave = relatedInterval->preferCalleeSave;
5372         }
5373     }
5374
5375     // If this has a delayed use (due to being used in a rmw position of a
5376     // non-commutative operator), its endLocation is delayed until the "def"
5377     // position, which is one location past the use (getRefEndLocation() takes care of this).
5378     LsraLocation rangeEndLocation = rangeEndRefPosition->getRefEndLocation();
5379     LsraLocation lastLocation     = lastRefPosition->getRefEndLocation();
5380     regNumber    prevReg          = REG_NA;
5381
5382     if (currentInterval->assignedReg)
5383     {
5384         bool useAssignedReg = false;
5385         // This was an interval that was previously allocated to the given
5386         // physical register, and we should try to allocate it to that register
5387         // again, if possible and reasonable.
5388         // Use it preemptively (i.e. before checking other available regs)
5389         // only if it is preferred and available.
5390
5391         RegRecord* regRec    = currentInterval->assignedReg;
5392         prevReg              = regRec->regNum;
5393         regMaskTP prevRegBit = genRegMask(prevReg);
5394
5395         // Is it in the preferred set of regs?
5396         if ((prevRegBit & preferences) != RBM_NONE)
5397         {
5398             // Is it currently available?
5399             LsraLocation nextPhysRefLoc;
5400             if (registerIsAvailable(regRec, currentLocation, &nextPhysRefLoc, currentInterval->registerType))
5401             {
5402                 // If the register is next referenced at this location, only use it if
5403                 // this has a fixed reg requirement (i.e. this is the reference that caused
5404                 // the FixedReg ref to be created)
5405
5406                 if (!regRec->conflictingFixedRegReference(refPosition))
5407                 {
5408                     useAssignedReg = true;
5409                 }
5410             }
5411         }
5412         if (useAssignedReg)
5413         {
5414             regNumber foundReg = prevReg;
5415             assignPhysReg(regRec, currentInterval);
5416             refPosition->registerAssignment = genRegMask(foundReg);
5417             return foundReg;
5418         }
5419         else
5420         {
5421             // Don't keep trying to allocate to this register
5422             currentInterval->assignedReg = nullptr;
5423         }
5424     }
5425
5426     RegRecord* availablePhysRegInterval = nullptr;
5427     Interval*  intervalToUnassign       = nullptr;
5428
5429     // Each register will receive a score which is the sum of the scoring criteria below.
5430     // These were selected on the assumption that they will have an impact on the "goodness"
5431     // of a register selection, and have been tuned to a certain extent by observing the impact
5432     // of the ordering on asmDiffs.  However, there is probably much more room for tuning,
5433     // and perhaps additional criteria.
5434     //
5435     // These are FLAGS (bits) so that we can easily order them and add them together.
5436     // If the scores are equal, but one covers more of the current interval's range,
5437     // then it wins.  Otherwise, the one encountered earlier in the regOrder wins.
5438
5439     enum RegisterScore
5440     {
5441         VALUE_AVAILABLE = 0x40, // It is a constant value that is already in an acceptable register.
5442         COVERS          = 0x20, // It is in the interval's preference set and it covers the entire lifetime.
5443         OWN_PREFERENCE  = 0x10, // It is in the preference set of this interval.
5444         COVERS_RELATED  = 0x08, // It is in the preference set of the related interval and covers the entire lifetime.
5445         RELATED_PREFERENCE = 0x04, // It is in the preference set of the related interval.
5446         CALLER_CALLEE      = 0x02, // It is in the right "set" for the interval (caller or callee-save).
5447         UNASSIGNED         = 0x01, // It is not currently assigned to an inactive interval.
5448     };
5449
5450     int bestScore = 0;
5451
5452     // Compute the best possible score so we can stop looping early if we find it.
5453     // TODO-Throughput: At some point we may want to short-circuit the computation of each score, but
5454     // probably not until we've tuned the order of these criteria.  At that point,
5455     // we'll need to avoid the short-circuit if we've got a stress option to reverse
5456     // the selection.
5457     int bestPossibleScore = COVERS + UNASSIGNED + OWN_PREFERENCE + CALLER_CALLEE;
5458     if (relatedPreferences != RBM_NONE)
5459     {
5460         bestPossibleScore |= RELATED_PREFERENCE + COVERS_RELATED;
5461     }
5462
5463     LsraLocation bestLocation = MinLocation;
5464
5465     // In non-debug builds, this will simply get optimized away
5466     bool reverseSelect = false;
5467 #ifdef DEBUG
5468     reverseSelect = doReverseSelect();
5469 #endif // DEBUG
5470
5471     // An optimization for the common case where there is only one candidate -
5472     // avoid looping over all the other registers
5473
5474     regNumber singleReg = REG_NA;
5475
5476     if (genMaxOneBit(candidates))
5477     {
5478         regOrderSize = 1;
5479         singleReg    = genRegNumFromMask(candidates);
5480         regOrder     = &singleReg;
5481     }
5482
5483     for (unsigned i = 0; i < regOrderSize && (candidates != RBM_NONE); i++)
5484     {
5485         regNumber regNum       = regOrder[i];
5486         regMaskTP candidateBit = genRegMask(regNum);
5487
5488         if (!(candidates & candidateBit))
5489         {
5490             continue;
5491         }
5492
5493         candidates &= ~candidateBit;
5494
5495         RegRecord* physRegRecord = getRegisterRecord(regNum);
5496
5497         int          score               = 0;
5498         LsraLocation nextPhysRefLocation = MaxLocation;
5499
5500         // By chance, is this register already holding this interval, as a copyReg or having
5501         // been restored as inactive after a kill?
5502         if (physRegRecord->assignedInterval == currentInterval)
5503         {
5504             availablePhysRegInterval = physRegRecord;
5505             intervalToUnassign       = nullptr;
5506             break;
5507         }
5508
5509         // Find the next RefPosition of the physical register
5510         if (!registerIsAvailable(physRegRecord, currentLocation, &nextPhysRefLocation, regType))
5511         {
5512             continue;
5513         }
5514
5515         // If the register is next referenced at this location, only use it if
5516         // this has a fixed reg requirement (i.e. this is the reference that caused
5517         // the FixedReg ref to be created)
5518
5519         if (physRegRecord->conflictingFixedRegReference(refPosition))
5520         {
5521             continue;
5522         }
5523
5524         // If this is a definition of a constant interval, check to see if its value is already in this register.
5525         if (currentInterval->isConstant && RefTypeIsDef(refPosition->refType) &&
5526             (physRegRecord->assignedInterval != nullptr) && physRegRecord->assignedInterval->isConstant)
5527         {
5528             noway_assert(refPosition->treeNode != nullptr);
5529             GenTree* otherTreeNode = physRegRecord->assignedInterval->firstRefPosition->treeNode;
5530             noway_assert(otherTreeNode != nullptr);
5531
5532             if (refPosition->treeNode->OperGet() == otherTreeNode->OperGet())
5533             {
5534                 switch (otherTreeNode->OperGet())
5535                 {
5536                     case GT_CNS_INT:
5537                         if ((refPosition->treeNode->AsIntCon()->IconValue() ==
5538                              otherTreeNode->AsIntCon()->IconValue()) &&
5539                             (varTypeGCtype(refPosition->treeNode) == varTypeGCtype(otherTreeNode)))
5540                         {
5541 #ifdef _TARGET_64BIT_
5542                             // If the constant is negative, only reuse registers of the same type.
5543                             // This is because, on a 64-bit system, we do not sign-extend immediates in registers to
5544                             // 64-bits unless they are actually longs, as this requires a longer instruction.
5545                             // This doesn't apply to a 32-bit system, on which long values occupy multiple registers.
5546                             // (We could sign-extend, but we would have to always sign-extend, because if we reuse more
5547                             // than once, we won't have access to the instruction that originally defines the constant).
5548                             if ((refPosition->treeNode->TypeGet() == otherTreeNode->TypeGet()) ||
5549                                 (refPosition->treeNode->AsIntCon()->IconValue() >= 0))
5550 #endif // _TARGET_64BIT_
5551                             {
5552                                 score |= VALUE_AVAILABLE;
5553                             }
5554                         }
5555                         break;
5556                     case GT_CNS_DBL:
5557                     {
5558                         // For floating point constants, the values must be identical, not simply compare
5559                         // equal.  So we compare the bits.
5560                         if (refPosition->treeNode->AsDblCon()->isBitwiseEqual(otherTreeNode->AsDblCon()) &&
5561                             (refPosition->treeNode->TypeGet() == otherTreeNode->TypeGet()))
5562                         {
5563                             score |= VALUE_AVAILABLE;
5564                         }
5565                         break;
5566                     }
5567                     default:
5568                         // for all other 'otherTreeNode->OperGet()' kinds, we leave 'score' unchanged
5569                         break;
5570                 }
5571             }
5572         }
5573
5574         // If the nextPhysRefLocation is a fixedRef for the rangeEndRefPosition, increment it so that
5575         // we don't think it isn't covering the live range.
5576         // This doesn't handle the case where earlier RefPositions for this Interval are also
5577         // FixedRefs of this regNum, but at least those are only interesting in the case where those
5578         // are "local last uses" of the Interval - otherwise the liveRange would interfere with the reg.
5579         if (nextPhysRefLocation == rangeEndLocation && rangeEndRefPosition->isFixedRefOfReg(regNum))
5580         {
5581             INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_INCREMENT_RANGE_END, currentInterval, regNum));
5582             nextPhysRefLocation++;
5583         }
5584
5585         if ((candidateBit & preferences) != RBM_NONE)
5586         {
5587             score |= OWN_PREFERENCE;
5588             if (nextPhysRefLocation > rangeEndLocation)
5589             {
5590                 score |= COVERS;
5591             }
5592         }
5593         if (relatedInterval != nullptr && (candidateBit & relatedPreferences) != RBM_NONE)
5594         {
5595             score |= RELATED_PREFERENCE;
5596             if (nextPhysRefLocation > relatedInterval->lastRefPosition->nodeLocation)
5597             {
5598                 score |= COVERS_RELATED;
5599             }
5600         }
5601
5602         // If we had a fixed-reg def of a reg that will be killed before the use, prefer it to any other registers
5603         // with the same score.  (Note that we haven't changed the original registerAssignment on the RefPosition).
5604         // Overload the RELATED_PREFERENCE value.
5605         else if (candidateBit == refPosition->registerAssignment)
5606         {
5607             score |= RELATED_PREFERENCE;
5608         }
5609
5610         if ((preferCalleeSave && physRegRecord->isCalleeSave) || (!preferCalleeSave && !physRegRecord->isCalleeSave))
5611         {
5612             score |= CALLER_CALLEE;
5613         }
5614
5615         // The register is considered unassigned if it has no assignedInterval, OR
5616         // if its next reference is beyond the range of this interval.
5617         if (physRegRecord->assignedInterval == nullptr ||
5618             physRegRecord->assignedInterval->getNextRefLocation() > lastLocation)
5619         {
5620             score |= UNASSIGNED;
5621         }
5622
5623         bool foundBetterCandidate = false;
5624
5625         if (score > bestScore)
5626         {
5627             foundBetterCandidate = true;
5628         }
5629         else if (score == bestScore)
5630         {
5631             // Prefer a register that covers the range.
5632             if (bestLocation <= lastLocation)
5633             {
5634                 if (nextPhysRefLocation > bestLocation)
5635                 {
5636                     foundBetterCandidate = true;
5637                 }
5638             }
5639             // If both cover the range, prefer a register that is killed sooner (leaving the longer range register
5640             // available). If both cover the range and also getting killed at the same location, prefer the one which
5641             // is same as previous assignment.
5642             else if (nextPhysRefLocation > lastLocation)
5643             {
5644                 if (nextPhysRefLocation < bestLocation)
5645                 {
5646                     foundBetterCandidate = true;
5647                 }
5648                 else if (nextPhysRefLocation == bestLocation && prevReg == regNum)
5649                 {
5650                     foundBetterCandidate = true;
5651                 }
5652             }
5653         }
5654
5655 #ifdef DEBUG
5656         if (doReverseSelect() && bestScore != 0)
5657         {
5658             foundBetterCandidate = !foundBetterCandidate;
5659         }
5660 #endif // DEBUG
5661
5662         if (foundBetterCandidate)
5663         {
5664             bestLocation             = nextPhysRefLocation;
5665             availablePhysRegInterval = physRegRecord;
5666             intervalToUnassign       = physRegRecord->assignedInterval;
5667             bestScore                = score;
5668         }
5669
5670         // there is no way we can get a better score so break out
5671         if (!reverseSelect && score == bestPossibleScore && bestLocation == rangeEndLocation + 1)
5672         {
5673             break;
5674         }
5675     }
5676
5677     if (availablePhysRegInterval != nullptr)
5678     {
5679         if (intervalToUnassign != nullptr)
5680         {
5681             RegRecord* physRegToUnassign = availablePhysRegInterval;
5682 #ifdef _TARGET_ARM_
5683             // We should unassign a double register if availablePhysRegInterval is part of the double register
5684             if (availablePhysRegInterval->assignedInterval->registerType == TYP_DOUBLE &&
5685                 !genIsValidDoubleReg(availablePhysRegInterval->regNum))
5686                 physRegToUnassign = findAnotherHalfRegRec(availablePhysRegInterval);
5687 #endif
5688             unassignPhysReg(physRegToUnassign, intervalToUnassign->recentRefPosition);
5689             if (bestScore & VALUE_AVAILABLE)
5690             {
5691                 assert(intervalToUnassign->isConstant);
5692                 refPosition->treeNode->SetReuseRegVal();
5693             }
5694             // If we considered this "unassigned" because this interval's lifetime ends before
5695             // the next ref, remember it.
5696             else if ((bestScore & UNASSIGNED) != 0 && intervalToUnassign != nullptr)
5697             {
5698                 updatePreviousInterval(physRegToUnassign, intervalToUnassign, intervalToUnassign->registerType);
5699             }
5700         }
5701         else
5702         {
5703             assert((bestScore & VALUE_AVAILABLE) == 0);
5704         }
5705         assignPhysReg(availablePhysRegInterval, currentInterval);
5706         foundReg                        = availablePhysRegInterval->regNum;
5707         regMaskTP foundRegMask          = genRegMask(foundReg);
5708         refPosition->registerAssignment = foundRegMask;
5709         if (relatedInterval != nullptr)
5710         {
5711             relatedInterval->updateRegisterPreferences(foundRegMask);
5712         }
5713     }
5714
5715     return foundReg;
5716 }
5717 //------------------------------------------------------------------------
5718 // canSpillReg: Determine whether we can spill physRegRecord
5719 //
5720 // Arguments:
5721 //    physRegRecord             - reg to spill
5722 //    refLocation               - Location of RefPosition where this register will be spilled
5723 //    recentAssignedRefWeight   - Weight of recent assigned RefPosition which will be determined in this function
5724 //    farthestRefPosWeight      - Current farthestRefPosWeight at allocateBusyReg()
5725 //
5726 // Return Value:
5727 //    True  - if we can spill physRegRecord
5728 //    False - otherwise
5729 //
5730 // Note: This helper is designed to be used only from allocateBusyReg() and canSpillDoubleReg()
5731 //
5732 bool LinearScan::canSpillReg(RegRecord*   physRegRecord,
5733                              LsraLocation refLocation,
5734                              unsigned*    recentAssignedRefWeight,
5735                              unsigned     farthestRefPosWeight)
5736 {
5737     assert(physRegRecord->assignedInterval != nullptr);
5738     RefPosition* recentAssignedRef = physRegRecord->assignedInterval->recentRefPosition;
5739
5740     if (recentAssignedRef != nullptr)
5741     {
5742         if (recentAssignedRef->nodeLocation == refLocation)
5743         {
5744             // We can't spill a register that's being used at the current location
5745             return false;
5746         }
5747
5748         // If the current position has the candidate register marked to be delayed,
5749         // check if the previous location is using this register, if that's the case we have to skip
5750         // since we can't spill this register.
5751         if (recentAssignedRef->delayRegFree && (refLocation == recentAssignedRef->nodeLocation + 1))
5752         {
5753             return false;
5754         }
5755
5756         // We don't prefer to spill a register if the weight of recentAssignedRef > weight
5757         // of the spill candidate found so far.  We would consider spilling a greater weight
5758         // ref position only if the refPosition being allocated must need a reg.
5759         *recentAssignedRefWeight = getWeight(recentAssignedRef);
5760         if (*recentAssignedRefWeight > farthestRefPosWeight)
5761         {
5762             return false;
5763         }
5764     }
5765     return true;
5766 }
5767
5768 #ifdef _TARGET_ARM_
5769 bool LinearScan::canSpillDoubleReg(RegRecord*   physRegRecord,
5770                                    LsraLocation refLocation,
5771                                    unsigned*    recentAssignedRefWeight,
5772                                    unsigned     farthestRefPosWeight)
5773 {
5774     bool     retVal  = true;
5775     unsigned weight  = BB_ZERO_WEIGHT;
5776     unsigned weight2 = BB_ZERO_WEIGHT;
5777
5778     RegRecord* physRegRecord2 = findAnotherHalfRegRec(physRegRecord);
5779
5780     if (physRegRecord->assignedInterval != nullptr)
5781         retVal &= canSpillReg(physRegRecord, refLocation, &weight, farthestRefPosWeight);
5782
5783     if (physRegRecord2->assignedInterval != nullptr)
5784         retVal &= canSpillReg(physRegRecord2, refLocation, &weight2, farthestRefPosWeight);
5785
5786     if (!(weight == BB_ZERO_WEIGHT && weight2 == BB_ZERO_WEIGHT))
5787     {
5788         // weight and/or weight2 have been updated.
5789         *recentAssignedRefWeight = (weight > weight2) ? weight : weight2;
5790     }
5791
5792     return retVal;
5793 }
5794 #endif
5795
5796 //----------------------------------------------------------------------------
5797 // checkActiveInterval: Test activness of an interval
5798 //                      and check assertions if the interval is not active
5799 //
5800 // Arguments:
5801 //    interval    - An interval to be tested
5802 //    refLocation - Location where the interval is being tested
5803 //
5804 // Return Value:
5805 //    True - iff the interval is active
5806 //    False - otherwise
5807 //
5808 // Note: This helper is designed to be used only from checkActiveIntervals()
5809 //
5810 bool LinearScan::checkActiveInterval(Interval* interval, LsraLocation refLocation)
5811 {
5812     if (!interval->isActive)
5813     {
5814         RefPosition* recentAssignedRef = interval->recentRefPosition;
5815         // Note that we may or may not have actually handled the reference yet, so it could either
5816         // be recentAssignedRef, or the next reference.
5817         assert(recentAssignedRef != nullptr);
5818         if (recentAssignedRef->nodeLocation != refLocation)
5819         {
5820             if (recentAssignedRef->nodeLocation + 1 == refLocation)
5821             {
5822                 assert(recentAssignedRef->delayRegFree);
5823             }
5824             else
5825             {
5826                 RefPosition* nextAssignedRef = recentAssignedRef->nextRefPosition;
5827                 assert(nextAssignedRef != nullptr);
5828                 assert(nextAssignedRef->nodeLocation == refLocation ||
5829                        (nextAssignedRef->nodeLocation + 1 == refLocation && nextAssignedRef->delayRegFree));
5830             }
5831         }
5832         return false;
5833     }
5834     return true;
5835 }
5836
5837 //----------------------------------------------------------------------------------------
5838 // checkActiveIntervals: Test activness of a interval assinged to a register
5839 //                       and check assertions if the interval is not active.
5840 //                       We look into all intervals of two float registers consisting
5841 //                       a double regsiter for ARM32.
5842 //
5843 // Arguments:
5844 //    physRegRecord - A register
5845 //    refLocation   - Location where intervsl is being tested
5846 //    registerType  - Type of regsiter
5847 //
5848 // Return Value:
5849 //    True - iff the all intervals are active
5850 //    False - otherwise
5851 //
5852 // Note: This helper is designed to be used only from allocateBusyReg()
5853 //
5854 bool LinearScan::checkActiveIntervals(RegRecord* physRegRecord, LsraLocation refLocation, RegisterType registerType)
5855 {
5856     Interval* assignedInterval = physRegRecord->assignedInterval;
5857
5858 #ifdef _TARGET_ARM_
5859     // Check two intervals for a double register in ARM32
5860     Interval* assignedInterval2 = nullptr;
5861     if (registerType == TYP_DOUBLE)
5862         assignedInterval2 = findAnotherHalfRegRec(physRegRecord)->assignedInterval;
5863
5864     // Both intervals should not be nullptr at the same time, becasue we already handle this case before.
5865     assert(!(assignedInterval == nullptr && assignedInterval2 == nullptr));
5866
5867     if (assignedInterval != nullptr && !checkActiveInterval(assignedInterval, refLocation))
5868         return false;
5869
5870     if (assignedInterval2 != nullptr && !checkActiveInterval(assignedInterval2, refLocation))
5871         return false;
5872
5873     return true;
5874 #else
5875     return checkActiveInterval(assignedInterval, refLocation);
5876 #endif
5877 }
5878
5879 #ifdef _TARGET_ARM_
5880 void LinearScan::unassignDoublePhysReg(RegRecord* doubleRegRecord)
5881 {
5882     RegRecord* doubleRegRecordLo = doubleRegRecord;
5883     RegRecord* doubleRegRecordHi = findAnotherHalfRegRec(doubleRegRecordLo);
5884     // For a double register, we has following four cases.
5885     // Case 1: doubleRegRecLo is assigned to TYP_DOUBLE interval
5886     // Case 2: doubleRegRecLo and doubleRegRecHi are assigned to different TYP_FLOAT intervals
5887     // Case 3: doubelRegRecLo is assgined to TYP_FLOAT interval and doubleRegRecHi is nullptr
5888     // Case 4: doubleRegRecordLo is nullptr, and doubleRegRecordHi is assigned to a TYP_FLOAT interval
5889     if (doubleRegRecordLo->assignedInterval != nullptr)
5890     {
5891         if (doubleRegRecordLo->assignedInterval->registerType == TYP_DOUBLE)
5892         {
5893             // Case 1: doubleRegRecLo is assigned to TYP_DOUBLE interval
5894             unassignPhysReg(doubleRegRecordLo, doubleRegRecordLo->assignedInterval->recentRefPosition);
5895         }
5896         else
5897         {
5898             // Case 2: doubleRegRecLo and doubleRegRecHi are assigned to different TYP_FLOAT intervals
5899             // Case 3: doubelRegRecLo is assgined to TYP_FLOAT interval and doubleRegRecHi is nullptr
5900             assert(doubleRegRecordLo->assignedInterval->registerType == TYP_FLOAT);
5901             unassignPhysReg(doubleRegRecordLo, doubleRegRecordLo->assignedInterval->recentRefPosition);
5902
5903             if (doubleRegRecordHi != nullptr)
5904             {
5905                 assert(doubleRegRecordHi->assignedInterval->registerType == TYP_FLOAT);
5906                 unassignPhysReg(doubleRegRecordHi, doubleRegRecordHi->assignedInterval->recentRefPosition);
5907             }
5908         }
5909     }
5910     else
5911     {
5912         // Case 4: doubleRegRecordLo is nullptr, and doubleRegRecordHi is assigned to a TYP_FLOAT interval
5913         assert(doubleRegRecordHi->assignedInterval != nullptr);
5914         assert(doubleRegRecordHi->assignedInterval->registerType == TYP_FLOAT);
5915         unassignPhysReg(doubleRegRecordHi, doubleRegRecordHi->assignedInterval->recentRefPosition);
5916     }
5917 }
5918
5919 #endif // _TARGET_ARM_
5920
5921 //----------------------------------------------------------------------------------------
5922 // isRegInUse: Test whether regRec is being used at the refPosition
5923 //
5924 // Arguments:
5925 //    regRec - A register to be tested
5926 //    refPosition - RefPosition where regRec is tested
5927 //    nextLocation - next RefPosition of interval assigned to regRec
5928 //
5929 // Return Value:
5930 //    True - if regRec is beding used
5931 //    False - otherwise
5932 //
5933 // Note: This helper is designed to be used only from allocateBusyReg()
5934 //
5935 bool LinearScan::isRegInUse(RegRecord* regRec, RefPosition* refPosition, LsraLocation* nextLocation)
5936 {
5937     Interval* assignedInterval = regRec->assignedInterval;
5938     if (assignedInterval != nullptr)
5939     {
5940         LsraLocation refLocation     = refPosition->nodeLocation;
5941         RefPosition* nextRefPosition = assignedInterval->getNextRefPosition();
5942         *nextLocation                = assignedInterval->getNextRefLocation();
5943
5944         // We should never spill a register that's occupied by an Interval with its next use at the current
5945         // location.
5946         // Normally this won't occur (unless we actually had more uses in a single node than there are registers),
5947         // because we'll always find something with a later nextLocation, but it can happen in stress when
5948         // we have LSRA_SELECT_NEAREST.
5949         if ((*nextLocation == refLocation) && !refPosition->isFixedRegRef && nextRefPosition->RequiresRegister())
5950         {
5951             return true;
5952         }
5953     }
5954     return false;
5955 }
5956
5957 //------------------------------------------------------------------------
5958 // allocateBusyReg: Find a busy register that satisfies the requirements for refPosition,
5959 //                  and that can be spilled.
5960 //
5961 // Arguments:
5962 //    current               The interval for the current allocation
5963 //    refPosition           The RefPosition of the current Interval for which a register is being allocated
5964 //    allocateIfProfitable  If true, a reg may not be allocated if all other ref positions currently
5965 //                          occupying registers are more important than the 'refPosition'.
5966 //
5967 // Return Value:
5968 //    The regNumber allocated to the RefPositon.  Returns REG_NA if no free register is found.
5969 //
5970 // Note:  Currently this routine uses weight and farthest distance of next reference
5971 // to select a ref position for spilling.
5972 // a) if allocateIfProfitable = false
5973 //        The ref position chosen for spilling will be the lowest weight
5974 //        of all and if there is is more than one ref position with the
5975 //        same lowest weight, among them choses the one with farthest
5976 //        distance to its next reference.
5977 //
5978 // b) if allocateIfProfitable = true
5979 //        The ref position chosen for spilling will not only be lowest weight
5980 //        of all but also has a weight lower than 'refPosition'.  If there is
5981 //        no such ref position, reg will not be allocated.
5982 regNumber LinearScan::allocateBusyReg(Interval* current, RefPosition* refPosition, bool allocateIfProfitable)
5983 {
5984     regNumber foundReg = REG_NA;
5985
5986     RegisterType regType     = getRegisterType(current, refPosition);
5987     regMaskTP    candidates  = refPosition->registerAssignment;
5988     regMaskTP    preferences = (current->registerPreferences & candidates);
5989     if (preferences == RBM_NONE)
5990     {
5991         preferences = candidates;
5992     }
5993     if (candidates == RBM_NONE)
5994     {
5995         // This assumes only integer and floating point register types
5996         // if we target a processor with additional register types,
5997         // this would have to change
5998         candidates = allRegs(regType);
5999     }
6000
6001 #ifdef DEBUG
6002     candidates = stressLimitRegs(refPosition, candidates);
6003 #endif // DEBUG
6004
6005     // TODO-CQ: Determine whether/how to take preferences into account in addition to
6006     // prefering the one with the furthest ref position when considering
6007     // a candidate to spill
6008     RegRecord* farthestRefPhysRegRecord = nullptr;
6009 #ifdef _TARGET_ARM_
6010     RegRecord* farthestRefPhysRegRecord2 = nullptr;
6011 #endif
6012     LsraLocation farthestLocation = MinLocation;
6013     LsraLocation refLocation      = refPosition->nodeLocation;
6014     unsigned     farthestRefPosWeight;
6015     if (allocateIfProfitable)
6016     {
6017         // If allocating a reg is optional, we will consider those ref positions
6018         // whose weight is less than 'refPosition' for spilling.
6019         farthestRefPosWeight = getWeight(refPosition);
6020     }
6021     else
6022     {
6023         // If allocating a reg is a must, we start off with max weight so
6024         // that the first spill candidate will be selected based on
6025         // farthest distance alone.  Since we start off with farthestLocation
6026         // initialized to MinLocation, the first available ref position
6027         // will be selected as spill candidate and its weight as the
6028         // fathestRefPosWeight.
6029         farthestRefPosWeight = BB_MAX_WEIGHT;
6030     }
6031
6032     for (regNumber regNum : Registers(regType))
6033     {
6034         regMaskTP candidateBit = genRegMask(regNum);
6035         if (!(candidates & candidateBit))
6036         {
6037             continue;
6038         }
6039         RegRecord* physRegRecord = getRegisterRecord(regNum);
6040 #ifdef _TARGET_ARM_
6041         RegRecord* physRegRecord2 = nullptr;
6042         // For ARM32, let's consider two float registers consisting a double reg together,
6043         // when allocaing a double register.
6044         if (current->registerType == TYP_DOUBLE)
6045         {
6046             assert(genIsValidDoubleReg(regNum));
6047             physRegRecord2 = findAnotherHalfRegRec(physRegRecord);
6048         }
6049 #endif
6050
6051         if (physRegRecord->isBusyUntilNextKill)
6052         {
6053             continue;
6054         }
6055         Interval* assignedInterval = physRegRecord->assignedInterval;
6056 #ifdef _TARGET_ARM_
6057         Interval* assignedInterval2 = (physRegRecord2 == nullptr) ? nullptr : physRegRecord2->assignedInterval;
6058 #endif
6059
6060         // If there is a fixed reference at the same location (and it's not due to this reference),
6061         // don't use it.
6062
6063         if (physRegRecord->conflictingFixedRegReference(refPosition))
6064         {
6065             assert(candidates != candidateBit);
6066             continue;
6067         }
6068
6069         LsraLocation physRegNextLocation = MaxLocation;
6070         if (refPosition->isFixedRefOfRegMask(candidateBit))
6071         {
6072             // Either there is a fixed reference due to this node, or one associated with a
6073             // fixed use fed by a def at this node.
6074             // In either case, we must use this register as it's the only candidate
6075             // TODO-CQ: At the time we allocate a register to a fixed-reg def, if it's not going
6076             // to remain live until the use, we should set the candidates to allRegs(regType)
6077             // to avoid a spill - codegen can then insert the copy.
6078             assert(candidates == candidateBit);
6079
6080             // If a refPosition has a fixed reg as its candidate and is also marked
6081             // as allocateIfProfitable, we should allocate fixed reg only if the
6082             // weight of this ref position is greater than the weight of the ref
6083             // position to which fixed reg is assigned.  Such a case would arise
6084             // on x86 under LSRA stress.
6085             if (!allocateIfProfitable)
6086             {
6087                 physRegNextLocation  = MaxLocation;
6088                 farthestRefPosWeight = BB_MAX_WEIGHT;
6089             }
6090         }
6091         else
6092         {
6093             physRegNextLocation = physRegRecord->getNextRefLocation();
6094
6095             // If refPosition requires a fixed register, we should reject all others.
6096             // Otherwise, we will still evaluate all phyRegs though their next location is
6097             // not better than farthestLocation found so far.
6098             //
6099             // TODO: this method should be using an approach similar to tryAllocateFreeReg()
6100             // where it uses a regOrder array to avoid iterating over any but the single
6101             // fixed candidate.
6102             if (refPosition->isFixedRegRef && physRegNextLocation < farthestLocation)
6103             {
6104                 continue;
6105             }
6106         }
6107
6108         // If this register is not assigned to an interval, either
6109         // - it has a FixedReg reference at the current location that is not this reference, OR
6110         // - this is the special case of a fixed loReg, where this interval has a use at the same location
6111         // In either case, we cannot use it
6112         CLANG_FORMAT_COMMENT_ANCHOR;
6113
6114 #ifdef _TARGET_ARM_
6115         if (assignedInterval == nullptr && assignedInterval2 == nullptr)
6116 #else
6117         if (assignedInterval == nullptr)
6118 #endif
6119         {
6120             RefPosition* nextPhysRegPosition = physRegRecord->getNextRefPosition();
6121
6122 #ifndef _TARGET_ARM64_
6123             // TODO-Cleanup: Revisit this after Issue #3524 is complete
6124             // On ARM64 the nodeLocation is not always == refLocation, Disabling this assert for now.
6125             assert(nextPhysRegPosition->nodeLocation == refLocation && candidateBit != candidates);
6126 #endif
6127             continue;
6128         }
6129
6130 #ifdef _TARGET_ARM_
6131         RefPosition* recentAssignedRef = (assignedInterval == nullptr) ? nullptr : assignedInterval->recentRefPosition;
6132         RefPosition* recentAssignedRef2 =
6133             (assignedInterval2 == nullptr) ? nullptr : assignedInterval2->recentRefPosition;
6134 #else
6135         RefPosition* recentAssignedRef = assignedInterval->recentRefPosition;
6136 #endif
6137
6138         if (!checkActiveIntervals(physRegRecord, refLocation, current->registerType))
6139         {
6140             continue;
6141         }
6142
6143         // If we have a recentAssignedRef, check that it is going to be OK to spill it
6144         //
6145         // TODO-Review: Under what conditions recentAssginedRef would be null?
6146         unsigned recentAssignedRefWeight = BB_ZERO_WEIGHT;
6147
6148 #ifdef _TARGET_ARM_
6149         if (current->registerType == TYP_DOUBLE)
6150         {
6151             if (!canSpillDoubleReg(physRegRecord, refLocation, &recentAssignedRefWeight, farthestRefPosWeight))
6152                 continue;
6153         }
6154         else
6155 #endif
6156             // This if-stmt is associated with the above else
6157             if (!canSpillReg(physRegRecord, refLocation, &recentAssignedRefWeight, farthestRefPosWeight))
6158         {
6159             continue;
6160         }
6161
6162         LsraLocation nextLocation = MinLocation;
6163
6164         if (isRegInUse(physRegRecord, refPosition, &nextLocation))
6165         {
6166             continue;
6167         }
6168
6169 #ifdef _TARGET_ARM_
6170         if (current->registerType == TYP_DOUBLE)
6171         {
6172             LsraLocation nextLocation2 = MinLocation;
6173             if (isRegInUse(physRegRecord2, refPosition, &nextLocation2))
6174             {
6175                 continue;
6176             }
6177             nextLocation = (nextLocation > nextLocation2) ? nextLocation : nextLocation2;
6178         }
6179 #endif
6180
6181         if (nextLocation > physRegNextLocation)
6182         {
6183             nextLocation = physRegNextLocation;
6184         }
6185
6186         bool isBetterLocation;
6187
6188 #ifdef DEBUG
6189         if (doSelectNearest() && farthestRefPhysRegRecord != nullptr)
6190         {
6191             isBetterLocation = (nextLocation <= farthestLocation);
6192         }
6193         else
6194 #endif
6195             // This if-stmt is associated with the above else
6196             if (recentAssignedRefWeight < farthestRefPosWeight)
6197         {
6198             isBetterLocation = true;
6199         }
6200         else
6201         {
6202             // This would mean the weight of spill ref position we found so far is equal
6203             // to the weight of the ref position that is being evaluated.  In this case
6204             // we prefer to spill ref position whose distance to its next reference is
6205             // the farthest.
6206             assert(recentAssignedRefWeight == farthestRefPosWeight);
6207
6208             // If allocateIfProfitable=true, the first spill candidate selected
6209             // will be based on weight alone. After we have found a spill
6210             // candidate whose weight is less than the 'refPosition', we will
6211             // consider farthest distance when there is a tie in weights.
6212             // This is to ensure that we don't spill a ref position whose
6213             // weight is equal to weight of 'refPosition'.
6214             if (allocateIfProfitable && farthestRefPhysRegRecord == nullptr)
6215             {
6216                 isBetterLocation = false;
6217             }
6218             else
6219             {
6220                 isBetterLocation = (nextLocation > farthestLocation);
6221
6222                 if (nextLocation > farthestLocation)
6223                 {
6224                     isBetterLocation = true;
6225                 }
6226                 else if (nextLocation == farthestLocation)
6227                 {
6228                     // Both weight and distance are equal.
6229                     // Prefer that ref position which is marked both reload and
6230                     // allocate if profitable.  These ref positions don't need
6231                     // need to be spilled as they are already in memory and
6232                     // codegen considers them as contained memory operands.
6233                     CLANG_FORMAT_COMMENT_ANCHOR;
6234 #ifdef _TARGET_ARM
6235                     // TODO-CQ-ARM: Just conservatively "and" two condition. We may implement better condision later.
6236                     isBetterLocation = true;
6237                     if (recentAssignedRef != nullptr)
6238                         isBetterLocation &= (recentAssignedRef->reload && recentAssignedRef->AllocateIfProfitable());
6239
6240                     if (recentAssignedRef2 != nullptr)
6241                         isBetterLocation &= (recentAssignedRef2->reload && recentAssignedRef2->AllocateIfProfitable());
6242 #else
6243                     isBetterLocation   = (recentAssignedRef != nullptr) && recentAssignedRef->reload &&
6244                                        recentAssignedRef->AllocateIfProfitable();
6245 #endif
6246                 }
6247                 else
6248                 {
6249                     isBetterLocation = false;
6250                 }
6251             }
6252         }
6253
6254         if (isBetterLocation)
6255         {
6256             farthestLocation         = nextLocation;
6257             farthestRefPhysRegRecord = physRegRecord;
6258 #ifdef _TARGET_ARM_
6259             farthestRefPhysRegRecord2 = physRegRecord2;
6260 #endif
6261             farthestRefPosWeight = recentAssignedRefWeight;
6262         }
6263     }
6264
6265 #if DEBUG
6266     if (allocateIfProfitable)
6267     {
6268         // There may not be a spill candidate or if one is found
6269         // its weight must be less than the weight of 'refPosition'
6270         assert((farthestRefPhysRegRecord == nullptr) || (farthestRefPosWeight < getWeight(refPosition)));
6271     }
6272     else
6273     {
6274         // Must have found a spill candidate.
6275         assert(farthestRefPhysRegRecord != nullptr);
6276         if ((farthestLocation == refLocation) && !refPosition->isFixedRegRef)
6277         {
6278 #ifdef _TARGET_ARM_
6279             Interval* assignedInterval =
6280                 (farthestRefPhysRegRecord == nullptr) ? nullptr : farthestRefPhysRegRecord->assignedInterval;
6281             Interval* assignedInterval2 =
6282                 (farthestRefPhysRegRecord2 == nullptr) ? nullptr : farthestRefPhysRegRecord2->assignedInterval;
6283             RefPosition* nextRefPosition =
6284                 (assignedInterval == nullptr) ? nullptr : assignedInterval->getNextRefPosition();
6285             RefPosition* nextRefPosition2 =
6286                 (assignedInterval2 == nullptr) ? nullptr : assignedInterval2->getNextRefPosition();
6287             if (nextRefPosition != nullptr)
6288             {
6289                 if (nextRefPosition2 != nullptr)
6290                 {
6291                     assert(!nextRefPosition->RequiresRegister() || !nextRefPosition2->RequiresRegister());
6292                 }
6293                 else
6294                 {
6295                     assert(!nextRefPosition->RequiresRegister());
6296                 }
6297             }
6298             else
6299             {
6300                 assert(nextRefPosition2 != nullptr && !nextRefPosition2->RequiresRegister());
6301             }
6302 #else  // !_TARGET_ARM_
6303             Interval*    assignedInterval = farthestRefPhysRegRecord->assignedInterval;
6304             RefPosition* nextRefPosition  = assignedInterval->getNextRefPosition();
6305             assert(!nextRefPosition->RequiresRegister());
6306 #endif // !_TARGET_ARM_
6307         }
6308         else
6309         {
6310             assert(farthestLocation > refLocation || refPosition->isFixedRegRef);
6311         }
6312     }
6313 #endif // DEBUG
6314
6315     if (farthestRefPhysRegRecord != nullptr)
6316     {
6317         foundReg = farthestRefPhysRegRecord->regNum;
6318
6319 #ifdef _TARGET_ARM_
6320         if (current->registerType == TYP_DOUBLE)
6321         {
6322             assert(genIsValidDoubleReg(foundReg));
6323             unassignDoublePhysReg(farthestRefPhysRegRecord);
6324         }
6325         else
6326 #endif
6327         {
6328             unassignPhysReg(farthestRefPhysRegRecord, farthestRefPhysRegRecord->assignedInterval->recentRefPosition);
6329         }
6330
6331         assignPhysReg(farthestRefPhysRegRecord, current);
6332         refPosition->registerAssignment = genRegMask(foundReg);
6333     }
6334     else
6335     {
6336         foundReg                        = REG_NA;
6337         refPosition->registerAssignment = RBM_NONE;
6338     }
6339
6340     return foundReg;
6341 }
6342
6343 // Grab a register to use to copy and then immediately use.
6344 // This is called only for localVar intervals that already have a register
6345 // assignment that is not compatible with the current RefPosition.
6346 // This is not like regular assignment, because we don't want to change
6347 // any preferences or existing register assignments.
6348 // Prefer a free register that's got the earliest next use.
6349 // Otherwise, spill something with the farthest next use
6350 //
6351 regNumber LinearScan::assignCopyReg(RefPosition* refPosition)
6352 {
6353     Interval* currentInterval = refPosition->getInterval();
6354     assert(currentInterval != nullptr);
6355     assert(currentInterval->isActive);
6356
6357     bool         foundFreeReg = false;
6358     RegRecord*   bestPhysReg  = nullptr;
6359     LsraLocation bestLocation = MinLocation;
6360     regMaskTP    candidates   = refPosition->registerAssignment;
6361
6362     // Save the relatedInterval, if any, so that it doesn't get modified during allocation.
6363     Interval* savedRelatedInterval   = currentInterval->relatedInterval;
6364     currentInterval->relatedInterval = nullptr;
6365
6366     // We don't want really want to change the default assignment,
6367     // so 1) pretend this isn't active, and 2) remember the old reg
6368     regNumber  oldPhysReg   = currentInterval->physReg;
6369     RegRecord* oldRegRecord = currentInterval->assignedReg;
6370     assert(oldRegRecord->regNum == oldPhysReg);
6371     currentInterval->isActive = false;
6372
6373     regNumber allocatedReg = tryAllocateFreeReg(currentInterval, refPosition);
6374     if (allocatedReg == REG_NA)
6375     {
6376         allocatedReg = allocateBusyReg(currentInterval, refPosition, false);
6377     }
6378
6379     // Now restore the old info
6380     currentInterval->relatedInterval = savedRelatedInterval;
6381     currentInterval->physReg         = oldPhysReg;
6382     currentInterval->assignedReg     = oldRegRecord;
6383     currentInterval->isActive        = true;
6384
6385     refPosition->copyReg = true;
6386     return allocatedReg;
6387 }
6388
6389 // Check if the interval is already assigned and if it is then unassign the physical record
6390 // then set the assignedInterval to 'interval'
6391 //
6392 void LinearScan::checkAndAssignInterval(RegRecord* regRec, Interval* interval)
6393 {
6394     if (regRec->assignedInterval != nullptr && regRec->assignedInterval != interval)
6395     {
6396         // This is allocated to another interval.  Either it is inactive, or it was allocated as a
6397         // copyReg and is therefore not the "assignedReg" of the other interval.  In the latter case,
6398         // we simply unassign it - in the former case we need to set the physReg on the interval to
6399         // REG_NA to indicate that it is no longer in that register.
6400         // The lack of checking for this case resulted in an assert in the retail version of System.dll,
6401         // in method SerialStream.GetDcbFlag.
6402         // Note that we can't check for the copyReg case, because we may have seen a more recent
6403         // RefPosition for the Interval that was NOT a copyReg.
6404         if (regRec->assignedInterval->assignedReg == regRec)
6405         {
6406             assert(regRec->assignedInterval->isActive == false);
6407             regRec->assignedInterval->physReg = REG_NA;
6408         }
6409         unassignPhysReg(regRec->regNum);
6410     }
6411
6412     updateAssignedInterval(regRec, interval, interval->registerType);
6413 }
6414
6415 // Assign the given physical register interval to the given interval
6416 void LinearScan::assignPhysReg(RegRecord* regRec, Interval* interval)
6417 {
6418     regMaskTP assignedRegMask = genRegMask(regRec->regNum);
6419     compiler->codeGen->regSet.rsSetRegsModified(assignedRegMask DEBUGARG(dumpTerse));
6420
6421     checkAndAssignInterval(regRec, interval);
6422     interval->assignedReg = regRec;
6423
6424     interval->physReg  = regRec->regNum;
6425     interval->isActive = true;
6426     if (interval->isLocalVar)
6427     {
6428         // Prefer this register for future references
6429         interval->updateRegisterPreferences(assignedRegMask);
6430     }
6431 }
6432
6433 //------------------------------------------------------------------------
6434 // setIntervalAsSplit: Set this Interval as being split
6435 //
6436 // Arguments:
6437 //    interval - The Interval which is being split
6438 //
6439 // Return Value:
6440 //    None.
6441 //
6442 // Notes:
6443 //    The given Interval will be marked as split, and it will be added to the
6444 //    set of splitOrSpilledVars.
6445 //
6446 // Assumptions:
6447 //    "interval" must be a lclVar interval, as tree temps are never split.
6448 //    This is asserted in the call to getVarIndex().
6449 //
6450 void LinearScan::setIntervalAsSplit(Interval* interval)
6451 {
6452     if (interval->isLocalVar)
6453     {
6454         unsigned varIndex = interval->getVarIndex(compiler);
6455         if (!interval->isSplit)
6456         {
6457             VarSetOps::AddElemD(compiler, splitOrSpilledVars, varIndex);
6458         }
6459         else
6460         {
6461             assert(VarSetOps::IsMember(compiler, splitOrSpilledVars, varIndex));
6462         }
6463     }
6464     interval->isSplit = true;
6465 }
6466
6467 //------------------------------------------------------------------------
6468 // setIntervalAsSpilled: Set this Interval as being spilled
6469 //
6470 // Arguments:
6471 //    interval - The Interval which is being spilled
6472 //
6473 // Return Value:
6474 //    None.
6475 //
6476 // Notes:
6477 //    The given Interval will be marked as spilled, and it will be added
6478 //    to the set of splitOrSpilledVars.
6479 //
6480 void LinearScan::setIntervalAsSpilled(Interval* interval)
6481 {
6482     if (interval->isLocalVar)
6483     {
6484         unsigned varIndex = interval->getVarIndex(compiler);
6485         if (!interval->isSpilled)
6486         {
6487             VarSetOps::AddElemD(compiler, splitOrSpilledVars, varIndex);
6488         }
6489         else
6490         {
6491             assert(VarSetOps::IsMember(compiler, splitOrSpilledVars, varIndex));
6492         }
6493     }
6494     interval->isSpilled = true;
6495 }
6496
6497 //------------------------------------------------------------------------
6498 // spill: Spill this Interval between "fromRefPosition" and "toRefPosition"
6499 //
6500 // Arguments:
6501 //    fromRefPosition - The RefPosition at which the Interval is to be spilled
6502 //    toRefPosition   - The RefPosition at which it must be reloaded
6503 //
6504 // Return Value:
6505 //    None.
6506 //
6507 // Assumptions:
6508 //    fromRefPosition and toRefPosition must not be null
6509 //
6510 void LinearScan::spillInterval(Interval* interval, RefPosition* fromRefPosition, RefPosition* toRefPosition)
6511 {
6512     assert(fromRefPosition != nullptr && toRefPosition != nullptr);
6513     assert(fromRefPosition->getInterval() == interval && toRefPosition->getInterval() == interval);
6514     assert(fromRefPosition->nextRefPosition == toRefPosition);
6515
6516     if (!fromRefPosition->lastUse)
6517     {
6518         // If not allocated a register, Lcl var def/use ref positions even if reg optional
6519         // should be marked as spillAfter.
6520         if (!fromRefPosition->RequiresRegister() && !(interval->isLocalVar && fromRefPosition->IsActualRef()))
6521         {
6522             fromRefPosition->registerAssignment = RBM_NONE;
6523         }
6524         else
6525         {
6526             fromRefPosition->spillAfter = true;
6527         }
6528     }
6529     assert(toRefPosition != nullptr);
6530
6531 #ifdef DEBUG
6532     if (VERBOSE)
6533     {
6534         dumpLsraAllocationEvent(LSRA_EVENT_SPILL, interval);
6535     }
6536 #endif // DEBUG
6537
6538     INTRACK_STATS(updateLsraStat(LSRA_STAT_SPILL, fromRefPosition->bbNum));
6539
6540     interval->isActive = false;
6541     setIntervalAsSpilled(interval);
6542
6543     // If fromRefPosition occurs before the beginning of this block, mark this as living in the stack
6544     // on entry to this block.
6545     if (fromRefPosition->nodeLocation <= curBBStartLocation)
6546     {
6547         // This must be a lclVar interval
6548         assert(interval->isLocalVar);
6549         setInVarRegForBB(curBBNum, interval->varNum, REG_STK);
6550     }
6551 }
6552
6553 //------------------------------------------------------------------------
6554 // unassignPhysRegNoSpill: Unassign the given physical register record from
6555 //                         an active interval, without spilling.
6556 //
6557 // Arguments:
6558 //    regRec           - the RegRecord to be unasssigned
6559 //
6560 // Return Value:
6561 //    None.
6562 //
6563 // Assumptions:
6564 //    The assignedInterval must not be null, and must be active.
6565 //
6566 // Notes:
6567 //    This method is used to unassign a register when an interval needs to be moved to a
6568 //    different register, but not (yet) spilled.
6569
6570 void LinearScan::unassignPhysRegNoSpill(RegRecord* regRec)
6571 {
6572     Interval* assignedInterval = regRec->assignedInterval;
6573     assert(assignedInterval != nullptr && assignedInterval->isActive);
6574     assignedInterval->isActive = false;
6575     unassignPhysReg(regRec, nullptr);
6576     assignedInterval->isActive = true;
6577 }
6578
6579 //------------------------------------------------------------------------
6580 // checkAndClearInterval: Clear the assignedInterval for the given
6581 //                        physical register record
6582 //
6583 // Arguments:
6584 //    regRec           - the physical RegRecord to be unasssigned
6585 //    spillRefPosition - The RefPosition at which the assignedInterval is to be spilled
6586 //                       or nullptr if we aren't spilling
6587 //
6588 // Return Value:
6589 //    None.
6590 //
6591 // Assumptions:
6592 //    see unassignPhysReg
6593 //
6594 void LinearScan::checkAndClearInterval(RegRecord* regRec, RefPosition* spillRefPosition)
6595 {
6596     Interval* assignedInterval = regRec->assignedInterval;
6597     assert(assignedInterval != nullptr);
6598     regNumber thisRegNum = regRec->regNum;
6599
6600     if (spillRefPosition == nullptr)
6601     {
6602         // Note that we can't assert  for the copyReg case
6603         //
6604         if (assignedInterval->physReg == thisRegNum)
6605         {
6606             assert(assignedInterval->isActive == false);
6607         }
6608     }
6609     else
6610     {
6611         assert(spillRefPosition->getInterval() == assignedInterval);
6612     }
6613
6614     updateAssignedInterval(regRec, nullptr, assignedInterval->registerType);
6615 }
6616
6617 //------------------------------------------------------------------------
6618 // unassignPhysReg: Unassign the given physical register record, and spill the
6619 //                  assignedInterval at the given spillRefPosition, if any.
6620 //
6621 // Arguments:
6622 //    regRec           - the RegRecord to be unasssigned
6623 //    spillRefPosition - The RefPosition at which the assignedInterval is to be spilled
6624 //
6625 // Return Value:
6626 //    None.
6627 //
6628 // Assumptions:
6629 //    The assignedInterval must not be null.
6630 //    If spillRefPosition is null, the assignedInterval must be inactive, or not currently
6631 //    assigned to this register (e.g. this is a copyReg for that Interval).
6632 //    Otherwise, spillRefPosition must be associated with the assignedInterval.
6633 //
6634 void LinearScan::unassignPhysReg(RegRecord* regRec, RefPosition* spillRefPosition)
6635 {
6636     Interval* assignedInterval = regRec->assignedInterval;
6637     assert(assignedInterval != nullptr);
6638
6639     regNumber thisRegNum = regRec->regNum;
6640
6641 #ifdef _TARGET_ARM_
6642     regNumber  nextRegNum = REG_NA;
6643     RegRecord* nextRegRec = nullptr;
6644
6645     // Prepare second half RegRecord of a double register for TYP_DOUBLE
6646     if (assignedInterval->registerType == TYP_DOUBLE)
6647     {
6648         assert(isFloatRegType(regRec->registerType));
6649         assert(genIsValidDoubleReg(regRec->regNum));
6650
6651         nextRegNum = REG_NEXT(regRec->regNum);
6652         nextRegRec = getRegisterRecord(nextRegNum);
6653
6654         // Both two RegRecords should have been assigned to the same interval.
6655         assert(assignedInterval == nextRegRec->assignedInterval);
6656     }
6657 #endif // _TARGET_ARM_
6658
6659     checkAndClearInterval(regRec, spillRefPosition);
6660
6661 #ifdef _TARGET_ARM_
6662     if (assignedInterval->registerType == TYP_DOUBLE)
6663     {
6664         // Both two RegRecords should have been unassigned together.
6665         assert(regRec->assignedInterval == nullptr);
6666         assert(nextRegRec->assignedInterval == nullptr);
6667     }
6668 #endif // _TARGET_ARM_
6669
6670 #ifdef DEBUG
6671     if (VERBOSE && !dumpTerse)
6672     {
6673         printf("unassigning %s: ", getRegName(regRec->regNum));
6674         assignedInterval->dump();
6675         printf("\n");
6676     }
6677 #endif // DEBUG
6678
6679     RefPosition* nextRefPosition = nullptr;
6680     if (spillRefPosition != nullptr)
6681     {
6682         nextRefPosition = spillRefPosition->nextRefPosition;
6683     }
6684
6685     if (assignedInterval->physReg != REG_NA && assignedInterval->physReg != thisRegNum)
6686     {
6687         // This must have been a temporary copy reg, but we can't assert that because there
6688         // may have been intervening RefPositions that were not copyRegs.
6689
6690         // reg->assignedInterval has already been set to nullptr by checkAndClearInterval()
6691         assert(regRec->assignedInterval == nullptr);
6692         return;
6693     }
6694
6695     regNumber victimAssignedReg = assignedInterval->physReg;
6696     assignedInterval->physReg   = REG_NA;
6697
6698     bool spill = assignedInterval->isActive && nextRefPosition != nullptr;
6699     if (spill)
6700     {
6701         // If this is an active interval, it must have a recentRefPosition,
6702         // otherwise it would not be active
6703         assert(spillRefPosition != nullptr);
6704
6705 #if 0
6706         // TODO-CQ: Enable this and insert an explicit GT_COPY (otherwise there's no way to communicate
6707         // to codegen that we want the copyReg to be the new home location).
6708         // If the last reference was a copyReg, and we're spilling the register
6709         // it was copied from, then make the copyReg the new primary location
6710         // if possible
6711         if (spillRefPosition->copyReg)
6712         {
6713             regNumber copyFromRegNum = victimAssignedReg;
6714             regNumber copyRegNum = genRegNumFromMask(spillRefPosition->registerAssignment);
6715             if (copyFromRegNum == thisRegNum &&
6716                 getRegisterRecord(copyRegNum)->assignedInterval == assignedInterval)
6717             {
6718                 assert(copyRegNum != thisRegNum);
6719                 assignedInterval->physReg = copyRegNum;
6720                 assignedInterval->assignedReg = this->getRegisterRecord(copyRegNum);
6721                 return;
6722             }
6723         }
6724 #endif // 0
6725 #ifdef DEBUG
6726         // With JitStressRegs == 0x80 (LSRA_EXTEND_LIFETIMES), we may have a RefPosition
6727         // that is not marked lastUse even though the treeNode is a lastUse.  In that case
6728         // we must not mark it for spill because the register will have been immediately freed
6729         // after use.  While we could conceivably add special handling for this case in codegen,
6730         // it would be messy and undesirably cause the "bleeding" of LSRA stress modes outside
6731         // of LSRA.
6732         if (extendLifetimes() && assignedInterval->isLocalVar && RefTypeIsUse(spillRefPosition->refType) &&
6733             spillRefPosition->treeNode != nullptr && (spillRefPosition->treeNode->gtFlags & GTF_VAR_DEATH) != 0)
6734         {
6735             dumpLsraAllocationEvent(LSRA_EVENT_SPILL_EXTENDED_LIFETIME, assignedInterval);
6736             assignedInterval->isActive = false;
6737             spill                      = false;
6738             // If the spillRefPosition occurs before the beginning of this block, it will have
6739             // been marked as living in this register on entry to this block, but we now need
6740             // to mark this as living on the stack.
6741             if (spillRefPosition->nodeLocation <= curBBStartLocation)
6742             {
6743                 setInVarRegForBB(curBBNum, assignedInterval->varNum, REG_STK);
6744                 if (spillRefPosition->nextRefPosition != nullptr)
6745                 {
6746                     setIntervalAsSpilled(assignedInterval);
6747                 }
6748             }
6749             else
6750             {
6751                 // Otherwise, we need to mark spillRefPosition as lastUse, or the interval
6752                 // will remain active beyond its allocated range during the resolution phase.
6753                 spillRefPosition->lastUse = true;
6754             }
6755         }
6756         else
6757 #endif // DEBUG
6758         {
6759             spillInterval(assignedInterval, spillRefPosition, nextRefPosition);
6760         }
6761     }
6762     // Maintain the association with the interval, if it has more references.
6763     // Or, if we "remembered" an interval assigned to this register, restore it.
6764     if (nextRefPosition != nullptr)
6765     {
6766         assignedInterval->assignedReg = regRec;
6767     }
6768     else if (canRestorePreviousInterval(regRec, assignedInterval))
6769     {
6770         regRec->assignedInterval = regRec->previousInterval;
6771         regRec->previousInterval = nullptr;
6772
6773 #ifdef _TARGET_ARM_
6774         // Note:
6775         //   We can not use updateAssignedInterval() and updatePreviousInterval() here,
6776         //   because regRec may not be a even-numbered float register.
6777
6778         // Update second half RegRecord of a double register for TYP_DOUBLE
6779         if (regRec->assignedInterval->registerType == TYP_DOUBLE)
6780         {
6781             RegRecord* anotherHalfRegRec = findAnotherHalfRegRec(regRec);
6782
6783             anotherHalfRegRec->assignedInterval = regRec->assignedInterval;
6784             anotherHalfRegRec->previousInterval = nullptr;
6785         }
6786 #endif // _TARGET_ARM_
6787
6788 #ifdef DEBUG
6789         if (spill)
6790         {
6791             dumpLsraAllocationEvent(LSRA_EVENT_RESTORE_PREVIOUS_INTERVAL_AFTER_SPILL, regRec->assignedInterval,
6792                                     thisRegNum);
6793         }
6794         else
6795         {
6796             dumpLsraAllocationEvent(LSRA_EVENT_RESTORE_PREVIOUS_INTERVAL, regRec->assignedInterval, thisRegNum);
6797         }
6798 #endif // DEBUG
6799     }
6800     else
6801     {
6802         updateAssignedInterval(regRec, nullptr, assignedInterval->registerType);
6803         updatePreviousInterval(regRec, nullptr, assignedInterval->registerType);
6804     }
6805 }
6806
6807 //------------------------------------------------------------------------
6808 // spillGCRefs: Spill any GC-type intervals that are currently in registers.a
6809 //
6810 // Arguments:
6811 //    killRefPosition - The RefPosition for the kill
6812 //
6813 // Return Value:
6814 //    None.
6815 //
6816 void LinearScan::spillGCRefs(RefPosition* killRefPosition)
6817 {
6818     // For each physical register that can hold a GC type,
6819     // if it is occupied by an interval of a GC type, spill that interval.
6820     regMaskTP candidateRegs = killRefPosition->registerAssignment;
6821     while (candidateRegs != RBM_NONE)
6822     {
6823         regMaskTP nextRegBit = genFindLowestBit(candidateRegs);
6824         candidateRegs &= ~nextRegBit;
6825         regNumber  nextReg          = genRegNumFromMask(nextRegBit);
6826         RegRecord* regRecord        = getRegisterRecord(nextReg);
6827         Interval*  assignedInterval = regRecord->assignedInterval;
6828         if (assignedInterval == nullptr || (assignedInterval->isActive == false) ||
6829             !varTypeIsGC(assignedInterval->registerType))
6830         {
6831             continue;
6832         }
6833         unassignPhysReg(regRecord, assignedInterval->recentRefPosition);
6834     }
6835     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DONE_KILL_GC_REFS, nullptr, REG_NA, nullptr));
6836 }
6837
6838 //------------------------------------------------------------------------
6839 // processBlockEndAllocation: Update var locations after 'currentBlock' has been allocated
6840 //
6841 // Arguments:
6842 //    currentBlock - the BasicBlock we have just finished allocating registers for
6843 //
6844 // Return Value:
6845 //    None
6846 //
6847 // Notes:
6848 //    Calls processBlockEndLocations() to set the outVarToRegMap, then gets the next block,
6849 //    and sets the inVarToRegMap appropriately.
6850
6851 void LinearScan::processBlockEndAllocation(BasicBlock* currentBlock)
6852 {
6853     assert(currentBlock != nullptr);
6854     if (enregisterLocalVars)
6855     {
6856         processBlockEndLocations(currentBlock);
6857     }
6858     markBlockVisited(currentBlock);
6859
6860     // Get the next block to allocate.
6861     // When the last block in the method has successors, there will be a final "RefTypeBB" to
6862     // ensure that we get the varToRegMap set appropriately, but in that case we don't need
6863     // to worry about "nextBlock".
6864     BasicBlock* nextBlock = getNextBlock();
6865     if (nextBlock != nullptr)
6866     {
6867         processBlockStartLocations(nextBlock, true);
6868     }
6869 }
6870
6871 //------------------------------------------------------------------------
6872 // rotateBlockStartLocation: When in the LSRA_BLOCK_BOUNDARY_ROTATE stress mode, attempt to
6873 //                           "rotate" the register assignment for a localVar to the next higher
6874 //                           register that is available.
6875 //
6876 // Arguments:
6877 //    interval      - the Interval for the variable whose register is getting rotated
6878 //    targetReg     - its register assignment from the predecessor block being used for live-in
6879 //    availableRegs - registers available for use
6880 //
6881 // Return Value:
6882 //    The new register to use.
6883
6884 #ifdef DEBUG
6885 regNumber LinearScan::rotateBlockStartLocation(Interval* interval, regNumber targetReg, regMaskTP availableRegs)
6886 {
6887     if (targetReg != REG_STK && getLsraBlockBoundaryLocations() == LSRA_BLOCK_BOUNDARY_ROTATE)
6888     {
6889         // If we're rotating the register locations at block boundaries, try to use
6890         // the next higher register number of the appropriate register type.
6891         regMaskTP candidateRegs = allRegs(interval->registerType) & availableRegs;
6892         regNumber firstReg      = REG_NA;
6893         regNumber newReg        = REG_NA;
6894         while (candidateRegs != RBM_NONE)
6895         {
6896             regMaskTP nextRegBit = genFindLowestBit(candidateRegs);
6897             candidateRegs &= ~nextRegBit;
6898             regNumber nextReg = genRegNumFromMask(nextRegBit);
6899             if (nextReg > targetReg)
6900             {
6901                 newReg = nextReg;
6902                 break;
6903             }
6904             else if (firstReg == REG_NA)
6905             {
6906                 firstReg = nextReg;
6907             }
6908         }
6909         if (newReg == REG_NA)
6910         {
6911             assert(firstReg != REG_NA);
6912             newReg = firstReg;
6913         }
6914         targetReg = newReg;
6915     }
6916     return targetReg;
6917 }
6918 #endif // DEBUG
6919
6920 #ifdef _TARGET_ARM_
6921 //--------------------------------------------------------------------------------------
6922 // isSecondHalfReg: Test if recRec is second half of double register
6923 //                  which is assigned to an interval.
6924 //
6925 // Arguments:
6926 //    regRec - a register to be tested
6927 //    interval - an interval which is assigned to some register
6928 //
6929 // Assumptions:
6930 //    None
6931 //
6932 // Return Value:
6933 //    True only if regRec is second half of assignedReg in interval
6934 //
6935 bool LinearScan::isSecondHalfReg(RegRecord* regRec, Interval* interval)
6936 {
6937     RegRecord* assignedReg = interval->assignedReg;
6938
6939     if (assignedReg != nullptr && interval->registerType == TYP_DOUBLE)
6940     {
6941         // interval should have been allocated to a valid double register
6942         assert(genIsValidDoubleReg(assignedReg->regNum));
6943
6944         // Find a second half RegRecord of double register
6945         regNumber firstRegNum  = assignedReg->regNum;
6946         regNumber secondRegNum = REG_NEXT(firstRegNum);
6947
6948         assert(genIsValidFloatReg(secondRegNum) && !genIsValidDoubleReg(secondRegNum));
6949
6950         RegRecord* secondRegRec = getRegisterRecord(secondRegNum);
6951
6952         return secondRegRec == regRec;
6953     }
6954
6955     return false;
6956 }
6957
6958 //------------------------------------------------------------------------------------------
6959 // findAnotherHalfRegRec: Find another half RegRecord which forms same ARM32 double register
6960 //
6961 // Arguments:
6962 //    regRec - A float RegRecord
6963 //
6964 // Assumptions:
6965 //    None
6966 //
6967 // Return Value:
6968 //    A RegRecord which forms same double register with regRec
6969 //
6970 RegRecord* LinearScan::findAnotherHalfRegRec(RegRecord* regRec)
6971 {
6972     regNumber  anotherHalfRegNum;
6973     RegRecord* anotherHalfRegRec;
6974
6975     assert(genIsValidFloatReg(regRec->regNum));
6976
6977     // Find another half register for TYP_DOUBLE interval,
6978     // following same logic in canRestorePreviousInterval().
6979     if (genIsValidDoubleReg(regRec->regNum))
6980     {
6981         anotherHalfRegNum = REG_NEXT(regRec->regNum);
6982         assert(!genIsValidDoubleReg(anotherHalfRegNum));
6983     }
6984     else
6985     {
6986         anotherHalfRegNum = REG_PREV(regRec->regNum);
6987         assert(genIsValidDoubleReg(anotherHalfRegNum));
6988     }
6989     anotherHalfRegRec = getRegisterRecord(anotherHalfRegNum);
6990
6991     return anotherHalfRegRec;
6992 }
6993 #endif
6994
6995 //--------------------------------------------------------------------------------------
6996 // canRestorePreviousInterval: Test if we can restore previous interval
6997 //
6998 // Arguments:
6999 //    regRec - a register which contains previous interval to be restored
7000 //    assignedInterval - an interval just unassigned
7001 //
7002 // Assumptions:
7003 //    None
7004 //
7005 // Return Value:
7006 //    True only if previous interval of regRec can be restored
7007 //
7008 bool LinearScan::canRestorePreviousInterval(RegRecord* regRec, Interval* assignedInterval)
7009 {
7010     bool retVal =
7011         (regRec->previousInterval != nullptr && regRec->previousInterval != assignedInterval &&
7012          regRec->previousInterval->assignedReg == regRec && regRec->previousInterval->getNextRefPosition() != nullptr);
7013
7014 #ifdef _TARGET_ARM_
7015     if (retVal && regRec->previousInterval->registerType == TYP_DOUBLE)
7016     {
7017         RegRecord* anotherHalfRegRec = findAnotherHalfRegRec(regRec);
7018
7019         retVal = retVal && anotherHalfRegRec->assignedInterval == nullptr;
7020     }
7021 #endif
7022
7023     return retVal;
7024 }
7025
7026 bool LinearScan::isAssignedToInterval(Interval* interval, RegRecord* regRec)
7027 {
7028     bool isAssigned = (interval->assignedReg == regRec);
7029 #ifdef _TARGET_ARM_
7030     isAssigned |= isSecondHalfReg(regRec, interval);
7031 #endif
7032     return isAssigned;
7033 }
7034
7035 //------------------------------------------------------------------------
7036 // processBlockStartLocations: Update var locations on entry to 'currentBlock' and clear constant
7037 //                             registers.
7038 //
7039 // Arguments:
7040 //    currentBlock   - the BasicBlock we are about to allocate registers for
7041 //    allocationPass - true if we are currently allocating registers (versus writing them back)
7042 //
7043 // Return Value:
7044 //    None
7045 //
7046 // Notes:
7047 //    During the allocation pass, we use the outVarToRegMap of the selected predecessor to
7048 //    determine the lclVar locations for the inVarToRegMap.
7049 //    During the resolution (write-back) pass, we only modify the inVarToRegMap in cases where
7050 //    a lclVar was spilled after the block had been completed.
7051 void LinearScan::processBlockStartLocations(BasicBlock* currentBlock, bool allocationPass)
7052 {
7053     // If we have no register candidates we should only call this method during allocation.
7054
7055     assert(enregisterLocalVars || allocationPass);
7056
7057     if (!enregisterLocalVars)
7058     {
7059         // Just clear any constant registers and return.
7060         for (regNumber reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
7061         {
7062             RegRecord* physRegRecord    = getRegisterRecord(reg);
7063             Interval*  assignedInterval = physRegRecord->assignedInterval;
7064
7065             if (assignedInterval != nullptr)
7066             {
7067                 assert(assignedInterval->isConstant);
7068                 physRegRecord->assignedInterval = nullptr;
7069             }
7070         }
7071         INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_START_BB, nullptr, REG_NA, currentBlock));
7072         return;
7073     }
7074
7075     unsigned    predBBNum         = blockInfo[currentBlock->bbNum].predBBNum;
7076     VarToRegMap predVarToRegMap   = getOutVarToRegMap(predBBNum);
7077     VarToRegMap inVarToRegMap     = getInVarToRegMap(currentBlock->bbNum);
7078     bool        hasCriticalInEdge = blockInfo[currentBlock->bbNum].hasCriticalInEdge;
7079
7080     VarSetOps::AssignNoCopy(compiler, currentLiveVars,
7081                             VarSetOps::Intersection(compiler, registerCandidateVars, currentBlock->bbLiveIn));
7082 #ifdef DEBUG
7083     if (getLsraExtendLifeTimes())
7084     {
7085         VarSetOps::AssignNoCopy(compiler, currentLiveVars, registerCandidateVars);
7086     }
7087     // If we are rotating register assignments at block boundaries, we want to make the
7088     // inactive registers available for the rotation.
7089     regMaskTP inactiveRegs = RBM_NONE;
7090 #endif // DEBUG
7091     regMaskTP       liveRegs = RBM_NONE;
7092     VarSetOps::Iter iter(compiler, currentLiveVars);
7093     unsigned        varIndex = 0;
7094     while (iter.NextElem(&varIndex))
7095     {
7096         unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
7097         if (!compiler->lvaTable[varNum].lvLRACandidate)
7098         {
7099             continue;
7100         }
7101         regNumber    targetReg;
7102         Interval*    interval        = getIntervalForLocalVar(varIndex);
7103         RefPosition* nextRefPosition = interval->getNextRefPosition();
7104         assert(nextRefPosition != nullptr);
7105
7106         if (allocationPass)
7107         {
7108             targetReg = getVarReg(predVarToRegMap, varIndex);
7109 #ifdef DEBUG
7110             regNumber newTargetReg = rotateBlockStartLocation(interval, targetReg, (~liveRegs | inactiveRegs));
7111             if (newTargetReg != targetReg)
7112             {
7113                 targetReg = newTargetReg;
7114                 setIntervalAsSplit(interval);
7115             }
7116 #endif // DEBUG
7117             setVarReg(inVarToRegMap, varIndex, targetReg);
7118         }
7119         else // !allocationPass (i.e. resolution/write-back pass)
7120         {
7121             targetReg = getVarReg(inVarToRegMap, varIndex);
7122             // There are four cases that we need to consider during the resolution pass:
7123             // 1. This variable had a register allocated initially, and it was not spilled in the RefPosition
7124             //    that feeds this block.  In this case, both targetReg and predVarToRegMap[varIndex] will be targetReg.
7125             // 2. This variable had not been spilled prior to the end of predBB, but was later spilled, so
7126             //    predVarToRegMap[varIndex] will be REG_STK, but targetReg is its former allocated value.
7127             //    In this case, we will normally change it to REG_STK.  We will update its "spilled" status when we
7128             //    encounter it in resolveLocalRef().
7129             // 2a. If the next RefPosition is marked as a copyReg, we need to retain the allocated register.  This is
7130             //     because the copyReg RefPosition will not have recorded the "home" register, yet downstream
7131             //     RefPositions rely on the correct "home" register.
7132             // 3. This variable was spilled before we reached the end of predBB.  In this case, both targetReg and
7133             //    predVarToRegMap[varIndex] will be REG_STK, and the next RefPosition will have been marked
7134             //    as reload during allocation time if necessary (note that by the time we actually reach the next
7135             //    RefPosition, we may be using a different predecessor, at which it is still in a register).
7136             // 4. This variable was spilled during the allocation of this block, so targetReg is REG_STK
7137             //    (because we set inVarToRegMap at the time we spilled it), but predVarToRegMap[varIndex]
7138             //    is not REG_STK.  We retain the REG_STK value in the inVarToRegMap.
7139             if (targetReg != REG_STK)
7140             {
7141                 if (getVarReg(predVarToRegMap, varIndex) != REG_STK)
7142                 {
7143                     // Case #1 above.
7144                     assert(getVarReg(predVarToRegMap, varIndex) == targetReg ||
7145                            getLsraBlockBoundaryLocations() == LSRA_BLOCK_BOUNDARY_ROTATE);
7146                 }
7147                 else if (!nextRefPosition->copyReg)
7148                 {
7149                     // case #2 above.
7150                     setVarReg(inVarToRegMap, varIndex, REG_STK);
7151                     targetReg = REG_STK;
7152                 }
7153                 // Else case 2a. - retain targetReg.
7154             }
7155             // Else case #3 or #4, we retain targetReg and nothing further to do or assert.
7156         }
7157         if (interval->physReg == targetReg)
7158         {
7159             if (interval->isActive)
7160             {
7161                 assert(targetReg != REG_STK);
7162                 assert(interval->assignedReg != nullptr && interval->assignedReg->regNum == targetReg &&
7163                        interval->assignedReg->assignedInterval == interval);
7164                 liveRegs |= genRegMask(targetReg);
7165                 continue;
7166             }
7167         }
7168         else if (interval->physReg != REG_NA)
7169         {
7170             // This can happen if we are using the locations from a basic block other than the
7171             // immediately preceding one - where the variable was in a different location.
7172             if (targetReg != REG_STK)
7173             {
7174                 // Unassign it from the register (it will get a new register below).
7175                 if (interval->assignedReg != nullptr && interval->assignedReg->assignedInterval == interval)
7176                 {
7177                     interval->isActive = false;
7178                     unassignPhysReg(getRegisterRecord(interval->physReg), nullptr);
7179                 }
7180                 else
7181                 {
7182                     // This interval was live in this register the last time we saw a reference to it,
7183                     // but has since been displaced.
7184                     interval->physReg = REG_NA;
7185                 }
7186             }
7187             else if (allocationPass)
7188             {
7189                 // Keep the register assignment - if another var has it, it will get unassigned.
7190                 // Otherwise, resolution will fix it up later, and it will be more
7191                 // likely to match other assignments this way.
7192                 interval->isActive = true;
7193                 liveRegs |= genRegMask(interval->physReg);
7194                 INDEBUG(inactiveRegs |= genRegMask(interval->physReg));
7195                 setVarReg(inVarToRegMap, varIndex, interval->physReg);
7196             }
7197             else
7198             {
7199                 interval->physReg = REG_NA;
7200             }
7201         }
7202         if (targetReg != REG_STK)
7203         {
7204             RegRecord* targetRegRecord = getRegisterRecord(targetReg);
7205             liveRegs |= genRegMask(targetReg);
7206             if (!interval->isActive)
7207             {
7208                 interval->isActive    = true;
7209                 interval->physReg     = targetReg;
7210                 interval->assignedReg = targetRegRecord;
7211             }
7212             Interval* assignedInterval = targetRegRecord->assignedInterval;
7213             if (assignedInterval != interval)
7214             {
7215                 // Is there another interval currently assigned to this register?  If so unassign it.
7216                 if (assignedInterval != nullptr)
7217                 {
7218                     if (isAssignedToInterval(assignedInterval, targetRegRecord))
7219                     {
7220                         regNumber assignedRegNum = assignedInterval->assignedReg->regNum;
7221
7222                         // If the interval is active, it will be set to active when we reach its new
7223                         // register assignment (which we must not yet have done, or it wouldn't still be
7224                         // assigned to this register).
7225                         assignedInterval->isActive = false;
7226                         unassignPhysReg(assignedInterval->assignedReg, nullptr);
7227                         if (allocationPass && assignedInterval->isLocalVar &&
7228                             inVarToRegMap[assignedInterval->getVarIndex(compiler)] == assignedRegNum)
7229                         {
7230                             inVarToRegMap[assignedInterval->getVarIndex(compiler)] = REG_STK;
7231                         }
7232                     }
7233                     else
7234                     {
7235                         // This interval is no longer assigned to this register.
7236                         updateAssignedInterval(targetRegRecord, nullptr, assignedInterval->registerType);
7237                     }
7238                 }
7239                 assignPhysReg(targetRegRecord, interval);
7240             }
7241             if (interval->recentRefPosition != nullptr && !interval->recentRefPosition->copyReg &&
7242                 interval->recentRefPosition->registerAssignment != genRegMask(targetReg))
7243             {
7244                 interval->getNextRefPosition()->outOfOrder = true;
7245             }
7246         }
7247     }
7248
7249     // Unassign any registers that are no longer live.
7250     for (regNumber reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
7251     {
7252         if ((liveRegs & genRegMask(reg)) == 0)
7253         {
7254             RegRecord* physRegRecord    = getRegisterRecord(reg);
7255             Interval*  assignedInterval = physRegRecord->assignedInterval;
7256
7257             if (assignedInterval != nullptr)
7258             {
7259                 assert(assignedInterval->isLocalVar || assignedInterval->isConstant);
7260
7261                 if (!assignedInterval->isConstant && assignedInterval->assignedReg == physRegRecord)
7262                 {
7263                     assignedInterval->isActive = false;
7264                     if (assignedInterval->getNextRefPosition() == nullptr)
7265                     {
7266                         unassignPhysReg(physRegRecord, nullptr);
7267                     }
7268                     inVarToRegMap[assignedInterval->getVarIndex(compiler)] = REG_STK;
7269                 }
7270                 else
7271                 {
7272                     // This interval may still be active, but was in another register in an
7273                     // intervening block.
7274                     updateAssignedInterval(physRegRecord, nullptr, assignedInterval->registerType);
7275                 }
7276
7277 #ifdef _TARGET_ARM_
7278                 if (assignedInterval->registerType == TYP_DOUBLE)
7279                 {
7280                     // Skip next float register, because we already addressed a double register
7281                     assert(genIsValidDoubleReg(reg));
7282                     reg = REG_NEXT(reg);
7283                 }
7284 #endif // _TARGET_ARM_
7285             }
7286         }
7287 #ifdef _TARGET_ARM_
7288         else
7289         {
7290             RegRecord* physRegRecord    = getRegisterRecord(reg);
7291             Interval*  assignedInterval = physRegRecord->assignedInterval;
7292
7293             if (assignedInterval != nullptr && assignedInterval->registerType == TYP_DOUBLE)
7294             {
7295                 // Skip next float register, because we already addressed a double register
7296                 assert(genIsValidDoubleReg(reg));
7297                 reg = REG_NEXT(reg);
7298             }
7299         }
7300 #endif // _TARGET_ARM_
7301     }
7302     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_START_BB, nullptr, REG_NA, currentBlock));
7303 }
7304
7305 //------------------------------------------------------------------------
7306 // processBlockEndLocations: Record the variables occupying registers after completing the current block.
7307 //
7308 // Arguments:
7309 //    currentBlock - the block we have just completed.
7310 //
7311 // Return Value:
7312 //    None
7313 //
7314 // Notes:
7315 //    This must be called both during the allocation and resolution (write-back) phases.
7316 //    This is because we need to have the outVarToRegMap locations in order to set the locations
7317 //    at successor blocks during allocation time, but if lclVars are spilled after a block has been
7318 //    completed, we need to record the REG_STK location for those variables at resolution time.
7319
7320 void LinearScan::processBlockEndLocations(BasicBlock* currentBlock)
7321 {
7322     assert(currentBlock != nullptr && currentBlock->bbNum == curBBNum);
7323     VarToRegMap outVarToRegMap = getOutVarToRegMap(curBBNum);
7324
7325     VarSetOps::AssignNoCopy(compiler, currentLiveVars,
7326                             VarSetOps::Intersection(compiler, registerCandidateVars, currentBlock->bbLiveOut));
7327 #ifdef DEBUG
7328     if (getLsraExtendLifeTimes())
7329     {
7330         VarSetOps::Assign(compiler, currentLiveVars, registerCandidateVars);
7331     }
7332 #endif // DEBUG
7333     regMaskTP       liveRegs = RBM_NONE;
7334     VarSetOps::Iter iter(compiler, currentLiveVars);
7335     unsigned        varIndex = 0;
7336     while (iter.NextElem(&varIndex))
7337     {
7338         Interval* interval = getIntervalForLocalVar(varIndex);
7339         if (interval->isActive)
7340         {
7341             assert(interval->physReg != REG_NA && interval->physReg != REG_STK);
7342             setVarReg(outVarToRegMap, varIndex, interval->physReg);
7343         }
7344         else
7345         {
7346             outVarToRegMap[varIndex] = REG_STK;
7347         }
7348     }
7349     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_END_BB));
7350 }
7351
7352 #ifdef DEBUG
7353 void LinearScan::dumpRefPositions(const char* str)
7354 {
7355     printf("------------\n");
7356     printf("REFPOSITIONS %s: \n", str);
7357     printf("------------\n");
7358     for (auto& refPos : refPositions)
7359     {
7360         refPos.dump();
7361     }
7362 }
7363 #endif // DEBUG
7364
7365 bool LinearScan::registerIsFree(regNumber regNum, RegisterType regType)
7366 {
7367     RegRecord* physRegRecord = getRegisterRecord(regNum);
7368
7369     bool isFree = physRegRecord->isFree();
7370
7371 #ifdef _TARGET_ARM_
7372     if (isFree && regType == TYP_DOUBLE)
7373     {
7374         isFree = getRegisterRecord(REG_NEXT(regNum))->isFree();
7375     }
7376 #endif // _TARGET_ARM_
7377
7378     return isFree;
7379 }
7380
7381 //------------------------------------------------------------------------
7382 // LinearScan::freeRegister: Make a register available for use
7383 //
7384 // Arguments:
7385 //    physRegRecord - the RegRecord for the register to be freed.
7386 //
7387 // Return Value:
7388 //    None.
7389 //
7390 // Assumptions:
7391 //    None.
7392 //    It may be that the RegRecord has already been freed, e.g. due to a kill,
7393 //    in which case this method has no effect.
7394 //
7395 // Notes:
7396 //    If there is currently an Interval assigned to this register, and it has
7397 //    more references (i.e. this is a local last-use, but more uses and/or
7398 //    defs remain), it will remain assigned to the physRegRecord.  However, since
7399 //    it is marked inactive, the register will be available, albeit less desirable
7400 //    to allocate.
7401 void LinearScan::freeRegister(RegRecord* physRegRecord)
7402 {
7403     Interval* assignedInterval = physRegRecord->assignedInterval;
7404     // It may have already been freed by a "Kill"
7405     if (assignedInterval != nullptr)
7406     {
7407         assignedInterval->isActive = false;
7408         // If this is a constant node, that we may encounter again (e.g. constant),
7409         // don't unassign it until we need the register.
7410         if (!assignedInterval->isConstant)
7411         {
7412             RefPosition* nextRefPosition = assignedInterval->getNextRefPosition();
7413             // Unassign the register only if there are no more RefPositions, or the next
7414             // one is a def.  Note that the latter condition doesn't actually ensure that
7415             // there aren't subsequent uses that could be reached by a def in the assigned
7416             // register, but is merely a heuristic to avoid tying up the register (or using
7417             // it when it's non-optimal).  A better alternative would be to use SSA, so that
7418             // we wouldn't unnecessarily link separate live ranges to the same register.
7419             if (nextRefPosition == nullptr || RefTypeIsDef(nextRefPosition->refType))
7420             {
7421 #ifdef _TARGET_ARM_
7422                 assert((assignedInterval->registerType != TYP_DOUBLE) || genIsValidDoubleReg(physRegRecord->regNum));
7423 #endif // _TARGET_ARM_
7424                 unassignPhysReg(physRegRecord, nullptr);
7425             }
7426         }
7427     }
7428 }
7429
7430 void LinearScan::freeRegisters(regMaskTP regsToFree)
7431 {
7432     if (regsToFree == RBM_NONE)
7433     {
7434         return;
7435     }
7436
7437     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_FREE_REGS));
7438     while (regsToFree != RBM_NONE)
7439     {
7440         regMaskTP nextRegBit = genFindLowestBit(regsToFree);
7441         regsToFree &= ~nextRegBit;
7442         regNumber nextReg = genRegNumFromMask(nextRegBit);
7443         freeRegister(getRegisterRecord(nextReg));
7444     }
7445 }
7446
7447 // Actual register allocation, accomplished by iterating over all of the previously
7448 // constructed Intervals
7449 // Loosely based on raAssignVars()
7450 //
7451 void LinearScan::allocateRegisters()
7452 {
7453     JITDUMP("*************** In LinearScan::allocateRegisters()\n");
7454     DBEXEC(VERBOSE, lsraDumpIntervals("before allocateRegisters"));
7455
7456     // at start, nothing is active except for register args
7457     for (auto& interval : intervals)
7458     {
7459         Interval* currentInterval          = &interval;
7460         currentInterval->recentRefPosition = nullptr;
7461         currentInterval->isActive          = false;
7462         if (currentInterval->isLocalVar)
7463         {
7464             LclVarDsc* varDsc = currentInterval->getLocalVar(compiler);
7465             if (varDsc->lvIsRegArg && currentInterval->firstRefPosition != nullptr)
7466             {
7467                 currentInterval->isActive = true;
7468             }
7469         }
7470     }
7471
7472     for (regNumber reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
7473     {
7474         getRegisterRecord(reg)->recentRefPosition = nullptr;
7475         getRegisterRecord(reg)->isActive          = false;
7476     }
7477
7478 #ifdef DEBUG
7479     regNumber lastAllocatedReg = REG_NA;
7480     if (VERBOSE)
7481     {
7482         dumpRefPositions("BEFORE ALLOCATION");
7483         dumpVarRefPositions("BEFORE ALLOCATION");
7484
7485         printf("\n\nAllocating Registers\n"
7486                "--------------------\n");
7487         if (dumpTerse)
7488         {
7489             dumpRegRecordHeader();
7490             // Now print an empty indent
7491             printf(indentFormat, "");
7492         }
7493     }
7494 #endif // DEBUG
7495
7496     BasicBlock* currentBlock = nullptr;
7497
7498     LsraLocation prevLocation    = MinLocation;
7499     regMaskTP    regsToFree      = RBM_NONE;
7500     regMaskTP    delayRegsToFree = RBM_NONE;
7501
7502     // This is the most recent RefPosition for which a register was allocated
7503     // - currently only used for DEBUG but maintained in non-debug, for clarity of code
7504     //   (and will be optimized away because in non-debug spillAlways() unconditionally returns false)
7505     RefPosition* lastAllocatedRefPosition = nullptr;
7506
7507     bool handledBlockEnd = false;
7508
7509     for (auto& refPosition : refPositions)
7510     {
7511         RefPosition* currentRefPosition = &refPosition;
7512
7513 #ifdef DEBUG
7514         // Set the activeRefPosition to null until we're done with any boundary handling.
7515         activeRefPosition = nullptr;
7516         if (VERBOSE)
7517         {
7518             if (dumpTerse)
7519             {
7520                 // We're really dumping the RegRecords "after" the previous RefPosition, but it's more convenient
7521                 // to do this here, since there are a number of "continue"s in this loop.
7522                 dumpRegRecords();
7523             }
7524             else
7525             {
7526                 printf("\n");
7527             }
7528         }
7529 #endif // DEBUG
7530
7531         // This is the previousRefPosition of the current Referent, if any
7532         RefPosition* previousRefPosition = nullptr;
7533
7534         Interval*      currentInterval = nullptr;
7535         Referenceable* currentReferent = nullptr;
7536         bool           isInternalRef   = false;
7537         RefType        refType         = currentRefPosition->refType;
7538
7539         currentReferent = currentRefPosition->referent;
7540
7541         if (spillAlways() && lastAllocatedRefPosition != nullptr && !lastAllocatedRefPosition->isPhysRegRef &&
7542             !lastAllocatedRefPosition->getInterval()->isInternal &&
7543             (RefTypeIsDef(lastAllocatedRefPosition->refType) || lastAllocatedRefPosition->getInterval()->isLocalVar))
7544         {
7545             assert(lastAllocatedRefPosition->registerAssignment != RBM_NONE);
7546             RegRecord* regRecord = lastAllocatedRefPosition->getInterval()->assignedReg;
7547             unassignPhysReg(regRecord, lastAllocatedRefPosition);
7548             // Now set lastAllocatedRefPosition to null, so that we don't try to spill it again
7549             lastAllocatedRefPosition = nullptr;
7550         }
7551
7552         // We wait to free any registers until we've completed all the
7553         // uses for the current node.
7554         // This avoids reusing registers too soon.
7555         // We free before the last true def (after all the uses & internal
7556         // registers), and then again at the beginning of the next node.
7557         // This is made easier by assigning two LsraLocations per node - one
7558         // for all the uses, internal registers & all but the last def, and
7559         // another for the final def (if any).
7560
7561         LsraLocation currentLocation = currentRefPosition->nodeLocation;
7562
7563         if ((regsToFree | delayRegsToFree) != RBM_NONE)
7564         {
7565             bool doFreeRegs = false;
7566             // Free at a new location, or at a basic block boundary
7567             if (currentLocation > prevLocation || refType == RefTypeBB)
7568             {
7569                 doFreeRegs = true;
7570             }
7571
7572             if (doFreeRegs)
7573             {
7574                 freeRegisters(regsToFree);
7575                 regsToFree      = delayRegsToFree;
7576                 delayRegsToFree = RBM_NONE;
7577             }
7578         }
7579         prevLocation = currentLocation;
7580
7581         // get previous refposition, then current refpos is the new previous
7582         if (currentReferent != nullptr)
7583         {
7584             previousRefPosition                = currentReferent->recentRefPosition;
7585             currentReferent->recentRefPosition = currentRefPosition;
7586         }
7587         else
7588         {
7589             assert((refType == RefTypeBB) || (refType == RefTypeKillGCRefs));
7590         }
7591
7592         // For the purposes of register resolution, we handle the DummyDefs before
7593         // the block boundary - so the RefTypeBB is after all the DummyDefs.
7594         // However, for the purposes of allocation, we want to handle the block
7595         // boundary first, so that we can free any registers occupied by lclVars
7596         // that aren't live in the next block and make them available for the
7597         // DummyDefs.
7598
7599         if (!handledBlockEnd && (refType == RefTypeBB || refType == RefTypeDummyDef))
7600         {
7601             // Free any delayed regs (now in regsToFree) before processing the block boundary
7602             freeRegisters(regsToFree);
7603             regsToFree         = RBM_NONE;
7604             handledBlockEnd    = true;
7605             curBBStartLocation = currentRefPosition->nodeLocation;
7606             if (currentBlock == nullptr)
7607             {
7608                 currentBlock = startBlockSequence();
7609             }
7610             else
7611             {
7612                 processBlockEndAllocation(currentBlock);
7613                 currentBlock = moveToNextBlock();
7614             }
7615 #ifdef DEBUG
7616             if (VERBOSE && currentBlock != nullptr && !dumpTerse)
7617             {
7618                 currentBlock->dspBlockHeader(compiler);
7619                 printf("\n");
7620             }
7621 #endif // DEBUG
7622         }
7623
7624 #ifdef DEBUG
7625         activeRefPosition = currentRefPosition;
7626         if (VERBOSE)
7627         {
7628             if (dumpTerse)
7629             {
7630                 dumpRefPositionShort(currentRefPosition, currentBlock);
7631             }
7632             else
7633             {
7634                 currentRefPosition->dump();
7635             }
7636         }
7637 #endif // DEBUG
7638
7639         if (refType == RefTypeBB)
7640         {
7641             handledBlockEnd = false;
7642             continue;
7643         }
7644
7645         if (refType == RefTypeKillGCRefs)
7646         {
7647             spillGCRefs(currentRefPosition);
7648             continue;
7649         }
7650
7651         // If this is a FixedReg, disassociate any inactive constant interval from this register.
7652         // Otherwise, do nothing.
7653         if (refType == RefTypeFixedReg)
7654         {
7655             RegRecord* regRecord        = currentRefPosition->getReg();
7656             Interval*  assignedInterval = regRecord->assignedInterval;
7657
7658             if (assignedInterval != nullptr && !assignedInterval->isActive && assignedInterval->isConstant)
7659             {
7660                 regRecord->assignedInterval = nullptr;
7661
7662 #ifdef _TARGET_ARM_
7663                 // Update overlapping floating point register for TYP_DOUBLE
7664                 if (assignedInterval->registerType == TYP_DOUBLE)
7665                 {
7666                     regRecord        = getRegisterRecord(REG_NEXT(regRecord->regNum));
7667                     assignedInterval = regRecord->assignedInterval;
7668
7669                     assert(assignedInterval != nullptr && !assignedInterval->isActive && assignedInterval->isConstant);
7670                     regRecord->assignedInterval = nullptr;
7671                 }
7672 #endif
7673             }
7674             INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_FIXED_REG, nullptr, currentRefPosition->assignedReg()));
7675             continue;
7676         }
7677
7678         // If this is an exposed use, do nothing - this is merely a placeholder to attempt to
7679         // ensure that a register is allocated for the full lifetime.  The resolution logic
7680         // will take care of moving to the appropriate register if needed.
7681
7682         if (refType == RefTypeExpUse)
7683         {
7684             INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_EXP_USE));
7685             continue;
7686         }
7687
7688         regNumber assignedRegister = REG_NA;
7689
7690         if (currentRefPosition->isIntervalRef())
7691         {
7692             currentInterval  = currentRefPosition->getInterval();
7693             assignedRegister = currentInterval->physReg;
7694 #if DEBUG
7695             if (VERBOSE && !dumpTerse)
7696             {
7697                 currentInterval->dump();
7698             }
7699 #endif // DEBUG
7700
7701             // Identify the special cases where we decide up-front not to allocate
7702             bool allocate = true;
7703             bool didDump  = false;
7704
7705             if (refType == RefTypeParamDef || refType == RefTypeZeroInit)
7706             {
7707                 // For a ParamDef with a weighted refCount less than unity, don't enregister it at entry.
7708                 // TODO-CQ: Consider doing this only for stack parameters, since otherwise we may be needlessly
7709                 // inserting a store.
7710                 LclVarDsc* varDsc = currentInterval->getLocalVar(compiler);
7711                 assert(varDsc != nullptr);
7712                 if (refType == RefTypeParamDef && varDsc->lvRefCntWtd <= BB_UNITY_WEIGHT)
7713                 {
7714                     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_NO_ENTRY_REG_ALLOCATED, currentInterval));
7715                     didDump  = true;
7716                     allocate = false;
7717                     setIntervalAsSpilled(currentInterval);
7718                 }
7719                 // If it has no actual references, mark it as "lastUse"; since they're not actually part
7720                 // of any flow they won't have been marked during dataflow.  Otherwise, if we allocate a
7721                 // register we won't unassign it.
7722                 else if (currentRefPosition->nextRefPosition == nullptr)
7723                 {
7724                     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_ZERO_REF, currentInterval));
7725                     currentRefPosition->lastUse = true;
7726                 }
7727             }
7728 #ifdef FEATURE_SIMD
7729             else if (refType == RefTypeUpperVectorSaveDef || refType == RefTypeUpperVectorSaveUse)
7730             {
7731                 Interval* lclVarInterval = currentInterval->relatedInterval;
7732                 if (lclVarInterval->physReg == REG_NA)
7733                 {
7734                     allocate = false;
7735                 }
7736             }
7737 #endif // FEATURE_SIMD
7738
7739             if (allocate == false)
7740             {
7741                 if (assignedRegister != REG_NA)
7742                 {
7743                     unassignPhysReg(getRegisterRecord(assignedRegister), currentRefPosition);
7744                 }
7745                 else if (!didDump)
7746                 {
7747                     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_NO_REG_ALLOCATED, currentInterval));
7748                     didDump = true;
7749                 }
7750                 currentRefPosition->registerAssignment = RBM_NONE;
7751                 continue;
7752             }
7753
7754             if (currentInterval->isSpecialPutArg)
7755             {
7756                 assert(!currentInterval->isLocalVar);
7757                 Interval* srcInterval = currentInterval->relatedInterval;
7758                 assert(srcInterval->isLocalVar);
7759                 if (refType == RefTypeDef)
7760                 {
7761                     assert(srcInterval->recentRefPosition->nodeLocation == currentLocation - 1);
7762                     RegRecord* physRegRecord = srcInterval->assignedReg;
7763
7764                     // For a putarg_reg to be special, its next use location has to be the same
7765                     // as fixed reg's next kill location. Otherwise, if source lcl var's next use
7766                     // is after the kill of fixed reg but before putarg_reg's next use, fixed reg's
7767                     // kill would lead to spill of source but not the putarg_reg if it were treated
7768                     // as special.
7769                     if (srcInterval->isActive &&
7770                         genRegMask(srcInterval->physReg) == currentRefPosition->registerAssignment &&
7771                         currentInterval->getNextRefLocation() == physRegRecord->getNextRefLocation())
7772                     {
7773                         assert(physRegRecord->regNum == srcInterval->physReg);
7774
7775                         // Special putarg_reg acts as a pass-thru since both source lcl var
7776                         // and putarg_reg have the same register allocated.  Physical reg
7777                         // record of reg continue to point to source lcl var's interval
7778                         // instead of to putarg_reg's interval.  So if a spill of reg
7779                         // allocated to source lcl var happens, to reallocate to another
7780                         // tree node, before its use at call node it will lead to spill of
7781                         // lcl var instead of putarg_reg since physical reg record is pointing
7782                         // to lcl var's interval. As a result, arg reg would get trashed leading
7783                         // to bad codegen. The assumption here is that source lcl var of a
7784                         // special putarg_reg doesn't get spilled and re-allocated prior to
7785                         // its use at the call node.  This is ensured by marking physical reg
7786                         // record as busy until next kill.
7787                         physRegRecord->isBusyUntilNextKill = true;
7788                     }
7789                     else
7790                     {
7791                         currentInterval->isSpecialPutArg = false;
7792                     }
7793                 }
7794                 // If this is still a SpecialPutArg, continue;
7795                 if (currentInterval->isSpecialPutArg)
7796                 {
7797                     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_SPECIAL_PUTARG, currentInterval,
7798                                                     currentRefPosition->assignedReg()));
7799                     continue;
7800                 }
7801             }
7802
7803             if (assignedRegister == REG_NA && RefTypeIsUse(refType))
7804             {
7805                 currentRefPosition->reload = true;
7806                 INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_RELOAD, currentInterval, assignedRegister));
7807             }
7808         }
7809
7810         regMaskTP assignedRegBit = RBM_NONE;
7811         bool      isInRegister   = false;
7812         if (assignedRegister != REG_NA)
7813         {
7814             isInRegister   = true;
7815             assignedRegBit = genRegMask(assignedRegister);
7816             if (!currentInterval->isActive)
7817             {
7818                 // If this is a use, it must have started the block on the stack, but the register
7819                 // was available for use so we kept the association.
7820                 if (RefTypeIsUse(refType))
7821                 {
7822                     assert(enregisterLocalVars);
7823                     assert(inVarToRegMaps[curBBNum][currentInterval->getVarIndex(compiler)] == REG_STK &&
7824                            previousRefPosition->nodeLocation <= curBBStartLocation);
7825                     isInRegister = false;
7826                 }
7827                 else
7828                 {
7829                     currentInterval->isActive = true;
7830                 }
7831             }
7832             assert(currentInterval->assignedReg != nullptr &&
7833                    currentInterval->assignedReg->regNum == assignedRegister &&
7834                    currentInterval->assignedReg->assignedInterval == currentInterval);
7835         }
7836
7837         // If this is a physical register, we unconditionally assign it to itself!
7838         if (currentRefPosition->isPhysRegRef)
7839         {
7840             RegRecord* currentReg       = currentRefPosition->getReg();
7841             Interval*  assignedInterval = currentReg->assignedInterval;
7842
7843             if (assignedInterval != nullptr)
7844             {
7845                 unassignPhysReg(currentReg, assignedInterval->recentRefPosition);
7846             }
7847             currentReg->isActive = true;
7848             assignedRegister     = currentReg->regNum;
7849             assignedRegBit       = genRegMask(assignedRegister);
7850             if (refType == RefTypeKill)
7851             {
7852                 currentReg->isBusyUntilNextKill = false;
7853             }
7854         }
7855         else if (previousRefPosition != nullptr)
7856         {
7857             assert(previousRefPosition->nextRefPosition == currentRefPosition);
7858             assert(assignedRegister == REG_NA || assignedRegBit == previousRefPosition->registerAssignment ||
7859                    currentRefPosition->outOfOrder || previousRefPosition->copyReg ||
7860                    previousRefPosition->refType == RefTypeExpUse || currentRefPosition->refType == RefTypeDummyDef);
7861         }
7862         else if (assignedRegister != REG_NA)
7863         {
7864             // Handle the case where this is a preassigned register (i.e. parameter).
7865             // We don't want to actually use the preassigned register if it's not
7866             // going to cover the lifetime - but we had to preallocate it to ensure
7867             // that it remained live.
7868             // TODO-CQ: At some point we may want to refine the analysis here, in case
7869             // it might be beneficial to keep it in this reg for PART of the lifetime
7870             if (currentInterval->isLocalVar)
7871             {
7872                 regMaskTP preferences        = currentInterval->registerPreferences;
7873                 bool      keepAssignment     = true;
7874                 bool      matchesPreferences = (preferences & genRegMask(assignedRegister)) != RBM_NONE;
7875
7876                 // Will the assigned register cover the lifetime?  If not, does it at least
7877                 // meet the preferences for the next RefPosition?
7878                 RegRecord*   physRegRecord     = getRegisterRecord(currentInterval->physReg);
7879                 RefPosition* nextPhysRegRefPos = physRegRecord->getNextRefPosition();
7880                 if (nextPhysRegRefPos != nullptr &&
7881                     nextPhysRegRefPos->nodeLocation <= currentInterval->lastRefPosition->nodeLocation)
7882                 {
7883                     // Check to see if the existing assignment matches the preferences (e.g. callee save registers)
7884                     // and ensure that the next use of this localVar does not occur after the nextPhysRegRefPos
7885                     // There must be a next RefPosition, because we know that the Interval extends beyond the
7886                     // nextPhysRegRefPos.
7887                     RefPosition* nextLclVarRefPos = currentRefPosition->nextRefPosition;
7888                     assert(nextLclVarRefPos != nullptr);
7889                     if (!matchesPreferences || nextPhysRegRefPos->nodeLocation < nextLclVarRefPos->nodeLocation ||
7890                         physRegRecord->conflictingFixedRegReference(nextLclVarRefPos))
7891                     {
7892                         keepAssignment = false;
7893                     }
7894                 }
7895                 else if (refType == RefTypeParamDef && !matchesPreferences)
7896                 {
7897                     // Don't use the register, even if available, if it doesn't match the preferences.
7898                     // Note that this case is only for ParamDefs, for which we haven't yet taken preferences
7899                     // into account (we've just automatically got the initial location).  In other cases,
7900                     // we would already have put it in a preferenced register, if it was available.
7901                     // TODO-CQ: Consider expanding this to check availability - that would duplicate
7902                     // code here, but otherwise we may wind up in this register anyway.
7903                     keepAssignment = false;
7904                 }
7905
7906                 if (keepAssignment == false)
7907                 {
7908                     currentRefPosition->registerAssignment = allRegs(currentInterval->registerType);
7909                     unassignPhysRegNoSpill(physRegRecord);
7910
7911                     // If the preferences are currently set to just this register, reset them to allRegs
7912                     // of the appropriate type (just as we just reset the registerAssignment for this
7913                     // RefPosition.
7914                     // Otherwise, simply remove this register from the preferences, if it's there.
7915
7916                     if (currentInterval->registerPreferences == assignedRegBit)
7917                     {
7918                         currentInterval->registerPreferences = currentRefPosition->registerAssignment;
7919                     }
7920                     else
7921                     {
7922                         currentInterval->registerPreferences &= ~assignedRegBit;
7923                     }
7924
7925                     assignedRegister = REG_NA;
7926                     assignedRegBit   = RBM_NONE;
7927                 }
7928             }
7929         }
7930
7931         if (assignedRegister != REG_NA)
7932         {
7933             // If there is a conflicting fixed reference, insert a copy.
7934             RegRecord* physRegRecord = getRegisterRecord(assignedRegister);
7935             if (physRegRecord->conflictingFixedRegReference(currentRefPosition))
7936             {
7937                 // We may have already reassigned the register to the conflicting reference.
7938                 // If not, we need to unassign this interval.
7939                 if (physRegRecord->assignedInterval == currentInterval)
7940                 {
7941                     unassignPhysRegNoSpill(physRegRecord);
7942                 }
7943                 currentRefPosition->moveReg = true;
7944                 assignedRegister            = REG_NA;
7945                 setIntervalAsSplit(currentInterval);
7946                 INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_MOVE_REG, currentInterval, assignedRegister));
7947             }
7948             else if ((genRegMask(assignedRegister) & currentRefPosition->registerAssignment) != 0)
7949             {
7950                 currentRefPosition->registerAssignment = assignedRegBit;
7951                 if (!currentReferent->isActive)
7952                 {
7953                     // If we've got an exposed use at the top of a block, the
7954                     // interval might not have been active.  Otherwise if it's a use,
7955                     // the interval must be active.
7956                     if (refType == RefTypeDummyDef)
7957                     {
7958                         currentReferent->isActive = true;
7959                         assert(getRegisterRecord(assignedRegister)->assignedInterval == currentInterval);
7960                     }
7961                     else
7962                     {
7963                         currentRefPosition->reload = true;
7964                     }
7965                 }
7966                 INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_KEPT_ALLOCATION, currentInterval, assignedRegister));
7967             }
7968             else
7969             {
7970                 assert(currentInterval != nullptr);
7971
7972                 // It's already in a register, but not one we need.
7973                 if (!RefTypeIsDef(currentRefPosition->refType))
7974                 {
7975                     regNumber copyReg = assignCopyReg(currentRefPosition);
7976                     assert(copyReg != REG_NA);
7977                     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_COPY_REG, currentInterval, copyReg));
7978                     lastAllocatedRefPosition = currentRefPosition;
7979                     if (currentRefPosition->lastUse)
7980                     {
7981                         if (currentRefPosition->delayRegFree)
7982                         {
7983                             INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_LAST_USE_DELAYED, currentInterval,
7984                                                             assignedRegister));
7985                             delayRegsToFree |= (genRegMask(assignedRegister) | currentRefPosition->registerAssignment);
7986                         }
7987                         else
7988                         {
7989                             INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_LAST_USE, currentInterval, assignedRegister));
7990                             regsToFree |= (genRegMask(assignedRegister) | currentRefPosition->registerAssignment);
7991                         }
7992                     }
7993                     // If this is a tree temp (non-localVar) interval, we will need an explicit move.
7994                     if (!currentInterval->isLocalVar)
7995                     {
7996                         currentRefPosition->moveReg = true;
7997                         currentRefPosition->copyReg = false;
7998                     }
7999                     continue;
8000                 }
8001                 else
8002                 {
8003                     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_NEEDS_NEW_REG, nullptr, assignedRegister));
8004                     regsToFree |= genRegMask(assignedRegister);
8005                     // We want a new register, but we don't want this to be considered a spill.
8006                     assignedRegister = REG_NA;
8007                     if (physRegRecord->assignedInterval == currentInterval)
8008                     {
8009                         unassignPhysRegNoSpill(physRegRecord);
8010                     }
8011                 }
8012             }
8013         }
8014
8015         if (assignedRegister == REG_NA)
8016         {
8017             bool allocateReg = true;
8018
8019             if (currentRefPosition->AllocateIfProfitable())
8020             {
8021                 // We can avoid allocating a register if it is a the last use requiring a reload.
8022                 if (currentRefPosition->lastUse && currentRefPosition->reload)
8023                 {
8024                     allocateReg = false;
8025                 }
8026
8027 #ifdef DEBUG
8028                 // Under stress mode, don't attempt to allocate a reg to
8029                 // reg optional ref position.
8030                 if (allocateReg && regOptionalNoAlloc())
8031                 {
8032                     allocateReg = false;
8033                 }
8034 #endif
8035             }
8036
8037             if (allocateReg)
8038             {
8039                 // Try to allocate a register
8040                 assignedRegister = tryAllocateFreeReg(currentInterval, currentRefPosition);
8041             }
8042
8043             // If no register was found, and if the currentRefPosition must have a register,
8044             // then find a register to spill
8045             if (assignedRegister == REG_NA)
8046             {
8047 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
8048                 if (refType == RefTypeUpperVectorSaveDef)
8049                 {
8050                     // TODO-CQ: Determine whether copying to two integer callee-save registers would be profitable.
8051
8052                     // SaveDef position occurs after the Use of args and at the same location as Kill/Def
8053                     // positions of a call node.  But SaveDef position cannot use any of the arg regs as
8054                     // they are needed for call node.
8055                     currentRefPosition->registerAssignment =
8056                         (allRegs(TYP_FLOAT) & RBM_FLT_CALLEE_TRASH & ~RBM_FLTARG_REGS);
8057                     assignedRegister = tryAllocateFreeReg(currentInterval, currentRefPosition);
8058
8059                     // There MUST be caller-save registers available, because they have all just been killed.
8060                     // Amd64 Windows: xmm4-xmm5 are guaranteed to be available as xmm0-xmm3 are used for passing args.
8061                     // Amd64 Unix: xmm8-xmm15 are guaranteed to be avilable as xmm0-xmm7 are used for passing args.
8062                     // X86 RyuJIT Windows: xmm4-xmm7 are guanrateed to be available.
8063                     assert(assignedRegister != REG_NA);
8064
8065                     // Now, spill it.
8066                     // Note:
8067                     //   i) The reason we have to spill is that SaveDef position is allocated after the Kill positions
8068                     //      of the call node are processed.  Since callee-trash registers are killed by call node
8069                     //      we explicity spill and unassign the register.
8070                     //  ii) These will look a bit backward in the dump, but it's a pain to dump the alloc before the
8071                     //  spill).
8072                     unassignPhysReg(getRegisterRecord(assignedRegister), currentRefPosition);
8073                     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_ALLOC_REG, currentInterval, assignedRegister));
8074
8075                     // Now set assignedRegister to REG_NA again so that we don't re-activate it.
8076                     assignedRegister = REG_NA;
8077                 }
8078                 else
8079 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
8080                     if (currentRefPosition->RequiresRegister() || currentRefPosition->AllocateIfProfitable())
8081                 {
8082                     if (allocateReg)
8083                     {
8084                         assignedRegister = allocateBusyReg(currentInterval, currentRefPosition,
8085                                                            currentRefPosition->AllocateIfProfitable());
8086                     }
8087
8088                     if (assignedRegister != REG_NA)
8089                     {
8090                         INDEBUG(
8091                             dumpLsraAllocationEvent(LSRA_EVENT_ALLOC_SPILLED_REG, currentInterval, assignedRegister));
8092                     }
8093                     else
8094                     {
8095                         // This can happen only for those ref positions that are to be allocated
8096                         // only if profitable.
8097                         noway_assert(currentRefPosition->AllocateIfProfitable());
8098
8099                         currentRefPosition->registerAssignment = RBM_NONE;
8100                         currentRefPosition->reload             = false;
8101                         setIntervalAsSpilled(currentInterval);
8102
8103                         INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_NO_REG_ALLOCATED, currentInterval));
8104                     }
8105                 }
8106                 else
8107                 {
8108                     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_NO_REG_ALLOCATED, currentInterval));
8109                     currentRefPosition->registerAssignment = RBM_NONE;
8110                     currentInterval->isActive              = false;
8111                     setIntervalAsSpilled(currentInterval);
8112                 }
8113             }
8114 #ifdef DEBUG
8115             else
8116             {
8117                 if (VERBOSE)
8118                 {
8119                     if (currentInterval->isConstant && (currentRefPosition->treeNode != nullptr) &&
8120                         currentRefPosition->treeNode->IsReuseRegVal())
8121                     {
8122                         dumpLsraAllocationEvent(LSRA_EVENT_REUSE_REG, nullptr, assignedRegister, currentBlock);
8123                     }
8124                     else
8125                     {
8126                         dumpLsraAllocationEvent(LSRA_EVENT_ALLOC_REG, nullptr, assignedRegister, currentBlock);
8127                     }
8128                 }
8129             }
8130 #endif // DEBUG
8131
8132             if (refType == RefTypeDummyDef && assignedRegister != REG_NA)
8133             {
8134                 setInVarRegForBB(curBBNum, currentInterval->varNum, assignedRegister);
8135             }
8136
8137             // If we allocated a register, and this is a use of a spilled value,
8138             // it should have been marked for reload above.
8139             if (assignedRegister != REG_NA && RefTypeIsUse(refType) && !isInRegister)
8140             {
8141                 assert(currentRefPosition->reload);
8142             }
8143         }
8144
8145         // If we allocated a register, record it
8146         if (currentInterval != nullptr && assignedRegister != REG_NA)
8147         {
8148             assignedRegBit                         = genRegMask(assignedRegister);
8149             currentRefPosition->registerAssignment = assignedRegBit;
8150             currentInterval->physReg               = assignedRegister;
8151             regsToFree &= ~assignedRegBit; // we'll set it again later if it's dead
8152
8153             // If this interval is dead, free the register.
8154             // The interval could be dead if this is a user variable, or if the
8155             // node is being evaluated for side effects, or a call whose result
8156             // is not used, etc.
8157             if (currentRefPosition->lastUse || currentRefPosition->nextRefPosition == nullptr)
8158             {
8159                 assert(currentRefPosition->isIntervalRef());
8160
8161                 if (refType != RefTypeExpUse && currentRefPosition->nextRefPosition == nullptr)
8162                 {
8163                     if (currentRefPosition->delayRegFree)
8164                     {
8165                         delayRegsToFree |= assignedRegBit;
8166
8167                         INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_LAST_USE_DELAYED));
8168                     }
8169                     else
8170                     {
8171                         regsToFree |= assignedRegBit;
8172
8173                         INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_LAST_USE));
8174                     }
8175                 }
8176                 else
8177                 {
8178                     currentInterval->isActive = false;
8179                 }
8180             }
8181
8182             lastAllocatedRefPosition = currentRefPosition;
8183         }
8184     }
8185
8186     // Free registers to clear associated intervals for resolution phase
8187     CLANG_FORMAT_COMMENT_ANCHOR;
8188
8189 #ifdef DEBUG
8190     if (getLsraExtendLifeTimes())
8191     {
8192         // If we have extended lifetimes, we need to make sure all the registers are freed.
8193         for (int regNumIndex = 0; regNumIndex <= REG_FP_LAST; regNumIndex++)
8194         {
8195             RegRecord& regRecord = physRegs[regNumIndex];
8196             Interval*  interval  = regRecord.assignedInterval;
8197             if (interval != nullptr)
8198             {
8199                 interval->isActive = false;
8200                 unassignPhysReg(&regRecord, nullptr);
8201             }
8202         }
8203     }
8204     else
8205 #endif // DEBUG
8206     {
8207         freeRegisters(regsToFree | delayRegsToFree);
8208     }
8209
8210 #ifdef DEBUG
8211     if (VERBOSE)
8212     {
8213         if (dumpTerse)
8214         {
8215             // Dump the RegRecords after the last RefPosition is handled.
8216             dumpRegRecords();
8217             printf("\n");
8218         }
8219
8220         dumpRefPositions("AFTER ALLOCATION");
8221         dumpVarRefPositions("AFTER ALLOCATION");
8222
8223         // Dump the intervals that remain active
8224         printf("Active intervals at end of allocation:\n");
8225
8226         // We COULD just reuse the intervalIter from above, but ArrayListIterator doesn't
8227         // provide a Reset function (!) - we'll probably replace this so don't bother
8228         // adding it
8229
8230         for (auto& interval : intervals)
8231         {
8232             if (interval.isActive)
8233             {
8234                 printf("Active ");
8235                 interval.dump();
8236             }
8237         }
8238
8239         printf("\n");
8240     }
8241 #endif // DEBUG
8242 }
8243
8244 //-----------------------------------------------------------------------------
8245 // updateAssignedInterval: Update assigned interval of register.
8246 //
8247 // Arguments:
8248 //    reg      -    register to be updated
8249 //    interval -    interval to be assigned
8250 //    regType  -    regsiter type
8251 //
8252 // Return Value:
8253 //    None
8254 //
8255 // Assumptions:
8256 //    For ARM32, when "regType" is TYP_DOUBLE, "reg" should be a even-numbered
8257 //    float register, i.e. lower half of double register.
8258 //
8259 // Note:
8260 //    For ARM32, two float registers consisting a double register are updated
8261 //    together when "regType" is TYP_DOUBLE.
8262 //
8263 void LinearScan::updateAssignedInterval(RegRecord* reg, Interval* interval, RegisterType regType)
8264 {
8265     reg->assignedInterval = interval;
8266
8267 #ifdef _TARGET_ARM_
8268     // Update overlapping floating point register for TYP_DOUBLE
8269     if (regType == TYP_DOUBLE)
8270     {
8271         assert(genIsValidDoubleReg(reg->regNum));
8272
8273         RegRecord* anotherHalfReg = findAnotherHalfRegRec(reg);
8274
8275         anotherHalfReg->assignedInterval = interval;
8276     }
8277 #endif
8278 }
8279
8280 //-----------------------------------------------------------------------------
8281 // updatePreviousInterval: Update previous interval of register.
8282 //
8283 // Arguments:
8284 //    reg      -    register to be updated
8285 //    interval -    interval to be assigned
8286 //    regType  -    regsiter type
8287 //
8288 // Return Value:
8289 //    None
8290 //
8291 // Assumptions:
8292 //    For ARM32, when "regType" is TYP_DOUBLE, "reg" should be a even-numbered
8293 //    float register, i.e. lower half of double register.
8294 //
8295 // Note:
8296 //    For ARM32, two float registers consisting a double register are updated
8297 //    together when "regType" is TYP_DOUBLE.
8298 //
8299 void LinearScan::updatePreviousInterval(RegRecord* reg, Interval* interval, RegisterType regType)
8300 {
8301     reg->previousInterval = interval;
8302
8303 #ifdef _TARGET_ARM_
8304     // Update overlapping floating point register for TYP_DOUBLE
8305     if (regType == TYP_DOUBLE)
8306     {
8307         assert(genIsValidDoubleReg(reg->regNum));
8308
8309         RegRecord* anotherHalfReg = findAnotherHalfRegRec(reg);
8310
8311         anotherHalfReg->previousInterval = interval;
8312     }
8313 #endif
8314 }
8315
8316 // LinearScan::resolveLocalRef
8317 // Description:
8318 //      Update the graph for a local reference.
8319 //      Also, track the register (if any) that is currently occupied.
8320 // Arguments:
8321 //      treeNode: The lclVar that's being resolved
8322 //      currentRefPosition: the RefPosition associated with the treeNode
8323 //
8324 // Details:
8325 // This method is called for each local reference, during the resolveRegisters
8326 // phase of LSRA.  It is responsible for keeping the following in sync:
8327 //   - varDsc->lvRegNum (and lvOtherReg) contain the unique register location.
8328 //     If it is not in the same register through its lifetime, it is set to REG_STK.
8329 //   - interval->physReg is set to the assigned register
8330 //     (i.e. at the code location which is currently being handled by resolveRegisters())
8331 //     - interval->isActive is true iff the interval is live and occupying a register
8332 //     - interval->isSpilled should have already been set to true if the interval is EVER spilled
8333 //     - interval->isSplit is set to true if the interval does not occupy the same
8334 //       register throughout the method
8335 //   - RegRecord->assignedInterval points to the interval which currently occupies
8336 //     the register
8337 //   - For each lclVar node:
8338 //     - gtRegNum/gtRegPair is set to the currently allocated register(s).
8339 //     - GTF_SPILLED is set on a use if it must be reloaded prior to use.
8340 //     - GTF_SPILL is set if it must be spilled after use.
8341 //
8342 // A copyReg is an ugly case where the variable must be in a specific (fixed) register,
8343 // but it currently resides elsewhere.  The register allocator must track the use of the
8344 // fixed register, but it marks the lclVar node with the register it currently lives in
8345 // and the code generator does the necessary move.
8346 //
8347 // Before beginning, the varDsc for each parameter must be set to its initial location.
8348 //
8349 // NICE: Consider tracking whether an Interval is always in the same location (register/stack)
8350 // in which case it will require no resolution.
8351 //
8352 void LinearScan::resolveLocalRef(BasicBlock* block, GenTreePtr treeNode, RefPosition* currentRefPosition)
8353 {
8354     assert((block == nullptr) == (treeNode == nullptr));
8355     assert(enregisterLocalVars);
8356
8357     // Is this a tracked local?  Or just a register allocated for loading
8358     // a non-tracked one?
8359     Interval* interval = currentRefPosition->getInterval();
8360     if (!interval->isLocalVar)
8361     {
8362         return;
8363     }
8364     interval->recentRefPosition = currentRefPosition;
8365     LclVarDsc* varDsc           = interval->getLocalVar(compiler);
8366
8367     // NOTE: we set the GTF_VAR_DEATH flag here unless we are extending lifetimes, in which case we write
8368     // this bit in checkLastUses. This is a bit of a hack, but is necessary because codegen requires
8369     // accurate last use info that is not reflected in the lastUse bit on ref positions when we are extending
8370     // lifetimes. See also the comments in checkLastUses.
8371     if ((treeNode != nullptr) && !extendLifetimes())
8372     {
8373         if (currentRefPosition->lastUse)
8374         {
8375             treeNode->gtFlags |= GTF_VAR_DEATH;
8376         }
8377         else
8378         {
8379             treeNode->gtFlags &= ~GTF_VAR_DEATH;
8380         }
8381     }
8382
8383     if (currentRefPosition->registerAssignment == RBM_NONE)
8384     {
8385         assert(!currentRefPosition->RequiresRegister());
8386         assert(interval->isSpilled);
8387
8388         varDsc->lvRegNum = REG_STK;
8389         if (interval->assignedReg != nullptr && interval->assignedReg->assignedInterval == interval)
8390         {
8391             updateAssignedInterval(interval->assignedReg, nullptr, interval->registerType);
8392         }
8393         interval->assignedReg = nullptr;
8394         interval->physReg     = REG_NA;
8395         if (treeNode != nullptr)
8396         {
8397             treeNode->SetContained();
8398         }
8399
8400         return;
8401     }
8402
8403     // In most cases, assigned and home registers will be the same
8404     // The exception is the copyReg case, where we've assigned a register
8405     // for a specific purpose, but will be keeping the register assignment
8406     regNumber assignedReg = currentRefPosition->assignedReg();
8407     regNumber homeReg     = assignedReg;
8408
8409     // Undo any previous association with a physical register, UNLESS this
8410     // is a copyReg
8411     if (!currentRefPosition->copyReg)
8412     {
8413         regNumber oldAssignedReg = interval->physReg;
8414         if (oldAssignedReg != REG_NA && assignedReg != oldAssignedReg)
8415         {
8416             RegRecord* oldRegRecord = getRegisterRecord(oldAssignedReg);
8417             if (oldRegRecord->assignedInterval == interval)
8418             {
8419                 updateAssignedInterval(oldRegRecord, nullptr, interval->registerType);
8420             }
8421         }
8422     }
8423
8424     if (currentRefPosition->refType == RefTypeUse && !currentRefPosition->reload)
8425     {
8426         // Was this spilled after our predecessor was scheduled?
8427         if (interval->physReg == REG_NA)
8428         {
8429             assert(inVarToRegMaps[curBBNum][varDsc->lvVarIndex] == REG_STK);
8430             currentRefPosition->reload = true;
8431         }
8432     }
8433
8434     bool reload     = currentRefPosition->reload;
8435     bool spillAfter = currentRefPosition->spillAfter;
8436
8437     // In the reload case we either:
8438     // - Set the register to REG_STK if it will be referenced only from the home location, or
8439     // - Set the register to the assigned register and set GTF_SPILLED if it must be loaded into a register.
8440     if (reload)
8441     {
8442         assert(currentRefPosition->refType != RefTypeDef);
8443         assert(interval->isSpilled);
8444         varDsc->lvRegNum = REG_STK;
8445         if (!spillAfter)
8446         {
8447             interval->physReg = assignedReg;
8448         }
8449
8450         // If there is no treeNode, this must be a RefTypeExpUse, in
8451         // which case we did the reload already
8452         if (treeNode != nullptr)
8453         {
8454             treeNode->gtFlags |= GTF_SPILLED;
8455             if (spillAfter)
8456             {
8457                 if (currentRefPosition->AllocateIfProfitable())
8458                 {
8459                     // This is a use of lclVar that is flagged as reg-optional
8460                     // by lower/codegen and marked for both reload and spillAfter.
8461                     // In this case we can avoid unnecessary reload and spill
8462                     // by setting reg on lclVar to REG_STK and reg on tree node
8463                     // to REG_NA.  Codegen will generate the code by considering
8464                     // it as a contained memory operand.
8465                     //
8466                     // Note that varDsc->lvRegNum is already to REG_STK above.
8467                     interval->physReg  = REG_NA;
8468                     treeNode->gtRegNum = REG_NA;
8469                     treeNode->gtFlags &= ~GTF_SPILLED;
8470                     treeNode->SetContained();
8471                 }
8472                 else
8473                 {
8474                     treeNode->gtFlags |= GTF_SPILL;
8475                 }
8476             }
8477         }
8478         else
8479         {
8480             assert(currentRefPosition->refType == RefTypeExpUse);
8481         }
8482     }
8483     else if (spillAfter && !RefTypeIsUse(currentRefPosition->refType))
8484     {
8485         // In the case of a pure def, don't bother spilling - just assign it to the
8486         // stack.  However, we need to remember that it was spilled.
8487
8488         assert(interval->isSpilled);
8489         varDsc->lvRegNum  = REG_STK;
8490         interval->physReg = REG_NA;
8491         if (treeNode != nullptr)
8492         {
8493             treeNode->gtRegNum = REG_NA;
8494         }
8495     }
8496     else
8497     {
8498         // Not reload and Not pure-def that's spillAfter
8499
8500         if (currentRefPosition->copyReg || currentRefPosition->moveReg)
8501         {
8502             // For a copyReg or moveReg, we have two cases:
8503             //  - In the first case, we have a fixedReg - i.e. a register which the code
8504             //    generator is constrained to use.
8505             //    The code generator will generate the appropriate move to meet the requirement.
8506             //  - In the second case, we were forced to use a different register because of
8507             //    interference (or JitStressRegs).
8508             //    In this case, we generate a GT_COPY.
8509             // In either case, we annotate the treeNode with the register in which the value
8510             // currently lives.  For moveReg, the homeReg is the new register (as assigned above).
8511             // But for copyReg, the homeReg remains unchanged.
8512
8513             assert(treeNode != nullptr);
8514             treeNode->gtRegNum = interval->physReg;
8515
8516             if (currentRefPosition->copyReg)
8517             {
8518                 homeReg = interval->physReg;
8519             }
8520             else
8521             {
8522                 assert(interval->isSplit);
8523                 interval->physReg = assignedReg;
8524             }
8525
8526             if (!currentRefPosition->isFixedRegRef || currentRefPosition->moveReg)
8527             {
8528                 // This is the second case, where we need to generate a copy
8529                 insertCopyOrReload(block, treeNode, currentRefPosition->getMultiRegIdx(), currentRefPosition);
8530             }
8531         }
8532         else
8533         {
8534             interval->physReg = assignedReg;
8535
8536             if (!interval->isSpilled && !interval->isSplit)
8537             {
8538                 if (varDsc->lvRegNum != REG_STK)
8539                 {
8540                     // If the register assignments don't match, then this interval is split.
8541                     if (varDsc->lvRegNum != assignedReg)
8542                     {
8543                         setIntervalAsSplit(interval);
8544                         varDsc->lvRegNum = REG_STK;
8545                     }
8546                 }
8547                 else
8548                 {
8549                     varDsc->lvRegNum = assignedReg;
8550                 }
8551             }
8552         }
8553         if (spillAfter)
8554         {
8555             if (treeNode != nullptr)
8556             {
8557                 treeNode->gtFlags |= GTF_SPILL;
8558             }
8559             assert(interval->isSpilled);
8560             interval->physReg = REG_NA;
8561             varDsc->lvRegNum  = REG_STK;
8562         }
8563     }
8564
8565     // Update the physRegRecord for the register, so that we know what vars are in
8566     // regs at the block boundaries
8567     RegRecord* physRegRecord = getRegisterRecord(homeReg);
8568     if (spillAfter || currentRefPosition->lastUse)
8569     {
8570         interval->isActive    = false;
8571         interval->assignedReg = nullptr;
8572         interval->physReg     = REG_NA;
8573
8574         updateAssignedInterval(physRegRecord, nullptr, interval->registerType);
8575     }
8576     else
8577     {
8578         interval->isActive    = true;
8579         interval->assignedReg = physRegRecord;
8580
8581         updateAssignedInterval(physRegRecord, interval, interval->registerType);
8582     }
8583 }
8584
8585 void LinearScan::writeRegisters(RefPosition* currentRefPosition, GenTree* tree)
8586 {
8587     lsraAssignRegToTree(tree, currentRefPosition->assignedReg(), currentRefPosition->getMultiRegIdx());
8588 }
8589
8590 //------------------------------------------------------------------------
8591 // insertCopyOrReload: Insert a copy in the case where a tree node value must be moved
8592 //   to a different register at the point of use (GT_COPY), or it is reloaded to a different register
8593 //   than the one it was spilled from (GT_RELOAD).
8594 //
8595 // Arguments:
8596 //    block             - basic block in which GT_COPY/GT_RELOAD is inserted.
8597 //    tree              - This is the node to copy or reload.
8598 //                        Insert copy or reload node between this node and its parent.
8599 //    multiRegIdx       - register position of tree node for which copy or reload is needed.
8600 //    refPosition       - The RefPosition at which copy or reload will take place.
8601 //
8602 // Notes:
8603 //    The GT_COPY or GT_RELOAD will be inserted in the proper spot in execution order where the reload is to occur.
8604 //
8605 // For example, for this tree (numbers are execution order, lower is earlier and higher is later):
8606 //
8607 //                                   +---------+----------+
8608 //                                   |       GT_ADD (3)   |
8609 //                                   +---------+----------+
8610 //                                             |
8611 //                                           /   \
8612 //                                         /       \
8613 //                                       /           \
8614 //                   +-------------------+           +----------------------+
8615 //                   |         x (1)     | "tree"    |         y (2)        |
8616 //                   +-------------------+           +----------------------+
8617 //
8618 // generate this tree:
8619 //
8620 //                                   +---------+----------+
8621 //                                   |       GT_ADD (4)   |
8622 //                                   +---------+----------+
8623 //                                             |
8624 //                                           /   \
8625 //                                         /       \
8626 //                                       /           \
8627 //                   +-------------------+           +----------------------+
8628 //                   |  GT_RELOAD (3)    |           |         y (2)        |
8629 //                   +-------------------+           +----------------------+
8630 //                             |
8631 //                   +-------------------+
8632 //                   |         x (1)     | "tree"
8633 //                   +-------------------+
8634 //
8635 // Note in particular that the GT_RELOAD node gets inserted in execution order immediately before the parent of "tree",
8636 // which seems a bit weird since normally a node's parent (in this case, the parent of "x", GT_RELOAD in the "after"
8637 // picture) immediately follows all of its children (that is, normally the execution ordering is postorder).
8638 // The ordering must be this weird "out of normal order" way because the "x" node is being spilled, probably
8639 // because the expression in the tree represented above by "y" has high register requirements. We don't want
8640 // to reload immediately, of course. So we put GT_RELOAD where the reload should actually happen.
8641 //
8642 // Note that GT_RELOAD is required when we reload to a different register than the one we spilled to. It can also be
8643 // used if we reload to the same register. Normally, though, in that case we just mark the node with GTF_SPILLED,
8644 // and the unspilling code automatically reuses the same register, and does the reload when it notices that flag
8645 // when considering a node's operands.
8646 //
8647 void LinearScan::insertCopyOrReload(BasicBlock* block, GenTreePtr tree, unsigned multiRegIdx, RefPosition* refPosition)
8648 {
8649     LIR::Range& blockRange = LIR::AsRange(block);
8650
8651     LIR::Use treeUse;
8652     bool     foundUse = blockRange.TryGetUse(tree, &treeUse);
8653     assert(foundUse);
8654
8655     GenTree* parent = treeUse.User();
8656
8657     genTreeOps oper;
8658     if (refPosition->reload)
8659     {
8660         oper = GT_RELOAD;
8661     }
8662     else
8663     {
8664         oper = GT_COPY;
8665
8666 #if TRACK_LSRA_STATS
8667         updateLsraStat(LSRA_STAT_COPY_REG, block->bbNum);
8668 #endif
8669     }
8670
8671     // If the parent is a reload/copy node, then tree must be a multi-reg call node
8672     // that has already had one of its registers spilled. This is Because multi-reg
8673     // call node is the only node whose RefTypeDef positions get independently
8674     // spilled or reloaded.  It is possible that one of its RefTypeDef position got
8675     // spilled and the next use of it requires it to be in a different register.
8676     //
8677     // In this case set the ith position reg of reload/copy node to the reg allocated
8678     // for copy/reload refPosition.  Essentially a copy/reload node will have a reg
8679     // for each multi-reg position of its child. If there is a valid reg in ith
8680     // position of GT_COPY or GT_RELOAD node then the corresponding result of its
8681     // child needs to be copied or reloaded to that reg.
8682     if (parent->IsCopyOrReload())
8683     {
8684         noway_assert(parent->OperGet() == oper);
8685         noway_assert(tree->IsMultiRegCall());
8686         GenTreeCall*         call         = tree->AsCall();
8687         GenTreeCopyOrReload* copyOrReload = parent->AsCopyOrReload();
8688         noway_assert(copyOrReload->GetRegNumByIdx(multiRegIdx) == REG_NA);
8689         copyOrReload->SetRegNumByIdx(refPosition->assignedReg(), multiRegIdx);
8690     }
8691     else
8692     {
8693         // Create the new node, with "tree" as its only child.
8694         var_types treeType = tree->TypeGet();
8695
8696         GenTreeCopyOrReload* newNode = new (compiler, oper) GenTreeCopyOrReload(oper, treeType, tree);
8697         assert(refPosition->registerAssignment != RBM_NONE);
8698         newNode->SetRegNumByIdx(refPosition->assignedReg(), multiRegIdx);
8699         newNode->gtLsraInfo.isLsraAdded   = true;
8700         newNode->gtLsraInfo.isLocalDefUse = false;
8701         if (refPosition->copyReg)
8702         {
8703             // This is a TEMPORARY copy
8704             assert(isCandidateLocalRef(tree));
8705             newNode->gtFlags |= GTF_VAR_DEATH;
8706         }
8707
8708         // Insert the copy/reload after the spilled node and replace the use of the original node with a use
8709         // of the copy/reload.
8710         blockRange.InsertAfter(tree, newNode);
8711         treeUse.ReplaceWith(compiler, newNode);
8712     }
8713 }
8714
8715 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
8716 //------------------------------------------------------------------------
8717 // insertUpperVectorSaveAndReload: Insert code to save and restore the upper half of a vector that lives
8718 //                                 in a callee-save register at the point of a kill (the upper half is
8719 //                                 not preserved).
8720 //
8721 // Arguments:
8722 //    tree              - This is the node around which we will insert the Save & Reload.
8723 //                        It will be a call or some node that turns into a call.
8724 //    refPosition       - The RefTypeUpperVectorSaveDef RefPosition.
8725 //
8726 void LinearScan::insertUpperVectorSaveAndReload(GenTreePtr tree, RefPosition* refPosition, BasicBlock* block)
8727 {
8728     Interval* lclVarInterval = refPosition->getInterval()->relatedInterval;
8729     assert(lclVarInterval->isLocalVar == true);
8730     LclVarDsc* varDsc = compiler->lvaTable + lclVarInterval->varNum;
8731     assert(varDsc->lvType == LargeVectorType);
8732     regNumber lclVarReg = lclVarInterval->physReg;
8733     if (lclVarReg == REG_NA)
8734     {
8735         return;
8736     }
8737
8738     assert((genRegMask(lclVarReg) & RBM_FLT_CALLEE_SAVED) != RBM_NONE);
8739
8740     regNumber spillReg   = refPosition->assignedReg();
8741     bool      spillToMem = refPosition->spillAfter;
8742
8743     LIR::Range& blockRange = LIR::AsRange(block);
8744
8745     // First, insert the save before the call.
8746
8747     GenTreePtr saveLcl                = compiler->gtNewLclvNode(lclVarInterval->varNum, LargeVectorType);
8748     saveLcl->gtLsraInfo.isLsraAdded   = true;
8749     saveLcl->gtRegNum                 = lclVarReg;
8750     saveLcl->gtLsraInfo.isLocalDefUse = false;
8751
8752     GenTreeSIMD* simdNode =
8753         new (compiler, GT_SIMD) GenTreeSIMD(LargeVectorSaveType, saveLcl, nullptr, SIMDIntrinsicUpperSave,
8754                                             varDsc->lvBaseType, genTypeSize(LargeVectorType));
8755     simdNode->gtLsraInfo.isLsraAdded = true;
8756     simdNode->gtRegNum               = spillReg;
8757     if (spillToMem)
8758     {
8759         simdNode->gtFlags |= GTF_SPILL;
8760     }
8761
8762     blockRange.InsertBefore(tree, LIR::SeqTree(compiler, simdNode));
8763
8764     // Now insert the restore after the call.
8765
8766     GenTreePtr restoreLcl                = compiler->gtNewLclvNode(lclVarInterval->varNum, LargeVectorType);
8767     restoreLcl->gtLsraInfo.isLsraAdded   = true;
8768     restoreLcl->gtRegNum                 = lclVarReg;
8769     restoreLcl->gtLsraInfo.isLocalDefUse = false;
8770
8771     simdNode = new (compiler, GT_SIMD)
8772         GenTreeSIMD(LargeVectorType, restoreLcl, nullptr, SIMDIntrinsicUpperRestore, varDsc->lvBaseType, 32);
8773     simdNode->gtLsraInfo.isLsraAdded = true;
8774     simdNode->gtRegNum               = spillReg;
8775     if (spillToMem)
8776     {
8777         simdNode->gtFlags |= GTF_SPILLED;
8778     }
8779
8780     blockRange.InsertAfter(tree, LIR::SeqTree(compiler, simdNode));
8781 }
8782 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
8783
8784 //------------------------------------------------------------------------
8785 // initMaxSpill: Initializes the LinearScan members used to track the max number
8786 //               of concurrent spills.  This is needed so that we can set the
8787 //               fields in Compiler, so that the code generator, in turn can
8788 //               allocate the right number of spill locations.
8789 //
8790 // Arguments:
8791 //    None.
8792 //
8793 // Return Value:
8794 //    None.
8795 //
8796 // Assumptions:
8797 //    This is called before any calls to updateMaxSpill().
8798
8799 void LinearScan::initMaxSpill()
8800 {
8801     needDoubleTmpForFPCall = false;
8802     needFloatTmpForFPCall  = false;
8803     for (int i = 0; i < TYP_COUNT; i++)
8804     {
8805         maxSpill[i]     = 0;
8806         currentSpill[i] = 0;
8807     }
8808 }
8809
8810 //------------------------------------------------------------------------
8811 // recordMaxSpill: Sets the fields in Compiler for the max number of concurrent spills.
8812 //                 (See the comment on initMaxSpill.)
8813 //
8814 // Arguments:
8815 //    None.
8816 //
8817 // Return Value:
8818 //    None.
8819 //
8820 // Assumptions:
8821 //    This is called after updateMaxSpill() has been called for all "real"
8822 //    RefPositions.
8823
8824 void LinearScan::recordMaxSpill()
8825 {
8826     // Note: due to the temp normalization process (see tmpNormalizeType)
8827     // only a few types should actually be seen here.
8828     JITDUMP("Recording the maximum number of concurrent spills:\n");
8829 #ifdef _TARGET_X86_
8830     var_types returnType = compiler->tmpNormalizeType(compiler->info.compRetType);
8831     if (needDoubleTmpForFPCall || (returnType == TYP_DOUBLE))
8832     {
8833         JITDUMP("Adding a spill temp for moving a double call/return value between xmm reg and x87 stack.\n");
8834         maxSpill[TYP_DOUBLE] += 1;
8835     }
8836     if (needFloatTmpForFPCall || (returnType == TYP_FLOAT))
8837     {
8838         JITDUMP("Adding a spill temp for moving a float call/return value between xmm reg and x87 stack.\n");
8839         maxSpill[TYP_FLOAT] += 1;
8840     }
8841 #endif // _TARGET_X86_
8842     for (int i = 0; i < TYP_COUNT; i++)
8843     {
8844         if (var_types(i) != compiler->tmpNormalizeType(var_types(i)))
8845         {
8846             // Only normalized types should have anything in the maxSpill array.
8847             // We assume here that if type 'i' does not normalize to itself, then
8848             // nothing else normalizes to 'i', either.
8849             assert(maxSpill[i] == 0);
8850         }
8851         if (maxSpill[i] != 0)
8852         {
8853             JITDUMP("  %s: %d\n", varTypeName(var_types(i)), maxSpill[i]);
8854             compiler->tmpPreAllocateTemps(var_types(i), maxSpill[i]);
8855         }
8856     }
8857     JITDUMP("\n");
8858 }
8859
8860 //------------------------------------------------------------------------
8861 // updateMaxSpill: Update the maximum number of concurrent spills
8862 //
8863 // Arguments:
8864 //    refPosition - the current RefPosition being handled
8865 //
8866 // Return Value:
8867 //    None.
8868 //
8869 // Assumptions:
8870 //    The RefPosition has an associated interval (getInterval() will
8871 //    otherwise assert).
8872 //
8873 // Notes:
8874 //    This is called for each "real" RefPosition during the writeback
8875 //    phase of LSRA.  It keeps track of how many concurrently-live
8876 //    spills there are, and the largest number seen so far.
8877
8878 void LinearScan::updateMaxSpill(RefPosition* refPosition)
8879 {
8880     RefType refType = refPosition->refType;
8881
8882     if (refPosition->spillAfter || refPosition->reload ||
8883         (refPosition->AllocateIfProfitable() && refPosition->assignedReg() == REG_NA))
8884     {
8885         Interval* interval = refPosition->getInterval();
8886         if (!interval->isLocalVar)
8887         {
8888             // The tmp allocation logic 'normalizes' types to a small number of
8889             // types that need distinct stack locations from each other.
8890             // Those types are currently gc refs, byrefs, <= 4 byte non-GC items,
8891             // 8-byte non-GC items, and 16-byte or 32-byte SIMD vectors.
8892             // LSRA is agnostic to those choices but needs
8893             // to know what they are here.
8894             var_types typ;
8895
8896 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
8897             if ((refType == RefTypeUpperVectorSaveDef) || (refType == RefTypeUpperVectorSaveUse))
8898             {
8899                 typ = LargeVectorSaveType;
8900             }
8901             else
8902 #endif // !FEATURE_PARTIAL_SIMD_CALLEE_SAVE
8903             {
8904                 GenTreePtr treeNode = refPosition->treeNode;
8905                 if (treeNode == nullptr)
8906                 {
8907                     assert(RefTypeIsUse(refType));
8908                     treeNode = interval->firstRefPosition->treeNode;
8909                 }
8910                 assert(treeNode != nullptr);
8911
8912                 // In case of multi-reg call nodes, we need to use the type
8913                 // of the return register given by multiRegIdx of the refposition.
8914                 if (treeNode->IsMultiRegCall())
8915                 {
8916                     ReturnTypeDesc* retTypeDesc = treeNode->AsCall()->GetReturnTypeDesc();
8917                     typ                         = retTypeDesc->GetReturnRegType(refPosition->getMultiRegIdx());
8918                 }
8919 #ifdef ARM_SOFTFP
8920                 else if (treeNode->OperIsPutArgReg())
8921                 {
8922                     // For double arg regs, the type is changed to long since they must be passed via `r0-r3`.
8923                     // However when they get spilled, they should be treated as separated int registers.
8924                     var_types typNode = treeNode->TypeGet();
8925                     typ               = (typNode == TYP_LONG) ? TYP_INT : typNode;
8926                 }
8927 #endif // ARM_SOFTFP
8928                 else
8929                 {
8930                     typ = treeNode->TypeGet();
8931                 }
8932                 typ = compiler->tmpNormalizeType(typ);
8933             }
8934
8935             if (refPosition->spillAfter && !refPosition->reload)
8936             {
8937                 currentSpill[typ]++;
8938                 if (currentSpill[typ] > maxSpill[typ])
8939                 {
8940                     maxSpill[typ] = currentSpill[typ];
8941                 }
8942             }
8943             else if (refPosition->reload)
8944             {
8945                 assert(currentSpill[typ] > 0);
8946                 currentSpill[typ]--;
8947             }
8948             else if (refPosition->AllocateIfProfitable() && refPosition->assignedReg() == REG_NA)
8949             {
8950                 // A spill temp not getting reloaded into a reg because it is
8951                 // marked as allocate if profitable and getting used from its
8952                 // memory location.  To properly account max spill for typ we
8953                 // decrement spill count.
8954                 assert(RefTypeIsUse(refType));
8955                 assert(currentSpill[typ] > 0);
8956                 currentSpill[typ]--;
8957             }
8958             JITDUMP("  Max spill for %s is %d\n", varTypeName(typ), maxSpill[typ]);
8959         }
8960     }
8961 }
8962
8963 // This is the final phase of register allocation.  It writes the register assignments to
8964 // the tree, and performs resolution across joins and backedges.
8965 //
8966 void LinearScan::resolveRegisters()
8967 {
8968     // Iterate over the tree and the RefPositions in lockstep
8969     //  - annotate the tree with register assignments by setting gtRegNum or gtRegPair (for longs)
8970     //    on the tree node
8971     //  - track globally-live var locations
8972     //  - add resolution points at split/merge/critical points as needed
8973
8974     // Need to use the same traversal order as the one that assigns the location numbers.
8975
8976     // Dummy RefPositions have been added at any split, join or critical edge, at the
8977     // point where resolution may be required.  These are located:
8978     //  - for a split, at the top of the non-adjacent block
8979     //  - for a join, at the bottom of the non-adjacent joining block
8980     //  - for a critical edge, at the top of the target block of each critical
8981     //    edge.
8982     // Note that a target block may have multiple incoming critical or split edges
8983     //
8984     // These RefPositions record the expected location of the Interval at that point.
8985     // At each branch, we identify the location of each liveOut interval, and check
8986     // against the RefPositions at the target.
8987
8988     BasicBlock*  block;
8989     LsraLocation currentLocation = MinLocation;
8990
8991     // Clear register assignments - these will be reestablished as lclVar defs (including RefTypeParamDefs)
8992     // are encountered.
8993     if (enregisterLocalVars)
8994     {
8995         for (regNumber reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
8996         {
8997             RegRecord* physRegRecord    = getRegisterRecord(reg);
8998             Interval*  assignedInterval = physRegRecord->assignedInterval;
8999             if (assignedInterval != nullptr)
9000             {
9001                 assignedInterval->assignedReg = nullptr;
9002                 assignedInterval->physReg     = REG_NA;
9003             }
9004             physRegRecord->assignedInterval  = nullptr;
9005             physRegRecord->recentRefPosition = nullptr;
9006         }
9007
9008         // Clear "recentRefPosition" for lclVar intervals
9009         for (unsigned varIndex = 0; varIndex < compiler->lvaTrackedCount; varIndex++)
9010         {
9011             if (localVarIntervals[varIndex] != nullptr)
9012             {
9013                 localVarIntervals[varIndex]->recentRefPosition = nullptr;
9014                 localVarIntervals[varIndex]->isActive          = false;
9015             }
9016             else
9017             {
9018                 assert(compiler->lvaTable[compiler->lvaTrackedToVarNum[varIndex]].lvLRACandidate == false);
9019             }
9020         }
9021     }
9022
9023     // handle incoming arguments and special temps
9024     auto currentRefPosition = refPositions.begin();
9025
9026     if (enregisterLocalVars)
9027     {
9028         VarToRegMap entryVarToRegMap = inVarToRegMaps[compiler->fgFirstBB->bbNum];
9029         while (currentRefPosition != refPositions.end() &&
9030                (currentRefPosition->refType == RefTypeParamDef || currentRefPosition->refType == RefTypeZeroInit))
9031         {
9032             Interval* interval = currentRefPosition->getInterval();
9033             assert(interval != nullptr && interval->isLocalVar);
9034             resolveLocalRef(nullptr, nullptr, currentRefPosition);
9035             regNumber reg      = REG_STK;
9036             int       varIndex = interval->getVarIndex(compiler);
9037
9038             if (!currentRefPosition->spillAfter && currentRefPosition->registerAssignment != RBM_NONE)
9039             {
9040                 reg = currentRefPosition->assignedReg();
9041             }
9042             else
9043             {
9044                 reg                = REG_STK;
9045                 interval->isActive = false;
9046             }
9047             setVarReg(entryVarToRegMap, varIndex, reg);
9048             ++currentRefPosition;
9049         }
9050     }
9051     else
9052     {
9053         assert(currentRefPosition == refPositions.end() ||
9054                (currentRefPosition->refType != RefTypeParamDef && currentRefPosition->refType != RefTypeZeroInit));
9055     }
9056
9057     BasicBlock* insertionBlock = compiler->fgFirstBB;
9058     GenTreePtr  insertionPoint = LIR::AsRange(insertionBlock).FirstNonPhiNode();
9059
9060     // write back assignments
9061     for (block = startBlockSequence(); block != nullptr; block = moveToNextBlock())
9062     {
9063         assert(curBBNum == block->bbNum);
9064
9065         if (enregisterLocalVars)
9066         {
9067             // Record the var locations at the start of this block.
9068             // (If it's fgFirstBB, we've already done that above, see entryVarToRegMap)
9069
9070             curBBStartLocation = currentRefPosition->nodeLocation;
9071             if (block != compiler->fgFirstBB)
9072             {
9073                 processBlockStartLocations(block, false);
9074             }
9075
9076             // Handle the DummyDefs, updating the incoming var location.
9077             for (; currentRefPosition != refPositions.end() && currentRefPosition->refType == RefTypeDummyDef;
9078                  ++currentRefPosition)
9079             {
9080                 assert(currentRefPosition->isIntervalRef());
9081                 // Don't mark dummy defs as reload
9082                 currentRefPosition->reload = false;
9083                 resolveLocalRef(nullptr, nullptr, currentRefPosition);
9084                 regNumber reg;
9085                 if (currentRefPosition->registerAssignment != RBM_NONE)
9086                 {
9087                     reg = currentRefPosition->assignedReg();
9088                 }
9089                 else
9090                 {
9091                     reg                                         = REG_STK;
9092                     currentRefPosition->getInterval()->isActive = false;
9093                 }
9094                 setInVarRegForBB(curBBNum, currentRefPosition->getInterval()->varNum, reg);
9095             }
9096         }
9097
9098         // The next RefPosition should be for the block.  Move past it.
9099         assert(currentRefPosition != refPositions.end());
9100         assert(currentRefPosition->refType == RefTypeBB);
9101         ++currentRefPosition;
9102
9103         // Handle the RefPositions for the block
9104         for (; currentRefPosition != refPositions.end() && currentRefPosition->refType != RefTypeBB &&
9105                currentRefPosition->refType != RefTypeDummyDef;
9106              ++currentRefPosition)
9107         {
9108             currentLocation = currentRefPosition->nodeLocation;
9109
9110             // Ensure that the spill & copy info is valid.
9111             // First, if it's reload, it must not be copyReg or moveReg
9112             assert(!currentRefPosition->reload || (!currentRefPosition->copyReg && !currentRefPosition->moveReg));
9113             // If it's copyReg it must not be moveReg, and vice-versa
9114             assert(!currentRefPosition->copyReg || !currentRefPosition->moveReg);
9115
9116             switch (currentRefPosition->refType)
9117             {
9118 #ifdef FEATURE_SIMD
9119                 case RefTypeUpperVectorSaveUse:
9120                 case RefTypeUpperVectorSaveDef:
9121 #endif // FEATURE_SIMD
9122                 case RefTypeUse:
9123                 case RefTypeDef:
9124                     // These are the ones we're interested in
9125                     break;
9126                 case RefTypeKill:
9127                 case RefTypeFixedReg:
9128                     // These require no handling at resolution time
9129                     assert(currentRefPosition->referent != nullptr);
9130                     currentRefPosition->referent->recentRefPosition = currentRefPosition;
9131                     continue;
9132                 case RefTypeExpUse:
9133                     // Ignore the ExpUse cases - a RefTypeExpUse would only exist if the
9134                     // variable is dead at the entry to the next block.  So we'll mark
9135                     // it as in its current location and resolution will take care of any
9136                     // mismatch.
9137                     assert(getNextBlock() == nullptr ||
9138                            !VarSetOps::IsMember(compiler, getNextBlock()->bbLiveIn,
9139                                                 currentRefPosition->getInterval()->getVarIndex(compiler)));
9140                     currentRefPosition->referent->recentRefPosition = currentRefPosition;
9141                     continue;
9142                 case RefTypeKillGCRefs:
9143                     // No action to take at resolution time, and no interval to update recentRefPosition for.
9144                     continue;
9145                 case RefTypeDummyDef:
9146                 case RefTypeParamDef:
9147                 case RefTypeZeroInit:
9148                 // Should have handled all of these already
9149                 default:
9150                     unreached();
9151                     break;
9152             }
9153             updateMaxSpill(currentRefPosition);
9154             GenTree* treeNode = currentRefPosition->treeNode;
9155
9156 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
9157             if (currentRefPosition->refType == RefTypeUpperVectorSaveDef)
9158             {
9159                 // The treeNode must be a call, and this must be a RefPosition for a LargeVectorType LocalVar.
9160                 // If the LocalVar is in a callee-save register, we are going to spill its upper half around the call.
9161                 // If we have allocated a register to spill it to, we will use that; otherwise, we will spill it
9162                 // to the stack.  We can use as a temp register any non-arg caller-save register.
9163                 noway_assert(treeNode != nullptr);
9164                 currentRefPosition->referent->recentRefPosition = currentRefPosition;
9165                 insertUpperVectorSaveAndReload(treeNode, currentRefPosition, block);
9166             }
9167             else if (currentRefPosition->refType == RefTypeUpperVectorSaveUse)
9168             {
9169                 continue;
9170             }
9171 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
9172
9173             // Most uses won't actually need to be recorded (they're on the def).
9174             // In those cases, treeNode will be nullptr.
9175             if (treeNode == nullptr)
9176             {
9177                 // This is either a use, a dead def, or a field of a struct
9178                 Interval* interval = currentRefPosition->getInterval();
9179                 assert(currentRefPosition->refType == RefTypeUse ||
9180                        currentRefPosition->registerAssignment == RBM_NONE || interval->isStructField);
9181
9182                 // TODO-Review: Need to handle the case where any of the struct fields
9183                 // are reloaded/spilled at this use
9184                 assert(!interval->isStructField ||
9185                        (currentRefPosition->reload == false && currentRefPosition->spillAfter == false));
9186
9187                 if (interval->isLocalVar && !interval->isStructField)
9188                 {
9189                     LclVarDsc* varDsc = interval->getLocalVar(compiler);
9190
9191                     // This must be a dead definition.  We need to mark the lclVar
9192                     // so that it's not considered a candidate for lvRegister, as
9193                     // this dead def will have to go to the stack.
9194                     assert(currentRefPosition->refType == RefTypeDef);
9195                     varDsc->lvRegNum = REG_STK;
9196                 }
9197                 continue;
9198             }
9199
9200             LsraLocation loc = treeNode->gtLsraInfo.loc;
9201             assert(treeNode->IsLocal() || currentLocation == loc || currentLocation == loc + 1);
9202
9203             if (currentRefPosition->isIntervalRef() && currentRefPosition->getInterval()->isInternal)
9204             {
9205                 treeNode->gtRsvdRegs |= currentRefPosition->registerAssignment;
9206             }
9207             else
9208             {
9209                 writeRegisters(currentRefPosition, treeNode);
9210
9211                 if (treeNode->IsLocal() && currentRefPosition->getInterval()->isLocalVar)
9212                 {
9213                     resolveLocalRef(block, treeNode, currentRefPosition);
9214                 }
9215
9216                 // Mark spill locations on temps
9217                 // (local vars are handled in resolveLocalRef, above)
9218                 // Note that the tree node will be changed from GTF_SPILL to GTF_SPILLED
9219                 // in codegen, taking care of the "reload" case for temps
9220                 else if (currentRefPosition->spillAfter || (currentRefPosition->nextRefPosition != nullptr &&
9221                                                             currentRefPosition->nextRefPosition->moveReg))
9222                 {
9223                     if (treeNode != nullptr && currentRefPosition->isIntervalRef())
9224                     {
9225                         if (currentRefPosition->spillAfter)
9226                         {
9227                             treeNode->gtFlags |= GTF_SPILL;
9228
9229                             // If this is a constant interval that is reusing a pre-existing value, we actually need
9230                             // to generate the value at this point in order to spill it.
9231                             if (treeNode->IsReuseRegVal())
9232                             {
9233                                 treeNode->ResetReuseRegVal();
9234                             }
9235
9236                             // In case of multi-reg call node, also set spill flag on the
9237                             // register specified by multi-reg index of current RefPosition.
9238                             // Note that the spill flag on treeNode indicates that one or
9239                             // more its allocated registers are in that state.
9240                             if (treeNode->IsMultiRegCall())
9241                             {
9242                                 GenTreeCall* call = treeNode->AsCall();
9243                                 call->SetRegSpillFlagByIdx(GTF_SPILL, currentRefPosition->getMultiRegIdx());
9244                             }
9245 #ifdef _TARGET_ARM_
9246                             else if (treeNode->OperIsPutArgSplit())
9247                             {
9248                                 GenTreePutArgSplit* splitArg = treeNode->AsPutArgSplit();
9249                                 splitArg->SetRegSpillFlagByIdx(GTF_SPILL, currentRefPosition->getMultiRegIdx());
9250                             }
9251                             else if (treeNode->OperIsMultiRegOp())
9252                             {
9253                                 GenTreeMultiRegOp* multiReg = treeNode->AsMultiRegOp();
9254                                 multiReg->SetRegSpillFlagByIdx(GTF_SPILL, currentRefPosition->getMultiRegIdx());
9255                             }
9256 #endif
9257                         }
9258
9259                         // If the value is reloaded or moved to a different register, we need to insert
9260                         // a node to hold the register to which it should be reloaded
9261                         RefPosition* nextRefPosition = currentRefPosition->nextRefPosition;
9262                         assert(nextRefPosition != nullptr);
9263                         if (INDEBUG(alwaysInsertReload() ||)
9264                                 nextRefPosition->assignedReg() != currentRefPosition->assignedReg())
9265                         {
9266                             if (nextRefPosition->assignedReg() != REG_NA)
9267                             {
9268                                 insertCopyOrReload(block, treeNode, currentRefPosition->getMultiRegIdx(),
9269                                                    nextRefPosition);
9270                             }
9271                             else
9272                             {
9273                                 assert(nextRefPosition->AllocateIfProfitable());
9274
9275                                 // In case of tree temps, if def is spilled and use didn't
9276                                 // get a register, set a flag on tree node to be treated as
9277                                 // contained at the point of its use.
9278                                 if (currentRefPosition->spillAfter && currentRefPosition->refType == RefTypeDef &&
9279                                     nextRefPosition->refType == RefTypeUse)
9280                                 {
9281                                     assert(nextRefPosition->treeNode == nullptr);
9282                                     treeNode->gtFlags |= GTF_NOREG_AT_USE;
9283                                 }
9284                             }
9285                         }
9286                     }
9287
9288                     // We should never have to "spill after" a temp use, since
9289                     // they're single use
9290                     else
9291                     {
9292                         unreached();
9293                     }
9294                 }
9295             }
9296         }
9297
9298         if (enregisterLocalVars)
9299         {
9300             processBlockEndLocations(block);
9301         }
9302     }
9303
9304     if (enregisterLocalVars)
9305     {
9306 #ifdef DEBUG
9307         if (VERBOSE)
9308         {
9309             printf("-----------------------\n");
9310             printf("RESOLVING BB BOUNDARIES\n");
9311             printf("-----------------------\n");
9312
9313             printf("Resolution Candidates: ");
9314             dumpConvertedVarSet(compiler, resolutionCandidateVars);
9315             printf("\n");
9316             printf("Has %sCritical Edges\n\n", hasCriticalEdges ? "" : "No");
9317
9318             printf("Prior to Resolution\n");
9319             foreach_block(compiler, block)
9320             {
9321                 printf("\nBB%02u use def in out\n", block->bbNum);
9322                 dumpConvertedVarSet(compiler, block->bbVarUse);
9323                 printf("\n");
9324                 dumpConvertedVarSet(compiler, block->bbVarDef);
9325                 printf("\n");
9326                 dumpConvertedVarSet(compiler, block->bbLiveIn);
9327                 printf("\n");
9328                 dumpConvertedVarSet(compiler, block->bbLiveOut);
9329                 printf("\n");
9330
9331                 dumpInVarToRegMap(block);
9332                 dumpOutVarToRegMap(block);
9333             }
9334
9335             printf("\n\n");
9336         }
9337 #endif // DEBUG
9338
9339         resolveEdges();
9340
9341         // Verify register assignments on variables
9342         unsigned   lclNum;
9343         LclVarDsc* varDsc;
9344         for (lclNum = 0, varDsc = compiler->lvaTable; lclNum < compiler->lvaCount; lclNum++, varDsc++)
9345         {
9346             if (!isCandidateVar(varDsc))
9347             {
9348                 varDsc->lvRegNum = REG_STK;
9349             }
9350             else
9351             {
9352                 Interval* interval = getIntervalForLocalVar(varDsc->lvVarIndex);
9353
9354                 // Determine initial position for parameters
9355
9356                 if (varDsc->lvIsParam)
9357                 {
9358                     regMaskTP initialRegMask = interval->firstRefPosition->registerAssignment;
9359                     regNumber initialReg     = (initialRegMask == RBM_NONE || interval->firstRefPosition->spillAfter)
9360                                                ? REG_STK
9361                                                : genRegNumFromMask(initialRegMask);
9362                     regNumber sourceReg = (varDsc->lvIsRegArg) ? varDsc->lvArgReg : REG_STK;
9363
9364 #ifdef _TARGET_ARM_
9365                     if (varTypeIsMultiReg(varDsc))
9366                     {
9367                         // TODO-ARM-NYI: Map the hi/lo intervals back to lvRegNum and lvOtherReg (these should NYI
9368                         // before this)
9369                         assert(!"Multi-reg types not yet supported");
9370                     }
9371                     else
9372 #endif // _TARGET_ARM_
9373                     {
9374                         varDsc->lvArgInitReg = initialReg;
9375                         JITDUMP("  Set V%02u argument initial register to %s\n", lclNum, getRegName(initialReg));
9376                     }
9377
9378                     // Stack args that are part of dependently-promoted structs should never be register candidates (see
9379                     // LinearScan::isRegCandidate).
9380                     assert(varDsc->lvIsRegArg || !compiler->lvaIsFieldOfDependentlyPromotedStruct(varDsc));
9381                 }
9382
9383                 // If lvRegNum is REG_STK, that means that either no register
9384                 // was assigned, or (more likely) that the same register was not
9385                 // used for all references.  In that case, codegen gets the register
9386                 // from the tree node.
9387                 if (varDsc->lvRegNum == REG_STK || interval->isSpilled || interval->isSplit)
9388                 {
9389                     // For codegen purposes, we'll set lvRegNum to whatever register
9390                     // it's currently in as we go.
9391                     // However, we never mark an interval as lvRegister if it has either been spilled
9392                     // or split.
9393                     varDsc->lvRegister = false;
9394
9395                     // Skip any dead defs or exposed uses
9396                     // (first use exposed will only occur when there is no explicit initialization)
9397                     RefPosition* firstRefPosition = interval->firstRefPosition;
9398                     while ((firstRefPosition != nullptr) && (firstRefPosition->refType == RefTypeExpUse))
9399                     {
9400                         firstRefPosition = firstRefPosition->nextRefPosition;
9401                     }
9402                     if (firstRefPosition == nullptr)
9403                     {
9404                         // Dead interval
9405                         varDsc->lvLRACandidate = false;
9406                         if (varDsc->lvRefCnt == 0)
9407                         {
9408                             varDsc->lvOnFrame = false;
9409                         }
9410                         else
9411                         {
9412                             // We may encounter cases where a lclVar actually has no references, but
9413                             // a non-zero refCnt.  For safety (in case this is some "hidden" lclVar that we're
9414                             // not correctly recognizing), we'll mark those as needing a stack location.
9415                             // TODO-Cleanup: Make this an assert if/when we correct the refCnt
9416                             // updating.
9417                             varDsc->lvOnFrame = true;
9418                         }
9419                     }
9420                     else
9421                     {
9422                         // If the interval was not spilled, it doesn't need a stack location.
9423                         if (!interval->isSpilled)
9424                         {
9425                             varDsc->lvOnFrame = false;
9426                         }
9427                         if (firstRefPosition->registerAssignment == RBM_NONE || firstRefPosition->spillAfter)
9428                         {
9429                             // Either this RefPosition is spilled, or regOptional or it is not a "real" def or use
9430                             assert(
9431                                 firstRefPosition->spillAfter || firstRefPosition->AllocateIfProfitable() ||
9432                                 (firstRefPosition->refType != RefTypeDef && firstRefPosition->refType != RefTypeUse));
9433                             varDsc->lvRegNum = REG_STK;
9434                         }
9435                         else
9436                         {
9437                             varDsc->lvRegNum = firstRefPosition->assignedReg();
9438                         }
9439                     }
9440                 }
9441                 else
9442                 {
9443                     {
9444                         varDsc->lvRegister = true;
9445                         varDsc->lvOnFrame  = false;
9446                     }
9447 #ifdef DEBUG
9448                     regMaskTP registerAssignment = genRegMask(varDsc->lvRegNum);
9449                     assert(!interval->isSpilled && !interval->isSplit);
9450                     RefPosition* refPosition = interval->firstRefPosition;
9451                     assert(refPosition != nullptr);
9452
9453                     while (refPosition != nullptr)
9454                     {
9455                         // All RefPositions must match, except for dead definitions,
9456                         // copyReg/moveReg and RefTypeExpUse positions
9457                         if (refPosition->registerAssignment != RBM_NONE && !refPosition->copyReg &&
9458                             !refPosition->moveReg && refPosition->refType != RefTypeExpUse)
9459                         {
9460                             assert(refPosition->registerAssignment == registerAssignment);
9461                         }
9462                         refPosition = refPosition->nextRefPosition;
9463                     }
9464 #endif // DEBUG
9465                 }
9466             }
9467         }
9468     }
9469
9470 #ifdef DEBUG
9471     if (VERBOSE)
9472     {
9473         printf("Trees after linear scan register allocator (LSRA)\n");
9474         compiler->fgDispBasicBlocks(true);
9475     }
9476
9477     verifyFinalAllocation();
9478 #endif // DEBUG
9479
9480     compiler->raMarkStkVars();
9481     recordMaxSpill();
9482
9483     // TODO-CQ: Review this comment and address as needed.
9484     // Change all unused promoted non-argument struct locals to a non-GC type (in this case TYP_INT)
9485     // so that the gc tracking logic and lvMustInit logic will ignore them.
9486     // Extract the code that does this from raAssignVars, and call it here.
9487     // PRECONDITIONS: Ensure that lvPromoted is set on promoted structs, if and
9488     // only if it is promoted on all paths.
9489     // Call might be something like:
9490     // compiler->BashUnusedStructLocals();
9491 }
9492
9493 //
9494 //------------------------------------------------------------------------
9495 // insertMove: Insert a move of a lclVar with the given lclNum into the given block.
9496 //
9497 // Arguments:
9498 //    block          - the BasicBlock into which the move will be inserted.
9499 //    insertionPoint - the instruction before which to insert the move
9500 //    lclNum         - the lclNum of the var to be moved
9501 //    fromReg        - the register from which the var is moving
9502 //    toReg          - the register to which the var is moving
9503 //
9504 // Return Value:
9505 //    None.
9506 //
9507 // Notes:
9508 //    If insertionPoint is non-NULL, insert before that instruction;
9509 //    otherwise, insert "near" the end (prior to the branch, if any).
9510 //    If fromReg or toReg is REG_STK, then move from/to memory, respectively.
9511
9512 void LinearScan::insertMove(
9513     BasicBlock* block, GenTreePtr insertionPoint, unsigned lclNum, regNumber fromReg, regNumber toReg)
9514 {
9515     LclVarDsc* varDsc = compiler->lvaTable + lclNum;
9516     // the lclVar must be a register candidate
9517     assert(isRegCandidate(varDsc));
9518     // One or both MUST be a register
9519     assert(fromReg != REG_STK || toReg != REG_STK);
9520     // They must not be the same register.
9521     assert(fromReg != toReg);
9522
9523     // This var can't be marked lvRegister now
9524     varDsc->lvRegNum = REG_STK;
9525
9526     GenTreePtr src              = compiler->gtNewLclvNode(lclNum, varDsc->TypeGet());
9527     src->gtLsraInfo.isLsraAdded = true;
9528
9529     // There are three cases we need to handle:
9530     // - We are loading a lclVar from the stack.
9531     // - We are storing a lclVar to the stack.
9532     // - We are copying a lclVar between registers.
9533     //
9534     // In the first and second cases, the lclVar node will be marked with GTF_SPILLED and GTF_SPILL, respectively.
9535     // It is up to the code generator to ensure that any necessary normalization is done when loading or storing the
9536     // lclVar's value.
9537     //
9538     // In the third case, we generate GT_COPY(GT_LCL_VAR) and type each node with the normalized type of the lclVar.
9539     // This is safe because a lclVar is always normalized once it is in a register.
9540
9541     GenTree* dst = src;
9542     if (fromReg == REG_STK)
9543     {
9544         src->gtFlags |= GTF_SPILLED;
9545         src->gtRegNum = toReg;
9546     }
9547     else if (toReg == REG_STK)
9548     {
9549         src->gtFlags |= GTF_SPILL;
9550         src->gtRegNum = fromReg;
9551     }
9552     else
9553     {
9554         var_types movType = genActualType(varDsc->TypeGet());
9555         src->gtType       = movType;
9556
9557         dst = new (compiler, GT_COPY) GenTreeCopyOrReload(GT_COPY, movType, src);
9558         // This is the new home of the lclVar - indicate that by clearing the GTF_VAR_DEATH flag.
9559         // Note that if src is itself a lastUse, this will have no effect.
9560         dst->gtFlags &= ~(GTF_VAR_DEATH);
9561         src->gtRegNum                 = fromReg;
9562         dst->gtRegNum                 = toReg;
9563         src->gtLsraInfo.isLocalDefUse = false;
9564         dst->gtLsraInfo.isLsraAdded   = true;
9565     }
9566     dst->gtLsraInfo.isLocalDefUse = true;
9567
9568     LIR::Range  treeRange  = LIR::SeqTree(compiler, dst);
9569     LIR::Range& blockRange = LIR::AsRange(block);
9570
9571     if (insertionPoint != nullptr)
9572     {
9573         blockRange.InsertBefore(insertionPoint, std::move(treeRange));
9574     }
9575     else
9576     {
9577         // Put the copy at the bottom
9578         // If there's a branch, make an embedded statement that executes just prior to the branch
9579         if (block->bbJumpKind == BBJ_COND || block->bbJumpKind == BBJ_SWITCH)
9580         {
9581             noway_assert(!blockRange.IsEmpty());
9582
9583             GenTree* branch = blockRange.LastNode();
9584             assert(branch->OperIsConditionalJump() || branch->OperGet() == GT_SWITCH_TABLE ||
9585                    branch->OperGet() == GT_SWITCH);
9586
9587             blockRange.InsertBefore(branch, std::move(treeRange));
9588         }
9589         else
9590         {
9591             assert(block->bbJumpKind == BBJ_NONE || block->bbJumpKind == BBJ_ALWAYS);
9592             blockRange.InsertAtEnd(std::move(treeRange));
9593         }
9594     }
9595 }
9596
9597 void LinearScan::insertSwap(
9598     BasicBlock* block, GenTreePtr insertionPoint, unsigned lclNum1, regNumber reg1, unsigned lclNum2, regNumber reg2)
9599 {
9600 #ifdef DEBUG
9601     if (VERBOSE)
9602     {
9603         const char* insertionPointString = "top";
9604         if (insertionPoint == nullptr)
9605         {
9606             insertionPointString = "bottom";
9607         }
9608         printf("   BB%02u %s: swap V%02u in %s with V%02u in %s\n", block->bbNum, insertionPointString, lclNum1,
9609                getRegName(reg1), lclNum2, getRegName(reg2));
9610     }
9611 #endif // DEBUG
9612
9613     LclVarDsc* varDsc1 = compiler->lvaTable + lclNum1;
9614     LclVarDsc* varDsc2 = compiler->lvaTable + lclNum2;
9615     assert(reg1 != REG_STK && reg1 != REG_NA && reg2 != REG_STK && reg2 != REG_NA);
9616
9617     GenTreePtr lcl1                = compiler->gtNewLclvNode(lclNum1, varDsc1->TypeGet());
9618     lcl1->gtLsraInfo.isLsraAdded   = true;
9619     lcl1->gtLsraInfo.isLocalDefUse = false;
9620     lcl1->gtRegNum                 = reg1;
9621
9622     GenTreePtr lcl2                = compiler->gtNewLclvNode(lclNum2, varDsc2->TypeGet());
9623     lcl2->gtLsraInfo.isLsraAdded   = true;
9624     lcl2->gtLsraInfo.isLocalDefUse = false;
9625     lcl2->gtRegNum                 = reg2;
9626
9627     GenTreePtr swap                = compiler->gtNewOperNode(GT_SWAP, TYP_VOID, lcl1, lcl2);
9628     swap->gtLsraInfo.isLsraAdded   = true;
9629     swap->gtLsraInfo.isLocalDefUse = false;
9630     swap->gtRegNum                 = REG_NA;
9631
9632     lcl1->gtNext = lcl2;
9633     lcl2->gtPrev = lcl1;
9634     lcl2->gtNext = swap;
9635     swap->gtPrev = lcl2;
9636
9637     LIR::Range  swapRange  = LIR::SeqTree(compiler, swap);
9638     LIR::Range& blockRange = LIR::AsRange(block);
9639
9640     if (insertionPoint != nullptr)
9641     {
9642         blockRange.InsertBefore(insertionPoint, std::move(swapRange));
9643     }
9644     else
9645     {
9646         // Put the copy at the bottom
9647         // If there's a branch, make an embedded statement that executes just prior to the branch
9648         if (block->bbJumpKind == BBJ_COND || block->bbJumpKind == BBJ_SWITCH)
9649         {
9650             noway_assert(!blockRange.IsEmpty());
9651
9652             GenTree* branch = blockRange.LastNode();
9653             assert(branch->OperIsConditionalJump() || branch->OperGet() == GT_SWITCH_TABLE ||
9654                    branch->OperGet() == GT_SWITCH);
9655
9656             blockRange.InsertBefore(branch, std::move(swapRange));
9657         }
9658         else
9659         {
9660             assert(block->bbJumpKind == BBJ_NONE || block->bbJumpKind == BBJ_ALWAYS);
9661             blockRange.InsertAtEnd(std::move(swapRange));
9662         }
9663     }
9664 }
9665
9666 //------------------------------------------------------------------------
9667 // getTempRegForResolution: Get a free register to use for resolution code.
9668 //
9669 // Arguments:
9670 //    fromBlock - The "from" block on the edge being resolved.
9671 //    toBlock   - The "to"block on the edge
9672 //    type      - the type of register required
9673 //
9674 // Return Value:
9675 //    Returns a register that is free on the given edge, or REG_NA if none is available.
9676 //
9677 // Notes:
9678 //    It is up to the caller to check the return value, and to determine whether a register is
9679 //    available, and to handle that case appropriately.
9680 //    It is also up to the caller to cache the return value, as this is not cheap to compute.
9681
9682 regNumber LinearScan::getTempRegForResolution(BasicBlock* fromBlock, BasicBlock* toBlock, var_types type)
9683 {
9684     // TODO-Throughput: This would be much more efficient if we add RegToVarMaps instead of VarToRegMaps
9685     // and they would be more space-efficient as well.
9686     VarToRegMap fromVarToRegMap = getOutVarToRegMap(fromBlock->bbNum);
9687     VarToRegMap toVarToRegMap   = getInVarToRegMap(toBlock->bbNum);
9688
9689     regMaskTP freeRegs = allRegs(type);
9690 #ifdef DEBUG
9691     if (getStressLimitRegs() == LSRA_LIMIT_SMALL_SET)
9692     {
9693         return REG_NA;
9694     }
9695 #endif // DEBUG
9696     INDEBUG(freeRegs = stressLimitRegs(nullptr, freeRegs));
9697
9698     // We are only interested in the variables that are live-in to the "to" block.
9699     VarSetOps::Iter iter(compiler, toBlock->bbLiveIn);
9700     unsigned        varIndex = 0;
9701     while (iter.NextElem(&varIndex) && freeRegs != RBM_NONE)
9702     {
9703         regNumber fromReg = getVarReg(fromVarToRegMap, varIndex);
9704         regNumber toReg   = getVarReg(toVarToRegMap, varIndex);
9705         assert(fromReg != REG_NA && toReg != REG_NA);
9706         if (fromReg != REG_STK)
9707         {
9708             freeRegs &= ~genRegMask(fromReg);
9709         }
9710         if (toReg != REG_STK)
9711         {
9712             freeRegs &= ~genRegMask(toReg);
9713         }
9714     }
9715     if (freeRegs == RBM_NONE)
9716     {
9717         return REG_NA;
9718     }
9719     else
9720     {
9721         regNumber tempReg = genRegNumFromMask(genFindLowestBit(freeRegs));
9722         return tempReg;
9723     }
9724 }
9725
9726 //------------------------------------------------------------------------
9727 // addResolution: Add a resolution move of the given interval
9728 //
9729 // Arguments:
9730 //    block          - the BasicBlock into which the move will be inserted.
9731 //    insertionPoint - the instruction before which to insert the move
9732 //    interval       - the interval of the var to be moved
9733 //    toReg          - the register to which the var is moving
9734 //    fromReg        - the register from which the var is moving
9735 //
9736 // Return Value:
9737 //    None.
9738 //
9739 // Notes:
9740 //    For joins, we insert at the bottom (indicated by an insertionPoint
9741 //    of nullptr), while for splits we insert at the top.
9742 //    This is because for joins 'block' is a pred of the join, while for splits it is a succ.
9743 //    For critical edges, this function may be called twice - once to move from
9744 //    the source (fromReg), if any, to the stack, in which case toReg will be
9745 //    REG_STK, and we insert at the bottom (leave insertionPoint as nullptr).
9746 //    The next time, we want to move from the stack to the destination (toReg),
9747 //    in which case fromReg will be REG_STK, and we insert at the top.
9748
9749 void LinearScan::addResolution(
9750     BasicBlock* block, GenTreePtr insertionPoint, Interval* interval, regNumber toReg, regNumber fromReg)
9751 {
9752 #ifdef DEBUG
9753     const char* insertionPointString = "top";
9754 #endif // DEBUG
9755     if (insertionPoint == nullptr)
9756     {
9757 #ifdef DEBUG
9758         insertionPointString = "bottom";
9759 #endif // DEBUG
9760     }
9761
9762     JITDUMP("   BB%02u %s: move V%02u from ", block->bbNum, insertionPointString, interval->varNum);
9763     JITDUMP("%s to %s", getRegName(fromReg), getRegName(toReg));
9764
9765     insertMove(block, insertionPoint, interval->varNum, fromReg, toReg);
9766     if (fromReg == REG_STK || toReg == REG_STK)
9767     {
9768         assert(interval->isSpilled);
9769     }
9770     else
9771     {
9772         // We should have already marked this as spilled or split.
9773         assert((interval->isSpilled) || (interval->isSplit));
9774     }
9775
9776     INTRACK_STATS(updateLsraStat(LSRA_STAT_RESOLUTION_MOV, block->bbNum));
9777 }
9778
9779 //------------------------------------------------------------------------
9780 // handleOutgoingCriticalEdges: Performs the necessary resolution on all critical edges that feed out of 'block'
9781 //
9782 // Arguments:
9783 //    block     - the block with outgoing critical edges.
9784 //
9785 // Return Value:
9786 //    None..
9787 //
9788 // Notes:
9789 //    For all outgoing critical edges (i.e. any successor of this block which is
9790 //    a join edge), if there are any conflicts, split the edge by adding a new block,
9791 //    and generate the resolution code into that block.
9792
9793 void LinearScan::handleOutgoingCriticalEdges(BasicBlock* block)
9794 {
9795     VARSET_TP outResolutionSet(VarSetOps::Intersection(compiler, block->bbLiveOut, resolutionCandidateVars));
9796     if (VarSetOps::IsEmpty(compiler, outResolutionSet))
9797     {
9798         return;
9799     }
9800     VARSET_TP sameResolutionSet(VarSetOps::MakeEmpty(compiler));
9801     VARSET_TP sameLivePathsSet(VarSetOps::MakeEmpty(compiler));
9802     VARSET_TP singleTargetSet(VarSetOps::MakeEmpty(compiler));
9803     VARSET_TP diffResolutionSet(VarSetOps::MakeEmpty(compiler));
9804
9805     // Get the outVarToRegMap for this block
9806     VarToRegMap outVarToRegMap = getOutVarToRegMap(block->bbNum);
9807     unsigned    succCount      = block->NumSucc(compiler);
9808     assert(succCount > 1);
9809     VarToRegMap firstSuccInVarToRegMap = nullptr;
9810     BasicBlock* firstSucc              = nullptr;
9811
9812     // First, determine the live regs at the end of this block so that we know what regs are
9813     // available to copy into.
9814     // Note that for this purpose we use the full live-out set, because we must ensure that
9815     // even the registers that remain the same across the edge are preserved correctly.
9816     regMaskTP       liveOutRegs = RBM_NONE;
9817     VarSetOps::Iter liveOutIter(compiler, block->bbLiveOut);
9818     unsigned        liveOutVarIndex = 0;
9819     while (liveOutIter.NextElem(&liveOutVarIndex))
9820     {
9821         regNumber fromReg = getVarReg(outVarToRegMap, liveOutVarIndex);
9822         if (fromReg != REG_STK)
9823         {
9824             liveOutRegs |= genRegMask(fromReg);
9825         }
9826     }
9827
9828     // Next, if this blocks ends with a switch table, we have to make sure not to copy
9829     // into the registers that it uses.
9830     regMaskTP switchRegs = RBM_NONE;
9831     if (block->bbJumpKind == BBJ_SWITCH)
9832     {
9833         // At this point, Lowering has transformed any non-switch-table blocks into
9834         // cascading ifs.
9835         GenTree* switchTable = LIR::AsRange(block).LastNode();
9836         assert(switchTable != nullptr && switchTable->OperGet() == GT_SWITCH_TABLE);
9837
9838         switchRegs   = switchTable->gtRsvdRegs;
9839         GenTree* op1 = switchTable->gtGetOp1();
9840         GenTree* op2 = switchTable->gtGetOp2();
9841         noway_assert(op1 != nullptr && op2 != nullptr);
9842         assert(op1->gtRegNum != REG_NA && op2->gtRegNum != REG_NA);
9843         switchRegs |= genRegMask(op1->gtRegNum);
9844         switchRegs |= genRegMask(op2->gtRegNum);
9845     }
9846
9847     VarToRegMap sameVarToRegMap = sharedCriticalVarToRegMap;
9848     regMaskTP   sameWriteRegs   = RBM_NONE;
9849     regMaskTP   diffReadRegs    = RBM_NONE;
9850
9851     // For each var that may require resolution, classify them as:
9852     // - in the same register at the end of this block and at each target (no resolution needed)
9853     // - in different registers at different targets (resolve separately):
9854     //     diffResolutionSet
9855     // - in the same register at each target at which it's live, but different from the end of
9856     //   this block.  We may be able to resolve these as if it is "join", but only if they do not
9857     //   write to any registers that are read by those in the diffResolutionSet:
9858     //     sameResolutionSet
9859
9860     VarSetOps::Iter outResolutionSetIter(compiler, outResolutionSet);
9861     unsigned        outResolutionSetVarIndex = 0;
9862     while (outResolutionSetIter.NextElem(&outResolutionSetVarIndex))
9863     {
9864         regNumber fromReg             = getVarReg(outVarToRegMap, outResolutionSetVarIndex);
9865         bool      isMatch             = true;
9866         bool      isSame              = false;
9867         bool      maybeSingleTarget   = false;
9868         bool      maybeSameLivePaths  = false;
9869         bool      liveOnlyAtSplitEdge = true;
9870         regNumber sameToReg           = REG_NA;
9871         for (unsigned succIndex = 0; succIndex < succCount; succIndex++)
9872         {
9873             BasicBlock* succBlock = block->GetSucc(succIndex, compiler);
9874             if (!VarSetOps::IsMember(compiler, succBlock->bbLiveIn, outResolutionSetVarIndex))
9875             {
9876                 maybeSameLivePaths = true;
9877                 continue;
9878             }
9879             else if (liveOnlyAtSplitEdge)
9880             {
9881                 // Is the var live only at those target blocks which are connected by a split edge to this block
9882                 liveOnlyAtSplitEdge = ((succBlock->bbPreds->flNext == nullptr) && (succBlock != compiler->fgFirstBB));
9883             }
9884
9885             regNumber toReg = getVarReg(getInVarToRegMap(succBlock->bbNum), outResolutionSetVarIndex);
9886             if (sameToReg == REG_NA)
9887             {
9888                 sameToReg = toReg;
9889                 continue;
9890             }
9891             if (toReg == sameToReg)
9892             {
9893                 continue;
9894             }
9895             sameToReg = REG_NA;
9896             break;
9897         }
9898
9899         // Check for the cases where we can't write to a register.
9900         // We only need to check for these cases if sameToReg is an actual register (not REG_STK).
9901         if (sameToReg != REG_NA && sameToReg != REG_STK)
9902         {
9903             // If there's a path on which this var isn't live, it may use the original value in sameToReg.
9904             // In this case, sameToReg will be in the liveOutRegs of this block.
9905             // Similarly, if sameToReg is in sameWriteRegs, it has already been used (i.e. for a lclVar that's
9906             // live only at another target), and we can't copy another lclVar into that reg in this block.
9907             regMaskTP sameToRegMask = genRegMask(sameToReg);
9908             if (maybeSameLivePaths &&
9909                 (((sameToRegMask & liveOutRegs) != RBM_NONE) || ((sameToRegMask & sameWriteRegs) != RBM_NONE)))
9910             {
9911                 sameToReg = REG_NA;
9912             }
9913             // If this register is used by a switch table at the end of the block, we can't do the copy
9914             // in this block (since we can't insert it after the switch).
9915             if ((sameToRegMask & switchRegs) != RBM_NONE)
9916             {
9917                 sameToReg = REG_NA;
9918             }
9919
9920             // If the var is live only at those blocks connected by a split edge and not live-in at some of the
9921             // target blocks, we will resolve it the same way as if it were in diffResolutionSet and resolution
9922             // will be deferred to the handling of split edges, which means copy will only be at those target(s).
9923             //
9924             // Another way to achieve similar resolution for vars live only at split edges is by removing them
9925             // from consideration up-front but it requires that we traverse those edges anyway to account for
9926             // the registers that must note be overwritten.
9927             if (liveOnlyAtSplitEdge && maybeSameLivePaths)
9928             {
9929                 sameToReg = REG_NA;
9930             }
9931         }
9932
9933         if (sameToReg == REG_NA)
9934         {
9935             VarSetOps::AddElemD(compiler, diffResolutionSet, outResolutionSetVarIndex);
9936             if (fromReg != REG_STK)
9937             {
9938                 diffReadRegs |= genRegMask(fromReg);
9939             }
9940         }
9941         else if (sameToReg != fromReg)
9942         {
9943             VarSetOps::AddElemD(compiler, sameResolutionSet, outResolutionSetVarIndex);
9944             setVarReg(sameVarToRegMap, outResolutionSetVarIndex, sameToReg);
9945             if (sameToReg != REG_STK)
9946             {
9947                 sameWriteRegs |= genRegMask(sameToReg);
9948             }
9949         }
9950     }
9951
9952     if (!VarSetOps::IsEmpty(compiler, sameResolutionSet))
9953     {
9954         if ((sameWriteRegs & diffReadRegs) != RBM_NONE)
9955         {
9956             // We cannot split the "same" and "diff" regs if the "same" set writes registers
9957             // that must be read by the "diff" set.  (Note that when these are done as a "batch"
9958             // we carefully order them to ensure all the input regs are read before they are
9959             // overwritten.)
9960             VarSetOps::UnionD(compiler, diffResolutionSet, sameResolutionSet);
9961             VarSetOps::ClearD(compiler, sameResolutionSet);
9962         }
9963         else
9964         {
9965             // For any vars in the sameResolutionSet, we can simply add the move at the end of "block".
9966             resolveEdge(block, nullptr, ResolveSharedCritical, sameResolutionSet);
9967         }
9968     }
9969     if (!VarSetOps::IsEmpty(compiler, diffResolutionSet))
9970     {
9971         for (unsigned succIndex = 0; succIndex < succCount; succIndex++)
9972         {
9973             BasicBlock* succBlock = block->GetSucc(succIndex, compiler);
9974
9975             // Any "diffResolutionSet" resolution for a block with no other predecessors will be handled later
9976             // as split resolution.
9977             if ((succBlock->bbPreds->flNext == nullptr) && (succBlock != compiler->fgFirstBB))
9978             {
9979                 continue;
9980             }
9981
9982             // Now collect the resolution set for just this edge, if any.
9983             // Check only the vars in diffResolutionSet that are live-in to this successor.
9984             bool        needsResolution   = false;
9985             VarToRegMap succInVarToRegMap = getInVarToRegMap(succBlock->bbNum);
9986             VARSET_TP   edgeResolutionSet(VarSetOps::Intersection(compiler, diffResolutionSet, succBlock->bbLiveIn));
9987             VarSetOps::Iter iter(compiler, edgeResolutionSet);
9988             unsigned        varIndex = 0;
9989             while (iter.NextElem(&varIndex))
9990             {
9991                 regNumber fromReg = getVarReg(outVarToRegMap, varIndex);
9992                 regNumber toReg   = getVarReg(succInVarToRegMap, varIndex);
9993
9994                 if (fromReg == toReg)
9995                 {
9996                     VarSetOps::RemoveElemD(compiler, edgeResolutionSet, varIndex);
9997                 }
9998             }
9999             if (!VarSetOps::IsEmpty(compiler, edgeResolutionSet))
10000             {
10001                 resolveEdge(block, succBlock, ResolveCritical, edgeResolutionSet);
10002             }
10003         }
10004     }
10005 }
10006
10007 //------------------------------------------------------------------------
10008 // resolveEdges: Perform resolution across basic block edges
10009 //
10010 // Arguments:
10011 //    None.
10012 //
10013 // Return Value:
10014 //    None.
10015 //
10016 // Notes:
10017 //    Traverse the basic blocks.
10018 //    - If this block has a single predecessor that is not the immediately
10019 //      preceding block, perform any needed 'split' resolution at the beginning of this block
10020 //    - Otherwise if this block has critical incoming edges, handle them.
10021 //    - If this block has a single successor that has multiple predecesors, perform any needed
10022 //      'join' resolution at the end of this block.
10023 //    Note that a block may have both 'split' or 'critical' incoming edge(s) and 'join' outgoing
10024 //    edges.
10025
10026 void LinearScan::resolveEdges()
10027 {
10028     JITDUMP("RESOLVING EDGES\n");
10029
10030     // The resolutionCandidateVars set was initialized with all the lclVars that are live-in to
10031     // any block. We now intersect that set with any lclVars that ever spilled or split.
10032     // If there are no candidates for resoultion, simply return.
10033
10034     VarSetOps::IntersectionD(compiler, resolutionCandidateVars, splitOrSpilledVars);
10035     if (VarSetOps::IsEmpty(compiler, resolutionCandidateVars))
10036     {
10037         return;
10038     }
10039
10040     BasicBlock *block, *prevBlock = nullptr;
10041
10042     // Handle all the critical edges first.
10043     // We will try to avoid resolution across critical edges in cases where all the critical-edge
10044     // targets of a block have the same home.  We will then split the edges only for the
10045     // remaining mismatches.  We visit the out-edges, as that allows us to share the moves that are
10046     // common among allt he targets.
10047
10048     if (hasCriticalEdges)
10049     {
10050         foreach_block(compiler, block)
10051         {
10052             if (block->bbNum > bbNumMaxBeforeResolution)
10053             {
10054                 // This is a new block added during resolution - we don't need to visit these now.
10055                 continue;
10056             }
10057             if (blockInfo[block->bbNum].hasCriticalOutEdge)
10058             {
10059                 handleOutgoingCriticalEdges(block);
10060             }
10061             prevBlock = block;
10062         }
10063     }
10064
10065     prevBlock = nullptr;
10066     foreach_block(compiler, block)
10067     {
10068         if (block->bbNum > bbNumMaxBeforeResolution)
10069         {
10070             // This is a new block added during resolution - we don't need to visit these now.
10071             continue;
10072         }
10073
10074         unsigned    succCount       = block->NumSucc(compiler);
10075         flowList*   preds           = block->bbPreds;
10076         BasicBlock* uniquePredBlock = block->GetUniquePred(compiler);
10077
10078         // First, if this block has a single predecessor,
10079         // we may need resolution at the beginning of this block.
10080         // This may be true even if it's the block we used for starting locations,
10081         // if a variable was spilled.
10082         VARSET_TP inResolutionSet(VarSetOps::Intersection(compiler, block->bbLiveIn, resolutionCandidateVars));
10083         if (!VarSetOps::IsEmpty(compiler, inResolutionSet))
10084         {
10085             if (uniquePredBlock != nullptr)
10086             {
10087                 // We may have split edges during critical edge resolution, and in the process split
10088                 // a non-critical edge as well.
10089                 // It is unlikely that we would ever have more than one of these in sequence (indeed,
10090                 // I don't think it's possible), but there's no need to assume that it can't.
10091                 while (uniquePredBlock->bbNum > bbNumMaxBeforeResolution)
10092                 {
10093                     uniquePredBlock = uniquePredBlock->GetUniquePred(compiler);
10094                     noway_assert(uniquePredBlock != nullptr);
10095                 }
10096                 resolveEdge(uniquePredBlock, block, ResolveSplit, inResolutionSet);
10097             }
10098         }
10099
10100         // Finally, if this block has a single successor:
10101         //  - and that has at least one other predecessor (otherwise we will do the resolution at the
10102         //    top of the successor),
10103         //  - and that is not the target of a critical edge (otherwise we've already handled it)
10104         // we may need resolution at the end of this block.
10105
10106         if (succCount == 1)
10107         {
10108             BasicBlock* succBlock = block->GetSucc(0, compiler);
10109             if (succBlock->GetUniquePred(compiler) == nullptr)
10110             {
10111                 VARSET_TP outResolutionSet(
10112                     VarSetOps::Intersection(compiler, succBlock->bbLiveIn, resolutionCandidateVars));
10113                 if (!VarSetOps::IsEmpty(compiler, outResolutionSet))
10114                 {
10115                     resolveEdge(block, succBlock, ResolveJoin, outResolutionSet);
10116                 }
10117             }
10118         }
10119     }
10120
10121     // Now, fixup the mapping for any blocks that were adding for edge splitting.
10122     // See the comment prior to the call to fgSplitEdge() in resolveEdge().
10123     // Note that we could fold this loop in with the checking code below, but that
10124     // would only improve the debug case, and would clutter up the code somewhat.
10125     if (compiler->fgBBNumMax > bbNumMaxBeforeResolution)
10126     {
10127         foreach_block(compiler, block)
10128         {
10129             if (block->bbNum > bbNumMaxBeforeResolution)
10130             {
10131                 // There may be multiple blocks inserted when we split.  But we must always have exactly
10132                 // one path (i.e. all blocks must be single-successor and single-predecessor),
10133                 // and only one block along the path may be non-empty.
10134                 // Note that we may have a newly-inserted block that is empty, but which connects
10135                 // two non-resolution blocks. This happens when an edge is split that requires it.
10136
10137                 BasicBlock* succBlock = block;
10138                 do
10139                 {
10140                     succBlock = succBlock->GetUniqueSucc();
10141                     noway_assert(succBlock != nullptr);
10142                 } while ((succBlock->bbNum > bbNumMaxBeforeResolution) && succBlock->isEmpty());
10143
10144                 BasicBlock* predBlock = block;
10145                 do
10146                 {
10147                     predBlock = predBlock->GetUniquePred(compiler);
10148                     noway_assert(predBlock != nullptr);
10149                 } while ((predBlock->bbNum > bbNumMaxBeforeResolution) && predBlock->isEmpty());
10150
10151                 unsigned succBBNum = succBlock->bbNum;
10152                 unsigned predBBNum = predBlock->bbNum;
10153                 if (block->isEmpty())
10154                 {
10155                     // For the case of the empty block, find the non-resolution block (succ or pred).
10156                     if (predBBNum > bbNumMaxBeforeResolution)
10157                     {
10158                         assert(succBBNum <= bbNumMaxBeforeResolution);
10159                         predBBNum = 0;
10160                     }
10161                     else
10162                     {
10163                         succBBNum = 0;
10164                     }
10165                 }
10166                 else
10167                 {
10168                     assert((succBBNum <= bbNumMaxBeforeResolution) && (predBBNum <= bbNumMaxBeforeResolution));
10169                 }
10170                 SplitEdgeInfo info = {predBBNum, succBBNum};
10171                 getSplitBBNumToTargetBBNumMap()->Set(block->bbNum, info);
10172             }
10173         }
10174     }
10175
10176 #ifdef DEBUG
10177     // Make sure the varToRegMaps match up on all edges.
10178     bool foundMismatch = false;
10179     foreach_block(compiler, block)
10180     {
10181         if (block->isEmpty() && block->bbNum > bbNumMaxBeforeResolution)
10182         {
10183             continue;
10184         }
10185         VarToRegMap toVarToRegMap = getInVarToRegMap(block->bbNum);
10186         for (flowList* pred = block->bbPreds; pred != nullptr; pred = pred->flNext)
10187         {
10188             BasicBlock*     predBlock       = pred->flBlock;
10189             VarToRegMap     fromVarToRegMap = getOutVarToRegMap(predBlock->bbNum);
10190             VarSetOps::Iter iter(compiler, block->bbLiveIn);
10191             unsigned        varIndex = 0;
10192             while (iter.NextElem(&varIndex))
10193             {
10194                 regNumber fromReg = getVarReg(fromVarToRegMap, varIndex);
10195                 regNumber toReg   = getVarReg(toVarToRegMap, varIndex);
10196                 if (fromReg != toReg)
10197                 {
10198                     if (!foundMismatch)
10199                     {
10200                         foundMismatch = true;
10201                         printf("Found mismatched var locations after resolution!\n");
10202                     }
10203                     unsigned varNum = compiler->lvaTrackedToVarNum[varIndex];
10204                     printf(" V%02u: BB%02u to BB%02u: %s to %s\n", varNum, predBlock->bbNum, block->bbNum,
10205                            getRegName(fromReg), getRegName(toReg));
10206                 }
10207             }
10208         }
10209     }
10210     assert(!foundMismatch);
10211 #endif
10212     JITDUMP("\n");
10213 }
10214
10215 //------------------------------------------------------------------------
10216 // resolveEdge: Perform the specified type of resolution between two blocks.
10217 //
10218 // Arguments:
10219 //    fromBlock     - the block from which the edge originates
10220 //    toBlock       - the block at which the edge terminates
10221 //    resolveType   - the type of resolution to be performed
10222 //    liveSet       - the set of tracked lclVar indices which may require resolution
10223 //
10224 // Return Value:
10225 //    None.
10226 //
10227 // Assumptions:
10228 //    The caller must have performed the analysis to determine the type of the edge.
10229 //
10230 // Notes:
10231 //    This method emits the correctly ordered moves necessary to place variables in the
10232 //    correct registers across a Split, Join or Critical edge.
10233 //    In order to avoid overwriting register values before they have been moved to their
10234 //    new home (register/stack), it first does the register-to-stack moves (to free those
10235 //    registers), then the register to register moves, ensuring that the target register
10236 //    is free before the move, and then finally the stack to register moves.
10237
10238 void LinearScan::resolveEdge(BasicBlock*      fromBlock,
10239                              BasicBlock*      toBlock,
10240                              ResolveType      resolveType,
10241                              VARSET_VALARG_TP liveSet)
10242 {
10243     VarToRegMap fromVarToRegMap = getOutVarToRegMap(fromBlock->bbNum);
10244     VarToRegMap toVarToRegMap;
10245     if (resolveType == ResolveSharedCritical)
10246     {
10247         toVarToRegMap = sharedCriticalVarToRegMap;
10248     }
10249     else
10250     {
10251         toVarToRegMap = getInVarToRegMap(toBlock->bbNum);
10252     }
10253
10254     // The block to which we add the resolution moves depends on the resolveType
10255     BasicBlock* block;
10256     switch (resolveType)
10257     {
10258         case ResolveJoin:
10259         case ResolveSharedCritical:
10260             block = fromBlock;
10261             break;
10262         case ResolveSplit:
10263             block = toBlock;
10264             break;
10265         case ResolveCritical:
10266             // fgSplitEdge may add one or two BasicBlocks.  It returns the block that splits
10267             // the edge from 'fromBlock' and 'toBlock', but if it inserts that block right after
10268             // a block with a fall-through it will have to create another block to handle that edge.
10269             // These new blocks can be mapped to existing blocks in order to correctly handle
10270             // the calls to recordVarLocationsAtStartOfBB() from codegen.  That mapping is handled
10271             // in resolveEdges(), after all the edge resolution has been done (by calling this
10272             // method for each edge).
10273             block = compiler->fgSplitEdge(fromBlock, toBlock);
10274
10275             // Split edges are counted against fromBlock.
10276             INTRACK_STATS(updateLsraStat(LSRA_STAT_SPLIT_EDGE, fromBlock->bbNum));
10277             break;
10278         default:
10279             unreached();
10280             break;
10281     }
10282
10283 #ifndef _TARGET_XARCH_
10284     // We record tempregs for beginning and end of each block.
10285     // For amd64/x86 we only need a tempReg for float - we'll use xchg for int.
10286     // TODO-Throughput: It would be better to determine the tempRegs on demand, but the code below
10287     // modifies the varToRegMaps so we don't have all the correct registers at the time
10288     // we need to get the tempReg.
10289     regNumber tempRegInt =
10290         (resolveType == ResolveSharedCritical) ? REG_NA : getTempRegForResolution(fromBlock, toBlock, TYP_INT);
10291 #endif // !_TARGET_XARCH_
10292     regNumber tempRegFlt = REG_NA;
10293     if ((compiler->compFloatingPointUsed) && (resolveType != ResolveSharedCritical))
10294     {
10295
10296 #ifdef _TARGET_ARM_
10297         // Let's try to reserve a double register for TYP_FLOAT and TYP_DOUBLE
10298         tempRegFlt = getTempRegForResolution(fromBlock, toBlock, TYP_DOUBLE);
10299         if (tempRegFlt == REG_NA)
10300         {
10301             // If fails, try to reserve a float register for TYP_FLOAT
10302             tempRegFlt = getTempRegForResolution(fromBlock, toBlock, TYP_FLOAT);
10303         }
10304 #else
10305         tempRegFlt = getTempRegForResolution(fromBlock, toBlock, TYP_FLOAT);
10306 #endif
10307     }
10308
10309     regMaskTP targetRegsToDo      = RBM_NONE;
10310     regMaskTP targetRegsReady     = RBM_NONE;
10311     regMaskTP targetRegsFromStack = RBM_NONE;
10312
10313     // The following arrays capture the location of the registers as they are moved:
10314     // - location[reg] gives the current location of the var that was originally in 'reg'.
10315     //   (Note that a var may be moved more than once.)
10316     // - source[reg] gives the original location of the var that needs to be moved to 'reg'.
10317     // For example, if a var is in rax and needs to be moved to rsi, then we would start with:
10318     //   location[rax] == rax
10319     //   source[rsi] == rax     -- this doesn't change
10320     // Then, if for some reason we need to move it temporary to rbx, we would have:
10321     //   location[rax] == rbx
10322     // Once we have completed the move, we will have:
10323     //   location[rax] == REG_NA
10324     // This indicates that the var originally in rax is now in its target register.
10325
10326     regNumberSmall location[REG_COUNT];
10327     C_ASSERT(sizeof(char) == sizeof(regNumberSmall)); // for memset to work
10328     memset(location, REG_NA, REG_COUNT);
10329     regNumberSmall source[REG_COUNT];
10330     memset(source, REG_NA, REG_COUNT);
10331
10332     // What interval is this register associated with?
10333     // (associated with incoming reg)
10334     Interval* sourceIntervals[REG_COUNT];
10335     memset(&sourceIntervals, 0, sizeof(sourceIntervals));
10336
10337     // Intervals for vars that need to be loaded from the stack
10338     Interval* stackToRegIntervals[REG_COUNT];
10339     memset(&stackToRegIntervals, 0, sizeof(stackToRegIntervals));
10340
10341     // Get the starting insertion point for the "to" resolution
10342     GenTreePtr insertionPoint = nullptr;
10343     if (resolveType == ResolveSplit || resolveType == ResolveCritical)
10344     {
10345         insertionPoint = LIR::AsRange(block).FirstNonPhiNode();
10346     }
10347
10348     // First:
10349     //   - Perform all moves from reg to stack (no ordering needed on these)
10350     //   - For reg to reg moves, record the current location, associating their
10351     //     source location with the target register they need to go into
10352     //   - For stack to reg moves (done last, no ordering needed between them)
10353     //     record the interval associated with the target reg
10354     // TODO-Throughput: We should be looping over the liveIn and liveOut registers, since
10355     // that will scale better than the live variables
10356
10357     VarSetOps::Iter iter(compiler, liveSet);
10358     unsigned        varIndex = 0;
10359     while (iter.NextElem(&varIndex))
10360     {
10361         regNumber fromReg = getVarReg(fromVarToRegMap, varIndex);
10362         regNumber toReg   = getVarReg(toVarToRegMap, varIndex);
10363         if (fromReg == toReg)
10364         {
10365             continue;
10366         }
10367
10368         // For Critical edges, the location will not change on either side of the edge,
10369         // since we'll add a new block to do the move.
10370         if (resolveType == ResolveSplit)
10371         {
10372             setVarReg(toVarToRegMap, varIndex, fromReg);
10373         }
10374         else if (resolveType == ResolveJoin || resolveType == ResolveSharedCritical)
10375         {
10376             setVarReg(fromVarToRegMap, varIndex, toReg);
10377         }
10378
10379         assert(fromReg < UCHAR_MAX && toReg < UCHAR_MAX);
10380
10381         Interval* interval = getIntervalForLocalVar(varIndex);
10382
10383         if (fromReg == REG_STK)
10384         {
10385             stackToRegIntervals[toReg] = interval;
10386             targetRegsFromStack |= genRegMask(toReg);
10387         }
10388         else if (toReg == REG_STK)
10389         {
10390             // Do the reg to stack moves now
10391             addResolution(block, insertionPoint, interval, REG_STK, fromReg);
10392             JITDUMP(" (%s)\n", resolveTypeName[resolveType]);
10393         }
10394         else
10395         {
10396             location[fromReg]        = (regNumberSmall)fromReg;
10397             source[toReg]            = (regNumberSmall)fromReg;
10398             sourceIntervals[fromReg] = interval;
10399             targetRegsToDo |= genRegMask(toReg);
10400         }
10401     }
10402
10403     // REGISTER to REGISTER MOVES
10404
10405     // First, find all the ones that are ready to move now
10406     regMaskTP targetCandidates = targetRegsToDo;
10407     while (targetCandidates != RBM_NONE)
10408     {
10409         regMaskTP targetRegMask = genFindLowestBit(targetCandidates);
10410         targetCandidates &= ~targetRegMask;
10411         regNumber targetReg = genRegNumFromMask(targetRegMask);
10412         if (location[targetReg] == REG_NA)
10413         {
10414             targetRegsReady |= targetRegMask;
10415         }
10416     }
10417
10418     // Perform reg to reg moves
10419     while (targetRegsToDo != RBM_NONE)
10420     {
10421         while (targetRegsReady != RBM_NONE)
10422         {
10423             regMaskTP targetRegMask = genFindLowestBit(targetRegsReady);
10424             targetRegsToDo &= ~targetRegMask;
10425             targetRegsReady &= ~targetRegMask;
10426             regNumber targetReg = genRegNumFromMask(targetRegMask);
10427             assert(location[targetReg] != targetReg);
10428             regNumber sourceReg = (regNumber)source[targetReg];
10429             regNumber fromReg   = (regNumber)location[sourceReg];
10430             assert(fromReg < UCHAR_MAX && sourceReg < UCHAR_MAX);
10431             Interval* interval = sourceIntervals[sourceReg];
10432             assert(interval != nullptr);
10433             addResolution(block, insertionPoint, interval, targetReg, fromReg);
10434             JITDUMP(" (%s)\n", resolveTypeName[resolveType]);
10435             sourceIntervals[sourceReg] = nullptr;
10436             location[sourceReg]        = REG_NA;
10437
10438             // Do we have a free targetReg?
10439             if (fromReg == sourceReg && source[fromReg] != REG_NA)
10440             {
10441                 regMaskTP fromRegMask = genRegMask(fromReg);
10442                 targetRegsReady |= fromRegMask;
10443             }
10444         }
10445         if (targetRegsToDo != RBM_NONE)
10446         {
10447             regMaskTP targetRegMask = genFindLowestBit(targetRegsToDo);
10448             regNumber targetReg     = genRegNumFromMask(targetRegMask);
10449
10450             // Is it already there due to other moves?
10451             // If not, move it to the temp reg, OR swap it with another register
10452             regNumber sourceReg = (regNumber)source[targetReg];
10453             regNumber fromReg   = (regNumber)location[sourceReg];
10454             if (targetReg == fromReg)
10455             {
10456                 targetRegsToDo &= ~targetRegMask;
10457             }
10458             else
10459             {
10460                 regNumber tempReg = REG_NA;
10461                 bool      useSwap = false;
10462                 if (emitter::isFloatReg(targetReg))
10463                 {
10464 #ifdef _TARGET_ARM_
10465                     if (sourceIntervals[fromReg]->registerType == TYP_DOUBLE)
10466                     {
10467                         // ARM32 requires a double temp register for TYP_DOUBLE.
10468                         // We tried to reserve a double temp register first, but sometimes we can't.
10469                         tempReg = genIsValidDoubleReg(tempRegFlt) ? tempRegFlt : REG_NA;
10470                     }
10471                     else
10472 #endif // _TARGET_ARM_
10473                         tempReg = tempRegFlt;
10474                 }
10475 #ifdef _TARGET_XARCH_
10476                 else
10477                 {
10478                     useSwap = true;
10479                 }
10480 #else // !_TARGET_XARCH_
10481
10482                 else
10483                 {
10484                     tempReg = tempRegInt;
10485                 }
10486
10487 #endif // !_TARGET_XARCH_
10488                 if (useSwap || tempReg == REG_NA)
10489                 {
10490                     // First, we have to figure out the destination register for what's currently in fromReg,
10491                     // so that we can find its sourceInterval.
10492                     regNumber otherTargetReg = REG_NA;
10493
10494                     // By chance, is fromReg going where it belongs?
10495                     if (location[source[fromReg]] == targetReg)
10496                     {
10497                         otherTargetReg = fromReg;
10498                         // If we can swap, we will be done with otherTargetReg as well.
10499                         // Otherwise, we'll spill it to the stack and reload it later.
10500                         if (useSwap)
10501                         {
10502                             regMaskTP fromRegMask = genRegMask(fromReg);
10503                             targetRegsToDo &= ~fromRegMask;
10504                         }
10505                     }
10506                     else
10507                     {
10508                         // Look at the remaining registers from targetRegsToDo (which we expect to be relatively
10509                         // small at this point) to find out what's currently in targetReg.
10510                         regMaskTP mask = targetRegsToDo;
10511                         while (mask != RBM_NONE && otherTargetReg == REG_NA)
10512                         {
10513                             regMaskTP nextRegMask = genFindLowestBit(mask);
10514                             regNumber nextReg     = genRegNumFromMask(nextRegMask);
10515                             mask &= ~nextRegMask;
10516                             if (location[source[nextReg]] == targetReg)
10517                             {
10518                                 otherTargetReg = nextReg;
10519                             }
10520                         }
10521                     }
10522                     assert(otherTargetReg != REG_NA);
10523
10524                     if (useSwap)
10525                     {
10526                         // Generate a "swap" of fromReg and targetReg
10527                         insertSwap(block, insertionPoint, sourceIntervals[source[otherTargetReg]]->varNum, targetReg,
10528                                    sourceIntervals[sourceReg]->varNum, fromReg);
10529                         location[sourceReg]              = REG_NA;
10530                         location[source[otherTargetReg]] = (regNumberSmall)fromReg;
10531
10532                         INTRACK_STATS(updateLsraStat(LSRA_STAT_RESOLUTION_MOV, block->bbNum));
10533                     }
10534                     else
10535                     {
10536                         // Spill "targetReg" to the stack and add its eventual target (otherTargetReg)
10537                         // to "targetRegsFromStack", which will be handled below.
10538                         // NOTE: This condition is very rare.  Setting COMPlus_JitStressRegs=0x203
10539                         // has been known to trigger it in JIT SH.
10540
10541                         // First, spill "otherInterval" from targetReg to the stack.
10542                         Interval* otherInterval = sourceIntervals[source[otherTargetReg]];
10543                         setIntervalAsSpilled(otherInterval);
10544                         addResolution(block, insertionPoint, otherInterval, REG_STK, targetReg);
10545                         JITDUMP(" (%s)\n", resolveTypeName[resolveType]);
10546                         location[source[otherTargetReg]] = REG_STK;
10547
10548                         // Now, move the interval that is going to targetReg, and add its "fromReg" to
10549                         // "targetRegsReady".
10550                         addResolution(block, insertionPoint, sourceIntervals[sourceReg], targetReg, fromReg);
10551                         JITDUMP(" (%s)\n", resolveTypeName[resolveType]);
10552                         location[sourceReg] = REG_NA;
10553                         targetRegsReady |= genRegMask(fromReg);
10554                     }
10555                     targetRegsToDo &= ~targetRegMask;
10556                 }
10557                 else
10558                 {
10559                     compiler->codeGen->regSet.rsSetRegsModified(genRegMask(tempReg) DEBUGARG(dumpTerse));
10560                     assert(sourceIntervals[targetReg] != nullptr);
10561                     addResolution(block, insertionPoint, sourceIntervals[targetReg], tempReg, targetReg);
10562                     JITDUMP(" (%s)\n", resolveTypeName[resolveType]);
10563                     location[targetReg] = (regNumberSmall)tempReg;
10564                     targetRegsReady |= targetRegMask;
10565                 }
10566             }
10567         }
10568     }
10569
10570     // Finally, perform stack to reg moves
10571     // All the target regs will be empty at this point
10572     while (targetRegsFromStack != RBM_NONE)
10573     {
10574         regMaskTP targetRegMask = genFindLowestBit(targetRegsFromStack);
10575         targetRegsFromStack &= ~targetRegMask;
10576         regNumber targetReg = genRegNumFromMask(targetRegMask);
10577
10578         Interval* interval = stackToRegIntervals[targetReg];
10579         assert(interval != nullptr);
10580
10581         addResolution(block, insertionPoint, interval, targetReg, REG_STK);
10582         JITDUMP(" (%s)\n", resolveTypeName[resolveType]);
10583     }
10584 }
10585
10586 void TreeNodeInfo::Initialize(LinearScan* lsra, GenTree* node, LsraLocation location)
10587 {
10588     regMaskTP dstCandidates;
10589
10590     // if there is a reg indicated on the tree node, use that for dstCandidates
10591     // the exception is the NOP, which sometimes show up around late args.
10592     // TODO-Cleanup: get rid of those NOPs.
10593     if (node->gtRegNum == REG_NA || node->gtOper == GT_NOP)
10594     {
10595 #ifdef ARM_SOFTFP
10596         if (node->OperGet() == GT_PUTARG_REG)
10597         {
10598             dstCandidates = lsra->allRegs(TYP_INT);
10599         }
10600         else
10601 #endif
10602         {
10603             dstCandidates = lsra->allRegs(node->TypeGet());
10604         }
10605     }
10606     else
10607     {
10608         dstCandidates = genRegMask(node->gtRegNum);
10609     }
10610
10611     internalIntCount    = 0;
10612     internalFloatCount  = 0;
10613     isLocalDefUse       = false;
10614     isLsraAdded         = false;
10615     definesAnyRegisters = false;
10616
10617     setDstCandidates(lsra, dstCandidates);
10618     srcCandsIndex = dstCandsIndex;
10619
10620     setInternalCandidates(lsra, lsra->allRegs(TYP_INT));
10621
10622     loc = location;
10623 #ifdef DEBUG
10624     isInitialized = true;
10625 #endif
10626
10627     assert(IsValid(lsra));
10628 }
10629
10630 regMaskTP TreeNodeInfo::getSrcCandidates(LinearScan* lsra)
10631 {
10632     return lsra->GetRegMaskForIndex(srcCandsIndex);
10633 }
10634
10635 void TreeNodeInfo::setSrcCandidates(LinearScan* lsra, regMaskTP mask)
10636 {
10637     LinearScan::RegMaskIndex i = lsra->GetIndexForRegMask(mask);
10638     assert(FitsIn<unsigned char>(i));
10639     srcCandsIndex = (unsigned char)i;
10640 }
10641
10642 regMaskTP TreeNodeInfo::getDstCandidates(LinearScan* lsra)
10643 {
10644     return lsra->GetRegMaskForIndex(dstCandsIndex);
10645 }
10646
10647 void TreeNodeInfo::setDstCandidates(LinearScan* lsra, regMaskTP mask)
10648 {
10649     LinearScan::RegMaskIndex i = lsra->GetIndexForRegMask(mask);
10650     assert(FitsIn<unsigned char>(i));
10651     dstCandsIndex = (unsigned char)i;
10652 }
10653
10654 regMaskTP TreeNodeInfo::getInternalCandidates(LinearScan* lsra)
10655 {
10656     return lsra->GetRegMaskForIndex(internalCandsIndex);
10657 }
10658
10659 void TreeNodeInfo::setInternalCandidates(LinearScan* lsra, regMaskTP mask)
10660 {
10661     LinearScan::RegMaskIndex i = lsra->GetIndexForRegMask(mask);
10662     assert(FitsIn<unsigned char>(i));
10663     internalCandsIndex = (unsigned char)i;
10664 }
10665
10666 void TreeNodeInfo::addInternalCandidates(LinearScan* lsra, regMaskTP mask)
10667 {
10668     LinearScan::RegMaskIndex i = lsra->GetIndexForRegMask(lsra->GetRegMaskForIndex(internalCandsIndex) | mask);
10669     assert(FitsIn<unsigned char>(i));
10670     internalCandsIndex = (unsigned char)i;
10671 }
10672
10673 #if TRACK_LSRA_STATS
10674 // ----------------------------------------------------------
10675 // updateLsraStat: Increment LSRA stat counter.
10676 //
10677 // Arguments:
10678 //    stat      -   LSRA stat enum
10679 //    bbNum     -   Basic block to which LSRA stat needs to be
10680 //                  associated with.
10681 //
10682 void LinearScan::updateLsraStat(LsraStat stat, unsigned bbNum)
10683 {
10684     if (bbNum > bbNumMaxBeforeResolution)
10685     {
10686         // This is a newly created basic block as part of resolution.
10687         // These blocks contain resolution moves that are already accounted.
10688         return;
10689     }
10690
10691     switch (stat)
10692     {
10693         case LSRA_STAT_SPILL:
10694             ++(blockInfo[bbNum].spillCount);
10695             break;
10696
10697         case LSRA_STAT_COPY_REG:
10698             ++(blockInfo[bbNum].copyRegCount);
10699             break;
10700
10701         case LSRA_STAT_RESOLUTION_MOV:
10702             ++(blockInfo[bbNum].resolutionMovCount);
10703             break;
10704
10705         case LSRA_STAT_SPLIT_EDGE:
10706             ++(blockInfo[bbNum].splitEdgeCount);
10707             break;
10708
10709         default:
10710             break;
10711     }
10712 }
10713
10714 // -----------------------------------------------------------
10715 // dumpLsraStats - dumps Lsra stats to given file.
10716 //
10717 // Arguments:
10718 //    file    -  file to which stats are to be written.
10719 //
10720 void LinearScan::dumpLsraStats(FILE* file)
10721 {
10722     unsigned sumSpillCount         = 0;
10723     unsigned sumCopyRegCount       = 0;
10724     unsigned sumResolutionMovCount = 0;
10725     unsigned sumSplitEdgeCount     = 0;
10726     UINT64   wtdSpillCount         = 0;
10727     UINT64   wtdCopyRegCount       = 0;
10728     UINT64   wtdResolutionMovCount = 0;
10729
10730     fprintf(file, "----------\n");
10731     fprintf(file, "LSRA Stats");
10732 #ifdef DEBUG
10733     if (!VERBOSE)
10734     {
10735         fprintf(file, " : %s\n", compiler->info.compFullName);
10736     }
10737     else
10738     {
10739         // In verbose mode no need to print full name
10740         // while printing lsra stats.
10741         fprintf(file, "\n");
10742     }
10743 #else
10744     fprintf(file, " : %s\n", compiler->eeGetMethodFullName(compiler->info.compCompHnd));
10745 #endif
10746
10747     fprintf(file, "----------\n");
10748
10749     for (BasicBlock* block = compiler->fgFirstBB; block != nullptr; block = block->bbNext)
10750     {
10751         if (block->bbNum > bbNumMaxBeforeResolution)
10752         {
10753             continue;
10754         }
10755
10756         unsigned spillCount         = blockInfo[block->bbNum].spillCount;
10757         unsigned copyRegCount       = blockInfo[block->bbNum].copyRegCount;
10758         unsigned resolutionMovCount = blockInfo[block->bbNum].resolutionMovCount;
10759         unsigned splitEdgeCount     = blockInfo[block->bbNum].splitEdgeCount;
10760
10761         if (spillCount != 0 || copyRegCount != 0 || resolutionMovCount != 0 || splitEdgeCount != 0)
10762         {
10763             fprintf(file, "BB%02u [%8d]: ", block->bbNum, block->bbWeight);
10764             fprintf(file, "SpillCount = %d, ResolutionMovs = %d, SplitEdges = %d, CopyReg = %d\n", spillCount,
10765                     resolutionMovCount, splitEdgeCount, copyRegCount);
10766         }
10767
10768         sumSpillCount += spillCount;
10769         sumCopyRegCount += copyRegCount;
10770         sumResolutionMovCount += resolutionMovCount;
10771         sumSplitEdgeCount += splitEdgeCount;
10772
10773         wtdSpillCount += (UINT64)spillCount * block->bbWeight;
10774         wtdCopyRegCount += (UINT64)copyRegCount * block->bbWeight;
10775         wtdResolutionMovCount += (UINT64)resolutionMovCount * block->bbWeight;
10776     }
10777
10778     fprintf(file, "Total Tracked Vars:  %d\n", compiler->lvaTrackedCount);
10779     fprintf(file, "Total Reg Cand Vars: %d\n", regCandidateVarCount);
10780     fprintf(file, "Total number of Intervals: %d\n", static_cast<unsigned>(intervals.size() - 1));
10781     fprintf(file, "Total number of RefPositions: %d\n", static_cast<unsigned>(refPositions.size() - 1));
10782     fprintf(file, "Total Spill Count: %d    Weighted: %I64u\n", sumSpillCount, wtdSpillCount);
10783     fprintf(file, "Total CopyReg Count: %d   Weighted: %I64u\n", sumCopyRegCount, wtdCopyRegCount);
10784     fprintf(file, "Total ResolutionMov Count: %d    Weighted: %I64u\n", sumResolutionMovCount, wtdResolutionMovCount);
10785     fprintf(file, "Total number of split edges: %d\n", sumSplitEdgeCount);
10786
10787     // compute total number of spill temps created
10788     unsigned numSpillTemps = 0;
10789     for (int i = 0; i < TYP_COUNT; i++)
10790     {
10791         numSpillTemps += maxSpill[i];
10792     }
10793     fprintf(file, "Total Number of spill temps created: %d\n\n", numSpillTemps);
10794 }
10795 #endif // TRACK_LSRA_STATS
10796
10797 #ifdef DEBUG
10798 void dumpRegMask(regMaskTP regs)
10799 {
10800     if (regs == RBM_ALLINT)
10801     {
10802         printf("[allInt]");
10803     }
10804     else if (regs == (RBM_ALLINT & ~RBM_FPBASE))
10805     {
10806         printf("[allIntButFP]");
10807     }
10808     else if (regs == RBM_ALLFLOAT)
10809     {
10810         printf("[allFloat]");
10811     }
10812     else if (regs == RBM_ALLDOUBLE)
10813     {
10814         printf("[allDouble]");
10815     }
10816     else
10817     {
10818         dspRegMask(regs);
10819     }
10820 }
10821
10822 static const char* getRefTypeName(RefType refType)
10823 {
10824     switch (refType)
10825     {
10826 #define DEF_REFTYPE(memberName, memberValue, shortName)                                                                \
10827     case memberName:                                                                                                   \
10828         return #memberName;
10829 #include "lsra_reftypes.h"
10830 #undef DEF_REFTYPE
10831         default:
10832             return nullptr;
10833     }
10834 }
10835
10836 static const char* getRefTypeShortName(RefType refType)
10837 {
10838     switch (refType)
10839     {
10840 #define DEF_REFTYPE(memberName, memberValue, shortName)                                                                \
10841     case memberName:                                                                                                   \
10842         return shortName;
10843 #include "lsra_reftypes.h"
10844 #undef DEF_REFTYPE
10845         default:
10846             return nullptr;
10847     }
10848 }
10849
10850 void RefPosition::dump()
10851 {
10852     printf("<RefPosition #%-3u @%-3u", rpNum, nodeLocation);
10853
10854     if (nextRefPosition)
10855     {
10856         printf(" ->#%-3u", nextRefPosition->rpNum);
10857     }
10858
10859     printf(" %s ", getRefTypeName(refType));
10860
10861     if (this->isPhysRegRef)
10862     {
10863         this->getReg()->tinyDump();
10864     }
10865     else if (getInterval())
10866     {
10867         this->getInterval()->tinyDump();
10868     }
10869
10870     if (this->treeNode)
10871     {
10872         printf("%s ", treeNode->OpName(treeNode->OperGet()));
10873     }
10874     printf("BB%02u ", this->bbNum);
10875
10876     printf("regmask=");
10877     dumpRegMask(registerAssignment);
10878
10879     if (this->lastUse)
10880     {
10881         printf(" last");
10882     }
10883     if (this->reload)
10884     {
10885         printf(" reload");
10886     }
10887     if (this->spillAfter)
10888     {
10889         printf(" spillAfter");
10890     }
10891     if (this->moveReg)
10892     {
10893         printf(" move");
10894     }
10895     if (this->copyReg)
10896     {
10897         printf(" copy");
10898     }
10899     if (this->isFixedRegRef)
10900     {
10901         printf(" fixed");
10902     }
10903     if (this->isLocalDefUse)
10904     {
10905         printf(" local");
10906     }
10907     if (this->delayRegFree)
10908     {
10909         printf(" delay");
10910     }
10911     if (this->outOfOrder)
10912     {
10913         printf(" outOfOrder");
10914     }
10915
10916     if (this->AllocateIfProfitable())
10917     {
10918         printf(" regOptional");
10919     }
10920     printf(">\n");
10921 }
10922
10923 void RegRecord::dump()
10924 {
10925     tinyDump();
10926 }
10927
10928 void Interval::dump()
10929 {
10930     printf("Interval %2u:", intervalIndex);
10931
10932     if (isLocalVar)
10933     {
10934         printf(" (V%02u)", varNum);
10935     }
10936     if (isInternal)
10937     {
10938         printf(" (INTERNAL)");
10939     }
10940     if (isSpilled)
10941     {
10942         printf(" (SPILLED)");
10943     }
10944     if (isSplit)
10945     {
10946         printf(" (SPLIT)");
10947     }
10948     if (isStructField)
10949     {
10950         printf(" (struct)");
10951     }
10952     if (isSpecialPutArg)
10953     {
10954         printf(" (specialPutArg)");
10955     }
10956     if (isConstant)
10957     {
10958         printf(" (constant)");
10959     }
10960
10961     printf(" RefPositions {");
10962     for (RefPosition* refPosition = this->firstRefPosition; refPosition != nullptr;
10963          refPosition              = refPosition->nextRefPosition)
10964     {
10965         printf("#%u@%u", refPosition->rpNum, refPosition->nodeLocation);
10966         if (refPosition->nextRefPosition)
10967         {
10968             printf(" ");
10969         }
10970     }
10971     printf("}");
10972
10973     // this is not used (yet?)
10974     // printf(" SpillOffset %d", this->spillOffset);
10975
10976     printf(" physReg:%s", getRegName(physReg));
10977
10978     printf(" Preferences=");
10979     dumpRegMask(this->registerPreferences);
10980
10981     if (relatedInterval)
10982     {
10983         printf(" RelatedInterval ");
10984         relatedInterval->microDump();
10985         printf("[%p]", dspPtr(relatedInterval));
10986     }
10987
10988     printf("\n");
10989 }
10990
10991 // print out very concise representation
10992 void Interval::tinyDump()
10993 {
10994     printf("<Ivl:%u", intervalIndex);
10995     if (isLocalVar)
10996     {
10997         printf(" V%02u", varNum);
10998     }
10999     if (isInternal)
11000     {
11001         printf(" internal");
11002     }
11003     printf("> ");
11004 }
11005
11006 // print out extremely concise representation
11007 void Interval::microDump()
11008 {
11009     char intervalTypeChar = 'I';
11010     if (isInternal)
11011     {
11012         intervalTypeChar = 'T';
11013     }
11014     else if (isLocalVar)
11015     {
11016         intervalTypeChar = 'L';
11017     }
11018
11019     printf("<%c%u>", intervalTypeChar, intervalIndex);
11020 }
11021
11022 void RegRecord::tinyDump()
11023 {
11024     printf("<Reg:%-3s> ", getRegName(regNum));
11025 }
11026
11027 void TreeNodeInfo::dump(LinearScan* lsra)
11028 {
11029     printf("<TreeNodeInfo @ %2u %d=%d %di %df", loc, dstCount, srcCount, internalIntCount, internalFloatCount);
11030     printf(" src=");
11031     dumpRegMask(getSrcCandidates(lsra));
11032     printf(" int=");
11033     dumpRegMask(getInternalCandidates(lsra));
11034     printf(" dst=");
11035     dumpRegMask(getDstCandidates(lsra));
11036     if (isLocalDefUse)
11037     {
11038         printf(" L");
11039     }
11040     if (isInitialized)
11041     {
11042         printf(" I");
11043     }
11044     if (isLsraAdded)
11045     {
11046         printf(" A");
11047     }
11048     if (isDelayFree)
11049     {
11050         printf(" D");
11051     }
11052     if (isTgtPref)
11053     {
11054         printf(" P");
11055     }
11056     if (regOptional)
11057     {
11058         printf(" O");
11059     }
11060     if (isInternalRegDelayFree)
11061     {
11062         printf(" ID");
11063     }
11064     printf(">\n");
11065 }
11066
11067 void LinearScan::lsraDumpIntervals(const char* msg)
11068 {
11069     Interval* interval;
11070
11071     printf("\nLinear scan intervals %s:\n", msg);
11072     for (auto& interval : intervals)
11073     {
11074         // only dump something if it has references
11075         // if (interval->firstRefPosition)
11076         interval.dump();
11077     }
11078
11079     printf("\n");
11080 }
11081
11082 // Dumps a tree node as a destination or source operand, with the style
11083 // of dump dependent on the mode
11084 void LinearScan::lsraGetOperandString(GenTreePtr        tree,
11085                                       LsraTupleDumpMode mode,
11086                                       char*             operandString,
11087                                       unsigned          operandStringLength)
11088 {
11089     const char* lastUseChar = "";
11090     if ((tree->gtFlags & GTF_VAR_DEATH) != 0)
11091     {
11092         lastUseChar = "*";
11093     }
11094     switch (mode)
11095     {
11096         case LinearScan::LSRA_DUMP_PRE:
11097             _snprintf_s(operandString, operandStringLength, operandStringLength, "t%d%s", tree->gtTreeID, lastUseChar);
11098             break;
11099         case LinearScan::LSRA_DUMP_REFPOS:
11100             _snprintf_s(operandString, operandStringLength, operandStringLength, "t%d%s", tree->gtTreeID, lastUseChar);
11101             break;
11102         case LinearScan::LSRA_DUMP_POST:
11103         {
11104             Compiler* compiler = JitTls::GetCompiler();
11105
11106             if (!tree->gtHasReg())
11107             {
11108                 _snprintf_s(operandString, operandStringLength, operandStringLength, "STK%s", lastUseChar);
11109             }
11110             else
11111             {
11112                 _snprintf_s(operandString, operandStringLength, operandStringLength, "%s%s",
11113                             getRegName(tree->gtRegNum, useFloatReg(tree->TypeGet())), lastUseChar);
11114             }
11115         }
11116         break;
11117         default:
11118             printf("ERROR: INVALID TUPLE DUMP MODE\n");
11119             break;
11120     }
11121 }
11122 void LinearScan::lsraDispNode(GenTreePtr tree, LsraTupleDumpMode mode, bool hasDest)
11123 {
11124     Compiler*      compiler            = JitTls::GetCompiler();
11125     const unsigned operandStringLength = 16;
11126     char           operandString[operandStringLength];
11127     const char*    emptyDestOperand = "               ";
11128     char           spillChar        = ' ';
11129
11130     if (mode == LinearScan::LSRA_DUMP_POST)
11131     {
11132         if ((tree->gtFlags & GTF_SPILL) != 0)
11133         {
11134             spillChar = 'S';
11135         }
11136         if (!hasDest && tree->gtHasReg())
11137         {
11138             // A node can define a register, but not produce a value for a parent to consume,
11139             // i.e. in the "localDefUse" case.
11140             // There used to be an assert here that we wouldn't spill such a node.
11141             // However, we can have unused lclVars that wind up being the node at which
11142             // it is spilled. This probably indicates a bug, but we don't realy want to
11143             // assert during a dump.
11144             if (spillChar == 'S')
11145             {
11146                 spillChar = '$';
11147             }
11148             else
11149             {
11150                 spillChar = '*';
11151             }
11152             hasDest = true;
11153         }
11154     }
11155     printf("%c N%03u. ", spillChar, tree->gtSeqNum);
11156
11157     LclVarDsc* varDsc = nullptr;
11158     unsigned   varNum = UINT_MAX;
11159     if (tree->IsLocal())
11160     {
11161         varNum = tree->gtLclVarCommon.gtLclNum;
11162         varDsc = &(compiler->lvaTable[varNum]);
11163         if (varDsc->lvLRACandidate)
11164         {
11165             hasDest = false;
11166         }
11167     }
11168     if (hasDest)
11169     {
11170         if (mode == LinearScan::LSRA_DUMP_POST && tree->gtFlags & GTF_SPILLED)
11171         {
11172             assert(tree->gtHasReg());
11173         }
11174         lsraGetOperandString(tree, mode, operandString, operandStringLength);
11175         printf("%-15s =", operandString);
11176     }
11177     else
11178     {
11179         printf("%-15s  ", emptyDestOperand);
11180     }
11181     if (varDsc != nullptr)
11182     {
11183         if (varDsc->lvLRACandidate)
11184         {
11185             if (mode == LSRA_DUMP_REFPOS)
11186             {
11187                 printf("  V%02u(L%d)", varNum, getIntervalForLocalVar(varDsc->lvVarIndex)->intervalIndex);
11188             }
11189             else
11190             {
11191                 lsraGetOperandString(tree, mode, operandString, operandStringLength);
11192                 printf("  V%02u(%s)", varNum, operandString);
11193                 if (mode == LinearScan::LSRA_DUMP_POST && tree->gtFlags & GTF_SPILLED)
11194                 {
11195                     printf("R");
11196                 }
11197             }
11198         }
11199         else
11200         {
11201             printf("  V%02u MEM", varNum);
11202         }
11203     }
11204     else if (tree->OperIsAssignment())
11205     {
11206         assert(!tree->gtHasReg());
11207         printf("  asg%s  ", GenTree::OpName(tree->OperGet()));
11208     }
11209     else
11210     {
11211         compiler->gtDispNodeName(tree);
11212         if (tree->OperKind() & GTK_LEAF)
11213         {
11214             compiler->gtDispLeaf(tree, nullptr);
11215         }
11216     }
11217 }
11218
11219 //------------------------------------------------------------------------
11220 // ComputeOperandDstCount: computes the number of registers defined by a
11221 //                         node.
11222 //
11223 // For most nodes, this is simple:
11224 // - Nodes that do not produce values (e.g. stores and other void-typed
11225 //   nodes) and nodes that immediately use the registers they define
11226 //   produce no registers
11227 // - Nodes that are marked as defining N registers define N registers.
11228 //
11229 // For contained nodes, however, things are more complicated: for purposes
11230 // of bookkeeping, a contained node is treated as producing the transitive
11231 // closure of the registers produced by its sources.
11232 //
11233 // Arguments:
11234 //    operand - The operand for which to compute a register count.
11235 //
11236 // Returns:
11237 //    The number of registers defined by `operand`.
11238 //
11239 void LinearScan::DumpOperandDefs(
11240     GenTree* operand, bool& first, LsraTupleDumpMode mode, char* operandString, const unsigned operandStringLength)
11241 {
11242     assert(operand != nullptr);
11243     assert(operandString != nullptr);
11244
11245     if (ComputeOperandDstCount(operand) == 0)
11246     {
11247         return;
11248     }
11249
11250     if (operand->gtLsraInfo.dstCount != 0)
11251     {
11252         // This operand directly produces registers; print it.
11253         for (int i = 0; i < operand->gtLsraInfo.dstCount; i++)
11254         {
11255             if (!first)
11256             {
11257                 printf(",");
11258             }
11259
11260             lsraGetOperandString(operand, mode, operandString, operandStringLength);
11261             printf("%s", operandString);
11262
11263             first = false;
11264         }
11265     }
11266     else
11267     {
11268         // This is a contained node. Dump the defs produced by its operands.
11269         for (GenTree* op : operand->Operands())
11270         {
11271             DumpOperandDefs(op, first, mode, operandString, operandStringLength);
11272         }
11273     }
11274 }
11275
11276 void LinearScan::TupleStyleDump(LsraTupleDumpMode mode)
11277 {
11278     BasicBlock*    block;
11279     LsraLocation   currentLoc          = 1; // 0 is the entry
11280     const unsigned operandStringLength = 16;
11281     char           operandString[operandStringLength];
11282
11283     // currentRefPosition is not used for LSRA_DUMP_PRE
11284     // We keep separate iterators for defs, so that we can print them
11285     // on the lhs of the dump
11286     auto currentRefPosition = refPositions.begin();
11287
11288     switch (mode)
11289     {
11290         case LSRA_DUMP_PRE:
11291             printf("TUPLE STYLE DUMP BEFORE LSRA\n");
11292             break;
11293         case LSRA_DUMP_REFPOS:
11294             printf("TUPLE STYLE DUMP WITH REF POSITIONS\n");
11295             break;
11296         case LSRA_DUMP_POST:
11297             printf("TUPLE STYLE DUMP WITH REGISTER ASSIGNMENTS\n");
11298             break;
11299         default:
11300             printf("ERROR: INVALID TUPLE DUMP MODE\n");
11301             return;
11302     }
11303
11304     if (mode != LSRA_DUMP_PRE)
11305     {
11306         printf("Incoming Parameters: ");
11307         for (; currentRefPosition != refPositions.end() && currentRefPosition->refType != RefTypeBB;
11308              ++currentRefPosition)
11309         {
11310             Interval* interval = currentRefPosition->getInterval();
11311             assert(interval != nullptr && interval->isLocalVar);
11312             printf(" V%02d", interval->varNum);
11313             if (mode == LSRA_DUMP_POST)
11314             {
11315                 regNumber reg;
11316                 if (currentRefPosition->registerAssignment == RBM_NONE)
11317                 {
11318                     reg = REG_STK;
11319                 }
11320                 else
11321                 {
11322                     reg = currentRefPosition->assignedReg();
11323                 }
11324                 LclVarDsc* varDsc = &(compiler->lvaTable[interval->varNum]);
11325                 printf("(");
11326                 regNumber assignedReg = varDsc->lvRegNum;
11327                 regNumber argReg      = (varDsc->lvIsRegArg) ? varDsc->lvArgReg : REG_STK;
11328
11329                 assert(reg == assignedReg || varDsc->lvRegister == false);
11330                 if (reg != argReg)
11331                 {
11332                     printf(getRegName(argReg, isFloatRegType(interval->registerType)));
11333                     printf("=>");
11334                 }
11335                 printf("%s)", getRegName(reg, isFloatRegType(interval->registerType)));
11336             }
11337         }
11338         printf("\n");
11339     }
11340
11341     for (block = startBlockSequence(); block != nullptr; block = moveToNextBlock())
11342     {
11343         currentLoc += 2;
11344
11345         if (mode == LSRA_DUMP_REFPOS)
11346         {
11347             bool printedBlockHeader = false;
11348             // We should find the boundary RefPositions in the order of exposed uses, dummy defs, and the blocks
11349             for (; currentRefPosition != refPositions.end() &&
11350                    (currentRefPosition->refType == RefTypeExpUse || currentRefPosition->refType == RefTypeDummyDef ||
11351                     (currentRefPosition->refType == RefTypeBB && !printedBlockHeader));
11352                  ++currentRefPosition)
11353             {
11354                 Interval* interval = nullptr;
11355                 if (currentRefPosition->isIntervalRef())
11356                 {
11357                     interval = currentRefPosition->getInterval();
11358                 }
11359                 switch (currentRefPosition->refType)
11360                 {
11361                     case RefTypeExpUse:
11362                         assert(interval != nullptr);
11363                         assert(interval->isLocalVar);
11364                         printf("  Exposed use of V%02u at #%d\n", interval->varNum, currentRefPosition->rpNum);
11365                         break;
11366                     case RefTypeDummyDef:
11367                         assert(interval != nullptr);
11368                         assert(interval->isLocalVar);
11369                         printf("  Dummy def of V%02u at #%d\n", interval->varNum, currentRefPosition->rpNum);
11370                         break;
11371                     case RefTypeBB:
11372                         block->dspBlockHeader(compiler);
11373                         printedBlockHeader = true;
11374                         printf("=====\n");
11375                         break;
11376                     default:
11377                         printf("Unexpected RefPosition type at #%d\n", currentRefPosition->rpNum);
11378                         break;
11379                 }
11380             }
11381         }
11382         else
11383         {
11384             block->dspBlockHeader(compiler);
11385             printf("=====\n");
11386         }
11387         if (enregisterLocalVars && mode == LSRA_DUMP_POST && block != compiler->fgFirstBB &&
11388             block->bbNum <= bbNumMaxBeforeResolution)
11389         {
11390             printf("Predecessor for variable locations: BB%02u\n", blockInfo[block->bbNum].predBBNum);
11391             dumpInVarToRegMap(block);
11392         }
11393         if (block->bbNum > bbNumMaxBeforeResolution)
11394         {
11395             SplitEdgeInfo splitEdgeInfo;
11396             splitBBNumToTargetBBNumMap->Lookup(block->bbNum, &splitEdgeInfo);
11397             assert(splitEdgeInfo.toBBNum <= bbNumMaxBeforeResolution);
11398             assert(splitEdgeInfo.fromBBNum <= bbNumMaxBeforeResolution);
11399             printf("New block introduced for resolution from BB%02u to BB%02u\n", splitEdgeInfo.fromBBNum,
11400                    splitEdgeInfo.toBBNum);
11401         }
11402
11403         for (GenTree* node : LIR::AsRange(block).NonPhiNodes())
11404         {
11405             GenTree* tree = node;
11406
11407             genTreeOps    oper = tree->OperGet();
11408             TreeNodeInfo& info = tree->gtLsraInfo;
11409             if (tree->gtLsraInfo.isLsraAdded)
11410             {
11411                 // This must be one of the nodes that we add during LSRA
11412
11413                 if (oper == GT_LCL_VAR)
11414                 {
11415                     info.srcCount = 0;
11416                     info.dstCount = 1;
11417                 }
11418                 else if (oper == GT_RELOAD || oper == GT_COPY)
11419                 {
11420                     info.srcCount = 1;
11421                     info.dstCount = 1;
11422                 }
11423 #ifdef FEATURE_SIMD
11424                 else if (oper == GT_SIMD)
11425                 {
11426                     if (tree->gtSIMD.gtSIMDIntrinsicID == SIMDIntrinsicUpperSave)
11427                     {
11428                         info.srcCount = 1;
11429                         info.dstCount = 1;
11430                     }
11431                     else
11432                     {
11433                         assert(tree->gtSIMD.gtSIMDIntrinsicID == SIMDIntrinsicUpperRestore);
11434                         info.srcCount = 2;
11435                         info.dstCount = 0;
11436                     }
11437                 }
11438 #endif // FEATURE_SIMD
11439                 else
11440                 {
11441                     assert(oper == GT_SWAP);
11442                     info.srcCount = 2;
11443                     info.dstCount = 0;
11444                 }
11445                 info.internalIntCount   = 0;
11446                 info.internalFloatCount = 0;
11447             }
11448
11449             int       consume   = info.srcCount;
11450             int       produce   = info.dstCount;
11451             regMaskTP killMask  = RBM_NONE;
11452             regMaskTP fixedMask = RBM_NONE;
11453
11454             lsraDispNode(tree, mode, produce != 0 && mode != LSRA_DUMP_REFPOS);
11455
11456             if (mode != LSRA_DUMP_REFPOS)
11457             {
11458                 if (consume > 0)
11459                 {
11460                     printf("; ");
11461
11462                     bool first = true;
11463                     for (GenTree* operand : tree->Operands())
11464                     {
11465                         DumpOperandDefs(operand, first, mode, operandString, operandStringLength);
11466                     }
11467                 }
11468             }
11469             else
11470             {
11471                 // Print each RefPosition on a new line, but
11472                 // printing all the kills for each node on a single line
11473                 // and combining the fixed regs with their associated def or use
11474                 bool         killPrinted        = false;
11475                 RefPosition* lastFixedRegRefPos = nullptr;
11476                 for (; currentRefPosition != refPositions.end() &&
11477                        (currentRefPosition->refType == RefTypeUse || currentRefPosition->refType == RefTypeFixedReg ||
11478                         currentRefPosition->refType == RefTypeKill || currentRefPosition->refType == RefTypeDef) &&
11479                        (currentRefPosition->nodeLocation == tree->gtSeqNum ||
11480                         currentRefPosition->nodeLocation == tree->gtSeqNum + 1);
11481                      ++currentRefPosition)
11482                 {
11483                     Interval* interval = nullptr;
11484                     if (currentRefPosition->isIntervalRef())
11485                     {
11486                         interval = currentRefPosition->getInterval();
11487                     }
11488                     switch (currentRefPosition->refType)
11489                     {
11490                         case RefTypeUse:
11491                             if (currentRefPosition->isPhysRegRef)
11492                             {
11493                                 printf("\n                               Use:R%d(#%d)",
11494                                        currentRefPosition->getReg()->regNum, currentRefPosition->rpNum);
11495                             }
11496                             else
11497                             {
11498                                 assert(interval != nullptr);
11499                                 printf("\n                               Use:");
11500                                 interval->microDump();
11501                                 printf("(#%d)", currentRefPosition->rpNum);
11502                                 if (currentRefPosition->isFixedRegRef)
11503                                 {
11504                                     assert(genMaxOneBit(currentRefPosition->registerAssignment));
11505                                     assert(lastFixedRegRefPos != nullptr);
11506                                     printf(" Fixed:%s(#%d)", getRegName(currentRefPosition->assignedReg(),
11507                                                                         isFloatRegType(interval->registerType)),
11508                                            lastFixedRegRefPos->rpNum);
11509                                     lastFixedRegRefPos = nullptr;
11510                                 }
11511                                 if (currentRefPosition->isLocalDefUse)
11512                                 {
11513                                     printf(" LocalDefUse");
11514                                 }
11515                                 if (currentRefPosition->lastUse)
11516                                 {
11517                                     printf(" *");
11518                                 }
11519                             }
11520                             break;
11521                         case RefTypeDef:
11522                         {
11523                             // Print each def on a new line
11524                             assert(interval != nullptr);
11525                             printf("\n        Def:");
11526                             interval->microDump();
11527                             printf("(#%d)", currentRefPosition->rpNum);
11528                             if (currentRefPosition->isFixedRegRef)
11529                             {
11530                                 assert(genMaxOneBit(currentRefPosition->registerAssignment));
11531                                 printf(" %s", getRegName(currentRefPosition->assignedReg(),
11532                                                          isFloatRegType(interval->registerType)));
11533                             }
11534                             if (currentRefPosition->isLocalDefUse)
11535                             {
11536                                 printf(" LocalDefUse");
11537                             }
11538                             if (currentRefPosition->lastUse)
11539                             {
11540                                 printf(" *");
11541                             }
11542                             if (interval->relatedInterval != nullptr)
11543                             {
11544                                 printf(" Pref:");
11545                                 interval->relatedInterval->microDump();
11546                             }
11547                         }
11548                         break;
11549                         case RefTypeKill:
11550                             if (!killPrinted)
11551                             {
11552                                 printf("\n        Kill: ");
11553                                 killPrinted = true;
11554                             }
11555                             printf(getRegName(currentRefPosition->assignedReg(),
11556                                               isFloatRegType(currentRefPosition->getReg()->registerType)));
11557                             printf(" ");
11558                             break;
11559                         case RefTypeFixedReg:
11560                             lastFixedRegRefPos = currentRefPosition;
11561                             break;
11562                         default:
11563                             printf("Unexpected RefPosition type at #%d\n", currentRefPosition->rpNum);
11564                             break;
11565                     }
11566                 }
11567             }
11568             printf("\n");
11569             if (info.internalIntCount != 0 && mode != LSRA_DUMP_REFPOS)
11570             {
11571                 printf("\tinternal (%d):\t", info.internalIntCount);
11572                 if (mode == LSRA_DUMP_POST)
11573                 {
11574                     dumpRegMask(tree->gtRsvdRegs);
11575                 }
11576                 else if ((info.getInternalCandidates(this) & allRegs(TYP_INT)) != allRegs(TYP_INT))
11577                 {
11578                     dumpRegMask(info.getInternalCandidates(this) & allRegs(TYP_INT));
11579                 }
11580                 printf("\n");
11581             }
11582             if (info.internalFloatCount != 0 && mode != LSRA_DUMP_REFPOS)
11583             {
11584                 printf("\tinternal (%d):\t", info.internalFloatCount);
11585                 if (mode == LSRA_DUMP_POST)
11586                 {
11587                     dumpRegMask(tree->gtRsvdRegs);
11588                 }
11589                 else if ((info.getInternalCandidates(this) & allRegs(TYP_INT)) != allRegs(TYP_INT))
11590                 {
11591                     dumpRegMask(info.getInternalCandidates(this) & allRegs(TYP_INT));
11592                 }
11593                 printf("\n");
11594             }
11595         }
11596         if (enregisterLocalVars && mode == LSRA_DUMP_POST)
11597         {
11598             dumpOutVarToRegMap(block);
11599         }
11600         printf("\n");
11601     }
11602     printf("\n\n");
11603 }
11604
11605 void LinearScan::dumpLsraAllocationEvent(LsraDumpEvent event,
11606                                          Interval*     interval,
11607                                          regNumber     reg,
11608                                          BasicBlock*   currentBlock)
11609 {
11610     if (!(VERBOSE))
11611     {
11612         return;
11613     }
11614     switch (event)
11615     {
11616         // Conflicting def/use
11617         case LSRA_EVENT_DEFUSE_CONFLICT:
11618             if (!dumpTerse)
11619             {
11620                 printf("  Def and Use have conflicting register requirements:");
11621             }
11622             else
11623             {
11624                 printf("DUconflict ");
11625                 dumpRegRecords();
11626             }
11627             break;
11628         case LSRA_EVENT_DEFUSE_FIXED_DELAY_USE:
11629             if (!dumpTerse)
11630             {
11631                 printf(" Can't change useAssignment ");
11632             }
11633             break;
11634         case LSRA_EVENT_DEFUSE_CASE1:
11635             if (!dumpTerse)
11636             {
11637                 printf(" case #1, use the defRegAssignment\n");
11638             }
11639             else
11640             {
11641                 printf(indentFormat, " case #1 use defRegAssignment");
11642                 dumpRegRecords();
11643                 dumpEmptyRefPosition();
11644             }
11645             break;
11646         case LSRA_EVENT_DEFUSE_CASE2:
11647             if (!dumpTerse)
11648             {
11649                 printf(" case #2, use the useRegAssignment\n");
11650             }
11651             else
11652             {
11653                 printf(indentFormat, " case #2 use useRegAssignment");
11654                 dumpRegRecords();
11655                 dumpEmptyRefPosition();
11656             }
11657             break;
11658         case LSRA_EVENT_DEFUSE_CASE3:
11659             if (!dumpTerse)
11660             {
11661                 printf(" case #3, change the defRegAssignment to the use regs\n");
11662             }
11663             else
11664             {
11665                 printf(indentFormat, " case #3 use useRegAssignment");
11666                 dumpRegRecords();
11667                 dumpEmptyRefPosition();
11668             }
11669             break;
11670         case LSRA_EVENT_DEFUSE_CASE4:
11671             if (!dumpTerse)
11672             {
11673                 printf(" case #4, change the useRegAssignment to the def regs\n");
11674             }
11675             else
11676             {
11677                 printf(indentFormat, " case #4 use defRegAssignment");
11678                 dumpRegRecords();
11679                 dumpEmptyRefPosition();
11680             }
11681             break;
11682         case LSRA_EVENT_DEFUSE_CASE5:
11683             if (!dumpTerse)
11684             {
11685                 printf(" case #5, Conflicting Def and Use single-register requirements require copies - set def to all "
11686                        "regs of the appropriate type\n");
11687             }
11688             else
11689             {
11690                 printf(indentFormat, " case #5 set def to all regs");
11691                 dumpRegRecords();
11692                 dumpEmptyRefPosition();
11693             }
11694             break;
11695         case LSRA_EVENT_DEFUSE_CASE6:
11696             if (!dumpTerse)
11697             {
11698                 printf(" case #6, Conflicting Def and Use register requirements require a copy\n");
11699             }
11700             else
11701             {
11702                 printf(indentFormat, " case #6 need a copy");
11703                 dumpRegRecords();
11704                 dumpEmptyRefPosition();
11705             }
11706             break;
11707
11708         case LSRA_EVENT_SPILL:
11709             if (!dumpTerse)
11710             {
11711                 printf("Spilled:\n");
11712                 interval->dump();
11713             }
11714             else
11715             {
11716                 assert(interval != nullptr && interval->assignedReg != nullptr);
11717                 printf("Spill %-4s ", getRegName(interval->assignedReg->regNum));
11718                 dumpRegRecords();
11719                 dumpEmptyRefPosition();
11720             }
11721             break;
11722         case LSRA_EVENT_SPILL_EXTENDED_LIFETIME:
11723             if (!dumpTerse)
11724             {
11725                 printf("  Spilled extended lifetime var V%02u at last use; not marked for actual spill.",
11726                        interval->intervalIndex);
11727             }
11728             break;
11729
11730         // Restoring the previous register
11731         case LSRA_EVENT_RESTORE_PREVIOUS_INTERVAL_AFTER_SPILL:
11732             assert(interval != nullptr);
11733             if (!dumpTerse)
11734             {
11735                 printf("  Assign register %s to previous interval Ivl:%d after spill\n", getRegName(reg),
11736                        interval->intervalIndex);
11737             }
11738             else
11739             {
11740                 // If we spilled, then the dump is already pre-indented, but we need to pre-indent for the subsequent
11741                 // allocation
11742                 // with a dumpEmptyRefPosition().
11743                 printf("SRstr %-4s ", getRegName(reg));
11744                 dumpRegRecords();
11745                 dumpEmptyRefPosition();
11746             }
11747             break;
11748         case LSRA_EVENT_RESTORE_PREVIOUS_INTERVAL:
11749             assert(interval != nullptr);
11750             if (!dumpTerse)
11751             {
11752                 printf("  Assign register %s to previous interval Ivl:%d\n", getRegName(reg), interval->intervalIndex);
11753             }
11754             else
11755             {
11756                 if (activeRefPosition == nullptr)
11757                 {
11758                     printf(emptyRefPositionFormat, "");
11759                 }
11760                 printf("Restr %-4s ", getRegName(reg));
11761                 dumpRegRecords();
11762                 if (activeRefPosition != nullptr)
11763                 {
11764                     printf(emptyRefPositionFormat, "");
11765                 }
11766             }
11767             break;
11768
11769         // Done with GC Kills
11770         case LSRA_EVENT_DONE_KILL_GC_REFS:
11771             printf("DoneKillGC ");
11772             break;
11773
11774         // Block boundaries
11775         case LSRA_EVENT_START_BB:
11776             assert(currentBlock != nullptr);
11777             if (!dumpTerse)
11778             {
11779                 printf("\n\n  Live Vars(Regs) at start of BB%02u (from pred BB%02u):", currentBlock->bbNum,
11780                        blockInfo[currentBlock->bbNum].predBBNum);
11781                 dumpVarToRegMap(inVarToRegMaps[currentBlock->bbNum]);
11782             }
11783             break;
11784         case LSRA_EVENT_END_BB:
11785             if (!dumpTerse)
11786             {
11787                 printf("\n\n  Live Vars(Regs) after BB%02u:", currentBlock->bbNum);
11788                 dumpVarToRegMap(outVarToRegMaps[currentBlock->bbNum]);
11789             }
11790             break;
11791
11792         case LSRA_EVENT_FREE_REGS:
11793             if (!dumpTerse)
11794             {
11795                 printf("Freeing registers:\n");
11796             }
11797             break;
11798
11799         // Characteristics of the current RefPosition
11800         case LSRA_EVENT_INCREMENT_RANGE_END:
11801             if (!dumpTerse)
11802             {
11803                 printf("  Incrementing nextPhysRegLocation for %s\n", getRegName(reg));
11804             }
11805             // else ???
11806             break;
11807         case LSRA_EVENT_LAST_USE:
11808             if (!dumpTerse)
11809             {
11810                 printf("    Last use, marked to be freed\n");
11811             }
11812             break;
11813         case LSRA_EVENT_LAST_USE_DELAYED:
11814             if (!dumpTerse)
11815             {
11816                 printf("    Last use, marked to be freed (delayed)\n");
11817             }
11818             break;
11819         case LSRA_EVENT_NEEDS_NEW_REG:
11820             if (!dumpTerse)
11821             {
11822                 printf("    Needs new register; mark %s to be freed\n", getRegName(reg));
11823             }
11824             else
11825             {
11826                 printf("Free  %-4s ", getRegName(reg));
11827                 dumpRegRecords();
11828                 dumpEmptyRefPosition();
11829             }
11830             break;
11831
11832         // Allocation decisions
11833         case LSRA_EVENT_FIXED_REG:
11834         case LSRA_EVENT_EXP_USE:
11835             if (!dumpTerse)
11836             {
11837                 printf("No allocation\n");
11838             }
11839             else
11840             {
11841                 printf("Keep  %-4s ", getRegName(reg));
11842             }
11843             break;
11844         case LSRA_EVENT_ZERO_REF:
11845             assert(interval != nullptr && interval->isLocalVar);
11846             if (!dumpTerse)
11847             {
11848                 printf("Marking V%02u as last use there are no actual references\n", interval->varNum);
11849             }
11850             else
11851             {
11852                 printf("NoRef      ");
11853                 dumpRegRecords();
11854                 dumpEmptyRefPosition();
11855             }
11856             break;
11857         case LSRA_EVENT_KEPT_ALLOCATION:
11858             if (!dumpTerse)
11859             {
11860                 printf("already allocated %4s\n", getRegName(reg));
11861             }
11862             else
11863             {
11864                 printf("Keep  %-4s ", getRegName(reg));
11865             }
11866             break;
11867         case LSRA_EVENT_COPY_REG:
11868             assert(interval != nullptr && interval->recentRefPosition != nullptr);
11869             if (!dumpTerse)
11870             {
11871                 printf("allocated %s as copyReg\n\n", getRegName(reg));
11872             }
11873             else
11874             {
11875                 printf("Copy  %-4s ", getRegName(reg));
11876             }
11877             break;
11878         case LSRA_EVENT_MOVE_REG:
11879             assert(interval != nullptr && interval->recentRefPosition != nullptr);
11880             if (!dumpTerse)
11881             {
11882                 printf("  needs a new register; marked as moveReg\n");
11883             }
11884             else
11885             {
11886                 printf("Move  %-4s ", getRegName(reg));
11887                 dumpRegRecords();
11888                 dumpEmptyRefPosition();
11889             }
11890             break;
11891         case LSRA_EVENT_ALLOC_REG:
11892             if (!dumpTerse)
11893             {
11894                 printf("allocated %s\n", getRegName(reg));
11895             }
11896             else
11897             {
11898                 printf("Alloc %-4s ", getRegName(reg));
11899             }
11900             break;
11901         case LSRA_EVENT_REUSE_REG:
11902             if (!dumpTerse)
11903             {
11904                 printf("reused constant in %s\n", getRegName(reg));
11905             }
11906             else
11907             {
11908                 printf("Reuse %-4s ", getRegName(reg));
11909             }
11910             break;
11911         case LSRA_EVENT_ALLOC_SPILLED_REG:
11912             if (!dumpTerse)
11913             {
11914                 printf("allocated spilled register %s\n", getRegName(reg));
11915             }
11916             else
11917             {
11918                 printf("Steal %-4s ", getRegName(reg));
11919             }
11920             break;
11921         case LSRA_EVENT_NO_ENTRY_REG_ALLOCATED:
11922             assert(interval != nullptr && interval->isLocalVar);
11923             if (!dumpTerse)
11924             {
11925                 printf("Not allocating an entry register for V%02u due to low ref count\n", interval->varNum);
11926             }
11927             else
11928             {
11929                 printf("LoRef      ");
11930             }
11931             break;
11932         case LSRA_EVENT_NO_REG_ALLOCATED:
11933             if (!dumpTerse)
11934             {
11935                 printf("no register allocated\n");
11936             }
11937             else
11938             {
11939                 printf("NoReg      ");
11940             }
11941             break;
11942         case LSRA_EVENT_RELOAD:
11943             if (!dumpTerse)
11944             {
11945                 printf("    Marked for reload\n");
11946             }
11947             else
11948             {
11949                 printf("ReLod %-4s ", getRegName(reg));
11950                 dumpRegRecords();
11951                 dumpEmptyRefPosition();
11952             }
11953             break;
11954         case LSRA_EVENT_SPECIAL_PUTARG:
11955             if (!dumpTerse)
11956             {
11957                 printf("    Special case of putArg - using lclVar that's in the expected reg\n");
11958             }
11959             else
11960             {
11961                 printf("PtArg %-4s ", getRegName(reg));
11962             }
11963             break;
11964         default:
11965             break;
11966     }
11967 }
11968
11969 //------------------------------------------------------------------------
11970 // dumpRegRecordHeader: Dump the header for a column-based dump of the register state.
11971 //
11972 // Arguments:
11973 //    None.
11974 //
11975 // Return Value:
11976 //    None.
11977 //
11978 // Assumptions:
11979 //    Reg names fit in 4 characters (minimum width of the columns)
11980 //
11981 // Notes:
11982 //    In order to make the table as dense as possible (for ease of reading the dumps),
11983 //    we determine the minimum regColumnWidth width required to represent:
11984 //      regs, by name (e.g. eax or xmm0) - this is fixed at 4 characters.
11985 //      intervals, as Vnn for lclVar intervals, or as I<num> for other intervals.
11986 //    The table is indented by the amount needed for dumpRefPositionShort, which is
11987 //    captured in shortRefPositionDumpWidth.
11988 //
11989 void LinearScan::dumpRegRecordHeader()
11990 {
11991     printf("The following table has one or more rows for each RefPosition that is handled during allocation.\n"
11992            "The first column provides the basic information about the RefPosition, with its type (e.g. Def,\n"
11993            "Use, Fixd) followed by a '*' if it is a last use, and a 'D' if it is delayRegFree, and then the\n"
11994            "action taken during allocation (e.g. Alloc a new register, or Keep an existing one).\n"
11995            "The subsequent columns show the Interval occupying each register, if any, followed by 'a' if it is\n"
11996            "active, and 'i'if it is inactive.  Columns are only printed up to the last modifed register, which\n"
11997            "may increase during allocation, in which case additional columns will appear.  Registers which are\n"
11998            "not marked modified have ---- in their column.\n\n");
11999
12000     // First, determine the width of each register column (which holds a reg name in the
12001     // header, and an interval name in each subsequent row).
12002     int intervalNumberWidth = (int)log10((double)intervals.size()) + 1;
12003     // The regColumnWidth includes the identifying character (I or V) and an 'i' or 'a' (inactive or active)
12004     regColumnWidth = intervalNumberWidth + 2;
12005     if (regColumnWidth < 4)
12006     {
12007         regColumnWidth = 4;
12008     }
12009     sprintf_s(intervalNameFormat, MAX_FORMAT_CHARS, "%%c%%-%dd", regColumnWidth - 2);
12010     sprintf_s(regNameFormat, MAX_FORMAT_CHARS, "%%-%ds", regColumnWidth);
12011
12012     // Next, determine the width of the short RefPosition (see dumpRefPositionShort()).
12013     // This is in the form:
12014     // nnn.#mmm NAME TYPEld
12015     // Where:
12016     //    nnn is the Location, right-justified to the width needed for the highest location.
12017     //    mmm is the RefPosition rpNum, left-justified to the width needed for the highest rpNum.
12018     //    NAME is dumped by dumpReferentName(), and is "regColumnWidth".
12019     //    TYPE is RefTypeNameShort, and is 4 characters
12020     //    l is either '*' (if a last use) or ' ' (otherwise)
12021     //    d is either 'D' (if a delayed use) or ' ' (otherwise)
12022
12023     maxNodeLocation = (maxNodeLocation == 0)
12024                           ? 1
12025                           : maxNodeLocation; // corner case of a method with an infinite loop without any gentree nodes
12026     assert(maxNodeLocation >= 1);
12027     assert(refPositions.size() >= 1);
12028     int nodeLocationWidth         = (int)log10((double)maxNodeLocation) + 1;
12029     int refPositionWidth          = (int)log10((double)refPositions.size()) + 1;
12030     int refTypeInfoWidth          = 4 /*TYPE*/ + 2 /* last-use and delayed */ + 1 /* space */;
12031     int locationAndRPNumWidth     = nodeLocationWidth + 2 /* .# */ + refPositionWidth + 1 /* space */;
12032     int shortRefPositionDumpWidth = locationAndRPNumWidth + regColumnWidth + 1 /* space */ + refTypeInfoWidth;
12033     sprintf_s(shortRefPositionFormat, MAX_FORMAT_CHARS, "%%%dd.#%%-%dd ", nodeLocationWidth, refPositionWidth);
12034     sprintf_s(emptyRefPositionFormat, MAX_FORMAT_CHARS, "%%-%ds", shortRefPositionDumpWidth);
12035
12036     // The width of the "allocation info"
12037     //  - a 5-character allocation decision
12038     //  - a space
12039     //  - a 4-character register
12040     //  - a space
12041     int allocationInfoWidth = 5 + 1 + 4 + 1;
12042
12043     // Next, determine the width of the legend for each row.  This includes:
12044     //  - a short RefPosition dump (shortRefPositionDumpWidth), which includes a space
12045     //  - the allocation info (allocationInfoWidth), which also includes a space
12046
12047     regTableIndent = shortRefPositionDumpWidth + allocationInfoWidth;
12048
12049     // BBnn printed left-justified in the NAME Typeld and allocationInfo space.
12050     int bbDumpWidth = regColumnWidth + 1 + refTypeInfoWidth + allocationInfoWidth;
12051     int bbNumWidth  = (int)log10((double)compiler->fgBBNumMax) + 1;
12052     // In the unlikely event that BB numbers overflow the space, we'll simply omit the predBB
12053     int predBBNumDumpSpace = regTableIndent - locationAndRPNumWidth - bbNumWidth - 9; // 'BB' + ' PredBB'
12054     if (predBBNumDumpSpace < bbNumWidth)
12055     {
12056         sprintf_s(bbRefPosFormat, MAX_LEGEND_FORMAT_CHARS, "BB%%-%dd", shortRefPositionDumpWidth - 2);
12057     }
12058     else
12059     {
12060         sprintf_s(bbRefPosFormat, MAX_LEGEND_FORMAT_CHARS, "BB%%-%dd PredBB%%-%dd", bbNumWidth, predBBNumDumpSpace);
12061     }
12062
12063     if (compiler->shouldDumpASCIITrees())
12064     {
12065         columnSeparator = "|";
12066         line            = "-";
12067         leftBox         = "+";
12068         middleBox       = "+";
12069         rightBox        = "+";
12070     }
12071     else
12072     {
12073         columnSeparator = "\xe2\x94\x82";
12074         line            = "\xe2\x94\x80";
12075         leftBox         = "\xe2\x94\x9c";
12076         middleBox       = "\xe2\x94\xbc";
12077         rightBox        = "\xe2\x94\xa4";
12078     }
12079     sprintf_s(indentFormat, MAX_FORMAT_CHARS, "%%-%ds", regTableIndent);
12080
12081     // Now, set up the legend format for the RefPosition info
12082     sprintf_s(legendFormat, MAX_LEGEND_FORMAT_CHARS, "%%-%d.%ds%%-%d.%ds%%-%ds%%s", nodeLocationWidth + 1,
12083               nodeLocationWidth + 1, refPositionWidth + 2, refPositionWidth + 2, regColumnWidth + 1);
12084
12085     // Finally, print a "title row" including the legend and the reg names
12086     dumpRegRecordTitle();
12087 }
12088
12089 int LinearScan::getLastUsedRegNumIndex()
12090 {
12091     int       lastUsedRegNumIndex = 0;
12092     regMaskTP usedRegsMask        = compiler->codeGen->regSet.rsGetModifiedRegsMask();
12093     int       lastRegNumIndex     = compiler->compFloatingPointUsed ? REG_FP_LAST : REG_INT_LAST;
12094     for (int regNumIndex = 0; regNumIndex <= lastRegNumIndex; regNumIndex++)
12095     {
12096         if ((usedRegsMask & genRegMask((regNumber)regNumIndex)) != 0)
12097         {
12098             lastUsedRegNumIndex = regNumIndex;
12099         }
12100     }
12101     return lastUsedRegNumIndex;
12102 }
12103
12104 void LinearScan::dumpRegRecordTitleLines()
12105 {
12106     for (int i = 0; i < regTableIndent; i++)
12107     {
12108         printf("%s", line);
12109     }
12110     int lastUsedRegNumIndex = getLastUsedRegNumIndex();
12111     for (int regNumIndex = 0; regNumIndex <= lastUsedRegNumIndex; regNumIndex++)
12112     {
12113         printf("%s", middleBox);
12114         for (int i = 0; i < regColumnWidth; i++)
12115         {
12116             printf("%s", line);
12117         }
12118     }
12119     printf("%s\n", rightBox);
12120 }
12121 void LinearScan::dumpRegRecordTitle()
12122 {
12123     dumpRegRecordTitleLines();
12124
12125     // Print out the legend for the RefPosition info
12126     printf(legendFormat, "Loc ", "RP# ", "Name ", "Type  Action Reg  ");
12127
12128     // Print out the register name column headers
12129     char columnFormatArray[MAX_FORMAT_CHARS];
12130     sprintf_s(columnFormatArray, MAX_FORMAT_CHARS, "%s%%-%d.%ds", columnSeparator, regColumnWidth, regColumnWidth);
12131     int lastUsedRegNumIndex = getLastUsedRegNumIndex();
12132     for (int regNumIndex = 0; regNumIndex <= lastUsedRegNumIndex; regNumIndex++)
12133     {
12134         regNumber   regNum  = (regNumber)regNumIndex;
12135         const char* regName = getRegName(regNum);
12136         printf(columnFormatArray, regName);
12137     }
12138     printf("%s\n", columnSeparator);
12139
12140     rowCountSinceLastTitle = 0;
12141
12142     dumpRegRecordTitleLines();
12143 }
12144
12145 void LinearScan::dumpRegRecords()
12146 {
12147     static char columnFormatArray[18];
12148     int         lastUsedRegNumIndex = getLastUsedRegNumIndex();
12149     regMaskTP   usedRegsMask        = compiler->codeGen->regSet.rsGetModifiedRegsMask();
12150
12151     for (int regNumIndex = 0; regNumIndex <= lastUsedRegNumIndex; regNumIndex++)
12152     {
12153         printf("%s", columnSeparator);
12154         RegRecord& regRecord = physRegs[regNumIndex];
12155         Interval*  interval  = regRecord.assignedInterval;
12156         if (interval != nullptr)
12157         {
12158             dumpIntervalName(interval);
12159             char activeChar = interval->isActive ? 'a' : 'i';
12160             printf("%c", activeChar);
12161         }
12162         else if (regRecord.isBusyUntilNextKill)
12163         {
12164             printf(columnFormatArray, "Busy");
12165         }
12166         else if ((usedRegsMask & genRegMask((regNumber)regNumIndex)) == 0)
12167         {
12168             sprintf_s(columnFormatArray, MAX_FORMAT_CHARS, "%%-%ds", regColumnWidth);
12169             printf(columnFormatArray, "----");
12170         }
12171         else
12172         {
12173             sprintf_s(columnFormatArray, MAX_FORMAT_CHARS, "%%-%ds", regColumnWidth);
12174             printf(columnFormatArray, "");
12175         }
12176     }
12177     printf("%s\n", columnSeparator);
12178
12179     if (rowCountSinceLastTitle > MAX_ROWS_BETWEEN_TITLES)
12180     {
12181         dumpRegRecordTitle();
12182     }
12183     rowCountSinceLastTitle++;
12184 }
12185
12186 void LinearScan::dumpIntervalName(Interval* interval)
12187 {
12188     if (interval->isLocalVar)
12189     {
12190         printf(intervalNameFormat, 'V', interval->varNum);
12191     }
12192     else if (interval->isConstant)
12193     {
12194         printf(intervalNameFormat, 'C', interval->intervalIndex);
12195     }
12196     else
12197     {
12198         printf(intervalNameFormat, 'I', interval->intervalIndex);
12199     }
12200 }
12201
12202 void LinearScan::dumpEmptyRefPosition()
12203 {
12204     printf(emptyRefPositionFormat, "");
12205 }
12206
12207 // Note that the size of this dump is computed in dumpRegRecordHeader().
12208 //
12209 void LinearScan::dumpRefPositionShort(RefPosition* refPosition, BasicBlock* currentBlock)
12210 {
12211     BasicBlock* block = currentBlock;
12212     if (refPosition->refType == RefTypeBB)
12213     {
12214         // Always print a title row before a RefTypeBB (except for the first, because we
12215         // will already have printed it before the parameters)
12216         if (refPosition->refType == RefTypeBB && block != compiler->fgFirstBB && block != nullptr)
12217         {
12218             dumpRegRecordTitle();
12219         }
12220     }
12221     printf(shortRefPositionFormat, refPosition->nodeLocation, refPosition->rpNum);
12222     if (refPosition->refType == RefTypeBB)
12223     {
12224         if (block == nullptr)
12225         {
12226             printf(regNameFormat, "END");
12227             printf("               ");
12228             printf(regNameFormat, "");
12229         }
12230         else
12231         {
12232             printf(bbRefPosFormat, block->bbNum, block == compiler->fgFirstBB ? 0 : blockInfo[block->bbNum].predBBNum);
12233         }
12234     }
12235     else if (refPosition->isIntervalRef())
12236     {
12237         Interval* interval = refPosition->getInterval();
12238         dumpIntervalName(interval);
12239         char lastUseChar = ' ';
12240         char delayChar   = ' ';
12241         if (refPosition->lastUse)
12242         {
12243             lastUseChar = '*';
12244             if (refPosition->delayRegFree)
12245             {
12246                 delayChar = 'D';
12247             }
12248         }
12249         printf("  %s%c%c ", getRefTypeShortName(refPosition->refType), lastUseChar, delayChar);
12250     }
12251     else if (refPosition->isPhysRegRef)
12252     {
12253         RegRecord* regRecord = refPosition->getReg();
12254         printf(regNameFormat, getRegName(regRecord->regNum));
12255         printf(" %s   ", getRefTypeShortName(refPosition->refType));
12256     }
12257     else
12258     {
12259         assert(refPosition->refType == RefTypeKillGCRefs);
12260         // There's no interval or reg name associated with this.
12261         printf(regNameFormat, "   ");
12262         printf(" %s   ", getRefTypeShortName(refPosition->refType));
12263     }
12264 }
12265
12266 //------------------------------------------------------------------------
12267 // LinearScan::IsResolutionMove:
12268 //     Returns true if the given node is a move inserted by LSRA
12269 //     resolution.
12270 //
12271 // Arguments:
12272 //     node - the node to check.
12273 //
12274 bool LinearScan::IsResolutionMove(GenTree* node)
12275 {
12276     if (!node->gtLsraInfo.isLsraAdded)
12277     {
12278         return false;
12279     }
12280
12281     switch (node->OperGet())
12282     {
12283         case GT_LCL_VAR:
12284         case GT_COPY:
12285             return node->gtLsraInfo.isLocalDefUse;
12286
12287         case GT_SWAP:
12288             return true;
12289
12290         default:
12291             return false;
12292     }
12293 }
12294
12295 //------------------------------------------------------------------------
12296 // LinearScan::IsResolutionNode:
12297 //     Returns true if the given node is either a move inserted by LSRA
12298 //     resolution or an operand to such a move.
12299 //
12300 // Arguments:
12301 //     containingRange - the range that contains the node to check.
12302 //     node - the node to check.
12303 //
12304 bool LinearScan::IsResolutionNode(LIR::Range& containingRange, GenTree* node)
12305 {
12306     for (;;)
12307     {
12308         if (IsResolutionMove(node))
12309         {
12310             return true;
12311         }
12312
12313         if (!node->gtLsraInfo.isLsraAdded || (node->OperGet() != GT_LCL_VAR))
12314         {
12315             return false;
12316         }
12317
12318         LIR::Use use;
12319         bool     foundUse = containingRange.TryGetUse(node, &use);
12320         assert(foundUse);
12321
12322         node = use.User();
12323     }
12324 }
12325
12326 //------------------------------------------------------------------------
12327 // verifyFinalAllocation: Traverse the RefPositions and verify various invariants.
12328 //
12329 // Arguments:
12330 //    None.
12331 //
12332 // Return Value:
12333 //    None.
12334 //
12335 // Notes:
12336 //    If verbose is set, this will also dump a table of the final allocations.
12337 void LinearScan::verifyFinalAllocation()
12338 {
12339     if (VERBOSE)
12340     {
12341         printf("\nFinal allocation\n");
12342     }
12343
12344     // Clear register assignments.
12345     for (regNumber reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
12346     {
12347         RegRecord* physRegRecord        = getRegisterRecord(reg);
12348         physRegRecord->assignedInterval = nullptr;
12349     }
12350
12351     for (auto& interval : intervals)
12352     {
12353         interval.assignedReg = nullptr;
12354         interval.physReg     = REG_NA;
12355     }
12356
12357     DBEXEC(VERBOSE, dumpRegRecordTitle());
12358
12359     BasicBlock*  currentBlock                = nullptr;
12360     GenTree*     firstBlockEndResolutionNode = nullptr;
12361     regMaskTP    regsToFree                  = RBM_NONE;
12362     regMaskTP    delayRegsToFree             = RBM_NONE;
12363     LsraLocation currentLocation             = MinLocation;
12364     for (auto& refPosition : refPositions)
12365     {
12366         RefPosition* currentRefPosition = &refPosition;
12367         Interval*    interval           = nullptr;
12368         RegRecord*   regRecord          = nullptr;
12369         regNumber    regNum             = REG_NA;
12370         if (currentRefPosition->refType == RefTypeBB)
12371         {
12372             regsToFree |= delayRegsToFree;
12373             delayRegsToFree = RBM_NONE;
12374             // For BB RefPositions, wait until we dump the "end of block" info before dumping the basic RefPosition
12375             // info.
12376         }
12377         else
12378         {
12379             // For other RefPosition types, we can dump the basic RefPosition info now.
12380             DBEXEC(VERBOSE, dumpRefPositionShort(currentRefPosition, currentBlock));
12381
12382             if (currentRefPosition->isPhysRegRef)
12383             {
12384                 regRecord                    = currentRefPosition->getReg();
12385                 regRecord->recentRefPosition = currentRefPosition;
12386                 regNum                       = regRecord->regNum;
12387             }
12388             else if (currentRefPosition->isIntervalRef())
12389             {
12390                 interval                    = currentRefPosition->getInterval();
12391                 interval->recentRefPosition = currentRefPosition;
12392                 if (currentRefPosition->registerAssignment != RBM_NONE)
12393                 {
12394                     if (!genMaxOneBit(currentRefPosition->registerAssignment))
12395                     {
12396                         assert(currentRefPosition->refType == RefTypeExpUse ||
12397                                currentRefPosition->refType == RefTypeDummyDef);
12398                     }
12399                     else
12400                     {
12401                         regNum    = currentRefPosition->assignedReg();
12402                         regRecord = getRegisterRecord(regNum);
12403                     }
12404                 }
12405             }
12406         }
12407
12408         LsraLocation newLocation = currentRefPosition->nodeLocation;
12409
12410         if (newLocation > currentLocation)
12411         {
12412             // Free Registers.
12413             // We could use the freeRegisters() method, but we'd have to carefully manage the active intervals.
12414             for (regNumber reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
12415             {
12416                 regMaskTP regMask = genRegMask(reg);
12417                 if ((regsToFree & regMask) != RBM_NONE)
12418                 {
12419                     RegRecord* physRegRecord        = getRegisterRecord(reg);
12420                     physRegRecord->assignedInterval = nullptr;
12421                 }
12422             }
12423             regsToFree = delayRegsToFree;
12424             regsToFree = RBM_NONE;
12425         }
12426         currentLocation = newLocation;
12427
12428         switch (currentRefPosition->refType)
12429         {
12430             case RefTypeBB:
12431             {
12432                 if (currentBlock == nullptr)
12433                 {
12434                     currentBlock = startBlockSequence();
12435                 }
12436                 else
12437                 {
12438                     // Verify the resolution moves at the end of the previous block.
12439                     for (GenTree* node = firstBlockEndResolutionNode; node != nullptr; node = node->gtNext)
12440                     {
12441                         assert(enregisterLocalVars);
12442                         // Only verify nodes that are actually moves; don't bother with the nodes that are
12443                         // operands to moves.
12444                         if (IsResolutionMove(node))
12445                         {
12446                             verifyResolutionMove(node, currentLocation);
12447                         }
12448                     }
12449
12450                     // Validate the locations at the end of the previous block.
12451                     if (enregisterLocalVars)
12452                     {
12453                         VarToRegMap     outVarToRegMap = outVarToRegMaps[currentBlock->bbNum];
12454                         VarSetOps::Iter iter(compiler, currentBlock->bbLiveOut);
12455                         unsigned        varIndex = 0;
12456                         while (iter.NextElem(&varIndex))
12457                         {
12458                             if (localVarIntervals[varIndex] == nullptr)
12459                             {
12460                                 assert(!compiler->lvaTable[compiler->lvaTrackedToVarNum[varIndex]].lvLRACandidate);
12461                                 continue;
12462                             }
12463                             regNumber regNum = getVarReg(outVarToRegMap, varIndex);
12464                             interval         = getIntervalForLocalVar(varIndex);
12465                             assert(interval->physReg == regNum || (interval->physReg == REG_NA && regNum == REG_STK));
12466                             interval->physReg     = REG_NA;
12467                             interval->assignedReg = nullptr;
12468                             interval->isActive    = false;
12469                         }
12470                     }
12471
12472                     // Clear register assignments.
12473                     for (regNumber reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
12474                     {
12475                         RegRecord* physRegRecord        = getRegisterRecord(reg);
12476                         physRegRecord->assignedInterval = nullptr;
12477                     }
12478
12479                     // Now, record the locations at the beginning of this block.
12480                     currentBlock = moveToNextBlock();
12481                 }
12482
12483                 if (currentBlock != nullptr)
12484                 {
12485                     if (enregisterLocalVars)
12486                     {
12487                         VarToRegMap     inVarToRegMap = inVarToRegMaps[currentBlock->bbNum];
12488                         VarSetOps::Iter iter(compiler, currentBlock->bbLiveIn);
12489                         unsigned        varIndex = 0;
12490                         while (iter.NextElem(&varIndex))
12491                         {
12492                             if (localVarIntervals[varIndex] == nullptr)
12493                             {
12494                                 assert(!compiler->lvaTable[compiler->lvaTrackedToVarNum[varIndex]].lvLRACandidate);
12495                                 continue;
12496                             }
12497                             regNumber regNum                  = getVarReg(inVarToRegMap, varIndex);
12498                             interval                          = getIntervalForLocalVar(varIndex);
12499                             interval->physReg                 = regNum;
12500                             interval->assignedReg             = &(physRegs[regNum]);
12501                             interval->isActive                = true;
12502                             physRegs[regNum].assignedInterval = interval;
12503                         }
12504                     }
12505
12506                     if (VERBOSE)
12507                     {
12508                         dumpRefPositionShort(currentRefPosition, currentBlock);
12509                         dumpRegRecords();
12510                     }
12511
12512                     // Finally, handle the resolution moves, if any, at the beginning of the next block.
12513                     firstBlockEndResolutionNode = nullptr;
12514                     bool foundNonResolutionNode = false;
12515
12516                     LIR::Range& currentBlockRange = LIR::AsRange(currentBlock);
12517                     for (GenTree* node : currentBlockRange.NonPhiNodes())
12518                     {
12519                         if (IsResolutionNode(currentBlockRange, node))
12520                         {
12521                             assert(enregisterLocalVars);
12522                             if (foundNonResolutionNode)
12523                             {
12524                                 firstBlockEndResolutionNode = node;
12525                                 break;
12526                             }
12527                             else if (IsResolutionMove(node))
12528                             {
12529                                 // Only verify nodes that are actually moves; don't bother with the nodes that are
12530                                 // operands to moves.
12531                                 verifyResolutionMove(node, currentLocation);
12532                             }
12533                         }
12534                         else
12535                         {
12536                             foundNonResolutionNode = true;
12537                         }
12538                     }
12539                 }
12540             }
12541
12542             break;
12543
12544             case RefTypeKill:
12545                 assert(regRecord != nullptr);
12546                 assert(regRecord->assignedInterval == nullptr);
12547                 dumpLsraAllocationEvent(LSRA_EVENT_KEPT_ALLOCATION, nullptr, regRecord->regNum, currentBlock);
12548                 break;
12549             case RefTypeFixedReg:
12550                 assert(regRecord != nullptr);
12551                 dumpLsraAllocationEvent(LSRA_EVENT_KEPT_ALLOCATION, nullptr, regRecord->regNum, currentBlock);
12552                 break;
12553
12554             case RefTypeUpperVectorSaveDef:
12555             case RefTypeUpperVectorSaveUse:
12556             case RefTypeDef:
12557             case RefTypeUse:
12558             case RefTypeParamDef:
12559             case RefTypeZeroInit:
12560                 assert(interval != nullptr);
12561
12562                 if (interval->isSpecialPutArg)
12563                 {
12564                     dumpLsraAllocationEvent(LSRA_EVENT_SPECIAL_PUTARG, interval, regNum);
12565                     break;
12566                 }
12567                 if (currentRefPosition->reload)
12568                 {
12569                     interval->isActive = true;
12570                     assert(regNum != REG_NA);
12571                     interval->physReg           = regNum;
12572                     interval->assignedReg       = regRecord;
12573                     regRecord->assignedInterval = interval;
12574                     dumpLsraAllocationEvent(LSRA_EVENT_RELOAD, nullptr, regRecord->regNum, currentBlock);
12575                 }
12576                 if (regNum == REG_NA)
12577                 {
12578                     dumpLsraAllocationEvent(LSRA_EVENT_NO_REG_ALLOCATED, interval);
12579                 }
12580                 else if (RefTypeIsDef(currentRefPosition->refType))
12581                 {
12582                     interval->isActive = true;
12583                     if (VERBOSE)
12584                     {
12585                         if (interval->isConstant && (currentRefPosition->treeNode != nullptr) &&
12586                             currentRefPosition->treeNode->IsReuseRegVal())
12587                         {
12588                             dumpLsraAllocationEvent(LSRA_EVENT_REUSE_REG, nullptr, regRecord->regNum, currentBlock);
12589                         }
12590                         else
12591                         {
12592                             dumpLsraAllocationEvent(LSRA_EVENT_ALLOC_REG, nullptr, regRecord->regNum, currentBlock);
12593                         }
12594                     }
12595                 }
12596                 else if (currentRefPosition->copyReg)
12597                 {
12598                     dumpLsraAllocationEvent(LSRA_EVENT_COPY_REG, interval, regRecord->regNum, currentBlock);
12599                 }
12600                 else if (currentRefPosition->moveReg)
12601                 {
12602                     assert(interval->assignedReg != nullptr);
12603                     interval->assignedReg->assignedInterval = nullptr;
12604                     interval->physReg                       = regNum;
12605                     interval->assignedReg                   = regRecord;
12606                     regRecord->assignedInterval             = interval;
12607                     if (VERBOSE)
12608                     {
12609                         printf("Move  %-4s ", getRegName(regRecord->regNum));
12610                     }
12611                 }
12612                 else
12613                 {
12614                     dumpLsraAllocationEvent(LSRA_EVENT_KEPT_ALLOCATION, nullptr, regRecord->regNum, currentBlock);
12615                 }
12616                 if (currentRefPosition->lastUse || currentRefPosition->spillAfter)
12617                 {
12618                     interval->isActive = false;
12619                 }
12620                 if (regNum != REG_NA)
12621                 {
12622                     if (currentRefPosition->spillAfter)
12623                     {
12624                         if (VERBOSE)
12625                         {
12626                             // If refPos is marked as copyReg, then the reg that is spilled
12627                             // is the homeReg of the interval not the reg currently assigned
12628                             // to refPos.
12629                             regNumber spillReg = regNum;
12630                             if (currentRefPosition->copyReg)
12631                             {
12632                                 assert(interval != nullptr);
12633                                 spillReg = interval->physReg;
12634                             }
12635                             dumpRegRecords();
12636                             dumpEmptyRefPosition();
12637                             printf("Spill %-4s ", getRegName(spillReg));
12638                         }
12639                     }
12640                     else if (currentRefPosition->copyReg)
12641                     {
12642                         regRecord->assignedInterval = interval;
12643                     }
12644                     else
12645                     {
12646                         interval->physReg           = regNum;
12647                         interval->assignedReg       = regRecord;
12648                         regRecord->assignedInterval = interval;
12649                     }
12650                 }
12651                 break;
12652             case RefTypeKillGCRefs:
12653                 // No action to take.
12654                 // However, we will assert that, at resolution time, no registers contain GC refs.
12655                 {
12656                     DBEXEC(VERBOSE, printf("           "));
12657                     regMaskTP candidateRegs = currentRefPosition->registerAssignment;
12658                     while (candidateRegs != RBM_NONE)
12659                     {
12660                         regMaskTP nextRegBit = genFindLowestBit(candidateRegs);
12661                         candidateRegs &= ~nextRegBit;
12662                         regNumber  nextReg          = genRegNumFromMask(nextRegBit);
12663                         RegRecord* regRecord        = getRegisterRecord(nextReg);
12664                         Interval*  assignedInterval = regRecord->assignedInterval;
12665                         assert(assignedInterval == nullptr || !varTypeIsGC(assignedInterval->registerType));
12666                     }
12667                 }
12668                 break;
12669
12670             case RefTypeExpUse:
12671             case RefTypeDummyDef:
12672                 // Do nothing; these will be handled by the RefTypeBB.
12673                 DBEXEC(VERBOSE, printf("           "));
12674                 break;
12675
12676             case RefTypeInvalid:
12677                 // for these 'currentRefPosition->refType' values, No action to take
12678                 break;
12679         }
12680
12681         if (currentRefPosition->refType != RefTypeBB)
12682         {
12683             DBEXEC(VERBOSE, dumpRegRecords());
12684             if (interval != nullptr)
12685             {
12686                 if (currentRefPosition->copyReg)
12687                 {
12688                     assert(interval->physReg != regNum);
12689                     regRecord->assignedInterval = nullptr;
12690                     assert(interval->assignedReg != nullptr);
12691                     regRecord = interval->assignedReg;
12692                 }
12693                 if (currentRefPosition->spillAfter || currentRefPosition->lastUse)
12694                 {
12695                     interval->physReg     = REG_NA;
12696                     interval->assignedReg = nullptr;
12697
12698                     // regRegcord could be null if the RefPosition does not require a register.
12699                     if (regRecord != nullptr)
12700                     {
12701                         regRecord->assignedInterval = nullptr;
12702                     }
12703                     else
12704                     {
12705                         assert(!currentRefPosition->RequiresRegister());
12706                     }
12707                 }
12708             }
12709         }
12710     }
12711
12712     // Now, verify the resolution blocks.
12713     // Currently these are nearly always at the end of the method, but that may not alwyas be the case.
12714     // So, we'll go through all the BBs looking for blocks whose bbNum is greater than bbNumMaxBeforeResolution.
12715     for (BasicBlock* currentBlock = compiler->fgFirstBB; currentBlock != nullptr; currentBlock = currentBlock->bbNext)
12716     {
12717         if (currentBlock->bbNum > bbNumMaxBeforeResolution)
12718         {
12719             // If we haven't enregistered an lclVars, we have no resolution blocks.
12720             assert(enregisterLocalVars);
12721
12722             if (VERBOSE)
12723             {
12724                 dumpRegRecordTitle();
12725                 printf(shortRefPositionFormat, 0, 0);
12726                 assert(currentBlock->bbPreds != nullptr && currentBlock->bbPreds->flBlock != nullptr);
12727                 printf(bbRefPosFormat, currentBlock->bbNum, currentBlock->bbPreds->flBlock->bbNum);
12728                 dumpRegRecords();
12729             }
12730
12731             // Clear register assignments.
12732             for (regNumber reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
12733             {
12734                 RegRecord* physRegRecord        = getRegisterRecord(reg);
12735                 physRegRecord->assignedInterval = nullptr;
12736             }
12737
12738             // Set the incoming register assignments
12739             VarToRegMap     inVarToRegMap = getInVarToRegMap(currentBlock->bbNum);
12740             VarSetOps::Iter iter(compiler, currentBlock->bbLiveIn);
12741             unsigned        varIndex = 0;
12742             while (iter.NextElem(&varIndex))
12743             {
12744                 if (localVarIntervals[varIndex] == nullptr)
12745                 {
12746                     assert(!compiler->lvaTable[compiler->lvaTrackedToVarNum[varIndex]].lvLRACandidate);
12747                     continue;
12748                 }
12749                 regNumber regNum                  = getVarReg(inVarToRegMap, varIndex);
12750                 Interval* interval                = getIntervalForLocalVar(varIndex);
12751                 interval->physReg                 = regNum;
12752                 interval->assignedReg             = &(physRegs[regNum]);
12753                 interval->isActive                = true;
12754                 physRegs[regNum].assignedInterval = interval;
12755             }
12756
12757             // Verify the moves in this block
12758             LIR::Range& currentBlockRange = LIR::AsRange(currentBlock);
12759             for (GenTree* node : currentBlockRange.NonPhiNodes())
12760             {
12761                 assert(IsResolutionNode(currentBlockRange, node));
12762                 if (IsResolutionMove(node))
12763                 {
12764                     // Only verify nodes that are actually moves; don't bother with the nodes that are
12765                     // operands to moves.
12766                     verifyResolutionMove(node, currentLocation);
12767                 }
12768             }
12769
12770             // Verify the outgoing register assignments
12771             {
12772                 VarToRegMap     outVarToRegMap = getOutVarToRegMap(currentBlock->bbNum);
12773                 VarSetOps::Iter iter(compiler, currentBlock->bbLiveOut);
12774                 unsigned        varIndex = 0;
12775                 while (iter.NextElem(&varIndex))
12776                 {
12777                     if (localVarIntervals[varIndex] == nullptr)
12778                     {
12779                         assert(!compiler->lvaTable[compiler->lvaTrackedToVarNum[varIndex]].lvLRACandidate);
12780                         continue;
12781                     }
12782                     regNumber regNum   = getVarReg(outVarToRegMap, varIndex);
12783                     Interval* interval = getIntervalForLocalVar(varIndex);
12784                     assert(interval->physReg == regNum || (interval->physReg == REG_NA && regNum == REG_STK));
12785                     interval->physReg     = REG_NA;
12786                     interval->assignedReg = nullptr;
12787                     interval->isActive    = false;
12788                 }
12789             }
12790         }
12791     }
12792
12793     DBEXEC(VERBOSE, printf("\n"));
12794 }
12795
12796 //------------------------------------------------------------------------
12797 // verifyResolutionMove: Verify a resolution statement.  Called by verifyFinalAllocation()
12798 //
12799 // Arguments:
12800 //    resolutionMove    - A GenTree* that must be a resolution move.
12801 //    currentLocation   - The LsraLocation of the most recent RefPosition that has been verified.
12802 //
12803 // Return Value:
12804 //    None.
12805 //
12806 // Notes:
12807 //    If verbose is set, this will also dump the moves into the table of final allocations.
12808 void LinearScan::verifyResolutionMove(GenTree* resolutionMove, LsraLocation currentLocation)
12809 {
12810     GenTree* dst = resolutionMove;
12811     assert(IsResolutionMove(dst));
12812
12813     if (dst->OperGet() == GT_SWAP)
12814     {
12815         GenTreeLclVarCommon* left          = dst->gtGetOp1()->AsLclVarCommon();
12816         GenTreeLclVarCommon* right         = dst->gtGetOp2()->AsLclVarCommon();
12817         regNumber            leftRegNum    = left->gtRegNum;
12818         regNumber            rightRegNum   = right->gtRegNum;
12819         LclVarDsc*           leftVarDsc    = compiler->lvaTable + left->gtLclNum;
12820         LclVarDsc*           rightVarDsc   = compiler->lvaTable + right->gtLclNum;
12821         Interval*            leftInterval  = getIntervalForLocalVar(leftVarDsc->lvVarIndex);
12822         Interval*            rightInterval = getIntervalForLocalVar(rightVarDsc->lvVarIndex);
12823         assert(leftInterval->physReg == leftRegNum && rightInterval->physReg == rightRegNum);
12824         leftInterval->physReg                  = rightRegNum;
12825         rightInterval->physReg                 = leftRegNum;
12826         leftInterval->assignedReg              = &physRegs[rightRegNum];
12827         rightInterval->assignedReg             = &physRegs[leftRegNum];
12828         physRegs[rightRegNum].assignedInterval = leftInterval;
12829         physRegs[leftRegNum].assignedInterval  = rightInterval;
12830         if (VERBOSE)
12831         {
12832             printf(shortRefPositionFormat, currentLocation, 0);
12833             dumpIntervalName(leftInterval);
12834             printf("  Swap   ");
12835             printf("      %-4s ", getRegName(rightRegNum));
12836             dumpRegRecords();
12837             printf(shortRefPositionFormat, currentLocation, 0);
12838             dumpIntervalName(rightInterval);
12839             printf("  \"      ");
12840             printf("      %-4s ", getRegName(leftRegNum));
12841             dumpRegRecords();
12842         }
12843         return;
12844     }
12845     regNumber            dstRegNum = dst->gtRegNum;
12846     regNumber            srcRegNum;
12847     GenTreeLclVarCommon* lcl;
12848     if (dst->OperGet() == GT_COPY)
12849     {
12850         lcl       = dst->gtGetOp1()->AsLclVarCommon();
12851         srcRegNum = lcl->gtRegNum;
12852     }
12853     else
12854     {
12855         lcl = dst->AsLclVarCommon();
12856         if ((lcl->gtFlags & GTF_SPILLED) != 0)
12857         {
12858             srcRegNum = REG_STK;
12859         }
12860         else
12861         {
12862             assert((lcl->gtFlags & GTF_SPILL) != 0);
12863             srcRegNum = dstRegNum;
12864             dstRegNum = REG_STK;
12865         }
12866     }
12867
12868     Interval* interval = getIntervalForLocalVarNode(lcl);
12869     assert(interval->physReg == srcRegNum || (srcRegNum == REG_STK && interval->physReg == REG_NA));
12870     if (srcRegNum != REG_STK)
12871     {
12872         physRegs[srcRegNum].assignedInterval = nullptr;
12873     }
12874     if (dstRegNum != REG_STK)
12875     {
12876         interval->physReg                    = dstRegNum;
12877         interval->assignedReg                = &(physRegs[dstRegNum]);
12878         physRegs[dstRegNum].assignedInterval = interval;
12879         interval->isActive                   = true;
12880     }
12881     else
12882     {
12883         interval->physReg     = REG_NA;
12884         interval->assignedReg = nullptr;
12885         interval->isActive    = false;
12886     }
12887     if (VERBOSE)
12888     {
12889         printf(shortRefPositionFormat, currentLocation, 0);
12890         dumpIntervalName(interval);
12891         printf("  Move   ");
12892         printf("      %-4s ", getRegName(dstRegNum));
12893         dumpRegRecords();
12894     }
12895 }
12896 #endif // DEBUG
12897
12898 #endif // !LEGACY_BACKEND