@@ -40,17 +40,18 @@ static bool isReallyValidReturnType(Type *Ty) {
40
40
}
41
41
42
42
// / Insert a ret inst after \p NewRetValue, which returns the value it produces.
43
- static void rewriteFuncWithReturnType (Function &OldF,
44
- Instruction *NewRetValue) {
43
+ static void rewriteFuncWithReturnType (Function &OldF, Value *NewRetValue) {
45
44
Type *NewRetTy = NewRetValue->getType ();
46
45
FunctionType *OldFuncTy = OldF.getFunctionType ();
47
46
48
47
FunctionType *NewFuncTy =
49
48
FunctionType::get (NewRetTy, OldFuncTy->params (), OldFuncTy->isVarArg ());
50
49
51
50
LLVMContext &Ctx = OldF.getContext ();
51
+ Instruction *NewRetI = cast<Instruction>(NewRetValue);
52
+ BasicBlock *NewRetBlock = NewRetI->getParent ();
52
53
53
- BasicBlock *NewRetBlock = NewRetValue-> getParent ();
54
+ BasicBlock::iterator NewValIt = NewRetI-> getIterator ();
54
55
55
56
// Hack up any return values in other blocks, we can't leave them as ret void.
56
57
if (OldFuncTy->getReturnType ()->isVoidTy ()) {
@@ -75,8 +76,8 @@ static void rewriteFuncWithReturnType(Function &OldF,
75
76
Succ->removePredecessor (NewRetBlock, /* KeepOneInputPHIs=*/ true );
76
77
77
78
// Now delete the tail of this block, in reverse to delete uses before defs.
78
- for (Instruction &I : make_early_inc_range (make_range (
79
- NewRetBlock->rbegin (), NewRetValue-> getIterator () .getReverse ()))) {
79
+ for (Instruction &I : make_early_inc_range (
80
+ make_range ( NewRetBlock->rbegin (), NewValIt .getReverse ()))) {
80
81
81
82
Value *Replacement = getDefaultValue (I.getType ());
82
83
I.replaceAllUsesWith (Replacement);
@@ -193,12 +194,19 @@ static bool canHandleSuccessors(const BasicBlock &BB) {
193
194
return true ;
194
195
}
195
196
196
- static bool tryForwardingValuesToReturn (
197
- Function &F, Oracle &O,
198
- std::vector<std::pair<Function *, Instruction *>> &FuncsToReplace) {
197
+ static bool shouldForwardValueToReturn (const BasicBlock &BB, const Value *V,
198
+ Type *RetTy) {
199
+ if (!isReallyValidReturnType (V->getType ()))
200
+ return false ;
201
+
202
+ return (RetTy->isVoidTy () ||
203
+ (RetTy == V->getType () && shouldReplaceNonVoidReturnValue (BB, V))) &&
204
+ canReplaceFuncUsers (*BB.getParent (), V->getType ());
205
+ }
199
206
200
- // TODO: Should this try to forward arguments to the return value before
201
- // instructions?
207
+ static bool tryForwardingInstructionsToReturn (
208
+ Function &F, Oracle &O,
209
+ std::vector<std::pair<Function *, Value *>> &FuncsToReplace) {
202
210
203
211
// TODO: Should we try to expand returns to aggregate for function that
204
212
// already have a return value?
@@ -209,12 +217,7 @@ static bool tryForwardingValuesToReturn(
209
217
continue ;
210
218
211
219
for (Instruction &I : BB) {
212
- if (!isReallyValidReturnType (I.getType ()))
213
- continue ;
214
-
215
- if ((RetTy->isVoidTy () ||
216
- (RetTy == I.getType () && shouldReplaceNonVoidReturnValue (BB, &I))) &&
217
- canReplaceFuncUsers (F, I.getType ()) && !O.shouldKeep ()) {
220
+ if (shouldForwardValueToReturn (BB, &I, RetTy) && !O.shouldKeep ()) {
218
221
FuncsToReplace.emplace_back (&F, &I);
219
222
return true ;
220
223
}
@@ -224,18 +227,19 @@ static bool tryForwardingValuesToReturn(
224
227
return false ;
225
228
}
226
229
227
- void llvm::reduceValuesToReturnDeltaPass (Oracle &O, ReducerWorkItem &WorkItem) {
230
+ void llvm::reduceInstructionsToReturnDeltaPass (Oracle &O,
231
+ ReducerWorkItem &WorkItem) {
228
232
Module &Program = WorkItem.getModule ();
229
233
230
234
// We're going to chaotically hack on the other users of the function in other
231
235
// functions, so we need to collect a worklist of returns to replace.
232
- std::vector<std::pair<Function *, Instruction *>> FuncsToReplace;
236
+ std::vector<std::pair<Function *, Value *>> FuncsToReplace;
233
237
234
238
for (Function &F : Program.functions ()) {
235
239
if (!F.isDeclaration () && canUseNonVoidReturnType (F))
236
- tryForwardingValuesToReturn (F, O, FuncsToReplace);
240
+ tryForwardingInstructionsToReturn (F, O, FuncsToReplace);
237
241
}
238
242
239
- for (auto [F, I ] : FuncsToReplace)
240
- rewriteFuncWithReturnType (*F, I );
243
+ for (auto [F, NewRetVal ] : FuncsToReplace)
244
+ rewriteFuncWithReturnType (*F, NewRetVal );
241
245
}
0 commit comments