[llvm-bugs] [Bug 31634] New: Clang's byval struct passing is still bad for code size
via llvm-bugs
llvm-bugs at lists.llvm.org
Fri Jan 13 09:36:41 PST 2017
https://llvm.org/bugs/show_bug.cgi?id=31634
Bug ID: 31634
Summary: Clang's byval struct passing is still bad for code
size
Product: clang
Version: unspecified
Hardware: PC
OS: Windows NT
Status: NEW
Severity: normal
Priority: P
Component: LLVM Codegen
Assignee: unassignedclangbugs at nondot.org
Reporter: rnk at google.com
CC: llvm-bugs at lists.llvm.org
Classification: Unclassified
I'm convinced we should avoid it because of this example:
struct ForcedByVal {
ForcedByVal();
char a, b, c, d;
};
void g(ForcedByVal, ForcedByVal, ForcedByVal);
void f() {
ForcedByVal o;
g(o, o, o);
}
This generates the following IR:
define void @"\01?f@@YAXXZ"() local_unnamed_addr #0 {
entry:
%o = alloca i32, align 4
%tmpcast3 = bitcast i32* %o to %struct.ForcedByVal*
%agg.tmp = alloca i32, align 4
%tmpcast = bitcast i32* %agg.tmp to %struct.ForcedByVal*
%agg.tmp1 = alloca i32, align 4
%tmpcast4 = bitcast i32* %agg.tmp1 to %struct.ForcedByVal*
%agg.tmp2 = alloca i32, align 4
%tmpcast5 = bitcast i32* %agg.tmp2 to %struct.ForcedByVal*
%0 = bitcast i32* %o to i8*
call void @llvm.lifetime.start(i64 4, i8* nonnull %0) #3
%call = call x86_thiscallcc %struct.ForcedByVal*
@"\01??0ForcedByVal@@QAE at XZ"(%struct.ForcedByVal* nonnull %tmpcast3)
%1 = load i32, i32* %o, align 4
store i32 %1, i32* %agg.tmp, align 4
store i32 %1, i32* %agg.tmp1, align 4
store i32 %1, i32* %agg.tmp2, align 4
call void @"\01?g@@YAXUForcedByVal@@00 at Z"(%struct.ForcedByVal* byval nonnull
align 4 %tmpcast5, %struct.ForcedByVal* byval nonnull align 4 %tmpcast4,
%struct.ForcedByVal* byval nonnull align 4 %tmpcast)
call void @llvm.lifetime.end(i64 4, i8* nonnull %0) #3
ret void
}
Which generates this assembly:
"?f@@YAXXZ": # @"\01?f@@YAXXZ"
# BB#0: # %entry
subl $28, %esp
leal 24(%esp), %ecx
calll "??0ForcedByVal@@QAE at XZ"
movl 24(%esp), %eax # Needed
movl %eax, 20(%esp)
movl %eax, 16(%esp)
movl %eax, 12(%esp)
movl 20(%esp), %eax
movl %eax, 8(%esp) # Needed
movl 16(%esp), %eax
movl %eax, 4(%esp) # Needed
movl 12(%esp), %eax
movl %eax, (%esp) # Needed
calll "?g@@YAXUForcedByVal@@00 at Z"
addl $28, %esp
retl
All the above loads and stores not tagged "# Needed" are completely redundant.
Clang has to create three temporary allocas to be the source of the byval
parameter. It's possible that we can elide those allocas in the frontend, but
memcpyopt would have to get a lot smarter about reasoning about byval to remove
those copies in the middle end.
I think instead of improving our reasoning about byval, we should migrate away
from it and move towards FCAs in arguments. The LLVM prototype would look like
this:
call void @"\01?g@@YAXUForcedByVal@@00 at Z"(%struct.ForcedByVal %fca,
%struct.ForcedByVal %fca, %struct.ForcedByVal %fca)
The %fca value would be produced by successive insertvalue or a bitcast from
i32.
--
You are receiving this mail because:
You are on the CC list for the bug.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-bugs/attachments/20170113/a6d1a752/attachment.html>
More information about the llvm-bugs
mailing list