Skip to content

Commit 848bef5

Browse files
authored
[llvm-mca] Add command line option -call-latency (#92958)
Currently we assume a constant latency of 100 cycles for call instructions. This commit allows the user to specify a custom value for the same as a command line argument. Default latency is set to 100.
1 parent 25b65be commit 848bef5

File tree

6 files changed

+80
-14
lines changed

6 files changed

+80
-14
lines changed

llvm/include/llvm/MCA/InstrBuilder.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ class InstrBuilder {
7878

7979
bool FirstCallInst;
8080
bool FirstReturnInst;
81+
unsigned CallLatency;
8182

8283
using InstRecycleCallback = std::function<Instruction *(const InstrDesc &)>;
8384
InstRecycleCallback InstRecycleCB;
@@ -98,7 +99,7 @@ class InstrBuilder {
9899
public:
99100
InstrBuilder(const MCSubtargetInfo &STI, const MCInstrInfo &MCII,
100101
const MCRegisterInfo &RI, const MCInstrAnalysis *IA,
101-
const InstrumentManager &IM);
102+
const InstrumentManager &IM, unsigned CallLatency);
102103

103104
void clear() {
104105
Descriptors.clear();

llvm/lib/MCA/InstrBuilder.cpp

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,9 @@ InstrBuilder::InstrBuilder(const llvm::MCSubtargetInfo &sti,
3131
const llvm::MCInstrInfo &mcii,
3232
const llvm::MCRegisterInfo &mri,
3333
const llvm::MCInstrAnalysis *mcia,
34-
const mca::InstrumentManager &im)
34+
const mca::InstrumentManager &im, unsigned cl)
3535
: STI(sti), MCII(mcii), MRI(mri), MCIA(mcia), IM(im), FirstCallInst(true),
36-
FirstReturnInst(true) {
36+
FirstReturnInst(true), CallLatency(cl) {
3737
const MCSchedModel &SM = STI.getSchedModel();
3838
ProcResourceMasks.resize(SM.getNumProcResourceKinds());
3939
computeProcResourceMasks(STI.getSchedModel(), ProcResourceMasks);
@@ -220,17 +220,19 @@ static void initializeUsedResources(InstrDesc &ID,
220220

221221
static void computeMaxLatency(InstrDesc &ID, const MCInstrDesc &MCDesc,
222222
const MCSchedClassDesc &SCDesc,
223-
const MCSubtargetInfo &STI) {
223+
const MCSubtargetInfo &STI,
224+
unsigned CallLatency) {
224225
if (MCDesc.isCall()) {
225226
// We cannot estimate how long this call will take.
226-
// Artificially set an arbitrarily high latency (100cy).
227-
ID.MaxLatency = 100U;
227+
// Artificially set an arbitrarily high latency.
228+
ID.MaxLatency = CallLatency;
228229
return;
229230
}
230231

231232
int Latency = MCSchedModel::computeInstrLatency(STI, SCDesc);
232-
// If latency is unknown, then conservatively assume a MaxLatency of 100cy.
233-
ID.MaxLatency = Latency < 0 ? 100U : static_cast<unsigned>(Latency);
233+
// If latency is unknown, then conservatively assume the MaxLatency set for
234+
// calls.
235+
ID.MaxLatency = Latency < 0 ? CallLatency : static_cast<unsigned>(Latency);
234236
}
235237

236238
static Error verifyOperands(const MCInstrDesc &MCDesc, const MCInst &MCI) {
@@ -568,7 +570,7 @@ InstrBuilder::createInstrDescImpl(const MCInst &MCI,
568570
// We don't correctly model calls.
569571
WithColor::warning() << "found a call in the input assembly sequence.\n";
570572
WithColor::note() << "call instructions are not correctly modeled. "
571-
<< "Assume a latency of 100cy.\n";
573+
<< "Assume a latency of " << CallLatency << "cy.\n";
572574
FirstCallInst = false;
573575
}
574576

@@ -580,7 +582,7 @@ InstrBuilder::createInstrDescImpl(const MCInst &MCI,
580582
}
581583

582584
initializeUsedResources(*ID, SCDesc, STI, ProcResourceMasks);
583-
computeMaxLatency(*ID, MCDesc, SCDesc, STI);
585+
computeMaxLatency(*ID, MCDesc, SCDesc, STI, CallLatency);
584586

585587
if (Error Err = verifyOperands(MCDesc, MCI))
586588
return std::move(Err);
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
# NOTE: Assertions have been autogenerated by utils/update_mca_test_checks.py
2+
# RUN: llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 -iterations=1 %s | FileCheck --check-prefixes=ALL,DEFAULT %s
3+
# RUN: llvm-mca -mtriple=x86_64-unknown-unknown -mcpu=btver2 -call-latency=50 -iterations=1 %s | FileCheck --check-prefixes=ALL,CUSTOM %s
4+
5+
callq printf
6+
7+
# ALL: Iterations: 1
8+
# ALL-NEXT: Instructions: 1
9+
10+
# CUSTOM-NEXT: Total Cycles: 53
11+
# DEFAULT-NEXT: Total Cycles: 103
12+
13+
# ALL-NEXT: Total uOps: 1
14+
15+
# ALL: Dispatch Width: 2
16+
17+
# CUSTOM-NEXT: uOps Per Cycle: 0.02
18+
# CUSTOM-NEXT: IPC: 0.02
19+
20+
# DEFAULT-NEXT: uOps Per Cycle: 0.01
21+
# DEFAULT-NEXT: IPC: 0.01
22+
23+
# ALL-NEXT: Block RThroughput: 0.5
24+
25+
# ALL: Instruction Info:
26+
# ALL-NEXT: [1]: #uOps
27+
# ALL-NEXT: [2]: Latency
28+
# ALL-NEXT: [3]: RThroughput
29+
# ALL-NEXT: [4]: MayLoad
30+
# ALL-NEXT: [5]: MayStore
31+
# ALL-NEXT: [6]: HasSideEffects (U)
32+
33+
# ALL: [1] [2] [3] [4] [5] [6] Instructions:
34+
# ALL-NEXT: 1 1 0.50 callq printf
35+
36+
# ALL: Resources:
37+
# ALL-NEXT: [0] - JALU0
38+
# ALL-NEXT: [1] - JALU1
39+
# ALL-NEXT: [2] - JDiv
40+
# ALL-NEXT: [3] - JFPA
41+
# ALL-NEXT: [4] - JFPM
42+
# ALL-NEXT: [5] - JFPU0
43+
# ALL-NEXT: [6] - JFPU1
44+
# ALL-NEXT: [7] - JLAGU
45+
# ALL-NEXT: [8] - JMul
46+
# ALL-NEXT: [9] - JSAGU
47+
# ALL-NEXT: [10] - JSTC
48+
# ALL-NEXT: [11] - JVALU0
49+
# ALL-NEXT: [12] - JVALU1
50+
# ALL-NEXT: [13] - JVIMUL
51+
52+
# ALL: Resource pressure per iteration:
53+
# ALL-NEXT: [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13]
54+
# ALL-NEXT: - 1.00 - - - - - - - - - - - -
55+
56+
# ALL: Resource pressure by instruction:
57+
# ALL-NEXT: [0] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] Instructions:
58+
# ALL-NEXT: - 1.00 - - - - - - - - - - - - callq printf

llvm/tools/llvm-mca/llvm-mca.cpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,11 @@ static cl::opt<unsigned>
135135
"(instructions per cycle)"),
136136
cl::cat(ToolOptions), cl::init(0));
137137

138+
static cl::opt<unsigned>
139+
CallLatency("call-latency", cl::Hidden,
140+
cl::desc("Number of cycles to assume for a call instruction"),
141+
cl::cat(ToolOptions), cl::init(100U));
142+
138143
enum class SkipType { NONE, LACK_SCHED, PARSE_FAILURE, ANY_FAILURE };
139144

140145
static cl::opt<enum SkipType> SkipUnsupportedInstructions(
@@ -568,7 +573,7 @@ int main(int argc, char **argv) {
568573
}
569574

570575
// Create an instruction builder.
571-
mca::InstrBuilder IB(*STI, *MCII, *MRI, MCIA.get(), *IM);
576+
mca::InstrBuilder IB(*STI, *MCII, *MRI, MCIA.get(), *IM, CallLatency);
572577

573578
// Create a context to control ownership of the pipeline hardware.
574579
mca::Context MCA(*MRI, *STI);

llvm/unittests/tools/llvm-mca/MCATestBase.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ Error MCATestBase::runBaselineMCA(json::Object &Result, ArrayRef<MCInst> Insts,
6666

6767
// Default InstrumentManager
6868
auto IM = std::make_unique<mca::InstrumentManager>(*STI, *MCII);
69-
mca::InstrBuilder IB(*STI, *MCII, *MRI, MCIA.get(), *IM);
69+
mca::InstrBuilder IB(*STI, *MCII, *MRI, MCIA.get(), *IM, /*CallLatency=*/100);
7070

7171
const SmallVector<mca::Instrument *> Instruments;
7272
SmallVector<std::unique_ptr<mca::Instruction>> LoweredInsts;

llvm/unittests/tools/llvm-mca/X86/TestIncrementalMCA.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ TEST_F(X86TestBase, TestResumablePipeline) {
3333
P->addEventListener(SV.get());
3434

3535
auto IM = std::make_unique<mca::InstrumentManager>(*STI, *MCII);
36-
mca::InstrBuilder IB(*STI, *MCII, *MRI, MCIA.get(), *IM);
36+
mca::InstrBuilder IB(*STI, *MCII, *MRI, MCIA.get(), *IM, /*CallLatency=*/100);
3737

3838
const SmallVector<mca::Instrument *> Instruments;
3939
// Tile size = 7
@@ -124,7 +124,7 @@ TEST_F(X86TestBase, TestInstructionRecycling) {
124124
// Default InstrumentManager
125125
auto IM = std::make_unique<mca::InstrumentManager>(*STI, *MCII);
126126

127-
mca::InstrBuilder IB(*STI, *MCII, *MRI, MCIA.get(), *IM);
127+
mca::InstrBuilder IB(*STI, *MCII, *MRI, MCIA.get(), *IM, /*CallLatency=*/100);
128128
IB.setInstRecycleCallback(GetRecycledInst);
129129

130130
const SmallVector<mca::Instrument *> Instruments;

0 commit comments

Comments
 (0)