Skip to content

Commit

Permalink
[llvm-mca][RISCV] vsetivli and vsetvli act as instruments
Browse files Browse the repository at this point in the history
Since the LMUL data that is needed to create an instrument is
avaliable statically from vsetivli and vsetvli instructions,
LMUL instruments can be automatically generated so that clients
of the tool do no need to manually insert instrument comments.

Instrument comments may be placed after a vset{i}vli instruction,
which will override instrument that was automatically inserted.
As a result, clients of llvm-mca instruments do not need to update
their existing instrument comments. However, if the instrument
has the same LMUL as the vset{i}vli, then it is reccomended to
remove the instrument comment as it becomes redundant.

Differential Revision: https://reviews.llvm.org/D154526
  • Loading branch information
michaelmaitland committed Jul 6, 2023
1 parent aef6d46 commit ecf372f
Show file tree
Hide file tree
Showing 10 changed files with 364 additions and 47 deletions.
9 changes: 8 additions & 1 deletion llvm/include/llvm/MCA/CustomBehaviour.h
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,16 @@ class InstrumentManager {
// Instrument.Desc equal to Type
virtual bool supportsInstrumentType(StringRef Type) const { return false; }

/// Allocate an Instrument, and return a unique pointer to it.
/// Allocate an Instrument, and return a unique pointer to it. This function
/// may be useful to create instruments coming from comments in the assembly.
/// See createInstruments to create Instruments from MCInst
virtual UniqueInstrument createInstrument(StringRef Desc, StringRef Data);

/// Return a list of unique pointers to Instruments, where each Instrument
/// is allocated by this function. See createInstrument to create Instrument
/// from a description and data.
virtual SmallVector<UniqueInstrument> createInstruments(const MCInst &Inst);

/// Given an MCInst and a vector of Instrument, a target can
/// return a SchedClassID. This can be used by a subtarget to return a
/// PseudoInstruction SchedClassID instead of the one that belongs to the
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/MCA/CustomBehaviour.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ UniqueInstrument InstrumentManager::createInstrument(llvm::StringRef Desc,
return std::make_unique<Instrument>(Desc, Data);
}

SmallVector<UniqueInstrument>
InstrumentManager::createInstruments(const MCInst &Inst) {
return SmallVector<UniqueInstrument>();
}

unsigned InstrumentManager::getSchedClassID(
const MCInstrInfo &MCII, const MCInst &MCI,
const llvm::SmallVector<Instrument *> &IVec) const {
Expand Down
44 changes: 44 additions & 0 deletions llvm/lib/Target/RISCV/MCA/RISCVCustomBehaviour.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include "RISCVCustomBehaviour.h"
#include "MCTargetDesc/RISCVMCTargetDesc.h"
#include "RISCV.h"
#include "RISCVInstrInfo.h"
#include "TargetInfo/RISCVTargetInfo.h"
#include "llvm/MC/TargetRegistry.h"
Expand Down Expand Up @@ -89,6 +90,49 @@ RISCVInstrumentManager::createInstrument(llvm::StringRef Desc,
return std::make_unique<RISCVLMULInstrument>(Data);
}

SmallVector<UniqueInstrument>
RISCVInstrumentManager::createInstruments(const MCInst &Inst) {
if (Inst.getOpcode() == RISCV::VSETVLI ||
Inst.getOpcode() == RISCV::VSETIVLI) {
LLVM_DEBUG(dbgs() << "RVCB: Found VSETVLI and creating instrument for it: "
<< Inst << "\n");
unsigned VTypeI = Inst.getOperand(2).getImm();
RISCVII::VLMUL VLMUL = RISCVVType::getVLMUL(VTypeI);

StringRef LMUL;
switch (VLMUL) {
case RISCVII::LMUL_1:
LMUL = "M1";
break;
case RISCVII::LMUL_2:
LMUL = "M2";
break;
case RISCVII::LMUL_4:
LMUL = "M4";
break;
case RISCVII::LMUL_8:
LMUL = "M8";
break;
case RISCVII::LMUL_F2:
LMUL = "MF2";
break;
case RISCVII::LMUL_F4:
LMUL = "MF4";
break;
case RISCVII::LMUL_F8:
LMUL = "MF8";
break;
case RISCVII::LMUL_RESERVED:
llvm_unreachable("Cannot create instrument for LMUL_RESERVED");
}
SmallVector<UniqueInstrument> Instruments;
Instruments.emplace_back(
createInstrument(RISCVLMULInstrument::DESC_NAME, LMUL));
return Instruments;
}
return SmallVector<UniqueInstrument>();
}

unsigned RISCVInstrumentManager::getSchedClassID(
const MCInstrInfo &MCII, const MCInst &MCI,
const llvm::SmallVector<Instrument *> &IVec) const {
Expand Down
2 changes: 2 additions & 0 deletions llvm/lib/Target/RISCV/MCA/RISCVCustomBehaviour.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ class RISCVInstrumentManager : public InstrumentManager {
/// Create a Instrument for RISC-V target
UniqueInstrument createInstrument(StringRef Desc, StringRef Data) override;

SmallVector<UniqueInstrument> createInstruments(const MCInst &Inst) override;

/// Using the Instrument, returns a SchedClassID to use instead of
/// the SchedClassID that belongs to the MCI or the original SchedClassID.
unsigned
Expand Down
69 changes: 69 additions & 0 deletions llvm/test/tools/llvm-mca/RISCV/no-vsetvli-to-start.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py
# RUN: llvm-mca -mtriple=riscv64 -mcpu=sifive-x280 -timeline -iterations=1 < %s | FileCheck %s

vadd.vv v12, v12, v12
vsetvli zero, a0, e8, m1, tu, mu
vadd.vv v12, v12, v12

# CHECK: Iterations: 1
# CHECK-NEXT: Instructions: 3
# CHECK-NEXT: Total Cycles: 21
# CHECK-NEXT: Total uOps: 3

# CHECK: Dispatch Width: 2
# CHECK-NEXT: uOps Per Cycle: 0.14
# CHECK-NEXT: IPC: 0.14
# CHECK-NEXT: Block RThroughput: 18.0

# 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 (U)

# CHECK: [1] [2] [3] [4] [5] [6] Instructions:
# CHECK-NEXT: 1 4 16.00 vadd.vv v12, v12, v12
# CHECK-NEXT: 1 3 1.00 U vsetvli zero, a0, e8, m1, tu, mu
# CHECK-NEXT: 1 4 2.00 vadd.vv v12, v12, v12

# CHECK: Resources:
# CHECK-NEXT: [0] - SiFive7FDiv
# CHECK-NEXT: [1] - SiFive7IDiv
# CHECK-NEXT: [2] - SiFive7PipeA
# CHECK-NEXT: [3] - SiFive7PipeB
# CHECK-NEXT: [4] - SiFive7PipeV
# CHECK-NEXT: [5] - SiFive7VA
# CHECK-NEXT: [6] - SiFive7VL
# CHECK-NEXT: [7] - SiFive7VS

# CHECK: Resource pressure per iteration:
# CHECK-NEXT: [0] [1] [2] [3] [4] [5] [6] [7]
# CHECK-NEXT: - - 1.00 - 18.00 18.00 - -

# CHECK: Resource pressure by instruction:
# CHECK-NEXT: [0] [1] [2] [3] [4] [5] [6] [7] Instructions:
# CHECK-NEXT: - - - - 16.00 16.00 - - vadd.vv v12, v12, v12
# CHECK-NEXT: - - 1.00 - - - - - vsetvli zero, a0, e8, m1, tu, mu
# CHECK-NEXT: - - - - 2.00 2.00 - - vadd.vv v12, v12, v12

# CHECK: Timeline view:
# CHECK-NEXT: 0123456789
# CHECK-NEXT: Index 0123456789 0

# CHECK: [0,0] DeeeE. . . . vadd.vv v12, v12, v12
# CHECK-NEXT: [0,1] .DeeE. . . . vsetvli zero, a0, e8, m1, tu, mu
# CHECK-NEXT: [0,2] . . . .DeeeE vadd.vv v12, v12, v12

# CHECK: Average Wait times (based on the timeline view):
# CHECK-NEXT: [0]: Executions
# CHECK-NEXT: [1]: Average time spent waiting in a scheduler's queue
# CHECK-NEXT: [2]: Average time spent waiting in a scheduler's queue while ready
# CHECK-NEXT: [3]: Average time elapsed from WB until retire stage

# CHECK: [0] [1] [2] [3]
# CHECK-NEXT: 0. 1 0.0 0.0 0.0 vadd.vv v12, v12, v12
# CHECK-NEXT: 1. 1 0.0 0.0 0.0 vsetvli zero, a0, e8, m1, tu, mu
# CHECK-NEXT: 2. 1 0.0 0.0 0.0 vadd.vv v12, v12, v12
# CHECK-NEXT: 1 0.0 0.0 0.0 <total>
74 changes: 74 additions & 0 deletions llvm/test/tools/llvm-mca/RISCV/vsetivli-lmul-instrument.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py
# RUN: llvm-mca -mtriple=riscv64 -mcpu=sifive-x280 -timeline -iterations=1 < %s | FileCheck %s

vsetivli zero, 8, e8, m1, tu, mu
vadd.vv v12, v12, v12
vsetivli zero, 8, e8, m8, tu, mu
vadd.vv v12, v12, v12

# CHECK: Iterations: 1
# CHECK-NEXT: Instructions: 4
# CHECK-NEXT: Total Cycles: 12
# CHECK-NEXT: Total uOps: 4

# CHECK: Dispatch Width: 2
# CHECK-NEXT: uOps Per Cycle: 0.33
# CHECK-NEXT: IPC: 0.33
# CHECK-NEXT: Block RThroughput: 18.0

# 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 (U)

# CHECK: [1] [2] [3] [4] [5] [6] Instructions:
# CHECK-NEXT: 1 3 1.00 U vsetivli zero, 8, e8, m1, tu, mu
# CHECK-NEXT: 1 4 2.00 vadd.vv v12, v12, v12
# CHECK-NEXT: 1 3 1.00 U vsetivli zero, 8, e8, m8, tu, mu
# CHECK-NEXT: 1 4 16.00 vadd.vv v12, v12, v12

# CHECK: Resources:
# CHECK-NEXT: [0] - SiFive7FDiv
# CHECK-NEXT: [1] - SiFive7IDiv
# CHECK-NEXT: [2] - SiFive7PipeA
# CHECK-NEXT: [3] - SiFive7PipeB
# CHECK-NEXT: [4] - SiFive7PipeV
# CHECK-NEXT: [5] - SiFive7VA
# CHECK-NEXT: [6] - SiFive7VL
# CHECK-NEXT: [7] - SiFive7VS

# CHECK: Resource pressure per iteration:
# CHECK-NEXT: [0] [1] [2] [3] [4] [5] [6] [7]
# CHECK-NEXT: - - 2.00 - 18.00 18.00 - -

# CHECK: Resource pressure by instruction:
# CHECK-NEXT: [0] [1] [2] [3] [4] [5] [6] [7] Instructions:
# CHECK-NEXT: - - 1.00 - - - - - vsetivli zero, 8, e8, m1, tu, mu
# CHECK-NEXT: - - - - 2.00 2.00 - - vadd.vv v12, v12, v12
# CHECK-NEXT: - - 1.00 - - - - - vsetivli zero, 8, e8, m8, tu, mu
# CHECK-NEXT: - - - - 16.00 16.00 - - vadd.vv v12, v12, v12

# CHECK: Timeline view:
# CHECK-NEXT: 01
# CHECK-NEXT: Index 0123456789

# CHECK: [0,0] DeeE . .. vsetivli zero, 8, e8, m1, tu, mu
# CHECK-NEXT: [0,1] . DeeeE .. vadd.vv v12, v12, v12
# CHECK-NEXT: [0,2] . DeeE .. vsetivli zero, 8, e8, m8, tu, mu
# CHECK-NEXT: [0,3] . . DeeeE vadd.vv v12, v12, v12

# CHECK: Average Wait times (based on the timeline view):
# CHECK-NEXT: [0]: Executions
# CHECK-NEXT: [1]: Average time spent waiting in a scheduler's queue
# CHECK-NEXT: [2]: Average time spent waiting in a scheduler's queue while ready
# CHECK-NEXT: [3]: Average time elapsed from WB until retire stage

# CHECK: [0] [1] [2] [3]
# CHECK-NEXT: 0. 1 0.0 0.0 0.0 vsetivli zero, 8, e8, m1, tu, mu
# CHECK-NEXT: 1. 1 0.0 0.0 0.0 vadd.vv v12, v12, v12
# CHECK-NEXT: 2. 1 0.0 0.0 0.0 vsetivli zero, 8, e8, m8, tu, mu
# CHECK-NEXT: 3. 1 0.0 0.0 0.0 vadd.vv v12, v12, v12
# CHECK-NEXT: 1 0.0 0.0 0.0 <total>
74 changes: 74 additions & 0 deletions llvm/test/tools/llvm-mca/RISCV/vsetvli-lmul-instrument.s
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py
# RUN: llvm-mca -mtriple=riscv64 -mcpu=sifive-x280 -timeline -iterations=1 < %s | FileCheck %s

vsetvli zero, a0, e8, m1, tu, mu
vadd.vv v12, v12, v12
vsetvli zero, a0, e8, m8, tu, mu
vadd.vv v12, v12, v12

# CHECK: Iterations: 1
# CHECK-NEXT: Instructions: 4
# CHECK-NEXT: Total Cycles: 12
# CHECK-NEXT: Total uOps: 4

# CHECK: Dispatch Width: 2
# CHECK-NEXT: uOps Per Cycle: 0.33
# CHECK-NEXT: IPC: 0.33
# CHECK-NEXT: Block RThroughput: 18.0

# 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 (U)

# CHECK: [1] [2] [3] [4] [5] [6] Instructions:
# CHECK-NEXT: 1 3 1.00 U vsetvli zero, a0, e8, m1, tu, mu
# CHECK-NEXT: 1 4 2.00 vadd.vv v12, v12, v12
# CHECK-NEXT: 1 3 1.00 U vsetvli zero, a0, e8, m8, tu, mu
# CHECK-NEXT: 1 4 16.00 vadd.vv v12, v12, v12

# CHECK: Resources:
# CHECK-NEXT: [0] - SiFive7FDiv
# CHECK-NEXT: [1] - SiFive7IDiv
# CHECK-NEXT: [2] - SiFive7PipeA
# CHECK-NEXT: [3] - SiFive7PipeB
# CHECK-NEXT: [4] - SiFive7PipeV
# CHECK-NEXT: [5] - SiFive7VA
# CHECK-NEXT: [6] - SiFive7VL
# CHECK-NEXT: [7] - SiFive7VS

# CHECK: Resource pressure per iteration:
# CHECK-NEXT: [0] [1] [2] [3] [4] [5] [6] [7]
# CHECK-NEXT: - - 2.00 - 18.00 18.00 - -

# CHECK: Resource pressure by instruction:
# CHECK-NEXT: [0] [1] [2] [3] [4] [5] [6] [7] Instructions:
# CHECK-NEXT: - - 1.00 - - - - - vsetvli zero, a0, e8, m1, tu, mu
# CHECK-NEXT: - - - - 2.00 2.00 - - vadd.vv v12, v12, v12
# CHECK-NEXT: - - 1.00 - - - - - vsetvli zero, a0, e8, m8, tu, mu
# CHECK-NEXT: - - - - 16.00 16.00 - - vadd.vv v12, v12, v12

# CHECK: Timeline view:
# CHECK-NEXT: 01
# CHECK-NEXT: Index 0123456789

# CHECK: [0,0] DeeE . .. vsetvli zero, a0, e8, m1, tu, mu
# CHECK-NEXT: [0,1] . DeeeE .. vadd.vv v12, v12, v12
# CHECK-NEXT: [0,2] . DeeE .. vsetvli zero, a0, e8, m8, tu, mu
# CHECK-NEXT: [0,3] . . DeeeE vadd.vv v12, v12, v12

# CHECK: Average Wait times (based on the timeline view):
# CHECK-NEXT: [0]: Executions
# CHECK-NEXT: [1]: Average time spent waiting in a scheduler's queue
# CHECK-NEXT: [2]: Average time spent waiting in a scheduler's queue while ready
# CHECK-NEXT: [3]: Average time elapsed from WB until retire stage

# CHECK: [0] [1] [2] [3]
# CHECK-NEXT: 0. 1 0.0 0.0 0.0 vsetvli zero, a0, e8, m1, tu, mu
# CHECK-NEXT: 1. 1 0.0 0.0 0.0 vadd.vv v12, v12, v12
# CHECK-NEXT: 2. 1 0.0 0.0 0.0 vsetvli zero, a0, e8, m8, tu, mu
# CHECK-NEXT: 3. 1 0.0 0.0 0.0 vadd.vv v12, v12, v12
# CHECK-NEXT: 1 0.0 0.0 0.0 <total>
16 changes: 12 additions & 4 deletions llvm/tools/llvm-mca/CodeRegion.h
Original file line number Diff line number Diff line change
Expand Up @@ -172,22 +172,30 @@ class CodeRegions {
bool isRegionActive(llvm::StringRef Description) const {
return ActiveRegions.contains(Description);
}

virtual void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc) = 0;
virtual void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc,
UniqueInstrument Instrument) = 0;
virtual void endRegion(llvm::StringRef Description, llvm::SMLoc Loc) = 0;
};

struct AnalysisRegions : public CodeRegions {
AnalysisRegions(llvm::SourceMgr &S);

void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc);
void endRegion(llvm::StringRef Description, llvm::SMLoc Loc);
void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc) override;
void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc,
UniqueInstrument Instrument) override {}
void endRegion(llvm::StringRef Description, llvm::SMLoc Loc) override;
};

struct InstrumentRegions : public CodeRegions {

InstrumentRegions(llvm::SourceMgr &S);

void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc) override{};
void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc,
UniqueInstrument Instrument);
void endRegion(llvm::StringRef Description, llvm::SMLoc Loc);
UniqueInstrument Instrument) override;
void endRegion(llvm::StringRef Description, llvm::SMLoc Loc) override;

const SmallVector<Instrument *> getActiveInstruments(llvm::SMLoc Loc) const;
};
Expand Down

0 comments on commit ecf372f

Please sign in to comment.