blob: 7c937e7b48b5b5bb6867531b102362ee334678b0 [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"
18#include "llvm/CodeGen/TargetSchedule.h"
19#include "llvm/Support/Debug.h"
20
21namespace mca {
22
23#define DEBUG_TYPE "llvm-mca"
24
25using namespace llvm;
26
Matt Davisdea343d2018-06-25 16:53:00 +000027void Pipeline::addEventListener(HWEventListener *Listener) {
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000028 if (Listener)
29 Listeners.insert(Listener);
Matt Davis7b5a36e2018-06-27 16:09:33 +000030 for (auto &S : Stages)
31 S->addListener(Listener);
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000032}
33
Matt Davisdea343d2018-06-25 16:53:00 +000034bool Pipeline::hasWorkToProcess() {
Matt Davis43de6db2018-06-22 16:17:26 +000035 const auto It = llvm::find_if(Stages, [](const std::unique_ptr<Stage> &S) {
36 return S->hasWorkToComplete();
37 });
38 return It != Stages.end();
39}
40
41// This routine returns early if any stage returns 'false' after execute() is
42// called on it.
Matt Davisdea343d2018-06-25 16:53:00 +000043bool Pipeline::executeStages(InstRef &IR) {
Matt Davis43de6db2018-06-22 16:17:26 +000044 for (const std::unique_ptr<Stage> &S : Stages)
45 if (!S->execute(IR))
46 return false;
47 return true;
48}
49
Matt Davisf6bcbf32018-07-14 00:10:42 +000050void Pipeline::preExecuteStages() {
Matt Davis32508992018-07-12 22:59:53 +000051 for (const std::unique_ptr<Stage> &S : Stages)
Matt Davisf6bcbf32018-07-14 00:10:42 +000052 S->preExecute();
Matt Davis32508992018-07-12 22:59:53 +000053}
54
Matt Davisf6bcbf32018-07-14 00:10:42 +000055void Pipeline::postExecuteStages() {
Matt Davis43de6db2018-06-22 16:17:26 +000056 for (const std::unique_ptr<Stage> &S : Stages)
Matt Davisf6bcbf32018-07-14 00:10:42 +000057 S->postExecute();
Matt Davis43de6db2018-06-22 16:17:26 +000058}
59
Matt Davisdea343d2018-06-25 16:53:00 +000060void Pipeline::run() {
Andrea Di Biagioef6b8a32018-07-13 09:27:34 +000061 while (hasWorkToProcess()) {
62 notifyCycleBegin();
63 runCycle();
64 notifyCycleEnd();
65 ++Cycles;
66 }
Matt Davis5d1cda12018-05-15 20:21:04 +000067}
68
Andrea Di Biagioef6b8a32018-07-13 09:27:34 +000069void Pipeline::runCycle() {
Matt Davis5b79ffc5b2018-05-25 18:00:25 +000070 // Update the stages before we do any processing for this cycle.
Matt Davis5d1cda12018-05-15 20:21:04 +000071 InstRef IR;
Matt Davis43de6db2018-06-22 16:17:26 +000072 for (auto &S : Stages)
Matt Davis32508992018-07-12 22:59:53 +000073 S->cycleStart();
Matt Davisbd125322018-05-22 20:51:58 +000074
Matt Davis43de6db2018-06-22 16:17:26 +000075 // Continue executing this cycle until any stage claims it cannot make
76 // progress.
Matt Davis32508992018-07-12 22:59:53 +000077 while (true) {
Matt Davisf6bcbf32018-07-14 00:10:42 +000078 preExecuteStages();
Matt Davis32508992018-07-12 22:59:53 +000079 if (!executeStages(IR))
80 break;
Matt Davisf6bcbf32018-07-14 00:10:42 +000081 postExecuteStages();
Matt Davis32508992018-07-12 22:59:53 +000082 }
83
84 for (auto &S : Stages)
85 S->cycleEnd();
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000086}
87
Andrea Di Biagioef6b8a32018-07-13 09:27:34 +000088void Pipeline::notifyCycleBegin() {
89 LLVM_DEBUG(dbgs() << "[E] Cycle begin: " << Cycles << '\n');
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000090 for (HWEventListener *Listener : Listeners)
Andrea Di Biagio3e646442018-04-12 10:49:40 +000091 Listener->onCycleBegin();
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000092}
93
Andrea Di Biagioef6b8a32018-07-13 09:27:34 +000094void Pipeline::notifyCycleEnd() {
95 LLVM_DEBUG(dbgs() << "[E] Cycle end: " << Cycles << "\n\n");
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000096 for (HWEventListener *Listener : Listeners)
Andrea Di Biagio3e646442018-04-12 10:49:40 +000097 Listener->onCycleEnd();
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000098}
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000099} // namespace mca.