-Os

When I use -Os with a clang that implicitly calls llc, I get much different code than when call clang first with -Os and then call llc.

How do I get these two paths to generate the same code?

Tia.

Reed

check that the same passes are running and check that you are getting
the same inline threshold.

When I use -Os with a clang that implicitly calls llc, I get much
different code than when call clang first with -Os and then call llc.

clang does NOT call llc internally.

How do I get these two paths to generate the same code?

Call llc with -Os?

When I use -Os with a clang that implicitly calls llc, I get much
different code than when call clang first with -Os and then call llc.

clang does NOT call llc internally.

I understand. It's invoking that functionality is what I meant to say but not technically
running that command.

How do I get these two paths to generate the same code?

Call llc with -Os?

You can't pass -Os to llc.

-Os is a clang only option. It's reflected in the IR used by llc in the function attributes.

Hi Reed,

First, make sure that it's really -Os that is generating the difference by
calling clang -v -Os, and explicitly calling all flags apart from -Os and
then compare the results. Try to mimic as many parameters in llc as
possible, with llc specific flags.

I've seen this happen when lowering to specific ARM cores and if I didn't
use the same relevant flags on both sides, the final code would be broken.

--renato

23.07.2013, 16:05, “reed kotler” <rkotler@mips.com>:

When I use -Os with a clang that implicitly calls llc, I get much
different code than when call clang first with -Os and then call llc.

clang does NOT call llc internally.

I understand. It’s invoking that functionality is what I meant to say but not technically
running that command.

This isn’t just a nitpick. This is exactly why you’re seeing differences. The pass managers aren’t always set up the same, for example.

FWIW, I feel your pain. This is a long-standing weakness of our infrastructure.

-Jim

Jim,

A while ago I proposed that we annotated the options the front-end passed
to the back-end on the IR with named metadata, but it didn't catch on.

Would it make sense to have some call-back mechanism while setting back-end
flags to keep a tab on what's called and have a dump as metadata, so that
you can just write it to the IR file at the end? More or less what we have
for functions, currently.

This would hint llc, lli and others to what flags it must set itself
(architecture, optimizations, etc) and would minimize the impact of split
compilation. Those tools are free to ignore any option it doesn't
recognize, of course, as with any metadata.

Another way would be to teach llc, lli and others all command line options
of all supported front-ends, but that wouldn't be very productive, I think.

cheers,
--renato

Maybe? I’m not sure what a good answer is here. Bob and Bill have both looked at this in more detail than I. What do you guys think?

-Jim

The plan is that all (or at least almost all) of those options will move to be function attributes. The backend will be changed to use those attributes instead of command line options. That should solve this problem.

Yes, I remember the discussion now, makes sense.

cheers,
--renato

What was the motivation for this design? Was it to save time by not creating another process, or were there other factors?

The IBM compiler for example, has all of its components in different executables. It makes debugging a lot more convenient (especially when working with large applications built with IPA).

-K

This isn’t just a nitpick. This is exactly why you’re seeing
differences. The pass managers aren’t always set up the same, for example.

FWIW, I feel your pain. This is a long-standing weakness of our
infrastructure.

What was the motivation for this design? Was it to save time by not creating another process, or were there other factors?

For having clang be one big executable rather than multiple? Yes, compile time was a very big motivator. Serializing and deserializing the intermediate state, etc, is not lightweight enough.

The IBM compiler for example, has all of its components in different executables. It makes debugging a lot more convenient (especially when working with large applications built with IPA).

Definitely. That’s why we have the separate components as well that theoretically allow us to do that sort of compartmentalized debugging.

Things get complicated in the cases where there are behavioral differences between running things all the way through in clang vs. using the piece-by-piece tools on the IR (clang -emit-llmv —> opt —> llc —> as). Thankfully, that’s not too common. It’s typically sufficient to specify the right triple and maybe one or two options for setting the cpu or something like that to reproduce an issue. When it is a problem, though, it’s a really unpleasant one. It’s also very related to the sorts of information needed to be passed along for proper LTO, so Bill’s work there will enable us to fix this problem, too.

-Jim