Commit ee959ddc authored by Sam Parker's avatar Sam Parker
Browse files

[TTI] Remove getOperationCost

This API call has been used recently with, a very valid, expectation
that it would do something useful but it doesn't actually query any
backend information. So, remove this method and merge its
functionality into getUserCost. As well as that, also use
getCastInstrCost to get a proper cost from the backend for the
concerned instructions though we only currently return the answer if
it's considered free. The default implementation now also checks
int/ptr conversions too, as well as truncs and bitcasts.

Differential Revision: https://reviews.llvm.org/D76124
parent e90fb82f
......@@ -201,35 +201,11 @@ public:
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<const Value *> 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;
/// \returns A value by which our inlining threshold should be multiplied.
......@@ -277,15 +253,7 @@ public:
/// 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.
///
/// 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
/// folded into a load or other instruction, but if they are used in some
/// other context they may not be folded. This routine can distinguish such
/// cases.
/// lowered.
///
/// \p Operands is a list of operands which can be a result of transformations
/// of the current operands. The number of the operands on the list must equal
......@@ -1187,7 +1155,6 @@ class TargetTransformInfo::Concept {
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<const Value *> Operands) = 0;
virtual int getExtCost(const Instruction *I, const Value *Src) = 0;
......@@ -1429,9 +1396,6 @@ public:
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<const Value *> Operands) override {
return Impl.getGEPCost(PointeeType, Ptr, Operands);
......
......@@ -44,69 +44,6 @@ public:
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<const Value *> Operands) {
// In the basic model, we just assume that all-constant GEPs will be folded
......@@ -445,6 +382,35 @@ public:
unsigned getCastInstrCost(unsigned Opcode, Type *Dst, Type *Src,
const Instruction *I) {
switch (Opcode) {
default:
break;
case Instruction::IntToPtr: {
unsigned SrcSize = Src->getScalarSizeInBits();
if (DL.isLegalInteger(SrcSize) &&
SrcSize <= DL.getPointerTypeSizeInBits(Dst))
return 0;
break;
}
case Instruction::PtrToInt: {
unsigned DstSize = Dst->getScalarSizeInBits();
if (DL.isLegalInteger(DstSize) &&
DstSize >= DL.getPointerTypeSizeInBits(Src))
return 0;
break;
}
case Instruction::BitCast:
if (Dst == Src || (Dst->isPointerTy() && Src->isPointerTy()))
// Identity and pointer-to-pointer casts are free.
return 0;
break;
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(Dst)))
return 0;
break;
}
return 1;
}
......@@ -828,27 +794,8 @@ public:
}
unsigned getUserCost(const User *U, ArrayRef<const Value *> Operands) {
if (isa<PHINode>(U))
return TTI::TCC_Free; // Model all PHI nodes as free.
if (isa<ExtractValueInst>(U))
return TTI::TCC_Free; // Model all ExtractValue nodes as free.
if (isa<FreezeInst>(U))
return TTI::TCC_Free; // Model all Freeze nodes as free.
// Static alloca doesn't generate target instructions.
if (auto *A = dyn_cast<AllocaInst>(U))
if (A->isStaticAlloca())
return TTI::TCC_Free;
auto *TargetTTI = static_cast<T *>(this);
if (const GEPOperator *GEP = dyn_cast<GEPOperator>(U))
return TargetTTI->getGEPCost(GEP->getSourceElementType(),
GEP->getPointerOperand(),
Operands.drop_front());
if (auto CS = ImmutableCallSite(U)) {
const Function *F = CS.getCalledFunction();
if (F) {
......@@ -867,14 +814,55 @@ public:
return TTI::TCC_Basic * (CS.arg_size() + 1);
}
if (isa<SExtInst>(U) || isa<ZExtInst>(U) || isa<FPExtInst>(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 TargetTTI->getExtCost(cast<Instruction>(U), Operands.back());
return TargetTTI->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;
unsigned Opcode = Operator::getOpcode(U);
auto *I = dyn_cast<Instruction>(U);
switch (Opcode) {
default:
break;
case Instruction::PHI:
case Instruction::ExtractValue:
case Instruction::Freeze:
return TTI::TCC_Free;
case Instruction::Alloca:
if (cast<AllocaInst>(U)->isStaticAlloca())
return TTI::TCC_Free;
break;
case Instruction::GetElementPtr: {
const GEPOperator *GEP = cast<GEPOperator>(U);
return TargetTTI->getGEPCost(GEP->getSourceElementType(),
GEP->getPointerOperand(),
Operands.drop_front());
}
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:
case Instruction::PtrToInt:
case Instruction::Trunc:
if (getCastInstrCost(Opcode, Ty, OpTy, I) == TTI::TCC_Free ||
TargetTTI->getCastInstrCost(Opcode, Ty, OpTy, I) == TTI::TCC_Free)
return TTI::TCC_Free;
break;
case Instruction::BitCast:
if (getCastInstrCost(Opcode, Ty, OpTy, I) == TTI::TCC_Free)
return TTI::TCC_Free;
break;
case Instruction::FPExt:
case Instruction::SExt:
case Instruction::ZExt:
if (TargetTTI->getExtCost(I, Operands.back()) == TTI::TCC_Free)
return TTI::TCC_Free;
break;
}
// By default, just classify everything as 'basic'.
return TTI::TCC_Basic;
}
int getInstructionLatency(const Instruction *I) {
......
......@@ -412,29 +412,6 @@ public:
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; }
......
......@@ -146,13 +146,6 @@ TargetTransformInfo &TargetTransformInfo::operator=(TargetTransformInfo &&RHS) {
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;
}
unsigned TargetTransformInfo::getInliningThresholdMultiplier() const {
return TTIImpl->getInliningThresholdMultiplier();
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment