This is an archive of the discontinued LLVM Phabricator instance.

Pass -mcmodel to LTO plugin
AbandonedPublic

Authored by khchen on Sep 10 2019, 12:01 AM.

Details

Summary

If user gives the -mcmodel with -flto, driver need to pass -code-model to LTO plugin.

Diff Detail

Event Timeline

khchen created this revision.Sep 10 2019, 12:01 AM
Herald added a project: Restricted Project. · View Herald TranscriptSep 10 2019, 12:01 AM
khchen updated this revision to Diff 220218.Sep 14 2019, 8:33 AM
khchen retitled this revision from Pass -mcmodel to gold-pulgin to Pass -mcmodel to LTO plugin.
khchen edited the summary of this revision. (Show Details)

added a test

khchen set the repository for this revision to rC Clang.Sep 14 2019, 8:41 AM

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?

@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?

@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.

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.

@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.

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)?

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.

khchen abandoned this revision.Sep 24 2019, 10:34 PM