Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
7 changes: 4 additions & 3 deletions core/interpreter/stepper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,15 +186,16 @@ bool FlayStepper::preorder(const IR::SwitchStatement *switchStatement) {
const auto *path = switchCaseLabel->checkedTo<IR::PathExpression>();
switchCaseLabel = IR::StringLiteral::get(path->path->toString());
}
const auto *switchCaseEquality = new IR::Equ(switchExpr, switchCaseLabel);
if (cond == nullptr) {
cond = new IR::Equ(switchExpr, switchCaseLabel);
cond = switchCaseEquality;
} else {
cond = new IR::LOr(cond, new IR::Equ(switchExpr, switchCaseLabel));
cond = new IR::LOr(cond, switchCaseEquality);
}
// We fall through, so add the statements to execute to a list.
accumulatedSwitchCases.push_back(switchCase);
// Add the switch case to the reachability map.
executionState.addReachabilityMapping(switchCase, cond);
executionState.addReachabilityMapping(switchCase, switchCaseEquality);
// Nothing to do with this statement. Fall through to the next case.
if (switchCase->statement == nullptr) {
continue;
Expand Down
22 changes: 20 additions & 2 deletions core/specialization/passes/elim_dead_code.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,24 +60,42 @@ const IR::Node *ElimDeadCode::preorder(IR::IfStatement *stmt) {

const IR::Node *ElimDeadCode::preorder(IR::SwitchStatement *switchStmt) {
IR::Vector<IR::SwitchCase> filteredSwitchCases;
bool previousFallThrough = false;
for (const auto *switchCase : switchStmt->cases) {
if (switchCase->label->is<IR::DefaultExpression>()) {
filteredSwitchCases.push_back(switchCase);
break;
}
auto isreachabilityOpt = _reachabilityMap.get().isNodeReachable(switchCase);
if (!isreachabilityOpt.has_value()) {
printInfo("---DEAD_CODE--- SwitchCase %1% can be executed.", switchCase->label);
filteredSwitchCases.push_back(switchCase);
previousFallThrough = switchCase->statement == nullptr;
continue;
}
auto reachability = isreachabilityOpt.value();
if (reachability) {
filteredSwitchCases.push_back(switchCase);
printInfo("---DEAD_CODE--- %1% is always true.", switchCase->label);
break;
printInfo("---DEAD_CODE--- SwitchCase %1% is always true.", switchCase->label);
previousFallThrough = switchCase->statement == nullptr;
if (switchCase->statement != nullptr) {
break;
}
continue;
}
printInfo("---DEAD_CODE--- %1% can be deleted.", switchCase->label);
_eliminatedNodes.emplace_back(switchCase, nullptr);
// We are removing a statement that had previous fall-through labels.
if (previousFallThrough && !filteredSwitchCases.empty() &&
switchCase->statement != nullptr) {
auto *previous = filteredSwitchCases.back()->clone();
printInfo("---DEAD_CODE--- Merging statements of %1% into %2%.", switchCase->label,
previous->label);
previous->statement = switchCase->statement;
filteredSwitchCases.pop_back();
filteredSwitchCases.push_back(previous);
}
previousFallThrough = switchCase->statement == nullptr;
}
if (filteredSwitchCases.empty()) {
return new IR::EmptyStatement(switchStmt->getSourceInfo());
Expand Down