void BT::runEdgeQueue(BitVector &BlockScanned) { while (!FlowQ.empty()) { CFGEdge Edge = FlowQ.front(); FlowQ.pop(); if (EdgeExec.count(Edge)) return; EdgeExec.insert(Edge); ReachedBB.insert(Edge.second); const MachineBasicBlock &B = *MF.getBlockNumbered(Edge.second); MachineBasicBlock::const_iterator It = B.begin(), End = B.end(); // Visit PHI nodes first. while (It != End && It->isPHI()) { const MachineInstr &PI = *It++; InstrExec.insert(&PI); visitPHI(PI); } // If this block has already been visited through a flow graph edge, // then the instructions have already been processed. Any updates to // the cells would now only happen through visitUsesOf... if (BlockScanned[Edge.second]) return; BlockScanned[Edge.second] = true; // Visit non-branch instructions. while (It != End && !It->isBranch()) { const MachineInstr &MI = *It++; InstrExec.insert(&MI); visitNonBranch(MI); } // If block end has been reached, add the fall-through edge to the queue. if (It == End) { MachineFunction::const_iterator BIt = B.getIterator(); MachineFunction::const_iterator Next = std::next(BIt); if (Next != MF.end() && B.isSuccessor(&*Next)) { int ThisN = B.getNumber(); int NextN = Next->getNumber(); FlowQ.push(CFGEdge(ThisN, NextN)); } } else { // Handle the remaining sequence of branches. This function will update // the work queue. visitBranchesFrom(*It); } } // while (!FlowQ->empty()) }
void BT::run() { reset(); assert(FlowQ.empty()); typedef GraphTraits<const MachineFunction*> MachineFlowGraphTraits; const MachineBasicBlock *Entry = MachineFlowGraphTraits::getEntryNode(&MF); unsigned MaxBN = 0; for (MachineFunction::const_iterator I = MF.begin(), E = MF.end(); I != E; ++I) { assert(I->getNumber() >= 0 && "Disconnected block"); unsigned BN = I->getNumber(); if (BN > MaxBN) MaxBN = BN; } // Keep track of visited blocks. BitVector BlockScanned(MaxBN+1); int EntryN = Entry->getNumber(); // Generate a fake edge to get something to start with. FlowQ.push(CFGEdge(-1, EntryN)); while (!FlowQ.empty()) { CFGEdge Edge = FlowQ.front(); FlowQ.pop(); if (EdgeExec.count(Edge)) continue; EdgeExec.insert(Edge); const MachineBasicBlock &B = *MF.getBlockNumbered(Edge.second); MachineBasicBlock::const_iterator It = B.begin(), End = B.end(); // Visit PHI nodes first. while (It != End && It->isPHI()) { const MachineInstr &PI = *It++; InstrExec.insert(&PI); visitPHI(PI); } // If this block has already been visited through a flow graph edge, // then the instructions have already been processed. Any updates to // the cells would now only happen through visitUsesOf... if (BlockScanned[Edge.second]) continue; BlockScanned[Edge.second] = true; // Visit non-branch instructions. while (It != End && !It->isBranch()) { const MachineInstr &MI = *It++; InstrExec.insert(&MI); visitNonBranch(MI); } // If block end has been reached, add the fall-through edge to the queue. if (It == End) { MachineFunction::const_iterator BIt = B.getIterator(); MachineFunction::const_iterator Next = std::next(BIt); if (Next != MF.end() && B.isSuccessor(&*Next)) { int ThisN = B.getNumber(); int NextN = Next->getNumber(); FlowQ.push(CFGEdge(ThisN, NextN)); } } else { // Handle the remaining sequence of branches. This function will update // the work queue. visitBranchesFrom(*It); } } // while (!FlowQ->empty()) if (Trace) print_cells(dbgs() << "Cells after propagation:\n"); }