#pragma once #ifdef __GNUC__ #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #endif //===---------------- IncrementalSourceMgr.h --------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// \file /// This file contains IncrementalSourceMgr, an implementation of SourceMgr /// that allows users to add new instructions incrementally / dynamically. /// //===----------------------------------------------------------------------===// #ifndef LLVM_MCA_INCREMENTALSOURCEMGR_H #define LLVM_MCA_INCREMENTALSOURCEMGR_H #include "llvm/MCA/SourceMgr.h" #include namespace llvm { namespace mca { /// An implementation of \a SourceMgr that allows users to add new instructions /// incrementally / dynamically. /// Note that this SourceMgr takes ownership of all \a mca::Instruction. class IncrementalSourceMgr : public SourceMgr { /// Owner of all mca::Instruction instances. Note that we use std::deque here /// to have a better throughput, in comparison to std::vector or /// llvm::SmallVector, as they usually pay a higher re-allocation cost when /// there is a large number of instructions. std::deque InstStorage; /// Instructions that are ready to be used. Each of them is a pointer of an /// \a UniqueInst inside InstStorage. std::deque Staging; /// Current instruction index. unsigned TotalCounter; /// End-of-stream flag. bool EOS; /// Called when an instruction is no longer needed. using InstFreedCallback = llvm::function_ref; InstFreedCallback InstFreedCB; public: IncrementalSourceMgr() : TotalCounter(0U), EOS(false) {} void clear(); /// Set a callback that is invoked when a mca::Instruction is /// no longer needed. This is usually used for recycling the /// instruction. void setOnInstFreedCallback(InstFreedCallback CB) { InstFreedCB = CB; } ArrayRef getInstructions() const override { llvm_unreachable("Not applicable"); } bool hasNext() const override { return !Staging.empty(); } bool isEnd() const override { return EOS; } SourceRef peekNext() const override { assert(hasNext()); return SourceRef(TotalCounter, *Staging.front()); } /// Add a new instruction. void addInst(UniqueInst &&Inst) { InstStorage.emplace_back(std::move(Inst)); Staging.push_back(InstStorage.back().get()); } /// Add a recycled instruction. void addRecycledInst(Instruction *Inst) { Staging.push_back(Inst); } void updateNext() override; /// Mark the end of instruction stream. void endOfStream() { EOS = true; } #ifndef NDEBUG /// Print statistic about instruction recycling stats. void printStatistic(raw_ostream &OS); #endif }; } // end namespace mca } // end namespace llvm #endif // LLVM_MCA_INCREMENTALSOURCEMGR_H #ifdef __GNUC__ #pragma GCC diagnostic pop #endif