Skip to content

Commit d0bcfb2

Browse files
opt: Fix ADCE DebugDeclare DebugValue treatment (KhronosGroup#6179)
1 parent a7be3a7 commit d0bcfb2

File tree

4 files changed

+381
-69
lines changed

4 files changed

+381
-69
lines changed

source/opt/aggressive_dead_code_elim_pass.cpp

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ constexpr uint32_t kExtInstSetInIdx = 0;
4444
constexpr uint32_t kExtInstOpInIdx = 1;
4545
constexpr uint32_t kInterpolantInIdx = 2;
4646
constexpr uint32_t kCooperativeMatrixLoadSourceAddrInIdx = 0;
47+
constexpr uint32_t kDebugValueLocalVariable = 2;
48+
constexpr uint32_t kDebugValueValue = 3;
49+
constexpr uint32_t kDebugValueExpression = 4;
4750

4851
// Sorting functor to present annotation instructions in an easy-to-process
4952
// order. The functor orders by opcode first and falls back on unique id
@@ -277,9 +280,53 @@ bool AggressiveDCEPass::AggressiveDCE(Function* func) {
277280
live_local_vars_.clear();
278281
InitializeWorkList(func, structured_order);
279282
ProcessWorkList(func);
283+
ProcessDebugInformation(structured_order);
284+
ProcessWorkList(func);
280285
return KillDeadInstructions(func, structured_order);
281286
}
282287

288+
void AggressiveDCEPass::ProcessDebugInformation(
289+
std::list<BasicBlock*>& structured_order) {
290+
for (auto bi = structured_order.begin(); bi != structured_order.end(); bi++) {
291+
(*bi)->ForEachInst([this](Instruction* inst) {
292+
// DebugDeclare is not dead. It must be converted to DebugValue in a
293+
// later pass
294+
if (inst->IsNonSemanticInstruction() &&
295+
inst->GetShader100DebugOpcode() ==
296+
NonSemanticShaderDebugInfo100DebugDeclare) {
297+
AddToWorklist(inst);
298+
return;
299+
}
300+
301+
// If the Value of a DebugValue is killed, set Value operand to Undef
302+
if (inst->IsNonSemanticInstruction() &&
303+
inst->GetShader100DebugOpcode() ==
304+
NonSemanticShaderDebugInfo100DebugValue) {
305+
uint32_t id = inst->GetSingleWordInOperand(kDebugValueValue);
306+
auto def = get_def_use_mgr()->GetDef(id);
307+
if (!live_insts_.Set(def->unique_id())) {
308+
AddToWorklist(inst);
309+
context()->get_def_use_mgr()->UpdateDefUse(inst);
310+
worklist_.push(def);
311+
def->SetOpcode(spv::Op::OpUndef);
312+
def->SetInOperands({});
313+
id = inst->GetSingleWordInOperand(kDebugValueLocalVariable);
314+
auto localVar = get_def_use_mgr()->GetDef(id);
315+
AddToWorklist(localVar);
316+
context()->get_def_use_mgr()->UpdateDefUse(localVar);
317+
AddOperandsToWorkList(localVar);
318+
context()->get_def_use_mgr()->UpdateDefUse(def);
319+
id = inst->GetSingleWordInOperand(kDebugValueExpression);
320+
auto expression = get_def_use_mgr()->GetDef(id);
321+
AddToWorklist(expression);
322+
context()->get_def_use_mgr()->UpdateDefUse(expression);
323+
return;
324+
}
325+
}
326+
});
327+
}
328+
}
329+
283330
bool AggressiveDCEPass::KillDeadInstructions(
284331
const Function* func, std::list<BasicBlock*>& structured_order) {
285332
bool modified = false;

source/opt/aggressive_dead_code_elim_pass.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,12 @@ class AggressiveDCEPass : public MemPass {
150150
// will be empty at the end.
151151
void ProcessWorkList(Function* func);
152152

153+
// Process each DebugDeclare and DebugValue in |func| that has not been
154+
// marked as live in the work list. DebugDeclare's are marked live now, and
155+
// DebugValue Value operands are set to OpUndef. The work list will be empty
156+
// at the end.
157+
void ProcessDebugInformation(std::list<BasicBlock*>& structured_order);
158+
153159
// Kills any instructions in |func| that have not been marked as live.
154160
bool KillDeadInstructions(const Function* func,
155161
std::list<BasicBlock*>& structured_order);

source/opt/instruction.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,6 +1035,12 @@ bool Instruction::IsOpcodeSafeToDelete() const {
10351035
return true;
10361036
}
10371037

1038+
if (IsNonSemanticInstruction() &&
1039+
(GetShader100DebugOpcode() == NonSemanticShaderDebugInfo100DebugDeclare ||
1040+
GetShader100DebugOpcode() == NonSemanticShaderDebugInfo100DebugValue)) {
1041+
return true;
1042+
}
1043+
10381044
switch (opcode()) {
10391045
case spv::Op::OpDPdx:
10401046
case spv::Op::OpDPdy:

0 commit comments

Comments
 (0)