diff options
-rw-r--r-- | compiler/vmdef.nim | 2 | ||||
-rw-r--r-- | compiler/vmgen.nim | 27 | ||||
-rw-r--r-- | koch.nim | 2 | ||||
-rw-r--r-- | todo.txt | 4 |
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 ``[]=`` |