From 2d0f7fbc1151004c4cf111b947f1070a03dfe092 Mon Sep 17 00:00:00 2001 From: greg-lunarg Date: Sat, 22 Jul 2017 08:32:19 -0600 Subject: [PATCH] Opt: LocalBlockElim: Add HasOnlySupportedRefs Verifies that targeted variables have only access chain and direct loads and stores as references. --- source/opt/aggressive_dead_code_elim_pass.cpp | 1 - source/opt/local_single_block_elim_pass.cpp | 25 +++++++++++++++++++++++++ source/opt/local_single_block_elim_pass.h | 8 ++++++++ source/opt/local_ssa_elim_pass.h | 3 +-- 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/source/opt/aggressive_dead_code_elim_pass.cpp b/source/opt/aggressive_dead_code_elim_pass.cpp index 8238206..85e8041 100644 --- a/source/opt/aggressive_dead_code_elim_pass.cpp +++ b/source/opt/aggressive_dead_code_elim_pass.cpp @@ -231,7 +231,6 @@ bool AggressiveDCEPass::AggressiveDCE(ir::Function* func) { } void AggressiveDCEPass::Initialize(ir::Module* module) { - module_ = module; // Initialize id-to-function map diff --git a/source/opt/local_single_block_elim_pass.cpp b/source/opt/local_single_block_elim_pass.cpp index 39d7ba5..c3c6613 100644 --- a/source/opt/local_single_block_elim_pass.cpp +++ b/source/opt/local_single_block_elim_pass.cpp @@ -218,6 +218,24 @@ void LocalSingleBlockLoadStoreElimPass::DCEInst(ir::Instruction* inst) { } } +bool LocalSingleBlockLoadStoreElimPass::HasOnlySupportedRefs(uint32_t ptrId) { + if (supported_ref_ptrs_.find(ptrId) != supported_ref_ptrs_.end()) + return true; + analysis::UseList* uses = def_use_mgr_->GetUses(ptrId); + assert(uses != nullptr); + for (auto u : *uses) { + SpvOp op = u.inst->opcode(); + if (IsNonPtrAccessChain(op)) { + if (!HasOnlySupportedRefs(u.inst->result_id())) + return false; + } + else if (op != SpvOpStore && op != SpvOpLoad && op != SpvOpName) + return false; + } + supported_ref_ptrs_.insert(ptrId); + return true; +} + bool LocalSingleBlockLoadStoreElimPass::LocalSingleBlockLoadStoreElim( ir::Function* func) { // Perform local store/load and load/load elimination on each block @@ -234,6 +252,8 @@ bool LocalSingleBlockLoadStoreElimPass::LocalSingleBlockLoadStoreElim( ir::Instruction* ptrInst = GetPtr(&*ii, &varId); if (!IsTargetVar(varId)) continue; + if (!HasOnlySupportedRefs(varId)) + continue; // Register the store if (ptrInst->opcode() == SpvOpVariable) { // if not pinned, look for WAW @@ -258,6 +278,8 @@ bool LocalSingleBlockLoadStoreElimPass::LocalSingleBlockLoadStoreElim( ir::Instruction* ptrInst = GetPtr(&*ii, &varId); if (!IsTargetVar(varId)) continue; + if (!HasOnlySupportedRefs(varId)) + continue; // Look for previous store or load uint32_t replId = 0; if (ptrInst->opcode() == SpvOpVariable) { @@ -320,6 +342,9 @@ void LocalSingleBlockLoadStoreElimPass::Initialize(ir::Module* module) { seen_target_vars_.clear(); seen_non_target_vars_.clear(); + // Clear collections + supported_ref_ptrs_.clear(); + // TODO(): Reuse def/use from previous passes def_use_mgr_.reset(new analysis::DefUseManager(consumer(), module_)); diff --git a/source/opt/local_single_block_elim_pass.h b/source/opt/local_single_block_elim_pass.h index b5a14f4..2476f26 100644 --- a/source/opt/local_single_block_elim_pass.h +++ b/source/opt/local_single_block_elim_pass.h @@ -85,6 +85,10 @@ class LocalSingleBlockLoadStoreElimPass : public Pass { // labels. void DCEInst(ir::Instruction* inst); + // Return true if all uses of |varId| are only through supported reference + // operations ie. loads and store. Also cache in supported_ref_ptrs_; + bool HasOnlySupportedRefs(uint32_t varId); + // On all entry point functions, within each basic block, eliminate // loads and stores to function variables where possible. For // loads, if previous load or store to same variable, replace @@ -142,6 +146,10 @@ class LocalSingleBlockLoadStoreElimPass : public Pass { // from this set each time a new store of that variable is encountered. std::unordered_set pinned_vars_; + // Variables that are only referenced by supported operations for this + // pass ie. loads and stores. + std::unordered_set supported_ref_ptrs_; + // Next unused ID uint32_t next_id_; }; diff --git a/source/opt/local_ssa_elim_pass.h b/source/opt/local_ssa_elim_pass.h index 7cce51a..7459c76 100644 --- a/source/opt/local_ssa_elim_pass.h +++ b/source/opt/local_ssa_elim_pass.h @@ -184,8 +184,7 @@ class LocalMultiStoreElimPass : public Pass { // the runtime and effectiveness of this function. bool EliminateMultiStoreLocal(ir::Function* func); - // Return true if all uses of varId are only through supported reference - // operations ie. loads and store. Also cache in supported_ref_vars_; + // Return true if |op| is decorate. inline bool IsDecorate(uint32_t op) const { return (op == SpvOpDecorate || op == SpvOpDecorateId); } -- 2.7.4