[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;
         }