summary refs log tree commit diff stats
path: root/compiler/transf.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/transf.nim')
-rw-r--r--compiler/transf.nim30
1 files changed, 30 insertions, 0 deletions
diff --git a/compiler/transf.nim b/compiler/transf.nim
index a81457b39..206c21c3d 100644
--- a/compiler/transf.nim
+++ b/compiler/transf.nim
@@ -588,6 +588,36 @@ proc dontInlineConstant(orig, cnst: PNode): bool {.inline.} =
   result = orig.kind == nkSym and cnst.kind in {nkCurly, nkPar, nkBracket} and 
       cnst.len != 0
 
+proc commonOptimizations*(c: PSym, n: PNode): PNode =
+  result = n
+  for i in 0 .. < n.safeLen:
+    result.sons[i] = commonOptimizations(c, n.sons[i])
+  var op = getMergeOp(n)
+  if (op != nil) and (op.magic != mNone) and (sonsLen(n) >= 3):
+    result = newNodeIT(nkCall, n.info, n.typ)
+    add(result, n.sons[0])
+    var args = newNode(nkArgList)
+    flattenTreeAux(args, n, op)
+    var j = 0
+    while j < sonsLen(args):
+      var a = args.sons[j]
+      inc(j)
+      if isConstExpr(a):
+        while j < sonsLen(args):
+          let b = args.sons[j]
+          if not isConstExpr(b): break
+          a = evalOp(op.magic, result, a, b, nil)
+          inc(j)
+      add(result, a)
+    if len(result) == 2: result = result[1]
+  else:
+    var cnst = getConstExpr(c, n)
+    # we inline constants if they are not complex constants:
+    if cnst != nil and not dontInlineConstant(n, cnst):
+      result = cnst
+    else:
+      result = n
+
 proc transform(c: PTransf, n: PNode): PTransNode = 
   case n.kind
   of nkSym: