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
diff --git a/src/IceCfg.cpp b/src/IceCfg.cpp
index d3c47d4..a16b35c 100644
--- a/src/IceCfg.cpp
+++ b/src/IceCfg.cpp
@@ -25,7 +25,7 @@
thread_local const Cfg *Cfg::CurrentCfg = nullptr;
-ArenaAllocator *getCurrentCfgAllocator() {
+ArenaAllocator<> *getCurrentCfgAllocator() {
return Cfg::getCurrentCfgAllocator();
}
@@ -33,7 +33,7 @@
: 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(
diff --git a/src/IceCfg.h b/src/IceCfg.h
index 1db1357..15f353c 100644
--- a/src/IceCfg.h
+++ b/src/IceCfg.h
@@ -43,7 +43,7 @@
// 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 @@
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;
diff --git a/src/IceDefs.h b/src/IceDefs.h
index f5147c6..584e059 100644
--- a/src/IceDefs.h
+++ b/src/IceDefs.h
@@ -58,10 +58,11 @@
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;
diff --git a/src/IceELFObjectWriter.cpp b/src/IceELFObjectWriter.cpp
index 4a31a99..7eebfa9 100644
--- a/src/IceELFObjectWriter.cpp
+++ b/src/IceELFObjectWriter.cpp
@@ -325,7 +325,7 @@
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);
diff --git a/src/IceGlobalContext.h b/src/IceGlobalContext.h
index 1b66294..9508b07 100644
--- a/src/IceGlobalContext.h
+++ b/src/IceGlobalContext.h
@@ -197,7 +197,7 @@
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;
diff --git a/src/IceInstX8632.cpp b/src/IceInstX8632.cpp
index 95be640..77f54ef 100644
--- a/src/IceInstX8632.cpp
+++ b/src/IceInstX8632.cpp
@@ -587,7 +587,8 @@
} 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 @@
} 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 @@
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 @@
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 @@
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 @@
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);
}
diff --git a/src/IceOperand.h b/src/IceOperand.h
index 035dc16..6eb5eb9 100644
--- a/src/IceOperand.h
+++ b/src/IceOperand.h
@@ -101,7 +101,9 @@
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;
diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp
index 5a111b8..b0a08b0 100644
--- a/src/IceTargetLoweringX8632.cpp
+++ b/src/IceTargetLoweringX8632.cpp
@@ -1013,8 +1013,8 @@
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 @@
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 {
diff --git a/src/assembler.cpp b/src/assembler.cpp
index a9516e8..d4f566b 100644
--- a/src/assembler.cpp
+++ b/src/assembler.cpp
@@ -124,14 +124,7 @@
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 @@
}
}
+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
diff --git a/src/assembler.h b/src/assembler.h
index cdbc505..44159e0 100644
--- a/src/assembler.h
+++ b/src/assembler.h
@@ -51,16 +51,20 @@
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 @@
void emitIASBytes(GlobalContext *Ctx) const;
private:
- ArenaAllocator Allocator;
+ ArenaAllocator<32 * 1024> Allocator;
protected:
AssemblerBuffer buffer_;
diff --git a/src/assembler_ia32.cpp b/src/assembler_ia32.cpp
index 30b84e8..8feb7fe 100644
--- a/src/assembler_ia32.cpp
+++ b/src/assembler_ia32.cpp
@@ -31,31 +31,21 @@
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() {
diff --git a/src/assembler_ia32.h b/src/assembler_ia32.h
index d38dca7..08347c4 100644
--- a/src/assembler_ia32.h
+++ b/src/assembler_ia32.h
@@ -51,13 +51,13 @@
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 @@
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 @@
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.