1 //===--------------------- SourceMgr.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 abstract class SourceMgr and the default implementation, 10 /// CircularSourceMgr. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_MCA_SOURCEMGR_H 15 #define LLVM_MCA_SOURCEMGR_H 16 17 #include "llvm/ADT/ArrayRef.h" 18 #include "llvm/MCA/Instruction.h" 19 20 namespace llvm { 21 namespace mca { 22 23 // MSVC >= 19.15, < 19.20 need to see the definition of class Instruction to 24 // prevent compiler error C2139 about intrinsic type trait '__is_assignable'. 25 typedef std::pair<unsigned, const Instruction &> SourceRef; 26 27 /// Abstracting the input code sequence (a sequence of MCInst) and assigning 28 /// unique identifiers to every instruction in the sequence. 29 struct SourceMgr { 30 using UniqueInst = std::unique_ptr<Instruction>; 31 32 /// Provides a fixed range of \a UniqueInst to iterate. 33 virtual ArrayRef<UniqueInst> getInstructions() const = 0; 34 35 /// (Fixed) Number of \a UniqueInst. Returns the size of 36 /// \a getInstructions by default. 37 virtual size_t size() const { return getInstructions().size(); } 38 39 /// Whether there is any \a SourceRef to inspect / peek next. 40 /// Note that returning false from this doesn't mean the instruction 41 /// stream has ended. 42 virtual bool hasNext() const = 0; 43 44 /// Whether the instruction stream has eneded. 45 virtual bool isEnd() const = 0; 46 47 /// The next \a SourceRef. 48 virtual SourceRef peekNext() const = 0; 49 50 /// Advance to the next \a SourceRef. 51 virtual void updateNext() = 0; 52 53 virtual ~SourceMgr() {} 54 }; 55 56 /// The default implementation of \a SourceMgr. It always takes a fixed number 57 /// of instructions and provides an option to loop the given sequence for a 58 /// certain iterations. 59 class CircularSourceMgr : public SourceMgr { 60 ArrayRef<UniqueInst> Sequence; 61 unsigned Current; 62 const unsigned Iterations; 63 static const unsigned DefaultIterations = 100; 64 65 public: 66 CircularSourceMgr(ArrayRef<UniqueInst> S, unsigned Iter) 67 : Sequence(S), Current(0U), Iterations(Iter ? Iter : DefaultIterations) {} 68 69 ArrayRef<UniqueInst> getInstructions() const override { return Sequence; } 70 71 unsigned getNumIterations() const { return Iterations; } 72 bool hasNext() const override { 73 return Current < (Iterations * Sequence.size()); 74 } 75 bool isEnd() const override { return !hasNext(); } 76 77 SourceRef peekNext() const override { 78 assert(hasNext() && "Already at end of sequence!"); 79 return SourceRef(Current, *Sequence[Current % Sequence.size()]); 80 } 81 82 void updateNext() override { ++Current; } 83 }; 84 85 } // namespace mca 86 } // namespace llvm 87 88 #endif // LLVM_MCA_SOURCEMGR_H 89