Removing old graph files with new graph files that I wrote. Updated ModuloScheduling...
authorTanya Lattner <tonic@nondot.org>
Mon, 1 Mar 2004 02:50:01 +0000 (02:50 +0000)
committerTanya Lattner <tonic@nondot.org>
Mon, 1 Mar 2004 02:50:01 +0000 (02:50 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@12030 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/ModuloScheduling/ModuloSchedGraph.cpp [deleted file]
lib/CodeGen/ModuloScheduling/ModuloSchedGraph.h [deleted file]
lib/CodeGen/ModuloScheduling/ModuloScheduling.cpp
lib/Target/SparcV9/ModuloScheduling/ModuloSchedGraph.cpp [deleted file]
lib/Target/SparcV9/ModuloScheduling/ModuloSchedGraph.h [deleted file]
lib/Target/SparcV9/ModuloScheduling/ModuloScheduling.cpp

diff --git a/lib/CodeGen/ModuloScheduling/ModuloSchedGraph.cpp b/lib/CodeGen/ModuloScheduling/ModuloSchedGraph.cpp
deleted file mode 100644 (file)
index 8aaaa2b..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-//===- ModuloSchedGraph.cpp - Modulo Scheduling Graph and Set -*- 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.
-// 
-//===----------------------------------------------------------------------===//
-// 
-// Description here
-//===----------------------------------------------------------------------===//
-
-#include "ModuloSchedGraph.h"
-#include "llvm/Type.h"
-
-namespace llvm {
-
-ModuloSchedGraphNode::ModuloSchedGraphNode(unsigned id, int index, 
-                                          const Instruction *inst, 
-                                          const TargetMachine &targ) 
-  : SchedGraphNodeCommon(id, index), Inst(inst), Target(targ) {
-}
-
-void ModuloSchedGraphNode::print(std::ostream &os) const {
-  os << "Modulo Scheduling Node\n";
-}
-
-ModuloSchedGraph::ModuloSchedGraph(const BasicBlock *bb, const TargetMachine &targ) 
-  : SchedGraphCommon(), BB(bb), Target(targ) {
-
-  assert(BB != NULL && "Basic Block is null");
-
-  //Builds nodes from each instruction in the basic block
-  buildNodesForBB();
-
-}
-
-void ModuloSchedGraph::buildNodesForBB() {
-  int count = 0;
-  for (BasicBlock::const_iterator i = BB->begin(), e = BB->end(); i != e; ++i) {
-    addNode(i,new ModuloSchedGraphNode(size(), count, i, Target));
-    count++;
-  }
-
-           //Get machine instruction(s) for the llvm instruction
-           //MachineCodeForInstruction &MC = MachineCodeForInstruction::get(Node->first);
-           
-
-}
-
-void ModuloSchedGraph::addNode(const Instruction *I,
-                              ModuloSchedGraphNode *node) {
-  assert(node!= NULL && "New ModuloSchedGraphNode is null");
-  GraphMap[I] = node;
-}
-
-void ModuloSchedGraph::addDepEdges() {
-  
-  //Get Machine target information for calculating delay
-  const TargetInstrInfo &MTI = Target.getInstrInfo();
-  
-  //Loop over instruction in BB and gather dependencies
-  for(BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
-    
-    //Ignore instructions of the void type
-    if(I->getType() != Type::VoidTy) {
-      
-      //Iterate over def-use chain and add true dependencies
-      for (Value::use_const_iterator U = I->use_begin(), e = I->use_end(); U != e; 
-          ++U) {
-       if (Instruction *Inst = dyn_cast<Instruction>(*U)) {
-         //Check if a node already exists for this instruction
-         ModuloSchedGraph::iterator Sink = find(Inst);
-         
-         //If the instruction is in our graph, add appropriate edges
-         if(Sink->second != NULL) {
-           //assert if self loop
-           assert(&*I == Sink->first && "Use edge to itself!");
-           
-           //Create edge and set delay equal to node latency
-           //FIXME: Is it safe to do this?
-           ModuloSchedGraph::iterator Src = find(I);
-           SchedGraphEdge *trueDep = new SchedGraphEdge(&*Src->second ,&*Sink->second,
-                                                        &*I, SchedGraphEdge::TrueDep,
-                                                        Src->second->getLatency());
-           //Determine the iteration difference
-           //FIXME: Will this ever happen?
-         }
-       }
-      }
-    }
-    
-  }
-  
-  
-}
-
-void ModuloSchedGraph::ASAP() {
-
-
-}
-
-void ModuloSchedGraph::ALAP() {
-
-
-}
-
-void ModuloSchedGraph::MOB() {
-
-}
-
-void ModuloSchedGraph::ComputeDepth() {
-
-}
-
-void  ModuloSchedGraph::ComputeHeight() {
-
-}
-
-void ModuloSchedGraphSet::addGraph(ModuloSchedGraph *graph) {
-  assert(graph!=NULL && "Graph for BasicBlock is null");
-  Graphs.push_back(graph);
-}
-
-
-ModuloSchedGraphSet::ModuloSchedGraphSet(const Function *F, 
-                                        const TargetMachine &targ) 
-  : function(F) {
-
-  //Create graph for each BB in this function
-  for (Function::const_iterator BI = F->begin(); BI != F->end(); ++BI)
-    addGraph(new ModuloSchedGraph(BI, targ));
-}
-
-ModuloSchedGraphSet::~ModuloSchedGraphSet(){
-  
-  //delete all the graphs
-}
-
-} // End llvm namespace
diff --git a/lib/CodeGen/ModuloScheduling/ModuloSchedGraph.h b/lib/CodeGen/ModuloScheduling/ModuloSchedGraph.h
deleted file mode 100644 (file)
index 552d699..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-//===- ModuloSchedGraph.h - Modulo Scheduling Graph and Set -*- 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.
-// 
-//===----------------------------------------------------------------------===//
-// 
-// TODO: Need a description here.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_MODULO_SCHED_GRAPH_H
-#define LLVM_MODULO_SCHED_GRAPH_H
-
-#include "llvm/Instruction.h"
-#include "llvm/CodeGen/SchedGraphCommon.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/BasicBlock.h"
-#include "llvm/Function.h"
-#include "Support/hash_map"
-#include <vector>
-
-namespace llvm {
-
-class ModuloSchedGraphNode : public SchedGraphNodeCommon {
-
-  const Instruction *Inst;  //Node's Instruction
-  unsigned Earliest;        //ASAP, or earliest time to be scheduled
-  unsigned Latest;          //ALAP, or latested time to be scheduled
-  unsigned Depth;           //Max Distance from node to the root
-  unsigned Height;          //Max Distance from node to leaf
-  unsigned Mobility;        //MOB, number of time slots it can be scheduled
-  const TargetMachine &Target; //Target information.
-
-public:
-  ModuloSchedGraphNode(unsigned ID, int index, const Instruction *inst, 
-                      const TargetMachine &target);
-  
-  void print(std::ostream &os) const;
-  const Instruction* getInst() { return Inst; }
-  unsigned getEarliest() { return Earliest; }
-  unsigned getLatest() { return Latest; }
-  unsigned getDepth() { return Depth; }
-  unsigned getHeight() { return Height; }
-  unsigned getMobility() { return Mobility; }
-  
-  void setEarliest(unsigned early) { Earliest = early; }
-  void setLatest(unsigned late) { Latest = late; }
-  void setDepth(unsigned depth) { Depth = depth; }
-  void setHeight(unsigned height) { Height = height; }
-  void setMobility(unsigned mob) { Mobility = mob; }
-
-
-};
-
-class ModuloSchedGraph : public SchedGraphCommon {
-  
-  const BasicBlock *BB; //The Basic block this graph represents
-  const TargetMachine &Target;
-  hash_map<const Instruction*, ModuloSchedGraphNode*> GraphMap;
-
-  void buildNodesForBB();
-
-public:
-  typedef hash_map<const Instruction*, 
-                  ModuloSchedGraphNode*>::iterator iterator;
-  typedef hash_map<const Instruction*, 
-                  ModuloSchedGraphNode*>::const_iterator const_iterator;
-
-
-  ModuloSchedGraph(const BasicBlock *bb, const TargetMachine &targ);
-
-  const BasicBlock* getBB() { return BB; }
-  void setBB(BasicBlock *bb) { BB = bb; }
-  unsigned size() { return GraphMap.size(); }
-  void addNode(const Instruction *I, ModuloSchedGraphNode *node);
-  void ASAP(); //Calculate earliest schedule time for all nodes in graph.
-  void ALAP(); //Calculate latest schedule time for all nodes in graph.
-  void MOB(); //Calculate mobility for all nodes in the graph.
-  void ComputeDepth(); //Compute depth of each node in graph
-  void ComputeHeight(); //Computer height of each node in graph
-  void addDepEdges(); //Add Dependencies
-  iterator find(const Instruction *I) { return GraphMap.find(I); }
-};
-
-
-class ModuloSchedGraphSet {
-  
-  const Function *function; //Function this set of graphs represent.
-  std::vector<ModuloSchedGraph*> Graphs;
-
-public:
-  typedef std::vector<ModuloSchedGraph*>::iterator iterator;
-  typedef std::vector<ModuloSchedGraph*>::const_iterator const_iterator;
-  iterator begin() { return Graphs.begin(); }
-  iterator end() { return Graphs.end(); }
-  ModuloSchedGraphSet(const Function *func, const TargetMachine &target);
-  ~ModuloSchedGraphSet();
-
-  void addGraph(ModuloSchedGraph *graph);
-  void dump() const;
-
-
-};
-
-} // End llvm namespace
-
-#endif
index 219d892d3143397bf117c62fb8fc00264405c6b0..acc0276c920260b62c62b1511cf3342e7e9b425d 100644 (file)
-//===-- ModuloScheduling.cpp - Software Pipeling Approach - SMS -----------===//
-// 
+//===-- 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.
-// 
+//
 //===----------------------------------------------------------------------===//
 //
-// The is a software pipelining pass based on the Swing Modulo Scheduling
-// algorithm (SMS).
+// 
 //
 //===----------------------------------------------------------------------===//
 
-#include "ModuloSchedGraph.h"
-#include "llvm/Function.h"
-#include "llvm/Pass.h"
+#define DEBUG_TYPE "ModuloSched"
 
-namespace llvm {
+#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); 
+}
 
-namespace {
+template<typename GraphType>
+static void WriteGraphToFile(std::ostream &O, const std::string &GraphName,
+                             const GraphType &GT) {
+  std::string Filename = GraphName + ".dot";
+  O << "Writing '" << Filename << "'...";
+  std::ofstream F(Filename.c_str());
   
-  class ModuloScheduling : public FunctionPass {
+  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";
+    }
     
-  public:
-    virtual bool runOnFunction(Function &F);
-  };
+    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;
+  }
 
-  RegisterOpt<ModuloScheduling> X("modulo-sched",
-                                  "Modulo Scheduling/Software Pipelining");
-}
 
