mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-19 05:50:30 +00:00
fixes cast expressions introduces unnecessary copies (#24004)
It speeds up ```nim proc foo = let piece = cast[seq[char]](newSeqUninit[uint8](5220600386'i64)) foo() ``` Notes that `cast[ref](...)` is excluded because we need to keep the ref alive if the parameter is something with pointer types (e.g. `cast[ref](pointer)`or `cast[ref](makePointer(...))`) --------- Co-authored-by: Andreas Rumpf <rumpf_a@web.de>
This commit is contained in:
@@ -501,7 +501,7 @@ proc containsConstSeq(n: PNode): bool =
|
||||
return true
|
||||
result = false
|
||||
case n.kind
|
||||
of nkExprEqExpr, nkExprColonExpr, nkHiddenStdConv, nkHiddenSubConv:
|
||||
of nkExprEqExpr, nkExprColonExpr, nkHiddenStdConv, nkHiddenSubConv, nkCast:
|
||||
result = containsConstSeq(n[1])
|
||||
of nkObjConstr, nkClosure:
|
||||
for i in 1..<n.len:
|
||||
@@ -829,6 +829,9 @@ proc p(n: PNode; c: var Con; s: var Scope; mode: ProcessMode; tmpFlags = {sfSing
|
||||
elif n.kind in {nkObjDownConv, nkObjUpConv}:
|
||||
result = copyTree(n)
|
||||
result[0] = p(n[0], c, s, sinkArg)
|
||||
elif n.kind == nkCast and n.typ.skipTypes(abstractInst).kind in {tyString, tySequence}:
|
||||
result = copyTree(n)
|
||||
result[1] = p(n[1], c, s, sinkArg)
|
||||
elif n.typ == nil:
|
||||
# 'raise X' can be part of a 'case' expression. Deal with it here:
|
||||
result = p(n, c, s, normal)
|
||||
|
||||
@@ -143,11 +143,13 @@ proc `=sink`*[T](m: var MySeq[T], m2: MySeq[T]) {.inline.} =
|
||||
`=destroy`(m)
|
||||
m.len = m2.len
|
||||
m.data = m2.data
|
||||
m.refcount = m2.refcount
|
||||
|
||||
proc len*[T](m: MySeq[T]): int {.inline.} = m.len
|
||||
|
||||
proc newMySeq*[T](size: int, initial_value: T): MySeq[T] =
|
||||
result.len = size
|
||||
result.refcount = 1
|
||||
if size > 0:
|
||||
result.data = cast[ptr UncheckedArray[T]](allocShared(sizeof(T) * size))
|
||||
|
||||
|
||||
@@ -10,69 +10,41 @@ destroying O1'''
|
||||
var
|
||||
data
|
||||
:tmpD
|
||||
:tmpD_1
|
||||
:tmpD_2
|
||||
data =
|
||||
:tmpD = `=dup`(cast[string](
|
||||
:tmpD_2 = encode(cast[seq[byte]](
|
||||
:tmpD_1 = newString(100)
|
||||
:tmpD_1))
|
||||
:tmpD_2))
|
||||
:tmpD
|
||||
`=destroy`(:tmpD_2)
|
||||
`=destroy_1`(:tmpD_1)
|
||||
`=destroy_1`(data)
|
||||
data = cast[string](encode(cast[seq[byte]](
|
||||
:tmpD = newString(100)
|
||||
:tmpD)))
|
||||
`=destroy`(:tmpD)
|
||||
`=destroy`(data)
|
||||
-- end of expandArc ------------------------
|
||||
--expandArc: main1
|
||||
|
||||
var
|
||||
s
|
||||
data
|
||||
:tmpD
|
||||
:tmpD_1
|
||||
s = newString(100)
|
||||
data =
|
||||
:tmpD = `=dup`(cast[string](
|
||||
:tmpD_1 = encode(toOpenArrayByte(s, 0, len(s) - 1))
|
||||
:tmpD_1))
|
||||
:tmpD
|
||||
`=destroy`(:tmpD_1)
|
||||
`=destroy_1`(data)
|
||||
`=destroy_1`(s)
|
||||
data = cast[string](encode(toOpenArrayByte(s, 0, len(s) - 1)))
|
||||
`=destroy`(data)
|
||||
`=destroy`(s)
|
||||
-- end of expandArc ------------------------
|
||||
--expandArc: main2
|
||||
|
||||
var
|
||||
s
|
||||
data
|
||||
:tmpD
|
||||
:tmpD_1
|
||||
s = newSeq(100)
|
||||
data =
|
||||
:tmpD = `=dup`(cast[string](
|
||||
:tmpD_1 = encode(s)
|
||||
:tmpD_1))
|
||||
:tmpD
|
||||
`=destroy`(:tmpD_1)
|
||||
`=destroy_1`(data)
|
||||
`=destroy`(s)
|
||||
data = cast[string](encode(s))
|
||||
`=destroy`(data)
|
||||
`=destroy_1`(s)
|
||||
-- end of expandArc ------------------------
|
||||
--expandArc: main3
|
||||
|
||||
var
|
||||
data
|
||||
:tmpD
|
||||
:tmpD_1
|
||||
:tmpD_2
|
||||
data =
|
||||
:tmpD = `=dup`(cast[string](
|
||||
:tmpD_2 = encode do:
|
||||
:tmpD_1 = newSeq(100)
|
||||
:tmpD_1
|
||||
:tmpD_2))
|
||||
:tmpD
|
||||
`=destroy`(:tmpD_2)
|
||||
`=destroy`(:tmpD_1)
|
||||
data = cast[string](encode do:
|
||||
:tmpD = newSeq(100)
|
||||
:tmpD)
|
||||
`=destroy`(:tmpD)
|
||||
`=destroy_1`(data)
|
||||
-- end of expandArc ------------------------
|
||||
'''
|
||||
|
||||
Reference in New Issue
Block a user