From a1f9e1342e77e47251e2f001d95f8af8a523745a Mon Sep 17 00:00:00 2001 From: Steven Perron Date: Fri, 1 Jun 2018 13:04:46 -0400 Subject: [PATCH] Preserve inst-to-block and def-use in passes. The following passes are updated to preserve the inst-to-block and def-use analysies: private-to-local aggressive dead-code elimination dead branch elimination local-single-block elimination local-single-store elimination reduce load size compact ids (inst-to-block only) merge block dead-insert elimination ccp The one execption is that compact ids still kills the def-use manager. This is because it changes so many ids it is faster to kill and rebuild. Does everything in https://github.com/KhronosGroup/SPIRV-Tools/issues/1593 except for the changes to merge return. --- source/opt/aggressive_dead_code_elim_pass.cpp | 3 ++- source/opt/aggressive_dead_code_elim_pass.h | 3 ++- source/opt/block_merge_pass.cpp | 8 ++++++++ source/opt/block_merge_pass.h | 7 +++++++ source/opt/ccp_pass.h | 8 ++++++++ source/opt/compact_ids_pass.h | 9 +++++++++ source/opt/dead_branch_elim_pass.cpp | 5 ++++- source/opt/dead_branch_elim_pass.h | 3 ++- source/opt/dead_insert_elim_pass.h | 8 ++++++++ source/opt/local_single_block_elim_pass.h | 3 ++- source/opt/local_single_store_elim_pass.h | 3 ++- source/opt/private_to_local_pass.cpp | 1 + source/opt/private_to_local_pass.h | 1 + source/opt/reduce_load_size.h | 3 ++- 14 files changed, 58 insertions(+), 7 deletions(-) diff --git a/source/opt/aggressive_dead_code_elim_pass.cpp b/source/opt/aggressive_dead_code_elim_pass.cpp index 6d1b7fb57..d7b241cd2 100644 --- a/source/opt/aggressive_dead_code_elim_pass.cpp +++ b/source/opt/aggressive_dead_code_elim_pass.cpp @@ -239,7 +239,8 @@ void AggressiveDCEPass::AddBranch(uint32_t labelId, ir::BasicBlock* bp) { std::unique_ptr newBranch(new ir::Instruction( context(), SpvOpBranch, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {labelId}}})); - get_def_use_mgr()->AnalyzeInstDefUse(&*newBranch); + context()->AnalyzeDefUse(&*newBranch); + context()->set_instr_block(&*newBranch, bp); bp->AddInstruction(std::move(newBranch)); } diff --git a/source/opt/aggressive_dead_code_elim_pass.h b/source/opt/aggressive_dead_code_elim_pass.h index aefdd7073..04cfc81c0 100644 --- a/source/opt/aggressive_dead_code_elim_pass.h +++ b/source/opt/aggressive_dead_code_elim_pass.h @@ -46,7 +46,8 @@ class AggressiveDCEPass : public MemPass { Status Process(ir::IRContext* c) override; ir::IRContext::Analysis GetPreservedAnalyses() override { - return ir::IRContext::kAnalysisDefUse; + return ir::IRContext::kAnalysisDefUse | + ir::IRContext::kAnalysisInstrToBlockMapping; } private: diff --git a/source/opt/block_merge_pass.cpp b/source/opt/block_merge_pass.cpp index fb370d690..09cd3c412 100644 --- a/source/opt/block_merge_pass.cpp +++ b/source/opt/block_merge_pass.cpp @@ -94,7 +94,15 @@ bool BlockMergePass::MergeBlocks(ir::Function* func) { // If bi is sbi's only predecessor, it dominates sbi and thus // sbi must follow bi in func's ordering. assert(sbi != func->end()); + + // Update the inst-to-block mapping for the instructions in sbi. + for (auto& inst : *sbi) { + context()->set_instr_block(&inst, &*bi); + } + + // Now actually move the instructions. bi->AddInstructions(&*sbi); + if (merge_inst) { if (pred_is_header && lab_id == merge_inst->GetSingleWordInOperand(0u)) { // Merging the header and merge blocks, so remove the structured control diff --git a/source/opt/block_merge_pass.h b/source/opt/block_merge_pass.h index a56f245e1..5b1213372 100644 --- a/source/opt/block_merge_pass.h +++ b/source/opt/block_merge_pass.h @@ -39,6 +39,13 @@ class BlockMergePass : public Pass { BlockMergePass(); const char* name() const override { return "merge-blocks"; } Status Process(ir::IRContext*) override; + virtual ir::IRContext::Analysis GetPreservedAnalyses() override { + return ir::IRContext::kAnalysisDefUse | + ir::IRContext::kAnalysisInstrToBlockMapping | + ir::IRContext::kAnalysisDecorations | + ir::IRContext::kAnalysisCombinators | + ir::IRContext::kAnalysisNameMap; + } private: // Kill any OpName instruction referencing |inst|, then kill |inst|. diff --git a/source/opt/ccp_pass.h b/source/opt/ccp_pass.h index e96e731a7..78142c786 100644 --- a/source/opt/ccp_pass.h +++ b/source/opt/ccp_pass.h @@ -30,6 +30,14 @@ class CCPPass : public MemPass { CCPPass() = default; const char* name() const override { return "ccp"; } Status Process(ir::IRContext* c) override; + virtual ir::IRContext::Analysis GetPreservedAnalyses() override { + return ir::IRContext::kAnalysisDefUse | + ir::IRContext::kAnalysisInstrToBlockMapping | + ir::IRContext::kAnalysisDecorations | + ir::IRContext::kAnalysisCombinators | ir::IRContext::kAnalysisCFG | + ir::IRContext::kAnalysisDominatorAnalysis | + ir::IRContext::kAnalysisNameMap; + } private: // Initializes the pass. diff --git a/source/opt/compact_ids_pass.h b/source/opt/compact_ids_pass.h index cf7c3fb72..fec236756 100644 --- a/source/opt/compact_ids_pass.h +++ b/source/opt/compact_ids_pass.h @@ -27,6 +27,15 @@ class CompactIdsPass : public Pass { public: const char* name() const override { return "compact-ids"; } Status Process(ir::IRContext*) override; + + // Return the mask of preserved Analyses. + ir::IRContext::Analysis GetPreservedAnalyses() override { + return ir::IRContext::kAnalysisInstrToBlockMapping | + ir::IRContext::kAnalysisCombinators | ir::IRContext::kAnalysisCFG | + ir::IRContext::kAnalysisDominatorAnalysis | + ir::IRContext::kAnalysisLoopAnalysis | + ir::IRContext::kAnalysisNameMap; + } }; } // namespace opt diff --git a/source/opt/dead_branch_elim_pass.cpp b/source/opt/dead_branch_elim_pass.cpp index 5dfe42e61..32c291138 100644 --- a/source/opt/dead_branch_elim_pass.cpp +++ b/source/opt/dead_branch_elim_pass.cpp @@ -77,7 +77,8 @@ void DeadBranchElimPass::AddBranch(uint32_t labelId, ir::BasicBlock* bp) { std::unique_ptr newBranch(new ir::Instruction( context(), SpvOpBranch, 0, 0, {{spv_operand_type_t::SPV_OPERAND_TYPE_ID, {labelId}}})); - get_def_use_mgr()->AnalyzeInstDefUse(&*newBranch); + context()->AnalyzeDefUse(&*newBranch); + context()->set_instr_block(&*newBranch, bp); bp->AddInstruction(std::move(newBranch)); } @@ -316,6 +317,7 @@ bool DeadBranchElimPass::EraseDeadBlocks( ebi->AddInstruction( MakeUnique(context(), SpvOpUnreachable, 0, 0, std::initializer_list{})); + context()->set_instr_block(&*ebi->tail(), &*ebi); modified = true; } ++ebi; @@ -333,6 +335,7 @@ bool DeadBranchElimPass::EraseDeadBlocks( std::initializer_list{ {SPV_OPERAND_TYPE_ID, {cont_id}}})); get_def_use_mgr()->AnalyzeInstUse(&*ebi->tail()); + context()->set_instr_block(&*ebi->tail(), &*ebi); modified = true; } ++ebi; diff --git a/source/opt/dead_branch_elim_pass.h b/source/opt/dead_branch_elim_pass.h index 62ec582ca..57450bbb6 100644 --- a/source/opt/dead_branch_elim_pass.h +++ b/source/opt/dead_branch_elim_pass.h @@ -42,7 +42,8 @@ class DeadBranchElimPass : public MemPass { Status Process(ir::IRContext* context) override; ir::IRContext::Analysis GetPreservedAnalyses() override { - return ir::IRContext::kAnalysisDefUse; + return ir::IRContext::kAnalysisDefUse | + ir::IRContext::kAnalysisInstrToBlockMapping; } private: diff --git a/source/opt/dead_insert_elim_pass.h b/source/opt/dead_insert_elim_pass.h index f7ee46a83..bc47473b5 100644 --- a/source/opt/dead_insert_elim_pass.h +++ b/source/opt/dead_insert_elim_pass.h @@ -38,6 +38,14 @@ class DeadInsertElimPass : public MemPass { DeadInsertElimPass(); const char* name() const override { return "eliminate-dead-inserts"; } Status Process(ir::IRContext*) override; + virtual ir::IRContext::Analysis GetPreservedAnalyses() override { + return ir::IRContext::kAnalysisDefUse | + ir::IRContext::kAnalysisInstrToBlockMapping | + ir::IRContext::kAnalysisDecorations | + ir::IRContext::kAnalysisCombinators | ir::IRContext::kAnalysisCFG | + ir::IRContext::kAnalysisDominatorAnalysis | + ir::IRContext::kAnalysisNameMap; + } private: // Return the number of subcomponents in the composite type |typeId|. diff --git a/source/opt/local_single_block_elim_pass.h b/source/opt/local_single_block_elim_pass.h index fa68788c1..5179cbcd4 100644 --- a/source/opt/local_single_block_elim_pass.h +++ b/source/opt/local_single_block_elim_pass.h @@ -40,7 +40,8 @@ class LocalSingleBlockLoadStoreElimPass : public MemPass { Status Process(ir::IRContext* c) override; ir::IRContext::Analysis GetPreservedAnalyses() override { - return ir::IRContext::kAnalysisDefUse; + return ir::IRContext::kAnalysisDefUse | + ir::IRContext::kAnalysisInstrToBlockMapping; } private: diff --git a/source/opt/local_single_store_elim_pass.h b/source/opt/local_single_store_elim_pass.h index 00f4a813b..6f23b9876 100644 --- a/source/opt/local_single_store_elim_pass.h +++ b/source/opt/local_single_store_elim_pass.h @@ -42,7 +42,8 @@ class LocalSingleStoreElimPass : public Pass { Status Process(ir::IRContext* irContext) override; ir::IRContext::Analysis GetPreservedAnalyses() override { - return ir::IRContext::kAnalysisDefUse; + return ir::IRContext::kAnalysisDefUse | + ir::IRContext::kAnalysisInstrToBlockMapping; } private: diff --git a/source/opt/private_to_local_pass.cpp b/source/opt/private_to_local_pass.cpp index cc8ef53c1..59ecb1d70 100644 --- a/source/opt/private_to_local_pass.cpp +++ b/source/opt/private_to_local_pass.cpp @@ -103,6 +103,7 @@ void PrivateToLocalPass::MoveVariable(ir::Instruction* variable, // Place the variable at the start of the first basic block. context()->AnalyzeUses(variable); + context()->set_instr_block(variable, &*function->begin()); function->begin()->begin()->InsertBefore(move(var)); // Update uses where the type may have changed. diff --git a/source/opt/private_to_local_pass.h b/source/opt/private_to_local_pass.h index 89cd994f1..7bd4696a7 100644 --- a/source/opt/private_to_local_pass.h +++ b/source/opt/private_to_local_pass.h @@ -31,6 +31,7 @@ class PrivateToLocalPass : public Pass { Status Process(ir::IRContext*) override; ir::IRContext::Analysis GetPreservedAnalyses() override { return ir::IRContext::kAnalysisDefUse | + ir::IRContext::kAnalysisInstrToBlockMapping | ir::IRContext::kAnalysisDecorations | ir::IRContext::kAnalysisCombinators | ir::IRContext::kAnalysisCFG | ir::IRContext::kAnalysisDominatorAnalysis | diff --git a/source/opt/reduce_load_size.h b/source/opt/reduce_load_size.h index ae3112ecc..beec52049 100644 --- a/source/opt/reduce_load_size.h +++ b/source/opt/reduce_load_size.h @@ -30,7 +30,8 @@ class ReduceLoadSize : public Pass { // Return the mask of preserved Analyses. ir::IRContext::Analysis GetPreservedAnalyses() override { - return ir::IRContext::kAnalysisInstrToBlockMapping | + return ir::IRContext::kAnalysisDefUse | + ir::IRContext::kAnalysisInstrToBlockMapping | ir::IRContext::kAnalysisCombinators | ir::IRContext::kAnalysisCFG | ir::IRContext::kAnalysisDominatorAnalysis | ir::IRContext::kAnalysisLoopAnalysis |