[llvm] 8e7d771 - [MC] Use subclass data for MCExpr to reduce memory usage
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 15 11:02:37 PDT 2020
Author: Nikita Popov
Date: 2020-04-15T20:02:11+02:00
New Revision: 8e7d771cf9b6197c723e1ea8739563d24aca2e3c
URL: https://github.com/llvm/llvm-project/commit/8e7d771cf9b6197c723e1ea8739563d24aca2e3c
DIFF: https://github.com/llvm/llvm-project/commit/8e7d771cf9b6197c723e1ea8739563d24aca2e3c.diff
LOG: [MC] Use subclass data for MCExpr to reduce memory usage
MCExpr has a bunch of free space that is currently going to waste.
Repurpose it as 24 bits of subclass data, which is enough to reduce
the size of all subclasses by 8 bytes. This gives us some respectable
savings for debuginfo builds. Here are the max-rss reductions for the
fat LTO link step:
kc.link 238MiB 231MiB (-2.82%)
sqlite3.link 258MiB 250MiB (-3.27%)
consumer-typeset.link 152MiB 148MiB (-2.51%)
bullet.link 197MiB 192MiB (-2.30%)
tramp3d-v4.link 578MiB 567MiB (-1.92%)
pairlocalalign.link 92MiB 90MiB (-1.98%)
clamscan.link 230MiB 223MiB (-2.81%)
lencod.link 242MiB 235MiB (-2.67%)
SPASS.link 235MiB 230MiB (-2.23%)
7zip-benchmark.link 450MiB 435MiB (-3.25%)
Differential Revision: https://reviews.llvm.org/D77939
Added:
Modified:
llvm/include/llvm/MC/MCExpr.h
llvm/lib/MC/MCExpr.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/MC/MCExpr.h b/llvm/include/llvm/MC/MCExpr.h
index 386fa9c533c1..d1ffef779a52 100644
--- a/llvm/include/llvm/MC/MCExpr.h
+++ b/llvm/include/llvm/MC/MCExpr.h
@@ -34,7 +34,7 @@ using SectionAddrMap = DenseMap<const MCSection *, uint64_t>;
/// needed for parsing.
class MCExpr {
public:
- enum ExprKind {
+ enum ExprKind : uint8_t {
Binary, ///< Binary expressions.
Constant, ///< Constant expressions.
SymbolRef, ///< References to labels and assigned expressions.
@@ -43,7 +43,14 @@ class MCExpr {
};
private:
+ static const unsigned NumSubclassDataBits = 24;
+ static_assert(
+ NumSubclassDataBits == CHAR_BIT * (sizeof(unsigned) - sizeof(ExprKind)),
+ "ExprKind and SubclassData together should take up one word");
+
ExprKind Kind;
+ /// Field reserved for use by MCExpr subclasses.
+ unsigned SubclassData : NumSubclassDataBits;
SMLoc Loc;
bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
@@ -51,13 +58,19 @@ class MCExpr {
const SectionAddrMap *Addrs, bool InSet) const;
protected:
- explicit MCExpr(ExprKind Kind, SMLoc Loc) : Kind(Kind), Loc(Loc) {}
+ explicit MCExpr(ExprKind Kind, SMLoc Loc, unsigned SubclassData = 0)
+ : Kind(Kind), SubclassData(SubclassData), Loc(Loc) {
+ assert(SubclassData < (1 << NumSubclassDataBits) &&
+ "Subclass data too large");
+ }
bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
const MCAsmLayout *Layout,
const MCFixup *Fixup,
const SectionAddrMap *Addrs, bool InSet) const;
+ unsigned getSubclassData() const { return SubclassData; }
+
public:
MCExpr(const MCExpr &) = delete;
MCExpr &operator=(const MCExpr &) = delete;
@@ -130,19 +143,20 @@ inline raw_ostream &operator<<(raw_ostream &OS, const MCExpr &E) {
//// Represent a constant integer expression.
class MCConstantExpr : public MCExpr {
int64_t Value;
- bool PrintInHex = false;
- unsigned SizeInBytes = 0;
- explicit MCConstantExpr(int64_t Value)
- : MCExpr(MCExpr::Constant, SMLoc()), Value(Value) {}
+ // Subclass data stores SizeInBytes in bits 0..7 and PrintInHex in bit 8.
+ static const unsigned SizeInBytesBits = 8;
+ static const unsigned SizeInBytesMask = (1 << SizeInBytesBits) - 1;
+ static const unsigned PrintInHexBit = 1 << SizeInBytesBits;
- MCConstantExpr(int64_t Value, bool PrintInHex)
- : MCExpr(MCExpr::Constant, SMLoc()), Value(Value),
- PrintInHex(PrintInHex) {}
+ static unsigned encodeSubclassData(bool PrintInHex, unsigned SizeInBytes) {
+ assert(SizeInBytes <= sizeof(int64_t) && "Excessive size");
+ return SizeInBytes | (PrintInHex ? PrintInHexBit : 0);
+ }
MCConstantExpr(int64_t Value, bool PrintInHex, unsigned SizeInBytes)
- : MCExpr(MCExpr::Constant, SMLoc()), Value(Value), PrintInHex(PrintInHex),
- SizeInBytes(SizeInBytes) {}
+ : MCExpr(MCExpr::Constant, SMLoc(),
+ encodeSubclassData(PrintInHex, SizeInBytes)), Value(Value) {}
public:
/// \name Construction
@@ -157,9 +171,11 @@ class MCConstantExpr : public MCExpr {
/// @{
int64_t getValue() const { return Value; }
- unsigned getSizeInBytes() const { return SizeInBytes; }
+ unsigned getSizeInBytes() const {
+ return getSubclassData() & SizeInBytesMask;
+ }
- bool useHexFormat() const { return PrintInHex; }
+ bool useHexFormat() const { return (getSubclassData() & PrintInHexBit) != 0; }
/// @}
@@ -315,17 +331,32 @@ class MCSymbolRefExpr : public MCExpr {
};
private:
- /// The symbol reference modifier.
- const VariantKind Kind;
+ /// The symbol being referenced.
+ const MCSymbol *Symbol;
+
+ // Subclass data stores VariantKind in bits 0..15, UseParensForSymbolVariant
+ // in bit 16 and HasSubsectionsViaSymbols in bit 17.
+ static const unsigned VariantKindBits = 16;
+ static const unsigned VariantKindMask = (1 << VariantKindBits) - 1;
/// Specifies how the variant kind should be printed.
- const unsigned UseParensForSymbolVariant : 1;
+ static const unsigned UseParensForSymbolVariantBit = 1 << VariantKindBits;
// FIXME: Remove this bit.
- const unsigned HasSubsectionsViaSymbols : 1;
+ static const unsigned HasSubsectionsViaSymbolsBit =
+ 1 << (VariantKindBits + 1);
+
+ static unsigned encodeSubclassData(VariantKind Kind,
+ bool UseParensForSymbolVariant,
+ bool HasSubsectionsViaSymbols) {
+ return (unsigned)Kind |
+ (UseParensForSymbolVariant ? UseParensForSymbolVariantBit : 0) |
+ (HasSubsectionsViaSymbols ? HasSubsectionsViaSymbolsBit : 0);
+ }
- /// The symbol being referenced.
- const MCSymbol *Symbol;
+ bool useParensForSymbolVariant() const {
+ return (getSubclassData() & UseParensForSymbolVariantBit) != 0;
+ }
explicit MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind,
const MCAsmInfo *MAI, SMLoc Loc = SMLoc());
@@ -349,11 +380,15 @@ class MCSymbolRefExpr : public MCExpr {
const MCSymbol &getSymbol() const { return *Symbol; }
- VariantKind getKind() const { return Kind; }
+ VariantKind getKind() const {
+ return (VariantKind)(getSubclassData() & VariantKindMask);
+ }
void printVariantKind(raw_ostream &OS) const;
- bool hasSubsectionsViaSymbols() const { return HasSubsectionsViaSymbols; }
+ bool hasSubsectionsViaSymbols() const {
+ return (getSubclassData() & HasSubsectionsViaSymbolsBit) != 0;
+ }
/// @}
/// \name Static Utility Functions
@@ -381,11 +416,10 @@ class MCUnaryExpr : public MCExpr {
};
private:
- Opcode Op;
const MCExpr *Expr;
MCUnaryExpr(Opcode Op, const MCExpr *Expr, SMLoc Loc)
- : MCExpr(MCExpr::Unary, Loc), Op(Op), Expr(Expr) {}
+ : MCExpr(MCExpr::Unary, Loc, Op), Expr(Expr) {}
public:
/// \name Construction
@@ -415,7 +449,7 @@ class MCUnaryExpr : public MCExpr {
/// @{
/// Get the kind of this unary expression.
- Opcode getOpcode() const { return Op; }
+ Opcode getOpcode() const { return (Opcode)getSubclassData(); }
/// Get the child of this unary expression.
const MCExpr *getSubExpr() const { return Expr; }
@@ -457,12 +491,11 @@ class MCBinaryExpr : public MCExpr {
};
private:
- Opcode Op;
const MCExpr *LHS, *RHS;
MCBinaryExpr(Opcode Op, const MCExpr *LHS, const MCExpr *RHS,
SMLoc Loc = SMLoc())
- : MCExpr(MCExpr::Binary, Loc), Op(Op), LHS(LHS), RHS(RHS) {}
+ : MCExpr(MCExpr::Binary, Loc, Op), LHS(LHS), RHS(RHS) {}
public:
/// \name Construction
@@ -572,7 +605,7 @@ class MCBinaryExpr : public MCExpr {
/// @{
/// Get the kind of this binary expression.
- Opcode getOpcode() const { return Op; }
+ Opcode getOpcode() const { return (Opcode)getSubclassData(); }
/// Get the left-hand side expression of the binary operator.
const MCExpr *getLHS() const { return LHS; }
diff --git a/llvm/lib/MC/MCExpr.cpp b/llvm/lib/MC/MCExpr.cpp
index 091880250ec5..1448a54a04e3 100644
--- a/llvm/lib/MC/MCExpr.cpp
+++ b/llvm/lib/MC/MCExpr.cpp
@@ -193,9 +193,9 @@ const MCConstantExpr *MCConstantExpr::create(int64_t Value, MCContext &Ctx,
MCSymbolRefExpr::MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind,
const MCAsmInfo *MAI, SMLoc Loc)
- : MCExpr(MCExpr::SymbolRef, Loc), Kind(Kind),
- UseParensForSymbolVariant(MAI->useParensForSymbolVariant()),
- HasSubsectionsViaSymbols(MAI->hasSubsectionsViaSymbols()),
+ : MCExpr(MCExpr::SymbolRef, Loc,
+ encodeSubclassData(Kind, MAI->useParensForSymbolVariant(),
+ MAI->hasSubsectionsViaSymbols())),
Symbol(Symbol) {
assert(Symbol);
}
@@ -464,7 +464,7 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
}
void MCSymbolRefExpr::printVariantKind(raw_ostream &OS) const {
- if (UseParensForSymbolVariant)
+ if (useParensForSymbolVariant())
OS << '(' << MCSymbolRefExpr::getVariantKindName(getKind()) << ')';
else
OS << '@' << MCSymbolRefExpr::getVariantKindName(getKind());
More information about the llvm-commits
mailing list