X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FAnalysis%2FTargetTransformInfo.cpp;h=cdb0b79fd7eedeed1b7b62f12187ba3931cf547c;hb=68caf1727f809804b4fcfcefd475490fef9d304d;hp=4ad71627beaf2a1b6042e55ec24f42718248c546;hpb=57e6b2d1f3de0bf459e96f7038e692d624f7e580;p=oota-llvm.git diff --git a/lib/Analysis/TargetTransformInfo.cpp b/lib/Analysis/TargetTransformInfo.cpp index 4ad71627bea..cdb0b79fd7e 100644 --- a/lib/Analysis/TargetTransformInfo.cpp +++ b/lib/Analysis/TargetTransformInfo.cpp @@ -7,18 +7,19 @@ // //===----------------------------------------------------------------------===// -#define DEBUG_TYPE "tti" #include "llvm/Analysis/TargetTransformInfo.h" +#include "llvm/IR/CallSite.h" #include "llvm/IR/DataLayout.h" -#include "llvm/IR/Operator.h" #include "llvm/IR/Instruction.h" -#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Instructions.h" -#include "llvm/Support/CallSite.h" +#include "llvm/IR/IntrinsicInst.h" +#include "llvm/IR/Operator.h" #include "llvm/Support/ErrorHandling.h" using namespace llvm; +#define DEBUG_TYPE "tti" + // Setup the analysis group to manage the TargetTransformInfo passes. INITIALIZE_ANALYSIS_GROUP(TargetTransformInfo, "Target Information", NoTTI) char TargetTransformInfo::ID = 0; @@ -35,16 +36,6 @@ void TargetTransformInfo::pushTTIStack(Pass *P) { PTTI->TopTTI = this; } -void TargetTransformInfo::popTTIStack() { - TopTTI = 0; - - // Walk up the chain and update the top TTI pointer. - for (TargetTransformInfo *PTTI = PrevTTI; PTTI; PTTI = PTTI->PrevTTI) - PTTI->TopTTI = PrevTTI; - - PrevTTI = 0; -} - void TargetTransformInfo::getAnalysisUsage(AnalysisUsage &AU) const { AU.addRequired(); } @@ -96,6 +87,11 @@ bool TargetTransformInfo::isLoweredToCall(const Function *F) const { return PrevTTI->isLoweredToCall(F); } +void TargetTransformInfo::getUnrollingPreferences(Loop *L, + UnrollingPreferences &UP) const { + PrevTTI->getUnrollingPreferences(L, UP); +} + bool TargetTransformInfo::isLegalAddImmediate(int64_t Imm) const { return PrevTTI->isLegalAddImmediate(Imm); } @@ -145,10 +141,24 @@ TargetTransformInfo::getPopcntSupport(unsigned IntTyWidthInBit) const { return PrevTTI->getPopcntSupport(IntTyWidthInBit); } +bool TargetTransformInfo::haveFastSqrt(Type *Ty) const { + return PrevTTI->haveFastSqrt(Ty); +} + unsigned TargetTransformInfo::getIntImmCost(const APInt &Imm, Type *Ty) const { return PrevTTI->getIntImmCost(Imm, Ty); } +unsigned TargetTransformInfo::getIntImmCost(unsigned Opc, unsigned Idx, + const APInt &Imm, Type *Ty) const { + return PrevTTI->getIntImmCost(Opc, Idx, Imm, Ty); +} + +unsigned TargetTransformInfo::getIntImmCost(Intrinsic::ID IID, unsigned Idx, + const APInt &Imm, Type *Ty) const { + return PrevTTI->getIntImmCost(IID, Idx, Imm, Ty); +} + unsigned TargetTransformInfo::getNumberOfRegisters(bool Vector) const { return PrevTTI->getNumberOfRegisters(Vector); } @@ -215,24 +225,30 @@ unsigned TargetTransformInfo::getAddressComputationCost(Type *Tp, return PrevTTI->getAddressComputationCost(Tp, IsComplex); } +unsigned TargetTransformInfo::getReductionCost(unsigned Opcode, Type *Ty, + bool IsPairwise) const { + return PrevTTI->getReductionCost(Opcode, Ty, IsPairwise); +} + namespace { -struct NoTTI : ImmutablePass, TargetTransformInfo { +struct NoTTI final : ImmutablePass, TargetTransformInfo { const DataLayout *DL; - NoTTI() : ImmutablePass(ID), DL(0) { + NoTTI() : ImmutablePass(ID), DL(nullptr) { initializeNoTTIPass(*PassRegistry::getPassRegistry()); } - virtual void initializePass() { + virtual void initializePass() override { // Note that this subclass is special, and must *not* call initializeTTI as // it does not chain. TopTTI = this; - PrevTTI = 0; - DL = getAnalysisIfAvailable(); + PrevTTI = nullptr; + DataLayoutPass *DLP = getAnalysisIfAvailable(); + DL = DLP ? &DLP->getDataLayout() : nullptr; } - virtual void getAnalysisUsage(AnalysisUsage &AU) const { + virtual void getAnalysisUsage(AnalysisUsage &AU) const override { // Note that this subclass is special, and must *not* call // TTI::getAnalysisUsage as it breaks the recursion. } @@ -241,13 +257,14 @@ struct NoTTI : ImmutablePass, TargetTransformInfo { static char ID; /// Provide necessary pointer adjustments for the two base classes. - virtual void *getAdjustedAnalysisPointer(const void *ID) { + virtual void *getAdjustedAnalysisPointer(const void *ID) override { if (ID == &TargetTransformInfo::ID) return (TargetTransformInfo*)this; return this; } - unsigned getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy) const { + unsigned getOperationCost(unsigned Opcode, Type *Ty, + Type *OpTy) const override { switch (Opcode) { default: // By default, just classify everything as 'basic'. @@ -265,26 +282,34 @@ struct NoTTI : ImmutablePass, TargetTransformInfo { // Otherwise, the default basic cost is used. return TCC_Basic; - case Instruction::IntToPtr: + case Instruction::IntToPtr: { + if (!DL) + return TCC_Basic; + // An inttoptr cast is free so long as the input is a legal integer type // which doesn't contain values outside the range of a pointer. - if (DL && DL->isLegalInteger(OpTy->getScalarSizeInBits()) && - OpTy->getScalarSizeInBits() <= DL->getPointerSizeInBits()) + unsigned OpSize = OpTy->getScalarSizeInBits(); + if (DL->isLegalInteger(OpSize) && + OpSize <= DL->getPointerTypeSizeInBits(Ty)) return TCC_Free; // Otherwise it's not a no-op. return TCC_Basic; + } + case Instruction::PtrToInt: { + if (!DL) + return TCC_Basic; - case Instruction::PtrToInt: // A ptrtoint cast is free so long as the result is large enough to store // the pointer, and a legal integer type. - if (DL && DL->isLegalInteger(Ty->getScalarSizeInBits()) && - Ty->getScalarSizeInBits() >= DL->getPointerSizeInBits()) + unsigned DestSize = Ty->getScalarSizeInBits(); + if (DL->isLegalInteger(DestSize) && + DestSize >= DL->getPointerTypeSizeInBits(OpTy)) return TCC_Free; // Otherwise it's not a no-op. return TCC_Basic; - + } case Instruction::Trunc: // trunc to a native type is free (assuming the target has compare and // shift-right of the same width). @@ -296,7 +321,7 @@ struct NoTTI : ImmutablePass, TargetTransformInfo { } unsigned getGEPCost(const Value *Ptr, - ArrayRef Operands) const { + ArrayRef Operands) const override { // In the basic model, we just assume that all-constant GEPs will be folded // into their uses via addressing modes. for (unsigned Idx = 0, Size = Operands.size(); Idx != Size; ++Idx) @@ -306,7 +331,8 @@ struct NoTTI : ImmutablePass, TargetTransformInfo { return TCC_Free; } - unsigned getCallCost(FunctionType *FTy, int NumArgs = -1) const { + unsigned getCallCost(FunctionType *FTy, int NumArgs = -1) const override + { assert(FTy && "FunctionType must be provided to this routine."); // The target-independent implementation just measures the size of the @@ -321,7 +347,8 @@ struct NoTTI : ImmutablePass, TargetTransformInfo { return TCC_Basic * (NumArgs + 1); } - unsigned getCallCost(const Function *F, int NumArgs = -1) const { + unsigned getCallCost(const Function *F, int NumArgs = -1) const override + { assert(F && "A concrete function must be provided to this routine."); if (NumArgs < 0) @@ -342,7 +369,7 @@ struct NoTTI : ImmutablePass, TargetTransformInfo { } unsigned getCallCost(const Function *F, - ArrayRef Arguments) const { + ArrayRef Arguments) const override { // Simply delegate to generic handling of the call. // FIXME: We should use instsimplify or something else to catch calls which // will constant fold with these arguments. @@ -350,7 +377,7 @@ struct NoTTI : ImmutablePass, TargetTransformInfo { } unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, - ArrayRef ParamTys) const { + ArrayRef ParamTys) const override { switch (IID) { default: // Intrinsics rarely (if ever) have normal argument setup constraints. @@ -372,8 +399,9 @@ struct NoTTI : ImmutablePass, TargetTransformInfo { } } - unsigned getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, - ArrayRef Arguments) const { + unsigned + getIntrinsicCost(Intrinsic::ID IID, Type *RetTy, + ArrayRef Arguments) const override { // Delegate to the generic intrinsic handling code. This mostly provides an // opportunity for targets to (for example) special case the cost of // certain intrinsics based on constants used as arguments. @@ -384,14 +412,14 @@ struct NoTTI : ImmutablePass, TargetTransformInfo { return TopTTI->getIntrinsicCost(IID, RetTy, ParamTys); } - unsigned getUserCost(const User *U) const { + unsigned getUserCost(const User *U) const override { if (isa(U)) return TCC_Free; // Model all PHI nodes as free. - if (const GEPOperator *GEP = dyn_cast(U)) - // In the basic model we just assume that all-constant GEPs will be - // folded into their uses via addressing modes. - return GEP->hasAllConstantIndices() ? TCC_Free : TCC_Basic; + if (const GEPOperator *GEP = dyn_cast(U)) { + SmallVector Indices(GEP->idx_begin(), GEP->idx_end()); + return TopTTI->getGEPCost(GEP->getPointerOperand(), Indices); + } if (ImmutableCallSite CS = U) { const Function *F = CS.getCalledFunction(); @@ -401,12 +429,7 @@ struct NoTTI : ImmutablePass, TargetTransformInfo { return TopTTI->getCallCost(cast(FTy), CS.arg_size()); } - SmallVector Arguments; - for (ImmutableCallSite::arg_iterator AI = CS.arg_begin(), - AE = CS.arg_end(); - AI != AE; ++AI) - Arguments.push_back(*AI); - + SmallVector Arguments(CS.arg_begin(), CS.arg_end()); return TopTTI->getCallCost(F, Arguments); } @@ -421,12 +444,12 @@ struct NoTTI : ImmutablePass, TargetTransformInfo { // Otherwise delegate to the fully generic implementations. return getOperationCost(Operator::getOpcode(U), U->getType(), U->getNumOperands() == 1 ? - U->getOperand(0)->getType() : 0); + U->getOperand(0)->getType() : nullptr); } - bool hasBranchDivergence() const { return false; } + bool hasBranchDivergence() const override { return false; } - bool isLoweredToCall(const Function *F) const { + bool isLoweredToCall(const Function *F) const override { // FIXME: These should almost certainly not be handled here, and instead // handled with the help of TLI or the target itself. This was largely // ported from existing analysis heuristics here so that such refactorings @@ -457,118 +480,138 @@ struct NoTTI : ImmutablePass, TargetTransformInfo { return true; } - bool isLegalAddImmediate(int64_t Imm) const { + void getUnrollingPreferences(Loop *, UnrollingPreferences &) const override { + } + + bool isLegalAddImmediate(int64_t Imm) const override { return false; } - bool isLegalICmpImmediate(int64_t Imm) const { + bool isLegalICmpImmediate(int64_t Imm) const override { return false; } bool isLegalAddressingMode(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, - bool HasBaseReg, int64_t Scale) const { + bool HasBaseReg, int64_t Scale) const override + { // Guess that reg+reg addressing is allowed. This heuristic is taken from // the implementation of LSR. return !BaseGV && BaseOffset == 0 && Scale <= 1; } int getScalingFactorCost(Type *Ty, GlobalValue *BaseGV, int64_t BaseOffset, - bool HasBaseReg, int64_t Scale) const { + bool HasBaseReg, int64_t Scale) const override { // Guess that all legal addressing mode are free. if(isLegalAddressingMode(Ty, BaseGV, BaseOffset, HasBaseReg, Scale)) return 0; return -1; } - - bool isTruncateFree(Type *Ty1, Type *Ty2) const { + bool isTruncateFree(Type *Ty1, Type *Ty2) const override { return false; } - bool isTypeLegal(Type *Ty) const { + bool isTypeLegal(Type *Ty) const override { return false; } - unsigned getJumpBufAlignment() const { + unsigned getJumpBufAlignment() const override { return 0; } - unsigned getJumpBufSize() const { + unsigned getJumpBufSize() const override { return 0; } - bool shouldBuildLookupTables() const { + bool shouldBuildLookupTables() const override { return true; } - PopcntSupportKind getPopcntSupport(unsigned IntTyWidthInBit) const { + PopcntSupportKind + getPopcntSupport(unsigned IntTyWidthInBit) const override { return PSK_Software; } - unsigned getIntImmCost(const APInt &Imm, Type *Ty) const { - return 1; + bool haveFastSqrt(Type *Ty) const override { + return false; + } + + unsigned getIntImmCost(const APInt &Imm, Type *Ty) const override { + return TCC_Basic; + } + + unsigned getIntImmCost(unsigned Opcode, unsigned Idx, const APInt &Imm, + Type *Ty) const override { + return TCC_Free; } - unsigned getNumberOfRegisters(bool Vector) const { + unsigned getIntImmCost(Intrinsic::ID IID, unsigned Idx, const APInt &Imm, + Type *Ty) const override { + return TCC_Free; + } + + unsigned getNumberOfRegisters(bool Vector) const override { return 8; } - unsigned getRegisterBitWidth(bool Vector) const { + unsigned getRegisterBitWidth(bool Vector) const override { return 32; } - unsigned getMaximumUnrollFactor() const { + unsigned getMaximumUnrollFactor() const override { return 1; } unsigned getArithmeticInstrCost(unsigned Opcode, Type *Ty, OperandValueKind, - OperandValueKind) const { + OperandValueKind) const override { return 1; } - unsigned getShuffleCost(ShuffleKind Kind, Type *Tp, - int Index = 0, Type *SubTp = 0) const { + unsigned getShuffleCost(ShuffleKind Kind, Type *Ty, + int Index = 0, Type *SubTp = nullptr) const override { return 1; } unsigned getCastInstrCost(unsigned Opcode, Type *Dst, - Type *Src) const { + Type *Src) const override { return 1; } - unsigned getCFInstrCost(unsigned Opcode) const { + unsigned getCFInstrCost(unsigned Opcode) const override { return 1; } unsigned getCmpSelInstrCost(unsigned Opcode, Type *ValTy, - Type *CondTy = 0) const { + Type *CondTy = nullptr) const override { return 1; } unsigned getVectorInstrCost(unsigned Opcode, Type *Val, - unsigned Index = -1) const { + unsigned Index = -1) const override { return 1; } - unsigned getMemoryOpCost(unsigned Opcode, Type *Src, - unsigned Alignment, - unsigned AddressSpace) const { + unsigned getMemoryOpCost(unsigned Opcode, Type *Src, unsigned Alignment, + unsigned AddressSpace) const override { return 1; } - unsigned getIntrinsicInstrCost(Intrinsic::ID ID, - Type *RetTy, - ArrayRef Tys) const { + unsigned getIntrinsicInstrCost(Intrinsic::ID ID, Type *RetTy, + ArrayRef Tys) const override { return 1; } - unsigned getNumberOfParts(Type *Tp) const { + unsigned getNumberOfParts(Type *Tp) const override { return 0; } - unsigned getAddressComputationCost(Type *Tp, bool) const { + unsigned getAddressComputationCost(Type *Tp, bool) const override { return 0; } + + unsigned getReductionCost(unsigned, Type *, bool) const override { + return 1; + } }; } // end anonymous namespace