Home | History | Annotate | Download | only in Scalar
      1 //===- DCE.cpp - Code to perform dead code elimination --------------------===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file implements the Aggressive Dead Code Elimination pass.  This pass
     11 // optimistically assumes that all instructions are dead until proven otherwise,
     12 // allowing it to eliminate dead computations that other DCE passes do not
     13 // catch, particularly involving loop computations.
     14 //
     15 //===----------------------------------------------------------------------===//
     16 
     17 #include "llvm/Transforms/Scalar.h"
     18 #include "llvm/ADT/DepthFirstIterator.h"
     19 #include "llvm/ADT/SmallPtrSet.h"
     20 #include "llvm/ADT/SmallVector.h"
     21 #include "llvm/ADT/Statistic.h"
     22 #include "llvm/IR/BasicBlock.h"
     23 #include "llvm/IR/CFG.h"
     24 #include "llvm/IR/InstIterator.h"
     25 #include "llvm/IR/Instructions.h"
     26 #include "llvm/IR/IntrinsicInst.h"
     27 #include "llvm/Pass.h"
     28 using namespace llvm;
     29 
     30 #define DEBUG_TYPE "adce"
     31 
     32 STATISTIC(NumRemoved, "Number of instructions removed");
     33 
     34 namespace {
     35   struct ADCE : public FunctionPass {
     36     static char ID; // Pass identification, replacement for typeid
     37     ADCE() : FunctionPass(ID) {
     38       initializeADCEPass(*PassRegistry::getPassRegistry());
     39     }
     40 
     41     bool runOnFunction(Function& F) override;
     42 
     43     void getAnalysisUsage(AnalysisUsage& AU) const override {
     44       AU.setPreservesCFG();
     45     }
     46 
     47   };
     48 }
     49 
     50 char ADCE::ID = 0;
     51 INITIALIZE_PASS(ADCE, "adce", "Aggressive Dead Code Elimination", false, false)
     52 
     53 bool ADCE::runOnFunction(Function& F) {
     54   if (skipOptnoneFunction(F))
     55     return false;
     56 
     57   SmallPtrSet<Instruction*, 128> alive;
     58   SmallVector<Instruction*, 128> worklist;
     59 
     60   // Collect the set of "root" instructions that are known live.
     61   for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
     62     if (isa<TerminatorInst>(I.getInstructionIterator()) ||
     63         isa<DbgInfoIntrinsic>(I.getInstructionIterator()) ||
     64         isa<LandingPadInst>(I.getInstructionIterator()) ||
     65         I->mayHaveSideEffects()) {
     66       alive.insert(I.getInstructionIterator());
     67       worklist.push_back(I.getInstructionIterator());
     68     }
     69 
     70   // Propagate liveness backwards to operands.
     71   while (!worklist.empty()) {
     72     Instruction* curr = worklist.pop_back_val();
     73     for (Instruction::op_iterator OI = curr->op_begin(), OE = curr->op_end();
     74          OI != OE; ++OI)
     75       if (Instruction* Inst = dyn_cast<Instruction>(OI))
     76         if (alive.insert(Inst))
     77           worklist.push_back(Inst);
     78   }
     79 
     80   // The inverse of the live set is the dead set.  These are those instructions
     81   // which have no side effects and do not influence the control flow or return
     82   // value of the function, and may therefore be deleted safely.
     83   // NOTE: We reuse the worklist vector here for memory efficiency.
     84   for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
     85     if (!alive.count(I.getInstructionIterator())) {
     86       worklist.push_back(I.getInstructionIterator());
     87       I->dropAllReferences();
     88     }
     89 
     90   for (SmallVectorImpl<Instruction *>::iterator I = worklist.begin(),
     91        E = worklist.end(); I != E; ++I) {
     92     ++NumRemoved;
     93     (*I)->eraseFromParent();
     94   }
     95 
     96   return !worklist.empty();
     97 }
     98 
     99 FunctionPass *llvm::createAggressiveDCEPass() {
    100   return new ADCE();
    101 }
    102