Remove constants from constant manager in KillInst
authorArseny Kapoulkine <arseny.kapoulkine@gmail.com>
Thu, 15 Feb 2018 20:27:38 +0000 (12:27 -0800)
committerSteven Perron <stevenperron@google.com>
Sat, 17 Feb 2018 01:37:12 +0000 (20:37 -0500)
Registering a constant in constant manager establishes a relation
between instruction that defined it and constant object. On complex
shaders this could result in the constant definition getting removed as
part of one of the DCE pass, and a subsequent simplification pass trying
to use the defining instruction for the constant.

To fix this, we now remove associated constant entries from constant
manager when killing constant instructions; the constant object is still
registered and can be remapped to a new instruction later.

GetDefiningInstruction shouldn't ever return nullptr after this change
so add an assertion to check for that.

source/opt/constants.cpp
source/opt/constants.h
source/opt/ir_context.cpp

index 336e061..d5b873f 100644 (file)
@@ -72,7 +72,9 @@ ir::Instruction* ConstantManager::GetDefiningInstruction(
     if (pos == nullptr) pos = &iter;
     return BuildInstructionAndAddToModule(c, pos);
   } else {
-    return context()->get_def_use_mgr()->GetDef(decl_id);
+    auto def = context()->get_def_use_mgr()->GetDef(decl_id);
+    assert(def != nullptr);
+    return def;
   }
 }
 
index e382e16..6ac9bef 100644 (file)
@@ -518,6 +518,14 @@ class ConstantManager {
     return false;
   }
 
+  void RemoveId(uint32_t id) {
+    auto it = id_to_const_val_.find(id);
+    if (it != id_to_const_val_.end()) {
+      const_val_to_id_.erase(it->second);
+      id_to_const_val_.erase(it);
+    }
+  }
+
   // Records a new mapping between |inst| and |const_value|. This updates the
   // two mappings |id_to_const_val_| and |const_val_to_id_|.
   void MapConstantToInst(const Constant* const_value, ir::Instruction* inst) {
index 895c8a9..8e11ecd 100644 (file)
@@ -106,6 +106,10 @@ Instruction* IRContext::KillInst(ir::Instruction* inst) {
     type_mgr_->RemoveId(inst->result_id());
   }
 
+  if (constant_mgr_ && ir::IsConstantInst(inst->opcode())) {
+    constant_mgr_->RemoveId(inst->result_id());
+  }
+
   RemoveFromIdToName(inst);
 
   Instruction* next_instruction = nullptr;