[llvm] r329590 - [llvm-mca] Add the ability to mark regions of code for analysis (PR36875)

Andrea Di Biagio via llvm-commits llvm-commits at lists.llvm.org
Mon Apr 9 09:39:52 PDT 2018


Author: adibiagio
Date: Mon Apr  9 09:39:52 2018
New Revision: 329590

URL: http://llvm.org/viewvc/llvm-project?rev=329590&view=rev
Log:
[llvm-mca] Add the ability to mark regions of code for analysis (PR36875)

This patch teaches llvm-mca how to parse code comments in search for special
"markers" used to select regions of code.

Example:

# LLVM-MCA-BEGIN My Code Region
  ....
# LLVM-MCA-END

The MCAsmLexer now delegates to an object of class MCACommentParser (i.e. an
AsmCommentConsumer) the parsing of code comments to search for begin/end code
region markers.

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 region.

This implementation doesn't allow regions to overlap. Each region can have a
optional description; internally, each region is identified by a range of source
code locations (SMLoc).

MCInst objects are added to a region R only if the source location for the
MCInst is in the range of locations specified by R.

By default, the tool allocates an implicit "Default" code region which contains
every source location.  See new tests llvm-mca-marker-*.s for a few examples.

A new Backend object is created for every region. So, the analysis is conducted
on every parsed code region.  The final report is the union of the reports
generated for every code region.  Note that empty regions are skipped.

Special "[#] Code Region - ..." strings are used in the report to mark the
portion which is specific to a code region only. For example, see
llvm-mca-markers-5.s.

Differential Revision: https://reviews.llvm.org/D45433

Added:
    llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-1.s
    llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-2.s
    llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-3.s
    llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-4.s
    llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-5.s
    llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-6.s
    llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-7.s
    llvm/trunk/tools/llvm-mca/CodeRegion.cpp
    llvm/trunk/tools/llvm-mca/CodeRegion.h
Modified:
    llvm/trunk/docs/CommandGuide/llvm-mca.rst
    llvm/trunk/tools/llvm-mca/CMakeLists.txt
    llvm/trunk/tools/llvm-mca/SourceMgr.h
    llvm/trunk/tools/llvm-mca/llvm-mca.cpp

Modified: llvm/trunk/docs/CommandGuide/llvm-mca.rst
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/docs/CommandGuide/llvm-mca.rst?rev=329590&r1=329589&r2=329590&view=diff
==============================================================================
--- llvm/trunk/docs/CommandGuide/llvm-mca.rst (original)
+++ llvm/trunk/docs/CommandGuide/llvm-mca.rst Mon Apr  9 09:39:52 2018
@@ -25,6 +25,24 @@ Given an assembly code sequence, llvm-mc
 Cycle), as well as hardware resource pressure. The analysis and reporting style
 were inspired by the IACA tool from Intel.
 
+:program:`llvm-mca` allows the usage of special code comments to mark regions of
+the assembly code to be analyzed.  A comment starting with substring
+``LLVM-MCA-BEGIN`` marks the beginning of a code region. A comment starting with
+substring ``LLVM-MCA-END`` marks the end of a code region.  For example:
+
+.. code-block:: none
+
+  # LLVM-MCA-BEGIN My Code Region
+    ...
+  # LLVM-MCA-END
+
+Multiple regions can be specified provided that they do not overlap.  A code
+region can have an optional description. If no user defined region is specified,
+then :program:`llvm-mca` assumes a default region which contains every
+instruction in the input file.  Every region is analyzed in isolation, and the
+final performance report is the union of all the reports generated for every
+code region.
+
 OPTIONS
 -------
 

Added: llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-1.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-1.s?rev=329590&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-1.s (added)
+++ llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-1.s Mon Apr  9 09:39:52 2018
@@ -0,0 +1,10 @@
+# RUN: not llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 %s 2>&1 | FileCheck %s
+
+# LLVM-MCA-BEGIN
+# LLVM-MCA-END
+
+# LLVM-MCA-BEGIN
+# LLVM-MCA-END
+
+# CHECK: error: no assembly instructions found.
+

Added: llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-2.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-2.s?rev=329590&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-2.s (added)
+++ llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-2.s Mon Apr  9 09:39:52 2018
@@ -0,0 +1,25 @@
+# RUN: llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 -iterations=1 -resource-pressure=false < %s | FileCheck %s
+
+  add %edi, %esi
+# LLVM-MCA-END
+  add %esi, %eax
+
+# CHECK:      [0] Code Region - Default
+
+# CHECK:      Iterations:     1
+# CHECK-NEXT: Instructions:   1
+# CHECK-NEXT: Total Cycles:   4
+# CHECK-NEXT: Dispatch Width: 2
+# CHECK-NEXT: IPC:            0.25
+
+# CHECK:      Instruction Info:
+# CHECK-NEXT: [1]: #uOps
+# CHECK-NEXT: [2]: Latency
+# CHECK-NEXT: [3]: RThroughput
+# CHECK-NEXT: [4]: MayLoad
+# CHECK-NEXT: [5]: MayStore
+# CHECK-NEXT: [6]: HasSideEffects
+
+# CHECK:      [1]    [2]    [3]    [4]    [5]    [6]	Instructions:
+# CHECK-NEXT:  1      1     0.50                    	addl	%edi, %esi
+

Added: llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-3.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-3.s?rev=329590&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-3.s (added)
+++ llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-3.s Mon Apr  9 09:39:52 2018
@@ -0,0 +1,25 @@
+# RUN: llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 -iterations=1 -resource-pressure=false < %s | FileCheck %s
+
+  add %esi, %edi
+# LLVM-MCA-BEGIN foo
+  add %edi, %eax
+
+# CHECK:      [0] Code Region -  foo
+
+# CHECK:      Iterations:     1
+# CHECK-NEXT: Instructions:   1
+# CHECK-NEXT: Total Cycles:   4
+# CHECK-NEXT: Dispatch Width: 2
+# CHECK-NEXT: IPC:            0.25
+
+# CHECK:      Instruction Info:
+# CHECK-NEXT: [1]: #uOps
+# CHECK-NEXT: [2]: Latency
+# CHECK-NEXT: [3]: RThroughput
+# CHECK-NEXT: [4]: MayLoad
+# CHECK-NEXT: [5]: MayStore
+# CHECK-NEXT: [6]: HasSideEffects
+
+# CHECK:      [1]    [2]    [3]    [4]    [5]    [6]	Instructions:
+# CHECK-NEXT:  1      1     0.50                    	addl	%edi, %eax
+

Added: llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-4.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-4.s?rev=329590&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-4.s (added)
+++ llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-4.s Mon Apr  9 09:39:52 2018
@@ -0,0 +1,29 @@
+# RUN: llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 -iterations=1 -resource-pressure=false < %s | FileCheck %s
+
+# LLVM-MCA-BEGIN Empty
+  # Empty sequence
+# LLVM-MCA-END
+
+# LLVM-MCA-BEGIN NotEmpty
+  add %edi, %eax
+# LLVM-MCA-END
+
+# CHECK:      [0] Code Region -  NotEmpty
+
+# CHECK:      Iterations:     1
+# CHECK-NEXT: Instructions:   1
+# CHECK-NEXT: Total Cycles:   4
+# CHECK-NEXT: Dispatch Width: 2
+# CHECK-NEXT: IPC:            0.25
+
+# CHECK:      Instruction Info:
+# CHECK-NEXT: [1]: #uOps
+# CHECK-NEXT: [2]: Latency
+# CHECK-NEXT: [3]: RThroughput
+# CHECK-NEXT: [4]: MayLoad
+# CHECK-NEXT: [5]: MayStore
+# CHECK-NEXT: [6]: HasSideEffects
+
+# CHECK:      [1]    [2]    [3]    [4]    [5]    [6]	Instructions:
+# CHECK-NEXT:  1      1     0.50                    	addl	%edi, %eax
+

