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

View file

@ -632,8 +632,10 @@ proc aliases*(obj, field: PNode): AliasKind =
case currFieldPath.kind
of nkSym:
if currFieldPath.sym != currObjPath.sym: return no
of nkDotExpr, nkCheckedFieldExpr:
of nkDotExpr:
if currFieldPath[1].sym != currObjPath[1].sym: return no
of nkCheckedFieldExpr:
if currFieldPath[0][1].sym != currObjPath[0][1].sym: return no
of nkBracketExpr:
if currFieldPath[1].kind in nkLiterals and currObjPath[1].kind in nkLiterals:
if currFieldPath[1].intVal != currObjPath[1].intVal:
@ -642,19 +644,6 @@ proc aliases*(obj, field: PNode): AliasKind =
result = maybe
else: assert false # unreachable
type InstrTargetKind* = enum
None, Full, Partial
proc instrTargets*(insloc, loc: PNode): InstrTargetKind =
case insloc.aliases(loc)
of yes:
Full # x -> x; x -> x.f
of maybe:
Partial # We treat this like a partial write/read
elif loc.aliases(insloc) != no:
Partial # x.f -> x
else: None
proc isAnalysableFieldAccess*(orig: PNode; owner: PSym): bool =
var n = orig
while true: