|  | //===- ConstantProp.cpp - Code to perform Simple Constant Propagation -----===// | 
|  | // | 
|  | //                     The LLVM Compiler Infrastructure | 
|  | // | 
|  | // This file is distributed under the University of Illinois Open Source | 
|  | // License. See LICENSE.TXT for details. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | // | 
|  | // This file implements constant propagation and merging: | 
|  | // | 
|  | // Specifically, this: | 
|  | //   * Converts instructions like "add int 1, 2" into 3 | 
|  | // | 
|  | // Notice that: | 
|  | //   * This pass has a habit of making definitions be dead.  It is a good idea | 
|  | //     to run a DIE pass sometime after running this pass. | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #include "llvm/ADT/Statistic.h" | 
|  | #include "llvm/Analysis/ConstantFolding.h" | 
|  | #include "llvm/Analysis/TargetLibraryInfo.h" | 
|  | #include "llvm/Analysis/Utils/Local.h" | 
|  | #include "llvm/IR/Constant.h" | 
|  | #include "llvm/IR/InstIterator.h" | 
|  | #include "llvm/IR/Instruction.h" | 
|  | #include "llvm/Pass.h" | 
|  | #include "llvm/Transforms/Scalar.h" | 
|  | #include <set> | 
|  | using namespace llvm; | 
|  |  | 
|  | #define DEBUG_TYPE "constprop" | 
|  |  | 
|  | STATISTIC(NumInstKilled, "Number of instructions killed"); | 
|  |  | 
|  | namespace { | 
|  | struct ConstantPropagation : public FunctionPass { | 
|  | static char ID; // Pass identification, replacement for typeid | 
|  | ConstantPropagation() : FunctionPass(ID) { | 
|  | initializeConstantPropagationPass(*PassRegistry::getPassRegistry()); | 
|  | } | 
|  |  | 
|  | bool runOnFunction(Function &F) override; | 
|  |  | 
|  | void getAnalysisUsage(AnalysisUsage &AU) const override { | 
|  | AU.setPreservesCFG(); | 
|  | AU.addRequired<TargetLibraryInfoWrapperPass>(); | 
|  | } | 
|  | }; | 
|  | } | 
|  |  | 
|  | char ConstantPropagation::ID = 0; | 
|  | INITIALIZE_PASS_BEGIN(ConstantPropagation, "constprop", | 
|  | "Simple constant propagation", false, false) | 
|  | INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass) | 
|  | INITIALIZE_PASS_END(ConstantPropagation, "constprop", | 
|  | "Simple constant propagation", false, false) | 
|  |  | 
|  | FunctionPass *llvm::createConstantPropagationPass() { | 
|  | return new ConstantPropagation(); | 
|  | } | 
|  |  | 
|  | bool ConstantPropagation::runOnFunction(Function &F) { | 
|  | if (skipFunction(F)) | 
|  | return false; | 
|  |  | 
|  | // Initialize the worklist to all of the instructions ready to process... | 
|  | std::set<Instruction*> WorkList; | 
|  | for (Instruction &I: instructions(&F)) | 
|  | WorkList.insert(&I); | 
|  |  | 
|  | bool Changed = false; | 
|  | const DataLayout &DL = F.getParent()->getDataLayout(); | 
|  | TargetLibraryInfo *TLI = | 
|  | &getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(); | 
|  |  | 
|  | while (!WorkList.empty()) { | 
|  | Instruction *I = *WorkList.begin(); | 
|  | WorkList.erase(WorkList.begin());    // Get an element from the worklist... | 
|  |  | 
|  | if (!I->use_empty())                 // Don't muck with dead instructions... | 
|  | if (Constant *C = ConstantFoldInstruction(I, DL, TLI)) { | 
|  | // Add all of the users of this instruction to the worklist, they might | 
|  | // be constant propagatable now... | 
|  | for (User *U : I->users()) | 
|  | WorkList.insert(cast<Instruction>(U)); | 
|  |  | 
|  | // Replace all of the uses of a variable with uses of the constant. | 
|  | I->replaceAllUsesWith(C); | 
|  |  | 
|  | // Remove the dead instruction. | 
|  | WorkList.erase(I); | 
|  | if (isInstructionTriviallyDead(I, TLI)) { | 
|  | I->eraseFromParent(); | 
|  | ++NumInstKilled; | 
|  | } | 
|  |  | 
|  | // We made a change to the function... | 
|  | Changed = true; | 
|  | } | 
|  | } | 
|  | return Changed; | 
|  | } |