Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions src/coreclr/jit/compiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4912,6 +4912,10 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl

if (opts.OptimizationEnabled())
{
// Conditional to switch conversion, and switch peeling
//
DoPhase(this, PHASE_SWITCH_RECOGNITION, &Compiler::optRecognizeAndOptimizeSwitchJumps);

// Optimize boolean conditions
//
DoPhase(this, PHASE_OPTIMIZE_BOOLS, &Compiler::optOptimizeBools);
Expand All @@ -4920,10 +4924,6 @@ void Compiler::compCompile(void** methodCodePtr, uint32_t* methodCodeSize, JitFl
//
DoPhase(this, PHASE_IF_CONVERSION, &Compiler::optIfConversion);

// Conditional to switch conversion, and switch peeling
//
DoPhase(this, PHASE_SWITCH_RECOGNITION, &Compiler::optRecognizeAndOptimizeSwitchJumps);

// Run flow optimizations before reordering blocks
//
DoPhase(this, PHASE_OPTIMIZE_PRE_LAYOUT, &Compiler::optOptimizePreLayout);
Expand Down
32 changes: 29 additions & 3 deletions src/coreclr/jit/switchrecognition.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,32 @@ PhaseStatus Compiler::optRecognizeAndOptimizeSwitchJumps()
return modified ? PhaseStatus::MODIFIED_EVERYTHING : PhaseStatus::MODIFIED_NOTHING;
}

//------------------------------------------------------------------------------
// SkipFallthroughBlocks : Skip all fallthrough blocks (empty BBJ_ALWAYS blocks)
//
// Arguments:
// block - the block to process
//
// Return Value:
// block that is not an empty fallthrough block
//
static BasicBlock* SkipFallthroughBlocks(BasicBlock* block)
{
// FALLTHROUGH
BasicBlock* origBlock = block;
while (block->KindIs(BBJ_ALWAYS) && (block->firstStmt() == nullptr) &&
BasicBlock::sameEHRegion(block, block->GetTarget()))
{
block = block->GetTarget();
if (block == origBlock)
{
// A cycle detected, bail out.
return origBlock;
}
}
return block;
}

//------------------------------------------------------------------------------
// IsConstantTestCondBlock : Does the given block represent a simple BBJ_COND
// constant test? e.g. JTRUE(EQ/NE(X, CNS)).
Expand Down Expand Up @@ -124,8 +150,8 @@ bool IsConstantTestCondBlock(const BasicBlock* block,
}

*isReversed = rootNode->gtGetOp1()->OperIs(GT_NE);
*trueTarget = *isReversed ? block->GetFalseTarget() : block->GetTrueTarget();
*falseTarget = *isReversed ? block->GetTrueTarget() : block->GetFalseTarget();
*trueTarget = SkipFallthroughBlocks(*isReversed ? block->GetFalseTarget() : block->GetTrueTarget());
*falseTarget = SkipFallthroughBlocks(*isReversed ? block->GetTrueTarget() : block->GetFalseTarget());

if (block->FalseTargetIs(block) || block->TrueTargetIs(block))
{
Expand Down Expand Up @@ -402,7 +428,7 @@ bool Compiler::optSwitchConvert(BasicBlock* firstBlock,
const bool isTest = IsConstantTestCondBlock(lastBlock, false, &blockIfTrue, &blockIfFalse, &isReversed);
assert(isTest);

assert(firstBlock->TrueTargetIs(blockIfTrue));
assert(SkipFallthroughBlocks(firstBlock->GetTrueTarget()) == SkipFallthroughBlocks(blockIfTrue));
FlowEdge* const trueEdge = firstBlock->GetTrueEdge();
FlowEdge* const falseEdge = firstBlock->GetFalseEdge();

Expand Down
Loading