mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-16 12:24:03 +00:00
Loop Vectorizer: Handle pointer stores/loads in getWidestType()
In the loop vectorizer cost model, we used to ignore stores/loads of a pointer type when computing the widest type within a loop. This meant that if we had only stores/loads of pointers in a loop we would return a widest type of 8bits (instead of 32 or 64 bit) and therefore a vector factor that was too big. Now, if we see a consecutive store/load of pointers we use the size of a pointer (from data layout). This problem occured in SingleSource/Benchmarks/Shootout-C++/hash.cpp (reduced test case is the first test in vector_ptr_load_store.ll). radar://13139343 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174377 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -518,8 +518,9 @@ class LoopVectorizationCostModel {
|
||||
public:
|
||||
LoopVectorizationCostModel(Loop *L, ScalarEvolution *SE, LoopInfo *LI,
|
||||
LoopVectorizationLegality *Legal,
|
||||
const TargetTransformInfo &TTI)
|
||||
: TheLoop(L), SE(SE), LI(LI), Legal(Legal), TTI(TTI) {}
|
||||
const TargetTransformInfo &TTI,
|
||||
DataLayout *DL)
|
||||
: TheLoop(L), SE(SE), LI(LI), Legal(Legal), TTI(TTI), DL(DL) {}
|
||||
|
||||
/// Information about vectorization costs
|
||||
struct VectorizationFactor {
|
||||
@ -575,6 +576,10 @@ private:
|
||||
/// the scalar type.
|
||||
static Type* ToVectorTy(Type *Scalar, unsigned VF);
|
||||
|
||||
/// Returns whether the instruction is a load or store and will be a emitted
|
||||
/// as a vector operation.
|
||||
bool isConsecutiveLoadOrStore(Instruction *I);
|
||||
|
||||
/// The loop that we evaluate.
|
||||
Loop *TheLoop;
|
||||
/// Scev analysis.
|
||||
@ -585,6 +590,8 @@ private:
|
||||
LoopVectorizationLegality *Legal;
|
||||
/// Vector target information.
|
||||
const TargetTransformInfo &TTI;
|
||||
/// Target data layout information.
|
||||
DataLayout *DL;
|
||||
};
|
||||
|
||||
/// The LoopVectorize Pass.
|
||||
@ -624,7 +631,7 @@ struct LoopVectorize : public LoopPass {
|
||||
}
|
||||
|
||||
// Use the cost model.
|
||||
LoopVectorizationCostModel CM(L, SE, LI, &LVL, *TTI);
|
||||
LoopVectorizationCostModel CM(L, SE, LI, &LVL, *TTI, DL);
|
||||
|
||||
// Check the function attribues to find out if this function should be
|
||||
// optimized for size.
|
||||
@ -2786,14 +2793,17 @@ unsigned LoopVectorizationCostModel::getWidestType() {
|
||||
continue;
|
||||
|
||||
// Examine the stored values.
|
||||
if (StoreInst *ST = dyn_cast<StoreInst>(it))
|
||||
StoreInst *ST = 0;
|
||||
if ((ST = dyn_cast<StoreInst>(it)))
|
||||
T = ST->getValueOperand()->getType();
|
||||
|
||||
// Ignore stored/loaded pointer types.
|
||||
if (T->isPointerTy())
|
||||
continue;
|
||||
|
||||
MaxWidth = std::max(MaxWidth, T->getScalarSizeInBits());
|
||||
// Ignore loaded pointer types and stored pointer types that are not
|
||||
// consecutive. However, we do want to take consecutive stores/loads of
|
||||
// pointer vectors into account.
|
||||
if (T->isPointerTy() && isConsecutiveLoadOrStore(it))
|
||||
MaxWidth = std::max(MaxWidth, DL->getPointerSizeInBits());
|
||||
else
|
||||
MaxWidth = std::max(MaxWidth, T->getScalarSizeInBits());
|
||||
}
|
||||
}
|
||||
|
||||
@ -3241,4 +3251,16 @@ namespace llvm {
|
||||
}
|
||||
}
|
||||
|
||||
bool LoopVectorizationCostModel::isConsecutiveLoadOrStore(Instruction *Inst) {
|
||||
// Check for a store.
|
||||
StoreInst *ST = dyn_cast<StoreInst>(Inst);
|
||||
if (ST)
|
||||
return Legal->isConsecutivePtr(ST->getPointerOperand()) != 0;
|
||||
|
||||
// Check for a load.
|
||||
LoadInst *LI = dyn_cast<LoadInst>(Inst);
|
||||
if (LI)
|
||||
return Legal->isConsecutivePtr(LI->getPointerOperand()) != 0;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
Reference in New Issue
Block a user