[llvm-commits] [llvm] r38517 - in /llvm/trunk: include/llvm/LinkAllPasses.h include/llvm/Transforms/Scalar.h lib/Transforms/Scalar/FastDSE.cpp
Chris Lattner
clattner at apple.com
Tue Jul 10 22:05:00 PDT 2007
> Add FastDSE, a new algorithm for doing dead store elimination.
> This algorithm is not as accurate
> as the current DSE, but it only a linear scan over each block,
> rather than quadratic. Eventually
> (once it has been improved somewhat), this will replace the current
> DSE.
Woot.
> +//===- DeadStoreElimination.cpp - Dead Store Elimination
> ------------------===//
> +//
> +// The LLVM Compiler Infrastructure
> +//
> +// This file was developed by the LLVM research group and is
> distributed under
s/LLVM research group/the amazing and unpredictable owen/
> +FunctionPass *llvm::createFastDeadStoreEliminationPass() { return
> new FDSE(); }
> +
> +bool FDSE::runOnBasicBlock(BasicBlock &BB) {
> + MemoryDependenceAnalysis& MD =
> getAnalysis<MemoryDependenceAnalysis>();
> +
> + DenseMap<Value*, StoreInst*> lastStore;
> + SetVector<Instruction*> possiblyDead;
Please add comments describing what these are and what they contain
at any point in time.
> + bool MadeChange = false;
> +
> + // Do a top-down walk on the BB
> + for (BasicBlock::iterator BBI = BB.begin(), BBE = BB.end(); BBI !
> = BBE; ++BBI) {
> + // If we find a store...
> + if (StoreInst* S = dyn_cast<StoreInst>(BBI)) {
Since you only look at stores, I suggest structuring this loop like
this to reduce nesting (which makes it easier to read the code):
> + for (BasicBlock::iterator BBI = BB.begin(), BBE = BB.end(); BBI !
> = BBE; ++BBI) {
> + // If we find a store...
> + StoreInst* S = dyn_cast<StoreInst>(BBI);
> + if (!S) continue;
...
> +
> + // ... to a pointer that has been stored to before...
> + if (lastStore.count(S->getPointerOperand())) {
> + StoreInst* last = lastStore[S->getPointerOperand()];
This does two hashtable lookups, and the insert below does another.
I'd suggest just doing:
StoreInst *&last = lastStore[S->getPointerOperand()];
if (last) {
...
}
last = S;
> + // ... and no other memory dependencies are between them....
> + if (MD.getDependency(S) == last) {
> + // Remove it!
> + MD.removeInstruction(last);
> +
> + // DCE instructions only used to calculate that store
> + if (Instruction* D = dyn_cast<Instruction>(last-
> >getOperand(0)))
> + possiblyDead.insert(D);
> +
> + last->eraseFromParent();
> + NumFastStores++;
> + MadeChange = true;
> + }
> + }
Nice and simple!
> + // Update our most-recent-store map
> + lastStore.insert(std::make_pair(S->getPointerOperand(), S));
> + }
> + }
> +
> + // Do a trivial DCE
> + while (!possiblyDead.empty()) {
> + Instruction *I = possiblyDead.back();
> + possiblyDead.pop_back();
> + DeleteDeadInstructionChains(I, possiblyDead);
> + }
> +
> + return MadeChange;
> +}
> +
> +void FDSE::DeleteDeadInstructionChains(Instruction *I,
> + SetVector<Instruction*>
> &DeadInsts) {
> + // Instruction must be dead.
> + if (!I->use_empty() || !isInstructionTriviallyDead(I)) return;
> +
> + // Let the memory dependence know
> + getAnalysis<MemoryDependenceAnalysis>().removeInstruction(I);
> +
> + // See if this made any operands dead. We do it this way in
> case the
> + // instruction uses the same operand twice. We don't want to
> delete a
> + // value then reference it.
> + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
> + if (Instruction *Op = dyn_cast<Instruction>(I->getOperand(i)))
> + DeadInsts.insert(Op); // Attempt to nuke it later.
> + I->setOperand(i, 0); // Drop from the operand list.
With this design, there is no reason to call setOperand. You
probably want something like this:
> + for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) {
> + if (I->getOperand(i)->hasOneUse())
> + if (Instruction *Op = dyn_cast<Instruction>(I->getOperand(i)))
> + DeadInsts.insert(Op); // Attempt to nuke it later.
> + I->setOperand(i, 0); // Drop from the operand list.
Otherwise, nice work! How fast is this on the slow bugzilla case
compared to slow dse?
-Chris
> + }
> +
> + I->eraseFromParent();
> + ++NumFastOther;
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list