[llvm] r315077 - Directly return promoted direct call instead of rely on stripPointerCast.

Dehao Chen via llvm-commits llvm-commits at lists.llvm.org
Fri Oct 6 10:04:55 PDT 2017


Author: dehao
Date: Fri Oct  6 10:04:55 2017
New Revision: 315077

URL: http://llvm.org/viewvc/llvm-project?rev=315077&view=rev
Log:
Directly return promoted direct call instead of rely on stripPointerCast.

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

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

Modified: llvm/trunk/lib/Transforms/IPO/SampleProfile.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/SampleProfile.cpp?rev=315077&r1=315076&r2=315077&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/SampleProfile.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/SampleProfile.cpp Fri Oct  6 10:04:55 2017
@@ -790,9 +790,8 @@ bool SampleProfileLoader::inlineHotFunct
             // 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)) &&

Modified: llvm/trunk/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp?rev=315077&r1=315076&r2=315077&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/IndirectCallPromotion.cpp Fri Oct  6 10:04:55 2017
@@ -461,11 +461,13 @@ static Instruction *insertCallRetCast(co
 // 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
     }
   }
 
-  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(I
   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(I
     // 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");

Modified: llvm/trunk/test/Transforms/SampleProfile/Inputs/indirect-call.prof
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SampleProfile/Inputs/indirect-call.prof?rev=315077&r1=315076&r2=315077&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SampleProfile/Inputs/indirect-call.prof (original)
+++ llvm/trunk/test/Transforms/SampleProfile/Inputs/indirect-call.prof Fri Oct  6 10:04:55 2017
@@ -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

Modified: llvm/trunk/test/Transforms/SampleProfile/indirect-call.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/SampleProfile/indirect-call.ll?rev=315077&r1=315076&r2=315077&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/SampleProfile/indirect-call.ll (original)
+++ llvm/trunk/test/Transforms/SampleProfile/indirect-call.ll Fri Oct  6 10:04:55 2017
@@ -92,6 +92,32 @@ define void @test_norecursive_inline() !
   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)




More information about the llvm-commits mailing list