[llvm-dev] [LoopVectorizer] getScalarizationOverhead()
Jonas Paulsson via llvm-dev
llvm-dev at lists.llvm.org
Tue Sep 4 08:43:31 PDT 2018
Hi,
I was looking at the loop vectorizer instruction costs and found that a
vector load that was scalarized was getting the cost of 2 * VF. This was
because it was computing the cost as 1 for each scalar load plus 1 for
each extracted operand. However, that operand was also scalarized, so
there was actually no cost for any operand extraction.
Since this gives a considerable difference for a small loop with high
VFs, I wanted to make a patch that calls
getOperandsScalarizationOverhead() only with non-scalar (vectorized)
operands. So I modified getScalarizationOverhead() per below. However, I
also got the assert "Scalar values are not calculated for VF" when using it.
I wonder if this is just too difficult to implement right now, or if
there is a way to do it? Basically, I think
setCostBasedWideningDecision() would have to be called after
collectLoopScalars(), but it seems there are some dependencies there
that would make this difficult..?
/Jonas
/// Estimate the overhead of scalarizing an instruction. This is a
/// convenience wrapper for the type-based getScalarizationOverhead API.
-static unsigned getScalarizationOverhead(Instruction *I, unsigned VF,
- const TargetTransformInfo &TTI) {
+unsigned LoopVectorizationCostModel::
+getScalarizationOverhead(Instruction *I, unsigned VF,
+ const TargetTransformInfo &TTI) {
if (VF == 1)
return 0;
unsigned Cost = 0;
Type *RetTy = ToVectorTy(I->getType(), VF);
if (!RetTy->isVoidTy() &&
(!isa<LoadInst>(I) ||
!TTI.supportsEfficientVectorElementLoadStore()))
Cost += TTI.getScalarizationOverhead(RetTy, true, false);
- if (CallInst *CI = dyn_cast<CallInst>(I)) {
- SmallVector<const Value *, 4> Operands(CI->arg_operands());
- Cost += TTI.getOperandsScalarizationOverhead(Operands, VF);
- }
+ SmallVector<Value *, 4> Operands;
+ if (CallInst *CI = dyn_cast<CallInst>(I))
+ Operands.assign(CI->op_begin(), CI->op_end());
else if (!isa<StoreInst>(I) ||
- !TTI.supportsEfficientVectorElementLoadStore()) {
- SmallVector<const Value *, 4> Operands(I->operand_values());
- Cost += TTI.getOperandsScalarizationOverhead(Operands, VF);
+ !TTI.supportsEfficientVectorElementLoadStore())
+ Operands.assign(I->value_op_begin(), I->value_op_end());
+ SmallVector<Value *, 4> NonScalarOperands;
+ for (Value *Op : Operands) {
+ if (auto *I = dyn_cast<Instruction>(Op))
+ if (isScalarAfterVectorization(I, VF) ||
isProfitableToScalarize(I, VF))
+ continue;
+ NonScalarOperands.push_back(Op);
}
+ Cost += TTI.getOperandsScalarizationOverhead(NonScalarOperands, VF);
return Cost;
}
More information about the llvm-dev
mailing list