1 //===--------------------- Pipeline.cpp -------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
11 /// This file implements an ordered container of stages that simulate the
12 /// pipeline of a hardware backend.
14 //===----------------------------------------------------------------------===//
16 #include "llvm/MCA/Pipeline.h"
17 #include "llvm/MCA/HWEventListener.h"
18 #include "llvm/Support/Debug.h"
23 #define DEBUG_TYPE "llvm-mca"
25 void Pipeline::addEventListener(HWEventListener *Listener) {
27 Listeners.insert(Listener);
28 for (auto &S : Stages)
29 S->addListener(Listener);
32 bool Pipeline::hasWorkToProcess() {
33 return any_of(Stages, [](const std::unique_ptr<Stage> &S) {
34 return S->hasWorkToComplete();
38 Expected<unsigned> Pipeline::run() {
39 assert(!Stages.empty() && "Unexpected empty pipeline found!");
43 if (Error Err = runCycle())
44 return std::move(Err);
47 } while (hasWorkToProcess());
52 Error 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 Err = S->cycleStart();
60 // Now fetch and execute new instructions.
62 Stage &FirstStage = *Stages[0];
63 while (!Err && FirstStage.isAvailable(IR))
64 Err = FirstStage.execute(IR);
66 // Update stages in preparation for a new cycle.
67 for (auto I = Stages.rbegin(), E = Stages.rend(); I != E && !Err; ++I) {
68 const std::unique_ptr<Stage> &S = *I;
75 void Pipeline::appendStage(std::unique_ptr<Stage> S) {
76 assert(S && "Invalid null stage in input!");
77 if (!Stages.empty()) {
78 Stage *Last = Stages.back().get();
79 Last->setNextInSequence(S.get());
82 Stages.push_back(std::move(S));
85 void Pipeline::notifyCycleBegin() {
86 LLVM_DEBUG(dbgs() << "\n[E] Cycle begin: " << Cycles << '\n');
87 for (HWEventListener *Listener : Listeners)
88 Listener->onCycleBegin();
91 void Pipeline::notifyCycleEnd() {
92 LLVM_DEBUG(dbgs() << "[E] Cycle end: " << Cycles << "\n");
93 for (HWEventListener *Listener : Listeners)
94 Listener->onCycleEnd();