extern cl::opt<unsigned> PartialUnrollingThreshold;
+/// \brief Base class which can be used to help build a TTI implementation.
+///
+/// This class provides as much implementation of the TTI interface as is
+/// possible using the target independent parts of the code generator.
+///
+/// In order to subclass it, your class must implement a getTM() method to
+/// return the target machine, and a getTLI() method to return the target
+/// lowering. We need these methods implemented in the derived class so that
+/// this class doesn't have to duplicate storage for them.
template <typename T>
class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
private:
return Cost;
}
+ /// \brief Local query method delegates up to T which *must* implement this!
+ const TargetMachine *getTM() const {
+ return static_cast<const T *>(this)->getTM();
+ }
+
+ /// \brief Local query method delegates up to T which *must* implement this!
const TargetLoweringBase *getTLI() const {
- return TM->getSubtargetImpl()->getTargetLowering();
+ return static_cast<const T *>(this)->getTLI();
}
protected:
- const TargetMachine *TM;
-
explicit BasicTTIImplBase(const TargetMachine *TM)
- : BaseT(TM->getDataLayout()), TM(TM) {}
+ : BaseT(TM->getDataLayout()) {}
public:
// Provide value semantics. MSVC requires that we spell all of these out.
BasicTTIImplBase(const BasicTTIImplBase &Arg)
- : BaseT(static_cast<const BaseT &>(Arg)), TM(Arg.TM) {}
+ : BaseT(static_cast<const BaseT &>(Arg)) {}
BasicTTIImplBase(BasicTTIImplBase &&Arg)
- : BaseT(std::move(static_cast<BaseT &>(Arg))), TM(std::move(Arg.TM)) {}
+ : BaseT(std::move(static_cast<BaseT &>(Arg))) {}
BasicTTIImplBase &operator=(const BasicTTIImplBase &RHS) {
BaseT::operator=(static_cast<const BaseT &>(RHS));
- TM = RHS.TM;
return *this;
}
BasicTTIImplBase &operator=(BasicTTIImplBase &&RHS) {
BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
- TM = std::move(RHS.TM);
return *this;
}
// until someone finds a case where it matters in practice.
unsigned MaxOps;
- const TargetSubtargetInfo *ST = TM->getSubtargetImpl(*F);
+ const TargetSubtargetInfo *ST = getTM()->getSubtargetImpl(*F);
if (PartialUnrollingThreshold.getNumOccurrences() > 0)
MaxOps = PartialUnrollingThreshold;
else if (ST->getSchedModel().LoopMicroOpBufferSize > 0)
/// is needed.
class BasicTTIImpl : public BasicTTIImplBase<BasicTTIImpl> {
typedef BasicTTIImplBase<BasicTTIImpl> BaseT;
+ friend class BasicTTIImplBase<BasicTTIImpl>;
+
+ const TargetMachine *TM;
+ const TargetLoweringBase *TLI;
+
+ const TargetMachine *getTM() const { return TM; }
+ const TargetLoweringBase *getTLI() const { return TLI; }
public:
explicit BasicTTIImpl(const TargetMachine *TM);
// Provide value semantics. MSVC requires that we spell all of these out.
BasicTTIImpl(const BasicTTIImpl &Arg)
- : BaseT(static_cast<const BaseT &>(Arg)) {}
+ : BaseT(static_cast<const BaseT &>(Arg)), TM(Arg.TM), TLI(Arg.TLI) {}
BasicTTIImpl(BasicTTIImpl &&Arg)
- : BaseT(std::move(static_cast<BaseT &>(Arg))) {}
+ : BaseT(std::move(static_cast<BaseT &>(Arg))), TM(std::move(Arg.TM)),
+ TLI(std::move(Arg.TLI)) {}
BasicTTIImpl &operator=(const BasicTTIImpl &RHS) {
BaseT::operator=(static_cast<const BaseT &>(RHS));
+ TM = RHS.TM;
+ TLI = RHS.TLI;
return *this;
}
BasicTTIImpl &operator=(BasicTTIImpl &&RHS) {
BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
+ TM = std::move(RHS.TM);
+ TLI = std::move(RHS.TLI);
return *this;
}
};
cl::desc("Threshold for partial unrolling"),
cl::Hidden);
-BasicTTIImpl::BasicTTIImpl(const TargetMachine *TM) : BaseT(TM) {}
+BasicTTIImpl::BasicTTIImpl(const TargetMachine *TM)
+ : BaseT(TM), TM(TM), TLI(TM->getSubtargetImpl()->getTargetLowering()) {}
class AArch64TTIImpl : public BasicTTIImplBase<AArch64TTIImpl> {
typedef BasicTTIImplBase<AArch64TTIImpl> BaseT;
typedef TargetTransformInfo TTI;
+ friend BaseT;
+ const AArch64TargetMachine *TM;
const AArch64Subtarget *ST;
const AArch64TargetLowering *TLI;
/// are set if the result needs to be inserted and/or extracted from vectors.
unsigned getScalarizationOverhead(Type *Ty, bool Insert, bool Extract);
+ const AArch64TargetMachine *getTM() const { return TM; }
+ const AArch64TargetLowering *getTLI() const { return TLI; }
+
enum MemIntrinsicType {
VECTOR_LDST_TWO_ELEMENTS,
VECTOR_LDST_THREE_ELEMENTS,
public:
explicit AArch64TTIImpl(const AArch64TargetMachine *TM, Function &F)
- : BaseT(TM), ST(TM->getSubtargetImpl(F)), TLI(ST->getTargetLowering()) {}
+ : BaseT(TM), TM(TM), ST(TM->getSubtargetImpl(F)),
+ TLI(ST->getTargetLowering()) {}
// Provide value semantics. MSVC requires that we spell all of these out.
AArch64TTIImpl(const AArch64TTIImpl &Arg)
- : BaseT(static_cast<const BaseT &>(Arg)), ST(Arg.ST), TLI(Arg.TLI) {}
+ : BaseT(static_cast<const BaseT &>(Arg)), TM(Arg.TM), ST(Arg.ST),
+ TLI(Arg.TLI) {}
AArch64TTIImpl(AArch64TTIImpl &&Arg)
- : BaseT(std::move(static_cast<BaseT &>(Arg))), ST(std::move(Arg.ST)),
- TLI(std::move(Arg.TLI)) {}
+ : BaseT(std::move(static_cast<BaseT &>(Arg))), TM(std::move(Arg.TM)),
+ ST(std::move(Arg.ST)), TLI(std::move(Arg.TLI)) {}
AArch64TTIImpl &operator=(const AArch64TTIImpl &RHS) {
BaseT::operator=(static_cast<const BaseT &>(RHS));
+ TM = RHS.TM;
ST = RHS.ST;
TLI = RHS.TLI;
return *this;
}
AArch64TTIImpl &operator=(AArch64TTIImpl &&RHS) {
BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
+ TM = std::move(RHS.TM);
ST = std::move(RHS.ST);
TLI = std::move(RHS.TLI);
return *this;
class ARMTTIImpl : public BasicTTIImplBase<ARMTTIImpl> {
typedef BasicTTIImplBase<ARMTTIImpl> BaseT;
typedef TargetTransformInfo TTI;
+ friend BaseT;
+ const ARMBaseTargetMachine *TM;
const ARMSubtarget *ST;
const ARMTargetLowering *TLI;
/// are set if the result needs to be inserted and/or extracted from vectors.
unsigned getScalarizationOverhead(Type *Ty, bool Insert, bool Extract);
+ const ARMBaseTargetMachine *getTM() const { return TM; }
+ const ARMTargetLowering *getTLI() const { return TLI; }
+
public:
explicit ARMTTIImpl(const ARMBaseTargetMachine *TM, Function &F)
- : BaseT(TM), ST(TM->getSubtargetImpl(F)), TLI(ST->getTargetLowering()) {}
+ : BaseT(TM), TM(TM), ST(TM->getSubtargetImpl(F)),
+ TLI(ST->getTargetLowering()) {}
// Provide value semantics. MSVC requires that we spell all of these out.
ARMTTIImpl(const ARMTTIImpl &Arg)
- : BaseT(static_cast<const BaseT &>(Arg)), ST(Arg.ST), TLI(Arg.TLI) {}
+ : BaseT(static_cast<const BaseT &>(Arg)), TM(Arg.TM), ST(Arg.ST), TLI(Arg.TLI) {}
ARMTTIImpl(ARMTTIImpl &&Arg)
- : BaseT(std::move(static_cast<BaseT &>(Arg))), ST(std::move(Arg.ST)),
- TLI(std::move(Arg.TLI)) {}
+ : BaseT(std::move(static_cast<BaseT &>(Arg))), TM(std::move(Arg.TM)),
+ ST(std::move(Arg.ST)), TLI(std::move(Arg.TLI)) {}
ARMTTIImpl &operator=(const ARMTTIImpl &RHS) {
BaseT::operator=(static_cast<const BaseT &>(RHS));
+ TM = RHS.TM;
ST = RHS.ST;
TLI = RHS.TLI;
return *this;
}
ARMTTIImpl &operator=(ARMTTIImpl &&RHS) {
BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
+ TM = std::move(RHS.TM);
ST = std::move(RHS.ST);
TLI = std::move(RHS.TLI);
return *this;
class NVPTXTTIImpl : public BasicTTIImplBase<NVPTXTTIImpl> {
typedef BasicTTIImplBase<NVPTXTTIImpl> BaseT;
typedef TargetTransformInfo TTI;
+ friend BaseT;
+ const NVPTXTargetMachine *TM;
const NVPTXTargetLowering *TLI;
+ const NVPTXTargetMachine *getTM() const { return TM; };
+ const NVPTXTargetLowering *getTLI() const { return TLI; };
+
public:
explicit NVPTXTTIImpl(const NVPTXTargetMachine *TM)
- : BaseT(TM), TLI(TM->getSubtargetImpl()->getTargetLowering()) {}
+ : BaseT(TM), TM(TM), TLI(TM->getSubtargetImpl()->getTargetLowering()) {}
// Provide value semantics. MSVC requires that we spell all of these out.
NVPTXTTIImpl(const NVPTXTTIImpl &Arg)
- : BaseT(static_cast<const BaseT &>(Arg)), TLI(Arg.TLI) {}
+ : BaseT(static_cast<const BaseT &>(Arg)), TM(Arg.TM), TLI(Arg.TLI) {}
NVPTXTTIImpl(NVPTXTTIImpl &&Arg)
- : BaseT(std::move(static_cast<BaseT &>(Arg))), TLI(std::move(Arg.TLI)) {}
+ : BaseT(std::move(static_cast<BaseT &>(Arg))), TM(std::move(Arg.TM)), TLI(std::move(Arg.TLI)) {}
NVPTXTTIImpl &operator=(const NVPTXTTIImpl &RHS) {
BaseT::operator=(static_cast<const BaseT &>(RHS));
+ TM = RHS.TM;
TLI = RHS.TLI;
return *this;
}
NVPTXTTIImpl &operator=(NVPTXTTIImpl &&RHS) {
BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
+ TM = std::move(RHS.TM);
TLI = std::move(RHS.TLI);
return *this;
}
class PPCTTIImpl : public BasicTTIImplBase<PPCTTIImpl> {
typedef BasicTTIImplBase<PPCTTIImpl> BaseT;
typedef TargetTransformInfo TTI;
+ friend BaseT;
+ const PPCTargetMachine *TM;
const PPCSubtarget *ST;
const PPCTargetLowering *TLI;
+ const PPCTargetMachine *getTM() const { return TM; }
+ const PPCTargetLowering *getTLI() const { return TLI; }
+
public:
explicit PPCTTIImpl(const PPCTargetMachine *TM, Function &F)
- : BaseT(TM), ST(TM->getSubtargetImpl(F)), TLI(ST->getTargetLowering()) {}
+ : BaseT(TM), TM(TM), ST(TM->getSubtargetImpl(F)),
+ TLI(ST->getTargetLowering()) {}
// Provide value semantics. MSVC requires that we spell all of these out.
PPCTTIImpl(const PPCTTIImpl &Arg)
- : BaseT(static_cast<const BaseT &>(Arg)), ST(Arg.ST), TLI(Arg.TLI) {}
+ : BaseT(static_cast<const BaseT &>(Arg)), TM(Arg.TM), ST(Arg.ST),
+ TLI(Arg.TLI) {}
PPCTTIImpl(PPCTTIImpl &&Arg)
- : BaseT(std::move(static_cast<BaseT &>(Arg))), ST(std::move(Arg.ST)),
- TLI(std::move(Arg.TLI)) {}
+ : BaseT(std::move(static_cast<BaseT &>(Arg))), TM(std::move(Arg.TM)),
+ ST(std::move(Arg.ST)), TLI(std::move(Arg.TLI)) {}
PPCTTIImpl &operator=(const PPCTTIImpl &RHS) {
BaseT::operator=(static_cast<const BaseT &>(RHS));
+ TM = RHS.TM;
ST = RHS.ST;
TLI = RHS.TLI;
return *this;
}
PPCTTIImpl &operator=(PPCTTIImpl &&RHS) {
BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
+ TM = std::move(RHS.TM);
ST = std::move(RHS.ST);
TLI = std::move(RHS.TLI);
return *this;
class AMDGPUTTIImpl : public BasicTTIImplBase<AMDGPUTTIImpl> {
typedef BasicTTIImplBase<AMDGPUTTIImpl> BaseT;
typedef TargetTransformInfo TTI;
+ friend BaseT;
+ const AMDGPUTargetMachine *TM;
const AMDGPUSubtarget *ST;
+ const AMDGPUTargetLowering *TLI;
+
+ const AMDGPUTargetMachine *getTM() const { return TM; }
+ const AMDGPUTargetLowering *getTLI() const { return TLI; }
public:
explicit AMDGPUTTIImpl(const AMDGPUTargetMachine *TM)
- : BaseT(TM), ST(TM->getSubtargetImpl()) {}
+ : BaseT(TM), TM(TM), ST(TM->getSubtargetImpl()),
+ TLI(ST->getTargetLowering()) {}
// Provide value semantics. MSVC requires that we spell all of these out.
AMDGPUTTIImpl(const AMDGPUTTIImpl &Arg)
- : BaseT(static_cast<const BaseT &>(Arg)), ST(Arg.ST) {}
+ : BaseT(static_cast<const BaseT &>(Arg)), TM(Arg.TM), ST(Arg.ST),
+ TLI(Arg.TLI) {}
AMDGPUTTIImpl(AMDGPUTTIImpl &&Arg)
- : BaseT(std::move(static_cast<BaseT &>(Arg))), ST(std::move(Arg.ST)) {}
+ : BaseT(std::move(static_cast<BaseT &>(Arg))), TM(std::move(Arg.TM)),
+ ST(std::move(Arg.ST)), TLI(std::move(Arg.TLI)) {}
AMDGPUTTIImpl &operator=(const AMDGPUTTIImpl &RHS) {
BaseT::operator=(static_cast<const BaseT &>(RHS));
+ TM = RHS.TM;
ST = RHS.ST;
+ TLI = RHS.TLI;
return *this;
}
AMDGPUTTIImpl &operator=(AMDGPUTTIImpl &&RHS) {
BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
+ TM = std::move(RHS.TM);
ST = std::move(RHS.ST);
+ TLI = std::move(RHS.TLI);
return *this;
}
class X86TTIImpl : public BasicTTIImplBase<X86TTIImpl> {
typedef BasicTTIImplBase<X86TTIImpl> BaseT;
typedef TargetTransformInfo TTI;
+ friend BaseT;
+ const X86TargetMachine *TM;
const X86Subtarget *ST;
const X86TargetLowering *TLI;
unsigned getScalarizationOverhead(Type *Ty, bool Insert, bool Extract);
+ const X86TargetMachine *getTM() const { return TM; }
+ const X86TargetLowering *getTLI() const { return TLI; }
+
public:
explicit X86TTIImpl(const X86TargetMachine *TM, Function &F)
- : BaseT(TM), ST(TM->getSubtargetImpl(F)), TLI(ST->getTargetLowering()) {}
+ : BaseT(TM), TM(TM), ST(TM->getSubtargetImpl(F)),
+ TLI(ST->getTargetLowering()) {}
// Provide value semantics. MSVC requires that we spell all of these out.
X86TTIImpl(const X86TTIImpl &Arg)
- : BaseT(static_cast<const BaseT &>(Arg)), ST(Arg.ST), TLI(Arg.TLI) {}
+ : BaseT(static_cast<const BaseT &>(Arg)), TM(Arg.TM), ST(Arg.ST),
+ TLI(Arg.TLI) {}
X86TTIImpl(X86TTIImpl &&Arg)
- : BaseT(std::move(static_cast<BaseT &>(Arg))), ST(std::move(Arg.ST)),
- TLI(std::move(Arg.TLI)) {}
+ : BaseT(std::move(static_cast<BaseT &>(Arg))), TM(std::move(Arg.TM)),
+ ST(std::move(Arg.ST)), TLI(std::move(Arg.TLI)) {}
X86TTIImpl &operator=(const X86TTIImpl &RHS) {
BaseT::operator=(static_cast<const BaseT &>(RHS));
+ TM = RHS.TM;
ST = RHS.ST;
TLI = RHS.TLI;
return *this;
}
X86TTIImpl &operator=(X86TTIImpl &&RHS) {
BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
+ TM = std::move(RHS.TM);
ST = std::move(RHS.ST);
TLI = std::move(RHS.TLI);
return *this;
class XCoreTTIImpl : public BasicTTIImplBase<XCoreTTIImpl> {
typedef BasicTTIImplBase<XCoreTTIImpl> BaseT;
typedef TargetTransformInfo TTI;
+ friend BaseT;
+
+ const XCoreTargetMachine *TM;
+ const XCoreTargetLowering *TLI;
+
+ const XCoreTargetMachine *getTM() const { return TM; }
+ const XCoreTargetLowering *getTLI() const { return TLI; }
public:
- explicit XCoreTTIImpl(const XCoreTargetMachine *TM) : BaseT(TM) {}
+ explicit XCoreTTIImpl(const XCoreTargetMachine *TM)
+ : BaseT(TM), TM(TM), TLI(TM->getSubtargetImpl()->getTargetLowering()) {}
// Provide value semantics. MSVC requires that we spell all of these out.
XCoreTTIImpl(const XCoreTTIImpl &Arg)
- : BaseT(static_cast<const BaseT &>(Arg)) {}
+ : BaseT(static_cast<const BaseT &>(Arg)), TM(Arg.TM), TLI(Arg.TLI) {}
XCoreTTIImpl(XCoreTTIImpl &&Arg)
- : BaseT(std::move(static_cast<BaseT &>(Arg))) {}
+ : BaseT(std::move(static_cast<BaseT &>(Arg))), TM(std::move(Arg.TM)),
+ TLI(std::move(Arg.TLI)) {}
XCoreTTIImpl &operator=(const XCoreTTIImpl &RHS) {
BaseT::operator=(static_cast<const BaseT &>(RHS));
+ TM = RHS.TM;
+ TLI = RHS.TLI;
return *this;
}
XCoreTTIImpl &operator=(XCoreTTIImpl &&RHS) {
BaseT::operator=(std::move(static_cast<BaseT &>(RHS)));
+ TM = std::move(RHS.TM);
+ TLI = std::move(RHS.TLI);
return *this;
}