[LLVMdev] Embedding cpu and feature strings into IR and enabling switching subtarget on a per function basis

Akira Hatanaka ahatanak at gmail.com
Tue Jan 27 09:36:53 PST 2015


On Mon, Jan 26, 2015 at 9:53 PM, Eric Christopher <echristo at gmail.com>
wrote:

> Hi Akira,
>
> A bit of a follow up to my earlier email with some review on the patches
> themselves. Some of them I think are good and some I think need some
> thought.
>
> +  Options.CPUStr = MCPU;
> +  Options.FeaturesStr = MAttrs;
>
> I'd definitely like to avoid having the CPU and Feature string on
> TargetOptions. Ideally the only things that are going to be on there are
> global options that can't be anywhere else - and I'd really like to
> investigate module flags here as well. I know we've had some discussion on
> that, and I've got my own opinions, but in general anything that's per
> function needs to be kept on the functions and anything that's general
> should be kept on the module.
>
>
I added CPU and Feature string to TargetOptions to enable tools like llc to
override the function attributes in the IR with command line options. The
code which does subtarget lookup in
X86TargetMachine::getSubtargetImpl(const Function&) in won't pick the CPU
string in TargetOptions if there is a function attribute "target-cpu" in
the IR. This means if you try to compile an IR that has function attribute
"target-cpu" == "cpu1" with command "llc -mcpu=cpu2 ...", "cpu1" will be
used to construct subtarget, and that's not what users of llc expect (at
least that's my understanding). The TargetOptions::Option class has a bit
to indicate whether the command line options was specified, which enables
the function attribute to be overridden (see function
llvm::getFnAttributeVal in the patch).

+  template <typename STC> const STC &getSubtarget(const Function *F) const
> {
> +    return *static_cast<const STC*>(getSubtargetImpl(*F));
>
> Right. Though you missed getSubtargetImpl above, etc. A lot of the passes
> and backends use it rather than the other way around. I'm pulling them out
> and more help is definitely good. As I said in my first email perhaps the
> TTI->FTTI transition is a good place to start working here without having
> to worry much about redoing huge swaths of llvm.
>
>
Yes, getSubtargetImpl should be fixed too.


> -    : Fn(F), Target(TM), STI(TM.getSubtargetImpl()),
> Ctx(mmi.getContext()),
> +    : Fn(F), Target(TM), STI(TM.getSubtargetImpl(*F)),
> Ctx(mmi.getContext()),
>
> This is obviously fine, but I've been avoiding this so that we don't have
> partial implementations in flight. I.e. if you do this then code that looks
> like what we want in the future will start being ... halfway code generated.
>
> +  // Find the first function defined in the module and copy the cpu and
> +  // feature string to Options.
>
> Very much against this.
>
>
I'm trying to avoid passing an empty CPU and features string to
createTargetMachine (and constructor of the module-level subtarget) here.
This won't be needed if the module-level subtarget aspect is going to be
removed completely.


>  // FIXME: This should stop caching the target machine as soon as
>  // we can remove resetOperationActions et al.
> -X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM)
> -    : TargetLowering(TM) {
> -  Subtarget = &TM.getSubtarget<X86Subtarget>();
> +X86TargetLowering::X86TargetLowering(const X86TargetMachine &TM,
> +                                     const X86Subtarget *ST)
> +    : TargetLowering(TM), Subtarget(ST) {
>
> If we get rid of resetOperationActions then we don't need to do this and
> it only takes the X86Subtarget here.
>
>
OK. I see there is more work to do here.


> -    : LLVMTargetMachine(T, TT, CPU, FS, Options, RM, CM, OL),
> +    : LLVMTargetMachine(T, TT, Options.CPUStr.val(),
> Options.FeaturesStr.val(),
> +                        Options, RM, CM, OL),
>        TLOF(createTLOF(Triple(getTargetTriple()))),
>        DL(computeDataLayout(Triple(TT))),
> -      Subtarget(TT, CPU, FS, *this, Options.StackAlignmentOverride) {
> +      Subtarget(TT, Options.CPUStr, Options.FeaturesStr, *this,
> +                Options.StackAlignmentOverride) {
>
> Again, I don't think this is the right way to go. The default CPU and FS
> can quite easily just be what's default in the module, there's no need to
> do this.
>
> Anyhow, it's definitely the direction I've been headed, I think there's
> some disconnect on how various things related to options should go and
> there's a lot of work that can be done in the meantime. I'll see what I can
> do to write up a more detailed plan of attack and start listing good places
> to start working on this (or complicated and hard ones if you'd like, there
> are a few of those left as well!)
>
>
Yes, a detailed plan would definitely help, although I think it's getting a
little clearer what needs to be done.

Thanks!
>
> -eric
>
>
> On Mon Jan 26 2015 at 4:28:41 PM Akira Hatanaka <ahatanak at gmail.com>
> wrote:
>
>> I've been investigating what is needed to ensure command line options are
>> passed to the backend codegen passes during LTO and enable compiling
>> different functions in a module with different command line options (see
>> the links below for previous discussions).
>>
>> http://thread.gmane.org/gmane.comp.compilers.llvm.devel/78855
>> http://thread.gmane.org/gmane.comp.compilers.llvm.devel/80456
>>
>> The command line options I'm currently looking into are "-target-cpu" and
>> "-target-feature" and I would like to get feedback about the approach I've
>> taken (patches attached).
>>
>>
>
>
>> The attached patches make the following changes:
>>
>> - In TargetMachine::getSubtarget(const Function*) and MachineFunction's
>> constructor, use per-function subtarget object instead of TargetMachine's
>> (module-level) subtarget object. This allows passes like selection dag to
>> switch the target on a per-function basis.
>>
>> - Define class TargetOptions::Option, which records whether an option has
>> appeared on the command line along with the option's value. Long term, this
>> might not be the best solution and I expect it will be modified or replaced
>> when the new command line infrastructure becomes available.
>>
>> - Fix X86's subtarget lookup to override the function attributes if the
>> corresponding options were specified on the command line.
>>
>> - FIx clang to embed "-target-cpu" and "-target-feature" attributes in
>> the IR.
>>
>> I've tested the changes I made and confirmed that target options such as
>> "-mavx2" don't get dropped during LTO and are honored by backend codegen
>> passes.
>>
>> This is my plan for the remaining tasks:
>>
>> 1. FIx other in-tree targets and other code-gen passes that are still
>> using TargetMachine's subtarget where the per-function subtarget should be
>> used.
>>
>> 2. Fix TargetTransformInfo to compute the various code-gen costs
>> accurately when subtarget is switched on a per-function basis. One way to
>> do this is to make the pointer or reference to the Function object
>> available to the various subclasses of TargetTransformInfo by defining the
>> necessary functions in FunctionTargetTransformInfo (similar to the changes
>> made in r218004). However, passes like Inliner that are not function passes
>> cannot access FunctionTargetTransformInfo, so it has to be done in a
>> different way.
>>
>> 3. Forbid inlining functions that have incompatible cpu and feature
>> attributes. It seems the simplest approach is to allow inlining only if the
>> cpu and feature attributes match exactly, but it's also possible to relax
>> this restriction.
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150127/685080d4/attachment.html>


More information about the llvm-dev mailing list