[llvm-dev] Intended behavior of CGSCC pass manager.
Sanjoy Das via llvm-dev
llvm-dev at lists.llvm.org
Mon Jun 20 13:50:14 PDT 2016
Hi David,
Xinliang David Li wrote:
> [snip]
>
> However, in real applications, what I see is the following pattern (for
> instances LLVM's Pass )
>
> Caller() {
> Base *B = Factory::create(...);
> Stash (B); // store the object in some container to be
retrieved later
> ...
> }
>
> SomeTask() {
>
> Base *B = findObject(...);
> B->vCall(); // do the work
> }
>
> Driver() {
> Caller(); // create objects ...
> SomeTask();
> }
>
> Set aside the fact that it is usually much harder to do
> de-viritualization in this case, assuming the virtual call in
> SomeTask can be devritualized. What we need is that the virtual
> functions are processed before SomeTask node, but this is not guaranteed
> unless we also model the call edge ordering imposed by control flow.
I think the thesis here is you cannot devirtualize the call in
`SomeTask` without also looking at `Caller` [0]. So the flow is:
- Optimize Caller, SomeTask independently as much as you want
* Caller -refs-> Factory::create which -refs-> the constructors
which -refs-> the various implementation of virtual functions
(based on my current understanding of how C++ vtables are
lowered); so these implementations should have been simplified by
the time we look at Caller.
- Then look at Driver. Caller, SomeTask are all maximally
simplified. We now (presumably) inline Caller and SomeTask,
devirtualize the B->vCall (as you said: theoretically possible, but
if findObject etc. are complex then practically maybe not), and now
inline the maximally simplified devirtualized call targets.
> However, this is enforcing virtual methods to be processed before their
> object's creators. Are there other simpler ways to achieve the effect
> (if we have data to justify it)?
Honestly: I'll have to think about it. It is entirely possible that a
(much?) simpler design will catch 99% (or even better) of the
idiomatic cases, I just don't have a good mental model for what those
cases are.
At this point I'm waiting for Chandler to upload his patch so that we
can have this discussion on the review thread. :)
[0]: This breaks down when we allow "out of thin air"
devirtualizations (I'm stealing this term from memory models, but I
think it is appropriate here :) ), where you look at call site and
"magically" (i.e. in a way not expressible in terms of "normal"
optimizations like store forwarding, pre, gvn etc.) are able to
devirtualize the call site. We do this all the time in Java (we'll
look at the type of the receiver object, look at the current class
hierarchy and directly mandate that a certain call site has to have a
certain target), but the RefSCC call graph does not allow for that.
These kinds of out-of-thin-air devirtualizations will have to be
modeled as ModulePass es, IIUC.
-- Sanjoy
More information about the llvm-dev
mailing list