Index: llvm/include/llvm/Analysis/TargetTransformInfo.h =================================================================== --- llvm/include/llvm/Analysis/TargetTransformInfo.h +++ llvm/include/llvm/Analysis/TargetTransformInfo.h @@ -202,43 +202,14 @@ TCC_Expensive = 4 ///< The cost of a 'div' instruction on x86. }; - /// Estimate the cost of a specific operation when lowered. - /// - /// Note that this is designed to work on an arbitrary synthetic opcode, and - /// thus work for hypothetical queries before an instruction has even been - /// formed. However, this does *not* work for GEPs, and must not be called - /// for a GEP instruction. Instead, use the dedicated getGEPCost interface as - /// analyzing a GEP's cost required more information. - /// - /// Typically only the result type is required, and the operand type can be - /// omitted. However, if the opcode is one of the cast instructions, the - /// operand type is required. - /// - /// The returned cost is defined in terms of \c TargetCostConstants, see its - /// comments for a detailed explanation of the cost values. - int getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy = nullptr) const; - /// Estimate the cost of a GEP operation when lowered. - /// - /// The contract for this function is the same as \c getOperationCost except - /// that it supports an interface that provides extra information specific to - /// the GEP operation. int getGEPCost(Type *PointeeType, const Value *Ptr, ArrayRef Operands) const; /// Estimate the cost of a EXT operation when lowered. - /// - /// The contract for this function is the same as \c getOperationCost except - /// that it supports an interface that provides extra information specific to - /// the EXT operation. int getExtCost(const Instruction *I, const Value *Src) const; /// Estimate the cost of a function call when lowered. - /// - /// The contract for this is the same as \c getOperationCost except that it - /// supports an interface that provides extra information specific to call - /// instructions. - /// /// This is the most basic query for estimating call cost: it only knows the /// function type and (potentially) the number of arguments at the call site. /// The latter is only interesting for varargs function types. @@ -307,9 +278,9 @@ /// Estimate the cost of a given IR user when lowered. /// /// This can estimate the cost of either a ConstantExpr or Instruction when - /// lowered. It has two primary advantages over the \c getOperationCost and - /// \c getGEPCost above, and one significant disadvantage: it can only be - /// used when the IR construct has already been formed. + /// lowered. It has two primary advantages over the \c getGEPCost above, + /// and one significant disadvantage: it can only be used when the IR + /// construct has already been formed. /// /// The advantages are that it can inspect the SSA use graph to reason more /// accurately about the cost. For example, all-constant-GEPs can often be @@ -1190,7 +1161,6 @@ public: virtual ~Concept() = 0; virtual const DataLayout &getDataLayout() const = 0; - virtual int getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy) = 0; virtual int getGEPCost(Type *PointeeType, const Value *Ptr, ArrayRef Operands) = 0; virtual int getExtCost(const Instruction *I, const Value *Src) = 0; @@ -1428,9 +1398,6 @@ return Impl.getDataLayout(); } - int getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy) override { - return Impl.getOperationCost(Opcode, Ty, OpTy); - } int getGEPCost(Type *PointeeType, const Value *Ptr, ArrayRef Operands) override { return Impl.getGEPCost(PointeeType, Ptr, Operands); Index: llvm/include/llvm/Analysis/TargetTransformInfoImpl.h =================================================================== --- llvm/include/llvm/Analysis/TargetTransformInfoImpl.h +++ llvm/include/llvm/Analysis/TargetTransformInfoImpl.h @@ -44,69 +44,6 @@ const DataLayout &getDataLayout() const { return DL; } - unsigned getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy) { - switch (Opcode) { - default: - // By default, just classify everything as 'basic'. - return TTI::TCC_Basic; - - case Instruction::GetElementPtr: - llvm_unreachable("Use getGEPCost for GEP operations!"); - - case Instruction::BitCast: - assert(OpTy && "Cast instructions must provide the operand type"); - if (Ty == OpTy || (Ty->isPointerTy() && OpTy->isPointerTy())) - // Identity and pointer-to-pointer casts are free. - return TTI::TCC_Free; - - // Otherwise, the default basic cost is used. - return TTI::TCC_Basic; - - case Instruction::Freeze: - // Freeze operation is free because it should be lowered into a register - // use without any register copy in assembly code. - return TTI::TCC_Free; - - case Instruction::FDiv: - case Instruction::FRem: - case Instruction::SDiv: - case Instruction::SRem: - case Instruction::UDiv: - case Instruction::URem: - return TTI::TCC_Expensive; - - case Instruction::IntToPtr: { - // 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. - unsigned OpSize = OpTy->getScalarSizeInBits(); - if (DL.isLegalInteger(OpSize) && - OpSize <= DL.getPointerTypeSizeInBits(Ty)) - return TTI::TCC_Free; - - // Otherwise it's not a no-op. - return TTI::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. - unsigned DestSize = Ty->getScalarSizeInBits(); - if (DL.isLegalInteger(DestSize) && - DestSize >= DL.getPointerTypeSizeInBits(OpTy)) - return TTI::TCC_Free; - - // Otherwise it's not a no-op. - return TTI::TCC_Basic; - } - case Instruction::Trunc: - // trunc to a native type is free (assuming the target has compare and - // shift-right of the same width). - if (DL.isLegalInteger(DL.getTypeSizeInBits(Ty))) - return TTI::TCC_Free; - - return TTI::TCC_Basic; - } - } - int getGEPCost(Type *PointeeType, const Value *Ptr, ArrayRef Operands) { // In the basic model, we just assume that all-constant GEPs will be folded @@ -882,34 +819,72 @@ if (A->isStaticAlloca()) return TTI::TCC_Free; - if (const GEPOperator *GEP = dyn_cast(U)) { - return static_cast(this)->getGEPCost(GEP->getSourceElementType(), - GEP->getPointerOperand(), - Operands.drop_front()); - } + auto TargetTTI = static_cast(this); + if (const GEPOperator *GEP = dyn_cast(U)) + return TargetTTI->getGEPCost(GEP->getSourceElementType(), + GEP->getPointerOperand(), + Operands.drop_front()); if (auto CS = ImmutableCallSite(U)) { const Function *F = CS.getCalledFunction(); if (!F) { // Just use the called value type. Type *FTy = CS.getCalledValue()->getType()->getPointerElementType(); - return static_cast(this) - ->getCallCost(cast(FTy), CS.arg_size(), U); + return TargetTTI->getCallCost(cast(FTy), + CS.arg_size(), U); } SmallVector Arguments(CS.arg_begin(), CS.arg_end()); - return static_cast(this)->getCallCost(F, Arguments, U); + return TargetTTI->getCallCost(F, Arguments, U); } - if (isa(U) || isa(U) || isa(U)) - // The old behaviour of generally treating extensions of icmp to be free - // has been removed. A target that needs it should override getUserCost(). - return static_cast(this)->getExtCost(cast(U), - Operands.back()); - - return static_cast(this)->getOperationCost( - Operator::getOpcode(U), U->getType(), - U->getNumOperands() == 1 ? U->getOperand(0)->getType() : nullptr); + Type *Ty = U->getType(); + Type *OpTy = + U->getNumOperands() == 1 ? U->getOperand(0)->getType() : nullptr; + switch (Operator::getOpcode(U)) { + default: + break; + case Instruction::Freeze: + // Freeze operation is free because it should be lowered into a register + // use without any register copy in assembly code. + return TTI::TCC_Free; + case Instruction::FDiv: + case Instruction::FRem: + case Instruction::SDiv: + case Instruction::SRem: + case Instruction::UDiv: + case Instruction::URem: + return TTI::TCC_Expensive; + case Instruction::IntToPtr: { + unsigned OpSize = OpTy->getScalarSizeInBits(); + if (DL.isLegalInteger(OpSize) && + OpSize <= DL.getPointerTypeSizeInBits(Ty)) + return TTI::TCC_Free; + return TargetTTI->getCastInstrCost(Operator::getOpcode(U), Ty, OpTy, + dyn_cast(U)); + } + case Instruction::PtrToInt: { + unsigned DestSize = Ty->getScalarSizeInBits(); + if (DL.isLegalInteger(DestSize) && + DestSize >= DL.getPointerTypeSizeInBits(OpTy)) + return TTI::TCC_Free; + return TargetTTI->getCastInstrCost(Operator::getOpcode(U), Ty, OpTy, + dyn_cast(U)); + } + case Instruction::SExt: + case Instruction::ZExt: + if (TargetTTI->getExtCost(cast(U), Operands.back()) == + TargetTransformInfo::TCC_Free) + return 0; + LLVM_FALLTHROUGH; + case Instruction::BitCast: + case Instruction::FPExt: + case Instruction::Trunc: + return TargetTTI->getCastInstrCost(Operator::getOpcode(U), Ty, OpTy, + cast(U)); + } + // By default, just classify everything as 'basic'. + return TTI::TCC_Basic; } int getInstructionLatency(const Instruction *I) { Index: llvm/include/llvm/CodeGen/BasicTTIImpl.h =================================================================== --- llvm/include/llvm/CodeGen/BasicTTIImpl.h +++ llvm/include/llvm/CodeGen/BasicTTIImpl.h @@ -413,29 +413,6 @@ return TargetTransformInfo::TCC_Expensive; } - unsigned getOperationCost(unsigned Opcode, Type *Ty, Type *OpTy) { - const TargetLoweringBase *TLI = getTLI(); - switch (Opcode) { - default: break; - case Instruction::Trunc: - if (TLI->isTruncateFree(OpTy, Ty)) - return TargetTransformInfo::TCC_Free; - return TargetTransformInfo::TCC_Basic; - case Instruction::ZExt: - if (TLI->isZExtFree(OpTy, Ty)) - return TargetTransformInfo::TCC_Free; - return TargetTransformInfo::TCC_Basic; - - case Instruction::AddrSpaceCast: - if (TLI->isFreeAddrSpaceCast(OpTy->getPointerAddressSpace(), - Ty->getPointerAddressSpace())) - return TargetTransformInfo::TCC_Free; - return TargetTransformInfo::TCC_Basic; - } - - return BaseT::getOperationCost(Opcode, Ty, OpTy); - } - unsigned getInliningThresholdMultiplier() { return 1; } int getInlinerVectorBonusPercent() { return 150; } @@ -704,28 +681,30 @@ std::pair SrcLT = TLI->getTypeLegalizationCost(DL, Src); std::pair DstLT = TLI->getTypeLegalizationCost(DL, Dst); - // Check for NOOP conversions. - if (SrcLT.first == DstLT.first && - SrcLT.second.getSizeInBits() == DstLT.second.getSizeInBits()) { - - // Bitcast between types that are legalized to the same type are free. - if (Opcode == Instruction::BitCast || Opcode == Instruction::Trunc) + unsigned DstSize = DstLT.second.getSizeInBits(); + unsigned SrcSize = SrcLT.second.getSizeInBits(); + switch (Opcode) { + default: + break; + case Instruction::Trunc: + if (TLI->isTruncateFree(SrcLT.second, DstLT.second)) + return 0; + LLVM_FALLTHROUGH; + case Instruction::BitCast: + if (SrcLT.first == DstLT.first && SrcSize == DstSize) + return 0; + break; + case Instruction::ZExt: + if (TLI->isZExtFree(SrcLT.second, DstLT.second)) + return 0; + break; + case Instruction::AddrSpaceCast: + if (TLI->isFreeAddrSpaceCast(Src->getPointerAddressSpace(), + Dst->getPointerAddressSpace())) return 0; + break; } - if (Opcode == Instruction::Trunc && - TLI->isTruncateFree(SrcLT.second, DstLT.second)) - return 0; - - if (Opcode == Instruction::ZExt && - TLI->isZExtFree(SrcLT.second, DstLT.second)) - return 0; - - if (Opcode == Instruction::AddrSpaceCast && - TLI->isFreeAddrSpaceCast(Src->getPointerAddressSpace(), - Dst->getPointerAddressSpace())) - return 0; - // If this is a zext/sext of a load, return 0 if the corresponding // extending load exists on target. if ((Opcode == Instruction::ZExt || Opcode == Instruction::SExt) && Index: llvm/lib/Analysis/TargetTransformInfo.cpp =================================================================== --- llvm/lib/Analysis/TargetTransformInfo.cpp +++ llvm/lib/Analysis/TargetTransformInfo.cpp @@ -146,13 +146,6 @@ return *this; } -int TargetTransformInfo::getOperationCost(unsigned Opcode, Type *Ty, - Type *OpTy) const { - int Cost = TTIImpl->getOperationCost(Opcode, Ty, OpTy); - assert(Cost >= 0 && "TTI should not produce negative costs!"); - return Cost; -} - int TargetTransformInfo::getCallCost(FunctionType *FTy, int NumArgs, const User *U) const { int Cost = TTIImpl->getCallCost(FTy, NumArgs, U); Index: llvm/test/Analysis/CostModel/SystemZ/ext-of-icmp-cost.ll =================================================================== --- llvm/test/Analysis/CostModel/SystemZ/ext-of-icmp-cost.ll +++ llvm/test/Analysis/CostModel/SystemZ/ext-of-icmp-cost.ll @@ -7,7 +7,7 @@ define i64 @fun1(i64 %v) { ; CHECK-LABEL: 'fun1' ; CHECK: Cost Model: Found an estimated cost of 1 for instruction: %cmp = icmp eq i64 %v, 0 -; CHECK: Cost Model: Found an estimated cost of 1 for instruction: %z = zext i1 %cmp to i64 +; CHECK: Cost Model: Found an estimated cost of 2 for instruction: %z = zext i1 %cmp to i64 ; CHECK: Cost Model: Found an estimated cost of 1 for instruction: ret i64 %z %cmp = icmp eq i64 %v, 0 %z = zext i1 %cmp to i64 @@ -17,7 +17,7 @@ define i64 @fun2(i64 %v) { ; CHECK-LABEL: 'fun2' ; CHECK: Cost Model: Found an estimated cost of 1 for instruction: %cmp = icmp eq i64 %v, 0 -; CHECK: Cost Model: Found an estimated cost of 1 for instruction: %z = sext i1 %cmp to i64 +; CHECK: Cost Model: Found an estimated cost of 2 for instruction: %z = sext i1 %cmp to i64 ; CHECK: Cost Model: Found an estimated cost of 1 for instruction: ret i64 %z %cmp = icmp eq i64 %v, 0 %z = sext i1 %cmp to i64 @@ -46,7 +46,7 @@ define i64 @fun5(i1 %v) { ; CHECK-LABEL: 'fun5' -; CHECK: Cost Model: Found an estimated cost of 1 for instruction: %z = zext i1 %v to i64 +; CHECK: Cost Model: Found an estimated cost of 2 for instruction: %z = zext i1 %v to i64 ; CHECK: Cost Model: Found an estimated cost of 1 for instruction: ret i64 %z %z = zext i1 %v to i64 ret i64 %z