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 #include "llvm/Transforms/Scalar.h"
00022 #include "llvm/ADT/Statistic.h"
00023 #include "llvm/Analysis/ConstantFolding.h"
00024 #include "llvm/IR/Constant.h"
00025 #include "llvm/IR/DataLayout.h"
00026 #include "llvm/IR/InstIterator.h"
00027 #include "llvm/IR/Instruction.h"
00028 #include "llvm/Pass.h"
00029 #include "llvm/Target/TargetLibraryInfo.h"
00030 #include <set>
00031 using namespace llvm;
00032 
00033 #define DEBUG_TYPE "constprop"
00034 
00035 STATISTIC(NumInstKilled, "Number of instructions killed");
00036 
00037 namespace {
00038   struct ConstantPropagation : public FunctionPass {
00039     static char ID; // Pass identification, replacement for typeid
00040     ConstantPropagation() : FunctionPass(ID) {
00041       initializeConstantPropagationPass(*PassRegistry::getPassRegistry());
00042     }
00043 
00044     bool runOnFunction(Function &F) override;
00045 
00046     void getAnalysisUsage(AnalysisUsage &AU) const override {
00047       AU.setPreservesCFG();
00048       AU.addRequired<TargetLibraryInfo>();
00049     }
00050   };
00051 }
00052 
00053 char ConstantPropagation::ID = 0;
00054 INITIALIZE_PASS_BEGIN(ConstantPropagation, "constprop",
00055                 "Simple constant propagation", false, false)
00056 INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfo)
00057 INITIALIZE_PASS_END(ConstantPropagation, "constprop",
00058                 "Simple constant propagation", false, false)
00059 
00060 FunctionPass *llvm::createConstantPropagationPass() {
00061   return new ConstantPropagation();
00062 }
00063 
00064 bool ConstantPropagation::runOnFunction(Function &F) {
00065   // Initialize the worklist to all of the instructions ready to process...
00066   std::set<Instruction*> WorkList;
00067   for(inst_iterator i = inst_begin(F), e = inst_end(F); i != e; ++i) {
00068       WorkList.insert(&*i);
00069   }
00070   bool Changed = false;
00071   DataLayoutPass *DLP = getAnalysisIfAvailable<DataLayoutPass>();
00072   const DataLayout *DL = DLP ? &DLP->getDataLayout() : nullptr;
00073   TargetLibraryInfo *TLI = &getAnalysis<TargetLibraryInfo>();
00074 
00075   while (!WorkList.empty()) {
00076     Instruction *I = *WorkList.begin();
00077     WorkList.erase(WorkList.begin());    // Get an element from the worklist...
00078 
00079     if (!I->use_empty())                 // Don't muck with dead instructions...
00080       if (Constant *C = ConstantFoldInstruction(I, DL, TLI)) {
00081         // Add all of the users of this instruction to the worklist, they might
00082         // be constant propagatable now...
00083         for (User *U : I->users())
00084           WorkList.insert(cast<Instruction>(U));
00085 
00086         // Replace all of the uses of a variable with uses of the constant.
00087         I->replaceAllUsesWith(C);
00088 
00089         // Remove the dead instruction.
00090         WorkList.erase(I);
00091         I->eraseFromParent();
00092 
00093         // We made a change to the function...
00094         Changed = true;
00095         ++NumInstKilled;
00096       }
00097   }
00098   return Changed;
00099 }