When I compile my C fibonacci example fib.c with 'clang -O3 -c -emit-llvm -o fib-clang.bc fib.c&& llvm-dis fib-clang.bc' I get fib-clang.ll that has some degree of inlining in it. But when I get an equivalent to fib.c file fib.ll and run it through opt with the command 'llvm-as fib.ll&& opt -O3 fib.bc -o fib-opt.bc&& llvm-dis fib-opt.bc' resulting fib-opt.ll doesn't have any degree of inlining despite the flag -O3. Why clang with the flag -O3 inlines code and opt with the same -O3 doesn't? How can I make opt inline my .ll code the same way? Yuri --- fiobonacci fib.c example --- #include<stdlib.h> #include<stdio.h> int fib(int AnArg) { if (AnArg<= 2) return (1); return (fib(AnArg-1)+fib(AnArg-2)); } int main(int argc, char* argv[]) { int n = atoi(argv[1]); printf("fib(%i)=%i\n", n, fib(n)); } --- my handcrafted fib.ll --- define i32 @fib(i32) nounwind readnone { fib.top: %xcmp1 = icmp ugt i32 %0, 1 br i1 %xcmp1, label %maj, label %spec maj: %m1 = add i32 %0, -1 %1 = tail call i32 @fib(i32 %m1) %m2 = add i32 %0, -2 %2 = tail call i32 @fib(i32 %m2) %res = add i32 %2, %1 ret i32 %res spec: %xcmp = icmp eq i32 %0, 1 %mres = zext i1 %xcmp to i32 ret i32 %mres } @.str = private constant [12 x i8] c"fib(%i)=%i\0A\00" ;<[12 x i8]*> [#uses=1] define i32 @main(i32 %argc, i8** nocapture %argv) nounwind { entry: %arrayidx = getelementptr inbounds i8** %argv, i64 1 ;<i8**> [#uses=1] %tmp1 = load i8** %arrayidx, align 8 ;<i8*> [#uses=1] %call = tail call i32 @atoi(i8* %tmp1) nounwind ;<i32> [#uses=2] %call4 = tail call i32 @fib(i32 %call) ;<i32> [#uses=1] %call5 = tail call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str, i64 0, i64 0), i32 %call, i32 %call4) nounwind ;<i32> [#uses=0] ret i32 0 } declare i32 @atoi(i8* nocapture) nounwind readonly declare i32 @printf(i8* nocapture, ...) nounwind
Duncan Sands
2010-Sep-03 08:17 UTC
[LLVMdev] Why clang inlines with -O3 flag and opt doesn't?
Hi Yuri,> But when I get an equivalent to fib.c file fib.ll and run it through opt with the command 'llvm-as fib.ll&& opt -O3 fib.bc -o fib-opt.bc&& llvm-dis fib-opt.bc' resulting fib-opt.ll doesn't have any degree of inlining despite the flag -O3.perhaps because your hand written .ll has no target information in it. I'm not sure why that would effect inlining, but in general it vastly reduces the number of optimizations that can be performed. Ciao, Duncan.
Eli Friedman
2010-Sep-03 08:21 UTC
[LLVMdev] Why clang inlines with -O3 flag and opt doesn't?
On Fri, Sep 3, 2010 at 12:46 AM, Yuri <yuri at rawbw.com> wrote:> When I compile my C fibonacci example fib.c with 'clang -O3 -c -emit-llvm -o fib-clang.bc fib.c&& llvm-dis fib-clang.bc' I get fib-clang.ll that has some degree of inlining in it. > > But when I get an equivalent to fib.c file fib.ll and run it through opt with the command 'llvm-as fib.ll&& opt -O3 fib.bc -o fib-opt.bc&& llvm-dis fib-opt.bc' resulting fib-opt.ll doesn't have any degree of inlining despite the flag -O3. > > Why clang with the flag -O3 inlines code and opt with the same -O3 doesn't? > How can I make opt inline my .ll code the same way?Trunk clang and opt appear to completely refuse to inline the function in question because it is recursive. If you're using an earlier version, I think opt might not be using exactly the same inlining thresholds as clang... -Eli
On 09/03/2010 01:21, Eli Friedman wrote:> Trunk clang and opt appear to completely refuse to inline the function > in question because it is recursive. If you're using an earlier > version, I think opt might not be using exactly the same inlining > thresholds as clang..I use rev.112342 from few days ago. Yuri
On 09/03/2010 01:17, Duncan Sands wrote:> perhaps because your hand written .ll has no target information in it. > I'm not sure why that would effect inlining, but in general it vastly > reduces the number of optimizations that can be performedI tried to copy target information from .ll file generated by clang but result after opt is the same. Yuri
Duncan Sands
2010-Sep-03 08:52 UTC
[LLVMdev] Why clang inlines with -O3 flag and opt doesn't?
Hi Eli,> Trunk clang and opt appear to completely refuse to inline the function > in question because it is recursive. If you're using an earlier > version, I think opt might not be using exactly the same inlining > thresholds as clang...that brings up the question of why tailcallopt didn't turn it into a loop... Ciao, Duncan.
Duncan Sands
2010-Sep-03 10:25 UTC
[LLVMdev] Why clang inlines with -O3 flag and opt doesn't?
Hi Yuri,> When I compile my C fibonacci example fib.c with 'clang -O3 -c -emit-llvm -o fib-clang.bc fib.c&& llvm-dis fib-clang.bc' I get fib-clang.ll that has some degree of inlining in it.this is not exactly inlining, it is tail recursion elimination.> But when I get an equivalent to fib.c file fib.ll and run it through opt with the command 'llvm-as fib.ll&& opt -O3 fib.bc -o fib-opt.bc&& llvm-dis fib-opt.bc' resulting fib-opt.ll doesn't have any degree of inlining despite the flag -O3.It is not equivalent, because your C program returns 1 for the first Fibonacci number, while the .ll returns 0. If you change this> spec: > %xcmp = icmp eq i32 %0, 1 > %mres = zext i1 %xcmp to i32 > ret i32 %mresto spec: return i32 1 then you get tail recursion elimination for the .ll too. Ciao, Duncan.
Reasonably Related Threads
- [LLVMdev] Why clang inlines with -O3 flag and opt doesn't?
- [LLVMdev] Why clang inlines with -O3 flag and opt doesn't?
- [LLVMdev] Why the same code is much slower in JIT compared to separate executable?
- [LLVMdev] Why the same code is much slower in JIT compared to separate executable?
- [LLVMdev] Why the same code is much slower in JIT compared to separate executable?