forked from OSchip/llvm-project
[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
This commit is contained in:
parent
a916e81927
commit
8e7d771cf9
|
@ -34,7 +34,7 @@ using SectionAddrMap = DenseMap<const MCSection *, uint64_t>;
|
||||||
/// needed for parsing.
|
/// needed for parsing.
|
||||||
class MCExpr {
|
class MCExpr {
|
||||||
public:
|
public:
|
||||||
enum ExprKind {
|
enum ExprKind : uint8_t {
|
||||||
Binary, ///< Binary expressions.
|
Binary, ///< Binary expressions.
|
||||||
Constant, ///< Constant expressions.
|
Constant, ///< Constant expressions.
|
||||||
SymbolRef, ///< References to labels and assigned expressions.
|
SymbolRef, ///< References to labels and assigned expressions.
|
||||||
|
@ -43,7 +43,14 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
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;
|
ExprKind Kind;
|
||||||
|
/// Field reserved for use by MCExpr subclasses.
|
||||||
|
unsigned SubclassData : NumSubclassDataBits;
|
||||||
SMLoc Loc;
|
SMLoc Loc;
|
||||||
|
|
||||||
bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
|
bool evaluateAsAbsolute(int64_t &Res, const MCAssembler *Asm,
|
||||||
|
@ -51,13 +58,19 @@ private:
|
||||||
const SectionAddrMap *Addrs, bool InSet) const;
|
const SectionAddrMap *Addrs, bool InSet) const;
|
||||||
|
|
||||||
protected:
|
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,
|
bool evaluateAsRelocatableImpl(MCValue &Res, const MCAssembler *Asm,
|
||||||
const MCAsmLayout *Layout,
|
const MCAsmLayout *Layout,
|
||||||
const MCFixup *Fixup,
|
const MCFixup *Fixup,
|
||||||
const SectionAddrMap *Addrs, bool InSet) const;
|
const SectionAddrMap *Addrs, bool InSet) const;
|
||||||
|
|
||||||
|
unsigned getSubclassData() const { return SubclassData; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
MCExpr(const MCExpr &) = delete;
|
MCExpr(const MCExpr &) = delete;
|
||||||
MCExpr &operator=(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.
|
//// Represent a constant integer expression.
|
||||||
class MCConstantExpr : public MCExpr {
|
class MCConstantExpr : public MCExpr {
|
||||||
int64_t Value;
|
int64_t Value;
|
||||||
bool PrintInHex = false;
|
|
||||||
unsigned SizeInBytes = 0;
|
|
||||||
|
|
||||||
explicit MCConstantExpr(int64_t Value)
|
// Subclass data stores SizeInBytes in bits 0..7 and PrintInHex in bit 8.
|
||||||
: MCExpr(MCExpr::Constant, SMLoc()), Value(Value) {}
|
static const unsigned SizeInBytesBits = 8;
|
||||||
|
static const unsigned SizeInBytesMask = (1 << SizeInBytesBits) - 1;
|
||||||
|
static const unsigned PrintInHexBit = 1 << SizeInBytesBits;
|
||||||
|
|
||||||
MCConstantExpr(int64_t Value, bool PrintInHex)
|
static unsigned encodeSubclassData(bool PrintInHex, unsigned SizeInBytes) {
|
||||||
: MCExpr(MCExpr::Constant, SMLoc()), Value(Value),
|
assert(SizeInBytes <= sizeof(int64_t) && "Excessive size");
|
||||||
PrintInHex(PrintInHex) {}
|
return SizeInBytes | (PrintInHex ? PrintInHexBit : 0);
|
||||||
|
}
|
||||||
|
|
||||||
MCConstantExpr(int64_t Value, bool PrintInHex, unsigned SizeInBytes)
|
MCConstantExpr(int64_t Value, bool PrintInHex, unsigned SizeInBytes)
|
||||||
: MCExpr(MCExpr::Constant, SMLoc()), Value(Value), PrintInHex(PrintInHex),
|
: MCExpr(MCExpr::Constant, SMLoc(),
|
||||||
SizeInBytes(SizeInBytes) {}
|
encodeSubclassData(PrintInHex, SizeInBytes)), Value(Value) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// \name Construction
|
/// \name Construction
|
||||||
|
@ -157,9 +171,11 @@ public:
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
int64_t getValue() const { return Value; }
|
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,18 +331,33 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/// The symbol reference modifier.
|
|
||||||
const VariantKind Kind;
|
|
||||||
|
|
||||||
/// Specifies how the variant kind should be printed.
|
|
||||||
const unsigned UseParensForSymbolVariant : 1;
|
|
||||||
|
|
||||||
// FIXME: Remove this bit.
|
|
||||||
const unsigned HasSubsectionsViaSymbols : 1;
|
|
||||||
|
|
||||||
/// The symbol being referenced.
|
/// The symbol being referenced.
|
||||||
const MCSymbol *Symbol;
|
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.
|
||||||
|
static const unsigned UseParensForSymbolVariantBit = 1 << VariantKindBits;
|
||||||
|
|
||||||
|
// FIXME: Remove this bit.
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool useParensForSymbolVariant() const {
|
||||||
|
return (getSubclassData() & UseParensForSymbolVariantBit) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
explicit MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind,
|
explicit MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind,
|
||||||
const MCAsmInfo *MAI, SMLoc Loc = SMLoc());
|
const MCAsmInfo *MAI, SMLoc Loc = SMLoc());
|
||||||
|
|
||||||
|
@ -349,11 +380,15 @@ public:
|
||||||
|
|
||||||
const MCSymbol &getSymbol() const { return *Symbol; }
|
const MCSymbol &getSymbol() const { return *Symbol; }
|
||||||
|
|
||||||
VariantKind getKind() const { return Kind; }
|
VariantKind getKind() const {
|
||||||
|
return (VariantKind)(getSubclassData() & VariantKindMask);
|
||||||
|
}
|
||||||
|
|
||||||
void printVariantKind(raw_ostream &OS) const;
|
void printVariantKind(raw_ostream &OS) const;
|
||||||
|
|
||||||
bool hasSubsectionsViaSymbols() const { return HasSubsectionsViaSymbols; }
|
bool hasSubsectionsViaSymbols() const {
|
||||||
|
return (getSubclassData() & HasSubsectionsViaSymbolsBit) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
/// @}
|
/// @}
|
||||||
/// \name Static Utility Functions
|
/// \name Static Utility Functions
|
||||||
|
@ -381,11 +416,10 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Opcode Op;
|
|
||||||
const MCExpr *Expr;
|
const MCExpr *Expr;
|
||||||
|
|
||||||
MCUnaryExpr(Opcode Op, const MCExpr *Expr, SMLoc Loc)
|
MCUnaryExpr(Opcode Op, const MCExpr *Expr, SMLoc Loc)
|
||||||
: MCExpr(MCExpr::Unary, Loc), Op(Op), Expr(Expr) {}
|
: MCExpr(MCExpr::Unary, Loc, Op), Expr(Expr) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// \name Construction
|
/// \name Construction
|
||||||
|
@ -415,7 +449,7 @@ public:
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/// Get the kind of this unary expression.
|
/// 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.
|
/// Get the child of this unary expression.
|
||||||
const MCExpr *getSubExpr() const { return Expr; }
|
const MCExpr *getSubExpr() const { return Expr; }
|
||||||
|
@ -457,12 +491,11 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Opcode Op;
|
|
||||||
const MCExpr *LHS, *RHS;
|
const MCExpr *LHS, *RHS;
|
||||||
|
|
||||||
MCBinaryExpr(Opcode Op, const MCExpr *LHS, const MCExpr *RHS,
|
MCBinaryExpr(Opcode Op, const MCExpr *LHS, const MCExpr *RHS,
|
||||||
SMLoc Loc = SMLoc())
|
SMLoc Loc = SMLoc())
|
||||||
: MCExpr(MCExpr::Binary, Loc), Op(Op), LHS(LHS), RHS(RHS) {}
|
: MCExpr(MCExpr::Binary, Loc, Op), LHS(LHS), RHS(RHS) {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// \name Construction
|
/// \name Construction
|
||||||
|
@ -572,7 +605,7 @@ public:
|
||||||
/// @{
|
/// @{
|
||||||
|
|
||||||
/// Get the kind of this binary expression.
|
/// 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.
|
/// Get the left-hand side expression of the binary operator.
|
||||||
const MCExpr *getLHS() const { return LHS; }
|
const MCExpr *getLHS() const { return LHS; }
|
||||||
|
|
|
@ -193,9 +193,9 @@ const MCConstantExpr *MCConstantExpr::create(int64_t Value, MCContext &Ctx,
|
||||||
|
|
||||||
MCSymbolRefExpr::MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind,
|
MCSymbolRefExpr::MCSymbolRefExpr(const MCSymbol *Symbol, VariantKind Kind,
|
||||||
const MCAsmInfo *MAI, SMLoc Loc)
|
const MCAsmInfo *MAI, SMLoc Loc)
|
||||||
: MCExpr(MCExpr::SymbolRef, Loc), Kind(Kind),
|
: MCExpr(MCExpr::SymbolRef, Loc,
|
||||||
UseParensForSymbolVariant(MAI->useParensForSymbolVariant()),
|
encodeSubclassData(Kind, MAI->useParensForSymbolVariant(),
|
||||||
HasSubsectionsViaSymbols(MAI->hasSubsectionsViaSymbols()),
|
MAI->hasSubsectionsViaSymbols())),
|
||||||
Symbol(Symbol) {
|
Symbol(Symbol) {
|
||||||
assert(Symbol);
|
assert(Symbol);
|
||||||
}
|
}
|
||||||
|
@ -464,7 +464,7 @@ MCSymbolRefExpr::getVariantKindForName(StringRef Name) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MCSymbolRefExpr::printVariantKind(raw_ostream &OS) const {
|
void MCSymbolRefExpr::printVariantKind(raw_ostream &OS) const {
|
||||||
if (UseParensForSymbolVariant)
|
if (useParensForSymbolVariant())
|
||||||
OS << '(' << MCSymbolRefExpr::getVariantKindName(getKind()) << ')';
|
OS << '(' << MCSymbolRefExpr::getVariantKindName(getKind()) << ')';
|
||||||
else
|
else
|
||||||
OS << '@' << MCSymbolRefExpr::getVariantKindName(getKind());
|
OS << '@' << MCSymbolRefExpr::getVariantKindName(getKind());
|
||||||
|
|
Loading…
Reference in New Issue