optimize sinks even when in a loop
This commit is contained in:
parent
78513a9204
commit
37a98c77f3
1 changed files with 12 additions and 23 deletions
|
|
@ -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,16 +542,10 @@ 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, arg.typ, arg.info)
|
||||||
let tmp = c.getTemp(s.parent[], 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
|
s.final.add newTree(nkStmtList, c.genDestroy(tmp), c.genWasMoved(tmp))
|
||||||
s.parent[].final.add newTree(nkStmtList, c.genDestroy(tmp), c.genWasMoved(tmp))
|
|
||||||
else:
|
|
||||||
let tmp = c.getTemp(s, arg.typ, arg.info)
|
|
||||||
result.add c.genSink(s, tmp, arg, isDecl = true)
|
|
||||||
result.add tmp
|
|
||||||
s.final.add newTree(nkStmtList, c.genDestroy(tmp), c.genWasMoved(tmp))
|
|
||||||
else:
|
else:
|
||||||
result = arg
|
result = arg
|
||||||
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue