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