LLVM API Documentation

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 is distributed under the University of Illinois Open Source
00006 // 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 run a DIE pass sometime after running this pass.
00018 //
00019 //===----------------------------------------------------------------------===//
00020 
00021 #define DEBUG_TYPE "constprop"
00022 #include "llvm/Transforms/Scalar.h"
00023 #include "llvm/Analysis/ConstantFolding.h"
00024 #include "llvm/Constant.h"
00025 #include "llvm/Instruction.h"
00026 #include "llvm/Pass.h"
00027 #include "llvm/Support/Compiler.h"
00028 #include "llvm/Support/InstIterator.h"
00029 #include "llvm/ADT/Statistic.h"
00030 #include <set>
00031 using namespace llvm;
00032 
00033 STATISTIC(NumInstKilled, "Number of instructions killed");
00034 
00035 namespace {
00036   struct VISIBILITY_HIDDEN ConstantPropagation : public FunctionPass {
00037     static char ID; // Pass identification, replacement for typeid
00038     ConstantPropagation() : FunctionPass(&ID) {}
00039 
00040     bool runOnFunction(Function &F);
00041 
00042     virtual void getAnalysisUsage(AnalysisUsage &AU) const {
00043       AU.setPreservesCFG();
00044     }
00045   };
00046 }
00047 
00048 char ConstantPropagation::ID = 0;
00049 static RegisterPass<ConstantPropagation>
00050 X("constprop", "Simple constant propagation");
00051 
00052 FunctionPass *llvm::createConstantPropagationPass() {
00053   return new ConstantPropagation();
00054 }
00055 
00056 
00057 bool ConstantPropagation::runOnFunction(Function &F) {
00058   // Initialize the worklist to all of the instructions ready to process...
00059   std::set<Instruction*> WorkList;
00060   for(inst_iterator i = inst_begin(F), e = inst_end(F); i != e; ++i) {
00061       WorkList.insert(&*i);
00062   }
00063   bool Changed = false;
00064 
00065   while (!WorkList.empty()) {
00066     Instruction *I = *WorkList.begin();
00067     WorkList.erase(WorkList.begin());    // Get an element from the worklist...
00068 
00069     if (!I->use_empty())                 // Don't muck with dead instructions...
00070       if (Constant *C = ConstantFoldInstruction(I)) {
00071         // Add all of the users of this instruction to the worklist, they might
00072         // be constant propagatable now...
00073         for (Value::use_iterator UI = I->use_begin(), UE = I->use_end();
00074              UI != UE; ++UI)
00075           WorkList.insert(cast<Instruction>(*UI));
00076 
00077         // Replace all of the uses of a variable with uses of the constant.
00078         I->replaceAllUsesWith(C);
00079 
00080         // Remove the dead instruction.
00081         WorkList.erase(I);
00082         I->eraseFromParent();
00083 
00084         // We made a change to the function...
00085         Changed = true;
00086         ++NumInstKilled;
00087       }
00088   }
00089   return Changed;
00090 }