Skip to content

Commit ecf372f

Browse files
[llvm-mca][RISCV] vsetivli and vsetvli act as instruments
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
1 parent aef6d46 commit ecf372f

File tree

10 files changed

+364
-47
lines changed

10 files changed

+364
-47
lines changed

llvm/include/llvm/MCA/CustomBehaviour.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,16 @@ class InstrumentManager {
156156
// Instrument.Desc equal to Type
157157
virtual bool supportsInstrumentType(StringRef Type) const { return false; }
158158

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

164+
/// Return a list of unique pointers to Instruments, where each Instrument
165+
/// is allocated by this function. See createInstrument to create Instrument
166+
/// from a description and data.
167+
virtual SmallVector<UniqueInstrument> createInstruments(const MCInst &Inst);
168+
162169
/// Given an MCInst and a vector of Instrument, a target can
163170
/// return a SchedClassID. This can be used by a subtarget to return a
164171
/// PseudoInstruction SchedClassID instead of the one that belongs to the

llvm/lib/MCA/CustomBehaviour.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ UniqueInstrument InstrumentManager::createInstrument(llvm::StringRef Desc,
4747
return std::make_unique<Instrument>(Desc, Data);
4848
}
4949

50+
SmallVector<UniqueInstrument>
51+
InstrumentManager::createInstruments(const MCInst &Inst) {
52+
return SmallVector<UniqueInstrument>();
53+
}
54+
5055
unsigned InstrumentManager::getSchedClassID(
5156
const MCInstrInfo &MCII, const MCInst &MCI,
5257
const llvm::SmallVector<Instrument *> &IVec) const {

llvm/lib/Target/RISCV/MCA/RISCVCustomBehaviour.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313

1414
#include "RISCVCustomBehaviour.h"
1515
#include "MCTargetDesc/RISCVMCTargetDesc.h"
16+
#include "RISCV.h"
1617
#include "RISCVInstrInfo.h"
1718
#include "TargetInfo/RISCVTargetInfo.h"
1819
#include "llvm/MC/TargetRegistry.h"
@@ -89,6 +90,49 @@ RISCVInstrumentManager::createInstrument(llvm::StringRef Desc,
8990
return std::make_unique<RISCVLMULInstrument>(Data);
9091
}
9192

93+
SmallVector<UniqueInstrument>
94+
RISCVInstrumentManager::createInstruments(const MCInst &Inst) {
95+
if (Inst.getOpcode() == RISCV::VSETVLI ||
96+
Inst.getOpcode() == RISCV::VSETIVLI) {
97+
LLVM_DEBUG(dbgs() << "RVCB: Found VSETVLI and creating instrument for it: "
98+
<< Inst << "\n");
99+
unsigned VTypeI = Inst.getOperand(2).getImm();
100+
RISCVII::VLMUL VLMUL = RISCVVType::getVLMUL(VTypeI);
101+
102+
StringRef LMUL;
103+
switch (VLMUL) {
104+
case RISCVII::LMUL_1:
105+
LMUL = "M1";
106+
break;
107+
case RISCVII::LMUL_2:
108+
LMUL = "M2";
109+
break;
110+
case RISCVII::LMUL_4:
111+
LMUL = "M4";
112+
break;
113+
case RISCVII::LMUL_8:
114+
LMUL = "M8";
115+
break;
116+
case RISCVII::LMUL_F2:
117+
LMUL = "MF2";
118+
break;
119+
case RISCVII::LMUL_F4:
120+
LMUL = "MF4";
121+
break;
122+
case RISCVII::LMUL_F8:
123+
LMUL = "MF8";
124+
break;
125+
case RISCVII::LMUL_RESERVED:
126+
llvm_unreachable("Cannot create instrument for LMUL_RESERVED");
127+
}
128+
SmallVector<UniqueInstrument> Instruments;
129+
Instruments.emplace_back(
130+
createInstrument(RISCVLMULInstrument::DESC_NAME, LMUL));
131+
return Instruments;
132+
}
133+
return SmallVector<UniqueInstrument>();
134+
}
135+
92136
unsigned RISCVInstrumentManager::getSchedClassID(
93137
const MCInstrInfo &MCII, const MCInst &MCI,
94138
const llvm::SmallVector<Instrument *> &IVec) const {

llvm/lib/Target/RISCV/MCA/RISCVCustomBehaviour.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ class RISCVInstrumentManager : public InstrumentManager {
4949
/// Create a Instrument for RISC-V target
5050
UniqueInstrument createInstrument(StringRef Desc, StringRef Data) override;
5151

52+
SmallVector<UniqueInstrument> createInstruments(const MCInst &Inst) override;
53+
5254
/// Using the Instrument, returns a SchedClassID to use instead of
5355
/// the SchedClassID that belongs to the MCI or the original SchedClassID.
5456
unsigned
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py
2+
# RUN: llvm-mca -mtriple=riscv64 -mcpu=sifive-x280 -timeline -iterations=1 < %s | FileCheck %s
3+
4+
vadd.vv v12, v12, v12
5+
vsetvli zero, a0, e8, m1, tu, mu
6+
vadd.vv v12, v12, v12
7+
8+
# CHECK: Iterations: 1
9+
# CHECK-NEXT: Instructions: 3
10+
# CHECK-NEXT: Total Cycles: 21
11+
# CHECK-NEXT: Total uOps: 3
12+
13+
# CHECK: Dispatch Width: 2
14+
# CHECK-NEXT: uOps Per Cycle: 0.14
15+
# CHECK-NEXT: IPC: 0.14
16+
# CHECK-NEXT: Block RThroughput: 18.0
17+
18+
# CHECK: Instruction Info:
19+
# CHECK-NEXT: [1]: #uOps
20+
# CHECK-NEXT: [2]: Latency
21+
# CHECK-NEXT: [3]: RThroughput
22+
# CHECK-NEXT: [4]: MayLoad
23+
# CHECK-NEXT: [5]: MayStore
24+
# CHECK-NEXT: [6]: HasSideEffects (U)
25+
26+
# CHECK: [1] [2] [3] [4] [5] [6] Instructions:
27+
# CHECK-NEXT: 1 4 16.00 vadd.vv v12, v12, v12
28+
# CHECK-NEXT: 1 3 1.00 U vsetvli zero, a0, e8, m1, tu, mu
29+
# CHECK-NEXT: 1 4 2.00 vadd.vv v12, v12, v12
30+
31+
# CHECK: Resources:
32+
# CHECK-NEXT: [0] - SiFive7FDiv
33+
# CHECK-NEXT: [1] - SiFive7IDiv
34+
# CHECK-NEXT: [2] - SiFive7PipeA
35+
# CHECK-NEXT: [3] - SiFive7PipeB
36+
# CHECK-NEXT: [4] - SiFive7PipeV
37+
# CHECK-NEXT: [5] - SiFive7VA
38+
# CHECK-NEXT: [6] - SiFive7VL
39+
# CHECK-NEXT: [7] - SiFive7VS
40+
41+
# CHECK: Resource pressure per iteration:
42+
# CHECK-NEXT: [0] [1] [2] [3] [4] [5] [6] [7]
43+
# CHECK-NEXT: - - 1.00 - 18.00 18.00 - -
44+
45+
# CHECK: Resource pressure by instruction:
46+
# CHECK-NEXT: [0] [1] [2] [3] [4] [5] [6] [7] Instructions:
47+
# CHECK-NEXT: - - - - 16.00 16.00 - - vadd.vv v12, v12, v12
48+
# CHECK-NEXT: - - 1.00 - - - - - vsetvli zero, a0, e8, m1, tu, mu
49+
# CHECK-NEXT: - - - - 2.00 2.00 - - vadd.vv v12, v12, v12
50+
51+
# CHECK: Timeline view:
52+
# CHECK-NEXT: 0123456789
53+
# CHECK-NEXT: Index 0123456789 0
54+
55+
# CHECK: [0,0] DeeeE. . . . vadd.vv v12, v12, v12
56+
# CHECK-NEXT: [0,1] .DeeE. . . . vsetvli zero, a0, e8, m1, tu, mu
57+
# CHECK-NEXT: [0,2] . . . .DeeeE vadd.vv v12, v12, v12
58+
59+
# CHECK: Average Wait times (based on the timeline view):
60+
# CHECK-NEXT: [0]: Executions
61+
# CHECK-NEXT: [1]: Average time spent waiting in a scheduler's queue
62+
# CHECK-NEXT: [2]: Average time spent waiting in a scheduler's queue while ready
63+
# CHECK-NEXT: [3]: Average time elapsed from WB until retire stage
64+
65+
# CHECK: [0] [1] [2] [3]
66+
# CHECK-NEXT: 0. 1 0.0 0.0 0.0 vadd.vv v12, v12, v12
67+
# CHECK-NEXT: 1. 1 0.0 0.0 0.0 vsetvli zero, a0, e8, m1, tu, mu
68+
# CHECK-NEXT: 2. 1 0.0 0.0 0.0 vadd.vv v12, v12, v12
69+
# CHECK-NEXT: 1 0.0 0.0 0.0 <total>
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py
2+
# RUN: llvm-mca -mtriple=riscv64 -mcpu=sifive-x280 -timeline -iterations=1 < %s | FileCheck %s
3+
4+
vsetivli zero, 8, e8, m1, tu, mu
5+
vadd.vv v12, v12, v12
6+
vsetivli zero, 8, e8, m8, tu, mu
7+
vadd.vv v12, v12, v12
8+
9+
# CHECK: Iterations: 1
10+
# CHECK-NEXT: Instructions: 4
11+
# CHECK-NEXT: Total Cycles: 12
12+
# CHECK-NEXT: Total uOps: 4
13+
14+
# CHECK: Dispatch Width: 2
15+
# CHECK-NEXT: uOps Per Cycle: 0.33
16+
# CHECK-NEXT: IPC: 0.33
17+
# CHECK-NEXT: Block RThroughput: 18.0
18+
19+
# CHECK: Instruction Info:
20+
# CHECK-NEXT: [1]: #uOps
21+
# CHECK-NEXT: [2]: Latency
22+
# CHECK-NEXT: [3]: RThroughput
23+
# CHECK-NEXT: [4]: MayLoad
24+
# CHECK-NEXT: [5]: MayStore
25+
# CHECK-NEXT: [6]: HasSideEffects (U)
26+
27+
# CHECK: [1] [2] [3] [4] [5] [6] Instructions:
28+
# CHECK-NEXT: 1 3 1.00 U vsetivli zero, 8, e8, m1, tu, mu
29+
# CHECK-NEXT: 1 4 2.00 vadd.vv v12, v12, v12
30+
# CHECK-NEXT: 1 3 1.00 U vsetivli zero, 8, e8, m8, tu, mu
31+
# CHECK-NEXT: 1 4 16.00 vadd.vv v12, v12, v12
32+
33+
# CHECK: Resources:
34+
# CHECK-NEXT: [0] - SiFive7FDiv
35+
# CHECK-NEXT: [1] - SiFive7IDiv
36+
# CHECK-NEXT: [2] - SiFive7PipeA
37+
# CHECK-NEXT: [3] - SiFive7PipeB
38+
# CHECK-NEXT: [4] - SiFive7PipeV
39+
# CHECK-NEXT: [5] - SiFive7VA
40+
# CHECK-NEXT: [6] - SiFive7VL
41+
# CHECK-NEXT: [7] - SiFive7VS
42+
43+
# CHECK: Resource pressure per iteration:
44+
# CHECK-NEXT: [0] [1] [2] [3] [4] [5] [6] [7]
45+
# CHECK-NEXT: - - 2.00 - 18.00 18.00 - -
46+
47+
# CHECK: Resource pressure by instruction:
48+
# CHECK-NEXT: [0] [1] [2] [3] [4] [5] [6] [7] Instructions:
49+
# CHECK-NEXT: - - 1.00 - - - - - vsetivli zero, 8, e8, m1, tu, mu
50+
# CHECK-NEXT: - - - - 2.00 2.00 - - vadd.vv v12, v12, v12
51+
# CHECK-NEXT: - - 1.00 - - - - - vsetivli zero, 8, e8, m8, tu, mu
52+
# CHECK-NEXT: - - - - 16.00 16.00 - - vadd.vv v12, v12, v12
53+
54+
# CHECK: Timeline view:
55+
# CHECK-NEXT: 01
56+
# CHECK-NEXT: Index 0123456789
57+
58+
# CHECK: [0,0] DeeE . .. vsetivli zero, 8, e8, m1, tu, mu
59+
# CHECK-NEXT: [0,1] . DeeeE .. vadd.vv v12, v12, v12
60+
# CHECK-NEXT: [0,2] . DeeE .. vsetivli zero, 8, e8, m8, tu, mu
61+
# CHECK-NEXT: [0,3] . . DeeeE vadd.vv v12, v12, v12
62+
63+
# CHECK: Average Wait times (based on the timeline view):
64+
# CHECK-NEXT: [0]: Executions
65+
# CHECK-NEXT: [1]: Average time spent waiting in a scheduler's queue
66+
# CHECK-NEXT: [2]: Average time spent waiting in a scheduler's queue while ready
67+
# CHECK-NEXT: [3]: Average time elapsed from WB until retire stage
68+
69+
# CHECK: [0] [1] [2] [3]
70+
# CHECK-NEXT: 0. 1 0.0 0.0 0.0 vsetivli zero, 8, e8, m1, tu, mu
71+
# CHECK-NEXT: 1. 1 0.0 0.0 0.0 vadd.vv v12, v12, v12
72+
# CHECK-NEXT: 2. 1 0.0 0.0 0.0 vsetivli zero, 8, e8, m8, tu, mu
73+
# CHECK-NEXT: 3. 1 0.0 0.0 0.0 vadd.vv v12, v12, v12
74+
# CHECK-NEXT: 1 0.0 0.0 0.0 <total>
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py
2+
# RUN: llvm-mca -mtriple=riscv64 -mcpu=sifive-x280 -timeline -iterations=1 < %s | FileCheck %s
3+
4+
vsetvli zero, a0, e8, m1, tu, mu
5+
vadd.vv v12, v12, v12
6+
vsetvli zero, a0, e8, m8, tu, mu
7+
vadd.vv v12, v12, v12
8+
9+
# CHECK: Iterations: 1
10+
# CHECK-NEXT: Instructions: 4
11+
# CHECK-NEXT: Total Cycles: 12
12+
# CHECK-NEXT: Total uOps: 4
13+
14+
# CHECK: Dispatch Width: 2
15+
# CHECK-NEXT: uOps Per Cycle: 0.33
16+
# CHECK-NEXT: IPC: 0.33
17+
# CHECK-NEXT: Block RThroughput: 18.0
18+
19+
# CHECK: Instruction Info:
20+
# CHECK-NEXT: [1]: #uOps
21+
# CHECK-NEXT: [2]: Latency
22+
# CHECK-NEXT: [3]: RThroughput
23+
# CHECK-NEXT: [4]: MayLoad
24+
# CHECK-NEXT: [5]: MayStore
25+
# CHECK-NEXT: [6]: HasSideEffects (U)
26+
27+
# CHECK: [1] [2] [3] [4] [5] [6] Instructions:
28+
# CHECK-NEXT: 1 3 1.00 U vsetvli zero, a0, e8, m1, tu, mu
29+
# CHECK-NEXT: 1 4 2.00 vadd.vv v12, v12, v12
30+
# CHECK-NEXT: 1 3 1.00 U vsetvli zero, a0, e8, m8, tu, mu
31+
# CHECK-NEXT: 1 4 16.00 vadd.vv v12, v12, v12
32+
33+
# CHECK: Resources:
34+
# CHECK-NEXT: [0] - SiFive7FDiv
35+
# CHECK-NEXT: [1] - SiFive7IDiv
36+
# CHECK-NEXT: [2] - SiFive7PipeA
37+
# CHECK-NEXT: [3] - SiFive7PipeB
38+
# CHECK-NEXT: [4] - SiFive7PipeV
39+
# CHECK-NEXT: [5] - SiFive7VA
40+
# CHECK-NEXT: [6] - SiFive7VL
41+
# CHECK-NEXT: [7] - SiFive7VS
42+
43+
# CHECK: Resource pressure per iteration:
44+
# CHECK-NEXT: [0] [1] [2] [3] [4] [5] [6] [7]
45+
# CHECK-NEXT: - - 2.00 - 18.00 18.00 - -
46+
47+
# CHECK: Resource pressure by instruction:
48+
# CHECK-NEXT: [0] [1] [2] [3] [4] [5] [6] [7] Instructions:
49+
# CHECK-NEXT: - - 1.00 - - - - - vsetvli zero, a0, e8, m1, tu, mu
50+
# CHECK-NEXT: - - - - 2.00 2.00 - - vadd.vv v12, v12, v12
51+
# CHECK-NEXT: - - 1.00 - - - - - vsetvli zero, a0, e8, m8, tu, mu
52+
# CHECK-NEXT: - - - - 16.00 16.00 - - vadd.vv v12, v12, v12
53+
54+
# CHECK: Timeline view:
55+
# CHECK-NEXT: 01
56+
# CHECK-NEXT: Index 0123456789
57+
58+
# CHECK: [0,0] DeeE . .. vsetvli zero, a0, e8, m1, tu, mu
59+
# CHECK-NEXT: [0,1] . DeeeE .. vadd.vv v12, v12, v12
60+
# CHECK-NEXT: [0,2] . DeeE .. vsetvli zero, a0, e8, m8, tu, mu
61+
# CHECK-NEXT: [0,3] . . DeeeE vadd.vv v12, v12, v12
62+
63+
# CHECK: Average Wait times (based on the timeline view):
64+
# CHECK-NEXT: [0]: Executions
65+
# CHECK-NEXT: [1]: Average time spent waiting in a scheduler's queue
66+
# CHECK-NEXT: [2]: Average time spent waiting in a scheduler's queue while ready
67+
# CHECK-NEXT: [3]: Average time elapsed from WB until retire stage
68+
69+
# CHECK: [0] [1] [2] [3]
70+
# CHECK-NEXT: 0. 1 0.0 0.0 0.0 vsetvli zero, a0, e8, m1, tu, mu
71+
# CHECK-NEXT: 1. 1 0.0 0.0 0.0 vadd.vv v12, v12, v12
72+
# CHECK-NEXT: 2. 1 0.0 0.0 0.0 vsetvli zero, a0, e8, m8, tu, mu
73+
# CHECK-NEXT: 3. 1 0.0 0.0 0.0 vadd.vv v12, v12, v12
74+
# CHECK-NEXT: 1 0.0 0.0 0.0 <total>

llvm/tools/llvm-mca/CodeRegion.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -172,22 +172,30 @@ class CodeRegions {
172172
bool isRegionActive(llvm::StringRef Description) const {
173173
return ActiveRegions.contains(Description);
174174
}
175+
176+
virtual void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc) = 0;
177+
virtual void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc,
178+
UniqueInstrument Instrument) = 0;
179+
virtual void endRegion(llvm::StringRef Description, llvm::SMLoc Loc) = 0;
175180
};
176181

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

180-
void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc);
181-
void endRegion(llvm::StringRef Description, llvm::SMLoc Loc);
185+
void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc) override;
186+
void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc,
187+
UniqueInstrument Instrument) override {}
188+
void endRegion(llvm::StringRef Description, llvm::SMLoc Loc) override;
182189
};
183190

184191
struct InstrumentRegions : public CodeRegions {
185192

186193
InstrumentRegions(llvm::SourceMgr &S);
187194

195+
void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc) override{};
188196
void beginRegion(llvm::StringRef Description, llvm::SMLoc Loc,
189-
UniqueInstrument Instrument);
190-
void endRegion(llvm::StringRef Description, llvm::SMLoc Loc);
197+
UniqueInstrument Instrument) override;
198+
void endRegion(llvm::StringRef Description, llvm::SMLoc Loc) override;
191199

192200
const SmallVector<Instrument *> getActiveInstruments(llvm::SMLoc Loc) const;
193201
};

0 commit comments

Comments
 (0)