From 11dd49da1625e1a8197c6d9f8d22743a974ddb72 Mon Sep 17 00:00:00 2001 From: Shinya Sato Date: Sat, 21 Mar 2026 20:10:16 +0900 Subject: V0.13.2-1 --- Changelog.md | 32 ++++++++++++++++++++++++++++++++ README.md | 2 +- src/cas_spinlock.h | 23 +++++++++++++++++++++++ src/inpla.y | 35 ++++++++++++++++++++++------------- src/unlikely.h | 14 ++++++++++++++ 5 files changed, 92 insertions(+), 14 deletions(-) create mode 100644 src/unlikely.h diff --git a/Changelog.md b/Changelog.md index 231344e..a9c7d5c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,37 @@ # Change log +### v0.13.2-1 (released on 21 March 2026) + +#### Bug fix + +- **Fixed a register reallocation bug during intermediate code optimisation** + During the register reallocation pass, the optimiser correctly reuses a source register (`src`) in a `LOAD src, dest` instruction if it is no longer used later in the block. However, a bug caused the optimiser to incorrectly apply this same logic to `LOADI $i, dest` instructions, mistakenly interpreting the immediate value (`$i`) as a register ID. This version fixes this optimisation bug. As a result, parsing and compiling long lists with distinct elements (e.g., `1..100`) can now finally be completed without crashing! + + ```c + int CmEnv_Optimise_check_occurence_in_block(int localvar, + int target_imcode_addr) { + ... + + case OP_LOAD: + case OP_LOADI: + // OP src1 dest + if (imcode->operand1 == localvar) { + return 1; + } + break; + ==> + case OP_LOAD: + //case OP_LOADI: + // OP src1 dest + if (imcode->operand1 == localvar) { + return 1; + } + break; + + ``` + + + ### v0.13.2 (released on 16 March 2026) #### Polished diff --git a/README.md b/README.md index 2ff9b95..f00de3f 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Inpla is a multi-threaded parallel interpreter of interaction nets. Once you write programs for sequential execution, it works also in multi-threaded parallel execution. Each thread is managed on each CPU-core with POSIX-thread library. -* The current version is 0.13.2, released on **16 March 2026**. (See [Changelog.md](Changelog.md) for details.) +* The current version is 0.13.2-1, released on **21 March 2026**. (See [Changelog.md](Changelog.md) for details.) * The below graph shows speed-up ratio to threads numbers for programs in the following benchmark table. ![speedup-ratio](pic/benchmark_reuse_v0.13.0.png) diff --git a/src/cas_spinlock.h b/src/cas_spinlock.h index cb2dabd..1f25ebf 100644 --- a/src/cas_spinlock.h +++ b/src/cas_spinlock.h @@ -1,11 +1,34 @@ //#define CAS_LOCK_USLEEP 4 #define CAS_LOCK_USLEEP 200 + + +#define USE_UNLIKELY +#ifdef USE_UNLIKELY +#include "unlikely.h" +static inline void lock(volatile int *aexclusion) { + if (likely(__sync_lock_test_and_set(aexclusion, 1) == 0)) { + return; + } + + while (__sync_lock_test_and_set(aexclusion, 1)) { + while (*aexclusion) { + usleep(CAS_LOCK_USLEEP); + } + } +} + +#else + static inline void lock(volatile int *aexclusion) { while (__sync_lock_test_and_set(aexclusion, 1)) while (*aexclusion) usleep(CAS_LOCK_USLEEP); } + +#endif + + static inline void unlock(volatile int *aexclusion) { __sync_lock_release(aexclusion); } diff --git a/src/inpla.y b/src/inpla.y index aa13dbd..799a974 100644 --- a/src/inpla.y +++ b/src/inpla.y @@ -7,22 +7,22 @@ #include #include +#include "unlikely.h" #include "timer.h" //#include #include "linenoise/linenoise.h" #include "ast.h" #include "id_table.h" #include "name_table.h" -#include "name_table.h" #include "mytype.h" #include "inpla.h" - + #include "config.h" // ---------------------------------------------- -#define VERSION "0.13.2" +#define VERSION "0.13.2-1" #define BUILT_DATE "16 March 2026" // ------------------------------------------------------------------ @@ -2029,7 +2029,7 @@ void VM_EQStack_Push(VirtualMachine * restrict vm, VALUE l, VALUE r) { vm->nextPtr_eqStack++; - if (vm->nextPtr_eqStack >= vm->eqStack_size) { + if (unlikely(vm->nextPtr_eqStack >= vm->eqStack_size)) { vm->eqStack_size += vm->eqStack_size; vm->eqStack = realloc(vm->eqStack, sizeof(EQ)*vm->eqStack_size); @@ -2056,13 +2056,14 @@ void VM_EQStack_Push(VirtualMachine * restrict vm, VALUE l, VALUE r) { } int VM_EQStack_Pop(VirtualMachine * restrict vm, VALUE *l, VALUE *r) { - if (vm->nextPtr_eqStack >= 0) { - *l = vm->eqStack[vm->nextPtr_eqStack].l; - *r = vm->eqStack[vm->nextPtr_eqStack].r; - vm->nextPtr_eqStack--; - return 1; - } - return 0; + if (unlikely(vm->nextPtr_eqStack < 0)) { + return 0; + } + + *l = vm->eqStack[vm->nextPtr_eqStack].l; + *r = vm->eqStack[vm->nextPtr_eqStack].r; + vm->nextPtr_eqStack--; + return 1; } @@ -3797,7 +3798,7 @@ int CmEnv_Optimise_check_occurence_in_block(int localvar, } case OP_LOAD: - case OP_LOADI: + //case OP_LOADI: // OP src1 dest if (imcode->operand1 == localvar) { return 1; @@ -3889,7 +3890,7 @@ int CmEnv_Optimise_check_occurence_in_block(int localvar, break; case OP_EQI_R0: - // OP src1 + // OP src1 $n if (imcode->operand1 == localvar) { return 1; } @@ -7785,10 +7786,18 @@ void *exec_code(int mode, VirtualMachine * restrict vm, void * restrict *code) { // To create the table. // mode=0: Create table (only for initialise) // mode=1: Execute codes (the normal operation) + + /* if (mode == 0) { return table; } + */ + + if (unlikely((mode == 0))) { + return table; + } + int i, pc=0; VALUE a1; VALUE *reg = vm->reg; diff --git a/src/unlikely.h b/src/unlikely.h new file mode 100644 index 0000000..602c723 --- /dev/null +++ b/src/unlikely.h @@ -0,0 +1,14 @@ +#ifndef INPLA_UNLIKELY_H +#define INPLA_UNLIKELY_H + +#if defined(__GNUC__) || defined(__clang__) + // GCC と Clang の場合は、極限まで最適化! + #define likely(x) __builtin_expect(!!(x), 1) + #define unlikely(x) __builtin_expect(!!(x), 0) +#else + // それ以外のコンパイラ(MSVCなど)では、ただの素通り(無害化) + #define likely(x) (x) + #define unlikely(x) (x) +#endif + +#endif -- cgit v1.2.3