[spirv-reader] Simplify if-selection bookkeeping
In BlockInfo, remove the backpointers from true-head, false-head, and
premerge-head to the if-selection header block.
Convert the forward references from if-selection to its internal heads
from pointers to IDs.
Bug: tint:3
Change-Id: Ic931df519795e14374bff4f60ad37a4b32f79c91
Reviewed-on: https://dawn-review.googlesource.com/c/tint/+/23140
Reviewed-by: dan sinclair <dsinclair@google.com>
diff --git a/src/reader/spirv/function.cc b/src/reader/spirv/function.cc
index bf9ce5f..3c42772 100644
--- a/src/reader/spirv/function.cc
+++ b/src/reader/spirv/function.cc
@@ -1336,12 +1336,10 @@
const bool contains_false = construct->ContainsPos(false_head_pos);
if (contains_true) {
- true_head_info->true_head_for = construct.get();
- if_header_info->true_head = true_head_info;
+ if_header_info->true_head = true_head;
}
if (contains_false) {
- false_head_info->false_head_for = construct.get();
- if_header_info->false_head = false_head_info;
+ if_header_info->false_head = false_head;
}
if ((true_head_info->header_for_merge != 0) &&
@@ -1438,8 +1436,7 @@
}
premerge_id = dest_id;
auto* dest_block_info = GetBlockInfo(dest_id);
- dest_block_info->premerge_head_for = construct.get();
- if_header_info->premerge_head = dest_block_info;
+ if_header_info->premerge_head = dest_id;
if (dest_block_info->header_for_merge != 0) {
// Premerge has two edges coming into it, from the then-clause
// and the else-clause. It's also, by construction, not the
@@ -1743,8 +1740,8 @@
assert(construct->kind == Construct::kIfSelection);
assert(construct->begin_id == block_info.id);
- const auto* const false_head = block_info.false_head;
- const auto* const premerge_head = block_info.premerge_head;
+ const uint32_t false_head = block_info.false_head;
+ const uint32_t premerge_head = block_info.premerge_head;
auto* const if_stmt =
AddStatement(std::make_unique<ast::IfStatement>())->AsIf();
@@ -1772,7 +1769,7 @@
// Emit it as: if (cond) {} else {....}
// Move the merge up to where the premerge is.
const uint32_t intended_merge =
- premerge_head ? premerge_head->id : construct->end_id;
+ premerge_head ? premerge_head : construct->end_id;
// then-clause:
// If true_head exists:
@@ -1781,11 +1778,11 @@
// Otherwise:
// ends at from the false head (if it exists), otherwise the selection
// end.
- const uint32_t then_end = false_head ? false_head->id : intended_merge;
+ const uint32_t then_end = false_head ? false_head : intended_merge;
// else-clause:
// ends at the premerge head (if it exists) or at the selection end.
- const uint32_t else_end = premerge_head ? premerge_head->id : intended_merge;
+ const uint32_t else_end = premerge_head ? premerge_head : intended_merge;
// Push statement blocks for the then-clause and the else-clause.
// But make sure we do it in the right order.
diff --git a/src/reader/spirv/function.h b/src/reader/spirv/function.h
index 30fe252..a96f7e8c 100644
--- a/src/reader/spirv/function.h
+++ b/src/reader/spirv/function.h
@@ -137,31 +137,17 @@
/// The following fields record relationships among blocks in a selection
/// construct for an OpBranchConditional instruction.
- /// If not null, then the pointed-at construct is a selection for an
- /// OpBranchConditional and this block is the "true" target for it. We say
- /// this block "heads" the true case.
- const Construct* true_head_for = nullptr;
- /// If not null, then the pointed-at construct is a selection for an
- /// OpBranchConditional and this block is the "false" target for it. We say
- /// this block "heads" the false case.
- const Construct* false_head_for = nullptr;
- /// If not null, then the pointed-at construct is the first block at which
- /// control reconverges between the "then" and "else" clauses, but before
- /// the merge block for that selection.
- const Construct* premerge_head_for = nullptr;
- /// If not null, then this block is an if-selection header, and |true_head| is
- /// the target of the true branch on the OpBranchConditional.
- /// In particular, true_head->true_head_for == this
- const BlockInfo* true_head = nullptr;
- /// If not null, then this block is an if-selection header, and |false_head|
- /// is the target of the false branch on the OpBranchConditional.
- /// In particular, false_head->false_head_for == this
- const BlockInfo* false_head = nullptr;
- /// If not null, then this block is an if-selection header, and when following
+ /// If not 0, then this block is an if-selection header, and |true_head| is
+ /// the target id of the true branch on the OpBranchConditional.
+ uint32_t true_head = 0;
+ /// If not 0, then this block is an if-selection header, and |false_head|
+ /// is the target id of the false branch on the OpBranchConditional.
+ uint32_t false_head = 0;
+ /// If not 0, then this block is an if-selection header, and when following
/// the flow via the true and false branches, control first reconverges at
- /// |premerge_head|, and |premerge_head| is still inside the if-selection.
- /// In particular, premerge_head->premerge_head_for == this
- const BlockInfo* premerge_head = nullptr;
+ /// the block with ID |premerge_head|, and |premerge_head| is still inside
+ /// the if-selection.
+ uint32_t premerge_head = 0;
};
inline std::ostream& operator<<(std::ostream& o, const BlockInfo& bi) {
diff --git a/src/reader/spirv/function_cfg_test.cc b/src/reader/spirv/function_cfg_test.cc
index 3984f3b..4d64864 100644
--- a/src/reader/spirv/function_cfg_test.cc
+++ b/src/reader/spirv/function_cfg_test.cc
@@ -6683,10 +6683,9 @@
auto* bi = fe.GetBlockInfo(10);
ASSERT_NE(bi, nullptr);
- EXPECT_EQ(bi->true_head_for, nullptr);
- EXPECT_EQ(bi->false_head_for, nullptr);
- EXPECT_EQ(bi->premerge_head_for, nullptr);
- EXPECT_EQ(bi->premerge_head_for, nullptr);
+ EXPECT_EQ(bi->true_head, 0u);
+ EXPECT_EQ(bi->false_head, 0u);
+ EXPECT_EQ(bi->premerge_head, 0u);
}
TEST_F(SpvParserTest, FindIfSelectionInternalHeaders_ThenElse) {
@@ -6711,19 +6710,29 @@
FunctionEmitter fe(p, *spirv_function(100));
EXPECT_TRUE(FlowFindIfSelectionInternalHeaders(&fe));
+ auto* bi10 = fe.GetBlockInfo(10);
+ ASSERT_NE(bi10, nullptr);
+ EXPECT_EQ(bi10->true_head, 20u);
+ EXPECT_EQ(bi10->false_head, 30u);
+ EXPECT_EQ(bi10->premerge_head, 0u);
+
auto* bi20 = fe.GetBlockInfo(20);
ASSERT_NE(bi20, nullptr);
- ASSERT_NE(bi20->true_head_for, nullptr);
- EXPECT_EQ(bi20->true_head_for->begin_id, 10u);
- EXPECT_EQ(bi20->false_head_for, nullptr);
- EXPECT_EQ(bi20->premerge_head_for, nullptr);
+ EXPECT_EQ(bi20->true_head, 0u);
+ EXPECT_EQ(bi20->false_head, 0u);
+ EXPECT_EQ(bi20->premerge_head, 0u);
auto* bi30 = fe.GetBlockInfo(30);
ASSERT_NE(bi30, nullptr);
- EXPECT_EQ(bi30->true_head_for, nullptr);
- ASSERT_NE(bi30->false_head_for, nullptr);
- EXPECT_EQ(bi30->false_head_for->begin_id, 10u);
- EXPECT_EQ(bi30->premerge_head_for, nullptr);
+ EXPECT_EQ(bi30->true_head, 0u);
+ EXPECT_EQ(bi30->false_head, 0u);
+ EXPECT_EQ(bi30->premerge_head, 0u);
+
+ auto* bi99 = fe.GetBlockInfo(99);
+ ASSERT_NE(bi99, nullptr);
+ EXPECT_EQ(bi99->true_head, 0u);
+ EXPECT_EQ(bi99->false_head, 0u);
+ EXPECT_EQ(bi99->premerge_head, 0u);
}
TEST_F(SpvParserTest, FindIfSelectionInternalHeaders_IfOnly) {
@@ -6745,12 +6754,23 @@
FunctionEmitter fe(p, *spirv_function(100));
EXPECT_TRUE(FlowFindIfSelectionInternalHeaders(&fe));
+ auto* bi10 = fe.GetBlockInfo(10);
+ ASSERT_NE(bi10, nullptr);
+ EXPECT_EQ(bi10->true_head, 30u);
+ EXPECT_EQ(bi10->false_head, 0u);
+ EXPECT_EQ(bi10->premerge_head, 0u);
+
auto* bi30 = fe.GetBlockInfo(30);
ASSERT_NE(bi30, nullptr);
- ASSERT_NE(bi30->true_head_for, nullptr);
- EXPECT_EQ(bi30->true_head_for->begin_id, 10u);
- EXPECT_EQ(bi30->false_head_for, nullptr);
- EXPECT_EQ(bi30->premerge_head_for, nullptr);
+ EXPECT_EQ(bi30->true_head, 0u);
+ EXPECT_EQ(bi30->false_head, 0u);
+ EXPECT_EQ(bi30->premerge_head, 0u);
+
+ auto* bi99 = fe.GetBlockInfo(99);
+ ASSERT_NE(bi99, nullptr);
+ EXPECT_EQ(bi99->true_head, 0u);
+ EXPECT_EQ(bi99->false_head, 0u);
+ EXPECT_EQ(bi99->premerge_head, 0u);
}
TEST_F(SpvParserTest, FindIfSelectionInternalHeaders_ElseOnly) {
@@ -6772,12 +6792,23 @@
FunctionEmitter fe(p, *spirv_function(100));
EXPECT_TRUE(FlowFindIfSelectionInternalHeaders(&fe));
+ auto* bi10 = fe.GetBlockInfo(10);
+ ASSERT_NE(bi10, nullptr);
+ EXPECT_EQ(bi10->true_head, 0u);
+ EXPECT_EQ(bi10->false_head, 30u);
+ EXPECT_EQ(bi10->premerge_head, 0u);
+
auto* bi30 = fe.GetBlockInfo(30);
ASSERT_NE(bi30, nullptr);
- EXPECT_EQ(bi30->true_head_for, nullptr);
- ASSERT_NE(bi30->false_head_for, nullptr);
- EXPECT_EQ(bi30->false_head_for->begin_id, 10u);
- EXPECT_EQ(bi30->premerge_head_for, nullptr);
+ EXPECT_EQ(bi30->true_head, 0u);
+ EXPECT_EQ(bi30->false_head, 0u);
+ EXPECT_EQ(bi30->premerge_head, 0u);
+
+ auto* bi99 = fe.GetBlockInfo(99);
+ ASSERT_NE(bi99, nullptr);
+ EXPECT_EQ(bi99->true_head, 0u);
+ EXPECT_EQ(bi99->false_head, 0u);
+ EXPECT_EQ(bi99->premerge_head, 0u);
}
TEST_F(SpvParserTest, FindIfSelectionInternalHeaders_Regardless) {
@@ -6804,19 +6835,11 @@
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 80, 99));
- auto* bi20 = fe.GetBlockInfo(20);
- ASSERT_NE(bi20, nullptr);
- ASSERT_NE(bi20->true_head_for, nullptr);
- EXPECT_EQ(bi20->true_head_for->begin_id, 10u);
- ASSERT_NE(bi20->false_head_for, nullptr);
- EXPECT_EQ(bi20->false_head_for->begin_id, 10u);
- EXPECT_EQ(bi20->premerge_head_for, nullptr);
-
- auto* bi80 = fe.GetBlockInfo(80);
- ASSERT_NE(bi80, nullptr);
- EXPECT_EQ(bi80->true_head_for, nullptr);
- EXPECT_EQ(bi80->false_head_for, nullptr);
- EXPECT_EQ(bi80->premerge_head_for, nullptr);
+ auto* bi10 = fe.GetBlockInfo(10);
+ ASSERT_NE(bi10, nullptr);
+ EXPECT_EQ(bi10->true_head, 20u);
+ EXPECT_EQ(bi10->false_head, 20u);
+ EXPECT_EQ(bi10->premerge_head, 0u);
}
TEST_F(SpvParserTest, FindIfSelectionInternalHeaders_Premerge_Simple) {
@@ -6846,12 +6869,11 @@
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 30, 80, 99));
- auto* bi80 = fe.GetBlockInfo(80);
- ASSERT_NE(bi80, nullptr);
- EXPECT_EQ(bi80->true_head_for, nullptr);
- EXPECT_EQ(bi80->false_head_for, nullptr);
- ASSERT_NE(bi80->premerge_head_for, nullptr);
- EXPECT_EQ(bi80->premerge_head_for->begin_id, 10u);
+ auto* bi10 = fe.GetBlockInfo(10);
+ ASSERT_NE(bi10, nullptr);
+ EXPECT_EQ(bi10->true_head, 20u);
+ EXPECT_EQ(bi10->false_head, 30u);
+ EXPECT_EQ(bi10->premerge_head, 80u);
}
TEST_F(SpvParserTest,
@@ -6882,26 +6904,11 @@
EXPECT_THAT(fe.block_order(), ElementsAre(10, 20, 30, 80, 99));
- auto* bi20 = fe.GetBlockInfo(20);
- ASSERT_NE(bi20, nullptr);
- ASSERT_NE(bi20->true_head_for, nullptr);
- EXPECT_EQ(bi20->true_head_for->begin_id, 10u);
- EXPECT_EQ(bi20->false_head_for, nullptr);
- EXPECT_EQ(bi20->premerge_head_for, nullptr);
-
- auto* bi30 = fe.GetBlockInfo(30);
- ASSERT_NE(bi30, nullptr);
- EXPECT_EQ(bi30->true_head_for, nullptr);
- ASSERT_NE(bi30->false_head_for, nullptr);
- EXPECT_EQ(bi30->false_head_for->begin_id, 10u);
- ASSERT_NE(bi30->premerge_head_for, nullptr);
- EXPECT_EQ(bi30->premerge_head_for->begin_id, 10u);
-
- auto* bi80 = fe.GetBlockInfo(80);
- ASSERT_NE(bi80, nullptr);
- EXPECT_EQ(bi80->true_head_for, nullptr);
- EXPECT_EQ(bi80->false_head_for, nullptr);
- EXPECT_EQ(bi80->premerge_head_for, nullptr);
+ auto* bi10 = fe.GetBlockInfo(10);
+ ASSERT_NE(bi10, nullptr);
+ EXPECT_EQ(bi10->true_head, 20u);
+ EXPECT_EQ(bi10->false_head, 30u);
+ EXPECT_EQ(bi10->premerge_head, 30u);
}
TEST_F(SpvParserTest,
@@ -6932,26 +6939,11 @@
EXPECT_THAT(fe.block_order(), ElementsAre(10, 30, 20, 80, 99));
- auto* bi20 = fe.GetBlockInfo(20);
- ASSERT_NE(bi20, nullptr);
- ASSERT_NE(bi20->true_head_for, nullptr);
- EXPECT_EQ(bi20->true_head_for->begin_id, 10u);
- EXPECT_EQ(bi20->false_head_for, nullptr);
- ASSERT_NE(bi20->premerge_head_for, nullptr);
- EXPECT_EQ(bi20->premerge_head_for->begin_id, 10u);
-
- auto* bi30 = fe.GetBlockInfo(30);
- ASSERT_NE(bi30, nullptr);
- EXPECT_EQ(bi30->true_head_for, nullptr);
- ASSERT_NE(bi30->false_head_for, nullptr);
- EXPECT_EQ(bi30->false_head_for->begin_id, 10u);
- EXPECT_EQ(bi30->premerge_head_for, nullptr);
-
- auto* bi80 = fe.GetBlockInfo(80);
- ASSERT_NE(bi80, nullptr);
- EXPECT_EQ(bi80->true_head_for, nullptr);
- EXPECT_EQ(bi80->false_head_for, nullptr);
- EXPECT_EQ(bi80->premerge_head_for, nullptr);
+ auto* bi10 = fe.GetBlockInfo(10);
+ ASSERT_NE(bi10, nullptr);
+ EXPECT_EQ(bi10->true_head, 20u);
+ EXPECT_EQ(bi10->false_head, 30u);
+ EXPECT_EQ(bi10->premerge_head, 20u);
}
TEST_F(SpvParserTest,