summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/vmdef.nim2
-rw-r--r--compiler/vmgen.nim27
-rw-r--r--koch.nim2
-rw-r--r--todo.txt4
4 files changed, 20 insertions, 15 deletions
diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim
index f91b8a821..16ba1ed8e 100644
--- a/compiler/vmdef.nim
+++ b/compiler/vmdef.nim
@@ -201,3 +201,5 @@ template regA*(x: TInstr): TRegister {.immediate.} = TRegister(x.uint32 shr 8'u3
 template regB*(x: TInstr): TRegister {.immediate.} = TRegister(x.uint32 shr 16'u32 and 0xff'u32)
 template regC*(x: TInstr): TRegister {.immediate.} = TRegister(x.uint32 shr 24'u32)
 template regBx*(x: TInstr): int {.immediate.} = (x.uint32 shr 16'u32).int
+
+template jmpDiff*(x: TInstr): int {.immediate.} = regBx(x) - wordExcess
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim
index 40116de1d..175cae2f5 100644
--- a/compiler/vmgen.nim
+++ b/compiler/vmgen.nim
@@ -1243,12 +1243,11 @@ proc optimizeJumps(c: PCtx; start: int) =
     case opc
     of opcTJmp, opcFJmp:
       var reg = c.code[i].regA
-      var d = i + c.code[i].regBx
-      var iters = maxIterations
-      while iters > 0:
+      var d = i + c.code[i].jmpDiff
+      for iters in countdown(maxIterations, 0):
         case c.code[d].opcode
         of opcJmp:
-          d = d + c.code[d].regBx
+          d = d + c.code[d].jmpDiff
         of opcTJmp, opcFJmp:
           if c.code[d].regA != reg: break
           # tjmp x, 23
@@ -1256,22 +1255,26 @@ proc optimizeJumps(c: PCtx; start: int) =
           # tjmp x, 12
           # -- we know 'x' is true, and so can jump to 12+13:
           if c.code[d].opcode == opc:
-            d = d + c.code[d].regBx
+            d = d + c.code[d].jmpDiff
           else:
             # tjmp x, 23
             # fjmp x, 22
             # We know 'x' is true so skip to the next instruction:
             d = d + 1
         else: break
-        dec iters
-      c.finalJumpTarget(i, d - i)
+      if d != i + c.code[i].jmpDiff:
+        c.finalJumpTarget(i, d - i)
     of opcJmp:
-      var d = i + c.code[i].regBx
+      var d = i + c.code[i].jmpDiff
       var iters = maxIterations
       while c.code[d].opcode == opcJmp and iters > 0:
-        d = d + c.code[d].regBx
+        d = d + c.code[d].jmpDiff
         dec iters
-      c.finalJumpTarget(i, d - i)
+      if c.code[d].opcode == opcRet:
+        # optimize 'jmp to ret' to 'ret' here
+        c.code[i] = c.code[d]
+      elif d != i + c.code[i].jmpDiff:
+        c.finalJumpTarget(i, d - i)
     else: discard
 
 proc genProc(c: PCtx; s: PSym): int =
@@ -1300,9 +1303,11 @@ proc genProc(c: PCtx; s: PSym): int =
     # generate final 'return' statement:
     c.gABC(body, opcRet)
     c.patch(procStart)
-    
     c.gABC(body, opcEof, eofInstr.regA)
+    c.optimizeJumps(result)
     s.position = c.prc.maxSlots
+    #if s.name.s == "temp":
+    #  c.echoCode
     c.prc = oldPrc
   else:
     c.prc.maxSlots = s.position
diff --git a/koch.nim b/koch.nim
index 26dde73ea..6e0d5bdf2 100644
--- a/koch.nim
+++ b/koch.nim
@@ -271,7 +271,7 @@ proc tests(args: string) =
 
 proc temp(args: string) =
   var output = "compiler" / "nimrod".exe
-  var finalDest = "bin" / "nimrod".exe
+  var finalDest = "bin" / "nimrod_temp".exe
   exec("nimrod c compiler" / "nimrod")
   copyExe(output, finalDest)
   if args.len > 0: exec(finalDest & " " & args)
diff --git a/todo.txt b/todo.txt
index 1fb8748a6..1a75ab66f 100644
--- a/todo.txt
+++ b/todo.txt
@@ -2,12 +2,10 @@ version 0.9.4
 =============
 
 - new VM:
-   compiling htmlgen (txmlgen) makes the compiler go into an infinite loop
-   tcntseq
+  - tcntseq fails
   - new VM requires lambda lifting
   - implement overflow checking
   - implement the FFI
-  - test and activate the jump optimizer
 
 - make 'bind' default for templates and introduce 'mixin'
 - special rule for ``[]=``