Remove DebugDeclare only for target variables in ssa-rewrite (#3511)

For each local variable, ssa-rewrite should remove its DebugDeclare
if and only if it is replaced by any number of DebugValues for store
and phi instructions.

For example, when we have two variables `a` whose DebugDeclare
will be replaced to DebugValues by ssa-rewrite pass and `b` whose
DebugDeclare will not be replaced, we have to remove only DebugDeclare
for `a`, not `b`.
This commit is contained in:
Jaebaek Seo 2020-07-31 10:00:30 -04:00 committed by GitHub
parent 91cea06ab4
commit b78f4b1518
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 135 additions and 12 deletions

View File

@ -222,13 +222,6 @@ bool IRContext::KillDef(uint32_t id) {
return false;
}
void IRContext::KillDebugDeclareInsts(Function* fn) {
fn->ForEachInst([this](Instruction* inst) {
if (inst->GetOpenCL100DebugOpcode() == OpenCLDebugInfo100DebugDeclare)
KillInst(inst);
});
}
bool IRContext::ReplaceAllUsesWith(uint32_t before, uint32_t after) {
return ReplaceAllUsesWithPredicate(
before, after, [](Instruction*, uint32_t) { return true; });

View File

@ -403,9 +403,6 @@ class IRContext {
// instruction exists.
Instruction* KillInst(Instruction* inst);
// Deletes DebugDeclare instructions in the given function |fn|.
void KillDebugDeclareInsts(Function* fn);
// Returns true if all of the given analyses are valid.
bool AreAnalysesValid(Analysis set) { return (set & valid_analyses_) == set; }

View File

@ -615,8 +615,6 @@ Pass::Status SSARewriter::RewriteFunctionIntoSSA(Function* fp) {
<< fp->PrettyPrint(0) << "\n";
#endif
if (modified) pass_->context()->KillDebugDeclareInsts(fp);
return modified ? Pass::Status::SuccessWithChange
: Pass::Status::SuccessWithoutChange;
}
@ -626,6 +624,12 @@ Pass::Status SSARewritePass::Process() {
for (auto& fn : *get_module()) {
status =
CombineStatus(status, SSARewriter(this).RewriteFunctionIntoSSA(&fn));
if (status == Status::SuccessWithChange) {
// Kill DebugDeclares for target variables.
for (auto var_id : seen_target_vars_) {
context()->get_debug_info_mgr()->KillDebugDeclares(var_id);
}
}
if (status == Status::Failure) {
break;
}

View File

@ -2165,6 +2165,135 @@ OpFunctionEnd
SinglePassRunAndMatch<SSARewritePass>(text, true);
}
TEST_F(LocalSSAElimTest, PartiallyKillDebugDeclare) {
// For a reference variable e.g., int i in the following example,
// we do not propagate DebugValue for a store or phi instruction
// out of the variable's scope. In that case, we should not remove
// DebugDeclare for the variable that we did not add its DebugValue.
//
// #version 140
//
// in vec4 BC;
// out float fo;
//
// int j;
// void main()
// {
// float f = 0.0;
// for (j=0; j<4; j++) {
// int& i = j;
// f = f + BC[i];
// }
// fo = f;
// }
const std::string text = R"(
; CHECK: [[f_name:%\w+]] = OpString "f"
; CHECK: [[i_name:%\w+]] = OpString "i"
; CHECK: [[fn:%\w+]] = OpExtInst %void [[ext:%\d+]] DebugFunction
; CHECK: [[bb:%\w+]] = OpExtInst %void [[ext]] DebugLexicalBlock
; CHECK: [[dbg_f:%\w+]] = OpExtInst %void [[ext]] DebugLocalVariable [[f_name]] {{%\w+}} {{%\w+}} 0 0 [[fn]]
; CHECK: [[dbg_i:%\w+]] = OpExtInst %void [[ext]] DebugLocalVariable [[i_name]] {{%\w+}} {{%\w+}} 0 0 [[bb]]
; CHECK: OpStore %f %float_0
; CHECK-NEXT: OpExtInst %void [[ext]] DebugValue [[dbg_f]] %float_0
; CHECK-NOT: DebugDeclare [[dbg_f]]
; CHECK: OpExtInst %void [[ext]] DebugDeclare [[dbg_i]] %j
OpCapability Shader
%1 = OpExtInstImport "GLSL.std.450"
%ext = OpExtInstImport "OpenCL.DebugInfo.100"
OpMemoryModel Logical GLSL450
OpEntryPoint Fragment %main "main" %BC %fo
OpExecutionMode %main OriginUpperLeft
%file_name = OpString "test"
OpSource GLSL 140
%float_name = OpString "float"
%main_name = OpString "main"
%f_name = OpString "f"
%i_name = OpString "i"
%j_name = OpString "j"
OpName %main "main"
OpName %f "f"
OpName %j "j"
OpName %BC "BC"
OpName %fo "fo"
%void = OpTypeVoid
%8 = OpTypeFunction %void
%float = OpTypeFloat 32
%_ptr_Function_float = OpTypePointer Function %float
%float_0 = OpConstant %float 0
%int = OpTypeInt 32 1
%uint = OpTypeInt 32 0
%uint_32 = OpConstant %uint 32
%_ptr_Function_int = OpTypePointer Function %int
%_ptr_Private_int = OpTypePointer Private %int
%int_0 = OpConstant %int 0
%int_4 = OpConstant %int 4
%bool = OpTypeBool
%v4float = OpTypeVector %float 4
%_ptr_Input_v4float = OpTypePointer Input %v4float
%BC = OpVariable %_ptr_Input_v4float Input
%_ptr_Input_float = OpTypePointer Input %float
%int_1 = OpConstant %int 1
%_ptr_Output_float = OpTypePointer Output %float
%fo = OpVariable %_ptr_Output_float Output
%j = OpVariable %_ptr_Private_int Private
%null_expr = OpExtInst %void %ext DebugExpression
%src = OpExtInst %void %ext DebugSource %file_name
%cu = OpExtInst %void %ext DebugCompilationUnit 1 4 %src HLSL
%dbg_tf = OpExtInst %void %ext DebugTypeBasic %float_name %uint_32 Float
%dbg_v4f = OpExtInst %void %ext DebugTypeVector %dbg_tf 4
%main_ty = OpExtInst %void %ext DebugTypeFunction FlagIsProtected|FlagIsPrivate %dbg_v4f %dbg_v4f
%dbg_main = OpExtInst %void %ext DebugFunction %main_name %main_ty %src 0 0 %cu %main_name FlagIsProtected|FlagIsPrivate 10 %main
%bb = OpExtInst %void %ext DebugLexicalBlock %src 0 0 %dbg_main
%dbg_f = OpExtInst %void %ext DebugLocalVariable %f_name %dbg_v4f %src 0 0 %dbg_main FlagIsLocal
%dbg_i = OpExtInst %void %ext DebugLocalVariable %i_name %dbg_v4f %src 0 0 %bb FlagIsLocal
%dbg_j = OpExtInst %void %ext DebugGlobalVariable %j_name %dbg_v4f %src 0 0 %dbg_main %j_name %j FlagIsPrivate
%main = OpFunction %void None %8
%22 = OpLabel
%s0 = OpExtInst %void %ext DebugScope %dbg_main
%f = OpVariable %_ptr_Function_float Function
OpStore %f %float_0
OpStore %j %int_0
%decl0 = OpExtInst %void %ext DebugDeclare %dbg_f %f %null_expr
OpBranch %23
%23 = OpLabel
%s1 = OpExtInst %void %ext DebugScope %dbg_main
OpLoopMerge %24 %25 None
OpBranch %26
%26 = OpLabel
%s2 = OpExtInst %void %ext DebugScope %dbg_main
%27 = OpLoad %int %j
%28 = OpSLessThan %bool %27 %int_4
OpBranchConditional %28 %29 %24
%29 = OpLabel
%s3 = OpExtInst %void %ext DebugScope %bb
%decl1 = OpExtInst %void %ext DebugDeclare %dbg_i %j %null_expr
%30 = OpLoad %float %f
%31 = OpLoad %int %j
%32 = OpAccessChain %_ptr_Input_float %BC %31
%33 = OpLoad %float %32
%34 = OpFAdd %float %30 %33
OpStore %f %34
OpBranch %25
%25 = OpLabel
%s4 = OpExtInst %void %ext DebugScope %dbg_main
%35 = OpLoad %int %j
%36 = OpIAdd %int %35 %int_1
OpStore %j %36
OpBranch %23
%24 = OpLabel
%s5 = OpExtInst %void %ext DebugScope %dbg_main
%37 = OpLoad %float %f
OpStore %fo %37
OpReturn
OpFunctionEnd
)";
SinglePassRunAndMatch<SSARewritePass>(text, true);
}
TEST_F(LocalSSAElimTest, DebugValueForReferenceVariable) {
// #version 140
//