due: Friday, April 13, in class
Suppose we want to add a new kind of type to Iota, similar to C++ anonymous union types to Iota. Let the type expression
union { a:T1 b:T2 }denote a type whose values may be either a value of type
T1
or a value of type
T2
, tagged with some
information about which of the two is present. This kind of type is
sometimes known as a variant record.
Unlike C++ unions, our unions are type-safe: they keep track of which one of the fields currently contains a value.
If an attempt is made to read one of the other union fields, the result
is null
. Assigning into a union field sets that field as the current
field. Here is an example of the use of unions:
x: union { color: Color shape: Shape } red: Color square: Shape ... x.color = red; // x now contains the color red if (x.shape) print("It can't happen here"); x.shape = square; // now x contains the shape square, //and not the color red if (x.color) print("Can't happen here either");
union
{x1:T1,
..., xn:Tn} make sense?
n´m Ti <: T'i i21..n |
|
union {f1: T1,
..., fn: Tn} <: union {f1:
T'1, ..., fn: T'n,
..., fm: T'm} |
x=y
, we replace subsequent uses of x
with uses of y
if there are no intervening instructions that change
either x
or y
. For example, the code
c = a + b d = a e = d + b d = d * 2 f = d + b
becomes, after propagation of the copied value in a
to the
appropriate uses of d
,
c = a + b d = a e = a + b d = a * 2 f = d + b
Copy propagation is useful because it can create dead code, such as the first assignment to d
, and new opportunities for optimization, such as common
subexpression elimination on a + b
. It is easy to do copy propagation within a basic block, but for the
more general case of a control flow graph, we perform a dataflow analysis
to determine which copy assignments reach uses of their left-hand
variables without having either variable redefined. An element of the lattice on
which the dataflow analysis operates is a set of copy assignments,
which are pairs (x
,y
). Each such copy assignment indicates that the variable
x
contains a copy of the variable y
.
Is this properly a forward or backward data-flow analysis?
What combining operator u should be used?
What are the top and bottom elements of the lattice?
Let
x = y
x = a1 OP a2
if x goto L1 else L2
goto L1
x = f(a1, a2, ..., an)
Define the flow function Fn(x) for a node n in terms of GEN(n) and KILL(n)
Draw a control flow graph for the following code:
y = b a = y L1: x = a z = y*2 y = f(x) y = y + z c = x < b; if (c) goto L1 else L2 L2: y = a + 1