parent
bb4b27a2ca
commit
2e4b6b94e6
3 changed files with 61 additions and 126 deletions
|
|
@ -19,7 +19,7 @@ import
|
||||||
lineinfos, parampatterns, sighashes, liftdestructors, optimizer,
|
lineinfos, parampatterns, sighashes, liftdestructors, optimizer,
|
||||||
varpartitions
|
varpartitions
|
||||||
|
|
||||||
from trees import exprStructuralEquivalent, getRoot, sameLocation
|
from trees import exprStructuralEquivalent, getRoot
|
||||||
|
|
||||||
type
|
type
|
||||||
Scope = object # well we do scope-based memory management. \
|
Scope = object # well we do scope-based memory management. \
|
||||||
|
|
@ -969,10 +969,6 @@ proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode): PNode =
|
||||||
internalError(c.graph.config, n.info, "cannot inject destructors to node kind: " & $n.kind)
|
internalError(c.graph.config, n.info, "cannot inject destructors to node kind: " & $n.kind)
|
||||||
|
|
||||||
proc moveOrCopy(dest, ri: PNode; c: var Con; s: var Scope, isDecl = false): PNode =
|
proc moveOrCopy(dest, ri: PNode; c: var Con; s: var Scope, isDecl = false): PNode =
|
||||||
if sameLocation(dest, ri):
|
|
||||||
# rule (self-assignment-removal):
|
|
||||||
result = newNodeI(nkEmpty, dest.info)
|
|
||||||
else:
|
|
||||||
case ri.kind
|
case ri.kind
|
||||||
of nkCallKinds:
|
of nkCallKinds:
|
||||||
result = c.genSink(dest, p(ri, c, s, consumed), isDecl)
|
result = c.genSink(dest, p(ri, c, s, consumed), isDecl)
|
||||||
|
|
@ -1000,7 +996,10 @@ proc moveOrCopy(dest, ri: PNode; c: var Con; s: var Scope, isDecl = false): PNod
|
||||||
of nkObjConstr, nkTupleConstr, nkClosure, nkCharLit..nkNilLit:
|
of nkObjConstr, nkTupleConstr, nkClosure, nkCharLit..nkNilLit:
|
||||||
result = c.genSink(dest, p(ri, c, s, consumed), isDecl)
|
result = c.genSink(dest, p(ri, c, s, consumed), isDecl)
|
||||||
of nkSym:
|
of nkSym:
|
||||||
if isSinkParam(ri.sym) and isLastRead(ri, c):
|
if dest.kind == nkSym and dest.sym == ri.sym:
|
||||||
|
# rule (self-assignment-removal):
|
||||||
|
result = newNodeI(nkEmpty, dest.info)
|
||||||
|
elif isSinkParam(ri.sym) and isLastRead(ri, c):
|
||||||
# Rule 3: `=sink`(x, z); wasMoved(z)
|
# Rule 3: `=sink`(x, z); wasMoved(z)
|
||||||
let snk = c.genSink(dest, ri, isDecl)
|
let snk = c.genSink(dest, ri, isDecl)
|
||||||
result = newTree(nkStmtList, snk, c.genWasMoved(ri))
|
result = newTree(nkStmtList, snk, c.genWasMoved(ri))
|
||||||
|
|
|
||||||
|
|
@ -54,21 +54,6 @@ proc exprStructuralEquivalent*(a, b: PNode; strictSymEquality=false): bool =
|
||||||
strictSymEquality): return
|
strictSymEquality): return
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
proc sameLocation*(a, b: PNode): bool =
|
|
||||||
if a == b: true
|
|
||||||
elif a == nil or b == nil: false
|
|
||||||
elif a.kind == b.kind:
|
|
||||||
case a.kind:
|
|
||||||
of nkCheckedFieldExpr, nkDerefExpr, nkHiddenDeref,
|
|
||||||
nkAddr, nkHiddenAddr, nkObjDownConv, nkObjUpConv:
|
|
||||||
sameLocation(a[0], b[0])
|
|
||||||
of nkDotExpr, nkBracketExpr:
|
|
||||||
sameLocation(a[0], b[0]) and sameLocation(a[1], b[1])
|
|
||||||
of nkHiddenStdConv, nkHiddenSubConv: sameLocation(a[1], b[1])
|
|
||||||
of nkNone..nkNilLit: exprStructuralEquivalent(a, b, strictSymEquality = true)
|
|
||||||
else: false
|
|
||||||
else: false
|
|
||||||
|
|
||||||
proc sameTree*(a, b: PNode): bool =
|
proc sameTree*(a, b: PNode): bool =
|
||||||
if a == b:
|
if a == b:
|
||||||
result = true
|
result = true
|
||||||
|
|
|
||||||
|
|
@ -126,52 +126,3 @@ proc main =
|
||||||
echo avals.len, " ", rankdef.len
|
echo avals.len, " ", rankdef.len
|
||||||
|
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
# Issue #16185, complex self-assingment elimination
|
|
||||||
#------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
type
|
|
||||||
CpuStorage*[T] = ref CpuStorageObj[T]
|
|
||||||
CpuStorageObj[T] = object
|
|
||||||
size*: int
|
|
||||||
raw_buffer*: ptr UncheckedArray[T]
|
|
||||||
Tensor[T] = object
|
|
||||||
buf*: CpuStorage[T]
|
|
||||||
TestObject = object
|
|
||||||
x: Tensor[float]
|
|
||||||
|
|
||||||
proc `=destroy`[T](s: var CpuStorageObj[T]) =
|
|
||||||
if s.raw_buffer != nil:
|
|
||||||
s.raw_buffer.deallocShared()
|
|
||||||
s.size = 0
|
|
||||||
s.raw_buffer = nil
|
|
||||||
|
|
||||||
proc `=`[T](a: var CpuStorageObj[T]; b: CpuStorageObj[T]) {.error.}
|
|
||||||
|
|
||||||
proc allocCpuStorage[T](s: var CpuStorage[T], size: int) =
|
|
||||||
new(s)
|
|
||||||
s.raw_buffer = cast[ptr UncheckedArray[T]](allocShared0(sizeof(T) * size))
|
|
||||||
s.size = size
|
|
||||||
|
|
||||||
proc newTensor[T](size: int): Tensor[T] =
|
|
||||||
allocCpuStorage(result.buf, size)
|
|
||||||
|
|
||||||
proc `[]`[T](t: Tensor[T], idx: int): T = t.buf.raw_buffer[idx]
|
|
||||||
proc `[]=`[T](t: Tensor[T], idx: int, val: T) = t.buf.raw_buffer[idx] = val
|
|
||||||
|
|
||||||
proc toTensor[T](s: seq[T]): Tensor[T] =
|
|
||||||
result = newTensor[T](s.len)
|
|
||||||
for i, x in s:
|
|
||||||
result[i] = x
|
|
||||||
|
|
||||||
proc main2() =
|
|
||||||
var t: TestObject
|
|
||||||
t.x = toTensor(@[1.0, 2, 3, 4])
|
|
||||||
t.x = t.x
|
|
||||||
doAssert(t.x.buf != nil) # self-assignment above should be eliminated
|
|
||||||
|
|
||||||
main2()
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue