This is an archive of the discontinued LLVM Phabricator instance.

[Inliner] Teach the inliner to propagate attributes that have specific effects on inlining thresholds when we happen to inline into the entry (extended) basic block.
Needs ReviewPublic

Authored by chandlerc on Aug 14 2017, 6:04 PM.

Details

Summary

The fundamental idea here is to address a fragility in the bottom-up
inliner. When inlining a call edge it can *erase* information which
would otherwise very dramatically impact the inlining heuristics. We've
seen this before with noalias and alignment parameter attributes and
addressed them with scoped aliasing information and assumptions
respectively.

However, another aspect of information that may be lost are the
inlinehint and cold attributes which can have a significant impact
on inlining thresholds. Specifically, there is an assymetry in how these
end up being handled depending on whether we happen to successfully
defer inlining during the bottom-up walk or not.

If we defer inlining during the bottom-up walk, we will *also* end up
"propagating" the inlinehint and cold up one level of the call graph
by inlining the wrapper function first and then re-considering the new
call edge which still has these attributes.

If we *don't* defer inlining, then we will inline into the function and
lose these attributes. Later on, we may simplify away everything else
and end up forming an *exact copy* of the original function body. But
because the inlining step lost these attributes this copy of the
original function body will inline substantially differently (either too
little in the case of inlinehint or too much in the case of cold).

With this patch, we try to detect the obviously safe cases where we are
inlining into a callsite that could easily simplify into a trivial
wrapper by looking for callsites in the (extended) entry block. This
also makes it easy to ensure that the callsite is reached for the case
of the cold attribute that may be a dynamic property.

The goal here is mostly to make inlining decisions a bit more
predictable. We should still work on improving the logic around
deferring inlining during the bottom-up walk to find better inlining
candidates, this should just be a useful backstop to ensure that in
addition to missing the deferral opportunity we don't *also* erase
valuable inlining attributes.

An example of a case today that is highly surprising (and motivates this
patch) would be a trivial lambda function passed to STL algorithms. The
operator()s on this lambda object may not be marked with inlinehint,
but it may be a trivial wrapper around some other function which is
marked with inlinehint. It is then surprising when the inliner
"erases" this information and makes different (in either direction)
inlining decisions through the wrapper than it would through a direct
call to the member function. This pattern has actually shown up in a few
benchmarks.

So far, initial benchmarking has shown no substantial performance swings
either direction, but I'm still collecting more precise numbers. I just
wanted to get this out for review.

Depends on D36722.

Event Timeline

chandlerc created this revision.Aug 14 2017, 6:04 PM
davidxl edited edge metadata.Aug 14 2017, 6:20 PM

I will provide more comments on propagating the inline hint later. However, I do think it is wrong to propagate the cold attribute in inliner -- there should be already an inter-procedural attribute propagation pass that does this.

I will provide more comments on propagating the inline hint later. However, I do think it is wrong to propagate the cold attribute in inliner -- there should be already an inter-procedural attribute propagation pass that does this.

While I'd love to teach our IPO attribute propagation to do that, we might still need to do it here. The inliner might make the opportunity for this propagation visible and then delete the call removing the chance to do it all within a single pass run, and the interprocedural pass never get a chance to see the intermediate state.

sanjoy resigned from this revision.Jan 29 2022, 5:33 PM