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/StringMap.h" 39 #include "llvm/ADT/StringRef.h" 40 #include "llvm/MC/MCInst.h" 41 #include "llvm/Support/Error.h" 42 #include "llvm/Support/SMLoc.h" 43 #include "llvm/Support/SourceMgr.h" 44 #include <vector> 45 46 namespace llvm { 47 namespace mca { 48 49 /// A region of assembly code. 50 /// 51 /// It identifies a sequence of machine instructions. 52 class CodeRegion { 53 // An optional descriptor for this region. 54 llvm::StringRef Description; 55 // Instructions that form this region. 56 llvm::SmallVector<llvm::MCInst, 8> Instructions; 57 // Source location range. 58 llvm::SMLoc RangeStart; 59 llvm::SMLoc RangeEnd; 60 61 CodeRegion(const CodeRegion &) = delete; 62 CodeRegion &operator=(const CodeRegion &) = delete; 63 64 public: CodeRegion(llvm::StringRef Desc,llvm::SMLoc Start)65 CodeRegion(llvm::StringRef Desc, llvm::SMLoc Start) 66 : Description(Desc), RangeStart(Start), RangeEnd() {} 67 addInstruction(const llvm::MCInst & Instruction)68 void addInstruction(const llvm::MCInst &Instruction) { 69 Instructions.emplace_back(Instruction); 70 } 71 startLoc()72 llvm::SMLoc startLoc() const { return RangeStart; } endLoc()73 llvm::SMLoc endLoc() const { return RangeEnd; } 74 setEndLocation(llvm::SMLoc End)75 void setEndLocation(llvm::SMLoc End) { RangeEnd = End; } empty()76 bool empty() const { return Instructions.empty(); } 77 bool isLocInRange(llvm::SMLoc Loc) const; 78 getInstructions()79 llvm::ArrayRef<llvm::MCInst> getInstructions() const { return Instructions; } 80 getDescription()81 llvm::StringRef getDescription() const { return Description; } 82 }; 83 84 class CodeRegionParseError final : public Error {}; 85 86 class CodeRegions { 87 // A source manager. Used by the tool to generate meaningful warnings. 88 llvm::SourceMgr &SM; 89 90 using UniqueCodeRegion = std::unique_ptr<CodeRegion>; 91 std::vector<UniqueCodeRegion> Regions; 92 llvm::StringMap<unsigned> ActiveRegions; 93 bool FoundErrors; 94 95 CodeRegions(const CodeRegions &) = delete; 96 CodeRegions &operator=(const CodeRegions &) = delete; 97 98 public: 99 CodeRegions(llvm::SourceMgr &S); 100 101 typedef std::vector<UniqueCodeRegion>::iterator iterator; 102 typedef std::vector<UniqueCodeRegion>::const_iterator const_iterator; 103 begin()104 iterator begin() { return Regions.begin(); } end()105 iterator end() { return Regions.end(); } begin()106 const_iterator begin() const { return Regions.cbegin(); } end()107 const_iterator end() const { return Regions.cend(); } 108 109 void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc); 110 void endRegion(llvm::StringRef Description, llvm::SMLoc Loc); 111 void addInstruction(const llvm::MCInst &Instruction); getSourceMgr()112 llvm::SourceMgr &getSourceMgr() const { return SM; } 113 getInstructionSequence(unsigned Idx)114 llvm::ArrayRef<llvm::MCInst> getInstructionSequence(unsigned Idx) const { 115 return Regions[Idx]->getInstructions(); 116 } 117 empty()118 bool empty() const { 119 return llvm::all_of(Regions, [](const UniqueCodeRegion &Region) { 120 return Region->empty(); 121 }); 122 } 123 isValid()124 bool isValid() const { return !FoundErrors; } 125 }; 126 127 } // namespace mca 128 } // namespace llvm 129 130 #endif 131