Você está na página 1de 6

Alocaca o de Registradores: Coloraca o de Grafos Baseado em

Prioridades
Fernando Leite RA:80819, Gabriel Schiavon RA:80823, Lailson Tofanelli RA:80827
1

Departamento de Informatica - Universidade Estadual de Maringa (UEM)


Maringa PR Brasil

Resumo. Alocaca o de registradores e uma fase importante da geraca o de


codigo, essa fase e quem determina quais variaveis do codigo fonte ficam em
registradores, se essa fase for bem construda o acesso a memoria e menor e
consequentemente existe uma maior otimizaca o do programa compilado. Esse
problema pode ser resolvido a partir de um grafo e sua k-coloraca o.

1. Introduca o
A construca o de compiladores abrange diversas a reas de estudo em computaca o, como por
exemplo conceitos de linguagens de programaca o, arquitetura de maquina, algoritmos e
engenharia de software. Assim, um compilador converte um programa originado de uma
linguagem de programaca o para uma linguagem que possa ser entendida e executada
por um computador. Uma infraestrutura de compilador e o LLVM (Low Level Virtual
Machine), foi desenvolvido para otimizar em tempos de compilaca o, ligaca o e execuca o
de programas escritos em linguagens de programaca o variadas.
Uma das fases de um compilador e a alocaca o de registradores, essa fase e um
processo que define quais variaveis e valores intermediarios do codigo fonte ficam em
registradores e quais ficam em memoria. Uma forma de solucionar esse problema e a
partir de um grafo aplicando coloraca o, entretanto, esse metodo pode apresentar algumas
deficiencias. Uma maneira de se tratar e adotar a noca o de prioridades em coloraca o de
nos.

2. Fundamentaca o Teorica
Nesta seca o serao apresentados os principais conceitos relacionados a este trabalho, sendo
eles: alocaca o de registradores, LLVM e Priority-based graph coloring.
2.1. Alocador de Registradores
Um compilador pode ser dividido em duas partes: o frontend e o backend. As tarefas
realizadas pelo backend sao [6]:
Seleca o de Instruca o: Mapeia as instruco es no codigo intermediario para
instruco es presentes na arquitetura alvo.
Escalonamento de Codigo: Reoordena as instruco es para tirar proveito de bicaractersticas de tempo de execuca o de cada instruca o.
Alocaca o de Registradores: Consiste em decidir quais variaveis deverao residir em registradores presentes no processador. Se a representaca o intermediaria
so trabalha com valores em memoria, o alocador tem um papel de otimizador,
pois o codigo original ja era funcional e as mudancas apenas melhorarao a performance. Caso contrario, o codigo intermediario usou quantos registradores fossem

necessarios, assim o alocador precisa decidir quais variaveis ficarao em memoria


