diff --git a/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/llvm/include/llvm/CodeGen/BasicTTIImpl.h index 2b9ee6b7db31..90c41dc9b9d1 100644 --- a/llvm/include/llvm/CodeGen/BasicTTIImpl.h +++ b/llvm/include/llvm/CodeGen/BasicTTIImpl.h @@ -26,6 +26,15 @@ namespace llvm { extern cl::opt 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 class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase { private: @@ -70,30 +79,32 @@ private: return Cost; } + /// \brief Local query method delegates up to T which *must* implement this! + const TargetMachine *getTM() const { + return static_cast(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(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(Arg)), TM(Arg.TM) {} + : BaseT(static_cast(Arg)) {} BasicTTIImplBase(BasicTTIImplBase &&Arg) - : BaseT(std::move(static_cast(Arg))), TM(std::move(Arg.TM)) {} + : BaseT(std::move(static_cast(Arg))) {} BasicTTIImplBase &operator=(const BasicTTIImplBase &RHS) { BaseT::operator=(static_cast(RHS)); - TM = RHS.TM; return *this; } BasicTTIImplBase &operator=(BasicTTIImplBase &&RHS) { BaseT::operator=(std::move(static_cast(RHS))); - TM = std::move(RHS.TM); return *this; } @@ -182,7 +193,7 @@ public: // 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) @@ -626,21 +637,33 @@ public: /// is needed. class BasicTTIImpl : public BasicTTIImplBase { typedef BasicTTIImplBase BaseT; + friend class BasicTTIImplBase; + + 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(Arg)) {} + : BaseT(static_cast(Arg)), TM(Arg.TM), TLI(Arg.TLI) {} BasicTTIImpl(BasicTTIImpl &&Arg) - : BaseT(std::move(static_cast(Arg))) {} + : BaseT(std::move(static_cast(Arg))), TM(std::move(Arg.TM)), + TLI(std::move(Arg.TLI)) {} BasicTTIImpl &operator=(const BasicTTIImpl &RHS) { BaseT::operator=(static_cast(RHS)); + TM = RHS.TM; + TLI = RHS.TLI; return *this; } BasicTTIImpl &operator=(BasicTTIImpl &&RHS) { BaseT::operator=(std::move(static_cast(RHS))); + TM = std::move(RHS.TM); + TLI = std::move(RHS.TLI); return *this; } }; diff --git a/llvm/lib/CodeGen/BasicTargetTransformInfo.cpp b/llvm/lib/CodeGen/BasicTargetTransformInfo.cpp index a9fe43c66050..e0334732fdcd 100644 --- a/llvm/lib/CodeGen/BasicTargetTransformInfo.cpp +++ b/llvm/lib/CodeGen/BasicTargetTransformInfo.cpp @@ -33,4 +33,5 @@ cl::opt 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()) {} diff --git a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h index 8a98779d95b4..5d83e5e433d1 100644 --- a/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h +++ b/llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h @@ -29,7 +29,9 @@ namespace llvm { class AArch64TTIImpl : public BasicTTIImplBase { typedef BasicTTIImplBase BaseT; typedef TargetTransformInfo TTI; + friend BaseT; + const AArch64TargetMachine *TM; const AArch64Subtarget *ST; const AArch64TargetLowering *TLI; @@ -37,6 +39,9 @@ class AArch64TTIImpl : public BasicTTIImplBase { /// 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, @@ -45,22 +50,26 @@ class AArch64TTIImpl : public BasicTTIImplBase { 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(Arg)), ST(Arg.ST), TLI(Arg.TLI) {} + : BaseT(static_cast(Arg)), TM(Arg.TM), ST(Arg.ST), + TLI(Arg.TLI) {} AArch64TTIImpl(AArch64TTIImpl &&Arg) - : BaseT(std::move(static_cast(Arg))), ST(std::move(Arg.ST)), - TLI(std::move(Arg.TLI)) {} + : BaseT(std::move(static_cast(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(RHS)); + TM = RHS.TM; ST = RHS.ST; TLI = RHS.TLI; return *this; } AArch64TTIImpl &operator=(AArch64TTIImpl &&RHS) { BaseT::operator=(std::move(static_cast(RHS))); + TM = std::move(RHS.TM); ST = std::move(RHS.ST); TLI = std::move(RHS.TLI); return *this; diff --git a/llvm/lib/Target/ARM/ARMTargetTransformInfo.h b/llvm/lib/Target/ARM/ARMTargetTransformInfo.h index 8dcba8dca854..b9e52914d2ad 100644 --- a/llvm/lib/Target/ARM/ARMTargetTransformInfo.h +++ b/llvm/lib/Target/ARM/ARMTargetTransformInfo.h @@ -28,7 +28,9 @@ namespace llvm { class ARMTTIImpl : public BasicTTIImplBase { typedef BasicTTIImplBase BaseT; typedef TargetTransformInfo TTI; + friend BaseT; + const ARMBaseTargetMachine *TM; const ARMSubtarget *ST; const ARMTargetLowering *TLI; @@ -36,24 +38,30 @@ class ARMTTIImpl : public BasicTTIImplBase { /// 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(Arg)), ST(Arg.ST), TLI(Arg.TLI) {} + : BaseT(static_cast(Arg)), TM(Arg.TM), ST(Arg.ST), TLI(Arg.TLI) {} ARMTTIImpl(ARMTTIImpl &&Arg) - : BaseT(std::move(static_cast(Arg))), ST(std::move(Arg.ST)), - TLI(std::move(Arg.TLI)) {} + : BaseT(std::move(static_cast(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(RHS)); + TM = RHS.TM; ST = RHS.ST; TLI = RHS.TLI; return *this; } ARMTTIImpl &operator=(ARMTTIImpl &&RHS) { BaseT::operator=(std::move(static_cast(RHS))); + TM = std::move(RHS.TM); ST = std::move(RHS.ST); TLI = std::move(RHS.TLI); return *this; diff --git a/llvm/lib/Target/NVPTX/NVPTXTargetTransformInfo.h b/llvm/lib/Target/NVPTX/NVPTXTargetTransformInfo.h index f18b5f01799b..3e96979f0862 100644 --- a/llvm/lib/Target/NVPTX/NVPTXTargetTransformInfo.h +++ b/llvm/lib/Target/NVPTX/NVPTXTargetTransformInfo.h @@ -28,25 +28,32 @@ namespace llvm { class NVPTXTTIImpl : public BasicTTIImplBase { typedef BasicTTIImplBase 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(Arg)), TLI(Arg.TLI) {} + : BaseT(static_cast(Arg)), TM(Arg.TM), TLI(Arg.TLI) {} NVPTXTTIImpl(NVPTXTTIImpl &&Arg) - : BaseT(std::move(static_cast(Arg))), TLI(std::move(Arg.TLI)) {} + : BaseT(std::move(static_cast(Arg))), TM(std::move(Arg.TM)), TLI(std::move(Arg.TLI)) {} NVPTXTTIImpl &operator=(const NVPTXTTIImpl &RHS) { BaseT::operator=(static_cast(RHS)); + TM = RHS.TM; TLI = RHS.TLI; return *this; } NVPTXTTIImpl &operator=(NVPTXTTIImpl &&RHS) { BaseT::operator=(std::move(static_cast(RHS))); + TM = std::move(RHS.TM); TLI = std::move(RHS.TLI); return *this; } diff --git a/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.h b/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.h index 7238460467d5..83cb5e5d1136 100644 --- a/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.h +++ b/llvm/lib/Target/PowerPC/PPCTargetTransformInfo.h @@ -28,28 +28,37 @@ namespace llvm { class PPCTTIImpl : public BasicTTIImplBase { typedef BasicTTIImplBase 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(Arg)), ST(Arg.ST), TLI(Arg.TLI) {} + : BaseT(static_cast(Arg)), TM(Arg.TM), ST(Arg.ST), + TLI(Arg.TLI) {} PPCTTIImpl(PPCTTIImpl &&Arg) - : BaseT(std::move(static_cast(Arg))), ST(std::move(Arg.ST)), - TLI(std::move(Arg.TLI)) {} + : BaseT(std::move(static_cast(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(RHS)); + TM = RHS.TM; ST = RHS.ST; TLI = RHS.TLI; return *this; } PPCTTIImpl &operator=(PPCTTIImpl &&RHS) { BaseT::operator=(std::move(static_cast(RHS))); + TM = std::move(RHS.TM); ST = std::move(RHS.ST); TLI = std::move(RHS.TLI); return *this; diff --git a/llvm/lib/Target/R600/AMDGPUTargetTransformInfo.h b/llvm/lib/Target/R600/AMDGPUTargetTransformInfo.h index c35bfab67a7e..3d3f86e5d0e0 100644 --- a/llvm/lib/Target/R600/AMDGPUTargetTransformInfo.h +++ b/llvm/lib/Target/R600/AMDGPUTargetTransformInfo.h @@ -28,26 +28,39 @@ namespace llvm { class AMDGPUTTIImpl : public BasicTTIImplBase { typedef BasicTTIImplBase 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(Arg)), ST(Arg.ST) {} + : BaseT(static_cast(Arg)), TM(Arg.TM), ST(Arg.ST), + TLI(Arg.TLI) {} AMDGPUTTIImpl(AMDGPUTTIImpl &&Arg) - : BaseT(std::move(static_cast(Arg))), ST(std::move(Arg.ST)) {} + : BaseT(std::move(static_cast(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(RHS)); + TM = RHS.TM; ST = RHS.ST; + TLI = RHS.TLI; return *this; } AMDGPUTTIImpl &operator=(AMDGPUTTIImpl &&RHS) { BaseT::operator=(std::move(static_cast(RHS))); + TM = std::move(RHS.TM); ST = std::move(RHS.ST); + TLI = std::move(RHS.TLI); return *this; } diff --git a/llvm/lib/Target/X86/X86TargetTransformInfo.h b/llvm/lib/Target/X86/X86TargetTransformInfo.h index 3c1f5c0167ad..57d40581a23a 100644 --- a/llvm/lib/Target/X86/X86TargetTransformInfo.h +++ b/llvm/lib/Target/X86/X86TargetTransformInfo.h @@ -28,30 +28,39 @@ namespace llvm { class X86TTIImpl : public BasicTTIImplBase { typedef BasicTTIImplBase 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(Arg)), ST(Arg.ST), TLI(Arg.TLI) {} + : BaseT(static_cast(Arg)), TM(Arg.TM), ST(Arg.ST), + TLI(Arg.TLI) {} X86TTIImpl(X86TTIImpl &&Arg) - : BaseT(std::move(static_cast(Arg))), ST(std::move(Arg.ST)), - TLI(std::move(Arg.TLI)) {} + : BaseT(std::move(static_cast(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(RHS)); + TM = RHS.TM; ST = RHS.ST; TLI = RHS.TLI; return *this; } X86TTIImpl &operator=(X86TTIImpl &&RHS) { BaseT::operator=(std::move(static_cast(RHS))); + TM = std::move(RHS.TM); ST = std::move(RHS.ST); TLI = std::move(RHS.TLI); return *this; diff --git a/llvm/lib/Target/XCore/XCoreTargetTransformInfo.h b/llvm/lib/Target/XCore/XCoreTargetTransformInfo.h index adb21cf467e8..8a0c58ffaba2 100644 --- a/llvm/lib/Target/XCore/XCoreTargetTransformInfo.h +++ b/llvm/lib/Target/XCore/XCoreTargetTransformInfo.h @@ -28,21 +28,34 @@ namespace llvm { class XCoreTTIImpl : public BasicTTIImplBase { typedef BasicTTIImplBase 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(Arg)) {} + : BaseT(static_cast(Arg)), TM(Arg.TM), TLI(Arg.TLI) {} XCoreTTIImpl(XCoreTTIImpl &&Arg) - : BaseT(std::move(static_cast(Arg))) {} + : BaseT(std::move(static_cast(Arg))), TM(std::move(Arg.TM)), + TLI(std::move(Arg.TLI)) {} XCoreTTIImpl &operator=(const XCoreTTIImpl &RHS) { BaseT::operator=(static_cast(RHS)); + TM = RHS.TM; + TLI = RHS.TLI; return *this; } XCoreTTIImpl &operator=(XCoreTTIImpl &&RHS) { BaseT::operator=(std::move(static_cast(RHS))); + TM = std::move(RHS.TM); + TLI = std::move(RHS.TLI); return *this; }