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 20namespace llvm { 21namespace 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. 26class 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 = llvm::function_ref<void(Instruction *)>; 45 InstFreedCallback InstFreedCB; 46 47public: 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. 55 void setOnInstFreedCallback(InstFreedCallback CB) { InstFreedCB = CB; } 56 57 ArrayRef<UniqueInst> getInstructions() const override { 58 llvm_unreachable("Not applicable"); 59 } 60 61 bool hasNext() const override { return !Staging.empty(); } 62 bool isEnd() const override { return EOS; } 63 64 SourceRef peekNext() const override { 65 assert(hasNext()); 66 return SourceRef(TotalCounter, *Staging.front()); 67 } 68 69 /// Add a new instruction. 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. 76 void addRecycledInst(Instruction *Inst) { Staging.push_back(Inst); } 77 78 void updateNext() override; 79 80 /// Mark the end of instruction stream. 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