From aaca4da94fcdcdeedc2b9bff7dec1e3d7c7ecf9a Mon Sep 17 00:00:00 2001 From: Nick Gasson Date: Sun, 1 Jan 2023 10:15:46 +0000 Subject: [PATCH] Optimise $EXP to $SHL for powers-of-2 --- src/jit/jit-llvm.c | 12 ++++++------ src/jit/jit-optim.c | 15 +++++++++++++++ test/test_jit.c | 8 ++++++++ 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/jit/jit-llvm.c b/src/jit/jit-llvm.c index c030475c..0c4f5549 100644 --- a/src/jit/jit-llvm.c +++ b/src/jit/jit-llvm.c @@ -1722,15 +1722,15 @@ static void cgen_op_call(llvm_obj_t *obj, cgen_block_t *cgb, jit_ir_t *ir) #if CLOSED_WORLD entry = llvm_add_fn(obj, istr(callee->name), obj->types[LLVM_ENTRY_FN]); -#else - // Must have acquire semantics to synchronise with installing new code - entry = LLVMBuildLoad2(obj->builder, obj->types[LLVM_PTR], fptr, "entry"); - LLVMSetOrdering(entry, LLVMAtomicOrderingAcquire); #endif } - else { - entry = llvm_ptr(obj, callee->entry); + else fptr = llvm_ptr(obj, callee); + + if (entry == NULL) { + // Must have acquire semantics to synchronise with installing new code + entry = LLVMBuildLoad2(obj->builder, obj->types[LLVM_PTR], fptr, "entry"); + LLVMSetOrdering(entry, LLVMAtomicOrderingAcquire); } #ifndef LLVM_HAS_OPAQUE_POINTERS diff --git a/src/jit/jit-optim.c b/src/jit/jit-optim.c index 3e47fcf0..0d722e62 100644 --- a/src/jit/jit-optim.c +++ b/src/jit/jit-optim.c @@ -724,6 +724,20 @@ static void jit_lvn_bzero(jit_ir_t *ir, lvn_state_t *state) state->regvn[ir->result] = lvn_new_value(state); } +static void jit_lvn_exp(jit_ir_t *ir, lvn_state_t *state) +{ + int64_t base, exp; + if (lvn_can_fold(ir, state, &base, &exp)) + lvn_convert_mov(ir, state, LVN_CONST(ipow(base, exp))); + else if (lvn_is_const(ir->arg1, state, &base) && base == 2) { + ir->op = J_SHL; + ir->arg1.int64 = 1; + jit_lvn_generic(ir, state, VN_INVALID); + } + else + jit_lvn_generic(ir, state, VN_INVALID); +} + void jit_do_lvn(jit_func_t *f) { lvn_state_t state = { @@ -762,6 +776,7 @@ void jit_do_lvn(jit_func_t *f) case J_CLAMP: jit_lvn_clamp(ir, &state); break; case MACRO_COPY: jit_lvn_copy(ir, &state); break; case MACRO_BZERO: jit_lvn_bzero(ir, &state); break; + case MACRO_EXP: jit_lvn_exp(ir, &state); break; default: break; } } diff --git a/test/test_jit.c b/test/test_jit.c index cda54688..e093f972 100644 --- a/test/test_jit.c +++ b/test/test_jit.c @@ -1367,6 +1367,8 @@ START_TEST(test_lvn1) " SUB R1, R1, #0 \n" " SUB R2, #0, R2 \n" " SUB.O R2, #0, R2 \n" + " $EXP R3, #3, #4 \n" + " $EXP R3, #2, R2 \n" " RET \n"; jit_handle_t h1 = jit_assemble(j, ident_new("myfunc"), text1); @@ -1408,6 +1410,12 @@ START_TEST(test_lvn1) ck_assert_int_eq(f->irbuf[15].op, J_SUB); + ck_assert_int_eq(f->irbuf[16].op, J_MOV); + ck_assert_int_eq(f->irbuf[16].arg1.int64, 81); + + ck_assert_int_eq(f->irbuf[17].op, J_SHL); + ck_assert_int_eq(f->irbuf[17].arg1.int64, 1); + jit_free(j); } END_TEST -- 2.39.2