[PROPOSAL] per-function optimization level control

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
23 messages Options
12
Reply | Threaded
Open this post in threaded view
|

[PROPOSAL] per-function optimization level control

Andrea_DiBiagio
Hello,

We've had a high priority feature request from a number of our customers
to
provide per-function optimization in our Clang/LLVM compiler.
I would be interested in working with the community to implement this.
The idea is to allow the optimization level to be overridden
for specific functions.

The rest of this proposal is organized as follows:
 - Section 1. describes this new feature and explains why and when
   per-function optimization options are useful;
 - Sections 2. and 3. describe how the optimizer could be adapted/changed
   to allow the definition of per-function optimizations;
 - Section 4. tries to outline a possible workflow for implementing this
   new feature.

I am looking for any feedback or suggestions etc.

Thanks!
Andrea Di Biagio
SN Systems Ltd.
http://www.snsys.com

1. Description
==============
The idea is to add pragmas to control the optimization level on functions.

A similar approach has been implemented by GCC as well.
Since GCC 4.4, new function specific option pragmas have been added to
allow
users to set the optimization level on a per function basis.

http://gcc.gnu.org/onlinedocs/gcc/Function-Specific-Option-Pragmas.html
describes the pragmas as
  #pragma GCC optimize ("string")
  #pragma GCC push_options
  #pragma GCC pop_options
  #pragma GCC reset_options

Instead of imitating GCC's syntax, I think it would be better to use a
syntax
consistent with existing pragma clang diagnostics:

  #pragma clang optimize push
  #pragma clang optimize "string"
  #pragma clang optimize pop

Each directive would have its own stack, which in my opinion keeps
everything
more modular and simpler to implement.

#pragma clang optimize push
#pragma clang optimize pop
  A "optimize push" will temporary push the current set of optimization
  options while a "optimize pop" could be used to pop back to the
  previous set optimization options.

#pragma clang optimize "string"
  This pragma allows to override the optimization level on
  functions defined later in the source code. Argument "string" is a
string
  that begins with 'O' and it is assumed to be an optimization level
(examples:
  "O0" for optimization level 0; "O1" for optimization level 1).
  In the future we may also extend the set of accepted strings in input to

  allow other codegen options to be overridden for specific functions.

Example:

////
#pragma clang optimize push
#pragma clang optimize "O0"
void f1() { ... }
#pragma clang optimize push
#pragma clang optimize "O2"
void f2() { ... }
void f3() { ... }
#pragma clang optimize pop
void f4() { ... }
#pragma clang optimize pop
////

Optimization level for f1 and f4 is -O0.
Optimization level for f2 and f3 is -O2.


1.1 Why it is useful to define per-function optimization levels
===============================================================
The main motivation of our customers is to be able to selectively disable
optimizations when debugging one function in a compilation unit, in the
case
where compiling the whole unit at -O0 would make the program run too
slowly.

Being able to set the optimization level on a per function basis can also
help in those cases where we know that there is a problem in an
optimization
but for some reasons either
 a) we don't know which optimization is performing the wrong
    transformation or
 b) we know the problematic Pass, however there is not an easy way
    to workaround the problem and fixing it would take too much time or
 c) there is an unknown error in the code being compiled that only causes
    problems when optimized (example: the code breaks strict aliasing).

If we know that the bug only affects few functions in the code, we could
think of disabling optimizations for those functions only. This would
allow us
to provide quick workarounds to customers encountering optimization bugs.

2. CHANGES REQUIRED IN clang
============================
Clang must be able to parse the new "pragma clang optimize".
The idea is that optimization levels would be codified as IR attributes to
functions.

A discussion on how to codify the optimization levels in LLVM was
originally
started by Chandler here:
lists.cs.uiuc.edu/pipermail/llvmdev/2013-January/058112.html

3. CHANGES REQUIRED IN LLVM
===========================
The global optimization level strongly affects how Passes are added
to PassManagers.

Example:
When the global optimization level is -O0,
method PassManagerBuilder::populateModulePassManager
[in lib/Transforms/IPO/PassManagerBuilder.cpp] populates the per-module
pass manager with the following passes:
 - AlwaysInliner (if inlining is not disabled)
 - extra Passes which may have been registered as extensions
   "to be enabled at optimization level 0".

With an optimization level bigger than zero however
several analysis and transform passes are potentially added to
the "per-module" pass manager.

The major problem with this approach is that both the optimizer
and the backend work under the assumption that the set of codegen options
is the same for all modules and functions.
This also means that the sequence of passes to run is fixed at each
optimization
level and cannot be dynamically changed or adapted. If a FunctionPass is
scheduled for running then it will be always run on all functions in the
code
(i.e. there is no way to control which passes to run on a per-function
basis).

One solution to allow the definition of optimization levels on a
per-function
basis is to implement a "common" pipeline of passes for all optimization
levels.

Rather than statically composing the sequence of passes to run, we
could instead teach pass managers how to dynamically select which passes
to run
based on the knowledge of pass constraints.

A pass constraint could be used to specify at which optimization levels it
is
safe to run the pass. Constraints on passes could be made available for
example
through the global PassRegistry, in which case the pass managers would
then be
able to query the registry to obtain the constraints.

In conclusion, we could teach PassManagers how to retrieve constraints on
passes and which passes to run taking into account both:
 - the information stored on Pass Constraints and
 - the optimization level associated to single functions (if available);

