diff options
author | Araq <rumpf_a@web.de> | 2015-10-15 09:31:43 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2015-10-15 09:31:54 +0200 |
commit | c97cbe7abd85d134e95ad1a7044fc314c60e5bed (patch) | |
tree | 018959820cb3510daf9db092946a7a210c384cc6 /compiler/vmgen.nim | |
parent | 7d6c9143d70d1ba09ef43d1580a0ad870d46e2a6 (diff) | |
download | Nim-c97cbe7abd85d134e95ad1a7044fc314c60e5bed.tar.gz |
fixes #3299
Diffstat (limited to 'compiler/vmgen.nim')
-rw-r--r-- | compiler/vmgen.nim | 22 |
1 files changed, 22 insertions, 0 deletions
diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 92db0d513..97c6a5580 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -1091,10 +1091,32 @@ proc requiresCopy(n: PNode): bool = proc unneededIndirection(n: PNode): bool = n.typ.skipTypes(abstractInst-{tyTypeDesc}).kind == tyRef +proc canElimAddr(n: PNode): PNode = + case n.sons[0].kind + of nkObjUpConv, nkObjDownConv, nkChckRange, nkChckRangeF, nkChckRange64: + var m = n.sons[0].sons[0] + if m.kind in {nkDerefExpr, nkHiddenDeref}: + # addr ( nkConv ( deref ( x ) ) ) --> nkConv(x) + result = copyNode(n.sons[0]) + result.add m.sons[0] + of nkHiddenStdConv, nkHiddenSubConv, nkConv: + var m = n.sons[0].sons[1] + if m.kind in {nkDerefExpr, nkHiddenDeref}: + # addr ( nkConv ( deref ( x ) ) ) --> nkConv(x) + result = copyNode(n.sons[0]) + result.add m.sons[0] + else: + if n.sons[0].kind in {nkDerefExpr, nkHiddenDeref}: + # addr ( deref ( x )) --> x + result = n.sons[0].sons[0] + proc genAddrDeref(c: PCtx; n: PNode; dest: var TDest; opc: TOpcode; flags: TGenFlags) = # a nop for certain types let isAddr = opc in {opcAddrNode, opcAddrReg} + if isAddr and (let m = canElimAddr(n); m != nil): + gen(c, m, dest, flags) + return let newflags = if isAddr: flags+{gfAddrOf} else: flags # consider: # proc foo(f: var ref int) = |