parent
a644f443bc
commit
eb9043c0e9
3 changed files with 61 additions and 24 deletions
|
|
@ -567,19 +567,36 @@ proc genReturn(c: var Con; n: PNode) =
|
||||||
|
|
||||||
const
|
const
|
||||||
InterestingSyms = {skVar, skResult, skLet, skParam, skForVar, skTemp}
|
InterestingSyms = {skVar, skResult, skLet, skParam, skForVar, skTemp}
|
||||||
PathKinds* = {nkDotExpr, nkCheckedFieldExpr,
|
PathKinds0 = {nkDotExpr, nkCheckedFieldExpr,
|
||||||
nkBracketExpr, nkDerefExpr, nkHiddenDeref,
|
nkBracketExpr, nkDerefExpr, nkHiddenDeref,
|
||||||
nkAddr, nkHiddenAddr,
|
nkAddr, nkHiddenAddr,
|
||||||
nkHiddenStdConv, nkHiddenSubConv, nkObjDownConv, nkObjUpConv}
|
nkObjDownConv, nkObjUpConv}
|
||||||
|
PathKinds1 = {nkHiddenStdConv, nkHiddenSubConv}
|
||||||
|
|
||||||
|
proc getRoot(n: PNode): PNode =
|
||||||
|
result = n
|
||||||
|
while true:
|
||||||
|
case result.kind
|
||||||
|
of PathKinds0:
|
||||||
|
result = result[0]
|
||||||
|
of PathKinds1:
|
||||||
|
result = result[1]
|
||||||
|
else: break
|
||||||
|
|
||||||
|
proc skipConvDfa*(n: PNode): PNode =
|
||||||
|
result = n
|
||||||
|
while true:
|
||||||
|
case result.kind
|
||||||
|
of nkObjDownConv, nkObjUpConv:
|
||||||
|
result = result[0]
|
||||||
|
of PathKinds1:
|
||||||
|
result = result[1]
|
||||||
|
else: break
|
||||||
|
|
||||||
proc genUse(c: var Con; orig: PNode) =
|
proc genUse(c: var Con; orig: PNode) =
|
||||||
var n = orig
|
let n = dfa.getRoot(orig)
|
||||||
var iters = 0
|
|
||||||
while n.kind in PathKinds:
|
|
||||||
n = n[0]
|
|
||||||
inc iters
|
|
||||||
if n.kind == nkSym and n.sym.kind in InterestingSyms:
|
if n.kind == nkSym and n.sym.kind in InterestingSyms:
|
||||||
c.code.add Instr(n: orig, kind: use, sym: if iters > 0: nil else: n.sym)
|
c.code.add Instr(n: orig, kind: use, sym: if orig != n: nil else: n.sym)
|
||||||
|
|
||||||
proc aliases(obj, field: PNode): bool =
|
proc aliases(obj, field: PNode): bool =
|
||||||
var n = field
|
var n = field
|
||||||
|
|
@ -729,7 +746,7 @@ proc gen(c: var Con; n: PNode) =
|
||||||
# "uses" 'i'. But we are only talking about builtin array indexing so
|
# "uses" 'i'. But we are only talking about builtin array indexing so
|
||||||
# it doesn't matter and 'x = 34' is NOT a usage of 'x'.
|
# it doesn't matter and 'x = 34' is NOT a usage of 'x'.
|
||||||
genDef(c, n[0])
|
genDef(c, n[0])
|
||||||
of PathKinds:
|
of PathKinds0 - {nkHiddenStdConv, nkHiddenSubConv, nkObjDownConv, nkObjUpConv}:
|
||||||
genUse(c, n)
|
genUse(c, n)
|
||||||
of nkIfStmt, nkIfExpr: genIf(c, n)
|
of nkIfStmt, nkIfExpr: genIf(c, n)
|
||||||
of nkWhenStmt:
|
of nkWhenStmt:
|
||||||
|
|
@ -746,8 +763,8 @@ proc gen(c: var Con; n: PNode) =
|
||||||
nkBracket, nkCurly, nkPar, nkTupleConstr, nkClosure, nkObjConstr:
|
nkBracket, nkCurly, nkPar, nkTupleConstr, nkClosure, nkObjConstr:
|
||||||
for x in n: gen(c, x)
|
for x in n: gen(c, x)
|
||||||
of nkPragmaBlock: gen(c, n.lastSon)
|
of nkPragmaBlock: gen(c, n.lastSon)
|
||||||
of nkDiscardStmt: gen(c, n.sons[0])
|
of nkDiscardStmt, nkObjDownConv, nkObjUpConv: gen(c, n.sons[0])
|
||||||
of nkConv, nkExprColonExpr, nkExprEqExpr, nkCast:
|
of nkConv, nkExprColonExpr, nkExprEqExpr, nkCast, nkHiddenSubConv, nkHiddenStdConv:
|
||||||
gen(c, n.sons[1])
|
gen(c, n.sons[1])
|
||||||
of nkStringToCString, nkCStringToString: gen(c, n.sons[0])
|
of nkStringToCString, nkCStringToString: gen(c, n.sons[0])
|
||||||
of nkVarSection, nkLetSection: genVarSection(c, n)
|
of nkVarSection, nkLetSection: genVarSection(c, n)
|
||||||
|
|
|
||||||
|
|
@ -195,15 +195,17 @@ proc isLastRead(n: PNode; c: var Con): bool =
|
||||||
# first we need to search for the instruction that belongs to 'n':
|
# first we need to search for the instruction that belongs to 'n':
|
||||||
c.otherRead = nil
|
c.otherRead = nil
|
||||||
var instr = -1
|
var instr = -1
|
||||||
|
let m = dfa.skipConvDfa(n)
|
||||||
|
|
||||||
for i in 0..<c.g.len:
|
for i in 0..<c.g.len:
|
||||||
# This comparison is correct and MUST not be ``instrTargets``:
|
# This comparison is correct and MUST not be ``instrTargets``:
|
||||||
if c.g[i].kind == use and c.g[i].n == n:
|
if c.g[i].kind == use and c.g[i].n == m:
|
||||||
if instr < 0:
|
if instr < 0:
|
||||||
instr = i
|
instr = i
|
||||||
break
|
break
|
||||||
|
|
||||||
dbg:
|
dbg:
|
||||||
echo "starting point for ", n, " is ", instr
|
echo "starting point for ", n, " is ", instr, " ", n.kind
|
||||||
|
|
||||||
if instr < 0: return false
|
if instr < 0: return false
|
||||||
# we go through all paths beginning from 'instr+1' and need to
|
# we go through all paths beginning from 'instr+1' and need to
|
||||||
|
|
@ -625,7 +627,9 @@ proc moveOrCopy(dest, ri: PNode; c: var Con): PNode =
|
||||||
result = genCopy(c, dest.typ, dest, ri)
|
result = genCopy(c, dest.typ, dest, ri)
|
||||||
result.add p(ri, c)
|
result.add p(ri, c)
|
||||||
of nkHiddenSubConv, nkHiddenStdConv:
|
of nkHiddenSubConv, nkHiddenStdConv:
|
||||||
if ri[1].kind in movableNodeKinds:
|
if sameType(ri.typ, ri[1].typ):
|
||||||
|
result = moveOrCopy(dest, ri[1], c)
|
||||||
|
elif ri[1].kind in movableNodeKinds:
|
||||||
result = moveOrCopy(dest, ri[1], c)
|
result = moveOrCopy(dest, ri[1], c)
|
||||||
var b = newNodeIT(ri.kind, ri.info, ri.typ)
|
var b = newNodeIT(ri.kind, ri.info, ri.typ)
|
||||||
b.add ri[0] # add empty node
|
b.add ri[0] # add empty node
|
||||||
|
|
|
||||||
|
|
@ -2,30 +2,46 @@ discard """
|
||||||
output: '''works'''
|
output: '''works'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
type
|
# bug #11095
|
||||||
MyVal = object
|
|
||||||
f: ptr float
|
|
||||||
|
|
||||||
proc `=destroy`(x: var MyVal) =
|
type
|
||||||
|
MyVal[T] = object
|
||||||
|
f: ptr T
|
||||||
|
|
||||||
|
proc `=destroy`[T](x: var MyVal[T]) =
|
||||||
if x.f != nil:
|
if x.f != nil:
|
||||||
dealloc(x.f)
|
dealloc(x.f)
|
||||||
|
|
||||||
proc `=sink`(x1: var MyVal, x2: Myval) =
|
proc `=sink`[T](x1: var MyVal[T], x2: MyVal[T]) =
|
||||||
if x1.f != x2.f:
|
if x1.f != x2.f:
|
||||||
`=destroy`(x1)
|
`=destroy`(x1)
|
||||||
x1.f = x2.f
|
x1.f = x2.f
|
||||||
|
|
||||||
proc `=`(x1: var MyVal, x2: Myval) {.error.}
|
proc `=`[T](x1: var MyVal[T], x2: MyVal[T]) {.error.}
|
||||||
|
|
||||||
proc newVal(x: float): MyVal =
|
proc newVal[T](x: sink T): MyVal[T] =
|
||||||
result.f = create(float)
|
result.f = create(T)
|
||||||
result.f[] = x
|
result.f[] = x
|
||||||
|
|
||||||
proc sinkMe(x: sink MyVal) =
|
proc set[T](x: var MyVal[T], val: T) =
|
||||||
|
x.f[] = val
|
||||||
|
|
||||||
|
proc sinkMe[T](x: sink MyVal[T]) =
|
||||||
discard
|
discard
|
||||||
|
|
||||||
|
var flag = false
|
||||||
|
|
||||||
proc main =
|
proc main =
|
||||||
var y = (newVal(3.0), newVal(4.0))
|
var y = case flag
|
||||||
|
of true:
|
||||||
|
var x1 = newVal[float](1.0)
|
||||||
|
var x2 = newVal[float](2.0)
|
||||||
|
(newVal(x1), newVal(x2))
|
||||||
|
|
||||||
|
of false:
|
||||||
|
var x1 = newVal[float](1.0)
|
||||||
|
var x2 = newVal[float](2.0)
|
||||||
|
(newVal(x1), newVal(x2))
|
||||||
|
|
||||||
sinkMe y[0]
|
sinkMe y[0]
|
||||||
sinkMe y[1]
|
sinkMe y[1]
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue