[llvm] r279860 - [Inliner] Report when inlining fails because callee's def is unavailable

Adam Nemet via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 26 13:21:05 PDT 2016


Author: anemet
Date: Fri Aug 26 15:21:05 2016
New Revision: 279860

URL: http://llvm.org/viewvc/llvm-project?rev=279860&view=rev
Log:
[Inliner] Report when inlining fails because callee's def is unavailable

Summary:
This is obviously an interesting case because it may motivate code
restructuring or LTO.

Reporting this requires instantiation of ORE in the loop where the call
sites are first gathered.  I've checked compile-time
overhead *with* -Rpass-with-hotness and the worst slow-down was 6% in
mcf and quickly tailing off.  As before without -Rpass-with-hotness
there is no overhead.

Because this could be a pretty noisy diagnostics, it is currently
qualified as 'verbose'.  As of this patch, 'verbose' diagnostics are
only emitted with -Rpass-with-hotness, i.e. when the output is expected
to be filtered.

Reviewers: eraman, chandlerc, davidxl, hfinkel

Subscribers: tejohnson, Prazek, davide, llvm-commits

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

Modified:
    llvm/trunk/include/llvm/Analysis/OptimizationDiagnosticInfo.h
    llvm/trunk/lib/Analysis/OptimizationDiagnosticInfo.cpp
    llvm/trunk/lib/Transforms/IPO/Inliner.cpp
    llvm/trunk/test/Transforms/Inline/optimization-remarks.ll

Modified: llvm/trunk/include/llvm/Analysis/OptimizationDiagnosticInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Analysis/OptimizationDiagnosticInfo.h?rev=279860&r1=279859&r2=279860&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Analysis/OptimizationDiagnosticInfo.h (original)
+++ llvm/trunk/include/llvm/Analysis/OptimizationDiagnosticInfo.h Fri Aug 26 15:21:05 2016
@@ -91,21 +91,24 @@ public:
   /// -Rpass-missed= is given and the name matches the regular expression in
   /// -Rpass, then the remark will be emitted.  \p DLoc is the debug location
   /// where the diagnostic is generated. \p V is the IR Value that identifies
-  /// the code region. \p Msg is the message string to use.
+  /// the code region. \p Msg is the message string to use.  If \p IsVerbose is
+  /// true, the message is considered verbose and will only be emitted when
+  /// verbose output is turned on.
   void emitOptimizationRemarkMissed(const char *PassName, const DebugLoc &DLoc,
-                                    const Value *V, const Twine &Msg);
+                                    const Value *V, const Twine &Msg,
+                                    bool IsVerbose = false);
 
   /// \brief Same as above but derives the IR Value for the code region and the
   /// debug location from the Loop parameter \p L.
   void emitOptimizationRemarkMissed(const char *PassName, Loop *L,
-                                    const Twine &Msg);
+                                    const Twine &Msg, bool IsVerbose = false);
 
   /// \brief Same as above but derives the debug location and the code region
   /// from the debug location and the basic block of \p Inst, respectively.
   void emitOptimizationRemarkMissed(const char *PassName, Instruction *Inst,
-                                    const Twine &Msg) {
+                                    const Twine &Msg, bool IsVerbose = false) {
     emitOptimizationRemarkMissed(PassName, Inst->getDebugLoc(),
-                                 Inst->getParent(), Msg);
+                                 Inst->getParent(), Msg, IsVerbose);
   }
 
   /// Emit an optimization analysis remark message.
@@ -114,22 +117,46 @@ public:
   /// -Rpass-analysis= is given and \p PassName matches the regular expression
   /// in -Rpass, then the remark will be emitted. \p DLoc is the debug location
   /// where the diagnostic is generated. \p V is the IR Value that identifies
