[cfe-dev] Redundant byval in C codegen?

Rafael Espindola espindola at google.com
Sat Jan 16 12:43:52 PST 2010

> Could somebody explain the rationale behind this behavior? Thanks.

I have no idea why we are unable to remove one of the allocas in the
caller, but I think I know why we always keep a copy in the caller and
one in the callee. Take a modified testcase:

#include <string.h>
struct s {
  int a[40];

void g(struct s a);

void f() {
  struct s a;
  memset(&a, 0, sizeof(struct s));

This gets compiled to
  %agg.tmp = alloca %struct.s, align 8            ; <%struct.s*> [#uses=2]
  %agg.tmp2 = bitcast %struct.s* %agg.tmp to i8*  ; <i8*> [#uses=1]
  call void @llvm.memset.i64(i8* %agg.tmp2, i8 0, i64 160, i32 8)
  call void @g(%struct.s* byval %agg.tmp) nounwind optsize
  ret void

Ideally we would not have that alloca since the struct is passed by
value and we now have first class aggregates. The problem is that
byval is a pointer. This is very good for the callee since it
correctly represents the fact that the argument is in memory (as
mandated by the ABI). It is  not so good for the caller that is forced
to produce an object in memory that will be copied by the code

If we were to use first class aggregates we would have a problem is
the callee that now would not have explicit loads.

One of my crazy ideas I never have time to implement is to change the
call function to support passing first class aggregates to byval
arguments. It already does an implicit copy, this would just add
support for it copying things that are not in memory in the caller.

Rafael Ávila de Espíndola

More information about the cfe-dev mailing list