If user gives the -mcmodel with -flto, driver need to pass -code-model to LTO plugin.
Details
Diff Detail
Event Timeline
Typically -mcmodel is passed to the clang compile invocation which sets a module flag in the IR, which is then used by LTO (see calls to Module::setCodeModel() and Module::getCodeModel()). Why is it necessary to pass through the mcmodel passed to the link invocation?
@tejohnson when I run the clang -flto -Wl,-plugin-opt=-help command, it shows the
--code-model=<value> - Choose code model =tiny - Tiny code model =small - Small code model =kernel - Kernel code model =medium - Medium code model =large - Large code model
so I think the clang driver need to pass this info to LTO codegen, does it make sense?
This is an internal LLVM option, that can be used to override the mcmodel set in the Module IR when the code was compiled into Bitcode. I don't think it makes sense to have the clang driver automatically set this internal option for the plugin, overridding what was set when the code was compiled, it can be set manually via a -plugin-opt if one needs to override for debugging etc. Why isn't the code model module flag in the Bitcode sufficient for your LTO case?
@tejohnson for example:
$ clang -flto a.c -c -o a.o $ llvm-ar q a.a a.o // archive libraries $ clang -flto a.a b.c -O2 -o main -mcmodel=small
In above case user need to aware that passing -Wl,-plugin-opt=-code-model=small to plugin is necessary.
It seems to me that is inconvenience because I believe user doesn't know it.
I think this case is similar to if a user has a bitcode library compiled with -O2 or -Oz, and link a program with -O3 -flto, what is expected behavior for user?
In general, -flto should be transparent to the build process. Think about what happens in your example if you remove -flto:
$ clang a.c -c -o a.o
$ llvm-ar q a.a a.o // archive libraries
$ clang a.a b.c -O2 -o main -mcmodel=small
a.o will be a native code built with the default mcmodel and -O0.
Generally, adding -flto shouldn't change this - I would argue that it would be unexpected to apply mcmodel=small as the user chose to compile a.c with the default mcmodel. We are going more and more toward a model where info is communicated via the IR from the compile step, as the mcmodel already is. Is there a compelling reason why a.c should not get the default mcmodel in this case (without having compiled it mcmodel=small in the first place)?
I think this case is similar to if a user has a bitcode library compiled with -O2 or -Oz, and link a program with -O3 -flto, what is expected behavior for user?
There are a few things that are passed through the link command line to the plugin for legacy reasons, including -O2/-O3. However, note that in your above example the -O2 will not cause a.o to be O2 optimized: a.c is built at -O0 and this is encoded in the IR via function attributes (noinline and optnone), so the functions will not get O2/O3 optimizations like inlining, etc.
Because this library (a.c) is provided by another user/developer.
But you are right, if -flto should be transparent to the build process, user should be aware that.
I think this case is similar to if a user has a bitcode library compiled with -O2 or -Oz, and link a program with -O3 -flto, what is expected behavior for user?
There are a few things that are passed through the link command line to the plugin for legacy reasons, including -O2/-O3. However, note that in your above example the -O2 will not cause a.o to be O2 optimized: a.c is built at -O0 and this is encoded in the IR via function attributes (noinline and optnone), so the functions will not get O2/O3 optimizations like inlining, etc.
Got it, that's helpful.
Thanks for your time and effort.