With this optimisation we 'remove' return types whose values are the same as one of the arguments. I.e., the returned value is unchanged. A prominent example of this is the identity function.
If we encounter an application that has an unmodified return type, we lookup which actual argument corresponds to that return value and replace any following uses of that return value by that actual argument (N_id) instead. Consider the following example:
int main() {
a = 37;
b = 42;
c = second (a, b);
return c;
}
Where second
returns the second value of the two given arguments. Because
this function keeps that return value unchanged, the N_ret is marked as being
the same as its second argument, after which any occurences of c
can be
replaced by b
.
int main() {
a = 37;
b = 42;
c = second (a, b); // can now be removed by dead code removal
return b; // c becomes b
}
Requires a new identity function in mini-stdlib.sac
to avoid fusion in tests, because this optimisation breaks some tests otherwise.