aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Changelog.md32
-rw-r--r--README.md2
-rw-r--r--src/cas_spinlock.h23
-rw-r--r--src/inpla.y35
-rw-r--r--src/unlikely.h14
5 files changed, 92 insertions, 14 deletions
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 <errno.h>
#include <sched.h>
+#include "unlikely.h"
#include "timer.h" //#include <time.h>
#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