[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.

llvm-svn: 262045
This commit is contained in:
Reid Kleckner 2016-02-26 18:08:59 +00:00
parent 334685b486
commit 1762ad3e73
4 changed files with 30 additions and 31 deletions

View File

@ -476,7 +476,7 @@ inline LLVMTargetDataRef wrap(const DataLayout *P) {
class StructLayout {
uint64_t StructSize;
unsigned StructAlignment;
bool IsPadded : 1;
unsigned IsPadded : 1;
unsigned NumElements : 31;
uint64_t MemberOffsets[1]; // variable sized array!
public:

View File

@ -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 hasLinkOnceODRLinkage() const { return isLinkOnceODRLinkage(Linkage); }
bool hasWeakLinkage() const {
return isWeakLinkage(Linkage);
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 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.

View File

@ -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'

View File

@ -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() {