From: Jonas Paulsson Date: Fri, 5 Oct 2018 14:34:04 +0000 (+0000) Subject: [LoopVectorizer] Use TTI.getOperandInfo() X-Git-Tag: llvmorg-8.0.0-rc1~7164 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=29d80f07eeb4f5b609e54f5443166b709a3c6ba6;p=platform%2Fupstream%2Fllvm.git [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 --- diff --git a/llvm/include/llvm/Analysis/TargetTransformInfo.h b/llvm/include/llvm/Analysis/TargetTransformInfo.h index 9cf6ff9..18b5a5c 100644 --- a/llvm/include/llvm/Analysis/TargetTransformInfo.h +++ b/llvm/include/llvm/Analysis/TargetTransformInfo.h @@ -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 diff --git a/llvm/lib/Analysis/TargetTransformInfo.cpp b/llvm/lib/Analysis/TargetTransformInfo.cpp index 7233a86..4ad48e3 100644 --- a/llvm/lib/Analysis/TargetTransformInfo.cpp +++ b/llvm/lib/Analysis/TargetTransformInfo.cpp @@ -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(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(V) || isa(V)) { + OpInfo = OK_NonUniformConstantValue; + if (Splat) { + OpInfo = OK_UniformConstantValue; + if (auto *CI = dyn_cast(Splat)) + if (CI->getValue().isPowerOf2()) + OpProps = OP_PowerOf2; + } else if (auto *CDS = dyn_cast(V)) { + OpProps = OP_PowerOf2; + for (unsigned I = 0, E = CDS->getNumElements(); I != E; ++I) { + if (auto *CI = dyn_cast(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(Splat) || isa(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(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(V) || isa(V)) { - OpInfo = TargetTransformInfo::OK_NonUniformConstantValue; - if (Splat) { - OpInfo = TargetTransformInfo::OK_UniformConstantValue; - if (auto *CI = dyn_cast(Splat)) - if (CI->getValue().isPowerOf2()) - OpProps = TargetTransformInfo::OP_PowerOf2; - } else if (auto *CDS = dyn_cast(V)) { - OpProps = TargetTransformInfo::OP_PowerOf2; - for (unsigned I = 0, E = CDS->getNumElements(); I != E; ++I) { - if (auto *CI = dyn_cast(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(Splat) || isa(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 diff --git a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp index 1f2aa70..07f4d81 100644 --- a/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp +++ b/llvm/lib/Transforms/Vectorize/LoopVectorize.cpp @@ -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(Op2)) { - ConstantInt *CInt = cast(Op2); - if (CInt && CInt->getValue().isPowerOf2()) - Op2VP = TargetTransformInfo::OP_PowerOf2; - Op2VK = TargetTransformInfo::OK_UniformConstantValue; - } else if (isa(Op2) || isa(Op2)) { - Op2VK = TargetTransformInfo::OK_NonUniformConstantValue; - Constant *SplatValue = cast(Op2)->getSplatValue(); - if (SplatValue) { - ConstantInt *CInt = dyn_cast(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 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(I);