ADCE.cpp revision dce4a407a24b04eebc6a376f8e62b41aaa7b071f
178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch//===- DCE.cpp - Code to perform dead code elimination --------------------===//
278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch//
378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch//                     The LLVM Compiler Infrastructure
478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch//
578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch// This file is distributed under the University of Illinois Open Source
678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch// License. See LICENSE.TXT for details.
778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch//
878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch//===----------------------------------------------------------------------===//
978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch//
1078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch// This file implements the Aggressive Dead Code Elimination pass.  This pass
1178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch// optimistically assumes that all instructions are dead until proven otherwise,
1278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch// allowing it to eliminate dead computations that other DCE passes do not
1378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch// catch, particularly involving loop computations.
1478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch//
1578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch//===----------------------------------------------------------------------===//
1678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
1778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "llvm/Transforms/Scalar.h"
1878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "llvm/ADT/DepthFirstIterator.h"
1978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "llvm/ADT/SmallPtrSet.h"
2078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "llvm/ADT/SmallVector.h"
2178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "llvm/ADT/Statistic.h"
2278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "llvm/IR/BasicBlock.h"
2378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "llvm/IR/CFG.h"
2478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "llvm/IR/InstIterator.h"
2578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "llvm/IR/Instructions.h"
2678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "llvm/IR/IntrinsicInst.h"
2778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#include "llvm/Pass.h"
2878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochusing namespace llvm;
2978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
3078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch#define DEBUG_TYPE "adce"
3178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
3278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben MurdochSTATISTIC(NumRemoved, "Number of instructions removed");
3378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
3478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochnamespace {
3578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  struct ADCE : public FunctionPass {
3678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    static char ID; // Pass identification, replacement for typeid
3778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    ADCE() : FunctionPass(ID) {
3878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch      initializeADCEPass(*PassRegistry::getPassRegistry());
3978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    }
4078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
4178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    bool runOnFunction(Function& F) override;
4278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
4378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    void getAnalysisUsage(AnalysisUsage& AU) const override {
4478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch      AU.setPreservesCFG();
4578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    }
4678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
4778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  };
4878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch}
4978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
5078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochchar ADCE::ID = 0;
5178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben MurdochINITIALIZE_PASS(ADCE, "adce", "Aggressive Dead Code Elimination", false, false)
5278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
5378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdochbool ADCE::runOnFunction(Function& F) {
5478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  if (skipOptnoneFunction(F))
5578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    return false;
5678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
5778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  SmallPtrSet<Instruction*, 128> alive;
5878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  SmallVector<Instruction*, 128> worklist;
5978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
6078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  // Collect the set of "root" instructions that are known live.
6178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
6278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    if (isa<TerminatorInst>(I.getInstructionIterator()) ||
6378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch        isa<DbgInfoIntrinsic>(I.getInstructionIterator()) ||
6478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch        isa<LandingPadInst>(I.getInstructionIterator()) ||
6578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch        I->mayHaveSideEffects()) {
6678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch      alive.insert(I.getInstructionIterator());
6778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch      worklist.push_back(I.getInstructionIterator());
6878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    }
6978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
7078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  // Propagate liveness backwards to operands.
7178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  while (!worklist.empty()) {
7278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    Instruction* curr = worklist.pop_back_val();
7378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    for (Instruction::op_iterator OI = curr->op_begin(), OE = curr->op_end();
7478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch         OI != OE; ++OI)
7578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch      if (Instruction* Inst = dyn_cast<Instruction>(OI))
7678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch        if (alive.insert(Inst))
7778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch          worklist.push_back(Inst);
7878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  }
7978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
8078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  // The inverse of the live set is the dead set.  These are those instructions
8178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  // which have no side effects and do not influence the control flow or return
8278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  // value of the function, and may therefore be deleted safely.
8378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  // NOTE: We reuse the worklist vector here for memory efficiency.
8478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  for (inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I)
8578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    if (!alive.count(I.getInstructionIterator())) {
8678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch      worklist.push_back(I.getInstructionIterator());
8778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch      I->dropAllReferences();
8878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    }
8978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
9078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  for (SmallVectorImpl<Instruction *>::iterator I = worklist.begin(),
9178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch       E = worklist.end(); I != E; ++I) {
9278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    ++NumRemoved;
9378901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch    (*I)->eraseFromParent();
9478901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  }
9578901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
9678901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  return !worklist.empty();
9778901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch}
9878901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch
9978901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben MurdochFunctionPass *llvm::createAggressiveDCEPass() {
10078901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch  return new ADCE();
10178901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch}
10278901d17b47ef1f8d6d0a89eaf37f9523ba1de85Ben Murdoch