Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ability to specify target CPU features #2883

Closed
5 tasks
andrewrk opened this issue Jul 13, 2019 · 16 comments
Closed
5 tasks

ability to specify target CPU features #2883

andrewrk opened this issue Jul 13, 2019 · 16 comments
Labels
enhancement Solving this issue will likely involve adding new logic or components to the codebase. stage1 The process of building from source via WebAssembly and the C backend. zig build system
Milestone

Comments

@andrewrk
Copy link
Member

andrewrk commented Jul 13, 2019

Zig currently will take full advantage of native CPU features when compiling for the native target, however when cross compiling, there is no way to specify which CPU features to enable.

  • Add the list of possible options to zig targets so that they are discoverable
  • Add the CLI parameters to specify target CPU features
  • Make sure those options are passed to zig cc when compiling C code and don't forget to add the params to the cache hash.
  • Expose the CPU features in @import("builtin").
  • Add support to the zig build system
@andrewrk andrewrk added enhancement Solving this issue will likely involve adding new logic or components to the codebase. stage1 The process of building from source via WebAssembly and the C backend. zig build system labels Jul 13, 2019
@andrewrk andrewrk added this to the 0.6.0 milestone Jul 13, 2019
@emekoi
Copy link
Contributor

emekoi commented Jul 13, 2019

related #2595

@layneson
Copy link
Contributor

