[cfe-commits] r77038 - /cfe/trunk/lib/CodeGen/CGExprConstant.cpp

Anders Carlsson andersca at mac.com
Fri Jul 24 18:40:29 PDT 2009


Author: andersca
Date: Fri Jul 24 20:40:29 2009
New Revision: 77038

URL: http://llvm.org/viewvc/llvm-project?rev=77038&view=rev
Log:
More work on the constant struct builder. We can now convert the struct to a packed struct when necessary.

Modified:
    cfe/trunk/lib/CodeGen/CGExprConstant.cpp

Modified: cfe/trunk/lib/CodeGen/CGExprConstant.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprConstant.cpp?rev=77038&r1=77037&r2=77038&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprConstant.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprConstant.cpp Fri Jul 24 20:40:29 2009
@@ -61,13 +61,50 @@
       llvm::RoundUpToAlignment(NextFieldOffsetInBytes, FieldAlignment);
     
     if (AlignedNextFieldOffsetInBytes > FieldOffsetInBytes) {
-      // FIXME: Must convert the struct to a packed struct.
-      return false;
+      std::vector<llvm::Constant *> PackedElements;
+      
+      assert(!Packed && "Alignment is wrong even with a packed struct!");
+      
+      // Convert the struct to a packed struct.
+      uint64_t ElementOffsetInBytes = 0;
+      
+      for (unsigned i = 0, e = Elements.size(); i != e; ++i) {
+        llvm::Constant *C = Elements[i];
+        
+        unsigned ElementAlign = 
+          CGM.getTargetData().getABITypeAlignment(C->getType());
+        uint64_t AlignedElementOffsetInBytes = 
+          llvm::RoundUpToAlignment(ElementOffsetInBytes, ElementAlign);
+        
+        if (AlignedElementOffsetInBytes > ElementOffsetInBytes) {
+          // We need some padding.
+          uint64_t NumBytes = 
+            AlignedElementOffsetInBytes - ElementOffsetInBytes;
+          
+          const llvm::Type *Ty = llvm::Type::Int8Ty;
+          if (NumBytes > 1) 
+            Ty = CGM.getLLVMContext().getArrayType(Ty, NumBytes);
+          
+          llvm::Constant *Padding = CGM.getLLVMContext().getNullValue(Ty);
+          PackedElements.push_back(Padding);
+          ElementOffsetInBytes += getSizeInBytes(Padding);
+        }
+        
+        PackedElements.push_back(C);
+        ElementOffsetInBytes += getSizeInBytes(C);
+      }
+
+      assert(ElementOffsetInBytes == NextFieldOffsetInBytes &&
+             "Packing the struct changed its size!");
+
+      Elements = PackedElements;
+      Packed = true;
+      AlignedNextFieldOffsetInBytes = NextFieldOffsetInBytes;
     }
 
     if (AlignedNextFieldOffsetInBytes < FieldOffsetInBytes) {
       // We need to append padding.
-      AppendPadding(FieldOffsetInBytes - AlignedNextFieldOffsetInBytes);
+      AppendPadding(FieldOffsetInBytes - NextFieldOffsetInBytes);
       
       assert(NextFieldOffsetInBytes == FieldOffsetInBytes &&
              "Did not add enough padding!");





More information about the cfe-commits mailing list