avoid creating temporary in genObjConstr if possible (#7032)
This commit is contained in:
parent
2aebb8ed7e
commit
d0a9fac362
3 changed files with 45 additions and 17 deletions
|
|
@ -1202,18 +1202,30 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
|
||||||
# we skip this step here:
|
# we skip this step here:
|
||||||
if not p.module.compileToCpp:
|
if not p.module.compileToCpp:
|
||||||
if handleConstExpr(p, e, d): return
|
if handleConstExpr(p, e, d): return
|
||||||
var tmp: TLoc
|
|
||||||
var t = e.typ.skipTypes(abstractInst)
|
var t = e.typ.skipTypes(abstractInst)
|
||||||
getTemp(p, t, tmp)
|
|
||||||
let isRef = t.kind == tyRef
|
let isRef = t.kind == tyRef
|
||||||
var r = rdLoc(tmp)
|
|
||||||
if isRef:
|
# check if we need to construct the object in a temporary
|
||||||
rawGenNew(p, tmp, nil)
|
var useTemp =
|
||||||
t = t.lastSon.skipTypes(abstractInst)
|
isRef or
|
||||||
r = "(*$1)" % [r]
|
(d.k notin {locTemp,locLocalVar,locGlobalVar,locParam,locField}) or
|
||||||
gcUsage(e)
|
(isPartOf(d.lode, e) != arNo)
|
||||||
|
|
||||||
|
var tmp: TLoc
|
||||||
|
var r: Rope
|
||||||
|
if useTemp:
|
||||||
|
getTemp(p, t, tmp)
|
||||||
|
r = rdLoc(tmp)
|
||||||
|
if isRef:
|
||||||
|
rawGenNew(p, tmp, nil)
|
||||||
|
t = t.lastSon.skipTypes(abstractInst)
|
||||||
|
r = "(*$1)" % [r]
|
||||||
|
gcUsage(e)
|
||||||
|
else:
|
||||||
|
constructLoc(p, tmp)
|
||||||
else:
|
else:
|
||||||
constructLoc(p, tmp)
|
resetLoc(p, d)
|
||||||
|
r = rdLoc(d)
|
||||||
discard getTypeDesc(p.module, t)
|
discard getTypeDesc(p.module, t)
|
||||||
let ty = getUniqueType(t)
|
let ty = getUniqueType(t)
|
||||||
for i in 1 ..< e.len:
|
for i in 1 ..< e.len:
|
||||||
|
|
@ -1227,15 +1239,19 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
|
||||||
genFieldCheck(p, it.sons[2], r, field)
|
genFieldCheck(p, it.sons[2], r, field)
|
||||||
add(tmp2.r, ".")
|
add(tmp2.r, ".")
|
||||||
add(tmp2.r, field.loc.r)
|
add(tmp2.r, field.loc.r)
|
||||||
tmp2.k = locTemp
|
if useTemp:
|
||||||
|
tmp2.k = locTemp
|
||||||
|
tmp2.storage = if isRef: OnHeap else: OnStack
|
||||||
|
else:
|
||||||
|
tmp2.k = d.k
|
||||||
|
tmp2.storage = if isRef: OnHeap else: d.storage
|
||||||
tmp2.lode = it.sons[1]
|
tmp2.lode = it.sons[1]
|
||||||
tmp2.storage = if isRef: OnHeap else: OnStack
|
|
||||||
expr(p, it.sons[1], tmp2)
|
expr(p, it.sons[1], tmp2)
|
||||||
|
if useTemp:
|
||||||
if d.k == locNone:
|
if d.k == locNone:
|
||||||
d = tmp
|
d = tmp
|
||||||
else:
|
else:
|
||||||
genAssignment(p, d, tmp, {})
|
genAssignment(p, d, tmp, {})
|
||||||
|
|
||||||
proc lhsDoesAlias(a, b: PNode): bool =
|
proc lhsDoesAlias(a, b: PNode): bool =
|
||||||
for y in b:
|
for y in b:
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,8 @@ discard """
|
||||||
(y: 678, x: 123)
|
(y: 678, x: 123)
|
||||||
(y: 678, x: 123)
|
(y: 678, x: 123)
|
||||||
(y: 0, x: 123)
|
(y: 0, x: 123)
|
||||||
(y: 678, x: 123)'''
|
(y: 678, x: 123)
|
||||||
|
(y: 123, x: 678)'''
|
||||||
"""
|
"""
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
@ -75,3 +76,7 @@ when true:
|
||||||
echo b # (y: 0, x: 123)
|
echo b # (y: 0, x: 123)
|
||||||
b=B(y: 678, x: 123)
|
b=B(y: 678, x: 123)
|
||||||
echo b # (y: 678, x: 123)
|
echo b # (y: 678, x: 123)
|
||||||
|
b=B(y: b.x, x: b.y)
|
||||||
|
echo b # (y: 123, x: 678)
|
||||||
|
|
||||||
|
GC_fullCollect()
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
discard """
|
||||||
|
output: '''42
|
||||||
|
Foo'''
|
||||||
|
"""
|
||||||
|
|
||||||
type TFoo{.exportc.} = object
|
type TFoo{.exportc.} = object
|
||||||
x:int
|
x:int
|
||||||
|
|
||||||
|
|
@ -48,3 +53,5 @@ type NamedGraphic = object of Graphic2
|
||||||
|
|
||||||
var ngr = NamedGraphic(kind: Koo, radius: 6.9, name: "Foo")
|
var ngr = NamedGraphic(kind: Koo, radius: 6.9, name: "Foo")
|
||||||
echo ngr.name
|
echo ngr.name
|
||||||
|
|
||||||
|
GC_fullCollect()
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue