diff --git a/lib/CodeGen/ModuloScheduling/MSchedGraph.cpp b/lib/CodeGen/ModuloScheduling/MSchedGraph.cpp
new file mode 100644
index 0000000..b76a97f
--- /dev/null
+++ b/lib/CodeGen/ModuloScheduling/MSchedGraph.cpp
@@ -0,0 +1,391 @@
+//===-- MSchedGraph.h - Scheduling Graph ------------------------*- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// A graph class for dependencies
+//
+//===----------------------------------------------------------------------===//
+#define DEBUG_TYPE "ModuloSched"
+
+#include "MSchedGraph.h"
+#include "llvm/CodeGen/MachineBasicBlock.h"
+#include "llvm/Target/TargetInstrInfo.h"
+#include "Support/Debug.h"
+#include <iostream>
+using namespace llvm;
+
+MSchedGraphNode::MSchedGraphNode(const MachineInstr* inst, 
+				 MSchedGraph *graph, 
+				 unsigned late) 
+  : Inst(inst), Parent(graph), latency(late) {
+
+  //Add to the graph
+  graph->addNode(inst, this);
+}
+
+void MSchedGraphNode::print(std::ostream &os) const {
+  os << "MSehedGraphNode: Inst=" << *Inst << ", latency= " << latency << "\n"; 
+}
+
+MSchedGraphEdge MSchedGraphNode::getInEdge(MSchedGraphNode *pred) {
+  //Loop over all the successors of our predecessor
+  //return the edge the corresponds to this in edge
+  for(MSchedGraphNode::succ_iterator I = pred->succ_begin(), E = pred->succ_end();
+      I != E; ++I) {
+    if(*I == this)
+      return I.getEdge();
+  }
+  assert(0 && "Should have found edge between this node and its predecessor!");
+  
+}
+
+void MSchedGraph::addNode(const MachineInstr *MI,
+			  MSchedGraphNode *node) {
+  
+  //Make sure node does not already exist  
+  assert(GraphMap.find(MI) == GraphMap.end() 
+	 && "New MSchedGraphNode already exists for this instruction");
+  
+  GraphMap[MI] = node;
+}
+
+MSchedGraph::MSchedGraph(const MachineBasicBlock *bb, const TargetMachine &targ)
+  : BB(bb), Target(targ) {
+  
+  //Make sure BB is not null, 
+  assert(BB != NULL && "Basic Block is null");
+  
+  DEBUG(std::cerr << "Constructing graph for " << bb << "\n");
+
+  //Create nodes and edges for this BB
+  buildNodesAndEdges();
+}
+
+MSchedGraph::~MSchedGraph () {
+  for(MSchedGraph::iterator I = GraphMap.begin(), E = GraphMap.end(); I != E; ++I)
+    delete I->second;
+}
+
+void MSchedGraph::buildNodesAndEdges() {
+  
+  //Get Machine target information for calculating latency
+  const TargetInstrInfo &MTI = Target.getInstrInfo();
+
+  std::vector<MSchedGraphNode*> memInstructions;
+  std::map<int, std::vector<OpIndexNodePair> > regNumtoNodeMap;
+  std::map<const Value*, std::vector<OpIndexNodePair> > valuetoNodeMap;
+
+  //Save PHI instructions to deal with later
+  std::vector<const MachineInstr*> phiInstrs;
+
+  //Loop over instructions in MBB and add nodes and edges
+  for (MachineBasicBlock::const_iterator MI = BB->begin(), e = BB->end(); MI != e; ++MI) {
+    //Get each instruction of machine basic block, get the delay
+    //using the op code, create a new node for it, and add to the
+    //graph.
+    
+    MachineOpCode MIopCode = MI->getOpcode();
+    int delay;
+
+    //Check if subsequent instructions can be issued before
+    //the result is ready, if so use min delay.
+    if(MTI.hasResultInterlock(MIopCode))
+      delay = MTI.minLatency(MIopCode);
+    else
+      delay = MTI.maxLatency(MIopCode);
+    
+    //Create new node for this machine instruction and add to the graph.
+    //Create only if not a nop
+    if(MTI.isNop(MIopCode))
+      continue;
+    
+    //Add PHI to phi instruction list to be processed later
+    if (MIopCode == TargetInstrInfo::PHI)
+      phiInstrs.push_back(MI);
+
+    //Node is created and added to the graph automatically
+    MSchedGraphNode *node =  new MSchedGraphNode(MI, this, delay);
+
+    DEBUG(std::cerr << "Created Node: " << *node << "\n"); 
+    
+    //Check OpCode to keep track of memory operations to add memory dependencies later.
+    MachineOpCode opCode = MI->getOpcode();
+
+    if(MTI.isLoad(opCode) || MTI.isStore(opCode))
+      memInstructions.push_back(node);
+
+    //Loop over all operands, and put them into the register number to
+    //graph node map for determining dependencies
+    //If an operands is a use/def, we have an anti dependence to itself
+    for(unsigned i=0; i < MI->getNumOperands(); ++i) {
+      //Get Operand
+      const MachineOperand &mOp = MI->getOperand(i);
+      
+      //Check if it has an allocated register (Note: this means it
+      //is greater then zero because zero is a special register for
+      //Sparc that holds the constant zero
+      if(mOp.hasAllocatedReg()) {
+	int regNum = mOp.getReg();
+	
+	//Put into our map
+	regNumtoNodeMap[regNum].push_back(std::make_pair(i, node));
+	continue;
+      }
+      
+      
+      //Add virtual registers dependencies
+      //Check if any exist in the value map already and create dependencies
+      //between them.
+      if(mOp.getType() == MachineOperand::MO_VirtualRegister ||  mOp.getType() == MachineOperand::MO_CCRegister) {
+
+	//Make sure virtual register value is not null
+	assert((mOp.getVRegValue() != NULL) && "Null value is defined");
+
+	//Check if this is a read operation in a phi node, if so DO NOT PROCESS
+	if(mOp.isUse() && (MIopCode == TargetInstrInfo::PHI))
+	  continue;
+
+      
+	if (const Value* srcI = mOp.getVRegValue()) {
+	  
+	  //Find value in the map
+	  std::map<const Value*, std::vector<OpIndexNodePair> >::iterator V 
+	    = valuetoNodeMap.find(srcI);
+	  
+	  //If there is something in the map already, add edges from
+	  //those instructions
+	  //to this one we are processing
+	  if(V != valuetoNodeMap.end()) {
+	    addValueEdges(V->second, node, mOp.isUse(), mOp.isDef());
+	    
+	    //Add to value map
+	    V->second.push_back(std::make_pair(i,node));
+	  }
+	  //Otherwise put it in the map
+	  else
+	    //Put into value map
+	  valuetoNodeMap[mOp.getVRegValue()].push_back(std::make_pair(i, node));
+	}
+      } 
+    }
+  }
+  addMemEdges(memInstructions);
+  addMachRegEdges(regNumtoNodeMap);
+
+  //Finally deal with PHI Nodes and Value*
+  for(std::vector<const MachineInstr*>::iterator I = phiInstrs.begin(), E = phiInstrs.end(); I != E;  ++I) {
+    //Get Node for this instruction
+    MSchedGraphNode *node = find(*I)->second;
+  
+    //Loop over operands for this instruction and add value edges
+    for(unsigned i=0; i < (*I)->getNumOperands(); ++i) {
+      //Get Operand
+      const MachineOperand &mOp = (*I)->getOperand(i);
+      if((mOp.getType() == MachineOperand::MO_VirtualRegister ||  mOp.getType() == MachineOperand::MO_CCRegister) && mOp.isUse()) {
+	//find the value in the map
+	if (const Value* srcI = mOp.getVRegValue()) {
+	  
+	  //Find value in the map
+	  std::map<const Value*, std::vector<OpIndexNodePair> >::iterator V 
+	    = valuetoNodeMap.find(srcI);
+	  
+	  //If there is something in the map already, add edges from
+	  //those instructions
+	  //to this one we are processing
+	  if(V != valuetoNodeMap.end()) {
+	    addValueEdges(V->second, node, mOp.isUse(), mOp.isDef(), 1);
+	  }
+	}
+      }
+    }
+  }
+} 
+
+void MSchedGraph::addValueEdges(std::vector<OpIndexNodePair> &NodesInMap,
+				MSchedGraphNode *destNode, bool nodeIsUse, 
+				bool nodeIsDef, int diff) {
+
+  for(std::vector<OpIndexNodePair>::iterator I = NodesInMap.begin(), 
+	E = NodesInMap.end(); I != E; ++I) {
+    
+    //Get node in vectors machine operand that is the same value as node
+    MSchedGraphNode *srcNode = I->second;
+    MachineOperand mOp = srcNode->getInst()->getOperand(I->first);
+
+    //Node is a Def, so add output dep.
+    if(nodeIsDef) {
+      if(mOp.isUse())
+	srcNode->addOutEdge(destNode, MSchedGraphEdge::ValueDep, 
+			    MSchedGraphEdge::AntiDep, diff);
+      if(mOp.isDef())
+	srcNode->addOutEdge(destNode, MSchedGraphEdge::ValueDep, 
+			    MSchedGraphEdge::OutputDep, diff);
+      
+    }
+    if(nodeIsUse) {
+      if(mOp.isDef())
+	srcNode->addOutEdge(destNode, MSchedGraphEdge::ValueDep, 
+			    MSchedGraphEdge::TrueDep, diff);
+    }
+  } 
+}
+
+
+void MSchedGraph::addMachRegEdges(std::map<int, std::vector<OpIndexNodePair> >& regNumtoNodeMap) {
+  //Loop over all machine registers in the map, and add dependencies
+  //between the instructions that use it
+  typedef std::map<int, std::vector<OpIndexNodePair> > regNodeMap;
+  for(regNodeMap::iterator I = regNumtoNodeMap.begin(); I != regNumtoNodeMap.end(); ++I) {
+    //Get the register number
+    int regNum = (*I).first;
+
+    //Get Vector of nodes that use this register
+    std::vector<OpIndexNodePair> Nodes = (*I).second;
+    
+    //Loop over nodes and determine the dependence between the other
+    //nodes in the vector
+    for(unsigned i =0; i < Nodes.size(); ++i) {
+      
+      //Get src node operator index that uses this machine register
+      int srcOpIndex = Nodes[i].first;
+      
+      //Get the actual src Node
+      MSchedGraphNode *srcNode = Nodes[i].second;
+      
+      //Get Operand
+      const MachineOperand &srcMOp = srcNode->getInst()->getOperand(srcOpIndex);
+      
+      bool srcIsUseandDef = srcMOp.isDef() && srcMOp.isUse();
+      bool srcIsUse = srcMOp.isUse() && !srcMOp.isDef();
+      
+      
+      //Look at all instructions after this in execution order
+      for(unsigned j=i+1; j < Nodes.size(); ++j) {
+	
+	//Sink node is a write
+	if(Nodes[j].second->getInst()->getOperand(Nodes[j].first).isDef()) {
+	              //Src only uses the register (read)
+            if(srcIsUse)
+	      srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
+				  MSchedGraphEdge::AntiDep);
+	    
+            else if(srcIsUseandDef) {
+	      srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
+				  MSchedGraphEdge::AntiDep);
+	      
+	      srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
+				  MSchedGraphEdge::OutputDep);
+	    }
+            else
+	      srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
+				  MSchedGraphEdge::OutputDep);
+	}
+	//Dest node is a read
+	else {
+	  if(!srcIsUse || srcIsUseandDef)
+	    srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
+				MSchedGraphEdge::TrueDep);
+	}
+        
+      }
+      
+      //Look at all the instructions before this one since machine registers
+      //could live across iterations.
+      for(unsigned j = 0; j < i; ++j) {
+		//Sink node is a write
+	if(Nodes[j].second->getInst()->getOperand(Nodes[j].first).isDef()) {
+	              //Src only uses the register (read)
+            if(srcIsUse)
+	      srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
+				  MSchedGraphEdge::AntiDep, 1);
+	    
+            else if(srcIsUseandDef) {
+	      srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
+				  MSchedGraphEdge::AntiDep, 1);
+	      
+	      srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
+				  MSchedGraphEdge::OutputDep, 1);
+	    }
+            else
+	      srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
+				  MSchedGraphEdge::OutputDep, 1);
+	}
+	//Dest node is a read
+	else {
+	  if(!srcIsUse || srcIsUseandDef)
+	    srcNode->addOutEdge(Nodes[j].second, MSchedGraphEdge::MachineRegister,
+				MSchedGraphEdge::TrueDep,1 );
+	}
+	
+
+      }
+
+    }
+    
+  }
+  
+}
+
+void MSchedGraph::addMemEdges(const std::vector<MSchedGraphNode*>& memInst) {
+
+  //Get Target machine instruction info
+  const TargetInstrInfo& TMI = Target.getInstrInfo();
+  
+  //Loop over all memory instructions in the vector
+  //Knowing that they are in execution, add true, anti, and output dependencies
+  for (unsigned srcIndex = 0; srcIndex < memInst.size(); ++srcIndex) {
+
+    //Get the machine opCode to determine type of memory instruction
+    MachineOpCode srcNodeOpCode = memInst[srcIndex]->getInst()->getOpcode();
+      
+    //All instructions after this one in execution order have an iteration delay of 0
+    for(unsigned destIndex = srcIndex + 1; destIndex < memInst.size(); ++destIndex) {
+       
+      //source is a Load, so add anti-dependencies (store after load)
+      if(TMI.isLoad(srcNodeOpCode))
+	if(TMI.isStore(memInst[destIndex]->getInst()->getOpcode()))
+	  memInst[srcIndex]->addOutEdge(memInst[destIndex], 
+			      MSchedGraphEdge::MemoryDep, 
+			      MSchedGraphEdge::AntiDep);
+      
+      //If source is a store, add output and true dependencies
+      if(TMI.isStore(srcNodeOpCode)) {
+	if(TMI.isStore(memInst[destIndex]->getInst()->getOpcode()))
+	   memInst[srcIndex]->addOutEdge(memInst[destIndex], 
+			      MSchedGraphEdge::MemoryDep, 
+			      MSchedGraphEdge::OutputDep);
+	else
+	  memInst[srcIndex]->addOutEdge(memInst[destIndex], 
+			      MSchedGraphEdge::MemoryDep, 
+			      MSchedGraphEdge::TrueDep);
+      }
+    }
+    
+    //All instructions before the src in execution order have an iteration delay of 1
+    for(unsigned destIndex = 0; destIndex < srcIndex; ++destIndex) {
+      //source is a Load, so add anti-dependencies (store after load)
+      if(TMI.isLoad(srcNodeOpCode))
+	if(TMI.isStore(memInst[destIndex]->getInst()->getOpcode()))
+	  memInst[srcIndex]->addOutEdge(memInst[destIndex], 
+			      MSchedGraphEdge::MemoryDep, 
+			      MSchedGraphEdge::AntiDep, 1);
+      if(TMI.isStore(srcNodeOpCode)) {
+	if(TMI.isStore(memInst[destIndex]->getInst()->getOpcode()))
+	  memInst[srcIndex]->addOutEdge(memInst[destIndex], 
+			      MSchedGraphEdge::MemoryDep, 
+			      MSchedGraphEdge::OutputDep, 1);
+	else
+	  memInst[srcIndex]->addOutEdge(memInst[destIndex], 
+			      MSchedGraphEdge::MemoryDep, 
+			      MSchedGraphEdge::TrueDep, 1);
+      }
+	  
+    }
+    
+  }
+}
diff --git a/lib/CodeGen/ModuloScheduling/MSchedGraph.h b/lib/CodeGen/ModuloScheduling/MSchedGraph.h
new file mode 100644
index 0000000..9fe6b52
--- /dev/null
+++ b/lib/CodeGen/ModuloScheduling/MSchedGraph.h
@@ -0,0 +1,310 @@
+//===-- MSchedGraph.h - Scheduling Graph ------------------------*- 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// A graph class for dependencies
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MSCHEDGRAPH_H
+#define LLVM_MSCHEDGRAPH_H
+
+#include "llvm/CodeGen/MachineInstr.h"
+#include "llvm/Target/TargetMachine.h"
+#include "Support/GraphTraits.h"
+#include "Support/STLExtras.h"
+#include "Support/iterator"
+#include <vector>
+
+namespace llvm {
+  class MSchedGraph;
+  class MSchedGraphNode;
+  template<class IteratorType, class NodeType>
+  class MSchedGraphNodeIterator;
+
+
+  struct MSchedGraphEdge {
+    enum DataDepOrderType {
+      TrueDep, AntiDep, OutputDep, NonDataDep
+    };
+    
+    enum MSchedGraphEdgeType {
+      MemoryDep, ValueDep, MachineRegister
+    };
+
+    MSchedGraphNode *getDest() const { return dest; }
+    unsigned getIteDiff() { return iteDiff; }
+    unsigned getDepOrderType() { return depOrderType; }
+
+  private:
+    friend class MSchedGraphNode;
+    MSchedGraphEdge(MSchedGraphNode *destination, MSchedGraphEdgeType type, 
+		    unsigned deptype, unsigned diff) 
+      : dest(destination), depType(type), depOrderType(deptype), iteDiff(diff) {}
+    
+    MSchedGraphNode *dest;
+    MSchedGraphEdgeType depType;
+    unsigned depOrderType;
+    unsigned iteDiff;
+  };
+
+  class MSchedGraphNode {
+   
+    const MachineInstr* Inst; //Machine Instruction
+    MSchedGraph* Parent; //Graph this node belongs to
+    unsigned latency; //Latency of Instruction
+    
+    std::vector<MSchedGraphNode*> Predecessors; //Predecessor Nodes
+    std::vector<MSchedGraphEdge> Successors;
+
+  public:
+    MSchedGraphNode(const MachineInstr *inst, MSchedGraph *graph, 
+		    unsigned late=0);
+
+    //Iterators
+    typedef std::vector<MSchedGraphNode*>::iterator pred_iterator;
+    pred_iterator pred_begin() { return Predecessors.begin(); }
+    pred_iterator pred_end() { return Predecessors.end(); }
+    
+    typedef std::vector<MSchedGraphNode*>::const_iterator pred_const_iterator;
+    pred_const_iterator pred_begin() const { return Predecessors.begin(); }
+    pred_const_iterator pred_end() const { return Predecessors.end(); }
+
+    // Successor iterators.
+    typedef MSchedGraphNodeIterator<std::vector<MSchedGraphEdge>::const_iterator,
+				    const MSchedGraphNode> succ_const_iterator;
+    succ_const_iterator succ_begin() const;
+    succ_const_iterator succ_end() const;
+
+    typedef MSchedGraphNodeIterator<std::vector<MSchedGraphEdge>::iterator,
+				    MSchedGraphNode> succ_iterator;
+    succ_iterator succ_begin();
+    succ_iterator succ_end();
+    
+
+    void addOutEdge(MSchedGraphNode *destination, 
+		    MSchedGraphEdge::MSchedGraphEdgeType type, 
+		    unsigned deptype, unsigned diff=0) {
+      Successors.push_back(MSchedGraphEdge(destination, type, deptype,diff));
+      destination->Predecessors.push_back(this);
+    }
+    const MachineInstr* getInst() { return Inst; }
+    MSchedGraph* getParent() { return Parent; }
+    bool hasPredecessors() { return (Predecessors.size() > 0); }
+    bool hasSuccessors() { return (Successors.size() > 0); }
+    int getLatency() { return latency; }
+    MSchedGraphEdge getInEdge(MSchedGraphNode *pred);
+
+    //Debug support
+    void print(std::ostream &os) const;
+
+  };
+
+  template<class IteratorType, class NodeType>
+  class MSchedGraphNodeIterator : public forward_iterator<NodeType*, ptrdiff_t> {
+    IteratorType I;   // std::vector<MSchedGraphEdge>::iterator or const_iterator
+  public:
+    MSchedGraphNodeIterator(IteratorType i) : I(i) {}
+
+    bool operator==(const MSchedGraphNodeIterator RHS) const { return I == RHS.I; }
+    bool operator!=(const MSchedGraphNodeIterator RHS) const { return I != RHS.I; }
+
+    const MSchedGraphNodeIterator &operator=(const MSchedGraphNodeIterator &RHS) {
+      I = RHS.I;
+      return *this;
+    }
+
+    NodeType* operator*() const {
+      return I->getDest();
+    }
+    NodeType* operator->() const { return operator*(); }
+    
+    MSchedGraphNodeIterator& operator++() {                // Preincrement
+      ++I;
+      return *this;
+    }
+    MSchedGraphNodeIterator operator++(int) { // Postincrement
+      MSchedGraphNodeIterator tmp = *this; ++*this; return tmp; 
+    }
+
+    MSchedGraphEdge &getEdge() {
+      return *I;
+    }
+    const MSchedGraphEdge &getEdge() const {
+      return *I;
+    }
+  };
+
+  inline MSchedGraphNode::succ_const_iterator MSchedGraphNode::succ_begin() const {
+    return succ_const_iterator(Successors.begin());
+  }
+  inline MSchedGraphNode::succ_const_iterator MSchedGraphNode::succ_end() const {
+    return succ_const_iterator(Successors.end());
+  }
+  inline MSchedGraphNode::succ_iterator MSchedGraphNode::succ_begin() {
+    return succ_iterator(Successors.begin());
+  }
+  inline MSchedGraphNode::succ_iterator MSchedGraphNode::succ_end() {
+    return succ_iterator(Successors.end());
+  }
+
+  // ostream << operator for MSGraphNode class
+  inline std::ostream &operator<<(std::ostream &os, 
+				  const MSchedGraphNode &node) {
+    node.print(os);
+    return os;
+  }
+
+
+
+  class MSchedGraph {
+    
+    const MachineBasicBlock *BB; //Machine basic block
+    const TargetMachine &Target; //Target Machine
+        
+    //Nodes
+    std::map<const MachineInstr*, MSchedGraphNode*> GraphMap;
+
+    //Add Nodes and Edges to this graph for our BB
+    typedef std::pair<int, MSchedGraphNode*> OpIndexNodePair;
+    void buildNodesAndEdges();
+    void addValueEdges(std::vector<OpIndexNodePair> &NodesInMap, 
+		       MSchedGraphNode *node,
+		       bool nodeIsUse, bool nodeIsDef, int diff=0);
+    void addMachRegEdges(std::map<int, 
+			 std::vector<OpIndexNodePair> >& regNumtoNodeMap);
+    void addMemEdges(const std::vector<MSchedGraphNode*>& memInst);
+
+  public:
+    MSchedGraph(const MachineBasicBlock *bb, const TargetMachine &targ);
+    ~MSchedGraph();
+    
+    //Add Nodes to the Graph
+    void addNode(const MachineInstr* MI, MSchedGraphNode *node);
+    
+    //iterators 
+    typedef std::map<const MachineInstr*, MSchedGraphNode*>::iterator iterator;
+    typedef std::map<const MachineInstr*, MSchedGraphNode*>::const_iterator const_iterator;
+    typedef std::map<const MachineInstr*, MSchedGraphNode*>::reverse_iterator reverse_iterator;
+    iterator find(const MachineInstr* I) { return GraphMap.find(I); }
+    iterator end() { return GraphMap.end(); }
+    iterator begin() { return GraphMap.begin(); }
+    reverse_iterator rbegin() { return GraphMap.rbegin(); }
+    reverse_iterator rend() { return GraphMap.rend(); }
+    
+  };
+
+  
+  static MSchedGraphNode& getSecond(std::pair<const MachineInstr* const,
+					 MSchedGraphNode*> &Pair) {
+    return *Pair.second;
+  }
+
+
+
+  // Provide specializations of GraphTraits to be able to use graph
+  // iterators on the scheduling graph!
+  //
+  template <> struct GraphTraits<MSchedGraph*> {
+    typedef MSchedGraphNode NodeType;
+    typedef MSchedGraphNode::succ_iterator ChildIteratorType;
+    
+    static inline ChildIteratorType child_begin(NodeType *N) { 
+      return N->succ_begin(); 
+    }
+    static inline ChildIteratorType child_end(NodeType *N) { 
+      return N->succ_end();
+    }
+
+    typedef std::pointer_to_unary_function<std::pair<const MachineInstr* const,
+           MSchedGraphNode*>&, MSchedGraphNode&> DerefFun;
+
+    typedef mapped_iterator<MSchedGraph::iterator, DerefFun> nodes_iterator;
+    static nodes_iterator nodes_begin(MSchedGraph *G) {
+      return map_iterator(((MSchedGraph*)G)->begin(), DerefFun(getSecond));
+    }
+    static nodes_iterator nodes_end(MSchedGraph *G) {
+      return map_iterator(((MSchedGraph*)G)->end(), DerefFun(getSecond));
+    }
+    
+
+  };
+  
+  template <> struct GraphTraits<const MSchedGraph*> {
+    typedef const MSchedGraphNode NodeType;
+    typedef MSchedGraphNode::succ_const_iterator ChildIteratorType;
+    
+    static inline ChildIteratorType child_begin(NodeType *N) { 
+      return N->succ_begin(); 
+    }
+    static inline ChildIteratorType child_end(NodeType *N) { 
+      return N->succ_end();
+    }
+    typedef std::pointer_to_unary_function<std::pair<const MachineInstr* const,
+						     MSchedGraphNode*>&, MSchedGraphNode&> DerefFun;
+    
+    typedef mapped_iterator<MSchedGraph::iterator, DerefFun> nodes_iterator;
+    static nodes_iterator nodes_begin(MSchedGraph *G) {
+      return map_iterator(((MSchedGraph*)G)->begin(), DerefFun(getSecond));
+    }
+    static nodes_iterator nodes_end(MSchedGraph *G) {
+      return map_iterator(((MSchedGraph*)G)->end(), DerefFun(getSecond));
+    }
+  };
+  
+  template <> struct GraphTraits<Inverse<MSchedGraph*> > {
+    typedef MSchedGraphNode NodeType;
+    typedef MSchedGraphNode::pred_iterator ChildIteratorType;
+    
+    static inline ChildIteratorType child_begin(NodeType *N) { 
+      return N->pred_begin();
+    }
+    static inline ChildIteratorType child_end(NodeType *N) { 
+      return N->pred_end();
+    }
+    typedef std::pointer_to_unary_function<std::pair<const MachineInstr* const,
+           MSchedGraphNode*>&, MSchedGraphNode&> DerefFun;
+
+    typedef mapped_iterator<MSchedGraph::iterator, DerefFun> nodes_iterator;
+    static nodes_iterator nodes_begin(MSchedGraph *G) {
+      return map_iterator(((MSchedGraph*)G)->begin(), DerefFun(getSecond));
+    }
+    static nodes_iterator nodes_end(MSchedGraph *G) {
+      return map_iterator(((MSchedGraph*)G)->end(), DerefFun(getSecond));
+    }
+  };
+  
+  template <> struct GraphTraits<Inverse<const MSchedGraph*> > {
+    typedef const MSchedGraphNode NodeType;
+    typedef MSchedGraphNode::pred_const_iterator ChildIteratorType;
+    
+    static inline ChildIteratorType child_begin(NodeType *N) { 
+      return N->pred_begin();
+    }
+    static inline ChildIteratorType child_end(NodeType *N) { 
+      return N->pred_end();
+    }
+
+    typedef std::pointer_to_unary_function<std::pair<const MachineInstr* const,
+						     MSchedGraphNode*>&, MSchedGraphNode&> DerefFun;
+    
+    typedef mapped_iterator<MSchedGraph::iterator, DerefFun> nodes_iterator;
+    static nodes_iterator nodes_begin(MSchedGraph *G) {
+      return map_iterator(((MSchedGraph*)G)->begin(), DerefFun(getSecond));
+    }
+    static nodes_iterator nodes_end(MSchedGraph *G) {
+      return map_iterator(((MSchedGraph*)G)->end(), DerefFun(getSecond));
+    }
+  };
+
+
+
+
+}
+
+#endif
diff --git a/lib/CodeGen/ModuloScheduling/ModuloScheduling.h b/lib/CodeGen/ModuloScheduling/ModuloScheduling.h
new file mode 100644
index 0000000..296d705
--- /dev/null
+++ b/lib/CodeGen/ModuloScheduling/ModuloScheduling.h
@@ -0,0 +1,68 @@
+//===-- ModuloScheduling.h - Swing Modulo Scheduling------------*- 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.
+//
+//===----------------------------------------------------------------------===//
+// 
+// 
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_MODULOSCHEDULING_H
+#define LLVM_MODULOSCHEDULING_H
+
+#include "MSchedGraph.h"
+#include "llvm/Function.h"
+#include "llvm/Pass.h"
+#include <set>
+
+namespace llvm {
+  
+
+  //Struct to contain ModuloScheduling Specific Information for each node
+  struct MSNodeAttributes {
+    int ASAP; //Earliest time at which the opreation can be scheduled
+    int ALAP; //Latest time at which the operation can be scheduled.
+    int MOB;
+    int depth;
+    int height;
+    MSNodeAttributes(int asap=-1, int alap=-1, int mob=-1, 
+			     int d=-1, int h=-1) : ASAP(asap), ALAP(alap), 
+						   MOB(mob), depth(d), 
+						   height(h) {}
+  };
+
+
+  class ModuloSchedulingPass : public FunctionPass {
+    const TargetMachine &target;
+
+    //Map that holds node to node attribute information
+    std::map<MSchedGraphNode*, MSNodeAttributes> nodeToAttributesMap;
+
+    //Internal functions
+    bool MachineBBisValid(const MachineBasicBlock *BI);
+    int calculateResMII(const MachineBasicBlock *BI);
+    void calculateNodeAttributes(MSchedGraph *graph, int MII);
+    void calculateASAP(MSchedGraphNode *node, MSNodeAttributes &attributes, 
+		       int MII,std::set<MSchedGraphNode*> &visitedNodes);
+    void calculateALAP(MSchedGraphNode *node, MSNodeAttributes &attributes, int MII, 
+		       int maxASAP, std::set<MSchedGraphNode*> &visitedNodes);
+    void calculateHeight(MSchedGraphNode *node, 
+			 MSNodeAttributes &attributes, std::set<MSchedGraphNode*> &visitedNodes);
+    void calculateDepth(MSchedGraphNode *node, MSNodeAttributes &attributes, 
+			std::set<MSchedGraphNode*> &visitedNodes);
+
+    int findMaxASAP();
+    void ModuloSchedulingPass::orderNodes();
+    void findAllReccurrences(MSchedGraphNode *node, std::vector<MSchedGraphNode*> &visitedNodes);
+  public:
+    ModuloSchedulingPass(TargetMachine &targ) : target(targ) {}
+    virtual bool runOnFunction(Function &F);
+  };
+
+}
+
+
+#endif
