Commit 1d62cf08 by Jan Voung

Make fixups reference any constant (allow const float/double pool literals).

This avoids doing getConstantSym to avoid hitting the global context's getConstantSym during emitIAS(), which may be desirable for multi-threading, since each function's emitIAS() should be able to happen on a separate thread. The stringification is moved till later, so it still happens, just without creating a constant relocatable w/ offset of 0. This ends up tickling an issue where -O0 on 252.eon now gets 2x as many page faults, and I'm not sure exactly why. This makes the overall time higher, though emit time is lower. When translating with -O2 # of page faults is about the same before/after, so that oddness is restricted to O0. Before this change, tweaking the slab size at O0 doesn't seem to affect as drastically as 2x swings either. To work around this, I turned the slab size of the assembler down to 32KB. === Move all the .L$type$poolid into a function (replacing getPoolEntryID). BUG=none R=stichnot@chromium.org Review URL: https://codereview.chromium.org/837553009
parent 2e7daeff
...@@ -25,7 +25,7 @@ namespace Ice { ...@@ -25,7 +25,7 @@ namespace Ice {
thread_local const Cfg *Cfg::CurrentCfg = nullptr; thread_local const Cfg *Cfg::CurrentCfg = nullptr;
ArenaAllocator *getCurrentCfgAllocator() { ArenaAllocator<> *getCurrentCfgAllocator() {
return Cfg::getCurrentCfgAllocator(); return Cfg::getCurrentCfgAllocator();
} }
...@@ -33,7 +33,7 @@ Cfg::Cfg(GlobalContext *Ctx) ...@@ -33,7 +33,7 @@ Cfg::Cfg(GlobalContext *Ctx)
: Ctx(Ctx), FunctionName(""), ReturnType(IceType_void), : Ctx(Ctx), FunctionName(""), ReturnType(IceType_void),
IsInternalLinkage(false), HasError(false), FocusedTiming(false), IsInternalLinkage(false), HasError(false), FocusedTiming(false),
ErrorMessage(""), Entry(nullptr), NextInstNumber(Inst::NumberInitial), ErrorMessage(""), Entry(nullptr), NextInstNumber(Inst::NumberInitial),
Allocator(new ArenaAllocator()), Live(nullptr), Allocator(new ArenaAllocator<>()), Live(nullptr),
Target(TargetLowering::createLowering(Ctx->getTargetArch(), this)), Target(TargetLowering::createLowering(Ctx->getTargetArch(), this)),
VMetadata(new VariablesMetadata(this)), VMetadata(new VariablesMetadata(this)),
TargetAssembler( TargetAssembler(
......
...@@ -43,7 +43,7 @@ public: ...@@ -43,7 +43,7 @@ public:
// Gets a pointer to the current thread's Cfg. // Gets a pointer to the current thread's Cfg.
static const Cfg *getCurrentCfg() { return CurrentCfg; } static const Cfg *getCurrentCfg() { return CurrentCfg; }
// Gets a pointer to the current thread's Cfg's allocator. // Gets a pointer to the current thread's Cfg's allocator.
static ArenaAllocator *getCurrentCfgAllocator() { static ArenaAllocator<> *getCurrentCfgAllocator() {
assert(CurrentCfg); assert(CurrentCfg);
return CurrentCfg->Allocator.get(); return CurrentCfg->Allocator.get();
} }
...@@ -197,7 +197,7 @@ private: ...@@ -197,7 +197,7 @@ private:
VarList Variables; VarList Variables;
VarList Args; // subset of Variables, in argument order VarList Args; // subset of Variables, in argument order
VarList ImplicitArgs; // subset of Variables VarList ImplicitArgs; // subset of Variables
std::unique_ptr<ArenaAllocator> Allocator; std::unique_ptr<ArenaAllocator<>> Allocator;
std::unique_ptr<Liveness> Live; std::unique_ptr<Liveness> Live;
std::unique_ptr<TargetLowering> Target; std::unique_ptr<TargetLowering> Target;
std::unique_ptr<VariablesMetadata> VMetadata; std::unique_ptr<VariablesMetadata> VMetadata;
......
...@@ -58,10 +58,11 @@ class Variable; ...@@ -58,10 +58,11 @@ class Variable;
class VariableDeclaration; class VariableDeclaration;
class VariablesMetadata; class VariablesMetadata;
typedef llvm::BumpPtrAllocatorImpl<llvm::MallocAllocator, 1024 * 1024> template <size_t SlabSize = 1024 * 1024>
ArenaAllocator; using ArenaAllocator =
llvm::BumpPtrAllocatorImpl<llvm::MallocAllocator, SlabSize>;
ArenaAllocator *getCurrentCfgAllocator(); ArenaAllocator<> *getCurrentCfgAllocator();
template <typename T> struct CfgLocalAllocator { template <typename T> struct CfgLocalAllocator {
using value_type = T; using value_type = T;
......
...@@ -325,7 +325,7 @@ template <typename ConstType> void ELFObjectWriter::writeConstantPool(Type Ty) { ...@@ -325,7 +325,7 @@ template <typename ConstType> void ELFObjectWriter::writeConstantPool(Type Ty) {
auto Const = llvm::cast<ConstType>(C); auto Const = llvm::cast<ConstType>(C);
std::string SymBuffer; std::string SymBuffer;
llvm::raw_string_ostream SymStrBuf(SymBuffer); llvm::raw_string_ostream SymStrBuf(SymBuffer);
SymStrBuf << ".L$" << Ty << "$" << Const->getPoolEntryID(); Const->emitPoolLabel(SymStrBuf);
std::string &SymName = SymStrBuf.str(); std::string &SymName = SymStrBuf.str();
SymTab->createDefinedSym(SymName, STT_NOTYPE, STB_LOCAL, Section, SymTab->createDefinedSym(SymName, STT_NOTYPE, STB_LOCAL, Section,
OffsetInSection, SymbolSize); OffsetInSection, SymbolSize);
......
...@@ -197,7 +197,7 @@ private: ...@@ -197,7 +197,7 @@ private:
Ostream *StrDump; // Stream for dumping / diagnostics Ostream *StrDump; // Stream for dumping / diagnostics
Ostream *StrEmit; // Stream for code emission Ostream *StrEmit; // Stream for code emission
ArenaAllocator Allocator; ArenaAllocator<> Allocator;
VerboseMask VMask; VerboseMask VMask;
std::unique_ptr<class ConstantPool> ConstPool; std::unique_ptr<class ConstantPool> ConstPool;
Intrinsics IntrinsicsInfo; Intrinsics IntrinsicsInfo;
......
...@@ -587,7 +587,8 @@ void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Var, ...@@ -587,7 +587,8 @@ void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Var,
} else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
AssemblerFixup *Fixup = AssemblerFixup *Fixup =
x86::DisplacementRelocation::create(Asm, FK_Abs_4, Reloc); x86::DisplacementRelocation::create(Asm, FK_Abs_4, Reloc);
(Asm->*(Emitter.GPRImm))(Ty, VarReg, x86::Immediate(Fixup)); (Asm->*(Emitter.GPRImm))(Ty, VarReg,
x86::Immediate(Reloc->getOffset(), Fixup));
} else if (const auto Split = llvm::dyn_cast<VariableSplit>(Src)) { } else if (const auto Split = llvm::dyn_cast<VariableSplit>(Src)) {
(Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func)); (Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func));
} else { } else {
...@@ -610,7 +611,8 @@ void emitIASAddrOpTyGPR(const Cfg *Func, Type Ty, const x86::Address &Addr, ...@@ -610,7 +611,8 @@ void emitIASAddrOpTyGPR(const Cfg *Func, Type Ty, const x86::Address &Addr,
} else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) { } else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
AssemblerFixup *Fixup = AssemblerFixup *Fixup =
x86::DisplacementRelocation::create(Asm, FK_Abs_4, Reloc); x86::DisplacementRelocation::create(Asm, FK_Abs_4, Reloc);
(Asm->*(Emitter.AddrImm))(Ty, Addr, x86::Immediate(Fixup)); (Asm->*(Emitter.AddrImm))(Ty, Addr,
x86::Immediate(Reloc->getOffset(), Fixup));
} else { } else {
llvm_unreachable("Unexpected operand type"); llvm_unreachable("Unexpected operand type");
} }
...@@ -727,8 +729,7 @@ void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var, ...@@ -727,8 +729,7 @@ void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var,
assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
(Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm)); (Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm));
} else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) {
(Asm->*(Emitter.XmmAddr))( (Asm->*(Emitter.XmmAddr))(Ty, VarReg, x86::Address::ofConstPool(Asm, Imm));
Ty, VarReg, x86::Address::ofConstPool(Func->getContext(), Asm, Imm));
} else { } else {
llvm_unreachable("Unexpected operand type"); llvm_unreachable("Unexpected operand type");
} }
...@@ -2319,7 +2320,7 @@ void InstX8632Fld::emitIAS(const Cfg *Func) const { ...@@ -2319,7 +2320,7 @@ void InstX8632Fld::emitIAS(const Cfg *Func) const {
assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment); assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
Asm->fld(Ty, Mem->toAsmAddress(Asm)); Asm->fld(Ty, Mem->toAsmAddress(Asm));
} else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) { } else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) {
Asm->fld(Ty, x86::Address::ofConstPool(Func->getContext(), Asm, Imm)); Asm->fld(Ty, x86::Address::ofConstPool(Asm, Imm));
} else { } else {
llvm_unreachable("Unexpected operand type"); llvm_unreachable("Unexpected operand type");
} }
...@@ -2849,6 +2850,7 @@ x86::Address OperandX8632Mem::toAsmAddress(Assembler *Asm) const { ...@@ -2849,6 +2850,7 @@ x86::Address OperandX8632Mem::toAsmAddress(Assembler *Asm) const {
Disp = static_cast<int32_t>(CI->getValue()); Disp = static_cast<int32_t>(CI->getValue());
} else if (const auto CR = } else if (const auto CR =
llvm::dyn_cast<ConstantRelocatable>(getOffset())) { llvm::dyn_cast<ConstantRelocatable>(getOffset())) {
Disp = CR->getOffset();
Fixup = x86::DisplacementRelocation::create(Asm, FK_Abs_4, CR); Fixup = x86::DisplacementRelocation::create(Asm, FK_Abs_4, CR);
} else { } else {
llvm_unreachable("Unexpected offset type"); llvm_unreachable("Unexpected offset type");
...@@ -2866,9 +2868,7 @@ x86::Address OperandX8632Mem::toAsmAddress(Assembler *Asm) const { ...@@ -2866,9 +2868,7 @@ x86::Address OperandX8632Mem::toAsmAddress(Assembler *Asm) const {
return x86::Address(RegX8632::getEncodedGPR(getIndex()->getRegNum()), return x86::Address(RegX8632::getEncodedGPR(getIndex()->getRegNum()),
x86::ScaleFactor(getShift()), Disp); x86::ScaleFactor(getShift()), Disp);
} else if (Fixup) { } else if (Fixup) {
// The fixup itself has an offset, so Disp should still be 0. return x86::Address::Absolute(Disp, Fixup);
assert(Disp == 0);
return x86::Address::Absolute(Fixup);
} else { } else {
return x86::Address::Absolute(Disp); return x86::Address::Absolute(Disp);
} }
......
...@@ -101,7 +101,9 @@ class Constant : public Operand { ...@@ -101,7 +101,9 @@ class Constant : public Operand {
Constant &operator=(const Constant &) = delete; Constant &operator=(const Constant &) = delete;
public: public:
uint32_t getPoolEntryID() const { return PoolEntryID; } void emitPoolLabel(Ostream &Str) const {
Str << ".L$" << getType() << "$" << PoolEntryID;
}
using Operand::dump; using Operand::dump;
void emit(const Cfg *Func) const override { emit(Func->getContext()); } void emit(const Cfg *Func) const override { emit(Func->getContext()); }
virtual void emit(GlobalContext *Ctx) const = 0; virtual void emit(GlobalContext *Ctx) const = 0;
......
...@@ -1013,8 +1013,8 @@ template <typename T> void TargetX8632::emitConstantPool() const { ...@@ -1013,8 +1013,8 @@ template <typename T> void TargetX8632::emitConstantPool() const {
assert(CharsPrinted >= 0 && assert(CharsPrinted >= 0 &&
(size_t)CharsPrinted < llvm::array_lengthof(buf)); (size_t)CharsPrinted < llvm::array_lengthof(buf));
(void)CharsPrinted; // avoid warnings if asserts are disabled (void)CharsPrinted; // avoid warnings if asserts are disabled
Str << ".L$" << Ty << "$" << Const->getPoolEntryID() << ":\n"; Const->emitPoolLabel(Str);
Str << "\t" << T::AsmTag << "\t" << buf << "\t# " << T::TypeName << " " Str << ":\n\t" << T::AsmTag << "\t" << buf << "\t# " << T::TypeName << " "
<< Value << "\n"; << Value << "\n";
} }
} }
...@@ -4610,14 +4610,14 @@ template <> void ConstantFloat::emit(GlobalContext *Ctx) const { ...@@ -4610,14 +4610,14 @@ template <> void ConstantFloat::emit(GlobalContext *Ctx) const {
if (!ALLOW_DUMP) if (!ALLOW_DUMP)
return; return;
Ostream &Str = Ctx->getStrEmit(); Ostream &Str = Ctx->getStrEmit();
Str << ".L$" << IceType_f32 << "$" << getPoolEntryID(); emitPoolLabel(Str);
} }
template <> void ConstantDouble::emit(GlobalContext *Ctx) const { template <> void ConstantDouble::emit(GlobalContext *Ctx) const {
if (!ALLOW_DUMP) if (!ALLOW_DUMP)
return; return;
Ostream &Str = Ctx->getStrEmit(); Ostream &Str = Ctx->getStrEmit();
Str << ".L$" << IceType_f64 << "$" << getPoolEntryID(); emitPoolLabel(Str);
} }
void ConstantUndef::emit(GlobalContext *) const { void ConstantUndef::emit(GlobalContext *) const {
......
...@@ -124,14 +124,7 @@ void Assembler::emitIASBytes(GlobalContext *Ctx) const { ...@@ -124,14 +124,7 @@ void Assembler::emitIASBytes(GlobalContext *Ctx) const {
Str << "\n"; Str << "\n";
} }
Str << "\t.long "; Str << "\t.long ";
const ConstantRelocatable *Reloc = NextFixup->value(); NextFixup->emit(Ctx);
if (Reloc->getSuppressMangling())
Str << Reloc->getName();
else
Str << Ctx->mangleName(Reloc->getName());
if (Reloc->getOffset()) {
Str << " + " << Reloc->getOffset();
}
bool IsPCRel = NextFixup->kind() == FK_PcRel_4; bool IsPCRel = NextFixup->kind() == FK_PcRel_4;
if (IsPCRel) if (IsPCRel)
Str << " - (. + " << FixupSize << ")"; Str << " - (. + " << FixupSize << ")";
...@@ -147,4 +140,34 @@ void Assembler::emitIASBytes(GlobalContext *Ctx) const { ...@@ -147,4 +140,34 @@ void Assembler::emitIASBytes(GlobalContext *Ctx) const {
} }
} }
RelocOffsetT AssemblerFixup::offset() const {
if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(value_))
return CR->getOffset();
return 0;
}
IceString AssemblerFixup::symbol(GlobalContext *Ctx) const {
std::string Buffer;
llvm::raw_string_ostream Str(Buffer);
const Constant *C = value_;
if (const auto CR = llvm::dyn_cast<ConstantRelocatable>(C)) {
if (CR->getSuppressMangling())
Str << CR->getName();
else
Str << Ctx->mangleName(CR->getName());
} else {
assert(llvm::isa<ConstantFloat>(C) || llvm::isa<ConstantDouble>(C));
C->emitPoolLabel(Str);
}
return Str.str();
}
void AssemblerFixup::emit(GlobalContext *Ctx) const {
Ostream &Str = Ctx->getStrEmit();
Str << symbol(Ctx);
RelocOffsetT Offset = offset();
if (Offset)
Str << " + " << Offset;
}
} // end of namespace Ice } // end of namespace Ice
...@@ -51,16 +51,20 @@ public: ...@@ -51,16 +51,20 @@ public:
FixupKind kind() const { return kind_; } FixupKind kind() const { return kind_; }
const ConstantRelocatable *value() const { return value_; } RelocOffsetT offset() const;
IceString symbol(GlobalContext *Ctx) const;
void emit(GlobalContext *Ctx) const;
protected: protected:
AssemblerFixup(FixupKind Kind, const ConstantRelocatable *Value) AssemblerFixup(FixupKind Kind, const Constant *Value)
: position_(0), kind_(Kind), value_(Value) {} : position_(0), kind_(Kind), value_(Value) {}
private: private:
intptr_t position_; intptr_t position_;
FixupKind kind_; FixupKind kind_;
const ConstantRelocatable *value_; const Constant *value_;
void set_position(intptr_t position) { position_ = position; } void set_position(intptr_t position) { position_ = position; }
...@@ -230,7 +234,7 @@ public: ...@@ -230,7 +234,7 @@ public:
void emitIASBytes(GlobalContext *Ctx) const; void emitIASBytes(GlobalContext *Ctx) const;
private: private:
ArenaAllocator Allocator; ArenaAllocator<32 * 1024> Allocator;
protected: protected:
AssemblerBuffer buffer_; AssemblerBuffer buffer_;
......
...@@ -31,31 +31,21 @@ class DirectCallRelocation : public AssemblerFixup { ...@@ -31,31 +31,21 @@ class DirectCallRelocation : public AssemblerFixup {
public: public:
static DirectCallRelocation *create(Assembler *Asm, FixupKind Kind, static DirectCallRelocation *create(Assembler *Asm, FixupKind Kind,
const ConstantRelocatable *Sym) { const Constant *Sym) {
return new (Asm->Allocate<DirectCallRelocation>()) return new (Asm->Allocate<DirectCallRelocation>())
DirectCallRelocation(Kind, Sym); DirectCallRelocation(Kind, Sym);
} }
private: private:
DirectCallRelocation(FixupKind Kind, const ConstantRelocatable *Sym) DirectCallRelocation(FixupKind Kind, const Constant *Sym)
: AssemblerFixup(Kind, Sym) {} : AssemblerFixup(Kind, Sym) {}
}; };
Address Address::ofConstPool(GlobalContext *Ctx, Assembler *Asm, Address Address::ofConstPool(Assembler *Asm, const Constant *Imm) {
const Constant *Imm) { AssemblerFixup *Fixup =
// We should make this much lighter-weight. E.g., just record the const pool x86::DisplacementRelocation::create(Asm, FK_Abs_4, Imm);
// entry ID.
std::string Buffer;
llvm::raw_string_ostream StrBuf(Buffer);
Type Ty = Imm->getType();
assert(llvm::isa<ConstantFloat>(Imm) || llvm::isa<ConstantDouble>(Imm));
StrBuf << ".L$" << Ty << "$" << Imm->getPoolEntryID();
const RelocOffsetT Offset = 0; const RelocOffsetT Offset = 0;
const bool SuppressMangling = true; return x86::Address::Absolute(Offset, Fixup);
Constant *Sym = Ctx->getConstantSym(Offset, StrBuf.str(), SuppressMangling);
AssemblerFixup *Fixup = x86::DisplacementRelocation::create(
Asm, FK_Abs_4, llvm::cast<ConstantRelocatable>(Sym));
return x86::Address::Absolute(Fixup);
} }
AssemblerX86::~AssemblerX86() { AssemblerX86::~AssemblerX86() {
......
...@@ -51,13 +51,13 @@ class DisplacementRelocation : public AssemblerFixup { ...@@ -51,13 +51,13 @@ class DisplacementRelocation : public AssemblerFixup {
public: public:
static DisplacementRelocation *create(Assembler *Asm, FixupKind Kind, static DisplacementRelocation *create(Assembler *Asm, FixupKind Kind,
const ConstantRelocatable *Sym) { const Constant *Sym) {
return new (Asm->Allocate<DisplacementRelocation>()) return new (Asm->Allocate<DisplacementRelocation>())
DisplacementRelocation(Kind, Sym); DisplacementRelocation(Kind, Sym);
} }
private: private:
DisplacementRelocation(FixupKind Kind, const ConstantRelocatable *Sym) DisplacementRelocation(FixupKind Kind, const Constant *Sym)
: AssemblerFixup(Kind, Sym) {} : AssemblerFixup(Kind, Sym) {}
}; };
...@@ -68,8 +68,8 @@ class Immediate { ...@@ -68,8 +68,8 @@ class Immediate {
public: public:
explicit Immediate(int32_t value) : value_(value), fixup_(nullptr) {} explicit Immediate(int32_t value) : value_(value), fixup_(nullptr) {}
explicit Immediate(AssemblerFixup *fixup) Immediate(RelocOffsetT offset, AssemblerFixup *fixup)
: value_(fixup->value()->getOffset()), fixup_(fixup) { : value_(offset), fixup_(fixup) {
// Use the Offset in the "value" for now. If the symbol is part of // Use the Offset in the "value" for now. If the symbol is part of
// ".bss", then the relocation's symbol will be plain ".bss" and // ".bss", then the relocation's symbol will be plain ".bss" and
// the value will need to be adjusted further to be sym's // the value will need to be adjusted further to be sym's
...@@ -250,20 +250,19 @@ public: ...@@ -250,20 +250,19 @@ public:
return result; return result;
} }
static Address Absolute(AssemblerFixup *fixup) { static Address Absolute(RelocOffsetT Offset, AssemblerFixup *fixup) {
Address result; Address result;
result.SetModRM(0, RegX8632::Encoded_Reg_ebp); result.SetModRM(0, RegX8632::Encoded_Reg_ebp);
// Use the Offset in the displacement for now. If the symbol is part of // Use the Offset in the displacement for now. If the symbol is part of
// ".bss", then the relocation's symbol will be plain .bss and the // ".bss", then the relocation's symbol will be plain .bss and the
// displacement will need to be adjusted further to be sym's // displacement will need to be adjusted further to be sym's
// bss offset + Offset. // bss offset + Offset.
result.SetDisp32(fixup->value()->getOffset()); result.SetDisp32(Offset);
result.SetFixup(fixup); result.SetFixup(fixup);
return result; return result;
} }
static Address ofConstPool(GlobalContext *Ctx, Assembler *Asm, static Address ofConstPool(Assembler *Asm, const Constant *Imm);
const Constant *Imm);
private: private:
Address() {} // Needed by Address::Absolute. Address() {} // Needed by Address::Absolute.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment