Skip to content

Commit f3378df

Browse files
committed
RISC-V: Cache instruction support
Calling riscv_subset_supports repeatedly harms the performance in a measurable way (about 3-13% in total on the most cases). As a simple solution, this commit now caches instruction class support (whether specific instruction class is supported) as a signed char array. It is expected to have 5-7% performance improvements when disassembling linked RISC-V ELF programs using objdump but this is particularly effective with programs with many CSR instructions (up to ~42% on the author's PC). include/ChangeLog: * opcode/riscv.h (enum riscv_insn_class): Add NUM_INSN_CLASSES. opcodes/ChangeLog: * riscv-dis.c (riscv_insn_support_cache) New. (init_riscv_dis_state_for_arch): Clear the instruction support cache. (riscv_disassemble_insn): Cache the instruction support.
1 parent c331388 commit f3378df

File tree

2 files changed

+16
-1
lines changed

2 files changed

+16
-1
lines changed

include/opcode/riscv.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -422,6 +422,8 @@ enum riscv_insn_class
422422
INSN_CLASS_XTHEADMEMIDX,
423423
INSN_CLASS_XTHEADMEMPAIR,
424424
INSN_CLASS_XTHEADSYNC,
425+
426+
NUM_INSN_CLASSES,
425427
};
426428

427429
/* This structure holds information for a particular instruction. */

opcodes/riscv-dis.c

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,9 @@ static bool no_aliases = false;
107107

108108
/* If set, disassemble with numeric register names. */
109109
static bool is_numeric = false;
110+
111+
/* Instruction support cache. */
112+
static signed char riscv_insn_support_cache[NUM_INSN_CLASSES];
110113

111114

112115
/* Set current disassembler context (dis_arch_context_current).
@@ -200,6 +203,9 @@ static void
200203
init_riscv_dis_state_for_arch (void)
201204
{
202205
is_arch_changed = true;
206+
/* Clear instruction support cache. */
207+
for (size_t i = 0; i < NUM_INSN_CLASSES; i++)
208+
riscv_insn_support_cache[i] = 0;
203209
}
204210

205211
/* Initialization (for arch and options). */
@@ -955,7 +961,14 @@ riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
955961
if ((op->xlen_requirement != 0) && (op->xlen_requirement != xlen))
956962
continue;
957963
/* Is this instruction supported by the current architecture? */
958-
if (!riscv_multi_subset_supports (&riscv_rps_dis, op->insn_class))
964+
if (riscv_insn_support_cache[op->insn_class] == 0)
965+
{
966+
riscv_insn_support_cache[op->insn_class]
967+
= riscv_multi_subset_supports (&riscv_rps_dis, op->insn_class)
968+
? +1
969+
: -1;
970+
}
971+
if (riscv_insn_support_cache[op->insn_class] < 0)
959972
continue;
960973

961974
matched_op = op;

0 commit comments

Comments
 (0)