Skip to content

Commit e058716

Browse files
AnastasiyaChernikovaKonstantin Vladimirovdnpetrov-scdybv-scmga-sc
committed
[Exegesis][RISCV] Add RISCV support for llvm-exegesis
Llvm-exegesis RISCV port is a result of team effort. Below everyone involved listed. Co-authored-by: Konstantin Vladimirov <konstantin.vladimirov@syntacore.com> Co-authored-by: Dmitrii Petrov <dmitrii.petrov@syntacore.com> Co-authored-by: Dmitry Bushev <dmitry.bushev@syntacore.com> Co-authored-by: Mark Goncharov <mark.goncharov@syntacore.com> Co-authored-by: Anastasiya Chernikova <anastasiya.chernikova@syntacore.com>
1 parent 971237d commit e058716

31 files changed

+983
-48
lines changed

llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,9 @@ enum OperandType : unsigned {
299299
OPERAND_RVKRNUM_2_14,
300300
OPERAND_SPIMM,
301301
OPERAND_LAST_RISCV_IMM = OPERAND_SPIMM,
302+
// Operand is a 3-bit rounding mode, '111' indicates FRM register.
303+
// Represents 'frm' argument passing to floating-point operations.
304+
OPERAND_FRMARG,
302305
// Operand is either a register or uimm5, this is used by V extension pseudo
303306
// instructions to represent a value that be passed as AVL to either vsetvli
304307
// or vsetivli.

llvm/lib/Target/RISCV/RISCVInstrInfo.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ class BranchCC_rri<bits<3> funct3, string opcodestr>
509509
let isTerminator = 1;
510510
}
511511

