[llvm-dev] New Pass Manager and CGSSCPassManager
Mircea Trofin via llvm-dev
llvm-dev at lists.llvm.org
Tue Oct 20 10:36:10 PDT 2020
On Tue, Oct 20, 2020 at 10:32 AM Arthur Eubanks via llvm-dev <
llvm-dev at lists.llvm.org> wrote:
>
>
> On Tue, Oct 20, 2020 at 7:24 AM David Greene via llvm-dev <
> llvm-dev at lists.llvm.org> wrote:
>
>> Hi all,
>>
>> I've run into a sticky situation with CGSSCPassManager. I have a module
>> pass that needs to run after all inlining has occurred but *before*
>> loops have been optimized significantly. I'm not sure this is possible
>> with the way CGSCCPassManager is formulated, at least not without
>> hackery.
>>
> Could you explain what your pass does and why it needs to be where it
> needs to be?
>
>>
>> My pass has to be a module pass or a CGSCC pass because it has to add
>> global variables and function declarations. It does not otherwise modify
>> global state or the call graph SCC.
>>
>> Incidentally WRT my pass, this page about pass requirements seems
>> ambiguous:
>>
>> http://llvm.org/docs/WritingAnLLVMPass.html
>>
>> To be explicit, FunctionPass subclasses are not allowed to:
>>
>> 1. Inspect or modify a Function other than the one currently being
>> processed.
>> 2. Add or remove Functions from the current Module.
>> 3. Add or remove global variables from the current Module.
>> 4. Maintain state across invocations of runOnFunction (including global
>> data).
>>
>> #2 is ambiguous to me. Does "add or remove Functions" mean definitions
>> only or both definitions and declarations? It might be helpful to
>> clarify that in this section of the document.
>>
> At least for the NPM, it was designed with potential future concurrency in
> mind. Modifying the list of functions in a module, even just declarations,
> could mess with that. http://llvm.org/docs/WritingAnLLVMPass.html is more
> of a legacy PM tutorial. I started on
> http://llvm.org/docs/WritingAnLLVMNewPMPass.html for the NPM, I can
> clarify that there.
>
>>
>> As I understand things, CGSCCPassManager is designed to run things in a
>> bottom-up manner:
>>
>> // #1
>> for scc in scc_list {
>> inline callees everywhere
>> do other CG passes
>> for function in bottom_up(scc) {
>> run function passes
>> }
>> }
>>
>> Have I got that right? I have some questions below about this general
>> structure that are only tangentially related to my main issue.
>>
> The inliner inlines calls within the function, it doesn't look at callers
> of the current function. A CGSCC pass shouldn't look at anything above the
> current SCC. As you mentioned below, this is what makes callers see the
> most optimized version of these functions when deciding to inline or not.
>
(may be nit) not quite: see "shouldBeDeferred"
<https://github.com/llvm/llvm-project/blob/master/llvm/lib/Analysis/InlineAdvisor.cpp#L185>,
where the cost of inlining the current caller into its callers is evaluated.
> I need to be able to do something like this:
>>
>> // #2
>> for scc in scc_list {
>> inline callees everywhere
>> run my pass
>> do other CG passes
>> for function in bottom_up(scc) {
>> run function passes
>> }
>> }
>>
>> It doesn't seem possible currently because there's no adaptor to run a
>> module pass inside CGSCCPassManager. You can run a CGSCCPassManager
>> inside a ModulePassManager but not the other way around. It kind of
>> makes sense because a call graph SCC doesn't necessarily contain all of
>> the Functions in a Module. On the other hand, my pass doesn't really
>> care that it might not see all Functions in the Module in a single
>> invocation. It would eventually see them all as CGSCCPassManager
>> processes additional SCCs.
>>
>> I suppose I could make my pass a CGSCC pass but that seems like overkill
>> for my purposes. Indeed, I had no need to do this with the Old Pass
>> Manager as inlining ran in a ModulePassManager, not a CGSCCPassManager.
>>
> It doesn't really make sense to run a module pass multiple times because
> of the number of SCCs/functions. A module pass should just do everything it
> needs to do once and be done.
>
>>
>> When I first looked into this I expected the inliner SCC algorithm to
>> work something like this:
>>
>> // #3
>> for scc in scc_list {
>> for function in bottom_up(scc) {
>> inline callees into function
>> run function passes
>> }
>> do other CG passes
>> }
>>
>> But it apparently doesn't work that way. If it did I would be in really
>> bad shape because there would be no way to run my pass after all
>> inlining has occurred but before loops have been significantly altered.
>> It is functionally incorrect for my pass to modify a Function B and have
>> B inlined into the Function A which my pass also modifies.
>>
>> Another option would be to split the current CGSCC pass pipeline in two,
>> creating one pipeline for things to run before my pass and another for
>> things to run after my pass. But upstream is definitely not interested
>> in my pass so this would be a downstream change and rather burdensome to
>> maintain.
>>
>> Now for the additional questions about CGSCCPassManager mentioned above.
>>
>> From the pseudocode #1 above, it looks like all inlining happens before
>> any optimization. This seems sub-optimal to me because transformations
>> may make Functions good inline candidates when they were not previously.
>> Is this a know issue with the current setup? I'm kind of glad it works
>> like #1 (if indeed it does) because it at least makes my goal
>> theoretically attainable. But another part of me really wants it to
>> work like pseudocode #3 because it seems better for optimization.
>>
>> Thanks for all insights and help!
>>
>> -David
>> _______________________________________________
>> LLVM Developers mailing list
>> llvm-dev at lists.llvm.org
>> https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
>>
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> https://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/20201020/9e638b7e/attachment-0001.html>
More information about the llvm-dev
mailing list