* fix #16185 * fix test * fix comment * fix comment * better approach
This commit is contained in:
parent
5a43a20f53
commit
bb4b27a2ca
3 changed files with 126 additions and 61 deletions
|
|
@ -19,7 +19,7 @@ import
|
|||
lineinfos, parampatterns, sighashes, liftdestructors, optimizer,
|
||||
varpartitions
|
||||
|
||||
from trees import exprStructuralEquivalent, getRoot
|
||||
from trees import exprStructuralEquivalent, getRoot, sameLocation
|
||||
|
||||
type
|
||||
Scope = object # well we do scope-based memory management. \
|
||||
|
|
@ -969,6 +969,10 @@ 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)
|
||||
|
||||
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
|
||||
of nkCallKinds:
|
||||
result = c.genSink(dest, p(ri, c, s, consumed), isDecl)
|
||||
|
|
@ -996,10 +1000,7 @@ proc moveOrCopy(dest, ri: PNode; c: var Con; s: var Scope, isDecl = false): PNod
|
|||
of nkObjConstr, nkTupleConstr, nkClosure, nkCharLit..nkNilLit:
|
||||
result = c.genSink(dest, p(ri, c, s, consumed), isDecl)
|
||||
of nkSym:
|
||||
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):
|
||||
if isSinkParam(ri.sym) and isLastRead(ri, c):
|
||||
# Rule 3: `=sink`(x, z); wasMoved(z)
|
||||
let snk = c.genSink(dest, ri, isDecl)
|
||||
result = newTree(nkStmtList, snk, c.genWasMoved(ri))
|
||||
|
|
|
|||
|
|
@ -54,6 +54,21 @@ proc exprStructuralEquivalent*(a, b: PNode; strictSymEquality=false): bool =
|
|||
strictSymEquality): return
|
||||
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 =
|
||||
if a == b:
|
||||
result = true
|
||||
|
|
|
|||
|
|
@ -126,3 +126,52 @@ proc main =
|
|||
echo avals.len, " ", rankdef.len
|
||||
|
||||
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