3.1 How pass constraints can be used to select passes to run
------------------------------------------------------------
A pass with no constraints can always be run at any optimization level.

A Pass P is run by a PassManager if and only if its constraints match the
"effective" optimization level (see below the definition of effective
optimization level).

By default the effective optimization level for all passes is equal
to the global optimization level (i.e. the command line based
optimization level).

The effective optimization level for a Pass running on a function F
(or a basic block BB) is the optimization level overridden by F
(or by the function containing BB). If F does not specify any optimization
level
then the effective optimization level is set equal to the
global optimization level.

It is the responsibility of the pass manager to check the effective
optimization
level for all passes with a registered set of constraints.

Example:
--------

The following sequence of passes are given: A,B,C,D,E.
Pass constraints are:
  1. A is only run at OptLevel == 0
  2. B is only run at OptLevel > 0
  3. D is only run at OptLevel > 1

Given the following scenario where:
 - the global optimization level is set equal to 2 and
 - there are two IR functions, namely Fun1 and Fun2, where:
   * Fun1 does not override the default optimization level;
   * Fun2 overrides the optimization level to -O0;
   * Fun3 overrides the optimization level to -O1.

The table below describes the relationship between functions and
passes that are expected to be run on them.
Boxes with an 'X' in them represent the pass being allowed to run on the
function.

        \  A   B   C   D   E
         +---+---+---+---+---+
 Fun1    |   | X | X | X | X |
         +---+---+---+---+---+
 Fun2    | X |   | X |   | X |
         +---+---+---+---+---+
 Fun3    |   | X | X |   | X |
         +---+---+---+---+---+
 
In the case of Fun1, the effective optimization level is equal
to the global optimization level (i.e. 2). Therefore
the PassManager will skip pass A and run passes B,C,D,E on it.

In the case of Fun2, the effective optimization level is
set equal to 0 since Fun2 overrides it.
The Pass Manager will therefore run Passes A,C,E on it.

In the case of Fun3, the PassManager will run B,C,E.

3.2 How to deal with size levels
--------------------------------
By default, clang sets the optimization level to 2 when either option
"-Os" or
"-Oz" is specified. See for example in clang how function
`getOptimizationLevel'
is implemented (in File lib/Frontend/CompilerInvocation.cpp).
This is also true for the 'opt' tool but not for bugpoint which
only accepts options -O1, -O2, -O3 to control the optimization level.

In addition to "-Os" and "-Oz" clang also accepts option "-O".
By default "-O" has the effect of setting the optimization level to 2.

Internally, clang differentiates between optimization level and "size
level".
Option "-Os" has the effect of setting the SizeLevel to 1, while option
"-Oz"
has the effect of setting the SizeLevel to 2.

Pass Constraints should allow the definition of constraints on both
the optimization level and the size level.

The effective optimization level described in 3.1 used by the pass
managers must
take into account both the optimization and the size level.

3.3 How Pass Constraints could be implemented
---------------------------------------------
Constraints on the optimization level could be implement as pairs of
values of
the form of (minOptLevel,maxOptLevel), where:
 - minOptLevel is the minimum allowed optimization level;
 - maxOptLevel is the maximum allowed optimization level.

Similarly, constraints on the size level could be implemented as pairs of
values
of the form (minSizeLevel,maxSizeLevel).
 
Examples:
A Pass with optimization constraints (0,0) is a Pass that can only be run
at -O0
while a Pass with optimization constraints (1,MAXOPTLEVEL) is a Pass that
can
only be run at optimization level >=1.

More than one set of constraints can be registered for each pass.
Example, a Pass with optimization constraints (2,2) and size constraints
(1,1)
is a Pass that can only be run at -Os (since "-Os" sets respectively
the optimization level to 2 and the size level to 1).

3.4 About the inlining strategy
-------------------------------
At the current state there are two strategies available in LLVM
for function inlining:
  1) Inline Always (by default only used at -O0 and -O1);
  2) Inline Simple (OptLevel >= 2).

The Inline Always strategy can be used in place of the Inline Simple
if specifically requested by the user.

The constructor of SimpleInliner (see
"lib/Transform/IPO/InlineSimple.cpp")
requires that we pass a Threshold value as an argument to the constructor.

In general, the threshold would be set by the front-end (it could
be either clang or bugpoint or opt etc.) according to both the OptLevel
and
the SizeLevel.

In order to support per-function optimizations, we should modify the
existing SimpleInliner to allow adapting the Threshold dynamically based
on changes in the effective optimization level.

As a future develelopment, we might allow setting the inlining threshold
using the optimize pragma.

3.5 Backend changes
-------------------
Code generator passes would benefit from the same changes described in
Section 3. A MachineFunctionPass is also a FunctionPass, which means that
it
should always be possible to specify optimization constraints for it.

Class TargetPassConfig (see "include/CodeGen/Passes.h") provides several
methods
for populating the pass manager with common CodeGen passes.
It is the responsibility of each target to override the default behavior
for
some of the methods exposed by the TargetPassConfig interface.

Unfortunately changing how code generator passes are added to pass
managers
require that we potentially make changes on target specific parts of the
backend.

Examples:
  file "Target/X86/X86TargetMachine.cpp";
  file "Target/Sparc/SparcTargetMachine.cpp";
  file "Target/PowerPC/PPCTargetMachine.cpp" etc.

In general, changes are required in every place in the backend where
decisions
are made based on the optimization level.
More specifically, changes are required in the following components:
  1. Instruction Selector:
    -- Use the effective optimization level to decide whether FastISel
       should be enable/disable;
  2. Register Allocator:
    -- Select the register allocation strategy based on the effective
       optimization level;
  3. CodeGen Passes whose behavior is affected by the global optimization
Level:
      -- TwoAddressInstructionPass
         (lib/CodeGen/TwoAddressInstructionPass.cpp)
      -- PostRASchedulerList
         (lib/CodeGen/PostRASchedulerList.cpp)

4. Proposed Implementation Workflow
===================================
The proposed work is:
 1. Add support for modeling constraints on Passes:
  - The idea is to support constraints on optimization levels.
    In future we could think of adding support for constraints on other
    codegen options using the same framework;
 2. Add support for registering constraints on passes into the
PassRegistry;
 3. Teach Pass Managers how to identify passes which are safe to be run;
 4. Adapt the existing SimpleInliner Algorithm (or add a new algorithm);
 5. Teach both the optimizer and backend how to register constraints on
passes;
 6. Define (or use the existing) IR attributes to decorate functions with
    optimization levels.
 7. Teach Clang how to parse the new #pragma optimize and also how
    to emit IR attributes for controlling the optimization level on
functions.


**********************************************************************
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 [hidden email]
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
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [cfe-dev] [PROPOSAL] per-function optimization level control

Richard Smith-33
On Wed, Apr 24, 2013 at 6:00 AM, <[hidden email]> wrote:
Hello,

We've had a high priority feature request from a number of our customers
to
provide per-function optimization in our Clang/LLVM compiler.
I would be interested in working with the community to implement this.
The idea is to allow the optimization level to be overridden
for specific functions.

The rest of this proposal is organized as follows:
 - Section 1. describes this new feature and explains why and when
   per-function optimization options are useful;
 - Sections 2. and 3. describe how the optimizer could be adapted/changed
   to allow the definition of per-function optimizations;
 - Section 4. tries to outline a possible workflow for implementing this
   new feature.

I am looking for any feedback or suggestions etc.

Thanks!
Andrea Di Biagio
SN Systems Ltd.
http://www.snsys.com

1. Description
==============
The idea is to add pragmas to control the optimization level on functions.

A similar approach has been implemented by GCC as well.
Since GCC 4.4, new function specific option pragmas have been added to
allow
users to set the optimization level on a per function basis.

http://gcc.gnu.org/onlinedocs/gcc/Function-Specific-Option-Pragmas.html
describes the pragmas as
  #pragma GCC optimize ("string")
  #pragma GCC push_options
  #pragma GCC pop_options
  #pragma GCC reset_options

Instead of imitating GCC's syntax, I think it would be better to use a
syntax
consistent with existing pragma clang diagnostics:

  #pragma clang optimize push
  #pragma clang optimize "string"
  #pragma clang optimize pop

Since the intent is to provide overrides on a per-function basis, have you considered using a function attribute instead of a pragma?

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [cfe-dev] [PROPOSAL] per-function optimization level control

Eric Christopher
Especially since we have support for per function code gen attributes now.

-eric

On Wed, Apr 24, 2013 at 3:50 PM, Richard Smith <[hidden email]> wrote:

> On Wed, Apr 24, 2013 at 6:00 AM, <[hidden email]> wrote:
>>
>> Hello,
>>
>> We've had a high priority feature request from a number of our customers
>> to
>> provide per-function optimization in our Clang/LLVM compiler.
>> I would be interested in working with the community to implement this.
>> The idea is to allow the optimization level to be overridden
>> for specific functions.
>>
>> The rest of this proposal is organized as follows:
>>  - Section 1. describes this new feature and explains why and when
>>    per-function optimization options are useful;
>>  - Sections 2. and 3. describe how the optimizer could be adapted/changed
>>    to allow the definition of per-function optimizations;
>>  - Section 4. tries to outline a possible workflow for implementing this
>>    new feature.
>>
>> I am looking for any feedback or suggestions etc.
>>
>> Thanks!
>> Andrea Di Biagio
>> SN Systems Ltd.
>> http://www.snsys.com
>>
>> 1. Description
>> ==============
>> The idea is to add pragmas to control the optimization level on functions.
>>
>> A similar approach has been implemented by GCC as well.
>> Since GCC 4.4, new function specific option pragmas have been added to
>> allow
>> users to set the optimization level on a per function basis.
>>
>> http://gcc.gnu.org/onlinedocs/gcc/Function-Specific-Option-Pragmas.html
>> describes the pragmas as
>>   #pragma GCC optimize ("string")
>>   #pragma GCC push_options
>>   #pragma GCC pop_options
>>   #pragma GCC reset_options
>>
>> Instead of imitating GCC's syntax, I think it would be better to use a
>> syntax
>> consistent with existing pragma clang diagnostics:
>>
>>   #pragma clang optimize push
>>   #pragma clang optimize "string"
>>   #pragma clang optimize pop
>
>
> Since the intent is to provide overrides on a per-function basis, have you
> considered using a function attribute instead of a pragma?
>
> _______________________________________________
> cfe-dev mailing list
> [hidden email]
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev
>
_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [cfe-dev] [PROPOSAL] per-function optimization level control

Andrea_DiBiagio
Hi,

> Especially since we have support for per function code gen attributes
now.

I think having function attributes would certainly be useful.
GCC for example provide support for both pragma and function attributes to
control per-function optimizations. Also, the effect of using pragma
optimize to control optimizations on a per-function basis is equivalent in
GCC to specifying the 'optimize' function attribute (followed by a string
describing an optimization option) for that function.

In my opinion we could also have both pragma and function attributes:
having a pragma does not mean that we cannot have function attributes.

A very common pattern that we see in our customers' code is a unity build.
 That is, in order to reduce debug data overhead, and to improve link-time
they'll group large numbers of their source files together into single
"unity files".  e.g.

// ------------------
// unity01.cpp
#include <physics.cpp>
#include <textures.cpp>
#include <renderer.cpp>
etc.
// ------------------

In some cases if they've narrowed down a problem, they'll want to debug
individual functions inside one of these files in which case an attribute
may be enough.
However, if they just know, for example, that they have a problem
somewhere in their texture code they'll often want to do something like
this:

// ------------------
// unity01.cpp
#include <physics.cpp>

#pragma clang optimize push
#pragma clang optimize "O0"
#include <textures.cpp>
#pragma clang optimize pop

#include <renderer.cpp>
etc.
// ------------------

Thanks,
-- Andrea DiBiagio


**********************************************************************
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 [hidden email]
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
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [PROPOSAL] per-function optimization level control

Renato Golin-2
In reply to this post by Andrea_DiBiagio
On 24 April 2013 14:00, <[hidden email]> wrote:
In conclusion, we could teach PassManagers how to retrieve constraints on
passes and which passes to run taking into account both:
 - the information stored on Pass Constraints and
 - the optimization level associated to single functions (if available);

I like this approach. Today, the way to know which passes are added is to look at the functions and follow the branches for O1, O2, etc. Your proposal is way cleaner and allows for a table-based approach. It also makes it simpler to experiment with passes in different optimization levels on randomized benchmarks.

I often tried to comment passes to identify bugs (that bugpoint wouldn't) and realized that it could generate many segmentation faults in the compiler, which is worrying...


 
3.1 How pass constraints can be used to select passes to run
------------------------------------------------------------
It is the responsibility of the pass manager to check the effective
optimization level for all passes with a registered set of constraints.

There is a catch here. Passes generally have unwritten dependencies which you cannot tell just by looking at the code. Things like "run DCE after PassFoo only if state of variable Bar is Baz" can sometimes only be found out by going back on the commits that introduced them and finding that they were indeed, introduced together and it's not just an artefact of code movement elsewhere.

The table I refer above would have to have the dependencies (backwards and forwards) with possible condition code (a virtual method) to define if it has to pass or not, based on some context, in addition to which optimization levels they should run. In theory, having that, would be just a matter of listing all passes for O-N which nobody depends on and follow all the dependencies to get the list of passes on the PassManager.

Removing a pass from the O3 level would have to remove all orphaned passes that it would create, too. Just like Linux package management. ;)



 
Pass Constraints should allow the definition of constraints on both
the optimization level and the size level.

Yes, AND to run, OR to not run.


 
In order to support per-function optimizations, we should modify the
existing SimpleInliner to allow adapting the Threshold dynamically based
on changes in the effective optimization level.

This is a can of worms. A few years back, when writing our front-end we figured that since there weren't tests on inline thresholds of any other value than the hard-coded one, anything outside a small range around the hard-coded values would create codegen problems, segfaults, etc. It could be much better now, but I doubt it's well tested yet.


 
As a future develelopment, we might allow setting the inlining threshold
using the optimize pragma.

This, again, would be good to write randomized tests. But before we have some coverage, I wouldn't venture on doing that in real code.




Unfortunately changing how code generator passes are added to pass
managers require that we potentially make changes on target specific parts of the
backend.

Shouldn't be too hard, but you'll have to look closely if there is any back-end that depends on optimization levels to define other specific properties (cascading dependencies).



4. Proposed Implementation Workflow

I think your workflow makes sense, and I agree that this is a nice feature (for many uses). Thanks for looking into this!

cheers,
--renato

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [cfe-dev] [PROPOSAL] per-function optimization level control

Andrea_DiBiagio
In reply to this post by Andrea_DiBiagio
Hi Jonathan,

> From: Jonathan Sauer <[hidden email]>

> Have you looked at "Noise", presented at this year's European LLVM
Conference?

>
> | Noise is a language extension that allows a programmer to create
> custom optimization
> | strategies and apply them to specific code segments. This enables
> fine-grained control
> | over the optimizations applied by the compiler to conveniently
> tune code without
> | actually rewriting it.
> <http://llvm.org/devmtg/2013-04/#poster6>
>
> This seems to go into the same direction as your proposal. It's not
> yet open source,
> but it's planned: <http://www.cdl.uni-saarland.de/projects/noise/>

Thanks for the feedback.
During the poster session I had a quick chat with Ralf Karrenberg who gave
a lightning talk on project Noise.

In my understanding, their approach consists in running a sequence of
extra optimization passes on
functions and/or blocks of code (either generic compound statements or
loop statements) guarded by the NOISE keyword.
Those extra passes are run on the IR produced by Clang and before the
optimizer takes place.

Their approach does not allow for example to selectively disable passes or
in general to override optimization options for specific functions.

Also, the sequence of extra passes is always run in order based on the
sequence specified by the user through the NOISE keyword.
No changes are required for the optimizer which still works as before:
 1) pass managers are still populated based on the global optimization
level;
 2) there is no way to dynamically select passes to run based on the
per-function optimization level.

The only use case (partially) in common between my proposal and their
approach seems to be the case where the user tries to run extra
optimizations on specific functions.


**********************************************************************
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 [hidden email]
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
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [cfe-dev] [PROPOSAL] per-function optimization level control

Andrea_DiBiagio
In reply to this post by Andrea_DiBiagio
Hi,

I just wanted to bump this discussion in case anyone had any more comments
to make.

We're in a bit of a bind here as we've now had requests for this feature
from 10 separate customers, so we're going to be required to implement
this feature somehow in our private branch at least (all of the other
compilers they use already support some form of this feature so it is very
heavily used in our field).  Obviously we don't want to significantly
diverge from the mainline so it would be great to work with the community
to implement this in such a way that it could be incorporated into the
mainline and be beneficial to all of the other users too :-).

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 [hidden email]
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
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [cfe-dev] [PROPOSAL] per-function optimization level control

Rafael Espíndola
On 29 May 2013 09:28,  <[hidden email]> wrote:

> Hi,
>
> I just wanted to bump this discussion in case anyone had any more comments
> to make.
>
> We're in a bit of a bind here as we've now had requests for this feature
> from 10 separate customers, so we're going to be required to implement
> this feature somehow in our private branch at least (all of the other
> compilers they use already support some form of this feature so it is very
> heavily used in our field).  Obviously we don't want to significantly
> diverge from the mainline so it would be great to work with the community
> to implement this in such a way that it could be incorporated into the
> mainline and be beneficial to all of the other users too :-).

What is the common use case? Making sure some funtion is always
optimized or making sure it never optimized? If the second one, I
wonder if marking it cold would be a good enough approximation.

If we do need to enabled/disable passes run in each function, I would
suggest starting by proposing which attributes should be added to the
language reference.

Cheers,
Rafael
_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [cfe-dev] [PROPOSAL] per-function optimization level control

Reid Kleckner-2
On Wed, May 29, 2013 at 10:17 AM, Rafael Espíndola <[hidden email]> wrote:
On 29 May 2013 09:28,  <[hidden email]> wrote:
> Hi,
>
> I just wanted to bump this discussion in case anyone had any more comments
> to make.
>
> We're in a bit of a bind here as we've now had requests for this feature
> from 10 separate customers, so we're going to be required to implement
> this feature somehow in our private branch at least (all of the other
> compilers they use already support some form of this feature so it is very
> heavily used in our field).  Obviously we don't want to significantly
> diverge from the mainline so it would be great to work with the community
> to implement this in such a way that it could be incorporated into the
> mainline and be beneficial to all of the other users too :-).

What is the common use case? Making sure some funtion is always
optimized or making sure it never optimized? If the second one, I
wonder if marking it cold would be a good enough approximation.

If we do need to enabled/disable passes run in each function, I would
suggest starting by proposing which attributes should be added to the
language reference.

Wasn't this already proposed?

LLVM already has optsize.  Maybe it's just a matter of hooking up gcc's attr(optimize) to it in clang, as a first approximation.

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [cfe-dev] [PROPOSAL] per-function optimization level control

Rafael Espíndola
> Wasn't this already proposed?
> http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-January/058112.html
>
> LLVM already has optsize.  Maybe it's just a matter of hooking up gcc's
> attr(optimize) to it in clang, as a first approximation.

Looks like it, yes!

Chandler, what were you thoughts on the pass manager? Should it select
the set of passes for a function based on the function's attributes?

Cheers,
Rafael
_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [cfe-dev] [PROPOSAL] per-function optimization level control

Andrea_DiBiagio
In reply to the question about what would be the common use case:

> What is the common use case? Making sure some funtion is always
> optimized or making sure it never optimized? If the second one, I
> wonder if marking it cold would be a good enough approximation.

Although both cases would be nice and our users have expressed some
interest in both, the critical one is the second case of making sure that
some functions are never optimized is the most critical one.  The major
use-case for this is for ease of debugging optimized builds.  Generally,
the type of programs that our users are writing run so slowly in
unoptimized builds that they are essentially unusable for
testing/debugging purposes.  Unfortunately in fully optimized builds, as
we all know, the debugging experience is not always entirely pleasant. Our
users generally build against multiple targets each with their own
compiler and have adopted the typical workflow of marking functions and
ranges of functions that need closer inspection in the debugger with a
pragma to prevent the optimizer from coming along and hurting the
debuggability of them whilst still running with everything else fully
optimized and at a usable speed.

Rafael Espíndola <[hidden email]> wrote on 29/05/2013
16:04:47:

> > Wasn't this already proposed?
> > http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-January/058112.html
> >
> > LLVM already has optsize.  Maybe it's just a matter of hooking up
gcc's
> > attr(optimize) to it in clang, as a first approximation.
>
> Looks like it, yes!
>
> Chandler, what were you thoughts on the pass manager? Should it select
> the set of passes for a function based on the function's attributes?

Yes, Chandler's proposal goes on the same direction as our proposal. In
fact the declared goals was
"to allow a specific function to have its optimization level overridden
from the command line based level".
Our proposal tries also to focus more on how function attributes could be
used to guide pass managers in the process of selecting which passes to
run etc.

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 [hidden email]
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
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [cfe-dev] [PROPOSAL] per-function optimization level control

Ralf Karrenberg
In reply to this post by Andrea_DiBiagio
Hi Andrea,

please excuse the very delayed response, this thread somehow got out of
my sight before I found the time to respond.

As Jonathan and you have mentioned already, "Noise" is indeed going into
the same direction. Let me comment on a few of your observations:

On 5/7/13 7:02 PM, [hidden email] wrote:
> In my understanding, their approach consists in running a sequence of
> extra optimization passes on
> functions and/or blocks of code (either generic compound statements or
> loop statements) guarded by the NOISE keyword.
> Those extra passes are run on the IR produced by Clang and before the
> optimizer takes place.
>
> Their approach does not allow for example to selectively disable passes or
> in general to override optimization options for specific functions.

This is not entirely true.
We actually *do* override the general optimization options set via
command line for that specified piece of code. The intent of the noise
attribute is exactly to give the programmer *full* control over what
optimizations are applied to a given code segment (a function, loop, or
compound statement). This includes the fact that using an empty noise
attribute results in no optimization being applied.
The only thing we currently do not support is something along the lines
of "please do -O3 but exclude passes X, Y, and Z". However, this is not
a conceptual shortcoming but simply not implemented yet.

> Also, the sequence of extra passes is always run in order based on the
> sequence specified by the user through the NOISE keyword.
> No changes are required for the optimizer which still works as before:
>   1) pass managers are still populated based on the global optimization
> level;

To further clarify what I stated above: This is only true for all code
*except* the parts marked with noise attributes.

>   2) there is no way to dynamically select passes to run based on the
> per-function optimization level.

I don't understand what "dynamically" means here.

> The only use case (partially) in common between my proposal and their
> approach seems to be the case where the user tries to run extra
> optimizations on specific functions.

To sum it up, frankly, I don't think so ;).

Take a look at the examples on our webpage if you like:
http://www.cdl.uni-saarland.de/projects/noise

All of those only show what happens to the attributed functions. The
rest of the program is compiled as it would have been with an unmodified
Clang (e.g. all code that is not marked is optimized with -O3 if that is
supplied via command line).

Best,
Ralf
_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [cfe-dev] [PROPOSAL] per-function optimization level control

Evan Cheng-2
In reply to this post by Rafael Espíndola
The pass manager, as it is designed now, doesn't have the capability to dynamically change pass configurations. Until that's fixed, the only way to do this would be for clang to build multiple pass managers. That would open a can of worm though.

Evan

Sent from my iPad

On May 29, 2013, at 8:04 AM, Rafael Espíndola <[hidden email]> wrote:

>> Wasn't this already proposed?
>> http://lists.cs.uiuc.edu/pipermail/llvmdev/2013-January/058112.html
>>
>> LLVM already has optsize.  Maybe it's just a matter of hooking up gcc's
>> attr(optimize) to it in clang, as a first approximation.
>
> Looks like it, yes!
>
> Chandler, what were you thoughts on the pass manager? Should it select
> the set of passes for a function based on the function's attributes?
>
> Cheers,
> Rafael
> _______________________________________________
> LLVM Developers mailing list
> [hidden email]         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [cfe-dev] [PROPOSAL] per-function optimization level control

Dallman, John
In reply to this post by Andrea_DiBiagio
> Although both cases would be nice and our users have expressed some
> interest in both, the critical one is the second case of making sure that
> some functions are never optimized is the most critical one.  The major
> use-case for this is for ease of debugging optimized builds.

I have a similar usage case: I work on code that tends to show up optimiser
bugs, possibly because it is very thoroughly tested. Optimization control
pragmas are invaluable for locating optimizer bugs in a particular function;
the lack of them is one of the reasons why my GCC and Clang builds don't have
optimization turned up so high as on some other compilers.

--
John Dallman
-----------------
Siemens Industry Software Limited is a limited company registered in England and Wales.
Registered number: 3476850.
Registered office: Faraday House, Sir William Siemens Square, Frimley, Surrey, GU16 8QD.

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [cfe-dev] [PROPOSAL] per-function optimization level control

Xinliang David Li-2
GCC's optimize attribute should work fine (at least with trunk):

__attribute__((optimize("O3","no-tree-pre"))) int foo( ...)
{
    ...
}

will turn on -O3 for 'foo', but disable PRE pass for it.

If you see any problems there, you should file a bug.

Regarding Andrea's proposal -- the new #pragma can be useful (in rare
cases when there is a compiler bug), the intended use cases are
questionable:
1) it should not be used as a mechanism to triage compiler bugs -- the
compiler backend should have mechanism to allow any pass to be
disabled for any (range of) function(s) via command line options so
that it can be automated -- you should not expect doing this via
source modification
2) Improve debuggability of optimized code. GCC has -Og option that
can be used to generate well optimized code with good debuggability.
3) there is a much bigger issue if the customer needs to resort to
this pragmas frequently to hide optimizer bugs.



David


On Wed, Jun 12, 2013 at 8:11 AM, Dallman, John <[hidden email]> wrote:

>> Although both cases would be nice and our users have expressed some
>> interest in both, the critical one is the second case of making sure that
>> some functions are never optimized is the most critical one.  The major
>> use-case for this is for ease of debugging optimized builds.
>
> I have a similar usage case: I work on code that tends to show up optimiser
> bugs, possibly because it is very thoroughly tested. Optimization control
> pragmas are invaluable for locating optimizer bugs in a particular function;
> the lack of them is one of the reasons why my GCC and Clang builds don't have
> optimization turned up so high as on some other compilers.
>
> --
> John Dallman
> -----------------
> Siemens Industry Software Limited is a limited company registered in England and Wales.
> Registered number: 3476850.
> Registered office: Faraday House, Sir William Siemens Square, Frimley, Surrey, GU16 8QD.
>
> _______________________________________________
> LLVM Developers mailing list
> [hidden email]         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [cfe-dev] [PROPOSAL] per-function optimization level control

Ralf Karrenberg
Hi,

On 13.06.2013 20:15, Xinliang David Li wrote:
> GCC's optimize attribute should work fine (at least with trunk):
>
> __attribute__((optimize("O3","no-tree-pre"))) int foo( ...)
> {
>      ...
> }
>
> will turn on -O3 for 'foo', but disable PRE pass for it.

Indeed, the optimize attribute should do the job if you require
optimization control on function level only.

If you need finer-grained control mechanisms, you need to resort to a
pragma or attributes (or whatever kind of annotation) approach.
For instance, noise allows you to annotate loops or compound statements.

> Regarding Andrea's proposal -- the new #pragma can be useful (in rare
> cases when there is a compiler bug), the intended use cases are
> questionable:
> 1) it should not be used as a mechanism to triage compiler bugs -- the
> compiler backend should have mechanism to allow any pass to be
> disabled for any (range of) function(s) via command line options so
> that it can be automated -- you should not expect doing this via
> source modification
> 2) Improve debuggability of optimized code. GCC has -Og option that
> can be used to generate well optimized code with good debuggability.
> 3) there is a much bigger issue if the customer needs to resort to
> this pragmas frequently to hide optimizer bugs.

I agree, these are indeed questionable.
However, there is a very important use case that I would call
"performance tuning of critical code segments".

Cheers,
Ralf

>
> David
>
>
> On Wed, Jun 12, 2013 at 8:11 AM, Dallman, John <[hidden email]> wrote:
>>> Although both cases would be nice and our users have expressed some
>>> interest in both, the critical one is the second case of making sure that
>>> some functions are never optimized is the most critical one.  The major
>>> use-case for this is for ease of debugging optimized builds.
>>
>> I have a similar usage case: I work on code that tends to show up optimiser
>> bugs, possibly because it is very thoroughly tested. Optimization control
>> pragmas are invaluable for locating optimizer bugs in a particular function;
>> the lack of them is one of the reasons why my GCC and Clang builds don't have
>> optimization turned up so high as on some other compilers.
>>
>> --
>> John Dallman
>> -----------------
>> Siemens Industry Software Limited is a limited company registered in England and Wales.
>> Registered number: 3476850.
>> Registered office: Faraday House, Sir William Siemens Square, Frimley, Surrey, GU16 8QD.
>>
>> _______________________________________________
>> LLVM Developers mailing list
>> [hidden email]         http://llvm.cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
> _______________________________________________
> LLVM Developers mailing list
> [hidden email]         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>
_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [cfe-dev] [PROPOSAL] per-function optimization level control

Xinliang David Li-2
On Thu, Jun 13, 2013 at 1:40 PM, Ralf Karrenberg <[hidden email]> wrote:

> Hi,
>
>
> On 13.06.2013 20:15, Xinliang David Li wrote:
>>
>> GCC's optimize attribute should work fine (at least with trunk):
>>
>> __attribute__((optimize("O3","no-tree-pre"))) int foo( ...)
>> {
>>      ...
>> }
>>
>> will turn on -O3 for 'foo', but disable PRE pass for it.
>
>
> Indeed, the optimize attribute should do the job if you require optimization
> control on function level only.
>
> If you need finer-grained control mechanisms, you need to resort to a pragma
> or attributes (or whatever kind of annotation) approach.
> For instance, noise allows you to annotate loops or compound statements.
>


yes -- I like the fine grain control capability provided by Noise --
it will be a very useful tool for compiler engineers to find
opportunities and tune the default compiler behavior.  Using the
annotations in the source to 'permanently override compiler's
decisions won't be good as it may get stale/invalid overtime or be
invalid for different targets (e.g. unroll decisions).

>
>> Regarding Andrea's proposal -- the new #pragma can be useful (in rare
>> cases when there is a compiler bug), the intended use cases are
>> questionable:
>> 1) it should not be used as a mechanism to triage compiler bugs -- the
>> compiler backend should have mechanism to allow any pass to be
>> disabled for any (range of) function(s) via command line options so
>> that it can be automated -- you should not expect doing this via
>> source modification
>> 2) Improve debuggability of optimized code. GCC has -Og option that
>> can be used to generate well optimized code with good debuggability.
>> 3) there is a much bigger issue if the customer needs to resort to
>> this pragmas frequently to hide optimizer bugs.
>
>
> I agree, these are indeed questionable.
> However, there is a very important use case that I would call "performance
> tuning of critical code segments".

yes, and that.

thanks,

David

>
> Cheers,
> Ralf
>
>
>>
>> David
>>
>>
>> On Wed, Jun 12, 2013 at 8:11 AM, Dallman, John <[hidden email]>
>> wrote:
>>>>
>>>> Although both cases would be nice and our users have expressed some
>>>> interest in both, the critical one is the second case of making sure
>>>> that
>>>> some functions are never optimized is the most critical one.  The major
>>>> use-case for this is for ease of debugging optimized builds.
>>>
>>>
>>> I have a similar usage case: I work on code that tends to show up
>>> optimiser
>>> bugs, possibly because it is very thoroughly tested. Optimization control
>>> pragmas are invaluable for locating optimizer bugs in a particular
>>> function;
>>> the lack of them is one of the reasons why my GCC and Clang builds don't
>>> have
>>> optimization turned up so high as on some other compilers.
>>>
>>> --
>>> John Dallman
>>> -----------------
>>> Siemens Industry Software Limited is a limited company registered in
>>> England and Wales.
>>> Registered number: 3476850.
>>> Registered office: Faraday House, Sir William Siemens Square, Frimley,
>>> Surrey, GU16 8QD.
>>>
>>> _______________________________________________
>>> LLVM Developers mailing list
>>> [hidden email]         http://llvm.cs.uiuc.edu
>>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>>
>> _______________________________________________
>> LLVM Developers mailing list
>> [hidden email]         http://llvm.cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
>>
>
_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [cfe-dev] [PROPOSAL] per-function optimization level control

Dallman, John
In reply to this post by Xinliang David Li-2
> 1) it should not be used as a mechanism to triage compiler bugs -- the
> compiler backend should have mechanism to allow any pass to be
> disabled for any (range of) function(s) via command line options so
> that it can be automated -- you should not expect doing this via
> source modification

That would be just fine; I'm not seeking pragmas specifically, just a
way to control optimisation with finer distinction than a whole file.

> 3) there is a much bigger issue if the customer needs to resort to
> this pragmas frequently to hide optimizer bugs.

I'm not using them to hide optimise bugs, but to help isolate them so
that they can be reported effectively.

--
John Dallman

-----------------
Siemens Industry Software Limited is a limited company registered in England and Wales.
Registered number: 3476850.
Registered office: Faraday House, Sir William Siemens Square, Frimley, Surrey, GU16 8QD.

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [cfe-dev] [PROPOSAL] per-function optimization level control

Andrea_DiBiagio
In reply to this post by Xinliang David Li-2
Hi David,

> Regarding Andrea's proposal -- the new #pragma can be useful (in rare
> cases when there is a compiler bug), the intended use cases are
> questionable:
> 1) it should not be used as a mechanism to triage compiler bugs -- the
> compiler backend should have mechanism to allow any pass to be
> disabled for any (range of) function(s) via command line options so
> that it can be automated -- you should not expect doing this via
> source modification
> 2) Improve debuggability of optimized code. GCC has -Og option that
> can be used to generate well optimized code with good debuggability.
> 3) there is a much bigger issue if the customer needs to resort to
> this pragmas frequently to hide optimizer bugs.

Just to clarify, although in our opinion the ability to workaround
optimization
bugs is a useful side effect of this proposal, we don't consider it the
main
use case.
That's probably my fault, I should have put more emphasis on the main use
case:

"The main motivation of our customers is to be able to selectively disable
optimizations when debugging one function in a compilation unit, in the
case
where compiling the whole unit at -O0 would make the program run too
slowly."

In general, it is something that should help improve the debugging
experience when customers have to debug specific portions of their code
without sacrificing any of their overall runtime performances.
As a side note, using GCC is not a option for us.

We discussed this proposal with a number of people at the recent Bay Area
social and agreed to submit a new proposal which should be much simpler
and smaller in scope to let us achieve our primary use case by adding a
function attribute (something like: "optnone").
Hopefully I'll post this on the list early next week.

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 [hidden email]
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
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
Reply | Threaded
Open this post in threaded view
|

Re: [cfe-dev] [PROPOSAL] per-function optimization level control

Xinliang David Li-2
On Fri, Jun 14, 2013 at 4:06 AM,  <[hidden email]> wrote:

> Hi David,
>
>> Regarding Andrea's proposal -- the new #pragma can be useful (in rare
>> cases when there is a compiler bug), the intended use cases are
>> questionable:
>> 1) it should not be used as a mechanism to triage compiler bugs -- the
>> compiler backend should have mechanism to allow any pass to be
>> disabled for any (range of) function(s) via command line options so
>> that it can be automated -- you should not expect doing this via
>> source modification
>> 2) Improve debuggability of optimized code. GCC has -Og option that
>> can be used to generate well optimized code with good debuggability.
>> 3) there is a much bigger issue if the customer needs to resort to
>> this pragmas frequently to hide optimizer bugs.
>
> Just to clarify, although in our opinion the ability to workaround
> optimization
> bugs is a useful side effect of this proposal, we don't consider it the
> main
> use case.
> That's probably my fault, I should have put more emphasis on the main use
> case:
>
> "The main motivation of our customers is to be able to selectively disable
> optimizations when debugging one function in a compilation unit, in the
> case
> where compiling the whole unit at -O0 would make the program run too
> slowly."
>
> In general, it is something that should help improve the debugging
> experience when customers have to debug specific portions of their code
> without sacrificing any of their overall runtime performances.
> As a side note, using GCC is not a option for us.
>

To be clear, I am not advocating GCC at all here. Just pointing out
there is room for improvement for DOC so that user does not need to
resort to these workarounds. I know Eric Christopher  is working very
hard to make this happen for LLVM :)

thanks,

David


> **********************************************************************
> 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 [hidden email]
> 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
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
12