diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2023-12-20 06:47:34 -0800 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2023-12-20 06:47:34 -0800 |
commit | 8c68a36a88ec6fd056307b2eb13a3e8ab6eb0c42 (patch) | |
tree | d1d05fd8ad9e4a351251678c02f2a9e00087d4a9 /tests/016 | |
parent | b811679fd881573b13d0a957f9f78889d5a9d69a (diff) | |
download | txr-8c68a36a88ec6fd056307b2eb13a3e8ab6eb0c42.tar.gz txr-8c68a36a88ec6fd056307b2eb13a3e8ab6eb0c42.tar.bz2 txr-8c68a36a88ec6fd056307b2eb13a3e8ab6eb0c42.zip |
compiler: optimizer must watch for throwing constant exprs
We have these issues, which are regressions:
1> (compile-toplevel '(/ 1 0))
** expr-1:1: warning: sys:b/: constant expression (sys:b/ 1 0) throws
** /: division by zero
** during evaluation at expr-1:1 of form (sys:b/ 1 0)
1> (compile-toplevel '(let ((a 1) (b 0)) (/ a b)))
** /: division by zero
** during evaluation at expr-1:1 of form (compile-toplevel [...])
While the compiler's early pass constant folding is careful
to detect constant expressions that throw, care was not taken
in the optimizer's later constant folding which takes place
after constant values are propagated around.
After the fix:
1> (compile-toplevel '(let ((a 1) (b 0) (c t)) (if c (/ a b))))
** expr-1:1: warning: let: function sys:b/ with arguments (1 0) throws
#<sys:vm-desc: 9aceb20>
2> (compile-toplevel '(let ((a 1) (b 0) (c nil)) (if c (/ a b))))
#<sys:vm-desc: 9aef9f0>
* stdlib/compiler.tl (compiler): New slot top-form.
(compile-toplevel): Initialize the top-form slot of the
compiler. The optimizer uses this to issue a warning now.
Since the warning is based on analyzing generated code, we
cannot trace it to the code more precisely than to the top-level
form.
* stdlib/optimize.tl (basic-blocks): New slot, warned-insns.
List of instructions that have been warned about.
(basic-blocks do-peephole-block): Rearrange the constant folding
case so that as part of the pattern match condition, we include
the fact that the function will not throw when called with those
constant arguments. Only in that case do we do the optimization.
We warn in the case when the function call does throw.
A function rejected due to throwing could be processed through
this rule multiple times, under multiple peephole passes, so
for that reason we use the warned-insns list to suppress duplicate
warnings.
Diffstat (limited to 'tests/016')
0 files changed, 0 insertions, 0 deletions