ARC: optimize the code better when --panics:off (#15031)
This commit is contained in:
parent
5fafa2fd5c
commit
911e39351e
1 changed files with 24 additions and 18 deletions
|
|
@ -10,9 +10,6 @@
|
||||||
## This module implements lifting for type-bound operations
|
## This module implements lifting for type-bound operations
|
||||||
## (``=sink``, ``=``, ``=destroy``, ``=deepCopy``).
|
## (``=sink``, ``=``, ``=destroy``, ``=deepCopy``).
|
||||||
|
|
||||||
# Todo:
|
|
||||||
# - use openArray instead of array to avoid over-specializations
|
|
||||||
|
|
||||||
import modulegraphs, lineinfos, idents, ast, renderer, semdata,
|
import modulegraphs, lineinfos, idents, ast, renderer, semdata,
|
||||||
sighashes, lowerings, options, types, msgs, magicsys, tables
|
sighashes, lowerings, options, types, msgs, magicsys, tables
|
||||||
|
|
||||||
|
|
@ -26,8 +23,9 @@ type
|
||||||
fn: PSym
|
fn: PSym
|
||||||
asgnForType: PType
|
asgnForType: PType
|
||||||
recurse: bool
|
recurse: bool
|
||||||
filterDiscriminator: PSym # we generating destructor for case branch
|
|
||||||
addMemReset: bool # add wasMoved() call after destructor call
|
addMemReset: bool # add wasMoved() call after destructor call
|
||||||
|
canRaise: bool
|
||||||
|
filterDiscriminator: PSym # we generating destructor for case branch
|
||||||
c: PContext # c can be nil, then we are called from lambdalifting!
|
c: PContext # c can be nil, then we are called from lambdalifting!
|
||||||
|
|
||||||
proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode)
|
proc fillBody(c: var TLiftCtx; t: PType; body, x, y: PNode)
|
||||||
|
|
@ -120,10 +118,12 @@ proc genContainerOf(c: TLiftCtx; objType: PType, field, x: PSym): PNode =
|
||||||
result.add newNodeIT(nkType, c.info, objPtr)
|
result.add newNodeIT(nkType, c.info, objPtr)
|
||||||
result.add minusExpr
|
result.add minusExpr
|
||||||
|
|
||||||
proc destructorCall(c: TLiftCtx; op: PSym; x: PNode): PNode =
|
proc destructorCall(c: var TLiftCtx; op: PSym; x: PNode): PNode =
|
||||||
var destroy = newNodeIT(nkCall, x.info, op.typ[0])
|
var destroy = newNodeIT(nkCall, x.info, op.typ[0])
|
||||||
destroy.add(newSymNode(op))
|
destroy.add(newSymNode(op))
|
||||||
destroy.add genAddr(c.g, x)
|
destroy.add genAddr(c.g, x)
|
||||||
|
if sfNeverRaises notin op.flags:
|
||||||
|
c.canRaise = true
|
||||||
if c.addMemReset:
|
if c.addMemReset:
|
||||||
result = newTree(nkStmtList, destroy, genBuiltin(c.g, mWasMoved, "wasMoved", x))
|
result = newTree(nkStmtList, destroy, genBuiltin(c.g, mWasMoved, "wasMoved", x))
|
||||||
else:
|
else:
|
||||||
|
|
@ -243,25 +243,29 @@ proc fillBodyObjT(c: var TLiftCtx; t: PType, body, x, y: PNode) =
|
||||||
else:
|
else:
|
||||||
fillBodyObjTImpl(c, t, body, x, y)
|
fillBodyObjTImpl(c, t, body, x, y)
|
||||||
|
|
||||||
proc newHookCall(g: ModuleGraph; op: PSym; x, y: PNode): PNode =
|
proc newHookCall(c: var TLiftCtx; op: PSym; x, y: PNode): PNode =
|
||||||
#if sfError in op.flags:
|
#if sfError in op.flags:
|
||||||
# localError(c.config, x.info, "usage of '$1' is a user-defined error" % op.name.s)
|
# localError(c.config, x.info, "usage of '$1' is a user-defined error" % op.name.s)
|
||||||
result = newNodeI(nkCall, x.info)
|
result = newNodeI(nkCall, x.info)
|
||||||
result.add newSymNode(op)
|
result.add newSymNode(op)
|
||||||
|
if sfNeverRaises notin op.flags:
|
||||||
|
c.canRaise = true
|
||||||
if op.typ.sons[1].kind == tyVar:
|
if op.typ.sons[1].kind == tyVar:
|
||||||
result.add genAddr(g, x)
|
result.add genAddr(c.g, x)
|
||||||
else:
|
else:
|
||||||
result.add x
|
result.add x
|
||||||
if y != nil:
|
if y != nil:
|
||||||
result.add y
|
result.add y
|
||||||
|
|
||||||
proc newOpCall(op: PSym; x: PNode): PNode =
|
proc newOpCall(c: var TLiftCtx; op: PSym; x: PNode): PNode =
|
||||||
result = newNodeIT(nkCall, x.info, op.typ[0])
|
result = newNodeIT(nkCall, x.info, op.typ[0])
|
||||||
result.add(newSymNode(op))
|
result.add(newSymNode(op))
|
||||||
result.add x
|
result.add x
|
||||||
|
if sfNeverRaises notin op.flags:
|
||||||
|
c.canRaise = true
|
||||||
|
|
||||||
proc newDeepCopyCall(op: PSym; x, y: PNode): PNode =
|
proc newDeepCopyCall(c: var TLiftCtx; op: PSym; x, y: PNode): PNode =
|
||||||
result = newAsgnStmt(x, newOpCall(op, y))
|
result = newAsgnStmt(x, newOpCall(c, op, y))
|
||||||
|
|
||||||
proc usesBuiltinArc(t: PType): bool =
|
proc usesBuiltinArc(t: PType): bool =
|
||||||
proc wrap(t: PType): bool {.nimcall.} = ast.isGCedMem(t)
|
proc wrap(t: PType): bool {.nimcall.} = ast.isGCedMem(t)
|
||||||
|
|
@ -293,7 +297,7 @@ proc considerAsgnOrSink(c: var TLiftCtx; t: PType; body, x, y: PNode;
|
||||||
#else:
|
#else:
|
||||||
# markUsed(c.g.config, c.info, op, c.g.usageSym)
|
# markUsed(c.g.config, c.info, op, c.g.usageSym)
|
||||||
onUse(c.info, op)
|
onUse(c.info, op)
|
||||||
body.add newHookCall(c.g, op, x, y)
|
body.add newHookCall(c, op, x, y)
|
||||||
result = true
|
result = true
|
||||||
elif tfHasAsgn in t.flags:
|
elif tfHasAsgn in t.flags:
|
||||||
var op: PSym
|
var op: PSym
|
||||||
|
|
@ -322,7 +326,7 @@ proc considerAsgnOrSink(c: var TLiftCtx; t: PType; body, x, y: PNode;
|
||||||
#debug(t)
|
#debug(t)
|
||||||
#return false
|
#return false
|
||||||
assert op.ast[genericParamsPos].kind == nkEmpty
|
assert op.ast[genericParamsPos].kind == nkEmpty
|
||||||
body.add newHookCall(c.g, op, x, y)
|
body.add newHookCall(c, op, x, y)
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
proc addDestructorCall(c: var TLiftCtx; orig: PType; body, x: PNode) =
|
proc addDestructorCall(c: var TLiftCtx; orig: PType; body, x: PNode) =
|
||||||
|
|
@ -373,7 +377,7 @@ proc considerUserDefinedOp(c: var TLiftCtx; t: PType; body, x, y: PNode): bool =
|
||||||
if op != nil:
|
if op != nil:
|
||||||
#markUsed(c.g.config, c.info, op, c.g.usageSym)
|
#markUsed(c.g.config, c.info, op, c.g.usageSym)
|
||||||
onUse(c.info, op)
|
onUse(c.info, op)
|
||||||
body.add newDeepCopyCall(op, x, y)
|
body.add newDeepCopyCall(c, op, x, y)
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
proc declareCounter(c: var TLiftCtx; body: PNode; first: BiggestInt): PNode =
|
proc declareCounter(c: var TLiftCtx; body: PNode; first: BiggestInt): PNode =
|
||||||
|
|
@ -460,7 +464,7 @@ proc useSeqOrStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||||
of attachedAsgn, attachedDeepCopy:
|
of attachedAsgn, attachedDeepCopy:
|
||||||
if t.assignment == nil:
|
if t.assignment == nil:
|
||||||
return # protect from recursion
|
return # protect from recursion
|
||||||
body.add newHookCall(c.g, t.assignment, x, y)
|
body.add newHookCall(c, t.assignment, x, y)
|
||||||
of attachedSink:
|
of attachedSink:
|
||||||
# we always inline the move for better performance:
|
# we always inline the move for better performance:
|
||||||
let moveCall = genBuiltin(c.g, mMove, "move", x)
|
let moveCall = genBuiltin(c.g, mMove, "move", x)
|
||||||
|
|
@ -471,18 +475,18 @@ proc useSeqOrStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||||
# alternatively we could do this:
|
# alternatively we could do this:
|
||||||
when false:
|
when false:
|
||||||
doAssert t.asink != nil
|
doAssert t.asink != nil
|
||||||
body.add newHookCall(c.g, t.asink, x, y)
|
body.add newHookCall(c, t.asink, x, y)
|
||||||
of attachedDestructor:
|
of attachedDestructor:
|
||||||
doAssert t.destructor != nil
|
doAssert t.destructor != nil
|
||||||
body.add destructorCall(c, t.destructor, x)
|
body.add destructorCall(c, t.destructor, x)
|
||||||
of attachedTrace:
|
of attachedTrace:
|
||||||
if t.attachedOps[c.kind] == nil:
|
if t.attachedOps[c.kind] == nil:
|
||||||
return # protect from recursion
|
return # protect from recursion
|
||||||
body.add newHookCall(c.g, t.attachedOps[c.kind], x, y)
|
body.add newHookCall(c, t.attachedOps[c.kind], x, y)
|
||||||
of attachedDispose:
|
of attachedDispose:
|
||||||
if t.attachedOps[c.kind] == nil:
|
if t.attachedOps[c.kind] == nil:
|
||||||
return # protect from recursion
|
return # protect from recursion
|
||||||
body.add newHookCall(c.g, t.attachedOps[c.kind], x, nil)
|
body.add newHookCall(c, t.attachedOps[c.kind], x, nil)
|
||||||
|
|
||||||
proc fillStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
proc fillStrOp(c: var TLiftCtx; t: PType; body, x, y: PNode) =
|
||||||
case c.kind
|
case c.kind
|
||||||
|
|
@ -837,7 +841,7 @@ proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp;
|
||||||
sfOverriden in typ.attachedOps[attachedDestructor].flags:
|
sfOverriden in typ.attachedOps[attachedDestructor].flags:
|
||||||
## compiler can use a combination of `=destroy` and memCopy for sink op
|
## compiler can use a combination of `=destroy` and memCopy for sink op
|
||||||
dest.flags.incl sfCursor
|
dest.flags.incl sfCursor
|
||||||
result.ast[bodyPos].add newOpCall(typ.attachedOps[attachedDestructor], d[0])
|
result.ast[bodyPos].add newOpCall(a, typ.attachedOps[attachedDestructor], d[0])
|
||||||
result.ast[bodyPos].add newAsgnStmt(d, src)
|
result.ast[bodyPos].add newAsgnStmt(d, src)
|
||||||
else:
|
else:
|
||||||
var tk: TTypeKind
|
var tk: TTypeKind
|
||||||
|
|
@ -852,6 +856,7 @@ proc produceSym(g: ModuleGraph; c: PContext; typ: PType; kind: TTypeAttachedOp;
|
||||||
fillStrOp(a, typ, result.ast[bodyPos], d, src)
|
fillStrOp(a, typ, result.ast[bodyPos], d, src)
|
||||||
else:
|
else:
|
||||||
fillBody(a, typ, result.ast[bodyPos], d, src)
|
fillBody(a, typ, result.ast[bodyPos], d, src)
|
||||||
|
if not a.canRaise: incl result.flags, sfNeverRaises
|
||||||
|
|
||||||
|
|
||||||
proc produceDestructorForDiscriminator*(g: ModuleGraph; typ: PType; field: PSym, info: TLineInfo): PSym =
|
proc produceDestructorForDiscriminator*(g: ModuleGraph; typ: PType; field: PSym, info: TLineInfo): PSym =
|
||||||
|
|
@ -873,6 +878,7 @@ proc produceDestructorForDiscriminator*(g: ModuleGraph; typ: PType; field: PSym,
|
||||||
result.ast[bodyPos].add v
|
result.ast[bodyPos].add v
|
||||||
let placeHolder = newNodeIT(nkSym, info, getSysType(g, info, tyPointer))
|
let placeHolder = newNodeIT(nkSym, info, getSysType(g, info, tyPointer))
|
||||||
fillBody(a, typ, result.ast[bodyPos], d, placeHolder)
|
fillBody(a, typ, result.ast[bodyPos], d, placeHolder)
|
||||||
|
if not a.canRaise: incl result.flags, sfNeverRaises
|
||||||
|
|
||||||
|
|
||||||
template liftTypeBoundOps*(c: PContext; typ: PType; info: TLineInfo) =
|
template liftTypeBoundOps*(c: PContext; typ: PType; info: TLineInfo) =
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue