X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FTransforms%2FScalar%2FDCE.cpp;h=e8a090af40c316f1d3d09b53d00b926f67b633aa;hb=d93e8a06b2ca09ab18f390cd514b7443e2e571f7;hp=ec9a387c18fa92ce05215025de9b3c4f1ba3f2f4;hpb=2ed01d8f0bdb8aa73d893a8beb23b1838422fa32;p=oota-llvm.git diff --git a/lib/Transforms/Scalar/DCE.cpp b/lib/Transforms/Scalar/DCE.cpp index ec9a387c18f..e8a090af40c 100644 --- a/lib/Transforms/Scalar/DCE.cpp +++ b/lib/Transforms/Scalar/DCE.cpp @@ -1,5 +1,12 @@ //===- DCE.cpp - Code to perform dead code elimination --------------------===// // +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// // This file implements dead inst elimination and dead code elimination. // // Dead Inst Elimination performs a single pass over the function removing @@ -9,108 +16,119 @@ // //===----------------------------------------------------------------------===// -#include "llvm/Transforms/Scalar/DCE.h" -#include "llvm/Transforms/Utils/Local.h" -#include "llvm/Instruction.h" +#define DEBUG_TYPE "dce" +#include "llvm/Transforms/Scalar.h" +#include "llvm/ADT/Statistic.h" +#include "llvm/IR/Instruction.h" #include "llvm/Pass.h" #include "llvm/Support/InstIterator.h" -#include +#include "llvm/Target/TargetLibraryInfo.h" +#include "llvm/Transforms/Utils/Local.h" +using namespace llvm; -//===----------------------------------------------------------------------===// -// DeadInstElimination pass implementation -// +STATISTIC(DIEEliminated, "Number of insts removed by DIE pass"); +STATISTIC(DCEEliminated, "Number of insts removed"); namespace { + //===--------------------------------------------------------------------===// + // DeadInstElimination pass implementation + // struct DeadInstElimination : public BasicBlockPass { - const char *getPassName() const { return "Dead Instruction Elimination"; } - - virtual bool runOnBasicBlock(BasicBlock *BB) { - BasicBlock::InstListType &Vals = BB->getInstList(); + static char ID; // Pass identification, replacement for typeid + DeadInstElimination() : BasicBlockPass(ID) { + initializeDeadInstEliminationPass(*PassRegistry::getPassRegistry()); + } + virtual bool runOnBasicBlock(BasicBlock &BB) { + TargetLibraryInfo *TLI = getAnalysisIfAvailable(); bool Changed = false; - for (BasicBlock::iterator DI = Vals.begin(); DI != Vals.end(); ) - if (dceInstruction(Vals, DI)) + for (BasicBlock::iterator DI = BB.begin(); DI != BB.end(); ) { + Instruction *Inst = DI++; + if (isInstructionTriviallyDead(Inst, TLI)) { + Inst->eraseFromParent(); Changed = true; - else - ++DI; + ++DIEEliminated; + } + } return Changed; } virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.preservesCFG(); + AU.setPreservesCFG(); } }; } -Pass *createDeadInstEliminationPass() { +char DeadInstElimination::ID = 0; +INITIALIZE_PASS(DeadInstElimination, "die", + "Dead Instruction Elimination", false, false) + +Pass *llvm::createDeadInstEliminationPass() { return new DeadInstElimination(); } - -//===----------------------------------------------------------------------===// -// DeadCodeElimination pass implementation -// - namespace { + //===--------------------------------------------------------------------===// + // DeadCodeElimination pass implementation + // struct DCE : public FunctionPass { - const char *getPassName() const { return "Dead Code Elimination"; } + static char ID; // Pass identification, replacement for typeid + DCE() : FunctionPass(ID) { + initializeDCEPass(*PassRegistry::getPassRegistry()); + } - virtual bool runOnFunction(Function *F); + virtual bool runOnFunction(Function &F); virtual void getAnalysisUsage(AnalysisUsage &AU) const { - AU.preservesCFG(); + AU.setPreservesCFG(); } }; } -bool DCE::runOnFunction(Function *F) { +char DCE::ID = 0; +INITIALIZE_PASS(DCE, "dce", "Dead Code Elimination", false, false) + +bool DCE::runOnFunction(Function &F) { + TargetLibraryInfo *TLI = getAnalysisIfAvailable(); + // Start out with all of the instructions in the worklist... - std::vector WorkList(inst_begin(F), inst_end(F)); - std::set DeadInsts; - + std::vector WorkList; + for (inst_iterator i = inst_begin(F), e = inst_end(F); i != e; ++i) + WorkList.push_back(&*i); + // Loop over the worklist finding instructions that are dead. If they are // dead make them drop all of their uses, making other instructions // potentially dead, and work until the worklist is empty. // + bool MadeChange = false; while (!WorkList.empty()) { Instruction *I = WorkList.back(); WorkList.pop_back(); - - if (isInstructionTriviallyDead(I)) { // If the instruction is dead... + + if (isInstructionTriviallyDead(I, TLI)) { // If the instruction is dead. // Loop over all of the values that the instruction uses, if there are // instructions being used, add them to the worklist, because they might // go dead after this one is removed. // - for (User::use_iterator UI = I->use_begin(), UE = I->use_end(); - UI != UE; ++UI) - if (Instruction *Used = dyn_cast(*UI)) + for (User::op_iterator OI = I->op_begin(), E = I->op_end(); OI != E; ++OI) + if (Instruction *Used = dyn_cast(*OI)) WorkList.push_back(Used); - // Tell the instruction to let go of all of the values it uses... - I->dropAllReferences(); + // Remove the instruction. + I->eraseFromParent(); - // Keep track of this instruction, because we are going to delete it later - DeadInsts.insert(I); - } - } + // Remove the instruction from the worklist if it still exists in it. + WorkList.erase(std::remove(WorkList.begin(), WorkList.end(), I), + WorkList.end()); - // If we found no dead instructions, we haven't changed the function... - if (DeadInsts.empty()) return false; - - // Otherwise, loop over the program, removing and deleting the instructions... - for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) { - BasicBlock::InstListType &BBIL = (*I)->getInstList(); - for (BasicBlock::iterator BI = BBIL.begin(); BI != BBIL.end(); ) - if (DeadInsts.count(*BI)) { // Is this instruction dead? - delete BBIL.remove(BI); // Yup, remove and delete inst - } else { // This instruction is not dead - ++BI; // Continue on to the next one... - } + MadeChange = true; + ++DCEEliminated; + } } - - return true; + return MadeChange; } -Pass *createDeadCodeEliminationPass() { +FunctionPass *llvm::createDeadCodeEliminationPass() { return new DCE(); } +