Commit 94844f12 by Jim Stichnoth

Subzero: Refactor some common TargetLowering initializations.

Each TargetLowering subclass has several fields (generally register allocation related) that are initialized to the same values every time a TargetLowering object is created. These fields are essentially const once initialized, so there is no reason to repeatedly initialize them. The solution is to make them static fields, and statically initialize them at program startup. This also makes it practical to access such fields without needing a TargetLowering object. There are likely more items that should also get this treatment, but those can be changed later. The staticInit() method needs a run-once guard because the unit tests actually cause it to be called more than once. BUG= none R=kschimpf@google.com Review URL: https://codereview.chromium.org/1418853005 .
parent b81b9015
...@@ -270,6 +270,8 @@ GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, ...@@ -270,6 +270,8 @@ GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError,
ProfileBlockInfoVarDecl->setName("__Sz_block_profile_info"); ProfileBlockInfoVarDecl->setName("__Sz_block_profile_info");
ProfileBlockInfoVarDecl->setSuppressMangling(); ProfileBlockInfoVarDecl->setSuppressMangling();
ProfileBlockInfoVarDecl->setLinkage(llvm::GlobalValue::ExternalLinkage); ProfileBlockInfoVarDecl->setLinkage(llvm::GlobalValue::ExternalLinkage);
TargetLowering::staticInit(Flags.getTargetArch());
} }
void GlobalContext::translateFunctions() { void GlobalContext::translateFunctions() {
......
...@@ -105,6 +105,24 @@ TargetLowering *TargetLowering::createLowering(TargetArch Target, Cfg *Func) { ...@@ -105,6 +105,24 @@ TargetLowering *TargetLowering::createLowering(TargetArch Target, Cfg *Func) {
return nullptr; return nullptr;
} }
void TargetLowering::staticInit(TargetArch Target) {
// Call the specified target's static initializer.
switch (Target) {
default:
llvm::report_fatal_error("Unsupported target");
break;
#define SUBZERO_TARGET(X) \
case Target_##X: { \
static bool InitGuard##X = false; \
if (InitGuard##X) \
return; \
InitGuard##X = true; \
Target##X::staticInit(); \
} break;
#include "llvm/Config/SZTargets.def"
}
}
TargetLowering::TargetLowering(Cfg *Func) TargetLowering::TargetLowering(Cfg *Func)
: Func(Func), Ctx(Func->getContext()), Context() {} : Func(Func), Ctx(Func->getContext()), Context() {}
......
...@@ -136,6 +136,9 @@ class TargetLowering { ...@@ -136,6 +136,9 @@ class TargetLowering {
public: public:
// TODO(jvoung): return a unique_ptr like the other factory functions. // TODO(jvoung): return a unique_ptr like the other factory functions.
static TargetLowering *createLowering(TargetArch Target, Cfg *Func); static TargetLowering *createLowering(TargetArch Target, Cfg *Func);
static void staticInit(TargetArch Target);
// Each target must define a public static method:
// static void staticInit();
static std::unique_ptr<Assembler> createAssembler(TargetArch Target, static std::unique_ptr<Assembler> createAssembler(TargetArch Target,
Cfg *Func); Cfg *Func);
void translate() { void translate() {
......
...@@ -160,9 +160,9 @@ TargetARM32Features::TargetARM32Features(const ClFlags &Flags) { ...@@ -160,9 +160,9 @@ TargetARM32Features::TargetARM32Features(const ClFlags &Flags) {
} }
TargetARM32::TargetARM32(Cfg *Func) TargetARM32::TargetARM32(Cfg *Func)
: TargetLowering(Func), CPUFeatures(Func->getContext()->getFlags()) { : TargetLowering(Func), CPUFeatures(Func->getContext()->getFlags()) {}
// TODO: Don't initialize IntegerRegisters and friends every time. Instead,
// initialize in some sort of static initializer for the class. void TargetARM32::staticInit() {
// Limit this size (or do all bitsets need to be the same width)??? // Limit this size (or do all bitsets need to be the same width)???
llvm::SmallBitVector IntegerRegisters(RegARM32::Reg_NUM); llvm::SmallBitVector IntegerRegisters(RegARM32::Reg_NUM);
llvm::SmallBitVector I64PairRegisters(RegARM32::Reg_NUM); llvm::SmallBitVector I64PairRegisters(RegARM32::Reg_NUM);
...@@ -4268,4 +4268,8 @@ void TargetHeaderARM32::lower() { ...@@ -4268,4 +4268,8 @@ void TargetHeaderARM32::lower() {
Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n"; Str << ".eabi_attribute 14, 3 @ Tag_ABI_PCS_R9_use: Not used\n";
} }
llvm::SmallBitVector TargetARM32::TypeToRegisterSet[IceType_NUM];
llvm::SmallBitVector TargetARM32::RegisterAliases[RegARM32::Reg_NUM];
llvm::SmallBitVector TargetARM32::ScratchRegs;
} // end of namespace Ice } // end of namespace Ice
...@@ -55,6 +55,7 @@ class TargetARM32 : public TargetLowering { ...@@ -55,6 +55,7 @@ class TargetARM32 : public TargetLowering {
TargetARM32 &operator=(const TargetARM32 &) = delete; TargetARM32 &operator=(const TargetARM32 &) = delete;
public: public:
static void staticInit();
// TODO(jvoung): return a unique_ptr. // TODO(jvoung): return a unique_ptr.
static TargetARM32 *create(Cfg *Func) { return new TargetARM32(Func); } static TargetARM32 *create(Cfg *Func) { return new TargetARM32(Func); }
...@@ -551,9 +552,9 @@ protected: ...@@ -551,9 +552,9 @@ protected:
bool MaybeLeafFunc = true; bool MaybeLeafFunc = true;
size_t SpillAreaSizeBytes = 0; size_t SpillAreaSizeBytes = 0;
// TODO(jpp): std::array instead of array. // TODO(jpp): std::array instead of array.
llvm::SmallBitVector TypeToRegisterSet[IceType_NUM]; static llvm::SmallBitVector TypeToRegisterSet[IceType_NUM];
llvm::SmallBitVector RegisterAliases[RegARM32::Reg_NUM]; static llvm::SmallBitVector RegisterAliases[RegARM32::Reg_NUM];
llvm::SmallBitVector ScratchRegs; static llvm::SmallBitVector ScratchRegs;
llvm::SmallBitVector RegsUsed; llvm::SmallBitVector RegsUsed;
VarList PhysicalRegisters[IceType_NUM]; VarList PhysicalRegisters[IceType_NUM];
......
...@@ -41,10 +41,9 @@ constexpr uint32_t MIPS32_MAX_GPR_ARG = 4; ...@@ -41,10 +41,9 @@ constexpr uint32_t MIPS32_MAX_GPR_ARG = 4;
} // end of anonymous namespace } // end of anonymous namespace
TargetMIPS32::TargetMIPS32(Cfg *Func) : TargetLowering(Func) { TargetMIPS32::TargetMIPS32(Cfg *Func) : TargetLowering(Func) {}
// TODO: Don't initialize IntegerRegisters and friends every time. Instead,
// initialize in some sort of static initializer for the class.
void TargetMIPS32::staticInit() {
llvm::SmallBitVector IntegerRegisters(RegMIPS32::Reg_NUM); llvm::SmallBitVector IntegerRegisters(RegMIPS32::Reg_NUM);
llvm::SmallBitVector I64PairRegisters(RegMIPS32::Reg_NUM); llvm::SmallBitVector I64PairRegisters(RegMIPS32::Reg_NUM);
llvm::SmallBitVector Float32Registers(RegMIPS32::Reg_NUM); llvm::SmallBitVector Float32Registers(RegMIPS32::Reg_NUM);
...@@ -1055,4 +1054,8 @@ void TargetHeaderMIPS32::lower() { ...@@ -1055,4 +1054,8 @@ void TargetHeaderMIPS32::lower() {
Str << "\t.set\tnomips16\n"; Str << "\t.set\tnomips16\n";
} }
llvm::SmallBitVector TargetMIPS32::TypeToRegisterSet[IceType_NUM];
llvm::SmallBitVector TargetMIPS32::RegisterAliases[RegMIPS32::Reg_NUM];
llvm::SmallBitVector TargetMIPS32::ScratchRegs;
} // end of namespace Ice } // end of namespace Ice
...@@ -29,6 +29,7 @@ class TargetMIPS32 : public TargetLowering { ...@@ -29,6 +29,7 @@ class TargetMIPS32 : public TargetLowering {
TargetMIPS32 &operator=(const TargetMIPS32 &) = delete; TargetMIPS32 &operator=(const TargetMIPS32 &) = delete;
public: public:
static void staticInit();
// TODO(jvoung): return a unique_ptr. // TODO(jvoung): return a unique_ptr.
static TargetMIPS32 *create(Cfg *Func) { return new TargetMIPS32(Func); } static TargetMIPS32 *create(Cfg *Func) { return new TargetMIPS32(Func); }
...@@ -197,9 +198,9 @@ protected: ...@@ -197,9 +198,9 @@ protected:
bool UsesFramePointer = false; bool UsesFramePointer = false;
bool NeedsStackAlignment = false; bool NeedsStackAlignment = false;
llvm::SmallBitVector TypeToRegisterSet[IceType_NUM]; static llvm::SmallBitVector TypeToRegisterSet[IceType_NUM];
llvm::SmallBitVector RegisterAliases[RegMIPS32::Reg_NUM]; static llvm::SmallBitVector RegisterAliases[RegMIPS32::Reg_NUM];
llvm::SmallBitVector ScratchRegs; static llvm::SmallBitVector ScratchRegs;
llvm::SmallBitVector RegsUsed; llvm::SmallBitVector RegsUsed;
VarList PhysicalRegisters[IceType_NUM]; VarList PhysicalRegisters[IceType_NUM];
......
...@@ -86,6 +86,19 @@ const size_t MachineTraits<TargetX8632>::TableTypeX8632AttributesSize = ...@@ -86,6 +86,19 @@ const size_t MachineTraits<TargetX8632>::TableTypeX8632AttributesSize =
const uint32_t MachineTraits<TargetX8632>::X86_STACK_ALIGNMENT_BYTES = 16; const uint32_t MachineTraits<TargetX8632>::X86_STACK_ALIGNMENT_BYTES = 16;
const char *MachineTraits<TargetX8632>::TargetName = "X8632"; const char *MachineTraits<TargetX8632>::TargetName = "X8632";
template <>
std::array<llvm::SmallBitVector, IceType_NUM>
TargetX86Base<TargetX8632>::TypeToRegisterSet = {};
template <>
std::array<llvm::SmallBitVector,
TargetX86Base<TargetX8632>::Traits::RegisterSet::Reg_NUM>
TargetX86Base<TargetX8632>::RegisterAliases = {};
template <>
llvm::SmallBitVector
TargetX86Base<TargetX8632>::ScratchRegs = llvm::SmallBitVector();
} // end of namespace X86Internal } // end of namespace X86Internal
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
......
...@@ -86,6 +86,19 @@ const size_t MachineTraits<TargetX8664>::TableTypeX8664AttributesSize = ...@@ -86,6 +86,19 @@ const size_t MachineTraits<TargetX8664>::TableTypeX8664AttributesSize =
const uint32_t MachineTraits<TargetX8664>::X86_STACK_ALIGNMENT_BYTES = 16; const uint32_t MachineTraits<TargetX8664>::X86_STACK_ALIGNMENT_BYTES = 16;
const char *MachineTraits<TargetX8664>::TargetName = "X8664"; const char *MachineTraits<TargetX8664>::TargetName = "X8664";
template <>
std::array<llvm::SmallBitVector, IceType_NUM>
TargetX86Base<TargetX8664>::TypeToRegisterSet = {};
template <>
std::array<llvm::SmallBitVector,
TargetX86Base<TargetX8664>::Traits::RegisterSet::Reg_NUM>
TargetX86Base<TargetX8664>::RegisterAliases = {};
template <>
llvm::SmallBitVector
TargetX86Base<TargetX8664>::ScratchRegs = llvm::SmallBitVector();
} // end of namespace X86Internal } // end of namespace X86Internal
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
......
...@@ -58,6 +58,7 @@ public: ...@@ -58,6 +58,7 @@ public:
~TargetX86Base() override = default; ~TargetX86Base() override = default;
static void staticInit();
static TargetX86Base *create(Cfg *Func) { return new TargetX86Base(Func); } static TargetX86Base *create(Cfg *Func) { return new TargetX86Base(Func); }
void translateOm1() override; void translateOm1() override;
...@@ -669,10 +670,10 @@ protected: ...@@ -669,10 +670,10 @@ protected:
bool NeedsStackAlignment = false; bool NeedsStackAlignment = false;
size_t SpillAreaSizeBytes = 0; size_t SpillAreaSizeBytes = 0;
size_t FixedAllocaSizeBytes = 0; size_t FixedAllocaSizeBytes = 0;
std::array<llvm::SmallBitVector, IceType_NUM> TypeToRegisterSet; static std::array<llvm::SmallBitVector, IceType_NUM> TypeToRegisterSet;
std::array<llvm::SmallBitVector, Traits::RegisterSet::Reg_NUM> static std::array<llvm::SmallBitVector, Traits::RegisterSet::Reg_NUM>
RegisterAliases; RegisterAliases;
llvm::SmallBitVector ScratchRegs; static llvm::SmallBitVector ScratchRegs;
llvm::SmallBitVector RegsUsed; llvm::SmallBitVector RegsUsed;
std::array<VarList, IceType_NUM> PhysicalRegisters; std::array<VarList, IceType_NUM> PhysicalRegisters;
......
...@@ -281,8 +281,9 @@ TargetX86Base<Machine>::TargetX86Base(Cfg *Func) ...@@ -281,8 +281,9 @@ TargetX86Base<Machine>::TargetX86Base(Cfg *Func)
TargetInstructionSet::X86InstructionSet_Begin) + TargetInstructionSet::X86InstructionSet_Begin) +
Traits::InstructionSet::Begin); Traits::InstructionSet::Begin);
} }
// TODO: Don't initialize IntegerRegisters and friends every time. Instead, }
// initialize in some sort of static initializer for the class.
template <class Machine> void TargetX86Base<Machine>::staticInit() {
Traits::initRegisterSet(&TypeToRegisterSet, &RegisterAliases, &ScratchRegs); Traits::initRegisterSet(&TypeToRegisterSet, &RegisterAliases, &ScratchRegs);
} }
......
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