512-
let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {
512+
let hasSideEffects = 0, mayLoad = 1, mayStore = 0, UseNamedOperandTable = 1 in {
513513
class Load_ri<bits<3> funct3, string opcodestr>
514514
: RVInstI<funct3, OPC_LOAD, (outs GPR:$rd), (ins GPRMem:$rs1, simm12:$imm12),
515515
opcodestr, "$rd, ${imm12}(${rs1})">;
@@ -524,7 +524,7 @@ class HLoad_r<bits<7> funct7, bits<5> funct5, string opcodestr>
524524
// Operands for stores are in the order srcreg, base, offset rather than
525525
// reflecting the order these fields are specified in the instruction
526526
// encoding.
527-
let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {
527+
let hasSideEffects = 0, mayLoad = 0, mayStore = 1, UseNamedOperandTable = 1 in {
528528
class Store_rri<bits<3> funct3, string opcodestr>
529529
: RVInstS<funct3, OPC_STORE, (outs),
530530
(ins GPR:$rs2, GPRMem:$rs1, simm12:$imm12),

llvm/lib/Target/RISCV/RISCVInstrInfoF.td

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,8 @@ def frmarg : Operand<XLenVT> {
130130
let ParserMatchClass = FRMArg;
131131
let PrintMethod = "printFRMArg";
132132
let DecoderMethod = "decodeFRMArg";
133+
let OperandType = "OPERAND_FRMARG";
134+
let OperandNamespace = "RISCVOp";
133135
}
134136

135137
// Variants of the rounding mode operand that default to 'rne'. This is used
@@ -150,6 +152,8 @@ def frmarglegacy : Operand<XLenVT> {
150152
let ParserMatchClass = FRMArgLegacy;
151153
let PrintMethod = "printFRMArgLegacy";
152154
let DecoderMethod = "decodeFRMArg";
155+
let OperandType = "OPERAND_FRMARG";
156+
let OperandNamespace = "RISCVOp";
153157
}
154158

155159
//===----------------------------------------------------------------------===//
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --benchmark-phase=assemble-measured-code -opcode-name=AMOAND_D -mattr="+a" |& FileCheck --check-prefix=TEST1 %s
2+
3+
TEST1: ---
4+
TEST1-NEXT: mode: latency
5+
TEST1-NEXT: key:
6+
TEST1-NEXT: instructions:
7+
TEST1-NEXT: - 'AMOAND_D [[RE01:X[0-9]+]] X10 [[RE01:X[0-9]+]]'
8+
TEST1-NEXT: config: ''
9+
TEST1-NEXT: register_initial_values:
10+
TEST1-NEXT: - '[[RE01:X[0-9]+]]=0x0'
11+
TEST1-LAST: ...
12+
13+
# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --benchmark-phase=assemble-measured-code -opcode-name=AMOADD_W -mattr="+a" |& FileCheck --check-prefix=TEST2 %s
14+
15+
TEST2: ---
16+
TEST2-NEXT: mode: latency
17+
TEST2-NEXT: key:
18+
TEST2-NEXT: instructions:
19+
TEST2-NEXT: - 'AMOADD_W [[RE02:X[0-9]+]] X10 [[RE02:X[0-9]+]]'
20+
TEST2-NEXT: config: ''
21+
TEST2-NEXT: register_initial_values:
22+
TEST2-NEXT: - '[[RE02:X[0-9]+]]=0x0'
23+
TEST2-LAST: ...
24+
25+
# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --benchmark-phase=assemble-measured-code -opcode-name=AMOMAXU_D -mattr="+a" |& FileCheck --check-prefix=TEST3 %s
26+
27+
TEST3: ---
28+
TEST3-NEXT: mode: latency
29+
TEST3-NEXT: key:
30+
TEST3-NEXT: instructions:
31+
TEST3-NEXT: - 'AMOMAXU_D [[RE03:X[0-9]+]] X10 [[RE03:X[0-9]+]]'
32+
TEST3-NEXT: config: ''
33+
TEST3-NEXT: register_initial_values:
34+
TEST3-NEXT: - '[[RE03:X[0-9]+]]=0x0'
35+
TEST3-LAST: ...
36+
37+
# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --benchmark-phase=assemble-measured-code -opcode-name=AMOMIN_W -mattr="+a" |& FileCheck --check-prefix=TEST4 %s
38+
39+
TEST4: ---
40+
TEST4-NEXT: mode: latency
41+
TEST4-NEXT: key:
42+
TEST4-NEXT: instructions:
43+
TEST4-NEXT: - 'AMOMIN_W [[RE04:X[0-9]+]] X10 [[RE04:X[0-9]+]]'
44+
TEST4-NEXT: config: ''
45+
TEST4-NEXT: register_initial_values:
46+
TEST4-NEXT: - '[[RE04:X[0-9]+]]=0x0'
47+
TEST4-LAST: ...
48+
49+
# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --benchmark-phase=assemble-measured-code -opcode-name=AMOXOR_D -mattr="+a" |& FileCheck --check-prefix=TEST5 %s
50+
51+
TEST5: ---
52+
TEST5-NEXT: mode: latency
53+
TEST5-NEXT: key:
54+
TEST5-NEXT: instructions:
55+
TEST5-NEXT: - 'AMOXOR_D [[RE05:X[0-9]+]] X10 [[RE05:X[0-9]+]]'
56+
TEST5-NEXT: config: ''
57+
TEST5-NEXT: register_initial_values:
58+
TEST5-NEXT: - '[[RE05:X[0-9]+]]=0x0'
59+
TEST5-LAST: ...
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --benchmark-phase=assemble-measured-code -opcode-name=C_ADDI -mattr=+c |& FileCheck --check-prefix=TEST1 %s
2+
3+
TEST1: ---
4+
TEST1-NEXT: mode: latency
5+
TEST1-NEXT: key:
6+
TEST1-NEXT: instructions:
7+
TEST1-NEXT: - 'C_ADDI [[REG01:X[0-9]+]] [[RE02:X[0-9]+]] [[IMM0:i_0x[0-9]+]]'
8+
9+
# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --benchmark-phase=assemble-measured-code -opcode-name=C_ADDIW -mattr=+c |& FileCheck --check-prefix=TEST2 %s
10+
11+
TEST2: ---
12+
TEST2-NEXT: mode: latency
13+
TEST2-NEXT: key:
14+
TEST2-NEXT: instructions:
15+
TEST2-NEXT: - 'C_ADDIW [[REG11:X[0-9]+]] [[RE12:X[0-9]+]] [[IMM1:i_0x[0-9]+]]'
16+
17+
# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --benchmark-phase=assemble-measured-code -opcode-name=C_ANDI -mattr=+c |& FileCheck --check-prefix=TEST3 %s
18+
19+
TEST3: ---
20+
TEST3-NEXT: mode: latency
21+
TEST3-NEXT: key:
22+
TEST3-NEXT: instructions:
23+
TEST3-NEXT: - 'C_ANDI [[REG31:X[0-9]+]] [[REG32:X[0-9]+]] [[IMM3:i_0x[0-9]+]]'
24+
25+
# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --benchmark-phase=assemble-measured-code -opcode-name=C_SLLI -mattr=+c |& FileCheck --check-prefix=TEST4 %s
26+
27+
TEST4: ---
28+
TEST4-NEXT: mode: latency
29+
TEST4-NEXT: key:
30+
TEST4-NEXT: instructions:
31+
TEST4-NEXT: - 'C_SLLI [[REG81:X[0-9]+]] [[REG82:X[0-9]+]] [[IMM8:i_0x[0-9]+]]'
32+
33+
# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --benchmark-phase=assemble-measured-code -opcode-name=C_SRAI -mattr=+c |& FileCheck --check-prefix=TEST5 %s
34+
35+
TEST5: ---
36+
TEST5-NEXT: mode: latency
37+
TEST5-NEXT: key:
38+
TEST5-NEXT: instructions:
39+
TEST5-NEXT: - 'C_SRAI [[REG91:X[0-9]+]] [[REG92:X[0-9]+]] [[IMM9:i_0x[0-9]+]]'
40+
41+
# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --benchmark-phase=assemble-measured-code -opcode-name=C_SRLI -mattr=+c |& FileCheck --check-prefix=TEST6 %s
42+
43+
TEST6: ---
44+
TEST6-NEXT: mode: latency
45+
TEST6-NEXT: key:
46+
TEST6-NEXT: instructions:
47+
TEST6-NEXT: - 'C_SRLI [[REG101:X[0-9]+]] [[REG102:X[0-9]+]] [[IMM10:i_0x[0-9]+]]'
48+
TEST6-LAST: ...
49+
50+
51+
# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --benchmark-phase=assemble-measured-code -opcode-name=C_LD -mattr=+c |& FileCheck --check-prefix=TEST7 %s
52+
53+
TEST7: ---
54+
TEST7-NEXT: mode: latency
55+
TEST7-NEXT: key:
56+
TEST7-NEXT: instructions:
57+
TEST7-NEXT: - 'C_LD [[REG61:X[0-9]+]] [[REG62:X[0-9]+]] [[IMM6:i_0x[0-9]+]]'
58+
59+
# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --benchmark-phase=assemble-measured-code -opcode-name=C_LW -mattr=+c |& FileCheck --check-prefix=TEST8 %s
60+
61+
TEST8: ---
62+
TEST8-NEXT: mode: latency
63+
TEST8-NEXT: key:
64+
TEST8-NEXT: instructions:
65+
TEST8-NEXT: - 'C_LW [[REG71:X[0-9]+]] [[REG72:X[0-9]+]] [[IMM7:i_0x[0-9]+]]'
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
# RUN: llvm-exegesis -mode=latency -mtriple=riscv64-unknown-linux-gnu --benchmark-phase=assemble-measured-code -opcode-name=LD |& 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 -mtriple=riscv64-unknown-linux-gnu --benchmark-phase=assemble-measured-code -opcode-name=LW |& 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 -mtriple=riscv64-unknown-linux-gnu --benchmark-phase=assemble-measured-code -opcode-name=LH |& 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 -mtriple=riscv64-unknown-linux-gnu --benchmark-phase=assemble-measured-code -opcode-name=LWU |& 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 -mtriple=riscv64-unknown-linux-gnu --benchmark-phase=assemble-measured-code -opcode-name=LBU |& 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 -mtriple=riscv64-unknown-linux-gnu --benchmark-phase=assemble-measured-code -opcode-name=LUI |& 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 -mtriple=riscv64-unknown-linux-gnu --benchmark-phase=assemble-measured-code -opcode-name=LB |& 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 -mtriple=riscv64-unknown-linux-gnu --benchmark-phase=assemble-measured-code -opcode-name=LR_W_RL -mattr="+a" |& 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'
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# RUN: llvm-exegesis -mtriple=riscv64-unknown-linux-gnu -mode=latency --benchmark-phase=assemble-measured-code -mattr=+d -opcode-name=FADD_D |& FileCheck %s
2+
3+
CHECK: ---
4+
CHECK-NEXT: mode: latency
5+
CHECK-NEXT: key:
6+
CHECK-NEXT: instructions:
7+
CHECK-NEXT: - 'FADD_D [[REG1:F[0-9]+_D]] [[REG2:F[0-9]+_D]] [[REG3:F[0-9]+_D]] i_0x7'
8+
CHECK-NEXT: config: ''
9+
CHECK-NEXT: register_initial_values:
10+
CHECK-DAG: - '[[REG1]]=0x0'
11+
CHECK-LAST: ...
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
RUN: llvm-exegesis -mode=latency --benchmark-phase=assemble-measured-code -opcode-name=LB -mtriple=riscv64-unknown-linux-gnu
2+
3+
CHECK: Warning: Pre-assigned register prevented usage of self-aliasing strategy.

llvm/tools/llvm-exegesis/lib/AArch64/Target.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,10 @@ class ExegesisAArch64Target : public ExegesisTarget {
4545
: ExegesisTarget(AArch64CpuPfmCounters, AArch64_MC::isOpcodeAvailable) {}
4646

4747
private:
48+
unsigned findRegisterByName(const StringRef RegName) const override {
49+
return AArch64::NoRegister;
50+
}
51+
4852
std::vector<MCInst> setRegTo(const MCSubtargetInfo &STI, unsigned Reg,
4953
const APInt &Value) const override {
5054
if (AArch64::GPR32RegClass.contains(Reg))

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,15 @@ void BasicBlockFiller::addInstruction(const MCInst &Inst, const DebugLoc &DL) {
168168
} else if (Op.isImm()) {
169169
Builder.addImm(Op.getImm());
170170
} else if (!Op.isValid()) {
171-
llvm_unreachable("Operand is not set");
171+
std::string Message;
172+
llvm::raw_string_ostream MessageOut(Message);
173+
MessageOut << "Operand is not set: Instr: ";
174+
Inst.dump_pretty(MessageOut, MCII->getName(Inst.getOpcode()));
175+
MessageOut << "; OpIndex: " << OpIndex;
176+
const MCOperandInfo &OperandInfo = MCID.operands()[OpIndex];
177+
MessageOut << "; OpInfo.OperandType: "
178+
<< static_cast<uint32_t>(OperandInfo.OperandType);
179+
report_fatal_error(Twine(Message));
172180
} else {
173181
llvm_unreachable("Not yet implemented");
174182
}

llvm/tools/llvm-exegesis/lib/BenchmarkCode.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,11 @@
1717
namespace llvm {
1818
namespace exegesis {
1919

20+
struct ScratchMemoryStore {
21+
unsigned Reg;
22+
unsigned Offset;
23+
};
24+
2025
// A collection of instructions that are to be assembled, executed and measured.
2126
struct BenchmarkCode {
2227
BenchmarkKey Key;

llvm/tools/llvm-exegesis/lib/CMakeLists.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ endif()
1212
if (LLVM_TARGETS_TO_BUILD MATCHES "Mips")
1313
list(APPEND LLVM_EXEGESIS_TARGETS "Mips")
1414
endif()
15+
if(LLVM_TARGETS_TO_BUILD MATCHES "RISCV")
16+
list(APPEND LLVM_EXEGESIS_TARGETS "RISCV")
17+
endif()
1518

1619
set(LLVM_EXEGESIS_TARGETS ${LLVM_EXEGESIS_TARGETS} PARENT_SCOPE)
1720

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,14 @@ const MCOperand &InstructionTemplate::getValueFor(const Operand &Op) const {
5757
return getValueFor(Instr->Variables[Op.getVariableIndex()]);
5858
}
5959

60+
MCOperand &InstructionTemplate::getValueFor(unsigned OpIdx) {
61+
return getValueFor(Instr->Variables[OpIdx]);
62+
}
63+
64+
const MCOperand &InstructionTemplate::getValueFor(unsigned OpIdx) const {
65+
return getValueFor(Instr->Variables[OpIdx]);
66+
}
67+
6068
bool InstructionTemplate::hasImmediateVariables() const {
6169
return any_of(Instr->Variables, [this](const Variable &Var) {
6270
return Instr->getPrimaryOperand(Var).isImmediate();

llvm/tools/llvm-exegesis/lib/CodeTemplate.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ struct InstructionTemplate {
3535
const MCOperand &getValueFor(const Variable &Var) const;
3636
MCOperand &getValueFor(const Operand &Op);
3737
const MCOperand &getValueFor(const Operand &Op) const;
38+
MCOperand &getValueFor(unsigned OpIdx);
39+
const MCOperand &getValueFor(unsigned OpIdx) const;
3840
bool hasImmediateVariables() const;
3941
const Instruction &getInstr() const { return *Instr; }
4042
ArrayRef<MCOperand> getVariableValues() const { return VariableValues; }
@@ -133,6 +135,10 @@ struct CodeTemplate {
133135
// the pointer to this memory is passed in to the function.
134136
unsigned ScratchSpacePointerInReg = 0;
135137

138+
// Require to pre-store value of a given register (fisrt)
139+
// to scratch memory with given offset (second)
140+
SmallVector<std::pair<unsigned, unsigned>, 2> PreinitScratchMemory;
141+
136142
#if defined(__GNUC__) && (defined(__clang__) || LLVM_GNUC_PREREQ(8, 0, 0))
137143
// FIXME: GCC7 bug workaround. Drop #if after GCC7 no longer supported.
138144
private:

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ Expected<LLVMState> LLVMState::Create(std::string TripleName,
4545
if (CpuName == "native")
4646
CpuName = std::string(sys::getHostCPUName());
4747

48+
if (CpuName.empty()) {
49+
std::unique_ptr<MCSubtargetInfo> Empty_STI(
50+
TheTarget->createMCSubtargetInfo(TripleName, "", ""));
51+
CpuName = Empty_STI->getAllProcessorDescriptions().begin()->Key;
52+
}
53+
4854
std::unique_ptr<MCSubtargetInfo> STI(
4955
TheTarget->createMCSubtargetInfo(TripleName, CpuName, ""));
5056
assert(STI && "Unable to create subtarget info!");

0 commit comments

Comments
 (0)