Reproducing output of llvm-gcc using opt tool

Hi,

Recently, I was looking into the bug #1227. I wanted to check if
reordering optimization passes could solve it. To start with, I tried to
reproduce the output of llvm-g++ -O3 using the combination of llvm-g++
-O0 and opt with the appropriate passes. However, I was unable to. I use
SVN versions of llvm and llvm-gcc-4.2.

First, I compile example.cpp (attached; taken from the bug #1227) with:
$ llvm-g++ -c -emit-llvm -O3 -fdebug-pass-arguments example.cpp -o
example1.bc

Next, I run:
$ llvm-g++ -c -emit-llvm -O0 example.cpp -o - | opt /switches copied
from the above command debug output/ > example2.bc

The minor issue is that opt doesn't know -strip-dead-prototypes pass. Is
it possible that this pass isn't linked into the opt tool because
opt.cpp doesn't reference any symbol defined in StripDeadPrototypes.cpp.

After skipping -strip-dead-prototypes pass bitcode is produced. However,
the function assign() in example2.bc is much less optimized than in
example1.bc. Is this the expected behavior? If it is, then, what is the
correct way to reproduce llvm-gcc -O3 output with the opt tool?

-Wojtek

example.cpp (211 Bytes)

Recently, I was looking into the bug #1227. I wanted to check if
reordering optimization passes could solve it. To start with, I tried to
reproduce the output of llvm-g++ -O3 using the combination of llvm-g++
-O0 and opt with the appropriate passes. However, I was unable to. I use
SVN versions of llvm and llvm-gcc-4.2.

First, I compile example.cpp (attached; taken from the bug #1227) with:
$ llvm-g++ -c -emit-llvm -O3 -fdebug-pass-arguments example.cpp -o
example1.bc

This looks about right, you can also try opt -debug-pass=Arguments -std-compile-opts foo.bc -o foo.out.bc

Next, I run:
$ llvm-g++ -c -emit-llvm -O0 example.cpp -o - | opt /switches copied
from the above command debug output/ > example2.bc

The minor issue is that opt doesn't know -strip-dead-prototypes pass. Is
it possible that this pass isn't linked into the opt tool because
opt.cpp doesn't reference any symbol defined in StripDeadPrototypes.cpp.

Yep, that pass is an internal llvm-gcc pass.

After skipping -strip-dead-prototypes pass bitcode is produced. However,
the function assign() in example2.bc is much less optimized than in
example1.bc. Is this the expected behavior? If it is, then, what is the
correct way to reproduce llvm-gcc -O3 output with the opt tool?

It's a bit complicated, because llvm-gcc runs a couple of local passes as it parses and builds the llvm code, then it runs the passes above on the whole module afterwards. I don't know if there is a good way to get the prepasses, Devang, do you know?

-Chris

Hi Wojtek, I agree that it's very annoying that you cannot always
reproduce with opt optimizers bugs seen with llvm-gcc. I don't
know of a solution unfortunately.

Ciao,

Duncan.

$ cat a.c

#include <stdio.h>

void print() {
  printf("I'm print\n");
}

int main(int argc, char *argv) {
   printf (" me = %s\n", argv[0]);
}
$llvm-gcc-4.2 -O2 -fdebug-pass-arguments a.c
Pass Arguments: -simplifycfg -domtree -domfrontier -scalarrepl -instcombine
Pass Arguments: -simplifycfg -domtree -domfrontier -scalarrepl -instcombine
Pass Arguments: -raiseallocs -simplifycfg -domtree -domfrontier -mem2reg -globalopt -globaldce -ipconstprop -deadargelim -instcombine -simplifycfg -basiccg -prune-eh -simplify-libcalls -tailduplicate -instcombine -simplifycfg -domtree -domfrontier -scalarrepl -instcombine -break-crit-edges -condprop -tailcallelim -simplifycfg -reassociate -domtree -loops -loopsimplify -domfrontier -scalar-evolution -lcssa -loop-rotate -licm -lcssa -loop-unswitch -instcombine -scalar-evolution -lcssa -indvars -scalar-evolution -lcssa -loop-unroll -instcombine -domtree -memdep -gvn -sccp -instcombine -break-crit-edges -condprop -memdep -dse -mergereturn -postdomtree -postdomfrontier -adce -simplifycfg -constmerge -strip-dead-prototypes
Pass Arguments: -domtree -loops -loopsimplify -scalar-evolution -loop-reduce -lowergc -lowerinvoke -unreachableblockelim -codegenprepare -livevars -phi-node-elimination -twoaddressinstruction -liveintervals -domtree -loops -simple-register-coalescing -domtree -loops -livevars
Pass Arguments: -domtree -loops -loopsimplify -scalar-evolution -loop-reduce -lowergc -lowerinvoke -unreachableblockelim -codegenprepare -livevars -phi-node-elimination -twoaddressinstruction -liveintervals -domtree -loops -simple-register-coalescing -domtree -loops -livevars
$

Here, each function is processed by "-simplifycfg -domtree -domfrontier -scalarrepl -instcombine" local passes before entire module is optimized.