Encode MCSymbol alignment as log2(align).
authorPete Cooper <peter_cooper@apple.com>
Wed, 1 Jul 2015 21:07:03 +0000 (21:07 +0000)
committerPete Cooper <peter_cooper@apple.com>
Wed, 1 Jul 2015 21:07:03 +0000 (21:07 +0000)
Given that alignments are always powers of 2, just encode it this way.

This matches how we encode alignment on IR GlobalValue's for example.

This compresses the CommonAlign member down to 5 bits which allows it
to pack better with the surrounding fields.

Reviewed by Duncan Exon Smith.

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

include/llvm/MC/MCSymbol.h
lib/MC/MCSymbol.cpp

index 48b50d9ada1ee208528e1024b798e0b69d768437..e52a34601b091da1ec162e1b2af0c3c07d391e9e 100644 (file)
@@ -109,6 +109,14 @@ protected:
   /// extension and achieve better bitpacking with MSVC.
   unsigned SymbolContents : 2;
 
+  /// The alignment of the symbol, if it is 'common', or -1.
+  ///
+  /// The alignment is stored as log2(align) + 1.  This allows all values from
+  /// 0 to 2^31 to be stored which is every power of 2 representable by an
+  /// unsigned.
+  static const unsigned NumCommonAlignmentBits = 5;
+  unsigned CommonAlignLog2 : NumCommonAlignmentBits;
+
   /// Index field, for use by the object file implementation.
   mutable uint32_t Index = 0;
 
@@ -123,11 +131,6 @@ protected:
     const MCExpr *Value;
   };
 
-  /// The alignment of the symbol, if it is 'common', or -1.
-  //
-  // FIXME: Pack this in with other fields?
-  unsigned CommonAlign = -1U;
-
   /// The Flags field is used by object file implementations to store
   /// additional per symbol information which is not easily classified.
   mutable uint32_t Flags = 0;
@@ -148,7 +151,8 @@ protected: // MCContext creates and uniques these.
   MCSymbol(SymbolKind Kind, const StringMapEntry<bool> *Name, bool isTemporary)
       : IsTemporary(isTemporary), IsRedefinable(false), IsUsed(false),
         IsRegistered(false), IsExternal(false), IsPrivateExtern(false),
-        Kind(Kind), IsUsedInReloc(false), SymbolContents(SymContentsUnset) {
+        Kind(Kind), IsUsedInReloc(false), SymbolContents(SymContentsUnset),
+        CommonAlignLog2(0) {
     Offset = 0;
     SectionOrFragmentAndHasName.setInt(!!Name);
     if (Name)
@@ -338,14 +342,20 @@ public:
   void setCommon(uint64_t Size, unsigned Align) {
     assert(getOffset() == 0);
     CommonSize = Size;
-    CommonAlign = Align;
     SymbolContents = SymContentsCommon;
+
+    assert((!Align || isPowerOf2_32(Align)) &&
+           "Alignment must be a power of 2");
+    unsigned Log2Align = Log2_32(Align) + 1;
+    assert(Log2Align < (1U << NumCommonAlignmentBits) &&
+           "Out of range alignment");
+    CommonAlignLog2 = Log2Align;
   }
 
   ///  Return the alignment of a 'common' symbol.
   unsigned getCommonAlignment() const {
     assert(isCommon() && "Not a 'common' symbol!");
-    return CommonAlign;
+    return CommonAlignLog2 ? (1U << (CommonAlignLog2 - 1)) : 0;
   }
 
   /// Declare this symbol as being 'common'.
@@ -356,7 +366,7 @@ public:
   bool declareCommon(uint64_t Size, unsigned Align) {
     assert(isCommon() || getOffset() == 0);
     if(isCommon()) {
-      if(CommonSize != Size || CommonAlign != Align)
+      if(CommonSize != Size || getCommonAlignment() != Align)
        return true;
     } else
       setCommon(Size, Align);
index 125380a9d14066aea4508f4a35d8f37b9366512e..2655a181a2323a70828ddf6f0c5bed3780d1ef5e 100644 (file)
@@ -19,6 +19,8 @@ using namespace llvm;
 // Sentinel value for the absolute pseudo section.
 MCSection *MCSymbol::AbsolutePseudoSection = reinterpret_cast<MCSection *>(1);
 
+const unsigned MCSymbol::NumCommonAlignmentBits;
+
 void *MCSymbol::operator new(size_t s, const StringMapEntry<bool> *Name,
                              MCContext &Ctx) {
   // We may need more space for a Name to account for alignment.  So allocate