1 //===---------------------- RetireStage.cpp ---------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 ///
10 /// This file defines the retire stage of an instruction pipeline.
11 /// The RetireStage represents the process logic that interacts with the
12 /// simulated RetireControlUnit hardware.
13 ///
14 //===----------------------------------------------------------------------===//
15 
16 #include "llvm/MCA/Stages/RetireStage.h"
17 #include "llvm/MCA/HWEventListener.h"
18 #include "llvm/Support/Debug.h"
19 
20 #define DEBUG_TYPE "llvm-mca"
21 
22 namespace llvm {
23 namespace mca {
24 
25 llvm::Error RetireStage::cycleStart() {
26   PRF.cycleStart();
27 
28   const unsigned MaxRetirePerCycle = RCU.getMaxRetirePerCycle();
29   unsigned NumRetired = 0;
30   while (!RCU.isEmpty()) {
31     if (MaxRetirePerCycle != 0 && NumRetired == MaxRetirePerCycle)
32       break;
33     const RetireControlUnit::RUToken &Current = RCU.getCurrentToken();
34     if (!Current.Executed)
35       break;
36     notifyInstructionRetired(Current.IR);
37     RCU.consumeCurrentToken();
38     NumRetired++;
39   }
40 
41   return llvm::ErrorSuccess();
42 }
43 
44 llvm::Error RetireStage::cycleEnd() {
45   PRF.cycleEnd();
46   return llvm::ErrorSuccess();
47 }
48 
49 llvm::Error RetireStage::execute(InstRef &IR) {
50   Instruction &IS = *IR.getInstruction();
51 
52   PRF.onInstructionExecuted(&IS);
53   unsigned TokenID = IS.getRCUTokenID();
54   assert(TokenID != RetireControlUnit::UnhandledTokenID);
55   RCU.onInstructionExecuted(TokenID);
56 
57   return llvm::ErrorSuccess();
58 }
59 
60 void RetireStage::notifyInstructionRetired(const InstRef &IR) const {
61   LLVM_DEBUG(llvm::dbgs() << "[E] Instruction Retired: #" << IR << '\n');
62   llvm::SmallVector<unsigned, 4> FreedRegs(PRF.getNumRegisterFiles());
63   const Instruction &Inst = *IR.getInstruction();
64 
65   // Release the load/store queue entries.
66   if (Inst.isMemOp())
67     LSU.onInstructionRetired(IR);
68 
69   for (const WriteState &WS : Inst.getDefs())
70     PRF.removeRegisterWrite(WS, FreedRegs);
71   notifyEvent<HWInstructionEvent>(HWInstructionRetiredEvent(IR, FreedRegs));
72 }
73 
74 } // namespace mca
75 } // namespace llvm
76