Added: llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-5.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-5.s?rev=329590&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-5.s (added)
+++ llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-5.s Mon Apr  9 09:39:52 2018
@@ -0,0 +1,71 @@
+# RUN: llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 -iterations=1 -resource-pressure=false < %s | FileCheck %s
+
+  add %ecx, %esi
+# LLVM-MCA-BEGIN First Region
+  add %edi, %esi
+# LLVM-MCA-END
+# LLVM-MCA-BEGIN Second Region
+  add %esi, %edx
+# LLVM-MCA-END
+# LLVM-MCA-BEGIN Third Region
+  add %edx, %eax
+# LLVM-MCA-END
+  add %esi, %eax
+
+# CHECK:      [0] Code Region -  First Region
+
+# CHECK:      Iterations:     1
+# CHECK-NEXT: Instructions:   1
+# CHECK-NEXT: Total Cycles:   4
+# CHECK-NEXT: Dispatch Width: 2
+# CHECK-NEXT: IPC:            0.25
+
+# CHECK:      Instruction Info:
+# CHECK-NEXT: [1]: #uOps
+# CHECK-NEXT: [2]: Latency
+# CHECK-NEXT: [3]: RThroughput
+# CHECK-NEXT: [4]: MayLoad
+# CHECK-NEXT: [5]: MayStore
+# CHECK-NEXT: [6]: HasSideEffects
+
+# CHECK:      [1]    [2]    [3]    [4]    [5]    [6]	Instructions:
+# CHECK-NEXT:  1      1     0.50                    	addl	%edi, %esi
+
+# CHECK:      [1] Code Region -  Second Region
+
+# CHECK:      Iterations:     1
+# CHECK-NEXT: Instructions:   1
+# CHECK-NEXT: Total Cycles:   4
+# CHECK-NEXT: Dispatch Width: 2
+# CHECK-NEXT: IPC:            0.25
+
+# CHECK:      Instruction Info:
+# CHECK-NEXT: [1]: #uOps
+# CHECK-NEXT: [2]: Latency
+# CHECK-NEXT: [3]: RThroughput
+# CHECK-NEXT: [4]: MayLoad
+# CHECK-NEXT: [5]: MayStore
+# CHECK-NEXT: [6]: HasSideEffects
+
+# CHECK:      [1]    [2]    [3]    [4]    [5]    [6]	Instructions:
+# CHECK-NEXT:  1      1     0.50                    	addl	%esi, %edx
+
+# CHECK:      [2] Code Region -  Third Region
+
+# CHECK:      Iterations:     1
+# CHECK-NEXT: Instructions:   1
+# CHECK-NEXT: Total Cycles:   4
+# CHECK-NEXT: Dispatch Width: 2
+# CHECK-NEXT: IPC:            0.25
+
+# CHECK:      Instruction Info:
+# CHECK-NEXT: [1]: #uOps
+# CHECK-NEXT: [2]: Latency
+# CHECK-NEXT: [3]: RThroughput
+# CHECK-NEXT: [4]: MayLoad
+# CHECK-NEXT: [5]: MayStore
+# CHECK-NEXT: [6]: HasSideEffects
+
+# CHECK:      [1]    [2]    [3]    [4]    [5]    [6]	Instructions:
+# CHECK-NEXT:  1      1     0.50                    	addl	%edx, %eax
+

Added: llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-6.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-6.s?rev=329590&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-6.s (added)
+++ llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-6.s Mon Apr  9 09:39:52 2018
@@ -0,0 +1,13 @@
+# RUN: not llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 %s 2>&1 | FileCheck %s
+
+# LLVM-MCA-BEGIN  foo
+
+# LLVM-MCA-BEGIN  bar
+
+# LLVM-MCA-END
+
+# CHECK:      llvm-mca-markers-6.s:5:2: warning: Ignoring invalid region start
+# CHECK-NEXT: # LLVM-MCA-BEGIN  bar
+# CHECK-NEXT:  ^
+# CHECK-NEXT: error: no assembly instructions found.
+

Added: llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-7.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-7.s?rev=329590&view=auto
==============================================================================
--- llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-7.s (added)
+++ llvm/trunk/test/tools/llvm-mca/X86/llvm-mca-markers-7.s Mon Apr  9 09:39:52 2018
@@ -0,0 +1,12 @@
+# RUN: not llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 %s 2>&1 | FileCheck %s
+
+# LLVM-MCA-BEGIN  foo
+
+# LLVM-MCA-END
+
+# LLVM-MCA-END
+
+# CHECK:      llvm-mca-markers-7.s:7:2: warning: Ignoring invalid region end
+# CHECK-NEXT: # LLVM-MCA-END
+# CHECK-NEXT:  ^
+

