[tint][ir][ToProgram] Emit 'else if' instead of 'else { if'
Bug: tint:1902 Change-Id: If49a7fd71d72cd562fc49957a5715ea7eefc8b4d Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/133140 Kokoro: Ben Clayton <bclayton@google.com> Reviewed-by: Dan Sinclair <dsinclair@chromium.org> Commit-Queue: Ben Clayton <bclayton@google.com>
This commit is contained in:
parent
1ea1e1a375
commit
6ab77f16f0
|
@ -116,10 +116,27 @@ class State {
|
|||
const ast::IfStatement* If(const ir::If* i) {
|
||||
auto* cond = Expr(i->condition);
|
||||
auto* t = FlowNodeGraph(i->true_.target, i->merge.target);
|
||||
if (!t) {
|
||||
return nullptr;
|
||||
}
|
||||
if (!IsEmpty(i->false_.target, i->merge.target)) {
|
||||
// TODO(crbug.com/tint/1902): Merge if else
|
||||
auto* f = FlowNodeGraph(i->false_.target, i->merge.target);
|
||||
return b.If(cond, t, b.Else(f));
|
||||
// If the else target is an if flow node with the same merge target as this if, then
|
||||
// emit an 'else if' instead of a block statement for the else.
|
||||
if (auto* else_if = As<ir::If>(NextNonEmptyNode(i->false_.target));
|
||||
else_if &&
|
||||
NextNonEmptyNode(i->merge.target) == NextNonEmptyNode(else_if->merge.target)) {
|
||||
auto* f = If(else_if);
|
||||
if (!f) {
|
||||
return nullptr;
|
||||
}
|
||||
return b.If(cond, t, b.Else(f));
|
||||
} else {
|
||||
auto* f = FlowNodeGraph(i->false_.target, i->merge.target);
|
||||
if (!f) {
|
||||
return nullptr;
|
||||
}
|
||||
return b.If(cond, t, b.Else(f));
|
||||
}
|
||||
}
|
||||
return b.If(cond, t);
|
||||
}
|
||||
|
@ -139,6 +156,21 @@ class State {
|
|||
return true;
|
||||
}
|
||||
|
||||
/// @return the next flow node that isn't an empty block
|
||||
const ir::FlowNode* NextNonEmptyNode(const ir::FlowNode* node) {
|
||||
while (node) {
|
||||
if (auto* block = node->As<ir::Block>()) {
|
||||
if (block->instructions.Length() > 0) {
|
||||
return node;
|
||||
}
|
||||
node = block->branch.target;
|
||||
} else {
|
||||
return node;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const ast::Statement* Stmt(const ir::Instruction* inst) {
|
||||
return Switch(
|
||||
inst, //
|
||||
|
|
|
@ -152,28 +152,6 @@ fn f() {
|
|||
b();
|
||||
}
|
||||
}
|
||||
)",
|
||||
R"(
|
||||
fn a() {
|
||||
}
|
||||
|
||||
fn b() {
|
||||
}
|
||||
|
||||
fn c() {
|
||||
}
|
||||
|
||||
fn f() {
|
||||
var cond_a : bool = true;
|
||||
var cond_b : bool = true;
|
||||
if (cond_a) {
|
||||
a();
|
||||
} else {
|
||||
if (cond_b) {
|
||||
b();
|
||||
}
|
||||
}
|
||||
}
|
||||
)");
|
||||
}
|
||||
} // namespace
|
||||
|
|
Loading…
Reference in New Issue