mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-31 18:32:11 +00:00
codegen produces better code for complex assignments
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
#
|
||||
#
|
||||
# c2nim - C to Nimrod source converter
|
||||
# (c) Copyright 2012 Andreas Rumpf
|
||||
# (c) Copyright 2013 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
@@ -15,7 +15,7 @@ const
|
||||
Version = NimrodVersion
|
||||
Usage = """
|
||||
c2nim - C to Nimrod source converter
|
||||
(c) 2012 Andreas Rumpf
|
||||
(c) 2013 Andreas Rumpf
|
||||
Usage: c2nim [options] inputfile [options]
|
||||
Options:
|
||||
-o, --out:FILE set output filename
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#
|
||||
#
|
||||
# The Nimrod Compiler
|
||||
# (c) Copyright 2012 Andreas Rumpf
|
||||
# (c) Copyright 2013 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
|
||||
@@ -195,6 +195,46 @@ proc genRefAssign(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||
addrLoc(dest), rdLoc(src))
|
||||
if needToKeepAlive in flags: keepAlive(p, dest)
|
||||
|
||||
proc asgnComplexity(n: PNode): int =
|
||||
if n != nil:
|
||||
case n.kind
|
||||
of nkSym: result = 1
|
||||
of nkRecCase:
|
||||
# 'case objects' are too difficult to inline their assignment operation:
|
||||
result = 100
|
||||
of nkRecList:
|
||||
for t in items(n):
|
||||
result += asgnComplexity(t)
|
||||
else: nil
|
||||
|
||||
proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags)
|
||||
|
||||
proc optAsgnLoc(a: TLoc, t: PType, field: PRope): TLoc =
|
||||
result.k = locField
|
||||
result.s = a.s
|
||||
result.t = t
|
||||
result.r = rdLoc(a).con(".").con(field)
|
||||
result.heapRoot = a.heapRoot
|
||||
|
||||
proc genOptAsgnTuple(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||
for i in 0 .. <dest.t.len:
|
||||
let t = dest.t.sons[i]
|
||||
let field = ropef("Field$1", i.toRope)
|
||||
genAssignment(p, optAsgnLoc(dest, t, field),
|
||||
optAsgnLoc(src, t, field), flags)
|
||||
|
||||
proc genOptAsgnObject(p: BProc, dest, src: TLoc, flags: TAssignmentFlags,
|
||||
t: PNode) =
|
||||
if t == nil: return
|
||||
case t.kind
|
||||
of nkSym:
|
||||
let field = t.sym
|
||||
genAssignment(p, optAsgnLoc(dest, field.typ, field.loc.r),
|
||||
optAsgnLoc(src, field.typ, field.loc.r), flags)
|
||||
of nkRecList:
|
||||
for child in items(t): genOptAsgnObject(p, dest, src, flags, child)
|
||||
else: nil
|
||||
|
||||
proc genGenericAsgn(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||
# Consider:
|
||||
# type TMyFastString {.shallow.} = string
|
||||
@@ -251,10 +291,29 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
|
||||
linefmt(p, cpsStmts, "#unsureAsgnRef((void**) $1, #copyString($2));$n",
|
||||
addrLoc(dest), rdLoc(src))
|
||||
if needToKeepAlive in flags: keepAlive(p, dest)
|
||||
of tyTuple, tyObject, tyProc:
|
||||
of tyProc:
|
||||
if needsComplexAssignment(dest.t):
|
||||
# optimize closure assignment:
|
||||
let a = optAsgnLoc(dest, dest.t, "ClEnv".toRope)
|
||||
let b = optAsgnLoc(src, dest.t, "ClEnv".toRope)
|
||||
genRefAssign(p, a, b, flags)
|
||||
linefmt(p, cpsStmts, "$1.ClPrc = $2.ClPrc;$n", rdLoc(dest), rdLoc(src))
|
||||
else:
|
||||
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
|
||||
of tyTuple:
|
||||
if needsComplexAssignment(dest.t):
|
||||
if dest.t.len <= 4: genOptAsgnTuple(p, dest, src, flags)
|
||||
else: genGenericAsgn(p, dest, src, flags)
|
||||
else:
|
||||
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
|
||||
of tyObject:
|
||||
# XXX: check for subtyping?
|
||||
if needsComplexAssignment(dest.t):
|
||||
genGenericAsgn(p, dest, src, flags)
|
||||
if asgnComplexity(dest.t.n) <= 4:
|
||||
discard getTypeDesc(p.module, dest.t)
|
||||
genOptAsgnObject(p, dest, src, flags, dest.t.n)
|
||||
else:
|
||||
genGenericAsgn(p, dest, src, flags)
|
||||
else:
|
||||
linefmt(p, cpsStmts, "$1 = $2;$n", rdLoc(dest), rdLoc(src))
|
||||
of tyArray, tyArrayConstr:
|
||||
|
||||
9
todo.txt
9
todo.txt
@@ -4,16 +4,11 @@ version 0.9.2
|
||||
- FFI:
|
||||
* test libffi on windows
|
||||
* test: times.format with the FFI
|
||||
- GC: implement simple generational GC
|
||||
* first version: mark black in write barrier
|
||||
* second version: introduce fake roots instead of marking black
|
||||
* third version: find some clever heuristic which is preferable
|
||||
- acyclic vs prunable; introduce GC hints
|
||||
- implement constructors + full 'not nil' checking
|
||||
- CGEN: ``restrict`` pragma + backend support; computed goto support
|
||||
- fix:
|
||||
- 'result' is not properly cleaned for NRVO
|
||||
- optimize genericAssign in the code generator
|
||||
- document NimMain and check whether it works for threading
|
||||
|
||||
|
||||
@@ -94,6 +89,10 @@ Not essential for 1.0.0
|
||||
- implement marker procs for message passing
|
||||
- activate more thread tests
|
||||
- implement closures that support nesting of *procs* > 1
|
||||
- GC: implement simple generational GC
|
||||
* first version: mark black in write barrier
|
||||
* second version: introduce fake roots instead of marking black
|
||||
* third version: find some clever heuristic which is preferable
|
||||
|
||||
|
||||
GC
|
||||
|
||||
Reference in New Issue
Block a user