mirror of
https://github.com/encounter/dawn-cmake.git
synced 2025-06-06 06:33:30 +00:00
[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) {
|
const ast::IfStatement* If(const ir::If* i) {
|
||||||
auto* cond = Expr(i->condition);
|
auto* cond = Expr(i->condition);
|
||||||
auto* t = FlowNodeGraph(i->true_.target, i->merge.target);
|
auto* t = FlowNodeGraph(i->true_.target, i->merge.target);
|
||||||
|
if (!t) {
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
if (!IsEmpty(i->false_.target, i->merge.target)) {
|
if (!IsEmpty(i->false_.target, i->merge.target)) {
|
||||||
// TODO(crbug.com/tint/1902): Merge if else
|
// If the else target is an if flow node with the same merge target as this if, then
|
||||||
auto* f = FlowNodeGraph(i->false_.target, i->merge.target);
|
// emit an 'else if' instead of a block statement for the else.
|
||||||
return b.If(cond, t, b.Else(f));
|
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);
|
return b.If(cond, t);
|
||||||
}
|
}
|
||||||
@ -139,6 +156,21 @@ class State {
|
|||||||
return true;
|
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) {
|
const ast::Statement* Stmt(const ir::Instruction* inst) {
|
||||||
return Switch(
|
return Switch(
|
||||||
inst, //
|
inst, //
|
||||||
|
@ -152,28 +152,6 @@ fn f() {
|
|||||||
b();
|
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
|
} // namespace
|
||||||
|
Loading…
x
Reference in New Issue
Block a user