blob: 65d507798b77d6614270cdcc99e9da8712605384 [file] [log] [blame]
Chris Lattnerd358e6f2003-10-23 16:52:27 +00001//===-- IPConstantPropagation.cpp - Propagate constants through calls -----===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file was developed by the LLVM research group and is distributed under
6// the University of Illinois Open Source License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This pass implements an _extremely_ simple interprocedural constant
11// propagation pass. It could certainly be improved in many different ways,
12// like using a worklist. This pass makes arguments dead, but does not remove
13// them. The existing dead argument elimination pass should be run after this
14// to clean up the mess.
15//
16//===----------------------------------------------------------------------===//
17
18#include "llvm/Transforms/IPO.h"
Chris Lattnera990d942004-11-14 06:10:11 +000019#include "llvm/Constants.h"
20#include "llvm/Instructions.h"
Chris Lattnerd358e6f2003-10-23 16:52:27 +000021#include "llvm/Module.h"
22#include "llvm/Pass.h"
Chris Lattnerd358e6f2003-10-23 16:52:27 +000023#include "llvm/Support/CallSite.h"
Reid Spencer551ccae2004-09-01 22:55:40 +000024#include "llvm/ADT/Statistic.h"
Chris Lattner1e2385b2003-11-21 21:54:22 +000025using namespace llvm;
Brian Gaeked0fde302003-11-11 22:41:34 +000026
Chris Lattnerd358e6f2003-10-23 16:52:27 +000027namespace {
28 Statistic<> NumArgumentsProped("ipconstprop",
29 "Number of args turned into constants");
Chris Lattnera990d942004-11-14 06:10:11 +000030 Statistic<> NumReturnValProped("ipconstprop",
31 "Number of return values turned into constants");
Chris Lattnerd358e6f2003-10-23 16:52:27 +000032
33 /// IPCP - The interprocedural constant propagation pass
34 ///
Chris Lattnerb12914b2004-09-20 04:48:05 +000035 struct IPCP : public ModulePass {
36 bool runOnModule(Module &M);
Chris Lattnerd358e6f2003-10-23 16:52:27 +000037 private:
Chris Lattnera990d942004-11-14 06:10:11 +000038 bool PropagateConstantsIntoArguments(Function &F);
39 bool PropagateConstantReturn(Function &F);
Chris Lattnerd358e6f2003-10-23 16:52:27 +000040 };
41 RegisterOpt<IPCP> X("ipconstprop", "Interprocedural constant propagation");
42}
43
Chris Lattnerb12914b2004-09-20 04:48:05 +000044ModulePass *llvm::createIPConstantPropagationPass() { return new IPCP(); }
Chris Lattnerd358e6f2003-10-23 16:52:27 +000045
Chris Lattnerb12914b2004-09-20 04:48:05 +000046bool IPCP::runOnModule(Module &M) {
Chris Lattnerd358e6f2003-10-23 16:52:27 +000047 bool Changed = false;
Chris Lattner2e8dfb82003-10-27 21:09:00 +000048 bool LocalChange = true;
49
50 // FIXME: instead of using smart algorithms, we just iterate until we stop
51 // making changes.
52 while (LocalChange) {
53 LocalChange = false;
54 for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
Chris Lattnera990d942004-11-14 06:10:11 +000055 if (!I->isExternal()) {
56 // Delete any klingons.
57 I->removeDeadConstantUsers();
58 if (I->hasInternalLinkage())
59 LocalChange |= PropagateConstantsIntoArguments(*I);
60 Changed |= PropagateConstantReturn(*I);
61 }
Chris Lattner2e8dfb82003-10-27 21:09:00 +000062 Changed |= LocalChange;
63 }
Chris Lattnerd358e6f2003-10-23 16:52:27 +000064 return Changed;
65}
66
Chris Lattnera990d942004-11-14 06:10:11 +000067/// PropagateConstantsIntoArguments - Look at all uses of the specified
68/// function. If all uses are direct call sites, and all pass a particular
69/// constant in for an argument, propagate that constant in as the argument.
Chris Lattnerd358e6f2003-10-23 16:52:27 +000070///
Chris Lattnera990d942004-11-14 06:10:11 +000071bool IPCP::PropagateConstantsIntoArguments(Function &F) {
Chris Lattnerd358e6f2003-10-23 16:52:27 +000072 if (F.aempty() || F.use_empty()) return false; // No arguments? Early exit.
73
74 std::vector<std::pair<Constant*, bool> > ArgumentConstants;
75 ArgumentConstants.resize(F.asize());
76
77 unsigned NumNonconstant = 0;
78
79 for (Value::use_iterator I = F.use_begin(), E = F.use_end(); I != E; ++I)
80 if (!isa<Instruction>(*I))
81 return false; // Used by a non-instruction, do not transform
82 else {
83 CallSite CS = CallSite::get(cast<Instruction>(*I));
84 if (CS.getInstruction() == 0 ||
85 CS.getCalledFunction() != &F)
86 return false; // Not a direct call site?
87
88 // Check out all of the potentially constant arguments
89 CallSite::arg_iterator AI = CS.arg_begin();
Chris Lattnerff1529b2004-11-10 19:43:59 +000090 Function::aiterator Arg = F.abegin();
91 for (unsigned i = 0, e = ArgumentConstants.size(); i != e;
92 ++i, ++AI, ++Arg) {
Chris Lattnerd358e6f2003-10-23 16:52:27 +000093 if (*AI == &F) return false; // Passes the function into itself
94
95 if (!ArgumentConstants[i].second) {
Reid Spencer3188cab2004-07-18 08:31:18 +000096 if (Constant *C = dyn_cast<Constant>(*AI)) {
Chris Lattnerd358e6f2003-10-23 16:52:27 +000097 if (!ArgumentConstants[i].first)
98 ArgumentConstants[i].first = C;
99 else if (ArgumentConstants[i].first != C) {
100 // Became non-constant
101 ArgumentConstants[i].second = true;
102 ++NumNonconstant;
103 if (NumNonconstant == ArgumentConstants.size()) return false;
104 }
Chris Lattnerff1529b2004-11-10 19:43:59 +0000105 } else if (*AI != &*Arg) { // Ignore recursive calls with same arg
Chris Lattnerd358e6f2003-10-23 16:52:27 +0000106 // This is not a constant argument. Mark the argument as
107 // non-constant.
108 ArgumentConstants[i].second = true;
109 ++NumNonconstant;
110 if (NumNonconstant == ArgumentConstants.size()) return false;
111 }
112 }
113 }
114 }
115
116 // If we got to this point, there is a constant argument!
117 assert(NumNonconstant != ArgumentConstants.size());
118 Function::aiterator AI = F.abegin();
Chris Lattner2e8dfb82003-10-27 21:09:00 +0000119 bool MadeChange = false;
Chris Lattnerd358e6f2003-10-23 16:52:27 +0000120 for (unsigned i = 0, e = ArgumentConstants.size(); i != e; ++i, ++AI)
121 // Do we have a constant argument!?
Chris Lattnerd79c7b42004-11-11 07:47:54 +0000122 if (!ArgumentConstants[i].second && !AI->use_empty()) {
Chris Lattner2e56dd82003-10-23 18:49:23 +0000123 Value *V = ArgumentConstants[i].first;
Chris Lattner3e062ea2004-11-11 07:46:29 +0000124 if (V == 0) V = UndefValue::get(AI->getType());
Chris Lattner2e56dd82003-10-23 18:49:23 +0000125 AI->replaceAllUsesWith(V);
Chris Lattnerd358e6f2003-10-23 16:52:27 +0000126 ++NumArgumentsProped;
Chris Lattner2e8dfb82003-10-27 21:09:00 +0000127 MadeChange = true;
Chris Lattnerd358e6f2003-10-23 16:52:27 +0000128 }
Chris Lattner2e8dfb82003-10-27 21:09:00 +0000129 return MadeChange;
Chris Lattnerd358e6f2003-10-23 16:52:27 +0000130}
Brian Gaeked0fde302003-11-11 22:41:34 +0000131
Chris Lattnera990d942004-11-14 06:10:11 +0000132
133// Check to see if this function returns a constant. If so, replace all callers
134// that user the return value with the returned valued. If we can replace ALL
135// callers,
136bool IPCP::PropagateConstantReturn(Function &F) {
137 if (F.getReturnType() == Type::VoidTy)
138 return false; // No return value.
139
140 // Check to see if this function returns a constant.
141 Value *RetVal = 0;
142 for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
143 if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator()))
144 if (isa<UndefValue>(RI->getOperand(0))) {
145 // Ignore.
146 } else if (Constant *C = dyn_cast<Constant>(RI->getOperand(0))) {
147 if (RetVal == 0)
148 RetVal = C;
149 else if (RetVal != C)
150 return false; // Does not return the same constant.
151 } else {
152 return false; // Does not return a constant.
153 }
154
155 if (RetVal == 0) RetVal = UndefValue::get(F.getReturnType());
156
157 // If we got here, the function returns a constant value. Loop over all
158 // users, replacing any uses of the return value with the returned constant.
159 bool ReplacedAllUsers = true;
160 bool MadeChange = false;
161 for (Value::use_iterator I = F.use_begin(), E = F.use_end(); I != E; ++I)
162 if (!isa<Instruction>(*I))
163 ReplacedAllUsers = false;
164 else {
165 CallSite CS = CallSite::get(cast<Instruction>(*I));
166 if (CS.getInstruction() == 0 ||
167 CS.getCalledFunction() != &F) {
168 ReplacedAllUsers = false;
169 } else {
170 if (!CS.getInstruction()->use_empty()) {
171 CS.getInstruction()->replaceAllUsesWith(RetVal);
172 MadeChange = true;
173 }
174 }
175 }
176
177 // If we replace all users with the returned constant, and there can be no
178 // other callers of the function, replace the constant being returned in the
179 // function with an undef value.
180 if (ReplacedAllUsers && F.hasInternalLinkage() && !isa<UndefValue>(RetVal)) {
181 Value *RV = UndefValue::get(RetVal->getType());
182 for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
Chris Lattner2ffa47b2004-12-11 17:00:14 +0000183 if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) {
184 if (RI->getOperand(0) != RV) {
185 RI->setOperand(0, RV);
186 MadeChange = true;
187 }
188 }
Chris Lattnera990d942004-11-14 06:10:11 +0000189 }
190
191 if (MadeChange) ++NumReturnValProped;
Chris Lattnera990d942004-11-14 06:10:11 +0000192 return MadeChange;
193}