brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.7 KiB · c94fe14 Raw
109 lines · cpp
1//===--------------------- Pipeline.cpp -------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8/// \file9///10/// This file implements an ordered container of stages that simulate the11/// pipeline of a hardware backend.12///13//===----------------------------------------------------------------------===//14 15#include "llvm/MCA/Pipeline.h"16#include "llvm/MCA/HWEventListener.h"17#include "llvm/Support/Debug.h"18 19namespace llvm {20namespace mca {21 22#define DEBUG_TYPE "llvm-mca"23 24void Pipeline::addEventListener(HWEventListener *Listener) {25  if (Listener)26    Listeners.insert(Listener);27  for (auto &S : Stages)28    S->addListener(Listener);29}30 31bool Pipeline::hasWorkToProcess() {32  return any_of(Stages, [](const std::unique_ptr<Stage> &S) {33    return S->hasWorkToComplete();34  });35}36 37Expected<unsigned> Pipeline::run() {38  assert(!Stages.empty() && "Unexpected empty pipeline found!");39 40  do {41    if (!isPaused())42      notifyCycleBegin();43    if (Error Err = runCycle())44      return std::move(Err);45    notifyCycleEnd();46    ++Cycles;47  } while (hasWorkToProcess());48 49  return Cycles;50}51 52Error Pipeline::runCycle() {53  Error Err = ErrorSuccess();54  // Update stages before we start processing new instructions.55  for (auto I = Stages.rbegin(), E = Stages.rend(); I != E && !Err; ++I) {56    const std::unique_ptr<Stage> &S = *I;57    if (isPaused())58      Err = S->cycleResume();59    else60      Err = S->cycleStart();61  }62 63  CurrentState = State::Started;64 65  // Now fetch and execute new instructions.66  InstRef IR;67  Stage &FirstStage = *Stages[0];68  while (!Err && FirstStage.isAvailable(IR))69    Err = FirstStage.execute(IR);70 71  if (Err.isA<InstStreamPause>()) {72    CurrentState = State::Paused;73    return Err;74  }75 76  // Update stages in preparation for a new cycle.77  for (const std::unique_ptr<Stage> &S : Stages) {78    Err = S->cycleEnd();79    if (Err)80      break;81  }82 83  return Err;84}85 86void Pipeline::appendStage(std::unique_ptr<Stage> S) {87  assert(S && "Invalid null stage in input!");88  if (!Stages.empty()) {89    Stage *Last = Stages.back().get();90    Last->setNextInSequence(S.get());91  }92 93  Stages.push_back(std::move(S));94}95 96void Pipeline::notifyCycleBegin() {97  LLVM_DEBUG(dbgs() << "\n[E] Cycle begin: " << Cycles << '\n');98  for (HWEventListener *Listener : Listeners)99    Listener->onCycleBegin();100}101 102void Pipeline::notifyCycleEnd() {103  LLVM_DEBUG(dbgs() << "[E] Cycle end: " << Cycles << "\n");104  for (HWEventListener *Listener : Listeners)105    Listener->onCycleEnd();106}107} // namespace mca.108} // namespace llvm109