Skip to content

Commit

Permalink
If-merge optimizations (#1618)
Browse files Browse the repository at this point in the history
These changes improve the compiler's type estimation of certain types of
if expressions.
  • Loading branch information
housel authored Jun 20, 2024
2 parents 3398f64 + a023760 commit aa565dc
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 4 deletions.
13 changes: 13 additions & 0 deletions documentation/source/release-notes/2024.2.rst
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,19 @@ Compiler
* The build rules for unified executables now properly depend on
copying included run-time libraries such as libunwind.

* Optimizations that allow the type of ``if`` expressions to be more
accurately estimated have been improved. For example, in this
function:

.. code-block::
define function if-example (arg :: false-or(<integer>)) => (result :: <integer>);
min(arg | 20, 30)
end;
the comparison can now be properly inlined because the first
argument to :drm:`min` is known to be an :drm:`<integer>`.

Tools
=====

Expand Down
10 changes: 8 additions & 2 deletions sources/dfmc/optimization/assignment.dylan
Original file line number Diff line number Diff line change
Expand Up @@ -190,14 +190,20 @@ define method maybe-rename-temporaries-in-conditional
(c.environment, <constrain-type>,
value: to-be-renamed, type: constraint);
let then-f = c.consequent;
let merge-c :: <if-merge> = c.next-computation;
let changed? = #f;
rename-temporary!(to-be-renamed, tt-t);
for-computations(tc from then-f before c.next-computation)
for-computations(tc from then-f before merge-c)
let now-changed? = rename-temporary-references!(tc, to-be-renamed, tt-t);
changed? := (changed? | now-changed?);
end;
// The left side of the merge is also part of the consequent
if (merge-c.merge-left-value == to-be-renamed)
merge-replace-left-value!(merge-c, to-be-renamed, tt-t);
changed? := #t;
end;
if (changed?)
insert-computation-before!(then-f, tt-c);
insert-computation-before-reference!(then-f, tt-c, tt-t);
else // It's not used in the consequent, so get rid of it.
remove-user!(to-be-renamed, tt-c);
end;
Expand Down
10 changes: 8 additions & 2 deletions sources/dfmc/optimization/calls.dylan
Original file line number Diff line number Diff line change
Expand Up @@ -79,13 +79,19 @@ define method do-optimize-instance?-user(c :: <if>, object, type) => ();
= make-with-temporary(c.environment, <constrain-type>,
value: object, type: type);
let then-f = c.consequent;
let merge-c :: <if-merge> = c.next-computation;
let changed? = #f;
for-computations(tc from then-f before c.next-computation)
for-computations(tc from then-f before merge-c)
let now-changed? = rename-temporary-references!(tc, object, tt-t);
changed? := (changed? | now-changed?);
end;
// The left side of the merge is also part of the consequent
if (merge-c.merge-left-value == object)
merge-replace-left-value!(merge-c, object, tt-t);
changed? := #t;
end;
if (changed?)
insert-computation-before!(then-f, tt-c);
insert-computation-before-reference!(then-f, tt-c, tt-t);
else // It's not used in the consequent, so get rid of it.
remove-user!(object, tt-c);
end
Expand Down

0 comments on commit aa565dc

Please sign in to comment.