On Fri, 7 Nov 2003, Michelle Strout wrote:> I plan on responding to your email to the various mailing lists, but
> first I want to run something past you.
Ok, email the lists is preferred though, because then there is an archive,
and others with similar questions can get them answered that way. I'm
CC'ing the list because some of the info in my response may be useful to
others.
> I have been messing around with llvm some. I would like to see what
> the SSA looks like before any other optimization and analyses are done.
To get the 'raw' output of the C frontend, use:
llvmgcc -S test.c -o foo.ll
The .ll file is the raw C frontend output.
To get the 'optimized' output, run:
gccas foo.ll -o foo.bc
'gccas' is a simple series of ecanned LLVM passes strung together in an
order that makes sense, with some glue to parse command line options and
such. You can get the same effect by doing this:
gccas /dev/null -o /dev/null -debug-pass=Arguments
This prints out all of the optimization passes run by gccas, by default.
After you have this list, you can run:
llvm-as < test.ll | opt <all of the passes> | llvm-dis >
test_optimized.ll
To play around with the various optimizations, you can now add and remove
them from the command line to opt, to see the effect of each one. Also,
you can try adding other optimizations that LLVM has. You can get a list
with 'opt --help'.
> When I use the following input program and llvm tools I get llvm that
> appears to have had some alias analysis performed even though I use the
> -no-aa flag. The phi assignments is
> %A.0 = phi int [ 10, %then ], [ 20, %else ]
> which means the opt program figured out that q points to A.
> int test(int B, int C, _Bool Z, int *P) {
> int *q;
> int A = B + C;
> q = &A;
> if (Z)
> A = 10;
> else
> *q = 20;
> return A;
> }
Ok, there are certain 'optimizations' that you cannot turn off in LLVM.
A trivial example of this is copy-propagation. LLVM does not _even have_
a copy instruction, so the 'q = &A' instruction is just deleted, and
any
references to q use &A instead. This means that your *q turns into a
direct assignment to A.
> % llvmgcc test1.c -o test1.llvm -S
> % llvm-as test1.llvm
> % opt -no-aa -mem2reg test1.llvm.bc > test1.llvm.mem2reg.bc
> % llvm-dis < test1.llvm.mem2reg.bc
The part that is thwarting your efforts is the combination of this
implicit copy-prop along with the fact that mem2reg always promotes all
variables which never "have their address taken" (in LLVM terms, this
means it promotes anything that is only used by loads and stores).
In fact, the mem2reg pass doesn't even use the alias analysis interfaces
in LLVM. The primary passes that use them are the LICM pass (for scalar
promotion), and the GCSE pass (which actually uses 'load-vn', which uses
alias analysis to assign value numbers to loads). When LLVM eventually
gets a dead store elimination pass, and a load-store PRE pass, these too
will use it (either directly or through the load-vn pass, as appropriate).
If you don't want it to promote something to a register, try passing its
address into an external function, like so:
int test(int B, int C, _Bool Z, int *P) {
int A = B + C; // This is a store
foo(&A); // This might modify A
return A; // This is a load
}
> I appreciate all your clarifications by the way. LLVM seems very well
> put together, and I think it could really help out the OpenAnalysis
> project.
Thanks! I hope it will be useful, and hopefully you'll be able to
contribute something back to LLVM in turn. :)
-Chris
--
http://llvm.cs.uiuc.edu/
http://www.nondot.org/~sabre/Projects/