[LV/LAA] Use PSE to identify stride multiplies which simplify [mostly nfc]
LV/LAA will speculate that (some) strided access patterns have unit stride, and insert runtime checks if required. LV cost models a multiply by such a stride as free. We did this by keeping around the StrideSet structure, just to check if one of the operands were one of the strides we speculated. We can instead just ask PredicatedScalarEvolution if either of the operands are one (after predicates are applied). We get mostly the same result - PSE can prove it in more cases in theory - and simpler code.
This commit is contained in:
parent
dcac993732
commit
7fbfcc653f
@ -616,9 +616,6 @@ public:
|
||||
return SymbolicStrides;
|
||||
}
|
||||
|
||||
/// Pointer has a symbolic stride.
|
||||
bool hasStride(Value *V) const { return StrideSet.count(V); }
|
||||
|
||||
/// Print the information about the memory accesses in the loop.
|
||||
void print(raw_ostream &OS, unsigned Depth = 0) const;
|
||||
|
||||
@ -702,9 +699,6 @@ private:
|
||||
/// If an access has a symbolic strides, this maps the pointer value to
|
||||
/// the stride symbol.
|
||||
DenseMap<Value *, const SCEV *> SymbolicStrides;
|
||||
|
||||
/// Set of symbolic strides values.
|
||||
SmallPtrSet<Value *, 8> StrideSet;
|
||||
};
|
||||
|
||||
Value *stripIntegerCast(Value *V);
|
||||
|
||||
@ -371,8 +371,6 @@ public:
|
||||
return LAI->getDepChecker().getMaxSafeVectorWidthInBits();
|
||||
}
|
||||
|
||||
bool hasStride(Value *V) { return LAI->hasStride(V); }
|
||||
|
||||
/// Returns true if vector representation of the instruction \p I
|
||||
/// requires mask.
|
||||
bool isMaskRequired(const Instruction *I) const {
|
||||
|
||||
@ -2758,7 +2758,6 @@ void LoopAccessInfo::collectStridedAccess(Value *MemAccess) {
|
||||
// SCEVUnknown as we expect.
|
||||
Value *StrideVal = stripIntegerCast(Stride);
|
||||
SymbolicStrides[Ptr] = cast<SCEVUnknown>(PSE->getSCEV(StrideVal));
|
||||
StrideSet.insert(Stride);
|
||||
}
|
||||
|
||||
LoopAccessInfo::LoopAccessInfo(Loop *L, ScalarEvolution *SE,
|
||||
|
||||
@ -6447,11 +6447,6 @@ static const SCEV *getAddressAccessSCEV(
|
||||
return PSE.getSCEV(Ptr);
|
||||
}
|
||||
|
||||
static bool isStrideMul(Instruction *I, LoopVectorizationLegality *Legal) {
|
||||
return Legal->hasStride(I->getOperand(0)) ||
|
||||
Legal->hasStride(I->getOperand(1));
|
||||
}
|
||||
|
||||
InstructionCost
|
||||
LoopVectorizationCostModel::getMemInstScalarizationCost(Instruction *I,
|
||||
ElementCount VF) {
|
||||
@ -7219,8 +7214,12 @@ LoopVectorizationCostModel::getInstructionCost(Instruction *I, ElementCount VF,
|
||||
case Instruction::And:
|
||||
case Instruction::Or:
|
||||
case Instruction::Xor: {
|
||||
// Since we will replace the stride by 1 the multiplication should go away.
|
||||
if (I->getOpcode() == Instruction::Mul && isStrideMul(I, Legal))
|
||||
// If we're speculating on the stride being 1, the multiplication may
|
||||
// fold away. We can generalize this for all operations using the notion
|
||||
// of neutral elements. (TODO)
|
||||
if (I->getOpcode() == Instruction::Mul &&
|
||||
(PSE.getSCEV(I->getOperand(0))->isOne() ||
|
||||
PSE.getSCEV(I->getOperand(1))->isOne()))
|
||||
return 0;
|
||||
|
||||
// Detect reduction patterns
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user