[cfe-dev] C++ AST Question

Chris Lattner clattner at apple.com
Sun Jun 27 00:44:34 PDT 2010


I'm trying to get this simple function to compile to decent code.  Lack of it is causing -O0 codegen to be monsterous:

struct DeclGroup {
  unsigned NumDecls;
};

int foo(DeclGroup D);
void bar(DeclGroup *D) {
  foo(*D);
}

The current issue that I'm fighting is that we get an extra pointless temporary and memcpy, which llvm-gcc isn't generating:

$ clang t.cc -S -o - -emit-llvm
...
define void @_Z3barP9DeclGroup(%struct.DeclGroup* %D) ssp {
entry:
  %D.addr = alloca %struct.DeclGroup*, align 8    ; <%struct.DeclGroup**> [#uses=2]
  %agg.tmp = alloca %struct.DeclGroup, align 4    ; <%struct.DeclGroup*> [#uses=2]
  store %struct.DeclGroup* %D, %struct.DeclGroup** %D.addr
  %tmp = load %struct.DeclGroup** %D.addr         ; <%struct.DeclGroup*> [#uses=1]
  %tmp1 = bitcast %struct.DeclGroup* %agg.tmp to i8* ; <i8*> [#uses=1]
  %tmp2 = bitcast %struct.DeclGroup* %tmp to i8*  ; <i8*> [#uses=1]
  call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp1, i8* %tmp2, i64 4, i32 4, i1 false)
  %coerce.dive = getelementptr %struct.DeclGroup* %agg.tmp, i32 0, i32 0 ; <i32*> [#uses=1]
  %0 = load i32* %coerce.dive                     ; <i32> [#uses=1]
  %coerce.val.ii = zext i32 %0 to i64             ; <i64> [#uses=1]
  %call = call i32 @_Z3foo9DeclGroup(i64 %coerce.val.ii) ; <i32> [#uses=0]
  ret void
}

After diving into it, the memcpy is being made by CodeGenFunction::EmitCXXConstructorCall, so I came up with this patch:

-------------- next part --------------
A non-text attachment was scrubbed...
Name: cxxctorcall.patch
Type: application/octet-stream
Size: 746 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20100627/e4260e0b/attachment.obj>
-------------- next part --------------


However, though it is a cleanup, it doesn't help this case.  I think the problem here is actually the AST, which looks like this:

void bar(DeclGroup *D) (CompoundStmt 0x103a19080 <t.cc:7:24, line:9:1>
  (CallExpr 0x103a19040 <line:8:3, col:9> 'int'
    (ImplicitCastExpr 0x103a19000 <col:3> 'int (*)(struct DeclGroup)' <FunctionToPointerDecay>
      (DeclRefExpr 0x103a18fa0 <col:3> 'int (struct DeclGroup)' FunctionDecl='foo' 0x103a18d20))
    (CXXConstructExpr 0x103a191f0 <col:7, col:8> 'struct DeclGroup''void (struct DeclGroup const &)'
      (ImplicitCastExpr 0x103a191b0 <col:7, col:8> 'struct DeclGroup const' <NoOp> lvalue
        (UnaryOperator 0x103a18f70 <col:7, col:8> 'struct DeclGroup' prefix '*'
          (DeclRefExpr 0x103a18f40 <col:8> 'struct DeclGroup *' ParmVar='D' 0x103a18da0))))))

I don't see why the CXXConstructExpr exists at all in this case.  Is this a C++ Sema bug?  Also, is the patch above useful?

-Chris




More information about the cfe-dev mailing list