1//===---------------------- MicroOpQueueStage.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 MicroOpQueueStage.
11///
12//===----------------------------------------------------------------------===//
13
14#include "llvm/MCA/Stages/MicroOpQueueStage.h"
15
16namespace llvm {
17namespace mca {
18
19#define DEBUG_TYPE "llvm-mca"
20
21Error MicroOpQueueStage::moveInstructions() {
22  InstRef IR = Buffer[CurrentInstructionSlotIdx];
23  while (IR && checkNextStage(IR)) {
24    if (llvm::Error Val = moveToTheNextStage(IR))
25      return Val;
26
27    Buffer[CurrentInstructionSlotIdx].invalidate();
28    unsigned NormalizedOpcodes = getNormalizedOpcodes(IR);
29    CurrentInstructionSlotIdx += NormalizedOpcodes;
30    CurrentInstructionSlotIdx %= Buffer.size();
31    AvailableEntries += NormalizedOpcodes;
32    IR = Buffer[CurrentInstructionSlotIdx];
33  }
34
35  return llvm::ErrorSuccess();
36}
37
38MicroOpQueueStage::MicroOpQueueStage(unsigned Size, unsigned IPC,
39                                     bool ZeroLatencyStage)
40    : NextAvailableSlotIdx(0), CurrentInstructionSlotIdx(0), MaxIPC(IPC),
41      CurrentIPC(0), IsZeroLatencyStage(ZeroLatencyStage) {
42  Buffer.resize(Size ? Size : 1);
43  AvailableEntries = Buffer.size();
44}
45
46Error MicroOpQueueStage::execute(InstRef &IR) {
47  Buffer[NextAvailableSlotIdx] = IR;
48  unsigned NormalizedOpcodes = getNormalizedOpcodes(IR);
49  NextAvailableSlotIdx += NormalizedOpcodes;
50  NextAvailableSlotIdx %= Buffer.size();
51  AvailableEntries -= NormalizedOpcodes;
52  ++CurrentIPC;
53  return llvm::ErrorSuccess();
54}
55
56Error MicroOpQueueStage::cycleStart() {
57  CurrentIPC = 0;
58  if (!IsZeroLatencyStage)
59    return moveInstructions();
60  return llvm::ErrorSuccess();
61}
62
63Error MicroOpQueueStage::cycleEnd() {
64  if (IsZeroLatencyStage)
65    return moveInstructions();
66  return llvm::ErrorSuccess();
67}
68
69} // namespace mca
70} // namespace llvm
71