Skip to content

Commit

Permalink
GT_COPY source should be marked as consume during resolution
Browse files Browse the repository at this point in the history
  • Loading branch information
kunalspathak committed May 24, 2021
1 parent 51b6188 commit 3af9af2
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 6 deletions.
6 changes: 3 additions & 3 deletions docs/design/coreclr/jit/lsra-detail.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,11 @@ There are four main phases to LSRA:

- For fork edges (the source block has multiple targets, but
each target has only that one source), any required
resolution is placed at the target.
resolution is placed at the individual target(s).

- For join edges (a single target block has multiple sources,
but each source has only that one target), any required
resolution is placed at the source.
resolution is placed at the individual source(s).

- Critical edges require more complicated handling, and may
require splitting of the edge for placement of resolution.
Expand Down Expand Up @@ -707,7 +707,7 @@ LinearScanAllocation(List<RefPosition> refPositions)
- Next, for the remaining variables, classify them as either:
- In different registers at one or more targets. These require that the edge
be split so that we can insert the move on the edge (this is the `diffResolutionSet`).
- In the same register at each target (this is the `sameResolutionSet`).
- In the same register at each target (this is the `sameResolutionSet`), but different from the end of this block.
For these, we can insert a move at the end of this block, as long as they
don't write to any of the registers read by the `diffResolutionSet` as those
must remain live into the split block.
Expand Down
38 changes: 38 additions & 0 deletions src/coreclr/jit/clrjit.natvis
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,44 @@ The .NET Foundation licenses this file to you under the MIT license.
<Type Name="LinearScan">
<DisplayString>LinearScan</DisplayString>
<Expand>
<Item Name="inVarToRegMaps">"InVarToRegMaps"</Item>
<CustomListItems>
<Variable Name="block" InitialValue="this-&gt;compiler-&gt;fgFirstBB" />
<Variable Name="bbLiveInMap" InitialValue="block ? block->bbLiveIn[0] : 0" />
<Variable Name="inVarMap" InitialValue="block ? this->inVarToRegMaps[block->bbNum] : 0" />
<Variable Name="varIndex" InitialValue="0" />
<Loop Condition="block">
<Item Name="---BB{block->bbNum,2u}---">block->bbNum,2u</Item>
<Exec>varIndex = 0</Exec>
<Exec>inVarMap = this->inVarToRegMaps[block->bbNum]</Exec>
<Exec>bbLiveInMap = block->bbLiveIn[0]</Exec>
<Loop Condition="bbLiveInMap != 0">
<Item Name="V{this->localVarIntervals[varIndex]->varNum,2u}" Condition="(bbLiveInMap &amp; 1) != 0">((regNumber)inVarMap[varIndex]),en</Item>
<Exec>varIndex++</Exec>
<Exec>bbLiveInMap = bbLiveInMap >> 1</Exec>
</Loop>
<Exec>block = block->bbNext</Exec>
</Loop>
</CustomListItems>
<Item Name="outVarToRegMaps">"OutVarToRegMaps"</Item>
<CustomListItems>
<Variable Name="block" InitialValue="this-&gt;compiler-&gt;fgFirstBB" />
<Variable Name="bbLiveInMap" InitialValue="block ? block->bbLiveIn[0] : 0" />
<Variable Name="outVarMap" InitialValue="block ? this->outVarToRegMaps[block->bbNum] : 0" />
<Variable Name="varIndex" InitialValue="0" />
<Loop Condition="block">
<Item Name="---BB{block->bbNum,2u}---">block->bbNum,2u</Item>
<Exec>varIndex = 0</Exec>
<Exec>outVarMap = this->outVarToRegMaps[block->bbNum]</Exec>
<Exec>bbLiveInMap = block->bbLiveIn[0]</Exec>
<Loop Condition="bbLiveInMap != 0">
<Item Name="V{this->localVarIntervals[varIndex]->varNum,2u}" Condition="(bbLiveInMap &amp; 1) != 0">((regNumber)outVarMap[varIndex]),en</Item>
<Exec>varIndex++</Exec>
<Exec>bbLiveInMap = bbLiveInMap >> 1</Exec>
</Loop>
<Exec>block = block->bbNext</Exec>
</Loop>
</CustomListItems>
<Item Name="AvailableRegs mask">this-&gt;m_AvailableRegs</Item>
<CustomListItems>
<Variable Name="reg" InitialValue="this->m_AvailableRegs" />
Expand Down
14 changes: 11 additions & 3 deletions src/coreclr/jit/lsra.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7589,6 +7589,14 @@ void LinearScan::handleOutgoingCriticalEdges(BasicBlock* block)
assert(varTypeIsIntegralOrI(op1) && varTypeIsIntegralOrI(op2));
consumedRegs |= genRegMask(op1->GetRegNum());
consumedRegs |= genRegMask(op2->GetRegNum());

// Special handling for GT_COPY to not resolve into the source
// of switch's operand.
if (op1->OperIs(GT_COPY))
{
GenTree* srcOp1 = op1->gtGetOp1();
consumedRegs |= genRegMask(srcOp1->GetRegNum());
}
}

#ifdef TARGET_ARM64
Expand Down Expand Up @@ -7717,7 +7725,7 @@ void LinearScan::handleOutgoingCriticalEdges(BasicBlock* block)
//
// Another way to achieve similar resolution for vars live only at split edges is by removing them
// from consideration up-front but it requires that we traverse those edges anyway to account for
// the registers that must note be overwritten.
// the registers that must not be overwritten.
if (liveOnlyAtSplitEdge && maybeSameLivePaths)
{
sameToReg = REG_NA;
Expand Down Expand Up @@ -9578,7 +9586,7 @@ void LinearScan::dumpLsraAllocationEvent(
// Conflicting def/use
case LSRA_EVENT_DEFUSE_CONFLICT:
dumpRefPositionShort(activeRefPosition, currentBlock);
printf("DUconflict ");
printf("DUconflict ");
dumpRegRecords();
break;
case LSRA_EVENT_DEFUSE_CASE1:
Expand Down Expand Up @@ -10056,7 +10064,7 @@ void LinearScan::dumpNewBlock(BasicBlock* currentBlock, LsraLocation location)
if (activeRefPosition->refType == RefTypeDummyDef)
{
dumpEmptyRefPosition();
printf("DDefs ");
printf("DDefs ");
printf(regNameFormat, "");
return;
}
Expand Down

0 comments on commit 3af9af2

Please sign in to comment.