diff options
author | GregF <greg@LunarG.com> | 2017-07-10 17:20:35 -0600 |
---|---|---|
committer | David Neto <dneto@google.com> | 2017-07-12 15:58:42 -0400 |
commit | e2544ddc908261ba0d3dd8898cc0001e9c349f76 (patch) | |
tree | 93fc58006d4c9dbb65327873697a4bd536d53b84 | |
parent | 06d4fd52c244ee5abf6819f721b9f68e5a3fcdb0 (diff) | |
download | SPIRV-Tools-e2544ddc908261ba0d3dd8898cc0001e9c349f76.tar.gz SPIRV-Tools-e2544ddc908261ba0d3dd8898cc0001e9c349f76.tar.bz2 SPIRV-Tools-e2544ddc908261ba0d3dd8898cc0001e9c349f76.zip |
DeadBranchElim: Improve algorithm to only remove blocks with no predecessors
Must be careful not to remove blocks pointed at by unreachable blocks
-rw-r--r-- | source/opt/dead_branch_elim_pass.cpp | 33 |
1 files changed, 11 insertions, 22 deletions
diff --git a/source/opt/dead_branch_elim_pass.cpp b/source/opt/dead_branch_elim_pass.cpp index 5333468e..48bfc6c2 100644 --- a/source/opt/dead_branch_elim_pass.cpp +++ b/source/opt/dead_branch_elim_pass.cpp @@ -218,27 +218,11 @@ bool DeadBranchElimPass::EliminateDeadBranches(ir::Function* func) { def_use_mgr_->KillInst(mergeInst); // Iterate to merge block adding dead blocks to elimination set - std::unordered_set<uint32_t> deadSuccIds; - deadSuccIds.insert(deadLabId); auto dbi = bi; ++dbi; uint32_t dLabId = (*dbi)->id(); while (dLabId != mergeLabId) { - if (deadSuccIds.find(dLabId) != deadSuccIds.end()) { - // Add successor blocks to dead successor set - (*dbi)->ForEachSuccessorLabel([&deadSuccIds](uint32_t succ) { - deadSuccIds.insert(succ); - }); - // If dead block is header block, add its merge block to dead - // successor set in case it has no predecessors. Add continue - // target if loop header. - uint32_t cbid; - const uint32_t dMergeLabId = MergeBlockIdIfAny(**dbi, &cbid); - if (dMergeLabId != 0) { - deadSuccIds.insert(dMergeLabId); - if (cbid != 0) - deadSuccIds.insert(cbid); - } + if (!HasNonPhiRef(dLabId)) { // Kill use/def for all instructions and mark block for elimination KillAllInsts(*dbi); elimBlocks.insert(*dbi); @@ -248,14 +232,19 @@ bool DeadBranchElimPass::EliminateDeadBranches(ir::Function* func) { } // Process phi instructions in merge block. - // deadLabIds are now blocks which cannot precede merge block. - // If eliminated branch is to merge label, add current block to dead blocks. + // elimBlocks are now blocks which cannot precede merge block. Also, + // if eliminated branch is to merge label, remember the conditional block + // also cannot precede merge block. + uint32_t deadCondLabId = 0; if (deadLabId == mergeLabId) - deadSuccIds.insert((*bi)->id()); - (*dbi)->ForEachPhiInst([&deadSuccIds, this](ir::Instruction* phiInst) { + deadCondLabId = (*bi)->id(); + (*dbi)->ForEachPhiInst([&elimBlocks, &deadCondLabId, this]( + ir::Instruction* phiInst) { const uint32_t phiLabId0 = phiInst->GetSingleWordInOperand(kPhiLab0IdInIdx); - const bool useFirst = deadSuccIds.find(phiLabId0) == deadSuccIds.end(); + const bool useFirst = + elimBlocks.find(id2block_[phiLabId0]) == elimBlocks.end() && + phiLabId0 != deadCondLabId; const uint32_t phiValIdx = useFirst ? kPhiVal0IdInIdx : kPhiVal1IdInIdx; const uint32_t replId = phiInst->GetSingleWordInOperand(phiValIdx); |