[PATCH] D24523: [ObjCARC] Traverse chain downwards to replace uses of argument passed to ObjC library call with call return
Akira Hatanaka via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 13 16:51:56 PDT 2016
This revision was automatically updated to reflect the committed changes.
Closed by commit rL281419: [ObjCARC] Traverse chain downwards to replace uses of argument passed to (authored by ahatanak).
Changed prior to commit:
https://reviews.llvm.org/D24523?vs=71239&id=71269#toc
Repository:
rL LLVM
https://reviews.llvm.org/D24523
Files:
llvm/trunk/lib/Transforms/ObjCARC/ObjCARCContract.cpp
llvm/trunk/test/Transforms/ObjCARC/contract-replace-arg-use.ll
Index: llvm/trunk/test/Transforms/ObjCARC/contract-replace-arg-use.ll
===================================================================
--- llvm/trunk/test/Transforms/ObjCARC/contract-replace-arg-use.ll
+++ llvm/trunk/test/Transforms/ObjCARC/contract-replace-arg-use.ll
@@ -0,0 +1,18 @@
+; RUN: opt -objc-arc-contract -S < %s | FileCheck %s
+
+declare i8* @objc_autoreleaseReturnValue(i8*)
+declare i8* @foo1()
+
+; Check that ARC contraction replaces the function return with the value
+; returned by @objc_autoreleaseReturnValue.
+
+; CHECK: %[[V0:[0-9]+]] = tail call i8* @objc_autoreleaseReturnValue(
+; CHECK: %[[V1:[0-9]+]] = bitcast i8* %[[V0]] to i32*
+; CHECK: ret i32* %[[V1]]
+
+define i32* @autoreleaseRVTailCall() {
+ %1 = call i8* @foo1()
+ %2 = bitcast i8* %1 to i32*
+ %3 = tail call i8* @objc_autoreleaseReturnValue(i8* %1)
+ ret i32* %2
+}
Index: llvm/trunk/lib/Transforms/ObjCARC/ObjCARCContract.cpp
===================================================================
--- llvm/trunk/lib/Transforms/ObjCARC/ObjCARCContract.cpp
+++ llvm/trunk/lib/Transforms/ObjCARC/ObjCARCContract.cpp
@@ -547,13 +547,13 @@
// Don't use GetArgRCIdentityRoot because we don't want to look through bitcasts
// and such; to do the replacement, the argument must have type i8*.
- Value *Arg = cast<CallInst>(Inst)->getArgOperand(0);
- // TODO: Change this to a do-while.
- for (;;) {
+ // Function for replacing uses of Arg dominated by Inst.
+ auto ReplaceArgUses = [Inst, this](Value *Arg) {
// If we're compiling bugpointed code, don't get in trouble.
if (!isa<Instruction>(Arg) && !isa<Argument>(Arg))
- break;
+ return;
+
// Look through the uses of the pointer.
for (Value::use_iterator UI = Arg->use_begin(), UE = Arg->use_end();
UI != UE; ) {
@@ -598,6 +598,14 @@
}
}
}
+ };
+
+
+ Value *Arg = cast<CallInst>(Inst)->getArgOperand(0), *OrigArg = Arg;
+
+ // TODO: Change this to a do-while.
+ for (;;) {
+ ReplaceArgUses(Arg);
// If Arg is a no-op casted pointer, strip one level of casts and iterate.
if (const BitCastInst *BI = dyn_cast<BitCastInst>(Arg))
@@ -611,6 +619,24 @@
else
break;
}
+
+ // Replace bitcast users of Arg that are dominated by Inst.
+ SmallVector<BitCastInst *, 2> BitCastUsers;
+
+ // Add all bitcast users of the function argument first.
+ for (User *U : OrigArg->users())
+ if (auto *BC = dyn_cast<BitCastInst>(U))
+ BitCastUsers.push_back(BC);
+
+ // Replace the bitcasts with the call return. Iterate until list is empty.
+ while (!BitCastUsers.empty()) {
+ auto *BC = BitCastUsers.pop_back_val();
+ for (User *U : BC->users())
+ if (auto *B = dyn_cast<BitCastInst>(U))
+ BitCastUsers.push_back(B);
+
+ ReplaceArgUses(BC);
+ }
}
// If this function has no escaping allocas or suspicious vararg usage,
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D24523.71269.patch
Type: text/x-patch
Size: 2976 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160913/3e29b3e8/attachment.bin>
More information about the llvm-commits
mailing list