Skip to content

Commit 944e253

Browse files
authored
Handle switch cases removal in the dead code elimination, not in the stepper. (#143)
1 parent 83cf582 commit 944e253

File tree

2 files changed

+24
-5
lines changed

2 files changed

+24
-5
lines changed

core/interpreter/stepper.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -186,15 +186,16 @@ bool FlayStepper::preorder(const IR::SwitchStatement *switchStatement) {
186186
const auto *path = switchCaseLabel->checkedTo<IR::PathExpression>();
187187
switchCaseLabel = IR::StringLiteral::get(path->path->toString());
188188
}
189+
const auto *switchCaseEquality = new IR::Equ(switchExpr, switchCaseLabel);
189190
if (cond == nullptr) {
190-
cond = new IR::Equ(switchExpr, switchCaseLabel);
191+
cond = switchCaseEquality;
191192
} else {
192-
cond = new IR::LOr(cond, new IR::Equ(switchExpr, switchCaseLabel));
193+
cond = new IR::LOr(cond, switchCaseEquality);
193194
}
194195
// We fall through, so add the statements to execute to a list.
195196
accumulatedSwitchCases.push_back(switchCase);
196197
// Add the switch case to the reachability map.
197-
executionState.addReachabilityMapping(switchCase, cond);
198+
executionState.addReachabilityMapping(switchCase, switchCaseEquality);
198199
// Nothing to do with this statement. Fall through to the next case.
199200
if (switchCase->statement == nullptr) {
200201
continue;

core/specialization/passes/elim_dead_code.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,24 +60,42 @@ const IR::Node *ElimDeadCode::preorder(IR::IfStatement *stmt) {
6060

6161
const IR::Node *ElimDeadCode::preorder(IR::SwitchStatement *switchStmt) {
6262
IR::Vector<IR::SwitchCase> filteredSwitchCases;
63+
bool previousFallThrough = false;
6364
for (const auto *switchCase : switchStmt->cases) {
6465
if (switchCase->label->is<IR::DefaultExpression>()) {
6566
filteredSwitchCases.push_back(switchCase);
6667
break;
6768
}
6869
auto isreachabilityOpt = _reachabilityMap.get().isNodeReachable(switchCase);
6970
if (!isreachabilityOpt.has_value()) {
71+
printInfo("---DEAD_CODE--- SwitchCase %1% can be executed.", switchCase->label);
7072
filteredSwitchCases.push_back(switchCase);
73+
previousFallThrough = switchCase->statement == nullptr;
7174
continue;
7275
}
7376
auto reachability = isreachabilityOpt.value();
7477
if (reachability) {
7578
filteredSwitchCases.push_back(switchCase);
76-
printInfo("---DEAD_CODE--- %1% is always true.", switchCase->label);
77-
break;
79+
printInfo("---DEAD_CODE--- SwitchCase %1% is always true.", switchCase->label);
80+
previousFallThrough = switchCase->statement == nullptr;
81+
if (switchCase->statement != nullptr) {
82+
break;
83+
}
84+
continue;
7885
}
7986
printInfo("---DEAD_CODE--- %1% can be deleted.", switchCase->label);
8087
_eliminatedNodes.emplace_back(switchCase, nullptr);
88+
// We are removing a statement that had previous fall-through labels.
89+
if (previousFallThrough && !filteredSwitchCases.empty() &&
90+
switchCase->statement != nullptr) {
91+
auto *previous = filteredSwitchCases.back()->clone();
92+
printInfo("---DEAD_CODE--- Merging statements of %1% into %2%.", switchCase->label,
93+
previous->label);
94+
previous->statement = switchCase->statement;
95+
filteredSwitchCases.pop_back();
96+
filteredSwitchCases.push_back(previous);
97+
}
98+
previousFallThrough = switchCase->statement == nullptr;
8199
}
82100
if (filteredSwitchCases.empty()) {
83101
return new IR::EmptyStatement(switchStmt->getSourceInfo());

0 commit comments

Comments
 (0)