aboutsummaryrefslogtreecommitdiff
path: root/lib/IR/TargetTransformInfo.cpp
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 /lib/IR/TargetTransformInfo.cpp
parentbe73c7b903647221fbcaae302d31e90f53583040 (diff)
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
Diffstat (limited to 'lib/IR/TargetTransformInfo.cpp')
-rw-r--r--lib/IR/TargetTransformInfo.cpp262
1 files changed, 247 insertions, 15 deletions
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);
+}