Skip to content
This repository was archived by the owner on Feb 5, 2019. It is now read-only.

Commit 00b675d

Browse files
committed
[LAA] Introduce RuntimePointerChecking::PointerInfo, NFC
Turn this structure-of-arrays (i.e. the various pointer attributes) into array-of-structures. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@242219 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 944e082 commit 00b675d

File tree

3 files changed

+67
-54
lines changed

3 files changed

+67
-54
lines changed

include/llvm/Analysis/LoopAccessAnalysis.h

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -295,18 +295,37 @@ class MemoryDepChecker {
295295
/// This struct holds information about the memory runtime legality check that
296296
/// a group of pointers do not overlap.
297297
struct RuntimePointerChecking {
298+
struct PointerInfo {
299+
/// Holds the pointer value that we need to check.
300+
TrackingVH<Value> PointerValue;
301+
/// Holds the pointer value at the beginning of the loop.
302+
const SCEV *Start;
303+
/// Holds the pointer value at the end of the loop.
304+
const SCEV *End;
305+
/// Holds the information if this pointer is used for writing to memory.
306+
bool IsWritePtr;
307+
/// Holds the id of the set of pointers that could be dependent because of a
308+
/// shared underlying object.
309+
unsigned DependencySetId;
310+
/// Holds the id of the disjoint alias set to which this pointer belongs.
311+
unsigned AliasSetId;
312+
/// SCEV for the access.
313+
const SCEV *Expr;
314+
315+
PointerInfo(Value *PointerValue, const SCEV *Start, const SCEV *End,
316+
bool IsWritePtr, unsigned DependencySetId, unsigned AliasSetId,
317+
const SCEV *Expr)
318+
: PointerValue(PointerValue), Start(Start), End(End),
319+
IsWritePtr(IsWritePtr), DependencySetId(DependencySetId),
320+
AliasSetId(AliasSetId), Expr(Expr) {}
321+
};
322+
298323
RuntimePointerChecking(ScalarEvolution *SE) : Need(false), SE(SE) {}
299324

300325
/// Reset the state of the pointer runtime information.
301326
void reset() {
302327
Need = false;
303328
Pointers.clear();
304-
Starts.clear();
305-
Ends.clear();
306-
IsWritePtr.clear();
307-
DependencySetId.clear();
308-
AliasSetId.clear();
309-
Exprs.clear();
310329
}
311330

312331
/// Insert a pointer and calculate the start and end SCEVs.
@@ -322,8 +341,8 @@ struct RuntimePointerChecking {
322341
/// \brief Create a new pointer checking group containing a single
323342
/// pointer, with index \p Index in RtCheck.
324343
CheckingPtrGroup(unsigned Index, RuntimePointerChecking &RtCheck)
325-
: RtCheck(RtCheck), High(RtCheck.Ends[Index]),
326-
Low(RtCheck.Starts[Index]) {
344+
: RtCheck(RtCheck), High(RtCheck.Pointers[Index].End),
345+
Low(RtCheck.Pointers[Index].Start) {
327346
Members.push_back(Index);
328347
}
329348

@@ -387,23 +406,13 @@ struct RuntimePointerChecking {
387406

388407
/// This flag indicates if we need to add the runtime check.
389408
bool Need;
390-
/// Holds the pointers that we need to check.
391-
SmallVector<TrackingVH<Value>, 2> Pointers;
392-
/// Holds the pointer value at the beginning of the loop.
393-
SmallVector<const SCEV *, 2> Starts;
394-
/// Holds the pointer value at the end of the loop.
395-
SmallVector<const SCEV *, 2> Ends;
396-
/// Holds the information if this pointer is used for writing to memory.
397-
SmallVector<bool, 2> IsWritePtr;
398-
/// Holds the id of the set of pointers that could be dependent because of a
399-
/// shared underlying object.
400-
SmallVector<unsigned, 2> DependencySetId;
401-
/// Holds the id of the disjoint alias set to which this pointer belongs.
402-
SmallVector<unsigned, 2> AliasSetId;
403-
/// Holds at position i the SCEV for the access i
404-
SmallVector<const SCEV *, 2> Exprs;
409+
410+
/// Information about the pointers that may require checking.
411+
SmallVector<PointerInfo, 2> Pointers;
412+
405413
/// Holds a partitioning of pointers into "check groups".
406414
SmallVector<CheckingPtrGroup, 2> CheckingGroups;
415+
407416
/// Holds a pointer to the ScalarEvolution analysis.
408417
ScalarEvolution *SE;
409418
};

lib/Analysis/LoopAccessAnalysis.cpp

Lines changed: 33 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -128,13 +128,8 @@ void RuntimePointerChecking::insert(Loop *Lp, Value *Ptr, bool WritePtr,
128128
assert(AR && "Invalid addrec expression");
129129
const SCEV *Ex = SE->getBackedgeTakenCount(Lp);
130130
const SCEV *ScEnd = AR->evaluateAtIteration(Ex, *SE);
131-
Pointers.push_back(Ptr);
132-
Starts.push_back(AR->getStart());
133-
Ends.push_back(ScEnd);
134-
IsWritePtr.push_back(WritePtr);
135-
DependencySetId.push_back(DepSetId);
136-
AliasSetId.push_back(ASId);
137-
Exprs.push_back(Sc);
131+
Pointers.emplace_back(Ptr, AR->getStart(), ScEnd, WritePtr, DepSetId, ASId,
132+
Sc);
138133
}
139134

140135
bool RuntimePointerChecking::needsChecking(
@@ -162,24 +157,27 @@ static const SCEV *getMinFromExprs(const SCEV *I, const SCEV *J,
162157
}
163158

164159
bool RuntimePointerChecking::CheckingPtrGroup::addPointer(unsigned Index) {
160+
const SCEV *Start = RtCheck.Pointers[Index].Start;
161+
const SCEV *End = RtCheck.Pointers[Index].End;
162+
165163
// Compare the starts and ends with the known minimum and maximum
166164
// of this set. We need to know how we compare against the min/max
167165
// of the set in order to be able to emit memchecks.
168-
const SCEV *Min0 = getMinFromExprs(RtCheck.Starts[Index], Low, RtCheck.SE);
166+
const SCEV *Min0 = getMinFromExprs(Start, Low, RtCheck.SE);
169167
if (!Min0)
170168
return false;
171169

172-
const SCEV *Min1 = getMinFromExprs(RtCheck.Ends[Index], High, RtCheck.SE);
170+
const SCEV *Min1 = getMinFromExprs(End, High, RtCheck.SE);
173171
if (!Min1)
174172
return false;
175173

176174
// Update the low bound expression if we've found a new min value.
177-
if (Min0 == RtCheck.Starts[Index])
178-
Low = RtCheck.Starts[Index];
175+
if (Min0 == Start)
176+
Low = Start;
179177

180178
// Update the high bound expression if we've found a new max value.
181-
if (Min1 != RtCheck.Ends[Index])
182-
High = RtCheck.Ends[Index];
179+
if (Min1 != End)
180+
High = End;
183181

184182
Members.push_back(Index);
185183
return true;
@@ -217,8 +215,8 @@ void RuntimePointerChecking::groupChecks(
217215
unsigned TotalComparisons = 0;
218216

219217
DenseMap<Value *, unsigned> PositionMap;
220-
for (unsigned Pointer = 0; Pointer < Pointers.size(); ++Pointer)
221-
PositionMap[Pointers[Pointer]] = Pointer;
218+
for (unsigned Index = 0; Index < Pointers.size(); ++Index)
219+
PositionMap[Pointers[Index].PointerValue] = Index;
222220

223221
// We need to keep track of what pointers we've already seen so we
224222
// don't process them twice.
@@ -233,7 +231,8 @@ void RuntimePointerChecking::groupChecks(
233231
if (Seen.count(I))
234232
continue;
235233

236-
MemoryDepChecker::MemAccessInfo Access(Pointers[I], IsWritePtr[I]);
234+
MemoryDepChecker::MemAccessInfo Access(Pointers[I].PointerValue,
235+
Pointers[I].IsWritePtr);
237236

238237
SmallVector<CheckingPtrGroup, 2> Groups;
239238
auto LeaderI = DepCands.findValue(DepCands.getLeaderValue(Access));
@@ -283,16 +282,19 @@ void RuntimePointerChecking::groupChecks(
283282

284283
bool RuntimePointerChecking::needsChecking(
285284
unsigned I, unsigned J, const SmallVectorImpl<int> *PtrPartition) const {
285+
const PointerInfo &PointerI = Pointers[I];
286+
const PointerInfo &PointerJ = Pointers[J];
287+
286288
// No need to check if two readonly pointers intersect.
287-
if (!IsWritePtr[I] && !IsWritePtr[J])
289+
if (!PointerI.IsWritePtr && !PointerJ.IsWritePtr)
288290
return false;
289291

290292
// Only need to check pointers between two different dependency sets.
291-
if (DependencySetId[I] == DependencySetId[J])
293+
if (PointerI.DependencySetId == PointerJ.DependencySetId)
292294
return false;
293295

294296
// Only need to check pointers in the same alias set.
295-
if (AliasSetId[I] != AliasSetId[J])
297+
if (PointerI.AliasSetId != PointerJ.AliasSetId)
296298
return false;
297299

298300
// If PtrPartition is set omit checks between pointers of the same partition.
@@ -319,8 +321,8 @@ void RuntimePointerChecking::print(
319321
OS.indent(Depth + 2) << "Comparing group " << I << ":\n";
320322

321323
for (unsigned K = 0; K < CheckingGroups[I].Members.size(); ++K) {
322-
OS.indent(Depth + 2) << *Pointers[CheckingGroups[I].Members[K]]
323-
<< "\n";
324+
OS.indent(Depth + 2)
325+
<< *Pointers[CheckingGroups[I].Members[K]].PointerValue << "\n";
324326
if (PtrPartition)
325327
OS << " (Partition: "
326328
<< (*PtrPartition)[CheckingGroups[I].Members[K]] << ")"
@@ -330,8 +332,8 @@ void RuntimePointerChecking::print(
330332
OS.indent(Depth + 2) << "Against group " << J << ":\n";
331333

332334
for (unsigned K = 0; K < CheckingGroups[J].Members.size(); ++K) {
333-
OS.indent(Depth + 2) << *Pointers[CheckingGroups[J].Members[K]]
334-
<< "\n";
335+
OS.indent(Depth + 2)
336+
<< *Pointers[CheckingGroups[J].Members[K]].PointerValue << "\n";
335337
if (PtrPartition)
336338
OS << " (Partition: "
337339
<< (*PtrPartition)[CheckingGroups[J].Members[K]] << ")"
@@ -345,7 +347,8 @@ void RuntimePointerChecking::print(
345347
OS.indent(Depth + 4) << "(Low: " << *CheckingGroups[I].Low
346348
<< " High: " << *CheckingGroups[I].High << ")\n";
347349
for (unsigned J = 0; J < CheckingGroups[I].Members.size(); ++J) {
348-
OS.indent(Depth + 6) << "Member: " << *Exprs[CheckingGroups[I].Members[J]]
350+
OS.indent(Depth + 6) << "Member: "
351+
<< *Pointers[CheckingGroups[I].Members[J]].Expr
349352
<< "\n";
350353
}
351354
}
@@ -575,14 +578,15 @@ bool AccessAnalysis::canCheckPtrAtRT(RuntimePointerChecking &RtCheck,
575578
for (unsigned i = 0; i < NumPointers; ++i) {
576579
for (unsigned j = i + 1; j < NumPointers; ++j) {
577580
// Only need to check pointers between two different dependency sets.
578-
if (RtCheck.DependencySetId[i] == RtCheck.DependencySetId[j])
581+
if (RtCheck.Pointers[i].DependencySetId ==
582+
RtCheck.Pointers[j].DependencySetId)
579583
continue;
580584
// Only need to check pointers in the same alias set.
581-
if (RtCheck.AliasSetId[i] != RtCheck.AliasSetId[j])
585+
if (RtCheck.Pointers[i].AliasSetId != RtCheck.Pointers[j].AliasSetId)
582586
continue;
583587

584-
Value *PtrI = RtCheck.Pointers[i];
585-
Value *PtrJ = RtCheck.Pointers[j];
588+
Value *PtrI = RtCheck.Pointers[i].PointerValue;
589+
Value *PtrJ = RtCheck.Pointers[j].PointerValue;
586590

587591
unsigned ASi = PtrI->getType()->getPointerAddressSpace();
588592
unsigned ASj = PtrJ->getType()->getPointerAddressSpace();
@@ -1577,7 +1581,7 @@ std::pair<Instruction *, Instruction *> LoopAccessInfo::addRuntimeCheck(
15771581
for (unsigned i = 0; i < PtrRtChecking.CheckingGroups.size(); ++i) {
15781582
const RuntimePointerChecking::CheckingPtrGroup &CG =
15791583
PtrRtChecking.CheckingGroups[i];
1580-
Value *Ptr = PtrRtChecking.Pointers[CG.Members[0]];
1584+
Value *Ptr = PtrRtChecking.Pointers[CG.Members[0]].PointerValue;
15811585
const SCEV *Sc = SE->getSCEV(Ptr);
15821586

15831587
if (SE->isLoopInvariant(Sc, TheLoop)) {

lib/Transforms/Scalar/LoopDistribute.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -437,9 +437,9 @@ class InstPartitionContainer {
437437
unsigned N = RtPtrCheck->Pointers.size();
438438
SmallVector<int, 8> PtrToPartitions(N);
439439
for (unsigned I = 0; I < N; ++I) {
440-
Value *Ptr = RtPtrCheck->Pointers[I];
440+
Value *Ptr = RtPtrCheck->Pointers[I].PointerValue;
441441
auto Instructions =
442-
LAI.getInstructionsForAccess(Ptr, RtPtrCheck->IsWritePtr[I]);
442+
LAI.getInstructionsForAccess(Ptr, RtPtrCheck->Pointers[I].IsWritePtr);
443443

444444
int &Partition = PtrToPartitions[I];
445445
// First set it to uninitialized.

0 commit comments

Comments
 (0)