[LLVMdev] [RFC] add Function Attribute to disable optimization
Andrea_DiBiagio at sn.scee.net
Andrea_DiBiagio at sn.scee.net
Thu Jul 18 08:23:28 PDT 2013
So..
I have investigated more on how a new function attribute to disable
optimization on a per-function basis could be implemented.
At the current state, with the lack of specific support from the pass
managers I found two big problems when trying to implement a prototype
implementation of the new attribute.
Here are the problems found:
1) It is not safe to disable some transform passes in the backend.
It looks like there are some unwritten dependences between passes and
disrupting the sequence of passes to run may result in unexpected crashes
and/or assertion failures;
2) The fact that pass managers are not currently designed to support
per-function optimization makes it difficult to find a reasonable way to
implement this new feature.
About point 2. the Idea that came in my mind consisted in making passes
aware of the 'noopt' attribute.
In my experiment:
- I added a virtual method called 'mustAlwaysRun' in class Pass that
'returns true if it is not safe to disable this pass'.
If a pass does not override the default implementation of that method,
then by default it will always return true (i.e. the pass "must
always run" pass even when attribute 'noopt' is specified).
- I then redefined in override that method on all the optimization passes
that could have been safely turned off when attribute noopt was present.
In my experiment, I specifically didn't disable Module Passes;
- Then I modified the 'doInitialize()' 'run*()' and 'doFinalize' methods
in Pass Manger to check for both the presence of attribute noopt AND the
value returned by method 'mustAlwaysRun' called on the current pass
instance.
That experiment seemed to "work" on a few tests and benchmarks.
However:
a) 'noopt' wouldn't really imply no optimization, since not all codegen
optimization passes can be safely disabled. As a result, the assembly
produced for noopt functions had few differences with respect to the
assembly generated for the same functions at -O0;
b) I don't particularly like the idea of making passes "aware" of the
'noopt' attribute. However, I don't know if there is a reasonable way to
implement the noopt attribute without having to re-design how pass
managers work.
c) Because of a. and b., I am concerned that a change like the one
described above won't be accepted. If so however, I would be really
interested in the feedback from the community. Maybe there are better ways
to implement 'noopt' which I don't know/didn't think about?
As I said, I am not very happy with the proposed solution and any feedback
would be really appreciated at this point.
By the way, here is how I thought the 'noopt' proposal could have been
contributed in terms of patches:
[LLVM IR][Patch 1]
================
This patch extends the IR adding a new attribute called 'noopt'.
Below, is a sequence of steps which describes how to implement this patch.
1) Add a definition for attribute 'noopt' in File llvm/IR/Attribute.h;
2) Teach how attribute 'noopt' should be encoded and also how to print it
out
as a string value (File lib/IR/Attributes.cpp);
2b) Add a new enum value for the new attribute in enum LLVMAttribute
(File "include/llvm-c/Core.h");
3) The new attribute is a function attribute;
Teach the verifier pass that 'noopt' is a function attribute;
Add checks in method VerifyAttributeTypes() (File lib/IR/Verifier.cpp):
* NoOpt is a function-only attribute;
* Assert if NoOpt is used in the same context as alwaysinline;
* Assert if NoOpt is used in the same context as OptimizeForSize
(needed?);
* Assert if NoOpt is used in the same context as MinSize (needed?).
4) Add a LLVM test in test/Feature to verify that we correctly disassemble
the new function attribute (see for example file cold.ll);
5) Teach the AsmParser how to parse the new attribute:
* Add a new token for the new attribute noopt;
* Add rules to parse the new token;
6) Add a description of the new attribute in "docs/LangRef.rst";
[LLVM][Opt][Patch 2]
==================
This patch implements the required changes to passes and pass managers.
Below, is a sequence of steps which describes how to implement this patch.
1) Make the new inliner aware of the new flag.
* In lib/Transforms/IPO/Inliner.cpp:
** do not inline the callee if it is not always_inline and the caller
is marked 'noopt'.
* No other changes are required since 'noopt' already implies 'noinline'.
2) Tell the pass manager which transform passes can be safely disabled
with 'noopt'.
[CLANG][Patch 3]
===============
This patch teaches clang how to parse and generate code for functions that
are marked with attribute 'noopt'.
1) Lex
* Add a new token for the 'noopt' keyword.
* That keyword is for a function attribute.
2) Sema
* Add a rule to handle the case where noopt is passed as function
attribute.
* check that the attribute does not take extra arguments.
* check that the attribute is associated to a function declaration.
* Add the attribute to the IR Set of Attributes.
3) CodeGen
* noopt implies 'noinline.
* noopt always wins over always_inline
* noopt does not win over 'naked': naked functions only contain asm
statements. This attribute is only valid for ARM, AVX, MCORE, RL78, RX
and
SPU to indicate that the specified function does not need
prologue/epilogue
sequence generated by the compiler. (NOTE: this constraint can be
removed).
4) Add clang tests:
* in test/Sema:
** Verify that noopt only applies to functions. (-cc1 -fsyntax-only
-verify)
* in test/CodeGen:
** Check that noopt implies noinline
** Check combinations of noopt and noinline and always_inline
Andrea Di Biagio
SN Systems - Sony Computer Entertainment Group.
Andrea DiBiagio/SN R&D/BS/UK/SCEE wrote on 25/06/2013 15:20:12:
> From: Andrea DiBiagio/SN R&D/BS/UK/SCEE
> To: Nick Lewycky <nicholas at mxc.ca>
> Cc: cfe-dev at cs.uiuc.edu, llvmdev at cs.uiuc.edu
> Date: 25/06/2013 15:20
> Subject: Re: [LLVMdev] [RFC] add Function Attribute to disable
optimization
>
> Hi Nick,
>
> > From: Nick Lewycky <nicholas at mxc.ca>
> > > This proposal is to create a new function-level attribute which
would tell
> > > the compiler to not to perform any optimizing transformations on the
> > > specified function.
> >
> > What about module passes? Do you want to disable all module passes in
a
> > TU which contains a single one of these? I'll be unhappy if we need to
> > litter checks throughout the module passes that determine whether a
> > given instruction is inside an unoptimizable function or not. Saying
> > that module passes are exempt from checking the 'noopt' attribute is
> > fine to me, but then somebody needs to know how to module passes (and
> > users may be surprised to discover that adding such an annotation to
one
> > function will cause seemingly-unrelated functions to become less
optimized).
> Right, module passes are a difficult case.
> I understand your point. I think ignoring the `noopt' attribute (or
> whatever we want to call it) may be the best approach in this case:
> it avoid the problems you describe but should still be sufficient
> for the purposes we care about. I am currently studying the module
> passes in more details to be certain about this.
> Thanks for the useful feedback,
> Andrea Di Biagio
> SN Systems - Sony Computer Entertainment Group
>
> > > The use-case is to be able to selectively disable optimizations when
> > > debugging a small number of functions in a compilation unit to
provide an
> > > -O0-like quality of debugging in cases where compiling the whole
unit at
> > > anything less than full optimization would make the program run too
> > > slowly. A useful secondary-effect of this feature would be to allow
users
> > > to temporarily work-around optimization bugs in LLVM without having
to
> > > reduce the optimization level for the whole compilation unit,
however we
> > > do not consider this the most important use-case.
> > >
> > > Our suggestion for the name for this attribute is "optnone" which
seems to
> > > be in keeping with the existing "optsize" attribute, although it
could
> > > equally be called "noopt" or something else entirely. It would be
exposed
> > > to Clang users through __attribute__((optnone)) or [[optnone]].
> > >
> > > I would like to discuss this proposal with the rest of the community
to
> > > share opinions and have feedback on this.
> > >
> > > ===================================================
> > > Interactions with the existing function attributes:
> > >
> > > LLVM allows to decorate functions with 'noinline', alwaysinline' and
> > > 'inlinehint'. We think that it makes sense for 'optnone' to
implicitly
> > > imply 'noinline' (at least from a user's point of view) and
therefore
> > > 'optnone' should be considered incompatible with 'alwaysinline' and
> > > 'inlinehint'.
> > >
> > > Example:
> > > __attribute__((optnone, always_inline))
> > > void foo() { ... }
> > >
> > > In this case we could make 'optnone' override 'alwaysinline'. The
effect
> > > would be that 'alwaysinline' wouldn't appear in the IR if 'optnone'
is
> > > specified.
> > >
> > > Under the assumption that 'optnone' implies 'noinline', other things
that
> > > should be taken into account are:
> > > 1) functions marked as 'optnone' should never be considered as
potential
> > > candidates for inlining;
> > > 2) the inliner shouldn't try to inline a function if the call site
is in a
> > > 'optnone' function.
> > >
> > > Point 1 can be easily achieved by simply pushing attribute
'noinline' on
> > > the list of function attributes if 'optnone' is used.
> > > point 2 however would probably require to teach the Inliner about
> > > 'optnone' and how to deal with it.
> > >
> > > As in the case of 'alwaysinline' and 'inlinehint', I think 'optnone'
> > > should also override 'optsize'/'minsize'.
> > >
> > > Last (but not least), implementing 'optnone' would still require
changes
> > > in how optimizations are run on functions. This last part is
probably the
> > > hardest part since the current optimizer does not allow the level of
> > > flexibility required by 'optnone'. It seems it would either require
some
> > > modifications to the Pass Manager or we would have to make
individual
> > > passes aware of the attribute. Neither of these solutions seem
> > > particularly attractive to me, so I'm open to any suggestions!
> > >
> > > Thanks,
> > > Andrea Di Biagio
> > > SN Systems - Sony Computer Entertainment Group
> > >
> > >
> > >
**********************************************************************
> > > This email and any files transmitted with it are confidential and
intended
> > > solely for the use of the individual or entity to whom they are
addressed.
> > > If you have received this email in error please notify
postmaster at scee.net
> > > This footnote also confirms that this email message has been checked
for
> > > all known viruses.
> > > Sony Computer Entertainment Europe Limited
> > > Registered Office: 10 Great Marlborough Street, London W1F 7LP,
United
> > > Kingdom
> > > Registered in England: 3277793
> > >
**********************************************************************
> > >
> > > P Please consider the environment before printing this e-mail
> > > _______________________________________________
> > > LLVM Developers mailing list
> > > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
> > > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
> > >
> >
>
>
> **********************************************************************
> This email and any files transmitted with it are confidential and
> intended solely for the use of the individual or entity to whom they
> are addressed. If you have received this email in error please
> notify postmaster at scee.net
> This footnote also confirms that this email message has been checked
> for all known viruses.
> Sony Computer Entertainment Europe Limited
> Registered Office: 10 Great Marlborough Street, London W1F 7LP, United
Kingdom
> Registered in England: 3277793
> **********************************************************************
>
> P Please consider the environment before printing this e-mail
**********************************************************************
This email and any files transmitted with it are confidential and intended
solely for the use of the individual or entity to whom they are addressed.
If you have received this email in error please notify postmaster at scee.net
This footnote also confirms that this email message has been checked for
all known viruses.
Sony Computer Entertainment Europe Limited
Registered Office: 10 Great Marlborough Street, London W1F 7LP, United
Kingdom
Registered in England: 3277793
**********************************************************************
P Please consider the environment before printing this e-mail
More information about the llvm-dev
mailing list