.byref always optimizes sink call into a bitwise memcopy

This commit is contained in:
ringabout
2024-10-18 21:59:35 +08:00
parent 1e25844f55
commit adf3aa7ec9
3 changed files with 35 additions and 4 deletions

View File

@@ -84,7 +84,8 @@ proc cleanupTemp(p: BProc; returnType: PType, tmp: TLoc): bool =
let dtor = getAttachedOp(p.module.g.graph, returnType, attachedDestructor)
var op = initLocExpr(p, newSymNode(dtor))
var callee = rdLoc(op)
let destroy = if dtor.typ.firstParamType.kind == tyVar:
let destroy = if dtor.typ.firstParamType.kind == tyVar or
tfByRef in dtor.typ.firstParamType.flags:
callee & "(&" & rdLoc(tmp) & ")"
else:
callee & "(" & rdLoc(tmp) & ")"

View File

@@ -277,7 +277,8 @@ proc deepAliases(dest, ri: PNode): bool =
proc genSink(c: var Con; s: var Scope; dest, ri: PNode; flags: set[MoveOrCopyFlag] = {}): PNode =
if (c.inLoopCond == 0 and (isUnpackedTuple(dest) or IsDecl in flags or
(isAnalysableFieldAccess(dest, c.owner) and isFirstWrite(dest, c)))) or
isNoInit(dest) or IsReturn in flags:
isNoInit(dest) or IsReturn in flags or
tfByRef in dest.typ.flags:
# optimize sink call into a bitwise memcopy
result = newTree(nkFastAsgn, dest, ri)
else:

View File

@@ -99,7 +99,7 @@ type
proc imageCopy*(image: Image): Image {.nodestroy.}
proc `=destroy`*(x: var Image) =
proc `=destroy`*(x: Image) =
discard
proc `=sink`*(dest: var Image; source: Image) =
`=destroy`(dest)
@@ -111,7 +111,7 @@ proc `=dup`*(source: Image): Image {.nodestroy.} =
proc `=copy`*(dest: var Image; source: Image) =
dest = imageCopy(source) # calls =sink implicitly
proc `=destroy`*(x: var EmbeddedImage) = discard
proc `=destroy`*(x: EmbeddedImage) = discard
proc `=dup`*(source: EmbeddedImage): EmbeddedImage {.nodestroy.} = source
@@ -184,3 +184,32 @@ block: # bug #24147
let oo = OO(val: "hello world")
var ooCopy : OO
`=copy`(ooCopy, oo)
block:
type MyObj {.byref.} = object
value: int
proc `=copy`(a: var MyObj, b: MyObj) {.error.}
proc `=sink`(a: var MyObj, b: MyObj) {.error.}
proc createMyObj(value: int): MyObj =
result.value = value
var x: MyObj
x = createMyObj(3)
block:
type MyObj {.byref.} = object
value: int
proc `=copy`(a: var MyObj, b: MyObj) {.error.}
proc `=sink`(a: var MyObj, b: MyObj) {.error.}
proc createMyObj(value: int): MyObj =
result.value = value
proc foo =
var x: MyObj
x = createMyObj(3)
foo()