commit.hh revision 13563:68c171235dc5
1/* 2 * Copyright (c) 2010-2012, 2014 ARM Limited 3 * All rights reserved. 4 * 5 * The license below extends only to copyright in the software and shall 6 * not be construed as granting a license to any other intellectual 7 * property including but not limited to intellectual property relating 8 * to a hardware implementation of the functionality of the software 9 * licensed hereunder. You may use the software subject to the license 10 * terms below provided that you ensure that this notice is replicated 11 * unmodified and in its entirety in all distributions of the software, 12 * modified or unmodified, in source code or in binary form. 13 * 14 * Copyright (c) 2004-2006 The Regents of The University of Michigan 15 * All rights reserved. 16 * 17 * Redistribution and use in source and binary forms, with or without 18 * modification, are permitted provided that the following conditions are 19 * met: redistributions of source code must retain the above copyright 20 * notice, this list of conditions and the following disclaimer; 21 * redistributions in binary form must reproduce the above copyright 22 * notice, this list of conditions and the following disclaimer in the 23 * documentation and/or other materials provided with the distribution; 24 * neither the name of the copyright holders nor the names of its 25 * contributors may be used to endorse or promote products derived from 26 * this software without specific prior written permission. 27 * 28 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 29 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 30 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 31 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 32 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 33 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 34 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 35 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 36 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 38 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 39 * 40 * Authors: Kevin Lim 41 * Korey Sewell 42 */ 43 44#ifndef __CPU_O3_COMMIT_HH__ 45#define __CPU_O3_COMMIT_HH__ 46 47#include <queue> 48 49#include "base/statistics.hh" 50#include "cpu/exetrace.hh" 51#include "cpu/inst_seq.hh" 52#include "cpu/timebuf.hh" 53#include "enums/CommitPolicy.hh" 54#include "sim/probe/probe.hh" 55 56struct DerivO3CPUParams; 57 58template <class> 59struct O3ThreadState; 60 61/** 62 * DefaultCommit handles single threaded and SMT commit. Its width is 63 * specified by the parameters; each cycle it tries to commit that 64 * many instructions. The SMT policy decides which thread it tries to 65 * commit instructions from. Non- speculative instructions must reach 66 * the head of the ROB before they are ready to execute; once they 67 * reach the head, commit will broadcast the instruction's sequence 68 * number to the previous stages so that they can issue/ execute the 69 * instruction. Only one non-speculative instruction is handled per 70 * cycle. Commit is responsible for handling all back-end initiated 71 * redirects. It receives the redirect, and then broadcasts it to all 72 * stages, indicating the sequence number they should squash until, 73 * and any necessary branch misprediction information as well. It 74 * priortizes redirects by instruction's age, only broadcasting a 75 * redirect if it corresponds to an instruction that should currently 76 * be in the ROB. This is done by tracking the sequence number of the 77 * youngest instruction in the ROB, which gets updated to any 78 * squashing instruction's sequence number, and only broadcasting a 79 * redirect if it corresponds to an older instruction. Commit also 80 * supports multiple cycle squashing, to model a ROB that can only 81 * remove a certain number of instructions per cycle. 82 */ 83template<class Impl> 84class DefaultCommit 85{ 86 public: 87 // Typedefs from the Impl. 88 typedef typename Impl::O3CPU O3CPU; 89 typedef typename Impl::DynInstPtr DynInstPtr; 90 typedef typename Impl::CPUPol CPUPol; 91 92 typedef typename CPUPol::RenameMap RenameMap; 93 typedef typename CPUPol::ROB ROB; 94 95 typedef typename CPUPol::TimeStruct TimeStruct; 96 typedef typename CPUPol::FetchStruct FetchStruct; 97 typedef typename CPUPol::IEWStruct IEWStruct; 98 typedef typename CPUPol::RenameStruct RenameStruct; 99 100 typedef typename CPUPol::Fetch Fetch; 101 typedef typename CPUPol::IEW IEW; 102 103 typedef O3ThreadState<Impl> Thread; 104 105 /** Overall commit status. Used to determine if the CPU can deschedule 106 * itself due to a lack of activity. 107 */ 108 enum CommitStatus{ 109 Active, 110 Inactive 111 }; 112 113 /** Individual thread status. */ 114 enum ThreadStatus { 115 Running, 116 Idle, 117 ROBSquashing, 118 TrapPending, 119 FetchTrapPending, 120 SquashAfterPending, //< Committing instructions before a squash. 121 }; 122 123 private: 124 /** Overall commit status. */ 125 CommitStatus _status; 126 /** Next commit status, to be set at the end of the cycle. */ 127 CommitStatus _nextStatus; 128 /** Per-thread status. */ 129 ThreadStatus commitStatus[Impl::MaxThreads]; 130 /** Commit policy used in SMT mode. */ 131 CommitPolicy commitPolicy; 132 133 /** Probe Points. */ 134 ProbePointArg<DynInstPtr> *ppCommit; 135 ProbePointArg<DynInstPtr> *ppCommitStall; 136 /** To probe when an instruction is squashed */ 137 ProbePointArg<DynInstPtr> *ppSquash; 138 139 /** Mark the thread as processing a trap. */ 140 void processTrapEvent(ThreadID tid); 141 142 public: 143 /** Construct a DefaultCommit with the given parameters. */ 144 DefaultCommit(O3CPU *_cpu, DerivO3CPUParams *params); 145 146 /** Returns the name of the DefaultCommit. */ 147 std::string name() const; 148 149 /** Registers statistics. */ 150 void regStats(); 151 152 /** Registers probes. */ 153 void regProbePoints(); 154 155 /** Sets the list of threads. */ 156 void setThreads(std::vector<Thread *> &threads); 157 158 /** Sets the main time buffer pointer, used for backwards communication. */ 159 void setTimeBuffer(TimeBuffer<TimeStruct> *tb_ptr); 160 161 void setFetchQueue(TimeBuffer<FetchStruct> *fq_ptr); 162 163 /** Sets the pointer to the queue coming from rename. */ 164 void setRenameQueue(TimeBuffer<RenameStruct> *rq_ptr); 165 166 /** Sets the pointer to the queue coming from IEW. */ 167 void setIEWQueue(TimeBuffer<IEWStruct> *iq_ptr); 168 169 /** Sets the pointer to the IEW stage. */ 170 void setIEWStage(IEW *iew_stage); 171 172 /** The pointer to the IEW stage. Used solely to ensure that 173 * various events (traps, interrupts, syscalls) do not occur until 174 * all stores have written back. 175 */ 176 IEW *iewStage; 177 178 /** Sets pointer to list of active threads. */ 179 void setActiveThreads(std::list<ThreadID> *at_ptr); 180 181 /** Sets pointer to the commited state rename map. */ 182 void setRenameMap(RenameMap rm_ptr[Impl::MaxThreads]); 183 184 /** Sets pointer to the ROB. */ 185 void setROB(ROB *rob_ptr); 186 187 /** Initializes stage by sending back the number of free entries. */ 188 void startupStage(); 189 190 /** Initializes the draining of commit. */ 191 void drain(); 192 193 /** Resumes execution after draining. */ 194 void drainResume(); 195 196 /** Perform sanity checks after a drain. */ 197 void drainSanityCheck() const; 198 199 /** Has the stage drained? */ 200 bool isDrained() const; 201 202 /** Takes over from another CPU's thread. */ 203 void takeOverFrom(); 204 205 /** Deschedules a thread from scheduling */ 206 void deactivateThread(ThreadID tid); 207 208 /** Ticks the commit stage, which tries to commit instructions. */ 209 void tick(); 210 211 /** Handles any squashes that are sent from IEW, and adds instructions 212 * to the ROB and tries to commit instructions. 213 */ 214 void commit(); 215 216 /** Returns the number of free ROB entries for a specific thread. */ 217 size_t numROBFreeEntries(ThreadID tid); 218 219 /** Generates an event to schedule a squash due to a trap. */ 220 void generateTrapEvent(ThreadID tid, Fault inst_fault); 221 222 /** Records that commit needs to initiate a squash due to an 223 * external state update through the TC. 224 */ 225 void generateTCEvent(ThreadID tid); 226 227 private: 228 /** Updates the overall status of commit with the nextStatus, and 229 * tell the CPU if commit is active/inactive. 230 */ 231 void updateStatus(); 232 233 /** Returns if any of the threads have the number of ROB entries changed 234 * on this cycle. Used to determine if the number of free ROB entries needs 235 * to be sent back to previous stages. 236 */ 237 bool changedROBEntries(); 238 239 /** Squashes all in flight instructions. */ 240 void squashAll(ThreadID tid); 241 242 /** Handles squashing due to a trap. */ 243 void squashFromTrap(ThreadID tid); 244 245 /** Handles squashing due to an TC write. */ 246 void squashFromTC(ThreadID tid); 247 248 /** Handles a squash from a squashAfter() request. */ 249 void squashFromSquashAfter(ThreadID tid); 250 251 /** 252 * Handle squashing from instruction with SquashAfter set. 253 * 254 * This differs from the other squashes as it squashes following 255 * instructions instead of the current instruction and doesn't 256 * clean up various status bits about traps/tc writes 257 * pending. Since there might have been instructions committed by 258 * the commit stage before the squashing instruction was reached 259 * and we can't commit and squash in the same cycle, we have to 260 * squash in two steps: 261 * 262 * <ol> 263 * <li>Immediately set the commit status of the thread of 264 * SquashAfterPending. This forces the thread to stop 265 * committing instructions in this cycle. The last 266 * instruction to be committed in this cycle will be the 267 * SquashAfter instruction. 268 * <li>In the next cycle, commit() checks for the 269 * SquashAfterPending state and squashes <i>all</i> 270 * in-flight instructions. Since the SquashAfter instruction 271 * was the last instruction to be committed in the previous 272 * cycle, this causes all subsequent instructions to be 273 * squashed. 274 * </ol> 275 * 276 * @param tid ID of the thread to squash. 277 * @param head_inst Instruction that requested the squash. 278 */ 279 void squashAfter(ThreadID tid, const DynInstPtr &head_inst); 280 281 /** Handles processing an interrupt. */ 282 void handleInterrupt(); 283 284 /** Get fetch redirecting so we can handle an interrupt */ 285 void propagateInterrupt(); 286 287 /** Commits as many instructions as possible. */ 288 void commitInsts(); 289 290 /** Tries to commit the head ROB instruction passed in. 291 * @param head_inst The instruction to be committed. 292 */ 293 bool commitHead(const DynInstPtr &head_inst, unsigned inst_num); 294 295 /** Gets instructions from rename and inserts them into the ROB. */ 296 void getInsts(); 297 298 /** Marks completed instructions using information sent from IEW. */ 299 void markCompletedInsts(); 300 301 /** Gets the thread to commit, based on the SMT policy. */ 302 ThreadID getCommittingThread(); 303 304 /** Returns the thread ID to use based on a round robin policy. */ 305 ThreadID roundRobin(); 306 307 /** Returns the thread ID to use based on an oldest instruction policy. */ 308 ThreadID oldestReady(); 309 310 public: 311 /** Reads the PC of a specific thread. */ 312 TheISA::PCState pcState(ThreadID tid) { return pc[tid]; } 313 314 /** Sets the PC of a specific thread. */ 315 void pcState(const TheISA::PCState &val, ThreadID tid) 316 { pc[tid] = val; } 317 318 /** Returns the PC of a specific thread. */ 319 Addr instAddr(ThreadID tid) { return pc[tid].instAddr(); } 320 321 /** Returns the next PC of a specific thread. */ 322 Addr nextInstAddr(ThreadID tid) { return pc[tid].nextInstAddr(); } 323 324 /** Reads the micro PC of a specific thread. */ 325 Addr microPC(ThreadID tid) { return pc[tid].microPC(); } 326 327 private: 328 /** Time buffer interface. */ 329 TimeBuffer<TimeStruct> *timeBuffer; 330 331 /** Wire to write information heading to previous stages. */ 332 typename TimeBuffer<TimeStruct>::wire toIEW; 333 334 /** Wire to read information from IEW (for ROB). */ 335 typename TimeBuffer<TimeStruct>::wire robInfoFromIEW; 336 337 TimeBuffer<FetchStruct> *fetchQueue; 338 339 typename TimeBuffer<FetchStruct>::wire fromFetch; 340 341 /** IEW instruction queue interface. */ 342 TimeBuffer<IEWStruct> *iewQueue; 343 344 /** Wire to read information from IEW queue. */ 345 typename TimeBuffer<IEWStruct>::wire fromIEW; 346 347 /** Rename instruction queue interface, for ROB. */ 348 TimeBuffer<RenameStruct> *renameQueue; 349 350 /** Wire to read information from rename queue. */ 351 typename TimeBuffer<RenameStruct>::wire fromRename; 352 353 public: 354 /** ROB interface. */ 355 ROB *rob; 356 357 private: 358 /** Pointer to O3CPU. */ 359 O3CPU *cpu; 360 361 /** Vector of all of the threads. */ 362 std::vector<Thread *> thread; 363 364 /** Records that commit has written to the time buffer this cycle. Used for 365 * the CPU to determine if it can deschedule itself if there is no activity. 366 */ 367 bool wroteToTimeBuffer; 368 369 /** Records if the number of ROB entries has changed this cycle. If it has, 370 * then the number of free entries must be re-broadcast. 371 */ 372 bool changedROBNumEntries[Impl::MaxThreads]; 373 374 /** Records if a thread has to squash this cycle due to a trap. */ 375 bool trapSquash[Impl::MaxThreads]; 376 377 /** Records if a thread has to squash this cycle due to an XC write. */ 378 bool tcSquash[Impl::MaxThreads]; 379 380 /** 381 * Instruction passed to squashAfter(). 382 * 383 * The squash after implementation needs to buffer the instruction 384 * that caused a squash since this needs to be passed to the fetch 385 * stage once squashing starts. 386 */ 387 DynInstPtr squashAfterInst[Impl::MaxThreads]; 388 389 /** Priority List used for Commit Policy */ 390 std::list<ThreadID> priority_list; 391 392 /** IEW to Commit delay. */ 393 const Cycles iewToCommitDelay; 394 395 /** Commit to IEW delay. */ 396 const Cycles commitToIEWDelay; 397 398 /** Rename to ROB delay. */ 399 const Cycles renameToROBDelay; 400 401 const Cycles fetchToCommitDelay; 402 403 /** Rename width, in instructions. Used so ROB knows how many 404 * instructions to get from the rename instruction queue. 405 */ 406 const unsigned renameWidth; 407 408 /** Commit width, in instructions. */ 409 const unsigned commitWidth; 410 411 /** Number of Reorder Buffers */ 412 unsigned numRobs; 413 414 /** Number of Active Threads */ 415 const ThreadID numThreads; 416 417 /** Is a drain pending? Commit is looking for an instruction boundary while 418 * there are no pending interrupts 419 */ 420 bool drainPending; 421 422 /** Is a drain imminent? Commit has found an instruction boundary while no 423 * interrupts were present or in flight. This was the last architecturally 424 * committed instruction. Interrupts disabled and pipeline flushed. 425 * Waiting for structures to finish draining. 426 */ 427 bool drainImminent; 428 429 /** The latency to handle a trap. Used when scheduling trap 430 * squash event. 431 */ 432 const Cycles trapLatency; 433 434 /** The interrupt fault. */ 435 Fault interrupt; 436 437 /** The commit PC state of each thread. Refers to the instruction that 438 * is currently being processed/committed. 439 */ 440 TheISA::PCState pc[Impl::MaxThreads]; 441 442 /** The sequence number of the youngest valid instruction in the ROB. */ 443 InstSeqNum youngestSeqNum[Impl::MaxThreads]; 444 445 /** The sequence number of the last commited instruction. */ 446 InstSeqNum lastCommitedSeqNum[Impl::MaxThreads]; 447 448 /** Records if there is a trap currently in flight. */ 449 bool trapInFlight[Impl::MaxThreads]; 450 451 /** Records if there were any stores committed this cycle. */ 452 bool committedStores[Impl::MaxThreads]; 453 454 /** Records if commit should check if the ROB is truly empty (see 455 commit_impl.hh). */ 456 bool checkEmptyROB[Impl::MaxThreads]; 457 458 /** Pointer to the list of active threads. */ 459 std::list<ThreadID> *activeThreads; 460 461 /** Rename map interface. */ 462 RenameMap *renameMap[Impl::MaxThreads]; 463 464 /** True if last committed microop can be followed by an interrupt */ 465 bool canHandleInterrupts; 466 467 /** Have we had an interrupt pending and then seen it de-asserted because 468 of a masking change? In this case the variable is set and the next time 469 interrupts are enabled and pending the pipeline will squash to avoid 470 a possible livelock senario. */ 471 bool avoidQuiesceLiveLock; 472 473 /** Updates commit stats based on this instruction. */ 474 void updateComInstStats(const DynInstPtr &inst); 475 476 /** Stat for the total number of squashed instructions discarded by commit. 477 */ 478 Stats::Scalar commitSquashedInsts; 479 /** Stat for the total number of times commit has had to stall due to a non- 480 * speculative instruction reaching the head of the ROB. 481 */ 482 Stats::Scalar commitNonSpecStalls; 483 /** Stat for the total number of branch mispredicts that caused a squash. */ 484 Stats::Scalar branchMispredicts; 485 /** Distribution of the number of committed instructions each cycle. */ 486 Stats::Distribution numCommittedDist; 487 488 /** Total number of instructions committed. */ 489 Stats::Vector instsCommitted; 490 /** Total number of ops (including micro ops) committed. */ 491 Stats::Vector opsCommitted; 492 /** Total number of software prefetches committed. */ 493 Stats::Vector statComSwp; 494 /** Stat for the total number of committed memory references. */ 495 Stats::Vector statComRefs; 496 /** Stat for the total number of committed loads. */ 497 Stats::Vector statComLoads; 498 /** Total number of committed memory barriers. */ 499 Stats::Vector statComMembars; 500 /** Total number of committed branches. */ 501 Stats::Vector statComBranches; 502 /** Total number of vector instructions */ 503 Stats::Vector statComVector; 504 /** Total number of floating point instructions */ 505 Stats::Vector statComFloating; 506 /** Total number of integer instructions */ 507 Stats::Vector statComInteger; 508 /** Total number of function calls */ 509 Stats::Vector statComFunctionCalls; 510 /** Committed instructions by instruction type (OpClass) */ 511 Stats::Vector2d statCommittedInstType; 512 513 /** Number of cycles where the commit bandwidth limit is reached. */ 514 Stats::Scalar commitEligibleSamples; 515}; 516 517#endif // __CPU_O3_COMMIT_HH__ 518