How to make gcc uses march=native as default?
Asked Answered
C

3

6

Is there a way to change the specs file so that it will pass -march=native if nothing is specified in command line?

Related things in the default specs file is:

*cc1:
%(cc1_cpu)

*cc1_cpu:
%{march=native:%>march=native %:local_cpu_detect(arch)   %{!mtune=*:%>mtune=native %:local_cpu_detect(tune)}} %{mtune=native:%>mtune=native %:local_cpu_detect(tune)}

I am not sure how specs works. Simply specifying -march=native before or after %(cc1_cpu) doesn't work. However, this line does take effect because GCC will report error if I put -something_wierd instead of -march=native.

Another thing I noticed is if I put %{march=i386:-something_wierd} before %(cc1_cpu), gcc reports error so looks like -march=i386 is always passed in if nothing is specified, so is there a way to distinguish between nothing specified and -march=i386 in specs file?

BTW, what does %> do? Seems like it is not specified in the documentation.

I am using MinGW's gcc-4.6.2.

Convergent answered 2/1, 2012 at 22:1 Comment(0)
B
4

Referring to your last question: The gcc 4.6.1 sources (gcc/gcc.c) contain the following comment on %>:

 %>S    Similar to "%<S", but keep it in the GCC command line.

For the sake of completeness following the comment for %< form the same file:

 %<S    remove all occurrences of -S from the command line.
        Note - this command is position dependent.  % commands in the
        spec string before this one will see -S, % commands in the
        spec string after this one will not.

To answer the first question in short: yes, but ....

... the only generic solution I found has the significant drawback that the -march option will be ignored, so every build is done as if -march=native had been specified. Anyhow there is a workaround to that.

1 The solution (without workaround)

Create a specs-file called let's say specs.nativealways containing:

*cc1_cpu:
%<march=* -march=native %>march=native %:local_cpu_detect(arch) %{!mtune=*:%>mtune=native %:local_cpu_detect(tune)} %{mtune=native:%>mtune=native %:local_cpu_detect(tune)}

When using the specs-file (for example by invoking gcc with the option -specs=specs.nativealways) the build will be done as if -march=native was specified (with the mentioned drawback that any occurrence of option -march=<arch> would have simply been ignored).

2 The workaround

To still by able to override the newly configured default behavior one can use a modified version of the specs-file described above, introducing a new option called -myarch using the same syntax as -march (except for -myarch=native, which won't work, which does not metter as native now is the default).

The modfied specs-file looks like this:

*cc1_cpu:
%<march=* %{myarch=*:%<myarch* -march=%* ; :-march=native %>march=native %:local_cpu_detect(arch) %{!mtune=*:%>mtune=native %:local_cpu_detect(tune)}}  %{mtune=native:%>mtune=native %:local_cpu_detect(tune)}

PS: This has been tested with with gcc 4.6.2 on Linux, but should work on MinGW.

Beasley answered 4/1, 2012 at 16:0 Comment(1)
I actually came out with some similar solution to your first approach. I actually realized that the major problem is -march=i386 is always passed in by default and there is no way to tell if it passed in by default or through command line. I guess changing the GCC source code is almost the only way.Convergent
A
2

While not a direct answer to your question, you can reach a very similar effect by defining CFLAGS and CXXFLAGS in your shell's initialization file. 99% of the Makefiles are sufficiently standard to pick up the environment values and pass the flags to gcc.

Abeabeam answered 4/1, 2012 at 17:10 Comment(0)
C
1
*cc1_cpu:
+ %{!march*:-march=native}
Cellar answered 31/5, 2012 at 10:19 Comment(4)
this won't work, if I remember correctly (the question was too old). The reason is cc1 doesn't accept native as parameter to -march. It actually calls local_cpu_detect to have a correct value to -march.Convergent
@icando The important part is %{!march*:. This will only match if -march= is not in the command line, meaning you get a "default" if nothing else is specified. I don't know anything about the actual -march parameters.Cellar
@icando And I know this question is old. I was just looking to do something similar (set the default for g++ to be c++11 if nothing else is defined) and found my way here via Google. Once I figured out a solution to my problem, I figured I would put it here for the benefit of anyone else looking for something similar in the future.Cellar
thanks for sharing your answer. I think it may work for -std=c++11 flag, but you can see from my question, -march=i386 will be passed in if no -march is specified in the command line. So your stuff won't match anything thus takes no effect.Convergent

© 2022 - 2024 — McMap. All rights reserved.