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 {
thread_local const Cfg *Cfg::CurrentCfg = nullptr;
ArenaAllocator *getCurrentCfgAllocator() {
ArenaAllocator<> *getCurrentCfgAllocator() {
return Cfg::getCurrentCfgAllocator();
}
......@@ -33,7 +33,7 @@ Cfg::Cfg(GlobalContext *Ctx)
: Ctx(Ctx), FunctionName(""), ReturnType(IceType_void),
IsInternalLinkage(false), HasError(false), FocusedTiming(false),
ErrorMessage(""), Entry(nullptr), NextInstNumber(Inst::NumberInitial),
Allocator(new ArenaAllocator()), Live(nullptr),
Allocator(new ArenaAllocator<>()), Live(nullptr),
Target(TargetLowering::createLowering(Ctx->getTargetArch(), this)),
VMetadata(new VariablesMetadata(this)),
TargetAssembler(
......
......@@ -43,7 +43,7 @@ public:
// Gets a pointer to the current thread's Cfg.
static const Cfg *getCurrentCfg() { return CurrentCfg; }
// Gets a pointer to the current thread's Cfg's allocator.
static ArenaAllocator *getCurrentCfgAllocator() {
static ArenaAllocator<> *getCurrentCfgAllocator() {
assert(CurrentCfg);
return CurrentCfg->Allocator.get();
}
......@@ -197,7 +197,7 @@ private:
VarList Variables;
VarList Args; // subset of Variables, in argument order
VarList ImplicitArgs; // subset of Variables
std::unique_ptr<ArenaAllocator> Allocator;
std::unique_ptr<ArenaAllocator<>> Allocator;
std::unique_ptr<Liveness> Live;
std::unique_ptr<TargetLowering> Target;
std::unique_ptr<VariablesMetadata> VMetadata;
......
......@@ -58,10 +58,11 @@ class Variable;
class VariableDeclaration;
class VariablesMetadata;
typedef llvm::BumpPtrAllocatorImpl<llvm::MallocAllocator, 1024 * 1024>
ArenaAllocator;
template <size_t SlabSize = 1024 * 1024>
using ArenaAllocator =
llvm::BumpPtrAllocatorImpl<llvm::MallocAllocator, SlabSize>;
ArenaAllocator *getCurrentCfgAllocator();
ArenaAllocator<> *getCurrentCfgAllocator();
template <typename T> struct CfgLocalAllocator {
using value_type = T;
......
......@@ -325,7 +325,7 @@ template <typename ConstType> void ELFObjectWriter::writeConstantPool(Type Ty) {
auto Const = llvm::cast<ConstType>(C);
std::string SymBuffer;
llvm::raw_string_ostream SymStrBuf(SymBuffer);
SymStrBuf << ".L$" << Ty << "$" << Const->getPoolEntryID();
Const->emitPoolLabel(SymStrBuf);
std::string &SymName = SymStrBuf.str();
SymTab->createDefinedSym(SymName, STT_NOTYPE, STB_LOCAL, Section,
OffsetInSection, SymbolSize);
......
......@@ -197,7 +197,7 @@ private:
Ostream *StrDump; // Stream for dumping / diagnostics
Ostream *StrEmit; // Stream for code emission
ArenaAllocator Allocator;
ArenaAllocator<> Allocator;
VerboseMask VMask;
std::unique_ptr<class ConstantPool> ConstPool;
Intrinsics IntrinsicsInfo;
......
......@@ -587,7 +587,8 @@ void emitIASRegOpTyGPR(const Cfg *Func, Type Ty, const Variable *Var,
} else if (const auto Reloc = llvm::dyn_cast<ConstantRelocatable>(Src)) {
AssemblerFixup *Fixup =
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)) {
(Asm->*(Emitter.GPRAddr))(Ty, VarReg, Split->toAsmAddress(Func));
} else {
......@@ -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)) {
AssemblerFixup *Fixup =
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 {
llvm_unreachable("Unexpected operand type");
}
......@@ -727,8 +729,7 @@ void emitIASRegOpTyXMM(const Cfg *Func, Type Ty, const Variable *Var,
assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
(Asm->*(Emitter.XmmAddr))(Ty, VarReg, Mem->toAsmAddress(Asm));
} else if (const auto Imm = llvm::dyn_cast<Constant>(Src)) {
(Asm->*(Emitter.XmmAddr))(
Ty, VarReg, x86::Address::ofConstPool(Func->getContext(), Asm, Imm));
(Asm->*(Emitter.XmmAddr))(Ty, VarReg, x86::Address::ofConstPool(Asm, Imm));
} else {
llvm_unreachable("Unexpected operand type");
}
......@@ -2319,7 +2320,7 @@ void InstX8632Fld::emitIAS(const Cfg *Func) const {
assert(Mem->getSegmentRegister() == OperandX8632Mem::DefaultSegment);
Asm->fld(Ty, Mem->toAsmAddress(Asm));
} 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 {
llvm_unreachable("Unexpected operand type");
}
......@@ -2849,6 +2850,7 @@ x86::Address OperandX8632Mem::toAsmAddress(Assembler *Asm) const {
Disp = static_cast<int32_t>(CI->getValue());
} else if (const auto CR =
llvm::dyn_cast<ConstantRelocatable>(getOffset())) {
Disp = CR->getOffset();
Fixup = x86::DisplacementRelocation::create(Asm, FK_Abs_4, CR);
} else {
llvm_unreachable("Unexpected offset type");
......@@ -2866,9 +2868,7 @@ x86::Address OperandX8632Mem::toAsmAddress(Assembler *Asm) const {
return x86::Address(RegX8632::getEncodedGPR(getIndex()->getRegNum()),
x86::ScaleFactor(getShift()), Disp);
} else if (Fixup) {
// The fixup itself has an offset, so Disp should still be 0.
assert(Disp == 0);
return x86::Address::Absolute(Fixup);
return x86::Address::Absolute(Disp, Fixup);
} else {
return x86::Address::Absolute(Disp);
}
......
......@@ -101,7 +101,9 @@ class Constant : public Operand {
Constant &operator=(const Constant &) = delete;
public:
uint32_t getPoolEntryID() const { return PoolEntryID; }
void emitPoolLabel(Ostream &Str) const {
Str << ".L$" << getType() << "$" << PoolEntryID;
}
using Operand::dump;
void emit(const Cfg *Func) const override { emit(Func->getContext()); }
virtual void emit(GlobalContext *Ctx) const = 0;
......
......@@ -1013,8 +1013,8 @@ template <typename T> void TargetX8632::emitConstantPool() const {
assert(CharsPrinted >= 0 &&
(size_t)CharsPrinted < llvm::array_lengthof(buf));
(void)CharsPrinted; // avoid warnings if asserts are disabled
Str << ".L$" << Ty << "$" << Const->getPoolEntryID() << ":\n";
Str << "\t" << T::AsmTag << "\t" << buf << "\t# " << T::TypeName << " "
Const->emitPoolLabel(Str);
Str << ":\n\t" << T::AsmTag << "\t" << buf << "\t# " << T::TypeName << " "
<< Value << "\n";
}
}
......@@ -4610,14 +4610,14 @@ template <> void ConstantFloat::emit(GlobalContext *Ctx) const {
if (!ALLOW_DUMP)
return;
Ostream &Str = Ctx->getStrEmit();
Str << ".L$" << IceType_f32 << "$" << getPoolEntryID();
emitPoolLabel(Str);
}
template <> void ConstantDouble::emit(GlobalContext *Ctx) const {
if (!ALLOW_DUMP)
return;
Ostream &Str = Ctx->getStrEmit();
Str << ".L$" << IceType_f64 << "$" << getPoolEntryID();
emitPoolLabel(Str);
}
void ConstantUndef::emit(GlobalContext *) const {
......
......@@ -124,14 +124,7 @@ void Assembler::emitIASBytes(GlobalContext *Ctx) const {
Str << "\n";
}
Str << "\t.long ";
const ConstantRelocatable *Reloc = NextFixup->value();
if (Reloc->getSuppressMangling())
Str << Reloc->getName();
else
Str << Ctx->mangleName(Reloc->getName());
if (Reloc->getOffset()) {
Str << " + " << Reloc->getOffset();
}
NextFixup->emit(Ctx);
bool IsPCRel = NextFixup->kind() == FK_PcRel_4;
if (IsPCRel)
Str << " - (. + " << FixupSize << ")";
......@@ -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
......@@ -51,16 +51,20 @@ public:
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:
AssemblerFixup(FixupKind Kind, const ConstantRelocatable *Value)
AssemblerFixup(FixupKind Kind, const Constant *Value)
: position_(0), kind_(Kind), value_(Value) {}
private:
intptr_t position_;
FixupKind kind_;
const ConstantRelocatable *value_;
const Constant *value_;
void set_position(intptr_t position) { position_ = position; }
......@@ -230,7 +234,7 @@ public:
void emitIASBytes(GlobalContext *Ctx) const;
private:
ArenaAllocator Allocator;
ArenaAllocator<32 * 1024> Allocator;
protected:
AssemblerBuffer buffer_;
......
......@@ -31,31 +31,21 @@ class DirectCallRelocation : public AssemblerFixup {
public:
static DirectCallRelocation *create(Assembler *Asm, FixupKind Kind,
const ConstantRelocatable *Sym) {
const Constant *Sym) {
return new (Asm->Allocate<DirectCallRelocation>())
DirectCallRelocation(Kind, Sym);
}
private:
DirectCallRelocation(FixupKind Kind, const ConstantRelocatable *Sym)
DirectCallRelocation(FixupKind Kind, const Constant *Sym)
: AssemblerFixup(Kind, Sym) {}
};
Address Address::ofConstPool(GlobalContext *Ctx, Assembler *Asm,
const Constant *Imm) {
// We should make this much lighter-weight. E.g., just record the const pool
// 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();
Address Address::ofConstPool(Assembler *Asm, const Constant *Imm) {
AssemblerFixup *Fixup =
x86::DisplacementRelocation::create(Asm, FK_Abs_4, Imm);
const RelocOffsetT Offset = 0;
const bool SuppressMangling = true;
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);
return x86::Address::Absolute(Offset, Fixup);
}
AssemblerX86::~AssemblerX86() {
......
......@@ -51,13 +51,13 @@ class DisplacementRelocation : public AssemblerFixup {
public:
static DisplacementRelocation *create(Assembler *Asm, FixupKind Kind,
const ConstantRelocatable *Sym) {
const Constant *Sym) {
return new (Asm->Allocate<DisplacementRelocation>())
DisplacementRelocation(Kind, Sym);
}
private:
DisplacementRelocation(FixupKind Kind, const ConstantRelocatable *Sym)
DisplacementRelocation(FixupKind Kind, const Constant *Sym)
: AssemblerFixup(Kind, Sym) {}
};
......@@ -68,8 +68,8 @@ class Immediate {
public:
explicit Immediate(int32_t value) : value_(value), fixup_(nullptr) {}
explicit Immediate(AssemblerFixup *fixup)
: value_(fixup->value()->getOffset()), fixup_(fixup) {
Immediate(RelocOffsetT offset, AssemblerFixup *fixup)
: value_(offset), fixup_(fixup) {
// 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
// the value will need to be adjusted further to be sym's
......@@ -250,20 +250,19 @@ public:
return result;
}
static Address Absolute(AssemblerFixup *fixup) {
static Address Absolute(RelocOffsetT Offset, AssemblerFixup *fixup) {
Address result;
result.SetModRM(0, RegX8632::Encoded_Reg_ebp);
// 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
// displacement will need to be adjusted further to be sym's
// bss offset + Offset.
result.SetDisp32(fixup->value()->getOffset());
result.SetDisp32(Offset);
result.SetFixup(fixup);
return result;
}
static Address ofConstPool(GlobalContext *Ctx, Assembler *Asm,
const Constant *Imm);
static Address ofConstPool(Assembler *Asm, const Constant *Imm);
private:
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