[Attributor] Manifest constant return values
authorJohannes Doerfert <jdoerfert@anl.gov>
Fri, 23 Aug 2019 17:41:37 +0000 (17:41 +0000)
committerJohannes Doerfert <jdoerfert@anl.gov>
Fri, 23 Aug 2019 17:41:37 +0000 (17:41 +0000)
Summary:
If the unique return value is a constant we now replace call uses with
that constant.

Reviewers: sstefan1, uenoku

Subscribers: hiraditya, bollu, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D66551

llvm-svn: 369785

llvm/lib/Transforms/IPO/Attributor.cpp
llvm/test/Transforms/FunctionAttrs/nounwind.ll

index 9367f482cc98e6c36593286b4d44be132c4efa1b..f75fc2c3ee6fda61f896625ab03097883d2c83a8 100644 (file)
@@ -807,10 +807,34 @@ ChangeStatus AAReturnedValuesImpl::manifest(Attributor &A) {
   STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
                   "Number of function with unique return");
 
+  // Callback to replace the uses of CB with the constant C.
+  auto ReplaceCallSiteUsersWith = [](CallBase &CB, Constant &C) {
+    if (CB.getNumUses() == 0)
+      return ChangeStatus::UNCHANGED;
+    CB.replaceAllUsesWith(&C);
+    return ChangeStatus::CHANGED;
+  };
+
   // If the assumed unique return value is an argument, annotate it.
   if (auto *UniqueRVArg = dyn_cast<Argument>(UniqueRV.getValue())) {
     getIRPosition() = IRPosition::argument(*UniqueRVArg);
-    Changed = IRAttribute::manifest(A) | Changed;
+    Changed = IRAttribute::manifest(A);
+  } else if (auto *RVC = dyn_cast<Constant>(UniqueRV.getValue())) {
+    // We can replace the returned value with the unique returned constant.
+    Value &AnchorValue = getAnchorValue();
+    if (Function *F = dyn_cast<Function>(&AnchorValue)) {
+      for (const Use &U : F->uses())
+        if (CallBase *CB = dyn_cast<CallBase>(U.getUser()))
+          if (CB->isCallee(&U))
+            Changed = ReplaceCallSiteUsersWith(*CB, *RVC) | Changed;
+    } else {
+      assert(isa<CallBase>(AnchorValue) &&
+             "Expcected a function or call base anchor!");
+      Changed = ReplaceCallSiteUsersWith(cast<CallBase>(AnchorValue), *RVC);
+    }
+    if (Changed == ChangeStatus::CHANGED)
+      STATS_DECLTRACK(UniqueConstantReturnValue, FunctionReturn,
+                      "Number of function returns replaced by constant return");
   }
 
   return Changed;
index 02527892f01d97a0f4aba53992788a697fde4990..cc3451d939f096caa4d12abf80d7dd36fb2cf283 100644 (file)
@@ -92,6 +92,15 @@ define i32 @catch_thing() personality i8* bitcast (i32 (...)* @__gxx_personality
   ret i32 -1
 }
 
+define i32 @catch_thing_user() {
+; ATTRIBUTOR:     define i32 @catch_thing_user
+; ATTRIBUTOR-NEXT: %catch_thing_call = call
+; ATTRIBUTOR-NEXT: ret i32 -1
+  %catch_thing_call = call i32 @catch_thing()
+  ret i32 %catch_thing_call
+}
+
+
 declare i32 @__gxx_personality_v0(...)
 
 declare i8* @__cxa_begin_catch(i8*)