diff options
Diffstat (limited to 'compiler/optimizer.nim')
-rw-r--r-- | compiler/optimizer.nim | 31 |
1 files changed, 17 insertions, 14 deletions
diff --git a/compiler/optimizer.nim b/compiler/optimizer.nim index 744c82ab5..34e8ec80f 100644 --- a/compiler/optimizer.nim +++ b/compiler/optimizer.nim @@ -12,10 +12,12 @@ ## - recognize "all paths lead to 'wasMoved(x)'" import - ast, renderer, idents, intsets + ast, renderer, idents from trees import exprStructuralEquivalent +import std/[strutils, intsets] + const nfMarkForDeletion = nfNone # faster than a lookup table @@ -64,7 +66,7 @@ proc mergeBasicBlockInfo(parent: var BasicBlock; this: BasicBlock) {.inline.} = proc wasMovedTarget(matches: var IntSet; branch: seq[PNode]; moveTarget: PNode): bool = result = false for i in 0..<branch.len: - if exprStructuralEquivalent(branch[i][1].skipAddr, moveTarget, + if exprStructuralEquivalent(branch[i][1].skipHiddenAddr, moveTarget, strictSymEquality = true): result = true matches.incl i @@ -74,7 +76,7 @@ proc intersect(summary: var seq[PNode]; branch: seq[PNode]) = var i = 0 var matches = initIntSet() while i < summary.len: - if wasMovedTarget(matches, branch, summary[i][1].skipAddr): + if wasMovedTarget(matches, branch, summary[i][1].skipHiddenAddr): inc i else: summary.del i @@ -85,7 +87,7 @@ proc intersect(summary: var seq[PNode]; branch: seq[PNode]) = proc invalidateWasMoved(c: var BasicBlock; x: PNode) = var i = 0 while i < c.wasMovedLocs.len: - if exprStructuralEquivalent(c.wasMovedLocs[i][1].skipAddr, x, + if exprStructuralEquivalent(c.wasMovedLocs[i][1].skipHiddenAddr, x, strictSymEquality = true): c.wasMovedLocs.del i else: @@ -94,7 +96,7 @@ proc invalidateWasMoved(c: var BasicBlock; x: PNode) = proc wasMovedDestroyPair(c: var Con; b: var BasicBlock; d: PNode) = var i = 0 while i < b.wasMovedLocs.len: - if exprStructuralEquivalent(b.wasMovedLocs[i][1].skipAddr, d[1].skipAddr, + if exprStructuralEquivalent(b.wasMovedLocs[i][1].skipHiddenAddr, d[1].skipHiddenAddr, strictSymEquality = true): b.wasMovedLocs[i].flags.incl nfMarkForDeletion c.somethingTodo = true @@ -110,16 +112,17 @@ proc analyse(c: var Con; b: var BasicBlock; n: PNode) = var reverse = false if n[0].kind == nkSym: let s = n[0].sym - if s.magic == mWasMoved: + let name = s.name.s.normalize + if name == "=wasmoved": b.wasMovedLocs.add n special = true - elif s.name.s == "=destroy": + elif name == "=destroy": if c.inFinally > 0 and (b.hasReturn or b.hasBreak): discard "cannot optimize away the destructor" else: c.wasMovedDestroyPair b, n special = true - elif s.name.s == "=sink": + elif name == "=sink": reverse = true if not special: @@ -127,11 +130,11 @@ proc analyse(c: var Con; b: var BasicBlock; n: PNode) = for i in 0 ..< n.len: analyse(c, b, n[i]) else: - #[ Test tmatrix.test3: + #[ Test destructor/tmatrix.test3: Prevent this from being elided. We should probably find a better solution... - `=sink`(b, - ( + `=sink`(b, - let blitTmp = b; wasMoved(b); blitTmp + a) @@ -154,7 +157,7 @@ proc analyse(c: var Con; b: var BasicBlock; n: PNode) = nkTypeOfExpr, nkMixinStmt, nkBindStmt: discard "do not follow the construct" - of nkAsgn, nkFastAsgn: + of nkAsgn, nkFastAsgn, nkSinkAsgn: # reverse order, see remark for `=sink`: analyse(c, b, n[1]) analyse(c, b, n[0]) @@ -178,7 +181,7 @@ proc analyse(c: var Con; b: var BasicBlock; n: PNode) = of nkCaseStmt: let isExhaustive = skipTypes(n[0].typ, - abstractVarRange-{tyTypeDesc}).kind notin {tyFloat..tyFloat128, tyString} or + abstractVarRange-{tyTypeDesc}).kind notin {tyFloat..tyFloat128, tyString, tyCstring} or n[^1].kind == nkElse analyse(c, b, n[0]) @@ -276,8 +279,8 @@ proc optimize*(n: PNode): PNode = Now assume 'use' raises, then we shouldn't do the 'wasMoved(s)' ]# - var c: Con - var b: BasicBlock + var c: Con = Con() + var b: BasicBlock = default(BasicBlock) analyse(c, b, n) if c.somethingTodo: result = shallowCopy(n) |