blob: 0f91060ef3fb38291fcd71ce073105a8f42477ac [file] [log] [blame]
Matt Davisdea343d2018-06-25 16:53:00 +00001//===--------------------- Pipeline.cpp -------------------------*- C++ -*-===//
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +00002//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9/// \file
10///
Matt Davisdea343d2018-06-25 16:53:00 +000011/// This file implements an ordered container of stages that simulate the
12/// pipeline of a hardware backend.
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000013///
14//===----------------------------------------------------------------------===//
15
Matt Davisdea343d2018-06-25 16:53:00 +000016#include "Pipeline.h"
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000017#include "HWEventListener.h"
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000018#include "llvm/Support/Debug.h"
19
Fangrui Song5a8fd652018-10-30 15:56:08 +000020namespace llvm {
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000021namespace mca {
22
23#define DEBUG_TYPE "llvm-mca"
24
Matt Davisdea343d2018-06-25 16:53:00 +000025void Pipeline::addEventListener(HWEventListener *Listener) {
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000026 if (Listener)
27 Listeners.insert(Listener);
Matt Davis7b5a36e2018-06-27 16:09:33 +000028 for (auto &S : Stages)
29 S->addListener(Listener);
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000030}
31
Matt Davisdea343d2018-06-25 16:53:00 +000032bool Pipeline::hasWorkToProcess() {
Andrea Di Biagioa7699122018-09-28 10:47:24 +000033 return any_of(Stages, [](const std::unique_ptr<Stage> &S) {
Matt Davis43de6db2018-06-22 16:17:26 +000034 return S->hasWorkToComplete();
35 });
Matt Davis43de6db2018-06-22 16:17:26 +000036}
37
Andrea Di Biagio2a68a272018-11-28 16:24:51 +000038Expected<unsigned> Pipeline::run() {
Andrea Di Biagio492816d2018-08-16 15:43:09 +000039 assert(!Stages.empty() && "Unexpected empty pipeline found!");
40
Andrea Di Biagiocd4deea2018-10-24 19:37:45 +000041 do {
Andrea Di Biagioef6b8a32018-07-13 09:27:34 +000042 notifyCycleBegin();
Andrea Di Biagioa7699122018-09-28 10:47:24 +000043 if (Error Err = runCycle())
Matt Davis4bcf3692018-08-13 18:11:48 +000044 return Err;
Andrea Di Biagioef6b8a32018-07-13 09:27:34 +000045 notifyCycleEnd();
46 ++Cycles;
Andrea Di Biagiocd4deea2018-10-24 19:37:45 +000047 } while (hasWorkToProcess());
48
Andrea Di Biagio2a68a272018-11-28 16:24:51 +000049 return Cycles;
Matt Davis5d1cda12018-05-15 20:21:04 +000050}
51
Andrea Di Biagioa7699122018-09-28 10:47:24 +000052Error Pipeline::runCycle() {
53 Error Err = ErrorSuccess();
Andrea Di Biagiodb630882018-08-16 19:00:48 +000054 // Update stages before we start processing new instructions.
55 for (auto I = Stages.rbegin(), E = Stages.rend(); I != E && !Err; ++I) {
Andrea Di Biagio492816d2018-08-16 15:43:09 +000056 const std::unique_ptr<Stage> &S = *I;
57 Err = S->cycleStart();
58 }
Matt Davisbd125322018-05-22 20:51:58 +000059
Andrea Di Biagio492816d2018-08-16 15:43:09 +000060 // Now fetch and execute new instructions.
61 InstRef IR;
Andrea Di Biagiodb630882018-08-16 19:00:48 +000062 Stage &FirstStage = *Stages[0];
63 while (!Err && FirstStage.isAvailable(IR))
64 Err = FirstStage.execute(IR);
Matt Davis32508992018-07-12 22:59:53 +000065
Andrea Di Biagio492816d2018-08-16 15:43:09 +000066 // Update stages in preparation for a new cycle.
Andrea Di Biagiodb630882018-08-16 19:00:48 +000067 for (auto I = Stages.rbegin(), E = Stages.rend(); I != E && !Err; ++I) {
Andrea Di Biagio492816d2018-08-16 15:43:09 +000068 const std::unique_ptr<Stage> &S = *I;
69 Err = S->cycleEnd();
70 }
Andrea Di Biagiodb630882018-08-16 19:00:48 +000071
Andrea Di Biagio492816d2018-08-16 15:43:09 +000072 return Err;
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000073}
74
Andrea Di Biagiodb630882018-08-16 19:00:48 +000075void 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());
80 }
81
82 Stages.push_back(std::move(S));
83}
84
Andrea Di Biagioef6b8a32018-07-13 09:27:34 +000085void Pipeline::notifyCycleBegin() {
86 LLVM_DEBUG(dbgs() << "[E] Cycle begin: " << Cycles << '\n');
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000087 for (HWEventListener *Listener : Listeners)
Andrea Di Biagio3e646442018-04-12 10:49:40 +000088 Listener->onCycleBegin();
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000089}
90
Andrea Di Biagioef6b8a32018-07-13 09:27:34 +000091void Pipeline::notifyCycleEnd() {
92 LLVM_DEBUG(dbgs() << "[E] Cycle end: " << Cycles << "\n\n");
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000093 for (HWEventListener *Listener : Listeners)
Andrea Di Biagio3e646442018-04-12 10:49:40 +000094 Listener->onCycleEnd();
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000095}
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000096} // namespace mca.
Fangrui Song5a8fd652018-10-30 15:56:08 +000097} // namespace llvm