# Translating C to C — An example

## The C statement

Let’s look at some C code to set an integer `m` to the larger of the integers `x`, `y`, and `z`.

```if (x >= y && x >= z) {
m = x ;
} else if (y >= z) {
m = y ;
} else {
m = z ;
}
```

If you use the rules of the control structures section, which ignores expression evaluation, you’ll get something like the following:

```      int τ1 = x >= y && x >= z ;
if (τ1 == 0) goto λ1 ;
m = x ;
goto λ3 ;
λ1:   int τ2 = y >= z ;
if (τ2 == 0) goto λ2 ;
m = y ;
goto λ3 ;
λ2:   m = z ;
λ3:
```

Now we have to worry about evaluating the expression with the `&&`. Here we use the rules for dealing with logical expression. This is going to get very messy. First, we get the following:

```      int τ1 ;
if (! (x >= y)) {
τ1 = 0 ;
} else if (! (x >= z)) {
τ1 = 0 ;
} else {
τ1 = 1 ;
}
if (τ1 == 0) goto λ1 ;
m = x ;
goto λ3 ;
λ1:   int τ2 = y >= z ;
if (τ2 == 0) goto λ2 ;
m = y ;
goto λ3 ;
λ2:   m = z ;
λ3:
```

Then we go back and apply the rules of the `if``else`, and it gets even worse.

```      int τ1 ;
int τ3 = ! (x >= y) ;
if (τ3 == 0) goto λ4 ;
τ1 = 0 ;
goto λ6 ;
λ4:   int τ4 = ! (x >= z) ;
if (τ4 == 0) goto λ5 ;
τ1 = 0 ;
goto λ6 ;
λ5:   τ1 = 1 ;
λ6:   if (τ1 == 0) goto λ1 ;
m = x ;
goto λ3 ;
λ1:   int τ2 = y >= z ;
if (τ2 == 0) goto λ2 ;
m = y ;
goto λ3 ;
λ2:   m = z ;
λ3:
```

## Huh?

Yep. That’s pretty silly. Let’s do some optimiztions. First simplify those comparisions.

```      int τ1 ;
int τ3 = (x < y) ;
if (τ3 == 0) goto λ4 ;
τ1 = 0 ;
goto λ6 ;
λ4:   int τ4 = (x < z) ;
if (τ4 == 0) goto λ5 ;
τ1 = 0 ;
goto λ6 ;
λ5:   τ1 = 1 ;
λ6:   if (τ1 == 0) goto λ1 ;
m = x ;
goto λ3 ;
λ1:   int τ2 = y >= z ;
if (τ2 == 0) goto λ2 ;
m = y ;
goto λ3 ;
λ2:   m = z ;
λ3:
```

There are some branching inefficiences here. For example, in one place `τ1` is set to 0 before a transfer to `λ6` where `τ1` is immediately compared to 0 before transfering to `λ1`. Let’s speed that up a little. We can even eliminate `τ1`.

```      int τ3 = (x < y) ;
if (τ3 == 0) goto λ4 ;
goto λ1 ;
λ4:   int τ4 = (x < z) ;
if (τ4 == 0) goto λ5 ;
goto λ1 ;
λ5:   m = x ;
goto λ3 ;
λ1:   int τ2 = y >= z ;
if (τ2 == 0) goto λ2 ;
m = y ;
goto λ3 ;
λ2:   m = z ;
λ3:
```

Next we can remove a few of those unconditional `goto`’s by optimizing the tests.

```      int τ3 = (x < y) ;
if (τ3 != 0) goto λ1 ;
int τ4 = (x < z) ;
if (τ4 != 0) goto λ1 ;
m = x ;
goto λ3 ;
λ1:   int τ2 = y >= z ;
if (τ2 == 0) goto λ2 ;
m = y ;
goto λ3 ;
λ2:   m = z ;
λ3:
```

You might find this a little easier to read if we just got rid of `τ2`, `τ3`, and `τ4`.

```      if (x < y) goto λ1 ;
if (x < z) goto λ1 ;
m = x ;
goto λ3 ;
λ1:   if (y < z) goto λ2 ;
m = y ;
goto λ3 ;
λ2:   m = z ;
λ3:
```

That’s what any self respecting C compiler would do.