An optimizer for ARC (#14962)

* WIP: an optimizer for ARC
* do not optimize away destructors in 'finally' if unstructured control flow is involved
* optimized the optimizer
* minor code cleanup
* first steps to .cursor inference
* cursor inference: big steps to a working solution
* baby steps
* better .cursor inference
* new feature: expandArc for easy inspection of the AST after ARC transformations
* added topt_cursor test
* adapt tests
* cleanups, make tests green
* optimize common traversal patterns
* moved test case
* fixes .cursor inference so that npeg compiles once again
* cursor inference: more bugfixes

Co-authored-by: Clyybber <darkmine956@gmail.com>
This commit is contained in:
Andreas Rumpf 2020-07-15 23:00:06 +02:00 • committed by GitHub
commit c5358b0d4b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
19 changed files with 895 additions and 62 deletions

View file

@ -0,0 +1,92 @@
discard """
output: ''''''
cmd: '''nim c --gc:arc --expandArc:main --expandArc:tfor --hint:Performance:off $file'''
nimout: '''--expandArc: main
var
a
b
x
x = f()
if cond:
add(a):
let blitTmp = x
blitTmp
else:
add(b):
let blitTmp_1 = x
blitTmp_1
`=destroy`(b)
`=destroy`(a)
-- end of expandArc ------------------------
--expandArc: tfor
var
a
b
x
try:
x = f()
block :tmp:
var i
var i_1 = 0
block :tmp_1:
while i_1 < 4:
var :tmpD
i = i_1
if i == 2:
return
add(a):
wasMoved(:tmpD)
`=`(:tmpD, x)
:tmpD
inc i_1, 1
if cond:
add(a):
let blitTmp = x
wasMoved(x)
blitTmp
else:
add(b):
let blitTmp_1 = x
wasMoved(x)
blitTmp_1
finally:
`=destroy`(x)
`=destroy_1`(b)
`=destroy_1`(a)
-- end of expandArc ------------------------'''
"""
proc f(): seq[int] =
@[1, 2, 3]
proc main(cond: bool) =
var a, b: seq[seq[int]]
var x = f()
if cond:
a.add x
else:
b.add x
# all paths move 'x' so no wasMoved(x); destroy(x) pair should be left in the
# AST.
main(false)
proc tfor(cond: bool) =
var a, b: seq[seq[int]]
var x = f()
for i in 0 ..< 4:
if i == 2: return
a.add x
if cond:
a.add x
else:
b.add x
tfor(false)