mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-12-24 16:51:06 +00:00
spirv-opt: Add support for OpLabel to dominator analysis (#3516)
Fixes #3515.
This commit is contained in:
parent
f12c40f5a6
commit
8e0215afe0
@ -55,12 +55,25 @@ bool DominatorAnalysisBase::Dominates(Instruction* a, Instruction* b) const {
|
||||
return tree_.Dominates(bb_a, bb_b);
|
||||
}
|
||||
|
||||
Instruction* current_inst = a;
|
||||
while ((current_inst = current_inst->NextNode())) {
|
||||
if (current_inst == b) {
|
||||
const Instruction* current = a;
|
||||
const Instruction* other = b;
|
||||
|
||||
if (tree_.IsPostDominator()) {
|
||||
std::swap(current, other);
|
||||
}
|
||||
|
||||
// We handle OpLabel instructions explicitly since they are not stored in the
|
||||
// instruction list.
|
||||
if (current->opcode() == SpvOpLabel) {
|
||||
return true;
|
||||
}
|
||||
|
||||
while ((current = current->NextNode())) {
|
||||
if (current == other) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -895,6 +895,126 @@ TEST_F(PassClassTest, DominatorUnreachableFromEntry) {
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(PassClassTest, DominationForInstructions) {
|
||||
const std::string text = R"(
|
||||
OpCapability Shader
|
||||
%1 = OpExtInstImport "GLSL.std.450"
|
||||
OpMemoryModel Logical GLSL450
|
||||
OpEntryPoint Fragment %4 "main"
|
||||
OpExecutionMode %4 OriginUpperLeft
|
||||
OpSource ESSL 310
|
||||
%2 = OpTypeVoid
|
||||
%3 = OpTypeFunction %2
|
||||
%6 = OpTypeInt 32 1
|
||||
%7 = OpTypeBool
|
||||
%8 = OpConstantTrue %7
|
||||
%9 = OpConstant %6 37
|
||||
%10 = OpConstant %6 3
|
||||
%13 = OpConstant %6 5
|
||||
%4 = OpFunction %2 None %3
|
||||
%5 = OpLabel
|
||||
%12 = OpIAdd %6 %9 %10
|
||||
%15 = OpISub %6 %12 %13
|
||||
OpSelectionMerge %18 None
|
||||
OpBranchConditional %8 %16 %17
|
||||
%16 = OpLabel
|
||||
%20 = OpISub %6 %12 %13
|
||||
OpBranch %18
|
||||
%17 = OpLabel
|
||||
%21 = OpISub %6 %12 %13
|
||||
OpBranch %18
|
||||
%18 = OpLabel
|
||||
%22 = OpISub %6 %12 %13
|
||||
OpReturn
|
||||
OpFunctionEnd
|
||||
)";
|
||||
|
||||
// clang-format on
|
||||
std::unique_ptr<IRContext> context =
|
||||
BuildModule(SPV_ENV_UNIVERSAL_1_0, nullptr, text,
|
||||
SPV_TEXT_TO_BINARY_OPTION_PRESERVE_NUMERIC_IDS);
|
||||
EXPECT_NE(nullptr, context->module()) << "Assembling failed for shader:\n"
|
||||
<< text << std::endl;
|
||||
|
||||
{
|
||||
const DominatorAnalysis* dominator_analysis = context->GetDominatorAnalysis(
|
||||
spvtest::GetFunction(context->module(), 4));
|
||||
|
||||
EXPECT_TRUE(
|
||||
dominator_analysis->Dominates(context->get_def_use_mgr()->GetDef(12),
|
||||
context->get_def_use_mgr()->GetDef(15)));
|
||||
EXPECT_FALSE(
|
||||
dominator_analysis->Dominates(context->get_def_use_mgr()->GetDef(15),
|
||||
context->get_def_use_mgr()->GetDef(12)));
|
||||
EXPECT_TRUE(
|
||||
dominator_analysis->Dominates(context->get_def_use_mgr()->GetDef(5),
|
||||
context->get_def_use_mgr()->GetDef(12)));
|
||||
EXPECT_FALSE(
|
||||
dominator_analysis->Dominates(context->get_def_use_mgr()->GetDef(12),
|
||||
context->get_def_use_mgr()->GetDef(5)));
|
||||
EXPECT_TRUE(
|
||||
dominator_analysis->Dominates(context->get_def_use_mgr()->GetDef(15),
|
||||
context->get_def_use_mgr()->GetDef(16)));
|
||||
EXPECT_TRUE(
|
||||
dominator_analysis->Dominates(context->get_def_use_mgr()->GetDef(15),
|
||||
context->get_def_use_mgr()->GetDef(21)));
|
||||
EXPECT_TRUE(
|
||||
dominator_analysis->Dominates(context->get_def_use_mgr()->GetDef(15),
|
||||
context->get_def_use_mgr()->GetDef(18)));
|
||||
EXPECT_TRUE(
|
||||
dominator_analysis->Dominates(context->get_def_use_mgr()->GetDef(15),
|
||||
context->get_def_use_mgr()->GetDef(22)));
|
||||
EXPECT_FALSE(
|
||||
dominator_analysis->Dominates(context->get_def_use_mgr()->GetDef(20),
|
||||
context->get_def_use_mgr()->GetDef(22)));
|
||||
EXPECT_FALSE(
|
||||
dominator_analysis->Dominates(context->get_def_use_mgr()->GetDef(21),
|
||||
context->get_def_use_mgr()->GetDef(22)));
|
||||
EXPECT_TRUE(
|
||||
dominator_analysis->Dominates(context->get_def_use_mgr()->GetDef(15),
|
||||
context->get_def_use_mgr()->GetDef(15)));
|
||||
}
|
||||
{
|
||||
const PostDominatorAnalysis* post_dominator_analysis =
|
||||
context->GetPostDominatorAnalysis(
|
||||
spvtest::GetFunction(context->module(), 4));
|
||||
|
||||
EXPECT_TRUE(post_dominator_analysis->Dominates(
|
||||
context->get_def_use_mgr()->GetDef(15),
|
||||
context->get_def_use_mgr()->GetDef(12)));
|
||||
EXPECT_FALSE(post_dominator_analysis->Dominates(
|
||||
context->get_def_use_mgr()->GetDef(12),
|
||||
context->get_def_use_mgr()->GetDef(15)));
|
||||
EXPECT_TRUE(post_dominator_analysis->Dominates(
|
||||
context->get_def_use_mgr()->GetDef(12),
|
||||
context->get_def_use_mgr()->GetDef(5)));
|
||||
EXPECT_FALSE(post_dominator_analysis->Dominates(
|
||||
context->get_def_use_mgr()->GetDef(5),
|
||||
context->get_def_use_mgr()->GetDef(12)));
|
||||
EXPECT_FALSE(post_dominator_analysis->Dominates(
|
||||
context->get_def_use_mgr()->GetDef(16),
|
||||
context->get_def_use_mgr()->GetDef(15)));
|
||||
EXPECT_FALSE(post_dominator_analysis->Dominates(
|
||||
context->get_def_use_mgr()->GetDef(21),
|
||||
context->get_def_use_mgr()->GetDef(15)));
|
||||
EXPECT_TRUE(post_dominator_analysis->Dominates(
|
||||
context->get_def_use_mgr()->GetDef(18),
|
||||
context->get_def_use_mgr()->GetDef(15)));
|
||||
EXPECT_TRUE(post_dominator_analysis->Dominates(
|
||||
context->get_def_use_mgr()->GetDef(22),
|
||||
context->get_def_use_mgr()->GetDef(15)));
|
||||
EXPECT_TRUE(post_dominator_analysis->Dominates(
|
||||
context->get_def_use_mgr()->GetDef(22),
|
||||
context->get_def_use_mgr()->GetDef(20)));
|
||||
EXPECT_TRUE(post_dominator_analysis->Dominates(
|
||||
context->get_def_use_mgr()->GetDef(22),
|
||||
context->get_def_use_mgr()->GetDef(21)));
|
||||
EXPECT_TRUE(post_dominator_analysis->Dominates(
|
||||
context->get_def_use_mgr()->GetDef(15),
|
||||
context->get_def_use_mgr()->GetDef(15)));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace opt
|
||||
} // namespace spvtools
|
||||
|
Loading…
Reference in New Issue
Block a user