[ir] Convert FlowNode to Block where possible.
This CL updates a bunch of uses of FlowNode to use Block instead. The
InboundBranches are moved from FlowNode to Block.
Bug: tint:1718
Change-Id: Ic1c07dae103e25364a3a6b3333cfcb57d10b30c2
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/134260
Reviewed-by: James Price <jrprice@google.com>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Dan Sinclair <dsinclair@chromium.org>
diff --git a/src/tint/ir/block.h b/src/tint/ir/block.h
index abdf2a3..7c3b530 100644
--- a/src/tint/ir/block.h
+++ b/src/tint/ir/block.h
@@ -35,7 +35,7 @@
~Block() override;
/// @returns true if this is block has a branch target set
- bool HasBranchTarget() const override {
+ bool HasBranchTarget() const {
return !instructions_.IsEmpty() && instructions_.Back()->Is<ir::Branch>();
}
@@ -49,7 +49,7 @@
/// @param target the block to see if we trampoline too
/// @returns if this block just branches to the provided target.
- bool IsTrampoline(const FlowNode* target) const {
+ bool IsTrampoline(const Block* target) const {
if (instructions_.Length() != 1) {
return false;
}
@@ -78,9 +78,26 @@
/// @returns the params to the block
utils::Vector<const BlockParam*, 0>& Params() { return params_; }
+ /// @returns true if this node has inbound branches and branches out
+ bool IsConnected() const { return HasBranchTarget(); }
+
+ /// @returns the inbound branch list for the flow node
+ utils::VectorRef<ir::Branch*> InboundBranches() const { return inbound_branches_; }
+
+ /// Adds the given node to the inbound branches
+ /// @param node the node to add
+ void AddInboundBranch(ir::Branch* node) { inbound_branches_.Push(node); }
+
private:
utils::Vector<const Instruction*, 16> instructions_;
utils::Vector<const BlockParam*, 0> params_;
+
+ /// The list of flow nodes which branch into this node. This list maybe empty for several
+ /// reasons:
+ /// - Node is a start node
+ /// - Node is a merge target outside control flow (e.g. an if that returns in both branches)
+ /// - Node is a continue target outside control flow (e.g. a loop that returns)
+ utils::Vector<ir::Branch*, 2> inbound_branches_;
};
} // namespace tint::ir
diff --git a/src/tint/ir/branch.cc b/src/tint/ir/branch.cc
index a16b7ae..3648b61 100644
--- a/src/tint/ir/branch.cc
+++ b/src/tint/ir/branch.cc
@@ -16,13 +16,13 @@
#include <utility>
-#include "src/tint/ir/flow_node.h"
+#include "src/tint/ir/block.h"
TINT_INSTANTIATE_TYPEINFO(tint::ir::Branch);
namespace tint::ir {
-Branch::Branch(FlowNode* to, utils::VectorRef<Value*> args) : to_(to), args_(std::move(args)) {
+Branch::Branch(Block* to, utils::VectorRef<Value*> args) : to_(to), args_(std::move(args)) {
TINT_ASSERT(IR, to_);
to_->AddInboundBranch(this);
for (auto* arg : args) {
diff --git a/src/tint/ir/branch.h b/src/tint/ir/branch.h
index fcb1256..fe08b97 100644
--- a/src/tint/ir/branch.h
+++ b/src/tint/ir/branch.h
@@ -21,7 +21,7 @@
// Forward declarations
namespace tint::ir {
-class FlowNode;
+class Block;
} // namespace tint::ir
namespace tint::ir {
@@ -32,17 +32,17 @@
/// Constructor
/// @param to the block to branch too
/// @param args the branch arguments
- explicit Branch(FlowNode* to, utils::VectorRef<Value*> args = {});
+ explicit Branch(Block* to, utils::VectorRef<Value*> args = {});
~Branch() override;
/// @returns the block being branched too.
- const FlowNode* To() const { return to_; }
+ const Block* To() const { return to_; }
/// @returns the branch arguments
utils::VectorRef<Value*> Args() const { return args_; }
private:
- FlowNode* to_;
+ Block* to_;
utils::Vector<Value*, 2> args_;
};
diff --git a/src/tint/ir/builder.cc b/src/tint/ir/builder.cc
index cc4af5d..cdedf44 100644
--- a/src/tint/ir/builder.cc
+++ b/src/tint/ir/builder.cc
@@ -217,7 +217,7 @@
return ir.values.Create<ir::Var>(type);
}
-ir::Branch* Builder::Branch(FlowNode* to, utils::VectorRef<Value*> args) {
+ir::Branch* Builder::Branch(Block* to, utils::VectorRef<Value*> args) {
return ir.values.Create<ir::Branch>(to, args);
}
diff --git a/src/tint/ir/builder.h b/src/tint/ir/builder.h
index 732c8f2..fdddc6e 100644
--- a/src/tint/ir/builder.h
+++ b/src/tint/ir/builder.h
@@ -402,7 +402,7 @@
/// @param to the node being branched too
/// @param args the branch arguments
/// @returns the instruction
- ir::Branch* Branch(FlowNode* to, utils::VectorRef<Value*> args = {});
+ ir::Branch* Branch(Block* to, utils::VectorRef<Value*> args = {});
/// Creates a new `BlockParam`
/// @param type the parameter type
diff --git a/src/tint/ir/debug.cc b/src/tint/ir/debug.cc
index 807e951..fc14d91 100644
--- a/src/tint/ir/debug.cc
+++ b/src/tint/ir/debug.cc
@@ -31,8 +31,8 @@
std::string Debug::AsDotGraph(const Module* mod) {
size_t node_count = 0;
- std::unordered_set<const FlowNode*> visited;
- std::unordered_set<const FlowNode*> merge_nodes;
+ std::unordered_set<const Block*> visited;
+ std::unordered_set<const Block*> merge_nodes;
std::unordered_map<const FlowNode*, std::string> node_to_name;
utils::StringStream out;
@@ -48,7 +48,7 @@
return name;
};
- std::function<void(const FlowNode*)> Graph = [&](const FlowNode* node) {
+ std::function<void(const Block*)> Graph = [&](const Block* node) {
if (visited.count(node) > 0) {
return;
}
diff --git a/src/tint/ir/flow_node.h b/src/tint/ir/flow_node.h
index b072964..1b5aabe 100644
--- a/src/tint/ir/flow_node.h
+++ b/src/tint/ir/flow_node.h
@@ -16,7 +16,6 @@
#define SRC_TINT_IR_FLOW_NODE_H_
#include "src/tint/utils/castable.h"
-#include "src/tint/utils/vector.h"
// Forward Declarations
namespace tint::ir {
@@ -30,30 +29,9 @@
public:
~FlowNode() override;
- /// @returns true if this node has inbound branches and branches out
- bool IsConnected() const { return HasBranchTarget(); }
-
- /// @returns true if the node has a branch target
- virtual bool HasBranchTarget() const { return false; }
-
- /// @returns the inbound branch list for the flow node
- utils::VectorRef<Branch*> InboundBranches() const { return inbound_branches_; }
-
- /// Adds the given node to the inbound branches
- /// @param node the node to add
- void AddInboundBranch(Branch* node) { inbound_branches_.Push(node); }
-
protected:
/// Constructor
FlowNode();
-
- private:
- /// The list of flow nodes which branch into this node. This list maybe empty for several
- /// reasons:
- /// - Node is a start node
- /// - Node is a merge target outside control flow (e.g. an if that returns in both branches)
- /// - Node is a continue target outside control flow (e.g. a loop that returns)
- utils::Vector<Branch*, 2> inbound_branches_;
};
} // namespace tint::ir
diff --git a/src/tint/ir/from_program.cc b/src/tint/ir/from_program.cc
index 4371620..ad94235 100644
--- a/src/tint/ir/from_program.cc
+++ b/src/tint/ir/from_program.cc
@@ -101,11 +101,7 @@
// For an `if` and `switch` block, the merge has a registered incoming branch instruction of the
// `if` and `switch. So, to determine if the merge is connected to any of the branches that happend
// in the `if` or `switch` we need a `count` value that is larger then 1.
-bool IsConnected(const FlowNode* b, uint32_t count) {
- // Function is always connected as it's the start.
- if (b->Is<ir::Function>()) {
- return true;
- }
+bool IsConnected(const Block* b, uint32_t count) {
return b->InboundBranches().Length() > count;
}
@@ -170,7 +166,7 @@
diagnostics_.add_error(tint::diag::System::IR, err, s);
}
- void BranchTo(FlowNode* node, utils::VectorRef<Value*> args = {}) {
+ void BranchTo(Block* node, utils::VectorRef<Value*> args = {}) {
TINT_ASSERT(IR, current_flow_block_);
TINT_ASSERT(IR, !current_flow_block_->HasBranchTarget());
@@ -178,7 +174,7 @@
current_flow_block_ = nullptr;
}
- void BranchToIfNeeded(FlowNode* node) {
+ void BranchToIfNeeded(Block* node) {
if (!current_flow_block_ || current_flow_block_->HasBranchTarget()) {
return;
}
@@ -752,7 +748,7 @@
// Discard is being treated as an instruction. The semantics in WGSL is demote_to_helper, so
// the code has to continue as before it just predicates writes. If WGSL grows some kind of
- // terminating discard that would probably make sense as a FlowNode but would then require
+ // terminating discard that would probably make sense as a Block but would then require
// figuring out the multi-level exit that is triggered.
void EmitDiscard(const ast::DiscardStatement*) {
auto* inst = builder_.Discard();
diff --git a/src/tint/ir/to_program.cc b/src/tint/ir/to_program.cc
index 05b735c..842f41d 100644
--- a/src/tint/ir/to_program.cc
+++ b/src/tint/ir/to_program.cc
@@ -98,7 +98,7 @@
if (!ret_ty) {
return nullptr;
}
- auto* body = FlowNodeGraph(fn->StartTarget());
+ auto* body = BlockGraph(fn->StartTarget());
if (!body) {
return nullptr;
}
@@ -108,13 +108,13 @@
std::move(ret_attrs));
}
- const ast::BlockStatement* FlowNodeGraph(const ir::Block* start_node) {
+ const ast::BlockStatement* BlockGraph(const ir::Block* start_node) {
// TODO(crbug.com/tint/1902): Check if the block is dead
utils::Vector<const ast::Statement*,
decltype(ast::BlockStatement::statements)::static_length>
stmts;
- const ir::FlowNode* block = start_node;
+ const ir::Block* block = start_node;
// TODO(crbug.com/tint/1902): Handle block arguments.
@@ -171,7 +171,7 @@
const ast::IfStatement* If(const ir::If* i) {
SCOPED_NESTING();
auto* cond = Expr(i->Condition());
- auto* t = FlowNodeGraph(i->True());
+ auto* t = BlockGraph(i->True());
if (TINT_UNLIKELY(!t)) {
return nullptr;
}
@@ -187,7 +187,7 @@
}
return b.If(cond, t, b.Else(f));
} else {
- auto* f = FlowNodeGraph(i->False());
+ auto* f = BlockGraph(i->False());
if (!f) {
return nullptr;
}
@@ -210,7 +210,7 @@
s->Cases(), //
[&](const ir::Switch::Case c) -> const tint::ast::CaseStatement* {
SCOPED_NESTING();
- auto* body = FlowNodeGraph(c.start);
+ auto* body = BlockGraph(c.start);
if (!body) {
return nullptr;
}
@@ -270,7 +270,7 @@
}
/// @return true if there are no instructions between @p node and and @p stop_at
- bool IsEmpty(const ir::Block* node, const ir::FlowNode* stop_at) {
+ bool IsEmpty(const ir::Block* node, const ir::Block* stop_at) {
if (node->Instructions().IsEmpty()) {
return true;
}