add_llvm_tool(llvm-mca
CodeRegion.cpp
+ Context.cpp
DispatchStage.cpp
DispatchStatistics.cpp
ExecuteStage.cpp
FetchStage.cpp
HWEventListener.cpp
+ HardwareUnit.cpp
InstrBuilder.cpp
Instruction.cpp
InstructionInfoView.cpp
--- /dev/null
+//===---------------------------- Context.cpp -------------------*- 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 defines a class for holding ownership of various simulated
+/// hardware units. A Context also provides a utility routine for constructing
+/// a default out-of-order pipeline with fetch, dispatch, execute, and retire
+/// stages).
+///
+//===----------------------------------------------------------------------===//
+
+#include "Context.h"
+#include "DispatchStage.h"
+#include "ExecuteStage.h"
+#include "FetchStage.h"
+#include "RegisterFile.h"
+#include "RetireControlUnit.h"
+#include "RetireStage.h"
+#include "Scheduler.h"
+
+namespace mca {
+
+using namespace llvm;
+
+std::unique_ptr<Pipeline>
+Context::createDefaultPipeline(const PipelineOptions &Opts, InstrBuilder &IB,
+ SourceMgr &SrcMgr) {
+ const MCSchedModel &SM = STI.getSchedModel();
+
+ // Create the hardware units defining the backend.
+ auto RCU = llvm::make_unique<RetireControlUnit>(SM);
+ auto PRF = llvm::make_unique<RegisterFile>(SM, MRI, Opts.RegisterFileSize);
+ auto HWS = llvm::make_unique<Scheduler>(
+ SM, Opts.LoadQueueSize, Opts.StoreQueueSize, Opts.AssumeNoAlias);
+
+ // Create the pipeline and its stages.
+ auto P = llvm::make_unique<Pipeline>(
+ Opts.DispatchWidth, Opts.RegisterFileSize, Opts.LoadQueueSize,
+ Opts.StoreQueueSize, Opts.AssumeNoAlias);
+ auto F = llvm::make_unique<FetchStage>(IB, SrcMgr);
+ auto D = llvm::make_unique<DispatchStage>(
+ STI, MRI, Opts.RegisterFileSize, Opts.DispatchWidth, *RCU, *PRF, *HWS);
+ auto R = llvm::make_unique<RetireStage>(*RCU, *PRF);
+ auto E = llvm::make_unique<ExecuteStage>(*RCU, *HWS);
+
+ // Add the hardware to the context.
+ addHardwareUnit(std::move(RCU));
+ addHardwareUnit(std::move(PRF));
+ addHardwareUnit(std::move(HWS));
+
+ // Build the pipeline.
+ P->appendStage(std::move(F));
+ P->appendStage(std::move(D));
+ P->appendStage(std::move(R));
+ P->appendStage(std::move(E));
+ return P;
+}
+
+} // namespace mca
--- /dev/null
+//===---------------------------- Context.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 defines a class for holding ownership of various simulated
+/// hardware units. A Context also provides a utility routine for constructing
+/// a default out-of-order pipeline with fetch, dispatch, execute, and retire
+/// stages).
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVM_MCA_CONTEXT_H
+#define LLVM_TOOLS_LLVM_MCA_CONTEXT_H
+#include "HardwareUnit.h"
+#include "InstrBuilder.h"
+#include "Pipeline.h"
+#include "SourceMgr.h"
+#include "llvm/MC/MCRegisterInfo.h"
+#include "llvm/MC/MCSchedule.h"
+#include "llvm/MC/MCSubtargetInfo.h"
+#include <memory>
+
+namespace mca {
+
+/// This is a convenience struct to hold the parameters necessary for creating
+/// the pre-built "default" out-of-order pipeline.
+struct PipelineOptions {
+ PipelineOptions(unsigned DW, unsigned RFS, unsigned LQS, unsigned SQS,
+ bool NoAlias)
+ : DispatchWidth(DW), RegisterFileSize(RFS), LoadQueueSize(LQS),
+ StoreQueueSize(SQS), AssumeNoAlias(NoAlias) {}
+ unsigned DispatchWidth;
+ unsigned RegisterFileSize;
+ unsigned LoadQueueSize;
+ unsigned StoreQueueSize;
+ bool AssumeNoAlias;
+};
+
+class Context {
+ llvm::SmallVector<std::unique_ptr<HardwareUnit>, 4> Hardware;
+ const llvm::MCRegisterInfo &MRI;
+ const llvm::MCSubtargetInfo &STI;
+
+public:
+ Context(const llvm::MCRegisterInfo &R, const llvm::MCSubtargetInfo &S)
+ : MRI(R), STI(S) {}
+ Context(const Context &C) = delete;
+ Context &operator=(const Context &C) = delete;
+
+ void addHardwareUnit(std::unique_ptr<HardwareUnit> H) {
+ Hardware.push_back(std::move(H));
+ }
+
+ /// Construct a basic pipeline for simulating an out-of-order pipeline.
+ /// This pipeline consists of Fetch, Dispatch, Execute, and Retire stages.
+ std::unique_ptr<Pipeline> createDefaultPipeline(const PipelineOptions &Opts,
+ InstrBuilder &IB,
+ SourceMgr &SrcMgr);
+};
+
+} // namespace mca
+#endif // LLVM_TOOLS_LLVM_MCA_CONTEXT_H
--- /dev/null
+//===------------------------- HardwareUnit.cpp -----------------*- 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 defines the anchor for the base class that describes
+/// simulated hardware units.
+///
+//===----------------------------------------------------------------------===//
+
+#include "HardwareUnit.h"
+
+namespace mca {
+
+// Pin the vtable with this method.
+HardwareUnit::~HardwareUnit() = default;
+
+} // namespace mca
--- /dev/null
+//===-------------------------- HardwareUnit.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 defines a base class for describing a simulated hardware
+/// unit. These units are used to construct a simulated backend.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_TOOLS_LLVM_MCA_HARDWAREUNIT_H
+#define LLVM_TOOLS_LLVM_MCA_HARDWAREUNIT_H
+
+namespace mca {
+
+class HardwareUnit {
+ HardwareUnit(const HardwareUnit &H) = delete;
+ HardwareUnit &operator=(const HardwareUnit &H) = delete;
+
+public:
+ HardwareUnit() = default;
+ virtual ~HardwareUnit();
+};
+
+} // namespace mca
+#endif // LLVM_TOOLS_LLVM_MCA_HARDWAREUNIT_H
#ifndef LLVM_TOOLS_LLVM_MCA_REGISTER_FILE_H
#define LLVM_TOOLS_LLVM_MCA_REGISTER_FILE_H
+#include "HardwareUnit.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSchedule.h"
/// Manages hardware register files, and tracks register definitions for
/// register renaming purposes.
-class RegisterFile {
+class RegisterFile : public HardwareUnit {
const llvm::MCRegisterInfo &MRI;
// Each register file is associated with an instance of
- // RegisterMappingTracker. A RegisterMappingTracker tracks the number of
- // physical registers that are dynamically allocated by the simulator.
+ // RegisterMappingTracker.
+ // A RegisterMappingTracker keeps track of the number of physical registers
+ // which have been dynamically allocated by the simulator.
struct RegisterMappingTracker {
// The total number of physical registers that are available in this
// register file for register renaming purpouses. A value of zero for this
#ifndef LLVM_TOOLS_LLVM_MCA_RETIRE_CONTROL_UNIT_H
#define LLVM_TOOLS_LLVM_MCA_RETIRE_CONTROL_UNIT_H
+#include "HardwareUnit.h"
#include "Instruction.h"
#include "llvm/MC/MCSchedule.h"
#include <vector>
/// On instruction retired, register updates are all architecturally
/// committed, and any temporary registers originally allocated for the
/// retired instruction are freed.
-struct RetireControlUnit {
+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.
//
#define LLVM_TOOLS_LLVM_MCA_SCHEDULER_H
#include "HWEventListener.h"
+#include "HardwareUnit.h"
#include "Instruction.h"
#include "LSUnit.h"
#include "RetireControlUnit.h"
/// issued to a (one or more) pipeline(s). This event also causes an instruction
/// state transition (i.e. from state IS_READY, to state IS_EXECUTING).
/// An Instruction leaves the IssuedQueue when it reaches the write-back stage.
-class Scheduler {
+class Scheduler : public HardwareUnit {
const llvm::MCSchedModel &SM;
// Hardware resources that are managed by this scheduler.
//===----------------------------------------------------------------------===//
#include "CodeRegion.h"
-#include "DispatchStage.h"
+#include "Context.h"
#include "DispatchStatistics.h"
-#include "ExecuteStage.h"
-#include "FetchStage.h"
#include "InstructionInfoView.h"
#include "InstructionTables.h"
#include "Pipeline.h"
#include "PipelinePrinter.h"
-#include "RegisterFile.h"
#include "RegisterFileStatistics.h"
#include "ResourcePressureView.h"
-#include "RetireControlUnit.h"
#include "RetireControlUnitStatistics.h"
-#include "RetireStage.h"
-#include "Scheduler.h"
#include "SchedulerStatistics.h"
#include "SummaryView.h"
#include "TimelineView.h"
// Create an instruction builder.
mca::InstrBuilder IB(*STI, *MCII, *MRI, *MCIA);
+ // Create a context to control ownership of the pipeline hardware.
+ mca::Context MCA(*MRI, *STI);
+
+ mca::PipelineOptions PO(Width, RegisterFileSize, LoadQueueSize,
+ StoreQueueSize, AssumeNoAlias);
+
// Number each region in the sequence.
unsigned RegionIdx = 0;
for (const std::unique_ptr<mca::CodeRegion> &Region : Regions) {
continue;
}
- // Create the hardware components required for the pipeline.
- mca::RetireControlUnit RCU(SM);
- mca::RegisterFile PRF(SM, *MRI, RegisterFileSize);
- mca::Scheduler HWS(SM, LoadQueueSize, StoreQueueSize, AssumeNoAlias);
-
- // Create the pipeline and add stages to it.
- auto P = llvm::make_unique<mca::Pipeline>(
- Width, RegisterFileSize, LoadQueueSize, StoreQueueSize, AssumeNoAlias);
- P->appendStage(llvm::make_unique<mca::FetchStage>(IB, S));
- P->appendStage(llvm::make_unique<mca::DispatchStage>(
- *STI, *MRI, RegisterFileSize, Width, RCU, PRF, HWS));
- P->appendStage(llvm::make_unique<mca::RetireStage>(RCU, PRF));
- P->appendStage(llvm::make_unique<mca::ExecuteStage>(RCU, HWS));
+ // Create a basic pipeline simulating an out-of-order backend.
+ auto P = MCA.createDefaultPipeline(PO, IB, S);
mca::PipelinePrinter Printer(*P);
if (PrintSummaryView)