Optimize stores in a single basic block.
Bug swiftshader:27
Change-Id: Ia5f7da431902c3e87aab47b1dd388e05ced74cd3
Reviewed-on: https://swiftshader-review.googlesource.com/8274
Tested-by: Nicolas Capens <capn@google.com>
Reviewed-by: Alexis Hétu <sugoi@google.com>
Reviewed-by: Nicolas Capens <capn@google.com>
diff --git a/src/Reactor/Optimizer.cpp b/src/Reactor/Optimizer.cpp
index a3b328e..39de5f0 100644
--- a/src/Reactor/Optimizer.cpp
+++ b/src/Reactor/Optimizer.cpp
@@ -32,6 +32,7 @@
void eliminateUnusedAllocas();
void eliminateUnitializedLoads();
void eliminateLoadsFollowingSingleStore();
+ void optimizeStoresInSingleBasicBlock();
void replace(Ice::Inst *instruction, Ice::Operand *newValue);
void deleteInstruction(Ice::Inst *instruction);
@@ -70,6 +71,7 @@
eliminateUnusedAllocas();
eliminateUnitializedLoads();
eliminateLoadsFollowingSingleStore();
+ optimizeStoresInSingleBasicBlock();
}
void Optimizer::eliminateUnusedAllocas()
@@ -243,6 +245,88 @@
}
}
+ void Optimizer::optimizeStoresInSingleBasicBlock()
+ {
+ Ice::CfgNode *entryBlock = function->getEntryNode();
+
+ for(Ice::Inst &alloca : entryBlock->getInsts())
+ {
+ if(alloca.isDeleted())
+ {
+ continue;
+ }
+
+ if(!llvm::isa<Ice::InstAlloca>(alloca))
+ {
+ return; // Allocas are all at the top
+ }
+
+ Ice::Operand *address = alloca.getDest();
+ const auto &addressEntry = uses.find(address);
+ const auto &addressUses = addressEntry->second;
+
+ if(!addressUses.areOnlyLoadStore())
+ {
+ continue;
+ }
+
+ Ice::CfgNode *singleBasicBlock = node[addressUses.stores[0]];
+
+ for(int i = 1; i < addressUses.stores.size(); i++)
+ {
+ Ice::Inst *store = addressUses.stores[i];
+ if(node[store] != singleBasicBlock)
+ {
+ singleBasicBlock = nullptr;
+ break;
+ }
+ }
+
+ if(singleBasicBlock)
+ {
+ auto &insts = singleBasicBlock->getInsts();
+ Ice::Inst *store = nullptr;
+ Ice::Operand *storeValue = nullptr;
+
+ for(Ice::Inst &inst : insts)
+ {
+ if(inst.isDeleted())
+ {
+ continue;
+ }
+
+ if(isStore(inst))
+ {
+ if(storeAddress(&inst) != address)
+ {
+ continue;
+ }
+
+ // New store found. If we had a previous one, eliminate it.
+ if(store)
+ {
+ deleteInstruction(store);
+ }
+
+ store = &inst;
+ storeValue = storeData(store);
+ }
+ else if(isLoad(inst))
+ {
+ Ice::Inst *load = &inst;
+
+ if(loadAddress(load) != address)
+ {
+ continue;
+ }
+
+ replace(load, storeValue);
+ }
+ }
+ }
+ }
+ }
+
void Optimizer::analyzeUses(Ice::Cfg *function)
{
uses.clear();