|
16 | 16 | #ifndef LLVM_ANALYSIS_GENERICDOMTREEUPDATERIMPL_H
|
17 | 17 | #define LLVM_ANALYSIS_GENERICDOMTREEUPDATERIMPL_H
|
18 | 18 |
|
| 19 | +#include "llvm/ADT/SmallBitVector.h" |
19 | 20 | #include "llvm/Analysis/GenericDomTreeUpdater.h"
|
20 | 21 | #include "llvm/Support/Debug.h"
|
21 | 22 | #include "llvm/Support/raw_ostream.h"
|
@@ -61,6 +62,9 @@ void GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>::applyUpdates(
|
61 | 62 | return;
|
62 | 63 |
|
63 | 64 | if (Strategy == UpdateStrategy::Lazy) {
|
| 65 | + if (!CriticalEdgesToSplit.empty()) |
| 66 | + applySplitCriticalEdges(); |
| 67 | + |
64 | 68 | PendUpdates.reserve(PendUpdates.size() + Updates.size());
|
65 | 69 | for (const auto &U : Updates)
|
66 | 70 | if (!isSelfDominance(U))
|
@@ -348,6 +352,123 @@ void GenericDomTreeUpdater<DerivedT, DomTreeT,
|
348 | 352 | PendPDTUpdateIndex -= dropIndex;
|
349 | 353 | }
|
350 | 354 |
|
| 355 | +template <typename DerivedT, typename DomTreeT, typename PostDomTreeT> |
| 356 | +void GenericDomTreeUpdater<DerivedT, DomTreeT, PostDomTreeT>:: |
| 357 | + applyUpdatesForCriticalEdgeSplitting(BasicBlockT *FromBB, BasicBlockT *ToBB, |
| 358 | + BasicBlockT *NewBB) { |
| 359 | + if (!DT && !PDT) |
| 360 | + return; |
| 361 | + CriticalEdgesToSplit.push_back({FromBB, ToBB, NewBB}); |
| 362 | + bool Inserted = NewBBs.insert(NewBB).second; |
| 363 | + (void)Inserted; |
| 364 | + assert(Inserted && |
| 365 | + "A basic block inserted via edge splitting cannot appear twice"); |
| 366 | + if (Strategy == UpdateStrategy::Lazy) { |
| 367 | + applyDomTreeUpdates(); |
| 368 | + applyPostDomTreeUpdates(); |
| 369 | + } |
| 370 | + if (Strategy == UpdateStrategy::Eager) |
| 371 | + applySplitCriticalEdges(); |
| 372 | +} |
| 373 | + |
| 374 | +template <typename DerivedT, typename DomTreeT, typename PostDomTreeT> |
| 375 | +void GenericDomTreeUpdater<DerivedT, DomTreeT, |
| 376 | + PostDomTreeT>::applySplitCriticalEdges() { |
| 377 | + // Bail out early if there is nothing to do. |
| 378 | + if (CriticalEdgesToSplit.empty()) |
| 379 | + return; |
| 380 | + |
| 381 | + // For each element in CriticalEdgesToSplit, remember whether or not element |
| 382 | + // is the new immediate domminator of its successor. The mapping is done by |
| 383 | + // index, i.e., the information for the ith element of CriticalEdgesToSplit is |
| 384 | + // the ith element of IsNewIDom. |
| 385 | + SmallBitVector IsNewIDom(CriticalEdgesToSplit.size(), true); |
| 386 | + SmallBitVector IsNewIPDom(CriticalEdgesToSplit.size(), true); |
| 387 | + size_t Idx = 0; |
| 388 | + |
| 389 | + // Collect all the dominance properties info, before invalidating |
| 390 | + // the underlying DT. |
| 391 | + for (CriticalEdge &Edge : CriticalEdgesToSplit) { |
| 392 | + // Update dominator information. |
| 393 | + if (DT) { |
| 394 | + BasicBlockT *Succ = Edge.ToBB; |
| 395 | + auto *SuccDTNode = DT->getNode(Succ); |
| 396 | + |
| 397 | + for (BasicBlockT *PredBB : predecessors(Succ)) { |
| 398 | + if (PredBB == Edge.NewBB) |
| 399 | + continue; |
| 400 | + // If we are in this situation: |
| 401 | + // FromBB1 FromBB2 |
| 402 | + // + + |
| 403 | + // + + + + |
| 404 | + // + + + + |
| 405 | + // ... Split1 Split2 ... |
| 406 | + // + + |
| 407 | + // + + |
| 408 | + // + |
| 409 | + // Succ |
| 410 | + // Instead of checking the domiance property with Split2, we check it |
| 411 | + // with FromBB2 since Split2 is still unknown of the underlying DT |
| 412 | + // structure. |
| 413 | + if (NewBBs.count(PredBB)) { |
| 414 | + assert(pred_size(PredBB) == 1 && "A basic block resulting from a " |
| 415 | + "critical edge split has more " |
| 416 | + "than one predecessor!"); |
| 417 | + PredBB = *pred_begin(PredBB); |
| 418 | + } |
| 419 | + if (!DT->dominates(SuccDTNode, DT->getNode(PredBB))) { |
| 420 | + IsNewIDom[Idx] = false; |
| 421 | + break; |
| 422 | + } |
| 423 | + } |
| 424 | + } |
| 425 | + |
| 426 | + // Same as DT version but from another direction. |
| 427 | + if (PDT) { |
| 428 | + BasicBlockT *Pred = Edge.FromBB; |
| 429 | + auto *PredDTNode = PDT->getNode(Pred); |
| 430 | + for (BasicBlockT *SuccBB : successors(Pred)) { |
| 431 | + if (SuccBB == Edge.NewBB) |
| 432 | + continue; |
| 433 | + if (NewBBs.count(SuccBB)) { |
| 434 | + assert(succ_size(SuccBB) == 1 && "A basic block resulting from a " |
| 435 | + "critical edge split has more " |
| 436 | + "than one predecessor!"); |
| 437 | + SuccBB = *succ_begin(SuccBB); |
| 438 | + } |
| 439 | + if (!PDT->dominates(PredDTNode, PDT->getNode(SuccBB))) { |
| 440 | + IsNewIPDom[Idx] = false; |
| 441 | + break; |
| 442 | + } |
| 443 | + } |
| 444 | + } |
| 445 | + ++Idx; |
| 446 | + } |
| 447 | + |
| 448 | + // Now, update DT with the collected dominance properties info. |
| 449 | + Idx = 0; |
| 450 | + for (CriticalEdge &Edge : CriticalEdgesToSplit) { |
| 451 | + if (DT) { |
| 452 | + // We know FromBB dominates NewBB. |
| 453 | + auto *NewDTNode = DT->addNewBlock(Edge.NewBB, Edge.FromBB); |
| 454 | + |
| 455 | + // If all the other predecessors of "Succ" are dominated by "Succ" itself |
| 456 | + // then the new block is the new immediate dominator of "Succ". Otherwise, |
| 457 | + // the new block doesn't dominate anything. |
| 458 | + if (IsNewIDom[Idx]) |
| 459 | + DT->changeImmediateDominator(DT->getNode(Edge.ToBB), NewDTNode); |
| 460 | + } |
| 461 | + if (PDT) { |
| 462 | + auto *NewPDTNode = PDT->addNewBlock(Edge.NewBB, Edge.ToBB); |
| 463 | + if (IsNewIPDom[Idx]) |
| 464 | + PDT->changeImmediateDominator(PDT->getNode(Edge.FromBB), NewPDTNode); |
| 465 | + } |
| 466 | + ++Idx; |
| 467 | + } |
| 468 | + NewBBs.clear(); |
| 469 | + CriticalEdgesToSplit.clear(); |
| 470 | +} |
| 471 | + |
351 | 472 | } // namespace llvm
|
352 | 473 |
|
353 | 474 | #endif // LLVM_ANALYSIS_GENERICDOMTREEUPDATERIMPL_H
|
0 commit comments