jump optimizer works
This commit is contained in:
parent
b4e25a6372
commit
be45263623
4 changed files with 20 additions and 15 deletions
|
|
@ -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 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 regC*(x: TInstr): TRegister {.immediate.} = TRegister(x.uint32 shr 24'u32)
|
||||||
template regBx*(x: TInstr): int {.immediate.} = (x.uint32 shr 16'u32).int
|
template regBx*(x: TInstr): int {.immediate.} = (x.uint32 shr 16'u32).int
|
||||||
|
|
||||||
|
template jmpDiff*(x: TInstr): int {.immediate.} = regBx(x) - wordExcess
|
||||||
|
|
|
||||||
|
|
@ -1243,12 +1243,11 @@ proc optimizeJumps(c: PCtx; start: int) =
|
||||||
case opc
|
case opc
|
||||||
of opcTJmp, opcFJmp:
|
of opcTJmp, opcFJmp:
|
||||||
var reg = c.code[i].regA
|
var reg = c.code[i].regA
|
||||||
var d = i + c.code[i].regBx
|
var d = i + c.code[i].jmpDiff
|
||||||
var iters = maxIterations
|
for iters in countdown(maxIterations, 0):
|
||||||
while iters > 0:
|
|
||||||
case c.code[d].opcode
|
case c.code[d].opcode
|
||||||
of opcJmp:
|
of opcJmp:
|
||||||
d = d + c.code[d].regBx
|
d = d + c.code[d].jmpDiff
|
||||||
of opcTJmp, opcFJmp:
|
of opcTJmp, opcFJmp:
|
||||||
if c.code[d].regA != reg: break
|
if c.code[d].regA != reg: break
|
||||||
# tjmp x, 23
|
# tjmp x, 23
|
||||||
|
|
@ -1256,22 +1255,26 @@ proc optimizeJumps(c: PCtx; start: int) =
|
||||||
# tjmp x, 12
|
# tjmp x, 12
|
||||||
# -- we know 'x' is true, and so can jump to 12+13:
|
# -- we know 'x' is true, and so can jump to 12+13:
|
||||||
if c.code[d].opcode == opc:
|
if c.code[d].opcode == opc:
|
||||||
d = d + c.code[d].regBx
|
d = d + c.code[d].jmpDiff
|
||||||
else:
|
else:
|
||||||
# tjmp x, 23
|
# tjmp x, 23
|
||||||
# fjmp x, 22
|
# fjmp x, 22
|
||||||
# We know 'x' is true so skip to the next instruction:
|
# We know 'x' is true so skip to the next instruction:
|
||||||
d = d + 1
|
d = d + 1
|
||||||
else: break
|
else: break
|
||||||
dec iters
|
if d != i + c.code[i].jmpDiff:
|
||||||
c.finalJumpTarget(i, d - i)
|
c.finalJumpTarget(i, d - i)
|
||||||
of opcJmp:
|
of opcJmp:
|
||||||
var d = i + c.code[i].regBx
|
var d = i + c.code[i].jmpDiff
|
||||||
var iters = maxIterations
|
var iters = maxIterations
|
||||||
while c.code[d].opcode == opcJmp and iters > 0:
|
while c.code[d].opcode == opcJmp and iters > 0:
|
||||||
d = d + c.code[d].regBx
|
d = d + c.code[d].jmpDiff
|
||||||
dec iters
|
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
|
else: discard
|
||||||
|
|
||||||
proc genProc(c: PCtx; s: PSym): int =
|
proc genProc(c: PCtx; s: PSym): int =
|
||||||
|
|
@ -1300,9 +1303,11 @@ proc genProc(c: PCtx; s: PSym): int =
|
||||||
# generate final 'return' statement:
|
# generate final 'return' statement:
|
||||||
c.gABC(body, opcRet)
|
c.gABC(body, opcRet)
|
||||||
c.patch(procStart)
|
c.patch(procStart)
|
||||||
|
|
||||||
c.gABC(body, opcEof, eofInstr.regA)
|
c.gABC(body, opcEof, eofInstr.regA)
|
||||||
|
c.optimizeJumps(result)
|
||||||
s.position = c.prc.maxSlots
|
s.position = c.prc.maxSlots
|
||||||
|
#if s.name.s == "temp":
|
||||||
|
# c.echoCode
|
||||||
c.prc = oldPrc
|
c.prc = oldPrc
|
||||||
else:
|
else:
|
||||||
c.prc.maxSlots = s.position
|
c.prc.maxSlots = s.position
|
||||||
|
|
|
||||||
2
koch.nim
2
koch.nim
|
|
@ -271,7 +271,7 @@ proc tests(args: string) =
|
||||||
|
|
||||||
proc temp(args: string) =
|
proc temp(args: string) =
|
||||||
var output = "compiler" / "nimrod".exe
|
var output = "compiler" / "nimrod".exe
|
||||||
var finalDest = "bin" / "nimrod".exe
|
var finalDest = "bin" / "nimrod_temp".exe
|
||||||
exec("nimrod c compiler" / "nimrod")
|
exec("nimrod c compiler" / "nimrod")
|
||||||
copyExe(output, finalDest)
|
copyExe(output, finalDest)
|
||||||
if args.len > 0: exec(finalDest & " " & args)
|
if args.len > 0: exec(finalDest & " " & args)
|
||||||
|
|
|
||||||
4
todo.txt
4
todo.txt
|
|
@ -2,12 +2,10 @@ version 0.9.4
|
||||||
=============
|
=============
|
||||||
|
|
||||||
- new VM:
|
- new VM:
|
||||||
compiling htmlgen (txmlgen) makes the compiler go into an infinite loop
|
- tcntseq fails
|
||||||
tcntseq
|
|
||||||
- new VM requires lambda lifting
|
- new VM requires lambda lifting
|
||||||
- implement overflow checking
|
- implement overflow checking
|
||||||
- implement the FFI
|
- implement the FFI
|
||||||
- test and activate the jump optimizer
|
|
||||||
|
|
||||||
- make 'bind' default for templates and introduce 'mixin'
|
- make 'bind' default for templates and introduce 'mixin'
|
||||||
- special rule for ``[]=``
|
- special rule for ``[]=``
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue