How to visualise Clang optimisation phases

When I'm trying to understand how or why the back end does something
I've found the -view-* options to llc to be useful. It's not ideal,
because "clang" doesn't take those options, so I have to invoke first
"clang" and then "llc", and sometimes that combination gives different
final code from invoking just "clang", but usually I can construct a
simple example in which "clang" and "clang | llc" give the same output
and then use -view-legalize-dags, etc with "llc".

However, when I'm trying to understand an optimisation that happens
(or doesn't happen) earlier on in the compiler I've found this
approach sometimes doesn't work at all. If I invoke "clang" with no
optimisation options then the optimisation I'm interested in has
already happened before the bitcode is generated, but if I invoke
"clang" with -O0 then "llc" doesn't do it either and the optimisation
doesn't happen at all.

Is there a way of tracing what "clang" actually does and extracting
the intermediate representation between the phases?

Or is this a question for cfe-dev?

(I'm currently trying to understand how some conditional expressions
are optimised.)

Thanks for any advice.

Having a look at clang's source, you can find in
"lib/CodeGen/BackendUtil.cpp" the functions where clang builds the
passes to emit code. The optimization passes used are there and you can
simulate them via the "opt" utility, by running each pass one at a time.
LLVM also declares standard module/function passes on
include/llvm/Support/StandardPasses.h. Have a look and see if that's
what you want.

Having a look at clang's source, you can find in
"lib/CodeGen/BackendUtil.cpp" the functions where clang builds the
passes to emit code. The optimization passes used are there and you can
simulate them via the "opt" utility, by running each pass one at a time.
LLVM also declares standard module/function passes on
include/llvm/Support/StandardPasses.h. Have a look and see if that's
what you want.

Thanks.

Here's a very simple example where I can't get llc do what clang does. Just taking

int f(int a, int b)
{
  return a + b;
}

and compiling it on the one hand with

clang -cc1 -O3 x.c -S -o 1.s

and on the other hand with

clang -cc1 -O0 x.c -emit-llvm-bc -o - | llc -O3 -o 2.s

gives different code because in the latter case the output includes some pointless writes to the stack. Is the non-volatile character of those writes already lost in the output from clang -cc1 -O0?

I don't think I used to have this problem. Perhaps the command-line interface has changed while I wasn't paying attention.

Hello Edmund-

In the second invocation, you're not running the usual set of IR optimisations, only the backend optimisations.

Try :

clang -cc1 -O0 x.c -emit-llvm-bc -o - | opt -std-compile-opts | llc -O3 -o 2.s

Alistair