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

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

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

Akira Hatanaka
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).


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.

_______________________________________________
LLVM Developers mailing list
[hidden email]         http://llvm.cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev

cpufs_llvm1.patch (16K) Download Attachment
cpufs_clang1.patch (4K) Download Attachment
Reply | Threaded
Open this post in threaded view
|

Re: Embedding cpu and feature strings into IR and enabling switching subtarget on a per function basis

Eric Christopher
Hi Akira,

Your patches are doing some of the things that are currently in progress, see the recent patches I've been applying in an attempt to untangle all of this.

FWIW the clang patch can be done about like this I believe (at least this is the working code I've been using):

+    // Add target-cpu and target-features work if they differ from the defaults.
+    // FIXME: Triple: x86_64-* versus CPU x86-64.
+    std::string &CPU = getTarget().getTargetOpts().CPU;
+    if (CPU != "" && CPU != getTarget().getTriple().getArchName())
+      FuncAttrs.addAttribute("target-cpu", getTarget().getTargetOpts().CPU);
+
+    std::vector<std::string> &Features =
+        getTarget().getTargetOpts().FeaturesAsWritten;
+    if (!Features.empty()) {
+      std::stringstream S;
+      std::copy(Features.begin(), Features.end(),
+                std::ostream_iterator<std::string>(S, " "));
+      // The drop_back gets rid of the trailing space.
+      FuncAttrs.addAttribute("target-features",
+                             StringRef(S.str()).drop_back(1));
+    }

The first step is to remove all uses of the module level subtarget aspect. I've got the outline for this already done for various targets. The next step is to remove the use of getSubtargetImpl() and getSubtarget<>() and replace them with the ones that take the Functions. Part of your patch does this and is a reasonable first start to get things started (though not acceptable to go in as yet). Migrating things to FunctionTargetTransformInfo where applicable (i.e. anything that uses the stashed TargetLowering instance) would be a good start for you.

Until then we can't go forward with the rest of the work. Your assistance is welcome in untangling the various bits of the infrastructure. I can highlight additional areas if you'd like.

-eric

On Mon Jan 26 2015 at 4:28:41 PM Akira Hatanaka <[hidden email]> 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).


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.

_______________________________________________
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: Embedding cpu and feature strings into IR and enabling switching subtarget on a per function basis

Eric Christopher
In reply to this post by Akira Hatanaka
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.

+  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.

-    : 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.

 // 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.

-    : 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!)

Thanks!

-eric


On Mon Jan 26 2015 at 4:28:41 PM Akira Hatanaka <[hidden email]> 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).


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.

_______________________________________________
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: Embedding cpu and feature strings into IR and enabling switching subtarget on a per function basis

Alex Rosenberg
In reply to this post by Akira Hatanaka
The chosen float ABI is also critical to pass down.

Alex

On Jan 27, 2015, at 12:28 AM, Akira Hatanaka <[hidden email]> 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).


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.
<cpufs_llvm1.patch>
<cpufs_clang1.patch>
_______________________________________________
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: Embedding cpu and feature strings into IR and enabling switching subtarget on a per function basis

Chandler Carruth-2
In reply to this post by Eric Christopher

On Mon, Jan 26, 2015 at 9:53 PM, Eric Christopher <[hidden email]> wrote:
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.

FWIW, TTI is next on my hit list for porting to the new pass manager. In order to work in that world, the entire thing needs to be simplified to not be an analysis group and it needs to be split into per-module TTI and per-function TTI. I'm working on this *right now*, but let me know if there is some other change you would like to see incorporated into this.

_______________________________________________
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: Embedding cpu and feature strings into IR and enabling switching subtarget on a per function basis

Eric Christopher


On Tue Jan 27 2015 at 12:31:20 AM Chandler Carruth <[hidden email]> wrote:

On Mon, Jan 26, 2015 at 9:53 PM, Eric Christopher <[hidden email]> wrote:
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.

FWIW, TTI is next on my hit list for porting to the new pass manager. In order to work in that world, the entire thing needs to be simplified to not be an analysis group and it needs to be split into per-module TTI and per-function TTI. I'm working on this *right now*, but let me know if there is some other change you would like to see incorporated into this.

No, this sounds great. Another place to work right now that would see some good code cleanup is the LTOCodeGeneration stuff. There's a use of the subtarget there that's not going to be safe and so the entire thing around accumulating and sorting all of the library calls needs to be rethought and rewritten.

-eric 

_______________________________________________
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: Embedding cpu and feature strings into IR and enabling switching subtarget on a per function basis

Duncan P. N. Exon Smith

> On 2015 Jan 27, at 00:37, Eric Christopher <[hidden email]> wrote:
>
>
>
> On Tue Jan 27 2015 at 12:31:20 AM Chandler Carruth <[hidden email]> wrote:
>
> On Mon, Jan 26, 2015 at 9:53 PM, Eric Christopher <[hidden email]> wrote:
> 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.
>
> FWIW, TTI is next on my hit list for porting to the new pass manager. In order to work in that world, the entire thing needs to be simplified to not be an analysis group and it needs to be split into per-module TTI and per-function TTI. I'm working on this *right now*, but let me know if there is some other change you would like to see incorporated into this.
>
> No, this sounds great. Another place to work right now that would see some good code cleanup is the LTOCodeGeneration stuff. There's a use of the subtarget there that's not going to be safe and so the entire thing around accumulating and sorting all of the library calls needs to be rethought and rewritten.

BTW, this code here is preventing LTO from "internalizing" user-provided
replacements for C library functions, since otherwise optimizations will
gut and/or delete them (and then later lower calls to them).

We need to figure out a (conservative) list up-front of which user-provided
library function replacements will be needed later.  One obvious option is
to blacklist internalizing library function replacements in *all*
subtargets (similar to this code, but visit all subtargets instead of the
"main" one).

You can see the original discussion in the archives [1][2].

[1]: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20131104/193828.html
[2]: http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20131104/193977.html
_______________________________________________
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: Embedding cpu and feature strings into IR and enabling switching subtarget on a per function basis

Akira Hatanaka
In reply to this post by Eric Christopher
Hi Eric,

On Mon, Jan 26, 2015 at 4:40 PM, Eric Christopher <[hidden email]> wrote:
Hi Akira,

Your patches are doing some of the things that are currently in progress, see the recent patches I've been applying in an attempt to untangle all of this.


I saw your recent commits that untangle all of this. Thank you for your work!
 
FWIW the clang patch can be done about like this I believe (at least this is the working code I've been using):

+    // Add target-cpu and target-features work if they differ from the defaults.
+    // FIXME: Triple: x86_64-* versus CPU x86-64.
+    std::string &CPU = getTarget().getTargetOpts().CPU;
+    if (CPU != "" && CPU != getTarget().getTriple().getArchName())
+      FuncAttrs.addAttribute("target-cpu", getTarget().getTargetOpts().CPU);
+
+    std::vector<std::string> &Features =
+        getTarget().getTargetOpts().FeaturesAsWritten;
+    if (!Features.empty()) {
+      std::stringstream S;
+      std::copy(Features.begin(), Features.end(),
+                std::ostream_iterator<std::string>(S, " "));
+      // The drop_back gets rid of the trailing space.
+      FuncAttrs.addAttribute("target-features",
+                             StringRef(S.str()).drop_back(1));
+    }


I noticed that this is setting the attributes in CodeGenModule::ConstructAttributeList instead of in CodeGenFunction::StartFunction as I did in my patch. This is probably the correct thing to do. I wonder whether these attributes should be added to function declarations, but that's another discussion.
 
Another difference is that this is passing TargetOptions::FeaturesAsWritten to the IR instead of TargetOptions::Features. Since TargetOptions::Features is passed to createTargetMachine in EmitAssemblyHelper::CreateTargetMachine (and eventually passed to subtarget constructor), I was thinking TargetOptions::Features should be written to the IR so that it can be used later to construct per-function subtarget objects.

The first step is to remove all uses of the module level subtarget aspect. I've got the outline for this already done for various targets. The next step is to remove the use of getSubtargetImpl() and getSubtarget<>() and replace them with the ones that take the Functions. Part of your patch does this and is a reasonable first start to get things started (though not acceptable to go in as yet). Migrating things to FunctionTargetTransformInfo where applicable (i.e. anything that uses the stashed TargetLowering instance) would be a good start for you.

Until then we can't go forward with the rest of the work. Your assistance is welcome in untangling the various bits of the infrastructure. I can highlight additional areas if you'd like.


I was also thinking it would be nice if the module level subtarget aspect could be removed, but I didn't realize you were already working on doing that. I think that will be a huge step towards fully enabling compiling different functions with different options. 
 
-eric

On Mon Jan 26 2015 at 4:28:41 PM Akira Hatanaka <[hidden email]> 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).


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.


_______________________________________________
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: Embedding cpu and feature strings into IR and enabling switching subtarget on a per function basis

Akira Hatanaka
In reply to this post by Eric Christopher
On Mon, Jan 26, 2015 at 9:53 PM, Eric Christopher <[hidden email]> 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 <[hidden email]> 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).


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.


_______________________________________________
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: Embedding cpu and feature strings into IR and enabling switching subtarget on a per function basis

Akira Hatanaka
In reply to this post by Alex Rosenberg
Yes, I believe float ABI will be discussed later. I'm choosing a few options at a time from the list (see the file attached to PR21471) and trying to understand what changes are necessary to pass down the options to the backend for LTO and also enable compiling function with different options.

On Tue, Jan 27, 2015 at 12:11 AM, Alex Rosenberg <[hidden email]> wrote:
The chosen float ABI is also critical to pass down.

Alex

On Jan 27, 2015, at 12:28 AM, Akira Hatanaka <[hidden email]> 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).


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.
<cpufs_llvm1.patch>
<cpufs_clang1.patch>
_______________________________________________
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