Path: blob/main/contrib/llvm-project/llvm/lib/MCA/Pipeline.cpp
35259 views
//===--------------------- Pipeline.cpp -------------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7/// \file8///9/// This file implements an ordered container of stages that simulate the10/// pipeline of a hardware backend.11///12//===----------------------------------------------------------------------===//1314#include "llvm/MCA/Pipeline.h"15#include "llvm/MCA/HWEventListener.h"16#include "llvm/Support/Debug.h"1718namespace llvm {19namespace mca {2021#define DEBUG_TYPE "llvm-mca"2223void Pipeline::addEventListener(HWEventListener *Listener) {24if (Listener)25Listeners.insert(Listener);26for (auto &S : Stages)27S->addListener(Listener);28}2930bool Pipeline::hasWorkToProcess() {31return any_of(Stages, [](const std::unique_ptr<Stage> &S) {32return S->hasWorkToComplete();33});34}3536Expected<unsigned> Pipeline::run() {37assert(!Stages.empty() && "Unexpected empty pipeline found!");3839do {40if (!isPaused())41notifyCycleBegin();42if (Error Err = runCycle())43return std::move(Err);44notifyCycleEnd();45++Cycles;46} while (hasWorkToProcess());4748return Cycles;49}5051Error Pipeline::runCycle() {52Error Err = ErrorSuccess();53// Update stages before we start processing new instructions.54for (auto I = Stages.rbegin(), E = Stages.rend(); I != E && !Err; ++I) {55const std::unique_ptr<Stage> &S = *I;56if (isPaused())57Err = S->cycleResume();58else59Err = S->cycleStart();60}6162CurrentState = State::Started;6364// Now fetch and execute new instructions.65InstRef IR;66Stage &FirstStage = *Stages[0];67while (!Err && FirstStage.isAvailable(IR))68Err = FirstStage.execute(IR);6970if (Err.isA<InstStreamPause>()) {71CurrentState = State::Paused;72return Err;73}7475// Update stages in preparation for a new cycle.76for (const std::unique_ptr<Stage> &S : Stages) {77Err = S->cycleEnd();78if (Err)79break;80}8182return Err;83}8485void Pipeline::appendStage(std::unique_ptr<Stage> S) {86assert(S && "Invalid null stage in input!");87if (!Stages.empty()) {88Stage *Last = Stages.back().get();89Last->setNextInSequence(S.get());90}9192Stages.push_back(std::move(S));93}9495void Pipeline::notifyCycleBegin() {96LLVM_DEBUG(dbgs() << "\n[E] Cycle begin: " << Cycles << '\n');97for (HWEventListener *Listener : Listeners)98Listener->onCycleBegin();99}100101void Pipeline::notifyCycleEnd() {102LLVM_DEBUG(dbgs() << "[E] Cycle end: " << Cycles << "\n");103for (HWEventListener *Listener : Listeners)104Listener->onCycleEnd();105}106} // namespace mca.107} // namespace llvm108109110