37
1 Tradução para Código Intermediário Departamento de Estatística e Informátic Universidade Federal de Sergipe Compiladores Giovanny Lucero [email protected]

Tradução para Código Intermediário

  • Upload
    louise

  • View
    41

  • Download
    0

Embed Size (px)

DESCRIPTION

Departamento de Estatística e Informática Universidade Federal de Sergipe Compiladores. Tradução para Código Intermediário. Giovanny Lucero [email protected]. CI: Portabilidade e Modularidade. Linguagem. Arquitetura Alvo. Java. Sparc. 4 diferentes compiladores completos. MIPS. Pentium. - PowerPoint PPT Presentation

Citation preview

Page 1: Tradução para Código Intermediário

1

Tradução para Código Intermediário

Departamento de Estatística e InformáticaUniversidade Federal de Sergipe

Compiladores

Giovanny Lucero

[email protected]

Page 2: Tradução para Código Intermediário

2

CI: Portabilidade e Modularidade

Java Sparc

MIPS

Pentium

Alpha

Linguagem Arquitetura Alvo

Compilação

4 diferentes compiladores

completos

Page 3: Tradução para Código Intermediário

3

CI: Portabilidade e ModularidadeLinguagem Arquitetura Alvo

Java

ML

Pascal

C

C++

Sparc

MIPS

Pentium

Alpha

20 diferentes compiladores

completos

Compilação

Page 4: Tradução para Código Intermediário

4

Problema

• A cada nova arquitetura, n novos compiladores (um para cada linguagem).

• O projeto dos n novos compiladores não faz reuso do que foi desenvolvido anteriormente.

• Solução:– Geração de Código Intermediário

Page 5: Tradução para Código Intermediário

5

CI: Portabilidade e Modularidade

Java

ML

Pascal

C

C++

Sparc

MIPS

Pentium

Alpha

Page 6: Tradução para Código Intermediário

6

CI: Portabilidade e Modularidade

Java

ML

Pascal

C

C++

Sparc

MIPS

Pentium

Alpha

Java

ML

Pascal

C

C++

Sparc

MIPS

Pentium

Alpha

CódigoIntermediário

vanguardas retaguardas

Representação abstrata do código

de máquina

Page 7: Tradução para Código Intermediário

7

Código Intermediário

• Independente da máquina

• Independente da linguagem fonte

• Conveniente para que a análise semântica o produza

• Conveniente para traduzir para código de máquina

• Semântica clara e simples de c/construtor

Page 8: Tradução para Código Intermediário

8

Código Intermediário

• Exemplos:– TREE (Appel & Palsberg)– Código de 3 endereços (Aho et al)– E muitos outros...

Page 9: Tradução para Código Intermediário

constantes em BINOPPLUS, MINUS, MUL, DIV,AND, OR, LSHIFT, RSHIFT, ARSHIFT, XOR

constantes em CJUMPEQ, NE, LT, GT, LE, GE, ULT, ULE, UGT, UGE

A linguagem intermediária Treeabstract class Exp

CONST(int value)NAME(Label label)TEMP(Temp temp)BINOP(int binop,

Exp left, Exp right)

MEM(Exp exp)CALL(Exp func,

ExpList args) ESEQ(Stm stm, Exp exp)

abstract class StmMOVE(Exp dst, Exp src)EXP(Exp exp)JUMP(Exp exp,

LabelList targets)CJUMP(int relop,

Exp left, Exp right, Label iftrue, Label iffalse)

SEQ(Stm left, Stm right)LABEL(Label label)

4

Page 10: Tradução para Código Intermediário

10

Tradução• Pode ser feita depois ou em paralelo com a checagem de

