optimize sinks even when in a loop

This commit is contained in:
Araq 2020-07-10 09:51:43 +02:00 • committed by Andreas Rumpf
commit 37a98c77f3

View file

@ -46,7 +46,6 @@ type
owner: PSym owner: PSym
g: ControlFlowGraph g: ControlFlowGraph
jumpTargets: IntSet jumpTargets: IntSet
destroys, topLevelVars: PNode
graph: ModuleGraph graph: ModuleGraph
emptyNode: PNode emptyNode: PNode
otherRead: PNode otherRead: PNode
@ -59,6 +58,13 @@ type
consumed consumed
sinkArg sinkArg
const toDebug {.strdefine.} = ""
template dbg(body) =
when toDebug.len > 0:
if c.owner.name.s == toDebug or toDebug == "always":
body
proc getTemp(c: var Con; s: var Scope; typ: PType; info: TLineInfo): PNode = proc getTemp(c: var Con; s: var Scope; typ: PType; info: TLineInfo): PNode =
let sym = newSym(skTemp, getIdent(c.graph.cache, ":tmpD"), c.owner, info) let sym = newSym(skTemp, getIdent(c.graph.cache, ":tmpD"), c.owner, info)
sym.typ = typ sym.typ = typ
@ -89,7 +95,6 @@ proc optimize(s: var Scope) =
Now assume 'echo' raises, then we shouldn't do the 'wasMoved(s)' Now assume 'echo' raises, then we shouldn't do the 'wasMoved(s)'
]# ]#
# XXX: Investigate how to really insert 'wasMoved()' calls!
proc findCorrespondingDestroy(final: seq[PNode]; moved: PNode): int = proc findCorrespondingDestroy(final: seq[PNode]; moved: PNode): int =
# remember that it's destroy(addr(x)) # remember that it's destroy(addr(x))
for i in 0 ..< final.len: for i in 0 ..< final.len:
@ -169,14 +174,6 @@ proc toTree(c: var Con; s: var Scope; ret: PNode; flags: set[ToTreeFlag]): PNode
if r != nil: if r != nil:
result.add r result.add r
const toDebug {.strdefine.} = ""
template dbg(body) =
when toDebug.len > 0:
if c.owner.name.s == toDebug or toDebug == "always":
body
proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode): PNode proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode): PNode
proc moveOrCopy(dest, ri: PNode; c: var Con; s: var Scope; isDecl = false): PNode proc moveOrCopy(dest, ri: PNode; c: var Con; s: var Scope; isDecl = false): PNode
@ -391,7 +388,7 @@ proc isNoInit(dest: PNode): bool {.inline.} =
result = dest.kind == nkSym and sfNoInit in dest.sym.flags result = dest.kind == nkSym and sfNoInit in dest.sym.flags
proc genSink(c: var Con; s: var Scope; dest, ri: PNode, isDecl = false): PNode = proc genSink(c: var Con; s: var Scope; dest, ri: PNode, isDecl = false): PNode =
if isUnpackedTuple(dest) or (isDecl and c.inLoop <= 0) or if isUnpackedTuple(dest) or isDecl or
(isAnalysableFieldAccess(dest, c.owner) and isFirstWrite(dest, c)) or (isAnalysableFieldAccess(dest, c.owner) and isFirstWrite(dest, c)) or
isNoInit(dest): isNoInit(dest):
# optimize sink call into a bitwise memcopy # optimize sink call into a bitwise memcopy
@ -545,12 +542,6 @@ proc ensureDestruction(arg: PNode; c: var Con; s: var Scope): PNode =
# This was already done in the sink parameter handling logic. # This was already done in the sink parameter handling logic.
result = newNodeIT(nkStmtListExpr, arg.info, arg.typ) result = newNodeIT(nkStmtListExpr, arg.info, arg.typ)
if s.parent != nil:
let tmp = c.getTemp(s.parent[], arg.typ, arg.info)
result.add c.genSink(s, tmp, arg, isDecl = true)
result.add tmp
s.parent[].final.add newTree(nkStmtList, c.genDestroy(tmp), c.genWasMoved(tmp))
else:
let tmp = c.getTemp(s, arg.typ, arg.info) let tmp = c.getTemp(s, arg.typ, arg.info)
result.add c.genSink(s, tmp, arg, isDecl = true) result.add c.genSink(s, tmp, arg, isDecl = true)
result.add tmp result.add tmp
@ -1103,8 +1094,6 @@ proc injectDestructorCalls*(g: ModuleGraph; owner: PSym; n: PNode): PNode =
return n return n
var c: Con var c: Con
c.owner = owner c.owner = owner
c.destroys = newNodeI(nkStmtList, n.info)
c.topLevelVars = newNodeI(nkVarSection, n.info)
c.graph = g c.graph = g
c.emptyNode = newNodeI(nkEmpty, n.info) c.emptyNode = newNodeI(nkEmpty, n.info)
let cfg = constructCfg(owner, n) let cfg = constructCfg(owner, n)