This is an archive of the discontinued LLVM Phabricator instance.

Move inline threshold related flags to InlineSimple.cpp
ClosedPublic

Authored by eraman on Jul 7 2016, 4:30 PM.

Details

Summary

In http://reviews.llvm.org/D21405, Rong is adding a pre-inliner pass which uses the SimpleInliner pass with lower thresholds. If that is added, the use of -inline[.*]-threshold options will affect the preinliner as well which is not the intended behavior. This patch moves the threshold flags out of InlineCost.cpp and passes a set of knobs (based on the flags) to the getInlineCost method. This would allow the pre-inliner to ignore the threshold related flags.

Diff Detail

Repository
rL LLVM

Event Timeline

eraman updated this revision to Diff 63157.Jul 7 2016, 4:30 PM
eraman retitled this revision from to Move inline threshold related flags to InlineSimple.cpp.
eraman updated this object.
eraman added reviewers: chandlerc, davidxl.
eraman added subscribers: xur, llvm-commits.
davidxl added inline comments.Jul 22 2016, 2:04 PM
include/llvm/Analysis/InlineCost.h
114 ↗(On Diff #63157)

I don't quite like the name 'Knobs'. Perhaps more plain "Parameters"?

lib/Transforms/IPO/InlineSimple.cpp
138 ↗(On Diff #63157)

Why? If Threshold is explicitly passed in, should it be honored with highest precedence?

eraman added inline comments.Jul 22 2016, 2:16 PM
include/llvm/Analysis/InlineCost.h
114 ↗(On Diff #63157)

Ok, will rename this.

lib/Transforms/IPO/InlineSimple.cpp
138 ↗(On Diff #63157)

This is the current behavior : see the code in updateThreshold. It also makes sense. If the tool user sees a flag and explicitly passes a value to it, they expect the value to take effect. Even if you disagree with this, that should be a separate change.

davidxl added inline comments.Jul 22 2016, 2:25 PM
lib/Transforms/IPO/InlineSimple.cpp
138 ↗(On Diff #63157)

OK -- if this is intended as NFC. On the other hand how do you plan to handle fine grain control of different instances of the inliner ? (LTO, thinLTO, IRPGO)?

eraman added inline comments.Jul 22 2016, 2:37 PM
lib/Transforms/IPO/InlineSimple.cpp
138 ↗(On Diff #63157)

If we want their thresholds to be controlled by a flag, we need a separate flags and create separate entry points. For example, we should add a createPrePnliner pass that should set the threshold using a -preinline-threshold flag.

Well, in that case, you need to create a separate entry point that doesn't override the passed threshold. The behavior of createFunctionInliningPass should remain unchanged. Consider -O3 for example. What should happen if you pass -O3 and -inline-threshold=1000 ?

davidxl edited edge metadata.Jul 29 2016, 11:53 AM

You

include/llvm/Analysis/InlineCost.h
114 ↗(On Diff #63157)

The renaming to Parameters has not being done.

116 ↗(On Diff #63157)

Add brief documentation on each params

132 ↗(On Diff #63157)

Should defaultThreshold be wrapped in inline-params too?

Edit: probably not. The defaultThreshold here means many different things (opt level specific default when default-threshold option is not specified, threshold passed in API, or indirect call threshold etc.) -- I hope this can be cleaned up at some point: cost analysis should just look at the InlineParams to make decisions.

eraman marked 3 inline comments as done.Jul 29 2016, 3:18 PM
eraman added inline comments.
include/llvm/Analysis/InlineCost.h
132 ↗(On Diff #63157)

I actually think it should be moved to InlineParams. It is computed by different means, but the meaning is the same - use this threshold in the absence of any other overrides. If you agree I'll move this as well.

eraman updated this revision to Diff 66184.Jul 29 2016, 3:19 PM
eraman edited edge metadata.

Address review comments and rebase.

eraman updated this revision to Diff 66210.Jul 29 2016, 6:47 PM

Move DefaultThreshold to InlineParams

davidxl accepted this revision.Jul 29 2016, 8:37 PM
davidxl edited edge metadata.

lgtm with the nit suggestion.

include/llvm/Analysis/InlineCost.h
118 ↗(On Diff #66210)

I prefer this one be called 'InlineThreshold' (to not be confused with the internal option) and document how it is set.

This revision is now accepted and ready to land.Jul 29 2016, 8:37 PM
mehdi_amini added inline comments.
include/llvm/Analysis/InlineCost.h
38 ↗(On Diff #66210)

There is no O4, did you mean O{1,2,3} here?

115 ↗(On Diff #66210)

You have a funky line return now

davidxl added inline comments.Jul 29 2016, 8:46 PM
include/llvm/Analysis/InlineCost.h
118 ↗(On Diff #66210)

Or perhaps keeping this parameter name but changing the option name to be InlineThreshold (not Default...)

davidxl added inline comments.Jul 29 2016, 8:47 PM
include/llvm/Analysis/InlineCost.h
38 ↗(On Diff #66210)

Clang driver maps O4 to O3 (so O4 is actually 'supported').

mehdi_amini added inline comments.Jul 29 2016, 8:55 PM
include/llvm/Analysis/InlineCost.h
38 ↗(On Diff #66210)

Sure, but that's a clang "compatibility option" (O4 use to trigger LTO on top of O3). On the LLVM side O4 does not exist (I'm not sure it has ever existed in LLVM).
That said, I don't really mind if you want to add O4, but clarify the situation for O1/O2.

davidxl added inline comments.Jul 29 2016, 9:00 PM
include/llvm/Analysis/InlineCost.h
38 ↗(On Diff #66210)

ok -- this should be cleaned up then (it was in the original code that got moved here).

By the way, why deprecating O4? It is common to use it to turn on LTO.

mehdi_amini added inline comments.Jul 29 2016, 9:25 PM
include/llvm/Analysis/InlineCost.h
38 ↗(On Diff #66210)
chandlerc added inline comments.Jul 29 2016, 9:39 PM
include/llvm/Analysis/InlineCost.h
38 ↗(On Diff #66210)

Because LTO requires a complete change to the compilation model -- it isn't just an optimization level.

Still further, the other optimization levels still make sense within that model. We might want -Oz, -Os, -O2, and -O3 very usefully (and with different results) when doing LTO.

I would keep O4 out of LLVM for clarity -- it is really only supposed to be a compatibility thing in Clang. We should probably mark it as deprecated or something as I switched the behavior a loooong time ago.

118 ↗(On Diff #66210)

I like calling it "default" if it is OptSize is and such are going to override it.

Which parameter were you thinking that is currently named default?

lib/Transforms/IPO/InlineSimple.cpp
34–48 ↗(On Diff #66210)

I would much prefer these command line flags remain in the InlineCost analysis and next to all the other numbers used to tune things.

silvas added a subscriber: silvas.Jul 30 2016, 8:40 PM

To clarify, this patch itself is just a NFC refactoring in preparation for the real change, right? (to prevent the existing cl::opt flags from interfering with preinline for instrumentation)

A couple nits inline.

include/llvm/Analysis/InlineCost.h
122 ↗(On Diff #66210)

Can you add a comment about what happens when the "Optional" is in its "empty" state? I assume that DefaultThreshold is used in their place but it would be good to document explicitly what happens.

lib/Analysis/InlineCost.cpp
593 ↗(On Diff #66210)

This doesn't match the LLVM naming convention for functions (should start with lower case): http://llvm.org/docs/CodingStandards.html#name-types-functions-variables-and-enumerators-properly

Also, you may want to make this 'min' function a local lambda in updateThreshold as it is only used there I think.

eraman marked 4 inline comments as done.Aug 1 2016, 2:49 PM

To clarify, this patch itself is just a NFC refactoring in preparation for the real change, right? (to prevent the existing cl::opt flags from interfering with preinline for instrumentation)

Yes. I will add a new interface to create a SimpleInliner instance for pre-inlining which will ignore the -inline.*-threshold
flags while creating the InlineParams object

include/llvm/Analysis/InlineCost.h
38 ↗(On Diff #66210)

I have changed the comment to "Use when -O3 is specified".

118 ↗(On Diff #66210)

I have changed the command line flag's variable name to InlineThreshold (in sync with the "inline-threshold" string)

122 ↗(On Diff #66210)

I've expanded the comments. Let me know if you want to add anything else specific.

lib/Analysis/InlineCost.cpp
593 ↗(On Diff #66210)

Made this into a lambda and renamed it to minIfPresent

lib/Transforms/IPO/InlineSimple.cpp
34–48 ↗(On Diff #66210)

I am a bit unsure what you were suggesting but I assume you want to move this to InlineCost.cpp as globals in llvm namespace and reference them in InlineSimple.cpp

eraman updated this revision to Diff 66388.Aug 1 2016, 2:54 PM
eraman edited edge metadata.
eraman marked 3 inline comments as done.

Address review feedback.

eraman updated this revision to Diff 67211.Aug 8 2016, 11:52 AM

Rebase and move the newly added hot-callsite-threshold flag to InlineParams.

chandlerc edited edge metadata.Aug 8 2016, 1:06 PM

Tried to be more clear below. If this still isn't making sense, maybe let's talk or use IRC?

include/llvm/Analysis/InlineCost.h
121 ↗(On Diff #67211)

nit: I find it much easier to read with vertical whitespace between the values here.

lib/Analysis/InlineCost.cpp
624 ↗(On Diff #67211)

nit: We typically name local lambdas following the variable naming conventions even though they can be called.

lib/Transforms/IPO/InlineSimple.cpp
79–81 ↗(On Diff #67211)

Sorry, I guess I wasn't clear before...

I'm specifically suggesting keeping all of this logic inside of InlineCost.cpp as how the *default* parameters get set.

If we need the ability to get custom parameters which still reflect the command line flags, there should be some API in InlineCost.h that the inliner queries to get the necessary params.

My goal here stems from two related principles:

  • The tunable flags and the constants that interact are are fundamentally in the same unit domain should live in a single place (InlineCost.{h,cpp}).
  • The inliner *passes* should have no real logic to compute thresholds, they should call well documented APIs provided by the cost layer.

A minor secondary goal -- the inliner shouldn't have to do extra work to get the defaults. Those should just be used. It is when an inliner pass wants to deviate from the defaults that it should take explicit steps and call explicit flags.

eraman marked 2 inline comments as done.Aug 8 2016, 5:53 PM
eraman added inline comments.
lib/Transforms/IPO/InlineSimple.cpp
79–81 ↗(On Diff #67211)

Thanks for the clarification. I have moved getInlineParams and other associated logic that computes the threshold from the flags to InlineCost.cpp. SimpleInliner now calls one of these methods to get an InlineParams object which gets passed to getInlineCost.

chandlerc added inline comments.Aug 8 2016, 5:56 PM
lib/Transforms/IPO/InlineSimple.cpp
79–81 ↗(On Diff #67211)

Why can't getInlineCost do this by-default?

chandlerc added inline comments.Aug 8 2016, 6:17 PM
lib/Transforms/IPO/InlineSimple.cpp
79–81 ↗(On Diff #67211)

Summarizing an in-person chat with Easwaran:

The reason is because the createInlineFunctionsPass thing below actually takes the optimization level directly as an input. Or an integer threshold.

So we need to actually pass that information along to get the correct inline params.

I suggested sinking the call to getInlineParams all the way down to that create routine so that it was completely separate from the actual pass construction. Not ideal, but not a lot of good options here. Thanks for explaining this Easwaran, I was having trouble connecting the dots. =]

eraman updated this revision to Diff 67272.Aug 8 2016, 6:37 PM
eraman edited edge metadata.

Move threshold computation logic to InlineCost.cpp

eraman added a comment.Aug 8 2016, 6:41 PM

Chandler, I have not moved the logic in getInlineParams with no arguments to InlineParams constructor since leaving the default to be a trivial constructor is preferable when the pre-inliner creates a custom InlineParams object.

chandlerc accepted this revision.Aug 8 2016, 6:57 PM
chandlerc edited edge metadata.

LGTM with a bunch of nits addressed below. Thanks for bearing with me on the layering or structure of the code here, and thanks for the nice cleanup!

include/llvm/Analysis/InlineCost.h
144 ↗(On Diff #67272)

nit: s/used/is used/

149 ↗(On Diff #67272)

You might want to document what OptLevel and SizeOptLevel can be here. We've kind-of failed to do that for a long time sadly, but I think you can at least document the requirements that the internal code places upon them even if we want to incrementally improve this later.

164–166 ↗(On Diff #67272)

nit: I would put the Params parameter in the same position as DefaultThreshold was previously here and below.

lib/Analysis/InlineCost.cpp
959 ↗(On Diff #67272)

As you're not calling a constructor I would use = for initializing. Also, auto seems appropriate here. So:

auto IndirectCallParams = Params;
1540–1545 ↗(On Diff #67272)

This seems like it might be a better fit merged into the comments for the InlineParams class? Certainly it seems like documentation for users rather than implementation documentation.

eraman marked 5 inline comments as done.Aug 9 2016, 3:53 PM
eraman added inline comments.
lib/Analysis/InlineCost.cpp
1540–1545 ↗(On Diff #67272)

This also helped me catch some stale comments about InlineParams!

eraman updated this revision to Diff 67430.Aug 9 2016, 3:54 PM
eraman edited edge metadata.
eraman marked an inline comment as done.

Address Chandler's review comments

This revision was automatically updated to reflect the committed changes.