On Thu, Jul 15, 2010 at 1:34 PM, Stefan Behnel <[email protected]> wrote:
> Stefan Behnel, 15.07.2010 19:34:
>> In most cases,
>> nodes and their results have to be reused, and there isn't currently a good
>> way to do that, especially not before type inference and analysis, which
>> may end up wanting to assign different types to the same node result in the
>> different contexts.
>
> Let's exercise this a bit. The min/max transformation is a perfect example
> here. It expands this code
>
> x = min(a,b,c)
>
> into this code
>
> x = a
> if x > b: x = b
> if x > c: x = c
>
> Now, you have to evaluate each input parameter exactly once, and each
> evaluation can potentially throw an exception. How would you do this in a
> source-level transformation? The only way I see is to introduce temp nodes
> already at this point,
Yep, you have to anyway to preserve the semantics.
> i.e. you'd make it
>
> x, _b, _c = a, b, c
> if x > _b: x = _b
> if x > _c: x = _c
>
> Next, to make the comparisons efficient if x has a Python type, _b and _c
> must have the same type as x.
The expanded code would be
res, _b, _c = a, b, c
if res > _b: res = _b
if res > _c: res = _c
# cleanup _b, _c
x = res
so the assignment (and type of the user-visible x) is orthogonal. Of
course, a could be an object too...One could even do
r1, _b, _c = a, b, c
r2 = r1 if r1 < _b else _b
r3 = r2 if r2 < _c else _c
so it stays in C land as long as possible, but that may not be worth it.
> Otherwise, both the comparison and the
> assignment would lead to redundant coercions. How would you assure that?
> Note that type inference will not work here, as it only impacts the type of
> x. All other type analysis steps are local.
>
> I can see us making it less local by injecting back-references to those
> nodes that depend on a node's type. That might allow us to minimise the
> number of neccessary coercions for a value. However, to do this right, we
> need flow analysis to even see which code paths actually lead to a coercion.
Hopefully a simple kind of common subexpression elimination could
remove the redundant coercions (as well as help out in a lot of other
places).
Also, the 1-value min/max could be optimized away, and the 2-value one could be
x = a if a < b else b
in conjunction with another possible optimization
(a if X else b).coerce_to(T)
becomes
a.coerce_to(T) if X else b.coerce_to(T)
- Robert
_______________________________________________
Cython-dev mailing list
[email protected]
http://codespeak.net/mailman/listinfo/cython-dev