blob: ebaacb27a9f4779074aa46e7fd2c25a84f9a2cca [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 Davis32508992018-07-12 22:59:53 +000050void Pipeline::preExecuteStages(const InstRef &IR) {
51 for (const std::unique_ptr<Stage> &S : Stages)
52 S->preExecute(IR);
53}
54
Matt Davisdea343d2018-06-25 16:53:00 +000055void Pipeline::postExecuteStages(const InstRef &IR) {
Matt Davis43de6db2018-06-22 16:17:26 +000056 for (const std::unique_ptr<Stage> &S : Stages)
57 S->postExecute(IR);
58}
59
Matt Davisdea343d2018-06-25 16:53:00 +000060void Pipeline::run() {
Matt Davis43de6db2018-06-22 16:17:26 +000061 while (hasWorkToProcess())
Matt Davis5d1cda12018-05-15 20:21:04 +000062 runCycle(Cycles++);
63}
64
Matt Davisdea343d2018-06-25 16:53:00 +000065void Pipeline::runCycle(unsigned Cycle) {
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000066 notifyCycleBegin(Cycle);
67
Matt Davis5b79ffc5b2018-05-25 18:00:25 +000068 // Update the stages before we do any processing for this cycle.
Matt Davis5d1cda12018-05-15 20:21:04 +000069 InstRef IR;
Matt Davis43de6db2018-06-22 16:17:26 +000070 for (auto &S : Stages)
Matt Davis32508992018-07-12 22:59:53 +000071 S->cycleStart();
Matt Davisbd125322018-05-22 20:51:58 +000072
Matt Davis43de6db2018-06-22 16:17:26 +000073 // Continue executing this cycle until any stage claims it cannot make
74 // progress.
Matt Davis32508992018-07-12 22:59:53 +000075 while (true) {
76 preExecuteStages(IR);
77 if (!executeStages(IR))
78 break;
Matt Davis43de6db2018-06-22 16:17:26 +000079 postExecuteStages(IR);
Matt Davis32508992018-07-12 22:59:53 +000080 }
81
82 for (auto &S : Stages)
83 S->cycleEnd();
Andrea Di Biagio3a6b0922018-03-08 13:05:02 +000084
85 notifyCycleEnd(Cycle);
86}
87
Matt Davisdea343d2018-06-25 16:53:00 +000088void Pipeline::notifyCycleBegin(unsigned Cycle) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +000089 LLVM_DEBUG(dbgs() << "[E] Cycle begin: " << Cycle << '\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
Matt Davisdea343d2018-06-25 16:53:00 +000094void Pipeline::notifyCycleEnd(unsigned Cycle) {
Nicola Zaghend34e60c2018-05-14 12:53:11 +000095 LLVM_DEBUG(dbgs() << "[E] Cycle end: " << Cycle << "\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.