Uma Ferramenta Prot´
otipo para S´ıntese de Software
para Sistemas Embutidos a partir de SystemC
Uma Ferramenta Prot´
otipo para S´ıntese de Software
para Sistemas Embutidos a partir de SystemC
Roberto Hartke Neto
Autor
Luiz Cl´
audio Villar dos Santos
Orientador
Lu´ıs Fernando Friedrich
Jos´
e Mazzuco Jr.
Banca examinadora
Palavras-chave
Sistemas Embutidos
S´ıntese de Software
SystemC
Resumo
Abstract
1
Introdu¸
c˜
ao
p. 8
1.1
Sistemas Embutidos
. . . .
p. 8
1.2
Requisitos de Sistemas Embutidos . . . .
p. 8
1.3
Contexto do trabalho . . . .
p. 10
1.4
Caracter´ısticas e Funcionalidades de SystemC . . . .
p. 10
2
Projeto da Representa¸
c˜
ao
p. 12
2.1
Linguagem de Montagem Como Representa¸cao Intermedi´
aria . . . .
p. 12
2.1.1
Dependˆ
encias de dados . . . .
p. 12
2.1.2
Dependˆ
encias de nome . . . .
p. 13
2.2
Grafos Como Representa¸cao Intermedi´
aria . . . .
p. 14
2.2.1
Grafo de fluxo de dados
. . . .
p. 14
2.3
Um modelo unificado para s´ıntese de hardware e software . . . .
p. 15
2.3.1
Um modelo de comportamento baseado em grafos . . . .
p. 16
2.4
T´
ecnicas de otimiza¸c˜
ao . . . .
p. 16
2.4.1
Propaga¸c˜
ao de constantes . . . .
p. 16
2.4.2
Propaga¸c˜
ao de vari´
aveis . . . .
p. 17
2.4.3
Elimina¸c˜
ao de subexpress˜
oes comuns . . . .
p. 17
2.4.4
Elimina¸c˜
ao de c´
odigo morto . . . .
p. 18
3.1
Um prot´
otipo para o Fluxo de S´ıntese de Software . . . .
p. 21
3.1.1
Restri¸c˜
oes . . . .
p. 21
3.1.1.1
Subconjunto de SystemC
. . . .
p. 21
3.1.1.2
Otimiza¸c˜
oes . . . .
p. 24
3.1.1.3
Gera¸c˜
ao de c´
odigo . . . .
p. 24
3.1.1.4
Simulador da arquitetura MIPS . . . .
p. 24
4
Implementa¸
c˜
ao
p. 25
4.1
Pacote IOO . . . .
p. 25
4.2
Compilador . . . .
p. 26
4.3
Otimizador
. . . .
p. 27
4.4
Gerador de c´
odigo . . . .
p. 28
5
Valida¸
c˜
ao do Prot´
otipo
p. 31
5.1
Valida¸c˜
ao do Modelo da Arquitetura Alvo . . . .
p. 31
5.1.1
MIPS Cross-Toolchain . . . .
p. 32
5.1.2
Experimento . . . .
p. 32
5.2
Valida¸c˜
ao do Prot´
otipo de S´ıntese de Software . . . .
p. 32
5.2.1
Experimento . . . .
p. 33
5.2.2
Impacto das Otimiza¸c˜
oes . . . .
p. 33
6
Conclus˜
oes e Perspectivas
p. 35
6.1
Trabalhos futuros . . . .
p. 35
6.2
Conclus˜
oes finais . . . .
p. 36
Anexo A -- Ferramentas Auxiliares Implementadas
p. 38
A.1 Grafo para XML . . . .
p. 38
Anexo B -- Vis˜
ao geral da arquitetura MIPS e sua linguagem de
mon-tagem
p. 40
B.1 Processador . . . .
p. 40
B.2 Conjunto de instru¸c˜
oes . . . .
p. 40
B.3 Estrutura de um programa . . . .
p. 42
B.4 Chamadas de fun¸c˜
ao e retorno . . . .
p. 42
B.5 Chamadas de fun¸c˜
ao e a pilha . . . .
p. 42
B.5.1
Stack e frame pointer . . . .
p. 42
B.5.2
Salvar e restaurar o contexto . . . .
p. 43
B.6 Memory spilling . . . .
p. 43
Anexo C -- Ferramentas utilizadas
p. 45
C.1 ANTLR . . . .
p. 45
C.2 ArchC . . . .
p. 45
Anexo D -- Defini¸
c˜
oes de grafos
p. 46
D.1 Grafos polares . . . .
p. 46
D.2 Colora¸c˜
ao de grafos . . . .
p. 46
D.3 Grafo de intervalo . . . .
p. 46
Anexo E -- C´
odigo fonte
p. 47
E.1 Pacote IOO com suporte a hierarquia . . . .
p. 47
E.2 Compilador . . . .
p. 47
E.3 A¸c˜
oes de gera¸c˜
ao . . . .
p. 62
O objetivo deste trabalho ´
e tra¸car um modelo unificado para s´ıntese de software para
sistemas embutidos. O projeto ´
e especificado em SystemC, uma linguagem unificada que
descreve tanto o software quanto o hardware, que vem se tornando um novo padr˜
ao na ´
area
de desenvolvimento de sistemas embutidos. Este trabalho prop˜
oe um fluxo de s´ıntese de
software que usa grafos de fluxo como representa¸c˜
ao intermedi´
aria. Como grafos tˆ
em uma
base matem´
atica s´
olida, muitas otimiza¸c˜
oes de sistema podem ser feitas com algoritmos
bem conhecidos baseados em grafos.
Este trabalho tamb´
em mostra como c´
odigo de montagem pode ser gerado a partir da
representa¸c˜
ao baseada em grafos, traduzido para c´
odigo de m´
aquina e finalmente
execu-tado.
Palavras-chave: SystemC, grafos de fluxo, linguagem de montagem, ArchC, s´ıntese de
software.
The goal of this work is to pave the way to an unified model for embedded software
synthesis. The system is specified with SystemC, an unifying language describing both
hardware and software, which is becoming a new standard in the field of embedded system
design. This work proposes a software synthesis flow that uses flow graphs as
interme-diate representation. Since graphs have a solid mathematical background, many system
optimizations can be cast into well-known graph-based algorithms.
This work also shows how assembly code can be generated from the graph-based
representation, then translated into machine code and finally executed.
1
Introdu¸
c˜
ao
1.1
Sistemas Embutidos
Antes de tudo, o que seria um sistema embutido? Em uma defini¸c˜
ao superficial,
´
e qualquer dispositivo que inclui um computador program´
avel mas n˜
ao ´
e direcionado
para ser um computador de prop´
osito geral [10]. Ent˜
ao, um computador pessoal n˜
ao ´
e
um sistema embutido, mas um telefone ou microondas com um microprocessador ´
e um
sistema computacional embutido.
1.2
Requisitos de Sistemas Embutidos
Requisitos s˜
ao uma descri¸c˜
ao das necessidades ou dos desejos para um produto. O
objetivo b´
asico dos requisitos ´
e identificar e documentar o que ´
e realmente necess´
ario,
em uma forma que comunica claramente essa informa¸c˜
ao ao cliente e aos membros da
equipe de desenvolvimento. O desafio ´
e definir os requisitos de maneira n˜
ao-amb´ıgua, de
modo que os riscos sejam identificados e n˜
ao aconte¸cam surpresas quando o produto for
finalmente liberado [6].
A separa¸c˜
ao da an´
alise de requisitos da especifica¸c˜
ao do sistema ´
e geralmente
ne-cess´
aria por causa da grande lacuna entre o que os clientes podem descrever sobre o
sistema que eles querem e o que os arquitetos precisam para desenvolver o sistema.
Cli-entes de sistemas embutidos geralmente n˜
ao s˜
ao projetistas de sistemas embutidos. O
entendimento deles sobre o sistema ´
e baseado nas intera¸c˜
oes do usu´
ario com o sistema.
Eles podem ter expectativas irreais sobre o que pode ser feito com o seu or¸camento; e
tamb´
em expressar suas vontades em uma linguagem muito diferente do jarg˜
ao usado pelos
arquitetos do sistema. Capturar um conjunto consistente de requisitos e ent˜
ao transform´
a-los em uma especifica¸c˜
ao mais formal ´
e uma maneira estruturada de gerenciar o processo
de tradu¸c˜
ao da linguagem do cliente para a linguagem dos projetistas.
suficiente. Requisitos n˜
ao funcionais t´ıpicos incluem:
• Consumo de energia: energia, ´e claro, ´e importante em sistemas alimentados por
bateria e tamb´
em importante em outras aplica¸c˜
oes. Energia pode ser especificada
nos requisitos como tempo de dura¸c˜
ao da bateria — o cliente n˜
ao ser´
a capaz de
descrever coisas como voltagem.
• Custo: o custo do produto ou pre¸co de venda ´e quase sempre uma considera¸c˜
ao
importante. Os custos tˆ
em dois maiores componentes: a manufatura, que inclui os
componentes e sua montagem; e a engenharia, que incluem custos com pessoal e
outros custos do desenvolvimento.
• Desempenho: a velocidade do sistema ´e freq¨
uentemente a maior considera¸c˜
ao para
a usabilidade do sistema e para o seu custo final.
• Tamanho e peso: os aspectos f´ısicos do sistema final podem variar muito dependendo
da aplica¸c˜
ao. Um sistema para controle industrial para uma linha de montagem
pode ser desenhado para ajustar-se em uma prateleira com tamanho padr˜
ao e sem
limite de peso. J´
a um dispositivo de m˜
ao tipicamente tem requisitos de tamanho e
peso que podem se espalhar por todo o projeto do sistema.
Programas para sistemas embutidos s˜
ao em muitas maneiras mais restritos que os
programas feitos para computadores de uso geral. Funcionalidades s˜
ao importantes em
ambos, mas aplica¸c˜
oes embutidas enfrentam obst´
aculos diferentes. Por outro lado,
siste-mas computacionais embutidos tˆ
em que fornecer funcionalidades sofisticadas:
• Algoritmos complexos: as opera¸c˜
oes executadas pelo microprocessador podem ser
muito sofisticadas. Por exemplo, o microprocessador que controla o motor de um
autom´
ovel precisa executar complicadas fun¸c˜
oes de filtragem para otimizar o
desem-penho do carro enquanto precisa minimizar a polui¸c˜
ao e consumo de combust´ıvel.
• Interface com usu´
ario: microprocessadores s˜
ao freq¨
uentemente usados para controlar
interfaces com o usu´
ario que podem incluir m´
ultiplos menus e muitas op¸c˜
oes.
Para tornar as coisas mais dif´ıceis, opera¸c˜
oes computacionais `
as vezes apresentam
restri¸c˜
oes:
• Mem´
oria dispon´ıvel: em sistemas embutidos a quantidade de mem´
oria dispon´ıvel
´
e muitas vezes menor do que a de um computador de uso geral. As aplica¸c˜
oes
constru´ıdas para estes sistemas tˆ
em que levar em considera¸c˜
ao esta restri¸c˜
ao.
• Tempo real: muitas aplica¸c˜
oes embutidas precisam executar em tempo real — se o
dado n˜
ao estiver dispon´ıvel at´
e um determinado prazo, o sistema cai. Em alguns
casos, a falha de n˜
ao cumprir o prazo ´
e insegura e pode pˆ
or em risco vidas. Em
outros casos, o n˜
ao cumprimento do prazo n˜
ao cria problemas de seguran¸ca, mas
gera clientes insatisfeitos.
1.3
Contexto do trabalho
A abordagem predominante para o projeto de um sistema digital no n´ıvel de
arquite-tura ´
e descrevˆ
e-lo atrav´
es de uma linguagem de descri¸c˜
ao de hardware. Tal descri¸c˜
ao, al´
em
de servir como documenta¸c˜
ao, permite a simula¸c˜
ao da arquitetura do sistema e a s´ıntese
autom´
atica do circuito l´
ogico que implementa a arquitetura descrita. As linguagens de
descri¸c˜
ao de hardware mais populares atualmente s˜
ao VHDL e Verilog.
A ind´
ustria de EDA (Electronic Design Automation) continua reunindo esfor¸cos para
um movimento coletivo de desenvolvimento em n´ıveis mais altos de abstra¸c˜
ao do que o
n´ıvel de transferˆ
encia de registradores (Register Transfer Level ou RTL). ´
E necess´
ario uma
´
unica linguagem comum e funda¸c˜
oes de modelagem para criar um mercado de
interope-rabilidade de ferramentas de desenvolvimento, servi¸cos e fazer IP (Intellectual Property)
realidade.
Recentemente, a metodologia de projeto refor¸ca a descri¸c˜
ao em n´ıveis mais abstratos
de descri¸c˜
ao. A id´
eia ´
e descrever-se n˜
ao somente o componente de hardware como tamb´
em
sua intera¸c˜
ao com o software. Este tipo de descri¸c˜
ao ´
e referenciada como n´ıvel de sistema.
H´
a um esfor¸co da comunidade de automa¸c˜
ao de projetos para consolidar sua linguagem
de desenvolvimento de sistemas, conhecida como SystemC [8].
1.4
Caracter´ısticas e Funcionalidades de SystemC
O padr˜
ao SystemC ´
e controlado por um grupo composto pelas treze maiores
compa-nhias das ind´
ustrias de EDA e eletrˆ
onicos.
mas (system-level designs). Pode-se usar ferramentas de desenvolvimento de SystemC e
de C++ padr˜
ao para criar um modelo de sistema, rapidamente simular para validar e
otimizar o projeto, explorar v´
arios algoritmos, e conceder a equipe de desenvolvimento
de software e de hardware uma especifica¸c˜
ao execut´
avel do sistema. Uma especifica¸c˜
ao
execut´
avel ´
e essencialmente um programa em C++ que exibe o mesmo comportamento
do sistema quando executado.
C ou C++ s˜
ao as linguagens escolhidas para algoritmos de software e especifica¸c˜
oes
de interface porque elas fornecem o controle e abstra¸c˜
oes de dados necess´
arios para
de-senvolver descri¸c˜
oes de sistema compactas e eficientes. A maioria dos projetistas est˜
ao
familiarizados com estas linguagens e a um grande n´
umero de ferramentas de
desenvolvi-mento associadas a elas.
A biblioteca de classes de SystemC fornece o necess´
ario para construir modelos da
ar-quitetura de sistemas incluindo temporiza¸c˜
ao do hardware, paralelismo, e comportamento
reativo que falta em C++ padr˜
ao. Adicionar estas constru¸c˜
oes a C exigiria extens˜
oes
pro-priet´
arias a linguagem, o que n˜
ao ´
e uma solu¸c˜
ao aceit´
avel para a ind´
ustria. A linguagem
C++ orientada a objetos provˆ
e a habilidade de estender a linguagem atrav´
es de classes,
sem adicionar novas contru¸c˜
oes sint´
aticas. SystemC fornece essas classes necess´
arias e
permite que projetistas continuem a usar a linguagem C++ e as ferramentas de
desen-volvimento.
SystemC possui entre diversas outras caracter´ısticas, a possibilidade de m´
ultiplos
n´ıveis de abstra¸c˜
ao: suporta modelos sem temporiza¸c˜
ao em diferentes n´ıveis de abstra¸c˜
ao,
abrangendo de modelos alto-n´ıvel at´
e modelos detalhados em RTL. Suporta refinamento
iterativo de modelos de n´ıveis mais altos para n´ıveis de abstra¸c˜
ao mais baixos.
2
Projeto da Representa¸
c˜
ao
Representa¸c˜
oes intermedi´
arias s˜
ao o ponto de partida do que o programador
escre-veu para o que a m´
aquina entende. Durante a tradu¸c˜
ao de uma linguagem de alto-n´ıvel
para c´
odigo de m´
aquina, um compilador otimizador analisa e transforma a representa¸c˜
ao
intermedi´
aria v´
arias vezes. Os usu´
arios do compilador querem que essas an´
alises e
trans-forma¸c˜
oes sejam r´
apidas e corretas. Os programadores do compilador querem que as
otimiza¸c˜
oes sejam simples de escrever, f´
aceis de compreender, e f´
aceis de estender. O
objetivo ent˜
ao ´
e uma representa¸c˜
ao que seja simples e leve enquanto possibilita f´
acil
ex-press˜
ao e otimiza¸c˜
oes r´
apidas.
2.1
Linguagem de Montagem Como Representa¸
cao
Intermedi´
aria
Um c´
odigo escrito em linguagem de montagem (assembly language), usado como
re-presenta¸c˜
ao intermedi´
aria entre a linguagem de alto-n´ıvel e o c´
odigo de m´
aquina, tem
diversas desvantagens e limita¸c˜
oes:
• ´
E dependente do conjunto de instru¸c˜
oes, n˜
ao pode ser utilizado em outra m´
aquina
com um conjunto de instru¸c˜
oes diferente.
• Utiliza os recursos da arquitetura para qual foi gerado. Mesmo que o c´
odigo seja
compat´ıvel com outra m´
aquina, o programa n˜
ao utilizaria recursos adicionais que
esta m´
aquina poderia ter (maior n´
umero de registradores por exemplo).
2.1.1
Dependˆ
encias de dados
Suponha duas instru¸c˜
oes, I e J, com I ocorrendo antes que J. S˜
ao poss´ıveis de ocorrer
os hazards:
• WAW (write after write) - J tenta escrever em um operando antes de I escrever. A
escrita acaba sendo feita na ordem errada, deixando o valor escrito por I no destino
em vez do valor escrito por J. Este hazard est´
a presente apenas em pipelines que
permitem escrita em mais de um est´
agio (ou permite que uma instru¸c˜
ao continue a
executar mesmo quando alguma anterior est´
a parada).
• WAR (write after read ) - J tenta escrever no destino antes que ele seja lido por
I, ent˜
ao I lˆ
e o novo valor o que ´
e incorreto. Este hazard ocorre quando existem
algumas instru¸c˜
oes que escrevem seu resultado cedo no pipeline de instru¸c˜
oes, e
outras instru¸c˜
oes que lˆ
eem tarde no pipeline.
Quando o conjunto de instru¸c˜
oes possui instru¸c˜
oes multiciclo, como multiplica¸c˜
ao,
divis˜
ao ou opera¸c˜
oes com ponto flutuante, a ocorrˆ
encia de hazards (principalmente WAW)
aumenta. Isso porque as instru¸c˜
oes n˜
ao atingem mais os est´
agios na ordem que foram
iniciadas. Por exemplo, se a instru¸c˜
ao I for uma divis˜
ao e J uma simples soma, onde I
precede J e ambos escrevem no mesmo registrador, J chegar´
a antes que I no est´
agio de
escrita e causar´
a um hazard WAW.
2.1.2
Dependˆ
encias de nome
Uma dependˆ
encia de nome ocorre quando duas instru¸c˜
oes usam o mesmo registrador
ou local de mem´
oria, chamado de nome, mas n˜
ao h´
a nenhum fluxo de dados entre as
instru¸c˜
oes associado com o nome. H´
a dois tipos de dependˆ
encias entre uma instru¸c˜
ao I
que precede uma outra instru¸c˜
ao J na ordem do programa:
• Uma antidependˆ
encia entre a instru¸c˜
ao I e a instru¸c˜
ao J ocorre quando a instru¸c˜
ao
J escreve em uma registrador ou posi¸c˜
ao de mem´
oria que a instru¸c˜
ao I lˆ
e e a instru¸c˜
ao
I ´
e executada antes. Uma antidependˆ
encia corresponde a um hazard WAR.
• Uma dependˆ
encia de sa´ıda ocorre quando a instru¸c˜
ao I e a instru¸c˜
ao J escrevem
no mesmo registrador ou posi¸c˜
ao de mem´
oria. A ordem das instru¸c˜
oes precisa ser
preservada. Dependˆ
encias de sa´ıda correspondem a hazards WAW.
Antidependˆ
encias e dependˆ
encias de sa´ıda s˜
ao dependˆ
encias de nome, ao contr´
ario de
dependˆ
encias de dados reais, porque n˜
ao h´
a valor sendo transmitido entre as instru¸c˜
oes.
Isto significa que as instru¸c˜
oes envolvidas numa dependˆ
encia de nome podem executar
simultaneamente ou serem reordenadas, se o nome (registrador ou posi¸c˜
ao de mem´
oria)
usado nas instru¸c˜
oes for mudado de tal forma que n˜
ao exista mais conflito. Este
reno-meamento pode ser feito facilmente para registradores e ´
e chamado de renomeamento de
registradores (register renaming). Pode ser feito estaticamente por um compilador ou
dinamicamente pelo hardware.
2.2
Grafos Como Representa¸
cao Intermedi´
aria
Como vantagem de utilizar grafos como linguagem intermedi´
aria, pode-se citar:
• Independente de plataforma.
• Possibilidade de realizar otimiza¸c˜
oes, utilizando algoritmos b´
asicos sobre grafos.
• Deixam expl´ıcito o paralelismo das opera¸c˜
oes.
• Grafos s˜
ao velhos conhecidos do mundo da computa¸c˜
ao, tem uma base matem´
atica
s´
olida, e tˆ
em dispon´ıveis uma grande variedade de algoritmos.
2.2.1
Grafo de fluxo de dados
Um grafo de fluxo de dados ´
e um modelo de um programa sem condicionais. Em uma
linguagem de programa¸c˜
ao de alto-n´ıvel, um segmento de c´
odigo sem condicionais — mais
precisamente, com um ´
unico ponto de entrada e sa´ıda — ´
e conhecido como bloco b´
asico.
Antes que seja poss´ıvel desenhar o grafo de fluxo de dados para o c´
odigo, ´
e necess´
ario
modific´
a-lo um pouco. ´
E necess´
ario reescrever o c´
odigo no formato de atribui¸c˜
ao ´
unica
(single-assignment form), onde uma vari´
avel aparece apenas uma vez no lado esquerdo
de uma atribui¸c˜
ao (leia [10]). O formato de atribui¸c˜
ao ´
unica ´
e importante porque permite
identificar uma localiza¸c˜
ao ´
unica no c´
odigo onde uma vari´
avel ´
e computada. Este formato
de atribui¸c˜
ao ´
unica tamb´
em elimina as dependˆ
encias de nome das vari´
aveis.
O formato de atribui¸c˜
ao ´
unica significa que o grafo de fluxo de dados ´
e ac´ıclico. Manter
o grafo de fluxo de dados ac´ıclico ´
e importante em v´
arios tipos de an´
alises poss´ıveis de
serem feitas no grafo. H´
a mais detalhes sobre os grafos de fluxo de dados em se¸c˜
oes futuras.
A tabela 1 mostra um exemplo de c´
odigo e seu equivalente no formato de atribui¸c˜
ao ´
unica.
int x = 1;
int x = 1;
int y = 2;
int y = 2;
int z = 3;
int z = 3;
x = x ∗ y;
int x1 = x ∗ y;
y = y ∗ z;
int y1 = y ∗ z;
z = x ∗ y;
int z1 = x1 ∗ y1 ;
2.3
Um modelo unificado para s´ıntese de hardware e
software
Sistemas embutidos s˜
ao implementados como uma mistura de software e hardware.
Geralmente, software ´
e usado para proporcionar v´
arias funcionalidades e flexibilidade,
enquanto hardware ´
e usado para prover desempenho.
A metodologia atual de projeto de sistemas embutidos requer separa¸c˜
ao da
espe-cifica¸c˜
ao e desenvolvimento de hardware e software. Esta metodologia traz problemas
quando h´
a necessidade de modificar o projeto do hardware ou software, `
as vezes ´
e preciso
at´
e reprojetar o sistema. Esta metodologia ainda tem outros problemas:
• Falta de uma representa¸c˜
ao unificada do modelo de hardware e software, o que
leva a dificuldades na verifica¸c˜
ao do sistema como um todo, e consequentemente
incompatibilidades na integra¸c˜
ao software/hardware.
• Uma defini¸c˜
ao antecipada das parti¸c˜
oes, o que pode levar a projetos pouco
otimiza-dos.
• Falta de um fluxo de projeto bem definido, o que torna a revis˜
ao da especifica¸c˜
ao
dif´ıcil.
H´
a v´
arias abordagens diferentes para resolver o problema do projeto de sistemas
em-butidos. Nesse trabalho ser´
a desenvolvida e mostrada uma metodologia para especifica¸c˜
ao
do sistema, e s´ıntese e valida¸c˜
ao do software para o sistema embutido. O projeto ´
e feito
com uma linguagem unificada que descreve tanto o software quanto o hardware, SystemC,
e com uma ´
unica abordagem de representa¸c˜
ao intermedi´
aria de software, grafo, e tendo
como produto final c´
odigo de montagem e consequente c´
odigo de m´
aquina.
2.3.1
Um modelo de comportamento baseado em grafos
A representa¸c˜
ao intermedi´
aria neste projeto ´
e ent˜
ao uma estrutura baseada em grafos
e orientada a objetos, mais precisamente grafos polares
1de fluxo de dados.
Os v´
ertices do DFG denotam opera¸c˜
oes, parˆ
ametros, chamadas de fun¸c˜
ao, valores de
retorno, constantes ou s˜
ao usados para polarizar o grafo. As arestas podem ser de apenas
dois tipos: dados ou sequenciamento (n˜
ao transportam dados, tem custo zero).
O grafo de fluxo de dados de um c´
odigo torna a ordem em que as opera¸c˜
oes s˜
ao
executadas menos ´
obvia. Esta ´
e uma das vantagens do grafo de fluxo de dados.
Pode-se us´
a-lo para determinar reordenamentos poss´ıveis das opera¸c˜
oes, o que pode ajudar a
reduzir conflitos do pipeline e da cache. Pode-se utiliz´
a-lo tamb´
em quando a ordem exata
das opera¸c˜
oes n˜
ao importa. O grafo de fluxo de dados define uma ordem parcial das
opera¸c˜
oes no bloco b´
asico. ´
E necess´
ario garantir que um valor ´
e computado antes que
seja utilizado, mas geralmente h´
a diversos ordenamentos poss´ıveis de avaliar as express˜
oes
para satisfazer esse requisito.
2.4
T´
ecnicas de otimiza¸
c˜
ao
Otimiza¸c˜
oes s˜
ao um conjunto de transforma¸c˜
oes que preservam a semˆ
antica e que
mi-nimizam a quantidade de informa¸c˜
ao e instru¸c˜
oes necess´
arias para executar um programa.
Otimiza¸c˜
oes podem ser implementadas de diversas maneiras. Podem ser realizadas
du-rante a etapa de an´
alise da compila¸c˜
ao, durante a gera¸c˜
ao da representa¸c˜
ao intermedi´
aria,
ou mesmo na representa¸c˜
ao intermedi´
aria.
Nas pr´
oximas se¸c˜
oes ser˜
ao explanadas algumas otimiza¸c˜
oes poss´ıveis de serem feitas
em grafos, a representa¸c˜
ao intermedi´
aria alvo deste trabalho. Elas s˜
ao transforma¸c˜
oes
baseadas no fluxo de dados, e podem ser consideradas otimiza¸c˜
oes “cl´
assicas”. As
oti-miza¸c˜
oes implementadas neste trabalho s˜
ao locais, isto ´
e, se aplicam apenas ao escopo do
bloco b´
asico.
2.4.1
Propaga¸
c˜
ao de constantes
Propaga¸c˜
ao de constantes consiste em detectar operandos constantes e pr´
e-computar
o valor da opera¸c˜
ao. Sendo o resultado outra constante, a nova constante pode ser
Figura 1: Propaga¸c˜
ao de constantes
2.4.2
Propaga¸
c˜
ao de vari´
aveis
Propaga¸c˜
ao de vari´
aveis consiste em detectar c´
opias de vari´
aveis, por exemplo, as
atribui¸c˜
oes do tipo x = y. Este tipo de otimiza¸c˜
ao s´
o pode ser feito se o valor da vari´
avel
do lado esquerdo da atribui¸c˜
ao (ou seja, a “c´
opia”) n˜
ao for alterado em alguma atribui¸c˜
ao
futura, o que ´
e verdade no formato de atribui¸c˜
ao ´
unica. Veja a tabela 2 como exemplo.
Tabela 2: Propaga¸c˜
ao de vari´
aveis
C´
odigo original
C´
odigo equivalente
int a = 3 + 4;
int a = 3 + 4;
int b = a;
int c = a * 3;
int c = b * 3;
2.4.3
Elimina¸
c˜
ao de subexpress˜
oes comuns
A procura por subexpress˜
oes comuns tenta encontrar padr˜
oes isom´
orficos no grafo.
Este passo ´
e simplificado se as express˜
oes aritm´
eticas tiverem apenas dois operandos, que
´
e o caso da representa¸c˜
ao intermedi´
aria adotada no trabalho. Ent˜
ao, esta transforma¸c˜
ao
consiste em selecionar um alvo, por exemplo, uma opera¸c˜
ao qualquer, e procurar outra
opera¸c˜
ao do mesmo tipo e que tenha os mesmos operandos de entrada. Veja a figura 2
como exemplo.
Figura 2: Elimina¸c˜
ao de subexpress˜
oes comuns
2.4.4
Elimina¸
c˜
ao de c´
odigo morto
C´
odigo morto consiste em todas as opera¸c˜
oes que n˜
ao podem ser alcan¸cadas, e aquelas
que o resultado n˜
ao ´
e referenciado em nenhum outro lugar. Casos ´
obvios s˜
ao comandos
ap´
os um comando de retorno de um m´
etodo. Outros casos involvem opera¸c˜
oes que
pre-cedem o comando de retorno mas que n˜
ao tem seus resultados usados em nenhum lugar.
A figura 3 mostra um exemplo aplicado a representa¸c˜
ao intermedi´
aria usada no trabalho.
Figura 3: Elimina¸c˜
ao de c´
odigo morto
2.5
Linguagem de montagem
A linguagem de montagem ´
e equivalente a linguagem de m´
aquina, que tem instru¸c˜
oes
e vari´
aveis totalmente codificadas em bin´
ario, mas em vez da nota¸c˜
ao puramente bin´
aria
do que a linguagem de m´
aquina, ele ainda ´
e inteiramente dependente do conjunto de
instru¸c˜
oes dum dado processador, isto ´
e, n˜
ao ´
e port´
atil entre processadores de fam´ılias
diferentes.
Para converter de c´
odigo escrito em linguagem de montagem para c´
odigo de m´
aquina
utiliza-se programas chamados de montadores (assemblers).
2.5.1
Aloca¸
c˜
ao de registradores
Um dos problemas quando deseja-se escrever c´
odigo de montagem ´
e mapear vari´
aveis
e valores tempor´
arios para um conjunto fixo de registradores (juntamente com o espa¸co
dispon´ıvel na mem´
oria).
Para resolver o problema da aloca¸c˜
ao de registradores utiliza-se colora¸c˜
ao de grafos.
Cria-se um grafo de intervalo
2, e ap´
os a colora¸c˜
ao, garante-se que um valor (representado
por um nodo) n˜
ao vai alterar o valor de outro porque n˜
ao usam o mesmo registrador caso
haja intersec¸c˜
ao no seu tempo de vida.
H´
a v´
arios algoritmos de colora¸c˜
ao de grafos. Neste trabalho foi usado um algoritmo
simples que colore os v´
ertices sequencialmente, um de cada vez. Este algoritmo n˜
ao
garante que a colora¸cao seja m´ınima. O algoritmo e exemplos podem ser vistos em [3].
H´
a programas onde n˜
ao ´
e poss´ıvel converter todas as vari´
aveis e tempor´
arios em
re-gistradores. Nestes casos, os valores nos registradores precisam ser salvos na mem´
oria
(t´
ecnica chamada de “memory spilling”), e quando necess´
ario, colocados em algum
regis-trador novamente.
3
Fluxo de S´
ıntese de Software
O fluxo de s´ıntese de software pode ser visto na figura 4. Os retˆ
angulos denotam
fer-ramentas. Entradas, sa´ıdas e representa¸c˜
oes intermedi´
arias s˜
ao representadas por elipses.
Figura 4: Panorama de um fluxo completo de s´ıntese de software
intermedi´
aria do fluxo e onde ser˜
ao feitas todas as otimiza¸c˜
oes desejadas. O grafo
(otimi-zado ou n˜
ao) serve de entrada para o gerador de c´
odigo, que tem como sa´ıda um arquivo
escrito em c´
odigo de montagem para o processador MIPS. Com um montador ´
e poss´ıvel
gerar c´
odigo de m´
aquina (c´
odigo bin´
ario) e executar o programa em uma m´
aquina com
processador MIPS ou em um simulador da arquitetura MIPS (ArchC [2], por exemplo).
3.1
Um prot´
otipo para o Fluxo de S´ıntese de
Soft-ware
Primeiramente, ´
e necess´
ario especificar quais funcionalidades ser˜
ao implementadas. O
fluxo de s´ıntese foi mostrado e comentado na se¸c˜
ao anterior. Na pr´
oxima, ser˜
ao mostradas
as restri¸c˜
oes impostas ao prot´
otipo para viabilizar sua implementa¸c˜
ao em tempo h´
abil.
3.1.1
Restri¸
c˜
oes
As ferramentas implementadas ou utilizadas no trabalho possuem algumas restri¸c˜
oes
ou simplifica¸c˜
oes. Nas pr´
oximas se¸c˜
oes ser˜
ao listadas algumas caracter´ısticas do
com-pilador implementado, das otimiza¸c˜
oes realizadas, do c´
odigo de montagem gerado, e do
simulador de arquitetura utilizado.
3.1.1.1
Subconjunto de SystemC
O subconjunto de SystemC implementado ´
e apresentado nessa se¸c˜
ao. Algumas
fun-cionalidades presentes em SystemC n˜
ao fazem sentido no escopo de sistemas embutidos,
outras foram retiradas para simplificar a constru¸c˜
ao das ferramentas.
A tabela 3 mostra as constru¸c˜
oes de SystemC/C++ implementadas no subconjunto.
A primeira coluna diz qual a categoria da constru¸c˜
ao, a segunda coluna mostra um
exem-plo ou palavra-chave, e a terceira coluna traz coment´
arios ou observa¸c˜
oes sobre a
imple-menta¸c˜
ao da funcionalidade, se necess´
ario.
Apenas dois tipos de dados primitivos s˜
ao implementados. Eles s˜
ao mostrados na
tabela 4.
Tabela 3: Constru¸c˜
oes aceitas pela linguagem
Categoria
Constru¸
c˜
ao
Observa¸
c˜
oes
Coment´
arios
Bloco /* */ e linha //
Identificadores
Ex.: var, var, var3
Come¸cando com letra ou
su-blinhado e seguido por
le-tras, n´
umeros ou sublinhado
Classes
SC MODULE e class
Fun¸c˜
oes
tipo nome() { }
Express˜
oes
Ex.: a + b
Arquivos inclu´ıdos
#include arquivo
Ignorados,
como
os
co-ment´
arios.
Declara¸c˜
oes
tipo nome;
Retorno de fun¸c˜
ao
return
Atribui¸c˜
oes
Ex.: a = b + c
Construtor
SC MODULE ou classe()
Modificadores de acesso
public, protected, private
N˜
ao fazem sentido na
abor-dagem de grafos, mas s˜
ao
necess´
arios em C++
Tabela 4: Tipos de dados aceitos
Categoria
Constru¸
c˜
ao
Coment´
arios
Inteiros
int
Decimais
Booleanos
bool
true ou false
mostrados na tabela 4.
Tabela 5: Operadores aceitos
Categoria
Constru¸
c˜
ao
Aritm´
eticos
/, *, +, -, %
Relacionais
!=, ==, >, <, >=, <=, !
Outras coisas importantes sobre o subconjunto da linguagem:
• Aceita instancia¸c˜
ao de objetos das classes j´
a declaradas.
• Aceita passagem de parˆ
ametros nos m´
etodos, mas somente vari´
aveis ou constantes,
n˜
ao aceita express˜
oes ou chamada de fun¸c˜
ao como parˆ
ametro.
• N˜
ao aceita parˆ
enteses em express˜
oes.
• N˜
ao h´
a precedˆ
encia das opera¸c˜
oes. As express˜
oes s˜
ao avaliadas da esquerda para a
direita.
Abaixo est´
a um exemplo de c´
odigo escrito com o subconjunto implementado.
#include "systemc.h"
int some(int x, int y) { return x + y;
}
class MinhaClasse { public:
int divide(int x, int y) { return x / y; } MinhaClasse () { } int multiply() { int x = 1; int y = 2; return x * y; } }; int main() { MinhaClasse m; int c = 9 + 4; int a = m.divide(c, 10); int a1 = -a * m.multiply(); int a2 = a1 + some(0, 5); int b = 8 % c; return a2 - b;
}