[LLVMdev] [RFC] CodeGen Context

Bob Wilson bob.wilson at apple.com
Sun Oct 13 14:35:35 PDT 2013


On Oct 12, 2013, at 1:55 AM, Bill Wendling <isanbard at gmail.com> wrote:

> Hi all,
> 
> This is my proposal for how to solve the problem we have with function attributes that affect code generation changing between functions. (This is mostly a problem for LTO.)
> 
> Please take a look at this proposal, and let me know if you have any questions or comments.
> 
> Cheers!
> 
> -bw

Thanks, Bill.  I do have some comments, but first I want to apologize for not sending them earlier.  Bill had asked for feedback before sending this out to a wider audience but I didn’t get to it until now.  Sorry Bill!

[ background description removed ]

> 
> CGContext ::
> 
> A central repository for back-end objects. The back-end objects may change, so
> they should not be "cached" by individual passes. This is analogous to the
> current TargetMachine object. The term "CGContext" is used because it
> separates the current implementation from the "ideal" implementation.

I’m pretty strongly opposed to introducing this new CGContext thing.  We already have TargetMachine to collect all the target-specific information.  With function attributes, the target info may depend on which function is being compiled, so we should just fix the TargetMachine APIs where necessary to let you specify the function.  You describe the proposed CGContext as being analogous to TargetMachine, so let’s just keep TargetMachine and make it do what we need.

> 
> Important Options ::
> 
> Those options which affect back-end object construction.
> 
> --------------------------------------------------------------------------------
> 
> So, the back-end has to be prepared for "important options" to change. The ideal
> solution would be for the back-end to query the CGContext any time it needs
> information on how to generate code.  Unfortunately, this isn't currently
> feasible, because of how back-end objects are constructed, though it is
> something worth striving for. As such, there are four goals we want to achieve:
> 
> 1. As many options as possible should be queried via the back-end directly
>  rather than relying upon objects holding onto these options,

I’m not quite sure what you mean by “queried via the back-end directly”.  Here’s what I propose:  When constructing a target-specific instance of MachineFunctionInfo, any “simple” function attributes that the target backend may need to query should be read from the IR (per goal 3 below) and recorded in the MachineFunctionInfo object.  Target-independent function attributes can be handled in the MachineFunctionInfo base class.  The information will then be retrieved as needed from the MachineFunctionInfo object.

> 
> 2. Those which affect how objects are generated require those objects to be
>  regenerated when the important options change,

This whole notion of options “changing" is just wrong.  It is inherently tied to a sequential compilation process where we handle one function at a time.  See goal 4 below.  We can’t have a single CGContext that just returns information about “the current function”.  The right API should take the function as an argument.

> 
> 3. There is no more dependence upon IR-level code. I.e., the back-end would
>  still function if the IR code were deleted, and
> 
> 4. Not prevent the back-end from being parallelized.
> 
> Some things to note:
> 
> * Recreating the back-end for each changing set of important options is
> expensive. A simple test showed that there is a measurable slowdown in the
> worst-case scenario where the back-end is recreated for every function.
> 
> * Object creation in the back-end has a high order of coupling. I.e., one
> object creates another object, which uses the original object, and may
> create other objects dependent upon previous objects, etc.
> 
> * Most functions should have the same set of important options, thus reducing
> the need to regenerate the back-end objects for each function.
> 
> * Some objects are created on demand, and may change during code generation.
> 
> This is a simple model of how command line options and function attributes will
> be pass through the compiler from the front-end to the middle-end and finally
> the back-end:
> 
> The front-end generates the functions with appropriate function attributes taken
> from command line options. Because the front-end may be dealing with IR files
> and the command line options that are currently used may be different from those
> the function was generated with, the front-end will create an "OptionContext"
> object. Options specified by function attributes may be overridden by options
> specified in the OptionContext. These are used as IR options by the middle
> end. A suitable API will be set up to make this transparent to the middle end
> *waves hands wildly*.

I’m not sure I understand.  If I do this:

$ clang -mavx -flto -c file1.c
$ clang -mno-avx file1.o file2.c

that the -mno-avx should win and that file1.c will be compiled without AVX support?

Maybe I missed some earlier discussion, but that seems really wrong to me.  We need the front-end settings to be consistent with the code-gen options.  Whatever options are specified when running the front-end should be preserved without overrides in the bit code.

> 
> The function attributes and options context are used to generate the CGContext.
> All IR passes, that need to know about target data, and code-generation passes
> will query the CGContext for all information needed to construct the back-end.
> When important options change (based on a new function's attributes), the
> context can transparently reconstruct the objects that are affected. To minimize
> time spent recreating the back-end objects, they can be cached.
> 
> Have some ASCII art:
> 
>            ,---------------.
>        ::  | OptionContext | --.
>        |   `---------------'   |   ,------------.
> Front End |                       |-->| IR Options |   :: Middle End
>        |  ,----------------.   |   `------------'
>        :: | Function Attrs |---+-.
>           `----------------'     |    ,-----------.
>                                  `--> | CGContext | :: Back End
>                                       `-----------'
> 
> The CGContext will transparently recreate any objects it needs to. This means
> that back-end code won't be able to cache any of the objects the CGContext
> creates (this has already been addressed).
> 
> The CGContext can be reached through the MachineFunction object:
> 
> CGContext &context = MF->getContext();
> const TargetFrameLowering *TFL = context->getFrameLowering();
> 
> if (TFL->getStackGrowthDirection() == TargetFrameLowering::StackGrowsUp) {
>   // ...
> }
> 
> Currently, the best place to process the function attributes is towards the
> beginning of the `SelectionDAGISel::runOnMachineFunction()' method. This has one
> side-effect --- the CGContext may not be available to IR passes which use
> it. This will need to be addressed on a case-by-case basis. One option is to
> have the pass manager populate the CGContext at the point in the pipeline where
> we begin lowering.
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu         http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev





More information about the llvm-dev mailing list