-  /// the code region. \p Msg is the message string to use.
+  /// the code region. \p Msg is the message string to use. If \p IsVerbose is
+  /// true, the message is considered verbose and will only be emitted when
+  /// verbose output is turned on.
   void emitOptimizationRemarkAnalysis(const char *PassName,
                                       const DebugLoc &DLoc, const Value *V,
-                                      const Twine &Msg);
+                                      const Twine &Msg, bool IsVerbose = false);
 
   /// \brief Same as above but derives the IR Value for the code region and the
   /// debug location from the Loop parameter \p L.
   void emitOptimizationRemarkAnalysis(const char *PassName, Loop *L,
-                                      const Twine &Msg);
+                                      const Twine &Msg, bool IsVerbose = false);
 
   /// \brief Same as above but derives the debug location and the code region
   /// from the debug location and the basic block of \p Inst, respectively.
   void emitOptimizationRemarkAnalysis(const char *PassName, Instruction *Inst,
-                                      const Twine &Msg) {
+                                      const Twine &Msg,
+                                      bool IsVerbose = false) {
     emitOptimizationRemarkAnalysis(PassName, Inst->getDebugLoc(),
-                                   Inst->getParent(), Msg);
+                                   Inst->getParent(), Msg, IsVerbose);
+  }
+
+  /// \brief This variant allows specifying what should be emitted for missed
+  /// and analysis remarks in one call.
+  ///
+  /// \p PassName is the name of the pass emitting the message. If
+  /// -Rpass-missed= is given and \p PassName matches the regular expression, \p
+  /// MsgForMissedRemark is emitted.
+  ///
+  /// If -Rpass-analysis= is given and \p PassName matches the regular
+  /// expression, \p MsgForAnalysisRemark is emitted.
+  ///
+  /// The debug location and the code region is derived from \p Inst. If \p
+  /// IsVerbose is true, the message is considered verbose and will only be
+  /// emitted when verbose output is turned on.
+  void emitOptimizationRemarkMissedAndAnalysis(
+      const char *PassName, Instruction *Inst, const Twine &MsgForMissedRemark,
+      const Twine &MsgForAnalysisRemark, bool IsVerbose = false) {
+    emitOptimizationRemarkAnalysis(PassName, Inst, MsgForAnalysisRemark,
+                                   IsVerbose);
+    emitOptimizationRemarkMissed(PassName, Inst, MsgForMissedRemark, IsVerbose);
   }
 
   /// \brief Emit an optimization analysis remark related to floating-point
@@ -173,6 +200,10 @@ private:
 
   Optional<uint64_t> computeHotness(const Value *V);
 
+  /// \brief Only allow verbose messages if we know we're filtering by hotness
+  /// (BFI is only set in this case).
+  bool shouldEmitVerbose() { return BFI != nullptr; }
+
   OptimizationRemarkEmitter(const OptimizationRemarkEmitter &) = delete;
   void operator=(const OptimizationRemarkEmitter &) = delete;
 };

