LLVM API Documentation

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

ConstantProp.cpp

Go to the documentation of this file.
00001 //===- ConstantProp.cpp - Code to perform Simple Constant Propagation -----===//
00002 // 
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file was developed by the LLVM research group and is distributed under
00006 // the University of Illinois Open Source License. See LICENSE.TXT for details.
00007 // 
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file implements constant propagation and merging:
00011 //
00012 // Specifically, this:
00013 //   * Converts instructions like "add int 1, 2" into 3
00014 //
00015 // Notice that:
00016 //   * This pass has a habit of making definitions be dead.  It is a good idea
00017 //     to to run a DIE pass sometime after running this pass.
00018 //
00019 //===----------------------------------------------------------------------===//
00020 
00021 #include "llvm/Transforms/Scalar.h"
00022 #include "llvm/Transforms/Utils/Local.h"
00023 #include "llvm/Constant.h"
00024 #include "llvm/Instruction.h"
00025 #include "llvm/Pass.h"
00026 #include "llvm/Support/InstIterator.h"
00027 #include "llvm/ADT/Statistic.h"
00028 #include <set>
00029 using namespace llvm;
00030 
00031 namespace {
00032   Statistic<> NumInstKilled("constprop", "Number of instructions killed");
00033 
00034   struct ConstantPropagation : public FunctionPass {
00035     bool runOnFunction(Function &F);
00036 
00037     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
00038       AU.setPreservesCFG();
00039     }
00040   };
00041 
00042   RegisterOpt<ConstantPropagation> X("constprop","Simple constant propagation");
00043 }
00044 
00045 FunctionPass *llvm::createConstantPropagationPass() {
00046   return new ConstantPropagation();
00047 }
00048 
00049 
00050 bool ConstantPropagation::runOnFunction(Function &F) {
00051   // Initialize the worklist to all of the instructions ready to process...
00052   std::set<Instruction*> WorkList;
00053   for(inst_iterator i = inst_begin(F), e = inst_end(F); i != e; ++i) {
00054       WorkList.insert(&*i);
00055   }
00056   bool Changed = false;
00057 
00058   while (!WorkList.empty()) {
00059     Instruction *I = *WorkList.begin();
00060     WorkList.erase(WorkList.begin());    // Get an element from the worklist...
00061 
00062     if (!I->use_empty())                 // Don't muck with dead instructions...
00063       if (Constant *C = ConstantFoldInstruction(I)) {
00064         // Add all of the users of this instruction to the worklist, they might
00065         // be constant propagatable now...
00066         for (Value::use_iterator UI = I->use_begin(), UE = I->use_end();
00067              UI != UE; ++UI)
00068           WorkList.insert(cast<Instruction>(*UI));
00069         
00070         // Replace all of the uses of a variable with uses of the constant.
00071         I->replaceAllUsesWith(C);
00072 
00073         // Remove the dead instruction.
00074         WorkList.erase(I);
00075         I->getParent()->getInstList().erase(I);
00076 
00077         // We made a change to the function...
00078         Changed = true;
00079         ++NumInstKilled;
00080       }
00081   }
00082   return Changed;
00083 }