Dag Sverre Seljebotn wrote: > Dag Sverre Seljebotn wrote: >> So: >> - Each node still flags whether it needs a result variable (i.e. the >> is_temp of today, or rather needs_target as I'll call it from here on). >> >> - Before the parent calls subexpr.generate_result_code, it has to check >> subexpr.needs_target. If True, the parent must call >> subexpr.set_target(some_cname) >> >> - If the parent doesn't have a variable handy to put the result in, it >> needs to allocate a temp, hand it to the child for it to store its >> result in, and finally release the temp when the result is no longer needed. > > OK, I've played with it a bit. Here's a couple of extra points. Summary: > I'm not satisfied with my proposal, and Stefan's original approach might > be better. > > With e.g. x = ((((a + b) + c) + d) + e), and also the reverse nesting, > the theoretical optimum is 1 temporary. My approach by default makes > O(depth) temps, because each parent makes a new temp; while the old > approach achieves 2 = O(1).
A way to get around this would be to split generate_result_code. So mainly my proposal, but with this modification: self.subexpr.preparation_code(code) tmp = code.funcstate.allocate_temp(...) self.subexpr.store_result_code(tmp, code) # do stuff # perhaps DECREF, the parent will know this and no # workarounds for when DECREF shouldn't happen is needed code.funcstate.release_temp(tmp) This leaves the flow of temps in control of the parent. So currently there is generate_result_code, generate_disposal_code which I propose replaced with preparation_code, store_result_code (generate_result_code mostly maps directly to store_result_code except that more efficient temp use can be had if one splits it. What generate_disposal_code does is moved to the parent -- I didn't find a situation where disposal_code does anything beyond temp handling). -- Dag Sverre _______________________________________________ Cython-dev mailing list [email protected] http://codespeak.net/mailman/listinfo/cython-dev
