[LoopVectorize] Split out RuntimePointerCheck from LoopVectorizationLegality

RuntimePointerCheck will be used through LoopAccessAnalysis in
LoopVectorizationLegality.  Later in the patchset it will become a local class
of LoopAccessAnalysis.

NFC.  This is part of the patchset that splits out the memory dependence logic
from LoopVectorizationLegality into a new class LoopAccessAnalysis.
LoopAccessAnalysis will be used by the new Loop Distribution pass.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@227747 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Adam Nemet 2015-02-01 16:55:56 +00:00
parent 5b61b8f53c
commit 2659684fe3

View File

@ -558,6 +558,45 @@ static void propagateMetadata(SmallVectorImpl<Value *> &To, const Instruction *F
propagateMetadata(I, From); propagateMetadata(I, From);
} }
namespace {
/// This struct holds information about the memory runtime legality
/// check that a group of pointers do not overlap.
struct RuntimePointerCheck {
RuntimePointerCheck() : Need(false) {}
/// Reset the state of the pointer runtime information.
void reset() {
Need = false;
Pointers.clear();
Starts.clear();
Ends.clear();
IsWritePtr.clear();
DependencySetId.clear();
AliasSetId.clear();
}
/// Insert a pointer and calculate the start and end SCEVs.
void insert(ScalarEvolution *SE, Loop *Lp, Value *Ptr, bool WritePtr,
unsigned DepSetId, unsigned ASId, ValueToValueMap &Strides);
/// This flag indicates if we need to add the runtime check.
bool Need;
/// Holds the pointers that we need to check.
SmallVector<TrackingVH<Value>, 2> Pointers;
/// Holds the pointer value at the beginning of the loop.
SmallVector<const SCEV*, 2> Starts;
/// Holds the pointer value at the end of the loop.
SmallVector<const SCEV*, 2> Ends;
/// Holds the information if this pointer is used for writing to memory.
SmallVector<bool, 2> IsWritePtr;
/// Holds the id of the set of pointers that could be dependent because of a
/// shared underlying object.
SmallVector<unsigned, 2> DependencySetId;
/// Holds the id of the disjoint alias set to which this pointer belongs.
SmallVector<unsigned, 2> AliasSetId;
};
} // end anonymous namespace
/// LoopVectorizationLegality checks if it is legal to vectorize a loop, and /// LoopVectorizationLegality checks if it is legal to vectorize a loop, and
/// to what vectorization factor. /// to what vectorization factor.
/// This class does not look at the profitability of vectorization, only the /// This class does not look at the profitability of vectorization, only the
@ -655,43 +694,6 @@ public:
MinMaxReductionKind MinMaxKind; MinMaxReductionKind MinMaxKind;
}; };
/// This struct holds information about the memory runtime legality
/// check that a group of pointers do not overlap.
struct RuntimePointerCheck {
RuntimePointerCheck() : Need(false) {}
/// Reset the state of the pointer runtime information.
void reset() {
Need = false;
Pointers.clear();
Starts.clear();
Ends.clear();
IsWritePtr.clear();
DependencySetId.clear();
AliasSetId.clear();
}
/// Insert a pointer and calculate the start and end SCEVs.
void insert(ScalarEvolution *SE, Loop *Lp, Value *Ptr, bool WritePtr,
unsigned DepSetId, unsigned ASId, ValueToValueMap &Strides);
/// This flag indicates if we need to add the runtime check.
bool Need;
/// Holds the pointers that we need to check.
SmallVector<TrackingVH<Value>, 2> Pointers;
/// Holds the pointer value at the beginning of the loop.
SmallVector<const SCEV*, 2> Starts;
/// Holds the pointer value at the end of the loop.
SmallVector<const SCEV*, 2> Ends;
/// Holds the information if this pointer is used for writing to memory.
SmallVector<bool, 2> IsWritePtr;
/// Holds the id of the set of pointers that could be dependent because of a
/// shared underlying object.
SmallVector<unsigned, 2> DependencySetId;
/// Holds the id of the disjoint alias set to which this pointer belongs.
SmallVector<unsigned, 2> AliasSetId;
};
/// A struct for saving information about induction variables. /// A struct for saving information about induction variables.
struct InductionInfo { struct InductionInfo {
InductionInfo(Value *Start, InductionKind K, ConstantInt *Step) InductionInfo(Value *Start, InductionKind K, ConstantInt *Step)
@ -1608,9 +1610,9 @@ static const SCEV *replaceSymbolicStrideSCEV(ScalarEvolution *SE,
return SE->getSCEV(Ptr); return SE->getSCEV(Ptr);
} }
void LoopVectorizationLegality::RuntimePointerCheck::insert( void RuntimePointerCheck::insert(ScalarEvolution *SE, Loop *Lp, Value *Ptr,
ScalarEvolution *SE, Loop *Lp, Value *Ptr, bool WritePtr, unsigned DepSetId, bool WritePtr, unsigned DepSetId,
unsigned ASId, ValueToValueMap &Strides) { unsigned ASId, ValueToValueMap &Strides) {
// Get the stride replaced scev. // Get the stride replaced scev.
const SCEV *Sc = replaceSymbolicStrideSCEV(SE, Strides, Ptr); const SCEV *Sc = replaceSymbolicStrideSCEV(SE, Strides, Ptr);
const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(Sc); const SCEVAddRecExpr *AR = dyn_cast<SCEVAddRecExpr>(Sc);
@ -2132,8 +2134,7 @@ InnerLoopVectorizer::addStrideCheck(Instruction *Loc) {
std::pair<Instruction *, Instruction *> std::pair<Instruction *, Instruction *>
InnerLoopVectorizer::addRuntimeCheck(Instruction *Loc) { InnerLoopVectorizer::addRuntimeCheck(Instruction *Loc) {
LoopVectorizationLegality::RuntimePointerCheck *PtrRtCheck = RuntimePointerCheck *PtrRtCheck = Legal->getRuntimePointerCheck();
Legal->getRuntimePointerCheck();
Instruction *tnullptr = nullptr; Instruction *tnullptr = nullptr;
if (!PtrRtCheck->Need) if (!PtrRtCheck->Need)
@ -4066,9 +4067,9 @@ public:
/// \brief Check whether we can check the pointers at runtime for /// \brief Check whether we can check the pointers at runtime for
/// non-intersection. /// non-intersection.
bool canCheckPtrAtRT(LoopVectorizationLegality::RuntimePointerCheck &RtCheck, bool canCheckPtrAtRT(RuntimePointerCheck &RtCheck, unsigned &NumComparisons,
unsigned &NumComparisons, ScalarEvolution *SE, ScalarEvolution *SE, Loop *TheLoop,
Loop *TheLoop, ValueToValueMap &Strides, ValueToValueMap &Strides,
bool ShouldCheckStride = false); bool ShouldCheckStride = false);
/// \brief Goes over all memory accesses, checks whether a RT check is needed /// \brief Goes over all memory accesses, checks whether a RT check is needed
@ -4133,7 +4134,7 @@ static int isStridedPtr(ScalarEvolution *SE, const DataLayout *DL, Value *Ptr,
const Loop *Lp, ValueToValueMap &StridesMap); const Loop *Lp, ValueToValueMap &StridesMap);
bool AccessAnalysis::canCheckPtrAtRT( bool AccessAnalysis::canCheckPtrAtRT(
LoopVectorizationLegality::RuntimePointerCheck &RtCheck, RuntimePointerCheck &RtCheck,
unsigned &NumComparisons, ScalarEvolution *SE, Loop *TheLoop, unsigned &NumComparisons, ScalarEvolution *SE, Loop *TheLoop,
ValueToValueMap &StridesMap, bool ShouldCheckStride) { ValueToValueMap &StridesMap, bool ShouldCheckStride) {
// Find pointers with computable bounds. We are going to use this information // Find pointers with computable bounds. We are going to use this information