1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
4 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
5 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
7 XX Code Generation Support Methods for Linear Codegen XX
9 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
10 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
20 //------------------------------------------------------------------------
21 // genInitializeRegisterState: Initialize the register state contained in 'regSet'.
24 // On exit the "rsModifiedRegsMask" (in "regSet") holds all the registers' masks hosting an argument on the function
25 // and elements of "rsSpillDesc" (in "regSet") are setted to nullptr.
28 // This method is intended to be called only from initializeStructuresBeforeBlockCodeGeneration.
29 void CodeGen::genInitializeRegisterState()
31 // Initialize the spill tracking logic
35 // If any arguments live in registers, mark those regs as such
40 for (varNum = 0, varDsc = compiler->lvaTable; varNum < compiler->lvaCount; varNum++, varDsc++)
42 // Is this variable a parameter assigned to a register?
43 if (!varDsc->lvIsParam || !varDsc->lvRegister)
48 // Is the argument live on entry to the method?
49 if (!VarSetOps::IsMember(compiler, compiler->fgFirstBB->bbLiveIn, varDsc->lvVarIndex))
54 if (varDsc->IsAddressExposed())
59 // Mark the register as holding the variable
60 regNumber reg = varDsc->GetRegNum();
61 if (genIsValidIntReg(reg))
63 regSet.verifyRegUsed(reg);
68 //------------------------------------------------------------------------
69 // genInitialize: Initialize Scopes, registers, gcInfo and current liveness variables structures
70 // used in the generation of blocks' code before.
73 // -The pointer logic in "gcInfo" for pointers on registers and variable is cleaned.
74 // -"compiler->compCurLife" becomes an empty set
75 // -"compiler->compCurLife" are set to be a clean set
76 // -If there is local var info siScopes scope logic in codegen is initialized in "siInit()"
79 // This method is intended to be called when code generation for blocks happens, and before the list of blocks is
81 void CodeGen::genInitialize()
83 // Initialize the line# tracking logic
84 if (compiler->opts.compScopeInfo)
89 initializeVariableLiveKeeper();
91 genPendingCallLabel = nullptr;
93 // Initialize the pointer tracking code
95 gcInfo.gcRegPtrSetInit();
96 gcInfo.gcVarPtrSetInit();
98 // Initialize the register set logic
100 genInitializeRegisterState();
102 // Make sure a set is allocated for compiler->compCurLife (in the long case), so we can set it to empty without
103 // allocation at the start of each basic block.
104 VarSetOps::AssignNoCopy(compiler, compiler->compCurLife, VarSetOps::MakeEmpty(compiler));
106 // We initialize the stack level before first "BasicBlock" code is generated in case we need to report stack
107 // variable needs home and so its stack offset.
111 //------------------------------------------------------------------------
112 // genCodeForBBlist: Generate code for all the blocks in a method
118 // This is the main method for linear codegen. It calls genCodeForTreeNode
119 // to generate the code for each node in each BasicBlock, and handles BasicBlock
120 // boundaries and branches.
122 void CodeGen::genCodeForBBlist()
124 unsigned savedStkLvl;
127 genInterruptibleUsed = true;
129 // You have to be careful if you create basic blocks from now on
130 compiler->fgSafeBasicBlockCreation = false;
133 #if defined(DEBUG) && defined(TARGET_X86)
135 // Check stack pointer on call stress mode is not compatible with fully interruptible GC. REVIEW: why?
137 if (GetInterruptible() && compiler->opts.compStackCheckOnCall)
139 compiler->opts.compStackCheckOnCall = false;
142 #endif // defined(DEBUG) && defined(TARGET_X86)
144 #if defined(DEBUG) && defined(TARGET_XARCH)
146 // Check stack pointer on return stress mode is not compatible with fully interruptible GC. REVIEW: why?
147 // It is also not compatible with any function that makes a tailcall: we aren't smart enough to only
148 // insert the SP check in the non-tailcall returns.
150 if ((GetInterruptible() || compiler->compTailCallUsed) && compiler->opts.compStackCheckOnRet)
152 compiler->opts.compStackCheckOnRet = false;
155 #endif // defined(DEBUG) && defined(TARGET_XARCH)
157 genMarkLabelsForCodegen();
159 assert(!compiler->fgFirstBBScratch ||
160 compiler->fgFirstBB == compiler->fgFirstBBScratch); // compiler->fgFirstBBScratch has to be first.
162 /* Initialize structures used in the block list iteration */
165 /*-------------------------------------------------------------------------
167 * Walk the basic blocks and generate code for each one
173 for (block = compiler->fgFirstBB; block != nullptr; block = block->bbNext)
177 if (compiler->verbose)
179 printf("\n=============== Generating ");
180 block->dspBlockHeader(compiler, true, true);
181 compiler->fgDispBBLiveness(block);
185 assert(LIR::AsRange(block).CheckLIR(compiler));
187 // Figure out which registers hold variables on entry to this block
189 regSet.ClearMaskVars();
190 gcInfo.gcRegGCrefSetCur = RBM_NONE;
191 gcInfo.gcRegByrefSetCur = RBM_NONE;
193 compiler->m_pLinearScan->recordVarLocationsAtStartOfBB(block);
195 // Updating variable liveness after last instruction of previous block was emitted
196 // and before first of the current block is emitted
197 genUpdateLife(block->bbLiveIn);
199 // Even if liveness didn't change, we need to update the registers containing GC references.
200 // genUpdateLife will update the registers live due to liveness changes. But what about registers that didn't
201 // change? We cleared them out above. Maybe we should just not clear them out, but update the ones that change
202 // here. That would require handling the changes in recordVarLocationsAtStartOfBB().
204 regMaskTP newLiveRegSet = RBM_NONE;
205 regMaskTP newRegGCrefSet = RBM_NONE;
206 regMaskTP newRegByrefSet = RBM_NONE;
208 VARSET_TP removedGCVars(VarSetOps::MakeEmpty(compiler));
209 VARSET_TP addedGCVars(VarSetOps::MakeEmpty(compiler));
211 VarSetOps::Iter iter(compiler, block->bbLiveIn);
212 unsigned varIndex = 0;
213 while (iter.NextElem(&varIndex))
215 LclVarDsc* varDsc = compiler->lvaGetDescByTrackedIndex(varIndex);
217 if (varDsc->lvIsInReg())
219 newLiveRegSet |= varDsc->lvRegMask();
220 if (varDsc->lvType == TYP_REF)
222 newRegGCrefSet |= varDsc->lvRegMask();
224 else if (varDsc->lvType == TYP_BYREF)
226 newRegByrefSet |= varDsc->lvRegMask();
228 if (!varDsc->IsAlwaysAliveInMemory())
231 if (verbose && VarSetOps::IsMember(compiler, gcInfo.gcVarPtrSetCur, varIndex))
233 VarSetOps::AddElemD(compiler, removedGCVars, varIndex);
236 VarSetOps::RemoveElemD(compiler, gcInfo.gcVarPtrSetCur, varIndex);
239 if ((!varDsc->lvIsInReg() || varDsc->IsAlwaysAliveInMemory()) && compiler->lvaIsGCTracked(varDsc))
242 if (verbose && !VarSetOps::IsMember(compiler, gcInfo.gcVarPtrSetCur, varIndex))
244 VarSetOps::AddElemD(compiler, addedGCVars, varIndex);
247 VarSetOps::AddElemD(compiler, gcInfo.gcVarPtrSetCur, varIndex);
251 regSet.SetMaskVars(newLiveRegSet);
254 if (compiler->verbose)
256 if (!VarSetOps::IsEmpty(compiler, addedGCVars))
258 printf("\t\t\t\t\t\t\tAdded GCVars: ");
259 dumpConvertedVarSet(compiler, addedGCVars);
262 if (!VarSetOps::IsEmpty(compiler, removedGCVars))
264 printf("\t\t\t\t\t\t\tRemoved GCVars: ");
265 dumpConvertedVarSet(compiler, removedGCVars);
271 gcInfo.gcMarkRegSetGCref(newRegGCrefSet DEBUGARG(true));
272 gcInfo.gcMarkRegSetByref(newRegByrefSet DEBUGARG(true));
274 /* Blocks with handlerGetsXcptnObj()==true use GT_CATCH_ARG to
275 represent the exception object (TYP_REF).
276 We mark REG_EXCEPTION_OBJECT as holding a GC object on entry
277 to the block, it will be the first thing evaluated
278 (thanks to GTF_ORDER_SIDEEFF).
281 if (handlerGetsXcptnObj(block->bbCatchTyp))
283 for (GenTree* node : LIR::AsRange(block))
285 if (node->OperGet() == GT_CATCH_ARG)
287 gcInfo.gcMarkRegSetGCref(RBM_EXCEPTION_OBJECT);
293 #if defined(TARGET_ARM)
294 genInsertNopForUnwinder(block);
297 /* Start a new code output block */
299 genUpdateCurrentFunclet(block);
303 // Tell everyone which basic block we're working on
305 compiler->compCurBB = block;
307 block->bbEmitCookie = nullptr;
309 // If this block is a jump target or it requires a label then set 'needLabel' to true,
311 bool needLabel = (block->bbFlags & BBF_HAS_LABEL) != 0;
313 if (block == compiler->fgFirstColdBlock)
316 if (compiler->verbose)
318 printf("\nThis is the start of the cold region of the method\n");
321 // We should never have a block that falls through into the Cold section
322 noway_assert(!block->bbPrev->bbFallsThrough());
327 // We also want to start a new Instruction group by calling emitAddLabel below,
328 // when we need accurate bbWeights for this block in the emitter. We force this
329 // whenever our previous block was a BBJ_COND and it has a different weight than us.
331 // Note: We need to have set compCurBB before calling emitAddLabel
333 if ((block->bbPrev != nullptr) && (block->bbPrev->bbJumpKind == BBJ_COND) &&
334 (block->bbWeight != block->bbPrev->bbWeight))
336 JITDUMP("Adding label due to BB weight difference: BBJ_COND " FMT_BB " with weight " FMT_WT
337 " different from " FMT_BB " with weight " FMT_WT "\n",
338 block->bbPrev->bbNum, block->bbPrev->bbWeight, block->bbNum, block->bbWeight);
342 #if FEATURE_LOOP_ALIGN
343 if (GetEmitter()->emitEndsWithAlignInstr())
345 // Force new label if current IG ends with an align instruction.
352 // Mark a label and update the current set of live GC refs
354 block->bbEmitCookie = GetEmitter()->emitAddLabel(gcInfo.gcVarPtrSetCur, gcInfo.gcRegGCrefSetCur,
355 gcInfo.gcRegByrefSetCur, false DEBUG_ARG(block));
358 if (block == compiler->fgFirstColdBlock)
360 // We require the block that starts the Cold section to have a label
361 noway_assert(block->bbEmitCookie);
362 GetEmitter()->emitSetFirstColdIGCookie(block->bbEmitCookie);
365 // Both stacks are always empty on entry to a basic block.
366 assert(genStackLevel == 0);
367 genAdjustStackLevel(block);
368 savedStkLvl = genStackLevel;
370 // Needed when jitting debug code
373 // BBF_INTERNAL blocks don't correspond to any single IL instruction.
374 if (compiler->opts.compDbgInfo && (block->bbFlags & BBF_INTERNAL) &&
375 !compiler->fgBBisScratch(block)) // If the block is the distinguished first scratch block, then no need to
376 // emit a NO_MAPPING entry, immediately after the prolog.
378 genIPmappingAdd(IPmappingDscKind::NoMapping, DebugInfo(), true);
381 bool firstMapping = true;
383 #if defined(FEATURE_EH_FUNCLETS)
384 if (block->bbFlags & BBF_FUNCLET_BEG)
386 genReserveFuncletProlog(block);
388 #endif // FEATURE_EH_FUNCLETS
390 // Clear compCurStmt and compCurLifeTree.
391 compiler->compCurStmt = nullptr;
392 compiler->compCurLifeTree = nullptr;
394 // Emit poisoning into scratch BB that comes right after prolog.
395 // We cannot emit this code in the prolog as it might make the prolog too large.
396 if (compiler->compShouldPoisonFrame() && compiler->fgBBisScratch(block))
398 genPoisonFrame(newLiveRegSet);
401 // Traverse the block in linear order, generating code for each node as we
402 // as we encounter it.
403 CLANG_FORMAT_COMMENT_ANCHOR;
406 // Set the use-order numbers for each node.
409 for (GenTree* node : LIR::AsRange(block))
411 assert((node->gtDebugFlags & GTF_DEBUG_NODE_CG_CONSUMED) == 0);
414 if (node->isContained() || node->IsCopyOrReload())
419 for (GenTree* operand : node->Operands())
421 genNumberOperandUse(operand, useNum);
427 bool addRichMappings = JitConfig.RichDebugInfo() != 0;
429 INDEBUG(addRichMappings |= JitConfig.JitDisasmWithDebugInfo() != 0);
430 INDEBUG(addRichMappings |= JitConfig.WriteRichDebugInfoFile() != nullptr);
433 for (GenTree* node : LIR::AsRange(block))
435 // Do we have a new IL offset?
436 if (node->OperGet() == GT_IL_OFFSET)
438 GenTreeILOffset* ilOffset = node->AsILOffset();
439 DebugInfo rootDI = ilOffset->gtStmtDI.GetRoot();
440 if (rootDI.IsValid())
442 genEnsureCodeEmitted(currentDI);
444 genIPmappingAdd(IPmappingDscKind::Normal, currentDI, firstMapping);
445 firstMapping = false;
448 if (addRichMappings && ilOffset->gtStmtDI.IsValid())
450 genAddRichIPMappingHere(ilOffset->gtStmtDI);
454 assert(ilOffset->gtStmtLastILoffs <= compiler->info.compILCodeSize ||
455 ilOffset->gtStmtLastILoffs == BAD_IL_OFFSET);
457 if (compiler->opts.dspCode && compiler->opts.dspInstrs && ilOffset->gtStmtLastILoffs != BAD_IL_OFFSET)
459 while (genCurDispOffset <= ilOffset->gtStmtLastILoffs)
461 genCurDispOffset += dumpSingleInstr(compiler->info.compCode, genCurDispOffset, "> ");
468 genCodeForTreeNode(node);
469 if (node->gtHasReg(compiler) && node->IsUnusedValue())
473 } // end for each node in block
476 // The following set of register spill checks and GC pointer tracking checks used to be
477 // performed at statement boundaries. Now, with LIR, there are no statements, so they are
478 // performed at the end of each block.
479 // TODO: could these checks be performed more frequently? E.g., at each location where
480 // the register allocator says there are no live non-variable registers. Perhaps this could
481 // be done by using the map maintained by LSRA (operandToLocationInfoMap) to mark a node
482 // somehow when, after the execution of that node, there will be no live non-variable registers.
486 /* Make sure we didn't bungle pointer register tracking */
488 regMaskTP ptrRegs = gcInfo.gcRegGCrefSetCur | gcInfo.gcRegByrefSetCur;
489 regMaskTP nonVarPtrRegs = ptrRegs & ~regSet.GetMaskVars();
491 // If return is a GC-type, clear it. Note that if a common
492 // epilog is generated (genReturnBB) it has a void return
493 // even though we might return a ref. We can't use the compRetType
494 // as the determiner because something we are tracking as a byref
495 // might be used as a return value of a int function (which is legal)
496 GenTree* blockLastNode = block->lastNode();
497 if ((blockLastNode != nullptr) && (blockLastNode->gtOper == GT_RETURN) &&
498 (varTypeIsGC(compiler->info.compRetType) ||
499 (blockLastNode->AsOp()->gtOp1 != nullptr && varTypeIsGC(blockLastNode->AsOp()->gtOp1->TypeGet()))))
501 nonVarPtrRegs &= ~RBM_INTRET;
506 printf("Regset after " FMT_BB " gcr=", block->bbNum);
507 printRegMaskInt(gcInfo.gcRegGCrefSetCur & ~regSet.GetMaskVars());
508 compiler->GetEmitter()->emitDispRegSet(gcInfo.gcRegGCrefSetCur & ~regSet.GetMaskVars());
510 printRegMaskInt(gcInfo.gcRegByrefSetCur & ~regSet.GetMaskVars());
511 compiler->GetEmitter()->emitDispRegSet(gcInfo.gcRegByrefSetCur & ~regSet.GetMaskVars());
512 printf(", regVars=");
513 printRegMaskInt(regSet.GetMaskVars());
514 compiler->GetEmitter()->emitDispRegSet(regSet.GetMaskVars());
518 noway_assert(nonVarPtrRegs == RBM_NONE);
522 if (block->bbNext == nullptr)
524 // Unit testing of the emitter: generate a bunch of instructions into the last block
525 // (it's as good as any, but better than the prologue, which can only be a single instruction
526 // group) then use DOTNET_JitLateDisasm=* to see if the late disassembler
527 // thinks the instructions are the same as we do.
528 #if defined(TARGET_AMD64) && defined(LATE_DISASM)
529 genAmd64EmitterUnitTests();
530 #elif defined(TARGET_ARM64)
531 genArm64EmitterUnitTests();
532 #endif // TARGET_ARM64
534 #endif // defined(DEBUG)
536 // It is possible to reach the end of the block without generating code for the current IL offset.
537 // For example, if the following IR ends the current block, no code will have been generated for
540 // ( 0, 0) [000040] ------------ il_offset void IL offset: 21
542 // N001 ( 0, 0) [000039] ------------ nop void
544 // This can lead to problems when debugging the generated code. To prevent these issues, make sure
545 // we've generated code for the last IL offset we saw in the block.
546 genEnsureCodeEmitted(currentDI);
548 /* Is this the last block, and are there any open scopes left ? */
550 bool isLastBlockProcessed = (block->bbNext == nullptr);
551 if (block->isBBCallAlwaysPair())
553 isLastBlockProcessed = (block->bbNext->bbNext == nullptr);
556 if (compiler->opts.compDbgInfo && isLastBlockProcessed)
558 varLiveKeeper->siEndAllVariableLiveRange(compiler->compCurLife);
561 if (compiler->opts.compScopeInfo && (compiler->info.compVarScopesCount > 0))
566 SubtractStackLevel(savedStkLvl);
569 // compCurLife should be equal to the liveOut set, except that we don't keep
570 // it up to date for vars that are not register candidates
571 // (it would be nice to have a xor set function)
573 VARSET_TP mismatchLiveVars(VarSetOps::Diff(compiler, block->bbLiveOut, compiler->compCurLife));
574 VarSetOps::UnionD(compiler, mismatchLiveVars,
575 VarSetOps::Diff(compiler, compiler->compCurLife, block->bbLiveOut));
576 VarSetOps::Iter mismatchLiveVarIter(compiler, mismatchLiveVars);
577 unsigned mismatchLiveVarIndex = 0;
578 bool foundMismatchedRegVar = false;
579 while (mismatchLiveVarIter.NextElem(&mismatchLiveVarIndex))
581 LclVarDsc* varDsc = compiler->lvaGetDescByTrackedIndex(mismatchLiveVarIndex);
582 if (varDsc->lvIsRegCandidate())
584 if (!foundMismatchedRegVar)
586 JITDUMP("Mismatched live reg vars after " FMT_BB ":", block->bbNum);
587 foundMismatchedRegVar = true;
589 JITDUMP(" V%02u", compiler->lvaTrackedIndexToLclNum(mismatchLiveVarIndex));
592 if (foundMismatchedRegVar)
595 assert(!"Found mismatched live reg var(s) after block");
599 /* Both stacks should always be empty on exit from a basic block */
600 noway_assert(genStackLevel == 0);
603 // On AMD64, we need to generate a NOP after a call that is the last instruction of the block, in several
604 // situations, to support proper exception handling semantics. This is mostly to ensure that when the stack
605 // walker computes an instruction pointer for a frame, that instruction pointer is in the correct EH region.
606 // The document "X64 and ARM ABIs.docx" has more details. The situations:
607 // 1. If the call instruction is in a different EH region as the instruction that follows it.
608 // 2. If the call immediately precedes an OS epilog. (Note that what the JIT or VM consider an epilog might
609 // be slightly different from what the OS considers an epilog, and it is the OS-reported epilog that matters
611 // We handle case #1 here, and case #2 in the emitter.
612 if (GetEmitter()->emitIsLastInsCall())
614 // Ok, the last instruction generated is a call instruction. Do any of the other conditions hold?
615 // Note: we may be generating a few too many NOPs for the case of call preceding an epilog. Technically,
616 // if the next block is a BBJ_RETURN, an epilog will be generated, but there may be some instructions
617 // generated before the OS epilog starts, such as a GS cookie check.
618 if ((block->bbNext == nullptr) || !BasicBlock::sameEHRegion(block, block->bbNext))
620 // We only need the NOP if we're not going to generate any more code as part of the block end.
622 switch (block->bbJumpKind)
626 case BBJ_CALLFINALLY:
628 // We're going to generate more code below anyway, so no need for the NOP.
631 case BBJ_EHFINALLYRET:
633 case BBJ_EHFILTERRET:
634 // These are the "epilog follows" case, handled in the emitter.
639 if (block->bbNext == nullptr)
641 // Call immediately before the end of the code; we should never get here .
642 instGen(INS_BREAKPOINT); // This should never get executed
653 // These can't have a call as the last instruction!
656 noway_assert(!"Unexpected bbJumpKind");
661 #endif // TARGET_AMD64
663 /* Do we need to generate a jump or return? */
665 switch (block->bbJumpKind)
672 // If we have a throw at the end of a function or funclet, we need to emit another instruction
673 // afterwards to help the OS unwinder determine the correct context during unwind.
674 // We insert an unexecuted breakpoint instruction in several situations
675 // following a throw instruction:
676 // 1. If the throw is the last instruction of the function or funclet. This helps
677 // the OS unwinder determine the correct context during an unwind from the
679 // 2. If this is this is the last block of the hot section.
680 // 3. If the subsequent block is a special throw block.
681 // 4. On AMD64, if the next block is in a different EH region.
682 if ((block->bbNext == nullptr) || (block->bbNext->bbFlags & BBF_FUNCLET_BEG) ||
683 !BasicBlock::sameEHRegion(block, block->bbNext) ||
684 (!isFramePointerUsed() && compiler->fgIsThrowHlpBlk(block->bbNext)) ||
685 block->bbNext == compiler->fgFirstColdBlock)
687 instGen(INS_BREAKPOINT); // This should never get executed
689 // Do likewise for blocks that end in DOES_NOT_RETURN calls
690 // that were not caught by the above rules. This ensures that
691 // gc register liveness doesn't change across call instructions
692 // in fully-interruptible mode.
695 GenTree* call = block->lastNode();
697 if ((call != nullptr) && (call->gtOper == GT_CALL))
699 if ((call->AsCall()->gtCallMoreFlags & GTF_CALL_M_DOES_NOT_RETURN) != 0)
701 instGen(INS_BREAKPOINT); // This should never get executed
708 case BBJ_CALLFINALLY:
709 block = genCallFinally(block);
712 #if defined(FEATURE_EH_FUNCLETS)
715 genEHCatchRet(block);
718 case BBJ_EHFINALLYRET:
720 case BBJ_EHFILTERRET:
721 genReserveFuncletEpilog(block);
724 #else // !FEATURE_EH_FUNCLETS
727 noway_assert(!"Unexpected BBJ_EHCATCHRET"); // not used on x86
730 case BBJ_EHFINALLYRET:
732 case BBJ_EHFILTERRET:
733 genEHFinallyOrFilterRet(block);
736 #endif // !FEATURE_EH_FUNCLETS
745 // If a block was selected to place an alignment instruction because it ended
746 // with a jump, do not remove jumps from such blocks.
747 // Do not remove a jump between hot and cold regions.
748 bool isRemovableJmpCandidate =
749 !block->hasAlign() && !compiler->fgInDifferentRegions(block, block->bbJumpDest);
752 // AMD64 requires an instruction after a call instruction for unwinding
753 // inside an EH region so if the last instruction generated was a call instruction
754 // do not allow this jump to be marked for possible later removal.
755 isRemovableJmpCandidate = isRemovableJmpCandidate && !GetEmitter()->emitIsLastInsCall();
756 #endif // TARGET_AMD64
758 inst_JMP(EJ_jmp, block->bbJumpDest, isRemovableJmpCandidate);
761 inst_JMP(EJ_jmp, block->bbJumpDest);
762 #endif // TARGET_XARCH
768 #if FEATURE_LOOP_ALIGN
769 // This is the last place where we operate on blocks and after this, we operate
770 // on IG. Hence, if we know that the destination of "block" is the first block
771 // of a loop and needs alignment (it has BBF_LOOP_ALIGN), then "block" represents
772 // end of the loop. Propagate that information on the IG through "igLoopBackEdge".
774 // During emitter, this information will be used to calculate the loop size.
775 // Depending on the loop size, decision of whether to align a loop or not will be taken.
777 // In the emitter, we need to calculate the loop size from `block->bbJumpDest` through
778 // `block` (inclusive). Thus, we need to ensure there is a label on the lexical fall-through
779 // block, even if one is not otherwise needed, to be able to calculate the size of this
780 // loop (loop size is calculated by walking the instruction groups; see emitter::getLoopSize()).
782 if (block->bbJumpDest->isLoopAlign())
784 GetEmitter()->emitSetLoopBackEdge(block->bbJumpDest);
786 if (block->bbNext != nullptr)
788 JITDUMP("Mark " FMT_BB " as label: alignment end-of-loop\n", block->bbNext->bbNum);
789 block->bbNext->bbFlags |= BBF_HAS_LABEL;
792 #endif // FEATURE_LOOP_ALIGN
797 noway_assert(!"Unexpected bbJumpKind");
801 #if FEATURE_LOOP_ALIGN
802 if (block->hasAlign())
804 // If this block has 'align' instruction in the end (identified by BBF_HAS_ALIGN),
805 // then need to add align instruction in the current "block".
807 // For non-adaptive alignment, add alignment instruction of size depending on the
808 // compJitAlignLoopBoundary.
809 // For adaptive alignment, alignment instruction will always be of 15 bytes for xarch
810 // and 16 bytes for arm64.
812 assert(ShouldAlignLoops());
813 assert(!block->isBBCallAlwaysPairTail());
814 #if FEATURE_EH_CALLFINALLY_THUNKS
815 assert(block->bbJumpKind != BBJ_CALLFINALLY);
816 #endif // FEATURE_EH_CALLFINALLY_THUNKS
818 GetEmitter()->emitLoopAlignment(DEBUG_ARG1(block->bbJumpKind == BBJ_ALWAYS));
821 if ((block->bbNext != nullptr) && (block->bbNext->isLoopAlign()))
823 if (compiler->opts.compJitHideAlignBehindJmp)
825 // The current IG is the one that is just before the IG having loop start.
826 // Establish a connection of recent align instruction emitted to the loop
827 // it actually is aligning using 'idaLoopHeadPredIG'.
828 GetEmitter()->emitConnectAlignInstrWithCurIG();
834 if (compiler->verbose)
836 varLiveKeeper->dumpBlockVariableLiveRanges(block);
838 compiler->compCurBB = nullptr;
840 } //------------------ END-FOR each block of the method -------------------
842 // There could be variables alive at this point. For example see lvaKeepAliveAndReportThis.
843 // This call is for cleaning the GC refs
844 genUpdateLife(VarSetOps::MakeEmpty(compiler));
846 /* Finalize the spill tracking logic */
850 /* Finalize the temp tracking logic */
855 if (compiler->verbose)
858 printf("compCycleEstimate = %6d, compSizeEstimate = %5d ", compiler->compCycleEstimate,
859 compiler->compSizeEstimate);
860 printf("%s\n", compiler->info.compFullName);
866 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
867 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
869 XX Register Management XX
871 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
872 XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
875 //------------------------------------------------------------------------
876 // genSpillVar: Spill a local variable
879 // tree - the lclVar node for the variable being spilled
885 // The lclVar must be a register candidate (lvRegCandidate)
887 void CodeGen::genSpillVar(GenTree* tree)
889 unsigned varNum = tree->AsLclVarCommon()->GetLclNum();
890 LclVarDsc* varDsc = compiler->lvaGetDesc(varNum);
892 assert(varDsc->lvIsRegCandidate());
894 // We don't actually need to spill if it is already living in memory
895 bool needsSpill = ((tree->gtFlags & GTF_VAR_DEF) == 0 && varDsc->lvIsInReg());
898 // In order for a lclVar to have been allocated to a register, it must not have been aliasable, and can
899 // therefore be store-normalized (rather than load-normalized). In fact, not performing store normalization
900 // can lead to problems on architectures where a lclVar may be allocated to a register that is not
901 // addressable at the granularity of the lclVar's defined type (e.g. x86).
902 var_types lclType = varDsc->GetStackSlotHomeType();
903 emitAttr size = emitTypeSize(lclType);
905 // If this is a write-thru or a single-def variable, we don't actually spill at a use,
906 // but we will kill the var in the reg (below).
907 if (!varDsc->IsAlwaysAliveInMemory())
909 instruction storeIns = ins_Store(lclType, compiler->isSIMDTypeLocalAligned(varNum));
910 assert(varDsc->GetRegNum() == tree->GetRegNum());
911 inst_TT_RV(storeIns, size, tree, tree->GetRegNum());
914 // We should only have both GTF_SPILL (i.e. the flag causing this method to be called) and
915 // GTF_SPILLED on a write-thru/single-def def, for which we should not be calling this method.
916 assert((tree->gtFlags & GTF_SPILLED) == 0);
918 // Remove the live var from the register.
919 genUpdateRegLife(varDsc, /*isBorn*/ false, /*isDying*/ true DEBUGARG(tree));
920 gcInfo.gcMarkRegSetNpt(varDsc->lvRegMask());
922 if (VarSetOps::IsMember(compiler, gcInfo.gcTrkStkPtrLcls, varDsc->lvVarIndex))
925 if (!VarSetOps::IsMember(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex))
927 JITDUMP("\t\t\t\t\t\t\tVar V%02u becoming live\n", varNum);
931 JITDUMP("\t\t\t\t\t\t\tVar V%02u continuing live\n", varNum);
934 VarSetOps::AddElemD(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex);
938 tree->gtFlags &= ~GTF_SPILL;
939 // If this is NOT a write-thru, reset the var location.
940 if ((tree->gtFlags & GTF_SPILLED) == 0)
942 varDsc->SetRegNum(REG_STK);
943 if (varTypeIsMultiReg(tree))
945 varDsc->SetOtherReg(REG_STK);
950 // We only have 'GTF_SPILL' and 'GTF_SPILLED' on a def of a write-thru lclVar
951 // or a single-def var that is to be spilled at its definition.
952 assert((varDsc->IsAlwaysAliveInMemory()) && ((tree->gtFlags & GTF_VAR_DEF) != 0));
957 // We need this after "lvRegNum" has change because now we are sure that varDsc->lvIsInReg() is false.
958 // "SiVarLoc" constructor uses the "LclVarDsc" of the variable.
959 varLiveKeeper->siUpdateVariableLiveRange(varDsc, varNum);
963 //------------------------------------------------------------------------
964 // genUpdateVarReg: Update the current register location for a multi-reg lclVar
967 // varDsc - the LclVarDsc for the lclVar
968 // tree - the lclVar node
969 // regIndex - the index of the register in the node
972 void CodeGenInterface::genUpdateVarReg(LclVarDsc* varDsc, GenTree* tree, int regIndex)
974 // This should only be called for multireg lclVars.
975 assert(compiler->lvaEnregMultiRegVars);
976 assert(tree->IsMultiRegLclVar() || (tree->gtOper == GT_COPY));
977 varDsc->SetRegNum(tree->GetRegByIndex(regIndex));
980 //------------------------------------------------------------------------
981 // genUpdateVarReg: Update the current register location for a lclVar
984 // varDsc - the LclVarDsc for the lclVar
985 // tree - the lclVar node
988 void CodeGenInterface::genUpdateVarReg(LclVarDsc* varDsc, GenTree* tree)
990 // This should not be called for multireg lclVars.
991 assert((tree->OperIsScalarLocal() && !tree->IsMultiRegLclVar()) || (tree->gtOper == GT_COPY));
992 varDsc->SetRegNum(tree->GetRegNum());
995 //------------------------------------------------------------------------
996 // sameRegAsDst: Return the child that has the same reg as the dst (if any)
999 // tree - the node of interest
1000 // other - an out parameter to return the other child
1003 // If 'tree' has a child with the same assigned register as its target reg,
1004 // that child will be returned, and 'other' will contain the non-matching child.
1005 // Otherwise, both other and the return value will be nullptr.
1007 GenTree* sameRegAsDst(GenTree* tree, GenTree*& other /*out*/)
1009 if (tree->GetRegNum() == REG_NA)
1015 GenTree* op1 = tree->AsOp()->gtOp1;
1016 GenTree* op2 = tree->AsOp()->gtOp2;
1017 if (op1->GetRegNum() == tree->GetRegNum())
1022 if (op2->GetRegNum() == tree->GetRegNum())
1034 //------------------------------------------------------------------------
1035 // genUnspillLocal: Reload a register candidate local into a register, if needed.
1038 // varNum - The variable number of the local to be reloaded (unspilled).
1039 // It may be a local field.
1040 // type - The type of the local.
1041 // lclNode - The node being unspilled. Note that for a multi-reg local,
1042 // the gtLclNum will be that of the parent struct.
1043 // regNum - The register that 'varNum' should be loaded to.
1044 // reSpill - True if it will be immediately spilled after use.
1045 // isLastUse - True if this is a last use of 'varNum'.
1048 // The caller must have determined that this local needs to be unspilled.
1049 void CodeGen::genUnspillLocal(
1050 unsigned varNum, var_types type, GenTreeLclVar* lclNode, regNumber regNum, bool reSpill, bool isLastUse)
1052 LclVarDsc* varDsc = compiler->lvaGetDesc(varNum);
1053 inst_set_SV_var(lclNode);
1054 instruction ins = ins_Load(type, compiler->isSIMDTypeLocalAligned(varNum));
1055 GetEmitter()->emitIns_R_S(ins, emitTypeSize(type), regNum, varNum, 0);
1057 // TODO-Review: We would like to call:
1058 // genUpdateRegLife(varDsc, /*isBorn*/ true, /*isDying*/ false DEBUGARG(tree));
1059 // instead of the following code, but this ends up hitting this assert:
1060 // assert((regSet.GetMaskVars() & regMask) == 0);
1061 // due to issues with LSRA resolution moves.
1062 // So, just force it for now. This probably indicates a condition that creates a GC hole!
1064 // Extra note: I think we really want to call something like gcInfo.gcUpdateForRegVarMove,
1065 // because the variable is not really going live or dead, but that method is somewhat poorly
1066 // factored because it, in turn, updates rsMaskVars which is part of RegSet not GCInfo.
1067 // TODO-Cleanup: This code exists in other CodeGen*.cpp files, and should be moved to CodeGenCommon.cpp.
1069 // Don't update the variable's location if we are just re-spilling it again.
1073 varDsc->SetRegNum(regNum);
1075 // We want "VariableLiveRange" inclusive on the beginning and exclusive on the ending.
1076 // For that we shouldn't report an update of the variable location if is becoming dead
1077 // on the same native offset.
1080 // Report the home change for this variable
1081 varLiveKeeper->siUpdateVariableLiveRange(varDsc, varNum);
1084 if (!varDsc->IsAlwaysAliveInMemory())
1087 if (VarSetOps::IsMember(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex))
1089 JITDUMP("\t\t\t\t\t\t\tRemoving V%02u from gcVarPtrSetCur\n", varNum);
1092 VarSetOps::RemoveElemD(compiler, gcInfo.gcVarPtrSetCur, varDsc->lvVarIndex);
1096 if (compiler->verbose)
1098 printf("\t\t\t\t\t\t\tV%02u in reg ", varNum);
1099 varDsc->PrintVarReg();
1100 printf(" is becoming live ");
1101 compiler->printTreeID(lclNode);
1106 regSet.AddMaskVars(genGetRegMask(varDsc));
1109 gcInfo.gcMarkRegPtrVal(regNum, type);
1112 //------------------------------------------------------------------------
1113 // genUnspillRegIfNeeded: Reload a MultiReg source value into a register, if needed
1116 // tree - the MultiReg node of interest.
1117 // multiRegIndex - the index of the value to reload, if needed.
1120 // It must *not* be a GT_LCL_VAR (those are handled separately).
1121 // In the normal case, the value will be reloaded into the register it
1122 // was originally computed into. However, if that register is not available,
1123 // the register allocator will have allocated a different register, and
1124 // inserted a GT_RELOAD to indicate the register into which it should be
1127 void CodeGen::genUnspillRegIfNeeded(GenTree* tree, unsigned multiRegIndex)
1129 GenTree* unspillTree = tree;
1130 assert(unspillTree->IsMultiRegNode());
1132 if (tree->gtOper == GT_RELOAD)
1134 unspillTree = tree->AsOp()->gtOp1;
1137 // In case of multi-reg node, GTF_SPILLED flag on it indicates that
1138 // one or more of its result regs are spilled. Individual spill flags need to be
1139 // queried to determine which specific result regs need to be unspilled.
1140 if ((unspillTree->gtFlags & GTF_SPILLED) == 0)
1144 GenTreeFlags spillFlags = unspillTree->GetRegSpillFlagByIdx(multiRegIndex);
1145 if ((spillFlags & GTF_SPILLED) == 0)
1150 regNumber dstReg = tree->GetRegByIndex(multiRegIndex);
1151 if (dstReg == REG_NA)
1153 assert(tree->IsCopyOrReload());
1154 dstReg = unspillTree->GetRegByIndex(multiRegIndex);
1156 if (tree->IsMultiRegLclVar())
1158 GenTreeLclVar* lclNode = tree->AsLclVar();
1159 unsigned fieldVarNum = compiler->lvaGetDesc(lclNode)->lvFieldLclStart + multiRegIndex;
1160 bool reSpill = ((spillFlags & GTF_SPILL) != 0);
1161 bool isLastUse = lclNode->IsLastUse(multiRegIndex);
1162 genUnspillLocal(fieldVarNum, compiler->lvaGetDesc(fieldVarNum)->TypeGet(), lclNode, dstReg, reSpill, isLastUse);
1166 var_types dstType = unspillTree->GetRegTypeByIndex(multiRegIndex);
1167 regNumber unspillTreeReg = unspillTree->GetRegByIndex(multiRegIndex);
1168 TempDsc* t = regSet.rsUnspillInPlace(unspillTree, unspillTreeReg, multiRegIndex);
1169 emitAttr emitType = emitActualTypeSize(dstType);
1170 GetEmitter()->emitIns_R_S(ins_Load(dstType), emitType, dstReg, t->tdTempNum(), 0);
1171 regSet.tmpRlsTemp(t);
1172 gcInfo.gcMarkRegPtrVal(dstReg, dstType);
1176 //------------------------------------------------------------------------
1177 // genUnspillRegIfNeeded: Reload the value into a register, if needed
1180 // tree - the node of interest.
1183 // In the normal case, the value will be reloaded into the register it
1184 // was originally computed into. However, if that register is not available,
1185 // the register allocator will have allocated a different register, and
1186 // inserted a GT_RELOAD to indicate the register into which it should be
1189 // A GT_RELOAD never has a reg candidate lclVar or multi-reg lclVar as its child.
1190 // This is because register candidates locals always have distinct tree nodes
1191 // for uses and definitions. (This is unlike non-register candidate locals which
1192 // may be "defined" by a GT_LCL_VAR node that loads it into a register. It may
1193 // then have a GT_RELOAD inserted if it needs a different register, though this
1194 // is unlikely to happen except in stress modes.)
1196 void CodeGen::genUnspillRegIfNeeded(GenTree* tree)
1198 GenTree* unspillTree = tree;
1199 if (tree->gtOper == GT_RELOAD)
1201 unspillTree = tree->AsOp()->gtOp1;
1204 if ((unspillTree->gtFlags & GTF_SPILLED) != 0)
1206 if (genIsRegCandidateLocal(unspillTree))
1208 // We never have a GT_RELOAD for this case.
1209 assert(tree == unspillTree);
1211 // Reset spilled flag, since we are going to load a local variable from its home location.
1212 unspillTree->gtFlags &= ~GTF_SPILLED;
1214 GenTreeLclVar* lcl = unspillTree->AsLclVar();
1215 LclVarDsc* varDsc = compiler->lvaGetDesc(lcl);
1216 var_types unspillType = varDsc->GetRegisterType(lcl);
1217 assert(unspillType != TYP_UNDEF);
1219 // TODO-Cleanup: The following code could probably be further merged and cleaned up.
1220 #if defined(TARGET_XARCH) || defined(TARGET_ARM64) || defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
1222 // Pick type to reload register from stack with. Note that in
1223 // general, the type of 'lcl' does not have any relation to the
1224 // type of 'varDsc':
1226 // * For normalize-on-load (NOL) locals it is wider under normal
1227 // circumstances, where morph has added a cast on top. In some
1228 // cases it is the same, when morph has used a subrange assertion
1229 // to avoid normalizing.
1231 // * For all locals it can be narrower in some cases, when
1232 // lowering optimizes to use a smaller typed `cmp` (e.g. 32-bit cmp
1233 // for 64-bit local, or 8-bit cmp for 16-bit local).
1235 // * For byrefs it can differ in GC-ness (TYP_I_IMPL vs TYP_BYREF).
1237 // In the NOL case the potential use of subrange assertions means
1238 // we always have to normalize, even if 'lcl' is wide; we could
1239 // have a GTF_SPILLED LCL_VAR<int>(NOL local) with a future
1240 // LCL_VAR<ushort>(same NOL local), where the latter local then
1241 // relies on the normalization to have happened here as part of
1244 if (varDsc->lvNormalizeOnLoad())
1246 unspillType = varDsc->TypeGet();
1250 // Potentially narrower -- see if we should widen.
1251 var_types lclLoadType = varDsc->GetStackSlotHomeType();
1252 assert(lclLoadType != TYP_UNDEF);
1253 if (genTypeSize(unspillType) < genTypeSize(lclLoadType))
1255 unspillType = lclLoadType;
1259 #if defined(TARGET_LOONGARCH64)
1260 if (varTypeIsFloating(spillType) && emitter::isGeneralRegister(tree->GetRegNum()))
1262 unspillType = unspillType == TYP_FLOAT ? TYP_INT : TYP_LONG;
1265 #elif defined(TARGET_ARM)
1266 // No normalizing for ARM
1268 NYI("Unspilling not implemented for this target architecture.");
1271 bool reSpill = ((unspillTree->gtFlags & GTF_SPILL) != 0);
1272 bool isLastUse = lcl->IsLastUse(0);
1273 genUnspillLocal(lcl->GetLclNum(), unspillType, lcl->AsLclVar(), tree->GetRegNum(), reSpill, isLastUse);
1275 else if (unspillTree->IsMultiRegLclVar())
1277 // We never have a GT_RELOAD for this case.
1278 assert(tree == unspillTree);
1280 GenTreeLclVar* lclNode = unspillTree->AsLclVar();
1281 LclVarDsc* varDsc = compiler->lvaGetDesc(lclNode);
1282 unsigned regCount = varDsc->lvFieldCnt;
1284 for (unsigned i = 0; i < regCount; ++i)
1286 GenTreeFlags spillFlags = lclNode->GetRegSpillFlagByIdx(i);
1287 if ((spillFlags & GTF_SPILLED) != 0)
1289 regNumber reg = lclNode->GetRegNumByIdx(i);
1290 unsigned fieldVarNum = varDsc->lvFieldLclStart + i;
1291 bool reSpill = ((spillFlags & GTF_SPILL) != 0);
1292 bool isLastUse = lclNode->IsLastUse(i);
1293 genUnspillLocal(fieldVarNum, compiler->lvaGetDesc(fieldVarNum)->TypeGet(), lclNode, reg, reSpill,
1298 else if (unspillTree->IsMultiRegNode())
1300 // Here we may have a GT_RELOAD, and we will need to use that node ('tree') to
1301 // do the unspilling if needed. However, that tree doesn't have the register
1302 // count, so we use 'unspillTree' for that.
1303 unsigned regCount = unspillTree->GetMultiRegCount(compiler);
1304 for (unsigned i = 0; i < regCount; ++i)
1306 genUnspillRegIfNeeded(tree, i);
1308 unspillTree->gtFlags &= ~GTF_SPILLED;
1312 // Here we may have a GT_RELOAD.
1313 // The spill temp allocated for it is associated with the original tree that defined the
1314 // register that it was spilled from.
1315 // So we use 'unspillTree' to recover that spill temp.
1316 TempDsc* t = regSet.rsUnspillInPlace(unspillTree, unspillTree->GetRegNum());
1317 emitAttr emitType = emitActualTypeSize(unspillTree->TypeGet());
1318 // Reload into the register specified by 'tree' which may be a GT_RELOAD.
1319 regNumber dstReg = tree->GetRegNum();
1320 GetEmitter()->emitIns_R_S(ins_Load(unspillTree->gtType), emitType, dstReg, t->tdTempNum(), 0);
1321 regSet.tmpRlsTemp(t);
1323 unspillTree->gtFlags &= ~GTF_SPILLED;
1324 gcInfo.gcMarkRegPtrVal(dstReg, unspillTree->TypeGet());
1329 //------------------------------------------------------------------------
1330 // genCopyRegIfNeeded: Copy the given node into the specified register
1333 // node - The node that has been evaluated (consumed).
1334 // needReg - The register in which its value is needed.
1337 // This must be a node that has a register.
1339 void CodeGen::genCopyRegIfNeeded(GenTree* node, regNumber needReg)
1341 assert((node->GetRegNum() != REG_NA) && (needReg != REG_NA));
1342 assert(!node->isUsedFromSpillTemp());
1343 inst_Mov(node->TypeGet(), needReg, node->GetRegNum(), /* canSkip */ true);
1346 // Do Liveness update for a subnodes that is being consumed by codegen
1347 // including the logic for reload in case is needed and also takes care
1348 // of locating the value on the desired register.
1349 void CodeGen::genConsumeRegAndCopy(GenTree* node, regNumber needReg)
1351 if (needReg == REG_NA)
1355 genConsumeReg(node);
1356 genCopyRegIfNeeded(node, needReg);
1359 // Check that registers are consumed in the right order for the current node being generated.
1361 void CodeGen::genNumberOperandUse(GenTree* const operand, int& useNum) const
1363 assert(operand != nullptr);
1364 assert(operand->gtUseNum == -1);
1366 if (!operand->isContained() && !operand->IsCopyOrReload())
1368 operand->gtUseNum = useNum;
1373 for (GenTree* op : operand->Operands())
1375 genNumberOperandUse(op, useNum);
1380 void CodeGen::genCheckConsumeNode(GenTree* const node)
1382 assert(node != nullptr);
1386 if (node->gtUseNum == -1)
1388 // nothing wrong if the node was not consumed
1390 else if ((node->gtDebugFlags & GTF_DEBUG_NODE_CG_CONSUMED) != 0)
1392 printf("Node was consumed twice:\n");
1393 compiler->gtDispTree(node, nullptr, nullptr, true);
1395 else if ((lastConsumedNode != nullptr) && (node->gtUseNum < lastConsumedNode->gtUseNum))
1397 printf("Nodes were consumed out-of-order:\n");
1398 compiler->gtDispTree(lastConsumedNode, nullptr, nullptr, true);
1399 compiler->gtDispTree(node, nullptr, nullptr, true);
1403 assert((node->OperGet() == GT_CATCH_ARG) || ((node->gtDebugFlags & GTF_DEBUG_NODE_CG_CONSUMED) == 0));
1404 assert((lastConsumedNode == nullptr) || (node->gtUseNum == -1) || (node->gtUseNum > lastConsumedNode->gtUseNum));
1406 node->gtDebugFlags |= GTF_DEBUG_NODE_CG_CONSUMED;
1407 lastConsumedNode = node;
1411 //--------------------------------------------------------------------
1412 // genConsumeReg: Do liveness update for a single register of a multireg child node
1413 // that is being consumed by codegen.
1416 // tree - GenTree node
1417 // multiRegIndex - The index of the register to be consumed
1420 // Returns the reg number for the given multiRegIndex.
1422 regNumber CodeGen::genConsumeReg(GenTree* tree, unsigned multiRegIndex)
1424 regNumber reg = tree->GetRegByIndex(multiRegIndex);
1425 if (tree->OperIs(GT_COPY))
1427 reg = genRegCopy(tree, multiRegIndex);
1429 else if (reg == REG_NA)
1431 assert(tree->OperIs(GT_RELOAD));
1432 reg = tree->gtGetOp1()->GetRegByIndex(multiRegIndex);
1433 assert(reg != REG_NA);
1435 genUnspillRegIfNeeded(tree, multiRegIndex);
1437 // UpdateLifeFieldVar() will return true if local var should be spilled.
1438 if (tree->IsMultiRegLclVar() && treeLifeUpdater->UpdateLifeFieldVar(tree->AsLclVar(), multiRegIndex))
1440 GenTreeLclVar* lcl = tree->AsLclVar();
1441 genSpillLocal(lcl->GetLclNum(), lcl->GetFieldTypeByIndex(compiler, multiRegIndex), lcl,
1442 lcl->GetRegByIndex(multiRegIndex));
1445 if (tree->gtSkipReloadOrCopy()->OperIs(GT_LCL_VAR))
1447 assert(compiler->lvaEnregMultiRegVars);
1449 GenTreeLclVar* lcl = tree->gtSkipReloadOrCopy()->AsLclVar();
1450 assert(lcl->IsMultiReg());
1452 LclVarDsc* varDsc = compiler->lvaGetDesc(lcl);
1453 assert(varDsc->lvPromoted);
1454 assert(multiRegIndex < varDsc->lvFieldCnt);
1455 unsigned fieldVarNum = varDsc->lvFieldLclStart + multiRegIndex;
1456 LclVarDsc* fldVarDsc = compiler->lvaGetDesc(fieldVarNum);
1457 assert(fldVarDsc->lvLRACandidate);
1459 if (fldVarDsc->GetRegNum() == REG_STK)
1461 // We have loaded this into a register only temporarily
1462 gcInfo.gcMarkRegSetNpt(genRegMask(reg));
1464 else if (lcl->IsLastUse(multiRegIndex))
1466 gcInfo.gcMarkRegSetNpt(genRegMask(fldVarDsc->GetRegNum()));
1471 gcInfo.gcMarkRegSetNpt(tree->gtGetRegMask());
1476 //--------------------------------------------------------------------
1477 // genConsumeReg: Do liveness update for a subnode that is being
1478 // consumed by codegen.
1481 // tree - GenTree node
1484 // Returns the reg number of tree.
1485 // In case of multi-reg call node returns the first reg number
1486 // of the multi-reg return.
1488 regNumber CodeGen::genConsumeReg(GenTree* tree)
1490 if (tree->OperGet() == GT_COPY)
1495 // Handle the case where we have a lclVar that needs to be copied before use (i.e. because it
1496 // interferes with one of the other sources (or the target, if it's a "delayed use" register)).
1497 // TODO-Cleanup: This is a special copyReg case in LSRA - consider eliminating these and
1498 // always using GT_COPY to make the lclVar location explicit.
1499 // Note that we have to do this before calling genUpdateLife because otherwise if we spill it
1500 // the lvRegNum will be set to REG_STK and we will lose track of what register currently holds
1501 // the lclVar (normally when a lclVar is spilled it is then used from its former register
1502 // location, which matches the GetRegNum() on the node).
1503 // (Note that it doesn't matter if we call this before or after genUnspillRegIfNeeded
1504 // because if it's on the stack it will always get reloaded into tree->GetRegNum()).
1505 if (genIsRegCandidateLocal(tree))
1507 GenTreeLclVarCommon* lcl = tree->AsLclVarCommon();
1508 LclVarDsc* varDsc = compiler->lvaGetDesc(lcl);
1509 if (varDsc->GetRegNum() != REG_STK)
1511 var_types regType = varDsc->GetRegisterType(lcl);
1512 inst_Mov(regType, tree->GetRegNum(), varDsc->GetRegNum(), /* canSkip */ true);
1516 genUnspillRegIfNeeded(tree);
1518 // genUpdateLife() will also spill local var if marked as GTF_SPILL by calling CodeGen::genSpillVar
1519 genUpdateLife(tree);
1521 // there are three cases where consuming a reg means clearing the bit in the live mask
1522 // 1. it was not produced by a local
1523 // 2. it was produced by a local that is going dead
1524 // 3. it was produced by a local that does not live in that reg (like one allocated on the stack)
1526 if (genIsRegCandidateLocal(tree))
1528 assert(tree->gtHasReg(compiler));
1530 GenTreeLclVarCommon* lcl = tree->AsLclVar();
1531 LclVarDsc* varDsc = compiler->lvaGetDesc(lcl);
1532 assert(varDsc->lvLRACandidate);
1534 if (varDsc->GetRegNum() == REG_STK)
1536 // We have loaded this into a register only temporarily
1537 gcInfo.gcMarkRegSetNpt(genRegMask(tree->GetRegNum()));
1539 else if ((tree->gtFlags & GTF_VAR_DEATH) != 0)
1541 gcInfo.gcMarkRegSetNpt(genRegMask(varDsc->GetRegNum()));
1544 else if (tree->gtSkipReloadOrCopy()->IsMultiRegLclVar())
1546 assert(compiler->lvaEnregMultiRegVars);
1547 GenTreeLclVar* lcl = tree->gtSkipReloadOrCopy()->AsLclVar();
1548 LclVarDsc* varDsc = compiler->lvaGetDesc(lcl);
1549 unsigned firstFieldVarNum = varDsc->lvFieldLclStart;
1550 for (unsigned i = 0; i < varDsc->lvFieldCnt; ++i)
1552 LclVarDsc* fldVarDsc = compiler->lvaGetDesc(firstFieldVarNum + i);
1553 assert(fldVarDsc->lvLRACandidate);
1555 if (tree->OperIs(GT_COPY, GT_RELOAD) && (tree->AsCopyOrReload()->GetRegByIndex(i) != REG_NA))
1557 reg = tree->AsCopyOrReload()->GetRegByIndex(i);
1561 reg = lcl->AsLclVar()->GetRegNumByIdx(i);
1564 if (fldVarDsc->GetRegNum() == REG_STK)
1566 // We have loaded this into a register only temporarily
1567 gcInfo.gcMarkRegSetNpt(genRegMask(reg));
1569 else if (lcl->IsLastUse(i))
1571 gcInfo.gcMarkRegSetNpt(genRegMask(fldVarDsc->GetRegNum()));
1577 gcInfo.gcMarkRegSetNpt(tree->gtGetRegMask());
1580 genCheckConsumeNode(tree);
1581 return tree->GetRegNum();
1584 // Do liveness update for an address tree: one of GT_LEA, GT_LCL_VAR, or GT_CNS_INT (for call indirect).
1585 void CodeGen::genConsumeAddress(GenTree* addr)
1587 if (!addr->isContained())
1589 genConsumeReg(addr);
1591 else if (addr->OperGet() == GT_LEA)
1593 genConsumeAddrMode(addr->AsAddrMode());
1597 // do liveness update for a subnode that is being consumed by codegen
1598 void CodeGen::genConsumeAddrMode(GenTreeAddrMode* addr)
1600 genConsumeOperands(addr);
1603 void CodeGen::genConsumeRegs(GenTree* tree)
1605 #if !defined(TARGET_64BIT)
1606 if (tree->OperGet() == GT_LONG)
1608 genConsumeRegs(tree->gtGetOp1());
1609 genConsumeRegs(tree->gtGetOp2());
1612 #endif // !defined(TARGET_64BIT)
1614 if (tree->isUsedFromSpillTemp())
1616 // spill temps are un-tracked and hence no need to update life
1618 else if (tree->isContained())
1620 if (tree->OperIsIndir())
1622 genConsumeAddress(tree->AsIndir()->Addr());
1624 else if (tree->OperIs(GT_LEA))
1626 genConsumeAddress(tree);
1628 #if defined(TARGET_XARCH) || defined(TARGET_ARM64)
1629 else if (tree->OperIsCompare())
1631 // Compares can be contained by SELECT/compare chains.
1632 genConsumeRegs(tree->gtGetOp1());
1633 genConsumeRegs(tree->gtGetOp2());
1637 else if (tree->OperIs(GT_BFIZ))
1639 // Can be contained as part of LEA on ARM64
1640 GenTreeCast* cast = tree->gtGetOp1()->AsCast();
1641 assert(cast->isContained());
1642 genConsumeAddress(cast->CastOp());
1644 else if (tree->OperIs(GT_CAST))
1646 // Can be contained as part of LEA on ARM64
1647 GenTreeCast* cast = tree->AsCast();
1648 assert(cast->isContained());
1649 genConsumeAddress(cast->CastOp());
1651 else if (tree->OperIs(GT_AND))
1653 // ANDs may be contained in a chain.
1654 genConsumeRegs(tree->gtGetOp1());
1655 genConsumeRegs(tree->gtGetOp2());
1657 else if (tree->OperIsFieldList())
1659 for (GenTreeFieldList::Use& use : tree->AsFieldList()->Uses())
1661 GenTree* fieldNode = use.GetNode();
1662 genConsumeRegs(fieldNode);
1666 else if (tree->OperIsLocalRead())
1668 // A contained lcl var must be living on stack and marked as reg optional, or not be a
1669 // register candidate.
1670 unsigned varNum = tree->AsLclVarCommon()->GetLclNum();
1671 LclVarDsc* varDsc = compiler->lvaGetDesc(varNum);
1673 noway_assert(varDsc->GetRegNum() == REG_STK);
1674 noway_assert(tree->IsRegOptional() || !varDsc->lvLRACandidate);
1676 // Update the life of the lcl var.
1677 genUpdateLife(tree);
1680 #ifdef FEATURE_HW_INTRINSICS
1681 else if (tree->OperIs(GT_HWINTRINSIC))
1683 GenTreeHWIntrinsic* hwintrinsic = tree->AsHWIntrinsic();
1684 genConsumeMultiOpOperands(hwintrinsic);
1686 #endif // FEATURE_HW_INTRINSICS
1687 #endif // TARGET_XARCH
1688 else if (tree->OperIs(GT_BITCAST, GT_NEG, GT_CAST, GT_LSH, GT_RSH, GT_RSZ, GT_BSWAP, GT_BSWAP16))
1690 genConsumeRegs(tree->gtGetOp1());
1692 else if (tree->OperIs(GT_MUL))
1694 genConsumeRegs(tree->gtGetOp1());
1695 genConsumeRegs(tree->gtGetOp2());
1700 // (In)Equality operation that produces bool result, when compared
1701 // against Vector zero, marks its Vector Zero operand as contained.
1702 assert(tree->OperIsLeaf() || tree->IsVectorZero());
1704 assert(tree->OperIsLeaf());
1710 genConsumeReg(tree);
1714 //------------------------------------------------------------------------
1715 // genConsumeOperands: Do liveness update for the operands of a unary or binary tree
1718 // tree - the GenTreeOp whose operands will have their liveness updated.
1723 void CodeGen::genConsumeOperands(GenTreeOp* tree)
1725 GenTree* firstOp = tree->gtOp1;
1726 GenTree* secondOp = tree->gtOp2;
1728 if (firstOp != nullptr)
1730 genConsumeRegs(firstOp);
1732 if (secondOp != nullptr)
1734 genConsumeRegs(secondOp);
1738 #if defined(FEATURE_SIMD) || defined(FEATURE_HW_INTRINSICS)
1739 //------------------------------------------------------------------------
1740 // genConsumeOperands: Do liveness update for the operands of a multi-operand node,
1741 // currently GT_HWINTRINSIC
1744 // tree - the GenTreeMultiOp whose operands will have their liveness updated.
1749 void CodeGen::genConsumeMultiOpOperands(GenTreeMultiOp* tree)
1751 for (GenTree* operand : tree->Operands())
1753 genConsumeRegs(operand);
1756 #endif // defined(FEATURE_SIMD) || defined(FEATURE_HW_INTRINSICS)
1758 #if FEATURE_PUT_STRUCT_ARG_STK
1759 //------------------------------------------------------------------------
1760 // genConsumePutStructArgStk: Do liveness update for the operands of a PutArgStk node.
1761 // Also loads in the right register the addresses of the
1762 // src/dst for rep mov operation.
1765 // putArgNode - the PUTARG_STK tree.
1766 // dstReg - the dstReg for the rep move operation.
1767 // srcReg - the srcReg for the rep move operation.
1768 // sizeReg - the sizeReg for the rep move operation.
1774 // sizeReg can be REG_NA when this function is used to consume the dstReg and srcReg
1775 // for copying on the stack a struct with references.
1776 // The source address/offset is determined from the address on the GT_BLK node, while
1777 // the destination address is the address contained in 'm_stkArgVarNum' plus the offset
1778 // provided in the 'putArgNode'.
1779 // m_stkArgVarNum must be set to the varnum for the local used for placing the "by-value" args on the stack.
1781 void CodeGen::genConsumePutStructArgStk(GenTreePutArgStk* putArgNode,
1786 // The putArgNode children are always contained. We should not consume any registers.
1787 assert(putArgNode->Data()->isContained());
1790 GenTree* src = putArgNode->Data();
1791 regNumber srcAddrReg = REG_NA;
1792 assert(varTypeIsStruct(src));
1793 assert(src->OperIs(GT_BLK) || src->OperIsLocalRead() || (src->OperIs(GT_IND) && varTypeIsSIMD(src)));
1795 assert(dstReg != REG_NA);
1796 assert(srcReg != REG_NA);
1798 // Consume the register for the source address if needed.
1799 if (src->OperIsIndir())
1801 srcAddrReg = genConsumeReg(src->AsIndir()->Addr());
1804 // If the op1 is already in the dstReg - nothing to do.
1805 // Otherwise load the op1 (the address) into the dstReg to copy the struct on the stack by value.
1806 CLANG_FORMAT_COMMENT_ANCHOR;
1809 assert(dstReg != REG_SPBASE);
1810 inst_Mov(TYP_I_IMPL, dstReg, REG_SPBASE, /* canSkip */ false);
1811 #else // !TARGET_X86
1812 GenTree* dstAddr = putArgNode;
1813 if (dstAddr->GetRegNum() != dstReg)
1815 // Generate LEA instruction to load the stack of the outgoing var + SlotNum offset (or the incoming arg area
1816 // for tail calls) in RDI.
1817 // Destination is always local (on the stack) - use EA_PTRSIZE.
1818 assert(m_stkArgVarNum != BAD_VAR_NUM);
1819 GetEmitter()->emitIns_R_S(INS_lea, EA_PTRSIZE, dstReg, m_stkArgVarNum, putArgNode->getArgOffset());
1821 #endif // !TARGET_X86
1823 if (srcAddrReg != REG_NA)
1825 // Source is not known to be on the stack. Use EA_BYREF.
1826 GetEmitter()->emitIns_Mov(INS_mov, EA_BYREF, srcReg, srcAddrReg, /* canSkip */ true);
1830 // Generate LEA instruction to load the LclVar address in RSI.
1831 // Source is known to be on the stack. Use EA_PTRSIZE.
1832 GetEmitter()->emitIns_R_S(INS_lea, EA_PTRSIZE, srcReg, src->AsLclVarCommon()->GetLclNum(),
1833 src->AsLclVarCommon()->GetLclOffs());
1836 if (sizeReg != REG_NA)
1838 unsigned size = putArgNode->GetStackByteSize();
1839 inst_RV_IV(INS_mov, sizeReg, size, EA_PTRSIZE);
1842 #endif // FEATURE_PUT_STRUCT_ARG_STK
1844 #if FEATURE_ARG_SPLIT
1845 //------------------------------------------------------------------------
1846 // genConsumeArgRegSplit: Consume register(s) in Call node to set split struct argument.
1849 // putArgNode - the PUTARG_STK tree.
1854 void CodeGen::genConsumeArgSplitStruct(GenTreePutArgSplit* putArgNode)
1856 assert(putArgNode->OperGet() == GT_PUTARG_SPLIT);
1857 assert(putArgNode->gtHasReg(compiler));
1859 genUnspillRegIfNeeded(putArgNode);
1861 gcInfo.gcMarkRegSetNpt(putArgNode->gtGetRegMask());
1863 genCheckConsumeNode(putArgNode);
1865 #endif // FEATURE_ARG_SPLIT
1867 //------------------------------------------------------------------------
1868 // genPutArgStkFieldList: Generate code for a putArgStk whose source is a GT_FIELD_LIST
1871 // putArgStk - The putArgStk node
1872 // outArgVarNum - The lclVar num for the argument
1875 // The x86 version of this is in codegenxarch.cpp, and doesn't take an
1876 // outArgVarNum, as it pushes its args onto the stack.
1879 void CodeGen::genPutArgStkFieldList(GenTreePutArgStk* putArgStk, unsigned outArgVarNum)
1881 assert(putArgStk->gtOp1->OperIs(GT_FIELD_LIST));
1883 // Evaluate each of the GT_FIELD_LIST items into their register
1884 // and store their register into the outgoing argument area.
1885 const unsigned argOffset = putArgStk->getArgOffset();
1886 for (GenTreeFieldList::Use& use : putArgStk->gtOp1->AsFieldList()->Uses())
1888 GenTree* nextArgNode = use.GetNode();
1889 genConsumeReg(nextArgNode);
1891 regNumber reg = nextArgNode->GetRegNum();
1892 var_types type = use.GetType();
1893 unsigned thisFieldOffset = argOffset + use.GetOffset();
1895 // Emit store instructions to store the registers produced by the GT_FIELD_LIST into the outgoing
1898 #if defined(FEATURE_SIMD)
1899 if (type == TYP_SIMD12)
1901 GetEmitter()->emitStoreSimd12ToLclOffset(outArgVarNum, thisFieldOffset, reg, nextArgNode);
1904 #endif // FEATURE_SIMD
1906 emitAttr attr = emitTypeSize(type);
1907 GetEmitter()->emitIns_S_R(ins_Store(type), attr, reg, outArgVarNum, thisFieldOffset);
1910 // We can't write beyond the arg area unless this is a tail call, in which case we use
1911 // the first stack arg as the base of the incoming arg area.
1913 unsigned areaSize = compiler->lvaLclSize(outArgVarNum);
1914 #if FEATURE_FASTTAILCALL
1915 if (putArgStk->gtCall->IsFastTailCall())
1917 areaSize = compiler->info.compArgStackSize;
1921 assert((thisFieldOffset + genTypeSize(type)) <= areaSize);
1925 #endif // !TARGET_X86
1927 //------------------------------------------------------------------------
1928 // genSetBlockSize: Ensure that the block size is in the given register
1931 // blkNode - The block node
1932 // sizeReg - The register into which the block's size should go
1935 void CodeGen::genSetBlockSize(GenTreeBlk* blkNode, regNumber sizeReg)
1937 if (sizeReg != REG_NA)
1939 unsigned blockSize = blkNode->Size();
1940 if (!blkNode->OperIs(GT_STORE_DYN_BLK))
1942 assert((blkNode->gtRsvdRegs & genRegMask(sizeReg)) != 0);
1943 // This can go via helper which takes the size as a native uint.
1944 instGen_Set_Reg_To_Imm(EA_PTRSIZE, sizeReg, blockSize);
1948 GenTree* sizeNode = blkNode->AsStoreDynBlk()->gtDynamicSize;
1949 inst_Mov(sizeNode->TypeGet(), sizeReg, sizeNode->GetRegNum(), /* canSkip */ true);
1954 //------------------------------------------------------------------------
1955 // genConsumeBlockSrc: Consume the source address register of a block node, if any.
1958 // blkNode - The block node
1960 void CodeGen::genConsumeBlockSrc(GenTreeBlk* blkNode)
1962 GenTree* src = blkNode->Data();
1963 if (blkNode->OperIsCopyBlkOp())
1965 // For a CopyBlk we need the address of the source.
1966 assert(src->isContained());
1967 if (src->OperGet() == GT_IND)
1969 src = src->AsOp()->gtOp1;
1973 // This must be a local.
1974 // For this case, there is no source address register, as it is a
1975 // stack-based address.
1976 assert(src->OperIsLocal());
1982 if (src->OperIsInitVal())
1984 src = src->gtGetOp1();
1990 //------------------------------------------------------------------------
1991 // genSetBlockSrc: Ensure that the block source is in its allocated register.
1994 // blkNode - The block node
1995 // srcReg - The register in which to set the source (address or init val).
1997 void CodeGen::genSetBlockSrc(GenTreeBlk* blkNode, regNumber srcReg)
1999 GenTree* src = blkNode->Data();
2000 if (blkNode->OperIsCopyBlkOp())
2002 // For a CopyBlk we need the address of the source.
2003 if (src->OperGet() == GT_IND)
2005 src = src->AsOp()->gtOp1;
2009 // This must be a local struct.
2010 // Load its address into srcReg.
2011 unsigned varNum = src->AsLclVarCommon()->GetLclNum();
2012 unsigned offset = src->AsLclVarCommon()->GetLclOffs();
2013 GetEmitter()->emitIns_R_S(INS_lea, EA_BYREF, srcReg, varNum, offset);
2019 if (src->OperIsInitVal())
2021 src = src->gtGetOp1();
2024 genCopyRegIfNeeded(src, srcReg);
2027 //------------------------------------------------------------------------
2028 // genConsumeBlockOp: Ensure that the block's operands are enregistered
2031 // blkNode - The block node
2034 // This ensures that the operands are consumed in the proper order to
2035 // obey liveness modeling.
2037 void CodeGen::genConsumeBlockOp(GenTreeBlk* blkNode, regNumber dstReg, regNumber srcReg, regNumber sizeReg)
2039 // We have to consume the registers, and perform any copies, in the actual execution order: dst, src, size.
2041 // Note that the register allocator ensures that the registers ON THE NODES will not interfere
2042 // with one another if consumed (i.e. reloaded or moved to their ASSIGNED reg) in execution order.
2043 // Further, it ensures that they will not interfere with one another if they are then copied
2044 // to the REQUIRED register (if a fixed register requirement) in execution order. This requires,
2045 // then, that we first consume all the operands, then do any necessary moves.
2047 GenTree* const dstAddr = blkNode->Addr();
2049 // First, consume all the sources in order, and verify that registers have been allocated appropriately,
2050 // based on the 'gtBlkOpKind'.
2052 // The destination is always in a register; 'genConsumeReg' asserts that.
2053 genConsumeReg(dstAddr);
2054 // The source may be a local or in a register; 'genConsumeBlockSrc' will check that.
2055 genConsumeBlockSrc(blkNode);
2056 // 'genSetBlockSize' (called below) will ensure that a register has been reserved as needed
2057 // in the case where the size is a constant (i.e. it is not GT_STORE_DYN_BLK).
2058 if (blkNode->OperGet() == GT_STORE_DYN_BLK)
2060 genConsumeReg(blkNode->AsStoreDynBlk()->gtDynamicSize);
2063 // Next, perform any necessary moves.
2064 genCopyRegIfNeeded(dstAddr, dstReg);
2065 genSetBlockSrc(blkNode, srcReg);
2066 genSetBlockSize(blkNode, sizeReg);
2069 //-------------------------------------------------------------------------
2070 // genSpillLocal: Generate the actual spill of a local var.
2073 // varNum - The variable number of the local to be spilled.
2074 // It may be a local field.
2075 // type - The type of the local.
2076 // lclNode - The node being spilled. Note that for a multi-reg local,
2077 // the gtLclNum will be that of the parent struct.
2078 // regNum - The register that 'varNum' is currently in.
2083 void CodeGen::genSpillLocal(unsigned varNum, var_types type, GenTreeLclVar* lclNode, regNumber regNum)
2085 const LclVarDsc* varDsc = compiler->lvaGetDesc(varNum);
2086 assert(!varDsc->lvNormalizeOnStore() || (type == varDsc->GetStackSlotHomeType()));
2088 // We have a register candidate local that is marked with GTF_SPILL.
2089 // This flag generally means that we need to spill this local.
2090 // The exception is the case of a use of an EH/spill-at-single-def var use that is being "spilled"
2091 // to the stack, indicated by GTF_SPILL (note that all EH lclVar defs are always
2092 // spilled, i.e. write-thru. Likewise, single-def vars that are spilled at its definitions).
2093 // An EH or single-def var use is always valid on the stack (so we don't need to actually spill it),
2094 // but the GTF_SPILL flag records the fact that the register value is going dead.
2095 if (((lclNode->gtFlags & GTF_VAR_DEF) != 0) || (!varDsc->IsAlwaysAliveInMemory()))
2097 // Store local variable to its home location.
2098 // Ensure that lclVar stores are typed correctly.
2099 GetEmitter()->emitIns_S_R(ins_Store(type, compiler->isSIMDTypeLocalAligned(varNum)), emitTypeSize(type), regNum,
2104 //-------------------------------------------------------------------------
2105 // genProduceReg: do liveness update for register produced by the current
2106 // node in codegen after code has been emitted for it.
2109 // tree - Gentree node
2113 void CodeGen::genProduceReg(GenTree* tree)
2116 assert((tree->gtDebugFlags & GTF_DEBUG_NODE_CG_PRODUCED) == 0);
2117 tree->gtDebugFlags |= GTF_DEBUG_NODE_CG_PRODUCED;
2120 if (tree->gtFlags & GTF_SPILL)
2122 // Code for GT_COPY node gets generated as part of consuming regs by its parent.
2123 // A GT_COPY node in turn produces reg result and it should never be marked to
2126 // Similarly GT_RELOAD node gets generated as part of consuming regs by its
2127 // parent and should never be marked for spilling.
2128 noway_assert(!tree->IsCopyOrReload());
2130 if (genIsRegCandidateLocal(tree))
2132 GenTreeLclVar* lclNode = tree->AsLclVar();
2133 const LclVarDsc* varDsc = compiler->lvaGetDesc(lclNode);
2134 const unsigned varNum = lclNode->GetLclNum();
2135 const var_types spillType = varDsc->GetRegisterType(lclNode);
2136 genSpillLocal(varNum, spillType, lclNode, tree->GetRegNum());
2138 else if (tree->IsMultiRegLclVar())
2140 assert(compiler->lvaEnregMultiRegVars);
2142 GenTreeLclVar* lclNode = tree->AsLclVar();
2143 const LclVarDsc* varDsc = compiler->lvaGetDesc(lclNode);
2144 const unsigned regCount = lclNode->GetFieldCount(compiler);
2146 for (unsigned i = 0; i < regCount; ++i)
2148 GenTreeFlags flags = lclNode->GetRegSpillFlagByIdx(i);
2149 if ((flags & GTF_SPILL) != 0)
2151 const regNumber reg = lclNode->GetRegNumByIdx(i);
2152 const unsigned fieldVarNum = varDsc->lvFieldLclStart + i;
2153 const var_types spillType = compiler->lvaGetDesc(fieldVarNum)->GetRegisterType();
2154 genSpillLocal(fieldVarNum, spillType, lclNode, reg);
2160 if (tree->IsMultiRegNode())
2162 // In case of multi-reg node, spill flag on it indicates that one or more of its allocated regs need to
2163 // be spilled, and it needs to be further queried to know which of its result regs needs to be spilled.
2164 const unsigned regCount = tree->GetMultiRegCount(compiler);
2166 for (unsigned i = 0; i < regCount; ++i)
2168 GenTreeFlags flags = tree->GetRegSpillFlagByIdx(i);
2169 if ((flags & GTF_SPILL) != 0)
2171 regNumber reg = tree->GetRegByIndex(i);
2172 regSet.rsSpillTree(reg, tree, i);
2173 gcInfo.gcMarkRegSetNpt(genRegMask(reg));
2179 regSet.rsSpillTree(tree->GetRegNum(), tree);
2180 gcInfo.gcMarkRegSetNpt(genRegMask(tree->GetRegNum()));
2183 tree->gtFlags |= GTF_SPILLED;
2184 tree->gtFlags &= ~GTF_SPILL;
2190 // Updating variable liveness after instruction was emitted
2191 genUpdateLife(tree);
2193 // If we've produced a register, mark it as a pointer, as needed.
2194 if (tree->gtHasReg(compiler))
2196 // We only mark the register in the following cases:
2197 // 1. It is not a register candidate local. In this case, we're producing a
2198 // register from a local, but the local is not a register candidate. Thus,
2199 // we must be loading it as a temp register, and any "last use" flag on
2200 // the register wouldn't be relevant.
2201 // 2. The register candidate local is going dead. There's no point to mark
2202 // the register as live, with a GC pointer, if the variable is dead.
2203 if (!genIsRegCandidateLocal(tree) || ((tree->gtFlags & GTF_VAR_DEATH) == 0))
2205 // Multi-reg nodes will produce more than one register result.
2206 // Mark all the regs produced by the node.
2207 if (tree->IsMultiRegCall())
2209 const GenTreeCall* call = tree->AsCall();
2210 const ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc();
2211 const unsigned regCount = retTypeDesc->GetReturnRegCount();
2213 for (unsigned i = 0; i < regCount; ++i)
2215 regNumber reg = call->GetRegNumByIdx(i);
2216 var_types type = retTypeDesc->GetReturnRegType(i);
2217 gcInfo.gcMarkRegPtrVal(reg, type);
2220 else if (tree->IsCopyOrReloadOfMultiRegCall())
2222 // we should never see reload of multi-reg call here
2223 // because GT_RELOAD gets generated in reg consuming path.
2224 noway_assert(tree->OperGet() == GT_COPY);
2226 // A multi-reg GT_COPY node produces those regs to which
2227 // copy has taken place.
2228 const GenTreeCopyOrReload* copy = tree->AsCopyOrReload();
2229 const GenTreeCall* call = copy->gtGetOp1()->AsCall();
2230 const ReturnTypeDesc* retTypeDesc = call->GetReturnTypeDesc();
2231 const unsigned regCount = retTypeDesc->GetReturnRegCount();
2233 for (unsigned i = 0; i < regCount; ++i)
2235 var_types type = retTypeDesc->GetReturnRegType(i);
2236 regNumber toReg = copy->GetRegNumByIdx(i);
2238 if (toReg != REG_NA)
2240 gcInfo.gcMarkRegPtrVal(toReg, type);
2244 else if (tree->IsMultiRegLclVar())
2246 assert(compiler->lvaEnregMultiRegVars);
2247 GenTreeLclVar* lclNode = tree->AsLclVar();
2248 LclVarDsc* varDsc = compiler->lvaGetDesc(lclNode);
2249 unsigned regCount = varDsc->lvFieldCnt;
2250 for (unsigned i = 0; i < regCount; i++)
2252 if (!lclNode->IsLastUse(i))
2254 regNumber reg = lclNode->GetRegByIndex(i);
2257 var_types type = compiler->lvaGetDesc(varDsc->lvFieldLclStart + i)->TypeGet();
2258 gcInfo.gcMarkRegPtrVal(reg, type);
2265 gcInfo.gcMarkRegPtrVal(tree->GetRegNum(), tree->TypeGet());
2271 // transfer gc/byref status of src reg to dst reg
2272 void CodeGen::genTransferRegGCState(regNumber dst, regNumber src)
2274 regMaskTP srcMask = genRegMask(src);
2275 regMaskTP dstMask = genRegMask(dst);
2277 if (gcInfo.gcRegGCrefSetCur & srcMask)
2279 gcInfo.gcMarkRegSetGCref(dstMask);
2281 else if (gcInfo.gcRegByrefSetCur & srcMask)
2283 gcInfo.gcMarkRegSetByref(dstMask);
2287 gcInfo.gcMarkRegSetNpt(dstMask);
2291 // generates an ip-relative call or indirect call via reg ('call reg')
2292 // pass in 'addr' for a relative call or 'base' for a indirect register call
2293 // methHnd - optional, only used for pretty printing
2294 // retSize - emitter type of return for GC purposes, should be EA_BYREF, EA_GCREF, or EA_PTRSIZE(not GC)
2297 void CodeGen::genEmitCall(int callType,
2298 CORINFO_METHOD_HANDLE methHnd,
2299 INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo)
2301 X86_ARG(int argSize),
2303 MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
2304 const DebugInfo& di,
2308 #if !defined(TARGET_X86)
2310 #endif // !defined(TARGET_X86)
2312 // This should have been put in volatile registers to ensure it does not
2313 // get overridden by epilog sequence during tailcall.
2314 noway_assert(!isJump || (base == REG_NA) || ((RBM_INT_CALLEE_TRASH & genRegMask(base)) != 0));
2316 GetEmitter()->emitIns_Call(emitter::EmitCallType(callType),
2318 INDEBUG_LDISASM_COMMA(sigInfo)
2322 MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize),
2323 gcInfo.gcVarPtrSetCur,
2324 gcInfo.gcRegGCrefSetCur,
2325 gcInfo.gcRegByrefSetCur,
2326 di, base, REG_NA, 0, 0, isJump);
2330 // generates an indirect call via addressing mode (call []) given an indir node
2331 // methHnd - optional, only used for pretty printing
2332 // retSize - emitter type of return for GC purposes, should be EA_BYREF, EA_GCREF, or EA_PTRSIZE(not GC)
2335 void CodeGen::genEmitCallIndir(int callType,
2336 CORINFO_METHOD_HANDLE methHnd,
2337 INDEBUG_LDISASM_COMMA(CORINFO_SIG_INFO* sigInfo)
2339 X86_ARG(int argSize),
2341 MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(emitAttr secondRetSize),
2342 const DebugInfo& di,
2345 #if !defined(TARGET_X86)
2347 #endif // !defined(TARGET_X86)
2349 regNumber iReg = (indir->Base() != nullptr) ? indir->Base()->GetRegNum() : REG_NA;
2350 regNumber xReg = (indir->Index() != nullptr) ? indir->Index()->GetRegNum() : REG_NA;
2352 // These should have been put in volatile registers to ensure they do not
2353 // get overridden by epilog sequence during tailcall.
2354 noway_assert(!isJump || (iReg == REG_NA) || ((RBM_CALLEE_TRASH & genRegMask(iReg)) != 0));
2355 noway_assert(!isJump || (xReg == REG_NA) || ((RBM_CALLEE_TRASH & genRegMask(xReg)) != 0));
2357 GetEmitter()->emitIns_Call(emitter::EmitCallType(callType),
2359 INDEBUG_LDISASM_COMMA(sigInfo)
2363 MULTIREG_HAS_SECOND_GC_RET_ONLY_ARG(secondRetSize),
2364 gcInfo.gcVarPtrSetCur,
2365 gcInfo.gcRegGCrefSetCur,
2366 gcInfo.gcRegByrefSetCur,
2376 //------------------------------------------------------------------------
2377 // genCodeForCast: Generates the code for GT_CAST.
2380 // tree - the GT_CAST node.
2382 void CodeGen::genCodeForCast(GenTreeOp* tree)
2384 assert(tree->OperIs(GT_CAST));
2386 var_types targetType = tree->TypeGet();
2388 if (varTypeIsFloating(targetType) && varTypeIsFloating(tree->gtOp1))
2390 // Casts float/double <--> double/float
2391 genFloatToFloatCast(tree);
2393 else if (varTypeIsFloating(tree->gtOp1))
2395 // Casts float/double --> int32/int64
2396 genFloatToIntCast(tree);
2398 else if (varTypeIsFloating(targetType))
2400 // Casts int32/uint32/int64/uint64 --> float/double
2401 genIntToFloatCast(tree);
2403 #ifndef TARGET_64BIT
2404 else if (varTypeIsLong(tree->gtOp1))
2406 genLongToIntCast(tree);
2408 #endif // !TARGET_64BIT
2411 // Casts int <--> int
2412 genIntToIntCast(tree->AsCast());
2414 // The per-case functions call genProduceReg()
2417 CodeGen::GenIntCastDesc::GenIntCastDesc(GenTreeCast* cast)
2419 GenTree* const src = cast->CastOp();
2420 const var_types srcType = genActualType(src);
2421 const bool srcUnsigned = cast->IsUnsigned();
2422 const unsigned srcSize = genTypeSize(srcType);
2423 const var_types castType = cast->gtCastType;
2424 const bool castUnsigned = varTypeIsUnsigned(castType);
2425 const unsigned castSize = genTypeSize(castType);
2426 const var_types dstType = genActualType(cast->TypeGet());
2427 const unsigned dstSize = genTypeSize(dstType);
2428 const bool overflow = cast->gtOverflow();
2429 const bool castIsLoad = !src->isUsedFromReg();
2431 assert(castIsLoad == src->isUsedFromMemory());
2432 assert((srcSize == 4) || (srcSize == genTypeSize(TYP_I_IMPL)));
2433 assert((dstSize == 4) || (dstSize == genTypeSize(TYP_I_IMPL)));
2435 assert(dstSize == genTypeSize(genActualType(castType)));
2437 if (castSize < 4) // Cast to small int type
2441 m_checkKind = CHECK_SMALL_INT_RANGE;
2442 m_checkSrcSize = srcSize;
2443 // Since these are small int types we can compute the min and max
2444 // values of the castType without risk of integer overflow.
2445 const int castNumBits = (castSize * 8) - (castUnsigned ? 0 : 1);
2446 m_checkSmallIntMax = (1 << castNumBits) - 1;
2447 m_checkSmallIntMin = (castUnsigned || srcUnsigned) ? 0 : (-m_checkSmallIntMax - 1);
2449 m_extendKind = COPY;
2450 m_extendSrcSize = dstSize;
2454 m_checkKind = CHECK_NONE;
2456 // Casting to a small type really means widening from that small type to INT/LONG.
2457 m_extendKind = castUnsigned ? ZERO_EXTEND_SMALL_INT : SIGN_EXTEND_SMALL_INT;
2458 m_extendSrcSize = castSize;
2462 // castType cannot be (U)LONG on 32 bit targets, such casts should have been decomposed.
2463 // srcType cannot be a small int type since it's the "actual type" of the cast operand.
2464 // This means that widening casts do not occur on 32 bit targets.
2465 else if (castSize > srcSize) // (U)INT to (U)LONG widening cast
2467 assert((srcSize == 4) && (castSize == 8));
2469 if (overflow && !srcUnsigned && castUnsigned)
2471 // Widening from INT to ULONG, check if the value is positive
2472 m_checkKind = CHECK_POSITIVE;
2475 // This is the only overflow checking cast that requires changing the
2476 // source value (by zero extending), all others copy the value as is.
2477 assert((srcType == TYP_INT) && (castType == TYP_ULONG));
2478 m_extendKind = ZERO_EXTEND_INT;
2479 m_extendSrcSize = 4;
2483 m_checkKind = CHECK_NONE;
2485 m_extendKind = srcUnsigned ? ZERO_EXTEND_INT : SIGN_EXTEND_INT;
2486 m_extendSrcSize = 4;
2489 else if (castSize < srcSize) // (U)LONG to (U)INT narrowing cast
2491 assert((srcSize == 8) && (castSize == 4));
2495 if (castUnsigned) // (U)LONG to UINT cast
2497 m_checkKind = CHECK_UINT_RANGE;
2499 else if (srcUnsigned) // ULONG to INT cast
2501 m_checkKind = CHECK_POSITIVE_INT_RANGE;
2503 else // LONG to INT cast
2505 m_checkKind = CHECK_INT_RANGE;
2512 m_checkKind = CHECK_NONE;
2515 #if defined(TARGET_LOONGARCH64) || defined(TARGET_RISCV64)
2516 // For LoongArch64's ISA which is same with the MIPS64 ISA, even the instructions of 32bits operation need
2517 // the upper 32bits be sign-extended to 64 bits.
2518 m_extendKind = SIGN_EXTEND_INT;
2520 m_extendKind = COPY;
2522 m_extendSrcSize = 4;
2525 else // if (castSize == srcSize) // Sign changing or same type cast
2527 assert(castSize == srcSize);
2529 if (overflow && (srcUnsigned != castUnsigned))
2531 m_checkKind = CHECK_POSITIVE;
2532 m_checkSrcSize = srcSize;
2536 m_checkKind = CHECK_NONE;
2539 m_extendKind = COPY;
2540 m_extendSrcSize = srcSize;
2545 const var_types srcLoadType = src->TypeGet();
2547 switch (m_extendKind)
2549 case ZERO_EXTEND_SMALL_INT: // small type/int/long -> ubyte/ushort
2550 assert(varTypeIsUnsigned(srcLoadType) || (genTypeSize(srcLoadType) >= genTypeSize(castType)));
2551 m_extendKind = LOAD_ZERO_EXTEND_SMALL_INT;
2552 m_extendSrcSize = min(genTypeSize(srcLoadType), genTypeSize(castType));
2555 case SIGN_EXTEND_SMALL_INT: // small type/int/long -> byte/short
2556 assert(varTypeIsSigned(srcLoadType) || (genTypeSize(srcLoadType) >= genTypeSize(castType)));
2557 m_extendKind = LOAD_SIGN_EXTEND_SMALL_INT;
2558 m_extendSrcSize = min(genTypeSize(srcLoadType), genTypeSize(castType));
2562 case ZERO_EXTEND_INT: // ubyte/ushort/int -> long.
2563 assert(varTypeIsUnsigned(srcLoadType) || (srcLoadType == TYP_INT));
2564 m_extendKind = varTypeIsSmall(srcLoadType) ? LOAD_ZERO_EXTEND_SMALL_INT : LOAD_ZERO_EXTEND_INT;
2565 m_extendSrcSize = genTypeSize(srcLoadType);
2568 case SIGN_EXTEND_INT: // byte/short/int -> long.
2569 assert(varTypeIsSigned(srcLoadType) || (srcLoadType == TYP_INT));
2570 m_extendKind = varTypeIsSmall(srcLoadType) ? LOAD_SIGN_EXTEND_SMALL_INT : LOAD_SIGN_EXTEND_INT;
2571 m_extendSrcSize = genTypeSize(srcLoadType);
2573 #endif // TARGET_64BIT
2575 case COPY: // long -> long, small type/int/long -> int.
2576 m_extendKind = LOAD_SOURCE;
2577 m_extendSrcSize = 0;
2586 #if !defined(TARGET_64BIT)
2587 //------------------------------------------------------------------------
2588 // genStoreLongLclVar: Generate code to store a non-enregistered long lclVar
2591 // treeNode - A TYP_LONG lclVar node.
2597 // 'treeNode' must be a TYP_LONG lclVar node for a lclVar that has NOT been promoted.
2598 // Its operand must be a GT_LONG node.
2600 void CodeGen::genStoreLongLclVar(GenTree* treeNode)
2602 emitter* emit = GetEmitter();
2604 GenTreeLclVarCommon* lclNode = treeNode->AsLclVarCommon();
2605 unsigned lclNum = lclNode->GetLclNum();
2606 LclVarDsc* varDsc = compiler->lvaGetDesc(lclNum);
2607 assert(varDsc->TypeGet() == TYP_LONG);
2608 assert(!varDsc->lvPromoted);
2609 GenTree* op1 = treeNode->AsOp()->gtOp1;
2611 // A GT_LONG is always contained so it cannot have RELOAD or COPY inserted between it and its consumer.
2612 noway_assert(op1->OperIs(GT_LONG));
2613 genConsumeRegs(op1);
2615 GenTree* loVal = op1->gtGetOp1();
2616 GenTree* hiVal = op1->gtGetOp2();
2618 noway_assert((loVal->GetRegNum() != REG_NA) && (hiVal->GetRegNum() != REG_NA));
2620 emit->emitIns_S_R(ins_Store(TYP_INT), EA_4BYTE, loVal->GetRegNum(), lclNum, 0);
2621 emit->emitIns_S_R(ins_Store(TYP_INT), EA_4BYTE, hiVal->GetRegNum(), lclNum, genTypeSize(TYP_INT));
2623 #endif // !defined(TARGET_64BIT)
2625 #if !defined(TARGET_LOONGARCH64) && !defined(TARGET_RISCV64)
2627 //------------------------------------------------------------------------
2628 // genCodeForJcc: Generate code for a GT_JCC node.
2633 void CodeGen::genCodeForJcc(GenTreeCC* jcc)
2635 assert(compiler->compCurBB->bbJumpKind == BBJ_COND);
2636 assert(jcc->OperIs(GT_JCC));
2638 inst_JCC(jcc->gtCondition, compiler->compCurBB->bbJumpDest);
2641 //------------------------------------------------------------------------
2642 // inst_JCC: Generate a conditional branch instruction sequence.
2645 // condition - The branch condition
2646 // target - The basic block to jump to when the condition is true
2648 void CodeGen::inst_JCC(GenCondition condition, BasicBlock* target)
2650 const GenConditionDesc& desc = GenConditionDesc::Get(condition);
2652 if (desc.oper == GT_NONE)
2654 inst_JMP(desc.jumpKind1, target);
2656 else if (desc.oper == GT_OR)
2658 inst_JMP(desc.jumpKind1, target);
2659 inst_JMP(desc.jumpKind2, target);
2661 else // if (desc.oper == GT_AND)
2663 BasicBlock* labelNext = genCreateTempLabel();
2664 inst_JMP(emitter::emitReverseJumpKind(desc.jumpKind1), labelNext);
2665 inst_JMP(desc.jumpKind2, target);
2666 genDefineTempLabel(labelNext);
2670 //------------------------------------------------------------------------
2671 // genCodeForSetcc: Generate code for a GT_SETCC node.
2676 void CodeGen::genCodeForSetcc(GenTreeCC* setcc)
2678 assert(setcc->OperIs(GT_SETCC));
2680 inst_SETCC(setcc->gtCondition, setcc->TypeGet(), setcc->GetRegNum());
2681 genProduceReg(setcc);
2683 #endif // !TARGET_LOONGARCH64 && !TARGET_RISCV64