-/// Create Modulo Scheduling Pass
-/// 
-Pass *createModuloSchedPass() {
-  return new ModuloScheduling(); 
+
+  };
 }
 
 /// ModuloScheduling::runOnFunction - main transformation entry point
-///
-bool ModuloScheduling::runOnFunction(Function &F) {
+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;
 }
 
-} // End llvm namespace
+
+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;
+}
diff --git a/lib/Target/SparcV9/ModuloScheduling/ModuloSchedGraph.cpp b/lib/Target/SparcV9/ModuloScheduling/ModuloSchedGraph.cpp
deleted file mode 100644 (file)
index 8aaaa2b..0000000
+++ /dev/null
@@ -1,140 +0,0 @@
-//===- ModuloSchedGraph.cpp - Modulo Scheduling Graph and Set -*- 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.
-// 
-//===----------------------------------------------------------------------===//
-// 
-// Description here
-//===----------------------------------------------------------------------===//
-
-#include "ModuloSchedGraph.h"
-#include "llvm/Type.h"
-
-namespace llvm {
-
-ModuloSchedGraphNode::ModuloSchedGraphNode(unsigned id, int index, 
-                                          const Instruction *inst, 
-                                          const TargetMachine &targ) 
-  : SchedGraphNodeCommon(id, index), Inst(inst), Target(targ) {
-}
-
-void ModuloSchedGraphNode::print(std::ostream &os) const {
-  os << "Modulo Scheduling Node\n";
-}
-
-ModuloSchedGraph::ModuloSchedGraph(const BasicBlock *bb, const TargetMachine &targ) 
-  : SchedGraphCommon(), BB(bb), Target(targ) {
-
-  assert(BB != NULL && "Basic Block is null");
-
-  //Builds nodes from each instruction in the basic block
-  buildNodesForBB();
-
-}
-
-void ModuloSchedGraph::buildNodesForBB() {
-  int count = 0;
-  for (BasicBlock::const_iterator i = BB->begin(), e = BB->end(); i != e; ++i) {
-    addNode(i,new ModuloSchedGraphNode(size(), count, i, Target));
-    count++;
-  }
-
-           //Get machine instruction(s) for the llvm instruction
-           //MachineCodeForInstruction &MC = MachineCodeForInstruction::get(Node->first);
-           
-
-}
-
-void ModuloSchedGraph::addNode(const Instruction *I,
-                              ModuloSchedGraphNode *node) {
-  assert(node!= NULL && "New ModuloSchedGraphNode is null");
-  GraphMap[I] = node;
-}
-
-void ModuloSchedGraph::addDepEdges() {
-  
-  //Get Machine target information for calculating delay
-  const TargetInstrInfo &MTI = Target.getInstrInfo();
-  
-  //Loop over instruction in BB and gather dependencies
-  for(BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
-    
-    //Ignore instructions of the void type
-    if(I->getType() != Type::VoidTy) {
-      
-      //Iterate over def-use chain and add true dependencies
-      for (Value::use_const_iterator U = I->use_begin(), e = I->use_end(); U != e; 
-          ++U) {
-       if (Instruction *Inst = dyn_cast<Instruction>(*U)) {
-         //Check if a node already exists for this instruction
-         ModuloSchedGraph::iterator Sink = find(Inst);
-         
-         //If the instruction is in our graph, add appropriate edges
-         if(Sink->second != NULL) {
-           //assert if self loop
-           assert(&*I == Sink->first && "Use edge to itself!");
-           
-           //Create edge and set delay equal to node latency
-           //FIXME: Is it safe to do this?
-           ModuloSchedGraph::iterator Src = find(I);
-           SchedGraphEdge *trueDep = new SchedGraphEdge(&*Src->second ,&*Sink->second,
-                                                        &*I, SchedGraphEdge::TrueDep,
-                                                        Src->second->getLatency());
-           //Determine the iteration difference
-           //FIXME: Will this ever happen?
-         }
-       }
-      }
-    }
-    
-  }
-  
-  
-}
-
-void ModuloSchedGraph::ASAP() {
-
-
-}
-
-void ModuloSchedGraph::ALAP() {
-
-
-}
-
-void ModuloSchedGraph::MOB() {
-
-}
-
-void ModuloSchedGraph::ComputeDepth() {
-
-}
-
-void  ModuloSchedGraph::ComputeHeight() {
-
-}
-
-void ModuloSchedGraphSet::addGraph(ModuloSchedGraph *graph) {
-  assert(graph!=NULL && "Graph for BasicBlock is null");
-  Graphs.push_back(graph);
-}
-
-
-ModuloSchedGraphSet::ModuloSchedGraphSet(const Function *F, 
-                                        const TargetMachine &targ) 
-  : function(F) {
-
-  //Create graph for each BB in this function
-  for (Function::const_iterator BI = F->begin(); BI != F->end(); ++BI)
-    addGraph(new ModuloSchedGraph(BI, targ));
-}
-
-ModuloSchedGraphSet::~ModuloSchedGraphSet(){
-  
-  //delete all the graphs
-}
-
-} // End llvm namespace
diff --git a/lib/Target/SparcV9/ModuloScheduling/ModuloSchedGraph.h b/lib/Target/SparcV9/ModuloScheduling/ModuloSchedGraph.h
deleted file mode 100644 (file)
index 552d699..0000000
+++ /dev/null
@@ -1,112 +0,0 @@
-//===- ModuloSchedGraph.h - Modulo Scheduling Graph and Set -*- 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.
-// 
-//===----------------------------------------------------------------------===//
-// 
-// TODO: Need a description here.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_MODULO_SCHED_GRAPH_H
-#define LLVM_MODULO_SCHED_GRAPH_H
-
-#include "llvm/Instruction.h"
-#include "llvm/CodeGen/SchedGraphCommon.h"
-#include "llvm/Target/TargetMachine.h"
-#include "llvm/BasicBlock.h"
-#include "llvm/Function.h"
-#include "Support/hash_map"
-#include <vector>
-
-namespace llvm {
-
-class ModuloSchedGraphNode : public SchedGraphNodeCommon {
-
-  const Instruction *Inst;  //Node's Instruction
-  unsigned Earliest;        //ASAP, or earliest time to be scheduled
-  unsigned Latest;          //ALAP, or latested time to be scheduled
-  unsigned Depth;           //Max Distance from node to the root
-  unsigned Height;          //Max Distance from node to leaf
-  unsigned Mobility;        //MOB, number of time slots it can be scheduled
-  const TargetMachine &Target; //Target information.
-
-public:
-  ModuloSchedGraphNode(unsigned ID, int index, const Instruction *inst, 
-                      const TargetMachine &target);
-  
-  void print(std::ostream &os) const;
-  const Instruction* getInst() { return Inst; }
-  unsigned getEarliest() { return Earliest; }
-  unsigned getLatest() { return Latest; }
-  unsigned getDepth() { return Depth; }
-  unsigned getHeight() { return Height; }
-  unsigned getMobility() { return Mobility; }
-  
-  void setEarliest(unsigned early) { Earliest = early; }
-  void setLatest(unsigned late) { Latest = late; }
-  void setDepth(unsigned depth) { Depth = depth; }
-  void setHeight(unsigned height) { Height = height; }
-  void setMobility(unsigned mob) { Mobility = mob; }
-
-
-};
-
-class ModuloSchedGraph : public SchedGraphCommon {
-  
-  const BasicBlock *BB; //The Basic block this graph represents
-  const TargetMachine &Target;
-  hash_map<const Instruction*, ModuloSchedGraphNode*> GraphMap;
-
-  void buildNodesForBB();
-
-public:
-  typedef hash_map<const Instruction*, 
-                  ModuloSchedGraphNode*>::iterator iterator;
-  typedef hash_map<const Instruction*, 
-                  ModuloSchedGraphNode*>::const_iterator const_iterator;
-
-
-  ModuloSchedGraph(const BasicBlock *bb, const TargetMachine &targ);
-
-  const BasicBlock* getBB() { return BB; }
-  void setBB(BasicBlock *bb) { BB = bb; }
-  unsigned size() { return GraphMap.size(); }
-  void addNode(const Instruction *I, ModuloSchedGraphNode *node);
-  void ASAP(); //Calculate earliest schedule time for all nodes in graph.
-  void ALAP(); //Calculate latest schedule time for all nodes in graph.
-  void MOB(); //Calculate mobility for all nodes in the graph.
-  void ComputeDepth(); //Compute depth of each node in graph
-  void ComputeHeight(); //Computer height of each node in graph
-  void addDepEdges(); //Add Dependencies
-  iterator find(const Instruction *I) { return GraphMap.find(I); }
-};
-
-
-class ModuloSchedGraphSet {
-  
-  const Function *function; //Function this set of graphs represent.
-  std::vector<ModuloSchedGraph*> Graphs;
-
-public:
-  typedef std::vector<ModuloSchedGraph*>::iterator iterator;
-  typedef std::vector<ModuloSchedGraph*>::const_iterator const_iterator;
-  iterator begin() { return Graphs.begin(); }
-  iterator end() { return Graphs.end(); }
-  ModuloSchedGraphSet(const Function *func, const TargetMachine &target);
-  ~ModuloSchedGraphSet();
-
-  void addGraph(ModuloSchedGraph *graph);
-  void dump() const;
-
-
-};
-
-} // End llvm namespace
-
-#endif
index 219d892d3143397bf117c62fb8fc00264405c6b0..acc0276c920260b62c62b1511cf3342e7e9b425d 100644 (file)
-//===-- ModuloScheduling.cpp - Software Pipeling Approach - SMS -----------===//
-// 
+//===-- 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.
-// 
+//
 //===----------------------------------------------------------------------===//
 //
