[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Small LAP peephole optimization
From: |
Ken Raeburn |
Subject: |
Re: Small LAP peephole optimization |
Date: |
Wed, 9 May 2007 12:54:44 -0400 |
On May 9, 2007, at 06:19, Dmitry Antipov wrote:
Hello again,
this is a minor LAP peephole optimization intended to remove redundant
'(byte-constant 0) (byte-plus . 0)' byte code insns. As an obvious
example, for
(disassemble (byte-compile '(lambda (x y) (+ x (* 2 y)))))
it will produce
0 varref x
1 varref y
2 dup
3 plus
4 plus
5 return
instead of current
0 varref x
1 varref y
2 dup
3 plus
4 constant 0
5 plus
6 plus
7 return
This looks like a nice little optimization, yes. But consider that
+0 is not always a no-op. If the other value is not numeric, an
error will be thrown, and in fact you could use the one-argument form
of + as a cheap way to test for a numeric value. So, in a less
obvious example:
(defun foo (x y) (+ (quux 2 y)))
becomes:
byte code for foo:
args: (x y)
0 constant quux
1 constant 2
2 varref y
3 call 2
4 constant 0
5 plus
6 return
Now if the author of "foo" isn't sure that "quux" is going to return
a numeric value, removing the addition changes the semantics of "foo".
During full bootstrap, this small optimization is performed for more
than 100 LAPs, thus removing ~400 byte code insns. It was also
tested by
byte-force-recompile of all lisp, and hopefully it works.
I would guess that in most of these cases it's a safe optimization,
but you should really check. If the previous operation is guaranteed
to leave a numeric value at the top of the stack, as in your example,
and no other code can branch to the +0 sequence, then you can do the
optimization; otherwise, you probably shouldn't. (An opcode like
plus that generates a numeric value if it doesn't throw an error is
easy. Harder is figuring out after popping values off the stack
whether the next value left at the top is numeric, especially in the
face of branches.)
Ken