Skip to content
This repository has been archived by the owner on Jan 23, 2023. It is now read-only.

Commit

Permalink
Don't add resolution for outgoing EH edges.
Browse files Browse the repository at this point in the history
Make write-thru defs RegOptional
  • Loading branch information
CarolEidt committed Sep 18, 2019
1 parent c3a8468 commit cf074bb
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 23 deletions.
67 changes: 46 additions & 21 deletions src/jit/lsra.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,29 @@ LinearScan::LinearScan(Compiler* theCompiler)
}

//------------------------------------------------------------------------
// blockHasEHFlow: Determine if this block ends in exception flow.
// blockHasEHFlowIn: Determine if this block has incoming exception flow.
//
// Arguments:
// block - the BasicBlock
//
// Return Value:
// True iff the block is the target of an EH edge; false otherwise
//
// Notes:
// It may be that this functionality exists elsewhere, or that
// it should be moved onto BasicBlock.
//
bool LinearScan::blockHasEHFlowIn(BasicBlock* block)
{
#if FEATURE_EH_FUNCLETS
return ((block->bbCatchTyp != BBCT_NONE) || (block->bbFlags & BBF_FUNCLET_BEG));
#else // !FEATURE_EH_FUNCLETS
return (block->bbCatchTyp != BBCT_NONE);
#endif // !FEATURE_EH_FUNCLETS
}

