1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-18 10:32:48 +02:00
llvm-mirror/lib/MCA/Context.cpp
Patrick Holland 449e2cbd5e Reapply "[MCA] Adding the CustomBehaviour class to llvm-mca".
The original change was pushed in main as commit f7a23ecece52.
It was then reverted by commit a04f01bab2 because it caused linker failures
on buildbots that don't build the AMDGPU target.

--

Some instructions are not defined well enough within the target’s scheduling
model for llvm-mca to be able to properly simulate its behaviour. The ideal
solution to this situation is to modify the scheduling model, but that’s not
always a viable strategy. Maybe other parts of the backend depend on that
instruction being modelled the way that it is. Or maybe the instruction is quite
complex and it’s difficult to fully capture its behaviour with tablegen. The
CustomBehaviour class (which I will refer to as CB frequently) is designed to
provide intuitive scaffolding for developers to implement the correct modelling
for these instructions.

More details are available in the original commit log message (f7a23ecece52).

Differential Revision: https://reviews.llvm.org/D104149
2021-06-16 16:54:48 +01:00

94 lines
3.6 KiB
C++

//===---------------------------- Context.cpp -------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
/// \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 "llvm/MCA/Context.h"
#include "llvm/MCA/HardwareUnits/RegisterFile.h"
#include "llvm/MCA/HardwareUnits/RetireControlUnit.h"
#include "llvm/MCA/HardwareUnits/Scheduler.h"
#include "llvm/MCA/Stages/DispatchStage.h"
#include "llvm/MCA/Stages/EntryStage.h"
#include "llvm/MCA/Stages/ExecuteStage.h"
#include "llvm/MCA/Stages/InOrderIssueStage.h"
#include "llvm/MCA/Stages/MicroOpQueueStage.h"
#include "llvm/MCA/Stages/RetireStage.h"
namespace llvm {
namespace mca {
std::unique_ptr<Pipeline>
Context::createDefaultPipeline(const PipelineOptions &Opts, SourceMgr &SrcMgr,
CustomBehaviour &CB) {
const MCSchedModel &SM = STI.getSchedModel();
if (!SM.isOutOfOrder())
return createInOrderPipeline(Opts, SrcMgr, CB);
// Create the hardware units defining the backend.
auto RCU = std::make_unique<RetireControlUnit>(SM);
auto PRF = std::make_unique<RegisterFile>(SM, MRI, Opts.RegisterFileSize);
auto LSU = std::make_unique<LSUnit>(SM, Opts.LoadQueueSize,
Opts.StoreQueueSize, Opts.AssumeNoAlias);
auto HWS = std::make_unique<Scheduler>(SM, *LSU);
// Create the pipeline stages.
auto Fetch = std::make_unique<EntryStage>(SrcMgr);
auto Dispatch =
std::make_unique<DispatchStage>(STI, MRI, Opts.DispatchWidth, *RCU, *PRF);
auto Execute =
std::make_unique<ExecuteStage>(*HWS, Opts.EnableBottleneckAnalysis);
auto Retire = std::make_unique<RetireStage>(*RCU, *PRF, *LSU);
// Pass the ownership of all the hardware units to this Context.
addHardwareUnit(std::move(RCU));
addHardwareUnit(std::move(PRF));
addHardwareUnit(std::move(LSU));
addHardwareUnit(std::move(HWS));
// Build the pipeline.
auto StagePipeline = std::make_unique<Pipeline>();
StagePipeline->appendStage(std::move(Fetch));
if (Opts.MicroOpQueueSize)
StagePipeline->appendStage(std::make_unique<MicroOpQueueStage>(
Opts.MicroOpQueueSize, Opts.DecodersThroughput));
StagePipeline->appendStage(std::move(Dispatch));
StagePipeline->appendStage(std::move(Execute));
StagePipeline->appendStage(std::move(Retire));
return StagePipeline;
}
std::unique_ptr<Pipeline>
Context::createInOrderPipeline(const PipelineOptions &Opts, SourceMgr &SrcMgr,
CustomBehaviour &CB) {
const MCSchedModel &SM = STI.getSchedModel();
auto PRF = std::make_unique<RegisterFile>(SM, MRI, Opts.RegisterFileSize);
// Create the pipeline stages.
auto Entry = std::make_unique<EntryStage>(SrcMgr);
auto InOrderIssue = std::make_unique<InOrderIssueStage>(STI, *PRF, CB);
auto StagePipeline = std::make_unique<Pipeline>();
// Pass the ownership of all the hardware units to this Context.
addHardwareUnit(std::move(PRF));
// Build the pipeline.
StagePipeline->appendStage(std::move(Entry));
StagePipeline->appendStage(std::move(InOrderIssue));
return StagePipeline;
}
} // namespace mca
} // namespace llvm