diff options
author | Owen Anderson <resistor@mac.com> | 2010-08-31 07:41:39 +0000 |
---|---|---|
committer | Owen Anderson <resistor@mac.com> | 2010-08-31 07:41:39 +0000 |
commit | 7aff1cd0389d922d752b57b9ccf942b457977955 (patch) | |
tree | 68aa4bcdfe025e1ec689ccda024e66f2c212154e /lib/Transforms/Scalar/CorrelatedValuePropagation.cpp | |
parent | cb21190cbd8ae1aece5b833ebe3814ada4260627 (diff) |
Rename file to something more descriptive.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112590 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Scalar/CorrelatedValuePropagation.cpp')
-rw-r--r-- | lib/Transforms/Scalar/CorrelatedValuePropagation.cpp | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp b/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp new file mode 100644 index 0000000000..8f398883a2 --- /dev/null +++ b/lib/Transforms/Scalar/CorrelatedValuePropagation.cpp @@ -0,0 +1,119 @@ +//===- ValuePropagation.cpp - Propagate information derived control flow --===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file implements the Value Propagation pass. +// +//===----------------------------------------------------------------------===// + +#define DEBUG_TYPE "value-propagation" +#include "llvm/Transforms/Scalar.h" +#include "llvm/Function.h" +#include "llvm/Instructions.h" +#include "llvm/Pass.h" +#include "llvm/Analysis/LazyValueInfo.h" +#include "llvm/Transforms/Utils/Local.h" +#include "llvm/ADT/Statistic.h" +using namespace llvm; + +STATISTIC(NumPhis, "Number of phis propagated"); +STATISTIC(NumSelects, "Number of selects propagated"); + +namespace { + class ValuePropagation : public FunctionPass { + LazyValueInfo *LVI; + + bool processSelect(SelectInst *SI); + bool processPHI(PHINode *P); + + public: + static char ID; + ValuePropagation(): FunctionPass(ID) { } + + bool runOnFunction(Function &F); + + virtual void getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired<LazyValueInfo>(); + } + }; +} + +char ValuePropagation::ID = 0; +INITIALIZE_PASS(ValuePropagation, "value-propagation", + "Value Propagation", false, false); + +// Public interface to the Value Propagation pass +Pass *llvm::createValuePropagationPass() { + return new ValuePropagation(); +} + +bool ValuePropagation::processSelect(SelectInst *S) { + if (S->getType()->isVectorTy()) return false; + + Constant *C = LVI->getConstant(S->getOperand(0), S->getParent()); + if (!C) return false; + + ConstantInt *CI = dyn_cast<ConstantInt>(C); + if (!CI) return false; + + S->replaceAllUsesWith(S->getOperand(CI->isOne() ? 1 : 2)); + S->eraseFromParent(); + + ++NumSelects; + + return true; +} + +bool ValuePropagation::processPHI(PHINode *P) { + bool Changed = false; + + BasicBlock *BB = P->getParent(); + for (unsigned i = 0, e = P->getNumIncomingValues(); i < e; ++i) { + Value *Incoming = P->getIncomingValue(i); + if (isa<Constant>(Incoming)) continue; + + Constant *C = LVI->getConstantOnEdge(P->getIncomingValue(i), + P->getIncomingBlock(i), + BB); + if (!C) continue; + + P->setIncomingValue(i, C); + Changed = true; + } + + if (Value *ConstVal = P->hasConstantValue()) { + P->replaceAllUsesWith(ConstVal); + P->eraseFromParent(); + Changed = true; + } + + ++NumPhis; + + return Changed; +} + +bool ValuePropagation::runOnFunction(Function &F) { + LVI = &getAnalysis<LazyValueInfo>(); + + bool Changed = false; + + for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) + for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ) { + Instruction *II = BI++; + if (SelectInst *SI = dyn_cast<SelectInst>(II)) + Changed |= processSelect(SI); + else if (PHINode *P = dyn_cast<PHINode>(II)) + Changed |= processPHI(P); + } + + if (Changed) + for (Function::iterator FI = F.begin(), FE = F.end(); FI != FE; ++FI) + SimplifyInstructionsInBlock(FI); + + return Changed; +} |