move moves
This commit is contained in:
parent
8ff18c0fb9
commit
4b31d7bb83
2 changed files with 161 additions and 63 deletions
|
|
@ -410,7 +410,10 @@ proc passCopyToSink(n: PNode; c: var Con): PNode =
|
||||||
result.add tmp
|
result.add tmp
|
||||||
|
|
||||||
proc pArg(arg: PNode; c: var Con; isSink: bool): PNode =
|
proc pArg(arg: PNode; c: var Con; isSink: bool): PNode =
|
||||||
if isSink:
|
if arg.typ == nil:
|
||||||
|
# typ is nil if we are in if/case branch with noreturn
|
||||||
|
result = copyTree(arg)
|
||||||
|
elif isSink:
|
||||||
if arg.kind in nkCallKinds:
|
if arg.kind in nkCallKinds:
|
||||||
# recurse but skip the call expression in order to prevent
|
# recurse but skip the call expression in order to prevent
|
||||||
# destructor injections: Rule 5.1 is different from rule 5.4!
|
# destructor injections: Rule 5.1 is different from rule 5.4!
|
||||||
|
|
@ -420,7 +423,7 @@ proc pArg(arg: PNode; c: var Con; isSink: bool): PNode =
|
||||||
result.add arg[0]
|
result.add arg[0]
|
||||||
for i in 1..<arg.len:
|
for i in 1..<arg.len:
|
||||||
result.add pArg(arg[i], c, i < L and parameters[i].kind == tySink)
|
result.add pArg(arg[i], c, i < L and parameters[i].kind == tySink)
|
||||||
elif arg.kind in {nkObjConstr, nkCharLit..nkFloat128Lit}:
|
elif arg.kind in {nkObjConstr, nkTupleConstr, nkCharLit..nkFloat128Lit}:
|
||||||
discard "object construction to sink parameter: nothing to do"
|
discard "object construction to sink parameter: nothing to do"
|
||||||
result = arg
|
result = arg
|
||||||
elif arg.kind == nkSym and arg.sym.kind in InterestingSyms and isLastRead(arg, c):
|
elif arg.kind == nkSym and arg.sym.kind in InterestingSyms and isLastRead(arg, c):
|
||||||
|
|
@ -431,6 +434,37 @@ proc pArg(arg: PNode; c: var Con; isSink: bool): PNode =
|
||||||
elif arg.kind == nkSym and isSinkParam(arg.sym):
|
elif arg.kind == nkSym and isSinkParam(arg.sym):
|
||||||
# mark the sink parameter as used:
|
# mark the sink parameter as used:
|
||||||
result = destructiveMoveSink(arg, c)
|
result = destructiveMoveSink(arg, c)
|
||||||
|
elif arg.kind in {nkStmtListExpr, nkBlockExpr, nkBlockStmt}:
|
||||||
|
result = copyNode(arg)
|
||||||
|
for i in 0..arg.len-2:
|
||||||
|
result.add p(arg[i], c)
|
||||||
|
result.add pArg(arg[^1], c, isSink)
|
||||||
|
elif arg.kind in {nkIfExpr, nkIfStmt}:
|
||||||
|
result = copyNode(arg)
|
||||||
|
for i in 0..<arg.len:
|
||||||
|
var branch = copyNode(arg[i])
|
||||||
|
if arg[i].kind in {nkElifBranch, nkElifExpr}:
|
||||||
|
branch.add p(arg[i][0], c)
|
||||||
|
branch.add pArg(arg[i][1], c, isSink)
|
||||||
|
else:
|
||||||
|
branch.add pArg(arg[i][0], c, isSink)
|
||||||
|
result.add branch
|
||||||
|
elif arg.kind == nkCaseStmt:
|
||||||
|
result = copyNode(arg)
|
||||||
|
result.add p(arg[0], c)
|
||||||
|
for i in 1..<arg.len:
|
||||||
|
var branch: PNode
|
||||||
|
if arg[i].kind == nkOfbranch:
|
||||||
|
branch = arg[i] # of branch conditions are constants
|
||||||
|
branch[^1] = pArg(arg[i][^1], c, isSink)
|
||||||
|
elif arg[i].kind in {nkElifBranch, nkElifExpr}:
|
||||||
|
branch = copyNode(arg[i])
|
||||||
|
branch.add p(arg[i][0], c)
|
||||||
|
branch.add pArg(arg[i][1], c, isSink)
|
||||||
|
else:
|
||||||
|
branch = copyNode(arg[i])
|
||||||
|
branch.add pArg(arg[i][0], c, isSink)
|
||||||
|
result.add branch
|
||||||
else:
|
else:
|
||||||
# an object that is not temporary but passed to a 'sink' parameter
|
# an object that is not temporary but passed to a 'sink' parameter
|
||||||
# results in a copy.
|
# results in a copy.
|
||||||
|
|
@ -439,6 +473,10 @@ proc pArg(arg: PNode; c: var Con; isSink: bool): PNode =
|
||||||
result = p(arg, c)
|
result = p(arg, c)
|
||||||
|
|
||||||
proc moveOrCopy(dest, ri: PNode; c: var Con): PNode =
|
proc moveOrCopy(dest, ri: PNode; c: var Con): PNode =
|
||||||
|
if ri.typ == nil:
|
||||||
|
# typ is nil if we are in if/case branch with noreturn
|
||||||
|
result = copyTree(ri)
|
||||||
|
else:
|
||||||
case ri.kind
|
case ri.kind
|
||||||
of nkCallKinds:
|
of nkCallKinds:
|
||||||
result = genSink(c, dest.typ, dest, ri)
|
result = genSink(c, dest.typ, dest, ri)
|
||||||
|
|
@ -463,6 +501,38 @@ proc moveOrCopy(dest, ri: PNode; c: var Con): PNode =
|
||||||
for i in 0..ri.len-2:
|
for i in 0..ri.len-2:
|
||||||
result.add p(ri[i], c)
|
result.add p(ri[i], c)
|
||||||
result.add moveOrCopy(dest, ri[^1], c)
|
result.add moveOrCopy(dest, ri[^1], c)
|
||||||
|
of nkBlockExpr, nkBlockStmt:
|
||||||
|
result = newNodeI(nkBlockStmt, ri.info)
|
||||||
|
result.add ri[0] ## add label
|
||||||
|
for i in 1..ri.len-2:
|
||||||
|
result.add p(ri[i], c)
|
||||||
|
result.add moveOrCopy(dest, ri[^1], c)
|
||||||
|
of nkIfExpr, nkIfStmt:
|
||||||
|
result = newNodeI(nkIfStmt, ri.info)
|
||||||
|
for i in 0..<ri.len:
|
||||||
|
var branch = copyNode(ri[i])
|
||||||
|
if ri[i].kind in {nkElifBranch, nkElifExpr}:
|
||||||
|
branch.add p(ri[i][0], c)
|
||||||
|
branch.add moveOrCopy(dest, ri[i][1], c)
|
||||||
|
else:
|
||||||
|
branch.add moveOrCopy(dest, ri[i][0], c)
|
||||||
|
result.add branch
|
||||||
|
of nkCaseStmt:
|
||||||
|
result = newNodeI(nkCaseStmt, ri.info)
|
||||||
|
result.add p(ri[0], c)
|
||||||
|
for i in 1..<ri.len:
|
||||||
|
var branch: PNode
|
||||||
|
if ri[i].kind == nkOfbranch:
|
||||||
|
branch = ri[i] # of branch conditions are constants
|
||||||
|
branch[^1] = moveOrCopy(dest, ri[i][^1], c)
|
||||||
|
elif ri[i].kind in {nkElifBranch, nkElifExpr}:
|
||||||
|
branch = copyNode(ri[i])
|
||||||
|
branch.add p(ri[i][0], c)
|
||||||
|
branch.add moveOrCopy(dest, ri[i][1], c)
|
||||||
|
else:
|
||||||
|
branch = copyNode(ri[i])
|
||||||
|
branch.add moveOrCopy(dest, ri[i][0], c)
|
||||||
|
result.add branch
|
||||||
of nkObjConstr:
|
of nkObjConstr:
|
||||||
result = genSink(c, dest.typ, dest, ri)
|
result = genSink(c, dest.typ, dest, ri)
|
||||||
let ri2 = copyTree(ri)
|
let ri2 = copyTree(ri)
|
||||||
|
|
@ -561,7 +631,7 @@ proc p(n: PNode; c: var Con): PNode =
|
||||||
recurse(n, result)
|
recurse(n, result)
|
||||||
|
|
||||||
proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode =
|
proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode =
|
||||||
when false: # defined(nimDebugDestroys):
|
when true: # defined(nimDebugDestroys):
|
||||||
echo "injecting into ", n
|
echo "injecting into ", n
|
||||||
var c: Con
|
var c: Con
|
||||||
c.owner = owner
|
c.owner = owner
|
||||||
|
|
@ -597,8 +667,7 @@ proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode =
|
||||||
else:
|
else:
|
||||||
result.add body
|
result.add body
|
||||||
|
|
||||||
when defined(nimDebugDestroys):
|
when true:
|
||||||
if true:
|
|
||||||
echo "------------------------------------"
|
echo "------------------------------------"
|
||||||
echo owner.name.s, " transformed to: "
|
echo owner.name.s, " transformed to: "
|
||||||
echo result
|
echo result
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,14 @@ proc myfunc(x, y: int): (MySeqNonCopyable, MySeqNonCopyable) =
|
||||||
|
|
||||||
proc myfunc2(x, y: int): tuple[a: MySeqNonCopyable, b:int, c:MySeqNonCopyable] =
|
proc myfunc2(x, y: int): tuple[a: MySeqNonCopyable, b:int, c:MySeqNonCopyable] =
|
||||||
var cc = newMySeq(y, 5.0)
|
var cc = newMySeq(y, 5.0)
|
||||||
(a: newMySeq(x, 1.0), b:0, c: cc)
|
(a: case x:
|
||||||
|
of 1:
|
||||||
|
let (z1, z2) = myfunc(x,y)
|
||||||
|
z2
|
||||||
|
elif x > 5: raise newException(ValueError, "new error")
|
||||||
|
else: newMySeq(x, 1.0),
|
||||||
|
b:0,
|
||||||
|
c: if y > 0: move(cc) else: newMySeq(1, 3.0))
|
||||||
|
|
||||||
let (seq1, seq2) = myfunc(2, 3)
|
let (seq1, seq2) = myfunc(2, 3)
|
||||||
doAssert seq1.len == 2
|
doAssert seq1.len == 2
|
||||||
|
|
@ -123,3 +130,25 @@ doAssert seq3[0] == 1.0
|
||||||
|
|
||||||
var seq4, seq5: MySeqNonCopyable
|
var seq4, seq5: MySeqNonCopyable
|
||||||
(seq4, i, seq5) = myfunc2(2, 3)
|
(seq4, i, seq5) = myfunc2(2, 3)
|
||||||
|
|
||||||
|
seq4 = block:
|
||||||
|
var tmp = newMySeq(4, 1.0)
|
||||||
|
tmp[0] = 3.0
|
||||||
|
tmp
|
||||||
|
|
||||||
|
doAssert seq4[0] == 3.0
|
||||||
|
|
||||||
|
import macros
|
||||||
|
|
||||||
|
seq4 =
|
||||||
|
if i > 0: newMySeq(2, 5.0)
|
||||||
|
elif i < -100: raise newException(ValueError, "Parse Error")
|
||||||
|
else: newMySeq(2, 3.0)
|
||||||
|
|
||||||
|
seq4 =
|
||||||
|
case (char) i:
|
||||||
|
of 'A', {'W'..'Z'}: newMySeq(2, 5.0)
|
||||||
|
of 'B': quit(-1)
|
||||||
|
else:
|
||||||
|
let (x1, x2, x3) = myfunc2(2, 3)
|
||||||
|
x3
|
||||||
Loading…
Add table
Add a link
Reference in a new issue