[llvm] r352849 - Provide reason messages for unviable inlining

Yevgeny Rouban via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 1 02:44:43 PST 2019


Author: yrouban
Date: Fri Feb  1 02:44:43 2019
New Revision: 352849

URL: http://llvm.org/viewvc/llvm-project?rev=352849&view=rev
Log:
Provide reason messages for unviable inlining

InlineCost's isInlineViable() is changed to return InlineResult
instead of bool. This provides messages for failure reasons and
allows to get more specific messages for cases where callsites
are not viable for inlining.

Reviewed By: xbolva00, anemet

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

Modified:
    llvm/trunk/include/llvm/Analysis/InlineCost.h
    llvm/trunk/lib/Analysis/InlineCost.cpp
    llvm/trunk/lib/Target/AMDGPU/AMDGPUInline.cpp
    llvm/trunk/lib/Transforms/IPO/AlwaysInliner.cpp
    llvm/trunk/test/Transforms/Inline/inline-remark.ll

Modified: llvm/trunk/include/llvm/Analysis/InlineCost.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/InlineCost.h?rev=352849&r1=352848&r2=352849&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/InlineCost.h (original)
+++ llvm/trunk/include/llvm/Analysis/InlineCost.h Fri Feb  1 02:44:43 2019
@@ -231,7 +231,7 @@ getInlineCost(CallSite CS, Function *Cal
               ProfileSummaryInfo *PSI, OptimizationRemarkEmitter *ORE);
 
 /// Minimal filter to detect invalid constructs for inlining.
-bool isInlineViable(Function &Callee);
+InlineResult isInlineViable(Function &Callee);
 }
 
 #endif

