diff options
Diffstat (limited to 'llvm/tools/llvm-mca/Backend.cpp')
-rw-r--r-- | llvm/tools/llvm-mca/Backend.cpp | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/llvm/tools/llvm-mca/Backend.cpp b/llvm/tools/llvm-mca/Backend.cpp new file mode 100644 index 00000000000..890cbc14d86 --- /dev/null +++ b/llvm/tools/llvm-mca/Backend.cpp @@ -0,0 +1,132 @@ +//===--------------------- 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. |