mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-31 02:12:11 +00:00
fixes #4354
This commit is contained in:
@@ -1151,7 +1151,25 @@ proc genNewSeqOfCap(p: BProc; e: PNode; d: var TLoc) =
|
||||
genTypeInfo(p.module, seqtype), a.rdLoc]))
|
||||
gcUsage(e)
|
||||
|
||||
proc genConstExpr(p: BProc, n: PNode): Rope
|
||||
proc handleConstExpr(p: BProc, n: PNode, d: var TLoc): bool =
|
||||
if d.k == locNone and n.len > ord(n.kind == nkObjConstr) and n.isDeepConstExpr:
|
||||
var t = getUniqueType(n.typ)
|
||||
discard getTypeDesc(p.module, t) # so that any fields are initialized
|
||||
let id = nodeTableTestOrSet(p.module.dataCache, n, p.module.labels)
|
||||
fillLoc(d, locData, t, p.module.tmpBase & rope(id), OnStatic)
|
||||
if id == p.module.labels:
|
||||
# expression not found in the cache:
|
||||
inc(p.module.labels)
|
||||
addf(p.module.s[cfsData], "NIM_CONST $1 $2 = $3;$n",
|
||||
[getTypeDesc(p.module, t), d.r, genConstExpr(p, n)])
|
||||
result = true
|
||||
else:
|
||||
result = false
|
||||
|
||||
proc genObjConstr(p: BProc, e: PNode, d: var TLoc) =
|
||||
if handleConstExpr(p, e, d): return
|
||||
#echo rendertree e, " ", e.isDeepConstExpr
|
||||
var tmp: TLoc
|
||||
var t = e.typ.skipTypes(abstractInst)
|
||||
getTemp(p, t, tmp)
|
||||
@@ -1769,22 +1787,6 @@ proc genMagicExpr(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||
of mDotDot, mEqCString: genCall(p, e, d)
|
||||
else: internalError(e.info, "genMagicExpr: " & $op)
|
||||
|
||||
proc genConstExpr(p: BProc, n: PNode): Rope
|
||||
proc handleConstExpr(p: BProc, n: PNode, d: var TLoc): bool =
|
||||
if nfAllConst in n.flags and d.k == locNone and n.len > 0 and n.isDeepConstExpr:
|
||||
var t = getUniqueType(n.typ)
|
||||
discard getTypeDesc(p.module, t) # so that any fields are initialized
|
||||
let id = nodeTableTestOrSet(p.module.dataCache, n, p.module.labels)
|
||||
fillLoc(d, locData, t, p.module.tmpBase & rope(id), OnStatic)
|
||||
if id == p.module.labels:
|
||||
# expression not found in the cache:
|
||||
inc(p.module.labels)
|
||||
addf(p.module.s[cfsData], "NIM_CONST $1 $2 = $3;$n",
|
||||
[getTypeDesc(p.module, t), d.r, genConstExpr(p, n)])
|
||||
result = true
|
||||
else:
|
||||
result = false
|
||||
|
||||
proc genSetConstr(p: BProc, e: PNode, d: var TLoc) =
|
||||
# example: { a..b, c, d, e, f..g }
|
||||
# we have to emit an expression of the form:
|
||||
|
||||
@@ -103,14 +103,16 @@ proc getMagic*(op: PNode): TMagic =
|
||||
else: result = mNone
|
||||
else: result = mNone
|
||||
|
||||
proc treeToSym*(t: PNode): PSym =
|
||||
result = t.sym
|
||||
|
||||
proc isConstExpr*(n: PNode): bool =
|
||||
result = (n.kind in
|
||||
{nkCharLit..nkInt64Lit, nkStrLit..nkTripleStrLit,
|
||||
nkFloatLit..nkFloat64Lit, nkNilLit}) or (nfAllConst in n.flags)
|
||||
|
||||
proc isCaseObj*(n: PNode): bool =
|
||||
if n.kind == nkRecCase: return true
|
||||
for i in 0..<safeLen(n):
|
||||
if n[i].isCaseObj: return true
|
||||
|
||||
proc isDeepConstExpr*(n: PNode): bool =
|
||||
case n.kind
|
||||
of nkCharLit..nkInt64Lit, nkStrLit..nkTripleStrLit,
|
||||
@@ -119,11 +121,14 @@ proc isDeepConstExpr*(n: PNode): bool =
|
||||
of nkExprEqExpr, nkExprColonExpr, nkHiddenStdConv, nkHiddenSubConv:
|
||||
result = isDeepConstExpr(n.sons[1])
|
||||
of nkCurly, nkBracket, nkPar, nkObjConstr, nkClosure:
|
||||
for i in 0 .. <n.len:
|
||||
for i in ord(n.kind == nkObjConstr) .. <n.len:
|
||||
if not isDeepConstExpr(n.sons[i]): return false
|
||||
# XXX once constant objects are supported by the codegen this needs to be
|
||||
# weakened:
|
||||
result = n.typ.isNil or n.typ.skipTypes({tyGenericInst, tyDistinct}).kind != tyObject
|
||||
if n.typ.isNil: result = true
|
||||
else:
|
||||
let t = n.typ.skipTypes({tyGenericInst, tyDistinct})
|
||||
if t.kind in {tyRef, tyPtr}: return false
|
||||
if t.kind != tyObject or not isCaseObj(t.n):
|
||||
result = true
|
||||
else: discard
|
||||
|
||||
proc flattenTreeAux(d, a: PNode, op: TMagic) =
|
||||
|
||||
27
tests/ccgbugs/tinefficient_const_table.nim
Normal file
27
tests/ccgbugs/tinefficient_const_table.nim
Normal file
@@ -0,0 +1,27 @@
|
||||
discard """
|
||||
output: '''a
|
||||
long
|
||||
list
|
||||
of
|
||||
words'''
|
||||
cmd: r"nim c --hints:on $options -d:release $file"
|
||||
ccodecheck: "! @'genericSeqAssign'"
|
||||
"""
|
||||
|
||||
|
||||
# bug #4354
|
||||
import tables
|
||||
import sets
|
||||
import strutils
|
||||
|
||||
#const FRUITS = ["banana", "apple", "grapes"]
|
||||
#let FRUITS = ["banana", "apple", "grapes"].toSet
|
||||
const FRUITS = {"banana":0, "apple":0, "grapes":0}.toTable
|
||||
|
||||
proc main() =
|
||||
let L = "a long list of words".split()
|
||||
for word in L:
|
||||
if word notin FRUITS:
|
||||
echo(word)
|
||||
|
||||
main()
|
||||
Reference in New Issue
Block a user