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.