summary refs log tree commit diff stats
path: root/compiler/evals.nim
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 /compiler/evals.nim
parent0f2aa053d9e9bcbe67238c498ed96f27c8d737db (diff)
downloadNim-1c0c80ef2dba09bb50c470a013f3bdb9391620a7.tar.gz
micro optimizations for the evaluation engine
Diffstat (limited to 'compiler/evals.nim')
-rwxr-xr-xcompiler/evals.nim70
1 files changed, 41 insertions, 29 deletions
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)