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 46namespace llvm { 47namespace mca { 48 49/// A region of assembly code. 50/// 51/// It identifies a sequence of machine instructions. 52class 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 64public: 65 CodeRegion(llvm::StringRef Desc, llvm::SMLoc Start) 66 : Description(Desc), RangeStart(Start), RangeEnd() {} 67 68 void addInstruction(const llvm::MCInst &Instruction) { 69 Instructions.emplace_back(Instruction); 70 } 71 72 llvm::SMLoc startLoc() const { return RangeStart; } 73 llvm::SMLoc endLoc() const { return RangeEnd; } 74 75 void setEndLocation(llvm::SMLoc End) { RangeEnd = End; } 76 bool empty() const { return Instructions.empty(); } 77 bool isLocInRange(llvm::SMLoc Loc) const; 78 79 llvm::ArrayRef<llvm::MCInst> getInstructions() const { return Instructions; } 80 81 llvm::StringRef getDescription() const { return Description; } 82}; 83 84class CodeRegionParseError final : public Error {}; 85 86class 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 98public: 99 CodeRegions(llvm::SourceMgr &S); 100 101 typedef std::vector<UniqueCodeRegion>::iterator iterator; 102 typedef std::vector<UniqueCodeRegion>::const_iterator const_iterator; 103 104 iterator begin() { return Regions.begin(); } 105 iterator end() { return Regions.end(); } 106 const_iterator begin() const { return Regions.cbegin(); } 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); 112 llvm::SourceMgr &getSourceMgr() const { return SM; } 113 114 llvm::ArrayRef<llvm::MCInst> getInstructionSequence(unsigned Idx) const { 115 return Regions[Idx]->getInstructions(); 116 } 117 118 bool empty() const { 119 return llvm::all_of(Regions, [](const UniqueCodeRegion &Region) { 120 return Region->empty(); 121 }); 122 } 123 124 bool isValid() const { return !FoundErrors; } 125}; 126 127} // namespace mca 128} // namespace llvm 129 130#endif 131