forked from OSchip/llvm-project
[LoopVectorizer] Use TTI.getOperandInfo()
Call getOperandInfo() instead of using (near) duplicated code in LoopVectorizationCostModel::getInstructionCost(). This gets the OperandValueKind and OperandValueProperties values for a Value passed as operand to an arithmetic instruction. getOperandInfo() used to be a static method in TargetTransformInfo.cpp, but is now instead a public member. Review: Florian Hahn https://reviews.llvm.org/D52883 llvm-svn: 343852
This commit is contained in:
parent
faad1b3056
commit
29d80f07ee
|
@ -739,6 +739,10 @@ public:
|
|||
/// and the number of execution units in the CPU.
|
||||
unsigned getMaxInterleaveFactor(unsigned VF) const;
|
||||
|
||||
/// Collect properties of V used in cost analyzis, e.g. OP_PowerOf2.
|
||||
OperandValueKind getOperandInfo(Value *V,
|
||||
OperandValueProperties &OpProps) const;
|
||||
|
||||
/// This is an approximation of reciprocal throughput of a math/logic op.
|
||||
/// A higher cost indicates less expected throughput.
|
||||
/// From Agner Fog's guides, reciprocal throughput is "the average number of
|
||||
|
|
|
@ -384,6 +384,49 @@ unsigned TargetTransformInfo::getMaxInterleaveFactor(unsigned VF) const {
|
|||
return TTIImpl->getMaxInterleaveFactor(VF);
|
||||
}
|
||||
|
||||
TargetTransformInfo::OperandValueKind
|
||||
TargetTransformInfo::getOperandInfo(Value *V,
|
||||
OperandValueProperties &OpProps) const {
|
||||
OperandValueKind OpInfo = OK_AnyValue;
|
||||
OpProps = OP_None;
|
||||
|
||||
if (auto *CI = dyn_cast<ConstantInt>(V)) {
|
||||
if (CI->getValue().isPowerOf2())
|
||||
OpProps = OP_PowerOf2;
|
||||
return OK_UniformConstantValue;
|
||||
}
|
||||
|
||||
const Value *Splat = getSplatValue(V);
|
||||
|
||||
// Check for a splat of a constant or for a non uniform vector of constants
|
||||
// and check if the constant(s) are all powers of two.
|
||||
if (isa<ConstantVector>(V) || isa<ConstantDataVector>(V)) {
|
||||
OpInfo = OK_NonUniformConstantValue;
|
||||
if (Splat) {
|
||||
OpInfo = OK_UniformConstantValue;
|
||||
if (auto *CI = dyn_cast<ConstantInt>(Splat))
|
||||
if (CI->getValue().isPowerOf2())
|
||||
OpProps = OP_PowerOf2;
|
||||
} else if (auto *CDS = dyn_cast<ConstantDataSequential>(V)) {
|
||||
OpProps = OP_PowerOf2;
|
||||
for (unsigned I = 0, E = CDS->getNumElements(); I != E; ++I) {
|
||||
if (auto *CI = dyn_cast<ConstantInt>(CDS->getElementAsConstant(I)))
|
||||
if (CI->getValue().isPowerOf2())
|
||||
continue;
|
||||
OpProps = OP_None;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for a splat of a uniform value. This is not loop aware, so return
|
||||
// true only for the obviously uniform cases (argument, globalvalue)
|
||||
if (Splat && (isa<Argument>(Splat) || isa<GlobalValue>(Splat)))
|
||||
OpInfo = OK_UniformValue;
|
||||
|
||||
return OpInfo;
|
||||
}
|
||||
|
||||
int TargetTransformInfo::getArithmeticInstrCost(
|
||||
unsigned Opcode, Type *Ty, OperandValueKind Opd1Info,
|
||||
OperandValueKind Opd2Info, OperandValueProperties Opd1PropInfo,
|
||||
|
@ -630,49 +673,6 @@ int TargetTransformInfo::getInstructionLatency(const Instruction *I) const {
|
|||
return TTIImpl->getInstructionLatency(I);
|
||||
}
|
||||
|
||||
static TargetTransformInfo::OperandValueKind
|
||||
getOperandInfo(Value *V, TargetTransformInfo::OperandValueProperties &OpProps) {
|
||||
TargetTransformInfo::OperandValueKind OpInfo =
|
||||
TargetTransformInfo::OK_AnyValue;
|
||||
OpProps = TargetTransformInfo::OP_None;
|
||||
|
||||
if (auto *CI = dyn_cast<ConstantInt>(V)) {
|
||||
if (CI->getValue().isPowerOf2())
|
||||
OpProps = TargetTransformInfo::OP_PowerOf2;
|
||||
return TargetTransformInfo::OK_UniformConstantValue;
|
||||
}
|
||||
|
||||
const Value *Splat = getSplatValue(V);
|
||||
|
||||
// Check for a splat of a constant or for a non uniform vector of constants
|
||||
// and check if the constant(s) are all powers of two.
|
||||
if (isa<ConstantVector>(V) || isa<ConstantDataVector>(V)) {
|
||||
OpInfo = TargetTransformInfo::OK_NonUniformConstantValue;
|
||||
if (Splat) {
|
||||
OpInfo = TargetTransformInfo::OK_UniformConstantValue;
|
||||
if (auto *CI = dyn_cast<ConstantInt>(Splat))
|
||||
if (CI->getValue().isPowerOf2())
|
||||
OpProps = TargetTransformInfo::OP_PowerOf2;
|
||||
} else if (auto *CDS = dyn_cast<ConstantDataSequential>(V)) {
|
||||
OpProps = TargetTransformInfo::OP_PowerOf2;
|
||||
for (unsigned I = 0, E = CDS->getNumElements(); I != E; ++I) {
|
||||
if (auto *CI = dyn_cast<ConstantInt>(CDS->getElementAsConstant(I)))
|
||||
if (CI->getValue().isPowerOf2())
|
||||
continue;
|
||||
OpProps = TargetTransformInfo::OP_None;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Check for a splat of a uniform value. This is not loop aware, so return
|
||||
// true only for the obviously uniform cases (argument, globalvalue)
|
||||
if (Splat && (isa<Argument>(Splat) || isa<GlobalValue>(Splat)))
|
||||
OpInfo = TargetTransformInfo::OK_UniformValue;
|
||||
|
||||
return OpInfo;
|
||||
}
|
||||
|
||||
static bool matchPairwiseShuffleMask(ShuffleVectorInst *SI, bool IsLeft,
|
||||
unsigned Level) {
|
||||
// We don't need a shuffle if we just want to have element 0 in position 0 of
|
||||
|
|
|
@ -5669,38 +5669,18 @@ unsigned LoopVectorizationCostModel::getInstructionCost(Instruction *I,
|
|||
return 0;
|
||||
// Certain instructions can be cheaper to vectorize if they have a constant
|
||||
// second vector operand. One example of this are shifts on x86.
|
||||
TargetTransformInfo::OperandValueKind Op1VK =
|
||||
TargetTransformInfo::OK_AnyValue;
|
||||
TargetTransformInfo::OperandValueKind Op2VK =
|
||||
TargetTransformInfo::OK_AnyValue;
|
||||
TargetTransformInfo::OperandValueProperties Op1VP =
|
||||
TargetTransformInfo::OP_None;
|
||||
TargetTransformInfo::OperandValueProperties Op2VP =
|
||||
TargetTransformInfo::OP_None;
|
||||
Value *Op2 = I->getOperand(1);
|
||||
|
||||
// Check for a splat or for a non uniform vector of constants.
|
||||
if (isa<ConstantInt>(Op2)) {
|
||||
ConstantInt *CInt = cast<ConstantInt>(Op2);
|
||||
if (CInt && CInt->getValue().isPowerOf2())
|
||||
Op2VP = TargetTransformInfo::OP_PowerOf2;
|
||||
Op2VK = TargetTransformInfo::OK_UniformConstantValue;
|
||||
} else if (isa<ConstantVector>(Op2) || isa<ConstantDataVector>(Op2)) {
|
||||
Op2VK = TargetTransformInfo::OK_NonUniformConstantValue;
|
||||
Constant *SplatValue = cast<Constant>(Op2)->getSplatValue();
|
||||
if (SplatValue) {
|
||||
ConstantInt *CInt = dyn_cast<ConstantInt>(SplatValue);
|
||||
if (CInt && CInt->getValue().isPowerOf2())
|
||||
Op2VP = TargetTransformInfo::OP_PowerOf2;
|
||||
Op2VK = TargetTransformInfo::OK_UniformConstantValue;
|
||||
}
|
||||
} else if (Legal->isUniform(Op2)) {
|
||||
TargetTransformInfo::OperandValueProperties Op2VP;
|
||||
TargetTransformInfo::OperandValueKind Op2VK =
|
||||
TTI.getOperandInfo(Op2, Op2VP);
|
||||
if (Op2VK == TargetTransformInfo::OK_AnyValue && Legal->isUniform(Op2))
|
||||
Op2VK = TargetTransformInfo::OK_UniformValue;
|
||||
}
|
||||
|
||||
SmallVector<const Value *, 4> Operands(I->operand_values());
|
||||
unsigned N = isScalarAfterVectorization(I, VF) ? VF : 1;
|
||||
return N * TTI.getArithmeticInstrCost(I->getOpcode(), VectorTy, Op1VK,
|
||||
Op2VK, Op1VP, Op2VP, Operands);
|
||||
return N * TTI.getArithmeticInstrCost(
|
||||
I->getOpcode(), VectorTy, TargetTransformInfo::OK_AnyValue,
|
||||
Op2VK, TargetTransformInfo::OP_None, Op2VP, Operands);
|
||||
}
|
||||
case Instruction::Select: {
|
||||
SelectInst *SI = cast<SelectInst>(I);
|
||||
|
|
Loading…
Reference in New Issue