I plan to continue working on my PR (#2595) shortly. With the zig cc concern, I am thinking it might be best to keep the flag names consistent with clang/LLVM (-mcpu and -mattr), although I am not a fan of the -mattr name since even LLVM's C library uses the term "features".

@ibutra
Copy link

ibutra commented Jul 17, 2019

Can't we use the --target of clang for this? As far as I understand you can specify everything you can specify for -mcpu there. In addition the -mfloat and other options are specified with this as well. I am not sure whether the target tripple includes information about -mfpu and/or other cpu specifics?

@andrewrk
Copy link
Member Author

@ibutra Can you show an example of specifying all this information with --target? My current understanding is that only architecture, OS, and C ABI are in the target triple string.

@ibutra
Copy link

ibutra commented Jul 17, 2019

You are right I can't specify everything.
But then we should add other options as well like -mcpu, -mfpu and -mfloat-abi as is recommended by clang itself.
@layneson Can you include those options as well? Otherwise I can make a pull request just for these once yours is done (to ensure consitency).

@layneson
Copy link
Contributor

layneson commented Jul 17, 2019 via email

@andrewrk
Copy link
Member Author

andrewrk commented Jul 17, 2019

Matching the CLI of clang seems reasonable, however we do need to bring these concepts into zig land. A good start will be enumerating the options in target.hpp/target.cpp and exposing a corresponding type in @import("builtin"). Also they should be printed with zig targets.

@ibutra
Copy link

ibutra commented Jul 18, 2019

This answere on StackOverflow shows how to at least get supported cpus and attributes/features by llvm.

~I couldn't find any information about fpu yet. ~

As for the float-abi I am unsure whether this is needed as it can be specified as part of the target tripple as far as I can see. Edit: I looked into this and llvm only has the values Default,Soft and Hard so that should be covered by the target tripple.Source

And here are the fpus for ARM: Link

As far as I can see all cpus and features are defined in this folder in the .def files

@justinbalexander
Copy link
Contributor

justinbalexander commented Jul 18, 2019 via email

@layneson
Copy link
Contributor

layneson commented Jul 20, 2019

@andrewrk by "enumerating the options", do you mean enumerate all features/CPUs for each target zig supports? I ask because it is a long list that would have to be manually synchronized with LLVM, although there does not appear to be a way to query the LLVM API for the features and CPUs supported by a target (the lists are private with no clear way to retrieve them), so I am thinking that enumerating them might be the play.

@andrewrk
Copy link
Member Author

Yep that's what I mean. Currently the only backend of zig is LLVM but the language specification will not mention LLVM at all. LLVM is an implementation detail so the command line arguments and builtin declarations will not have LLVM-specific names.

andrewrk added a commit that referenced this issue Aug 1, 2019
once #2883 is done this can be revisited
andrewrk added a commit that referenced this issue Sep 25, 2019
Until ability to specify target CPU features (#2883) is done, this
commit gives riscv target better default features.

This side-steps #3275 which is a deficiency in compiler-rt when features
do not include 32 bit integer division.

With this commit, RISC-V compiler-rt tests pass and Hello World works
both pure-zig and with musl libc.
@layneson
Copy link
Contributor

layneson commented Oct 2, 2019

Here's a question concerning which CPUs and features to adopt... currently, the list of supported targets for Zig is based completely on what is available in LLVM, since that is the only backend as of now. Should all CPUs/features (defined for the targets supported by Zig) be blindly copied from LLVM? If not, this raises more questions concerning how to choose what CPUs/features to include. Otherwise, since the list of CPUs and features supported by LLVM is very long, future backends may not support all features. It seems as if a mapping between backends and supported targets/CPUs/features will be necessary, but not until a system to support multiple backends is in place.

For now, I think that mirroring LLVM's CPUs/features is appropriate. Since a "CPU" in this case is just a list of features, the mappings here will be difficult to express using the enum-and-array situation currently used to describe the available targets/subtargets. I think having a Zig analog to LLVM's FeatureBitset would be helpful here, since each CPU could have its feature set defined in static memory.

@layneson
Copy link
Contributor

I've spent a bit of time researching how LLVM features and CPUs are defined, since Zig's only backend is LLVM at the moment and thus Zig's target-specific options need to map to LLVM's. Since each target is quite different, LLVM's TableGen target description language allows arbitrary feature nesting that gets resolved at compile time.

Example: the AVR target defines Families, each of which contains the features of other Families and possibly additional features. From there, Devices are defined, each of which has an associated Family and possibly some additional features. Each Family is included in the final list of available features, as well as each "underlying" feature included in the Families. Thus, LLVM features can contain other features.

TableGen boils these hierarchies down to a list of features when it generates subtarget code. Then the frontend -mattr and -mcpu flags define the feature and cpu strings respectively, which is the unified interface for specifying options of all targets. This is why the available features for some targets are a hodge-podge of different types of values (for example, AVR's available features include architecture families and underlying features, and ARM's features include processor families, architectures, instruction sets, fpus, and features such as cryptography support).

How should Zig structure this information? LLVM has left the structure up to the targets since each one is quite different with respect to family/instruction set/subarch hierarchies. My proposal is to create abstract "catch-alls" for feature categories that should probably be separate. For instance, we could have Cpus, each of which can (optionally) include a list of base Features, Familys which contain sets of base features, and Fpus. Another option is to simplify everything by lumping all types of features together without allowing them to contain other features, and only group them within Cpuss.

A further question concerns how the initial CPU and feature data will be imported into Zig. Blindly copying LLVM will be difficult due to the arbitrary target representation mentioned above. I propose that important, well-known features be added for major targets initially, with others added as requested. This way, the new target abstractions can be tested on a minimal subset and the issues referenced above can be addressed ASAP.

Thoughts? (@andrewrk)

@andrewrk
Copy link
Member Author

@layneson Your approach sounds reasonable to me.

I propose that important, well-known features be added for major targets initially, with others added as requested. This way, the new target abstractions can be tested on a minimal subset and the issues referenced above can be addressed ASAP.

👍

For instance, we could have Cpus, each of which can (optionally) include a list of base Features, Familys which contain sets of base features, and Fpus. Another option is to simplify everything by lumping all types of features together without allowing them to contain other features, and only group them within Cpuss.

Either of these seems fine to me.

One note: I think we can probably do all of this work self-hosted (in .zig code) and call into it from stage1, like we already do for lots of stuff.

I believe the zig code would only have to expose to stage1 a function that essentially translated "zig format" CLI parameter data into "LLVM format". All the data structures, parsing, and understanding of what these features mean, etc, could be in zig code.

@andrewrk
Copy link
Member Author

Landed in 96e5f47

@Mouvedia
Copy link

Now that's fixed and #3033 has been merged, can you unskip this test?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement Solving this issue will likely involve adding new logic or components to the codebase. stage1 The process of building from source via WebAssembly and the C backend. zig build system
Projects
None yet
Development

No branches or pull requests

6 participants