mirror of
https://github.com/KhronosGroup/SPIRV-Tools
synced 2024-11-26 21:30:07 +00:00
Opt: LocalBlockElim: Add HasOnlySupportedRefs
Verifies that targeted variables have only access chain and direct loads and stores as references.
This commit is contained in:
parent
adb237f3bd
commit
2d0f7fbc11
@ -231,7 +231,6 @@ bool AggressiveDCEPass::AggressiveDCE(ir::Function* func) {
|
||||
}
|
||||
|
||||
void AggressiveDCEPass::Initialize(ir::Module* module) {
|
||||
|
||||
module_ = module;
|
||||
|
||||
// Initialize id-to-function map
|
||||
|
@ -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_));
|
||||
|
||||
|
@ -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<uint32_t> pinned_vars_;
|
||||
|
||||
// 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_;
|
||||
};
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user