diff options
author | Matt Davis <Matthew.Davis@sony.com> | 2018-08-27 17:16:32 +0000 |
---|---|---|
committer | Matt Davis <Matthew.Davis@sony.com> | 2018-08-27 17:16:32 +0000 |
commit | 271ce76352fdef802e6ecea7d1a9bb595963b609 (patch) | |
tree | 6e1615bba5451f7e3be62f6b88cf339c0294a18d /llvm/tools/llvm-mca/include/HardwareUnits/RetireControlUnit.h | |
parent | b09ecf93060d982c26fa036c9beb1140b7e5f627 (diff) | |
download | bcm5719-llvm-271ce76352fdef802e6ecea7d1a9bb595963b609.tar.gz bcm5719-llvm-271ce76352fdef802e6ecea7d1a9bb595963b609.zip |
[llvm-mca] Introduce the llvm-mca library and organize the directory accordingly. NFC.
Summary:
This patch introduces llvm-mca as a library. The driver (llvm-mca.cpp), views, and stats, are not part of the library.
Those are separate components that are not required for the functioning of llvm-mca.
The directory has been organized as follows:
All library source files now reside in:
- `lib/HardwareUnits/` - All subclasses of HardwareUnit (these represent the simulated hardware components of a backend).
(LSUnit does not inherit from HardwareUnit, but Scheduler does which uses LSUnit).
- `lib/Stages/` - All subclasses of the pipeline stages.
- `lib/` - This is the root of the library and contains library code that does not fit into the Stages or HardwareUnit subdirs.
All library header files now reside in the `include` directory and mimic the same layout as the `lib` directory mentioned above.
In the (near) future we would like to move the library (include and lib) contents from tools and into the core of llvm somewhere.
That change would allow various analysis and optimization passes to make use of MCA functionality for things like cost modeling.
I left all of the non-library code just where it has always been, in the root of the llvm-mca directory.
The include directives for the non-library source file have been updated to refer to the llvm-mca library headers.
I updated the llvm-mca/CMakeLists.txt file to include the library headers, but I made the non-library code
explicitly reference the library's 'include' directory. Once we eventually (hopefully) migrate the MCA library
components into llvm the include directives used by the non-library source files will be updated to point to the
proper location in llvm.
Reviewers: andreadb, courbet, RKSimon
Reviewed By: andreadb
Subscribers: mgorny, javed.absar, tschuett, gbedwell, llvm-commits
Differential Revision: https://reviews.llvm.org/D50929
llvm-svn: 340755
Diffstat (limited to 'llvm/tools/llvm-mca/include/HardwareUnits/RetireControlUnit.h')
-rw-r--r-- | llvm/tools/llvm-mca/include/HardwareUnits/RetireControlUnit.h | 97 |
1 files changed, 97 insertions, 0 deletions
diff --git a/llvm/tools/llvm-mca/include/HardwareUnits/RetireControlUnit.h b/llvm/tools/llvm-mca/include/HardwareUnits/RetireControlUnit.h new file mode 100644 index 00000000000..7f2d699e410 --- /dev/null +++ b/llvm/tools/llvm-mca/include/HardwareUnits/RetireControlUnit.h @@ -0,0 +1,97 @@ +//===---------------------- RetireControlUnit.h -----------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// +/// This file simulates the hardware responsible for retiring instructions. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_LLVM_MCA_RETIRE_CONTROL_UNIT_H +#define LLVM_TOOLS_LLVM_MCA_RETIRE_CONTROL_UNIT_H + +#include "HardwareUnits/HardwareUnit.h" +#include "Instruction.h" +#include "llvm/MC/MCSchedule.h" +#include <vector> + +namespace mca { + +/// This class tracks which instructions are in-flight (i.e., dispatched but not +/// retired) in the OoO backend. +// +/// This class checks on every cycle if/which instructions can be retired. +/// Instructions are retired in program order. +/// In the event of an instruction being retired, the pipeline that owns +/// this RetireControlUnit (RCU) gets notified. +/// +/// On instruction retired, register updates are all architecturally +/// committed, and any physicall registers previously allocated for the +/// retired instruction are freed. +struct RetireControlUnit : public HardwareUnit { + // A RUToken is created by the RCU for every instruction dispatched to the + // schedulers. These "tokens" are managed by the RCU in its token Queue. + // + // On every cycle ('cycleEvent'), the RCU iterates through the token queue + // looking for any token with its 'Executed' flag set. If a token has that + // flag set, then the instruction has reached the write-back stage and will + // be retired by the RCU. + // + // 'NumSlots' represents the number of entries consumed by the instruction in + // the reorder buffer. Those entries will become available again once the + // instruction is retired. + // + // Note that the size of the reorder buffer is defined by the scheduling + // model via field 'NumMicroOpBufferSize'. + struct RUToken { + InstRef IR; + unsigned NumSlots; // Slots reserved to this instruction. + bool Executed; // True if the instruction is past the WB stage. + }; + +private: + unsigned NextAvailableSlotIdx; + unsigned CurrentInstructionSlotIdx; + unsigned AvailableSlots; + unsigned MaxRetirePerCycle; // 0 means no limit. + std::vector<RUToken> Queue; + +public: + RetireControlUnit(const llvm::MCSchedModel &SM); + + bool isEmpty() const { return AvailableSlots == Queue.size(); } + bool isAvailable(unsigned Quantity = 1) const { + // Some instructions may declare a number of uOps which exceeds the size + // of the reorder buffer. To avoid problems, cap the amount of slots to + // the size of the reorder buffer. + Quantity = std::min(Quantity, static_cast<unsigned>(Queue.size())); + return AvailableSlots >= Quantity; + } + + unsigned getMaxRetirePerCycle() const { return MaxRetirePerCycle; } + + // Reserves a number of slots, and returns a new token. + unsigned reserveSlot(const InstRef &IS, unsigned NumMicroOps); + + // Return the current token from the RCU's circular token queue. + const RUToken &peekCurrentToken() const; + + // Advance the pointer to the next token in the circular token queue. + void consumeCurrentToken(); + + // Update the RCU token to represent the executed state. + void onInstructionExecuted(unsigned TokenID); + +#ifndef NDEBUG + void dump() const; +#endif +}; + +} // namespace mca + +#endif // LLVM_TOOLS_LLVM_MCA_RETIRE_CONTROL_UNIT_H |