[llvm] r262045 - [IR] Optimize bitfield layout of Value for MSVC

Reid Kleckner via llvm-commits llvm-commits at lists.llvm.org
Fri Feb 26 10:09:00 PST 2016


Author: rnk
Date: Fri Feb 26 12:08:59 2016
New Revision: 262045

URL: http://llvm.org/viewvc/llvm-project?rev=262045&view=rev
Log:
[IR] Optimize bitfield layout of Value for MSVC

This should save a pointer of padding from all MSVC Value subclasses.

Recall that MSVC will not pack the following bitfields together:
  unsigned Bits : 29;
  unsigned Flag1 : 1;
  unsigned Flag2 : 1;
  unsigned Flag3 : 1;

Add a static_assert because LLVM developers always trip over this
behavior. This regressed in June.

Modified:
    llvm/trunk/include/llvm/IR/DataLayout.h
    llvm/trunk/include/llvm/IR/GlobalValue.h
    llvm/trunk/include/llvm/IR/Value.h
    llvm/trunk/lib/IR/Value.cpp

Modified: llvm/trunk/include/llvm/IR/DataLayout.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/DataLayout.h?rev=262045&r1=262044&r2=262045&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/DataLayout.h (original)
+++ llvm/trunk/include/llvm/IR/DataLayout.h Fri Feb 26 12:08:59 2016
@@ -476,7 +476,7 @@ inline LLVMTargetDataRef wrap(const Data
 class StructLayout {
   uint64_t StructSize;
   unsigned StructAlignment;
-  bool IsPadded : 1;
+  unsigned IsPadded : 1;
   unsigned NumElements : 31;
   uint64_t MemberOffsets[1]; // variable sized array!
 public:

Modified: llvm/trunk/include/llvm/IR/GlobalValue.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/GlobalValue.h?rev=262045&r1=262044&r2=262045&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/GlobalValue.h (original)
+++ llvm/trunk/include/llvm/IR/GlobalValue.h Fri Feb 26 12:08:59 2016
@@ -75,9 +75,9 @@ protected:
   }
 
   Type *ValueType;
-  // Note: VC++ treats enums as signed, so an extra bit is required to prevent
-  // Linkage and Visibility from turning into negative values.
-  LinkageTypes Linkage : 5;   // The linkage of this global
+  // All bitfields use unsigned as the underlying type so that MSVC will pack
+  // them.
+  unsigned Linkage : 4;       // The linkage of this global
   unsigned Visibility : 2;    // The visibility style of this global
   unsigned UnnamedAddr : 1;   // This value's address is not significant
   unsigned DllStorageClass : 2; // DLL storage class
@@ -259,44 +259,40 @@ public:
            Linkage == CommonLinkage || Linkage == ExternalWeakLinkage;
   }
 
-  bool hasExternalLinkage() const { return isExternalLinkage(Linkage); }
+  bool hasExternalLinkage() const { return isExternalLinkage(getLinkage()); }
   bool hasAvailableExternallyLinkage() const {
-    return isAvailableExternallyLinkage(Linkage);
+    return isAvailableExternallyLinkage(getLinkage());
   }
