1 2#ifndef __CPU_O3_DEP_GRAPH_HH__ 3#define __CPU_O3_DEP_GRAPH_HH__ 4 5#include "cpu/o3/comm.hh" 6 |
7/** Node in a linked list. */ |
8template <class DynInstPtr> 9class DependencyEntry 10{ 11 public: 12 DependencyEntry() 13 : inst(NULL), next(NULL) 14 { } 15 16 DynInstPtr inst; 17 //Might want to include data about what arch. register the 18 //dependence is waiting on. 19 DependencyEntry<DynInstPtr> *next; 20}; 21 |
22/** Array of linked list that maintains the dependencies between 23 * producing instructions and consuming instructions. Each linked 24 * list represents a single physical register, having the future 25 * producer of the register's value, and all consumers waiting on that 26 * value on the list. The head node of each linked list represents 27 * the producing instruction of that register. Instructions are put 28 * on the list upon reaching the IQ, and are removed from the list 29 * either when the producer completes, or the instruction is squashed. 30*/ |
31template <class DynInstPtr> 32class DependencyGraph 33{ 34 public: 35 typedef DependencyEntry<DynInstPtr> DepEntry; 36 |
37 /** Default construction. Must call resize() prior to use. */ |
38 DependencyGraph() 39 : numEntries(0), memAllocCounter(0), nodesTraversed(0), nodesRemoved(0) 40 { } 41 |
42 /** Resize the dependency graph to have num_entries registers. */ |
43 void resize(int num_entries); 44 |
45 /** Clears all of the linked lists. */ |
46 void reset(); 47 |
48 /** Inserts an instruction to be dependent on the given index. */ |
49 void insert(PhysRegIndex idx, DynInstPtr &new_inst); 50 |
51 /** Sets the producing instruction of a given register. */ |
52 void setInst(PhysRegIndex idx, DynInstPtr &new_inst) 53 { dependGraph[idx].inst = new_inst; } 54 |
55 /** Clears the producing instruction. */ |
56 void clearInst(PhysRegIndex idx) 57 { dependGraph[idx].inst = NULL; } 58 |
59 /** Removes an instruction from a single linked list. */ |
60 void remove(PhysRegIndex idx, DynInstPtr &inst_to_remove); 61 |
62 /** Removes and returns the newest dependent of a specific register. */ |
63 DynInstPtr pop(PhysRegIndex idx); 64 |
65 /** Checks if there are any dependents on a specific register. */ |
66 bool empty(PhysRegIndex idx) { return !dependGraph[idx].next; } 67 68 /** Debugging function to dump out the dependency graph. 69 */ 70 void dump(); 71 72 private: 73 /** Array of linked lists. Each linked list is a list of all the 74 * instructions that depend upon a given register. The actual 75 * register's index is used to index into the graph; ie all 76 * instructions in flight that are dependent upon r34 will be 77 * in the linked list of dependGraph[34]. 78 */ 79 DepEntry *dependGraph; 80 |
81 /** Number of linked lists; identical to the number of registers. */ |
82 int numEntries; 83 84 // Debug variable, remove when done testing. 85 unsigned memAllocCounter; 86 87 public: |
88 // Debug variable, remove when done testing. |
89 uint64_t nodesTraversed; |
90 // Debug variable, remove when done testing. |
91 uint64_t nodesRemoved; 92}; 93 94template <class DynInstPtr> 95void 96DependencyGraph<DynInstPtr>::resize(int num_entries) 97{ 98 numEntries = num_entries; --- 137 unchanged lines hidden --- |