llvm.org GIT mirror llvm / 906e423
Learn IPConstProp to look at individual return values and propagate them individually. Also learn IPConstProp how returning first class aggregates work, in addition to old style multiple return instructions. Modify the return-constants testscase to confirm this behaviour. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@52396 91177308-0d34-0410-b5e6-96231b3b80d8 Matthijs Kooijman 11 years ago
2 changed file(s) with 110 addition(s) and 66 deletion(s). Raw diff Collapse all Expand all
2020 #include "llvm/Instructions.h"
2121 #include "llvm/Module.h"
2222 #include "llvm/Pass.h"
23 #include "llvm/Analysis/ValueTracking.h"
2324 #include "llvm/Support/CallSite.h"
2425 #include "llvm/Support/Compiler.h"
2526 #include "llvm/ADT/Statistic.h"
139140 }
140141
141142
142 // Check to see if this function returns a constant. If so, replace all callers
143 // that user the return value with the returned valued. If we can replace ALL
144 // callers,
143 // Check to see if this function returns one or more constants. If so, replace
144 // all callers that use those return values with the constant value. This will
145 // leave in the actual return values and instructions, but deadargelim will
146 // clean that up.
145147 bool IPCP::PropagateConstantReturn(Function &F) {
146148 if (F.getReturnType() == Type::VoidTy)
147149 return false; // No return value.
155157 SmallVector RetVals;
156158 const StructType *STy = dyn_cast(F.getReturnType());
157159 if (STy)
158 RetVals.assign(STy->getNumElements(), 0);
160 for (unsigned i = 0, e = STy->getNumElements(); i < e; ++i)
161 RetVals.push_back(UndefValue::get(STy->getElementType(i)));
159162 else
160 RetVals.push_back(0);
161
163 RetVals.push_back(UndefValue::get(F.getReturnType()));
164
165 unsigned NumNonConstant = 0;
162166 for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
163167 if (ReturnInst *RI = dyn_cast(BB->getTerminator())) {
164 assert(RetVals.size() == RI->getNumOperands() &&
165 "Invalid ReturnInst operands!");
168 // Return type does not match operand type, this is an old style multiple
169 // return
170 bool OldReturn = (F.getReturnType() != RI->getOperand(0)->getType());
171
166172 for (unsigned i = 0, e = RetVals.size(); i != e; ++i) {
167 if (isa(RI->getOperand(i)))
168 continue; // Ignore
169 Constant *C = dyn_cast(RI->getOperand(i));
170 if (C == 0)
171 return false; // Does not return a constant.
172
173 // Already found conflicting return values?
173174 Value *RV = RetVals[i];
174 if (RV == 0)
175 RetVals[i] = C;
176 else if (RV != C)
177 return false; // Does not return the same constant.
178 }
179 }
180
181 if (STy) {
182 for (unsigned i = 0, e = RetVals.size(); i < e; ++i)
183 if (RetVals[i] == 0)
184 RetVals[i] = UndefValue::get(STy->getElementType(i));
185 } else {
186 assert(RetVals.size() == 1);
187 if (RetVals[0] == 0)
188 RetVals[0] = UndefValue::get(F.getReturnType());
189 }
190
191 // If we got here, the function returns a constant value. Loop over all
192 // users, replacing any uses of the return value with the returned constant.
193 bool ReplacedAllUsers = true;
175 if (!RV)
176 continue;
177
178 // Find the returned value
179 Value *V;
180 if (!STy || OldReturn)
181 V = RI->getOperand(i);
182 else
183 V = FindInsertedValue(RI->getOperand(0), i);
184
185 if (V) {
186 // Ignore undefs, we can change them into anything
187 if (isa(V))
188 continue;
189
190 // Try to see if all the rets return the same constant.
191 if (isa(V)) {
192 if (isa(RV)) {
193 // No value found yet? Try the current one.
194 RetVals[i] = V;
195 continue;
196 }
197 // Returning the same value? Good.
198 if (RV == V)
199 continue;
200 }
201 }
202 // Different or no known return value? Don't propagate this return
203 // value.
204 RetVals[i] = 0;
205 // All values non constant? Stop looking.
206 if (++NumNonConstant == RetVals.size())
207 return false;
208 }
209 }
210
211 // If we got here, the function returns at least one constant value. Loop
212 // over all users, replacing any uses of the return value with the returned
213 // constant.
194214 bool MadeChange = false;
195215 for (Value::use_iterator UI = F.use_begin(), E = F.use_end(); UI != E; ++UI) {
196216 // Make sure this is an invoke or call and that the use is for the callee.
197217 if (!(isa(*UI) || isa(*UI)) ||
198218 UI.getOperandNo() != 0) {
199 ReplacedAllUsers = false;
200219 continue;
201220 }
202221
211230 continue;
212231 }
213232
214 while (!Call->use_empty()) {
215 GetResultInst *GR = cast(Call->use_back());
216 GR->replaceAllUsesWith(RetVals[GR->getIndex()]);
217 GR->eraseFromParent();
218 }
219 }
220
221 // If we replace all users with the returned constant, and there can be no
222 // other callers of the function, replace the constant being returned in the
223 // function with an undef value.
224 if (ReplacedAllUsers && F.hasInternalLinkage()) {
225 for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB) {
226 if (ReturnInst *RI = dyn_cast(BB->getTerminator())) {
227 for (unsigned i = 0, e = RetVals.size(); i < e; ++i) {
228 Value *RetVal = RetVals[i];
229 if (isa(RetVal))
230 continue;
231 Value *RV = UndefValue::get(RetVal->getType());
232 if (RI->getOperand(i) != RV) {
233 RI->setOperand(i, RV);
234 MadeChange = true;
235 }
233 for (Value::use_iterator I = Call->use_begin(), E = Call->use_end();
234 I != E;) {
235 Instruction *Ins = dyn_cast(*I);
236
237 // Increment now, so we can remove the use
238 ++I;
239
240 // Not an instruction? Ignore
241 if (!Ins)
242 continue;
243
244 // Find the index of the retval to replace with
245 int index = -1;
246 if (GetResultInst *GR = dyn_cast(Ins))
247 index = GR->getIndex();
248 else if (ExtractValueInst *EV = dyn_cast(Ins))
249 if (EV->hasIndices())
250 index = *EV->idx_begin();
251
252 // If this use uses a specific return value, and we have a replacement,
253 // replace it.
254 if (index != -1) {
255 Value *New = RetVals[index];
256 if (New) {
257 Ins->replaceAllUsesWith(New);
258 Ins->eraseFromParent();
236259 }
237260 }
238261 }
None ; RUN: llvm-as < %s | opt -ipconstprop | llvm-dis | grep {add i32 21, 21}
0 ; RUN: llvm-as < %s | opt -ipconstprop | llvm-dis > %t
1 ;; Check that the 21 constants got propagated properly
2 ; RUN: cat %t | grep {%M = add i32 21, 21}
3 ;; Check that the second return values didn't get propagated
4 ; RUN: cat %t | grep {%N = add i32 %B, %D}
15
2 define internal {i32, i32} @foo(i1 %C) {
3 br i1 %C, label %T, label %F
6 define internal {i32, i32} @foo(i1 %Q) {
7 br i1 %Q, label %T, label %F
48
59 T: ; preds = %0
6 ret i32 21, i32 21
10 ret i32 21, i32 22
711
812 F: ; preds = %0
9 ret i32 21, i32 21
13 ret i32 21, i32 23
1014 }
1115
12 define i32 @caller(i1 %C) {
13 %X = call {i32, i32} @foo( i1 %C )
16 define internal {i32, i32} @bar(i1 %Q) {
17 %A = insertvalue { i32, i32 } undef, i32 21, 0
18 br i1 %Q, label %T, label %F
19
20 T: ; preds = %0
21 %B = insertvalue { i32, i32 } %A, i32 22, 1
22 ret { i32, i32 } %B
23
24 F: ; preds = %0
25 %C = insertvalue { i32, i32 } %A, i32 23, 1
26 ret { i32, i32 } %C
27 }
28
29 define { i32, i32 } @caller(i1 %Q) {
30 %X = call {i32, i32} @foo( i1 %Q )
1431 %A = getresult {i32, i32} %X, 0
1532 %B = getresult {i32, i32} %X, 1
16 %Y = add i32 %A, %B
17 ret i32 %Y
33 %Y = call {i32, i32} @bar( i1 %Q )
34 %C = extractvalue {i32, i32} %Y, 0
35 %D = extractvalue {i32, i32} %Y, 1
36 %M = add i32 %A, %C
37 %N = add i32 %B, %D
38 ret { i32, i32 } %X
1839 }
1940