`-optc-O3` getting shadowed by automatically injected -O flags
Consider the following example:
{-# LANGUAGE CApiFFI #-}
{-# OPTIONS_GHC -optc-O3 #-}
module M where
foreign import capi unsafe "stdlib.h exit" c_exit :: Int -> IO ()
However, the -optc-O3
flag has no effect, unless ghc
is called without any -O
flags, or with -O0
.
Here's the resulting C compiler invocations for different -O
flags:
$ ghc -fforce-recomp -v -c m.hs |& grep O3
gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE -O3 -x c /tmp/ghc14023_0/ghc_2.c -o /tmp/ghc14023_0/ghc_3.s -Wimplicit -S -include /opt/ghc/8.2.1/lib/ghc-8.2.1/include/ghcversion.h -I. -I/opt/ghc/8.2.1/lib/ghc-8.2.1/base-4.10.0.0/include -I/opt/ghc/8.2.1/lib/ghc-8.2.1/integer-gmp-1.0.1.0/include -I/opt/ghc/8.2.1/lib/ghc-8.2.1/include
$ ghc -fforce-recomp -O0 -v -c m.hs |& grep O3
gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE -O3 -x c /tmp/ghc14045_0/ghc_2.c -o /tmp/ghc14045_0/ghc_3.s -Wimplicit -S -include /opt/ghc/8.2.1/lib/ghc-8.2.1/include/ghcversion.h -I. -I/opt/ghc/8.2.1/lib/ghc-8.2.1/base-4.10.0.0/include -I/opt/ghc/8.2.1/lib/ghc-8.2.1/integer-gmp-1.0.1.0/include -I/opt/ghc/8.2.1/lib/ghc-8.2.1/include
$ ghc -fforce-recomp -O1 -v -c m.hs |& grep O3
gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE -O3 -x c /tmp/ghc14073_0/ghc_2.c -o /tmp/ghc14073_0/ghc_3.s -Wimplicit -S -O -include /opt/ghc/8.2.1/lib/ghc-8.2.1/include/ghcversion.h -I. -I/opt/ghc/8.2.1/lib/ghc-8.2.1/base-4.10.0.0/include -I/opt/ghc/8.2.1/lib/ghc-8.2.1/integer-gmp-1.0.1.0/include -I/opt/ghc/8.2.1/lib/ghc-8.2.1/include
$ ghc -fforce-recomp -O2 -v -c m.hs |& grep O3
gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE -O3 -x c /tmp/ghc14093_0/ghc_2.c -o /tmp/ghc14093_0/ghc_3.s -Wimplicit -S -O2 -include /opt/ghc/8.2.1/lib/ghc-8.2.1/include/ghcversion.h -I. -I/opt/ghc/8.2.1/lib/ghc-8.2.1/base-4.10.0.0/include -I/opt/ghc/8.2.1/lib/ghc-8.2.1/integer-gmp-1.0.1.0/include -I/opt/ghc/8.2.1/lib/ghc-8.2.1/include
$ ghc -fforce-recomp -O3 -v -c m.hs |& grep O3
gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE -O3 -x c /tmp/ghc14119_0/ghc_2.c -o /tmp/ghc14119_0/ghc_3.s -Wimplicit -S -O2 -include /opt/ghc/8.2.1/lib/ghc-8.2.1/include/ghcversion.h -I. -I/opt/ghc/8.2.1/lib/ghc-8.2.1/base-4.10.0.0/include -I/opt/ghc/8.2.1/lib/ghc-8.2.1/integer-gmp-1.0.1.0/include -I/opt/ghc/8.2.1/lib/ghc-8.2.1/include
To summarise, here's the resulting effective -O
-level passed to gcc
:
GHC invocation | GCC invocation | Effective C `-O`-level |
---|---|---|
`ghc` | `gcc -O3` | `-O3` |
`ghc -O0` | `gcc -O3` | `-O3` |
`ghc -O1` | `gcc -O3 -O1` | `-O1` |
`ghc -O2` | `gcc -O3 -O2` | `-O2` |
`ghc -O3` | `gcc -O3 -O2` | `-O2` |
Consequently, the only way to have C code compiled with -O3
is to force GHC into -O0
mode; this is obviously not ideal, as it easily kills any benefit you'd gain from passing -O3
to the C compiler... ;-)
I see a few alternatives on how to resolve this:
- Have GHC recognise
-optc-O[0-9]
and suppress automatically injecting any-O<n>
of its own - Have GHC inject its automatic
-O
-flags before user-provided-optc
flags - Have GHC inject
-optc
flags as late as possible on the C compiler command-line - Implement a new variant of the
-optc
flag which injects its flags as late as possible on the C compiler command-line
Trac metadata
Trac field | Value |
---|---|
Version | 8.2.1 |
Type | Bug |
TypeOfFailure | OtherFailure |
Priority | normal |
Resolution | Unresolved |
Component | Compiler |
Test case | |
Differential revisions | |
BlockedBy | |
Related | |
Blocking | |
CC | |
Operating system | |
Architecture |