new variant for EmitAggregateCopy

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

new variant for EmitAggregateCopy

Jochen Wilhelmy
Hi!

when reading the comments in CodeGenFunction::EmitAggregateCopy
there seem to be two problems:

1. "Aggregate assignment turns into llvm.memcpy.  This is almost valid per
C99 6.5.16.1p3"
For me, "almost valid" means that it is valid for 99% of the cases but
there should
be the possibility to switch it off

2. "FIXME: If we have a volatile struct, the optimizer can remove what might
appear to be `extra' memory ops"
This sounds like the current implementation can produce incorrect code for
volatile struct variables.


This is my alternative implementation based on element wise copy of all
fields.
I would suggest that it is used if isVolatile is true or if a flag in
TargetInfo
indicates that it always should be used. This way the 99% of the cases
continue using memcpy.


     const clang::RecordType* recordType = Ty->getAs<clang::RecordType>();

     // get record decl
     clang::RecordDecl* recordDecl = recordType->getDecl();

     // iterate over fields
     clang::CodeGen::CodeGenTypes& codeGenTypes = CGM.getTypes();
     const clang::CodeGen::CGRecordLayout& layout =
codeGenTypes.getCGRecordLayout(recordDecl);
     clang::RecordDecl::field_iterator it = recordDecl->field_begin();
     clang::RecordDecl::field_iterator end = recordDecl->field_end();
     for (; it != end; ++it)
     {
         clang::FieldDecl* fieldDecl = *it;
         int fieldIndex = layout.getLLVMFieldNo(fieldDecl);

         llvm::Value *SrcFieldPtr =
Builder.CreateConstInBoundsGEP2_32(SrcPtr, 0, fieldIndex);
         llvm::Value *DestFieldPtr =
Builder.CreateConstInBoundsGEP2_32(DestPtr, 0, fieldIndex);

         // check if field is an aggregate
         QualType fieldType = fieldDecl->getType();
         if (fieldType->getAs<clang::RecordType>() != NULL)
         {
             // copy nested aggregate
             EmitAggregateCopy(DestFieldPtr, SrcFieldPtr, fieldType,
isVolatile);
         }
         else
         {
             // copy value
             llvm::Value *Element = Builder.CreateLoad(SrcFieldPtr,
isVolatile, "tmp");
             Builder.CreateStore(Element, DestFieldPtr, isVolatile);
         }
     }


-Jochen


_______________________________________________
cfe-dev mailing list
[hidden email]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-dev