summaryrefslogtreecommitdiffhomepage
path: root/ir/be/riscv
diff options
context:
space:
mode:
authorJohannes Bucher <johannes.bucher2@student.kit.edu>2019-06-19 14:45:34 +0200
committerJohannes Bucher <johannes.bucher2@student.kit.edu>2019-06-19 14:45:34 +0200
commit7d4909a9bbab9b2573d6e8d674c286152cc68abc (patch)
tree65c4c2acc8e6d0de3ab195a1c2f5850d29ef4a4f /ir/be/riscv
parent52e3d4e1e36d5f5eeb0945789e31379bda420045 (diff)
riscv: add a peephole optimization for consecutive shift operations
Diffstat (limited to 'ir/be/riscv')
-rw-r--r--ir/be/riscv/riscv_finish.c44
1 files changed, 44 insertions, 0 deletions
diff --git a/ir/be/riscv/riscv_finish.c b/ir/be/riscv/riscv_finish.c
index 81a7b39..1327c9e 100644
--- a/ir/be/riscv/riscv_finish.c
+++ b/ir/be/riscv/riscv_finish.c
@@ -122,11 +122,55 @@ static void peephole_be_IncSP(ir_node *const node)
be_peephole_IncSP_IncSP(node);
}
+/**
+ * Optimize consecutive shift immediate operations by combining them in a single operation
+ */
+static void peephole_riscv_shift(ir_node *const node)
+{
+ int opcode = get_riscv_irn_opcode(node);
+ ir_node *const pred = get_irn_n(node, n_riscv_srli_left);
+ if (!is_riscv_irn(pred) || !be_has_only_one_user(pred) || sched_prev(node) != pred) {
+ return;
+ }
+ if (get_riscv_irn_opcode(pred) == opcode) {
+ riscv_immediate_attr_t *const node_attr_imm = get_riscv_immediate_attr(node);
+ riscv_immediate_attr_t *const pred_attr_imm = get_riscv_immediate_attr(pred);
+ if (!is_uimm5(node_attr_imm->val + pred_attr_imm->val)) {
+ return;
+ }
+ int new_val = node_attr_imm->val + pred_attr_imm->val;
+
+ dbg_info *dbgi = get_irn_dbg_info(node);
+ ir_node *block = get_nodes_block(node);
+ ir_node *left = get_irn_n(pred, n_riscv_srli_left);
+ ir_node *new;
+ switch (opcode) {
+ case iro_riscv_srli:
+ new = new_bd_riscv_srli(dbgi, block, left, NULL, new_val);
+ break;
+ case iro_riscv_srai:
+ new = new_bd_riscv_srai(dbgi, block, left, NULL, new_val);
+ break;
+ case iro_riscv_slli:
+ new = new_bd_riscv_slli(dbgi, block, left, NULL, new_val);
+ break;
+ default:
+ return;
+ }
+ arch_set_irn_register(new, arch_get_irn_register(node));
+ be_peephole_replace(node, new);
+ sched_remove(pred);
+ }
+}
+
void riscv_finish_graph(ir_graph *irg)
{
/* perform peephole optimizations */
ir_clear_opcodes_generic_func();
register_peephole_optimization(op_be_IncSP, peephole_be_IncSP);
+ register_peephole_optimization(op_riscv_srli, peephole_riscv_shift);
+ register_peephole_optimization(op_riscv_srai, peephole_riscv_shift);
+ register_peephole_optimization(op_riscv_slli, peephole_riscv_shift);
be_peephole_opt(irg);
/* perform legalizations (mostly fix nodes with too big immediates) */