Revert "Revert "Opt: LocalBlockElim: Add HasOnlySupportedRefs""
authorLei Zhang <antiagainst@google.com>
Mon, 24 Jul 2017 14:37:38 +0000 (10:37 -0400)
committerLei Zhang <antiagainst@google.com>
Wed, 26 Jul 2017 03:22:09 +0000 (23:22 -0400)
This reverts commit df96e243c633b939690a42d89904e04f50126e86.

source/opt/aggressive_dead_code_elim_pass.cpp
source/opt/local_single_block_elim_pass.cpp
source/opt/local_single_block_elim_pass.h
source/opt/local_ssa_elim_pass.h

index da36d38..fe9c9f2 100644 (file)
@@ -233,7 +233,6 @@ bool AggressiveDCEPass::AggressiveDCE(ir::Function* func) {
 }
 
 void AggressiveDCEPass::Initialize(ir::Module* module) {
-
   module_ = module;
 
   // Initialize id-to-function map
index 8ef7d12..772289d 100644 (file)
@@ -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(greg-lunarg): Reuse def/use from previous passes
   def_use_mgr_.reset(new analysis::DefUseManager(consumer(), module_));
 
index 1406520..77c3dd8 100644 (file)
@@ -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
@@ -151,6 +155,10 @@ class LocalSingleBlockLoadStoreElimPass : public Pass {
   // Extensions supported by this pass.
   std::unordered_set<std::string> extensions_whitelist_;
 
+  // Variables that are only referenced by supported operations for this
+  // pass ie. loads and stores.
+  std::unordered_set<uint32_t> supported_ref_ptrs_;
+
   // Next unused ID
   uint32_t next_id_;
 };
index 71010fc..3beaeea 100644 (file)
@@ -185,8 +185,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);
   }