IncrementalSourceMgr.h 3.1 KB

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