Modified: llvm/trunk/tools/llvm-mca/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/CMakeLists.txt?rev=329590&r1=329589&r2=329590&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/CMakeLists.txt (original)
+++ llvm/trunk/tools/llvm-mca/CMakeLists.txt Mon Apr  9 09:39:52 2018
@@ -13,6 +13,7 @@ add_llvm_tool(llvm-mca
   Backend.cpp
   BackendPrinter.cpp
   BackendStatistics.cpp
+  CodeRegion.cpp
   Dispatch.cpp
   HWEventListener.cpp
   InstrBuilder.cpp

Added: llvm/trunk/tools/llvm-mca/CodeRegion.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/CodeRegion.cpp?rev=329590&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-mca/CodeRegion.cpp (added)
+++ llvm/trunk/tools/llvm-mca/CodeRegion.cpp Mon Apr  9 09:39:52 2018
@@ -0,0 +1,66 @@
+//===-------------------------- CodeRegion.cpp -----------------*- C++ -* -===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \file
+///
+/// This file implements methods from the CodeRegions interface.
+///
+//===----------------------------------------------------------------------===//
+
+#include "CodeRegion.h"
+
+using namespace llvm;
+
+namespace mca {
+
+bool CodeRegion::isLocInRange(SMLoc Loc) const {
+  if (RangeEnd.isValid() && Loc.getPointer() > RangeEnd.getPointer())
+    return false;
+  if (RangeStart.isValid() && Loc.getPointer() < RangeStart.getPointer())
+    return false;
+  return true;
+}
+
+void CodeRegions::beginRegion(StringRef Description, SMLoc Loc) {
+  assert(!Regions.empty() && "Missing Default region");
+  const CodeRegion &CurrentRegion = *Regions.back();
+  if (CurrentRegion.startLoc().isValid() && !CurrentRegion.endLoc().isValid()) {
+    SM.PrintMessage(Loc, SourceMgr::DK_Warning,
+                    "Ignoring invalid region start");
+    return;
+  }
+
+  // Remove the default region if there are user defined regions.
+  if (!CurrentRegion.startLoc().isValid())
+    Regions.erase(Regions.begin());
+  addRegion(Description, Loc);
+}
+
+void CodeRegions::endRegion(SMLoc Loc) {
+  assert(!Regions.empty() && "Missing Default region");
+  CodeRegion &CurrentRegion = *Regions.back();
+  if (CurrentRegion.endLoc().isValid()) {
+    SM.PrintMessage(Loc, SourceMgr::DK_Warning, "Ignoring invalid region end");
+    return;
+  }
+
+  CurrentRegion.setEndLocation(Loc);
+}
+
+void CodeRegions::addInstruction(std::unique_ptr<const MCInst> Instruction) {
+  const SMLoc &Loc = Instruction->getLoc();
+  const auto It =
+      std::find_if(Regions.rbegin(), Regions.rend(),
+                   [Loc](const std::unique_ptr<CodeRegion> &Region) {
+                     return Region->isLocInRange(Loc);
+                   });
+  if (It != Regions.rend())
+    (*It)->addInstruction(std::move(Instruction));
+}
+
+} // namespace mca

Added: llvm/trunk/tools/llvm-mca/CodeRegion.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/CodeRegion.h?rev=329590&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-mca/CodeRegion.h (added)
+++ llvm/trunk/tools/llvm-mca/CodeRegion.h Mon Apr  9 09:39:52 2018
@@ -0,0 +1,131 @@
+//===-------------------------- CodeRegion.h -------------------*- C++ -* -===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+/// \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/StringRef.h"
+#include "llvm/MC/MCInst.h"
+#include "llvm/Support/SMLoc.h"
+#include "llvm/Support/SourceMgr.h"
+#include <vector>
+
+namespace mca {
+
+/// \brief 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.
+  std::vector<std::unique_ptr<const llvm::MCInst>> 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(std::unique_ptr<const llvm::MCInst> Instruction) {
+    Instructions.emplace_back(std::move(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;
+
+  const std::vector<std::unique_ptr<const llvm::MCInst>> &
+  getInstructions() const {
+    return Instructions;
+  }
+
+  llvm::StringRef getDescription() const { return Description; }
+};
+
+class CodeRegions {
+  // A source manager. Used by the tool to generate meaningful warnings.
+  llvm::SourceMgr &SM;
+
+  std::vector<std::unique_ptr<CodeRegion>> Regions;
+
+  // Construct a new region of code guarded by LLVM-MCA comments.
+  void addRegion(llvm::StringRef Description, llvm::SMLoc Loc) {
+    Regions.emplace_back(llvm::make_unique<CodeRegion>(Description, Loc));
+  }
+
+  CodeRegions(const CodeRegions &) = delete;
+  CodeRegions &operator=(const CodeRegions &) = delete;
+
+public:
+  typedef std::vector<std::unique_ptr<CodeRegion>>::iterator iterator;
+  typedef std::vector<std::unique_ptr<CodeRegion>>::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::SMLoc Loc);
+  void addInstruction(std::unique_ptr<const llvm::MCInst> Instruction);
+
+  CodeRegions(llvm::SourceMgr &S) : SM(S) {
+    // Create a default region for the input code sequence.
+    addRegion("Default", llvm::SMLoc());
+  }
+
+  const std::vector<std::unique_ptr<const llvm::MCInst>> &
+  getInstructionSequence(unsigned Idx) const {
+    return Regions[Idx]->getInstructions();
+  }
+
+  bool empty() const {
+    return std::all_of(Regions.begin(), Regions.end(),
+                       [](const std::unique_ptr<CodeRegion> &Region) {
+                         return Region->empty();
+                       });
+  }
+};
+
+} // namespace mca
+
+#endif

Modified: llvm/trunk/tools/llvm-mca/SourceMgr.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/SourceMgr.h?rev=329590&r1=329589&r2=329590&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/SourceMgr.h (original)
+++ llvm/trunk/tools/llvm-mca/SourceMgr.h Mon Apr  9 09:39:52 2018
@@ -25,21 +25,20 @@ typedef std::pair<unsigned, const llvm::
 
 class SourceMgr {
   using InstVec = std::vector<std::unique_ptr<const llvm::MCInst>>;
-  InstVec Sequence;
+  const InstVec &Sequence;
   unsigned Current;
   unsigned Iterations;
   static const unsigned DefaultIterations = 70;
 
 public:
-  SourceMgr(unsigned NumIterations)
-      : Current(0),
+  SourceMgr(const InstVec &MCInstSequence, unsigned NumIterations)
+      : Sequence(MCInstSequence), Current(0),
         Iterations(NumIterations ? NumIterations : DefaultIterations) {}
 
   unsigned getCurrentIteration() const { return Current / Sequence.size(); }
   unsigned getNumIterations() const { return Iterations; }
   unsigned size() const { return Sequence.size(); }
   const InstVec &getSequence() const { return Sequence; }
-  InstVec &getSequence() { return Sequence; }
 
   bool hasNext() { return Current < (Iterations * size()); }
   void updateNext() { Current++; }

Modified: llvm/trunk/tools/llvm-mca/llvm-mca.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-mca/llvm-mca.cpp?rev=329590&r1=329589&r2=329590&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-mca/llvm-mca.cpp (original)
+++ llvm/trunk/tools/llvm-mca/llvm-mca.cpp Mon Apr  9 09:39:52 2018
@@ -23,6 +23,7 @@
 
 #include "BackendPrinter.h"
 #include "BackendStatistics.h"
+#include "CodeRegion.h"
 #include "InstructionInfoView.h"
 #include "InstructionTables.h"
 #include "RegisterFileStatistics.h"
@@ -158,6 +159,44 @@ const Target *getTarget(const char *Prog
   return TheTarget;
 }
 
+// A comment consumer that parses strings.
+// The only valid tokens are strings.
+class MCACommentConsumer : public AsmCommentConsumer {
+public:
+  mca::CodeRegions &Regions;
+
+  MCACommentConsumer(mca::CodeRegions &R) : Regions(R) {}
+  void HandleComment(SMLoc Loc, StringRef CommentText) override {
+    // Skip empty comments.
+    StringRef Comment(CommentText);
+    if (Comment.empty())
+      return;
+
+    // Skip spaces and tabs
+    unsigned Position = Comment.find_first_not_of(" \t");
+    if (Position >= Comment.size())
+      // we reached the end of the comment. Bail out.
+      return;
+
+    Comment = Comment.drop_front(Position);
+    if (Comment.consume_front("LLVM-MCA-END")) {
+      Regions.endRegion(Loc);
+      return;
+    }
+
+    // Now try to parse string LLVM-MCA-BEGIN
+    if (!Comment.consume_front("LLVM-MCA-BEGIN"))
+      return;
+
+    // Skip spaces and tabs
+    Position = Comment.find_first_not_of(" \t");
+    if (Position < Comment.size())
+      Comment.drop_front(Position);
+    // Use the rest of the string as a descriptor for this code snippet.
+    Regions.beginRegion(Comment, Loc);
+  }
+};
+
 int AssembleInput(const char *ProgName, MCAsmParser &Parser,
                   const Target *TheTarget, MCSubtargetInfo &STI,
                   MCInstrInfo &MCII, MCTargetOptions &MCOptions) {
@@ -186,17 +225,16 @@ ErrorOr<std::unique_ptr<ToolOutputFile>>
 }
 
 class MCStreamerWrapper final : public MCStreamer {
-  using InstVec = std::vector<std::unique_ptr<const MCInst>>;
-  InstVec &Insts;
+  mca::CodeRegions &Regions;
 
 public:
-  MCStreamerWrapper(MCContext &Context, InstVec &Vec)
-      : MCStreamer(Context), Insts(Vec) {}
+  MCStreamerWrapper(MCContext &Context, mca::CodeRegions &R)
+      : MCStreamer(Context), Regions(R) {}
 
   // We only want to intercept the emission of new instructions.
   virtual void EmitInstruction(const MCInst &Inst, const MCSubtargetInfo &STI,
                                bool /* unused */) override {
-    Insts.emplace_back(new MCInst(Inst));
+    Regions.addInstruction(llvm::make_unique<const MCInst>(Inst));
   }
 
   bool EmitSymbolAttribute(MCSymbol *Symbol, MCSymbolAttr Attribute) override {
@@ -213,7 +251,10 @@ public:
   void EmitCOFFSymbolType(int Type) override {}
   void EndCOFFSymbolDef() override {}
 
-  const InstVec &GetInstructionSequence() const { return Insts; }
+  const std::vector<std::unique_ptr<const MCInst>> &
+  GetInstructionSequence(unsigned Index) const {
+    return Regions.getInstructionSequence(Index);
+  }
 };
 } // end of anonymous namespace
 
@@ -272,9 +313,8 @@ int main(int argc, char **argv) {
 
   std::unique_ptr<buffer_ostream> BOS;
 
-  std::unique_ptr<mca::SourceMgr> S = llvm::make_unique<mca::SourceMgr>(
-      PrintInstructionTables ? 1 : Iterations);
-  MCStreamerWrapper Str(Ctx, S->getSequence());
+  mca::CodeRegions Regions(SrcMgr);
+  MCStreamerWrapper Str(Ctx, Regions);
 
   std::unique_ptr<MCInstrInfo> MCII(TheTarget->createMCInstrInfo());
   std::unique_ptr<MCSubtargetInfo> STI(
@@ -310,10 +350,14 @@ int main(int argc, char **argv) {
   }
 
   std::unique_ptr<MCAsmParser> P(createMCAsmParser(SrcMgr, Ctx, Str, *MAI));
+  MCAsmLexer &Lexer = P->getLexer();
+  MCACommentConsumer CC(Regions);
+  Lexer.setCommentConsumer(&CC);
+
   if (AssembleInput(ProgName, *P, TheTarget, *STI, *MCII, MCOptions))
     return 1;
 
-  if (S->isEmpty()) {
+  if (Regions.empty()) {
     errs() << "error: no assembly instructions found.\n";
     return 1;
   }
@@ -336,49 +380,68 @@ int main(int argc, char **argv) {
   // Create an instruction builder.
   mca::InstrBuilder IB(*STI, *MCII);
 
-  if (PrintInstructionTables) {
-    mca::InstructionTables IT(STI->getSchedModel(), IB, *S);
-
-    if (PrintInstructionInfoView) {
-      IT.addView(
-          llvm::make_unique<mca::InstructionInfoView>(*STI, *MCII, *S, *IP));
+  // Number each region in the sequence.
+  unsigned RegionIdx = 0;
+  for (const std::unique_ptr<mca::CodeRegion> &Region : Regions) {
+    // Skip empty code regions.
+    if (Region->empty())
+      continue;
+
+    // Don't print the header of this region if it is the default region, and
+    // it doesn't have an end location.
+    if (Region->startLoc().isValid() || Region->endLoc().isValid()) {
+      TOF->os() << "\n[" << RegionIdx++ << "] Code Region";
+      StringRef Desc = Region->getDescription();
+      if (!Desc.empty())
+        TOF->os() << " - " << Desc;
+      TOF->os() << "\n\n";
     }
 
-    IT.addView(llvm::make_unique<mca::ResourcePressureView>(*STI, *IP, *S));
-    IT.run();
-    IT.printReport(TOF->os());
-    TOF->keep();
-    return 0;
-  }
-
-  mca::Backend B(*STI, *MRI, IB, *S, Width, RegisterFileSize, LoadQueueSize,
-                 StoreQueueSize, AssumeNoAlias);
-  mca::BackendPrinter Printer(B);
-
-  Printer.addView(llvm::make_unique<mca::SummaryView>(*S, Width));
+    mca::SourceMgr S(Region->getInstructions(),
+                     PrintInstructionTables ? 1 : Iterations);
 
-  if (PrintInstructionInfoView)
-    Printer.addView(
-        llvm::make_unique<mca::InstructionInfoView>(*STI, *MCII, *S, *IP));
+    if (PrintInstructionTables) {
+      mca::InstructionTables IT(STI->getSchedModel(), IB, S);
 
-  if (PrintModeVerbose)
-    Printer.addView(llvm::make_unique<mca::BackendStatistics>(*STI));
-
-  if (PrintRegisterFileStats)
-    Printer.addView(llvm::make_unique<mca::RegisterFileStatistics>(*STI));
+      if (PrintInstructionInfoView) {
+        IT.addView(
+            llvm::make_unique<mca::InstructionInfoView>(*STI, *MCII, S, *IP));
+      }
+
+      IT.addView(llvm::make_unique<mca::ResourcePressureView>(*STI, *IP, S));
+      IT.run();
+      IT.printReport(TOF->os());
+      continue;
+    }
 
-  if (PrintResourcePressureView)
-    Printer.addView(
-        llvm::make_unique<mca::ResourcePressureView>(*STI, *IP, *S));
+    mca::Backend B(*STI, *MRI, IB, S, Width, RegisterFileSize, LoadQueueSize,
+                   StoreQueueSize, AssumeNoAlias);
+    mca::BackendPrinter Printer(B);
+
+    Printer.addView(llvm::make_unique<mca::SummaryView>(S, Width));
+    if (PrintInstructionInfoView)
+      Printer.addView(
+          llvm::make_unique<mca::InstructionInfoView>(*STI, *MCII, S, *IP));
+
+    if (PrintModeVerbose)
+      Printer.addView(llvm::make_unique<mca::BackendStatistics>(*STI));
+
+    if (PrintRegisterFileStats)
+      Printer.addView(llvm::make_unique<mca::RegisterFileStatistics>(*STI));
+
+    if (PrintResourcePressureView)
+      Printer.addView(
+          llvm::make_unique<mca::ResourcePressureView>(*STI, *IP, S));
+
+    if (PrintTimelineView) {
+      Printer.addView(llvm::make_unique<mca::TimelineView>(
+          *STI, *IP, S, TimelineMaxIterations, TimelineMaxCycles));
+    }
 
-  if (PrintTimelineView) {
-    Printer.addView(llvm::make_unique<mca::TimelineView>(
-        *STI, *IP, *S, TimelineMaxIterations, TimelineMaxCycles));
+    B.run();
+    Printer.printReport(TOF->os());
   }
 
-  B.run();
-  Printer.printReport(TOF->os());
   TOF->keep();
-
   return 0;
 }




More information about the llvm-commits mailing list