Eliminate dead code.
Bug swiftshader:23
Change-Id: Ifb2862e8358141f67a7974d3fa0a11e6fe41b904
Reviewed-on: https://swiftshader-review.googlesource.com/8290
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 39de5f0..ffd29bb 100644
--- a/src/Reactor/Optimizer.cpp
+++ b/src/Reactor/Optimizer.cpp
@@ -29,13 +29,14 @@
private:
void analyzeUses(Ice::Cfg *function);
- void eliminateUnusedAllocas();
+ void eliminateDeadCode();
void eliminateUnitializedLoads();
void eliminateLoadsFollowingSingleStore();
void optimizeStoresInSingleBasicBlock();
void replace(Ice::Inst *instruction, Ice::Operand *newValue);
void deleteInstruction(Ice::Inst *instruction);
+ bool isDead(Ice::Inst *instruction);
static bool isLoad(const Ice::Inst &instruction);
static bool isStore(const Ice::Inst &instruction);
@@ -68,30 +69,37 @@
analyzeUses(function);
- eliminateUnusedAllocas();
+ eliminateDeadCode();
eliminateUnitializedLoads();
eliminateLoadsFollowingSingleStore();
optimizeStoresInSingleBasicBlock();
+ eliminateDeadCode();
}
- void Optimizer::eliminateUnusedAllocas()
+ void Optimizer::eliminateDeadCode()
{
- Ice::CfgNode *entryBlock = function->getEntryNode();
-
- for(Ice::Inst &alloca : entryBlock->getInsts())
+ bool modified;
+ do
{
- if(!llvm::isa<Ice::InstAlloca>(alloca))
+ modified = false;
+ for(Ice::CfgNode *basicBlock : function->getNodes())
{
- return; // Allocas are all at the top
- }
+ for(Ice::Inst &inst : Ice::reverse_range(basicBlock->getInsts()))
+ {
+ if(inst.isDeleted())
+ {
+ continue;
+ }
- Ice::Operand *address = alloca.getDest();
-
- if(uses[address].empty())
- {
- alloca.setDeleted();
+ if(isDead(&inst))
+ {
+ deleteInstruction(&inst);
+ modified = true;
+ }
+ }
}
}
+ while(modified);
}
void Optimizer::eliminateUnitializedLoads()
@@ -397,7 +405,7 @@
void Optimizer::deleteInstruction(Ice::Inst *instruction)
{
- if(instruction->isDeleted())
+ if(!instruction || instruction->isDeleted())
{
return;
}
@@ -429,6 +437,30 @@
}
}
+ bool Optimizer::isDead(Ice::Inst *instruction)
+ {
+ Ice::Variable *dest = instruction->getDest();
+
+ if(dest)
+ {
+ return uses[dest].empty() && !instruction->hasSideEffects();
+ }
+ else if(isStore(*instruction))
+ {
+ if(Ice::Variable *address = llvm::dyn_cast<Ice::Variable>(storeAddress(instruction)))
+ {
+ Ice::Inst *def = definition[address];
+
+ if(!def || llvm::isa<Ice::InstAlloca>(def))
+ {
+ return uses[address].size() == 1; // Dead if this store is the only use
+ }
+ }
+ }
+
+ return false;
+ }
+
bool Optimizer::isLoad(const Ice::Inst &instruction)
{
if(llvm::isa<Ice::InstLoad>(&instruction))