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 addEventListener(HWEventListener * Listener)27void Pipeline::addEventListener(HWEventListener *Listener) { 28 if (Listener) 29 Listeners.insert(Listener); 30 for (auto &S : Stages) 31 S->addListener(Listener); 32 } 33 hasWorkToProcess()34bool 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. executeStages(InstRef & IR)43bool 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 preExecuteStages()50void Pipeline::preExecuteStages() { 51 for (const std::unique_ptr<Stage> &S : Stages) 52 S->preExecute(); 53 } 54 postExecuteStages()55void Pipeline::postExecuteStages() { 56 for (const std::unique_ptr<Stage> &S : Stages) 57 S->postExecute(); 58 } 59 run()60void Pipeline::run() { 61 while (hasWorkToProcess()) { 62 notifyCycleBegin(); 63 runCycle(); 64 notifyCycleEnd(); 65 ++Cycles; 66 } 67 } 68 runCycle()69void 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 notifyCycleBegin()88void Pipeline::notifyCycleBegin() { 89 LLVM_DEBUG(dbgs() << "[E] Cycle begin: " << Cycles << '\n'); 90 for (HWEventListener *Listener : Listeners) 91 Listener->onCycleBegin(); 92 } 93 notifyCycleEnd()94void Pipeline::notifyCycleEnd() { 95 LLVM_DEBUG(dbgs() << "[E] Cycle end: " << Cycles << "\n\n"); 96 for (HWEventListener *Listener : Listeners) 97 Listener->onCycleEnd(); 98 } 99 } // namespace mca. 100