[llvm-dev] RFC: Inlining report
Philip Reames via llvm-dev
llvm-dev at lists.llvm.org
Fri Oct 23 14:14:49 PDT 2015
This would be really nice to have. There will be lots of details to
work out - Hal already raised one of the more important ones - but I'd
be very happy to see LLVM grow in this direction. Thanks for working on
this.
Philip
On 10/22/2015 11:25 AM, Cox, Robert via llvm-dev wrote:
>
> *RFC: Inlining Report *
>
> **
>
> *Motivation *
>
> Making good inlining choices while optimizing an application is often
> key to achieving optimal performance. While the compiler’s default
> inlining heuristics sometimes provide great out-of-box results,
> optimal performance is sometimes achieved only after varying the
> settings of certain compiler options related to inlining or adding
> “always_inline” or “noinline” attributes to certain functions.
>
> Before we can determine how we need change the compiler’s inlining
> choices to get better performance for an application, we need to have
> a clear picture of the compiler’s inlining choices and what motivated
> them. Many compilers like LLVM and GCC provide *informational notes
> *when a function is inlined, but these notes provide only a “blow by
> blow” description of what the compiler did, rather than a high level
> illustration of the result. This high level picture can be provided by
> an *inlining report. *
>
> Over the years, I’ve worked with several compilers that provide
> inlining reports, and I can attest that the customers using those
> compilers have found them to be invaluable tool in investigating and
> improving their applications’ performance. In addition, the inlining
> report can be used by compiler developers to visualize and improve the
> compiler’s default heuristics and option values.
>
> For these reasons, I’d like to contribute code to LLVM to generate an
> inlining report as part of the inliner.
>
> *Description *
>
> The inlining report I am proposing contains the following information:
>
> (1)The values of the principle threshold options which affect how much
> inlining is done under various circumstances
>
> (2)Whether each function is compiled or has been eliminated by dead
> static function elimination.
>
> (3)For each function, the call sites that were and were not inlined.
> Since inlining a call site can expose other call sites for inlining,
> the inlining report also reports on whether these exposed call sites
> have been inlined or not. This information is presented in
> hierarchical manner.
>
> (4)For each call site, we include the principle reason the call site
> was or was not inlined, together with any cost vs . threshold
> computation that was done.
>
> *High Level Design *
>
> The inline report is created if the option –inline-report=X is passed
> on command line with a positive integer value of X. If X is 0, or
> this option is not specified, the Inliner does not create or perform
> any operations on the inline report, and there is no compile time
> overhead.
>
> Three main classes are used to implement the inline report:
>
> */class InlineReportCallSite /*
>
> This class contains the inlining report information specific to a
> particular CallSite CS, including:
>
> (1)A bool indicating whether or not the CallSite was or was not inlined
>
> (2)An inlining reason indicating why the CallSite was or was not inlined
>
> (3)The inlining cost, outer inlining cost, and threshold values used
> in calculating the profitability of inlining
>
> (4)A vector of InlineReportCallSite*, each of which points to an
> InlineReportCallSite for a CallSite exposed when CS was inlined.
>
> */class InlineReportFunction /*
>
> This class contains the inlining report information specific to a
> particular Function F in the call graph, including:
>
> (1)A bool indicating whether the function has been dead static
> eliminated.
>
> (2)A vector of call InlineReportCallSite*, each of which points to an
> InlineReportCallSite for a CallSite that appeared in F before any
> inlining was applied.
>
> */class InlineReport /*
>
> The main class which summarizes the high level information in the
> inline report, including:
>
> (1)The values of the inlining threshold options
>
> (2)The “level” of the inlining report, which is a bit vector of
> feature options. For example, whether to print external functions and
> intrinsics, whether to print the inlining reasons, etc.
>
> (3)A map MF from each Function* to InlineReportFunction*
>
> (4)A map MCS from each CallSite* to InlineReportCallSite*
>
> In addition, the class InlineCost (from InlineCost.h) is augmented to
> include the primary reason a call site was inlined.
>
> The class Inliner has been augmented with an InlineReport, which is
> created when an Inliner is constructed. The InlineReport is updated
> using calls to the member functions of these three classes in
> Inliner::runOnSCC() and the functions called by it.
>
> Before any inlining is done in a particular call to runOnSCC(), the
> map MF is updated so that each Function (caller or callee) that will
> be examined for inlining has a corresponding InlineReportFunction in
> the map. (The map MCS is also updated in a similar way, but only when
> a Function is actually inlined.)
>
> The Inliner determines if a CallSite should be inlined by first
> calling Inliner::ShouldInline(). This calls getInlineCost() which
> returns an InlineCost, which now includes the reason the call site
> should or should not be inlined. This reason, as well and costs and
> threshold from the InlineCost are stored in the InlineReportCallSite
> for the CallSite.
>
> Then Inliner calls the static function InlineCallPossible(). If the
> inlining was not performed, the reason for not inlining is recorded in
> the InlineReportCallSite corresponding to the CallSite. If the
> inlining was performed, the corresponding InlineReportCallSite is
> marked as inlined, and it is populated with the InlineReportCallSites
> corresponding to the newly exposed CallSites that were created during
> the inlining.
>
> The InlineReport is printed during the call to Inliner::doFinalization().
>
> Since the compiler can run any number of optimizations between two
> successive calls to runOnSCC(), the Instructions corresponding to
> CallSites can be deleted by the optimizations. Callbacks are used to
> mark the corresponding InlineReportCallSites as deleted when this
> happens.
>
> *Example *
>
> Here is an example of abbreviated inlining report that is generated in
> my locally modified copy of the LLVM sources. I generated this by
> compiling the file bzip2.c from the spec 2006 benchmark 401.bzip.
> (For the sake of brevity, I didn’t include all of the report.
> Omitted parts are indicated by …. in the report.)
>
> *---- Begin Inlining Report ----*
>
> **
>
> *Option Values:*
>
> * inline-threshold: 225*
>
> * inlinehint-threshold: 325*
>
> * inlinecold-threshold: 225*
>
> * inlineoptsize-threshold: 15*
>
> **
>
> *COMPILE FUNC: fopen_output_safely*
>
> * -> EXTERN: open*
>
> * -> EXTERN: fdopen*
>
> * -> EXTERN: close*
>
> **
>
> *DEAD STATIC FUNC: setExit*
>
> **
>
> *DEAD STATIC FUNC: copyFileName*
>
> **
>
> *DEAD STATIC FUNC: showFileNames*
>
> **
>
> *DEAD STATIC FUNC: stat*
>
> **
>
> *….*
>
> **
>
> *COMPILE FUNC: cleanUpAndFail*
>
> * -> llvm.lifetime.start*
>
> * [[Callee is intrinsic]]*
>
> * -> INLINE: stat (35<=487)*
>
> * <<Callee is single basic block>>*
>
> * -> EXTERN: __xstat*
>
> * -> EXTERN: fprintf*
>
> * -> EXTERN: fclose*
>
> * -> EXTERN: remove*
>
> * -> EXTERN: fprintf*
>
> * -> EXTERN: fprintf*
>
> * -> EXTERN: fprintf*
>
> * -> EXTERN: fprintf*
>
> * -> EXTERN: fprintf*
>
> * -> EXTERN: fprintf*
>
> * -> INLINE: setExit (15<=225)*
>
> * <<Inlining is profitable>>*
>
> * -> EXTERN: exit*
>
> **
>
> *….*
>
> **
>
> *COMPILE FUNC: outOfMemory*
>
> * -> EXTERN: fprintf*
>
> * -> INLINE: showFileNames (70<=225)*
>
> * <<Inlining is profitable>>*
>
> * -> EXTERN: fprintf*
>
> * -> cleanUpAndFail*
>
> * [[Callee is noreturn]]*
>
> **
>
> *….*
>
> **
>
> *COMPILE FUNC: snocString*
>
> * -> INLINE: mkCell (-14920<=225)*
>
> * <<Callee has single callsite and local linkage>>*
>
> * -> INLINE: myMalloc (70<=225)*
>
> * <<Inlining is profitable>>*
>
> * -> EXTERN: malloc*
>
> * -> outOfMemory*
>
> * [[Callee is noreturn]]*
>
> * -> EXTERN: strlen*
>
> * -> INLINE: myMalloc (-14925<=225)*
>
> * <<Callee has single callsite and local linkage>>*
>
> * -> EXTERN: malloc*
>
> * -> outOfMemory*
>
> * [[Callee is noreturn]]*
>
> * -> EXTERN: strcpy*
>
> * -> snocString*
>
> * [[Callee is never inline]]*
>
> **
>
> *…..*
>
> **
>
> *---- End Inlining Report ------*
>
> **
>
> Here is an explanation of some of the features:
>
> (1)Option values
>
> *Option Values:*
>
> *inline-threshold: 225*
>
> *inlinehint-threshold: 325*
>
> *inlinecold-threshold: 225*
>
> *inlineoptsize-threshold: 15*
>
> **
>
> The report begins with a list of the most relevant option values to
> inlining.
>
> (2)Compiled and dead functions
>
> *COMPILE FUNC: fopen_output_safely*
>
> * -> EXTERN: open*
>
> * -> EXTERN: fdopen*
>
> * -> EXTERN: close*
>
> **
>
> *DEAD STATIC FUNC: setExit*
>
> **
>
> Functions in the file are identified as either being compiled or
> eliminated by dead static function elimination.
>
> (3)External function calls
>
> *COMPILE FUNC: fopen_output_safely*
>
> *-> EXTERN: open*
>
> * -> EXTERN: fdopen*
>
> * -> EXTERN: close*
>
> Calls to externally defined functions are indicated by the word
> EXTERN. These lines can optionally be omitted.
>
> (4)Inlining and nesting
>
> *COMPILE FUNC: snocString*
>
> *-> INLINE: mkCell (-14920<=225)*
>
> * <<Callee has single callsite and local linkage>>*
>
> *-> INLINE: myMalloc (70<=225)*
>
> * <<Inlining is profitable>>*
>
> * -> EXTERN: malloc*
>
> **
>
> Inlined functions are marked INLINE. The inlining of a function within
> other inlined functions is shown clearly in the report using indentation.
>
> (5)Reasons functions were and were not inlined
>
> *COMPILE FUNC: cleanUpAndFail*
>
> * -> llvm.lifetime.start*
>
> *[[Callee is intrinsic]]*
>
> * -> INLINE: stat (35<=487)*
>
> *<<Callee is single basic block>>*
>
> * -> EXTERN: __xstat*
>
> * -> EXTERN: fprintf*
>
> * -> EXTERN: fclose*
>
> * -> EXTERN: remove*
>
> * -> EXTERN: fprintf*
>
> * -> EXTERN: fprintf*
>
> * -> EXTERN: fprintf*
>
> * -> EXTERN: fprintf*
>
> * -> EXTERN: fprintf*
>
> * -> EXTERN: fprintf*
>
> * -> INLINE: setExit (15<=225)*
>
> *<<Inlining is profitable>>*
>
> * -> EXTERN: exit*
>
> **
>
> ….
>
> *COMPILE FUNC: outOfMemory*
>
> * -> EXTERN: fprintf*
>
> * -> INLINE: showFileNames (70<=225)*
>
> *<<Inlining is profitable>>*
>
> * -> EXTERN: fprintf*
>
> * -> cleanUpAndFail*
>
> *[[Callee is noreturn]]*
>
> The principal reason a function was or was not inlined can be
> optionally displayed in the report. The reason a function was inlined
> is indicated in double angle brackets << >>. The reason a function
> was not inlined is indicated in double square brackets [[ ]]. When a
> comparison of the cost and threshold was used to determine if the
> function should be inlined, the comparison done is given. (Since
> intrinsics are never inlined, information about them can be suppressed
> in the report.) The reasons for or for not inlining can optionally be
> displayed on the same line as the function considered for inlining for
> easy analysis using grep, awk, etc.
>
> (6)Line and column info
>
> *COMPILE FUNC: outOfMemory*
>
> * -> EXTERN: fprintf bzip2.c(1016,4)*
>
> * -> showFileNames bzip2.c(1019,4) [[Callee is never inline]]*
>
> * -> cleanUpAndFail bzip2.c(1020,4) [[Callee is never inline]]*
>
> **
>
> Optionally, file, line, and column info can be provided for call sites
> if source position information is present (using –g or
>
> –gline-tables-only).
>
> I would appreciate any comments you have on whether you support the
> inclusion of an inline report in LLVM, the form and features I have
> outlined above, and your thoughts on the high level design.
>
> Thank you in advance for your comments,
>
> Robert Cox
>
> robert.cox at intel.com <mailto:robert.cox at intel.com>
>
>
>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20151023/f130a087/attachment.html>
More information about the llvm-dev
mailing list