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