Concurso/Encontro Nacional de Programação em Lógica

CeNPL’02

 

Universidade de Coimbra / Instituto Politécnico de Coimbra

 

11-13 de Abril de 2002

  

Problema nº 5

Alocador de Registos

Introdução

Na construção de compiladores, um sub-problema comum e bem identificado é o da geração de código para expressões aritméticas. As arquitecturas reais terem um número limitado de registos, facto que condiciona o código que pode ser gerado. Um compilador deverá saber qual o número de registos de que dispõe para calcular as expressões intermédias.


Tarefa

Considere que estamos a gerar código para um PDP-11 glorificado (ie. com número arbitrário de registos), que dispõe das seguintes instruções:

Instrução Acção Observações
mov SRC, DST DST ¬ SRC Copia SRC para DST.
add SRC, DST DST ¬ DST + SRC Efectua uma operação aritmética.
sub SRC, DST DST ¬ DST - SRC  
mul SRC, DST DST ¬ DST * SRC  
div SRC, DST DST ¬ DST / SRC  

Os operandos poderão ser registos, da forma rN (p/ex. r0, r7), constantes da forma #NNN (p/ex. #12) ou nomes, que obedecem à sintaxe habitual para os identificadores.

Pretende-se determinar o número mínimo de registos com os quais se consegue avaliar uma determinada expressão sem ``spilling,''1 produzindo neste processo uma sequência de instruções que avalie a expressão, colocando o resultado no registo r0.

O algoritmo a aplicar pode ser resumido da seguinte forma: considere que se pretende gerar código para uma expressão E=EL @ ER, em que ER e EL são expressões e @ é uma operação aritmética. Seja NL e NR o número de registos necessários à avaliação de EL e ER respectivamente, o número de registos para avaliar E será dado por N'=max(NL,NR+1) se avaliarmos EL primeiro e guardarmos o seu valor num registo enquanto avaliarmos ER. Se optarmos por avaliar ER primeiro, precisaremos de N''=max(NL+1,NR) registos. O objectivo será escolher a ordem de avaliação que resulte no menor valor de N (de entre N' e N''), preservando a correcção do resultado (a operação deverá ser comutativa).

Notas:

Os Dados

Pretende-se obter N, tal que sejam necessários N registos distintos (de r0 a rN-1) para avaliar uma expressão aritmética E. E será representada por um termo Prolog ``ground'', encarado como uma árvore cujas folhas poderão ser átomos (designam os nomes) ou números (designam as constantes) e cujos nós interiores corresponderão a uma operação aritmética (+/2, -/2, */2 e '/'/2). Deverá ser implementado o predicado sethi(+EXPR, ?NREGS) que produz como output uma sequência de instruções do PDP-11 correspondente à avaliação de EXPR com NREGS registos, colocando o resultado final no registo r0. NREGS será instanciado, caso esteja livre à entrada

Os Resultados

Exemplos de execução:

| ?- sethi(a+7*b, NR).
      mov #7,r0
      mul b,r0
      add a,r0
NR = 1
yes

| ?- sethi((a+3*b-4/c)*(7-8*d), NR).
      mov #3,r0
      mul b,r0
      add a,r0
      mov #4,r1
      div c,r1
      sub r1,r0
      mov #7,r1
      mov #8,r2
      mul d,r2
      sub r2,r1
      mul r1,r0
NR = 3
yes


1
ie. sem colocar resultados intermédios em localizações temporárias, na memória principal.

This document was translated from LATEX by HEVEA.