# # # The Nim Compiler # (c) Copyright 2015 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. # ## This module implements for loop detection for better C code generation. import ast, astalgo const someCmp = {mEqI, mEqF64, mEqEnum, mEqCh, mEqB, mEqRef, mEqProc, mEqUntracedRef, mLeI, mLeF64, mLeU, mLeU64, mLeEnum, mLeCh, mLeB, mLePtr, mLtI, mLtF64, mLtU, mLtU64, mLtEnum, mLtCh, mLtB, mLtPtr} proc isCounter(s: PSym): bool {.inline.} = s.kind in {skResult, skVar, skLet, skTemp} and {sfGlobal, sfAddrTaken} * s.flags == {} proc isCall(n: PNode): bool {.inline.} = n.kind in nkCallKinds and n[0].kind == nkSym proc fromSystem(op: PSym): bool = sfSystemModule in getModule(op).flags proc getCounter(lastStmt: PNode): PSym = if lastStmt.isCall: let op = lastStmt.sym if op.magic in {mDec, mInc} or ((op.name.s == "+=" or op.name.s == "-=") and op.fromSystem): if op[1].kind == nkSym and isCounter(op[1].sym): result = op[1].sym proc counterInTree(n, loop: PNode; counter: PSym): bool = # prune the search tree: within the loop the counter may be used: if n == loop: return case n.kind of nkSym: if n.sym == counter: return true of nkVarSection, nkLetSection: # definitions are fine! for it in n: if counterInTree(it.lastSon): return true else: for i in 0 ..