void reset() {
Need = false;
Pointers.clear();
+ Checks.clear();
}
/// Insert a pointer and calculate the start and end SCEVs.
typedef std::pair<const CheckingPtrGroup *, const CheckingPtrGroup *>
PointerCheck;
- /// \brief Groups pointers such that a single memcheck is required
- /// between two different groups. This will clear the CheckingGroups vector
- /// and re-compute it. We will only group dependecies if \p UseDependencies
- /// is true, otherwise we will create a separate group for each pointer.
- void groupChecks(MemoryDepChecker::DepCandidates &DepCands,
- bool UseDependencies);
+ /// \brief Generate the checks and store it. This also performs the grouping
+ /// of pointers to reduce the number of memchecks necessary.
+ void generateChecks(MemoryDepChecker::DepCandidates &DepCands,
+ bool UseDependencies);
- /// Generate the checks and return them.
- ///
- /// \p PtrToPartition contains the partition number for pointers. If passed,
- /// omit checks between pointers belonging to the same partition. Partition
- /// number -1 means that the pointer is used in multiple partitions. In this
- /// case we can't safely omit the check.
- SmallVector<PointerCheck, 4>
- generateChecks(const SmallVectorImpl<int> *PtrPartition = nullptr) const;
+ /// \brief \return the checks that generateChecks created.
+ const SmallVectorImpl<PointerCheck> &getChecks() const { return Checks; }
/// \brief Decide if we need to add a check between two groups of pointers,
/// according to needsChecking.
const SmallVectorImpl<int> *PtrPartition = nullptr) const;
private:
+ /// \brief Groups pointers such that a single memcheck is required
+ /// between two different groups. This will clear the CheckingGroups vector
+ /// and re-compute it. We will only group dependecies if \p UseDependencies
+ /// is true, otherwise we will create a separate group for each pointer.
+ void groupChecks(MemoryDepChecker::DepCandidates &DepCands,
+ bool UseDependencies);
+
+ /// Generate the checks and return them.
+ ///
+ /// \p PtrToPartition contains the partition number for pointers. If passed,
+ /// omit checks between pointers belonging to the same partition. Partition
+ /// number -1 means that the pointer is used in multiple partitions. In this
+ /// case we can't safely omit the check.
+ SmallVector<PointerCheck, 4>
+ generateChecks(const SmallVectorImpl<int> *PtrPartition = nullptr) const;
+
/// Holds a pointer to the ScalarEvolution analysis.
ScalarEvolution *SE;
+
+ /// \brief Set of run-time checks required to establish independence of
+ /// otherwise may-aliasing pointers in the loop.
+ SmallVector<PointerCheck, 4> Checks;
};
/// \brief Drive the analysis of memory accesses in the loop
return Checks;
}
+void RuntimePointerChecking::generateChecks(
+ MemoryDepChecker::DepCandidates &DepCands, bool UseDependencies) {
+ assert(Checks.empty() && "Checks is not empty");
+ groupChecks(DepCands, UseDependencies);
+ Checks = generateChecks();
+}
+
bool RuntimePointerChecking::needsChecking(
const CheckingPtrGroup &M, const CheckingPtrGroup &N,
const SmallVectorImpl<int> *PtrPartition) const {
void RuntimePointerChecking::print(raw_ostream &OS, unsigned Depth) const {
OS.indent(Depth) << "Run-time memory checks:\n";
- printChecks(OS, generateChecks(), Depth);
+ printChecks(OS, Checks, Depth);
OS.indent(Depth) << "Grouped accesses:\n";
for (unsigned I = 0; I < CheckingGroups.size(); ++I) {
}
if (NeedRTCheck && CanDoRT)
- RtCheck.groupChecks(DepCands, IsDepCheckNeeded);
+ RtCheck.generateChecks(DepCands, IsDepCheckNeeded);
DEBUG(dbgs() << "LAA: We need to do " << RtCheck.getNumberOfChecks(nullptr)
<< " pointer comparisons.\n");
if (!PtrRtChecking.Need)
return std::make_pair(nullptr, nullptr);
- return addRuntimeCheck(Loc, PtrRtChecking.generateChecks());
+ return addRuntimeCheck(Loc, PtrRtChecking.getChecks());
}
LoopAccessInfo::LoopAccessInfo(Loop *L, ScalarEvolution *SE,