]> granicus.if.org Git - clang/commitdiff
IRgen/ABI: Add support for realigning structures which are passed by indirect
authorDaniel Dunbar <daniel@zuster.org>
Thu, 16 Sep 2010 20:42:02 +0000 (20:42 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Thu, 16 Sep 2010 20:42:02 +0000 (20:42 +0000)
reference.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@114114 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/ABIInfo.h
lib/CodeGen/CGCall.cpp
lib/CodeGen/TargetInfo.cpp

index 91b7742557f562e6e9d275242668b32bd33679ec..c90c84a3524e1928245058924be086ac55c63b06 100644 (file)
@@ -70,11 +70,12 @@ namespace clang {
     Kind TheKind;
     llvm::PATypeHolder TypeData;
     unsigned UIntData;
-    bool BoolData;
+    bool BoolData0;
+    bool BoolData1;
 
     ABIArgInfo(Kind K, const llvm::Type *TD=0,
-               unsigned UI=0, bool B = false) 
-      : TheKind(K), TypeData(TD), UIntData(UI), BoolData(B) {}
+               unsigned UI=0, bool B0 = false, bool B1 = false) 
+      : TheKind(K), TypeData(TD), UIntData(UI), BoolData0(B0), BoolData1(B1) {}
 
   public:
     ABIArgInfo() : TheKind(Direct), TypeData(0), UIntData(0) {}
@@ -88,8 +89,9 @@ namespace clang {
     static ABIArgInfo getIgnore() {
       return ABIArgInfo(Ignore);
     }
-    static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true) {
-      return ABIArgInfo(Indirect, 0, Alignment, ByVal);
+    static ABIArgInfo getIndirect(unsigned Alignment, bool ByVal = true
+                                  , bool Realign = false) {
+      return ABIArgInfo(Indirect, 0, Alignment, ByVal, Realign);
     }
     static ABIArgInfo getExpand() {
       return ABIArgInfo(Expand);
@@ -129,7 +131,12 @@ namespace clang {
 
     bool getIndirectByVal() const {
       assert(TheKind == Indirect && "Invalid kind!");
-      return BoolData;
+      return BoolData0;
+    }
+
+    bool getIndirectRealign() const {
+      assert(TheKind == Indirect && "Invalid kind!");
+      return BoolData1;
     }
     
     void dump() const;
index 475dfa5c102a720b350bd9695ac87c7e534d0519..ae00040ec7ddd4f40fb59f263e39b77bb55dcccd 100644 (file)
@@ -866,9 +866,29 @@ void CodeGenFunction::EmitFunctionProlog(const CGFunctionInfo &FI,
     switch (ArgI.getKind()) {
     case ABIArgInfo::Indirect: {
       llvm::Value *V = AI;
+
       if (hasAggregateLLVMType(Ty)) {
-        // Do nothing, aggregates and complex variables are accessed by
-        // reference.
+        // Aggregates and complex variables are accessed by reference.  All we
+        // need to do is realign the value, if requested
+        if (ArgI.getIndirectRealign()) {
+          llvm::Value *AlignedTemp = CreateMemTemp(Ty, "coerce");
+
+          // Copy from the incoming argument pointer to the temporary with the
+          // appropriate alignment.
+          //
+          // FIXME: We should have a common utility for generating an aggregate
+          // copy.
+          const llvm::Type *I8PtrTy = llvm::Type::getInt8PtrTy(VMContext, 0);
+          unsigned Size = getContext().getTypeSize(Ty) / 8;
+          Builder.CreateCall5(CGM.getMemCpyFn(I8PtrTy, I8PtrTy, IntPtrTy),
+                              Builder.CreateBitCast(AlignedTemp, I8PtrTy),
+                              Builder.CreateBitCast(V, I8PtrTy),
+                              llvm::ConstantInt::get(IntPtrTy, Size),
+                              Builder.getInt32(ArgI.getIndirectAlign()),
+                              /*Volatile=*/Builder.getInt1(false));
+
+          V = AlignedTemp;
+        }
       } else {
         // Load scalar value from indirect argument.
         unsigned Alignment = getContext().getTypeAlignInChars(Ty).getQuantity();
index ab6f7c7dd0c858fc8ae1076e89dd7508dce44064..3ee4d1ad6df9d4b669e39d81be4995933ad7642b 100644 (file)
@@ -75,7 +75,8 @@ void ABIArgInfo::dump() const {
     break;
   case Indirect:
     OS << "Indirect Align=" << getIndirectAlign()
-       << " Byal=" << getIndirectByVal();
+       << " Byal=" << getIndirectByVal()
+       << " Realign=" << getIndirectRealign();
     break;
   case Expand:
     OS << "Expand";