1 //===-------------------------- CodeRegion.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 /// 10 /// This file implements class CodeRegion and CodeRegions. 11 /// 12 /// A CodeRegion describes a region of assembly code guarded by special LLVM-MCA 13 /// comment directives. 14 /// 15 /// # LLVM-MCA-BEGIN foo 16 /// ... ## asm 17 /// # LLVM-MCA-END 18 /// 19 /// A comment starting with substring LLVM-MCA-BEGIN marks the beginning of a 20 /// new region of code. 21 /// A comment starting with substring LLVM-MCA-END marks the end of the 22 /// last-seen region of code. 23 /// 24 /// Code regions are not allowed to overlap. Each region can have a optional 25 /// description; internally, regions are described by a range of source 26 /// locations (SMLoc objects). 27 /// 28 /// An instruction (a MCInst) is added to a region R only if its location is in 29 /// range [R.RangeStart, R.RangeEnd]. 30 // 31 //===----------------------------------------------------------------------===// 32 33 #ifndef LLVM_TOOLS_LLVM_MCA_CODEREGION_H 34 #define LLVM_TOOLS_LLVM_MCA_CODEREGION_H 35 36 #include "llvm/ADT/ArrayRef.h" 37 #include "llvm/ADT/SmallVector.h" 38 #include "llvm/ADT/StringRef.h" 39 #include "llvm/MC/MCInst.h" 40 #include "llvm/Support/SMLoc.h" 41 #include "llvm/Support/SourceMgr.h" 42 #include <vector> 43 44 namespace llvm { 45 namespace mca { 46 47 /// A region of assembly code. 48 /// 49 /// It identifies a sequence of machine instructions. 50 class CodeRegion { 51 // An optional descriptor for this region. 52 llvm::StringRef Description; 53 // Instructions that form this region. 54 llvm::SmallVector<llvm::MCInst, 8> Instructions; 55 // Source location range. 56 llvm::SMLoc RangeStart; 57 llvm::SMLoc RangeEnd; 58 59 CodeRegion(const CodeRegion &) = delete; 60 CodeRegion &operator=(const CodeRegion &) = delete; 61 62 public: 63 CodeRegion(llvm::StringRef Desc, llvm::SMLoc Start) 64 : Description(Desc), RangeStart(Start), RangeEnd() {} 65 66 void addInstruction(const llvm::MCInst &Instruction) { 67 Instructions.emplace_back(Instruction); 68 } 69 70 llvm::SMLoc startLoc() const { return RangeStart; } 71 llvm::SMLoc endLoc() const { return RangeEnd; } 72 73 void setEndLocation(llvm::SMLoc End) { RangeEnd = End; } 74 bool empty() const { return Instructions.empty(); } 75 bool isLocInRange(llvm::SMLoc Loc) const; 76 77 llvm::ArrayRef<llvm::MCInst> getInstructions() const { return Instructions; } 78 79 llvm::StringRef getDescription() const { return Description; } 80 }; 81 82 class CodeRegionParseError final : public Error {}; 83 84 class CodeRegions { 85 // A source manager. Used by the tool to generate meaningful warnings. 86 llvm::SourceMgr &SM; 87 88 using UniqueCodeRegion = std::unique_ptr<CodeRegion>; 89 std::vector<UniqueCodeRegion> Regions; 90 llvm::StringMap<unsigned> ActiveRegions; 91 bool FoundErrors; 92 93 CodeRegions(const CodeRegions &) = delete; 94 CodeRegions &operator=(const CodeRegions &) = delete; 95 96 public: 97 CodeRegions(llvm::SourceMgr &S); 98 99 typedef std::vector<UniqueCodeRegion>::iterator iterator; 100 typedef std::vector<UniqueCodeRegion>::const_iterator const_iterator; 101 102 iterator begin() { return Regions.begin(); } 103 iterator end() { return Regions.end(); } 104 const_iterator begin() const { return Regions.cbegin(); } 105 const_iterator end() const { return Regions.cend(); } 106 107 void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc); 108 void endRegion(llvm::StringRef Description, llvm::SMLoc Loc); 109 void addInstruction(const llvm::MCInst &Instruction); 110 llvm::SourceMgr &getSourceMgr() const { return SM; } 111 112 llvm::ArrayRef<llvm::MCInst> getInstructionSequence(unsigned Idx) const { 113 return Regions[Idx]->getInstructions(); 114 } 115 116 bool empty() const { 117 return llvm::all_of(Regions, [](const UniqueCodeRegion &Region) { 118 return Region->empty(); 119 }); 120 } 121 122 bool isValid() const { return !FoundErrors; } 123 }; 124 125 } // namespace mca 126 } // namespace llvm 127 128 #endif 129