| //===-- ModuloScheduling.cpp - ModuloScheduling ----------------*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file was developed by the LLVM research group and is distributed under |
| // the University of Illinois Open Source License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #define DEBUG_TYPE "ModuloSched" |
| |
| #include "ModuloScheduling.h" |
| #include "llvm/CodeGen/MachineFunction.h" |
| #include "llvm/CodeGen/Passes.h" |
| #include "llvm/Support/CFG.h" |
| #include "llvm/Target/TargetSchedInfo.h" |
| #include "Support/Debug.h" |
| #include "Support/GraphWriter.h" |
| #include <vector> |
| #include <utility> |
| #include <iostream> |
| #include <fstream> |
| #include <sstream> |
| |
| using namespace llvm; |
| |
| /// Create ModuloSchedulingPass |
| /// |
| FunctionPass *llvm::createModuloSchedulingPass(TargetMachine & targ) { |
| DEBUG(std::cerr << "Created ModuloSchedulingPass\n"); |
| return new ModuloSchedulingPass(targ); |
| } |
| |
| template<typename GraphType> |
| static void WriteGraphToFile(std::ostream &O, const std::string &GraphName, |
| const GraphType >) { |
| std::string Filename = GraphName + ".dot"; |
| O << "Writing '" << Filename << "'..."; |
| std::ofstream F(Filename.c_str()); |
| |
| if (F.good()) |
| WriteGraph(F, GT); |
| else |
| O << " error opening file for writing!"; |
| O << "\n"; |
| }; |
| |
| namespace llvm { |
| |
| template<> |
| struct DOTGraphTraits<MSchedGraph*> : public DefaultDOTGraphTraits { |
| static std::string getGraphName(MSchedGraph *F) { |
| return "Dependence Graph"; |
| } |
| |
| static std::string getNodeLabel(MSchedGraphNode *Node, MSchedGraph *Graph) { |
| if (Node->getInst()) { |
| std::stringstream ss; |
| ss << *(Node->getInst()); |
| return ss.str(); //((MachineInstr*)Node->getInst()); |
| } |
| else |
| return "No Inst"; |
| } |
| static std::string getEdgeSourceLabel(MSchedGraphNode *Node, |
| MSchedGraphNode::succ_iterator I) { |
| //Label each edge with the type of dependence |
| std::string edgelabel = ""; |
| switch (I.getEdge().getDepOrderType()) { |
| |
| case MSchedGraphEdge::TrueDep: |
| edgelabel = "True"; |
| break; |
| |
| case MSchedGraphEdge::AntiDep: |
| edgelabel = "Anti"; |
| break; |
| |
| case MSchedGraphEdge::OutputDep: |
| edgelabel = "Output"; |
| break; |
| |
| default: |
| edgelabel = "Unknown"; |
| break; |
| } |
| if(I.getEdge().getIteDiff() > 0) |
| edgelabel += I.getEdge().getIteDiff(); |
| |
| return edgelabel; |
| } |
| |
| |
| |
| }; |
| } |
| |
| /// ModuloScheduling::runOnFunction - main transformation entry point |
| bool ModuloSchedulingPass::runOnFunction(Function &F) { |
| bool Changed = false; |
| |
| DEBUG(std::cerr << "Creating ModuloSchedGraph for each BasicBlock in" + F.getName() + "\n"); |
| |
| //Get MachineFunction |
| MachineFunction &MF = MachineFunction::get(&F); |
| |
| //Iterate over BasicBlocks and do ModuloScheduling if they are valid |
| for (MachineFunction::const_iterator BI = MF.begin(); BI != MF.end(); ++BI) { |
| if(MachineBBisValid(BI)) { |
| MSchedGraph *MSG = new MSchedGraph(BI, target); |
| |
| //Write Graph out to file |
| DEBUG(WriteGraphToFile(std::cerr, "dependgraph", MSG)); |
| |
| //Print out BB for debugging |
| DEBUG(BI->print(std::cerr)); |
| |
| //Calculate Resource II |
| int ResMII = calculateResMII(BI); |
| |
| calculateNodeAttributes(MSG, ResMII); |
| |
| } |
| } |
| |
| |
| return Changed; |
| } |
| |
| |
| bool ModuloSchedulingPass::MachineBBisValid(const MachineBasicBlock *BI) { |
| |
| //Valid basic blocks must be loops and can not have if/else statements or calls. |
| bool isLoop = false; |
| |
| //Check first if its a valid loop |
| for(succ_const_iterator I = succ_begin(BI->getBasicBlock()), |
| E = succ_end(BI->getBasicBlock()); I != E; ++I) { |
| if (*I == BI->getBasicBlock()) // has single block loop |
| isLoop = true; |
| } |
| |
| if(!isLoop) { |
| DEBUG(std::cerr << "Basic Block is not a loop\n"); |
| return false; |
| } |
| else |
| DEBUG(std::cerr << "Basic Block is a loop\n"); |
| |
| //Get Target machine instruction info |
| /*const TargetInstrInfo& TMI = targ.getInstrInfo(); |
| |
| //Check each instruction and look for calls or if/else statements |
| unsigned count = 0; |
| for(MachineBasicBlock::const_iterator I = BI->begin(), E = BI->end(); I != E; ++I) { |
| //Get opcode to check instruction type |
| MachineOpCode OC = I->getOpcode(); |
| if(TMI.isControlFlow(OC) && (count+1 < BI->size())) |
| return false; |
| count++; |
| }*/ |
| return true; |
| |
| } |
| |
| //ResMII is calculated by determining the usage count for each resource |
| //and using the maximum. |
| //FIXME: In future there should be a way to get alternative resources |
| //for each instruction |
| int ModuloSchedulingPass::calculateResMII(const MachineBasicBlock *BI) { |
| |
| const TargetInstrInfo & mii = target.getInstrInfo(); |
| const TargetSchedInfo & msi = target.getSchedInfo(); |
| |
| int ResMII = 0; |
| |
| //Map to keep track of usage count of each resource |
| std::map<unsigned, unsigned> resourceUsageCount; |
| |
| for(MachineBasicBlock::const_iterator I = BI->begin(), E = BI->end(); I != E; ++I) { |
| |
| //Get resource usage for this instruction |
| InstrRUsage rUsage = msi.getInstrRUsage(I->getOpcode()); |
| std::vector<std::vector<resourceId_t> > resources = rUsage.resourcesByCycle; |
| |
| //Loop over resources in each cycle and increments their usage count |
| for(unsigned i=0; i < resources.size(); ++i) |
| for(unsigned j=0; j < resources[i].size(); ++j) { |
| if( resourceUsageCount.find(resources[i][j]) == resourceUsageCount.end()) { |
| resourceUsageCount[resources[i][j]] = 1; |
| } |
| else { |
| resourceUsageCount[resources[i][j]] = resourceUsageCount[resources[i][j]] + 1; |
| } |
| } |
| } |
| |
| //Find maximum usage count |
| |
| //Get max number of instructions that can be issued at once. |
| int issueSlots = msi.maxNumIssueTotal; |
| |
| for(std::map<unsigned,unsigned>::iterator RB = resourceUsageCount.begin(), RE = resourceUsageCount.end(); RB != RE; ++RB) { |
| //Get the total number of the resources in our cpu |
| //int resourceNum = msi.getCPUResourceNum(RB->first); |
| |
| //Get total usage count for this resources |
| unsigned usageCount = RB->second; |
| |
| //Divide the usage count by either the max number we can issue or the number of |
| //resources (whichever is its upper bound) |
| double finalUsageCount; |
| //if( resourceNum <= issueSlots) |
| //finalUsageCount = ceil(1.0 * usageCount / resourceNum); |
| //else |
| finalUsageCount = ceil(1.0 * usageCount / issueSlots); |
| |
| |
| DEBUG(std::cerr << "Resource ID: " << RB->first << " (usage=" << usageCount << ", resourceNum=X" << ", issueSlots=" << issueSlots << ", finalUsage=" << finalUsageCount << ")\n"); |
| |
| //Only keep track of the max |
| ResMII = std::max( (int) finalUsageCount, ResMII); |
| |
| } |
| |
| DEBUG(std::cerr << "Final Resource MII: " << ResMII << "\n"); |
| return ResMII; |
| |
| } |
| |
| void ModuloSchedulingPass::calculateNodeAttributes(MSchedGraph *graph, int MII) { |
| |
| //Loop over the nodes and add them to the map |
| for(MSchedGraph::iterator I = graph->begin(), E = graph->end(); I != E; ++I) { |
| //Assert if its already in the map |
| assert(nodeToAttributesMap.find(I->second) == nodeToAttributesMap.end() && "Node attributes are already in the map"); |
| |
| //Put into the map with default attribute values |
| nodeToAttributesMap[I->second] = MSNodeAttributes(); |
| } |
| |
| //Create set to deal with reccurrences |
| std::set<MSchedGraphNode*> visitedNodes; |
| std::vector<MSchedGraphNode*> vNodes; |
| //Now Loop over map and calculate the node attributes |
| for(std::map<MSchedGraphNode*, MSNodeAttributes>::iterator I = nodeToAttributesMap.begin(), E = nodeToAttributesMap.end(); I != E; ++I) { |
| // calculateASAP(I->first, (I->second), MII, visitedNodes); |
| findAllReccurrences(I->first, vNodes); |
| vNodes.clear(); |
| visitedNodes.clear(); |
| } |
| |
| //Calculate ALAP which depends on ASAP being totally calculated |
| /*for(std::map<MSchedGraphNode*, MSNodeAttributes>::iterator I = nodeToAttributesMap.begin(), E = nodeToAttributesMap.end(); I != E; ++I) { |
| calculateALAP(I->first, (I->second), MII, MII, visitedNodes); |
| visitedNodes.clear(); |
| }*/ |
| |
| //Calculate MOB which depends on ASAP being totally calculated, also do depth and height |
| /*for(std::map<MSchedGraphNode*, MSNodeAttributes>::iterator I = nodeToAttributesMap.begin(), E = nodeToAttributesMap.end(); I != E; ++I) { |
| (I->second).MOB = (I->second).ALAP - (I->second).ASAP; |
| DEBUG(std::cerr << "MOB: " << (I->second).MOB << " (" << *(I->first) << ")\n"); |
| calculateDepth(I->first, (I->second), visitedNodes); |
| visitedNodes.clear(); |
| calculateHeight(I->first, (I->second), visitedNodes); |
| visitedNodes.clear(); |
| }*/ |
| |
| |
| } |
| |
| void ModuloSchedulingPass::calculateASAP(MSchedGraphNode *node, MSNodeAttributes &attributes, |
| int MII, std::set<MSchedGraphNode*> &visitedNodes) { |
| |
| DEBUG(std::cerr << "Calculating ASAP for " << *node << "\n"); |
| |
| if(attributes.ASAP != -1 || (visitedNodes.find(node) != visitedNodes.end())) { |
| visitedNodes.erase(node); |
| return; |
| } |
| if(node->hasPredecessors()) { |
| int maxPredValue = 0; |
| |
| //Iterate over all of the predecessors and fine max |
| for(MSchedGraphNode::pred_iterator P = node->pred_begin(), E = node->pred_end(); P != E; ++P) { |
| |
| //Get that nodes ASAP |
| MSNodeAttributes predAttributes = nodeToAttributesMap.find(*P)->second; |
| if(predAttributes.ASAP == -1) { |
| //Put into set before you recurse |
| visitedNodes.insert(node); |
| calculateASAP(*P, predAttributes, MII, visitedNodes); |
| predAttributes = nodeToAttributesMap.find(*P)->second; |
| } |
| int iteDiff = node->getInEdge(*P).getIteDiff(); |
| |
| int currentPredValue = predAttributes.ASAP + node->getLatency() - iteDiff * MII; |
| DEBUG(std::cerr << "Current ASAP pred: " << currentPredValue << "\n"); |
| maxPredValue = std::max(maxPredValue, currentPredValue); |
| } |
| visitedNodes.erase(node); |
| attributes.ASAP = maxPredValue; |
| } |
| else { |
| visitedNodes.erase(node); |
| attributes.ASAP = 0; |
| } |
| |
| DEBUG(std::cerr << "ASAP: " << attributes.ASAP << " (" << *node << ")\n"); |
| } |
| |
| |
| void ModuloSchedulingPass::calculateALAP(MSchedGraphNode *node, MSNodeAttributes &attributes, |
| int MII, int maxASAP, |
| std::set<MSchedGraphNode*> &visitedNodes) { |
| |
| DEBUG(std::cerr << "Calculating AlAP for " << *node << "\n"); |
| |
| if(attributes.ALAP != -1|| (visitedNodes.find(node) != visitedNodes.end())) { |
| visitedNodes.erase(node); |
| return; |
| } |
| if(node->hasSuccessors()) { |
| int minSuccValue = 0; |
| |
| //Iterate over all of the predecessors and fine max |
| for(MSchedGraphNode::succ_iterator P = node->succ_begin(), |
| E = node->succ_end(); P != E; ++P) { |
| |
| MSNodeAttributes succAttributes = nodeToAttributesMap.find(*P)->second; |
| if(succAttributes.ASAP == -1) { |
| |
| //Put into set before recursing |
| visitedNodes.insert(node); |
| |
| calculateALAP(*P, succAttributes, MII, maxASAP, visitedNodes); |
| succAttributes = nodeToAttributesMap.find(*P)->second; |
| assert(succAttributes.ASAP == -1 && "Successors ALAP should have been caclulated"); |
| } |
| int iteDiff = P.getEdge().getIteDiff(); |
| int currentSuccValue = succAttributes.ALAP + node->getLatency() + iteDiff * MII; |
| minSuccValue = std::min(minSuccValue, currentSuccValue); |
| } |
| visitedNodes.erase(node); |
| attributes.ALAP = minSuccValue; |
| } |
| else { |
| visitedNodes.erase(node); |
| attributes.ALAP = maxASAP; |
| } |
| DEBUG(std::cerr << "ALAP: " << attributes.ALAP << " (" << *node << ")\n"); |
| } |
| |
| int ModuloSchedulingPass::findMaxASAP() { |
| int maxASAP = 0; |
| |
| for(std::map<MSchedGraphNode*, MSNodeAttributes>::iterator I = nodeToAttributesMap.begin(), |
| E = nodeToAttributesMap.end(); I != E; ++I) |
| maxASAP = std::max(maxASAP, I->second.ASAP); |
| return maxASAP; |
| } |
| |
| |
| void ModuloSchedulingPass::calculateHeight(MSchedGraphNode *node, |
| MSNodeAttributes &attributes, |
| std::set<MSchedGraphNode*> &visitedNodes) { |
| |
| if(attributes.depth != -1 || (visitedNodes.find(node) != visitedNodes.end())) { |
| //Remove from map before returning |
| visitedNodes.erase(node); |
| return; |
| } |
| |
| if(node->hasSuccessors()) { |
| int maxHeight = 0; |
| |
| //Iterate over all of the predecessors and fine max |
| for(MSchedGraphNode::succ_iterator P = node->succ_begin(), |
| E = node->succ_end(); P != E; ++P) { |
| |
| MSNodeAttributes succAttributes = nodeToAttributesMap.find(*P)->second; |
| if(succAttributes.height == -1) { |
| |
| //Put into map before recursing |
| visitedNodes.insert(node); |
| |
| calculateHeight(*P, succAttributes, visitedNodes); |
| succAttributes = nodeToAttributesMap.find(*P)->second; |
| assert(succAttributes.height == -1 && "Successors Height should have been caclulated"); |
| } |
| int currentHeight = succAttributes.height + node->getLatency(); |
| maxHeight = std::max(maxHeight, currentHeight); |
| } |
| visitedNodes.erase(node); |
| attributes.height = maxHeight; |
| } |
| else { |
| visitedNodes.erase(node); |
| attributes.height = 0; |
| } |
| |
| DEBUG(std::cerr << "Height: " << attributes.height << " (" << *node << ")\n"); |
| } |
| |
| |
| void ModuloSchedulingPass::calculateDepth(MSchedGraphNode *node, |
| MSNodeAttributes &attributes, |
| std::set<MSchedGraphNode*> &visitedNodes) { |
| |
| if(attributes.depth != -1 || (visitedNodes.find(node) != visitedNodes.end())) { |
| //Remove from map before returning |
| visitedNodes.erase(node); |
| return; |
| } |
| |
| if(node->hasPredecessors()) { |
| int maxDepth = 0; |
| |
| //Iterate over all of the predecessors and fine max |
| for(MSchedGraphNode::pred_iterator P = node->pred_begin(), E = node->pred_end(); P != E; ++P) { |
| |
| //Get that nodes depth |
| MSNodeAttributes predAttributes = nodeToAttributesMap.find(*P)->second; |
| if(predAttributes.depth == -1) { |
| |
| //Put into set before recursing |
| visitedNodes.insert(node); |
| |
| calculateDepth(*P, predAttributes, visitedNodes); |
| predAttributes = nodeToAttributesMap.find(*P)->second; |
| assert(predAttributes.depth == -1 && "Predecessors ASAP should have been caclulated"); |
| } |
| int currentDepth = predAttributes.depth + node->getLatency(); |
| maxDepth = std::max(maxDepth, currentDepth); |
| } |
| |
| //Remove from map before returning |
| visitedNodes.erase(node); |
| |
| attributes.height = maxDepth; |
| } |
| else { |
| //Remove from map before returning |
| visitedNodes.erase(node); |
| attributes.depth = 0; |
| } |
| |
| DEBUG(std::cerr << "Depth: " << attributes.depth << " (" << *node << "*)\n"); |
| |
| } |
| |
| |
| void ModuloSchedulingPass::findAllReccurrences(MSchedGraphNode *node, |
| std::vector<MSchedGraphNode*> &visitedNodes) { |
| |
| if(find(visitedNodes.begin(), visitedNodes.end(), node) != visitedNodes.end()) { |
| //DUMP out recurrence |
| DEBUG(std::cerr << "Reccurrence:\n"); |
| bool first = true; |
| for(std::vector<MSchedGraphNode*>::iterator I = visitedNodes.begin(), E = visitedNodes.end(); |
| I !=E; ++I) { |
| if(*I == node) |
| first = false; |
| if(first) |
| continue; |
| DEBUG(std::cerr << **I << "\n"); |
| } |
| DEBUG(std::cerr << "End Reccurrence:\n"); |
| return; |
| } |
| |
| for(MSchedGraphNode::succ_iterator I = node->succ_begin(), E = node->succ_end(); I != E; ++I) { |
| visitedNodes.push_back(node); |
| findAllReccurrences(*I, visitedNodes); |
| visitedNodes.pop_back(); |
| } |
| |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| void ModuloSchedulingPass::orderNodes() { |
| |
| int BOTTOM_UP = 0; |
| int TOP_DOWN = 1; |
| |
| //FIXME: Group nodes into sets and order all the sets based on RecMII |
| typedef std::vector<MSchedGraphNode*> NodeVector; |
| typedef std::pair<int, NodeVector> NodeSet; |
| |
| std::vector<NodeSet> NodeSetsToOrder; |
| |
| //Order the resulting sets |
| NodeVector FinalNodeOrder; |
| |
| //Loop over all the sets and place them in the final node order |
| for(unsigned i=0; i < NodeSetsToOrder.size(); ++i) { |
| |
| //Set default order |
| int order = BOTTOM_UP; |
| |
| //Get Nodes in Current set |
| NodeVector CurrentSet = NodeSetsToOrder[i].second; |
| |
| //Loop through the predecessors for each node in the final order |
| //and only keeps nodes both in the pred_set and currentset |
| NodeVector IntersectCurrent; |
| |
| //Sort CurrentSet so we can use lowerbound |
| sort(CurrentSet.begin(), CurrentSet.end()); |
| |
| for(unsigned j=0; j < FinalNodeOrder.size(); ++j) { |
| for(MSchedGraphNode::pred_iterator P = FinalNodeOrder[j]->pred_begin(), |
| E = FinalNodeOrder[j]->pred_end(); P != E; ++P) { |
| if(lower_bound(CurrentSet.begin(), |
| CurrentSet.end(), *P) != CurrentSet.end()) |
| IntersectCurrent.push_back(*P); |
| } |
| } |
| |
| //If the intersection of predecessor and current set is not empty |
| //sort nodes bottom up |
| if(IntersectCurrent.size() != 0) |
| order = BOTTOM_UP; |
| |
| //If empty, use successors |
| else { |
| |
| for(unsigned j=0; j < FinalNodeOrder.size(); ++j) { |
| for(MSchedGraphNode::succ_iterator P = FinalNodeOrder[j]->succ_begin(), |
| E = FinalNodeOrder[j]->succ_end(); P != E; ++P) { |
| if(lower_bound(CurrentSet.begin(), |
| CurrentSet.end(), *P) != CurrentSet.end()) |
| IntersectCurrent.push_back(*P); |
| } |
| } |
| |
| //sort top-down |
| if(IntersectCurrent.size() != 0) |
| order = TOP_DOWN; |
| |
| else { |
| //Find node with max ASAP in current Set |
| MSchedGraphNode *node; |
| int maxASAP = 0; |
| for(unsigned j=0; j < CurrentSet.size(); ++j) { |
| //Get node attributes |
| MSNodeAttributes nodeAttr= nodeToAttributesMap.find(CurrentSet[j])->second; |
| //assert(nodeAttr != nodeToAttributesMap.end() && "Node not in attributes map!"); |
| |
| if(maxASAP < nodeAttr.ASAP) { |
| maxASAP = nodeAttr.ASAP; |
| node = CurrentSet[j]; |
| } |
| } |
| order = BOTTOM_UP; |
| } |
| } |
| |
| //Repeat until all nodes are put into the final order from current set |
| /*while(IntersectCurrent.size() > 0) { |
| |
| if(order == TOP_DOWN) { |
| while(IntersectCurrent.size() > 0) { |
| |
| //FIXME |
| //Get node attributes |
| MSNodeAttributes nodeAttr= nodeToAttributesMap.find(IntersectCurrent[0])->second; |
| assert(nodeAttr != nodeToAttributesMap.end() && "Node not in attributes map!"); |
| |
| //Get node with highest height, if a tie, use one with lowest |
| //MOB |
| int MOB = nodeAttr.MBO; |
| int height = nodeAttr.height; |
| ModuloSchedGraphNode *V = IntersectCurrent[0]; |
| |
| for(unsigned j=0; j < IntersectCurrent.size(); ++j) { |
| int temp = IntersectCurrent[j]->getHeight(); |
| if(height < temp) { |
| V = IntersectCurrent[j]; |
| height = temp; |
| MOB = V->getMobility(); |
| } |
| else if(height == temp) { |
| if(MOB > IntersectCurrent[j]->getMobility()) { |
| V = IntersectCurrent[j]; |
| height = temp; |
| MOB = V->getMobility(); |
| } |
| } |
| } |
| |
| //Append V to the NodeOrder |
| NodeOrder.push_back(V); |
| |
| //Remove V from IntersectOrder |
| IntersectCurrent.erase(find(IntersectCurrent.begin(), |
| IntersectCurrent.end(), V)); |
| |
| //Intersect V's successors with CurrentSet |
| for(mod_succ_iterator P = succ_begin(V), |
| E = succ_end(V); P != E; ++P) { |
| if(lower_bound(CurrentSet.begin(), |
| CurrentSet.end(), *P) != CurrentSet.end()) { |
| //If not already in Intersect, add |
| if(find(IntersectCurrent.begin(), IntersectCurrent.end(), *P) == IntersectCurrent.end()) |
| IntersectCurrent.push_back(*P); |
| } |
| } |
| } //End while loop over Intersect Size |
| |
| //Change direction |
| order = BOTTOM_UP; |
| |
| //Reset Intersect to reflect changes in OrderNodes |
| IntersectCurrent.clear(); |
| for(unsigned j=0; j < NodeOrder.size(); ++j) { |
| for(mod_pred_iterator P = pred_begin(NodeOrder[j]), |
| E = pred_end(NodeOrder[j]); P != E; ++P) { |
| if(lower_bound(CurrentSet.begin(), |
| CurrentSet.end(), *P) != CurrentSet.end()) |
| IntersectCurrent.push_back(*P); |
| } |
| } |
| } //End If TOP_DOWN |
| |
| //Begin if BOTTOM_UP |
| else { |
| while(IntersectCurrent.size() > 0) { |
| //Get node with highest depth, if a tie, use one with lowest |
| //MOB |
| int MOB = IntersectCurrent[0]->getMobility(); |
| int depth = IntersectCurrent[0]->getDepth(); |
| ModuloSchedGraphNode *V = IntersectCurrent[0]; |
| |
| for(unsigned j=0; j < IntersectCurrent.size(); ++j) { |
| int temp = IntersectCurrent[j]->getDepth(); |
| if(depth < temp) { |
| V = IntersectCurrent[j]; |
| depth = temp; |
| MOB = V->getMobility(); |
| } |
| else if(depth == temp) { |
| if(MOB > IntersectCurrent[j]->getMobility()) { |
| V = IntersectCurrent[j]; |
| depth = temp; |
| MOB = V->getMobility(); |
| } |
| } |
| } |
| |
| //Append V to the NodeOrder |
| NodeOrder.push_back(V); |
| |
| //Remove V from IntersectOrder |
| IntersectCurrent.erase(find(IntersectCurrent.begin(), |
| IntersectCurrent.end(),V)); |
| |
| //Intersect V's pred with CurrentSet |
| for(mod_pred_iterator P = pred_begin(V), |
| E = pred_end(V); P != E; ++P) { |
| if(lower_bound(CurrentSet.begin(), |
| CurrentSet.end(), *P) != CurrentSet.end()) { |
| //If not already in Intersect, add |
| if(find(IntersectCurrent.begin(), IntersectCurrent.end(), *P) == IntersectCurrent.end()) |
| IntersectCurrent.push_back(*P); |
| } |
| } |
| } //End while loop over Intersect Size |
| |
| //Change order |
| order = TOP_DOWN; |
| |
| //Reset IntersectCurrent to reflect changes in OrderNodes |
| IntersectCurrent.clear(); |
| for(unsigned j=0; j < NodeOrder.size(); ++j) { |
| for(mod_succ_iterator P = succ_begin(NodeOrder[j]), |
| E = succ_end(NodeOrder[j]); P != E; ++P) { |
| if(lower_bound(CurrentSet.begin(), |
| CurrentSet.end(), *P) != CurrentSet.end()) |
| IntersectCurrent.push_back(*P); |
| } |
| |
| } |
| } //End if BOTTOM_DOWN |
| |
| }*/ |
| //End Wrapping while loop |
| |
| }//End for over all sets of nodes |
| |
| //Return final Order |
| //return FinalNodeOrder; |
| } |