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

@ -1,5 +1,6 @@
discard """
output: '''assign
output: '''
assign
destroy
destroy
5
@ -104,12 +105,12 @@ test()
#------------------------------------------------------------
# Issue #12883
type
type
TopObject = object
internal: UniquePtr[int]
proc deleteTop(p: ptr TopObject) =
if p != nil:
if p != nil:
`=destroy`(p[]) # !!! this operation used to leak the integer
deallocshared(p)
@ -117,12 +118,12 @@ proc createTop(): ptr TopObject =
result = cast[ptr TopObject](allocShared0(sizeof(TopObject)))
result.internal = newUniquePtr(1)
proc test2() =
proc test2() =
let x = createTop()
echo $x.internal
deleteTop(x)
echo "---------------"
echo "---------------"
echo "app begin"
test2()
echo "app end"

View file

@ -21,11 +21,13 @@ proc `=sink`(dest: var Foo, src: Foo) =
proc `=`(dest: var Foo, src: Foo) =
assign_counter.inc
proc createFoo(): Foo = Foo(boo: 0)
proc test(): auto =
var a, b: Foo
var a, b = createFoo()
return (a, b, Foo(boo: 5))
var (a, b, _) = test()
var (ag, bg, _) = test()
doAssert assign_counter == 0
doAssert sink_counter == 0

View file

@ -17,15 +17,20 @@ proc `=sink`(self: var Foo; other: Foo) =
proc `=destroy`(self: var Foo) = discard
template preventCursorInference(x) =
let p = unsafeAddr(x)
proc test(): Foo =
result = Foo()
let temp = result
preventCursorInference temp
doAssert temp.i > 0
return result
proc testB(): Foo =
result = Foo()
let temp = result
preventCursorInference temp
doAssert temp.i > 0
discard test()