summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorAraq <rumpf_a@web.de>2013-02-14 08:41:48 +0100
committerAraq <rumpf_a@web.de>2013-02-14 08:41:48 +0100
commit1c0c80ef2dba09bb50c470a013f3bdb9391620a7 (patch)
tree66011812d64f1f2f3c933d601ca72d647302c274
parent0f2aa053d9e9bcbe67238c498ed96f27c8d737db (diff)
downloadNim-1c0c80ef2dba09bb50c470a013f3bdb9391620a7.tar.gz
micro optimizations for the evaluation engine
-rwxr-xr-xcompiler/ast.nim10
-rwxr-xr-xcompiler/evals.nim70
-rw-r--r--doc/gc.txt16
-rwxr-xr-xlib/core/macros.nim11
4 files changed, 64 insertions, 43 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim
index 107489094..4fa3617d7 100755
--- a/compiler/ast.nim
+++ b/compiler/ast.nim
@@ -71,20 +71,23 @@ type
     nkDotCall,            # used to temporarily flag a nkCall node; 
                           # this is used
                           # for transforming ``s.len`` to ``len(s)``
+
     nkCommand,            # a call like ``p 2, 4`` without parenthesis
     nkCall,               # a call like p(x, y) or an operation like +(a, b)
     nkCallStrLit,         # a call with a string literal 
                           # x"abc" has two sons: nkIdent, nkRStrLit
                           # x"""abc""" has two sons: nkIdent, nkTripleStrLit
+    nkInfix,              # a call like (a + b)
+    nkPrefix,             # a call like !a
+    nkPostfix,            # something like a! (also used for visibility)
+    nkHiddenCallConv,     # an implicit type conversion via a type converter
+
     nkExprEqExpr,         # a named parameter with equals: ''expr = expr''
     nkExprColonExpr,      # a named parameter with colon: ''expr: expr''
     nkIdentDefs,          # a definition like `a, b: typeDesc = expr`
                           # either typeDesc or expr may be nil; used in
                           # formal parameters, var statements, etc.
     nkVarTuple,           # a ``var (a, b) = expr`` construct
-    nkInfix,              # a call like (a + b)
-    nkPrefix,             # a call like !a
-    nkPostfix,            # something like a! (also used for visibility)
     nkPar,                # syntactic (); may be a tuple constructor
     nkCurly,              # syntactic {}
     nkCurlyExpr,          # an expression like a{i}
@@ -109,7 +112,6 @@ type
     nkHiddenStdConv,      # an implicit standard type conversion
     nkHiddenSubConv,      # an implicit type conversion from a subtype
                           # to a supertype
-    nkHiddenCallConv,     # an implicit type conversion via a type converter
     nkConv,               # a type conversion
     nkCast,               # a type cast
     nkStaticExpr,         # a static expr
