How to enable single optimisation flags in gcc? - optimization

When using gcc, can individual optimisation flags be enabled without a -O level being specified?
gcc -ffasst-math foo.c
OR
gcc -O1 -ffast-math foo.c
Which one works?
Thanks!

Yes, you can enable individual optimization flags.
Info from the gcc man page:
-O
-O turns on the following optimization flags:
-fauto-inc-dec -fcprop-registers -fdce -fdefer-pop -fdelayed-branch -fdse -fguess-branch-probability -fif-conversion2 -fif-conversion -finline-small-functions -fipa-pure-const -fipa-reference -fmerge-constants -fsplit-wide-types -ftree-builtin-call-dce -ftree-ccp -ftree-ch -ftree-copyrename -ftree-dce -ftree-dominator-opts -ftree-dse -ftree-fre -ftree-sra -ftree-ter -funit-at-a-time
-O also turns on -fomit-frame-pointer on machines where doing so does not interfere with debugging.
-ffast-math
Sets -fno-math-errno, -funsafe-math-optimizations, -ffinite-math-only, -fno-rounding-math, -fno-signaling-nans and -fcx-limited-range.
This option causes the preprocessor macro "FAST_MATH" to be defined.
This option is not turned on by any -O option since it can result in incorrect output for programs which depend on an exact implementation of IEEE or ISO rules/specifications for math functions. It may, however, yield faster code for programs that do not require the guarantees of these specifications.

Related

CMake: pass list of compiler flags through NVCC

