[tint][ir] Remove Block::HasTerminator()

Terminator() gives you the same information, and discourages multiple
costly dynamic casts.

This also removes the double dynamic cast for Terminator().

Change-Id: I9a91144ad5133511965f151adab23d643d0f45ca
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/161004
Reviewed-by: dan sinclair <dsinclair@chromium.org>
Kokoro: Kokoro <noreply+kokoro@google.com>
Commit-Queue: Ben Clayton <bclayton@google.com>
diff --git a/src/tint/lang/core/ir/block.h b/src/tint/lang/core/ir/block.h
index 6273b29..7b13542 100644
--- a/src/tint/lang/core/ir/block.h
+++ b/src/tint/lang/core/ir/block.h
@@ -58,18 +58,9 @@
     /// @param out the block to clone into
     virtual void CloneInto(CloneContext& ctx, Block* out);
 
-    /// @returns true if this is block has a terminator instruction
-    bool HasTerminator() {
-        return instructions_.last != nullptr && instructions_.last->Is<ir::Terminator>();
-    }
-
-    /// @return the terminator instruction for this block
-    ir::Terminator* Terminator() {
-        if (!HasTerminator()) {
-            return nullptr;
-        }
-        return instructions_.last->As<ir::Terminator>();
-    }
+    /// @return the terminator instruction for this block, or nullptr if this block does not end in
+    /// a terminator.
+    ir::Terminator* Terminator() { return tint::As<ir::Terminator>(instructions_.last); }
 
     /// @returns the instructions in the block
     Instruction* Instructions() { return instructions_.first; }
diff --git a/src/tint/lang/core/ir/block_test.cc b/src/tint/lang/core/ir/block_test.cc
index d48b7c7..8e2f3b6 100644
--- a/src/tint/lang/core/ir/block_test.cc
+++ b/src/tint/lang/core/ir/block_test.cc
@@ -35,65 +35,65 @@
 using namespace tint::core::number_suffixes;  // NOLINT
 using IR_BlockTest = IRTestHelper;
 
