• 沒有找到結果。

INTERMEDIATE REPRESENTATION TREES

在文檔中 Modern Compiler Implementation in C (頁 162-165)

Activation Records

4. Some architectures have register windows, so that each function invocation can allocate a fresh set of registers without memory traffic

7.1 INTERMEDIATE REPRESENTATION TREES

FIGURE 7.1. Compilers for five languages and four target machines:

(left) without an IR, (right) with an IR.

7.1 INTERMEDIATE REPRESENTATION TREES

The intermediate representation tree language is defined by the interface tree.h, as shown inFigure 7.2.

A good intermediate representation has several qualities:

• It must be convenient for the semantic analysis phase to produce.

• It must be convenient to translate into real machine language, for all the de-sired target machines.

• Each construct must have a clear and simple meaning, so that optimizing transformations that rewrite the intermediate representation can easily be spec-ified and implemented.

Individual pieces of abstract syntax can be complicated things, such as array subscripts, procedure calls, and so on. And individual “real machine”

instructions can also have a complicated effect (though this is less true of modern RISC machines than of earlier architectures). Unfortunately, it is not always the case that complex pieces of the abstract syntax correspond exactly to the complex instructions that a machine can execute.

Therefore, the intermediate representation should have individual compo-nents that describe only extremely simple things: a single fetch, store, add, move, or jump. Then any “chunky” piece of abstract syntax can be trans-lated into just the right set of abstract machine instructions; and groups of abstract machine instructions can be clumped together (perhaps in quite dif-ferent clumps) to form “real” machine instructions.

Here is a description of the meaning of each tree operator. First, the

ex-/* tree.h */

typedef struct T_stm_ *T_stm;

struct T_stm_ {enum {T_SEQ, T_LABEL, T_JUMP, . . ., T_EXP} kind;

union {struct {T_stm left, right;} SEQ;

.. . } u; };

T_stm T_Seq(T_stm left, T_stm right);

T_stm T_Label(Temp_label);

T_stm T_Jump(T_exp exp, Temp_labelList labels);

T_stm T_Cjump(T_relOp op, T_exp left, T_exp right, Temp_label true, Temp_label false);

T_stm T_Move(T_exp, T_exp);

T_stm T_Exp(T_exp);

typedef struct T_exp_ *T_exp;

struct T_exp_ {enum {T_BINOP, T_MEM, T_TEMP, . . ., T_CALL} kind;

union {struct {T_binOp op; T_exp left, right;} BINOP;

.. . } u; };

T_exp T_Binop(T_binOp, T_exp, T_exp);

T_exp T_Mem(T_exp);

T_exp T_Temp(Temp_temp);

T_exp T_Eseq(T_stm, T_exp);

T_exp T_Name(Temp_label);

T_exp T_Const(int);

T_exp T_Call(T_exp, T_expList);

typedef struct T_expList_ *T_expList;

struct T_expList_ {T_exp head; T_expList tail;};

T_expList T_ExpList (T_exp head, T_expList tail);

typedef struct T_stmList_ *T_stmList;

struct T_stmList_ {T_stm head; T_stmList tail;};

T_stmList T_StmList (T_stm head, T_stmList tail);

typedef enum {T_plus, T_minus, T_mul, T_div, T_and, T_or, T_lshift, T_rshift, T_arshift, T_xor} T_binOp ; typedef enum {T_eq, T_ne, T_lt, T_gt, T_le, T_ge,

T_ult, T_ule, T_ugt, T_uge} T_relOp;

FIGURE 7.2. Intermediate representation trees.

7.1. INTERMEDIATE REPRESENTATION TREES

pressions (T_exp), which stand for the computation of some value (possibly with side effects):

CONST(i) The integer constant i. Written in C as T_Const(i).

NAME(n) The symbolic constant n (corresponding to an assembly language la-bel). Written in C as T_Name(n).

TEMP(t) Temporary t. A temporary in the abstract machine is similar to a reg-ister in a real machine. However, the abstract machine has an infinite number of temporaries.

BINOP(o, e1,e2) The application of binary operator o to operands e1,e2. Subex-pression e1is evaluated before e2. The integer arithmetic operators arePLUS,

MINUS, MUL, DIV; the integer bitwise logical operators areAND, OR, XOR; the integer logical shift operators areLSHIFT,RSHIFT; the integer arithmetic right-shift is ARSHIFT. The Tiger language has no logical operators, but the intermediate language is meant to be independent of any source language;

also, the logical operators might be used in implementing other features of Tiger.

MEM(e) The contents of wordSize bytes of memory starting at address e (where wordSizeis defined in the Frame module). Note that whenMEMis used as the left child of aMOVE, it means “store,” but anywhere else it means “fetch.”

CALL(f, l) A procedure call: the application of function f to argument list l.

The subexpression f is evaluated before the arguments which are evaluated left to right.

ESEQ(s, e) The statement s is evaluated for side effects, then e is evaluated for a result.

The statements (T_stm) of the tree language perform side effects and con-trol flow:

MOVE(TEMPt, e) Evaluate e and move it into temporary t.

MOVE(MEM(e1), e2) Evaluate e1, yielding address a. Then evaluate e2, and store the result into wordSize bytes of memory starting at a.

EXP(e) Evaluate e and discard the result.

JUMP(e, labs) Transfer control (jump) to address e. The destination e may be a literal label, as inNAME(lab), or it may be an address calculated by any other kind of expression. For example, a C-language switch(i) statement may be implemented by doing arithmetic on i. The list of labels labs specifies all the possible locations that the expression e can evaluate to; this is necessary for dataflow analysis later. The common case of jumping to a known label l is written as

T_Jump(l,Temp_LabelList(l,NULL));

CJUMP(o, e1,e2,t, f ) Evaluate e1,e2 in that order, yielding values a, b. Then compare a, b using the relational operator o. If the result is true, jump to

t; otherwise jump to f . The relational operators are EQand NE for integer equality and nonequality (signed or unsigned); signed integer inequalitiesLT,

GT,LE,GE; and unsigned integer inequalitiesULT,ULE,UGT,UGE.

SEQ(s1,s2) The statement s1followed by s2.

LABEL(n) Define the constant value of name n to be the current machine code address. This is like a label definition in assembly language. The value

NAME(n)may be the target of jumps, calls, etc.

It is almost possible to give a formal semantics to the Tree language.

However, there is no provision in this language for procedure and function definitions – we can specify only the body of each function. The procedure entry and exit sequences will be added later as special “glue” that is different for each target machine.

在文檔中 Modern Compiler Implementation in C (頁 162-165)