-  bool hasLinkOnceLinkage() const {
-    return isLinkOnceLinkage(Linkage);
+  bool hasLinkOnceLinkage() const { return isLinkOnceLinkage(getLinkage()); }
+  bool hasLinkOnceODRLinkage() const {
+    return isLinkOnceODRLinkage(getLinkage());
+  }
+  bool hasWeakLinkage() const { return isWeakLinkage(getLinkage()); }
+  bool hasWeakAnyLinkage() const { return isWeakAnyLinkage(getLinkage()); }
+  bool hasWeakODRLinkage() const { return isWeakODRLinkage(getLinkage()); }
+  bool hasAppendingLinkage() const { return isAppendingLinkage(getLinkage()); }
+  bool hasInternalLinkage() const { return isInternalLinkage(getLinkage()); }
+  bool hasPrivateLinkage() const { return isPrivateLinkage(getLinkage()); }
+  bool hasLocalLinkage() const { return isLocalLinkage(getLinkage()); }
+  bool hasExternalWeakLinkage() const {
+    return isExternalWeakLinkage(getLinkage());
   }
-  bool hasLinkOnceODRLinkage() const { return isLinkOnceODRLinkage(Linkage); }
-  bool hasWeakLinkage() const {
-    return isWeakLinkage(Linkage);
-  }
-  bool hasWeakAnyLinkage() const {
-    return isWeakAnyLinkage(Linkage);
-  }
-  bool hasWeakODRLinkage() const {
-    return isWeakODRLinkage(Linkage);
-  }
-  bool hasAppendingLinkage() const { return isAppendingLinkage(Linkage); }
-  bool hasInternalLinkage() const { return isInternalLinkage(Linkage); }
-  bool hasPrivateLinkage() const { return isPrivateLinkage(Linkage); }
-  bool hasLocalLinkage() const { return isLocalLinkage(Linkage); }
-  bool hasExternalWeakLinkage() const { return isExternalWeakLinkage(Linkage); }
-  bool hasCommonLinkage() const { return isCommonLinkage(Linkage); }
+  bool hasCommonLinkage() const { return isCommonLinkage(getLinkage()); }
 
   void setLinkage(LinkageTypes LT) {
     if (isLocalLinkage(LT))
       Visibility = DefaultVisibility;
     Linkage = LT;
   }
-  LinkageTypes getLinkage() const { return Linkage; }
+  LinkageTypes getLinkage() const { return LinkageTypes(Linkage); }
 
   bool isDiscardableIfUnused() const {
-    return isDiscardableIfUnused(Linkage);
+    return isDiscardableIfUnused(getLinkage());
   }
 
-  bool mayBeOverridden() const { return mayBeOverridden(Linkage); }
+  bool mayBeOverridden() const { return mayBeOverridden(getLinkage()); }
 
-  bool isWeakForLinker() const { return isWeakForLinker(Linkage); }
+  bool isWeakForLinker() const { return isWeakForLinker(getLinkage()); }
 
   /// Copy all additional attributes (those not needed to create a GlobalValue)
   /// from the GlobalValue Src to this one.

Modified: llvm/trunk/include/llvm/IR/Value.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Value.h?rev=262045&r1=262044&r2=262045&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Value.h (original)
+++ llvm/trunk/include/llvm/IR/Value.h Fri Feb 26 12:08:59 2016
@@ -107,10 +107,11 @@ protected:
   enum : unsigned { NumUserOperandsBits = 28 };
   unsigned NumUserOperands : NumUserOperandsBits;
 
-  bool IsUsedByMD : 1;
-  bool HasName : 1;
-  bool HasHungOffUses : 1;
-  bool HasDescriptor : 1;
+  // Use the same type as the bitfield above so that MSVC will pack them.
+  unsigned IsUsedByMD : 1;
+  unsigned HasName : 1;
+  unsigned HasHungOffUses : 1;
+  unsigned HasDescriptor : 1;
 
 private:
   template <typename UseT> // UseT == 'Use' or 'const Use'

Modified: llvm/trunk/lib/IR/Value.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Value.cpp?rev=262045&r1=262044&r2=262045&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Value.cpp (original)
+++ llvm/trunk/lib/IR/Value.cpp Fri Feb 26 12:08:59 2016
@@ -59,6 +59,8 @@ Value::Value(Type *ty, unsigned scid)
            (SubclassID < ConstantFirstVal || SubclassID > ConstantLastVal))
     assert((VTy->isFirstClassType() || VTy->isVoidTy()) &&
            "Cannot create non-first-class values except for constants!");
+  static_assert(sizeof(Value) == 3 * sizeof(void *) + 2 * sizeof(unsigned),
+                "Value too big");
 }
 
 Value::~Value() {




More information about the llvm-commits mailing list