1/*
| 1/*
|
2 * Copyright (c) 2004-2005 The Regents of The University of Michigan
| 2 * Copyright (c) 2004-2006 The Regents of The University of Michigan
|
3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28
| 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are 7 * met: redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer; 9 * redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution; 12 * neither the name of the copyright holders nor the names of its 13 * contributors may be used to endorse or promote products derived from 14 * this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28
|
29#ifndef __CPU_O3_CPU_INST_QUEUE_HH__ 30#define __CPU_O3_CPU_INST_QUEUE_HH__
| 29#ifndef __CPU_O3_INST_QUEUE_HH__ 30#define __CPU_O3_INST_QUEUE_HH__
|
31 32#include <list> 33#include <map> 34#include <queue> 35#include <vector> 36 37#include "base/statistics.hh" 38#include "base/timebuf.hh" 39#include "cpu/inst_seq.hh"
| 31 32#include <list> 33#include <map> 34#include <queue> 35#include <vector> 36 37#include "base/statistics.hh" 38#include "base/timebuf.hh" 39#include "cpu/inst_seq.hh"
|
| 40#include "cpu/o3/dep_graph.hh" 41#include "encumbered/cpu/full/op_class.hh"
|
40#include "sim/host.hh" 41
| 42#include "sim/host.hh" 43
|
| 44class FUPool; 45class MemInterface; 46
|
42/** 43 * A standard instruction queue class. It holds ready instructions, in 44 * order, in seperate priority queues to facilitate the scheduling of 45 * instructions. The IQ uses a separate linked list to track dependencies. 46 * Similar to the rename map and the free list, it expects that 47 * floating point registers have their indices start after the integer 48 * registers (ie with 96 int and 96 fp registers, regs 0-95 are integer 49 * and 96-191 are fp). This remains true even for both logical and
| 47/** 48 * A standard instruction queue class. It holds ready instructions, in 49 * order, in seperate priority queues to facilitate the scheduling of 50 * instructions. The IQ uses a separate linked list to track dependencies. 51 * Similar to the rename map and the free list, it expects that 52 * floating point registers have their indices start after the integer 53 * registers (ie with 96 int and 96 fp registers, regs 0-95 are integer 54 * and 96-191 are fp). This remains true even for both logical and
|
50 * physical register indices.
| 55 * physical register indices. The IQ depends on the memory dependence unit to 56 * track when memory operations are ready in terms of ordering; register 57 * dependencies are tracked normally. Right now the IQ also handles the 58 * execution timing; this is mainly to allow back-to-back scheduling without 59 * requiring IEW to be able to peek into the IQ. At the end of the execution 60 * latency, the instruction is put into the queue to execute, where it will 61 * have the execute() function called on it. 62 * @todo: Make IQ able to handle multiple FU pools.
|
51 */ 52template <class Impl> 53class InstructionQueue 54{ 55 public: 56 //Typedefs from the Impl. 57 typedef typename Impl::FullCPU FullCPU; 58 typedef typename Impl::DynInstPtr DynInstPtr; 59 typedef typename Impl::Params Params; 60
| 63 */ 64template <class Impl> 65class InstructionQueue 66{ 67 public: 68 //Typedefs from the Impl. 69 typedef typename Impl::FullCPU FullCPU; 70 typedef typename Impl::DynInstPtr DynInstPtr; 71 typedef typename Impl::Params Params; 72
|
| 73 typedef typename Impl::CPUPol::IEW IEW;
|
61 typedef typename Impl::CPUPol::MemDepUnit MemDepUnit; 62 typedef typename Impl::CPUPol::IssueStruct IssueStruct; 63 typedef typename Impl::CPUPol::TimeStruct TimeStruct; 64
| 74 typedef typename Impl::CPUPol::MemDepUnit MemDepUnit; 75 typedef typename Impl::CPUPol::IssueStruct IssueStruct; 76 typedef typename Impl::CPUPol::TimeStruct TimeStruct; 77
|
65 // Typedef of iterator through the list of instructions. Might be 66 // better to untie this from the FullCPU or pass its information to 67 // the stages.
| 78 // Typedef of iterator through the list of instructions.
|
68 typedef typename std::list<DynInstPtr>::iterator ListIt; 69
| 79 typedef typename std::list<DynInstPtr>::iterator ListIt; 80
|
70 /** 71 * Struct for comparing entries to be added to the priority queue. This 72 * gives reverse ordering to the instructions in terms of sequence 73 * numbers: the instructions with smaller sequence numbers (and hence 74 * are older) will be at the top of the priority queue. 75 */ 76 struct pqCompare 77 { 78 bool operator() (const DynInstPtr &lhs, const DynInstPtr &rhs) const 79 { 80 return lhs->seqNum > rhs->seqNum; 81 } 82 };
| 81 friend class Impl::FullCPU;
|
83
| 82
|
84 /** 85 * Struct for comparing entries to be added to the set. This gives 86 * standard ordering in terms of sequence numbers. 87 */ 88 struct setCompare 89 { 90 bool operator() (const DynInstPtr &lhs, const DynInstPtr &rhs) const 91 { 92 return lhs->seqNum < rhs->seqNum; 93 }
| 83 /** FU completion event class. */ 84 class FUCompletion : public Event { 85 private: 86 /** Executing instruction. */ 87 DynInstPtr inst; 88 89 /** Index of the FU used for executing. */ 90 int fuIdx; 91 92 /** Pointer back to the instruction queue. */ 93 InstructionQueue<Impl> *iqPtr; 94 95 bool freeFU; 96 97 public: 98 /** Construct a FU completion event. */ 99 FUCompletion(DynInstPtr &_inst, int fu_idx, 100 InstructionQueue<Impl> *iq_ptr); 101 102 virtual void process(); 103 virtual const char *description(); 104 void setFreeFU() { freeFU = true; }
|
94 }; 95
| 105 }; 106
|
96 typedef std::priority_queue<DynInstPtr, vector<DynInstPtr>, pqCompare> 97 ReadyInstQueue;
| 107 /** Constructs an IQ. */ 108 InstructionQueue(Params *params);
|
98
| 109
|
99 InstructionQueue(Params ¶ms);
| 110 /** Destructs the IQ. */ 111 ~InstructionQueue();
|
100
| 112
|
| 113 /** Returns the name of the IQ. */ 114 std::string name() const; 115 116 /** Registers statistics. */
|
101 void regStats(); 102
| 117 void regStats(); 118
|
103 void setCPU(FullCPU *cpu);
| 119 void resetState();
|
104
| 120
|
| 121 /** Sets CPU pointer. */ 122 void setCPU(FullCPU *_cpu) { cpu = _cpu; } 123 124 /** Sets active threads list. */ 125 void setActiveThreads(std::list<unsigned> *at_ptr); 126 127 /** Sets the IEW pointer. */ 128 void setIEW(IEW *iew_ptr) { iewStage = iew_ptr; } 129 130 /** Sets the timer buffer between issue and execute. */
|
105 void setIssueToExecuteQueue(TimeBuffer<IssueStruct> *i2eQueue); 106
| 131 void setIssueToExecuteQueue(TimeBuffer<IssueStruct> *i2eQueue); 132
|
| 133 /** Sets the global time buffer. */
|
107 void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr); 108
| 134 void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr); 135
|
| 136 void switchOut(); 137 138 void takeOverFrom(); 139 140 bool isSwitchedOut() { return switchedOut; } 141 142 /** Number of entries needed for given amount of threads. */ 143 int entryAmount(int num_threads); 144 145 /** Resets max entries for all threads. */ 146 void resetEntries(); 147 148 /** Returns total number of free entries. */
|
109 unsigned numFreeEntries(); 110
| 149 unsigned numFreeEntries(); 150
|
| 151 /** Returns number of free entries for a thread. */ 152 unsigned numFreeEntries(unsigned tid); 153 154 /** Returns whether or not the IQ is full. */
|
111 bool isFull(); 112
| 155 bool isFull(); 156
|
| 157 /** Returns whether or not the IQ is full for a specific thread. */ 158 bool isFull(unsigned tid); 159 160 /** Returns if there are any ready instructions in the IQ. */ 161 bool hasReadyInsts(); 162 163 /** Inserts a new instruction into the IQ. */
|
113 void insert(DynInstPtr &new_inst); 114
| 164 void insert(DynInstPtr &new_inst); 165
|
| 166 /** Inserts a new, non-speculative instruction into the IQ. */
|
115 void insertNonSpec(DynInstPtr &new_inst); 116
| 167 void insertNonSpec(DynInstPtr &new_inst); 168
|
117 void advanceTail(DynInstPtr &inst);
| 169 /** Inserts a memory or write barrier into the IQ to make sure 170 * loads and stores are ordered properly. 171 */ 172 void insertBarrier(DynInstPtr &barr_inst);
|
118
| 173
|
| 174 DynInstPtr getInstToExecute(); 175 176 /** 177 * Records the instruction as the producer of a register without 178 * adding it to the rest of the IQ. 179 */ 180 void recordProducer(DynInstPtr &inst) 181 { addToProducers(inst); } 182 183 /** Process FU completion event. */ 184 void processFUCompletion(DynInstPtr &inst, int fu_idx); 185 186 /** 187 * Schedules ready instructions, adding the ready ones (oldest first) to 188 * the queue to execute. 189 */
|
119 void scheduleReadyInsts(); 120
| 190 void scheduleReadyInsts(); 191
|
| 192 /** Schedules a single specific non-speculative instruction. */
|
121 void scheduleNonSpec(const InstSeqNum &inst); 122
| 193 void scheduleNonSpec(const InstSeqNum &inst); 194
|
123 void wakeDependents(DynInstPtr &completed_inst);
| 195 /** 196 * Commits all instructions up to and including the given sequence number, 197 * for a specific thread. 198 */ 199 void commit(const InstSeqNum &inst, unsigned tid = 0);
|
124
| 200
|
| 201 /** Wakes all dependents of a completed instruction. */ 202 int wakeDependents(DynInstPtr &completed_inst); 203 204 /** Adds a ready memory instruction to the ready list. */ 205 void addReadyMemInst(DynInstPtr &ready_inst); 206 207 /** 208 * Reschedules a memory instruction. It will be ready to issue once 209 * replayMemInst() is called. 210 */ 211 void rescheduleMemInst(DynInstPtr &resched_inst); 212 213 /** Replays a memory instruction. It must be rescheduled first. */ 214 void replayMemInst(DynInstPtr &replay_inst); 215 216 /** Completes a memory operation. */ 217 void completeMemInst(DynInstPtr &completed_inst); 218 219 /** Indicates an ordering violation between a store and a load. */
|
125 void violation(DynInstPtr &store, DynInstPtr &faulting_load); 126
| 220 void violation(DynInstPtr &store, DynInstPtr &faulting_load); 221
|
127 // Change this to take in the sequence number 128 void squash();
| 222 /** 223 * Squashes instructions for a thread. Squashing information is obtained 224 * from the time buffer. 225 */ 226 void squash(unsigned tid);
|
129
| 227
|
130 void doSquash();
| 228 /** Returns the number of used entries for a thread. */ 229 unsigned getCount(unsigned tid) { return count[tid]; };
|
131
| 230
|
132 void stopSquash();
| 231 /** Debug function to print all instructions. */ 232 void printInsts();
|
133 134 private:
| 233 234 private:
|
| 235 /** Does the actual squashing. */ 236 void doSquash(unsigned tid); 237 238 ///////////////////////// 239 // Various pointers 240 ///////////////////////// 241
|
135 /** Pointer to the CPU. */ 136 FullCPU *cpu; 137
| 242 /** Pointer to the CPU. */ 243 FullCPU *cpu; 244
|
| 245 /** Cache interface. */ 246 MemInterface *dcacheInterface; 247 248 /** Pointer to IEW stage. */ 249 IEW *iewStage; 250
|
138 /** The memory dependence unit, which tracks/predicts memory dependences 139 * between instructions. 140 */
| 251 /** The memory dependence unit, which tracks/predicts memory dependences 252 * between instructions. 253 */
|
141 MemDepUnit memDepUnit;
| 254 MemDepUnit memDepUnit[Impl::MaxThreads];
|
142 143 /** The queue to the execute stage. Issued instructions will be written 144 * into it. 145 */ 146 TimeBuffer<IssueStruct> *issueToExecuteQueue; 147 148 /** The backwards time buffer. */ 149 TimeBuffer<TimeStruct> *timeBuffer; 150 151 /** Wire to read information from timebuffer. */ 152 typename TimeBuffer<TimeStruct>::wire fromCommit; 153
| 255 256 /** The queue to the execute stage. Issued instructions will be written 257 * into it. 258 */ 259 TimeBuffer<IssueStruct> *issueToExecuteQueue; 260 261 /** The backwards time buffer. */ 262 TimeBuffer<TimeStruct> *timeBuffer; 263 264 /** Wire to read information from timebuffer. */ 265 typename TimeBuffer<TimeStruct>::wire fromCommit; 266
|
154 enum InstList { 155 Int, 156 Float, 157 Branch, 158 Memory, 159 Misc, 160 Squashed, 161 None 162 };
| 267 /** Function unit pool. */ 268 FUPool *fuPool;
|
163
| 269
|
164 /** List of ready int instructions. Used to keep track of the order in 165 * which instructions should issue. 166 */ 167 ReadyInstQueue readyIntInsts;
| 270 ////////////////////////////////////// 271 // Instruction lists, ready queues, and ordering 272 //////////////////////////////////////
|
168
| 273
|
169 /** List of ready floating point instructions. */ 170 ReadyInstQueue readyFloatInsts;
| 274 /** List of all the instructions in the IQ (some of which may be issued). */ 275 std::list<DynInstPtr> instList[Impl::MaxThreads];
|
171
| 276
|
172 /** List of ready branch instructions. */ 173 ReadyInstQueue readyBranchInsts;
| 277 std::list<DynInstPtr> instsToExecute;
|
174
| 278
|
175 /** List of ready miscellaneous instructions. */ 176 ReadyInstQueue readyMiscInsts;
| 279 /** 280 * Struct for comparing entries to be added to the priority queue. This 281 * gives reverse ordering to the instructions in terms of sequence 282 * numbers: the instructions with smaller sequence numbers (and hence 283 * are older) will be at the top of the priority queue. 284 */ 285 struct pqCompare { 286 bool operator() (const DynInstPtr &lhs, const DynInstPtr &rhs) const 287 { 288 return lhs->seqNum > rhs->seqNum; 289 } 290 };
|
177
| 291
|
178 /** List of squashed instructions (which are still valid and in IQ). 179 * Implemented using a priority queue; the entries must contain both 180 * the IQ index and sequence number of each instruction so that 181 * ordering based on sequence numbers can be used.
| 292 typedef std::priority_queue<DynInstPtr, std::vector<DynInstPtr>, pqCompare> 293 ReadyInstQueue; 294 295 /** List of ready instructions, per op class. They are separated by op 296 * class to allow for easy mapping to FUs.
|
182 */
| 297 */
|
183 ReadyInstQueue squashedInsts;
| 298 ReadyInstQueue readyInsts[Num_OpClasses];
|
184 185 /** List of non-speculative instructions that will be scheduled 186 * once the IQ gets a signal from commit. While it's redundant to 187 * have the key be a part of the value (the sequence number is stored 188 * inside of DynInst), when these instructions are woken up only 189 * the sequence number will be available. Thus it is most efficient to be 190 * able to search by the sequence number alone. 191 */ 192 std::map<InstSeqNum, DynInstPtr> nonSpecInsts; 193
| 299 300 /** List of non-speculative instructions that will be scheduled 301 * once the IQ gets a signal from commit. While it's redundant to 302 * have the key be a part of the value (the sequence number is stored 303 * inside of DynInst), when these instructions are woken up only 304 * the sequence number will be available. Thus it is most efficient to be 305 * able to search by the sequence number alone. 306 */ 307 std::map<InstSeqNum, DynInstPtr> nonSpecInsts; 308
|
194 typedef typename std::map<InstSeqNum, DynInstPtr>::iterator non_spec_it_t;
| 309 typedef typename std::map<InstSeqNum, DynInstPtr>::iterator NonSpecMapIt;
|
195
| 310
|
196 /** Number of free IQ entries left. */ 197 unsigned freeEntries;
| 311 /** Entry for the list age ordering by op class. */ 312 struct ListOrderEntry { 313 OpClass queueType; 314 InstSeqNum oldestInst; 315 };
|
198
| 316
|
199 /** The number of entries in the instruction queue. */ 200 unsigned numEntries;
| 317 /** List that contains the age order of the oldest instruction of each 318 * ready queue. Used to select the oldest instruction available 319 * among op classes. 320 * @todo: Might be better to just move these entries around instead 321 * of creating new ones every time the position changes due to an 322 * instruction issuing. Not sure std::list supports this. 323 */ 324 std::list<ListOrderEntry> listOrder;
|
201
| 325
|
202 /** The number of integer instructions that can be issued in one 203 * cycle.
| 326 typedef typename std::list<ListOrderEntry>::iterator ListOrderIt; 327 328 /** Tracks if each ready queue is on the age order list. */ 329 bool queueOnList[Num_OpClasses]; 330 331 /** Iterators of each ready queue. Points to their spot in the age order 332 * list.
|
204 */
| 333 */
|
205 unsigned intWidth;
| 334 ListOrderIt readyIt[Num_OpClasses];
|
206
| 335
|
207 /** The number of floating point instructions that can be issued 208 * in one cycle.
| 336 /** Add an op class to the age order list. */ 337 void addToOrderList(OpClass op_class); 338 339 /** 340 * Called when the oldest instruction has been removed from a ready queue; 341 * this places that ready queue into the proper spot in the age order list.
|
209 */
| 342 */
|
210 unsigned floatWidth;
| 343 void moveToYoungerInst(ListOrderIt age_order_it);
|
211
| 344
|
212 /** The number of branches that can be issued in one cycle. */ 213 unsigned branchWidth;
| 345 DependencyGraph<DynInstPtr> dependGraph;
|
214
| 346
|
215 /** The number of memory instructions that can be issued in one cycle. */ 216 unsigned memoryWidth;
| 347 ////////////////////////////////////// 348 // Various parameters 349 //////////////////////////////////////
|
217
| 350
|
| 351 /** IQ Resource Sharing Policy */ 352 enum IQPolicy { 353 Dynamic, 354 Partitioned, 355 Threshold 356 }; 357 358 /** IQ sharing policy for SMT. */ 359 IQPolicy iqPolicy; 360 361 /** Number of Total Threads*/ 362 unsigned numThreads; 363 364 /** Pointer to list of active threads. */ 365 std::list<unsigned> *activeThreads; 366 367 /** Per Thread IQ count */ 368 unsigned count[Impl::MaxThreads]; 369 370 /** Max IQ Entries Per Thread */ 371 unsigned maxEntries[Impl::MaxThreads]; 372 373 /** Number of free IQ entries left. */ 374 unsigned freeEntries; 375 376 /** The number of entries in the instruction queue. */ 377 unsigned numEntries; 378
|
218 /** The total number of instructions that can be issued in one cycle. */ 219 unsigned totalWidth; 220
| 379 /** The total number of instructions that can be issued in one cycle. */ 380 unsigned totalWidth; 381
|
221 //The number of physical registers in the CPU.
| 382 /** The number of physical registers in the CPU. */
|
222 unsigned numPhysRegs; 223 224 /** The number of physical integer registers in the CPU. */ 225 unsigned numPhysIntRegs; 226 227 /** The number of floating point registers in the CPU. */ 228 unsigned numPhysFloatRegs; 229 230 /** Delay between commit stage and the IQ. 231 * @todo: Make there be a distinction between the delays within IEW. 232 */ 233 unsigned commitToIEWDelay; 234
| 383 unsigned numPhysRegs; 384 385 /** The number of physical integer registers in the CPU. */ 386 unsigned numPhysIntRegs; 387 388 /** The number of floating point registers in the CPU. */ 389 unsigned numPhysFloatRegs; 390 391 /** Delay between commit stage and the IQ. 392 * @todo: Make there be a distinction between the delays within IEW. 393 */ 394 unsigned commitToIEWDelay; 395
|
235 ////////////////////////////////// 236 // Variables needed for squashing 237 //////////////////////////////////
| 396 bool switchedOut;
|
238 239 /** The sequence number of the squashed instruction. */
| 397 398 /** The sequence number of the squashed instruction. */
|
240 InstSeqNum squashedSeqNum;
| 399 InstSeqNum squashedSeqNum[Impl::MaxThreads];
|
241
| 400
|
242 /** Iterator that points to the youngest instruction in the IQ. */ 243 ListIt tail; 244 245 /** Iterator that points to the last instruction that has been squashed. 246 * This will not be valid unless the IQ is in the process of squashing. 247 */ 248 ListIt squashIt; 249 250 /////////////////////////////////// 251 // Dependency graph stuff 252 /////////////////////////////////// 253 254 class DependencyEntry 255 { 256 public: 257 DynInstPtr inst; 258 //Might want to include data about what arch. register the 259 //dependence is waiting on. 260 DependencyEntry *next; 261 262 //This function, and perhaps this whole class, stand out a little 263 //bit as they don't fit a classification well. I want access 264 //to the underlying structure of the linked list, yet at 265 //the same time it feels like this should be something abstracted 266 //away. So for now it will sit here, within the IQ, until 267 //a better implementation is decided upon. 268 // This function probably shouldn't be within the entry... 269 void insert(DynInstPtr &new_inst); 270 271 void remove(DynInstPtr &inst_to_remove); 272 273 // Debug variable, remove when done testing. 274 static unsigned mem_alloc_counter; 275 }; 276 277 /** Array of linked lists. Each linked list is a list of all the 278 * instructions that depend upon a given register. The actual 279 * register's index is used to index into the graph; ie all 280 * instructions in flight that are dependent upon r34 will be 281 * in the linked list of dependGraph[34]. 282 */ 283 DependencyEntry *dependGraph; 284
| |
285 /** A cache of the recently woken registers. It is 1 if the register 286 * has been woken up recently, and 0 if the register has been added 287 * to the dependency graph and has not yet received its value. It 288 * is basically a secondary scoreboard, and should pretty much mirror 289 * the scoreboard that exists in the rename map. 290 */
| 401 /** A cache of the recently woken registers. It is 1 if the register 402 * has been woken up recently, and 0 if the register has been added 403 * to the dependency graph and has not yet received its value. It 404 * is basically a secondary scoreboard, and should pretty much mirror 405 * the scoreboard that exists in the rename map. 406 */
|
291 vector regScoreboard;
| 407 std::vector<bool> regScoreboard;
|
292
| 408
|
| 409 /** Adds an instruction to the dependency graph, as a consumer. */
|
293 bool addToDependents(DynInstPtr &new_inst);
| 410 bool addToDependents(DynInstPtr &new_inst);
|
294 void insertDependency(DynInstPtr &new_inst); 295 void createDependency(DynInstPtr &new_inst);
| |
296
| 411
|
| 412 /** Adds an instruction to the dependency graph, as a producer. */ 413 void addToProducers(DynInstPtr &new_inst); 414 415 /** Moves an instruction to the ready queue if it is ready. */
|
297 void addIfReady(DynInstPtr &inst); 298
| 416 void addIfReady(DynInstPtr &inst); 417
|
299 private:
| |
300 /** Debugging function to count how many entries are in the IQ. It does 301 * a linear walk through the instructions, so do not call this function 302 * during normal execution. 303 */ 304 int countInsts(); 305
| 418 /** Debugging function to count how many entries are in the IQ. It does 419 * a linear walk through the instructions, so do not call this function 420 * during normal execution. 421 */ 422 int countInsts(); 423
|
306 /** Debugging function to dump out the dependency graph. 307 */ 308 void dumpDependGraph(); 309
| |
310 /** Debugging function to dump all the list sizes, as well as print 311 * out the list of nonspeculative instructions. Should not be used 312 * in any other capacity, but it has no harmful sideaffects. 313 */ 314 void dumpLists(); 315
| 424 /** Debugging function to dump all the list sizes, as well as print 425 * out the list of nonspeculative instructions. Should not be used 426 * in any other capacity, but it has no harmful sideaffects. 427 */ 428 void dumpLists(); 429
|
| 430 /** Debugging function to dump out all instructions that are in the 431 * IQ. 432 */ 433 void dumpInsts(); 434 435 /** Stat for number of instructions added. */
|
316 Stats::Scalar<> iqInstsAdded;
| 436 Stats::Scalar<> iqInstsAdded;
|
| 437 /** Stat for number of non-speculative instructions added. */
|
317 Stats::Scalar<> iqNonSpecInstsAdded;
| 438 Stats::Scalar<> iqNonSpecInstsAdded;
|
318// Stats::Scalar<> iqIntInstsAdded;
| 439 440 Stats::Scalar<> iqInstsIssued; 441 /** Stat for number of integer instructions issued. */
|
319 Stats::Scalar<> iqIntInstsIssued;
| 442 Stats::Scalar<> iqIntInstsIssued;
|
320// Stats::Scalar<> iqFloatInstsAdded;
| 443 /** Stat for number of floating point instructions issued. */
|
321 Stats::Scalar<> iqFloatInstsIssued;
| 444 Stats::Scalar<> iqFloatInstsIssued;
|
322// Stats::Scalar<> iqBranchInstsAdded;
| 445 /** Stat for number of branch instructions issued. */
|
323 Stats::Scalar<> iqBranchInstsIssued;
| 446 Stats::Scalar<> iqBranchInstsIssued;
|
324// Stats::Scalar<> iqMemInstsAdded;
| 447 /** Stat for number of memory instructions issued. */
|
325 Stats::Scalar<> iqMemInstsIssued;
| 448 Stats::Scalar<> iqMemInstsIssued;
|
326// Stats::Scalar<> iqMiscInstsAdded;
| 449 /** Stat for number of miscellaneous instructions issued. */
|
327 Stats::Scalar<> iqMiscInstsIssued;
| 450 Stats::Scalar<> iqMiscInstsIssued;
|
| 451 /** Stat for number of squashed instructions that were ready to issue. */
|
328 Stats::Scalar<> iqSquashedInstsIssued;
| 452 Stats::Scalar<> iqSquashedInstsIssued;
|
329 Stats::Scalar<> iqLoopSquashStalls;
| 453 /** Stat for number of squashed instructions examined when squashing. */
|
330 Stats::Scalar<> iqSquashedInstsExamined;
| 454 Stats::Scalar<> iqSquashedInstsExamined;
|
| 455 /** Stat for number of squashed instruction operands examined when 456 * squashing. 457 */
|
331 Stats::Scalar<> iqSquashedOperandsExamined;
| 458 Stats::Scalar<> iqSquashedOperandsExamined;
|
| 459 /** Stat for number of non-speculative instructions removed due to a squash. 460 */
|
332 Stats::Scalar<> iqSquashedNonSpecRemoved; 333
| 461 Stats::Scalar<> iqSquashedNonSpecRemoved; 462
|
| 463 Stats::VectorDistribution<> queueResDist; 464 Stats::Distribution<> numIssuedDist; 465 Stats::VectorDistribution<> issueDelayDist; 466 467 Stats::Vector<> statFuBusy; 468// Stats::Vector<> dist_unissued; 469 Stats::Vector2d<> statIssuedInstType; 470 471 Stats::Formula issueRate; 472// Stats::Formula issue_stores; 473// Stats::Formula issue_op_rate; 474 Stats::Vector<> fuBusy; //cumulative fu busy 475 476 Stats::Formula fuBusyRate;
|
334}; 335
| 477}; 478
|
336#endif //__CPU_O3_CPU_INST_QUEUE_HH__
| 479#endif //__CPU_O3_INST_QUEUE_HH__
|
| |