Skip to content

Commit 0fcbf14

Browse files
[Exegesis] Implemented strategy for load operation (#113458)
This fix helps to map operand memory to destination registers. If instruction is load, we can self-alias it in case when instruction overrides whole address register. For that we use provided scratch memory.
1 parent d0eeeab commit 0fcbf14

File tree

2 files changed

+102
-1
lines changed

2 files changed

+102
-1
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# RUN: llvm-exegesis -mode=latency --benchmark-phase=assemble-measured-code -mtriple=riscv64-unknown-linux-gnu --mcpu=generic -opcode-name=LD 2>&1 | FileCheck --check-prefix=TEST1 %s
2+
3+
TEST1: ---
4+
TEST1-NEXT: mode: latency
5+
TEST1-NEXT: key:
6+
TEST1-NEXT: instructions:
7+
TEST1-NEXT: - 'LD X10 X10 i_0x0'
8+
9+
# RUN: llvm-exegesis -mode=latency --benchmark-phase=assemble-measured-code -mtriple=riscv64-unknown-linux-gnu --mcpu=generic -opcode-name=LW 2>&1 | FileCheck --check-prefix=TEST2 %s
10+
11+
TEST2: ---
12+
TEST2-NEXT: mode: latency
13+
TEST2-NEXT: key:
14+
TEST2-NEXT: instructions:
15+
TEST2-NEXT: - 'LW X10 X10 i_0x0'
16+
17+
# RUN: llvm-exegesis -mode=latency --benchmark-phase=assemble-measured-code -mtriple=riscv64-unknown-linux-gnu --mcpu=generic -opcode-name=LH 2>&1 | FileCheck --check-prefix=TEST3 %s
18+
19+
TEST3: ---
20+
TEST3-NEXT: mode: latency
21+
TEST3-NEXT: key:
22+
TEST3-NEXT: instructions:
23+
TEST3-NEXT: - 'LH X10 X10 i_0x0'
24+
25+
# RUN: llvm-exegesis -mode=latency --benchmark-phase=assemble-measured-code -mtriple=riscv64-unknown-linux-gnu --mcpu=generic -opcode-name=LWU 2>&1 | FileCheck --check-prefix=TEST4 %s
26+
27+
TEST4: ---
28+
TEST4-NEXT: mode: latency
29+
TEST4-NEXT: key:
30+
TEST4-NEXT: instructions:
31+
TEST4-NEXT: - 'LWU X10 X10 i_0x0'
32+
33+
# RUN: llvm-exegesis -mode=latency --benchmark-phase=assemble-measured-code -mtriple=riscv64-unknown-linux-gnu --mcpu=generic -opcode-name=LBU 2>&1 | FileCheck --check-prefix=TEST5 %s
34+
35+
TEST5: ---
36+
TEST5-NEXT: mode: latency
37+
TEST5-NEXT: key:
38+
TEST5-NEXT: instructions:
39+
TEST5-NEXT: - 'LBU X10 X10 i_0x0'
40+
41+
# RUN: llvm-exegesis -mode=latency --benchmark-phase=assemble-measured-code -mtriple=riscv64-unknown-linux-gnu --mcpu=generic -opcode-name=LUI 2>&1 | FileCheck --check-prefix=TEST6 %s
42+
43+
TEST6: LUI: No strategy found to make the execution serial
44+
45+
46+
# RUN: llvm-exegesis -mode=latency --benchmark-phase=assemble-measured-code -mtriple=riscv64-unknown-linux-gnu --mcpu=generic -opcode-name=LB 2>&1 | FileCheck --check-prefix=TEST7 %s
47+
48+
TEST7: ---
49+
TEST7-NEXT: mode: latency
50+
TEST7-NEXT: key:
51+
TEST7-NEXT: instructions:
52+
TEST7-NEXT: - 'LB X10 X10 i_0x0'
53+
54+
# RUN: llvm-exegesis -mode=latency --benchmark-phase=assemble-measured-code -mtriple=riscv64-unknown-linux-gnu --mcpu=generic -mattr=+a -opcode-name=LR_W_RL 2>&1 | FileCheck --check-prefix=TEST8 %s
55+
56+
TEST8: ---
57+
TEST8-NEXT: mode: latency
58+
TEST8-NEXT: key:
59+
TEST8-NEXT: instructions:
60+
TEST8-NEXT: - 'LR_W_RL X10 X10'

llvm/tools/llvm-exegesis/lib/SerialSnippetGenerator.cpp

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,48 @@ static void appendCodeTemplates(const LLVMState &State,
106106
}
107107
case ExecutionMode::SERIAL_VIA_MEMORY_INSTR: {
108108
// Select back-to-back memory instruction.
109-
// TODO: Implement me.
109+
110+
auto &I = Variant.getInstr();
111+
if (I.Description.mayLoad()) {
112+
// If instruction is load, we can self-alias it in case when instruction
113+
// overrides whole address register. For that we use provided scratch
114+
// memory.
115+
116+
// TODO: now it is not checked if load writes the whole register.
117+
118+
auto DefOpIt = find_if(I.Operands, [](Operand const &Op) {
119+
return Op.isDef() && Op.isReg();
120+
});
121+
122+
if (DefOpIt == I.Operands.end())
123+
return;
124+
125+
const Operand &DefOp = *DefOpIt;
126+
const ExegesisTarget &ET = State.getExegesisTarget();
127+
unsigned ScratchMemoryRegister = ET.getScratchMemoryRegister(
128+
State.getTargetMachine().getTargetTriple());
129+
const llvm::MCRegisterClass &RegClass =
130+
State.getTargetMachine().getMCRegisterInfo()->getRegClass(
131+
DefOp.getExplicitOperandInfo().RegClass);
132+
133+
// Register classes of def operand and memory operand must be the same
134+
// to perform aliasing.
135+
if (!RegClass.contains(ScratchMemoryRegister))
136+
return;
137+
138+
ET.fillMemoryOperands(Variant, ScratchMemoryRegister, 0);
139+
Variant.getValueFor(DefOp) = MCOperand::createReg(ScratchMemoryRegister);
140+
141+
CodeTemplate CT;
142+
CT.Execution = ExecutionModeBit;
143+
CT.ScratchSpacePointerInReg = ScratchMemoryRegister;
144+
145+
CT.Info = std::string(ExecutionClassDescription);
146+
CT.Instructions.push_back(std::move(Variant));
147+
CodeTemplates.push_back(std::move(CT));
148+
}
149+
150+
// TODO: implement more cases
110151
return;
111152
}
112153
case ExecutionMode::SERIAL_VIA_EXPLICIT_REGS: {

0 commit comments

Comments
 (0)