1 //===--------------------- Pipeline.cpp -------------------------*- C++ -*-===//
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-exception
7 //===----------------------------------------------------------------------===//
10 /// This file implements an ordered container of stages that simulate the
11 /// pipeline of a hardware backend.
13 //===----------------------------------------------------------------------===//
15 #include "llvm/MCA/Pipeline.h"
16 #include "llvm/MCA/HWEventListener.h"
17 #include "llvm/Support/Debug.h"
22 #define DEBUG_TYPE "llvm-mca"
24 void Pipeline::addEventListener(HWEventListener
*Listener
) {
26 Listeners
.insert(Listener
);
27 for (auto &S
: Stages
)
28 S
->addListener(Listener
);
31 bool Pipeline::hasWorkToProcess() {
32 return any_of(Stages
, [](const std::unique_ptr
<Stage
> &S
) {
33 return S
->hasWorkToComplete();
37 Expected
<unsigned> Pipeline::run() {
38 assert(!Stages
.empty() && "Unexpected empty pipeline found!");
42 if (Error Err
= runCycle())
43 return std::move(Err
);
46 } while (hasWorkToProcess());
51 Error
Pipeline::runCycle() {
52 Error Err
= ErrorSuccess();
53 // Update stages before we start processing new instructions.
54 for (auto I
= Stages
.rbegin(), E
= Stages
.rend(); I
!= E
&& !Err
; ++I
) {
55 const std::unique_ptr
<Stage
> &S
= *I
;
56 Err
= S
->cycleStart();
59 // Now fetch and execute new instructions.
61 Stage
&FirstStage
= *Stages
[0];
62 while (!Err
&& FirstStage
.isAvailable(IR
))
63 Err
= FirstStage
.execute(IR
);
65 // Update stages in preparation for a new cycle.
66 for (const std::unique_ptr
<Stage
> &S
: Stages
) {
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();