//===-------------------------- CodeRegion.h -------------------*- C++ -* -===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// \file /// /// This file implements class CodeRegion and CodeRegions. /// /// A CodeRegion describes a region of assembly code guarded by special LLVM-MCA /// comment directives. /// /// # LLVM-MCA-BEGIN foo /// ... ## asm /// # LLVM-MCA-END /// /// A comment starting with substring LLVM-MCA-BEGIN marks the beginning of a /// new region of code. /// A comment starting with substring LLVM-MCA-END marks the end of the /// last-seen region of code. /// /// Code regions are not allowed to overlap. Each region can have a optional /// description; internally, regions are described by a range of source /// locations (SMLoc objects). /// /// An instruction (a MCInst) is added to a region R only if its location is in /// range [R.RangeStart, R.RangeEnd]. // //===----------------------------------------------------------------------===// #ifndef LLVM_TOOLS_LLVM_MCA_CODEREGION_H #define LLVM_TOOLS_LLVM_MCA_CODEREGION_H #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/MC/MCInst.h" #include "llvm/Support/Error.h" #include "llvm/Support/SMLoc.h" #include "llvm/Support/SourceMgr.h" #include namespace llvm { namespace mca { /// A region of assembly code. /// /// It identifies a sequence of machine instructions. class CodeRegion { // An optional descriptor for this region. llvm::StringRef Description; // Instructions that form this region. llvm::SmallVector Instructions; // Source location range. llvm::SMLoc RangeStart; llvm::SMLoc RangeEnd; CodeRegion(const CodeRegion &) = delete; CodeRegion &operator=(const CodeRegion &) = delete; public: CodeRegion(llvm::StringRef Desc, llvm::SMLoc Start) : Description(Desc), RangeStart(Start), RangeEnd() {} void addInstruction(const llvm::MCInst &Instruction) { Instructions.emplace_back(Instruction); } llvm::SMLoc startLoc() const { return RangeStart; } llvm::SMLoc endLoc() const { return RangeEnd; } void setEndLocation(llvm::SMLoc End) { RangeEnd = End; } bool empty() const { return Instructions.empty(); } bool isLocInRange(llvm::SMLoc Loc) const; llvm::ArrayRef getInstructions() const { return Instructions; } llvm::StringRef getDescription() const { return Description; } }; class CodeRegionParseError final : public Error {}; class CodeRegions { // A source manager. Used by the tool to generate meaningful warnings. llvm::SourceMgr &SM; using UniqueCodeRegion = std::unique_ptr; std::vector Regions; llvm::StringMap ActiveRegions; bool FoundErrors; CodeRegions(const CodeRegions &) = delete; CodeRegions &operator=(const CodeRegions &) = delete; public: CodeRegions(llvm::SourceMgr &S); typedef std::vector::iterator iterator; typedef std::vector::const_iterator const_iterator; iterator begin() { return Regions.begin(); } iterator end() { return Regions.end(); } const_iterator begin() const { return Regions.cbegin(); } const_iterator end() const { return Regions.cend(); } void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc); void endRegion(llvm::StringRef Description, llvm::SMLoc Loc); void addInstruction(const llvm::MCInst &Instruction); llvm::SourceMgr &getSourceMgr() const { return SM; } llvm::ArrayRef getInstructionSequence(unsigned Idx) const { return Regions[Idx]->getInstructions(); } bool empty() const { return llvm::all_of(Regions, [](const UniqueCodeRegion &Region) { return Region->empty(); }); } bool isValid() const { return !FoundErrors; } }; } // namespace mca } // namespace llvm #endif