mirror of
https://github.com/RPCS3/llvm.git
synced 2025-02-25 13:20:57 +00:00

This allows the customization of the performance report. Users can specify their own custom sequence of views. Each view contributes a portion of the performance report generated by the BackendPrinter. Internally, class BackendPrinter keeps a sequence of views; views are printed out in sequence when method 'printReport()' is called. This patch addresses one of the two review comments from Clement in D43951. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@327018 91177308-0d34-0410-b5e6-96231b3b80d8
133 lines
4.0 KiB
C++
133 lines
4.0 KiB
C++
//===--------------------- Backend.cpp --------------------------*- C++ -*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
/// \file
|
|
///
|
|
/// Implementation of class Backend which emulates an hardware OoO backend.
|
|
///
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "Backend.h"
|
|
#include "HWEventListener.h"
|
|
#include "llvm/CodeGen/TargetSchedule.h"
|
|
#include "llvm/Support/Debug.h"
|
|
|
|
namespace mca {
|
|
|
|
#define DEBUG_TYPE "llvm-mca"
|
|
|
|
using namespace llvm;
|
|
|
|
void Backend::addEventListener(HWEventListener *Listener) {
|
|
if (Listener)
|
|
Listeners.insert(Listener);
|
|
}
|
|
|
|
void Backend::runCycle(unsigned Cycle) {
|
|
notifyCycleBegin(Cycle);
|
|
|
|
if (!SM.hasNext()) {
|
|
notifyCycleEnd(Cycle);
|
|
return;
|
|
}
|
|
|
|
InstRef IR = SM.peekNext();
|
|
const InstrDesc *Desc = &IB->getOrCreateInstrDesc(STI, *IR.second);
|
|
while (DU->isAvailable(Desc->NumMicroOps) && DU->canDispatch(*Desc)) {
|
|
Instruction *NewIS = IB->createInstruction(STI, *DU, IR.first, *IR.second);
|
|
Instructions[IR.first] = std::unique_ptr<Instruction>(NewIS);
|
|
NewIS->setRCUTokenID(DU->dispatch(IR.first, NewIS));
|
|
|
|
// If this is a zero latency instruction, then we don't need to dispatch
|
|
// it. Instead, we can mark it as executed.
|
|
if (NewIS->isZeroLatency())
|
|
notifyInstructionExecuted(IR.first);
|
|
|
|
// Check if we have dispatched all the instructions.
|
|
SM.updateNext();
|
|
if (!SM.hasNext())
|
|
break;
|
|
|
|
// Prepare for the next round.
|
|
IR = SM.peekNext();
|
|
Desc = &IB->getOrCreateInstrDesc(STI, *IR.second);
|
|
}
|
|
|
|
notifyCycleEnd(Cycle);
|
|
}
|
|
|
|
void Backend::notifyCycleBegin(unsigned Cycle) {
|
|
DEBUG(dbgs() << "[E] Cycle begin: " << Cycle << '\n');
|
|
for (HWEventListener *Listener : Listeners)
|
|
Listener->onCycleBegin(Cycle);
|
|
|
|
DU->cycleEvent(Cycle);
|
|
HWS->cycleEvent(Cycle);
|
|
}
|
|
|
|
void Backend::notifyInstructionDispatched(unsigned Index) {
|
|
DEBUG(dbgs() << "[E] Instruction Dispatched: " << Index << '\n');
|
|
for (HWEventListener *Listener : Listeners)
|
|
Listener->onInstructionDispatched(Index);
|
|
}
|
|
|
|
void Backend::notifyInstructionReady(unsigned Index) {
|
|
DEBUG(dbgs() << "[E] Instruction Ready: " << Index << '\n');
|
|
for (HWEventListener *Listener : Listeners)
|
|
Listener->onInstructionReady(Index);
|
|
}
|
|
|
|
void Backend::notifyInstructionIssued(
|
|
unsigned Index, const ArrayRef<std::pair<ResourceRef, unsigned>> &Used) {
|
|
DEBUG(
|
|
dbgs() << "[E] Instruction Issued: " << Index << '\n';
|
|
for (const std::pair<ResourceRef, unsigned> &Resource : Used) {
|
|
dbgs() << "[E] Resource Used: [" << Resource.first.first << '.'
|
|
<< Resource.first.second << "]\n";
|
|
dbgs() << " cycles: " << Resource.second << '\n';
|
|
}
|
|
);
|
|
|
|
for (HWEventListener *Listener : Listeners)
|
|
Listener->onInstructionIssued(Index, Used);
|
|
}
|
|
|
|
void Backend::notifyInstructionExecuted(unsigned Index) {
|
|
DEBUG(dbgs() << "[E] Instruction Executed: " << Index << '\n');
|
|
for (HWEventListener *Listener : Listeners)
|
|
Listener->onInstructionExecuted(Index);
|
|
|
|
const Instruction &IS = *Instructions[Index];
|
|
DU->onInstructionExecuted(IS.getRCUTokenID());
|
|
}
|
|
|
|
void Backend::notifyInstructionRetired(unsigned Index) {
|
|
DEBUG(dbgs() << "[E] Instruction Retired: " << Index << '\n');
|
|
for (HWEventListener *Listener : Listeners)
|
|
Listener->onInstructionRetired(Index);
|
|
|
|
const Instruction &IS = *Instructions[Index];
|
|
DU->invalidateRegisterMappings(IS);
|
|
Instructions.erase(Index);
|
|
}
|
|
|
|
void Backend::notifyResourceAvailable(const ResourceRef &RR) {
|
|
DEBUG(dbgs() << "[E] Resource Available: [" << RR.first << '.' << RR.second
|
|
<< "]\n");
|
|
for (HWEventListener *Listener : Listeners)
|
|
Listener->onResourceAvailable(RR);
|
|
}
|
|
|
|
void Backend::notifyCycleEnd(unsigned Cycle) {
|
|
DEBUG(dbgs() << "[E] Cycle end: " << Cycle << "\n\n");
|
|
for (HWEventListener *Listener : Listeners)
|
|
Listener->onCycleEnd(Cycle);
|
|
}
|
|
|
|
} // namespace mca.
|