aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/IPO/IPConstantPropagation.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Transforms/IPO/IPConstantPropagation.cpp')
-rw-r--r--lib/Transforms/IPO/IPConstantPropagation.cpp75
1 files changed, 38 insertions, 37 deletions
diff --git a/lib/Transforms/IPO/IPConstantPropagation.cpp b/lib/Transforms/IPO/IPConstantPropagation.cpp
index af541d155254..916135e33cd5 100644
--- a/lib/Transforms/IPO/IPConstantPropagation.cpp
+++ b/lib/Transforms/IPO/IPConstantPropagation.cpp
@@ -41,44 +41,14 @@ namespace {
}
bool runOnModule(Module &M) override;
- private:
- bool PropagateConstantsIntoArguments(Function &F);
- bool PropagateConstantReturn(Function &F);
};
}
-char IPCP::ID = 0;
-INITIALIZE_PASS(IPCP, "ipconstprop",
- "Interprocedural constant propagation", false, false)
-
-ModulePass *llvm::createIPConstantPropagationPass() { return new IPCP(); }
-
-bool IPCP::runOnModule(Module &M) {
- bool Changed = false;
- bool LocalChange = true;
-
- // FIXME: instead of using smart algorithms, we just iterate until we stop
- // making changes.
- while (LocalChange) {
- LocalChange = false;
- for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
- if (!I->isDeclaration()) {
- // Delete any klingons.
- I->removeDeadConstantUsers();
- if (I->hasLocalLinkage())
- LocalChange |= PropagateConstantsIntoArguments(*I);
- Changed |= PropagateConstantReturn(*I);
- }
- Changed |= LocalChange;
- }
- return Changed;
-}
-
/// PropagateConstantsIntoArguments - Look at all uses of the specified
/// function. If all uses are direct call sites, and all pass a particular
/// constant in for an argument, propagate that constant in as the argument.
///
-bool IPCP::PropagateConstantsIntoArguments(Function &F) {
+static bool PropagateConstantsIntoArguments(Function &F) {
if (F.arg_empty() || F.use_empty()) return false; // No arguments? Early exit.
// For each argument, keep track of its constant value and whether it is a
@@ -157,13 +127,14 @@ bool IPCP::PropagateConstantsIntoArguments(Function &F) {
// Additionally if a function always returns one of its arguments directly,
// callers will be updated to use the value they pass in directly instead of
// using the return value.
-bool IPCP::PropagateConstantReturn(Function &F) {
+static bool PropagateConstantReturn(Function &F) {
if (F.getReturnType()->isVoidTy())
return false; // No return value.
- // If this function could be overridden later in the link stage, we can't
- // propagate information about its results into callers.
- if (F.mayBeOverridden())
+ // We can infer and propagate the return value only when we know that the
+ // definition we'll get at link time is *exactly* the definition we see now.
+ // For more details, see GlobalValue::mayBeDerefined.
+ if (!F.isDefinitionExact())
return false;
// Check to see if this function returns a constant.
@@ -176,8 +147,8 @@ bool IPCP::PropagateConstantReturn(Function &F) {
RetVals.push_back(UndefValue::get(F.getReturnType()));
unsigned NumNonConstant = 0;
- for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
- if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) {
+ for (BasicBlock &BB : F)
+ if (ReturnInst *RI = dyn_cast<ReturnInst>(BB.getTerminator())) {
for (unsigned i = 0, e = RetVals.size(); i != e; ++i) {
// Already found conflicting return values?
Value *RV = RetVals[i];
@@ -277,3 +248,33 @@ bool IPCP::PropagateConstantReturn(Function &F) {
if (MadeChange) ++NumReturnValProped;
return MadeChange;
}
+
+char IPCP::ID = 0;
+INITIALIZE_PASS(IPCP, "ipconstprop",
+ "Interprocedural constant propagation", false, false)
+
+ModulePass *llvm::createIPConstantPropagationPass() { return new IPCP(); }
+
+bool IPCP::runOnModule(Module &M) {
+ if (skipModule(M))
+ return false;
+
+ bool Changed = false;
+ bool LocalChange = true;
+
+ // FIXME: instead of using smart algorithms, we just iterate until we stop
+ // making changes.
+ while (LocalChange) {
+ LocalChange = false;
+ for (Function &F : M)
+ if (!F.isDeclaration()) {
+ // Delete any klingons.
+ F.removeDeadConstantUsers();
+ if (F.hasLocalLinkage())
+ LocalChange |= PropagateConstantsIntoArguments(F);
+ Changed |= PropagateConstantReturn(F);
+ }
+ Changed |= LocalChange;
+ }
+ return Changed;
+}