diff options
author | Araq <rumpf_a@web.de> | 2020-01-26 10:50:21 +0100 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2020-01-26 13:43:02 +0100 |
commit | a10cc18247cb576aa409e9056ed99f23539d14f9 (patch) | |
tree | 8ad1a8ac55ccb34b9438bbfb57476fcad01d7261 /compiler | |
parent | ab35f07e774c3faaee3708479523e66614eb3aa6 (diff) | |
download | Nim-a10cc18247cb576aa409e9056ed99f23539d14f9.tar.gz |
ARC: optimize complete object constructors to use nimNewObjUninit
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ast.nim | 2 | ||||
-rw-r--r-- | compiler/ccgexprs.nim | 24 | ||||
-rw-r--r-- | compiler/injectdestructors.nim | 6 | ||||
-rw-r--r-- | compiler/semobjconstr.nim | 3 |
4 files changed, 23 insertions, 12 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 733f60090..3d05fd2ca 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -1001,6 +1001,8 @@ const resultPos* = 7 dispatcherPos* = 8 + nfAllFieldsSet* = nfBase2 + nkCallKinds* = {nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit, nkHiddenCallConv} nkIdentKinds* = {nkIdent, nkSym, nkAccQuoted, nkOpenSymChoice, diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index c23b64257..84d491cf4 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -1197,7 +1197,7 @@ proc genDefault(p: BProc; n: PNode; d: var TLoc) = if d.k == locNone: getTemp(p, n.typ, d, needsInit=true) else: resetLoc(p, d) -proc rawGenNew(p: BProc, a: var TLoc, sizeExpr: Rope) = +proc rawGenNew(p: BProc, a: var TLoc, sizeExpr: Rope; needsInit: bool) = var sizeExpr = sizeExpr let typ = a.t var b: TLoc @@ -1209,8 +1209,12 @@ proc rawGenNew(p: BProc, a: var TLoc, sizeExpr: Rope) = sizeExpr = "sizeof($1)" % [getTypeDesc(p.module, bt)] if optTinyRtti in p.config.globalOptions: - b.r = ropecg(p.module, "($1) #nimNewObj($2)", - [getTypeDesc(p.module, typ), sizeExpr]) + if needsInit: + b.r = ropecg(p.module, "($1) #nimNewObj($2)", + [getTypeDesc(p.module, typ), sizeExpr]) + else: + b.r = ropecg(p.module, "($1) #nimNewObjUninit($2)", + [getTypeDesc(p.module, typ), sizeExpr]) genAssignment(p, a, b, {}) else: let ti = genTypeInfo(p.module, typ, a.lode.info) @@ -1254,9 +1258,9 @@ proc genNew(p: BProc, e: PNode) = if e.len == 3: var se: TLoc initLocExpr(p, e[2], se) - rawGenNew(p, a, se.rdLoc) + rawGenNew(p, a, se.rdLoc, needsInit = true) else: - rawGenNew(p, a, nil) + rawGenNew(p, a, nil, needsInit = true) gcUsage(p.config, e) proc genNewSeqAux(p: BProc, dest: TLoc, length: Rope; lenIsZero: bool) = @@ -1356,7 +1360,7 @@ proc genObjConstr(p: BProc, e: PNode, d: var TLoc) = getTemp(p, t, tmp) r = rdLoc(tmp) if isRef: - rawGenNew(p, tmp, nil) + rawGenNew(p, tmp, nil, needsInit = nfAllFieldsSet notin e.flags) t = t.lastSon.skipTypes(abstractInstOwned) r = "(*$1)" % [r] gcUsage(p.config, e) @@ -2180,7 +2184,7 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) = if optTinyRtti in p.config.globalOptions: var a: TLoc initLocExpr(p, e[1], a) - rawGenNew(p, a, nil) + rawGenNew(p, a, nil, needsInit = true) gcUsage(p.config, e) else: genNewFinalize(p, e) @@ -2811,7 +2815,7 @@ proc getNullValueAux(p: BProc; t: PType; obj, constOrNil: PNode, # else branch selectedBranch = i assert(selectedBranch >= 1) - + result.add "{" var countB = 0 let b = lastSon(obj[selectedBranch]) @@ -2822,10 +2826,10 @@ proc getNullValueAux(p: BProc; t: PType; obj, constOrNil: PNode, getNullValueAux(p, t, b, constOrNil, result, countB, isConst, info) result.add "}" elif b.kind == nkSym: - result.add "." & mangleRecFieldName(p.module, b.sym) & " = " + result.add "." & mangleRecFieldName(p.module, b.sym) & " = " getNullValueAux(p, t, b, constOrNil, result, countB, isConst, info) result.add "}" - + of nkSym: if count > 0: result.add ", " inc count diff --git a/compiler/injectdestructors.nim b/compiler/injectdestructors.nim index 27171ced6..dc431ef38 100644 --- a/compiler/injectdestructors.nim +++ b/compiler/injectdestructors.nim @@ -485,7 +485,8 @@ proc cycleCheck(n: PNode; c: var Con) = break proc p(n: PNode; c: var Con; mode: ProcessMode): PNode = - if n.kind in {nkStmtList, nkStmtListExpr, nkBlockStmt, nkBlockExpr, nkIfStmt, nkIfExpr, nkCaseStmt, nkWhen}: + if n.kind in {nkStmtList, nkStmtListExpr, nkBlockStmt, nkBlockExpr, nkIfStmt, + nkIfExpr, nkCaseStmt, nkWhen}: handleNested(n): p(node, c, mode) elif mode == sinkArg: if n.containsConstSeq: @@ -493,7 +494,8 @@ proc p(n: PNode; c: var Con; mode: ProcessMode): PNode = # sink parameter (bug #11524). Note that the string implementation is # different and can deal with 'const string sunk into var'. result = passCopyToSink(n, c) - elif n.kind in {nkBracket, nkObjConstr, nkTupleConstr, nkClosure} + nkCallKinds + nkLiterals: + elif n.kind in {nkBracket, nkObjConstr, nkTupleConstr, nkClosure, nkNilLit} + + nkCallKinds + nkLiterals: result = p(n, c, consumed) elif n.kind == nkSym and isSinkParam(n.sym): # Sinked params can be consumed only once. We need to reset the memory diff --git a/compiler/semobjconstr.nim b/compiler/semobjconstr.nim index 0ddec1706..489bc6684 100644 --- a/compiler/semobjconstr.nim +++ b/compiler/semobjconstr.nim @@ -388,3 +388,6 @@ proc semObjConstr(c: PContext, n: PNode, flags: TExprFlags): PNode = # 2) No such field exists in the constructed type localError(c.config, field.info, errUndeclaredFieldX % id.s) return + + if initResult == initFull: + incl result.flags, nfAllFieldsSet |