//------------------------------------------------------------------------
// blockHasEHFlowOut: Determine if this block ends in exception flow.
//
// Arguments:
// block - the BasicBlock
Expand All @@ -743,7 +765,7 @@ LinearScan::LinearScan(Compiler* theCompiler)
// It may be that this functionality exists elsewhere, or that
// it should be moved onto BasicBlock.
//
bool LinearScan::blockHasEHFlow(BasicBlock* block)
bool LinearScan::blockHasEHFlowOut(BasicBlock* block)
{
// If a predecessor is marked BBF_KEEP_BBJ_ALWAYS, then we must keep all live incoming
// vars on the stack.
Expand Down Expand Up @@ -853,7 +875,7 @@ void LinearScan::setBlockSequence()
blockInfo[block->bbNum].hasCriticalInEdge = false;
blockInfo[block->bbNum].hasCriticalOutEdge = false;
blockInfo[block->bbNum].weight = block->getBBWeight(compiler);
blockInfo[block->bbNum].hasEHBoundaryOut = blockHasEHFlow(block);
blockInfo[block->bbNum].hasEHBoundaryOut = blockHasEHFlowOut(block);

#if TRACK_LSRA_STATS
blockInfo[block->bbNum].spillCount = 0;
Expand All @@ -862,7 +884,7 @@ void LinearScan::setBlockSequence()
blockInfo[block->bbNum].splitEdgeCount = 0;
#endif // TRACK_LSRA_STATS

bool hasEHFlowIn = (block->bbCatchTyp != BBCT_NONE);
bool hasEHFlowIn = blockHasEHFlowIn(block);
#if FEATURE_EH_FUNCLETS
if (!hasEHFlowIn)
{
Expand All @@ -888,7 +910,7 @@ void LinearScan::setBlockSequence()
if (!hasEHFlowIn)
{
hasEHFlowIn = isBlockVisited(predBlock) ? blockInfo[predBlock->bbNum].hasEHBoundaryOut
: blockHasEHFlow(predBlock);
: blockHasEHFlowOut(predBlock);
}
}
blockInfo[block->bbNum].hasEHBoundaryIn = hasEHFlowIn;
Expand Down Expand Up @@ -1393,7 +1415,7 @@ void LinearScan::identifyCandidatesExceptionDataflow()

foreach_block(compiler, block)
{
if (block->bbCatchTyp != BBCT_NONE)
if (blockHasEHFlowIn(block))
{
// live on entry to handler
VarSetOps::UnionD(compiler, exceptVars, block->bbLiveIn);
Expand Down Expand Up @@ -2303,7 +2325,7 @@ BasicBlock* LinearScan::findPredBlockForLiveIn(BasicBlock* block,
if (predBlock != nullptr)
{
// We should already have returned null if this block has an incoming EH boundary edge.
assert(!blockHasEHFlow(predBlock));
assert(!blockHasEHFlowOut(predBlock));
if (isBlockVisited(predBlock))
{
if (predBlock->bbJumpKind == BBJ_COND)
Expand Down Expand Up @@ -2353,7 +2375,7 @@ BasicBlock* LinearScan::findPredBlockForLiveIn(BasicBlock* block,
{
BasicBlock* candidatePredBlock = pred->flBlock;
// We should already have returned null if this block has an incoming EH boundary edge.
assert(!blockHasEHFlow(candidatePredBlock));
assert(!blockHasEHFlowOut(candidatePredBlock));

if (isBlockVisited(candidatePredBlock))
{
Expand Down Expand Up @@ -6292,8 +6314,9 @@ void LinearScan::resolveLocalRef(BasicBlock* block, GenTree* treeNode, RefPositi
}
interval->assignedReg = nullptr;
interval->physReg = REG_NA;
if (treeNode != nullptr)
if (currentRefPosition->refType == RefTypeUse)
{
assert(treeNode != nullptr);
treeNode->SetContained();
}

Expand Down Expand Up @@ -7402,7 +7425,17 @@ void LinearScan::resolveRegisters()
printf("Prior to Resolution\n");
foreach_block(compiler, block)
{
printf("\n" FMT_BB " use def in out\n", block->bbNum);
printf("\n" FMT_BB, block->bbNum);
if (blockHasEHFlowIn(block))
{
JITDUMP(" EH flow in");
}
if (blockHasEHFlowOut(block))
{
JITDUMP(" EH flow out");
}

printf("\nuse def in out\n");
dumpConvertedVarSet(compiler, block->bbVarUse);
printf("\n");
dumpConvertedVarSet(compiler, block->bbVarDef);
Expand All @@ -7412,14 +7445,6 @@ void LinearScan::resolveRegisters()
dumpConvertedVarSet(compiler, block->bbLiveOut);
printf("\n");

#if FEATURE_EH_FUNCLETS
if ((block->bbCatchTyp != BBCT_NONE) || (block->bbFlags & BBF_FUNCLET_BEG))
#else // !FEATURE_EH_FUNCLETS
if (block->bbCatchTyp != BBCT_NONE)
#endif // !FEATURE_EH_FUNCLETS
{
JITDUMP("EH target: ");
}
dumpInVarToRegMap(block);
dumpOutVarToRegMap(block);
}
Expand Down Expand Up @@ -8612,9 +8637,9 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock,
{
// We don't actually move a writeThru var back to the stack, as its stack value is always valid.
// However, if this is a Join edge (i.e. the move is happening at the bottom of the block),
// we will go ahead and generate a mov instruction, which will be a NOP but will cause the
// variable to be removed from being live in the register.
if (resolveType == ResolveSplit)
// and it is a "normal" flow edge, we will go ahead and generate a mov instruction, which will be
// a NOP but will cause the variable to be removed from being live in the register.
if ((resolveType == ResolveSplit) || blockHasEHFlowOut(block))
{
continue;
}
Expand Down
4 changes: 3 additions & 1 deletion src/jit/lsra.h
Original file line number Diff line number Diff line change
Expand Up @@ -1408,7 +1408,9 @@ class LinearScan : public LinearScanInterface
// A map from bbNum to the block information used during register allocation.
LsraBlockInfo* blockInfo;

bool blockHasEHFlow(BasicBlock* block);
bool blockHasEHFlowIn(BasicBlock* block);
bool blockHasEHFlowOut(BasicBlock* block);

BasicBlock* findPredBlockForLiveIn(BasicBlock* block, BasicBlock* prevBlock DEBUGARG(bool* pPredBlockIsAllocated));

// The order in which the blocks will be allocated.
Expand Down
9 changes: 8 additions & 1 deletion src/jit/lsrabuild.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3099,7 +3099,14 @@ int LinearScan::BuildStoreLoc(GenTreeLclVarCommon* storeLoc)
srcInterval->assignRelatedInterval(varDefInterval);
}
}
newRefPosition(varDefInterval, currentLoc + 1, RefTypeDef, storeLoc, allRegs(storeLoc->TypeGet()));
RefPosition* def =
newRefPosition(varDefInterval, currentLoc + 1, RefTypeDef, storeLoc, allRegs(storeLoc->TypeGet()));
if (varDefInterval->isWriteThru)
{
// We always make write-thru defs reg-optional, as we can store them if they don't
// get a register.
def->regOptional = true;
}
}
else
{
Expand Down

0 comments on commit cf074bb

Please sign in to comment.