[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