Commit 53611e2c by John Porto

Subzero. Refactoring.

This is the first step towards hiding backend-specific stuff from the rest of subzero. In this CL, all the references to target-specific files (e.g., IceTargetLoweringX8632.h) are removed from target-independent files. This CL also changes the named constructors in the Target-specific classes (e.g., TargetX8632::create()) to return unique_ptrs. BUG= R=stichnot@chromium.org Review URL: https://codereview.chromium.org/1551633002 .
parent 93d85ce0
...@@ -331,6 +331,8 @@ public: ...@@ -331,6 +331,8 @@ public:
void emitTextInst(const std::string &Text, SizeT InstSize); void emitTextInst(const std::string &Text, SizeT InstSize);
private: private:
ENABLE_MAKE_UNIQUE;
// A vector of pool-allocated x86 labels for CFG nodes. // A vector of pool-allocated x86 labels for CFG nodes.
using LabelVector = std::vector<Label *>; using LabelVector = std::vector<Label *>;
LabelVector CfgNodeLabels; LabelVector CfgNodeLabels;
......
...@@ -79,6 +79,9 @@ public: ...@@ -79,6 +79,9 @@ public:
static bool classof(const Assembler *Asm) { static bool classof(const Assembler *Asm) {
return Asm->getKind() == Asm_MIPS32; return Asm->getKind() == Asm_MIPS32;
} }
private:
ENABLE_MAKE_UNIQUE;
}; };
} // end of namespace MIPS32 } // end of namespace MIPS32
......
...@@ -53,6 +53,9 @@ public: ...@@ -53,6 +53,9 @@ public:
static bool classof(const Assembler *Asm) { static bool classof(const Assembler *Asm) {
return Asm->getKind() == Asm_X8632; return Asm->getKind() == Asm_X8632;
} }
private:
ENABLE_MAKE_UNIQUE;
}; };
} // end of namespace X8632 } // end of namespace X8632
......
...@@ -53,6 +53,9 @@ public: ...@@ -53,6 +53,9 @@ public:
static bool classof(const Assembler *Asm) { static bool classof(const Assembler *Asm) {
return Asm->getKind() == Asm_X8664; return Asm->getKind() == Asm_X8664;
} }
private:
ENABLE_MAKE_UNIQUE;
}; };
} // end of namespace X8664 } // end of namespace X8664
......
...@@ -42,8 +42,7 @@ Cfg::Cfg(GlobalContext *Ctx, uint32_t SequenceNumber) ...@@ -42,8 +42,7 @@ Cfg::Cfg(GlobalContext *Ctx, uint32_t SequenceNumber)
Target(TargetLowering::createLowering(Ctx->getFlags().getTargetArch(), Target(TargetLowering::createLowering(Ctx->getFlags().getTargetArch(),
this)), this)),
VMetadata(new VariablesMetadata(this)), VMetadata(new VariablesMetadata(this)),
TargetAssembler(TargetLowering::createAssembler( TargetAssembler(Target->createAssembler()) {
Ctx->getFlags().getTargetArch(), this)) {
if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_Randomize) { if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_Randomize) {
// If -randomize-pool-immediates=randomize, create a random number // If -randomize-pool-immediates=randomize, create a random number
// generator to generate a cookie for constant blinding. // generator to generate a cookie for constant blinding.
......
...@@ -18,23 +18,43 @@ ...@@ -18,23 +18,43 @@
#include "IceTargetLowering.h" #include "IceTargetLowering.h"
#include "IceAssemblerARM32.h"
#include "IceAssemblerMIPS32.h"
#include "IceAssemblerX8632.h"
#include "IceAssemblerX8664.h"
#include "IceCfg.h" // setError() #include "IceCfg.h" // setError()
#include "IceCfgNode.h" #include "IceCfgNode.h"
#include "IceGlobalContext.h"
#include "IceGlobalInits.h" #include "IceGlobalInits.h"
#include "IceInstVarIter.h" #include "IceInstVarIter.h"
#include "IceOperand.h" #include "IceOperand.h"
#include "IceRegAlloc.h" #include "IceRegAlloc.h"
#include "IceTargetLoweringARM32.h"
#include "IceTargetLoweringMIPS32.h"
#include "IceTargetLoweringX8632.h"
#include "IceTargetLoweringX8664.h"
namespace Ice { // We prevent target-specific implementation details from leaking outside their
// implementations by forbidding #include of target-specific header files
// anywhere outside their own files. To create target-specific objects
// (TargetLowering, TargetDataLowering, and TargetHeaderLowering) we use the
// following named constructors. For reference, each target Foo needs to
// implement the following named constructors and initializer:
//
// namespace Foo {
// unique_ptr<Ice::TargetLowering> createTargetLowering(Ice::Cfg *);
// unique_ptr<Ice::TargetDataLowering>
// createTargetDataLowering(Ice::GlobalContext*);
// unique_ptr<Ice::TargetHeaderLowering>
// createTargetHeaderLowering(Ice::GlobalContext *);
// void staticInit();
// }
#define SUBZERO_TARGET(X) \
namespace X { \
std::unique_ptr<::Ice::TargetLowering> \
createTargetLowering(::Ice::Cfg *Func); \
std::unique_ptr<::Ice::TargetDataLowering> \
createTargetDataLowering(::Ice::GlobalContext *Ctx); \
std::unique_ptr<::Ice::TargetHeaderLowering> \
createTargetHeaderLowering(::Ice::GlobalContext *Ctx); \
void staticInit(); \
} // end of namespace X
#include "llvm/Config/SZTargets.def"
#undef SUBZERO_TARGET
namespace Ice {
void LoweringContext::init(CfgNode *N) { void LoweringContext::init(CfgNode *N) {
Node = N; Node = N;
End = getNode()->getInsts().end(); End = getNode()->getInsts().end();
...@@ -96,14 +116,17 @@ Variable *LoweringContext::availabilityGet(Operand *Src) const { ...@@ -96,14 +116,17 @@ Variable *LoweringContext::availabilityGet(Operand *Src) const {
return nullptr; return nullptr;
} }
TargetLowering *TargetLowering::createLowering(TargetArch Target, Cfg *Func) { std::unique_ptr<TargetLowering>
TargetLowering::createLowering(TargetArch Target, Cfg *Func) {
switch (Target) {
default:
llvm::report_fatal_error("Unsupported target");
#define SUBZERO_TARGET(X) \ #define SUBZERO_TARGET(X) \
if (Target == Target_##X) \ case Target_##X: \
return Target##X::create(Func); return ::X::createTargetLowering(Func);
#include "llvm/Config/SZTargets.def" #include "llvm/Config/SZTargets.def"
#undef SUBZERO_TARGET
Func->setError("Unsupported target"); }
return nullptr;
} }
void TargetLowering::staticInit(TargetArch Target) { void TargetLowering::staticInit(TargetArch Target) {
...@@ -111,33 +134,23 @@ void TargetLowering::staticInit(TargetArch Target) { ...@@ -111,33 +134,23 @@ void TargetLowering::staticInit(TargetArch Target) {
switch (Target) { switch (Target) {
default: default:
llvm::report_fatal_error("Unsupported target"); llvm::report_fatal_error("Unsupported target");
break;
#define SUBZERO_TARGET(X) \ #define SUBZERO_TARGET(X) \
case Target_##X: { \ case Target_##X: { \
static bool InitGuard##X = false; \ static bool InitGuard##X = false; \
if (InitGuard##X) \ if (InitGuard##X) { \
return; \ return; \
} \
InitGuard##X = true; \ InitGuard##X = true; \
Target##X::staticInit(); \ ::X::staticInit(); \
} break; }
#include "llvm/Config/SZTargets.def" #include "llvm/Config/SZTargets.def"
#undef SUBZERO_TARGET
} }
} }
TargetLowering::TargetLowering(Cfg *Func) TargetLowering::TargetLowering(Cfg *Func)
: Func(Func), Ctx(Func->getContext()), Context() {} : Func(Func), Ctx(Func->getContext()), Context() {}
std::unique_ptr<Assembler> TargetLowering::createAssembler(TargetArch Target,
Cfg *Func) {
#define SUBZERO_TARGET(X) \
if (Target == Target_##X) \
return std::unique_ptr<Assembler>(new X::Assembler##X());
#include "llvm/Config/SZTargets.def"
Func->setError("Unsupported target assembler");
return nullptr;
}
void TargetLowering::genTargetHelperCalls() { void TargetLowering::genTargetHelperCalls() {
for (CfgNode *Node : Func->getNodes()) { for (CfgNode *Node : Func->getNodes()) {
Context.init(Node); Context.init(Node);
...@@ -539,12 +552,15 @@ void TargetLowering::emit(const ConstantRelocatable *C) const { ...@@ -539,12 +552,15 @@ void TargetLowering::emit(const ConstantRelocatable *C) const {
std::unique_ptr<TargetDataLowering> std::unique_ptr<TargetDataLowering>
TargetDataLowering::createLowering(GlobalContext *Ctx) { TargetDataLowering::createLowering(GlobalContext *Ctx) {
TargetArch Target = Ctx->getFlags().getTargetArch(); TargetArch Target = Ctx->getFlags().getTargetArch();
switch (Target) {
default:
llvm::report_fatal_error("Unsupported target");
#define SUBZERO_TARGET(X) \ #define SUBZERO_TARGET(X) \
if (Target == Target_##X) \ case Target_##X: \
return TargetData##X::create(Ctx); return ::X::createTargetDataLowering(Ctx);
#include "llvm/Config/SZTargets.def" #include "llvm/Config/SZTargets.def"
#undef SUBZERO_TARGET
llvm::report_fatal_error("Unsupported target data lowering"); }
} }
TargetDataLowering::~TargetDataLowering() = default; TargetDataLowering::~TargetDataLowering() = default;
...@@ -661,12 +677,15 @@ void TargetDataLowering::emitGlobal(const VariableDeclaration &Var, ...@@ -661,12 +677,15 @@ void TargetDataLowering::emitGlobal(const VariableDeclaration &Var,
std::unique_ptr<TargetHeaderLowering> std::unique_ptr<TargetHeaderLowering>
TargetHeaderLowering::createLowering(GlobalContext *Ctx) { TargetHeaderLowering::createLowering(GlobalContext *Ctx) {
TargetArch Target = Ctx->getFlags().getTargetArch(); TargetArch Target = Ctx->getFlags().getTargetArch();
switch (Target) {
default:
llvm::report_fatal_error("Unsupported target");
#define SUBZERO_TARGET(X) \ #define SUBZERO_TARGET(X) \
if (Target == Target_##X) \ case Target_##X: \
return TargetHeader##X::create(Ctx); return ::X::createTargetHeaderLowering(Ctx);
#include "llvm/Config/SZTargets.def" #include "llvm/Config/SZTargets.def"
#undef SUBZERO_TARGET
llvm::report_fatal_error("Unsupported target header lowering"); }
} }
TargetHeaderLowering::~TargetHeaderLowering() = default; TargetHeaderLowering::~TargetHeaderLowering() = default;
......
...@@ -138,19 +138,27 @@ private: ...@@ -138,19 +138,27 @@ private:
LoweringContext &Context; LoweringContext &Context;
}; };
/// TargetLowering is the base class for all backends in Subzero. In addition to
/// implementing the abstract methods in this class, each concrete target must
/// also implement a named constructor in its own namespace. For instance, for
/// X8632 we have:
///
/// namespace X8632 {
/// void createTargetLowering(Cfg *Func);
/// }
class TargetLowering { class TargetLowering {
TargetLowering() = delete; TargetLowering() = delete;
TargetLowering(const TargetLowering &) = delete; TargetLowering(const TargetLowering &) = delete;
TargetLowering &operator=(const TargetLowering &) = delete; TargetLowering &operator=(const TargetLowering &) = delete;
public: public:
// TODO(jvoung): return a unique_ptr like the other factory functions.
static TargetLowering *createLowering(TargetArch Target, Cfg *Func);
static void staticInit(TargetArch Target); static void staticInit(TargetArch Target);
// Each target must define a public static method:
// static void staticInit(); static std::unique_ptr<TargetLowering> createLowering(TargetArch Target,
static std::unique_ptr<Assembler> createAssembler(TargetArch Target, Cfg *Func);
Cfg *Func);
virtual std::unique_ptr<Assembler> createAssembler() const = 0;
void translate() { void translate() {
switch (Ctx->getFlags().getOptLevel()) { switch (Ctx->getFlags().getOptLevel()) {
case Opt_m1: case Opt_m1:
......
...@@ -35,6 +35,24 @@ ...@@ -35,6 +35,24 @@
#include <array> #include <array>
#include <utility> #include <utility>
namespace ARM32 {
std::unique_ptr<::Ice::TargetLowering> createTargetLowering(::Ice::Cfg *Func) {
return ::Ice::TargetARM32::create(Func);
}
std::unique_ptr<::Ice::TargetDataLowering>
createTargetDataLowering(::Ice::GlobalContext *Ctx) {
return ::Ice::TargetDataARM32::create(Ctx);
}
std::unique_ptr<::Ice::TargetHeaderLowering>
createTargetHeaderLowering(::Ice::GlobalContext *Ctx) {
return ::Ice::TargetHeaderARM32::create(Ctx);
}
void staticInit() { ::Ice::TargetARM32::staticInit(); }
} // end of namespace ARM32
namespace Ice { namespace Ice {
namespace { namespace {
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#ifndef SUBZERO_SRC_ICETARGETLOWERINGARM32_H #ifndef SUBZERO_SRC_ICETARGETLOWERINGARM32_H
#define SUBZERO_SRC_ICETARGETLOWERINGARM32_H #define SUBZERO_SRC_ICETARGETLOWERINGARM32_H
#include "IceAssemblerARM32.h"
#include "IceDefs.h" #include "IceDefs.h"
#include "IceInstARM32.h" #include "IceInstARM32.h"
#include "IceRegistersARM32.h" #include "IceRegistersARM32.h"
...@@ -55,9 +56,17 @@ class TargetARM32 : public TargetLowering { ...@@ -55,9 +56,17 @@ class TargetARM32 : public TargetLowering {
TargetARM32 &operator=(const TargetARM32 &) = delete; TargetARM32 &operator=(const TargetARM32 &) = delete;
public: public:
~TargetARM32() = default;
static void staticInit(); 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 std::unique_ptr<::Ice::TargetLowering> create(Cfg *Func) {
return makeUnique<TargetARM32>(Func);
}
std::unique_ptr<::Ice::Assembler> createAssembler() const override {
return makeUnique<ARM32::AssemblerARM32>();
}
void initNodeForLowering(CfgNode *Node) override { void initNodeForLowering(CfgNode *Node) override {
Computations.forgetProducers(); Computations.forgetProducers();
...@@ -1057,7 +1066,7 @@ protected: ...@@ -1057,7 +1066,7 @@ protected:
}; };
private: private:
~TargetARM32() override = default; ENABLE_MAKE_UNIQUE;
OperandARM32Mem *formAddressingMode(Type Ty, Cfg *Func, const Inst *LdSt, OperandARM32Mem *formAddressingMode(Type Ty, Cfg *Func, const Inst *LdSt,
Operand *Base); Operand *Base);
......
...@@ -30,6 +30,24 @@ ...@@ -30,6 +30,24 @@
#include "IceUtils.h" #include "IceUtils.h"
#include "llvm/Support/MathExtras.h" #include "llvm/Support/MathExtras.h"
namespace MIPS32 {
std::unique_ptr<::Ice::TargetLowering> createTargetLowering(::Ice::Cfg *Func) {
return ::Ice::TargetMIPS32::create(Func);
}
std::unique_ptr<::Ice::TargetDataLowering>
createTargetDataLowering(::Ice::GlobalContext *Ctx) {
return ::Ice::TargetDataMIPS32::create(Ctx);
}
std::unique_ptr<::Ice::TargetHeaderLowering>
createTargetHeaderLowering(::Ice::GlobalContext *Ctx) {
return ::Ice::TargetHeaderMIPS32::create(Ctx);
}
void staticInit() { ::Ice::TargetMIPS32::staticInit(); }
} // end of namespace MIPS32
namespace Ice { namespace Ice {
using llvm::isInt; using llvm::isInt;
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#ifndef SUBZERO_SRC_ICETARGETLOWERINGMIPS32_H #ifndef SUBZERO_SRC_ICETARGETLOWERINGMIPS32_H
#define SUBZERO_SRC_ICETARGETLOWERINGMIPS32_H #define SUBZERO_SRC_ICETARGETLOWERINGMIPS32_H
#include "IceAssemblerMIPS32.h"
#include "IceDefs.h" #include "IceDefs.h"
#include "IceInstMIPS32.h" #include "IceInstMIPS32.h"
#include "IceRegistersMIPS32.h" #include "IceRegistersMIPS32.h"
...@@ -29,9 +30,16 @@ class TargetMIPS32 : public TargetLowering { ...@@ -29,9 +30,16 @@ class TargetMIPS32 : public TargetLowering {
TargetMIPS32 &operator=(const TargetMIPS32 &) = delete; TargetMIPS32 &operator=(const TargetMIPS32 &) = delete;
public: public:
~TargetMIPS32() override = default;
static void staticInit(); static void staticInit();
// TODO(jvoung): return a unique_ptr. static std::unique_ptr<::Ice::TargetLowering> create(Cfg *Func) {
static TargetMIPS32 *create(Cfg *Func) { return new TargetMIPS32(Func); } return makeUnique<TargetMIPS32>(Func);
}
std::unique_ptr<::Ice::Assembler> createAssembler() const override {
return makeUnique<MIPS32::AssemblerMIPS32>();
}
void translateOm1() override; void translateOm1() override;
void translateO2() override; void translateO2() override;
...@@ -257,7 +265,7 @@ protected: ...@@ -257,7 +265,7 @@ protected:
VarList PhysicalRegisters[IceType_NUM]; VarList PhysicalRegisters[IceType_NUM];
private: private:
~TargetMIPS32() override = default; ENABLE_MAKE_UNIQUE;
}; };
class TargetDataMIPS32 final : public TargetDataLowering { class TargetDataMIPS32 final : public TargetDataLowering {
......
...@@ -18,6 +18,24 @@ ...@@ -18,6 +18,24 @@
#include "IceTargetLoweringX8632Traits.h" #include "IceTargetLoweringX8632Traits.h"
#include "IceTargetLoweringX86Base.h" #include "IceTargetLoweringX86Base.h"
namespace X8632 {
std::unique_ptr<::Ice::TargetLowering> createTargetLowering(::Ice::Cfg *Func) {
return ::Ice::TargetX8632::create(Func);
}
std::unique_ptr<::Ice::TargetDataLowering>
createTargetDataLowering(::Ice::GlobalContext *Ctx) {
return ::Ice::TargetDataX8632::create(Ctx);
}
std::unique_ptr<::Ice::TargetHeaderLowering>
createTargetHeaderLowering(::Ice::GlobalContext *Ctx) {
return ::Ice::TargetHeaderX8632::create(Ctx);
}
void staticInit() { ::Ice::TargetX8632::staticInit(); }
} // end of namespace X8632
namespace Ice { namespace Ice {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
......
...@@ -36,9 +36,15 @@ class TargetX8632 final ...@@ -36,9 +36,15 @@ class TargetX8632 final
const InstJumpTable *JumpTable) const override; const InstJumpTable *JumpTable) const override;
public: public:
using X86InstructionSet = X8632::Traits::InstructionSet; ~TargetX8632() = default;
static TargetX8632 *create(Cfg *Func) { return new TargetX8632(Func); } static std::unique_ptr<::Ice::TargetLowering> create(Cfg *Func) {
return makeUnique<TargetX8632>(Func);
}
std::unique_ptr<::Ice::Assembler> createAssembler() const override {
return makeUnique<X8632::AssemblerX8632>();
}
protected: protected:
void lowerCall(const InstCall *Instr) override; void lowerCall(const InstCall *Instr) override;
...@@ -48,6 +54,7 @@ protected: ...@@ -48,6 +54,7 @@ protected:
void addEpilog(CfgNode *Node) override; void addEpilog(CfgNode *Node) override;
private: private:
ENABLE_MAKE_UNIQUE;
friend class ::Ice::X86Internal::TargetX86Base<TargetX8632>; friend class ::Ice::X86Internal::TargetX86Base<TargetX8632>;
Operand *createNaClReadTPSrcOperand() { Operand *createNaClReadTPSrcOperand() {
......
...@@ -18,6 +18,24 @@ ...@@ -18,6 +18,24 @@
#include "IceTargetLoweringX8664Traits.h" #include "IceTargetLoweringX8664Traits.h"
#include "IceTargetLoweringX86Base.h" #include "IceTargetLoweringX86Base.h"
namespace X8664 {
std::unique_ptr<::Ice::TargetLowering> createTargetLowering(::Ice::Cfg *Func) {
return ::Ice::TargetX8664::create(Func);
}
std::unique_ptr<::Ice::TargetDataLowering>
createTargetDataLowering(::Ice::GlobalContext *Ctx) {
return ::Ice::TargetDataX8664::create(Ctx);
}
std::unique_ptr<::Ice::TargetHeaderLowering>
createTargetHeaderLowering(::Ice::GlobalContext *Ctx) {
return ::Ice::TargetHeaderX8664::create(Ctx);
}
void staticInit() { ::Ice::TargetX8664::staticInit(); }
} // end of namespace X8664
namespace Ice { namespace Ice {
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
......
...@@ -36,7 +36,15 @@ class TargetX8664 final ...@@ -36,7 +36,15 @@ class TargetX8664 final
const InstJumpTable *JumpTable) const override; const InstJumpTable *JumpTable) const override;
public: public:
static TargetX8664 *create(Cfg *Func) { return new TargetX8664(Func); } ~TargetX8664() = default;
static std::unique_ptr<::Ice::TargetLowering> create(Cfg *Func) {
return makeUnique<TargetX8664>(Func);
}
std::unique_ptr<::Ice::Assembler> createAssembler() const override {
return makeUnique<X8664::AssemblerX8664>();
}
protected: protected:
void lowerCall(const InstCall *Instr) override; void lowerCall(const InstCall *Instr) override;
...@@ -46,6 +54,7 @@ protected: ...@@ -46,6 +54,7 @@ protected:
void addEpilog(CfgNode *Node) override; void addEpilog(CfgNode *Node) override;
private: private:
ENABLE_MAKE_UNIQUE;
friend class ::Ice::X86Internal::TargetX86Base<TargetX8664>; friend class ::Ice::X86Internal::TargetX86Base<TargetX8664>;
explicit TargetX8664(Cfg *Func) explicit TargetX8664(Cfg *Func)
...@@ -101,6 +110,7 @@ private: ...@@ -101,6 +110,7 @@ private:
explicit TargetHeaderX8664(GlobalContext *Ctx) : TargetHeaderLowering(Ctx) {} explicit TargetHeaderX8664(GlobalContext *Ctx) : TargetHeaderLowering(Ctx) {}
}; };
} // end of namespace Ice } // end of namespace Ice
#endif // SUBZERO_SRC_ICETARGETLOWERINGX8664_H #endif // SUBZERO_SRC_ICETARGETLOWERINGX8664_H
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