| Issue 34: | Tuple assignments can overwrite source values |
‹ Prev
34 of 34
|
| 1 person starred this issue and may be notified of changes. | Back to list |
A tuple assignment like (a, b) = (b, a) gets translated to:
a = b
b = a
Obviously this is going to surprise the programmer! In this case a better translation would be:
t = a
a = b
b = t
In general, if a destination X is used in a source expression Y, then we need to first save X into temporary T, assign it as normal, but use T in any of the source expressions that rely on it.
Or perhaps a better way of looking at it: if destination X is used, instead of assigning to X, assign to temporary T. Later on after all elements are assigned (either to their destinations or to temporaries), assign from temporaries to the corresponding final destinations.
But it might be simpler to just do this for all tuple assignments: Assign to a tuple of temporaries first, then assign from that to the destinations. And then the magic of register allocation will simplify out all the redundant moves!
In the case of the above example, we'd have (with live variables after each statement):
/* a, b */
t1 = a /* t1, b */
t2 = b /* t1, t2 */
b = t1 /* t2, b */
a = t2 /* a, b */
b interferes with everything, but a does not interfere with either t1 or t2, and can share the same register as them. Since there's an assignment a = t2, it makes sense to share with t2. That instruction therefore compiles to a no-op, and we have the optimal three move swap.
Aug 23, 2015
Project Member
#1
ejrh00@gmail.com
Status:
WontFix
|