1 //===---------------------- MicroOpQueueStage.h -----------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
10 /// This file defines a stage that implements a queue of micro opcodes.
11 /// It can be used to simulate a hardware micro-op queue that serves opcodes to
12 /// the out of order backend.
14 //===----------------------------------------------------------------------===//
16 #ifndef LLVM_MCA_MICRO_OP_QUEUE_STAGE_H
17 #define LLVM_MCA_MICRO_OP_QUEUE_STAGE_H
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/MCA/Stages/Stage.h"
25 /// A stage that simulates a queue of instruction opcodes.
26 class MicroOpQueueStage
: public Stage
{
27 SmallVector
<InstRef
, 8> Buffer
;
28 unsigned NextAvailableSlotIdx
;
29 unsigned CurrentInstructionSlotIdx
;
31 // Limits the number of instructions that can be written to this buffer every
32 // cycle. A value of zero means that there is no limit to the instruction
33 // throughput in input.
34 const unsigned MaxIPC
;
37 // Number of entries that are available during this cycle.
38 unsigned AvailableEntries
;
40 // True if instructions dispatched to this stage don't need to wait for the
41 // next cycle before moving to the next stage.
42 // False if this buffer acts as a one cycle delay in the execution pipeline.
43 bool IsZeroLatencyStage
;
45 MicroOpQueueStage(const MicroOpQueueStage
&Other
) = delete;
46 MicroOpQueueStage
&operator=(const MicroOpQueueStage
&Other
) = delete;
48 // By default, an instruction consumes a number of buffer entries equal to its
49 // number of micro opcodes (see field `InstrDesc::NumMicroOpcodes`). The
50 // number of entries consumed by an instruction is normalized to the
51 // minimum value between NumMicroOpcodes and the buffer size. This is to avoid
52 // problems with (microcoded) instructions that generate a number of micro
53 // opcodes than doesn't fit in the buffer.
54 unsigned getNormalizedOpcodes(const InstRef
&IR
) const {
55 unsigned NormalizedOpcodes
=
56 std::min(static_cast<unsigned>(Buffer
.size()),
57 IR
.getInstruction()->getDesc().NumMicroOps
);
58 return NormalizedOpcodes
? NormalizedOpcodes
: 1U;
61 Error
moveInstructions();
64 MicroOpQueueStage(unsigned Size
, unsigned IPC
= 0,
65 bool ZeroLatencyStage
= true);
67 bool isAvailable(const InstRef
&IR
) const override
{
68 if (MaxIPC
&& CurrentIPC
== MaxIPC
)
70 unsigned NormalizedOpcodes
= getNormalizedOpcodes(IR
);
71 if (NormalizedOpcodes
> AvailableEntries
)
76 bool hasWorkToComplete() const override
{
77 return AvailableEntries
!= Buffer
.size();
80 Error
execute(InstRef
&IR
) override
;
81 Error
cycleStart() override
;
82 Error
cycleEnd() override
;
88 #endif // LLVM_MCA_MICRO_OP_QUEUE_STAGE_H