inst_queue.hh revision 2301
15083Sgblack@eecs.umich.edu/* 25083Sgblack@eecs.umich.edu * Copyright (c) 2004-2005 The Regents of The University of Michigan 35083Sgblack@eecs.umich.edu * All rights reserved. 47087Snate@binkert.org * 57087Snate@binkert.org * Redistribution and use in source and binary forms, with or without 67087Snate@binkert.org * modification, are permitted provided that the following conditions are 77087Snate@binkert.org * met: redistributions of source code must retain the above copyright 87087Snate@binkert.org * notice, this list of conditions and the following disclaimer; 97087Snate@binkert.org * redistributions in binary form must reproduce the above copyright 107087Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 117087Snate@binkert.org * documentation and/or other materials provided with the distribution; 125083Sgblack@eecs.umich.edu * neither the name of the copyright holders nor the names of its 137087Snate@binkert.org * contributors may be used to endorse or promote products derived from 147087Snate@binkert.org * this software without specific prior written permission. 157087Snate@binkert.org * 167087Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 177087Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 187087Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 197087Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 207087Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 215083Sgblack@eecs.umich.edu * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 227087Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 235083Sgblack@eecs.umich.edu * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 245083Sgblack@eecs.umich.edu * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 255083Sgblack@eecs.umich.edu * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 265083Sgblack@eecs.umich.edu * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 275083Sgblack@eecs.umich.edu */ 285083Sgblack@eecs.umich.edu 295083Sgblack@eecs.umich.edu#ifndef __CPU_O3_INST_QUEUE_HH__ 305083Sgblack@eecs.umich.edu#define __CPU_O3_INST_QUEUE_HH__ 315083Sgblack@eecs.umich.edu 325083Sgblack@eecs.umich.edu#include <list> 335083Sgblack@eecs.umich.edu#include <map> 345083Sgblack@eecs.umich.edu#include <queue> 355083Sgblack@eecs.umich.edu#include <vector> 365083Sgblack@eecs.umich.edu 375083Sgblack@eecs.umich.edu#include "base/statistics.hh" 385083Sgblack@eecs.umich.edu#include "base/timebuf.hh" 395083Sgblack@eecs.umich.edu#include "cpu/inst_seq.hh" 405083Sgblack@eecs.umich.edu#include "encumbered/cpu/full/op_class.hh" 415083Sgblack@eecs.umich.edu#include "sim/host.hh" 425083Sgblack@eecs.umich.edu 435083Sgblack@eecs.umich.educlass FUPool; 445083Sgblack@eecs.umich.educlass MemInterface; 455083Sgblack@eecs.umich.edu 465083Sgblack@eecs.umich.edu/** 475083Sgblack@eecs.umich.edu * A standard instruction queue class. It holds ready instructions, in 485083Sgblack@eecs.umich.edu * order, in seperate priority queues to facilitate the scheduling of 495083Sgblack@eecs.umich.edu * instructions. The IQ uses a separate linked list to track dependencies. 505083Sgblack@eecs.umich.edu * Similar to the rename map and the free list, it expects that 515083Sgblack@eecs.umich.edu * floating point registers have their indices start after the integer 525083Sgblack@eecs.umich.edu * registers (ie with 96 int and 96 fp registers, regs 0-95 are integer 535083Sgblack@eecs.umich.edu * and 96-191 are fp). This remains true even for both logical and 545083Sgblack@eecs.umich.edu * physical register indices. The IQ depends on the memory dependence unit to 555083Sgblack@eecs.umich.edu * track when memory operations are ready in terms of ordering; register 565083Sgblack@eecs.umich.edu * dependencies are tracked normally. Right now the IQ also handles the 575083Sgblack@eecs.umich.edu * execution timing; this is mainly to allow back-to-back scheduling without 585083Sgblack@eecs.umich.edu * requiring IEW to be able to peek into the IQ. At the end of the execution 595083Sgblack@eecs.umich.edu * latency, the instruction is put into the queue to execute, where it will 605083Sgblack@eecs.umich.edu * have the execute() function called on it. 615083Sgblack@eecs.umich.edu * @todo: Make IQ able to handle multiple FU pools. 625083Sgblack@eecs.umich.edu */ 635083Sgblack@eecs.umich.edutemplate <class Impl> 645083Sgblack@eecs.umich.educlass InstructionQueue 655083Sgblack@eecs.umich.edu{ 665083Sgblack@eecs.umich.edu public: 675083Sgblack@eecs.umich.edu //Typedefs from the Impl. 685083Sgblack@eecs.umich.edu typedef typename Impl::FullCPU FullCPU; 695083Sgblack@eecs.umich.edu typedef typename Impl::DynInstPtr DynInstPtr; 705083Sgblack@eecs.umich.edu typedef typename Impl::Params Params; 715083Sgblack@eecs.umich.edu 725083Sgblack@eecs.umich.edu typedef typename Impl::CPUPol::IEW IEW; 735083Sgblack@eecs.umich.edu typedef typename Impl::CPUPol::MemDepUnit MemDepUnit; 745083Sgblack@eecs.umich.edu typedef typename Impl::CPUPol::IssueStruct IssueStruct; 755083Sgblack@eecs.umich.edu typedef typename Impl::CPUPol::TimeStruct TimeStruct; 765083Sgblack@eecs.umich.edu 775083Sgblack@eecs.umich.edu // Typedef of iterator through the list of instructions. 785083Sgblack@eecs.umich.edu typedef typename std::list<DynInstPtr>::iterator ListIt; 795083Sgblack@eecs.umich.edu 805083Sgblack@eecs.umich.edu friend class Impl::FullCPU; 815083Sgblack@eecs.umich.edu 827620Sgblack@eecs.umich.edu /** FU completion event class. */ 836345Sgblack@eecs.umich.edu class FUCompletion : public Event { 845083Sgblack@eecs.umich.edu private: 855083Sgblack@eecs.umich.edu /** Executing instruction. */ 865083Sgblack@eecs.umich.edu DynInstPtr inst; 875083Sgblack@eecs.umich.edu 886345Sgblack@eecs.umich.edu /** Index of the FU used for executing. */ 895083Sgblack@eecs.umich.edu int fuIdx; 905083Sgblack@eecs.umich.edu 915083Sgblack@eecs.umich.edu /** Pointer back to the instruction queue. */ 925083Sgblack@eecs.umich.edu InstructionQueue<Impl> *iqPtr; 935083Sgblack@eecs.umich.edu 945083Sgblack@eecs.umich.edu public: 955083Sgblack@eecs.umich.edu /** Construct a FU completion event. */ 965083Sgblack@eecs.umich.edu FUCompletion(DynInstPtr &_inst, int fu_idx, 975083Sgblack@eecs.umich.edu InstructionQueue<Impl> *iq_ptr); 985083Sgblack@eecs.umich.edu 995083Sgblack@eecs.umich.edu virtual void process(); 1005083Sgblack@eecs.umich.edu virtual const char *description(); 1015083Sgblack@eecs.umich.edu }; 1025083Sgblack@eecs.umich.edu 1035083Sgblack@eecs.umich.edu /** Constructs an IQ. */ 1046345Sgblack@eecs.umich.edu InstructionQueue(Params *params); 1055083Sgblack@eecs.umich.edu 1067620Sgblack@eecs.umich.edu /** Destructs the IQ. */ 1075083Sgblack@eecs.umich.edu ~InstructionQueue(); 1085083Sgblack@eecs.umich.edu 1095083Sgblack@eecs.umich.edu /** Returns the name of the IQ. */ 1105083Sgblack@eecs.umich.edu std::string name() const; 1115083Sgblack@eecs.umich.edu 1125083Sgblack@eecs.umich.edu /** Registers statistics. */ 1135083Sgblack@eecs.umich.edu void regStats(); 1147620Sgblack@eecs.umich.edu 1156345Sgblack@eecs.umich.edu /** Sets CPU pointer. */ 1165083Sgblack@eecs.umich.edu void setCPU(FullCPU *_cpu) { cpu = _cpu; } 1177620Sgblack@eecs.umich.edu 1185083Sgblack@eecs.umich.edu /** Sets active threads list. */ 1195083Sgblack@eecs.umich.edu void setActiveThreads(std::list<unsigned> *at_ptr); 1205083Sgblack@eecs.umich.edu 1215083Sgblack@eecs.umich.edu /** Sets the IEW pointer. */ 1225083Sgblack@eecs.umich.edu void setIEW(IEW *iew_ptr) { iewStage = iew_ptr; } 1235083Sgblack@eecs.umich.edu 1245083Sgblack@eecs.umich.edu /** Sets the timer buffer between issue and execute. */ 1255083Sgblack@eecs.umich.edu void setIssueToExecuteQueue(TimeBuffer<IssueStruct> *i2eQueue); 1265083Sgblack@eecs.umich.edu 1275083Sgblack@eecs.umich.edu /** Sets the global time buffer. */ 1285083Sgblack@eecs.umich.edu void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr); 1295083Sgblack@eecs.umich.edu 1305083Sgblack@eecs.umich.edu /** Number of entries needed for given amount of threads. */ 1315083Sgblack@eecs.umich.edu int entryAmount(int num_threads); 1325083Sgblack@eecs.umich.edu 1335083Sgblack@eecs.umich.edu /** Resets max entries for all threads. */ 1345083Sgblack@eecs.umich.edu void resetEntries(); 1355083Sgblack@eecs.umich.edu 1365083Sgblack@eecs.umich.edu /** Returns total number of free entries. */ 1375083Sgblack@eecs.umich.edu unsigned numFreeEntries(); 1385083Sgblack@eecs.umich.edu 1395083Sgblack@eecs.umich.edu /** Returns number of free entries for a thread. */ 1405083Sgblack@eecs.umich.edu unsigned numFreeEntries(unsigned tid); 1415083Sgblack@eecs.umich.edu 1425083Sgblack@eecs.umich.edu /** Returns whether or not the IQ is full. */ 1435083Sgblack@eecs.umich.edu bool isFull(); 1445083Sgblack@eecs.umich.edu 1455083Sgblack@eecs.umich.edu /** Returns whether or not the IQ is full for a specific thread. */ 1465083Sgblack@eecs.umich.edu bool isFull(unsigned tid); 1475083Sgblack@eecs.umich.edu 1485083Sgblack@eecs.umich.edu /** Returns if there are any ready instructions in the IQ. */ 1495083Sgblack@eecs.umich.edu bool hasReadyInsts(); 1505083Sgblack@eecs.umich.edu 1515083Sgblack@eecs.umich.edu /** Inserts a new instruction into the IQ. */ 1525083Sgblack@eecs.umich.edu void insert(DynInstPtr &new_inst); 1535083Sgblack@eecs.umich.edu 1545083Sgblack@eecs.umich.edu /** Inserts a new, non-speculative instruction into the IQ. */ 1555083Sgblack@eecs.umich.edu void insertNonSpec(DynInstPtr &new_inst); 1565083Sgblack@eecs.umich.edu 1575083Sgblack@eecs.umich.edu /** Inserts a memory or write barrier into the IQ to make sure 1585083Sgblack@eecs.umich.edu * loads and stores are ordered properly. 1595083Sgblack@eecs.umich.edu */ 1605083Sgblack@eecs.umich.edu void insertBarrier(DynInstPtr &barr_inst); 1615083Sgblack@eecs.umich.edu 1625083Sgblack@eecs.umich.edu /** 1635083Sgblack@eecs.umich.edu * Advances the tail of the IQ, used if an instruction is not added to the 1645083Sgblack@eecs.umich.edu * IQ for scheduling. 1655083Sgblack@eecs.umich.edu * @todo: Rename this function. 1665083Sgblack@eecs.umich.edu */ 1675083Sgblack@eecs.umich.edu void advanceTail(DynInstPtr &inst); 1685083Sgblack@eecs.umich.edu 1695083Sgblack@eecs.umich.edu /** Process FU completion event. */ 1705083Sgblack@eecs.umich.edu void processFUCompletion(DynInstPtr &inst, int fu_idx); 1715083Sgblack@eecs.umich.edu 1725083Sgblack@eecs.umich.edu /** 1735083Sgblack@eecs.umich.edu * Schedules ready instructions, adding the ready ones (oldest first) to 1745083Sgblack@eecs.umich.edu * the queue to execute. 1755083Sgblack@eecs.umich.edu */ 1765083Sgblack@eecs.umich.edu void scheduleReadyInsts(); 1775083Sgblack@eecs.umich.edu 1785083Sgblack@eecs.umich.edu /** Schedules a single specific non-speculative instruction. */ 1795083Sgblack@eecs.umich.edu void scheduleNonSpec(const InstSeqNum &inst); 1805083Sgblack@eecs.umich.edu 1815083Sgblack@eecs.umich.edu /** 1825083Sgblack@eecs.umich.edu * Commits all instructions up to and including the given sequence number, 1835083Sgblack@eecs.umich.edu * for a specific thread. 1845083Sgblack@eecs.umich.edu */ 1855083Sgblack@eecs.umich.edu void commit(const InstSeqNum &inst, unsigned tid = 0); 1865083Sgblack@eecs.umich.edu 1875083Sgblack@eecs.umich.edu /** Wakes all dependents of a completed instruction. */ 1885083Sgblack@eecs.umich.edu int wakeDependents(DynInstPtr &completed_inst); 1895083Sgblack@eecs.umich.edu 1905083Sgblack@eecs.umich.edu /** Adds a ready memory instruction to the ready list. */ 1915083Sgblack@eecs.umich.edu void addReadyMemInst(DynInstPtr &ready_inst); 1925083Sgblack@eecs.umich.edu 1935083Sgblack@eecs.umich.edu /** 1945083Sgblack@eecs.umich.edu * Reschedules a memory instruction. It will be ready to issue once 1955083Sgblack@eecs.umich.edu * replayMemInst() is called. 1965083Sgblack@eecs.umich.edu */ 1975083Sgblack@eecs.umich.edu void rescheduleMemInst(DynInstPtr &resched_inst); 1985083Sgblack@eecs.umich.edu 1995083Sgblack@eecs.umich.edu /** Replays a memory instruction. It must be rescheduled first. */ 2005083Sgblack@eecs.umich.edu void replayMemInst(DynInstPtr &replay_inst); 2015083Sgblack@eecs.umich.edu 2025083Sgblack@eecs.umich.edu /** Completes a memory operation. */ 2035083Sgblack@eecs.umich.edu void completeMemInst(DynInstPtr &completed_inst); 2045083Sgblack@eecs.umich.edu 2055083Sgblack@eecs.umich.edu /** Indicates an ordering violation between a store and a load. */ 2065083Sgblack@eecs.umich.edu void violation(DynInstPtr &store, DynInstPtr &faulting_load); 2075083Sgblack@eecs.umich.edu 2085083Sgblack@eecs.umich.edu /** 2095083Sgblack@eecs.umich.edu * Squashes instructions for a thread. Squashing information is obtained 2105083Sgblack@eecs.umich.edu * from the time buffer. 2115083Sgblack@eecs.umich.edu */ 2125083Sgblack@eecs.umich.edu void squash(unsigned tid); 2135083Sgblack@eecs.umich.edu 2145083Sgblack@eecs.umich.edu /** Returns the number of used entries for a thread. */ 2155083Sgblack@eecs.umich.edu unsigned getCount(unsigned tid) { return count[tid]; }; 2165083Sgblack@eecs.umich.edu 2175083Sgblack@eecs.umich.edu /** Updates the number of free entries. */ 2185083Sgblack@eecs.umich.edu void updateFreeEntries(int num) { freeEntries += num; } 2195083Sgblack@eecs.umich.edu 2205083Sgblack@eecs.umich.edu /** Debug function to print all instructions. */ 2215083Sgblack@eecs.umich.edu void printInsts(); 2225083Sgblack@eecs.umich.edu 2235083Sgblack@eecs.umich.edu private: 2245083Sgblack@eecs.umich.edu /** Does the actual squashing. */ 2257620Sgblack@eecs.umich.edu void doSquash(unsigned tid); 2267620Sgblack@eecs.umich.edu 2275083Sgblack@eecs.umich.edu ///////////////////////// 2285083Sgblack@eecs.umich.edu // Various pointers 2295083Sgblack@eecs.umich.edu ///////////////////////// 2305083Sgblack@eecs.umich.edu 2315083Sgblack@eecs.umich.edu /** Pointer to the CPU. */ 2325083Sgblack@eecs.umich.edu FullCPU *cpu; 2335083Sgblack@eecs.umich.edu 2345083Sgblack@eecs.umich.edu /** Cache interface. */ 2355083Sgblack@eecs.umich.edu MemInterface *dcacheInterface; 2365083Sgblack@eecs.umich.edu 2376345Sgblack@eecs.umich.edu /** Pointer to IEW stage. */ 2385083Sgblack@eecs.umich.edu IEW *iewStage; 2396345Sgblack@eecs.umich.edu 2405083Sgblack@eecs.umich.edu /** The memory dependence unit, which tracks/predicts memory dependences 2415122Sgblack@eecs.umich.edu * between instructions. 2425083Sgblack@eecs.umich.edu */ 2435083Sgblack@eecs.umich.edu MemDepUnit memDepUnit[Impl::MaxThreads]; 2445083Sgblack@eecs.umich.edu 2455083Sgblack@eecs.umich.edu /** The queue to the execute stage. Issued instructions will be written 2465083Sgblack@eecs.umich.edu * into it. 2475083Sgblack@eecs.umich.edu */ 2485083Sgblack@eecs.umich.edu TimeBuffer<IssueStruct> *issueToExecuteQueue; 2495083Sgblack@eecs.umich.edu 2505083Sgblack@eecs.umich.edu /** The backwards time buffer. */ 2515083Sgblack@eecs.umich.edu TimeBuffer<TimeStruct> *timeBuffer; 2525083Sgblack@eecs.umich.edu 2535083Sgblack@eecs.umich.edu /** Wire to read information from timebuffer. */ 2545083Sgblack@eecs.umich.edu typename TimeBuffer<TimeStruct>::wire fromCommit; 2556345Sgblack@eecs.umich.edu 2566345Sgblack@eecs.umich.edu /** Function unit pool. */ 2575083Sgblack@eecs.umich.edu FUPool *fuPool; 2585083Sgblack@eecs.umich.edu 2595083Sgblack@eecs.umich.edu ////////////////////////////////////// 2605083Sgblack@eecs.umich.edu // Instruction lists, ready queues, and ordering 2615083Sgblack@eecs.umich.edu ////////////////////////////////////// 2625083Sgblack@eecs.umich.edu 2635083Sgblack@eecs.umich.edu /** List of all the instructions in the IQ (some of which may be issued). */ 2645083Sgblack@eecs.umich.edu std::list<DynInstPtr> instList[Impl::MaxThreads]; 2655083Sgblack@eecs.umich.edu 2665083Sgblack@eecs.umich.edu /** 2675083Sgblack@eecs.umich.edu * Struct for comparing entries to be added to the priority queue. This 2685083Sgblack@eecs.umich.edu * gives reverse ordering to the instructions in terms of sequence 2695083Sgblack@eecs.umich.edu * numbers: the instructions with smaller sequence numbers (and hence 2705083Sgblack@eecs.umich.edu * are older) will be at the top of the priority queue. 2715083Sgblack@eecs.umich.edu */ 2725083Sgblack@eecs.umich.edu struct pqCompare { 2735083Sgblack@eecs.umich.edu bool operator() (const DynInstPtr &lhs, const DynInstPtr &rhs) const 2745083Sgblack@eecs.umich.edu { 2755083Sgblack@eecs.umich.edu return lhs->seqNum > rhs->seqNum; 2765083Sgblack@eecs.umich.edu } 2775083Sgblack@eecs.umich.edu }; 2785083Sgblack@eecs.umich.edu 2795083Sgblack@eecs.umich.edu /** 2805083Sgblack@eecs.umich.edu * Struct for an IQ entry. It includes the instruction and an iterator 2815083Sgblack@eecs.umich.edu * to the instruction's spot in the IQ. 2825083Sgblack@eecs.umich.edu */ 2835083Sgblack@eecs.umich.edu struct IQEntry { 2845083Sgblack@eecs.umich.edu DynInstPtr inst; 2855083Sgblack@eecs.umich.edu ListIt iqIt; 2865083Sgblack@eecs.umich.edu }; 2875083Sgblack@eecs.umich.edu 2885083Sgblack@eecs.umich.edu typedef std::priority_queue<DynInstPtr, std::vector<DynInstPtr>, pqCompare> 2895083Sgblack@eecs.umich.edu ReadyInstQueue; 2905083Sgblack@eecs.umich.edu 2915083Sgblack@eecs.umich.edu /** List of ready instructions, per op class. They are separated by op 2925083Sgblack@eecs.umich.edu * class to allow for easy mapping to FUs. 2935083Sgblack@eecs.umich.edu */ 2945083Sgblack@eecs.umich.edu ReadyInstQueue readyInsts[Num_OpClasses]; 2955083Sgblack@eecs.umich.edu 2965083Sgblack@eecs.umich.edu /** List of non-speculative instructions that will be scheduled 2975083Sgblack@eecs.umich.edu * once the IQ gets a signal from commit. While it's redundant to 2985083Sgblack@eecs.umich.edu * have the key be a part of the value (the sequence number is stored 2995083Sgblack@eecs.umich.edu * inside of DynInst), when these instructions are woken up only 3006345Sgblack@eecs.umich.edu * the sequence number will be available. Thus it is most efficient to be 3015083Sgblack@eecs.umich.edu * able to search by the sequence number alone. 3025083Sgblack@eecs.umich.edu * @todo: Maybe change this to a priority queue per thread. 3035083Sgblack@eecs.umich.edu */ 3045083Sgblack@eecs.umich.edu std::map<InstSeqNum, DynInstPtr> nonSpecInsts; 3055083Sgblack@eecs.umich.edu 3065083Sgblack@eecs.umich.edu typedef typename std::map<InstSeqNum, DynInstPtr>::iterator NonSpecMapIt; 3075083Sgblack@eecs.umich.edu 3085083Sgblack@eecs.umich.edu /** Entry for the list age ordering by op class. */ 3095083Sgblack@eecs.umich.edu struct ListOrderEntry { 3105083Sgblack@eecs.umich.edu OpClass queueType; 3115083Sgblack@eecs.umich.edu InstSeqNum oldestInst; 3125083Sgblack@eecs.umich.edu }; 3135083Sgblack@eecs.umich.edu 3145083Sgblack@eecs.umich.edu /** List that contains the age order of the oldest instruction of each 3155083Sgblack@eecs.umich.edu * ready queue. Used to select the oldest instruction available 3165083Sgblack@eecs.umich.edu * among op classes. 3175083Sgblack@eecs.umich.edu */ 3185083Sgblack@eecs.umich.edu std::list<ListOrderEntry> listOrder; 3195083Sgblack@eecs.umich.edu 3205083Sgblack@eecs.umich.edu typedef typename std::list<ListOrderEntry>::iterator ListOrderIt; 321 322 /** Tracks if each ready queue is on the age order list. */ 323 bool queueOnList[Num_OpClasses]; 324 325 /** Iterators of each ready queue. Points to their spot in the age order 326 * list. 327 */ 328 ListOrderIt readyIt[Num_OpClasses]; 329 330 /** Add an op class to the age order list. */ 331 void addToOrderList(OpClass op_class); 332 333 /** 334 * Called when the oldest instruction has been removed from a ready queue; 335 * this places that ready queue into the proper spot in the age order list. 336 */ 337 void moveToYoungerInst(ListOrderIt age_order_it); 338 339 ////////////////////////////////////// 340 // Various parameters 341 ////////////////////////////////////// 342 343 /** IQ Resource Sharing Policy */ 344 enum IQPolicy { 345 Dynamic, 346 Partitioned, 347 Threshold 348 }; 349 350 /** IQ sharing policy for SMT. */ 351 IQPolicy iqPolicy; 352 353 /** Number of Total Threads*/ 354 unsigned numThreads; 355 356 /** Pointer to list of active threads. */ 357 std::list<unsigned> *activeThreads; 358 359 /** Per Thread IQ count */ 360 unsigned count[Impl::MaxThreads]; 361 362 /** Max IQ Entries Per Thread */ 363 unsigned maxEntries[Impl::MaxThreads]; 364 365 /** Number of free IQ entries left. */ 366 unsigned freeEntries; 367 368 /** The number of entries in the instruction queue. */ 369 unsigned numEntries; 370 371 /** The total number of instructions that can be issued in one cycle. */ 372 unsigned totalWidth; 373 374 /** The number of physical registers in the CPU. */ 375 unsigned numPhysRegs; 376 377 /** The number of physical integer registers in the CPU. */ 378 unsigned numPhysIntRegs; 379 380 /** The number of floating point registers in the CPU. */ 381 unsigned numPhysFloatRegs; 382 383 /** Delay between commit stage and the IQ. 384 * @todo: Make there be a distinction between the delays within IEW. 385 */ 386 unsigned commitToIEWDelay; 387 388 ////////////////////////////////// 389 // Variables needed for squashing 390 ////////////////////////////////// 391 392 /** The sequence number of the squashed instruction. */ 393 InstSeqNum squashedSeqNum[Impl::MaxThreads]; 394 395 /** Iterator that points to the last instruction that has been squashed. 396 * This will not be valid unless the IQ is in the process of squashing. 397 */ 398 ListIt squashIt[Impl::MaxThreads]; 399 400 /////////////////////////////////// 401 // Dependency graph stuff 402 /////////////////////////////////// 403 404 class DependencyEntry 405 { 406 public: 407 DependencyEntry() 408 : inst(NULL), next(NULL) 409 { } 410 411 DynInstPtr inst; 412 //Might want to include data about what arch. register the 413 //dependence is waiting on. 414 DependencyEntry *next; 415 416 //This function, and perhaps this whole class, stand out a little 417 //bit as they don't fit a classification well. I want access 418 //to the underlying structure of the linked list, yet at 419 //the same time it feels like this should be something abstracted 420 //away. So for now it will sit here, within the IQ, until 421 //a better implementation is decided upon. 422 // This function probably shouldn't be within the entry... 423 void insert(DynInstPtr &new_inst); 424 425 void remove(DynInstPtr &inst_to_remove); 426 427 // Debug variable, remove when done testing. 428 static unsigned mem_alloc_counter; 429 }; 430 431 /** Array of linked lists. Each linked list is a list of all the 432 * instructions that depend upon a given register. The actual 433 * register's index is used to index into the graph; ie all 434 * instructions in flight that are dependent upon r34 will be 435 * in the linked list of dependGraph[34]. 436 */ 437 DependencyEntry *dependGraph; 438 439 /** A cache of the recently woken registers. It is 1 if the register 440 * has been woken up recently, and 0 if the register has been added 441 * to the dependency graph and has not yet received its value. It 442 * is basically a secondary scoreboard, and should pretty much mirror 443 * the scoreboard that exists in the rename map. 444 */ 445 std::vector<bool> regScoreboard; 446 447 /** Adds an instruction to the dependency graph, as a producer. */ 448 bool addToDependents(DynInstPtr &new_inst); 449 450 /** Adds an instruction to the dependency graph, as a consumer. */ 451 void createDependency(DynInstPtr &new_inst); 452 453 /** Moves an instruction to the ready queue if it is ready. */ 454 void addIfReady(DynInstPtr &inst); 455 456 /** Debugging function to count how many entries are in the IQ. It does 457 * a linear walk through the instructions, so do not call this function 458 * during normal execution. 459 */ 460 int countInsts(); 461 462 /** Debugging function to dump out the dependency graph. 463 */ 464 void dumpDependGraph(); 465 466 /** Debugging function to dump all the list sizes, as well as print 467 * out the list of nonspeculative instructions. Should not be used 468 * in any other capacity, but it has no harmful sideaffects. 469 */ 470 void dumpLists(); 471 472 /** Debugging function to dump out all instructions that are in the 473 * IQ. 474 */ 475 void dumpInsts(); 476 477 /** Stat for number of instructions added. */ 478 Stats::Scalar<> iqInstsAdded; 479 /** Stat for number of non-speculative instructions added. */ 480 Stats::Scalar<> iqNonSpecInstsAdded; 481// Stats::Scalar<> iqIntInstsAdded; 482 Stats::Scalar<> iqInstsIssued; 483 /** Stat for number of integer instructions issued. */ 484 Stats::Scalar<> iqIntInstsIssued; 485// Stats::Scalar<> iqFloatInstsAdded; 486 /** Stat for number of floating point instructions issued. */ 487 Stats::Scalar<> iqFloatInstsIssued; 488// Stats::Scalar<> iqBranchInstsAdded; 489 /** Stat for number of branch instructions issued. */ 490 Stats::Scalar<> iqBranchInstsIssued; 491// Stats::Scalar<> iqMemInstsAdded; 492 /** Stat for number of memory instructions issued. */ 493 Stats::Scalar<> iqMemInstsIssued; 494// Stats::Scalar<> iqMiscInstsAdded; 495 /** Stat for number of miscellaneous instructions issued. */ 496 Stats::Scalar<> iqMiscInstsIssued; 497 /** Stat for number of squashed instructions that were ready to issue. */ 498 Stats::Scalar<> iqSquashedInstsIssued; 499 /** Stat for number of squashed instructions examined when squashing. */ 500 Stats::Scalar<> iqSquashedInstsExamined; 501 /** Stat for number of squashed instruction operands examined when 502 * squashing. 503 */ 504 Stats::Scalar<> iqSquashedOperandsExamined; 505 /** Stat for number of non-speculative instructions removed due to a squash. 506 */ 507 Stats::Scalar<> iqSquashedNonSpecRemoved; 508 509 Stats::VectorDistribution<> queue_res_dist; 510 Stats::Vector<> n_issued_dist; 511 Stats::VectorDistribution<> issue_delay_dist; 512 513 Stats::Vector<> stat_fu_busy; 514// Stats::Vector<> dist_unissued; 515 Stats::Vector2d<> stat_issued_inst_type; 516 517 Stats::Formula issue_rate; 518// Stats::Formula issue_stores; 519// Stats::Formula issue_op_rate; 520 Stats::Vector<> fu_busy; //cumulative fu busy 521 522 Stats::Formula fu_busy_rate; 523}; 524 525#endif //__CPU_O3_INST_QUEUE_HH__ 526