1 //===---------------------- EntryStage.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 defines the Fetch stage of an instruction pipeline. Its sole 12 /// purpose in life is to produce instructions for the rest of the pipeline. 13 /// 14 //===----------------------------------------------------------------------===// 15 16 #include "llvm/MCA/Stages/EntryStage.h" 17 #include "llvm/MCA/Instruction.h" 18 19 namespace llvm { 20 namespace mca { 21 hasWorkToComplete() const22bool EntryStage::hasWorkToComplete() const { return CurrentInstruction; } 23 isAvailable(const InstRef &) const24bool EntryStage::isAvailable(const InstRef & /* unused */) const { 25 if (CurrentInstruction) 26 return checkNextStage(CurrentInstruction); 27 return false; 28 } 29 getNextInstruction()30void EntryStage::getNextInstruction() { 31 assert(!CurrentInstruction && "There is already an instruction to process!"); 32 if (!SM.hasNext()) 33 return; 34 SourceRef SR = SM.peekNext(); 35 std::unique_ptr<Instruction> Inst = llvm::make_unique<Instruction>(SR.second); 36 CurrentInstruction = InstRef(SR.first, Inst.get()); 37 Instructions.emplace_back(std::move(Inst)); 38 SM.updateNext(); 39 } 40 execute(InstRef &)41llvm::Error EntryStage::execute(InstRef & /*unused */) { 42 assert(CurrentInstruction && "There is no instruction to process!"); 43 if (llvm::Error Val = moveToTheNextStage(CurrentInstruction)) 44 return Val; 45 46 // Move the program counter. 47 CurrentInstruction.invalidate(); 48 getNextInstruction(); 49 return llvm::ErrorSuccess(); 50 } 51 cycleStart()52llvm::Error EntryStage::cycleStart() { 53 if (!CurrentInstruction) 54 getNextInstruction(); 55 return llvm::ErrorSuccess(); 56 } 57 cycleEnd()58llvm::Error EntryStage::cycleEnd() { 59 // Find the first instruction which hasn't been retired. 60 auto Range = make_range(&Instructions[NumRetired], Instructions.end()); 61 auto It = find_if(Range, [](const std::unique_ptr<Instruction> &I) { 62 return !I->isRetired(); 63 }); 64 65 NumRetired = std::distance(Instructions.begin(), It); 66 // Erase instructions up to the first that hasn't been retired. 67 if ((NumRetired * 2) >= Instructions.size()) { 68 Instructions.erase(Instructions.begin(), It); 69 NumRetired = 0; 70 } 71 72 return llvm::ErrorSuccess(); 73 } 74 75 } // namespace mca 76 } // namespace llvm 77