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