@@ -122,7 +122,7 @@ void AllocationLivenessAnalyzer::getAnalysisUsage(llvm::AnalysisUsage &AU) const
122
122
getAdditionalAnalysisUsage (AU);
123
123
}
124
124
125
- void AllocationLivenessAnalyzer::implementCallSpecificBehavior (CallInst *callI, Use* use, SmallVector<Use *> &worklist,
125
+ void AllocationLivenessAnalyzer::implementCallSpecificBehavior (CallInst *callI, Use * use, SmallVector<Use *> &worklist,
126
126
SetVector<Instruction *> &allUsers,
127
127
SetVector<Instruction *> &lifetimeLeakingUsers) {
128
128
@@ -137,8 +137,8 @@ void AllocationLivenessAnalyzer::implementCallSpecificBehavior(CallInst *callI,
137
137
}
138
138
139
139
template <typename range>
140
- static inline void doWorkLoop (SmallVector <BasicBlock *> &worklist, DenseSet <BasicBlock *> &bbSet1,
141
- DenseSet <BasicBlock *> &bbSet2, std::function<range(BasicBlock *)> iterate,
140
+ static inline void doWorkLoop (SmallVectorImpl <BasicBlock *> &worklist, SetVector <BasicBlock *> &bbSet1,
141
+ SetVector <BasicBlock *> &bbSet2, std::function<range(BasicBlock *)> iterate,
142
142
std::function<bool(BasicBlock *)> continueCondition) {
143
143
// perform data flow analysis
144
144
while (!worklist.empty ()) {
@@ -152,7 +152,7 @@ static inline void doWorkLoop(SmallVector<BasicBlock *> &worklist, DenseSet<Basi
152
152
for (auto *pbb : iterate(currbb)) {
153
153
addToSet1 = true ;
154
154
155
- bool inserted = bbSet2.insert (pbb). second ;
155
+ bool inserted = bbSet2.insert (pbb);
156
156
157
157
if (inserted)
158
158
worklist.push_back (pbb);
@@ -211,13 +211,13 @@ AllocationLivenessAnalyzer::LivenessData::LivenessData(Instruction *allocationIn
211
211
212
212
// add terminators to users, so we can later add them to our lifetimeEnd vector
213
213
auto leakingbbOnlyIn = leakingbbIn;
214
- set_subtract (leakingbbOnlyIn, leakingbbOut);
214
+ leakingbbOnlyIn. set_subtract (leakingbbOut);
215
215
216
216
for (auto *bb : leakingbbOnlyIn)
217
217
usersOfAllocation.insert (bb->getTerminator ());
218
218
219
- set_union (bbIn, leakingbbIn);
220
- set_union (bbOut, leakingbbOut);
219
+ bbIn. set_union (leakingbbIn);
220
+ bbOut. set_union (leakingbbOut);
221
221
}
222
222
223
223
// if the lifetime escapes any loop, we should make sure all the loops blocks are included
@@ -260,7 +260,7 @@ AllocationLivenessAnalyzer::LivenessData::LivenessData(Instruction *allocationIn
260
260
// substract the inflow blocks from the outflow blocks to find the block which starts the lifetime - there should be
261
261
// only one!
262
262
auto bbOutOnly = bbOut;
263
- set_subtract (bbOutOnly, bbIn);
263
+ bbOutOnly. set_subtract (bbIn);
264
264
265
265
IGC_ASSERT_MESSAGE (bbOutOnly.size () == 1 , " Multiple lifetime start blocks?" );
266
266
@@ -287,7 +287,7 @@ AllocationLivenessAnalyzer::LivenessData::LivenessData(Instruction *allocationIn
287
287
} else {
288
288
// find all blocks where lifetime flows in, but doesnt flow out
289
289
auto bbOnlyIn = bbIn;
290
- set_subtract (bbOnlyIn, bbOut);
290
+ bbOnlyIn. set_subtract (bbOut);
291
291
292
292
for (auto *bb : bbOnlyIn) {
293
293
for (auto &I : llvm::reverse (*bb)) {
@@ -316,11 +316,19 @@ AllocationLivenessAnalyzer::LivenessData::LivenessData(Instruction *allocationIn
316
316
}
317
317
318
318
bool AllocationLivenessAnalyzer::LivenessData::OverlapsWith (const LivenessData &LD) const {
319
+
320
+ // SetVector doesn't support set_intersect...
321
+ // set_intersect(overlapIn, LD.bbIn);
322
+ // so we emulate it via formula A ^ B = A - (A - B)
319
323
auto overlapIn = bbIn;
320
- set_intersect (overlapIn, LD.bbIn );
324
+ auto AminusBIn = bbIn;
325
+ AminusBIn.set_subtract (LD.bbIn );
326
+ overlapIn.set_subtract (AminusBIn);
321
327
322
328
auto overlapOut = bbOut;
323
- set_intersect (overlapOut, LD.bbOut );
329
+ auto AminusBOut = bbOut;
330
+ AminusBOut.set_subtract (LD.bbOut );
331
+ overlapOut.set_subtract (AminusBOut);
324
332
325
333
// check if both lifetimes flow out or in the same block, this means overlap
326
334
if (!overlapIn.empty () || !overlapOut.empty ())
@@ -364,7 +372,10 @@ bool AllocationLivenessAnalyzer::LivenessData::OverlapsWith(const LivenessData &
364
372
}
365
373
366
374
bool AllocationLivenessAnalyzer::LivenessData::ContainsInstruction (const llvm::Instruction &I) const {
367
- auto *bb = I.getParent ();
375
+
376
+ // SetVector::contains seems to have underimplemented const-correctness
377
+ // the const_cast is not needed for DenseSet based implementation, but then we introduce nondetereministic behavior when iterating
378
+ auto *bb = const_cast <BasicBlock *>(I.getParent ());
368
379
369
380
// if the LD is contained in a single block, bbIn and bbOut are going to be empty.
370
381
// TODO: maybe LivenessData deserves a flag to mark livenesses contained in a single block?
@@ -417,8 +428,7 @@ static bool tryFindPointerOrigin(GetElementPtrInst *Ptr, SmallVectorImpl<Instruc
417
428
return tryFindPointerOriginImpl (Ptr->getPointerOperand (), origins, cache);
418
429
}
419
430
420
- static bool tryFindPointerOrigin (SelectInst *Ptr, SmallVectorImpl<Instruction *> &origins,
421
- DenseSet<Value *> &cache) {
431
+ static bool tryFindPointerOrigin (SelectInst *Ptr, SmallVectorImpl<Instruction *> &origins, DenseSet<Value *> &cache) {
422
432
return tryFindPointerOriginImpl (Ptr->getTrueValue (), origins, cache) &&
423
433
tryFindPointerOriginImpl (Ptr->getFalseValue (), origins, cache);
424
434
}
0 commit comments