next up previous contents
Next: 9 Basic Blocks and Up: 8 Intermediate Code Previous: 8.1 Translating Variables, Records,   Contents

8.2 Control Statements

Statements, such as for-loop and while-loop, are translated into IR statements that contain jumps and conditional jumps.

The while loop while c do body; is evaluated in the following way:

loop: if c goto cont else goto done
cont: body
      goto loop
done:
which corresponds to the following IR:
SEQ(LABEL(loop),
    CJUMP(EQ,c,1,NAME(done),NAME(cont)),
    LABEL(cont),
    s,
    JUMP(NAME(loop)),
    LABEL(done))
The for statement for i:=lo to hi do body is evaluated in the following way:
      i := lo
      j := hi
      if i>j goto done
loop: body
      i := i+1
      if i<=j goto loop
done:
The break statement is translated into a JUMP. The compiler keeps track which label to JUMP to on a ``break" statement by maintaining a stack of labels that holds the ``done:" labels of the for- or while-loop. When it compiles a loop, it pushes the label in the stack, and when it exits a loop, it pops the stack. The break statement is thus translated into a JUMP to the label at the top of the stack.

A function call f(a1,...,an) is translated into the IR CALL(NAME(l_f),[sl,e1,...,en]), where l_r is the label of the first statement of the f code, sl is the static link, and ei is the IR for ai. For example, if the difference between the static levels of the caller and callee is one, then sl is MEM(+(TEMP(fp),CONST(static))), where static is the offset of the static link in a frame. That is, we follow the static link once. The code generated for the body of the function f is a sequence which contains the prolog, the code of f, and the epilogue, as it was discussed in Section 7.

For example, suppose that records and vectors are implemented as pointers (i.e. memory addresses) to dynamically allocated data in the heap. Consider the following declarations:

struct { X: int, Y: int, Z: int } S;      /* a record */
int i;
int V[10][10];                            /* a vector of vectors */
where the variables S, i, and V are stored in the current frame with offsets -16, -20, and -24 respectively. By using the following abbreviations:

S = MEM(+(TEMP(fp),CONST(-16)))
I = MEM(+(TEMP(fp),CONST(-20)))
V = MEM(+(TEMP(fp),CONST(-24)))
we have the following IR translations:

S.Z+S.X
  --> +(MEM(+(S,CONST(8))),MEM(S))

if (i<10) then S.Y := i else i := i-1
  --> SEQ(CJUMP(LT,I,CONST(10),trueL,falseL),
          LABEL(trueL),
          MOVE(MEM(+(S,CONST(4))),I),
          JUMP(exit),
          LABEL(falseL),
          MOVE(I,-(I,CONST(1))),
          JUMP(exit),
          LABEL(exit))

V[i][i+1] := V[i][i]+1
  --> MOVE(MEM(+(MEM(+(V,*(I,CONST(4)))),*(+(I,CONST(1)),CONST(4)))),
           MEM(+(MEM(+(V,*(I,CONST(4)))),*(I,CONST(4)))))

for i:=0 to 9 do V[0][i] := i
  --> SEQ(MOVE(I,CONST(0)),
          MOVE(TEMP(t1),CONST(9)),
          CJUMP(GT,I,TEMP(t1),done,loop),
          LABEL(loop),
          MOVE(MEM(+(MEM(V),*(I,CONST(4)))),I),
          MOVE(I,+(I,CONST(1))),
          CJUMP(LEQ,I,TEMP(t1),loop,done),
          LABEL(done))


next up previous contents
Next: 9 Basic Blocks and Up: 8 Intermediate Code Previous: 8.1 Translating Variables, Records,   Contents
fegaras 2012-01-10