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.
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;
}
}
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) {
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;