Path: blob/main/contrib/llvm-project/llvm/tools/llvm-mca/CodeRegion.h
35258 views
//===-------------------------- CodeRegion.h -------------------*- C++ -* -===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7/// \file8///9/// This file implements class CodeRegion and CodeRegions, InstrumentRegion,10/// AnalysisRegions, and InstrumentRegions.11///12/// A CodeRegion describes a region of assembly code guarded by special LLVM-MCA13/// comment directives.14///15/// # LLVM-MCA-BEGIN foo16/// ... ## asm17/// # LLVM-MCA-END18///19/// A comment starting with substring LLVM-MCA-BEGIN marks the beginning of a20/// new region of code.21/// A comment starting with substring LLVM-MCA-END marks the end of the22/// last-seen region of code.23///24/// Code regions are not allowed to overlap. Each region can have a optional25/// description; internally, regions are described by a range of source26/// locations (SMLoc objects).27///28/// An instruction (a MCInst) is added to a CodeRegion R only if its29/// location is in range [R.RangeStart, R.RangeEnd].30///31/// A InstrumentRegion describes a region of assembly code guarded by32/// special LLVM-MCA comment directives.33///34/// # LLVM-MCA-<INSTRUMENTATION_TYPE> <data>35/// ... ## asm36///37/// where INSTRUMENTATION_TYPE is a type defined in llvm and expects to use38/// data.39///40/// A comment starting with substring LLVM-MCA-<INSTRUMENTATION_TYPE>41/// brings data into scope for llvm-mca to use in its analysis for42/// all following instructions.43///44/// If the same INSTRUMENTATION_TYPE is found later in the instruction list,45/// then the original InstrumentRegion will be automatically ended,46/// and a new InstrumentRegion will begin.47///48/// If there are comments containing the different INSTRUMENTATION_TYPEs,49/// then both data sets remain available. In contrast with a CodeRegion,50/// an InstrumentRegion does not need a comment to end the region.51//52// An instruction (a MCInst) is added to an InstrumentRegion R only53// if its location is in range [R.RangeStart, R.RangeEnd].54//55//===----------------------------------------------------------------------===//5657#ifndef LLVM_TOOLS_LLVM_MCA_CODEREGION_H58#define LLVM_TOOLS_LLVM_MCA_CODEREGION_H5960#include "llvm/ADT/ArrayRef.h"61#include "llvm/ADT/SmallPtrSet.h"62#include "llvm/ADT/SmallVector.h"63#include "llvm/ADT/StringMap.h"64#include "llvm/ADT/StringRef.h"65#include "llvm/MC/MCInst.h"66#include "llvm/MCA/CustomBehaviour.h"67#include "llvm/Support/Error.h"68#include "llvm/Support/SMLoc.h"69#include "llvm/Support/SourceMgr.h"70#include <vector>7172namespace llvm {73namespace mca {7475/// A region of assembly code.76///77/// It identifies a sequence of machine instructions.78class CodeRegion {79// An optional descriptor for this region.80llvm::StringRef Description;81// Instructions that form this region.82llvm::SmallVector<llvm::MCInst, 16> Instructions;83// Source location range.84llvm::SMLoc RangeStart;85llvm::SMLoc RangeEnd;8687CodeRegion(const CodeRegion &) = delete;88CodeRegion &operator=(const CodeRegion &) = delete;8990public:91CodeRegion(llvm::StringRef Desc, llvm::SMLoc Start)92: Description(Desc), RangeStart(Start) {}9394virtual ~CodeRegion() = default;9596void addInstruction(const llvm::MCInst &Instruction) {97Instructions.emplace_back(Instruction);98}99100// Remove the given instructions from the set, for unsupported instructions101// being skipped. Returns an ArrayRef for the updated vector of Instructions.102[[nodiscard]] llvm::ArrayRef<llvm::MCInst>103dropInstructions(const llvm::SmallPtrSetImpl<const llvm::MCInst *> &Insts) {104if (Insts.empty())105return Instructions;106llvm::erase_if(Instructions, [&Insts](const llvm::MCInst &Inst) {107return Insts.contains(&Inst);108});109return Instructions;110}111112llvm::SMLoc startLoc() const { return RangeStart; }113llvm::SMLoc endLoc() const { return RangeEnd; }114115void setEndLocation(llvm::SMLoc End) { RangeEnd = End; }116bool empty() const { return Instructions.empty(); }117bool isLocInRange(llvm::SMLoc Loc) const;118119llvm::ArrayRef<llvm::MCInst> getInstructions() const { return Instructions; }120121llvm::StringRef getDescription() const { return Description; }122};123124/// Alias AnalysisRegion with CodeRegion since CodeRegionGenerator125/// is absract and AnalysisRegionGenerator operates on AnalysisRegions126using AnalysisRegion = CodeRegion;127128/// A CodeRegion that contains instrumentation that can be used129/// in analysis of the region.130class InstrumentRegion : public CodeRegion {131/// Instrument for this region.132UniqueInstrument I;133134public:135InstrumentRegion(llvm::StringRef Desc, llvm::SMLoc Start, UniqueInstrument I)136: CodeRegion(Desc, Start), I(std::move(I)) {}137138public:139Instrument *getInstrument() const { return I.get(); }140};141142class CodeRegionParseError final : public Error {};143144class CodeRegions {145CodeRegions(const CodeRegions &) = delete;146CodeRegions &operator=(const CodeRegions &) = delete;147148protected:149// A source manager. Used by the tool to generate meaningful warnings.150llvm::SourceMgr &SM;151152using UniqueCodeRegion = std::unique_ptr<CodeRegion>;153std::vector<UniqueCodeRegion> Regions;154llvm::StringMap<unsigned> ActiveRegions;155bool FoundErrors;156157public:158CodeRegions(llvm::SourceMgr &S) : SM(S), FoundErrors(false) {}159virtual ~CodeRegions() = default;160161typedef std::vector<UniqueCodeRegion>::iterator iterator;162typedef std::vector<UniqueCodeRegion>::const_iterator const_iterator;163164iterator begin() { return Regions.begin(); }165iterator end() { return Regions.end(); }166const_iterator begin() const { return Regions.cbegin(); }167const_iterator end() const { return Regions.cend(); }168169void addInstruction(const llvm::MCInst &Instruction);170llvm::SourceMgr &getSourceMgr() const { return SM; }171172llvm::ArrayRef<llvm::MCInst> getInstructionSequence(unsigned Idx) const {173return Regions[Idx]->getInstructions();174}175176bool empty() const {177return llvm::all_of(Regions, [](const UniqueCodeRegion &Region) {178return Region->empty();179});180}181182bool isValid() const { return !FoundErrors; }183184bool isRegionActive(llvm::StringRef Description) const {185return ActiveRegions.contains(Description);186}187188virtual void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc) = 0;189virtual void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc,190UniqueInstrument Instrument) = 0;191virtual void endRegion(llvm::StringRef Description, llvm::SMLoc Loc) = 0;192};193194struct AnalysisRegions : public CodeRegions {195AnalysisRegions(llvm::SourceMgr &S);196197void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc) override;198void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc,199UniqueInstrument Instrument) override {}200void endRegion(llvm::StringRef Description, llvm::SMLoc Loc) override;201};202203struct InstrumentRegions : public CodeRegions {204205InstrumentRegions(llvm::SourceMgr &S);206207void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc) override{};208void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc,209UniqueInstrument Instrument) override;210void endRegion(llvm::StringRef Description, llvm::SMLoc Loc) override;211212const SmallVector<Instrument *> getActiveInstruments(llvm::SMLoc Loc) const;213};214215} // namespace mca216} // namespace llvm217218#endif219220221