From 8f86e0f86bdbfb124c76288a498cdabd3ef48c50 Mon Sep 17 00:00:00 2001 From: Matthew Baulch Date: Sat, 27 Aug 2016 19:01:59 +1000 Subject: [PATCH 1/7] Rewrite cyclicTree. Performance improved by approx 50%. --- compiler/trees.nim | 30 ++++++++++-------------------- 1 file changed, 10 insertions(+), 20 deletions(-) diff --git a/compiler/trees.nim b/compiler/trees.nim index fdd88c348d..dde7b5367a 100644 --- a/compiler/trees.nim +++ b/compiler/trees.nim @@ -12,29 +12,19 @@ import ast, astalgo, lexer, msgs, strutils, wordrecg -proc hasSon(father, son: PNode): bool = - for i in countup(0, sonsLen(father) - 1): - if father.sons[i] == son: - return true - result = false - -proc cyclicTreeAux(n, s: PNode): bool = - if n == nil: - return false - if hasSon(s, n): - return true - var m = sonsLen(s) - addSon(s, n) +proc cyclicTreeAux(n: PNode, visited: var seq[PNode]): bool = + if n == nil: return + for v in visited: + if v == n: return true if not (n.kind in {nkEmpty..nkNilLit}): - for i in countup(0, sonsLen(n) - 1): - if cyclicTreeAux(n.sons[i], s): - return true - result = false - delSon(s, m) + visited.add(n) + for nSon in n.sons: + if cyclicTreeAux(nSon, visited): return true + discard visited.pop() proc cyclicTree*(n: PNode): bool = - var s = newNodeI(nkEmpty, n.info) - result = cyclicTreeAux(n, s) + var visited: seq[PNode] = @[] + cyclicTreeAux(n, visited) proc exprStructuralEquivalent*(a, b: PNode; strictSymEquality=false): bool = result = false From 701109e8c193db12a4fd320b214badfa08383fdd Mon Sep 17 00:00:00 2001 From: Matthew Baulch Date: Sat, 27 Aug 2016 19:05:26 +1000 Subject: [PATCH 2/7] Remove (unused) swapOperands proc. --- compiler/trees.nim | 5 ----- 1 file changed, 5 deletions(-) diff --git a/compiler/trees.nim b/compiler/trees.nim index dde7b5367a..15e0259d6e 100644 --- a/compiler/trees.nim +++ b/compiler/trees.nim @@ -135,11 +135,6 @@ proc flattenTree*(root: PNode, op: TMagic): PNode = addSon(result, copyNode(root.sons[0])) flattenTreeAux(result, root, op) -proc swapOperands*(op: PNode) = - var tmp = op.sons[1] - op.sons[1] = op.sons[2] - op.sons[2] = tmp - proc isRange*(n: PNode): bool {.inline.} = if n.kind in nkCallKinds: if n[0].kind == nkIdent and n[0].ident.id == ord(wDotDot) or From 5e0a062a9094c447cf9d102de92f1154eb6bc755 Mon Sep 17 00:00:00 2001 From: Matthew Baulch Date: Sat, 27 Aug 2016 19:38:23 +1000 Subject: [PATCH 3/7] Remove (unused) flattenTree proc. --- compiler/trees.nim | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/compiler/trees.nim b/compiler/trees.nim index 15e0259d6e..832b206d9f 100644 --- a/compiler/trees.nim +++ b/compiler/trees.nim @@ -121,20 +121,6 @@ proc isDeepConstExpr*(n: PNode): bool = result = true else: discard -proc flattenTreeAux(d, a: PNode, op: TMagic) = - if (getMagic(a) == op): # a is a "leaf", so add it: - for i in countup(1, sonsLen(a) - 1): # BUGFIX - flattenTreeAux(d, a.sons[i], op) - else: - addSon(d, copyTree(a)) - -proc flattenTree*(root: PNode, op: TMagic): PNode = - result = copyNode(root) - if getMagic(root) == op: - # BUGFIX: forget to copy prc - addSon(result, copyNode(root.sons[0])) - flattenTreeAux(result, root, op) - proc isRange*(n: PNode): bool {.inline.} = if n.kind in nkCallKinds: if n[0].kind == nkIdent and n[0].ident.id == ord(wDotDot) or From e1a5732838e89a131787c25e2fc89a5097ef65a0 Mon Sep 17 00:00:00 2001 From: Matthew Baulch Date: Sat, 27 Aug 2016 19:40:48 +1000 Subject: [PATCH 4/7] Remove unused procs getProcSym, getOpSym. --- compiler/trees.nim | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/compiler/trees.nim b/compiler/trees.nim index 832b206d9f..ece102c13b 100644 --- a/compiler/trees.nim +++ b/compiler/trees.nim @@ -74,17 +74,6 @@ proc sameTree*(a, b: PNode): bool = if not sameTree(a.sons[i], b.sons[i]): return result = true -proc getProcSym*(call: PNode): PSym = - result = call.sons[0].sym - -proc getOpSym*(op: PNode): PSym = - if op.kind notin {nkCall, nkHiddenCallConv, nkCommand, nkCallStrLit}: - result = nil - else: - if sonsLen(op) <= 0: internalError(op.info, "getOpSym") - elif op.sons[0].kind == nkSym: result = op.sons[0].sym - else: result = nil - proc getMagic*(op: PNode): TMagic = case op.kind of nkCallKinds: From ef0d1561d4f1020ef1f5b94f5cc62c0709638add Mon Sep 17 00:00:00 2001 From: Matthew Baulch Date: Sat, 27 Aug 2016 19:59:40 +1000 Subject: [PATCH 5/7] Remove useless/misleading comment. flattenStmts not only for patterns. --- compiler/trees.nim | 1 - 1 file changed, 1 deletion(-) diff --git a/compiler/trees.nim b/compiler/trees.nim index ece102c13b..c32782a509 100644 --- a/compiler/trees.nim +++ b/compiler/trees.nim @@ -128,7 +128,6 @@ proc unnestStmts(n, result: PNode) = result.add(n) proc flattenStmts*(n: PNode): PNode = - ## flattens a nested statement list; used for pattern matching result = newNodeI(nkStmtList, n.info) unnestStmts(n, result) if result.len == 1: From c23a3e1f840285c8e76f0cad379fc52ac59188f9 Mon Sep 17 00:00:00 2001 From: Matthew Baulch Date: Sat, 27 Aug 2016 20:07:10 +1000 Subject: [PATCH 6/7] Remove unnecessary result initialisations. --- compiler/trees.nim | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/compiler/trees.nim b/compiler/trees.nim index c32782a509..f2d417f72e 100644 --- a/compiler/trees.nim +++ b/compiler/trees.nim @@ -27,7 +27,6 @@ proc cyclicTree*(n: PNode): bool = cyclicTreeAux(n, visited) proc exprStructuralEquivalent*(a, b: PNode; strictSymEquality=false): bool = - result = false if a == b: result = true elif (a != nil) and (b != nil) and (a.kind == b.kind): @@ -51,7 +50,6 @@ proc exprStructuralEquivalent*(a, b: PNode; strictSymEquality=false): bool = result = true proc sameTree*(a, b: PNode): bool = - result = false if a == b: result = true elif a != nil and b != nil and a.kind == b.kind: @@ -83,6 +81,7 @@ proc getMagic*(op: PNode): TMagic = else: result = mNone proc isConstExpr*(n: PNode): bool = + const constKinds = {nkCharLit..nkInt64Lit, nkStrLit..nkTripleStrLit, nkFloatLit..nkFloat64Lit, nkNilLit} result = (n.kind in {nkCharLit..nkInt64Lit, nkStrLit..nkTripleStrLit, nkFloatLit..nkFloat64Lit, nkNilLit}) or (nfAllConst in n.flags) From defc7bbded2b38a45c0602f97e44fe702f8c5f0b Mon Sep 17 00:00:00 2001 From: Matthew Baulch Date: Sat, 27 Aug 2016 21:09:05 +1000 Subject: [PATCH 7/7] Cleanup and fix isConstExpr to return true for all atomic node types. --- compiler/trees.nim | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/compiler/trees.nim b/compiler/trees.nim index f2d417f72e..a629b38341 100644 --- a/compiler/trees.nim +++ b/compiler/trees.nim @@ -81,10 +81,8 @@ proc getMagic*(op: PNode): TMagic = else: result = mNone proc isConstExpr*(n: PNode): bool = - const constKinds = {nkCharLit..nkInt64Lit, nkStrLit..nkTripleStrLit, nkFloatLit..nkFloat64Lit, nkNilLit} - result = (n.kind in - {nkCharLit..nkInt64Lit, nkStrLit..nkTripleStrLit, - nkFloatLit..nkFloat64Lit, nkNilLit}) or (nfAllConst in n.flags) + const atomKinds = {nkCharLit..nkNilLit} # Char, Int, UInt, Str, Float and Nil literals + n.kind in atomKinds or nfAllConst in n.flags proc isCaseObj*(n: PNode): bool = if n.kind == nkRecCase: return true