I am trying to compile some CUDA and I wish to display compiler warnings. Equivalent to:
g++ fish.cpp -Wall -Wextra
Except NVCC doesn't understand these, and you have to pass them through:
nvcc fish.cu --compiler-options -Wall --compiler-options -Wextra
nvcc fish.cu --compiler-options "-Wall -Wextra"
(I favour the latter form, but ultimately, it doesn't really matter.)
Given this CMakeLists.txt (a very cut-down example):
cmake_minimum_required(VERSION 3.9)
project(test_project LANGUAGES CUDA CXX)
list(APPEND cxx_warning_flags "-Wall" "-Wextra") # ... maybe others
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options ${cxx_warning_flags}>")
add_executable(test_cuda fish.cu)
But this expands to:
nvcc "--compiler-options -Wall" -Wextra ...
which is obviously wrong. (Omitting the quotes around the generator expression just lands us in broken expansion hell.)
... skip ahead several thousand iterations of Monte Carlo programming ...
I've arrived at this gem:
set( temp ${cxx_warning_flags} )
string (REPLACE ";" " " temp "${temp}")
set( temp2 "--compiler-options \"${temp}\"" )
message( "${temp2}" )
which prints out the encouraging-looking
--compiler-options "-Wall -Wextra"
But then
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:${temp2}>")
expands to:
nvcc "--compiler-options \"-Wall -Wextra\"" ...
I'm at a loss; am I onto a dead end here? Or have I missed some crucial combination of punctuation?
I'm answering my own question, since I've found a few solutions that work, but I'm still interested to hear if there is a better (read: cleaner, more canonical) way.
TL;DR:
foreach(flag IN LISTS cxx_warning_flags)
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options=${flag}>")
endforeach()
Blow-by-blow account:
I tried this:
foreach(flag IN LISTS cxx_warning_flags)
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options ${flag}>")
endforeach()
but that still gives
nvcc "--compiler-options -Wall" "--compiler-options -Wextra"
nvcc fatal : Unknown option '-compiler-options -Wall'
Adding in a temporary however:
foreach(flag IN LISTS cxx_warning_flags)
set( temp --compiler-options ${flag}) # no quotes
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:${temp}>")
endforeach()
Gives a new outcome:
nvcc --compiler-options -Wall -Wextra ...
nvcc fatal : Unknown option 'Wextra'
What I assume is happening here is that CMake is combining the repeated --compiler-options flags, but I'm just speculating.
So, I tried eliminating the spaces using an equals:
foreach(flag IN LISTS cxx_warning_flags)
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options=${flag}>")
endforeach()
Hurrah! We have a winner:
nvcc --compiler-options=-Wall --compiler-options=-Wextra ...
Epilogue:
Can we do it without the loop?
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options=${cxx_warning_flags}>")
doesn't work (--compiler-options=-Wall -Wextra), but:
string (REPLACE ";" " " temp "${cxx_warning_flags}")
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:--compiler-options=${temp}>")
does work ("--compiler-options=-Wall -Wextra").
I'm slightly surprised about this last option, but I guess it makes sense. On balance, I think the looping option is clearest in its intention.
EDIT:
In Confusing flags passed to MSVC through NVCC with CMake, I spent a lot of time discovering that it might be better to use:
add_compile_options("$<$<COMPILE_LANGUAGE:CUDA>:-Xcompiler=${flag}>")
since CMake appears to do some rationalisation of flags to remove duplicates and ambiguity, but does not realise that --compiler-options is the same as its favoured -Xcompiler.

Please explain this CMake syntax for adding compiler options to a target

I have a CMakeLists.txt which builds a number of targets. Call one foo and one bar
At the moment foo and bar both share some settings given to ccmake configuration
CMAKE_CXX_FLAGS = -W -Wall
CMAKE_CXX_FLAGS_DEBUG = -g -pg
etc
I need to add -fPIC to foo but not bar. According to this answer I want to use TARGET_COMPILE_OTIONS
target_compile_options(foo PUBLIC "$<$<CONFIG:DEBUG>:${MY_DEBUG_OPTIONS}>")
target_compile_options(foo PUBLIC "$<$<CONFIG:RELEASE>:${MY_RELEASE_OPTIONS}>")
Note that target_compile_options add [sic] options
This sounds like it's what I need but what does this syntax mean?
"$<$<CONFIG:DEBUG>:${MY_DEBUG_OPTIONS}>"
To clarify, I want to add -fPIC as an additional flag when compiling foo but not when compiling bar
Please explain the $<$< business and show me, concretely, how -fPIC would be added as a flag for foo.
Looks like $<$< falls into the generator expressions category: https://cmake.org/cmake/help/v3.0/manual/cmake-generator-expressions.7.html#manual:cmake-generator-expressions(7),
precisely into
logical expressions
So in your case,
"$<$<CONFIG:DEBUG>:${MY_DEBUG_OPTIONS}>"
expands to MY_DEBUG_OPTIONS when the DEBUG configuration is used, and otherwise expands to nothing.
So in your case you should add -fPIC for example to MY_DEBUG_OPTIONS.
To be a little bit more precise:
$<CONFIG:DEBUG>
evaluates to 1 or 0 depending weather CONFIG is DEBUG or not, respectively.
Then you will have either:
$<0:${MY_DEBUG_OPTIONS}>
or
$<1:${MY_DEBUG_OPTIONS}>
The two expressions above will evaluate in the following way:
$<0:${MY_DEBUG_OPTIONS}> will evaluate to
Empty string (ignores ${MY_DEBUG_OPTIONS})
while $<1:${MY_DEBUG_OPTIONS}> will evaluate to
Content of ${MY_DEBUG_OPTIONS}
as the documentation states.
In the last case then -fPIC will be added to one of CMAKE_CXX_FLAGS or CMAKE_CXX_FLAGS_DEBUG.

include processed prepocessor directives into `g++ -E' output

I'm having some preprocessing mishap while compiling a 3rd party library with g++.
I can see in -E output that a certain header wrapped with #ifndef SYMBOL is being bypassed. Apparently, that symbol has been defined somewhere else.
But I cannot see where because processed directives are not present in the -E output.
Is there a way to include them (as comments, probably)?
No, there is no standard way to get preprocessed directives as comments.
However, you could use g++ -C -E and the line numbers (output in lines starting with #) and the comments (which are then copied to the preprocessed form).
And you might also use the -H option (to get the included files)
The closest thing I found is the -d<chars> family of options:
-dM dumps all the macros that are defined
-dD shows where they are defined (dumps #define directives)
-dU shows where they are used (in place of #if(n)def, it outputs #define or #undef depending on whether the macro was defined)
Adding I to any of these also dumps #include directives.
The downside is only one of the three can be used at a time and they suppress normal output.
Another, less understandable downside is -dD and -dU do not include predefined macros.

Is it possible to merge coverage data from two executables with gcov/gcovr?

On one project, I'm running the test cases on three different executables, compiled with different options. Depending on the options, some code paths are taken or not. Right now, I'm only using the coverage data from one executable.
I'm using gcovr to generate a XML that is then parsed by Sonar:
gcovr -x -b -r . --object-directory=debug/test > coverage_report.xml
I have three sets of gcda and gcno files, but I don't know how to generate a global report of them.
Is there any way to do that ?
Assuming that by "compiled with different options" you mean that you compile such that you obtain different outputs after preprocessing, with the help of lcov (as mentioned by k0n3ru) I was able to do it. Here's the sample code in file sut.c:
#include "sut.h"
#include <limits.h>
int foo(int a) {
#if defined(ADD)
a += 42;
#endif
#if defined(SUB)
a -= 42;
#endif
return a;
}
with sut.h only providing the declaration of foo, and a simple main in test.c, which calls foo and prints the results. Then, with this sequence of commands I was able to create a total.info file with 100% coverage for sut.c:
> g++ --coverage -DADD test.c sut.c -o add.out
> ./add.out
> lcov -c -d . -o add.info # save data from .gdda/.gcno into add.info
> g++ --coverage -DSUB test.c sut.c -o sub.out
> ./sub.out
> lcov -c -d . -o sub.info # save again, this time into sub.info
> lcov -a add.info -a sub.info -o total.info # combine them into total.info
> genhtml total.info
Which then for sut.c shows the following results:
EDIT (Thanks to Gluttton for reminding me of adding this part): Going from the total.info file in lcov format to the Cobertura XML output should then be possible with the help of the "lcov to cobertura XML converter" provided here (although I have not tried that): https://github.com/eriwen/lcov-to-cobertura-xml
The fact that merging of coverage information is possible, however, does certainly not mean that it is a good idea to do so: Coverage, IMO, has only limited informative value regarding the quality of a test suite. Merging coverage results from different preprocessor outputs will even further decrease this value.
This is because the possibilities for developers to learn about scenarios they have not considered will be reduced: By using conditional compilation the control structure and data flow of the code can vary tremendously between preprocessor outputs - coverage information that results from 'overlaying' results from test runs for different preprocessor outputs can make a meaningful interpretation of the results impossible.

Does "clang" perform common subexpression elimination?

I try do compile my opencl kernel to llvm IR.
With the following instruction
/home/mypass/llvm/Debug+Asserts/bin/clang -I/home/ian031545/libclc/generic/include -include clc/clc.h -Dcl_clang_storage_class_specifiers -target nvptx--nvidiacl -Xclang -mlink-bitcode-file -Xclang /ian031545/libclc/nvptx--nvidiacl/lib/builtins.bc -S -emit-llvm kernel.cl -o kernel.ll
The opencl kernel's structure look like this
__kernel(){
if() x[i]=a+b+1
else x[i]=a+b+2
}
And the llvm IR after using the instruction above look like this
entry: // it perform a+b here , we say c
then part: // it perform c+1
else part: // it perform c+2
Does anyone know why does clang do this kind of optimization here ? ( we say it frontend )
Or it may not be a kind of optimization ?
I don't know why clang do this here , for what purpose ?
Can i ask clang not to do this by adding flag to the instruction above ?
Thanks in advance
Try using -O0 flag with clang.