]> granicus.if.org Git - llvm/commitdiff
Directly return promoted direct call instead of rely on stripPointerCast.
authorDehao Chen <dehao@google.com>
Fri, 6 Oct 2017 17:04:55 +0000 (17:04 +0000)
committerDehao Chen <dehao@google.com>
Fri, 6 Oct 2017 17:04:55 +0000 (17:04 +0000)
Summary: stripPointerCast is not reliably returning the value that's being type-casted. Instead it may look further at function attributes to further propagate the value. Instead of relying on stripPOintercast, the more reliable solution is to directly use the pointer to the promoted direct call.

Reviewers: tejohnson, davidxl

Reviewed By: tejohnson

Subscribers: llvm-commits, sanjoy

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

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@315077 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/IPO/SampleProfile.cpp
lib/Transforms/Instrumentation/IndirectCallPromotion.cpp
test/Transforms/SampleProfile/Inputs/indirect-call.prof
test/Transforms/SampleProfile/indirect-call.ll

index fb7397c3d8e570ae5ec51b6f9bf1f840250f55d9..39e3696972df575db4d42b9e63a9515377bceacd 100644 (file)
@@ -790,9 +790,8 @@ bool SampleProfileLoader::inlineHotFunctions(
             // as a result, we do not have profile info for the branch
             // probability. We set the probability to 80% taken to indicate
             // that the static call is likely taken.
-            Instruction *DI = dyn_cast<Instruction>(
-                promoteIndirectCall(I, R->getValue(), 80, 100, false, ORE)
-                    ->stripPointerCasts());
+            Instruction *DI = promoteIndirectCall(
+                I, R->getValue(), 80, 100, false, ORE);
             PromotedInsns.insert(I);
             // If profile mismatches, we should not attempt to inline DI.
             if ((isa<CallInst>(DI) || isa<InvokeInst>(DI)) &&
index f323e0814950c4c0760c8d62781b6384daa3b124..d8baa4f864457ea6436fc59092ee255623e048ff 100644 (file)
@@ -461,11 +461,13 @@ static Instruction *insertCallRetCast(const Instruction *Inst,
 // MergeBB is the bottom BB of the if-then-else-diamond after the
 // transformation. For invoke instruction, the edges from DirectCallBB and
 // IndirectCallBB to MergeBB are removed before this call (during
-// createIfThenElse).
+// createIfThenElse). Stores the pointer to the Instruction that cast
+// the direct call in \p CastInst.
 static Instruction *createDirectCallInst(const Instruction *Inst,
                                          Function *DirectCallee,
                                          BasicBlock *DirectCallBB,
-                                         BasicBlock *MergeBB) {
+                                         BasicBlock *MergeBB,
+                                         Instruction *&CastInst) {
   Instruction *NewInst = Inst->clone();
   if (CallInst *CI = dyn_cast<CallInst>(NewInst)) {
     CI->setCalledFunction(DirectCallee);
@@ -499,7 +501,8 @@ static Instruction *createDirectCallInst(const Instruction *Inst,
     }
   }
 
-  return insertCallRetCast(Inst, NewInst, DirectCallee);
+  CastInst = insertCallRetCast(Inst, NewInst, DirectCallee);
+  return NewInst;
 }
 
 // Create a PHI to unify the return values of calls.
@@ -559,15 +562,17 @@ Instruction *llvm::promoteIndirectCall(Instruction *Inst,
   createIfThenElse(Inst, DirectCallee, Count, TotalCount, &DirectCallBB,
                    &IndirectCallBB, &MergeBB);
 
+  // If the return type of the NewInst is not the same as the Inst, a CastInst
+  // is needed for type casting. Otherwise CastInst is the same as NewInst.
+  Instruction *CastInst = nullptr;
   Instruction *NewInst =
-      createDirectCallInst(Inst, DirectCallee, DirectCallBB, MergeBB);
+      createDirectCallInst(Inst, DirectCallee, DirectCallBB, MergeBB, CastInst);
 
   if (AttachProfToDirectCall) {
     SmallVector<uint32_t, 1> Weights;
     Weights.push_back(Count);
     MDBuilder MDB(NewInst->getContext());
-    if (Instruction *DI = dyn_cast<Instruction>(NewInst->stripPointerCasts()))
-      DI->setMetadata(LLVMContext::MD_prof, MDB.createBranchWeights(Weights));
+    NewInst->setMetadata(LLVMContext::MD_prof, MDB.createBranchWeights(Weights));
   }
 
   // Move Inst from MergeBB to IndirectCallBB.
@@ -589,10 +594,10 @@ Instruction *llvm::promoteIndirectCall(Instruction *Inst,
     // We don't need to update the operand from NormalDest for DirectCallBB.
     // Pass nullptr here.
     fixupPHINodeForNormalDest(Inst, II->getNormalDest(), MergeBB,
-                              IndirectCallBB, NewInst);
+                              IndirectCallBB, CastInst);
   }
 
-  insertCallRetPHI(Inst, NewInst, DirectCallee);
+  insertCallRetPHI(Inst, CastInst, DirectCallee);
 
   DEBUG(dbgs() << "\n== Basic Blocks After ==\n");
   DEBUG(dbgs() << *BB << *DirectCallBB << *IndirectCallBB << *MergeBB << "\n");
index dda7d0585e3bf56ce4f73321583297ae6c1668c6..5cbfc0a73bcd9ead42c0e0ab66cd63f17020d512 100644 (file)
@@ -24,3 +24,8 @@ test_norecursive_inline:3000:0
 test_noinline_bitcast:3000:0
  1: foo_direct_i32:3000
   1: 3000
+return_arg_caller:3000:0
+ 1: foo_inline1:3000
+  11: 3000
+ 2: return_arg:3000
+  1: 3000
index 02fcb11060a4a4607cf64ef883eb18a36a18f638..8c80091c34711c61ad7f73dd1b86924a9d50eddd 100644 (file)
@@ -92,6 +92,32 @@ define void @test_norecursive_inline() !dbg !24 {
   ret void
 }
 
+define i32* @return_arg(i32* readnone returned) !dbg !29{
+  ret i32* %0
+}
+
+; CHECK-LABEL: @return_arg_caller
+; When the promoted indirect call returns a parameter that was defined by the
+; return value of a previous direct call. Checks both direct call and promoted
+; indirect call are inlined.
+define i32* @return_arg_caller(i32* (i32*)* nocapture) !dbg !30{
+; CHECK-NOT: call i32* @foo_inline1
+; CHECK: if.true.direct_targ:
+; CHECK-NOT: call
+; CHECK: if.false.orig_indirect:
+; CHECK: call
+  %2 = call i32* @foo_inline1(i32* null), !dbg !31
+  %cmp = icmp ne i32* %2, null
+  br i1 %cmp, label %then, label %else
+
+then:
+  %3 = tail call i32* %0(i32* %2), !dbg !32
+  ret i32* %3
+
+else:
+  ret i32* null
+}
+
 @x = global i32 0, align 4
 @y = global void ()* null, align 8
 
@@ -176,3 +202,7 @@ define void @test_direct() !dbg !22 {
 !26 = distinct !DISubprogram(name: "test_noinline_bitcast", scope: !1, file: !1, line: 12, unit: !0)
 !27 = !DILocation(line: 13, scope: !26)
 !28 = distinct !DISubprogram(name: "foo_direct_i32", scope: !1, file: !1, line: 11, unit: !0)
+!29 = distinct !DISubprogram(name: "return_arg", scope: !1, file: !1, line: 11, unit: !0)
+!30 = distinct !DISubprogram(name: "return_arg_caller", scope: !1, file: !1, line: 11, unit: !0)
+!31 = !DILocation(line: 12, scope: !30)
+!32 = !DILocation(line: 13, scope: !30)