From 7bdf6b00e04c177f22133b5d4be10cb246cb1e76 Mon Sep 17 00:00:00 2001 From: Chandler Carruth Date: Sat, 5 Jan 2013 11:43:11 +0000 Subject: [PATCH] Convert the TargetTransformInfo from an immutable pass with dynamic interfaces which could be extracted from it, and must be provided on construction, to a chained analysis group. The end goal here is that TTI works much like AA -- there is a baseline "no-op" and target independent pass which is in the group, and each target can expose a target-specific pass in the group. These passes will naturally chain allowing each target-specific pass to delegate to the generic pass as needed. In particular, this will allow a much simpler interface for passes that would like to use TTI -- they can have a hard dependency on TTI and it will just be satisfied by the stub implementation when that is all that is available. This patch is a WIP however. In particular, the "stub" pass is actually the one and only pass, and everything there is implemented by delegating to the target-provided interfaces. As a consequence the tools still have to explicitly construct the pass. Switching targets to provide custom passes and sinking the stub behavior into the NoTTI pass is the next step. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@171621 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/InitializePasses.h | 3 +- include/llvm/TargetTransformInfo.h | 359 +++++++++++++---------------- lib/IR/Core.cpp | 1 + lib/IR/TargetTransformInfo.cpp | 262 +++++++++++++++++++-- lib/Target/Target.cpp | 1 - tools/llc/llc.cpp | 4 +- tools/opt/opt.cpp | 4 +- 7 files changed, 412 insertions(+), 222 deletions(-) diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h index ee08fe0f797..9ee74dde1dd 100644 --- a/include/llvm/InitializePasses.h +++ b/include/llvm/InitializePasses.h @@ -250,7 +250,8 @@ void initializeTailCallElimPass(PassRegistry&); void initializeTailDuplicatePassPass(PassRegistry&); void initializeTargetPassConfigPass(PassRegistry&); void initializeDataLayoutPass(PassRegistry&); -void initializeTargetTransformInfoPass(PassRegistry&); +void initializeTargetTransformInfoAnalysisGroup(PassRegistry&); +void initializeNoTTIPass(PassRegistry&); void initializeTargetLibraryInfoPass(PassRegistry&); void initializeTwoAddressInstructionPassPass(PassRegistry&); void initializeTypeBasedAliasAnalysisPass(PassRegistry&); diff --git a/include/llvm/TargetTransformInfo.h b/include/llvm/TargetTransformInfo.h index 197fdcbeef1..97d0304a38b 100644 --- a/include/llvm/TargetTransformInfo.h +++ b/include/llvm/TargetTransformInfo.h @@ -30,6 +30,164 @@ namespace llvm { +class ScalarTargetTransformInfo; +class VectorTargetTransformInfo; + +/// TargetTransformInfo - This pass provides access to the codegen +/// interfaces that are needed for IR-level transformations. +class TargetTransformInfo { +protected: + /// \brief The TTI instance one level down the stack. + /// + /// This is used to implement the default behavior all of the methods which + /// is to delegate up through the stack of TTIs until one can answer the + /// query. + const TargetTransformInfo *PrevTTI; + + /// Every subclass must initialize the base with the previous TTI in the + /// stack, or 0 if there is no previous TTI in the stack. + TargetTransformInfo(const TargetTransformInfo *PrevTTI) : PrevTTI(PrevTTI) {} + + /// All pass subclasses must call TargetTransformInfo::getAnalysisUsage. + virtual void getAnalysisUsage(AnalysisUsage &AU) const; + +public: + /// This class is intended to be subclassed by real implementations. + virtual ~TargetTransformInfo() = 0; + + /// \name Scalar Target Information + /// @{ + + /// PopcntHwSupport - Hardware support for population count. Compared to the + /// SW implementation, HW support is supposed to significantly boost the + /// performance when the population is dense, and it may or may not degrade + /// performance if the population is sparse. A HW support is considered as + /// "Fast" if it can outperform, or is on a par with, SW implementaion when + /// the population is sparse; otherwise, it is considered as "Slow". + enum PopcntHwSupport { + None, + Fast, + Slow + }; + + /// isLegalAddImmediate - Return true if the specified immediate is legal + /// add immediate, that is the target has add instructions which can add + /// a register with the immediate without having to materialize the + /// immediate into a register. + virtual bool isLegalAddImmediate(int64_t Imm) const; + + /// isLegalICmpImmediate - Return true if the specified immediate is legal + /// icmp immediate, that is the target has icmp instructions which can compare + /// a register against the immediate without having to materialize the + /// immediate into a register. + virtual bool isLegalICmpImmediate(int64_t Imm) const; + + /// isLegalAddressingMode - Return true if the addressing mode represented by + /// AM is legal for this target, for a load/store of the specified type. + /// The type may be VoidTy, in which case only return true if the addressing + /// mode is legal for a load/store of any legal type. + /// TODO: Handle pre/postinc as well. + virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, + int64_t BaseOffset, bool HasBaseReg, + int64_t Scale) const; + + /// isTruncateFree - Return true if it's free to truncate a value of + /// type Ty1 to type Ty2. e.g. On x86 it's free to truncate a i32 value in + /// register EAX to i16 by referencing its sub-register AX. + virtual bool isTruncateFree(Type *Ty1, Type *Ty2) const; + + /// Is this type legal. + virtual bool isTypeLegal(Type *Ty) const; + + /// getJumpBufAlignment - returns the target's jmp_buf alignment in bytes + virtual unsigned getJumpBufAlignment() const; + + /// getJumpBufSize - returns the target's jmp_buf size in bytes. + virtual unsigned getJumpBufSize() const; + + /// shouldBuildLookupTables - Return true if switches should be turned into + /// lookup tables for the target. + virtual bool shouldBuildLookupTables() const; + + /// getPopcntHwSupport - Return hardware support for population count. + virtual PopcntHwSupport getPopcntHwSupport(unsigned IntTyWidthInBit) const; + + /// getIntImmCost - Return the expected cost of materializing the given + /// integer immediate of the specified type. + virtual unsigned getIntImmCost(const APInt &Imm, Type *Ty) const; + + /// @} + + /// \name Vector Target Information + /// @{ + + enum ShuffleKind { + Broadcast, // Broadcast element 0 to all other elements. + Reverse, // Reverse the order of the vector. + InsertSubvector, // InsertSubvector. Index indicates start offset. + ExtractSubvector // ExtractSubvector Index indicates start offset. + }; + + /// \return The number of scalar or vector registers that the target has. + /// If 'Vectors' is true, it returns the number of vector registers. If it is + /// set to false, it returns the number of scalar registers. + virtual unsigned getNumberOfRegisters(bool Vector) const; + + /// \return The expected cost of arithmetic ops, such as mul, xor, fsub, etc. + virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty) const; + + /// \return The cost of a shuffle instruction of kind Kind and of type Tp. + /// The index and subtype parameters are used by the subvector insertion and + /// extraction shuffle kinds. + virtual unsigned getShuffleCost(ShuffleKind Kind, Type *Tp, int Index = 0, + Type *SubTp = 0) const; + + /// \return The expected cost of cast instructions, such as bitcast, trunc, + /// zext, etc. + virtual unsigned getCastInstrCost(unsigned Opcode, Type *Dst, + Type *Src) const; + + /// \return The expected cost of control-flow related instrutctions such as + /// Phi, Ret, Br. + virtual unsigned getCFInstrCost(unsigned Opcode) const; + + /// \returns The expected cost of compare and select instructions. + virtual unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, + Type *CondTy = 0) const; + + /// \return The expected cost of vector Insert and Extract. + /// Use -1 to indicate that there is no information on the index value. + virtual unsigned getVectorInstrCost(unsigned Opcode, Type *Val, + unsigned Index = -1) const; + + /// \return The cost of Load and Store instructions. + virtual unsigned getMemoryOpCost(unsigned Opcode, Type *Src, + unsigned Alignment, + unsigned AddressSpace) const; + + /// \returns The cost of Intrinsic instructions. + virtual unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy, + ArrayRef Tys) const; + + /// \returns The number of pieces into which the provided type must be + /// split during legalization. Zero is returned when the answer is unknown. + virtual unsigned getNumberOfParts(Type *Tp) const; + + /// @} + + /// Analysis group identification. + static char ID; +}; + +/// \brief Create the base case instance of a pass in the TTI analysis group. +/// +/// This class provides the base case for the stack of TTI analyses. It doesn't +/// delegate to anything and uses the STTI and VTTI objects passed in to +/// satisfy the queries. +ImmutablePass *createNoTTIPass(const ScalarTargetTransformInfo *S, + const VectorTargetTransformInfo *V); + + // ---------------------------------------------------------------------------// // The classes below are inherited and implemented by target-specific classes // in the codegen. @@ -198,207 +356,6 @@ public: }; -/// TargetTransformInfo - This pass provides access to the codegen -/// interfaces that are needed for IR-level transformations. -class TargetTransformInfo : public ImmutablePass { -private: - const ScalarTargetTransformInfo *STTI; - const VectorTargetTransformInfo *VTTI; -public: - /// Default ctor. - /// - /// @note This has to exist, because this is a pass, but it should never be - /// used. - TargetTransformInfo(); - - TargetTransformInfo(const ScalarTargetTransformInfo* S, - const VectorTargetTransformInfo *V) - : ImmutablePass(ID), STTI(S), VTTI(V) { - initializeTargetTransformInfoPass(*PassRegistry::getPassRegistry()); - } - - TargetTransformInfo(const TargetTransformInfo &T) : - ImmutablePass(ID), STTI(T.STTI), VTTI(T.VTTI) { } - - /// \name Scalar Target Information - /// @{ - - /// PopcntHwSupport - Hardware support for population count. Compared to the - /// SW implementation, HW support is supposed to significantly boost the - /// performance when the population is dense, and it may or may not degrade - /// performance if the population is sparse. A HW support is considered as - /// "Fast" if it can outperform, or is on a par with, SW implementaion when - /// the population is sparse; otherwise, it is considered as "Slow". - enum PopcntHwSupport { - None, - Fast, - Slow - }; - - /// isLegalAddImmediate - Return true if the specified immediate is legal - /// add immediate, that is the target has add instructions which can add - /// a register with the immediate without having to materialize the - /// immediate into a register. - bool isLegalAddImmediate(int64_t Imm) const { - return STTI->isLegalAddImmediate(Imm); - } - - /// isLegalICmpImmediate - Return true if the specified immediate is legal - /// icmp immediate, that is the target has icmp instructions which can compare - /// a register against the immediate without having to materialize the - /// immediate into a register. - bool isLegalICmpImmediate(int64_t Imm) const { - return STTI->isLegalICmpImmediate(Imm); - } - - /// isLegalAddressingMode - Return true if the addressing mode represented by - /// AM is legal for this target, for a load/store of the specified type. - /// The type may be VoidTy, in which case only return true if the addressing - /// mode is legal for a load/store of any legal type. - /// TODO: Handle pre/postinc as well. - bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, - int64_t BaseOffset, bool HasBaseReg, - int64_t Scale) const { - return STTI->isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg, - Scale); - } - - /// isTruncateFree - Return true if it's free to truncate a value of - /// type Ty1 to type Ty2. e.g. On x86 it's free to truncate a i32 value in - /// register EAX to i16 by referencing its sub-register AX. - bool isTruncateFree(Type *Ty1, Type *Ty2) const { - return STTI->isTruncateFree(Ty1, Ty2); - } - - /// Is this type legal. - bool isTypeLegal(Type *Ty) const { - return STTI->isTypeLegal(Ty); - } - - /// getJumpBufAlignment - returns the target's jmp_buf alignment in bytes - unsigned getJumpBufAlignment() const { - return STTI->getJumpBufAlignment(); - } - - /// getJumpBufSize - returns the target's jmp_buf size in bytes. - unsigned getJumpBufSize() const { - return STTI->getJumpBufSize(); - } - - /// shouldBuildLookupTables - Return true if switches should be turned into - /// lookup tables for the target. - bool shouldBuildLookupTables() const { - return STTI->shouldBuildLookupTables(); - } - - /// getPopcntHwSupport - Return hardware support for population count. - PopcntHwSupport getPopcntHwSupport(unsigned IntTyWidthInBit) const { - return (PopcntHwSupport)STTI->getPopcntHwSupport(IntTyWidthInBit); - } - - /// getIntImmCost - Return the expected cost of materializing the given - /// integer immediate of the specified type. - unsigned getIntImmCost(const APInt &Imm, Type *Ty) const { - return STTI->getIntImmCost(Imm, Ty); - } - - /// @} - - /// \name Vector Target Information - /// @{ - - enum ShuffleKind { - Broadcast, // Broadcast element 0 to all other elements. - Reverse, // Reverse the order of the vector. - InsertSubvector, // InsertSubvector. Index indicates start offset. - ExtractSubvector // ExtractSubvector Index indicates start offset. - }; - - /// \return The number of scalar or vector registers that the target has. - /// If 'Vectors' is true, it returns the number of vector registers. If it is - /// set to false, it returns the number of scalar registers. - unsigned getNumberOfRegisters(bool Vector) const { - return VTTI->getNumberOfRegisters(Vector); - } - - /// \return The expected cost of arithmetic ops, such as mul, xor, fsub, etc. - unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty) const { - return VTTI->getArithmeticInstrCost(Opcode, Ty); - } - - /// \return The cost of a shuffle instruction of kind Kind and of type Tp. - /// The index and subtype parameters are used by the subvector insertion and - /// extraction shuffle kinds. - unsigned getShuffleCost(ShuffleKind Kind, Type *Tp, - int Index = 0, Type *SubTp = 0) const { - return VTTI->getShuffleCost((VectorTargetTransformInfo::ShuffleKind)Kind, - Tp, Index, SubTp); - } - - /// \return The expected cost of cast instructions, such as bitcast, trunc, - /// zext, etc. - unsigned getCastInstrCost(unsigned Opcode, Type *Dst, - Type *Src) const { - return VTTI->getCastInstrCost(Opcode, Dst, Src); - } - - /// \return The expected cost of control-flow related instrutctions such as - /// Phi, Ret, Br. - unsigned getCFInstrCost(unsigned Opcode) const { - return VTTI->getCFInstrCost(Opcode); - } - - /// \returns The expected cost of compare and select instructions. - unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, - Type *CondTy = 0) const { - return VTTI->getCmpSelInstrCost(Opcode, ValTy, CondTy); - } - - /// \return The expected cost of vector Insert and Extract. - /// Use -1 to indicate that there is no information on the index value. - unsigned getVectorInstrCost(unsigned Opcode, Type *Val, - unsigned Index = -1) const { - return VTTI->getVectorInstrCost(Opcode, Val, Index); - } - - /// \return The cost of Load and Store instructions. - unsigned getMemoryOpCost(unsigned Opcode, Type *Src, - unsigned Alignment, - unsigned AddressSpace) const { - return VTTI->getMemoryOpCost(Opcode, Src, Alignment, AddressSpace);; - } - - /// \returns The cost of Intrinsic instructions. - unsigned getIntrinsicInstrCost(Intrinsic::ID ID, - Type *RetTy, - ArrayRef Tys) const { - return VTTI->getIntrinsicInstrCost(ID, RetTy, Tys); - } - - /// \returns The number of pieces into which the provided type must be - /// split during legalization. Zero is returned when the answer is unknown. - unsigned getNumberOfParts(Type *Tp) const { - return VTTI->getNumberOfParts(Tp); - } - - /// @} - - /// \name Legacy sub-object getters - /// @{ - - const ScalarTargetTransformInfo* getScalarTargetTransformInfo() const { - return STTI; - } - const VectorTargetTransformInfo* getVectorTargetTransformInfo() const { - return VTTI; - } - - /// @} - - /// Pass identification, replacement for typeid. - static char ID; -}; - } // End llvm namespace #endif diff --git a/lib/IR/Core.cpp b/lib/IR/Core.cpp index 2024ac9b050..0b09a22d753 100644 --- a/lib/IR/Core.cpp +++ b/lib/IR/Core.cpp @@ -41,6 +41,7 @@ void llvm::initializeCore(PassRegistry &Registry) { initializePrintFunctionPassPass(Registry); initializeVerifierPass(Registry); initializePreVerifierPass(Registry); + initializeTargetTransformInfoAnalysisGroup(Registry); } void LLVMInitializeCore(LLVMPassRegistryRef R) { diff --git a/lib/IR/TargetTransformInfo.cpp b/lib/IR/TargetTransformInfo.cpp index 209e1dba8f2..8d5fb0d40bd 100644 --- a/lib/IR/TargetTransformInfo.cpp +++ b/lib/IR/TargetTransformInfo.cpp @@ -12,20 +12,252 @@ using namespace llvm; -/// Default ctor. -/// -/// @note This has to exist, because this is a pass, but it should never be -/// used. -TargetTransformInfo::TargetTransformInfo() : ImmutablePass(ID) { - /// You are seeing this error because your pass required the TTI - /// using a call to "getAnalysis()", and you did - /// not initialize a machine target which can provide the TTI. - /// You should use "getAnalysisIfAvailable()" instead. - report_fatal_error("Bad TargetTransformInfo ctor used. " - "Tool did not specify a TargetTransformInfo to use?"); -} - -INITIALIZE_PASS(TargetTransformInfo, "targettransforminfo", - "Target Transform Info", false, true) +// Setup the analysis group to manage the TargetTransformInfo passes. +INITIALIZE_ANALYSIS_GROUP(TargetTransformInfo, "Target Information", NoTTI) char TargetTransformInfo::ID = 0; +TargetTransformInfo::~TargetTransformInfo() { +} + +void TargetTransformInfo::getAnalysisUsage(AnalysisUsage &AU) const { + AU.addRequired(); +} + +bool TargetTransformInfo::isLegalAddImmediate(int64_t Imm) const { + return PrevTTI->isLegalAddImmediate(Imm); +} + +bool TargetTransformInfo::isLegalICmpImmediate(int64_t Imm) const { + return PrevTTI->isLegalICmpImmediate(Imm); +} + +bool TargetTransformInfo::isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, + int64_t BaseOffset, + bool HasBaseReg, + int64_t Scale) const { + return PrevTTI->isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg, + Scale); +} + +bool TargetTransformInfo::isTruncateFree(Type *Ty1, Type *Ty2) const { + return PrevTTI->isTruncateFree(Ty1, Ty2); +} + +bool TargetTransformInfo::isTypeLegal(Type *Ty) const { + return PrevTTI->isTypeLegal(Ty); +} + +unsigned TargetTransformInfo::getJumpBufAlignment() const { + return PrevTTI->getJumpBufAlignment(); +} + +unsigned TargetTransformInfo::getJumpBufSize() const { + return PrevTTI->getJumpBufSize(); +} + +bool TargetTransformInfo::shouldBuildLookupTables() const { + return PrevTTI->shouldBuildLookupTables(); +} + +TargetTransformInfo::PopcntHwSupport +TargetTransformInfo::getPopcntHwSupport(unsigned IntTyWidthInBit) const { + return PrevTTI->getPopcntHwSupport(IntTyWidthInBit); +} + +unsigned TargetTransformInfo::getIntImmCost(const APInt &Imm, Type *Ty) const { + return PrevTTI->getIntImmCost(Imm, Ty); +} + +unsigned TargetTransformInfo::getNumberOfRegisters(bool Vector) const { + return PrevTTI->getNumberOfRegisters(Vector); +} + +unsigned TargetTransformInfo::getArithmeticInstrCost(unsigned Opcode, + Type *Ty) const { + return PrevTTI->getArithmeticInstrCost(Opcode, Ty); +} + +unsigned TargetTransformInfo::getShuffleCost(ShuffleKind Kind, Type *Tp, + int Index, Type *SubTp) const { + return PrevTTI->getShuffleCost(Kind, Tp, Index, SubTp); +} + +unsigned TargetTransformInfo::getCastInstrCost(unsigned Opcode, Type *Dst, + Type *Src) const { + return PrevTTI->getCastInstrCost(Opcode, Dst, Src); +} + +unsigned TargetTransformInfo::getCFInstrCost(unsigned Opcode) const { + return PrevTTI->getCFInstrCost(Opcode); +} + +unsigned TargetTransformInfo::getCmpSelInstrCost(unsigned Opcode, Type *ValTy, + Type *CondTy) const { + return PrevTTI->getCmpSelInstrCost(Opcode, ValTy, CondTy); +} + +unsigned TargetTransformInfo::getVectorInstrCost(unsigned Opcode, Type *Val, + unsigned Index) const { + return PrevTTI->getVectorInstrCost(Opcode, Val, Index); +} + +unsigned TargetTransformInfo::getMemoryOpCost(unsigned Opcode, Type *Src, + unsigned Alignment, + unsigned AddressSpace) const { + return PrevTTI->getMemoryOpCost(Opcode, Src, Alignment, AddressSpace); + ; +} + +unsigned +TargetTransformInfo::getIntrinsicInstrCost(Intrinsic::ID ID, + Type *RetTy, + ArrayRef Tys) const { + return PrevTTI->getIntrinsicInstrCost(ID, RetTy, Tys); +} + +unsigned TargetTransformInfo::getNumberOfParts(Type *Tp) const { + return PrevTTI->getNumberOfParts(Tp); +} + + +namespace { + +class NoTTI : public ImmutablePass, public TargetTransformInfo { + const ScalarTargetTransformInfo *STTI; + const VectorTargetTransformInfo *VTTI; + +public: + // FIXME: This constructor doesn't work which breaks the use of NoTTI on the + // commandline. This has to be fixed for NoTTI to be fully usable as an + // analysis pass. + NoTTI() : ImmutablePass(ID), TargetTransformInfo(0) { + llvm_unreachable("Unsupported code path!"); + } + + NoTTI(const ScalarTargetTransformInfo *S, const VectorTargetTransformInfo *V) + : ImmutablePass(ID), + TargetTransformInfo(0), // NoTTI is special and doesn't delegate here. + STTI(S), VTTI(V) { + initializeNoTTIPass(*PassRegistry::getPassRegistry()); + } + + void getAnalysisUsage(AnalysisUsage &AU) const { + // Note that this subclass is special, and must *not* call + // TTI::getAnalysisUsage as it breaks the recursion. + } + + /// Pass identification. + static char ID; + + /// Provide necessary pointer adjustments for the two base classes. + virtual void *getAdjustedAnalysisPointer(const void *ID) { + if (ID == &TargetTransformInfo::ID) + return (TargetTransformInfo*)this; + return this; + } + + + // Delegate all predicates through the STTI or VTTI interface. + + bool isLegalAddImmediate(int64_t Imm) const { + return STTI->isLegalAddImmediate(Imm); + } + + bool isLegalICmpImmediate(int64_t Imm) const { + return STTI->isLegalICmpImmediate(Imm); + } + + bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, + bool HasBaseReg, int64_t Scale) const { + return STTI->isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg, + Scale); + } + + bool isTruncateFree(Type *Ty1, Type *Ty2) const { + return STTI->isTruncateFree(Ty1, Ty2); + } + + bool isTypeLegal(Type *Ty) const { + return STTI->isTypeLegal(Ty); + } + + unsigned getJumpBufAlignment() const { + return STTI->getJumpBufAlignment(); + } + + unsigned getJumpBufSize() const { + return STTI->getJumpBufSize(); + } + + bool shouldBuildLookupTables() const { + return STTI->shouldBuildLookupTables(); + } + + PopcntHwSupport getPopcntHwSupport(unsigned IntTyWidthInBit) const { + return (PopcntHwSupport)STTI->getPopcntHwSupport(IntTyWidthInBit); + } + + unsigned getIntImmCost(const APInt &Imm, Type *Ty) const { + return STTI->getIntImmCost(Imm, Ty); + } + + unsigned getNumberOfRegisters(bool Vector) const { + return VTTI->getNumberOfRegisters(Vector); + } + + unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty) const { + return VTTI->getArithmeticInstrCost(Opcode, Ty); + } + + unsigned getShuffleCost(ShuffleKind Kind, Type *Tp, + int Index = 0, Type *SubTp = 0) const { + return VTTI->getShuffleCost((VectorTargetTransformInfo::ShuffleKind)Kind, + Tp, Index, SubTp); + } + + unsigned getCastInstrCost(unsigned Opcode, Type *Dst, + Type *Src) const { + return VTTI->getCastInstrCost(Opcode, Dst, Src); + } + + unsigned getCFInstrCost(unsigned Opcode) const { + return VTTI->getCFInstrCost(Opcode); + } + + unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, + Type *CondTy = 0) const { + return VTTI->getCmpSelInstrCost(Opcode, ValTy, CondTy); + } + + unsigned getVectorInstrCost(unsigned Opcode, Type *Val, + unsigned Index = -1) const { + return VTTI->getVectorInstrCost(Opcode, Val, Index); + } + + unsigned getMemoryOpCost(unsigned Opcode, Type *Src, + unsigned Alignment, + unsigned AddressSpace) const { + return VTTI->getMemoryOpCost(Opcode, Src, Alignment, AddressSpace); + } + + unsigned getIntrinsicInstrCost(Intrinsic::ID ID, + Type *RetTy, + ArrayRef Tys) const { + return VTTI->getIntrinsicInstrCost(ID, RetTy, Tys); + } + + unsigned getNumberOfParts(Type *Tp) const { + return VTTI->getNumberOfParts(Tp); + } +}; + +} // end anonymous namespace + +INITIALIZE_AG_PASS(NoTTI, TargetTransformInfo, "no-tti", + "No target information", true, true, true) +char NoTTI::ID = 0; + +ImmutablePass *llvm::createNoTTIPass(const ScalarTargetTransformInfo *S, + const VectorTargetTransformInfo *V) { + return new NoTTI(S, V); +} diff --git a/lib/Target/Target.cpp b/lib/Target/Target.cpp index 3a8a9c9b332..9a78ebc3fac 100644 --- a/lib/Target/Target.cpp +++ b/lib/Target/Target.cpp @@ -26,7 +26,6 @@ using namespace llvm; void llvm::initializeTarget(PassRegistry &Registry) { initializeDataLayoutPass(Registry); initializeTargetLibraryInfoPass(Registry); - initializeTargetTransformInfoPass(Registry); } void LLVMInitializeTarget(LLVMPassRegistryRef R) { diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp index f81495cc7ea..68876ea22a2 100644 --- a/tools/llc/llc.cpp +++ b/tools/llc/llc.cpp @@ -321,8 +321,8 @@ static int compileModule(char **argv, LLVMContext &Context) { PM.add(TLI); if (target.get()) { - PM.add(new TargetTransformInfo(target->getScalarTargetTransformInfo(), - target->getVectorTargetTransformInfo())); + PM.add(createNoTTIPass(target->getScalarTargetTransformInfo(), + target->getVectorTargetTransformInfo())); } // Add the target data from the target machine, if it exists, or the module. diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index 9c9e3940434..c2987f19edd 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -658,8 +658,8 @@ int main(int argc, char **argv) { std::auto_ptr TM(Machine); if (TM.get()) { - Passes.add(new TargetTransformInfo(TM->getScalarTargetTransformInfo(), - TM->getVectorTargetTransformInfo())); + Passes.add(createNoTTIPass(TM->getScalarTargetTransformInfo(), + TM->getVectorTargetTransformInfo())); } OwningPtr FPasses;