]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/llvm-mca/Pipeline.cpp
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / llvm-mca / Pipeline.cpp
1 //===--------------------- Pipeline.cpp -------------------------*- C++ -*-===//
2 //
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 ///
11 /// This file implements an ordered container of stages that simulate the
12 /// pipeline of a hardware backend.
13 ///
14 //===----------------------------------------------------------------------===//
15
16 #include "Pipeline.h"
17 #include "HWEventListener.h"
18 #include "llvm/CodeGen/TargetSchedule.h"
19 #include "llvm/Support/Debug.h"
20
21 namespace mca {
22
23 #define DEBUG_TYPE "llvm-mca"
24
25 using namespace llvm;
26
27 void Pipeline::addEventListener(HWEventListener *Listener) {
28   if (Listener)
29     Listeners.insert(Listener);
30   for (auto &S : Stages)
31     S->addListener(Listener);
32 }
33
34 bool Pipeline::hasWorkToProcess() {
35   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.
43 bool Pipeline::executeStages(InstRef &IR) {
44   for (const std::unique_ptr<Stage> &S : Stages)
45     if (!S->execute(IR))
46       return false;
47   return true;
48 }
49
50 void Pipeline::preExecuteStages() {
51   for (const std::unique_ptr<Stage> &S : Stages)
52     S->preExecute();
53 }
54
55 void Pipeline::postExecuteStages() {
56   for (const std::unique_ptr<Stage> &S : Stages)
57     S->postExecute();
58 }
59
60 void Pipeline::run() {
61   while (hasWorkToProcess()) {
62     notifyCycleBegin();
63     runCycle();
64     notifyCycleEnd();
65     ++Cycles;
66   }
67 }
68
69 void Pipeline::runCycle() {
70   // Update the stages before we do any processing for this cycle.
71   InstRef IR;
72   for (auto &S : Stages)
73     S->cycleStart();
74
75   // Continue executing this cycle until any stage claims it cannot make
76   // progress.
77   while (true) {
78     preExecuteStages();
79     if (!executeStages(IR))
80       break;
81     postExecuteStages();
82   }
83
84   for (auto &S : Stages)
85     S->cycleEnd();
86 }
87
88 void Pipeline::notifyCycleBegin() {
89   LLVM_DEBUG(dbgs() << "[E] Cycle begin: " << Cycles << '\n');
90   for (HWEventListener *Listener : Listeners)
91     Listener->onCycleBegin();
92 }
93
94 void Pipeline::notifyCycleEnd() {
95   LLVM_DEBUG(dbgs() << "[E] Cycle end: " << Cycles << "\n\n");
96   for (HWEventListener *Listener : Listeners)
97     Listener->onCycleEnd();
98 }
99 } // namespace mca.