Modified: llvm/trunk/lib/Analysis/OptimizationDiagnosticInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Analysis/OptimizationDiagnosticInfo.cpp?rev=279860&r1=279859&r2=279860&view=diff
==============================================================================
--- llvm/trunk/lib/Analysis/OptimizationDiagnosticInfo.cpp (original)
+++ llvm/trunk/lib/Analysis/OptimizationDiagnosticInfo.cpp Fri Aug 26 15:21:05 2016
@@ -68,29 +68,32 @@ void OptimizationRemarkEmitter::emitOpti
 
 void OptimizationRemarkEmitter::emitOptimizationRemarkMissed(
     const char *PassName, const DebugLoc &DLoc, const Value *V,
-    const Twine &Msg) {
+    const Twine &Msg, bool IsVerbose) {
   LLVMContext &Ctx = F->getContext();
-  Ctx.diagnose(DiagnosticInfoOptimizationRemarkMissed(PassName, *F, DLoc, Msg,
-                                                      computeHotness(V)));
+  if (!IsVerbose || shouldEmitVerbose())
+    Ctx.diagnose(DiagnosticInfoOptimizationRemarkMissed(PassName, *F, DLoc, Msg,
+                                                        computeHotness(V)));
 }
 
 void OptimizationRemarkEmitter::emitOptimizationRemarkMissed(
-    const char *PassName, Loop *L, const Twine &Msg) {
-  emitOptimizationRemarkMissed(PassName, L->getStartLoc(), L->getHeader(), Msg);
+    const char *PassName, Loop *L, const Twine &Msg, bool IsVerbose) {
+  emitOptimizationRemarkMissed(PassName, L->getStartLoc(), L->getHeader(), Msg,
+                               IsVerbose);
 }
 
 void OptimizationRemarkEmitter::emitOptimizationRemarkAnalysis(
     const char *PassName, const DebugLoc &DLoc, const Value *V,
-    const Twine &Msg) {
+    const Twine &Msg, bool IsVerbose) {
   LLVMContext &Ctx = F->getContext();
-  Ctx.diagnose(DiagnosticInfoOptimizationRemarkAnalysis(PassName, *F, DLoc, Msg,
-                                                        computeHotness(V)));
+  if (!IsVerbose || shouldEmitVerbose())
+    Ctx.diagnose(DiagnosticInfoOptimizationRemarkAnalysis(
+        PassName, *F, DLoc, Msg, computeHotness(V)));
 }
 
 void OptimizationRemarkEmitter::emitOptimizationRemarkAnalysis(
-    const char *PassName, Loop *L, const Twine &Msg) {
+    const char *PassName, Loop *L, const Twine &Msg, bool IsVerbose) {
   emitOptimizationRemarkAnalysis(PassName, L->getStartLoc(), L->getHeader(),
-                                 Msg);
+                                 Msg, IsVerbose);
 }
 
 void OptimizationRemarkEmitter::emitOptimizationRemarkAnalysisFPCommute(

Modified: llvm/trunk/lib/Transforms/IPO/Inliner.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/Inliner.cpp?rev=279860&r1=279859&r2=279860&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/Inliner.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/Inliner.cpp Fri Aug 26 15:21:05 2016
@@ -452,9 +452,10 @@ inlineCallsImpl(CallGraphSCC &SCC, CallG
 
   for (CallGraphNode *Node : SCC) {
     Function *F = Node->getFunction();
-    if (!F)
+    if (!F || F->isDeclaration())
       continue;
 
+    OptimizationRemarkEmitter ORE(F);
     for (BasicBlock &BB : *F)
       for (Instruction &I : BB) {
         CallSite CS(cast<Value>(&I));
@@ -467,8 +468,16 @@ inlineCallsImpl(CallGraphSCC &SCC, CallG
         // it.  If it is an indirect call, inlining may resolve it to be a
         // direct call, so we keep it.
         if (Function *Callee = CS.getCalledFunction())
-          if (Callee->isDeclaration())
+          if (Callee->isDeclaration()) {
+            ORE.emitOptimizationRemarkMissedAndAnalysis(
+                DEBUG_TYPE, &I,
+                Twine(Callee->getName()) + " will not be inlined into " +
+                    CS.getCaller()->getName(),
+                Twine("definition of ") + Callee->getName() +
+                    " is not available",
+                /*Verbose=*/true);
             continue;
+          }
 
         CallSites.push_back(std::make_pair(CS, -1));
       }

Modified: llvm/trunk/test/Transforms/Inline/optimization-remarks.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/Inline/optimization-remarks.ll?rev=279860&r1=279859&r2=279860&view=diff
==============================================================================
--- llvm/trunk/test/Transforms/Inline/optimization-remarks.ll (original)
+++ llvm/trunk/test/Transforms/Inline/optimization-remarks.ll Fri Aug 26 15:21:05 2016
@@ -1,5 +1,14 @@
-; RUN: opt < %s -inline -pass-remarks=inline -pass-remarks-missed=inline -pass-remarks-analysis=inline -S 2>&1 | FileCheck %s
+; RUN: opt < %s -inline -pass-remarks=inline -pass-remarks-missed=inline \
+; RUN:       -pass-remarks-analysis=inline -S 2>&1 | \
+; RUN:       FileCheck -check-prefix=CHECK -check-prefix=NO_HOTNESS %s
+; RUN: opt < %s -inline -pass-remarks=inline -pass-remarks-missed=inline \
+; RUN:       -pass-remarks-analysis=inline -pass-remarks-with-hotness -S 2>&1 | \
+; RUN:       FileCheck -check-prefix=CHECK -check-prefix=HOTNESS %s
 
+; HOTNESS: definition of fox is not available
+; HOTNESS: fox will not be inlined into bar
+; NO_HOTNESS-NOT: definition of fox is not available
+; NO_HOTNESS-NOT: fox will not be inlined into bar
 ; CHECK: foo should always be inlined (cost=always)
 ; CHECK: foo inlined into bar
 ; CHECK: foz should never be inlined (cost=never)
@@ -32,6 +41,8 @@ entry:
   ret float %conv
 }
 
+declare i32 @fox()
+
 ; Function Attrs: nounwind uwtable
 define i32 @bar(i32 %j) #2 {
 entry:
@@ -48,7 +59,9 @@ entry:
   %call2 = call float @foz(i32 %sub1, i32 %3)
   %mul = fmul float %conv, %call2
   %conv3 = fptosi float %mul to i32
-  ret i32 %conv3
+  %call3 = call i32 @fox()
+  %add = add i32 %conv3, %call 
+  ret i32 %add
 }
 
 attributes #0 = { alwaysinline nounwind uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }




More information about the llvm-commits mailing list