Modified: llvm/trunk/lib/Analysis/InlineCost.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/InlineCost.cpp?rev=352849&r1=352848&r2=352849&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/InlineCost.cpp (original)
+++ llvm/trunk/lib/Analysis/InlineCost.cpp Fri Feb  1 02:44:43 2019
@@ -2022,9 +2022,10 @@ InlineCost llvm::getInlineCost(
   // Calls to functions with always-inline attributes should be inlined
   // whenever possible.
   if (CS.hasFnAttr(Attribute::AlwaysInline)) {
-    if (isInlineViable(*Callee))
+    auto IsViable = isInlineViable(*Callee);
+    if (IsViable)
       return llvm::InlineCost::getAlways("always inline attribute");
-    return llvm::InlineCost::getNever("inapplicable always inline attribute");
+    return llvm::InlineCost::getNever(IsViable.message);
   }
 
   // Never inline functions with conflicting attributes (unless callee has
@@ -2072,14 +2073,16 @@ InlineCost llvm::getInlineCost(
   return llvm::InlineCost::get(CA.getCost(), CA.getThreshold());
 }
 
-bool llvm::isInlineViable(Function &F) {
+InlineResult llvm::isInlineViable(Function &F) {
   bool ReturnsTwice = F.hasFnAttribute(Attribute::ReturnsTwice);
   for (Function::iterator BI = F.begin(), BE = F.end(); BI != BE; ++BI) {
     // Disallow inlining of functions which contain indirect branches or
     // blockaddresses.
-    if (isa<IndirectBrInst>(BI->getTerminator()) ||
-        BI->hasAddressTaken())
-      return false;
+    if (isa<IndirectBrInst>(BI->getTerminator()))
+      return "contains indirect branches";
+
+    if (BI->hasAddressTaken())
+      return "uses block address";
 
     for (auto &II : *BI) {
       CallSite CS(&II);
@@ -2088,13 +2091,13 @@ bool llvm::isInlineViable(Function &F) {
 
       // Disallow recursive calls.
       if (&F == CS.getCalledFunction())
-        return false;
+        return "recursive call";
 
       // Disallow calls which expose returns-twice to a function not previously
       // attributed as such.
       if (!ReturnsTwice && CS.isCall() &&
           cast<CallInst>(CS.getInstruction())->canReturnTwice())
-        return false;
+        return "exposes returns-twice attribute";
 
       if (CS.getCalledFunction())
         switch (CS.getCalledFunction()->getIntrinsicID()) {
@@ -2103,12 +2106,14 @@ bool llvm::isInlineViable(Function &F) {
         // Disallow inlining of @llvm.icall.branch.funnel because current
         // backend can't separate call targets from call arguments.
         case llvm::Intrinsic::icall_branch_funnel:
+          return "disallowed inlining of @llvm.icall.branch.funnel";
         // Disallow inlining functions that call @llvm.localescape. Doing this
         // correctly would require major changes to the inliner.
         case llvm::Intrinsic::localescape:
+          return "disallowed inlining of @llvm.localescape";
         // Disallow inlining of functions that initialize VarArgs with va_start.
         case llvm::Intrinsic::vastart:
-          return false;
+          return "contains VarArgs initialized with va_start";
         }
     }
   }

Modified: llvm/trunk/lib/Target/AMDGPU/AMDGPUInline.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/AMDGPU/AMDGPUInline.cpp?rev=352849&r1=352848&r2=352849&view=diff
==============================================================================
--- llvm/trunk/lib/Target/AMDGPU/AMDGPUInline.cpp (original)
+++ llvm/trunk/lib/Target/AMDGPU/AMDGPUInline.cpp Fri Feb  1 02:44:43 2019
@@ -181,9 +181,10 @@ InlineCost AMDGPUInliner::getInlineCost(
     return llvm::InlineCost::getNever("incompatible");
 
   if (CS.hasFnAttr(Attribute::AlwaysInline)) {
-    if (isInlineViable(*Callee))
+    auto IsViable = isInlineViable(*Callee);
+    if (IsViable)
       return llvm::InlineCost::getAlways("alwaysinline viable");
-    return llvm::InlineCost::getNever("alwaysinline unviable");
+    return llvm::InlineCost::getNever(IsViable.message);
   }
 
   if (isWrapperOnlyCall(CS))

Modified: llvm/trunk/lib/Transforms/IPO/AlwaysInliner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/AlwaysInliner.cpp?rev=352849&r1=352848&r2=352849&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/AlwaysInliner.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/AlwaysInliner.cpp Fri Feb  1 02:44:43 2019
@@ -145,11 +145,20 @@ InlineCost AlwaysInlinerLegacyPass::getI
   Function *Callee = CS.getCalledFunction();
 
   // Only inline direct calls to functions with always-inline attributes
-  // that are viable for inlining. FIXME: We shouldn't even get here for
-  // declarations.
-  if (Callee && !Callee->isDeclaration() &&
-      CS.hasFnAttr(Attribute::AlwaysInline) && isInlineViable(*Callee))
-    return InlineCost::getAlways("always inliner");
+  // that are viable for inlining.
+  if (!Callee)
+    return InlineCost::getNever("indirect call");
 
-  return InlineCost::getNever("always inliner");
+  // FIXME: We shouldn't even get here for declarations.
+  if (Callee->isDeclaration())
+    return InlineCost::getNever("no definition");
+
+  if (!CS.hasFnAttr(Attribute::AlwaysInline))
+    return InlineCost::getNever("no alwaysinline attribute");
+
+  auto IsViable = isInlineViable(*Callee);
+  if (!IsViable)
+    return InlineCost::getNever(IsViable.message);
+
+  return InlineCost::getAlways("always inliner");
 }

Modified: llvm/trunk/test/Transforms/Inline/inline-remark.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/inline-remark.ll?rev=352849&r1=352848&r2=352849&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/Inline/inline-remark.ll (original)
+++ llvm/trunk/test/Transforms/Inline/inline-remark.ll Fri Feb  1 02:44:43 2019
@@ -46,6 +46,16 @@ define void @test2(i8*) {
   ret void
 }
 
+;; Test 3 - InlineResult messages come from llvm::isInlineViable()
+define void @test3() {
+; CHECK-LABEL: @test3
+; CHECK-NEXT: call void @test3() [[ATTR4:#[0-9]+]]
+; CHECK-NEXT: ret void
+  call void @test3() alwaysinline
+  ret void
+}
+
 ; CHECK: attributes [[ATTR1]] = { "inline-remark"="(cost=25, threshold=0)" }
 ; CHECK: attributes [[ATTR2]] = { "inline-remark"="(cost=never): recursive" }
 ; CHECK: attributes [[ATTR3]] = { "inline-remark"="unsupported operand bundle; (cost={{.*}}, threshold={{.*}})" }
+; CHECK: attributes [[ATTR4]] = { alwaysinline "inline-remark"="(cost=never): recursive call" }




More information about the llvm-commits mailing list