e quais ficarao em registradores fsicos e gerar codigo para refletir essas decisoes.
A parte do compilador responsavel por gerar o codigo com um bom uso de registradores e o Alocador de Registradores. O alocador e uma das partes finais da compilaca o,
sua sada e um codigo equivalente ao codigo da representaca o intermediaria que usa apenas registradores presentes na maquina alvo. Instruco es com registradores sao mais curtas
e mais rapidas do que instruco es envolvendo memoria [6].
A escolha da representaca o intermediaria tem alto impacto no trabalho do alocador. Um alocador de registradores resolve dois problemas distintos em sequencia [6]:
Alocaca o: Etapa na qual seleciona-se o conjunto de variaveis que residirao nos
registradores em cada ponto do programa.
Atribuica o: Atribui um registrador especfico em que uma variavel residira.
2.2. LLVM
O LLVM e um ferramenta de compilaca o que tem por objetivo fazer a analise de vida de
um programa e as transformaco es disponveis para softwares arbitrarios de uma maneira
que e transparente para os programadores. O LLVM consegue cumprir seus objetivos de
duas formas:
1. Representaca o de Codigo: Fornece varios recursos que servem como uma
representaca o comum para analise, transformaca o e distribuica o de codigo;
2. Design de compilaca o: Explora essa representaca o para fornecer uma
combinaca o de recursos que nao esta disponvel em qualquer abordagem de
compilaca o conhecida atualmente.
De acordo com [3], a representaca o de codigo do LLVM descreve um programa
usando um conjunto de instruco es para uma representaca o abstrata de uma arquitetura
RISC, mas com informaco es em alto-nvel para uma analise mais eficiente.
Os novos recursos que o LLVM fornece para seus usuarios sao:
Linguagem, em baixo-nvel, independente de sistema que pode ser usado para
implementar tipos de dados e operaco es a partir de linguagens em alto-nvel, exibindo seu comportamento de implementaca o a todos os estagios de otimizaca o;
Instruco es para realizar conversoes de tipos e aritmetica de enderecos de baixo
nvel, preservando as informaco es de tipo;
Duas instruco es de manipulaca o de tratamento de exceca o de baixo nvel para
implementar a semantica de exceca o especfica da linguagem, enquanto expor
explicitamente fluxo de controle excepcional para o compilador.
Por causa da diferenca de objetivos e representaco es, o LLVM foi desenvolvido
para ser um complemento das linguagens de alto nvel (e.g. JVM e Small-Talk) e nao uma
alternativa para esses sistemas. De acordo com [3], e possvel se observar tres diferencas.
A primeira e que o LLVM nao tem nenhuma notaca o de construtores em alto nvel, assim
como classes, heranca ou tratamento de exceco es, mesmo quando estamos compilando
arquivos a partir de uma linguagem que fornece esses recursos. Segundo, o framework e
escrito em tao baixo nvel que em tempo de execuca o para uma linguagem em particular
pode ser implementado no proprio LLVM. Terceiro, LLVM nao garante seguranca de tipo,

ou de memoria ou interoperabilidade de linguagem mais do que a linguagem assembly faz


para um processador fsico.
LLVM fornece um conjunto infinito de registros virtuais digitados que podem conter valores de tipos primitivos (Boolean, integer, floating point e ponteiros). O LLVM e
uma arquitetura de load/store: os programas transferem valores entre registros e memoria
exclusivamente por meio de operaco es de load e store usando ponteiros de determinados
tipos.
O LLVM usa a forma SSA como sua representaca o de codigo primaria, isto e , cada
registro virtual e escrito em exatamente uma instruca o, e cada uso de um registro e dominado por sua definica o. As localizaco es de memoria no LLVM nao estao na forma SSA
porque muitas localizaco es possveis podem ser modificadas num u nico store atraves de
um ponteiro, tornando difcil a construca o de uma representaca o de codigo SSA explcita
e razoavelmente compacta para tais localizaco es [3].
O LLVM tambem faz com que o Control Flow Graph (CFG) de cada funca o seja
explcito na representaca o. De acordo com [3], uma funca o e um conjunto de blocos
basicos, e cada bloco basico e uma sequencia de instruco es LLVM, terminando em exatamente uma instruca o de terminaca o. Cada terminador especifica explicitamente seus
sucessivos blocos basicos.
2.3. Priority-based graph coloring
A coloraca o de grafos e uma tarefa onde para cada no de um grafo e atribudo uma cor,
entretanto, nos vizinhos nao podem possuir a mesma cor, essa tarefa busca encontrar o
menor numero possvel de cores para colorir o grafo. Para a alocaca o de registradores,
o grafo, chamado de interferencia ou conflito e construdo a partir do codigo fonte do
programa. Cada no do grafo representa uma variavel do programa que e candidato a
residir em um registrador qualquer.Um grupo de variaveis pertencentes a um mesmo bloco
basico de codigo correspondentes a um no de interferencia, essas variaveis nao devem
residir no mesmo registrador [2].
Na coloraca o do grafo de interferencia, o numero de cores (K) utilizadas para a
coloraca o, corresponde ao numero de registradores disponveis para a alocaca o, esse valor
e chamado de numero cromatico. Assim, um alocador de registradores precisa encontrar
uma atribuica o das variaveis do programa para registradores de modo a minimizar o tempo
de execuca o, ou seja, encontrar o menor valor cromatico para atribuir a esse grafo [2].
A coloraca o do grafo para a alocaca o de registradores e resolvida por meio de
prioridades. O algoritmo de alocaca o de registradores com base em prioridades, determina as prioridades para os candidatos residentes no registrador utilizando estimativas
derivadas do programa e os parametros da maquina e, em seguida, atribui os candidatos
aos registros de acordo com a ordem de prioridade. Ele produz resultados similares com
o metodo de coloraca o pura se o grafo e colorvel. Quando o algoritmo e bloqueado no
processo de coloraca o, ou seja, se nao puder atribuir uma cor ao proximo no de prioridade
mais alta, ele divide o bloco que nao pode ser colorido e continua [2].
No processo de coloraca o, e distinguido os blocos entre limitados e nao-limitados.
Os nao-limitados tem um numero de vizinhos menor do que o numero de registradores
disponveis. O algoritmo de coloraca o consiste nos seguintes passos [2]:

