ARC Analysis in one pass v3 (#17068)

* Analyse last reads all at once

* Integrate firstWrite analysis

* Small cleanup

* Use sets instead of seqs

* Remove instrTargets

* Reap the benefits

* Implement error diagnostics

* Operate on DFA index for lastRead analysis

* Use mgetOrPut

* Cache alias results

This improves performance by a lot, since many
CFG locations map to a single PNode

* Improve performance

* Improve performance

* Cleanup

* Fix #17025

* Grammar

* Expand testcase
This commit is contained in:
Clyybber 2021-02-17 14:17:35 +01:00 • committed by GitHub
commit aa3af9e053
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 208 additions and 130 deletions

56
tests/arc/t17025.nim Normal file
View file

@ -0,0 +1,56 @@
discard """
cmd: "nim c --gc:arc $file"
output: '''
{"Package": {"name": "hello"}, "Author": {"name": "name", "qq": "123456789", "email": "email"}}
hello
name
123456789
email
hello
name2
987654321
liame
'''
"""
import parsecfg, streams, tables
const cfg = """[Package]
name=hello
[Author]
name=name
qq=123456789
email="email""""
proc main() =
let stream = newStringStream(cfg)
let dict = loadConfig(stream)
var pname = dict.getSectionValue("Package","name")
var name = dict.getSectionValue("Author","name")
var qq = dict.getSectionValue("Author","qq")
var email = dict.getSectionValue("Author","email")
echo dict[]
echo pname & "\n" & name & "\n" & qq & "\n" & email
stream.close()
main()
proc getDict(): OrderedTableRef[string, OrderedTableRef[string, string]] =
result = newOrderedTable[string, OrderedTableRef[string, string]]()
result["Package"] = newOrderedTable[string, string]()
result["Package"]["name"] = "hello"
result["Author"] = newOrderedTable[string, string]()
result["Author"]["name"] = "name2"
result["Author"]["qq"] = "987654321"
result["Author"]["email"] = "liame"
proc main2() =
let dict = getDict()
var pname = dict.getSectionValue("Package","name")
var name = dict.getSectionValue("Author","name")
var qq = dict.getSectionValue("Author","qq")
var email = dict.getSectionValue("Author","email")
echo pname & "\n" & name & "\n" & qq & "\n" & email
main2()

View file

@ -93,7 +93,6 @@ destroy
destroy
destroy
sink
sink
destroy
copy
(f: 1)
@ -687,7 +686,7 @@ caseNotAConstant()
proc potentialSelfAssign(i: var int) =
var a: array[2, OO]
a[i] = OO(f: 1)
a[i] = OO(f: 1) # turned into a memcopy
a[1] = OO(f: 2)
a[i+1] = a[i] # This must not =sink, but =copy
inc i
@ -744,3 +743,30 @@ proc partToWholeUnownedRef =
partToWholeUnownedRef()
#--------------------------------------------------------------------
# test that nodes that get copied during the transformation
# (like dot exprs) don't loose their firstWrite/lastRead property
type
OOO = object
initialized: bool
C = object
o: OOO
proc `=destroy`(o: var OOO) =
doAssert o.initialized, "OOO was destroyed before initialization!"
proc initO(): OOO =
OOO(initialized: true)
proc initC(): C =
C(o: initO())
proc pair(): tuple[a: C, b: C] =
result.a = initC() # <- when firstWrite tries to find this node to start its analysis it fails, because injectdestructors uses copyTree/shallowCopy
result.b = initC()
discard pair()

View file

@ -56,7 +56,7 @@ _ = (
blitTmp, ";")
lvalue = _[0]
lnext = _[1]
`=sink`(result.value, move lvalue)
result.value = move lvalue
`=destroy`(lnext)
`=destroy_1`(lvalue)
-- end of expandArc ------------------------