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:
void emitTextInst(const std::string &Text, SizeT InstSize);
private:
ENABLE_MAKE_UNIQUE;
// A vector of pool-allocated x86 labels for CFG nodes.
using LabelVector = std::vector<Label *>;
LabelVector CfgNodeLabels;
......
......@@ -79,6 +79,9 @@ public:
static bool classof(const Assembler *Asm) {
return Asm->getKind() == Asm_MIPS32;
}
private:
ENABLE_MAKE_UNIQUE;
};
} // end of namespace MIPS32
......
......@@ -53,6 +53,9 @@ public:
static bool classof(const Assembler *Asm) {
return Asm->getKind() == Asm_X8632;
}
private:
ENABLE_MAKE_UNIQUE;
};
} // end of namespace X8632
......
......@@ -53,6 +53,9 @@ public:
static bool classof(const Assembler *Asm) {
return Asm->getKind() == Asm_X8664;
}
private:
ENABLE_MAKE_UNIQUE;
};
} // end of namespace X8664
......
......@@ -42,8 +42,7 @@ Cfg::Cfg(GlobalContext *Ctx, uint32_t SequenceNumber)
Target(TargetLowering::createLowering(Ctx->getFlags().getTargetArch(),
this)),
VMetadata(new VariablesMetadata(this)),
TargetAssembler(TargetLowering::createAssembler(
Ctx->getFlags().getTargetArch(), this)) {
TargetAssembler(Target->createAssembler()) {
if (Ctx->getFlags().getRandomizeAndPoolImmediatesOption() == RPI_Randomize) {
// If -randomize-pool-immediates=randomize, create a random number
// generator to generate a cookie for constant blinding.
......
......@@ -18,23 +18,43 @@
#include "IceTargetLowering.h"
#include "IceAssemblerARM32.h"
#include "IceAssemblerMIPS32.h"
#include "IceAssemblerX8632.h"
#include "IceAssemblerX8664.h"
#include "IceCfg.h" // setError()
#include "IceCfgNode.h"
#include "IceGlobalContext.h"
#include "IceGlobalInits.h"
#include "IceInstVarIter.h"
#include "IceOperand.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) {
Node = N;
End = getNode()->getInsts().end();
......@@ -96,14 +116,17 @@ Variable *LoweringContext::availabilityGet(Operand *Src) const {
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) \
if (Target == Target_##X) \
return Target##X::create(Func);
case Target_##X: \
return ::X::createTargetLowering(Func);
#include "llvm/Config/SZTargets.def"
Func->setError("Unsupported target");
return nullptr;
#undef SUBZERO_TARGET
}
}
void TargetLowering::staticInit(TargetArch Target) {
......@@ -111,33 +134,23 @@ void TargetLowering::staticInit(TargetArch Target) {
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) \
if (InitGuard##X) { \
return; \
} \
InitGuard##X = true; \
Target##X::staticInit(); \
} break;
::X::staticInit(); \
}
#include "llvm/Config/SZTargets.def"
#undef SUBZERO_TARGET
}
}
TargetLowering::TargetLowering(Cfg *Func)
: 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() {
for (CfgNode *Node : Func->getNodes()) {
Context.init(Node);
......@@ -539,12 +552,15 @@ void TargetLowering::emit(const ConstantRelocatable *C) const {
std::unique_ptr<TargetDataLowering>
TargetDataLowering::createLowering(GlobalContext *Ctx) {
TargetArch Target = Ctx->getFlags().getTargetArch();
switch (Target) {
default:
llvm::report_fatal_error("Unsupported target");
#define SUBZERO_TARGET(X) \
if (Target == Target_##X) \
return TargetData##X::create(Ctx);
case Target_##X: \
return ::X::createTargetDataLowering(Ctx);
#include "llvm/Config/SZTargets.def"
llvm::report_fatal_error("Unsupported target data lowering");
#undef SUBZERO_TARGET
}
}
TargetDataLowering::~TargetDataLowering() = default;
......@@ -661,12 +677,15 @@ void TargetDataLowering::emitGlobal(const VariableDeclaration &Var,
std::unique_ptr<TargetHeaderLowering>
TargetHeaderLowering::createLowering(GlobalContext *Ctx) {
TargetArch Target = Ctx->getFlags().getTargetArch();
switch (Target) {
default:
llvm::report_fatal_error("Unsupported target");
#define SUBZERO_TARGET(X) \
if (Target == Target_##X) \
return TargetHeader##X::create(Ctx);
case Target_##X: \
return ::X::createTargetHeaderLowering(Ctx);
#include "llvm/Config/SZTargets.def"
llvm::report_fatal_error("Unsupported target header lowering");
#undef SUBZERO_TARGET
}
}
TargetHeaderLowering::~TargetHeaderLowering() = default;
......
......@@ -138,19 +138,27 @@ private:
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 {
TargetLowering() = delete;
TargetLowering(const TargetLowering &) = delete;
TargetLowering &operator=(const TargetLowering &) = delete;
public:
// TODO(jvoung): return a unique_ptr like the other factory functions.
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,
Cfg *Func);
static std::unique_ptr<TargetLowering> createLowering(TargetArch Target,
Cfg *Func);
virtual std::unique_ptr<Assembler> createAssembler() const = 0;
void translate() {
switch (Ctx->getFlags().getOptLevel()) {
case Opt_m1:
......
......@@ -35,6 +35,24 @@
#include <array>
#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 {
......
......@@ -16,6 +16,7 @@
#ifndef SUBZERO_SRC_ICETARGETLOWERINGARM32_H
#define SUBZERO_SRC_ICETARGETLOWERINGARM32_H
#include "IceAssemblerARM32.h"
#include "IceDefs.h"
#include "IceInstARM32.h"
#include "IceRegistersARM32.h"
......@@ -55,9 +56,17 @@ class TargetARM32 : public TargetLowering {
TargetARM32 &operator=(const TargetARM32 &) = delete;
public:
~TargetARM32() = default;
static void staticInit();
// 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 {
Computations.forgetProducers();
......@@ -1057,7 +1066,7 @@ protected:
};
private:
~TargetARM32() override = default;
ENABLE_MAKE_UNIQUE;
OperandARM32Mem *formAddressingMode(Type Ty, Cfg *Func, const Inst *LdSt,
Operand *Base);
......
......@@ -30,6 +30,24 @@
#include "IceUtils.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 {
using llvm::isInt;
......
......@@ -16,6 +16,7 @@
#ifndef SUBZERO_SRC_ICETARGETLOWERINGMIPS32_H
#define SUBZERO_SRC_ICETARGETLOWERINGMIPS32_H
#include "IceAssemblerMIPS32.h"
#include "IceDefs.h"
#include "IceInstMIPS32.h"
#include "IceRegistersMIPS32.h"
......@@ -29,9 +30,16 @@ class TargetMIPS32 : public TargetLowering {
TargetMIPS32 &operator=(const TargetMIPS32 &) = delete;
public:
~TargetMIPS32() override = default;
static void staticInit();
// TODO(jvoung): return a unique_ptr.
static TargetMIPS32 *create(Cfg *Func) { return new TargetMIPS32(Func); }
static std::unique_ptr<::Ice::TargetLowering> create(Cfg *Func) {
return makeUnique<TargetMIPS32>(Func);
}
std::unique_ptr<::Ice::Assembler> createAssembler() const override {
return makeUnique<MIPS32::AssemblerMIPS32>();
}
void translateOm1() override;
void translateO2() override;
......@@ -257,7 +265,7 @@ protected:
VarList PhysicalRegisters[IceType_NUM];
private:
~TargetMIPS32() override = default;
ENABLE_MAKE_UNIQUE;
};
class TargetDataMIPS32 final : public TargetDataLowering {
......
......@@ -18,6 +18,24 @@
#include "IceTargetLoweringX8632Traits.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 {
//------------------------------------------------------------------------------
......
......@@ -36,9 +36,15 @@ class TargetX8632 final
const InstJumpTable *JumpTable) const override;
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:
void lowerCall(const InstCall *Instr) override;
......@@ -48,6 +54,7 @@ protected:
void addEpilog(CfgNode *Node) override;
private:
ENABLE_MAKE_UNIQUE;
friend class ::Ice::X86Internal::TargetX86Base<TargetX8632>;
Operand *createNaClReadTPSrcOperand() {
......
......@@ -18,6 +18,24 @@
#include "IceTargetLoweringX8664Traits.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 {
//------------------------------------------------------------------------------
......
......@@ -36,7 +36,15 @@ class TargetX8664 final
const InstJumpTable *JumpTable) const override;
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:
void lowerCall(const InstCall *Instr) override;
......@@ -46,6 +54,7 @@ protected:
void addEpilog(CfgNode *Node) override;
private:
ENABLE_MAKE_UNIQUE;
friend class ::Ice::X86Internal::TargetX86Base<TargetX8664>;
explicit TargetX8664(Cfg *Func)
......@@ -101,6 +110,7 @@ private:
explicit TargetHeaderX8664(GlobalContext *Ctx) : TargetHeaderLowering(Ctx) {}
};
} // end of namespace Ice
#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