1: separar os blocos nao-limitados;


2: repetir os passos A, B e C ate que todas as variaveis recebam um registrador ou
ate que nao haja nenhum registrador que possa mais ser atribudo:
A: computar a funca o de prioridade P(lr) para cada bloco limitado lr que
ainda nao foi calculado. Se P(lr) for negativo, o que ocorre quando todos
os registros disponveis tiverem sido usados em toda a sua regiao, marque
o bloco como um nao candidato e nao atribua registrador a ele;
B: encontre o bloco com a funca o de prioridade mais alta e atribua um
registrador a ele;
C: verifique se cada bloco precisa ser dividido. E necessario divisao se
todos seus registradores tiverem sidos atribudos a seus vizinhos no grafo
de interferencia.
3: atribuir um registrador a uma variavel, desde que o registrador nao pertenca ao
conjunto proibido(conjunto com registradores ja utilizados em uma vizinhanca).
A funca o de prioridade P(lr) e uma medida emprica dos benefcios de atribuir
um registrador a um bloco ou variavel. E proporcional ao tempo de execuca o. A seguir a
equaca o [2]:
Si = LODSAV E u + ST RSAV E d M OV COST n
1 Para calcular S(lr) e necessario avaliar os valores individuais. Para cada unidade i e
utilizado u para o numero de usos e d indica o numero de definico es. n denota o numero
de movimentos de registro necessarios para determinado bloco. LODSAVE e a quantidade
de tempo de execuca o economizado com uma variavel no registrador em vez de estar na
memoria. STRSAVE e a quantidade de tempo de execuca o para uma variavel em um registrador. MOVCOST e o custo do movimento memoria-registrador e registrador-memoria
[2].
S(lr) e calculada a partir de todos os blocos [2]:
S(lr) =

Si W i

ilr

Um fator que tambem e necessario considerar e o numero de blocos N. Um bloco


que contem maior codigo utiliza mais recursos, ou seja, mais registradores serao utilizados. O valor final deve ser normalizado por N de modo que os blocos menores tenham
maior prioridade. Assim, a equaca o final para a prioridade e [2]:
P (lr) =

S(lr)
N

A funca o de prioridade estima o total de registradores normalizados pelo tamanho


da regiao ocupada [2].
De forma geral, o algoritmo atribui um registrador para uma variavel a cada
iteraca o. O laco termina quando todas as variaveis recebem um registrador ou quando
todos os registradores ja tiverem sido utilizados nos blocos mais prioritarios.

