LLVM: include/llvm/Transforms/Utils/SSAUpdaterImpl.h Source File (original) (raw)
32private:
33 UpdaterT *Updater;
34
36 using BlkT = typename Traits::BlkT;
37 using ValT = typename Traits::ValT;
38 using PhiT = typename Traits::PhiT;
39
40
41
42
43 class BBInfo {
44 public:
45
46 BlkT *BB;
47
48
49 ValT AvailableVal;
50
51
52 BBInfo *DefBB;
53
54
55 int BlkNum = 0;
56
57
58 BBInfo *IDom = nullptr;
59
60
61 unsigned NumPreds = 0;
62
63
64 BBInfo **Preds = nullptr;
65
66
67 PhiT *PHITag = nullptr;
68
69 BBInfo(BlkT *ThisBB, ValT V)
70 : BB(ThisBB), AvailableVal(V), DefBB(V ? this : nullptr) {}
71 };
72
74
75 AvailableValsTy *AvailableVals;
76
78
81
82 BBMapTy BBMap;
84
85public:
88 Updater(U), AvailableVals(A), InsertedPHIs(Ins) {}
89
90
91
92
93
97
98
99 if (BlockList.size() == 0) {
100 ValT V = Traits::GetPoisonVal(BB, Updater);
101 (*AvailableVals)[BB] = V;
102 return V;
103 }
104
108
109 return BBMap[BB]->DefBB->AvailableVal;
110 }
111
112
113
114
115
119
120 BBInfo *Info = new (Allocator) BBInfo(BB, 0);
121 BBMap[BB] = Info;
123
124
125
126
128 while (!WorkList.empty()) {
131 Traits::FindPredecessorBlocks(Info->BB, &Preds);
132 Info->NumPreds = Preds.size();
133 if (Info->NumPreds == 0)
134 Info->Preds = nullptr;
135 else
136 Info->Preds = static_cast<BBInfo **>(Allocator.Allocate(
137 Info->NumPreds * sizeof(BBInfo *), alignof(BBInfo *)));
138
139 for (unsigned p = 0; p != Info->NumPreds; ++p) {
140 BlkT *Pred = Preds[p];
141
142 BBInfo *&BBMapBucket = BBMap[Pred];
143 if (BBMapBucket) {
144 Info->Preds[p] = BBMapBucket;
145 continue;
146 }
147
148
149 ValT PredVal = AvailableVals->lookup(Pred);
150 BBInfo *PredInfo = new (Allocator) BBInfo(Pred, PredVal);
151 BBMapBucket = PredInfo;
152 Info->Preds[p] = PredInfo;
153
154 if (PredInfo->AvailableVal) {
156 continue;
157 }
159 }
160 }
161
162
163
164
165 BBInfo *PseudoEntry = new (Allocator) BBInfo(nullptr, 0);
166 unsigned BlkNum = 1;
167
168
169 while (!RootList.empty()) {
171 Info->IDom = PseudoEntry;
172 Info->BlkNum = -1;
174 }
175
176 while (!WorkList.empty()) {
178
179 if (Info->BlkNum == -2) {
180
181 Info->BlkNum = BlkNum++;
182
183 if (->AvailableVal)
186 continue;
187 }
188
189
190
191
192
193 Info->BlkNum = -2;
194
195
196 for (typename Traits::BlkSucc_iterator SI =
197 Traits::BlkSucc_begin(Info->BB),
198 E = Traits::BlkSucc_end(Info->BB); SI != E; ++SI) {
199 BBInfo *SuccInfo = BBMap[*SI];
200 if (!SuccInfo || SuccInfo->BlkNum)
201 continue;
202 SuccInfo->BlkNum = -1;
204 }
205 }
206 PseudoEntry->BlkNum = BlkNum;
207 return PseudoEntry;
208 }
209
210
211
212
213
215 while (Blk1 != Blk2) {
216 while (Blk1->BlkNum < Blk2->BlkNum) {
217 Blk1 = Blk1->IDom;
218 if (!Blk1)
219 return Blk2;
220 }
221 while (Blk2->BlkNum < Blk1->BlkNum) {
222 Blk2 = Blk2->IDom;
223 if (!Blk2)
224 return Blk1;
225 }
226 }
227 return Blk1;
228 }
229
230
231
232
233
234
235
236
237
238
239
240 void FindDominators(BlockListTy *BlockList, BBInfo *PseudoEntry) {
242 do {
244
246 E = BlockList->rend(); I != E; ++I) {
248 BBInfo *NewIDom = nullptr;
249
250
251 for (unsigned p = 0; p != Info->NumPreds; ++p) {
252 BBInfo *Pred = Info->Preds[p];
253
254
255 if (Pred->BlkNum == 0) {
256 Pred->AvailableVal = Traits::GetPoisonVal(Pred->BB, Updater);
257 (*AvailableVals)[Pred->BB] = Pred->AvailableVal;
258 Pred->DefBB = Pred;
259 Pred->BlkNum = PseudoEntry->BlkNum;
260 PseudoEntry->BlkNum++;
261 }
262
263 if (!NewIDom)
264 NewIDom = Pred;
265 else
267 }
268
269
270 if (NewIDom && NewIDom != Info->IDom) {
271 Info->IDom = NewIDom;
273 }
274 }
276 }
277
278
279
280
281
283 for (; Pred != IDom; Pred = Pred->IDom) {
284 if (Pred->DefBB == Pred)
285 return true;
286 }
287 return false;
288 }
289
290
291
292
293
296 do {
298
300 E = BlockList->rend(); I != E; ++I) {
302
303
305 continue;
306
307
308 BBInfo *NewDefBB = Info->IDom->DefBB;
309 for (unsigned p = 0; p != Info->NumPreds; ++p) {
311
312 NewDefBB = Info;
313 break;
314 }
315 }
316
317
318 if (NewDefBB != Info->DefBB) {
319 Info->DefBB = NewDefBB;
321 }
322 }
324 }
325
326
327
328
330 if (->NumPreds)
331 return false;
332 ValT Singular = Info->Preds[0]->DefBB->AvailableVal;
333 if (!Singular)
334 return false;
335 for (unsigned Idx = 1; Idx < Info->NumPreds; ++Idx) {
336 ValT PredVal = Info->Preds[Idx]->DefBB->AvailableVal;
337 if (!PredVal || Singular != PredVal)
338 return false;
339 }
340
341 (*AvailableVals)[Info->BB] = Singular;
342 assert(BBMap[Info->BB] == Info && "Info missed in BBMap?");
343 Info->AvailableVal = Singular;
344 Info->DefBB = Info->Preds[0]->DefBB;
345 return true;
346 }
347
348
349
350
351
352
354
355
356
358 E = BlockList->end(); I != E; ++I) {
360
362 continue;
363
364
366 continue;
367
368
370 if (Info->AvailableVal)
371 continue;
372
373 ValT PHI = Traits::CreateEmptyPHI(Info->BB, Info->NumPreds, Updater);
375 (*AvailableVals)[Info->BB] = PHI;
376 }
377
378
379
381 E = BlockList->rend(); I != E; ++I) {
383
385
386
387 (*AvailableVals)[Info->BB] = Info->DefBB->AvailableVal;
388 continue;
389 }
390
391
392 PhiT *PHI = Traits::ValueIsNewPHI(Info->AvailableVal, Updater);
393 if ()
394 continue;
395
396
397 for (unsigned p = 0; p != Info->NumPreds; ++p) {
398 BBInfo *PredInfo = Info->Preds[p];
399 BlkT *Pred = PredInfo->BB;
400
401 if (PredInfo->DefBB != PredInfo)
402 PredInfo = PredInfo->DefBB;
403 Traits::AddPHIOperand(PHI, PredInfo->AvailableVal, Pred);
404 }
405
407
408
409 if (InsertedPHIs) InsertedPHIs->push_back(PHI);
410 }
411 }
412
413
414
417 for (auto &SomePHI : BB->phis()) {
420 break;
421 }
422 }
423 }
424
425
426
428
429
431 for (BBInfo *TaggedBlock : TaggedBlocks)
432 TaggedBlock->PHITag = nullptr;
433 TaggedBlocks.clear();
434 });
435
438
439
440 BBInfo *PHIBlock = BBMap[PHI->getParent()];
441 PHIBlock->PHITag = PHI;
442 TaggedBlocks.push_back(PHIBlock);
443
444 while (!WorkList.empty()) {
445 PHI = WorkList.pop_back_val();
446
447
448 for (typename Traits::PHI_iterator I = Traits::PHI_begin(PHI),
449 E = Traits::PHI_end(PHI); I != E; ++I) {
450 ValT IncomingVal = I.getIncomingValue();
451 BBInfo *PredInfo = BBMap[I.getIncomingBlock()];
452
453 if (PredInfo->DefBB != PredInfo)
454 PredInfo = PredInfo->DefBB;
455
456
457 if (PredInfo->AvailableVal) {
458 if (IncomingVal == PredInfo->AvailableVal)
459 continue;
460 return false;
461 }
462
463
464 PhiT *IncomingPHIVal = Traits::ValueIsPHI(IncomingVal, Updater);
465 if (!IncomingPHIVal || IncomingPHIVal->getParent() != PredInfo->BB)
466 return false;
467
468
469 if (PredInfo->PHITag) {
470 if (IncomingPHIVal == PredInfo->PHITag)
471 continue;
472 return false;
473 }
474 PredInfo->PHITag = IncomingPHIVal;
475 TaggedBlocks.push_back(PredInfo);
476
477 WorkList.push_back(IncomingPHIVal);
478 }
479 }
480
482 return true;
483 }
484
485
486
488 for (BBInfo *Block : TaggedBlocks) {
490 assert(PHI && "PHITag didn't set?");
491 BlkT *BB = PHI->getParent();
492 ValT PHIVal = Traits::GetPHIValue(PHI);
493 (*AvailableVals)[BB] = PHIVal;
494 BBMap[BB]->AvailableVal = PHIVal;
495 }
496 }
497};