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
22namespace llvm {
23namespace mca {
24
25llvm::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
44llvm::Error RetireStage::cycleEnd() {
45  PRF.cycleEnd();
46  return llvm::ErrorSuccess();
47}
48
49llvm::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
60void 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