Fix reading Time zone rules using Julian days (#17672)
[platform/upstream/coreclr.git] / src / jit / lsrabuild.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 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
6 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7 XX                                                                           XX
8 XX                    Interval and RefPosition Building                      XX
9 XX                                                                           XX
10 XX  This contains the logic for constructing Intervals and RefPositions that XX
11 XX  is common across architectures. See lsra{arch}.cpp for the architecture- XX
12 XX  specific methods for building.                                           XX
13 XX                                                                           XX
14 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
15 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
16 */
17
18 #include "jitpch.h"
19 #ifdef _MSC_VER
20 #pragma hdrstop
21 #endif
22
23 #ifndef LEGACY_BACKEND // This file is ONLY used for the RyuJIT backend that uses the linear scan register allocator
24
25 #include "lsra.h"
26
27 //------------------------------------------------------------------------
28 // LocationInfoListNodePool::LocationInfoListNodePool:
29 //    Creates a pool of `LocationInfoListNode` values.
30 //
31 // Arguments:
32 //    compiler    - The compiler context.
33 //    preallocate - The number of nodes to preallocate.
34 //
35 LocationInfoListNodePool::LocationInfoListNodePool(Compiler* compiler, unsigned preallocate) : m_compiler(compiler)
36 {
37     if (preallocate > 0)
38     {
39         size_t                preallocateSize = sizeof(LocationInfoListNode) * preallocate;
40         LocationInfoListNode* preallocatedNodes =
41             reinterpret_cast<LocationInfoListNode*>(compiler->compGetMem(preallocateSize, CMK_LSRA));
42
43         LocationInfoListNode* head = preallocatedNodes;
44         head->m_next               = nullptr;
45
46         for (unsigned i = 1; i < preallocate; i++)
47         {
48             LocationInfoListNode* node = &preallocatedNodes[i];
49             node->m_next               = head;
50             head                       = node;
51         }
52
53         m_freeList = head;
54     }
55 }
56
57 //------------------------------------------------------------------------
58 // LocationInfoListNodePool::GetNode: Fetches an unused node from the
59 //                                    pool.
60 //
61 // Arguments:
62 //    l -    - The `LsraLocation` for the `LocationInfo` value.
63 //    i      - The interval for the `LocationInfo` value.
64 //    t      - The IR node for the `LocationInfo` value
65 //    regIdx - The register index for the `LocationInfo` value.
66 //
67 // Returns:
68 //    A pooled or newly-allocated `LocationInfoListNode`, depending on the
69 //    contents of the pool.
70 LocationInfoListNode* LocationInfoListNodePool::GetNode(LsraLocation l, Interval* i, GenTree* t, unsigned regIdx)
71 {
72     LocationInfoListNode* head = m_freeList;
73     if (head == nullptr)
74     {
75         head = reinterpret_cast<LocationInfoListNode*>(m_compiler->compGetMem(sizeof(LocationInfoListNode)));
76     }
77     else
78     {
79         m_freeList = head->m_next;
80     }
81
82     head->loc      = l;
83     head->interval = i;
84     head->treeNode = t;
85     head->m_next   = nullptr;
86
87     return head;
88 }
89
90 //------------------------------------------------------------------------
91 // LocationInfoListNodePool::ReturnNodes: Returns a list of nodes to the node
92 //                                        pool and clears the given list.
93 //
94 // Arguments:
95 //    list - The list to return.
96 //
97 void LocationInfoListNodePool::ReturnNodes(LocationInfoList& list)
98 {
99     assert(list.m_head != nullptr);
100     assert(list.m_tail != nullptr);
101
102     LocationInfoListNode* head = m_freeList;
103     list.m_tail->m_next        = head;
104     m_freeList                 = list.m_head;
105
106     list.m_head = nullptr;
107     list.m_tail = nullptr;
108 }
109
110 //------------------------------------------------------------------------
111 // newInterval: Create a new Interval of the given RegisterType.
112 //
113 // Arguments:
114 //    theRegisterType - The type of Interval to create.
115 //
116 // TODO-Cleanup: Consider adding an overload that takes a varDsc, and can appropriately
117 // set such fields as isStructField
118 //
119 Interval* LinearScan::newInterval(RegisterType theRegisterType)
120 {
121     intervals.emplace_back(theRegisterType, allRegs(theRegisterType));
122     Interval* newInt = &intervals.back();
123
124 #ifdef DEBUG
125     newInt->intervalIndex = static_cast<unsigned>(intervals.size() - 1);
126 #endif // DEBUG
127
128     DBEXEC(VERBOSE, newInt->dump());
129     return newInt;
130 }
131
132 //------------------------------------------------------------------------
133 // newRefPositionRaw: Create a new RefPosition
134 //
135 // Arguments:
136 //    nodeLocation - The location of the reference.
137 //    treeNode     - The GenTree of the reference.
138 //    refType      - The type of reference
139 //
140 // Notes:
141 //    This is used to create RefPositions for both RegRecords and Intervals,
142 //    so it does only the common initialization.
143 //
144 RefPosition* LinearScan::newRefPositionRaw(LsraLocation nodeLocation, GenTree* treeNode, RefType refType)
145 {
146     refPositions.emplace_back(curBBNum, nodeLocation, treeNode, refType);
147     RefPosition* newRP = &refPositions.back();
148 #ifdef DEBUG
149     newRP->rpNum = static_cast<unsigned>(refPositions.size() - 1);
150 #endif // DEBUG
151     return newRP;
152 }
153
154 //------------------------------------------------------------------------
155 // resolveConflictingDefAndUse: Resolve the situation where we have conflicting def and use
156 //    register requirements on a single-def, single-use interval.
157 //
158 // Arguments:
159 //    defRefPosition - The interval definition
160 //    useRefPosition - The (sole) interval use
161 //
162 // Return Value:
163 //    None.
164 //
165 // Assumptions:
166 //    The two RefPositions are for the same interval, which is a tree-temp.
167 //
168 // Notes:
169 //    We require some special handling for the case where the use is a "delayRegFree" case of a fixedReg.
170 //    In that case, if we change the registerAssignment on the useRefPosition, we will lose the fact that,
171 //    even if we assign a different register (and rely on codegen to do the copy), that fixedReg also needs
172 //    to remain busy until the Def register has been allocated.  In that case, we don't allow Case 1 or Case 4
173 //    below.
174 //    Here are the cases we consider (in this order):
175 //    1. If The defRefPosition specifies a single register, and there are no conflicting
176 //       FixedReg uses of it between the def and use, we use that register, and the code generator
177 //       will insert the copy.  Note that it cannot be in use because there is a FixedRegRef for the def.
178 //    2. If the useRefPosition specifies a single register, and it is not in use, and there are no
179 //       conflicting FixedReg uses of it between the def and use, we use that register, and the code generator
180 //       will insert the copy.
181 //    3. If the defRefPosition specifies a single register (but there are conflicts, as determined
182 //       in 1.), and there are no conflicts with the useRefPosition register (if it's a single register),
183 ///      we set the register requirements on the defRefPosition to the use registers, and the
184 //       code generator will insert a copy on the def.  We can't rely on the code generator to put a copy
185 //       on the use if it has multiple possible candidates, as it won't know which one has been allocated.
186 //    4. If the useRefPosition specifies a single register, and there are no conflicts with the register
187 //       on the defRefPosition, we leave the register requirements on the defRefPosition as-is, and set
188 //       the useRefPosition to the def registers, for similar reasons to case #3.
189 //    5. If both the defRefPosition and the useRefPosition specify single registers, but both have conflicts,
190 //       We set the candiates on defRefPosition to be all regs of the appropriate type, and since they are
191 //       single registers, codegen can insert the copy.
192 //    6. Finally, if the RefPositions specify disjoint subsets of the registers (or the use is fixed but
193 //       has a conflict), we must insert a copy.  The copy will be inserted before the use if the
194 //       use is not fixed (in the fixed case, the code generator will insert the use).
195 //
196 // TODO-CQ: We get bad register allocation in case #3 in the situation where no register is
197 // available for the lifetime.  We end up allocating a register that must be spilled, and it probably
198 // won't be the register that is actually defined by the target instruction.  So, we have to copy it
199 // and THEN spill it.  In this case, we should be using the def requirement.  But we need to change
200 // the interface to this method a bit to make that work (e.g. returning a candidate set to use, but
201 // leaving the registerAssignment as-is on the def, so that if we find that we need to spill anyway
202 // we can use the fixed-reg on the def.
203 //
204
205 void LinearScan::resolveConflictingDefAndUse(Interval* interval, RefPosition* defRefPosition)
206 {
207     assert(!interval->isLocalVar);
208
209     RefPosition* useRefPosition   = defRefPosition->nextRefPosition;
210     regMaskTP    defRegAssignment = defRefPosition->registerAssignment;
211     regMaskTP    useRegAssignment = useRefPosition->registerAssignment;
212     RegRecord*   defRegRecord     = nullptr;
213     RegRecord*   useRegRecord     = nullptr;
214     regNumber    defReg           = REG_NA;
215     regNumber    useReg           = REG_NA;
216     bool         defRegConflict   = false;
217     bool         useRegConflict   = false;
218
219     // If the useRefPosition is a "delayRegFree", we can't change the registerAssignment
220     // on it, or we will fail to ensure that the fixedReg is busy at the time the target
221     // (of the node that uses this interval) is allocated.
222     bool canChangeUseAssignment = !useRefPosition->isFixedRegRef || !useRefPosition->delayRegFree;
223
224     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CONFLICT));
225     if (!canChangeUseAssignment)
226     {
227         INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_FIXED_DELAY_USE));
228     }
229     if (defRefPosition->isFixedRegRef)
230     {
231         defReg       = defRefPosition->assignedReg();
232         defRegRecord = getRegisterRecord(defReg);
233         if (canChangeUseAssignment)
234         {
235             RefPosition* currFixedRegRefPosition = defRegRecord->recentRefPosition;
236             assert(currFixedRegRefPosition != nullptr &&
237                    currFixedRegRefPosition->nodeLocation == defRefPosition->nodeLocation);
238
239             if (currFixedRegRefPosition->nextRefPosition == nullptr ||
240                 currFixedRegRefPosition->nextRefPosition->nodeLocation > useRefPosition->getRefEndLocation())
241             {
242                 // This is case #1.  Use the defRegAssignment
243                 INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CASE1));
244                 useRefPosition->registerAssignment = defRegAssignment;
245                 return;
246             }
247             else
248             {
249                 defRegConflict = true;
250             }
251         }
252     }
253     if (useRefPosition->isFixedRegRef)
254     {
255         useReg                               = useRefPosition->assignedReg();
256         useRegRecord                         = getRegisterRecord(useReg);
257         RefPosition* currFixedRegRefPosition = useRegRecord->recentRefPosition;
258
259         // We know that useRefPosition is a fixed use, so the nextRefPosition must not be null.
260         RefPosition* nextFixedRegRefPosition = useRegRecord->getNextRefPosition();
261         assert(nextFixedRegRefPosition != nullptr &&
262                nextFixedRegRefPosition->nodeLocation <= useRefPosition->nodeLocation);
263
264         // First, check to see if there are any conflicting FixedReg references between the def and use.
265         if (nextFixedRegRefPosition->nodeLocation == useRefPosition->nodeLocation)
266         {
267             // OK, no conflicting FixedReg references.
268             // Now, check to see whether it is currently in use.
269             if (useRegRecord->assignedInterval != nullptr)
270             {
271                 RefPosition* possiblyConflictingRef         = useRegRecord->assignedInterval->recentRefPosition;
272                 LsraLocation possiblyConflictingRefLocation = possiblyConflictingRef->getRefEndLocation();
273                 if (possiblyConflictingRefLocation >= defRefPosition->nodeLocation)
274                 {
275                     useRegConflict = true;
276                 }
277             }
278             if (!useRegConflict)
279             {
280                 // This is case #2.  Use the useRegAssignment
281                 INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CASE2));
282                 defRefPosition->registerAssignment = useRegAssignment;
283                 return;
284             }
285         }
286         else
287         {
288             useRegConflict = true;
289         }
290     }
291     if (defRegRecord != nullptr && !useRegConflict)
292     {
293         // This is case #3.
294         INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CASE3));
295         defRefPosition->registerAssignment = useRegAssignment;
296         return;
297     }
298     if (useRegRecord != nullptr && !defRegConflict && canChangeUseAssignment)
299     {
300         // This is case #4.
301         INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CASE4));
302         useRefPosition->registerAssignment = defRegAssignment;
303         return;
304     }
305     if (defRegRecord != nullptr && useRegRecord != nullptr)
306     {
307         // This is case #5.
308         INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CASE5));
309         RegisterType regType = interval->registerType;
310         assert((getRegisterType(interval, defRefPosition) == regType) &&
311                (getRegisterType(interval, useRefPosition) == regType));
312         regMaskTP candidates               = allRegs(regType);
313         defRefPosition->registerAssignment = candidates;
314         return;
315     }
316     INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_DEFUSE_CASE6));
317     return;
318 }
319
320 //------------------------------------------------------------------------
321 // applyCalleeSaveHeuristics: Set register preferences for an interval based on the given RefPosition
322 //
323 // Arguments:
324 //    rp - The RefPosition of interest
325 //
326 // Notes:
327 //    This is slightly more general than its name applies, and updates preferences not just
328 //    for callee-save registers.
329 //
330 void LinearScan::applyCalleeSaveHeuristics(RefPosition* rp)
331 {
332 #ifdef _TARGET_AMD64_
333     if (compiler->opts.compDbgEnC)
334     {
335         // We only use RSI and RDI for EnC code, so we don't want to favor callee-save regs.
336         return;
337     }
338 #endif // _TARGET_AMD64_
339
340     Interval* theInterval = rp->getInterval();
341
342 #ifdef DEBUG
343     if (!doReverseCallerCallee())
344 #endif // DEBUG
345     {
346         // Set preferences so that this register set will be preferred for earlier refs
347         theInterval->updateRegisterPreferences(rp->registerAssignment);
348     }
349 }
350
351 //------------------------------------------------------------------------
352 // checkConflictingDefUse: Ensure that we have consistent def/use on SDSU temps.
353 //
354 // Arguments:
355 //    useRP - The use RefPosition of a tree temp (SDSU Interval)
356 //
357 // Notes:
358 //    There are a couple of cases where this may over-constrain allocation:
359 //    1. In the case of a non-commutative rmw def (in which the rmw source must be delay-free), or
360 //    2. In the case where the defining node requires a temp distinct from the target (also a
361 //       delay-free case).
362 //    In those cases, if we propagate a single-register restriction from the consumer to the producer
363 //    the delayed uses will not see a fixed reference in the PhysReg at that position, and may
364 //    incorrectly allocate that register.
365 //    TODO-CQ: This means that we may often require a copy at the use of this node's result.
366 //    This case could be moved to BuildRefPositionsForNode, at the point where the def RefPosition is
367 //    created, causing a RefTypeFixedRef to be added at that location. This, however, results in
368 //    more PhysReg RefPositions (a throughput impact), and a large number of diffs that require
369 //    further analysis to determine benefit.
370 //    See Issue #11274.
371 //
372 void LinearScan::checkConflictingDefUse(RefPosition* useRP)
373 {
374     assert(useRP->refType == RefTypeUse);
375     Interval* theInterval = useRP->getInterval();
376     assert(!theInterval->isLocalVar);
377
378     RefPosition* defRP = theInterval->firstRefPosition;
379
380     // All defs must have a valid treeNode, but we check it below to be conservative.
381     assert(defRP->treeNode != nullptr);
382     regMaskTP prevAssignment = defRP->registerAssignment;
383     regMaskTP newAssignment  = (prevAssignment & useRP->registerAssignment);
384     if (newAssignment != RBM_NONE)
385     {
386         if (!isSingleRegister(newAssignment) || !theInterval->hasInterferingUses)
387         {
388             defRP->registerAssignment = newAssignment;
389         }
390     }
391     else
392     {
393         theInterval->hasConflictingDefUse = true;
394     }
395 }
396
397 //------------------------------------------------------------------------
398 // associateRefPosWithInterval: Update the Interval based on the given RefPosition.
399 //
400 // Arguments:
401 //    rp - The RefPosition of interest
402 //
403 // Notes:
404 //    This is called at the time when 'rp' has just been created, so it becomes
405 //    the nextRefPosition of the recentRefPosition, and both the recentRefPosition
406 //    and lastRefPosition of its referent.
407 //
408 void LinearScan::associateRefPosWithInterval(RefPosition* rp)
409 {
410     Referenceable* theReferent = rp->referent;
411
412     if (theReferent != nullptr)
413     {
414         // All RefPositions except the dummy ones at the beginning of blocks
415
416         if (rp->isIntervalRef())
417         {
418             Interval* theInterval = rp->getInterval();
419
420             applyCalleeSaveHeuristics(rp);
421
422             if (theInterval->isLocalVar)
423             {
424                 if (RefTypeIsUse(rp->refType))
425                 {
426                     RefPosition* const prevRP = theInterval->recentRefPosition;
427                     if ((prevRP != nullptr) && (prevRP->bbNum == rp->bbNum))
428                     {
429                         prevRP->lastUse = false;
430                     }
431                 }
432
433                 rp->lastUse = (rp->refType != RefTypeExpUse) && (rp->refType != RefTypeParamDef) &&
434                               (rp->refType != RefTypeZeroInit) && !extendLifetimes();
435             }
436             else if (rp->refType == RefTypeUse)
437             {
438                 checkConflictingDefUse(rp);
439                 rp->lastUse = true;
440             }
441         }
442
443         RefPosition* prevRP = theReferent->recentRefPosition;
444         if (prevRP != nullptr)
445         {
446             prevRP->nextRefPosition = rp;
447         }
448         else
449         {
450             theReferent->firstRefPosition = rp;
451         }
452         theReferent->recentRefPosition = rp;
453         theReferent->lastRefPosition   = rp;
454     }
455     else
456     {
457         assert((rp->refType == RefTypeBB) || (rp->refType == RefTypeKillGCRefs));
458     }
459 }
460
461 //---------------------------------------------------------------------------
462 // newRefPosition: allocate and initialize a new RefPosition.
463 //
464 // Arguments:
465 //     reg             -  reg number that identifies RegRecord to be associated
466 //                        with this RefPosition
467 //     theLocation     -  LSRA location of RefPosition
468 //     theRefType      -  RefPosition type
469 //     theTreeNode     -  GenTree node for which this RefPosition is created
470 //     mask            -  Set of valid registers for this RefPosition
471 //     multiRegIdx     -  register position if this RefPosition corresponds to a
472 //                        multi-reg call node.
473 //
474 // Return Value:
475 //     a new RefPosition
476 //
477 RefPosition* LinearScan::newRefPosition(
478     regNumber reg, LsraLocation theLocation, RefType theRefType, GenTree* theTreeNode, regMaskTP mask)
479 {
480     RefPosition* newRP = newRefPositionRaw(theLocation, theTreeNode, theRefType);
481
482     newRP->setReg(getRegisterRecord(reg));
483     newRP->registerAssignment = mask;
484
485     newRP->setMultiRegIdx(0);
486     newRP->setAllocateIfProfitable(false);
487
488     associateRefPosWithInterval(newRP);
489
490     DBEXEC(VERBOSE, newRP->dump());
491     return newRP;
492 }
493
494 //---------------------------------------------------------------------------
495 // newRefPosition: allocate and initialize a new RefPosition.
496 //
497 // Arguments:
498 //     theInterval     -  interval to which RefPosition is associated with.
499 //     theLocation     -  LSRA location of RefPosition
500 //     theRefType      -  RefPosition type
501 //     theTreeNode     -  GenTree node for which this RefPosition is created
502 //     mask            -  Set of valid registers for this RefPosition
503 //     multiRegIdx     -  register position if this RefPosition corresponds to a
504 //                        multi-reg call node.
505 //
506 // Return Value:
507 //     a new RefPosition
508 //
509 RefPosition* LinearScan::newRefPosition(Interval*    theInterval,
510                                         LsraLocation theLocation,
511                                         RefType      theRefType,
512                                         GenTree*     theTreeNode,
513                                         regMaskTP    mask,
514                                         unsigned     multiRegIdx /* = 0 */)
515 {
516 #ifdef DEBUG
517     if (theInterval != nullptr && regType(theInterval->registerType) == FloatRegisterType)
518     {
519         // In the case we're using floating point registers we must make sure
520         // this flag was set previously in the compiler since this will mandate
521         // whether LSRA will take into consideration FP reg killsets.
522         assert(compiler->compFloatingPointUsed || ((mask & RBM_FLT_CALLEE_SAVED) == 0));
523     }
524 #endif // DEBUG
525
526     // If this reference is constrained to a single register (and it's not a dummy
527     // or Kill reftype already), add a RefTypeFixedReg at this location so that its
528     // availability can be more accurately determined
529
530     bool isFixedRegister = isSingleRegister(mask);
531     bool insertFixedRef  = false;
532     if (isFixedRegister)
533     {
534         // Insert a RefTypeFixedReg for any normal def or use (not ParamDef or BB)
535         if (theRefType == RefTypeUse || theRefType == RefTypeDef)
536         {
537             insertFixedRef = true;
538         }
539     }
540
541     if (insertFixedRef)
542     {
543         regNumber    physicalReg = genRegNumFromMask(mask);
544         RefPosition* pos         = newRefPosition(physicalReg, theLocation, RefTypeFixedReg, nullptr, mask);
545         assert(theInterval != nullptr);
546         assert((allRegs(theInterval->registerType) & mask) != 0);
547     }
548
549     RefPosition* newRP = newRefPositionRaw(theLocation, theTreeNode, theRefType);
550
551     newRP->setInterval(theInterval);
552
553     // Spill info
554     newRP->isFixedRegRef = isFixedRegister;
555
556 #ifndef _TARGET_AMD64_
557     // We don't need this for AMD because the PInvoke method epilog code is explicit
558     // at register allocation time.
559     if (theInterval != nullptr && theInterval->isLocalVar && compiler->info.compCallUnmanaged &&
560         theInterval->varNum == compiler->genReturnLocal)
561     {
562         mask &= ~(RBM_PINVOKE_TCB | RBM_PINVOKE_FRAME);
563         noway_assert(mask != RBM_NONE);
564     }
565 #endif // !_TARGET_AMD64_
566     newRP->registerAssignment = mask;
567
568     newRP->setMultiRegIdx(multiRegIdx);
569     newRP->setAllocateIfProfitable(false);
570
571     associateRefPosWithInterval(newRP);
572
573     DBEXEC(VERBOSE, newRP->dump());
574     return newRP;
575 }
576
577 //------------------------------------------------------------------------
578 // IsContainableMemoryOp: Checks whether this is a memory op that can be contained.
579 //
580 // Arguments:
581 //    node        - the node of interest.
582 //
583 // Return value:
584 //    True if this will definitely be a memory reference that could be contained.
585 //
586 // Notes:
587 //    This differs from the isMemoryOp() method on GenTree because it checks for
588 //    the case of doNotEnregister local. This won't include locals that
589 //    for some other reason do not become register candidates, nor those that get
590 //    spilled.
591 //    Also, because we usually call this before we redo dataflow, any new lclVars
592 //    introduced after the last dataflow analysis will not yet be marked lvTracked,
593 //    so we don't use that.
594 //
595 bool LinearScan::isContainableMemoryOp(GenTree* node)
596 {
597     if (node->isMemoryOp())
598     {
599         return true;
600     }
601     if (node->IsLocal())
602     {
603         if (!enregisterLocalVars)
604         {
605             return true;
606         }
607         LclVarDsc* varDsc = &compiler->lvaTable[node->AsLclVar()->gtLclNum];
608         return varDsc->lvDoNotEnregister;
609     }
610     return false;
611 }
612
613 //------------------------------------------------------------------------
614 // addRefsForPhysRegMask: Adds RefPositions of the given type for all the registers in 'mask'.
615 //
616 // Arguments:
617 //    mask        - the mask (set) of registers.
618 //    currentLoc  - the location at which they should be added
619 //    refType     - the type of refposition
620 //    isLastUse   - true IFF this is a last use of the register
621 //
622 void LinearScan::addRefsForPhysRegMask(regMaskTP mask, LsraLocation currentLoc, RefType refType, bool isLastUse)
623 {
624     for (regNumber reg = REG_FIRST; mask; reg = REG_NEXT(reg), mask >>= 1)
625     {
626         if (mask & 1)
627         {
628             // This assumes that these are all "special" RefTypes that
629             // don't need to be recorded on the tree (hence treeNode is nullptr)
630             RefPosition* pos = newRefPosition(reg, currentLoc, refType, nullptr,
631                                               genRegMask(reg)); // This MUST occupy the physical register (obviously)
632
633             if (isLastUse)
634             {
635                 pos->lastUse = true;
636             }
637         }
638     }
639 }
640
641 //------------------------------------------------------------------------
642 // getKillSetForStoreInd: Determine the liveness kill set for a GT_STOREIND node.
643 // If the GT_STOREIND will generate a write barrier, determine the specific kill
644 // set required by the case-specific, platform-specific write barrier. If no
645 // write barrier is required, the kill set will be RBM_NONE.
646 //
647 // Arguments:
648 //    tree - the GT_STOREIND node
649 //
650 // Return Value:    a register mask of the registers killed
651 //
652 regMaskTP LinearScan::getKillSetForStoreInd(GenTreeStoreInd* tree)
653 {
654     assert(tree->OperIs(GT_STOREIND));
655
656     regMaskTP killMask = RBM_NONE;
657
658     GenTree* data = tree->Data();
659
660     GCInfo::WriteBarrierForm writeBarrierForm = compiler->codeGen->gcInfo.gcIsWriteBarrierCandidate(tree, data);
661     if (writeBarrierForm != GCInfo::WBF_NoBarrier)
662     {
663         if (compiler->codeGen->genUseOptimizedWriteBarriers(writeBarrierForm))
664         {
665             // We can't determine the exact helper to be used at this point, because it depends on
666             // the allocated register for the `data` operand. However, all the (x86) optimized
667             // helpers have the same kill set: EDX. And note that currently, only x86 can return
668             // `true` for genUseOptimizedWriteBarriers().
669             killMask = RBM_CALLEE_TRASH_NOGC;
670         }
671         else
672         {
673             // Figure out which helper we're going to use, and then get the kill set for that helper.
674             CorInfoHelpFunc helper =
675                 compiler->codeGen->genWriteBarrierHelperForWriteBarrierForm(tree, writeBarrierForm);
676             killMask = compiler->compHelperCallKillSet(helper);
677         }
678     }
679
680     return killMask;
681 }
682
683 //------------------------------------------------------------------------
684 // getKillSetForNode:   Return the registers killed by the given tree node.
685 //
686 // Arguments:
687 //    compiler   - the compiler context to use
688 //    tree       - the tree for which the kill set is needed.
689 //
690 // Return Value:    a register mask of the registers killed
691 //
692 regMaskTP LinearScan::getKillSetForNode(GenTree* tree)
693 {
694     regMaskTP killMask = RBM_NONE;
695     switch (tree->OperGet())
696     {
697 #ifdef _TARGET_XARCH_
698         case GT_MUL:
699             // We use the 128-bit multiply when performing an overflow checking unsigned multiply
700             //
701             if (((tree->gtFlags & GTF_UNSIGNED) != 0) && tree->gtOverflowEx())
702             {
703                 // Both RAX and RDX are killed by the operation
704                 killMask = RBM_RAX | RBM_RDX;
705             }
706             break;
707
708         case GT_MULHI:
709 #if defined(_TARGET_X86_) && !defined(LEGACY_BACKEND)
710         case GT_MUL_LONG:
711 #endif
712             killMask = RBM_RAX | RBM_RDX;
713             break;
714
715         case GT_MOD:
716         case GT_DIV:
717         case GT_UMOD:
718         case GT_UDIV:
719             if (!varTypeIsFloating(tree->TypeGet()))
720             {
721                 // Both RAX and RDX are killed by the operation
722                 killMask = RBM_RAX | RBM_RDX;
723             }
724             break;
725 #endif // _TARGET_XARCH_
726
727         case GT_STORE_OBJ:
728             if (tree->OperIsCopyBlkOp())
729             {
730                 assert(tree->AsObj()->gtGcPtrCount != 0);
731                 killMask = compiler->compHelperCallKillSet(CORINFO_HELP_ASSIGN_BYREF);
732                 break;
733             }
734             __fallthrough;
735
736         case GT_STORE_BLK:
737         case GT_STORE_DYN_BLK:
738         {
739             GenTreeBlk* blkNode   = tree->AsBlk();
740             bool        isCopyBlk = varTypeIsStruct(blkNode->Data());
741             switch (blkNode->gtBlkOpKind)
742             {
743                 case GenTreeBlk::BlkOpKindHelper:
744                     if (isCopyBlk)
745                     {
746                         killMask = compiler->compHelperCallKillSet(CORINFO_HELP_MEMCPY);
747                     }
748                     else
749                     {
750                         killMask = compiler->compHelperCallKillSet(CORINFO_HELP_MEMSET);
751                     }
752                     break;
753
754 #ifdef _TARGET_XARCH_
755                 case GenTreeBlk::BlkOpKindRepInstr:
756                     if (isCopyBlk)
757                     {
758                         // rep movs kills RCX, RDI and RSI
759                         killMask = RBM_RCX | RBM_RDI | RBM_RSI;
760                     }
761                     else
762                     {
763                         // rep stos kills RCX and RDI.
764                         // (Note that the Data() node, if not constant, will be assigned to
765                         // RCX, but it's find that this kills it, as the value is not available
766                         // after this node in any case.)
767                         killMask = RBM_RDI | RBM_RCX;
768                     }
769                     break;
770 #else
771                 case GenTreeBlk::BlkOpKindRepInstr:
772 #endif
773                 case GenTreeBlk::BlkOpKindUnroll:
774                 case GenTreeBlk::BlkOpKindInvalid:
775                     // for these 'gtBlkOpKind' kinds, we leave 'killMask' = RBM_NONE
776                     break;
777             }
778         }
779         break;
780
781         case GT_RETURNTRAP:
782             killMask = compiler->compHelperCallKillSet(CORINFO_HELP_STOP_FOR_GC);
783             break;
784         case GT_CALL:
785 #ifdef _TARGET_X86_
786             if (compiler->compFloatingPointUsed)
787             {
788                 if (tree->TypeGet() == TYP_DOUBLE)
789                 {
790                     needDoubleTmpForFPCall = true;
791                 }
792                 else if (tree->TypeGet() == TYP_FLOAT)
793                 {
794                     needFloatTmpForFPCall = true;
795                 }
796             }
797 #endif // _TARGET_X86_
798 #if defined(_TARGET_X86_) || defined(_TARGET_ARM_)
799             if (tree->IsHelperCall())
800             {
801                 GenTreeCall*    call     = tree->AsCall();
802                 CorInfoHelpFunc helpFunc = compiler->eeGetHelperNum(call->gtCallMethHnd);
803                 killMask                 = compiler->compHelperCallKillSet(helpFunc);
804             }
805             else
806 #endif // defined(_TARGET_X86_) || defined(_TARGET_ARM_)
807             {
808                 // if there is no FP used, we can ignore the FP kills
809                 if (compiler->compFloatingPointUsed)
810                 {
811                     killMask = RBM_CALLEE_TRASH;
812                 }
813                 else
814                 {
815                     killMask = RBM_INT_CALLEE_TRASH;
816                 }
817 #ifdef _TARGET_ARM_
818                 if (tree->AsCall()->IsVirtualStub())
819                 {
820                     killMask |= compiler->virtualStubParamInfo->GetRegMask();
821                 }
822 #else // !_TARGET_ARM_
823             // Verify that the special virtual stub call registers are in the kill mask.
824             // We don't just add them unconditionally to the killMask because for most architectures
825             // they are already in the RBM_CALLEE_TRASH set,
826             // and we don't want to introduce extra checks and calls in this hot function.
827             assert(!tree->AsCall()->IsVirtualStub() || ((killMask & compiler->virtualStubParamInfo->GetRegMask()) ==
828                                                         compiler->virtualStubParamInfo->GetRegMask()));
829 #endif
830             }
831             break;
832         case GT_STOREIND:
833             killMask = getKillSetForStoreInd(tree->AsStoreInd());
834             break;
835
836 #if defined(PROFILING_SUPPORTED)
837         // If this method requires profiler ELT hook then mark these nodes as killing
838         // callee trash registers (excluding RAX and XMM0). The reason for this is that
839         // profiler callback would trash these registers. See vm\amd64\asmhelpers.asm for
840         // more details.
841         case GT_RETURN:
842             if (compiler->compIsProfilerHookNeeded())
843             {
844                 killMask = compiler->compHelperCallKillSet(CORINFO_HELP_PROF_FCN_LEAVE);
845             }
846             break;
847
848         case GT_PROF_HOOK:
849             if (compiler->compIsProfilerHookNeeded())
850             {
851                 killMask = compiler->compHelperCallKillSet(CORINFO_HELP_PROF_FCN_TAILCALL);
852             }
853             break;
854 #endif // PROFILING_SUPPORTED
855
856         default:
857             // for all other 'tree->OperGet()' kinds, leave 'killMask' = RBM_NONE
858             break;
859     }
860     return killMask;
861 }
862
863 //------------------------------------------------------------------------
864 // buildKillPositionsForNode:
865 // Given some tree node add refpositions for all the registers this node kills
866 //
867 // Arguments:
868 //    tree       - the tree for which kill positions should be generated
869 //    currentLoc - the location at which the kills should be added
870 //
871 // Return Value:
872 //    true       - kills were inserted
873 //    false      - no kills were inserted
874 //
875 // Notes:
876 //    The return value is needed because if we have any kills, we need to make sure that
877 //    all defs are located AFTER the kills.  On the other hand, if there aren't kills,
878 //    the multiple defs for a regPair are in different locations.
879 //    If we generate any kills, we will mark all currentLiveVars as being preferenced
880 //    to avoid the killed registers.  This is somewhat conservative.
881
882 bool LinearScan::buildKillPositionsForNode(GenTree* tree, LsraLocation currentLoc)
883 {
884     regMaskTP killMask   = getKillSetForNode(tree);
885     bool      isCallKill = ((killMask == RBM_INT_CALLEE_TRASH) || (killMask == RBM_CALLEE_TRASH));
886     if (killMask != RBM_NONE)
887     {
888         // The killMask identifies a set of registers that will be used during codegen.
889         // Mark these as modified here, so when we do final frame layout, we'll know about
890         // all these registers. This is especially important if killMask contains
891         // callee-saved registers, which affect the frame size since we need to save/restore them.
892         // In the case where we have a copyBlk with GC pointers, can need to call the
893         // CORINFO_HELP_ASSIGN_BYREF helper, which kills callee-saved RSI and RDI, if
894         // LSRA doesn't assign RSI/RDI, they wouldn't get marked as modified until codegen,
895         // which is too late.
896         compiler->codeGen->regSet.rsSetRegsModified(killMask DEBUGARG(true));
897
898         addRefsForPhysRegMask(killMask, currentLoc, RefTypeKill, true);
899
900         // TODO-CQ: It appears to be valuable for both fp and int registers to avoid killing the callee
901         // save regs on infrequently exectued paths.  However, it results in a large number of asmDiffs,
902         // many of which appear to be regressions (because there is more spill on the infrequently path),
903         // but are not really because the frequent path becomes smaller.  Validating these diffs will need
904         // to be done before making this change.
905         // if (!blockSequence[curBBSeqNum]->isRunRarely())
906         if (enregisterLocalVars)
907         {
908             VarSetOps::Iter iter(compiler, currentLiveVars);
909             unsigned        varIndex = 0;
910             while (iter.NextElem(&varIndex))
911             {
912                 unsigned   varNum = compiler->lvaTrackedToVarNum[varIndex];
913                 LclVarDsc* varDsc = compiler->lvaTable + varNum;
914 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
915                 if (varTypeNeedsPartialCalleeSave(varDsc->lvType))
916                 {
917                     if (!VarSetOps::IsMember(compiler, largeVectorCalleeSaveCandidateVars, varIndex))
918                     {
919                         continue;
920                     }
921                 }
922                 else
923 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
924                     if (varTypeIsFloating(varDsc) &&
925                         !VarSetOps::IsMember(compiler, fpCalleeSaveCandidateVars, varIndex))
926                 {
927                     continue;
928                 }
929                 Interval* interval = getIntervalForLocalVar(varIndex);
930                 if (isCallKill)
931                 {
932                     interval->preferCalleeSave = true;
933                 }
934                 regMaskTP newPreferences = allRegs(interval->registerType) & (~killMask);
935
936                 if (newPreferences != RBM_NONE)
937                 {
938                     interval->updateRegisterPreferences(newPreferences);
939                 }
940                 else
941                 {
942                     // If there are no callee-saved registers, the call could kill all the registers.
943                     // This is a valid state, so in that case assert should not trigger. The RA will spill in order to
944                     // free a register later.
945                     assert(compiler->opts.compDbgEnC || (calleeSaveRegs(varDsc->lvType)) == RBM_NONE);
946                 }
947             }
948         }
949
950         if (compiler->killGCRefs(tree))
951         {
952             RefPosition* pos = newRefPosition((Interval*)nullptr, currentLoc, RefTypeKillGCRefs, tree,
953                                               (allRegs(TYP_REF) & ~RBM_ARG_REGS));
954         }
955         return true;
956     }
957
958     return false;
959 }
960
961 //----------------------------------------------------------------------------
962 // defineNewInternalTemp: Defines a ref position for an internal temp.
963 //
964 // Arguments:
965 //     tree                  -   Gentree node requiring an internal register
966 //     regType               -   Register type
967 //     currentLoc            -   Location of the temp Def position
968 //     regMask               -   register mask of candidates for temp
969 //
970 RefPosition* LinearScan::defineNewInternalTemp(GenTree* tree, RegisterType regType, regMaskTP regMask)
971 {
972     Interval* current   = newInterval(regType);
973     current->isInternal = true;
974     return newRefPosition(current, currentLoc, RefTypeDef, tree, regMask, 0);
975 }
976
977 //------------------------------------------------------------------------
978 // buildInternalRegisterDefsForNode - build Def positions for internal
979 // registers required for tree node.
980 //
981 // Arguments:
982 //   tree                  -   Gentree node that needs internal registers
983 //   temps                 -   in-out array which is populated with ref positions
984 //                             created for Def of internal registers
985 //
986 // Returns:
987 //   The total number of Def positions created for internal registers of tree no.
988 int LinearScan::buildInternalRegisterDefsForNode(GenTree* tree, TreeNodeInfo* info, RefPosition* temps[])
989 {
990     int       count;
991     int       internalIntCount = info->internalIntCount;
992     regMaskTP internalCands    = info->getInternalCandidates(this);
993
994     // If the number of internal integer registers required is the same as the number of candidate integer registers in
995     // the candidate set, then they must be handled as fixed registers.
996     // (E.g. for the integer registers that floating point arguments must be copied into for a varargs call.)
997     bool      fixedRegs             = false;
998     regMaskTP internalIntCandidates = (internalCands & allRegs(TYP_INT));
999     if (((int)genCountBits(internalIntCandidates)) == internalIntCount)
1000     {
1001         fixedRegs = true;
1002     }
1003
1004     for (count = 0; count < internalIntCount; count++)
1005     {
1006         regMaskTP internalIntCands = (internalCands & allRegs(TYP_INT));
1007         if (fixedRegs)
1008         {
1009             internalIntCands = genFindLowestBit(internalIntCands);
1010             internalCands &= ~internalIntCands;
1011         }
1012         temps[count] = defineNewInternalTemp(tree, IntRegisterType, internalIntCands);
1013     }
1014
1015     int internalFloatCount = info->internalFloatCount;
1016     for (int i = 0; i < internalFloatCount; i++)
1017     {
1018         regMaskTP internalFPCands = (internalCands & internalFloatRegCandidates());
1019         temps[count++]            = defineNewInternalTemp(tree, FloatRegisterType, internalFPCands);
1020     }
1021
1022     assert(count < MaxInternalRegisters);
1023     assert(count == (internalIntCount + internalFloatCount));
1024     return count;
1025 }
1026
1027 //------------------------------------------------------------------------
1028 // buildInternalRegisterUsesForNode - adds Use positions for internal
1029 // registers required for tree node.
1030 //
1031 // Arguments:
1032 //   tree                  -   Gentree node that needs internal registers
1033 //   defs                  -   int array containing Def positions of internal
1034 //                             registers.
1035 //   total                 -   Total number of Def positions in 'defs' array.
1036 //
1037 // Returns:
1038 //   Void.
1039 void LinearScan::buildInternalRegisterUsesForNode(GenTree* tree, TreeNodeInfo* info, RefPosition* defs[], int total)
1040 {
1041     assert(total < MaxInternalRegisters);
1042
1043     // defs[] has been populated by buildInternalRegisterDefsForNode
1044     // now just add uses to the defs previously added.
1045     for (int i = 0; i < total; i++)
1046     {
1047         RefPosition* prevRefPosition = defs[i];
1048         assert(prevRefPosition != nullptr);
1049         regMaskTP mask = prevRefPosition->registerAssignment;
1050         if (prevRefPosition->isPhysRegRef)
1051         {
1052             newRefPosition(defs[i]->getReg()->regNum, currentLoc, RefTypeUse, tree, mask);
1053         }
1054         else
1055         {
1056             RefPosition* newest = newRefPosition(defs[i]->getInterval(), currentLoc, RefTypeUse, tree, mask, 0);
1057
1058             if (info->isInternalRegDelayFree)
1059             {
1060                 newest->delayRegFree = true;
1061             }
1062         }
1063     }
1064 }
1065
1066 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
1067 //------------------------------------------------------------------------
1068 // buildUpperVectorSaveRefPositions - Create special RefPositions for saving
1069 //                                    the upper half of a set of large vector.
1070 //
1071 // Arguments:
1072 //    tree       - The current node being handled
1073 //    currentLoc - The location of the current node
1074 //
1075 // Return Value: Returns the set of lclVars that are killed by this node, and therefore
1076 //               required RefTypeUpperVectorSaveDef RefPositions.
1077 //
1078 // Notes: The returned set is used by buildUpperVectorRestoreRefPositions.
1079 //
1080 VARSET_VALRET_TP
1081 LinearScan::buildUpperVectorSaveRefPositions(GenTree* tree, LsraLocation currentLoc)
1082 {
1083     assert(enregisterLocalVars);
1084     VARSET_TP liveLargeVectors(VarSetOps::MakeEmpty(compiler));
1085     regMaskTP fpCalleeKillSet = RBM_NONE;
1086     if (!VarSetOps::IsEmpty(compiler, largeVectorVars))
1087     {
1088         // We actually need to find any calls that kill the upper-half of the callee-save vector registers.
1089         // But we will use as a proxy any node that kills floating point registers.
1090         // (Note that some calls are masquerading as other nodes at this point so we can't just check for calls.)
1091         fpCalleeKillSet = getKillSetForNode(tree);
1092         if ((fpCalleeKillSet & RBM_FLT_CALLEE_TRASH) != RBM_NONE)
1093         {
1094             VarSetOps::AssignNoCopy(compiler, liveLargeVectors,
1095                                     VarSetOps::Intersection(compiler, currentLiveVars, largeVectorVars));
1096             VarSetOps::Iter iter(compiler, liveLargeVectors);
1097             unsigned        varIndex = 0;
1098             while (iter.NextElem(&varIndex))
1099             {
1100                 Interval* varInterval    = getIntervalForLocalVar(varIndex);
1101                 Interval* tempInterval   = newInterval(varInterval->registerType);
1102                 tempInterval->isInternal = true;
1103                 RefPosition* pos =
1104                     newRefPosition(tempInterval, currentLoc, RefTypeUpperVectorSaveDef, tree, RBM_FLT_CALLEE_SAVED);
1105                 // We are going to save the existing relatedInterval of varInterval on tempInterval, so that we can set
1106                 // the tempInterval as the relatedInterval of varInterval, so that we can build the corresponding
1107                 // RefTypeUpperVectorSaveUse RefPosition.  We will then restore the relatedInterval onto varInterval,
1108                 // and set varInterval as the relatedInterval of tempInterval.
1109                 tempInterval->relatedInterval = varInterval->relatedInterval;
1110                 varInterval->relatedInterval  = tempInterval;
1111             }
1112         }
1113     }
1114     return liveLargeVectors;
1115 }
1116
1117 // buildUpperVectorRestoreRefPositions - Create special RefPositions for restoring
1118 //                                       the upper half of a set of large vectors.
1119 //
1120 // Arguments:
1121 //    tree       - The current node being handled
1122 //    currentLoc - The location of the current node
1123 //    liveLargeVectors - The set of lclVars needing restores (returned by buildUpperVectorSaveRefPositions)
1124 //
1125 void LinearScan::buildUpperVectorRestoreRefPositions(GenTree*         tree,
1126                                                      LsraLocation     currentLoc,
1127                                                      VARSET_VALARG_TP liveLargeVectors)
1128 {
1129     assert(enregisterLocalVars);
1130     if (!VarSetOps::IsEmpty(compiler, liveLargeVectors))
1131     {
1132         VarSetOps::Iter iter(compiler, liveLargeVectors);
1133         unsigned        varIndex = 0;
1134         while (iter.NextElem(&varIndex))
1135         {
1136             Interval* varInterval  = getIntervalForLocalVar(varIndex);
1137             Interval* tempInterval = varInterval->relatedInterval;
1138             assert(tempInterval->isInternal == true);
1139             RefPosition* pos =
1140                 newRefPosition(tempInterval, currentLoc, RefTypeUpperVectorSaveUse, tree, RBM_FLT_CALLEE_SAVED);
1141             // Restore the relatedInterval onto varInterval, and set varInterval as the relatedInterval
1142             // of tempInterval.
1143             varInterval->relatedInterval  = tempInterval->relatedInterval;
1144             tempInterval->relatedInterval = varInterval;
1145         }
1146     }
1147 }
1148 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
1149
1150 #ifdef DEBUG
1151 //------------------------------------------------------------------------
1152 // ComputeOperandDstCount: computes the number of registers defined by a
1153 //                         node.
1154 //
1155 // For most nodes, this is simple:
1156 // - Nodes that do not produce values (e.g. stores and other void-typed
1157 //   nodes) and nodes that immediately use the registers they define
1158 //   produce no registers
1159 // - Nodes that are marked as defining N registers define N registers.
1160 //
1161 // For contained nodes, however, things are more complicated: for purposes
1162 // of bookkeeping, a contained node is treated as producing the transitive
1163 // closure of the registers produced by its sources.
1164 //
1165 // Arguments:
1166 //    operand - The operand for which to compute a register count.
1167 //
1168 // Returns:
1169 //    The number of registers defined by `operand`.
1170 //
1171 // static
1172 int LinearScan::ComputeOperandDstCount(GenTree* operand)
1173 {
1174     // GT_ARGPLACE is the only non-LIR node that is currently in the trees at this stage, though
1175     // note that it is not in the linear order. It seems best to check for !IsLIR() rather than
1176     // GT_ARGPLACE directly, since it's that characteristic that makes it irrelevant for this method.
1177     if (!operand->IsLIR())
1178     {
1179         return 0;
1180     }
1181     if (operand->isContained())
1182     {
1183         int dstCount = 0;
1184         for (GenTree* op : operand->Operands())
1185         {
1186             dstCount += ComputeOperandDstCount(op);
1187         }
1188
1189         return dstCount;
1190     }
1191     if (operand->IsUnusedValue())
1192     {
1193         // Operands that define an unused value do not produce any registers.
1194         return 0;
1195     }
1196     if (operand->IsValue())
1197     {
1198         // Operands that are values and are not contained consume all of their operands
1199         // and produce one or more registers.
1200         return operand->GetRegisterDstCount();
1201     }
1202     else
1203     {
1204         // This must be one of the operand types that are neither contained nor produce a value.
1205         // Stores and void-typed operands may be encountered when processing call nodes, which contain
1206         // pointers to argument setup stores.
1207         assert(operand->OperIsStore() || operand->OperIsBlkOp() || operand->OperIsPutArgStk() ||
1208                operand->OperIsCompare() || operand->OperIs(GT_CMP) || operand->IsSIMDEqualityOrInequality() ||
1209                operand->TypeGet() == TYP_VOID);
1210         return 0;
1211     }
1212 }
1213
1214 //------------------------------------------------------------------------
1215 // ComputeAvailableSrcCount: computes the number of registers available as
1216 //                           sources for a node.
1217 //
1218 // This is simply the sum of the number of registers produced by each
1219 // operand to the node.
1220 //
1221 // Arguments:
1222 //    node - The node for which to compute a source count.
1223 //
1224 // Return Value:
1225 //    The number of registers available as sources for `node`.
1226 //
1227 // static
1228 int LinearScan::ComputeAvailableSrcCount(GenTree* node)
1229 {
1230     int numSources = 0;
1231     for (GenTree* operand : node->Operands())
1232     {
1233         numSources += ComputeOperandDstCount(operand);
1234     }
1235
1236     return numSources;
1237 }
1238 #endif // DEBUG
1239
1240 //------------------------------------------------------------------------
1241 // buildRefPositionsForNode: The main entry point for building the RefPositions
1242 //                           and "tree temp" Intervals for a given node.
1243 //
1244 // Arguments:
1245 //    tree       - The node for which we are building RefPositions
1246 //    block      - The BasicBlock in which the node resides
1247 //    currentLoc - The LsraLocation of the given node
1248 //
1249 void LinearScan::buildRefPositionsForNode(GenTree* tree, BasicBlock* block, LsraLocation currentLoc)
1250 {
1251 #ifdef _TARGET_ARM_
1252     assert(!isRegPairType(tree->TypeGet()));
1253 #endif // _TARGET_ARM_
1254
1255     // The LIR traversal doesn't visit GT_LIST or GT_ARGPLACE nodes.
1256     // GT_CLS_VAR nodes should have been eliminated by rationalizer.
1257     assert(tree->OperGet() != GT_ARGPLACE);
1258     assert(tree->OperGet() != GT_LIST);
1259     assert(tree->OperGet() != GT_CLS_VAR);
1260
1261     // The LIR traversal visits only the first node in a GT_FIELD_LIST.
1262     assert((tree->OperGet() != GT_FIELD_LIST) || tree->AsFieldList()->IsFieldListHead());
1263
1264     // The set of internal temporary registers used by this node are stored in the
1265     // gtRsvdRegs register mask. Clear it out.
1266     tree->gtRsvdRegs = RBM_NONE;
1267
1268 #ifdef DEBUG
1269     if (VERBOSE)
1270     {
1271         dumpDefList();
1272         compiler->gtDispTree(tree, nullptr, nullptr, true);
1273     }
1274 #endif // DEBUG
1275
1276     // If the node produces a value that will be consumed by a parent node, its TreeNodeInfo will
1277     // be allocated in the LocationInfoListNode. Otherwise, we'll just use a local value that will
1278     // be thrown away when we're done.
1279     LocationInfoListNode* locationInfo = nullptr;
1280     TreeNodeInfo          tempInfo;
1281     TreeNodeInfo*         info    = nullptr;
1282     int                   consume = 0;
1283     int                   produce = 0;
1284     if (!tree->isContained())
1285     {
1286         if (tree->IsValue())
1287         {
1288             locationInfo    = listNodePool.GetNode(currentLoc, nullptr, tree);
1289             currentNodeInfo = &locationInfo->info;
1290         }
1291         else
1292         {
1293             currentNodeInfo = &tempInfo;
1294         }
1295         info = currentNodeInfo;
1296         info->Initialize(this, tree);
1297         BuildNode(tree);
1298         assert(info->IsValid(this));
1299         consume = info->srcCount;
1300         produce = info->dstCount;
1301 #ifdef DEBUG
1302         if (VERBOSE)
1303         {
1304             printf("    +");
1305             info->dump(this);
1306             tree->dumpLIRFlags();
1307             printf("\n");
1308         }
1309 #endif // DEBUG
1310     }
1311
1312 #ifdef DEBUG
1313     if (VERBOSE)
1314     {
1315         if (tree->isContained())
1316         {
1317             JITDUMP("Contained\n");
1318         }
1319         else if (tree->OperIs(GT_LCL_VAR, GT_LCL_FLD) && tree->IsUnusedValue())
1320         {
1321             JITDUMP("Unused\n");
1322         }
1323         else
1324         {
1325             JITDUMP("  consume=%d produce=%d\n", consume, produce);
1326         }
1327     }
1328 #endif // DEBUG
1329
1330     assert(((consume == 0) && (produce == 0)) || (ComputeAvailableSrcCount(tree) == consume));
1331
1332     if (tree->OperIs(GT_LCL_VAR, GT_LCL_FLD))
1333     {
1334         LclVarDsc* const varDsc = &compiler->lvaTable[tree->AsLclVarCommon()->gtLclNum];
1335         if (isCandidateVar(varDsc))
1336         {
1337             assert(consume == 0);
1338
1339             // We handle tracked variables differently from non-tracked ones.  If it is tracked,
1340             // we simply add a use or def of the tracked variable.  Otherwise, for a use we need
1341             // to actually add the appropriate references for loading or storing the variable.
1342             //
1343             // It won't actually get used or defined until the appropriate ancestor tree node
1344             // is processed, unless this is marked "isLocalDefUse" because it is a stack-based argument
1345             // to a call
1346
1347             assert(varDsc->lvTracked);
1348             unsigned varIndex = varDsc->lvVarIndex;
1349
1350             if (!tree->IsUnusedValue() && !tree->isContained())
1351             {
1352                 assert(produce != 0);
1353
1354                 locationInfo->interval = getIntervalForLocalVar(varIndex);
1355                 defList.Append(locationInfo);
1356             }
1357             return;
1358         }
1359     }
1360     if (tree->isContained())
1361     {
1362         return;
1363     }
1364
1365     // Handle the case of local variable assignment
1366     Interval* varDefInterval = nullptr;
1367
1368     GenTree* defNode = tree;
1369
1370     // noAdd means the node creates a def but for purposes of map
1371     // management do not add it because data is not flowing up the
1372     // tree
1373
1374     bool         noAdd   = info->isLocalDefUse;
1375     RefPosition* prevPos = nullptr;
1376
1377     bool isSpecialPutArg = false;
1378
1379     assert(!tree->OperIsAssignment());
1380     if (tree->OperIsLocalStore())
1381     {
1382         GenTreeLclVarCommon* const store = tree->AsLclVarCommon();
1383         assert((consume > 1) || (regType(store->gtOp1->TypeGet()) == regType(store->TypeGet())));
1384
1385         LclVarDsc* varDsc = &compiler->lvaTable[store->gtLclNum];
1386         if (isCandidateVar(varDsc))
1387         {
1388             // We always push the tracked lclVar intervals
1389             assert(varDsc->lvTracked);
1390             unsigned varIndex = varDsc->lvVarIndex;
1391             varDefInterval    = getIntervalForLocalVar(varIndex);
1392             assert((store->gtFlags & GTF_VAR_DEF) != 0);
1393             defNode = tree;
1394             if (produce == 0)
1395             {
1396                 produce = 1;
1397                 noAdd   = true;
1398             }
1399
1400             assert(consume <= MAX_RET_REG_COUNT);
1401             if (consume == 1)
1402             {
1403                 // Get the location info for the register defined by the first operand.
1404                 LocationInfoListNode& operandInfo = *(useList.Begin());
1405                 assert(operandInfo.treeNode == tree->gtGetOp1());
1406
1407                 Interval* srcInterval = operandInfo.interval;
1408                 if (srcInterval->relatedInterval == nullptr)
1409                 {
1410                     // Preference the source to the dest, unless this is a non-last-use localVar.
1411                     // Note that the last-use info is not correct, but it is a better approximation than preferencing
1412                     // the source to the dest, if the source's lifetime extends beyond the dest.
1413                     if (!srcInterval->isLocalVar || (operandInfo.treeNode->gtFlags & GTF_VAR_DEATH) != 0)
1414                     {
1415                         srcInterval->assignRelatedInterval(varDefInterval);
1416                     }
1417                 }
1418                 else if (!srcInterval->isLocalVar)
1419                 {
1420                     // Preference the source to dest, if src is not a local var.
1421                     srcInterval->assignRelatedInterval(varDefInterval);
1422                 }
1423             }
1424         }
1425         else if (store->gtOp1->OperIs(GT_BITCAST))
1426         {
1427             store->gtType = store->gtOp1->gtType = store->gtOp1->AsUnOp()->gtOp1->TypeGet();
1428
1429             // Get the location info for the register defined by the first operand.
1430             LocationInfoListNode& operandInfo = *(useList.Begin());
1431             assert(operandInfo.treeNode == tree->gtGetOp1());
1432
1433             Interval* srcInterval     = operandInfo.interval;
1434             srcInterval->registerType = regType(store->TypeGet());
1435
1436             RefPosition* srcDefPosition = srcInterval->firstRefPosition;
1437             assert(srcDefPosition != nullptr);
1438             assert(srcDefPosition->refType == RefTypeDef);
1439             assert(srcDefPosition->treeNode == store->gtOp1);
1440
1441             srcDefPosition->registerAssignment = allRegs(store->TypeGet());
1442             operandInfo.info.setSrcCandidates(this, allRegs(store->TypeGet()));
1443         }
1444     }
1445     else if (noAdd && produce == 0)
1446     {
1447         // Dead nodes may remain after tree rationalization, decomposition or lowering.
1448         // They should be marked as UnusedValue.
1449         // TODO-Cleanup: Identify and remove these dead nodes prior to register allocation.
1450         assert(!noAdd || (produce != 0));
1451     }
1452
1453     Interval* prefSrcInterval = nullptr;
1454
1455     // If this is a binary operator that will be encoded with 2 operand fields
1456     // (i.e. the target is read-modify-write), preference the dst to op1.
1457
1458     bool hasDelayFreeSrc = info->hasDelayFreeSrc;
1459
1460 #if defined(DEBUG) && defined(_TARGET_X86_)
1461     // On x86, `LSRA_LIMIT_CALLER` is too restrictive to allow the use of special put args: this stress mode
1462     // leaves only three registers allocatable--eax, ecx, and edx--of which the latter two are also used for the
1463     // first two integral arguments to a call. This can leave us with too few registers to succesfully allocate in
1464     // situations like the following:
1465     //
1466     //     t1026 =    lclVar    ref    V52 tmp35        u:3 REG NA <l:$3a1, c:$98d>
1467     //
1468     //             /--*  t1026  ref
1469     //     t1352 = *  putarg_reg ref    REG NA
1470     //
1471     //      t342 =    lclVar    int    V14 loc6         u:4 REG NA $50c
1472     //
1473     //      t343 =    const     int    1 REG NA $41
1474     //
1475     //             /--*  t342   int
1476     //             +--*  t343   int
1477     //      t344 = *  +         int    REG NA $495
1478     //
1479     //      t345 =    lclVar    int    V04 arg4         u:2 REG NA $100
1480     //
1481     //             /--*  t344   int
1482     //             +--*  t345   int
1483     //      t346 = *  %         int    REG NA $496
1484     //
1485     //             /--*  t346   int
1486     //     t1353 = *  putarg_reg int    REG NA
1487     //
1488     //     t1354 =    lclVar    ref    V52 tmp35         (last use) REG NA
1489     //
1490     //             /--*  t1354  ref
1491     //     t1355 = *  lea(b+0)  byref  REG NA
1492     //
1493     // Here, the first `putarg_reg` would normally be considered a special put arg, which would remove `ecx` from the
1494     // set of allocatable registers, leaving only `eax` and `edx`. The allocator will then fail to allocate a register
1495     // for the def of `t345` if arg4 is not a register candidate: the corresponding ref position will be constrained to
1496     // { `ecx`, `ebx`, `esi`, `edi` }, which `LSRA_LIMIT_CALLER` will further constrain to `ecx`, which will not be
1497     // available due to the special put arg.
1498     const bool supportsSpecialPutArg = getStressLimitRegs() != LSRA_LIMIT_CALLER;
1499 #else
1500     const bool supportsSpecialPutArg = true;
1501 #endif
1502
1503     if (supportsSpecialPutArg)
1504     {
1505         if ((tree->OperGet() == GT_PUTARG_REG) && isCandidateLocalRef(tree->gtGetOp1()) &&
1506             (tree->gtGetOp1()->gtFlags & GTF_VAR_DEATH) == 0)
1507         {
1508             // This is the case for a "pass-through" copy of a lclVar.  In the case where it is a non-last-use,
1509             // we don't want the def of the copy to kill the lclVar register, if it is assigned the same register
1510             // (which is actually what we hope will happen).
1511             JITDUMP("Setting putarg_reg as a pass-through of a non-last use lclVar\n");
1512
1513             // Get the register information for the first operand of the node.
1514             LocationInfoListNode* operandDef = useList.Begin();
1515             assert(operandDef->treeNode == tree->gtGetOp1());
1516
1517             // Preference the destination to the interval of the first register defined by the first operand.
1518             Interval* srcInterval = operandDef->interval;
1519             assert(srcInterval->isLocalVar);
1520             prefSrcInterval = srcInterval;
1521             isSpecialPutArg = true;
1522             INDEBUG(specialPutArgCount++);
1523         }
1524         else if (tree->IsCall())
1525         {
1526             INDEBUG(specialPutArgCount = 0);
1527         }
1528     }
1529
1530     RefPosition* internalRefs[MaxInternalRegisters];
1531
1532 #ifdef DEBUG
1533     // If we are constraining the registers for allocation, we will modify all the RefPositions
1534     // we've built for this node after we've created them. In order to do that, we'll remember
1535     // the last RefPosition prior to those created for this node.
1536     RefPositionIterator refPositionMark = refPositions.backPosition();
1537 #endif // DEBUG
1538
1539     // Make intervals for all the 'internal' register requirements for this node,
1540     // where internal means additional registers required temporarily.
1541     // Create a RefTypeDef RefPosition for each such interval.
1542     int internalCount = buildInternalRegisterDefsForNode(tree, info, internalRefs);
1543
1544     // Make use RefPositions for all used values.
1545     int consumed = 0;
1546     for (LocationInfoListNode *listNode = useList.Begin(), *end = useList.End(); listNode != end;
1547          listNode = listNode->Next())
1548     {
1549         LocationInfo& locInfo = *static_cast<LocationInfo*>(listNode);
1550
1551         // For tree temps, a use is always a last use and the end of the range;
1552         // this is set by default in newRefPosition
1553         GenTree* const useNode = locInfo.treeNode;
1554         assert(useNode != nullptr);
1555
1556         Interval*     srcInterval = locInfo.interval;
1557         TreeNodeInfo& useNodeInfo = locInfo.info;
1558         if (useNodeInfo.isTgtPref)
1559         {
1560             prefSrcInterval = srcInterval;
1561         }
1562
1563         const bool delayRegFree = (hasDelayFreeSrc && useNodeInfo.isDelayFree);
1564
1565         regMaskTP candidates = useNodeInfo.getSrcCandidates(this);
1566 #ifdef _TARGET_ARM_
1567         regMaskTP allCandidates = candidates;
1568
1569         if (useNode->OperIsPutArgSplit() || useNode->OperIsMultiRegOp())
1570         {
1571             // get i-th candidate, set bits in useCandidates must be in sequential order.
1572             candidates = genFindLowestReg(allCandidates);
1573             allCandidates &= ~candidates;
1574         }
1575 #endif // _TARGET_ARM_
1576
1577         assert((candidates & allRegs(srcInterval->registerType)) != 0);
1578
1579         GenTree* refPosNode;
1580         if (srcInterval->isLocalVar)
1581         {
1582             // We have only approximate last-use information at this point.  This is because the
1583             // execution order doesn't actually reflect the true order in which the localVars
1584             // are referenced - but the order of the RefPositions will, so we recompute it after
1585             // RefPositions are built.
1586             // Use the old value for setting currentLiveVars - note that we do this with the
1587             // not-quite-correct setting of lastUse.  However, this is OK because
1588             // 1) this is only for preferencing, which doesn't require strict correctness, and
1589             //    for determing which largeVectors require having their upper-half saved & restored.
1590             //    (Issue #17481 tracks the issue that this system results in excessive spills and
1591             //    should be changed.)
1592             // 2) the cases where these out-of-order uses occur should not overlap a kill (they are
1593             //    only known to occur within a single expression).
1594             if ((useNode->gtFlags & GTF_VAR_DEATH) != 0)
1595             {
1596                 VarSetOps::RemoveElemD(compiler, currentLiveVars, srcInterval->getVarIndex(compiler));
1597             }
1598             refPosNode = useNode;
1599         }
1600         else
1601         {
1602             // For non-localVar uses we record nothing, as nothing needs to be written back to the tree.
1603             refPosNode = nullptr;
1604         }
1605
1606         RefPosition* pos = newRefPosition(srcInterval, currentLoc, RefTypeUse, refPosNode, candidates, 0);
1607         if (delayRegFree)
1608         {
1609             pos->delayRegFree = true;
1610         }
1611
1612         if (useNode->IsRegOptional())
1613         {
1614             pos->setAllocateIfProfitable(true);
1615         }
1616         consumed++;
1617
1618         // Create additional use RefPositions for multi-reg nodes.
1619         for (int idx = 1; idx < locInfo.info.dstCount; idx++)
1620         {
1621             noway_assert(srcInterval->relatedInterval != nullptr);
1622             srcInterval = srcInterval->relatedInterval;
1623 #ifdef _TARGET_ARM_
1624             if (useNode->OperIsPutArgSplit() ||
1625                 (compiler->opts.compUseSoftFP && (useNode->OperIsPutArgReg() || useNode->OperGet() == GT_BITCAST)))
1626             {
1627                 // get first candidate, set bits in useCandidates must be in sequential order.
1628                 candidates = genFindLowestReg(allCandidates);
1629                 allCandidates &= ~candidates;
1630             }
1631 #endif // _TARGET_ARM_
1632             RefPosition* pos = newRefPosition(srcInterval, currentLoc, RefTypeUse, refPosNode, candidates, idx);
1633             consumed++;
1634         }
1635     }
1636
1637     assert(consumed == consume);
1638     if (consume != 0)
1639     {
1640         listNodePool.ReturnNodes(useList);
1641     }
1642
1643     buildInternalRegisterUsesForNode(tree, info, internalRefs, internalCount);
1644
1645     RegisterType registerType  = getDefType(tree);
1646     regMaskTP    candidates    = info->getDstCandidates(this);
1647     regMaskTP    useCandidates = info->getSrcCandidates(this);
1648
1649 #ifdef DEBUG
1650     if (VERBOSE && produce)
1651     {
1652         printf("Def candidates ");
1653         dumpRegMask(candidates);
1654         printf(", Use candidates ");
1655         dumpRegMask(useCandidates);
1656         printf("\n");
1657     }
1658 #endif // DEBUG
1659
1660 #if defined(_TARGET_AMD64_)
1661     // Multi-reg call node is the only node that could produce multi-reg value
1662     assert(produce <= 1 || (tree->IsMultiRegCall() && produce == MAX_RET_REG_COUNT));
1663 #endif // _TARGET_xxx_
1664
1665     // Add kill positions before adding def positions
1666     buildKillPositionsForNode(tree, currentLoc + 1);
1667
1668 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
1669     VARSET_TP liveLargeVectors(VarSetOps::UninitVal());
1670     if (enregisterLocalVars && (RBM_FLT_CALLEE_SAVED != RBM_NONE))
1671     {
1672         // Build RefPositions for saving any live large vectors.
1673         // This must be done after the kills, so that we know which large vectors are still live.
1674         VarSetOps::AssignNoCopy(compiler, liveLargeVectors, buildUpperVectorSaveRefPositions(tree, currentLoc + 1));
1675     }
1676 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
1677
1678     ReturnTypeDesc* retTypeDesc    = nullptr;
1679     bool            isMultiRegCall = tree->IsMultiRegCall();
1680     if (isMultiRegCall)
1681     {
1682         retTypeDesc = tree->AsCall()->GetReturnTypeDesc();
1683         assert((int)genCountBits(candidates) == produce);
1684         assert(candidates == retTypeDesc->GetABIReturnRegs());
1685     }
1686
1687     // push defs
1688     LocationInfoList locationInfoList;
1689     LsraLocation     defLocation = currentLoc + 1;
1690     Interval*        interval    = varDefInterval;
1691     // For nodes that define multiple registers, subsequent intervals will be linked using the 'relatedInterval' field.
1692     // Keep track of the previous interval allocated, for that purpose.
1693     Interval* prevInterval = nullptr;
1694     for (int i = 0; i < produce; i++)
1695     {
1696         regMaskTP currCandidates = candidates;
1697
1698         // In case of multi-reg call node, registerType is given by
1699         // the type of ith position return register.
1700         if (isMultiRegCall)
1701         {
1702             registerType   = retTypeDesc->GetReturnRegType((unsigned)i);
1703             currCandidates = genRegMask(retTypeDesc->GetABIReturnReg(i));
1704             useCandidates  = allRegs(registerType);
1705         }
1706
1707 #ifdef _TARGET_ARM_
1708         // If oper is GT_PUTARG_REG, set bits in useCandidates must be in sequential order.
1709         if (tree->OperIsPutArgSplit() || tree->OperIsMultiRegOp())
1710         {
1711             // get i-th candidate
1712             currCandidates = genFindLowestReg(candidates);
1713             candidates &= ~currCandidates;
1714         }
1715 #endif // _TARGET_ARM_
1716
1717         if (interval == nullptr)
1718         {
1719             // Make a new interval
1720             interval = newInterval(registerType);
1721             if (hasDelayFreeSrc || info->isInternalRegDelayFree)
1722             {
1723                 interval->hasInterferingUses = true;
1724             }
1725             else if (tree->OperIsConst())
1726             {
1727                 assert(!tree->IsReuseRegVal());
1728                 interval->isConstant = true;
1729             }
1730
1731             if ((currCandidates & useCandidates) != RBM_NONE)
1732             {
1733                 interval->updateRegisterPreferences(currCandidates & useCandidates);
1734             }
1735
1736             if (isSpecialPutArg)
1737             {
1738                 interval->isSpecialPutArg = true;
1739             }
1740         }
1741         else
1742         {
1743             assert(registerTypesEquivalent(interval->registerType, registerType));
1744             assert(interval->isLocalVar);
1745             if ((tree->gtFlags & GTF_VAR_DEATH) == 0)
1746             {
1747                 VarSetOps::AddElemD(compiler, currentLiveVars, interval->getVarIndex(compiler));
1748             }
1749         }
1750
1751         if (prefSrcInterval != nullptr)
1752         {
1753             interval->assignRelatedIntervalIfUnassigned(prefSrcInterval);
1754         }
1755
1756         // for assignments, we want to create a refposition for the def
1757         // but not push it
1758         if (!noAdd)
1759         {
1760             if (i == 0)
1761             {
1762                 locationInfo->interval = interval;
1763                 prevInterval           = interval;
1764                 defList.Append(locationInfo);
1765             }
1766             else
1767             {
1768                 // This is the 2nd or subsequent register defined by a multi-reg node.
1769                 // Connect them using 'relatedInterval'.
1770                 noway_assert(prevInterval != nullptr);
1771                 prevInterval->relatedInterval = interval;
1772                 prevInterval                  = interval;
1773                 prevInterval->isMultiReg      = true;
1774                 interval->isMultiReg          = true;
1775             }
1776         }
1777
1778         RefPosition* pos = newRefPosition(interval, defLocation, RefTypeDef, defNode, currCandidates, (unsigned)i);
1779         if (info->isLocalDefUse)
1780         {
1781             // This must be an unused value, OR it is a special node for which we allocate
1782             // a target register even though it produces no value.
1783             assert(defNode->IsUnusedValue() || (defNode->gtOper == GT_LOCKADD));
1784             pos->isLocalDefUse = true;
1785             pos->lastUse       = true;
1786         }
1787         interval->updateRegisterPreferences(currCandidates);
1788         interval->updateRegisterPreferences(useCandidates);
1789         interval = nullptr;
1790     }
1791
1792 #if FEATURE_PARTIAL_SIMD_CALLEE_SAVE
1793     // SaveDef position must be at the same location as Def position of call node.
1794     if (enregisterLocalVars)
1795     {
1796         buildUpperVectorRestoreRefPositions(tree, defLocation, liveLargeVectors);
1797     }
1798 #endif // FEATURE_PARTIAL_SIMD_CALLEE_SAVE
1799
1800 #ifdef DEBUG
1801     // If we are constraining registers, modify all the RefPositions we've just built to specify the
1802     // minimum reg count required.
1803     if ((getStressLimitRegs() != LSRA_LIMIT_NONE) || (getSelectionHeuristics() != LSRA_SELECT_DEFAULT))
1804     {
1805         // The number of registers required for a tree node is the sum of
1806         //   consume + produce + internalCount + specialPutArgCount.
1807         // This is the minimum set of registers that needs to be ensured in the candidate set of ref positions created.
1808         //
1809         unsigned minRegCount =
1810             consume + produce + info->internalIntCount + info->internalFloatCount + specialPutArgCount;
1811
1812         for (refPositionMark++; refPositionMark != refPositions.end(); refPositionMark++)
1813         {
1814             RefPosition* newRefPosition    = &(*refPositionMark);
1815             unsigned     minRegCountForRef = minRegCount;
1816             if (RefTypeIsUse(newRefPosition->refType) && newRefPosition->delayRegFree)
1817             {
1818                 // If delayRegFree, then Use will interfere with the destination of the consuming node.
1819                 // Therefore, we also need add the kill set of the consuming node to minRegCount.
1820                 //
1821                 // For example consider the following IR on x86, where v01 and v02
1822                 // are method args coming in ecx and edx respectively.
1823                 //   GT_DIV(v01, v02)
1824                 //
1825                 // For GT_DIV, the minRegCount will be 3 without adding kill set of GT_DIV node.
1826                 //
1827                 // Assume further JitStressRegs=2, which would constrain candidates to callee trashable
1828                 // regs { eax, ecx, edx } on use positions of v01 and v02.  LSRA allocates ecx for v01.
1829                 // The use position of v02 cannot be allocated a reg since it is marked delay-reg free and
1830                 // {eax,edx} are getting killed before the def of GT_DIV.  For this reason, minRegCount for
1831                 // the use position of v02 also needs to take into account the kill set of its consuming node.
1832                 regMaskTP killMask = getKillSetForNode(tree);
1833                 if (killMask != RBM_NONE)
1834                 {
1835                     minRegCountForRef += genCountBits(killMask);
1836                 }
1837             }
1838             newRefPosition->minRegCandidateCount = minRegCountForRef;
1839             if (newRefPosition->IsActualRef() && doReverseCallerCallee())
1840             {
1841                 Interval* interval       = newRefPosition->getInterval();
1842                 regMaskTP oldAssignment  = newRefPosition->registerAssignment;
1843                 regMaskTP calleeSaveMask = calleeSaveRegs(interval->registerType);
1844                 newRefPosition->registerAssignment =
1845                     getConstrainedRegMask(oldAssignment, calleeSaveMask, minRegCountForRef);
1846                 if ((newRefPosition->registerAssignment != oldAssignment) && (newRefPosition->refType == RefTypeUse) &&
1847                     !interval->isLocalVar)
1848                 {
1849                     checkConflictingDefUse(newRefPosition);
1850                 }
1851             }
1852         }
1853     }
1854 #endif // DEBUG
1855     JITDUMP("\n");
1856 }
1857
1858 //------------------------------------------------------------------------
1859 // buildPhysRegRecords: Make an interval for each physical register
1860 //
1861 void LinearScan::buildPhysRegRecords()
1862 {
1863     RegisterType regType = IntRegisterType;
1864     for (regNumber reg = REG_FIRST; reg < ACTUAL_REG_COUNT; reg = REG_NEXT(reg))
1865     {
1866         RegRecord* curr = &physRegs[reg];
1867         curr->init(reg);
1868     }
1869 }
1870
1871 //------------------------------------------------------------------------
1872 // getNonEmptyBlock: Return the first non-empty block starting with 'block'
1873 //
1874 // Arguments:
1875 //    block - the BasicBlock from which we start looking
1876 //
1877 // Return Value:
1878 //    The first non-empty BasicBlock we find.
1879 //
1880 BasicBlock* getNonEmptyBlock(BasicBlock* block)
1881 {
1882     while (block != nullptr && block->bbTreeList == nullptr)
1883     {
1884         BasicBlock* nextBlock = block->bbNext;
1885         // Note that here we use the version of NumSucc that does not take a compiler.
1886         // That way this doesn't have to take a compiler, or be an instance method, e.g. of LinearScan.
1887         // If we have an empty block, it must have jump type BBJ_NONE or BBJ_ALWAYS, in which
1888         // case we don't need the version that takes a compiler.
1889         assert(block->NumSucc() == 1 && ((block->bbJumpKind == BBJ_ALWAYS) || (block->bbJumpKind == BBJ_NONE)));
1890         // sometimes the first block is empty and ends with an uncond branch
1891         // assert( block->GetSucc(0) == nextBlock);
1892         block = nextBlock;
1893     }
1894     assert(block != nullptr && block->bbTreeList != nullptr);
1895     return block;
1896 }
1897
1898 //------------------------------------------------------------------------
1899 // insertZeroInitRefPositions: Handle lclVars that are live-in to the first block
1900 //
1901 // Notes:
1902 //    Prior to calling this method, 'currentLiveVars' must be set to the set of register
1903 //    candidate variables that are liveIn to the first block.
1904 //    For each register candidate that is live-in to the first block:
1905 //    - If it is a GC ref, or if compInitMem is set, a ZeroInit RefPosition will be created.
1906 //    - Otherwise, it will be marked as spilled, since it will not be assigned a register
1907 //      on entry and will be loaded from memory on the undefined path.
1908 //      Note that, when the compInitMem option is not set, we may encounter these on
1909 //      paths that are protected by the same condition as an earlier def. However, since
1910 //      we don't do the analysis to determine this - and couldn't rely on always identifying
1911 //      such cases even if we tried - we must conservatively treat the undefined path as
1912 //      being possible. This is a relatively rare case, so the introduced conservatism is
1913 //      not expected to warrant the analysis required to determine the best placement of
1914 //      an initialization.
1915 //
1916 void LinearScan::insertZeroInitRefPositions()
1917 {
1918     assert(enregisterLocalVars);
1919 #ifdef DEBUG
1920     VARSET_TP expectedLiveVars(VarSetOps::Intersection(compiler, registerCandidateVars, compiler->fgFirstBB->bbLiveIn));
1921     assert(VarSetOps::Equal(compiler, currentLiveVars, expectedLiveVars));
1922 #endif //  DEBUG
1923
1924     // insert defs for this, then a block boundary
1925
1926     VarSetOps::Iter iter(compiler, currentLiveVars);
1927     unsigned        varIndex = 0;
1928     while (iter.NextElem(&varIndex))
1929     {
1930         unsigned   varNum = compiler->lvaTrackedToVarNum[varIndex];
1931         LclVarDsc* varDsc = compiler->lvaTable + varNum;
1932         if (!varDsc->lvIsParam && isCandidateVar(varDsc))
1933         {
1934             JITDUMP("V%02u was live in to first block:", varNum);
1935             Interval* interval = getIntervalForLocalVar(varIndex);
1936             if (compiler->info.compInitMem || varTypeIsGC(varDsc->TypeGet()))
1937             {
1938                 JITDUMP(" creating ZeroInit\n");
1939                 GenTree*     firstNode = getNonEmptyBlock(compiler->fgFirstBB)->firstNode();
1940                 RefPosition* pos =
1941                     newRefPosition(interval, MinLocation, RefTypeZeroInit, firstNode, allRegs(interval->registerType));
1942                 varDsc->lvMustInit = true;
1943             }
1944             else
1945             {
1946                 setIntervalAsSpilled(interval);
1947                 JITDUMP(" marking as spilled\n");
1948             }
1949         }
1950     }
1951 }
1952
1953 #if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
1954 //------------------------------------------------------------------------
1955 // unixAmd64UpdateRegStateForArg: Sets the register state for an argument of type STRUCT for System V systems.
1956 //
1957 // Arguments:
1958 //    argDsc - the LclVarDsc for the argument of interest
1959 //
1960 // Notes:
1961 //     See Compiler::raUpdateRegStateForArg(RegState *regState, LclVarDsc *argDsc) in regalloc.cpp
1962 //         for how state for argument is updated for unix non-structs and Windows AMD64 structs.
1963 //
1964 void LinearScan::unixAmd64UpdateRegStateForArg(LclVarDsc* argDsc)
1965 {
1966     assert(varTypeIsStruct(argDsc));
1967     RegState* intRegState   = &compiler->codeGen->intRegState;
1968     RegState* floatRegState = &compiler->codeGen->floatRegState;
1969
1970     if ((argDsc->lvArgReg != REG_STK) && (argDsc->lvArgReg != REG_NA))
1971     {
1972         if (genRegMask(argDsc->lvArgReg) & (RBM_ALLFLOAT))
1973         {
1974             assert(genRegMask(argDsc->lvArgReg) & (RBM_FLTARG_REGS));
1975             floatRegState->rsCalleeRegArgMaskLiveIn |= genRegMask(argDsc->lvArgReg);
1976         }
1977         else
1978         {
1979             assert(genRegMask(argDsc->lvArgReg) & (RBM_ARG_REGS));
1980             intRegState->rsCalleeRegArgMaskLiveIn |= genRegMask(argDsc->lvArgReg);
1981         }
1982     }
1983
1984     if ((argDsc->lvOtherArgReg != REG_STK) && (argDsc->lvOtherArgReg != REG_NA))
1985     {
1986         if (genRegMask(argDsc->lvOtherArgReg) & (RBM_ALLFLOAT))
1987         {
1988             assert(genRegMask(argDsc->lvOtherArgReg) & (RBM_FLTARG_REGS));
1989             floatRegState->rsCalleeRegArgMaskLiveIn |= genRegMask(argDsc->lvOtherArgReg);
1990         }
1991         else
1992         {
1993             assert(genRegMask(argDsc->lvOtherArgReg) & (RBM_ARG_REGS));
1994             intRegState->rsCalleeRegArgMaskLiveIn |= genRegMask(argDsc->lvOtherArgReg);
1995         }
1996     }
1997 }
1998
1999 #endif // defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
2000
2001 //------------------------------------------------------------------------
2002 // updateRegStateForArg: Updates rsCalleeRegArgMaskLiveIn for the appropriate
2003 //    regState (either compiler->intRegState or compiler->floatRegState),
2004 //    with the lvArgReg on "argDsc"
2005 //
2006 // Arguments:
2007 //    argDsc - the argument for which the state is to be updated.
2008 //
2009 // Return Value: None
2010 //
2011 // Assumptions:
2012 //    The argument is live on entry to the function
2013 //    (or is untracked and therefore assumed live)
2014 //
2015 // Notes:
2016 //    This relies on a method in regAlloc.cpp that is shared between LSRA
2017 //    and regAlloc.  It is further abstracted here because regState is updated
2018 //    separately for tracked and untracked variables in LSRA.
2019 //
2020 void LinearScan::updateRegStateForArg(LclVarDsc* argDsc)
2021 {
2022 #if defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
2023     // For System V AMD64 calls the argDsc can have 2 registers (for structs.)
2024     // Handle them here.
2025     if (varTypeIsStruct(argDsc))
2026     {
2027         unixAmd64UpdateRegStateForArg(argDsc);
2028     }
2029     else
2030 #endif // defined(FEATURE_UNIX_AMD64_STRUCT_PASSING)
2031     {
2032         RegState* intRegState   = &compiler->codeGen->intRegState;
2033         RegState* floatRegState = &compiler->codeGen->floatRegState;
2034         // In the case of AMD64 we'll still use the floating point registers
2035         // to model the register usage for argument on vararg calls, so
2036         // we will ignore the varargs condition to determine whether we use
2037         // XMM registers or not for setting up the call.
2038         bool isFloat = (isFloatRegType(argDsc->lvType)
2039 #ifndef _TARGET_AMD64_
2040                         && !compiler->info.compIsVarArgs
2041 #endif
2042                         && !compiler->opts.compUseSoftFP);
2043
2044         if (argDsc->lvIsHfaRegArg())
2045         {
2046             isFloat = true;
2047         }
2048
2049         if (isFloat)
2050         {
2051             JITDUMP("Float arg V%02u in reg %s\n", (argDsc - compiler->lvaTable), getRegName(argDsc->lvArgReg));
2052             compiler->raUpdateRegStateForArg(floatRegState, argDsc);
2053         }
2054         else
2055         {
2056             JITDUMP("Int arg V%02u in reg %s\n", (argDsc - compiler->lvaTable), getRegName(argDsc->lvArgReg));
2057 #if FEATURE_MULTIREG_ARGS
2058             if (argDsc->lvOtherArgReg != REG_NA)
2059             {
2060                 JITDUMP("(second half) in reg %s\n", getRegName(argDsc->lvOtherArgReg));
2061             }
2062 #endif // FEATURE_MULTIREG_ARGS
2063             compiler->raUpdateRegStateForArg(intRegState, argDsc);
2064         }
2065     }
2066 }
2067
2068 //------------------------------------------------------------------------
2069 // buildIntervals: The main entry point for building the data structures over
2070 //                 which we will do register allocation.
2071 //
2072 void LinearScan::buildIntervals()
2073 {
2074     BasicBlock* block;
2075
2076     JITDUMP("\nbuildIntervals ========\n");
2077
2078     // Build (empty) records for all of the physical registers
2079     buildPhysRegRecords();
2080
2081 #ifdef DEBUG
2082     if (VERBOSE)
2083     {
2084         printf("\n-----------------\n");
2085         printf("LIVENESS:\n");
2086         printf("-----------------\n");
2087         foreach_block(compiler, block)
2088         {
2089             printf("BB%02u use def in out\n", block->bbNum);
2090             dumpConvertedVarSet(compiler, block->bbVarUse);
2091             printf("\n");
2092             dumpConvertedVarSet(compiler, block->bbVarDef);
2093             printf("\n");
2094             dumpConvertedVarSet(compiler, block->bbLiveIn);
2095             printf("\n");
2096             dumpConvertedVarSet(compiler, block->bbLiveOut);
2097             printf("\n");
2098         }
2099     }
2100 #endif // DEBUG
2101
2102 #if DOUBLE_ALIGN
2103     // We will determine whether we should double align the frame during
2104     // identifyCandidates(), but we initially assume that we will not.
2105     doDoubleAlign = false;
2106 #endif
2107
2108     identifyCandidates();
2109
2110     // Figure out if we're going to use a frame pointer. We need to do this before building
2111     // the ref positions, because those objects will embed the frame register in various register masks
2112     // if the frame pointer is not reserved. If we decide to have a frame pointer, setFrameType() will
2113     // remove the frame pointer from the masks.
2114     setFrameType();
2115
2116     DBEXEC(VERBOSE, TupleStyleDump(LSRA_DUMP_PRE));
2117
2118     // second part:
2119     JITDUMP("\nbuildIntervals second part ========\n");
2120     currentLoc = 0;
2121     // TODO-Cleanup: This duplicates prior behavior where entry (ParamDef) RefPositions were
2122     // being assigned the bbNum of the last block traversed in the 2nd phase of Lowering.
2123     // Previously, the block sequencing was done for the (formerly separate) Build pass,
2124     // and the curBBNum was left as the last block sequenced. This block was then used to set the
2125     // weight for the entry (ParamDef) RefPositions. It would be logical to set this to the
2126     // normalized entry weight (compiler->fgCalledCount), but that results in a net regression.
2127     if (!blockSequencingDone)
2128     {
2129         setBlockSequence();
2130     }
2131     curBBNum = blockSequence[bbSeqCount - 1]->bbNum;
2132
2133     // Next, create ParamDef RefPositions for all the tracked parameters, in order of their varIndex.
2134     // Assign these RefPositions to the (nonexistent) BB0.
2135     curBBNum = 0;
2136
2137     LclVarDsc*   argDsc;
2138     unsigned int lclNum;
2139
2140     RegState* intRegState                   = &compiler->codeGen->intRegState;
2141     RegState* floatRegState                 = &compiler->codeGen->floatRegState;
2142     intRegState->rsCalleeRegArgMaskLiveIn   = RBM_NONE;
2143     floatRegState->rsCalleeRegArgMaskLiveIn = RBM_NONE;
2144
2145     for (unsigned int varIndex = 0; varIndex < compiler->lvaTrackedCount; varIndex++)
2146     {
2147         lclNum = compiler->lvaTrackedToVarNum[varIndex];
2148         argDsc = &(compiler->lvaTable[lclNum]);
2149
2150         if (!argDsc->lvIsParam)
2151         {
2152             continue;
2153         }
2154
2155         // Only reserve a register if the argument is actually used.
2156         // Is it dead on entry? If compJmpOpUsed is true, then the arguments
2157         // have to be kept alive, so we have to consider it as live on entry.
2158         // Use lvRefCnt instead of checking bbLiveIn because if it's volatile we
2159         // won't have done dataflow on it, but it needs to be marked as live-in so
2160         // it will get saved in the prolog.
2161         if (!compiler->compJmpOpUsed && argDsc->lvRefCnt == 0 && !compiler->opts.compDbgCode)
2162         {
2163             continue;
2164         }
2165
2166         if (argDsc->lvIsRegArg)
2167         {
2168             updateRegStateForArg(argDsc);
2169         }
2170
2171         if (isCandidateVar(argDsc))
2172         {
2173             Interval* interval = getIntervalForLocalVar(varIndex);
2174             regMaskTP mask     = allRegs(TypeGet(argDsc));
2175             if (argDsc->lvIsRegArg)
2176             {
2177                 // Set this interval as currently assigned to that register
2178                 regNumber inArgReg = argDsc->lvArgReg;
2179                 assert(inArgReg < REG_COUNT);
2180                 mask = genRegMask(inArgReg);
2181                 assignPhysReg(inArgReg, interval);
2182             }
2183             RefPosition* pos = newRefPosition(interval, MinLocation, RefTypeParamDef, nullptr, mask);
2184         }
2185         else if (varTypeIsStruct(argDsc->lvType))
2186         {
2187             for (unsigned fieldVarNum = argDsc->lvFieldLclStart;
2188                  fieldVarNum < argDsc->lvFieldLclStart + argDsc->lvFieldCnt; ++fieldVarNum)
2189             {
2190                 LclVarDsc* fieldVarDsc = &(compiler->lvaTable[fieldVarNum]);
2191                 if (fieldVarDsc->lvLRACandidate)
2192                 {
2193                     assert(fieldVarDsc->lvTracked);
2194                     Interval*    interval = getIntervalForLocalVar(fieldVarDsc->lvVarIndex);
2195                     RefPosition* pos =
2196                         newRefPosition(interval, MinLocation, RefTypeParamDef, nullptr, allRegs(TypeGet(fieldVarDsc)));
2197                 }
2198             }
2199         }
2200         else
2201         {
2202             // We can overwrite the register (i.e. codegen saves it on entry)
2203             assert(argDsc->lvRefCnt == 0 || !argDsc->lvIsRegArg || argDsc->lvDoNotEnregister ||
2204                    !argDsc->lvLRACandidate || (varTypeIsFloating(argDsc->TypeGet()) && compiler->opts.compDbgCode));
2205         }
2206     }
2207
2208     // Now set up the reg state for the non-tracked args
2209     // (We do this here because we want to generate the ParamDef RefPositions in tracked
2210     // order, so that loop doesn't hit the non-tracked args)
2211
2212     for (unsigned argNum = 0; argNum < compiler->info.compArgsCount; argNum++, argDsc++)
2213     {
2214         argDsc = &(compiler->lvaTable[argNum]);
2215
2216         if (argDsc->lvPromotedStruct())
2217         {
2218             noway_assert(argDsc->lvFieldCnt == 1); // We only handle one field here
2219
2220             unsigned fieldVarNum = argDsc->lvFieldLclStart;
2221             argDsc               = &(compiler->lvaTable[fieldVarNum]);
2222         }
2223         noway_assert(argDsc->lvIsParam);
2224         if (!argDsc->lvTracked && argDsc->lvIsRegArg)
2225         {
2226             updateRegStateForArg(argDsc);
2227         }
2228     }
2229
2230     // If there is a secret stub param, it is also live in
2231     if (compiler->info.compPublishStubParam)
2232     {
2233         intRegState->rsCalleeRegArgMaskLiveIn |= RBM_SECRET_STUB_PARAM;
2234     }
2235
2236     BasicBlock* predBlock = nullptr;
2237     BasicBlock* prevBlock = nullptr;
2238
2239     // Initialize currentLiveVars to the empty set.  We will set it to the current
2240     // live-in at the entry to each block (this will include the incoming args on
2241     // the first block).
2242     VarSetOps::AssignNoCopy(compiler, currentLiveVars, VarSetOps::MakeEmpty(compiler));
2243
2244     for (block = startBlockSequence(); block != nullptr; block = moveToNextBlock())
2245     {
2246         JITDUMP("\nNEW BLOCK BB%02u\n", block->bbNum);
2247
2248         bool predBlockIsAllocated = false;
2249         predBlock                 = findPredBlockForLiveIn(block, prevBlock DEBUGARG(&predBlockIsAllocated));
2250         if (predBlock)
2251         {
2252             JITDUMP("\n\nSetting BB%02u as the predecessor for determining incoming variable registers of BB%02u\n",
2253                     block->bbNum, predBlock->bbNum);
2254             assert(predBlock->bbNum <= bbNumMaxBeforeResolution);
2255             blockInfo[block->bbNum].predBBNum = predBlock->bbNum;
2256         }
2257
2258         if (enregisterLocalVars)
2259         {
2260             VarSetOps::AssignNoCopy(compiler, currentLiveVars,
2261                                     VarSetOps::Intersection(compiler, registerCandidateVars, block->bbLiveIn));
2262
2263             if (block == compiler->fgFirstBB)
2264             {
2265                 insertZeroInitRefPositions();
2266                 // The first real location is at 1; 0 is for the entry.
2267                 currentLoc = 1;
2268             }
2269
2270             // Any lclVars live-in to a block are resolution candidates.
2271             VarSetOps::UnionD(compiler, resolutionCandidateVars, currentLiveVars);
2272
2273             // Determine if we need any DummyDefs.
2274             // We need DummyDefs for cases where "predBlock" isn't really a predecessor.
2275             // Note that it's possible to have uses of unitialized variables, in which case even the first
2276             // block may require DummyDefs, which we are not currently adding - this means that these variables
2277             // will always be considered to be in memory on entry (and reloaded when the use is encountered).
2278             // TODO-CQ: Consider how best to tune this.  Currently, if we create DummyDefs for uninitialized
2279             // variables (which may actually be initialized along the dynamically executed paths, but not
2280             // on all static paths), we wind up with excessive liveranges for some of these variables.
2281             VARSET_TP newLiveIn(VarSetOps::MakeCopy(compiler, currentLiveVars));
2282             if (predBlock)
2283             {
2284                 // Compute set difference: newLiveIn = currentLiveVars - predBlock->bbLiveOut
2285                 VarSetOps::DiffD(compiler, newLiveIn, predBlock->bbLiveOut);
2286             }
2287             bool needsDummyDefs = (!VarSetOps::IsEmpty(compiler, newLiveIn) && block != compiler->fgFirstBB);
2288
2289             // Create dummy def RefPositions
2290
2291             if (needsDummyDefs)
2292             {
2293                 // If we are using locations from a predecessor, we should never require DummyDefs.
2294                 assert(!predBlockIsAllocated);
2295
2296                 JITDUMP("Creating dummy definitions\n");
2297                 VarSetOps::Iter iter(compiler, newLiveIn);
2298                 unsigned        varIndex = 0;
2299                 while (iter.NextElem(&varIndex))
2300                 {
2301                     unsigned   varNum = compiler->lvaTrackedToVarNum[varIndex];
2302                     LclVarDsc* varDsc = compiler->lvaTable + varNum;
2303                     // Add a dummyDef for any candidate vars that are in the "newLiveIn" set.
2304                     // If this is the entry block, don't add any incoming parameters (they're handled with ParamDefs).
2305                     if (isCandidateVar(varDsc) && (predBlock != nullptr || !varDsc->lvIsParam))
2306                     {
2307                         Interval*    interval = getIntervalForLocalVar(varIndex);
2308                         RefPosition* pos      = newRefPosition(interval, currentLoc, RefTypeDummyDef, nullptr,
2309                                                           allRegs(interval->registerType));
2310                     }
2311                 }
2312                 JITDUMP("Finished creating dummy definitions\n\n");
2313             }
2314         }
2315
2316         // Add a dummy RefPosition to mark the block boundary.
2317         // Note that we do this AFTER adding the exposed uses above, because the
2318         // register positions for those exposed uses need to be recorded at
2319         // this point.
2320
2321         RefPosition* pos = newRefPosition((Interval*)nullptr, currentLoc, RefTypeBB, nullptr, RBM_NONE);
2322         currentLoc += 2;
2323         JITDUMP("\n");
2324
2325         LIR::Range& blockRange = LIR::AsRange(block);
2326         for (GenTree* node : blockRange.NonPhiNodes())
2327         {
2328             // We increment the number position of each tree node by 2 to simplify the logic when there's the case of
2329             // a tree that implicitly does a dual-definition of temps (the long case).  In this case it is easier to
2330             // already have an idle spot to handle a dual-def instead of making some messy adjustments if we only
2331             // increment the number position by one.
2332             CLANG_FORMAT_COMMENT_ANCHOR;
2333
2334 #ifdef DEBUG
2335             node->gtSeqNum = currentLoc;
2336             // In DEBUG, we want to set the gtRegTag to GT_REGTAG_REG, so that subsequent dumps will so the register
2337             // value.
2338             // Although this looks like a no-op it sets the tag.
2339             node->gtRegNum = node->gtRegNum;
2340 #endif
2341
2342             buildRefPositionsForNode(node, block, currentLoc);
2343
2344 #ifdef DEBUG
2345             if (currentLoc > maxNodeLocation)
2346             {
2347                 maxNodeLocation = currentLoc;
2348             }
2349 #endif // DEBUG
2350             currentLoc += 2;
2351         }
2352
2353         // Note: the visited set is cleared in LinearScan::doLinearScan()
2354         markBlockVisited(block);
2355         assert(defList.IsEmpty());
2356
2357         if (enregisterLocalVars)
2358         {
2359             // Insert exposed uses for a lclVar that is live-out of 'block' but not live-in to the
2360             // next block, or any unvisited successors.
2361             // This will address lclVars that are live on a backedge, as well as those that are kept
2362             // live at a GT_JMP.
2363             //
2364             // Blocks ending with "jmp method" are marked as BBJ_HAS_JMP,
2365             // and jmp call is represented using GT_JMP node which is a leaf node.
2366             // Liveness phase keeps all the arguments of the method live till the end of
2367             // block by adding them to liveout set of the block containing GT_JMP.
2368             //
2369             // The target of a GT_JMP implicitly uses all the current method arguments, however
2370             // there are no actual references to them.  This can cause LSRA to assert, because
2371             // the variables are live but it sees no references.  In order to correctly model the
2372             // liveness of these arguments, we add dummy exposed uses, in the same manner as for
2373             // backward branches.  This will happen automatically via expUseSet.
2374             //
2375             // Note that a block ending with GT_JMP has no successors and hence the variables
2376             // for which dummy use ref positions are added are arguments of the method.
2377
2378             VARSET_TP expUseSet(VarSetOps::MakeCopy(compiler, block->bbLiveOut));
2379             VarSetOps::IntersectionD(compiler, expUseSet, registerCandidateVars);
2380             BasicBlock* nextBlock = getNextBlock();
2381             if (nextBlock != nullptr)
2382             {
2383                 VarSetOps::DiffD(compiler, expUseSet, nextBlock->bbLiveIn);
2384             }
2385             for (BasicBlock* succ : block->GetAllSuccs(compiler))
2386             {
2387                 if (VarSetOps::IsEmpty(compiler, expUseSet))
2388                 {
2389                     break;
2390                 }
2391
2392                 if (isBlockVisited(succ))
2393                 {
2394                     continue;
2395                 }
2396                 VarSetOps::DiffD(compiler, expUseSet, succ->bbLiveIn);
2397             }
2398
2399             if (!VarSetOps::IsEmpty(compiler, expUseSet))
2400             {
2401                 JITDUMP("Exposed uses:");
2402                 VarSetOps::Iter iter(compiler, expUseSet);
2403                 unsigned        varIndex = 0;
2404                 while (iter.NextElem(&varIndex))
2405                 {
2406                     unsigned   varNum = compiler->lvaTrackedToVarNum[varIndex];
2407                     LclVarDsc* varDsc = compiler->lvaTable + varNum;
2408                     assert(isCandidateVar(varDsc));
2409                     Interval*    interval = getIntervalForLocalVar(varIndex);
2410                     RefPosition* pos =
2411                         newRefPosition(interval, currentLoc, RefTypeExpUse, nullptr, allRegs(interval->registerType));
2412                     JITDUMP(" V%02u", varNum);
2413                 }
2414                 JITDUMP("\n");
2415             }
2416
2417             // Clear the "last use" flag on any vars that are live-out from this block.
2418             {
2419                 VarSetOps::Iter iter(compiler, block->bbLiveOut);
2420                 unsigned        varIndex = 0;
2421                 while (iter.NextElem(&varIndex))
2422                 {
2423                     unsigned         varNum = compiler->lvaTrackedToVarNum[varIndex];
2424                     LclVarDsc* const varDsc = &compiler->lvaTable[varNum];
2425                     if (isCandidateVar(varDsc))
2426                     {
2427                         RefPosition* const lastRP = getIntervalForLocalVar(varIndex)->lastRefPosition;
2428                         if ((lastRP != nullptr) && (lastRP->bbNum == block->bbNum))
2429                         {
2430                             lastRP->lastUse = false;
2431                         }
2432                     }
2433                 }
2434             }
2435
2436 #ifdef DEBUG
2437             checkLastUses(block);
2438
2439             if (VERBOSE)
2440             {
2441                 printf("use: ");
2442                 dumpConvertedVarSet(compiler, block->bbVarUse);
2443                 printf("\ndef: ");
2444                 dumpConvertedVarSet(compiler, block->bbVarDef);
2445                 printf("\n");
2446             }
2447 #endif // DEBUG
2448         }
2449
2450         prevBlock = block;
2451     }
2452
2453     if (enregisterLocalVars)
2454     {
2455         if (compiler->lvaKeepAliveAndReportThis())
2456         {
2457             // If we need to KeepAliveAndReportThis, add a dummy exposed use of it at the end
2458             unsigned keepAliveVarNum = compiler->info.compThisArg;
2459             assert(compiler->info.compIsStatic == false);
2460             LclVarDsc* varDsc = compiler->lvaTable + keepAliveVarNum;
2461             if (isCandidateVar(varDsc))
2462             {
2463                 JITDUMP("Adding exposed use of this, for lvaKeepAliveAndReportThis\n");
2464                 Interval*    interval = getIntervalForLocalVar(varDsc->lvVarIndex);
2465                 RefPosition* pos =
2466                     newRefPosition(interval, currentLoc, RefTypeExpUse, nullptr, allRegs(interval->registerType));
2467             }
2468         }
2469
2470 #ifdef DEBUG
2471         if (getLsraExtendLifeTimes())
2472         {
2473             LclVarDsc* varDsc;
2474             for (lclNum = 0, varDsc = compiler->lvaTable; lclNum < compiler->lvaCount; lclNum++, varDsc++)
2475             {
2476                 if (varDsc->lvLRACandidate)
2477                 {
2478                     JITDUMP("Adding exposed use of V%02u for LsraExtendLifetimes\n", lclNum);
2479                     Interval*    interval = getIntervalForLocalVar(varDsc->lvVarIndex);
2480                     RefPosition* pos =
2481                         newRefPosition(interval, currentLoc, RefTypeExpUse, nullptr, allRegs(interval->registerType));
2482                 }
2483             }
2484         }
2485 #endif // DEBUG
2486     }
2487
2488     // If the last block has successors, create a RefTypeBB to record
2489     // what's live
2490
2491     if (prevBlock->NumSucc(compiler) > 0)
2492     {
2493         RefPosition* pos = newRefPosition((Interval*)nullptr, currentLoc, RefTypeBB, nullptr, RBM_NONE);
2494     }
2495
2496 #ifdef DEBUG
2497     // Make sure we don't have any blocks that were not visited
2498     foreach_block(compiler, block)
2499     {
2500         assert(isBlockVisited(block));
2501     }
2502
2503     if (VERBOSE)
2504     {
2505         lsraDumpIntervals("BEFORE VALIDATING INTERVALS");
2506         dumpRefPositions("BEFORE VALIDATING INTERVALS");
2507         validateIntervals();
2508     }
2509 #endif // DEBUG
2510 }
2511
2512 #ifdef DEBUG
2513 //------------------------------------------------------------------------
2514 // validateIntervals: A DEBUG-only method that checks that the lclVar RefPositions
2515 //                    do not reflect uses of undefined values
2516 //
2517 // Notes: If an undefined use is encountered, it merely prints a message.
2518 //
2519 // TODO-Cleanup: This should probably assert, or at least print the message only
2520 //               when doing a JITDUMP.
2521 //
2522 void LinearScan::validateIntervals()
2523 {
2524     if (enregisterLocalVars)
2525     {
2526         for (unsigned i = 0; i < compiler->lvaTrackedCount; i++)
2527         {
2528             if (!compiler->lvaTable[compiler->lvaTrackedToVarNum[i]].lvLRACandidate)
2529             {
2530                 continue;
2531             }
2532             Interval* interval = getIntervalForLocalVar(i);
2533
2534             bool defined = false;
2535             printf("-----------------\n");
2536             for (RefPosition* ref = interval->firstRefPosition; ref != nullptr; ref = ref->nextRefPosition)
2537             {
2538                 ref->dump();
2539                 RefType refType = ref->refType;
2540                 if (!defined && RefTypeIsUse(refType))
2541                 {
2542                     if (compiler->info.compMethodName != nullptr)
2543                     {
2544                         printf("%s: ", compiler->info.compMethodName);
2545                     }
2546                     printf("LocalVar V%02u: undefined use at %u\n", interval->varNum, ref->nodeLocation);
2547                 }
2548                 // Note that there can be multiple last uses if they are on disjoint paths,
2549                 // so we can't really check the lastUse flag
2550                 if (ref->lastUse)
2551                 {
2552                     defined = false;
2553                 }
2554                 if (RefTypeIsDef(refType))
2555                 {
2556                     defined = true;
2557                 }
2558             }
2559         }
2560     }
2561 }
2562 #endif // DEBUG
2563
2564 //------------------------------------------------------------------------
2565 // GetIndirInfo: Get the source registers for an indirection that might be contained.
2566 //
2567 // Arguments:
2568 //    node      - The node of interest
2569 //
2570 // Return Value:
2571 //    The number of source registers used by the *parent* of this node.
2572 //
2573 // Notes:
2574 //    Adds the defining node for each register to the useList.
2575 //
2576 int LinearScan::GetIndirInfo(GenTreeIndir* indirTree)
2577 {
2578     GenTree* const addr = indirTree->gtOp1;
2579     if (!addr->isContained())
2580     {
2581         appendLocationInfoToList(addr);
2582         return 1;
2583     }
2584     if (!addr->OperIs(GT_LEA))
2585     {
2586         return 0;
2587     }
2588
2589     GenTreeAddrMode* const addrMode = addr->AsAddrMode();
2590
2591     unsigned srcCount = 0;
2592     if ((addrMode->Base() != nullptr) && !addrMode->Base()->isContained())
2593     {
2594         appendLocationInfoToList(addrMode->Base());
2595         srcCount++;
2596     }
2597     if ((addrMode->Index() != nullptr) && !addrMode->Index()->isContained())
2598     {
2599         appendLocationInfoToList(addrMode->Index());
2600         srcCount++;
2601     }
2602     return srcCount;
2603 }
2604
2605 //------------------------------------------------------------------------
2606 // GetOperandInfo: Get the source registers for an operand that might be contained.
2607 //
2608 // Arguments:
2609 //    node      - The node of interest
2610 //    useList   - The list of uses for the node that we're currently processing
2611 //
2612 // Return Value:
2613 //    The number of source registers used by the *parent* of this node.
2614 //
2615 // Notes:
2616 //    Adds the defining node for each register to the given useList.
2617 //
2618 int LinearScan::GetOperandInfo(GenTree* node)
2619 {
2620     if (!node->isContained())
2621     {
2622         appendLocationInfoToList(node);
2623         return 1;
2624     }
2625
2626 #if !defined(_TARGET_64BIT_)
2627     if (node->OperIs(GT_LONG))
2628     {
2629         return appendBinaryLocationInfoToList(node->AsOp());
2630     }
2631 #endif // !defined(_TARGET_64BIT_)
2632     if (node->OperIsIndir())
2633     {
2634         const unsigned srcCount = GetIndirInfo(node->AsIndir());
2635         return srcCount;
2636     }
2637     if (node->OperIsHWIntrinsic())
2638     {
2639         appendLocationInfoToList(node->gtGetOp1());
2640         return 1;
2641     }
2642
2643     return 0;
2644 }
2645
2646 //------------------------------------------------------------------------
2647 // GetOperandInfo: Get the source registers for an operand that might be contained.
2648 //
2649 // Arguments:
2650 //    node      - The node of interest
2651 //    useList   - The list of uses for the node that we're currently processing
2652 //
2653 // Return Value:
2654 //    The number of source registers used by the *parent* of this node.
2655 //
2656 // Notes:
2657 //    Adds the defining node for each register to the useList.
2658 //
2659 int LinearScan::GetOperandInfo(GenTree* node, LocationInfoListNode** pFirstInfo)
2660 {
2661     LocationInfoListNode* prevLast = useList.Last();
2662     int                   srcCount = GetOperandInfo(node);
2663     if (prevLast == nullptr)
2664     {
2665         *pFirstInfo = useList.Begin();
2666     }
2667     else
2668     {
2669         *pFirstInfo = prevLast->Next();
2670     }
2671     return srcCount;
2672 }
2673
2674 void TreeNodeInfo::Initialize(LinearScan* lsra, GenTree* node)
2675 {
2676     _dstCount           = 0;
2677     _srcCount           = 0;
2678     _internalIntCount   = 0;
2679     _internalFloatCount = 0;
2680
2681     isLocalDefUse          = false;
2682     isDelayFree            = false;
2683     hasDelayFreeSrc        = false;
2684     isTgtPref              = false;
2685     isInternalRegDelayFree = false;
2686
2687     regMaskTP dstCandidates;
2688
2689     // if there is a reg indicated on the tree node, use that for dstCandidates
2690     // the exception is the NOP, which sometimes show up around late args.
2691     // TODO-Cleanup: get rid of those NOPs.
2692     if (node->gtRegNum == REG_STK)
2693     {
2694         dstCandidates = RBM_NONE;
2695     }
2696     else if (node->gtRegNum == REG_NA || node->gtOper == GT_NOP)
2697     {
2698 #ifdef ARM_SOFTFP
2699         if (node->OperGet() == GT_PUTARG_REG)
2700         {
2701             dstCandidates = lsra->allRegs(TYP_INT);
2702         }
2703         else
2704 #endif
2705         {
2706             dstCandidates = lsra->allRegs(node->TypeGet());
2707         }
2708     }
2709     else
2710     {
2711         dstCandidates = genRegMask(node->gtRegNum);
2712     }
2713
2714     setDstCandidates(lsra, dstCandidates);
2715     srcCandsIndex = dstCandsIndex;
2716
2717     setInternalCandidates(lsra, lsra->allRegs(TYP_INT));
2718
2719 #ifdef DEBUG
2720     isInitialized = true;
2721 #endif
2722
2723     assert(IsValid(lsra));
2724 }
2725
2726 //------------------------------------------------------------------------
2727 // getSrcCandidates: Get the source candidates (candidates for the consumer
2728 //                   of the node) from the TreeNodeInfo
2729 //
2730 // Arguments:
2731 //    lsra - the LinearScan object
2732 //
2733 // Return Value:
2734 //    The set of registers (as a register mask) that are candidates for the
2735 //    consumer of the node
2736 //
2737 // Notes:
2738 //    The LinearScan object maintains the mapping from the indices kept in the
2739 //    TreeNodeInfo to the actual register masks.
2740 //
2741 regMaskTP TreeNodeInfo::getSrcCandidates(LinearScan* lsra)
2742 {
2743     return lsra->GetRegMaskForIndex(srcCandsIndex);
2744 }
2745
2746 //------------------------------------------------------------------------
2747 // setSrcCandidates: Set the source candidates (candidates for the consumer
2748 //                   of the node) on the TreeNodeInfo
2749 //
2750 // Arguments:
2751 //    lsra - the LinearScan object
2752 //
2753 // Notes: see getSrcCandidates
2754 //
2755 void TreeNodeInfo::setSrcCandidates(LinearScan* lsra, regMaskTP mask)
2756 {
2757     LinearScan::RegMaskIndex i = lsra->GetIndexForRegMask(mask);
2758     assert(FitsIn<unsigned char>(i));
2759     srcCandsIndex = (unsigned char)i;
2760 }
2761
2762 //------------------------------------------------------------------------
2763 // getDstCandidates: Get the dest candidates (candidates for the definition
2764 //                   of the node) from the TreeNodeInfo
2765 //
2766 // Arguments:
2767 //    lsra - the LinearScan object
2768 //
2769 // Return Value:
2770 //    The set of registers (as a register mask) that are candidates for the
2771 //    node itself
2772 //
2773 // Notes: see getSrcCandidates
2774 //
2775 regMaskTP TreeNodeInfo::getDstCandidates(LinearScan* lsra)
2776 {
2777     return lsra->GetRegMaskForIndex(dstCandsIndex);
2778 }
2779
2780 //------------------------------------------------------------------------
2781 // setDstCandidates: Set the dest candidates (candidates for the definition
2782 //                   of the node) on the TreeNodeInfo
2783 //
2784 // Arguments:
2785 //    lsra - the LinearScan object
2786 //
2787 // Notes: see getSrcCandidates
2788 //
2789 void TreeNodeInfo::setDstCandidates(LinearScan* lsra, regMaskTP mask)
2790 {
2791     LinearScan::RegMaskIndex i = lsra->GetIndexForRegMask(mask);
2792     assert(FitsIn<unsigned char>(i));
2793     dstCandsIndex = (unsigned char)i;
2794 }
2795
2796 //------------------------------------------------------------------------
2797 // getInternalCandidates: Get the internal candidates (candidates for the internal
2798 //                        temporary registers used by a node) from the TreeNodeInfo
2799 //
2800 // Arguments:
2801 //    lsra - the LinearScan object
2802 //
2803 // Return Value:
2804 //    The set of registers (as a register mask) that are candidates for the
2805 //    internal temporary registers.
2806 //
2807 // Notes: see getSrcCandidates
2808 //
2809 regMaskTP TreeNodeInfo::getInternalCandidates(LinearScan* lsra)
2810 {
2811     return lsra->GetRegMaskForIndex(internalCandsIndex);
2812 }
2813
2814 //------------------------------------------------------------------------
2815 // getInternalCandidates: Set the internal candidates (candidates for the internal
2816 //                        temporary registers used by a node) on the TreeNodeInfo
2817 //
2818 // Arguments:
2819 //    lsra - the LinearScan object
2820 //
2821 // Notes: see getSrcCandidates
2822 //
2823 void TreeNodeInfo::setInternalCandidates(LinearScan* lsra, regMaskTP mask)
2824 {
2825     LinearScan::RegMaskIndex i = lsra->GetIndexForRegMask(mask);
2826     assert(FitsIn<unsigned char>(i));
2827     internalCandsIndex = (unsigned char)i;
2828 }
2829
2830 //------------------------------------------------------------------------
2831 // addInternalCandidates: Add internal candidates (candidates for the internal
2832 //                        temporary registers used by a node) on the TreeNodeInfo
2833 //
2834 // Arguments:
2835 //    lsra - the LinearScan object
2836 //
2837 // Notes: see getSrcCandidates
2838 //
2839 void TreeNodeInfo::addInternalCandidates(LinearScan* lsra, regMaskTP mask)
2840 {
2841     LinearScan::RegMaskIndex i = lsra->GetIndexForRegMask(lsra->GetRegMaskForIndex(internalCandsIndex) | mask);
2842     assert(FitsIn<unsigned char>(i));
2843     internalCandsIndex = (unsigned char)i;
2844 }
2845
2846 //------------------------------------------------------------------------
2847 // BuildStoreLoc: Set register requirements for a store of a lclVar
2848 //
2849 // Arguments:
2850 //    storeLoc - the local store (GT_STORE_LCL_FLD or GT_STORE_LCL_VAR)
2851 //
2852 // Notes:
2853 //    This involves:
2854 //    - Setting the appropriate candidates for a store of a multi-reg call return value.
2855 //    - Handling of contained immediates.
2856 //    - Requesting an internal register for SIMD12 stores.
2857 //
2858 void LinearScan::BuildStoreLoc(GenTreeLclVarCommon* storeLoc)
2859 {
2860     TreeNodeInfo* info = currentNodeInfo;
2861     GenTree*      op1  = storeLoc->gtGetOp1();
2862
2863     assert(info->dstCount == 0);
2864
2865     if (op1->IsMultiRegCall())
2866     {
2867         // This is the case of var = call where call is returning
2868         // a value in multiple return registers.
2869         // Must be a store lclvar.
2870         assert(storeLoc->OperGet() == GT_STORE_LCL_VAR);
2871
2872         // srcCount = number of registers in which the value is returned by call
2873         GenTreeCall*    call        = op1->AsCall();
2874         ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc();
2875         unsigned        regCount    = retTypeDesc->GetReturnRegCount();
2876         info->srcCount              = regCount;
2877
2878         // Call node srcCandidates = Bitwise-OR(allregs(GetReturnRegType(i))) for all i=0..RetRegCount-1
2879         regMaskTP             srcCandidates = allMultiRegCallNodeRegs(call);
2880         LocationInfoListNode* locInfo       = getLocationInfo(op1);
2881         locInfo->info.setSrcCandidates(this, srcCandidates);
2882         useList.Append(locInfo);
2883     }
2884 #ifndef _TARGET_64BIT_
2885     else if (varTypeIsLong(op1))
2886     {
2887         if (op1->OperIs(GT_MUL_LONG))
2888         {
2889 #ifdef _TARGET_X86_
2890             // This is actually a bug. A GT_MUL_LONG produces two registers, but is modeled as only producing
2891             // eax (and killing edx). This only works because it always occurs as var = GT_MUL_LONG (ensured by
2892             // DecomposeMul), and therefore edx won't be reused before the store.
2893             // TODO-X86-Cleanup: GT_MUL_LONG should be a multireg node on x86, just as on ARM.
2894             info->srcCount = 1;
2895 #else
2896             info->srcCount         = 2;
2897 #endif
2898             appendLocationInfoToList(op1);
2899         }
2900         else
2901         {
2902             assert(op1->OperIs(GT_LONG));
2903             assert(op1->isContained() && !op1->gtOp.gtOp1->isContained() && !op1->gtOp.gtOp2->isContained());
2904             info->srcCount = appendBinaryLocationInfoToList(op1->AsOp());
2905             assert(info->srcCount == 2);
2906         }
2907     }
2908 #endif // !_TARGET_64BIT_
2909     else if (op1->isContained())
2910     {
2911         info->srcCount = 0;
2912     }
2913     else
2914     {
2915         info->srcCount = 1;
2916         appendLocationInfoToList(op1);
2917     }
2918
2919 #ifdef FEATURE_SIMD
2920     if (varTypeIsSIMD(storeLoc))
2921     {
2922         if (!op1->isContained() && (storeLoc->TypeGet() == TYP_SIMD12))
2923         {
2924 // Need an additional register to extract upper 4 bytes of Vector3.
2925 #ifdef _TARGET_XARCH_
2926             info->internalFloatCount = 1;
2927             info->setInternalCandidates(this, allSIMDRegs());
2928 #elif defined(_TARGET_ARM64_)
2929             info->internalIntCount = 1;
2930 #else
2931 #error "Unknown target architecture for STORE_LCL_VAR of SIMD12"
2932 #endif
2933         }
2934     }
2935 #endif // FEATURE_SIMD
2936 }
2937
2938 //------------------------------------------------------------------------
2939 // BuildSimple: Sets the srcCount for all the trees
2940 // without special handling based on the tree node type.
2941 //
2942 // Arguments:
2943 //    tree      - The node of interest
2944 //
2945 // Return Value:
2946 //    None.
2947 //
2948 void LinearScan::BuildSimple(GenTree* tree)
2949 {
2950     TreeNodeInfo* info = currentNodeInfo;
2951     unsigned      kind = tree->OperKind();
2952     assert(info->dstCount == (tree->IsValue() ? 1 : 0));
2953     if (kind & (GTK_CONST | GTK_LEAF))
2954     {
2955         info->srcCount = 0;
2956     }
2957     else if (kind & (GTK_SMPOP))
2958     {
2959         info->srcCount = appendBinaryLocationInfoToList(tree->AsOp());
2960     }
2961     else
2962     {
2963         unreached();
2964     }
2965 }
2966
2967 //------------------------------------------------------------------------
2968 // BuildReturn: Set the NodeInfo for a GT_RETURN.
2969 //
2970 // Arguments:
2971 //    tree - The node of interest
2972 //
2973 // Return Value:
2974 //    None.
2975 //
2976 void LinearScan::BuildReturn(GenTree* tree)
2977 {
2978     TreeNodeInfo* info = currentNodeInfo;
2979     assert(info->dstCount == 0);
2980     GenTree* op1 = tree->gtGetOp1();
2981
2982 #if !defined(_TARGET_64BIT_)
2983     if (tree->TypeGet() == TYP_LONG)
2984     {
2985         assert((op1->OperGet() == GT_LONG) && op1->isContained());
2986         GenTree* loVal                  = op1->gtGetOp1();
2987         GenTree* hiVal                  = op1->gtGetOp2();
2988         info->srcCount                  = 2;
2989         LocationInfoListNode* loValInfo = getLocationInfo(loVal);
2990         LocationInfoListNode* hiValInfo = getLocationInfo(hiVal);
2991         loValInfo->info.setSrcCandidates(this, RBM_LNGRET_LO);
2992         hiValInfo->info.setSrcCandidates(this, RBM_LNGRET_HI);
2993         useList.Append(loValInfo);
2994         useList.Append(hiValInfo);
2995     }
2996     else
2997 #endif // !defined(_TARGET_64BIT_)
2998         if ((tree->TypeGet() != TYP_VOID) && !op1->isContained())
2999     {
3000         regMaskTP useCandidates = RBM_NONE;
3001
3002         info->srcCount = 1;
3003
3004 #if FEATURE_MULTIREG_RET
3005         if (varTypeIsStruct(tree))
3006         {
3007             // op1 has to be either an lclvar or a multi-reg returning call
3008             if (op1->OperGet() != GT_LCL_VAR)
3009             {
3010                 noway_assert(op1->IsMultiRegCall());
3011
3012                 ReturnTypeDesc* retTypeDesc = op1->AsCall()->GetReturnTypeDesc();
3013                 info->srcCount              = retTypeDesc->GetReturnRegCount();
3014                 useCandidates               = retTypeDesc->GetABIReturnRegs();
3015             }
3016         }
3017         else
3018 #endif // FEATURE_MULTIREG_RET
3019         {
3020             // Non-struct type return - determine useCandidates
3021             switch (tree->TypeGet())
3022             {
3023                 case TYP_VOID:
3024                     useCandidates = RBM_NONE;
3025                     break;
3026                 case TYP_FLOAT:
3027                     useCandidates = RBM_FLOATRET;
3028                     break;
3029                 case TYP_DOUBLE:
3030                     // We ONLY want the valid double register in the RBM_DOUBLERET mask.
3031                     useCandidates = (RBM_DOUBLERET & RBM_ALLDOUBLE);
3032                     break;
3033                 case TYP_LONG:
3034                     useCandidates = RBM_LNGRET;
3035                     break;
3036                 default:
3037                     useCandidates = RBM_INTRET;
3038                     break;
3039             }
3040         }
3041
3042         LocationInfoListNode* locationInfo = getLocationInfo(op1);
3043         if (useCandidates != RBM_NONE)
3044         {
3045             locationInfo->info.setSrcCandidates(this, useCandidates);
3046         }
3047         useList.Append(locationInfo);
3048     }
3049 }
3050
3051 //------------------------------------------------------------------------
3052 // BuildPutArgReg: Set the NodeInfo for a PUTARG_REG.
3053 //
3054 // Arguments:
3055 //    node                - The PUTARG_REG node.
3056 //    argReg              - The register in which to pass the argument.
3057 //    info                - The info for the node's using call.
3058 //    isVarArgs           - True if the call uses a varargs calling convention.
3059 //    callHasFloatRegArgs - Set to true if this PUTARG_REG uses an FP register.
3060 //
3061 // Return Value:
3062 //    None.
3063 //
3064 void LinearScan::BuildPutArgReg(GenTreeUnOp* node)
3065 {
3066     TreeNodeInfo* info = currentNodeInfo;
3067     assert(node != nullptr);
3068     assert(node->OperIsPutArgReg());
3069     info->srcCount   = 1;
3070     regNumber argReg = node->gtRegNum;
3071     assert(argReg != REG_NA);
3072
3073     // Set the register requirements for the node.
3074     regMaskTP argMask = genRegMask(argReg);
3075
3076 #ifdef _TARGET_ARM_
3077     // If type of node is `long` then it is actually `double`.
3078     // The actual `long` types must have been transformed as a field list with two fields.
3079     if (node->TypeGet() == TYP_LONG)
3080     {
3081         info->srcCount++;
3082         info->dstCount = info->srcCount;
3083         assert(genRegArgNext(argReg) == REG_NEXT(argReg));
3084         argMask |= genRegMask(REG_NEXT(argReg));
3085     }
3086 #endif // _TARGET_ARM_
3087     info->setDstCandidates(this, argMask);
3088     info->setSrcCandidates(this, argMask);
3089
3090     // To avoid redundant moves, have the argument operand computed in the
3091     // register in which the argument is passed to the call.
3092     LocationInfoListNode* op1Info = getLocationInfo(node->gtOp.gtOp1);
3093     op1Info->info.setSrcCandidates(this, info->getSrcCandidates(this));
3094     op1Info->info.isDelayFree = true;
3095     useList.Append(op1Info);
3096 }
3097
3098 //------------------------------------------------------------------------
3099 // HandleFloatVarArgs: Handle additional register requirements for a varargs call
3100 //
3101 // Arguments:
3102 //    call    - The call node of interest
3103 //    argNode - The current argument
3104 //
3105 // Return Value:
3106 //    None.
3107 //
3108 // Notes:
3109 //    In the case of a varargs call, the ABI dictates that if we have floating point args,
3110 //    we must pass the enregistered arguments in both the integer and floating point registers.
3111 //    Since the integer register is not associated with the arg node, we will reserve it as
3112 //    an internal register on the call so that it is not used during the evaluation of the call node
3113 //    (e.g. for the target).
3114 void LinearScan::HandleFloatVarArgs(GenTreeCall* call, GenTree* argNode, bool* callHasFloatRegArgs)
3115 {
3116 #if FEATURE_VARARG
3117     TreeNodeInfo* info = currentNodeInfo;
3118     if (call->IsVarargs() && varTypeIsFloating(argNode))
3119     {
3120         *callHasFloatRegArgs = true;
3121
3122         regNumber argReg    = argNode->gtRegNum;
3123         regNumber targetReg = compiler->getCallArgIntRegister(argReg);
3124         info->setInternalIntCount(info->internalIntCount + 1);
3125         info->addInternalCandidates(this, genRegMask(targetReg));
3126     }
3127 #endif // FEATURE_VARARG
3128 }
3129
3130 //------------------------------------------------------------------------
3131 // BuildGCWriteBarrier: Handle additional register requirements for a GC write barrier
3132 //
3133 // Arguments:
3134 //    tree    - The STORE_IND for which a write barrier is required
3135 //
3136 void LinearScan::BuildGCWriteBarrier(GenTree* tree)
3137 {
3138     TreeNodeInfo*         info     = currentNodeInfo;
3139     GenTree*              dst      = tree;
3140     GenTree*              addr     = tree->gtOp.gtOp1;
3141     GenTree*              src      = tree->gtOp.gtOp2;
3142     LocationInfoListNode* addrInfo = getLocationInfo(addr);
3143     LocationInfoListNode* srcInfo  = getLocationInfo(src);
3144
3145     // In the case where we are doing a helper assignment, even if the dst
3146     // is an indir through an lea, we need to actually instantiate the
3147     // lea in a register
3148     assert(!addr->isContained() && !src->isContained());
3149     useList.Append(addrInfo);
3150     useList.Append(srcInfo);
3151     info->srcCount = 2;
3152     assert(info->dstCount == 0);
3153     bool customSourceRegs = false;
3154
3155 #if defined(_TARGET_ARM64_)
3156
3157     // the 'addr' goes into x14 (REG_WRITE_BARRIER_DST)
3158     // the 'src'  goes into x15 (REG_WRITE_BARRIER_SRC)
3159     //
3160     addrInfo->info.setSrcCandidates(this, RBM_WRITE_BARRIER_DST);
3161     srcInfo->info.setSrcCandidates(this, RBM_WRITE_BARRIER_SRC);
3162     customSourceRegs = true;
3163
3164 #elif defined(_TARGET_X86_) && NOGC_WRITE_BARRIERS
3165
3166     bool useOptimizedWriteBarrierHelper = compiler->codeGen->genUseOptimizedWriteBarriers(tree, src);
3167     if (useOptimizedWriteBarrierHelper)
3168     {
3169         // Special write barrier:
3170         // op1 (addr) goes into REG_WRITE_BARRIER (rdx) and
3171         // op2 (src) goes into any int register.
3172         addrInfo->info.setSrcCandidates(this, RBM_WRITE_BARRIER);
3173         srcInfo->info.setSrcCandidates(this, RBM_WRITE_BARRIER_SRC);
3174         customSourceRegs = true;
3175     }
3176
3177 #endif // defined(_TARGET_X86_) && NOGC_WRITE_BARRIERS
3178
3179     if (!customSourceRegs)
3180     {
3181         // For the standard JIT Helper calls:
3182         // op1 (addr) goes into REG_ARG_0 and
3183         // op2 (src) goes into REG_ARG_1
3184         addrInfo->info.setSrcCandidates(this, RBM_ARG_0);
3185         srcInfo->info.setSrcCandidates(this, RBM_ARG_1);
3186     }
3187
3188     // Both src and dst must reside in a register, which they should since we haven't set
3189     // either of them as contained.
3190     assert(addrInfo->info.dstCount == 1);
3191     assert(srcInfo->info.dstCount == 1);
3192 }
3193
3194 //------------------------------------------------------------------------
3195 // BuildCmp: Set the register requirements for a compare.
3196 //
3197 // Arguments:
3198 //    tree      - The node of interest
3199 //
3200 // Return Value:
3201 //    None.
3202 //
3203 void LinearScan::BuildCmp(GenTree* tree)
3204 {
3205     TreeNodeInfo* info = currentNodeInfo;
3206     assert(tree->OperIsCompare() || tree->OperIs(GT_CMP) || tree->OperIs(GT_JCMP));
3207
3208     info->srcCount = 0;
3209     assert((info->dstCount == 1) || (tree->TypeGet() == TYP_VOID));
3210
3211 #ifdef _TARGET_X86_
3212     // If the compare is used by a jump, we just need to set the condition codes. If not, then we need
3213     // to store the result into the low byte of a register, which requires the dst be a byteable register.
3214     // We always set the dst candidates, though, because if this is compare is consumed by a jump, they
3215     // won't be used. We might be able to use GTF_RELOP_JMP_USED to determine this case, but it's not clear
3216     // that flag is maintained until this location (especially for decomposed long compares).
3217     info->setDstCandidates(this, RBM_BYTE_REGS);
3218 #endif // _TARGET_X86_
3219
3220     info->srcCount = appendBinaryLocationInfoToList(tree->AsOp());
3221 }
3222
3223 #endif // !LEGACY_BACKEND