bool MachineCSE::PerformCSE(MachineDomTreeNode *Node) { SmallVector<MachineDomTreeNode*, 32> Scopes; SmallVector<MachineDomTreeNode*, 8> WorkList; DenseMap<MachineDomTreeNode*, unsigned> OpenChildren; CurrVN = 0; // Perform a DFS walk to determine the order of visit. WorkList.push_back(Node); do { Node = WorkList.pop_back_val(); Scopes.push_back(Node); const std::vector<MachineDomTreeNode*> &Children = Node->getChildren(); unsigned NumChildren = Children.size(); OpenChildren[Node] = NumChildren; for (unsigned i = 0; i != NumChildren; ++i) { MachineDomTreeNode *Child = Children[i]; WorkList.push_back(Child); } } while (!WorkList.empty()); // Now perform CSE. bool Changed = false; for (unsigned i = 0, e = Scopes.size(); i != e; ++i) { MachineDomTreeNode *Node = Scopes[i]; MachineBasicBlock *MBB = Node->getBlock(); EnterScope(MBB); Changed |= ProcessBlock(MBB); // If it's a leaf node, it's done. Traverse upwards to pop ancestors. ExitScopeIfDone(Node, OpenChildren); } return Changed; }
void HexagonEarlyIfConversion::removeBlock(MachineBasicBlock *B) { DEBUG(dbgs() << "Removing block " << PrintMB(B) << "\n"); // Transfer the immediate dominator information from B to its descendants. MachineDomTreeNode *N = MDT->getNode(B); MachineDomTreeNode *IDN = N->getIDom(); if (IDN) { MachineBasicBlock *IDB = IDN->getBlock(); typedef GraphTraits<MachineDomTreeNode*> GTN; typedef SmallVector<MachineDomTreeNode*,4> DTNodeVectType; DTNodeVectType Cn(GTN::child_begin(N), GTN::child_end(N)); for (DTNodeVectType::iterator I = Cn.begin(), E = Cn.end(); I != E; ++I) { MachineBasicBlock *SB = (*I)->getBlock(); MDT->changeImmediateDominator(SB, IDB); } } while (B->succ_size() > 0) B->removeSuccessor(B->succ_begin()); for (auto I = B->pred_begin(), E = B->pred_end(); I != E; ++I) (*I)->removeSuccessor(B); Deleted.insert(B); MDT->eraseNode(B); MachineFunction::iterator BI = B; MFN->erase(BI); }
MachineBasicBlock* SplitEditor::findShallowDominator(MachineBasicBlock *MBB, MachineBasicBlock *DefMBB) { if (MBB == DefMBB) return MBB; assert(MDT.dominates(DefMBB, MBB) && "MBB must be dominated by the def."); const MachineLoopInfo &Loops = SA.Loops; const MachineLoop *DefLoop = Loops.getLoopFor(DefMBB); MachineDomTreeNode *DefDomNode = MDT[DefMBB]; // Best candidate so far. MachineBasicBlock *BestMBB = MBB; unsigned BestDepth = UINT_MAX; for (;;) { const MachineLoop *Loop = Loops.getLoopFor(MBB); // MBB isn't in a loop, it doesn't get any better. All dominators have a // higher frequency by definition. if (!Loop) { DEBUG(dbgs() << "Def in BB#" << DefMBB->getNumber() << " dominates BB#" << MBB->getNumber() << " at depth 0\n"); return MBB; } // We'll never be able to exit the DefLoop. if (Loop == DefLoop) { DEBUG(dbgs() << "Def in BB#" << DefMBB->getNumber() << " dominates BB#" << MBB->getNumber() << " in the same loop\n"); return MBB; } // Least busy dominator seen so far. unsigned Depth = Loop->getLoopDepth(); if (Depth < BestDepth) { BestMBB = MBB; BestDepth = Depth; DEBUG(dbgs() << "Def in BB#" << DefMBB->getNumber() << " dominates BB#" << MBB->getNumber() << " at depth " << Depth << '\n'); } // Leave loop by going to the immediate dominator of the loop header. // This is a bigger stride than simply walking up the dominator tree. MachineDomTreeNode *IDom = MDT[Loop->getHeader()]->getIDom(); // Too far up the dominator tree? if (!IDom || !MDT.dominates(DefDomNode, IDom)) return BestMBB; MBB = IDom->getBlock(); } }
/// computeDFS - Computes the DFS-in and DFS-out numbers of the dominator tree /// of the given MachineFunction. These numbers are then used in other parts /// of the PHI elimination process. void StrongPHIElimination::computeDFS(MachineFunction& MF) { SmallPtrSet<MachineDomTreeNode*, 8> frontier; SmallPtrSet<MachineDomTreeNode*, 8> visited; unsigned time = 0; MachineDominatorTree& DT = getAnalysis<MachineDominatorTree>(); MachineDomTreeNode* node = DT.getRootNode(); std::vector<MachineDomTreeNode*> worklist; worklist.push_back(node); while (!worklist.empty()) { MachineDomTreeNode* currNode = worklist.back(); if (!frontier.count(currNode)) { frontier.insert(currNode); ++time; preorder.insert(std::make_pair(currNode->getBlock(), time)); } bool inserted = false; for (MachineDomTreeNode::iterator I = currNode->begin(), E = currNode->end(); I != E; ++I) if (!frontier.count(*I) && !visited.count(*I)) { worklist.push_back(*I); inserted = true; break; } if (!inserted) { frontier.erase(currNode); visited.insert(currNode); maxpreorder.insert(std::make_pair(currNode->getBlock(), time)); worklist.pop_back(); } } }
// This is essentially the same iterative algorithm that SSAUpdater uses, // except we already have a dominator tree, so we don't have to recompute it. void LiveRangeCalc::updateSSA() { assert(Indexes && "Missing SlotIndexes"); assert(DomTree && "Missing dominator tree"); // Interate until convergence. unsigned Changes; do { Changes = 0; // Propagate live-out values down the dominator tree, inserting phi-defs // when necessary. for (SmallVectorImpl<LiveInBlock>::iterator I = LiveIn.begin(), E = LiveIn.end(); I != E; ++I) { MachineDomTreeNode *Node = I->DomNode; // Skip block if the live-in value has already been determined. if (!Node) continue; MachineBasicBlock *MBB = Node->getBlock(); MachineDomTreeNode *IDom = Node->getIDom(); LiveOutPair IDomValue; // We need a live-in value to a block with no immediate dominator? // This is probably an unreachable block that has survived somehow. bool needPHI = !IDom || !Seen.test(IDom->getBlock()->getNumber()); // IDom dominates all of our predecessors, but it may not be their // immediate dominator. Check if any of them have live-out values that are // properly dominated by IDom. If so, we need a phi-def here. if (!needPHI) { IDomValue = LiveOut[IDom->getBlock()]; // Cache the DomTree node that defined the value. if (IDomValue.first && !IDomValue.second) LiveOut[IDom->getBlock()].second = IDomValue.second = DomTree->getNode(Indexes->getMBBFromIndex(IDomValue.first->def)); for (MachineBasicBlock::pred_iterator PI = MBB->pred_begin(), PE = MBB->pred_end(); PI != PE; ++PI) { LiveOutPair &Value = LiveOut[*PI]; if (!Value.first || Value.first == IDomValue.first) continue; // Cache the DomTree node that defined the value. if (!Value.second) Value.second = DomTree->getNode(Indexes->getMBBFromIndex(Value.first->def)); // This predecessor is carrying something other than IDomValue. // It could be because IDomValue hasn't propagated yet, or it could be // because MBB is in the dominance frontier of that value. if (DomTree->dominates(IDom, Value.second)) { needPHI = true; break; } } } // The value may be live-through even if Kill is set, as can happen when // we are called from extendRange. In that case LiveOutSeen is true, and // LiveOut indicates a foreign or missing value. LiveOutPair &LOP = LiveOut[MBB]; // Create a phi-def if required. if (needPHI) { ++Changes; assert(Alloc && "Need VNInfo allocator to create PHI-defs"); SlotIndex Start, End; tie(Start, End) = Indexes->getMBBRange(MBB); VNInfo *VNI = I->LI->getNextValue(Start, *Alloc); I->Value = VNI; // This block is done, we know the final value. I->DomNode = 0; // Add liveness since updateLiveIns now skips this node. if (I->Kill.isValid()) I->LI->addRange(LiveRange(Start, I->Kill, VNI)); else { I->LI->addRange(LiveRange(Start, End, VNI)); LOP = LiveOutPair(VNI, Node); } } else if (IDomValue.first) { // No phi-def here. Remember incoming value. I->Value = IDomValue.first; // If the IDomValue is killed in the block, don't propagate through. if (I->Kill.isValid()) continue; // Propagate IDomValue if it isn't killed: // MBB is live-out and doesn't define its own value. if (LOP.first == IDomValue.first) continue; ++Changes; LOP = IDomValue; } } } while (Changes); }
/// Walk the specified loop in the CFG (defined by all blocks dominated by the /// specified header block, and that are in the current loop) in depth first /// order w.r.t the DominatorTree. This allows us to visit definitions before /// uses, allowing us to hoist a loop body in one pass without iteration. /// void MachineLICM::HoistOutOfLoop(MachineDomTreeNode *HeaderN) { MachineBasicBlock *Preheader = getCurPreheader(); if (!Preheader) return; SmallVector<MachineDomTreeNode*, 32> Scopes; SmallVector<MachineDomTreeNode*, 8> WorkList; DenseMap<MachineDomTreeNode*, MachineDomTreeNode*> ParentMap; DenseMap<MachineDomTreeNode*, unsigned> OpenChildren; // Perform a DFS walk to determine the order of visit. WorkList.push_back(HeaderN); while (!WorkList.empty()) { MachineDomTreeNode *Node = WorkList.pop_back_val(); assert(Node && "Null dominator tree node?"); MachineBasicBlock *BB = Node->getBlock(); // If the header of the loop containing this basic block is a landing pad, // then don't try to hoist instructions out of this loop. const MachineLoop *ML = MLI->getLoopFor(BB); if (ML && ML->getHeader()->isEHPad()) continue; // If this subregion is not in the top level loop at all, exit. if (!CurLoop->contains(BB)) continue; Scopes.push_back(Node); const std::vector<MachineDomTreeNode*> &Children = Node->getChildren(); unsigned NumChildren = Children.size(); // Don't hoist things out of a large switch statement. This often causes // code to be hoisted that wasn't going to be executed, and increases // register pressure in a situation where it's likely to matter. if (BB->succ_size() >= 25) NumChildren = 0; OpenChildren[Node] = NumChildren; // Add children in reverse order as then the next popped worklist node is // the first child of this node. This means we ultimately traverse the // DOM tree in exactly the same order as if we'd recursed. for (int i = (int)NumChildren-1; i >= 0; --i) { MachineDomTreeNode *Child = Children[i]; ParentMap[Child] = Node; WorkList.push_back(Child); } } if (Scopes.size() == 0) return; // Compute registers which are livein into the loop headers. RegSeen.clear(); BackTrace.clear(); InitRegPressure(Preheader); // Now perform LICM. for (MachineDomTreeNode *Node : Scopes) { MachineBasicBlock *MBB = Node->getBlock(); EnterScope(MBB); // Process the block SpeculationState = SpeculateUnknown; for (MachineBasicBlock::iterator MII = MBB->begin(), E = MBB->end(); MII != E; ) { MachineBasicBlock::iterator NextMII = MII; ++NextMII; MachineInstr *MI = &*MII; if (!Hoist(MI, Preheader)) UpdateRegPressure(MI); MII = NextMII; } // If it's a leaf node, it's done. Traverse upwards to pop ancestors. ExitScopeIfDone(Node, OpenChildren, ParentMap); } }
// This is essentially the same iterative algorithm that SSAUpdater uses, // except we already have a dominator tree, so we don't have to recompute it. void LiveRangeCalc::updateSSA() { assert(Indexes && "Missing SlotIndexes"); assert(DomTree && "Missing dominator tree"); // Interate until convergence. bool Changed; do { Changed = false; // Propagate live-out values down the dominator tree, inserting phi-defs // when necessary. for (LiveInBlock &I : LiveIn) { MachineDomTreeNode *Node = I.DomNode; // Skip block if the live-in value has already been determined. if (!Node) continue; MachineBasicBlock *MBB = Node->getBlock(); MachineDomTreeNode *IDom = Node->getIDom(); LiveOutPair IDomValue; // We need a live-in value to a block with no immediate dominator? // This is probably an unreachable block that has survived somehow. bool needPHI = !IDom || !Seen.test(IDom->getBlock()->getNumber()); // IDom dominates all of our predecessors, but it may not be their // immediate dominator. Check if any of them have live-out values that are // properly dominated by IDom. If so, we need a phi-def here. if (!needPHI) { IDomValue = Map[IDom->getBlock()]; // Cache the DomTree node that defined the value. if (IDomValue.first && IDomValue.first != &UndefVNI && !IDomValue.second) { Map[IDom->getBlock()].second = IDomValue.second = DomTree->getNode(Indexes->getMBBFromIndex(IDomValue.first->def)); } for (MachineBasicBlock *Pred : MBB->predecessors()) { LiveOutPair &Value = Map[Pred]; if (!Value.first || Value.first == IDomValue.first) continue; if (Value.first == &UndefVNI) { needPHI = true; break; } // Cache the DomTree node that defined the value. if (!Value.second) Value.second = DomTree->getNode(Indexes->getMBBFromIndex(Value.first->def)); // This predecessor is carrying something other than IDomValue. // It could be because IDomValue hasn't propagated yet, or it could be // because MBB is in the dominance frontier of that value. if (DomTree->dominates(IDom, Value.second)) { needPHI = true; break; } } } // The value may be live-through even if Kill is set, as can happen when // we are called from extendRange. In that case LiveOutSeen is true, and // LiveOut indicates a foreign or missing value. LiveOutPair &LOP = Map[MBB]; // Create a phi-def if required. if (needPHI) { Changed = true; assert(Alloc && "Need VNInfo allocator to create PHI-defs"); SlotIndex Start, End; std::tie(Start, End) = Indexes->getMBBRange(MBB); LiveRange &LR = I.LR; VNInfo *VNI = LR.getNextValue(Start, *Alloc); I.Value = VNI; // This block is done, we know the final value. I.DomNode = nullptr; // Add liveness since updateFromLiveIns now skips this node. if (I.Kill.isValid()) { if (VNI) LR.addSegment(LiveInterval::Segment(Start, I.Kill, VNI)); } else { if (VNI) LR.addSegment(LiveInterval::Segment(Start, End, VNI)); LOP = LiveOutPair(VNI, Node); } } else if (IDomValue.first && IDomValue.first != &UndefVNI) { // No phi-def here. Remember incoming value. I.Value = IDomValue.first; // If the IDomValue is killed in the block, don't propagate through. if (I.Kill.isValid()) continue; // Propagate IDomValue if it isn't killed: // MBB is live-out and doesn't define its own value. if (LOP.first == IDomValue.first) continue; Changed = true; LOP = IDomValue; } } } while (Changed); }