tipos.public class ExpTranslator extends ExpVisitorR { ... public ExpTy translate(Expression e) { return (StmTy) e.accept(this); } protected Object visitAndExpR(AndExp e) { // código para checagem e tradução } ...}

class StmTy public Tree.Stm stm; public lps.semantica.vinculaveis.Type ty;}

Page 11: Tradução para Código Intermediário

11

Tradução de variáveis simples

MEM

BINOP

PLUS TEMP fp CONST k

MEM(BINOP(PLUS, TEMP fp, CONST k))

• k é o offset da variável dentro do frame• Calculado na tradução da declaração da variável

TEMP t

Ou então:

Page 12: Tradução para Código Intermediário

12

• Simplificaremos as árvores, assim:

MEM

+

TEMP fpCONST k

MEM(+( TEMP fp, CONST k))

Page 13: Tradução para Código Intermediário

13

Variáveis não locais

• Quando x é declarada num escopo externo, vínculos estáticos devem ser usados

MEM(+(CONS Kn, MEM(+(CONS Kn-1, ... MEM(+(CONS K1, TEMP fp))...)

Onde K1,...,Kn-1 são os offsets do vínculo estático nas

funções aninhadas e Kn é o offset de x no seu frame

• As informações de aninhamento deverão estar registradas no ambiente (tabela de símbolos)

Page 14: Tradução para Código Intermediário

14

Valores estruturados• Valores não atômicos (não escalares)• Tratamento depende da linguagem. Por exemplo:

– Pascal• Variável estruturada armazena um valor estruturado• Variáveis estruturadas são criadas na Pilha• Atribuição e comparação por cópia

– Java• Não há variáveis estruturadas, só valores

estruturados.• Variáveis de tipo estruturado armazenam, na pilha,

uma referência a um valor estruturado• Valores estruturados são criados no heap• Atribuição e comparação por referência

Page 15: Tradução para Código Intermediário

15

Variáveis array• Pascal

– Criação na pilha– Limites fazem parte da variável (para checagem

dinâmica)• O gerenciamento de heap é abstraído por uma biblioteca

de procedimentos externos

Page 16: Tradução para Código Intermediário

16

Seleção de componentes• Array em Pascal: a[i]

(i-lb)*s+a, onde a é o endereço base, s é o tamanho de cada elemento, lb é o limite inferior dos índices de a

– Se a for global a-s*lb pode ser calculado na compilação

– Adicionalmente checagem de limites deve ser feitaMEM

+

MEM *MEM(+(MEM(e), *(i, CONST(W)))

e i CONST

w

Page 17: Tradução para Código Intermediário

17

Seleção de componentes• Seleção de campo: a.f

a + offset de f em a– A informação do offset deve estar no ambiente– A árvore para a.f é:

MEM (+(TEMP fp, +(CONST ka, CONST ka.f)))

Page 18: Tradução para Código Intermediário

18

Criação de registros e arrays

• Em geral:– Campos inicializados com null ou 0

• Obs. Outra linguagem pode requerer a criação recursiva dos componentes

– Criação no heap• Chamando uma função do runtime system (função

externa)

• Esta função retorna um ponteiro para área onde o registro/array é criado.

CALL(NAME(malloc), EXPLIST(A1,...(new EXPLIST(AN,NULL)))

Page 19: Tradução para Código Intermediário

19

Criação de registros e arrays

Page 20: Tradução para Código Intermediário

20

Aritmética

• Em geral, um operador aritmético binário da sintaxe abstrata tem um correspondente em Tree.

• Tree não tem operadores unários.– Negação unária de inteiros implementada como

subtração de zero.– Etc.

Page 21: Tradução para Código Intermediário

21

Condicionais

• Expressões booleanas são representadas usando CJUMP– Combinar com if_then_else, while ...– Combinar em expressões com operadores lógicos de

circuito curto

• 5 < x é traduzido para

• 5 < x && x < 10

CJUMP(LT, CONST(5), x, t, f )

SEQ ( CJUMP(LT, CONST(5), x, c, f ), SEQ ( LABEL c,

CJUMP(LT, x, CONST(10), t, f ) ) )

Page 22: Tradução para Código Intermediário

22

If then else

• Considere:– s1(t, f) = CJUMP(BINOP, left, right, t, f)

• If e1 then e2 else e3.

–e1 é sempre uma expressão booleana

–No entanto e2 e e3 podem ser:• Um statement que não retorna valor algum • Uma expressão booleana• Uma expressão numérica

–É preciso analisar cada um dos casos.

Page 23: Tradução para Código Intermediário

23

If then else

• Caso e2 e e3 statements:

–SEQ ( S1(t, f ), SEQ ( LABEL t,

SEQ(e2, SEQ(LABEL f,

e3))))

• Caso e2 e e3 expressões booleanas:

SEQ(s1(z,f), SEQ(LABEL z,

SEQ(s2(t,f), SEQ(LABEL f, s3(r,f)))

Page 24: Tradução para Código Intermediário

24

If then else

• Caso e2 e e3 expressões:ESEQ(s1(t,f), SEQ(LABEL t, SEQ(

MOVE(TEMP r, e2), SEQ(LABEL F,

MOVE(TEMP r, e3)))), Temp r)

• Observação:–e2 e e3 podem ser diferentes. Neste casos emprega-se as abordagens apresentadas anteriormente de forma híbrida.

Page 25: Tradução para Código Intermediário

25

While

• Layout:

While (cond) { body}

Page 26: Tradução para Código Intermediário

26

While

• Layout:

While (cond) { body}

test: if not (condition) goto done body goto testdone:

Page 27: Tradução para Código Intermediário

27

While

• Layout:

• Se um break é encontrado no interior do laço, a tradução é simplesmente um jump(done).

LABEL(test);CJUMP(BINOP, e1,e2, done, body)LABEL(body);Loop body statementsJUMP (NAME test)

LABEL(done);

test: if not (condition) goto done body goto testdone:

Page 28: Tradução para Código Intermediário

28

FOR

• O for pode ser expresso usando o que foi definido pelo while:

For (i = lo; i <= hi; i++;){ //body}

i = lo;Limit = hi;While (i <= limit){

//body i++

}

Page 29: Tradução para Código Intermediário

29

FOR

• Problema– E se limit igual ao maior inteiro positivo

possível?

i = lo;limit = hi;While (i <= limit){

//body i++

}

Page 30: Tradução para Código Intermediário

30

FOR

• Solução – Colocar um teste adicional no fim do looping,

antes do incremento.i = lo;limit = hi;While (i <= limit){

//body if (i == maxInt)

break; i++

}

Page 31: Tradução para Código Intermediário

31

Chamada a subrotina

• f(a1,a2,...,an)

call(NAME(lf),[e1,...,en])– Onde lf é o label para a função f.

– [e1,...,en] representa um Explist.

Page 32: Tradução para Código Intermediário

32

Chamada a subrotina

• Para linguagens que suportam funções aninhadas, temos:

• f(a1,a2,...,an)

call(NAME(lf),[sL,e1,...,en])– Onde SL é o vínculo estático.

Page 33: Tradução para Código Intermediário

33

Declarações

• Declaração de tipos– Em geral, não geram código

• Declaração de variáveis– Define o local de memória

• Definição de função– Prólogo– Corpo– Epílogo

Page 34: Tradução para Código Intermediário

34

Definição de função

• Uma função é traduzida para um segmento de linguagem assembly com um prólogo, corpo e epilogo.

• O prologo contém:– Pseudo-instruções– O label relativo ao nome da função– Uma função para ajustar o stack pointer (alocar um novo frame)– Instruções para salvar argumentos escapados para o frame e mover

argumentos não escapados para os registradores.– Armazenar instruções para salvar qualquer callee save registers,

incluindo o registro que armazena o endereço de retorno.

Page 35: Tradução para Código Intermediário

35

Definição de função

• Em seguida vem o corpo.

• Depois do corpo vem o epilogo, que contém:– Uma instrução para mover o valor de retorno para o

registro reservado para esta proposta.– Instruções de carregamento para restaurar os callee

save registers.– Uma instrução para reiniciar o stack pointer (desalocar

frames).– Uma instrução de retorno (jump to return address).– Pseudo instruções para anunciar o fim de uma função.

Page 36: Tradução para Código Intermediário

36

Strings

• Um literal String é implementado como um endereço constante de um segmento de memória inicializado para os próprios caracteres.– NAME(lab)

• Toda string é colocada em uma lista global (lista de fragmentos).

• Todas operações com string são executadas por funções providas pelo próprio sistema.

Page 37: Tradução para Código Intermediário

37

Classes e Objetos

• Criação de objetos similar a criação de variáveis registro.

• Chamada a métodos similar a chamadas de funções.– Primeiro deve determinar qual classe declara o método.

– This pointer é passado como argumento do método.

• Acesso a variáveis– Similar ao acesso a campo de registro.