shithub: MicroHs

Download patch

ref: 1b53d530e7040d5de411bc2ad1cc5e99f226d4cf
parent: 664198084c6c98d754c53bb1cf81469148f4fb6a
author: Lennart Augustsson <lennart.augustsson@epicgames.com>
date: Fri Aug 25 09:37:20 EDT 2023

Don't push top node in eval.

This does not seem to make any performance difference,
despite saving memory traffic.  Modern CPUs are amazing.

--- a/src/runtime/eval.c
+++ b/src/runtime/eval.c
@@ -130,7 +130,7 @@
 typedef struct node {
   union {
     struct node *uufun;
-    uint64_t uutag;             /* LSB=1 indicates that this is a tag, LSB=0 that this is anT_AP node */
+    uint64_t uutag;             /* LSB=1 indicates that this is a tag, LSB=0 that this is a T_AP node */
   } ufun;
   union {
     struct node *uuarg;
@@ -142,8 +142,8 @@
 typedef struct node* NODEPTR;
 #define NIL 0
 #define HEAPREF(i) &cells[(i)]
-#define GETTAG(p) ((p)->ufun.uutag & 1 ? (int)((p)->ufun.uutag >> 1) :T_AP)
-#define SETTAG(p,t) do { if (t !=T_AP) (p)->ufun.uutag = ((t) << 1) + 1; } while(0)
+#define GETTAG(p) ((p)->ufun.uutag & 1 ? (int)((p)->ufun.uutag >> 1) : T_AP)
+#define SETTAG(p,t) do { if (t != T_AP) (p)->ufun.uutag = ((t) << 1) + 1; } while(0)
 #define GETVALUE(p) (p)->uarg.uuvalue
 #define SETVALUE(p,v) (p)->uarg.uuvalue = v
 #define FUN(p) (p)->ufun.uufun
@@ -831,7 +831,7 @@
   while (GETTAG(n) == T_IND)
     n = INDIR(n);
   //printf("find_sharing %p %llu ", n, LABEL(n));
-  if (GETTAG(n) ==T_AP) {
+  if (GETTAG(n) == T_AP) {
     if (test_bit(shared_bits, n)) {
       /* Alread marked as shared */
       //printf("shared\n");
@@ -850,7 +850,7 @@
     }
   } else {
     /* Not an application, so do nothing */
-    //printf("notT_AP\n");
+    //printf("not T_AP\n");
     ;
   }
 }
@@ -1147,7 +1147,7 @@
 /* Reset stack pointer and return. */
 #define RET do { stack_ptr = stk; return; } while(0)
 /* Check that there are at least n arguments, return if not. */
-#define CHECK(n) do { if (stack_ptr - stk <= (n)) RET; } while(0)
+#define CHECK(n) do { if (stack_ptr - stk < (n)) RET; } while(0)
 
 #define SETIND(n, x) do { SETTAG((n), T_IND); INDIR((n)) = (x); } while(0)
 #define GOIND(x) do { SETIND(n, (x)); goto ind; } while(0)
@@ -1160,20 +1160,19 @@
  * NOTE: No GC is allowed after these, since the stack has been popped.
  */
 #define CHKARG0 do { } while(0)
-#define CHKARG1 do { CHECK(1); POP(1); n = TOP(0); x = ARG(n); } while(0)
-#define CHKARG2 do { CHECK(2); POP(2); n = TOP(0); y = ARG(n); x = ARG(TOP(-1)); } while(0)
-#define CHKARG3 do { CHECK(3); POP(3); n = TOP(0); z = ARG(n); y = ARG(TOP(-1)); x = ARG(TOP(-2)); } while(0)
-#define CHKARG4 do { CHECK(4); POP(4); n = TOP(0); w = ARG(n); z = ARG(TOP(-1)); y = ARG(TOP(-2)); x = ARG(TOP(-3)); } while(0)
+#define CHKARG1 do { CHECK(1); POP(1); n = TOP(-1); x = ARG(n); } while(0)
+#define CHKARG2 do { CHECK(2); POP(2); n = TOP(-1); y = ARG(n); x = ARG(TOP(-2)); } while(0)
+#define CHKARG3 do { CHECK(3); POP(3); n = TOP(-1); z = ARG(n); y = ARG(TOP(-2)); x = ARG(TOP(-3)); } while(0)
+#define CHKARG4 do { CHECK(4); POP(4); n = TOP(-1); w = ARG(n); z = ARG(TOP(-2)); y = ARG(TOP(-3)); x = ARG(TOP(-4)); } while(0)
 
 /* Alloc a possible GC action, e, between setting x and popping */
-#define CHKARGEV1(e) do { CHECK(1); x = ARG(TOP(1)); e; POP(1); n = TOP(0); } while(0)
+#define CHKARGEV1(e) do { CHECK(1); x = ARG(TOP(0)); e; POP(1); n = TOP(-1); } while(0)
 
 #define SETINT(n,r)  do { SETTAG((n), T_INT); SETVALUE((n), (r)); } while(0)
-#define OPINT2(e)    do { CHECK(2); xi = evalint(ARG(TOP(1))); yi = evalint(ARG(TOP(2))); e; POP(2); n = TOP(0); } while(0);
+#define OPINT2(e)    do { CHECK(2); xi = evalint(ARG(TOP(0))); yi = evalint(ARG(TOP(1))); e; POP(2); n = TOP(-1); } while(0);
 #define ARITHBIN(op) do { OPINT2(r = xi op yi); SETINT(n, r); RET; } while(0)
 #define CMP(op)      do { OPINT2(r = xi op yi); GOIND(r ? comTrue : combFalse); } while(0)
 
-  PUSH(n);
   for(;;) {
     num_reductions++;
 #if FASTTAGS
@@ -1193,11 +1192,11 @@
     switch (tag) {
     ind:
       num_reductions++;
-    case T_IND:  n = INDIR(n); TOP(0) = n; break;
+    case T_IND:  n = INDIR(n); break;
 
     ap:
       num_reductions++;
-    case T_AP:   n = FUN(n); PUSH(n); break;
+    case T_AP:   PUSH(n); n = FUN(n); break;
 
     case T_STR:  GCCHECK(strNodes(strlen(STR(n)))); GOIND(mkStringC(STR(n)));
     case T_INT:  RET;
@@ -1299,7 +1298,7 @@
         NODEPTR bm;
         NODEPTR bmg = evali(ARG(TOP(1)));
         GCCHECKSAVE(bmg, 4);
-        if (GETTAG(bmg) ==T_AP && GETTAG(bm = indir(FUN(bmg))) ==T_AP && GETTAG(indir(FUN(bm))) == T_IO_BIND) {
+        if (GETTAG(bmg) == T_AP && GETTAG(bm = indir(FUN(bmg))) == T_AP && GETTAG(indir(FUN(bm))) == T_IO_BIND) {
           NODEPTR g = ARG(bmg);
           NODEPTR h = ARG(TOP(2));
           n = new_ap(bm, new_ap(new_ap(new_ap(combCC, combIOBIND), g), h));
@@ -1485,6 +1484,7 @@
   }
   run_time -= gettime();
   NODEPTR res = evalio(prog);
+  res = evali(res);
   run_time += gettime();
   if (0) {
     FILE *out = fopen("prog.comb", "w");
--