summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChandler Carruth <chandlerc@gmail.com>2013-01-05 11:43:11 +0000
committerChandler Carruth <chandlerc@gmail.com>2013-01-05 11:43:11 +0000
commit7bdf6b00e04c177f22133b5d4be10cb246cb1e76 (patch)
tree7eca0d64d4d8fb0c6e2f2ddc40f549d6b75ef1f1
parentbe73c7b903647221fbcaae302d31e90f53583040 (diff)
downloadllvm-7bdf6b00e04c177f22133b5d4be10cb246cb1e76.tar.gz
llvm-7bdf6b00e04c177f22133b5d4be10cb246cb1e76.tar.bz2
llvm-7bdf6b00e04c177f22133b5d4be10cb246cb1e76.tar.xz
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
-rw-r--r--include/llvm/InitializePasses.h3
-rw-r--r--include/llvm/TargetTransformInfo.h331
-rw-r--r--lib/IR/Core.cpp1
-rw-r--r--lib/IR/TargetTransformInfo.cpp262
-rw-r--r--lib/Target/Target.cpp1
-rw-r--r--tools/llc/llc.cpp4
-rw-r--r--tools/opt/opt.cpp4
7 files changed, 398 insertions, 208 deletions
diff --git a/include/llvm/InitializePasses.h b/include/llvm/InitializePasses.h
index ee08fe0f79..9ee74dde1d 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 197fdcbeef..97d0304a38 100644
--- a/include/llvm/TargetTransformInfo.h
+++ b/include/llvm/TargetTransformInfo.h
@@ -30,16 +30,34 @@
namespace llvm {
-// ---------------------------------------------------------------------------//
-// The classes below are inherited and implemented by target-specific classes
-// in the codegen.
-// ---------------------------------------------------------------------------//
+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;
-/// ScalarTargetTransformInfo - This interface is used by IR-level passes
-/// that need target-dependent information for generic scalar transformations.
-/// LSR, and LowerInvoke use this interface.
-class ScalarTargetTransformInfo {
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
@@ -52,22 +70,18 @@ public:
Slow
};
- virtual ~ScalarTargetTransformInfo() {}
-
/// 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) const {
- return false;
- }
+ 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) const {
- return false;
- }
+ 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
@@ -75,53 +89,37 @@ public:
/// TODO: Handle pre/postinc as well.
virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV,
int64_t BaseOffset, bool HasBaseReg,
- int64_t Scale) const {
- return false;
- }
+ 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 {
- return false;
- }
+ virtual bool isTruncateFree(Type *Ty1, Type *Ty2) const;
+
/// Is this type legal.
- virtual bool isTypeLegal(Type *Ty) const {
- return false;
- }
+ virtual bool isTypeLegal(Type *Ty) const;
+
/// getJumpBufAlignment - returns the target's jmp_buf alignment in bytes
- virtual unsigned getJumpBufAlignment() const {
- return 0;
- }
+ virtual unsigned getJumpBufAlignment() const;
+
/// getJumpBufSize - returns the target's jmp_buf size in bytes.
- virtual unsigned getJumpBufSize() const {
- return 0;
- }
+ virtual unsigned getJumpBufSize() const;
+
/// shouldBuildLookupTables - Return true if switches should be turned into
/// lookup tables for the target.
- virtual bool shouldBuildLookupTables() const {
- return true;
- }
+ virtual bool shouldBuildLookupTables() const;
+
/// getPopcntHwSupport - Return hardware support for population count.
- virtual PopcntHwSupport getPopcntHwSupport(unsigned IntTyWidthInBit) const {
- return None;
- }
+ 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&, Type*) const {
- // The default assumption is that the immediate is cheap.
- return 1;
- }
-};
+ virtual unsigned getIntImmCost(const APInt &Imm, Type *Ty) const;
-/// VectorTargetTransformInfo - This interface is used by the vectorizers
-/// to estimate the profitability of vectorization for different instructions.
-/// This interface provides the cost of different IR instructions. The cost
-/// is unit-less and represents the estimated throughput of the instruction
-/// (not the latency!) assuming that all branches are predicted, cache is hit,
-/// etc.
-class VectorTargetTransformInfo {
-public:
- virtual ~VectorTargetTransformInfo() {}
+ /// @}
+
+ /// \name Vector Target Information
+ /// @{
enum ShuffleKind {
Broadcast, // Broadcast element 0 to all other elements.
@@ -133,96 +131,73 @@ public:
/// \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 8;
- }
+ 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 1;
- }
+ 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 1;
- }
+ 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 1;
- }
+ Type *Src) const;
/// \return The expected cost of control-flow related instrutctions such as
/// Phi, Ret, Br.
- virtual unsigned getCFInstrCost(unsigned Opcode) const {
- return 1;
- }
+ 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 1;
- }
+ 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 1;
- }
+ unsigned Index = -1) const;
/// \return The cost of Load and Store instructions.
virtual unsigned getMemoryOpCost(unsigned Opcode, Type *Src,
unsigned Alignment,
- unsigned AddressSpace) const {
- return 1;
- }
+ unsigned AddressSpace) const;
/// \returns The cost of Intrinsic instructions.
- virtual unsigned getIntrinsicInstrCost(Intrinsic::ID,
- Type *RetTy,
- ArrayRef<Type*> Tys) const {
- return 1;
- }
+ virtual unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy,
+ ArrayRef<Type *> 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 {
- return 0;
- }
-};
+ virtual unsigned getNumberOfParts(Type *Tp) const;
+ /// @}
-/// 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());
- }
+ /// Analysis group identification.
+ static char ID;
+};
- TargetTransformInfo(const TargetTransformInfo &T) :
- ImmutablePass(ID), STTI(T.STTI), VTTI(T.VTTI) { }
+/// \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);
- /// \name Scalar Target Information
- /// @{
+// ---------------------------------------------------------------------------//
+// The classes below are inherited and implemented by target-specific classes
+// in the codegen.
+// ---------------------------------------------------------------------------//
+
+/// ScalarTargetTransformInfo - This interface is used by IR-level passes
+/// that need target-dependent information for generic scalar transformations.
+/// LSR, and LowerInvoke use this interface.
+class ScalarTargetTransformInfo {
+public:
/// 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
@@ -235,77 +210,76 @@ public:
Slow
};
+ virtual ~ScalarTargetTransformInfo() {}
+
/// 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);
+ virtual bool isLegalAddImmediate(int64_t) const {
+ return false;
}
-
/// 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);
+ virtual bool isLegalICmpImmediate(int64_t) const {
+ return false;
}
-
/// 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,
+ virtual bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV,
int64_t BaseOffset, bool HasBaseReg,
int64_t Scale) const {
- return STTI->isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg,
- Scale);
+ return false;
}
-
/// 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);
+ virtual bool isTruncateFree(Type *Ty1, Type *Ty2) const {
+ return false;
}
-
/// Is this type legal.
- bool isTypeLegal(Type *Ty) const {
- return STTI->isTypeLegal(Ty);
+ virtual bool isTypeLegal(Type *Ty) const {
+ return false;
}
-
/// getJumpBufAlignment - returns the target's jmp_buf alignment in bytes
- unsigned getJumpBufAlignment() const {
- return STTI->getJumpBufAlignment();
+ virtual unsigned getJumpBufAlignment() const {
+ return 0;
}
-
/// getJumpBufSize - returns the target's jmp_buf size in bytes.
- unsigned getJumpBufSize() const {
- return STTI->getJumpBufSize();
+ virtual unsigned getJumpBufSize() const {
+ return 0;
}
-
/// shouldBuildLookupTables - Return true if switches should be turned into
/// lookup tables for the target.
- bool shouldBuildLookupTables() const {
- return STTI->shouldBuildLookupTables();
+ virtual bool shouldBuildLookupTables() const {
+ return true;
}
-
/// getPopcntHwSupport - Return hardware support for population count.
- PopcntHwSupport getPopcntHwSupport(unsigned IntTyWidthInBit) const {
- return (PopcntHwSupport)STTI->getPopcntHwSupport(IntTyWidthInBit);
+ virtual PopcntHwSupport getPopcntHwSupport(unsigned IntTyWidthInBit) const {
+ return None;
}
-
/// 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);
+ virtual unsigned getIntImmCost(const APInt&, Type*) const {
+ // The default assumption is that the immediate is cheap.
+ return 1;
}
+};
- /// @}
-
- /// \name Vector Target Information
- /// @{
+/// VectorTargetTransformInfo - This interface is used by the vectorizers
+/// to estimate the profitability of vectorization for different instructions.
+/// This interface provides the cost of different IR instructions. The cost
+/// is unit-less and represents the estimated throughput of the instruction
+/// (not the latency!) assuming that all branches are predicted, cache is hit,
+/// etc.
+class VectorTargetTransformInfo {
+public:
+ virtual ~VectorTargetTransformInfo() {}
enum ShuffleKind {
Broadcast, // Broadcast element 0 to all other elements.
@@ -317,88 +291,71 @@ public:
/// \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);
+ virtual unsigned getNumberOfRegisters(bool Vector) const {
+ return 8;
}
/// \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);
+ virtual unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty) const {
+ return 1;
}
/// \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);
+ virtual unsigned getShuffleCost(ShuffleKind Kind, Type *Tp,
+ int Index = 0, Type *SubTp = 0) const {
+ return 1;
}
/// \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);
+ virtual unsigned getCastInstrCost(unsigned Opcode, Type *Dst,
+ Type *Src) const {
+ return 1;
}
/// \return The expected cost of control-flow related instrutctions such as
/// Phi, Ret, Br.
- unsigned getCFInstrCost(unsigned Opcode) const {
- return VTTI->getCFInstrCost(Opcode);
+ virtual unsigned getCFInstrCost(unsigned Opcode) const {
+ return 1;
}
/// \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);
+ virtual unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy,
+ Type *CondTy = 0) const {
+ return 1;
}
/// \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);
+ virtual unsigned getVectorInstrCost(unsigned Opcode, Type *Val,
+ unsigned Index = -1) const {
+ return 1;
}
/// \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);;
+ virtual unsigned getMemoryOpCost(unsigned Opcode, Type *Src,
+ unsigned Alignment,
+ unsigned AddressSpace) const {
+ return 1;
}
/// \returns The cost of Intrinsic instructions.
- unsigned getIntrinsicInstrCost(Intrinsic::ID ID,
- Type *RetTy,
- ArrayRef<Type*> Tys) const {
- return VTTI->getIntrinsicInstrCost(ID, RetTy, Tys);
+ virtual unsigned getIntrinsicInstrCost(Intrinsic::ID,
+ Type *RetTy,
+ ArrayRef<Type*> Tys) const {
+ return 1;
}
/// \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;
+ virtual unsigned getNumberOfParts(Type *Tp) const {
+ return 0;
}
-
- /// @}
-
- /// 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 2024ac9b05..0b09a22d75 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 209e1dba8f..8d5fb0d40b 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<TargetTransformInfo>()", and you did
- /// not initialize a machine target which can provide the TTI.
- /// You should use "getAnalysisIfAvailable<TargetTransformInfo>()" 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<TargetTransformInfo>();
+}
+
+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<Type *> 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<Type*> 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 3a8a9c9b33..9a78ebc3fa 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 f81495cc7e..68876ea22a 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 9c9e394043..c2987f19ed 100644
--- a/tools/opt/opt.cpp
+++ b/tools/opt/opt.cpp
@@ -658,8 +658,8 @@ int main(int argc, char **argv) {
std::auto_ptr<TargetMachine> TM(Machine);
if (TM.get()) {
- Passes.add(new TargetTransformInfo(TM->getScalarTargetTransformInfo(),
- TM->getVectorTargetTransformInfo()));
+ Passes.add(createNoTTIPass(TM->getScalarTargetTransformInfo(),
+ TM->getVectorTargetTransformInfo()));
}
OwningPtr<FunctionPassManager> FPasses;