-// The is a software pipelining pass based on the Swing Modulo Scheduling
-// algorithm (SMS).
+// 
 //
 //===----------------------------------------------------------------------===//
 
-#include "ModuloSchedGraph.h"
-#include "llvm/Function.h"
-#include "llvm/Pass.h"
+#define DEBUG_TYPE "ModuloSched"
 
-namespace llvm {
+#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); 
+}
 
-namespace {
+template<typename GraphType>
+static void WriteGraphToFile(std::ostream &O, const std::string &GraphName,
+                             const GraphType &GT) {
+  std::string Filename = GraphName + ".dot";
+  O << "Writing '" << Filename << "'...";
+  std::ofstream F(Filename.c_str());
   
-  class ModuloScheduling : public FunctionPass {
+  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";
+    }
     
-  public:
-    virtual bool runOnFunction(Function &F);
-  };
+    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;
+  }
 
-  RegisterOpt<ModuloScheduling> X("modulo-sched",
-                                  "Modulo Scheduling/Software Pipelining");
-}
 
-/// Create Modulo Scheduling Pass
-/// 
-Pass *createModuloSchedPass() {
-  return new ModuloScheduling(); 
+
+  };
 }
 
 /// ModuloScheduling::runOnFunction - main transformation entry point
-///
-bool ModuloScheduling::runOnFunction(Function &F) {
+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;
 }
 
-} // End llvm namespace
+
+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;
+}