diff --git a/compiler/evals.nim b/compiler/evals.nim
index 4b83cb703..c6e0e947f 100755
--- a/compiler/evals.nim
+++ b/compiler/evals.nim
@@ -444,29 +444,35 @@ proc evalArrayAccess(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
       stackTrace(c, n, errIndexOutOfBounds)
   else: stackTrace(c, n, errNilAccess)
   
-proc evalFieldAccess(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode = 
+proc evalFieldAccess(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
   # a real field access; proc calls have already been transformed
   # XXX: field checks!
   result = evalAux(c, n.sons[0], flags)
-  if isSpecial(result): return 
+  if isSpecial(result): return
   var x = result
   if x.kind != nkPar: return raiseCannotEval(c, n.info)
+  # this is performance critical:
   var field = n.sons[1].sym
-  for i in countup(0, sonsLen(x) - 1): 
-    var it = x.sons[i]
-    if it.kind != nkExprColonExpr:
-      # lookup per index:
-      result = x.sons[field.position]
-      if result.kind == nkExprColonExpr: result = result.sons[1]
-      if not aliasNeeded(result, flags): result = copyTree(result)
-      return
-      #InternalError(it.info, "evalFieldAccess")
-    if it.sons[0].sym.name.id == field.name.id: 
-      result = x.sons[i].sons[1]
-      if not aliasNeeded(result, flags): result = copyTree(result)
-      return
-  stackTrace(c, n, errFieldXNotFound, field.name.s)
-  result = emptyNode
+  result = x.sons[field.position]
+  if result.kind == nkExprColonExpr: result = result.sons[1]
+  if not aliasNeeded(result, flags): result = copyTree(result)
+  when false:
+    var field = n.sons[1].sym
+    for i in countup(0, sonsLen(x) - 1): 
+      var it = x.sons[i]
+      if it.kind != nkExprColonExpr:
+        # lookup per index:
+        result = x.sons[field.position]
+        if result.kind == nkExprColonExpr: result = result.sons[1]
+        if not aliasNeeded(result, flags): result = copyTree(result)
+        return
+        #InternalError(it.info, "evalFieldAccess")
+      if it.sons[0].sym.name.id == field.name.id: 
+        result = x.sons[i].sons[1]
+        if not aliasNeeded(result, flags): result = copyTree(result)
+        return
+    stackTrace(c, n, errFieldXNotFound, field.name.s)
+    result = emptyNode
 
 proc evalAsgn(c: PEvalContext, n: PNode): PNode = 
   var a = n.sons[0]
@@ -1341,14 +1347,23 @@ proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
   result = emptyNode
   dec(gNestedEvals)
   if gNestedEvals <= 0: stackTrace(c, n, errTooManyIterations)
-  case n.kind                 # atoms:
-  of nkEmpty: result = n
+  case n.kind
   of nkSym: result = evalSym(c, n, flags)
-  of nkType..nkNilLit: result = copyNode(n) # end of atoms
-  of nkCall, nkHiddenCallConv, nkCommand, nkCallStrLit, nkInfix,
-     nkPrefix, nkPostfix: 
+  of nkType..nkNilLit:
+    # XXX nkStrLit is VERY common in the traces, so we should avoid
+    # the 'copyNode' here. However, for now we cannot do this for unknown
+    # reasons.
+    result = n.copyNode
+  of nkAsgn, nkFastAsgn: result = evalAsgn(c, n)
+  of nkCommand..nkHiddenCallConv:
     result = evalMagicOrCall(c, n)
-  of nkCurly, nkBracket, nkRange: 
+  of nkDotExpr: result = evalFieldAccess(c, n, flags)
+  of nkBracketExpr:
+    result = evalArrayAccess(c, n, flags)
+  of nkDerefExpr, nkHiddenDeref: result = evalDeref(c, n, flags)
+  of nkAddr, nkHiddenAddr: result = evalAddr(c, n, flags)
+  of nkHiddenStdConv, nkHiddenSubConv, nkConv: result = evalConv(c, n)
+  of nkCurly, nkBracket, nkRange:
     # flags need to be passed here for mNAddMultiple :-(
     # XXX this is not correct in every case!
     var a = copyNode(n)
@@ -1370,12 +1385,6 @@ proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
         if isSpecial(result): return 
         a.sons[i] = result
     result = a
-  of nkBracketExpr: result = evalArrayAccess(c, n, flags)
-  of nkDotExpr: result = evalFieldAccess(c, n, flags)
-  of nkDerefExpr, nkHiddenDeref: result = evalDeref(c, n, flags)
-  of nkAddr, nkHiddenAddr: result = evalAddr(c, n, flags)
-  of nkHiddenStdConv, nkHiddenSubConv, nkConv: result = evalConv(c, n)
-  of nkAsgn, nkFastAsgn: result = evalAsgn(c, n)
   of nkWhenStmt, nkIfStmt, nkIfExpr: result = evalIf(c, n)
   of nkWhileStmt: result = evalWhile(c, n)
   of nkCaseStmt: result = evalCase(c, n)
@@ -1414,6 +1423,9 @@ proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
     result = raiseCannotEval(c, n.info)
   of nkRefTy:
     result = evalAux(c, n.sons[0], flags)
+  of nkEmpty: 
+    # nkEmpty occurs once in each trace that I looked at
+    result = n
   else: InternalError(n.info, "evalAux: " & $n.kind)
   if result == nil:
     InternalError(n.info, "evalAux: returned nil " & $n.kind)
diff --git a/doc/gc.txt b/doc/gc.txt
index 975a89308..854f9ce2a 100644
--- a/doc/gc.txt
+++ b/doc/gc.txt
@@ -22,6 +22,13 @@ delta-subgraph of the heap that changed since its last run.
 The GC is only triggered in a memory allocation operation. It it not triggered
 by some timer and does not run in a background thread.
 
+To force a full collection call ``GC_fullCollect``. Note that it is generally
+better to let the GC do its work and not enforce a full collection.
+
+
+Cycle collector
+===============
+
 The cycle collector can be en-/disabled independently from the other parts of
 the GC with ``GC_enableMarkAndSweep`` and ``GC_disableMarkAndSweep``. The
 compiler analyses the types for their possibility to build cycles, but often
@@ -30,11 +37,10 @@ it is necessary to help this analysis with the ``acyclic`` pragma (see
 
 You can also use the ``acyclic`` pragma for data that is cyclic in reality and 
 then break up the cycles explicitly with ``GC_addCycleRoot``. This can be a
-very good optimization; the Nimrod compiler itself relies on this optimization
-trick to improve performance.
-
-To force a full collection call ``GC_fullCollect``. Note that it is generally
-better to let the GC do its work and not enforce a full collection.
+very valuable optimization; the Nimrod compiler itself relies on this 
+optimization trick to improve performance. Note that ``GC_addCycleRoot`` is
+a quick operation; the root is only registered for the next run of the 
+cycle collector.
 
 
 Realtime support
diff --git a/lib/core/macros.nim b/lib/core/macros.nim
index bf7510a92..b72279777 100755
--- a/lib/core/macros.nim
+++ b/lib/core/macros.nim
@@ -1,7 +1,7 @@
 #
 #
 #            Nimrod's Runtime Library
-#        (c) Copyright 2012 Andreas Rumpf
+#        (c) Copyright 2013 Andreas Rumpf
 #
 #    See the file "copying.txt", included in this
 #    distribution, for details about the copyright.
@@ -21,9 +21,10 @@ type
     nnkUInt16Lit, nnkUInt32Lit, nnkUInt64Lit, nnkFloatLit,
     nnkFloat32Lit, nnkFloat64Lit, nnkFloat128Lit, nnkStrLit, nnkRStrLit,
     nnkTripleStrLit, nnkNilLit, nnkMetaNode, nnkDotCall,
-    nnkCommand, nnkCall, nnkCallStrLit, nnkExprEqExpr,
-    nnkExprColonExpr, nnkIdentDefs, nnkVarTuple, nnkInfix,
-    nnkPrefix, nnkPostfix, nnkPar, nnkCurly, nnkCurlyExpr,
+    nnkCommand, nnkCall, nnkCallStrLit, nnkInfix,
+    nnkPrefix, nnkPostfix, nnkHiddenCallConv, 
+    nnkExprEqExpr,
+    nnkExprColonExpr, nnkIdentDefs, nnkVarTuple, nnkPar, nnkCurly, nnkCurlyExpr,
     nnkBracket, nnkBracketExpr, nnkPragmaExpr, nnkRange,
     nnkDotExpr, nnkCheckedFieldExpr, nnkDerefExpr, nnkIfExpr,
     nnkElifExpr, nnkElseExpr, nnkLambda, nnkDo, nnkAccQuoted,
@@ -31,7 +32,7 @@ type
     nnkClosedSymChoice,
     nnkOpenSymChoice,
     nnkHiddenStdConv,
-    nnkHiddenSubConv, nnkHiddenCallConv, nnkConv, nnkCast, nnkStaticExpr,
+    nnkHiddenSubConv, nnkConv, nnkCast, nnkStaticExpr,
     nnkAddr, nnkHiddenAddr, nnkHiddenDeref, nnkObjDownConv,
     nnkObjUpConv, nnkChckRangeF, nnkChckRange64, nnkChckRange,
     nnkStringToCString, nnkCStringToString, nnkAsgn,