Hello all!
I apologize if this has been asked before, but I’m interested in following a specific code snippet through each pass to see how it changes. Basically, I’m trying to see if a piece of logic (addition followed by a max comparison) is rearranged or modified at any point in the passes pipeline.
But more broadly, I think it would be a very useful skill to be able practically parse an IR file and compare them between passes.
Does anyone know the easiest way to do this, or a tutorial/thread to get me started? Thank you!
Usually, I use clang ... -mllvm -print-after-all &> all.ll to dump IR after all passes, and search for the exact changed snippet. E.g., if ‘%add5 = add …’ was removed, then I’d search for the last occurance of ‘%add5’.
1 Like
Compiler Explorer has a “Opt Pipeline” feature based on the options mentioned above, for example. This can be enabled for LLVM IR or when using a clang compiler.
Istr there was a standalone tool that diffed each stage but can’t remember where I saw it.
(if you really like Compiler Explorer’s verison, you can run Compiler Explorer locally too)
1 Like
Thank you both for the responses! I figured out a slightly janky way of doing it by surrounding my statement with prints and then tracing when those specific strings get called through the IR. I’m running into a new issue though - I’m using opt -print-after-all to get the IR after each pass, but I’ve noticed that these two scripts give me pretty significantly different IR
clang++ -S -O0 -emit-llvm main3.cpp -o main3.0.ll
opt -O3 -S main3.0.ll -o main3.3.ll
versus:
clang++ -S -O3 -emit-llvm main3.cpp -o main3.3.ll
Specifically, in the following code:
double scalar_max_double(double a, double b, double c) {
printf(“testHere1”);
double sum = a + b;
double result = std::max(sum, c);
printf(“testHere2%f”, sum);
return result;
}
For the first script, the “%6 = fcmp olt double %5, %2” is not inlined. This function stays fairly large. For the second one where we just call O3 directly, it gets properly inlined. This is the behavior I’m interested in so I’m trying to see which pass it get’s inlined.
I know clang does some front end optimizations before passing to LLVM in the first place, but “clang++ -S -O0 -emit-llvm main3.cpp -o main3.0.ll” doesn’t have it inlined, so it must be during one of the optimization passes.
Thank you all for your help!
EDIT: I completely misread the “-mllvm” flag and went down a google rabbit hole and ended up going with "opt”. I reread your post @zsrkmyn and that was exactly it, thank you!!!