1 //===---------------- IncrementalSourceMgr.h --------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file contains IncrementalSourceMgr, an implementation of SourceMgr 10 /// that allows users to add new instructions incrementally / dynamically. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_MCA_INCREMENTALSOURCEMGR_H 15 #define LLVM_MCA_INCREMENTALSOURCEMGR_H 16 17 #include "llvm/MCA/SourceMgr.h" 18 #include <deque> 19 20 namespace llvm { 21 namespace mca { 22 23 /// An implementation of \a SourceMgr that allows users to add new instructions 24 /// incrementally / dynamically. 25 /// Note that this SourceMgr takes ownership of all \a mca::Instruction. 26 class IncrementalSourceMgr : public SourceMgr { 27 /// Owner of all mca::Instruction instances. Note that we use std::deque here 28 /// to have a better throughput, in comparison to std::vector or 29 /// llvm::SmallVector, as they usually pay a higher re-allocation cost when 30 /// there is a large number of instructions. 31 std::deque<UniqueInst> InstStorage; 32 33 /// Instructions that are ready to be used. Each of them is a pointer of an 34 /// \a UniqueInst inside InstStorage. 35 std::deque<Instruction *> Staging; 36 37 /// Current instruction index. 38 unsigned TotalCounter = 0U; 39 40 /// End-of-stream flag. 41 bool EOS = false; 42 43 /// Called when an instruction is no longer needed. 44 using InstFreedCallback = std::function<void(Instruction *)>; 45 InstFreedCallback InstFreedCB; 46 47 public: 48 IncrementalSourceMgr() = default; 49 50 void clear(); 51 52 /// Set a callback that is invoked when a mca::Instruction is 53 /// no longer needed. This is usually used for recycling the 54 /// instruction. setOnInstFreedCallback(InstFreedCallback CB)55 void setOnInstFreedCallback(InstFreedCallback CB) { InstFreedCB = CB; } 56 getInstructions()57 ArrayRef<UniqueInst> getInstructions() const override { 58 llvm_unreachable("Not applicable"); 59 } 60 hasNext()61 bool hasNext() const override { return !Staging.empty(); } isEnd()62 bool isEnd() const override { return EOS; } 63 peekNext()64 SourceRef peekNext() const override { 65 assert(hasNext()); 66 return SourceRef(TotalCounter, *Staging.front()); 67 } 68 69 /// Add a new instruction. addInst(UniqueInst && Inst)70 void addInst(UniqueInst &&Inst) { 71 InstStorage.emplace_back(std::move(Inst)); 72 Staging.push_back(InstStorage.back().get()); 73 } 74 75 /// Add a recycled instruction. addRecycledInst(Instruction * Inst)76 void addRecycledInst(Instruction *Inst) { Staging.push_back(Inst); } 77 78 void updateNext() override; 79 80 /// Mark the end of instruction stream. endOfStream()81 void endOfStream() { EOS = true; } 82 83 #ifndef NDEBUG 84 /// Print statistic about instruction recycling stats. 85 void printStatistic(raw_ostream &OS); 86 #endif 87 }; 88 89 } // end namespace mca 90 } // end namespace llvm 91 92 #endif // LLVM_MCA_INCREMENTALSOURCEMGR_H 93