[cfe-commits] r44875 - /cfe/trunk/CodeGen/CodeGenTypes.cpp

Devang Patel dpatel at apple.com
Tue Dec 11 11:51:40 PST 2007


Author: dpatel
Date: Tue Dec 11 13:51:39 2007
New Revision: 44875

URL: http://llvm.org/viewvc/llvm-project?rev=44875&view=rev
Log:
Refactor bit-field handling code into a separate method.
No functionality change.

Modified:
    cfe/trunk/CodeGen/CodeGenTypes.cpp

Modified: cfe/trunk/CodeGen/CodeGenTypes.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CodeGenTypes.cpp?rev=44875&r1=44874&r2=44875&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CodeGenTypes.cpp (original)
+++ cfe/trunk/CodeGen/CodeGenTypes.cpp Tue Dec 11 13:51:39 2007
@@ -78,6 +78,9 @@
     /// or last record field is a bit-field.
     void fixCursorPosition(const ASTRecordLayout &RL);
 
+    /// placeBitField - Find a place for FD, which is a bit-field. 
+    void placeBitField(const FieldDecl *FD);
+
   private:
     CodeGenTypes &CGT;
     llvm::Type *STy;
@@ -415,75 +418,9 @@
          E = FieldDecls.end(); I != E; ++I) {
     const FieldDecl *FD = *I;
 
-    if (FD->isBitField()) {
-      Expr *BitWidth = FD->getBitWidth();
-      llvm::APSInt FieldSize(32);
-      bool isBitField = 
-        BitWidth->isIntegerConstantExpr(FieldSize, CGT.getContext());
-      assert (isBitField  && "Invalid BitField size expression");
-      uint64_t BitFieldSize =  FieldSize.getZExtValue();
-      if (ExtraBits == 0) {
-        // CurrentField is a bit-field and structure is in one of the
-        // following form.
-        // struct { char CurrentField:2; char B:4; }
-        // struct { char A; char CurrentField:2; };
-        // struct { char A; short CurrentField:2; };
-        const llvm::Type *Ty = CGT.ConvertType(FD->getType());
-        // Calculate extra bits available in this bitfield.
-        ExtraBits = CGT.getTargetData().getABITypeSizeInBits(Ty) - BitFieldSize;
-
-        if (LLVMFields.empty()) 
-          // Ths is - struct { char CurrentField:2; char B:4; }
-          addLLVMField(Ty, BitFieldSize, FD, 0, ExtraBits);
-        else {
-          const llvm::Type *PrevTy = LLVMFields.back();
-          if (CGT.getTargetData().getABITypeSizeInBits(PrevTy) >=
-              CGT.getTargetData().getABITypeSizeInBits(Ty)) 
-            // This is - struct { char A; char CurrentField:2; };
-            addLLVMField(Ty, BitFieldSize, FD, 0, ExtraBits);
-          else {
-            // This is - struct { char A; short CurrentField:2; };
-            // Use one of the previous filed to access current field.
-            bool FoundPrevField = false;
-            unsigned TotalOffsets = Offsets.size();
-            uint64_t TySize = CGT.getTargetData().getABITypeSizeInBits(Ty);
-            for (unsigned i = TotalOffsets; i != 0; --i) {
-              uint64_t O = Offsets[i - 1];
-              if (O % TySize == 0) {
-                // This is appropriate llvm field to share access.
-                FoundPrevField = true;
-                CurrentFieldStart = O % TySize;
-                unsigned FieldBegin = Cursor - (O % TySize);
-                unsigned FieldEnd = TySize - (FieldBegin + BitFieldSize);
-                Cursor += BitFieldSize;
-                CGT.addFieldInfo(FD, i, FieldBegin, FieldEnd);
-              }
-            }
-            assert(FoundPrevField && 
-                   "Unable to find a place for bitfield in struct layout");
-          }
-        }
-      } else  if (ExtraBits >= BitFieldSize) {
-        // Reuse existing llvm field
-        ExtraBits = ExtraBits  - BitFieldSize;
-        CGT.addFieldInfo(FD, FieldNo, Cursor - CurrentFieldStart, ExtraBits);
-        Cursor = Cursor + BitFieldSize;
-        ++FieldNo;
-      } else {
-        //ExtraBits are not enough to hold entire FD.
-        const llvm::Type *Ty = CGT.ConvertType(FD->getType());
-        const llvm::Type *PrevTy = LLVMFields.back();
-        uint64_t TySize = CGT.getTargetData().getABITypeSizeInBits(Ty);
-        if (CGT.getTargetData().getABITypeSizeInBits(PrevTy) >= TySize) {
-          // Previous field does not allow sharing of ExtraBits. Use new field.
-          // struct { char a; char b:5; char c:4; } where c is current FD.
-          Cursor += ExtraBits;
-          ExtraBits = 0;
-          addLLVMField(Ty, TySize, FD, 0, BitFieldSize);
-        } else
-          assert (!FD->isBitField() && "Bit fields are not yet supported");
-      }
-    } else {
+    if (FD->isBitField()) 
+      placeBitField(FD);
+    else {
       ExtraBits = 0;
       // FD is not a bitfield. If prev field was a bit field then it may have
       // positioned cursor such that it needs adjustment now.
@@ -597,3 +534,83 @@
     addPaddingFields(StructPadding*8);
   }
 }
+
+/// placeBitField - Find a place for FD, which is a bit-field. 
+/// There are three separate cases to handle
+/// 1) Cursor starts at byte boundry and there are no extra
+///    bits are available in last llvm struct field. 
+/// 2) Extra bits from previous last llvm struct field are
+///    available and have enough space to hold entire FD.
+/// 3) Extra bits from previous last llvm struct field are
+///    available but they are not enough to hold FD entirly.
+void RecordOrganizer::placeBitField(const FieldDecl *FD) {
+
+  assert (FD->isBitField() && "FD is not a bit-field");
+  Expr *BitWidth = FD->getBitWidth();
+  llvm::APSInt FieldSize(32);
+  bool isBitField = 
+    BitWidth->isIntegerConstantExpr(FieldSize, CGT.getContext());
+  assert (isBitField  && "Invalid BitField size expression");
+  uint64_t BitFieldSize =  FieldSize.getZExtValue();
+  if (ExtraBits == 0) {
+    // CurrentField is a bit-field and structure is in one of the
+    // following form.
+    // struct { char CurrentField:2; char B:4; }
+    // struct { char A; char CurrentField:2; };
+    // struct { char A; short CurrentField:2; };
+    const llvm::Type *Ty = CGT.ConvertType(FD->getType());
+    // Calculate extra bits available in this bitfield.
+    ExtraBits = CGT.getTargetData().getABITypeSizeInBits(Ty) - BitFieldSize;
+    
+    if (LLVMFields.empty()) 
+      // Ths is - struct { char CurrentField:2; char B:4; }
+      addLLVMField(Ty, BitFieldSize, FD, 0, ExtraBits);
+    else {
+      const llvm::Type *PrevTy = LLVMFields.back();
+      if (CGT.getTargetData().getABITypeSizeInBits(PrevTy) >=
+          CGT.getTargetData().getABITypeSizeInBits(Ty)) 
+        // This is - struct { char A; char CurrentField:2; };
+        addLLVMField(Ty, BitFieldSize, FD, 0, ExtraBits);
+      else {
+        // This is - struct { char A; short CurrentField:2; };
+        // Use one of the previous filed to access current field.
+        bool FoundPrevField = false;
+        unsigned TotalOffsets = Offsets.size();
+        uint64_t TySize = CGT.getTargetData().getABITypeSizeInBits(Ty);
+        for (unsigned i = TotalOffsets; i != 0; --i) {
+          uint64_t O = Offsets[i - 1];
+          if (O % TySize == 0) {
+            // This is appropriate llvm field to share access.
+            FoundPrevField = true;
+            CurrentFieldStart = O % TySize;
+            unsigned FieldBegin = Cursor - (O % TySize);
+            unsigned FieldEnd = TySize - (FieldBegin + BitFieldSize);
+            Cursor += BitFieldSize;
+            CGT.addFieldInfo(FD, i, FieldBegin, FieldEnd);
+          }
+        }
+        assert(FoundPrevField && 
+               "Unable to find a place for bitfield in struct layout");
+      }
+    }
+  } else  if (ExtraBits >= BitFieldSize) {
+    // Reuse existing llvm field
+    ExtraBits = ExtraBits  - BitFieldSize;
+    CGT.addFieldInfo(FD, FieldNo, Cursor - CurrentFieldStart, ExtraBits);
+    Cursor = Cursor + BitFieldSize;
+    ++FieldNo;
+  } else {
+    //ExtraBits are not enough to hold entire FD.
+    const llvm::Type *Ty = CGT.ConvertType(FD->getType());
+    const llvm::Type *PrevTy = LLVMFields.back();
+    uint64_t TySize = CGT.getTargetData().getABITypeSizeInBits(Ty);
+    if (CGT.getTargetData().getABITypeSizeInBits(PrevTy) >= TySize) {
+      // Previous field does not allow sharing of ExtraBits. Use new field.
+      // struct { char a; char b:5; char c:4; } where c is current FD.
+      Cursor += ExtraBits;
+      ExtraBits = 0;
+      addLLVMField(Ty, TySize, FD, 0, BitFieldSize);
+    } else
+      assert (!FD->isBitField() && "Bit fields are not yet supported");
+  }
+}





More information about the cfe-commits mailing list