Part-to-whole optimization (#16775)
This commit is contained in:
parent
c17cad0992
commit
57d5c1465a
2 changed files with 62 additions and 16 deletions
|
|
@ -21,16 +21,6 @@ import
|
||||||
|
|
||||||
from trees import exprStructuralEquivalent, getRoot
|
from trees import exprStructuralEquivalent, getRoot
|
||||||
|
|
||||||
type
|
|
||||||
Scope = object # well we do scope-based memory management. \
|
|
||||||
# a scope is comparable to an nkStmtListExpr like
|
|
||||||
# (try: statements; dest = y(); finally: destructors(); dest)
|
|
||||||
vars: seq[PSym]
|
|
||||||
wasMoved: seq[PNode]
|
|
||||||
final: seq[PNode] # finally section
|
|
||||||
needsTry: bool
|
|
||||||
parent: ptr Scope
|
|
||||||
|
|
||||||
type
|
type
|
||||||
Con = object
|
Con = object
|
||||||
owner: PSym
|
owner: PSym
|
||||||
|
|
@ -42,6 +32,15 @@ type
|
||||||
uninitComputed: bool
|
uninitComputed: bool
|
||||||
idgen: IdGenerator
|
idgen: IdGenerator
|
||||||
|
|
||||||
|
Scope = object # we do scope-based memory management.
|
||||||
|
# a scope is comparable to an nkStmtListExpr like
|
||||||
|
# (try: statements; dest = y(); finally: destructors(); dest)
|
||||||
|
vars: seq[PSym]
|
||||||
|
wasMoved: seq[PNode]
|
||||||
|
final: seq[PNode] # finally section
|
||||||
|
needsTry: bool
|
||||||
|
parent: ptr Scope
|
||||||
|
|
||||||
ProcessMode = enum
|
ProcessMode = enum
|
||||||
normal
|
normal
|
||||||
consumed
|
consumed
|
||||||
|
|
@ -1006,11 +1005,13 @@ proc moveOrCopy(dest, ri: PNode; c: var Con; s: var Scope, isDecl = false): PNod
|
||||||
if isUnpackedTuple(ri[0]):
|
if isUnpackedTuple(ri[0]):
|
||||||
# unpacking of tuple: take over the elements
|
# unpacking of tuple: take over the elements
|
||||||
result = c.genSink(dest, p(ri, c, s, consumed), isDecl)
|
result = c.genSink(dest, p(ri, c, s, consumed), isDecl)
|
||||||
elif isAnalysableFieldAccess(ri, c.owner) and isLastRead(ri, c) and
|
elif isAnalysableFieldAccess(ri, c.owner) and isLastRead(ri, c):
|
||||||
not aliases(dest, ri):
|
if not aliases(dest, ri):
|
||||||
# Rule 3: `=sink`(x, z); wasMoved(z)
|
# Rule 3: `=sink`(x, z); wasMoved(z)
|
||||||
var snk = c.genSink(dest, ri, isDecl)
|
var snk = c.genSink(dest, ri, isDecl)
|
||||||
result = newTree(nkStmtList, snk, c.genWasMoved(ri))
|
result = newTree(nkStmtList, snk, c.genWasMoved(ri))
|
||||||
|
else:
|
||||||
|
result = c.genSink(dest, destructiveMoveVar(ri, c, s), isDecl)
|
||||||
else:
|
else:
|
||||||
result = c.genCopy(dest, ri)
|
result = c.genCopy(dest, ri)
|
||||||
result.add p(ri, c, s, consumed)
|
result.add p(ri, c, s, consumed)
|
||||||
|
|
|
||||||
|
|
@ -92,6 +92,12 @@ copy
|
||||||
destroy
|
destroy
|
||||||
destroy
|
destroy
|
||||||
destroy
|
destroy
|
||||||
|
part-to-whole assigment:
|
||||||
|
sink
|
||||||
|
(children: @[])
|
||||||
|
destroy
|
||||||
|
copy
|
||||||
|
destroy
|
||||||
'''
|
'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
@ -578,7 +584,7 @@ let w3 = newWrapper2(-1)
|
||||||
echo $w3[]
|
echo $w3[]
|
||||||
|
|
||||||
|
|
||||||
#---------------------------------------------------------------------
|
#--------------------------------------------------------------------
|
||||||
#self-assignments
|
#self-assignments
|
||||||
|
|
||||||
# Self-assignments that are not statically determinable will get
|
# Self-assignments that are not statically determinable will get
|
||||||
|
|
@ -668,3 +674,42 @@ proc caseNotAConstant =
|
||||||
echo s # @[(f: 2), (f: 2), (f: 3)]
|
echo s # @[(f: 2), (f: 2), (f: 3)]
|
||||||
|
|
||||||
caseNotAConstant()
|
caseNotAConstant()
|
||||||
|
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------
|
||||||
|
echo "part-to-whole assigment:"
|
||||||
|
|
||||||
|
type
|
||||||
|
Tree = object
|
||||||
|
children: seq[Tree]
|
||||||
|
|
||||||
|
TreeDefaultHooks = object
|
||||||
|
children: seq[TreeDefaultHooks]
|
||||||
|
|
||||||
|
proc `=destroy`(x: var Tree) = echo "destroy"
|
||||||
|
proc `=sink`(x: var Tree, y: Tree) = echo "sink"
|
||||||
|
proc `=copy`(x: var Tree, y: Tree) = echo "copy"
|
||||||
|
|
||||||
|
proc partToWholeSeq =
|
||||||
|
var t = Tree(children: @[Tree()])
|
||||||
|
t = t.children[0] # This should be sunk, but with the special transform (tmp = t.children[0]; wasMoved(0); `=sink`(t, tmp))
|
||||||
|
|
||||||
|
var tc = TreeDefaultHooks(children: @[TreeDefaultHooks()])
|
||||||
|
tc = tc.children[0] # Ditto; if this were sunk with the normal transform (`=sink`(t, t.children[0]); wasMoved(t.children[0]))
|
||||||
|
echo tc # then it would crash because t.children[0] does not exist after the call to `=sink`
|
||||||
|
|
||||||
|
partToWholeSeq()
|
||||||
|
|
||||||
|
type List = object
|
||||||
|
next: ref List
|
||||||
|
|
||||||
|
proc `=destroy`(x: var List) = echo "destroy"
|
||||||
|
proc `=sink`(x: var List, y: List) = echo "sink"
|
||||||
|
proc `=copy`(x: var List, y: List) = echo "copy"
|
||||||
|
|
||||||
|
proc partToWholeUnownedRef =
|
||||||
|
var t = List(next: new List)
|
||||||
|
t = t.next[] # Copy because t.next is not an owned ref, and thus t.next[] cannot be moved
|
||||||
|
|
||||||
|
partToWholeUnownedRef()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue