Skip to content

Commit fa9d1ca

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 e991ddb commit fa9d1ca

2 files changed

Lines changed: 16 additions & 1 deletion

File tree

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). */
@@ -958,7 +964,14 @@ riscv_disassemble_insn (bfd_vma memaddr,
958964
if ((op->xlen_requirement != 0) && (op->xlen_requirement != xlen))
959965
continue;
960966
/* Is this instruction supported by the current architecture? */
961-
if (!riscv_multi_subset_supports (&riscv_rps_dis, op->insn_class))
967+
if (riscv_insn_support_cache[op->insn_class] == 0)
968+
{
969+
riscv_insn_support_cache[op->insn_class]
970+
= riscv_multi_subset_supports (&riscv_rps_dis, op->insn_class)
971+
? +1
972+
: -1;
973+
}
974+
if (riscv_insn_support_cache[op->insn_class] < 0)
962975
continue;
963976

964977
matched_op = op;

0 commit comments

Comments
 (0)