3. Execuca o
Nesta seca o serao apresentados os passos seguidos e os resultados obtidos com a
realizaca o deste trabalho.
3.1. Passos para a Execuca o
O LLVM foi baixado a partir do SVN e instalado com os comandos
cmake -G "Unix Makefiles" ../llvm e make, o que constroi o LLVM
e CLANG para o modo de depuraca o.
Para a execuca o do algoritmo no LLVM foi necessario o uso de PASS. PASS e
uma tecnica estruturante para o codigo do compilador, ele executa as transformaco es e
otimizaco es que compoem o compilador, e constroi os resultados de analise que sao utilizados por essas transformaco es [5]. Os passos seguidos sao [4]:
1 - Criaca o da pasta do PASS dentro da pasta do LLVM em /lib/Transforms;
2 - Adica o do subdiretorio add_subdirectory(PASS), que e a pasta do
PASS, dentro do arquivo CMakeLists.txt;
3 - Inserca o do algoritmo .cpp dentro da pasta;
4 - Criaca o de um arquivo CMakeLists.txt dentro da pasta do PASS;
5 - Adicionar a instruca o add_llvm_loadable_module(LLVMRegAllocColoring
RegAllocColoring.cpp PLUGIN_TOOL opt) no arquivo criado;
6 - Criar uma pasta build e executar cmake -G "Unix Makefiles" ../
para a criaca o os makes do novo PASS;
7 - Executar make para criar o .so;
8 - Geraca o do bitcode do .cpp:
clang -emit-llvm RegAllocColoring.cpp -c -o RegAllocColoring.bc;
9 - E para executar o PASS:
opt -load ./PASS.so -PASS <RegAllocColoring.bc> /dev/null;
3.2. Resultados
Para encontrar os resultados referentes ao trabalho, seria feito algumas execuco es de
codigos fonte implementados em linguagem C para testes, essas execuco es seriam realizadas utilizando o alocador de registradores padrao do LLVM e o alocador utilizando prioridades em coloraca o de grafos descrito nesse relatorio. Entretanto, houveram algumas
dificuldades no momento da execuca o do PASS. No passo 5 apresentado na seca o anterior,
o LLVM utilizado (4.0) nao reconhecia a funca o: add_llvm_loadable_module.
Apos algumas tentativas essa parte foi concluda, mas no passo 6 ocorreram alguns erros
no codigo fonte que nao puderam ser solucionados.
Desse modo, apenas foi obtido o resultado das execuco es do alocador padrao do
LLVM. Entretanto, em [2] os resultados confirmam que, usando a coloraca o baseada
em prioridade, a alocaca o global de registradores pode ser realizada de forma pratica
e eficiente.

4. Conclusao
Compiladores modernos devem melhorar o desempenho do programa, uma forma bastante eficaz e o bom uso da memoria. Assim, a partir da boa implementaca o do alocador

de registradores e possvel economizar um grande tempo de execuca o com buscas em


memoria. O algoritmo apresentado nesse relatorio e descrito em [2], mostrou um esquema
de coloraca o de grafos baseado em prioridades utilizado para solucionar a alocaca o de registradores. E de acordo com [2], o algoritmo pode ser visto como bastante flexvel, pois
a funca o de prioridade utiliza aspectos inerentes a maquina que ele estiver executando.

Referencias
[1] AHO, Alfred V. SETHI, Ravi. ULLMAN, Jeffrey D. Compiladores : princpios, tecnicas
e ferramentas. Rio de Janeiro, 1995.
[2] CHOW, Fred C. HENNESSY, John L. The Priority-Based Colorin Approach to Register
Allocation. ACM Transactions on Programming Languages and Systems, Vol. 12,
No. 4, 1990, Pages 501-536.
[3] Lattner, Chris. Adve, Vikram. LLVM: A Compilation Framework for Lifelong Program
Analysis and Transformation. University of Illinois, Proceedings of the International
Symposium on Code Generation and Optimization, 2004.
[4] LLVM.
Developing
LLVM
passes
out
of
source.
http://llvm.org/docs/CMake.html Acesso em: 20 jan. 2017.

Disponvel

[5] LLVM.
Writing
an
LLVM
Pass.
Disponvel
http://llvm.org/docs/WritingAnLLVMPass.htm Acesso em: 20 jan. 2017.

em:
em:

[6] SILVEIRA, Felipe dos Santos. Alocaca o de Registradores Utilizando Inteligencia Artificial. Trabalho de Conclusao do Curso de Ciencia da Computaca o. Universidade
Estadual de Santa Catarina. Florianopolis, 2013.