[LLVMbugs] [Bug 6712] New: mergefunc work looks not as good as possible with weak_odr
bugzilla-daemon at llvm.org
bugzilla-daemon at llvm.org
Fri Mar 26 08:28:14 PDT 2010
http://llvm.org/bugs/show_bug.cgi?id=6712
Summary: mergefunc work looks not as good as possible with
weak_odr
Product: new-bugs
Version: 2.6
Platform: PC
OS/Version: Windows XP
Status: NEW
Keywords: code-quality
Severity: normal
Priority: P
Component: new bugs
AssignedTo: unassignedbugs at nondot.org
ReportedBy: bearophile at mailas.com
CC: llvmbugs at cs.uiuc.edu
I am looking at the -mergefunc pass to remove some template bloat from D
language programs that contain function templates.
This is the D code I have compiled with LDC:
import tango.stdc.stdio: printf;
import tango.stdc.stdlib: atoi;
T factorial(T)(T x) {
if (x == 0)
return 1;
else
return x * factorial(x - 1);
}
void main(char[][] args) {
printf("%d\n", factorial(atoi(args[1].ptr)));
printf("%d\n", factorial(cast(uint)atoi(args[1].ptr)));
}
Compiling it with:
ldc -mergefunc -output-s temp2.d
It produces the (cleaned up) asm:
factorial!int:
subl $4, %esp
call __unnamed_1
addl $4, %esp
ret
factorial!uint:
subl $4, %esp
call __unnamed_1
addl $4, %esp
ret
__unnamed_1:
subl $4, %esp
movl %eax, (%esp)
testl %eax, %eax
jne .LBB2_2
movl $1, %eax
addl $4, %esp
ret
.LBB2_2:
movl (%esp), %eax
decl %eax
call factorial!uint
imull (%esp), %eax
addl $4, %esp
ret
_Dmain:
subl $28, %esp
movl 36(%esp), %eax
movl %eax, 20(%esp)
movl 32(%esp), %eax
movl %eax, 16(%esp)
cmpl $1, 16(%esp)
jbe .LBB1_3
movl 20(%esp), %eax
movl 12(%eax), %eax
movl %eax, (%esp)
call atoi
call factorial!int
movl %eax, 4(%esp)
movl $.str, (%esp)
call printf
cmpl $1, 16(%esp)
jbe .LBB1_4
movl 20(%esp), %eax
movl 12(%eax), %eax
movl %eax, (%esp)
call atoi
call factorial!uint
movl %eax, 4(%esp)
movl $.str2, (%esp)
call printf
xorl %eax, %eax
addl $28, %esp
ret $8
.LBB1_3:
movl .modulefilename+4, %eax
movl %eax, 4(%esp)
movl .modulefilename, %eax
movl %eax, (%esp)
movl $12, 8(%esp)
call _d_array_bounds
.LBB1_4:
movl .modulefilename+4, %eax
movl %eax, 4(%esp)
movl .modulefilename, %eax
movl %eax, (%esp)
movl $13, 8(%esp)
call _d_array_bounds
The bytecode generated with (some parts of the bytecode removed):
ldc -mergefunc -release -output-ll temp2.d
define x86_stdcallcc i32 @_Dmain(%"char[][]" %args_arg) {
entry:
%args = alloca %"char[][]" ; <%"char[][]"*> [#uses=3]
store %"char[][]" %args_arg, %"char[][]"* %args
%tmp = getelementptr %"char[][]"* %args, i32 0, i32 1 ; <%"byte[]"**>
[#uses=1]
%.ptr = load %"byte[]"** %tmp ; <%"byte[]"*> [#uses=1]
%tmp1 = getelementptr %"byte[]"* %.ptr, i32 1 ; <%"byte[]"*> [#uses=1]
%tmp2 = getelementptr %"byte[]"* %tmp1, i32 0, i32 1 ; <i8**> [#uses=1]
%.ptr3 = load i8** %tmp2 ; <i8*> [#uses=1]
%tmp4 = call i32 @atoi(i8* %.ptr3) ; <i32> [#uses=1]
%tmp5 = call x86_stdcallcc i32 @_D5temp216__T9factorialTiZ9factorialFiZi(i32
inreg %tmp4) ; <i32> [#uses=1]
%tmp6 = call i32 (i8*, ...)* @printf(i8* getelementptr ([4 x i8]* @.str, i32
0, i32 0), i32 %tmp5) ; <i32> [#uses=0]
%tmp7 = getelementptr %"char[][]"* %args, i32 0, i32 1 ; <%"byte[]"**>
[#uses=1]
%.ptr8 = load %"byte[]"** %tmp7 ; <%"byte[]"*> [#uses=1]
%tmp9 = getelementptr %"byte[]"* %.ptr8, i32 1 ; <%"byte[]"*> [#uses=1]
%tmp10 = getelementptr %"byte[]"* %tmp9, i32 0, i32 1 ; <i8**> [#uses=1]
%.ptr11 = load i8** %tmp10 ; <i8*> [#uses=1]
%tmp12 = call i32 @atoi(i8* %.ptr11) ; <i32> [#uses=1]
%tmp13 = call x86_stdcallcc i32 @_D5temp216__T9factorialTkZ9factorialFkZk(i32
inreg %tmp12) ; <i32> [#uses=1]
%tmp14 = call i32 (i8*, ...)* @printf(i8* getelementptr ([4 x i8]* @.str1,
i32 0, i32 0), i32 %tmp13) ; <i32> [#uses=0]
ret i32 0
}
define internal x86_stdcallcc i32 @0(i32 inreg %x_arg) {
entry:
%x = alloca i32 ; <i32*> [#uses=4]
store i32 %x_arg, i32* %x
%tmp = load i32* %x ; <i32> [#uses=1]
%tmp1 = icmp eq i32 %tmp, 0 ; <i1> [#uses=1]
br i1 %tmp1, label %if, label %else
if: ; preds = %entry
ret i32 1
afterreturn: ; No predecessors!
br label %endif
else: ; preds = %entry
%tmp2 = load i32* %x ; <i32> [#uses=1]
%tmp3 = sub i32 %tmp2, 1 ; <i32> [#uses=1]
%tmp4 = call x86_stdcallcc i32 @_D5temp216__T9factorialTkZ9factorialFkZk(i32
inreg %tmp3) ; <i32> [#uses=1]
%tmp5 = load i32* %x ; <i32> [#uses=1]
%tmp6 = mul i32 %tmp5, %tmp4 ; <i32> [#uses=1]
ret i32 %tmp6
afterreturn7: ; No predecessors!
br label %endif
endif: ; preds = %afterreturn7,
%afterreturn
ret i32 undef
}
define weak_odr x86_stdcallcc i32 @_D5temp216__T9factorialTiZ9factorialFiZi(i32
inreg) {
%2 = tail call x86_stdcallcc i32 @0(i32 %0) ; <i32> [#uses=1]
ret i32 %2
}
define weak_odr x86_stdcallcc i32 @_D5temp216__T9factorialTkZ9factorialFkZk(i32
inreg) {
%2 = tail call x86_stdcallcc i32 @0(i32 %0) ; <i32> [#uses=1]
ret i32 %2
}
On IRC in #llvm baldrick has said:
this may well be a bug - it's not clear to me why weak_odr linkage would be a
problem
try asking nlewycky
--
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.
More information about the llvm-bugs
mailing list