-TEST_F(IR_BlockTest, HasTerminator_Empty) {
+TEST_F(IR_BlockTest, Terminator_Empty) {
     auto* blk = b.Block();
-    EXPECT_FALSE(blk->HasTerminator());
+    EXPECT_EQ(blk->Terminator(), nullptr);
 }
 
-TEST_F(IR_BlockTest, HasTerminator_None) {
+TEST_F(IR_BlockTest, Terminator_None) {
     auto* blk = b.Block();
     blk->Append(b.Add(mod.Types().i32(), 1_u, 2_u));
-    EXPECT_FALSE(blk->HasTerminator());
+    EXPECT_EQ(blk->Terminator(), nullptr);
 }
 
-TEST_F(IR_BlockTest, HasTerminator_BreakIf) {
+TEST_F(IR_BlockTest, Terminator_BreakIf) {
     auto* blk = b.Block();
     auto* loop = b.Loop();
     blk->Append(b.BreakIf(loop, true));
-    EXPECT_TRUE(blk->HasTerminator());
+    EXPECT_NE(blk->Terminator(), nullptr);
 }
 
-TEST_F(IR_BlockTest, HasTerminator_Continue) {
+TEST_F(IR_BlockTest, Terminator_Continue) {
     auto* blk = b.Block();
     auto* loop = b.Loop();
     blk->Append(b.Continue(loop));
-    EXPECT_TRUE(blk->HasTerminator());
+    EXPECT_NE(blk->Terminator(), nullptr);
 }
 
-TEST_F(IR_BlockTest, HasTerminator_ExitIf) {
+TEST_F(IR_BlockTest, Terminator_ExitIf) {
     auto* blk = b.Block();
     auto* if_ = b.If(true);
     blk->Append(b.ExitIf(if_));
-    EXPECT_TRUE(blk->HasTerminator());
+    EXPECT_NE(blk->Terminator(), nullptr);
 }
 
-TEST_F(IR_BlockTest, HasTerminator_ExitLoop) {
+TEST_F(IR_BlockTest, Terminator_ExitLoop) {
     auto* blk = b.Block();
     auto* loop = b.Loop();
     blk->Append(b.ExitLoop(loop));
-    EXPECT_TRUE(blk->HasTerminator());
+    EXPECT_NE(blk->Terminator(), nullptr);
 }
 
-TEST_F(IR_BlockTest, HasTerminator_ExitSwitch) {
+TEST_F(IR_BlockTest, Terminator_ExitSwitch) {
     auto* blk = b.Block();
     auto* s = b.Switch(1_u);
     blk->Append(b.ExitSwitch(s));
-    EXPECT_TRUE(blk->HasTerminator());
+    EXPECT_NE(blk->Terminator(), nullptr);
 }
 
-TEST_F(IR_BlockTest, HasTerminator_NextIteration) {
+TEST_F(IR_BlockTest, Terminator_NextIteration) {
     auto* blk = b.Block();
     auto* loop = b.Loop();
     blk->Append(b.NextIteration(loop));
-    EXPECT_TRUE(blk->HasTerminator());
+    EXPECT_NE(blk->Terminator(), nullptr);
 }
 
-TEST_F(IR_BlockTest, HasTerminator_Return) {
+TEST_F(IR_BlockTest, Terminator_Return) {
     auto* f = b.Function("myFunc", mod.Types().void_());
 
     auto* blk = b.Block();
     blk->Append(b.Return(f));
-    EXPECT_TRUE(blk->HasTerminator());
+    EXPECT_NE(blk->Terminator(), nullptr);
 }
 
 TEST_F(IR_BlockTest, Append) {
diff --git a/src/tint/lang/core/ir/loop.cc b/src/tint/lang/core/ir/loop.cc
index efb0cd7..a5e3519 100644
--- a/src/tint/lang/core/ir/loop.cc
+++ b/src/tint/lang/core/ir/loop.cc
@@ -85,7 +85,7 @@
 }
 
 bool Loop::HasInitializer() {
-    return initializer_->HasTerminator();
+    return initializer_->Terminator() != nullptr;
 }
 
 }  // namespace tint::core::ir
diff --git a/src/tint/lang/core/ir/validator.cc b/src/tint/lang/core/ir/validator.cc
index 4eb0cf3..8550d2f 100644
--- a/src/tint/lang/core/ir/validator.cc
+++ b/src/tint/lang/core/ir/validator.cc
@@ -451,7 +451,7 @@
 void Validator::CheckBlock(Block* blk) {
     TINT_SCOPED_ASSIGNMENT(current_block_, blk);
 
-    if (!blk->HasTerminator()) {
+    if (!blk->Terminator()) {
         AddError(blk, "block: does not end in a terminator instruction");
     }
 
diff --git a/src/tint/lang/spirv/writer/printer/printer.cc b/src/tint/lang/spirv/writer/printer/printer.cc
index a7c86b8..03456a9 100644
--- a/src/tint/lang/spirv/writer/printer/printer.cc
+++ b/src/tint/lang/spirv/writer/printer/printer.cc
@@ -975,11 +975,11 @@
         uint32_t true_label = merge_label;
         uint32_t false_label = merge_label;
         if (true_block->Length() > 1 || i->HasResults() ||
-            (true_block->HasTerminator() && !true_block->Terminator()->Is<core::ir::ExitIf>())) {
+            (true_block->Terminator() && !true_block->Terminator()->Is<core::ir::ExitIf>())) {
             true_label = Label(true_block);
         }
         if (false_block->Length() > 1 || i->HasResults() ||
-            (false_block->HasTerminator() && !false_block->Terminator()->Is<core::ir::ExitIf>())) {
+            (false_block->Terminator() && !false_block->Terminator()->Is<core::ir::ExitIf>())) {
             false_label = Label(false_block);
         }
 
@@ -1862,7 +1862,7 @@
         EmitBlockInstructions(loop->Body());
 
         // Emit the loop continuing block.
-        if (loop->Continuing()->HasTerminator()) {
+        if (loop->Continuing()->Terminator()) {
             EmitBlock(loop->Continuing());
         } else {
             // We still need to emit a continuing block with a back-edge, even if it is unreachable.
diff --git a/src/tint/lang/spirv/writer/raise/merge_return.cc b/src/tint/lang/spirv/writer/raise/merge_return.cc
index dbd06d7..08e3f0a 100644
--- a/src/tint/lang/spirv/writer/raise/merge_return.cc
+++ b/src/tint/lang/spirv/writer/raise/merge_return.cc
@@ -178,8 +178,8 @@
                 return b.InstructionResult(v->Type());
             };
 
-            if (inner_if->True()->HasTerminator()) {
-                if (auto* exit_if = inner_if->True()->Terminator()->As<core::ir::ExitIf>()) {
+            if (auto* terminator = inner_if->True()->Terminator()) {
+                if (auto* exit_if = terminator->As<core::ir::ExitIf>()) {
                     // Ensure the associated 'if' is updated.
                     exit_if->SetIf(inner_if);
 
@@ -198,10 +198,10 @@
             // Loop over the 'if' instructions, starting with the inner-most, and add any missing
             // terminating instructions to the blocks holding the 'if'.
             for (auto* i = inner_if; i; i = tint::As<core::ir::If>(i->Block()->Parent())) {
-                if (!i->Block()->HasTerminator() && i->Block()->Parent()) {
+                if (!i->Block()->Terminator() && i->Block()->Parent()) {
                     // Append the exit instruction to the block holding the 'if'.
                     Vector<core::ir::InstructionResult*, 8> exit_args = i->Results();
-                    if (!i->HasResults()) {
+                    if (i->Results().IsEmpty()) {
                         i->SetResults(tint::Transform(exit_args, new_value_with_type));
                     }
                     auto* exit = b.Exit(i->Block()->Parent(), std::move(exit_args));
diff --git a/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc b/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc
index e2c1c43..e472629 100644
--- a/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc
+++ b/src/tint/lang/wgsl/reader/program_to_ir/program_to_ir.cc
@@ -205,11 +205,11 @@
         diagnostics_.add_error(tint::diag::System::IR, err, s);
     }
 
-    bool NeedTerminator() { return current_block_ && !current_block_->HasTerminator(); }
+    bool NeedTerminator() { return current_block_ && !current_block_->Terminator(); }
 
     void SetTerminator(core::ir::Terminator* terminator) {
         TINT_ASSERT(current_block_);
-        TINT_ASSERT(!current_block_->HasTerminator());
+        TINT_ASSERT(!current_block_->Terminator());
 
         current_block_->Append(terminator);
         current_block_ = nullptr;