static unsigned numberCtrlPredInSU(SUnit *SU) { unsigned NumberDeps = 0; for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) if (I->isCtrl()) NumberDeps++; return NumberDeps; }
unsigned ResourcePriorityQueue::numberRCValPredInSU(SUnit *SU, unsigned RCId) { unsigned NumberDeps = 0; for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { if (I->isCtrl()) continue; SUnit *PredSU = I->getSUnit(); const SDNode *ScegN = PredSU->getNode(); if (!ScegN) continue; // If value is passed to CopyToReg, it is probably // live outside BB. switch (ScegN->getOpcode()) { default: break; case ISD::TokenFactor: break; case ISD::CopyFromReg: NumberDeps++; break; case ISD::CopyToReg: break; case ISD::INLINEASM: break; } if (!ScegN->isMachineOpcode()) continue; for (unsigned i = 0, e = ScegN->getNumValues(); i != e; ++i) { MVT VT = ScegN->getSimpleValueType(i); if (TLI->isTypeLegal(VT) && (TLI->getRegClassFor(VT)->getID() == RCId)) { NumberDeps++; break; } } } return NumberDeps; }
/// Main resource tracking point. void ResourcePriorityQueue::scheduledNode(SUnit *SU) { // Use NULL entry as an event marker to reset // the DFA state. if (!SU) { ResourcesModel->clearResources(); Packet.clear(); return; } const SDNode *ScegN = SU->getNode(); // Update reg pressure tracking. // First update current node. if (ScegN->isMachineOpcode()) { // Estimate generated regs. for (unsigned i = 0, e = ScegN->getNumValues(); i != e; ++i) { MVT VT = ScegN->getSimpleValueType(i); if (TLI->isTypeLegal(VT)) { const TargetRegisterClass *RC = TLI->getRegClassFor(VT); if (RC) RegPressure[RC->getID()] += numberRCValSuccInSU(SU, RC->getID()); } } // Estimate killed regs. for (unsigned i = 0, e = ScegN->getNumOperands(); i != e; ++i) { const SDValue &Op = ScegN->getOperand(i); MVT VT = Op.getNode()->getSimpleValueType(Op.getResNo()); if (TLI->isTypeLegal(VT)) { const TargetRegisterClass *RC = TLI->getRegClassFor(VT); if (RC) { if (RegPressure[RC->getID()] > (numberRCValPredInSU(SU, RC->getID()))) RegPressure[RC->getID()] -= numberRCValPredInSU(SU, RC->getID()); else RegPressure[RC->getID()] = 0; } } } for (SUnit::pred_iterator I = SU->Preds.begin(), E = SU->Preds.end(); I != E; ++I) { if (I->isCtrl() || (I->getSUnit()->NumRegDefsLeft == 0)) continue; --I->getSUnit()->NumRegDefsLeft; } } // Reserve resources for this SU. reserveResources(SU); // Adjust number of parallel live ranges. // Heuristic is simple - node with no data successors reduces // number of live ranges. All others, increase it. unsigned NumberNonControlDeps = 0; for (SUnit::const_succ_iterator I = SU->Succs.begin(), E = SU->Succs.end(); I != E; ++I) { adjustPriorityOfUnscheduledPreds(I->getSUnit()); if (!I->isCtrl()) NumberNonControlDeps++; } if (!NumberNonControlDeps) { if (ParallelLiveRanges >= SU->NumPreds) ParallelLiveRanges -= SU->NumPreds; else ParallelLiveRanges = 0; } else ParallelLiveRanges += SU->NumRegDefsLeft; // Track parallel live chains. HorizontalVerticalBalance += (SU->Succs.size() - numberCtrlDepsInSU(SU)); HorizontalVerticalBalance -= (SU->Preds.size() - numberCtrlPredInSU(SU)); }