MicroOpQueueStage.h revision 360660
1304910Soshogbo//===---------------------- MicroOpQueueStage.h -----------------*- C++ -*-===//
2304910Soshogbo//
3304910Soshogbo// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4304910Soshogbo// See https://llvm.org/LICENSE.txt for license information.
5304910Soshogbo// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6304910Soshogbo//
7304910Soshogbo//===----------------------------------------------------------------------===//
8304910Soshogbo/// \file
9304910Soshogbo///
10304910Soshogbo/// This file defines a stage that implements a queue of micro opcodes.
11304910Soshogbo/// It can be used to simulate a hardware micro-op queue that serves opcodes to
12304910Soshogbo/// the out of order backend.
13304910Soshogbo///
14304910Soshogbo//===----------------------------------------------------------------------===//
15304910Soshogbo
16304910Soshogbo#ifndef LLVM_MCA_MICRO_OP_QUEUE_STAGE_H
17304910Soshogbo#define LLVM_MCA_MICRO_OP_QUEUE_STAGE_H
18304910Soshogbo
19304910Soshogbo#include "llvm/ADT/SmallVector.h"
20304910Soshogbo#include "llvm/MCA/Stages/Stage.h"
21304910Soshogbo
22304910Soshogbonamespace llvm {
23304910Soshogbonamespace mca {
24304910Soshogbo
25304910Soshogbo/// A stage that simulates a queue of instruction opcodes.
26304910Soshogboclass MicroOpQueueStage : public Stage {
27304910Soshogbo  SmallVector<InstRef, 8> Buffer;
28336346Skevans  unsigned NextAvailableSlotIdx;
29304910Soshogbo  unsigned CurrentInstructionSlotIdx;
30304910Soshogbo
31304910Soshogbo  // Limits the number of instructions that can be written to this buffer every
32336346Skevans  // cycle. A value of zero means that there is no limit to the instruction
33336346Skevans  // throughput in input.
34336346Skevans  const unsigned MaxIPC;
35304910Soshogbo  unsigned CurrentIPC;
36304910Soshogbo
37304910Soshogbo  // Number of entries that are available during this cycle.
38304910Soshogbo  unsigned AvailableEntries;
39304910Soshogbo
40336346Skevans  // True if instructions dispatched to this stage don't need to wait for the
41336346Skevans  // next cycle before moving to the next stage.
42336346Skevans  // False if this buffer acts as a one cycle delay in the execution pipeline.
43336346Skevans  bool IsZeroLatencyStage;
44336346Skevans
45304910Soshogbo  MicroOpQueueStage(const MicroOpQueueStage &Other) = delete;
46336346Skevans  MicroOpQueueStage &operator=(const MicroOpQueueStage &Other) = delete;
47304910Soshogbo
48336346Skevans  // By default, an instruction consumes a number of buffer entries equal to its
49304910Soshogbo  // number of micro opcodes (see field `InstrDesc::NumMicroOpcodes`).  The
50336346Skevans  // number of entries consumed by an instruction is normalized to the
51304910Soshogbo  // minimum value between NumMicroOpcodes and the buffer size. This is to avoid
52336346Skevans  // problems with (microcoded) instructions that generate a number of micro
53304910Soshogbo  // opcodes than doesn't fit in the buffer.
54336346Skevans  unsigned getNormalizedOpcodes(const InstRef &IR) const {
55304910Soshogbo    unsigned NormalizedOpcodes =
56336346Skevans        std::min(static_cast<unsigned>(Buffer.size()),
57304910Soshogbo                 IR.getInstruction()->getDesc().NumMicroOps);
58336346Skevans    return NormalizedOpcodes ? NormalizedOpcodes : 1U;
59304910Soshogbo  }
60336346Skevans
61304910Soshogbo  Error moveInstructions();
62336346Skevans
63304910Soshogbopublic:
64336346Skevans  MicroOpQueueStage(unsigned Size, unsigned IPC = 0,
65304910Soshogbo                    bool ZeroLatencyStage = true);
66336346Skevans
67304910Soshogbo  bool isAvailable(const InstRef &IR) const override {
68304910Soshogbo    if (MaxIPC && CurrentIPC == MaxIPC)
69336346Skevans      return false;
70304910Soshogbo    unsigned NormalizedOpcodes = getNormalizedOpcodes(IR);
71336346Skevans    if (NormalizedOpcodes > AvailableEntries)
72304910Soshogbo      return false;
73336346Skevans    return true;
74304910Soshogbo  }
75336346Skevans
76304910Soshogbo  bool hasWorkToComplete() const override {
77336346Skevans    return AvailableEntries != Buffer.size();
78304910Soshogbo  }
79336346Skevans
80304910Soshogbo  Error execute(InstRef &IR) override;
81336346Skevans  Error cycleStart() override;
82304910Soshogbo  Error cycleEnd() override;
83336346Skevans};
84304910Soshogbo
85336346Skevans} // namespace mca
86304910Soshogbo} // namespace llvm
87336346Skevans
88304910Soshogbo#endif // LLVM_MCA_MICRO_OP_QUEUE_STAGE_H
89336346Skevans