46
Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino [email protected]

Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino [email protected]

Embed Size (px)

Citation preview

Page 1: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Phoenix Framework

Infra-estrutura para construção de compiladores

Guilherme Amaral [email protected]

Page 2: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Agenda

• Introdução

• Core Componentes

• Mapeando Estruturas

• Gerando Código

• Exemplo Prático

Page 3: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Phoenix - Proposta

VS

Page 4: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

O que é o Phoenix?• Plataforma para desenvolvimento de compiladores e

ferramentas de análise e otimização• Escrito em C++/CLI (performance e extensibilidade)• Estrutura

– Robusta – rica API e ferramentas– Extensível – modelo de plugins– Flexível – readers, writers e IR

• Ecossistema rico– Academia – técnicas de construção e funcionamento de um

compilador– Pesquisas – laboratório para testes e pesquisas– Indústria – ferramentas customizadas e alteração de programas

• Futuros Compiliadores Microsoft– JITs, PreJITs e C++ Backend

Guilherme Amaral Avelino
Extensibilidade: Gerenciamento de memória, permite integração segura com as linguagens .NET
Page 5: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Phoenix

Page 6: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Phoenix - Aplicações• Rápida implementação e teste de

novas técnicas de compilação• Estender o Visual Studio (Add-on),

para fazer análise de código– Control Flow Graph e Dynamic Slicing

• Instrumentação de código– Novas funcionalidades, AOP e profiling

• Construção de compiladores

Page 7: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Core Componentes

• Intermediate Representation (IR)– Instruções– Unidades e Lifetimes– Sistema de símbolos– Sistema de tipos

• Phases

• Plugins e Controls

Page 8: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Representação Intermediária (IR)

• Representação fortemente tipada• Vários níveis de abstração

– HIR (High-level IR) – totalmente independente– MIR (Mid-level IR) – dependente do ambiente de

execução– LIR (Low-lever IR) – totalmente dependente– EIR (Encoded IR) – código binário

• Represnta o fluxo de instruções de uma função como uma lista de instruções duplamente ligada

Page 9: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

IR - Instruções

• Operador (opcode)

• Lista Operandos– Origem– Destino

• Apresenta explicitamente todos os recursos (efeitos colaterais)

Page 10: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

IR - Instruções

Page 11: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

IR - Operandos • Phx.IR.Operand• Recursos utilizados pelos operadores

– Dados, labels, referências.

• Armazena tipos e campos• VariableOperand, MemoryOperand,

ImmediateOperand, LabelOperand, FunctionOperand.

• Referência ou valor (Operand.isAdress)

Page 12: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

IR - Instruções• Instruções reais

– Simples: operações lógicas e aritiméticas (ValueInstruction e CompareInstruction)

– Complexas: chamadas diretas/indiretas a procedimentos (CallInstruction)

– Control flow: desvios condicionais e incondicionais (BranchInstruction e SwitchInstruction)

– Summary: blocos inline (OutlineInstruction)

• Pseudo instruções– Label, Pragma, Data

OBS: API em dois níveis de Operandos e Instruções (propriedades)

Guilherme Amaral Avelino
Simples: operação aritmética ou lógica que produz um valor.Complexa: uma chamada direta ou indireta a um outro procedimento. Control Flow: operações de fluxo de controle do programa tais como desvios condicionais e incondicionais.Summary: instruções para retirada do fluxo principal de instruções, tal como um bloco de assembly \emph{inline}.
Page 13: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

IR – Instruções

Phx.IR.ImmediateOperand op1 = Phx.IR.ImmediateOperand.New(functionUnit, typeTable.Int32Type, 1);

Phx.IR.ImmediateOperand op2 = Phx.IR.ImmediateOperand.New(functionUnit, typeTable.Int32Type, 2);

Phx.IR.VariableOperand dst = Phx.IR.VariableOperand.New(functionUnit, sym.Type, sym);

Phx.IR.Instruction instr = Phx.IR.ValueInstruction.NewBinary (functionUnit, Phx.Common.Opcode.Add, dst, op1, op2);

Page 14: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

IR – Unidades• Classe Phx.Unit• Unidades básicas de um programa

– Assemblies, programas, módulos, funções e dados

• Repositório IR– Tabela de símbolos– Instruções

• Representação Hierárquica

Page 15: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br
Page 16: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

IR - Lifetimes

• Phx.Lifetimes

• Gerenciamento de memória do Phoenix

• Tempo de vida de objetos Phoenix

• Associado às unidades (Phx.Lifetimes.LifetimeKind)– Function, Module, Global, etc

Page 17: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

IR – Unidades e LifetimesPhx.Lifetime lifetime =

Phx.Lifetime.New(Phx.LifetimeKind.Module, null);

Phx.Name moduleName = Phx.Name.New(lifetime, "main.obj");

Phx.ModuleUnit moduleUnit = Phx.ModuleUnit.New(lifetime, moduleName, null,

typeTable, runtime.Architecture, runtime);

Page 18: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

IR – Sistema de Símbolos• Identificam entidades Phoenix

– Variáveis, tipos, labels, funções e módulos (importados e exportados)

• São armazenados em tabelas (Phx.Symbols.Table)

• Units/Table – escopo dos símbolos• Proxies - simbolos em outras tabelas• Lookup usando objetos (Phx.Symbols.Map)

– LocalIdMap, ExternIdMap, NameMap

Page 19: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

IR – Sistema de Símbolos// Criando a tabela Phx.Symbols.Table moduleSymTable =

Phx.Symbols.Table.New(moduleUnit, 256, true);

// Adicionando mapeamentoPhx.Symbols.Map moduleNameMap = Phx.Symbols.NameMap.New(moduleSymTable, 256);

//Adicionando símboloPhx.Symbols.GlobalVariableSymbol xSym =

Phx.Symbols.GlobalVariableSymbol.New(moduleSymTable, externId, symName, symType, Phx.Symbols.Visibility.GlobalReference);

//Fazendo busca por nomePhx.Symbols.Symbol sym = moduleSymTable.NameMap.Lookup(symName);

Page 20: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

IR – Criando um Proxy//Símbolo da variável externaPhx.Symbols.GlobalVariableSymbol varSym;

//Adicionar o símbolo externo a tabela de símbolo da função

Phx.Symbols.NonLocalVariableSymbol varProxy = Phx.Symbols.NonLocalVariableSymbol.New(SymbolTable, varSym);

Page 21: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

IR – Sistema de Tipos• Fornece aparato para criação de tipos e

regras– Phx.Types.Type– Phx.Types.Check

• Checagem HIR,MIR e LIR• Phx.Types.Table

– Repositório de tipos– Métodos para obter principais tipos

• Dependente da arquitetura

Page 22: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

IR – Tipos Phoenix• PrimitiveTypes - int, float, uknown• PointerTypes - Object, managed, unmanaged • AggregateTypes - Classes, structs, interfaces

– Metapropriedades (IsEnum, IsSealed, IsAbstract, etc)

• ArrayTypes - managed, unmanaged• FunctionTypes

– Lista de tipos dos parâmetros– Lista de tipos de resultados– Convenção de chamada (CDecl, ClrCall, FastCall)

Page 23: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Controls• Manipulam opções de linha de comando• Tipos

– Boolean (SetBooleanControl, ClearBooleanControl )– Integer (IntControl, CounterControl) – String (StringControl, PluginControl)

• Deve ser stático• Constituído:

– Nome– Valor default– Descrição– Localização

Phx.Controls.IntControl myIntCtrl = Phx.Controls.IntControl.New( "myint", 999, “exemplo IntControl", “exemplo.cs" );

Page 24: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Phases• Divisão em fases específicas

– Alocação de registradores, Otimizações, etc

• Opera sobre Unidades (FunctionUnit)• Infraestrutura de fases Phoenix:

– Phx.Phases.Phase– Phx.Phases.PhaseConfiguration – Phx.Phases.PrePhaseEvent e

Phx.Phases.PostPhaseEvent– Phx.Phases.List

Page 25: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Phases

Page 26: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Phases – Criando uma Phaseclass TestPhase : Phx.Phases.Phase {

public static TestPhase New (Phx.Phases.PhaseConfiguration config) {

TestPhase phase = new TestPhase; phase.Initialize(config, "MyPhase");

return phase;}override void Execute (Phx.Unit unit) {

Phx.Output.WriteLine("TestPhase {0}", unit.ToString()); }

}

Page 27: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Phases – Construindo Uma Lista de Fases

Phx.Phases.PhaseConfiguration config = Phx.Phases.PhaseConfiguration.New(

Phx.GlobalData.GlobalLifetime, "Hello Phases");

Phx.Phases.PhaseList phaseList = config.PhaseList;

phaseList.AppendPhase(TestPhase.New (config));

Config.PhaseList.DoPhaseList(unit)

Page 28: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Plugins• Plugins e Phases• Permite modificar programas Phoenix

– Adicionando, removendo ou alterando fases

• Deve ser um Dll gerenciado• Interface Phx.Plugin• Métodos RegisterObjects e BuildPhases• Phx.GlobalData.BuildPlugInPhases(config)

Page 29: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Plugins

Page 30: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Plugins – Criando um Pluginpublic class PlugIn : Phx.Plugin {

public override void RegisterObjects() { }

public override void BuildPhases (Phx.Phases.PhaseConfiguration config )

{ Phx.Phases.Phase encodingPhase; Phx.Phases.Phase testPhase = TestPhase.New(config);encodingPhase = config.PhaseList.FindByName("Encoding"); encodingPhase.InsertBefore(testPhase);

}}

Page 31: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Plugins - Demo

Page 32: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Plugins - Teste

#include <stdio.h>

main(){

int i = 2;i = 8+6*i;

printf ("i= %d",i);}

Main.c

cl –d2plugin:<caminho p/ o plugin> main.c

Page 33: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Mapeando Estruturas• O que foi visto?

– Criação de Fases e Plugins– Criação de Instruções (operandos e operadores)– Criação de Unidades– Criação de Tabela de símbolos e tipos

• Próximas estruturas– Construindo Variáveis– Atribuindo Valor a uma Variável– Construindo uma Função

Page 34: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Criando Variável Local// cria o símbolo da variável

Phx.Symbols.LocalVariableSymbol sym = Phx.Symbols.LocalVariableSymbol.New (

Table symbolTable,

uint externId,

Name symbolName,

Type symbolType,

StorageClass storageClass ) ; // static, argument, // parameter,

auto, illegal

sym.Alignment = Phx.Alignment.NaturalAlignment(sym.Type);

Page 35: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Atribuindo Valor a Variável// Cria os operandos de origem (expressão) e destino (variável) Phx.Symbols.Symbol sym = symbolTable.LookupByName(symbolName);Phx.IR.VariableOperand dst = Phx.IR.VariableOperand.New(

functionUnit, sym.Type, sym);Phx.IR.Operand src = Expression();

// Cria a instrução de atribuiçãoPhx.Opcode opcode = Phx.Common.Opcode.Assign;Phx.IR.Instruction instr = Phx.IR.ValueInstruction.New(func, opcode);instr.AppendSource(src);instr.AppendDestination(dst);

// Insere a instrução de atribuiçãofunctionUnit.LastInstruction.InsertBefore(instr);

Page 36: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Construindo Funções Phoenix

1. Criar o Tipo Função– Phx.Types.Table.GetFunctionType– Phx.Types.FunctionTypeBuilder

2. Símbolo, lifetime e unidade que representem a função

3. Tabela de símbolos da função

4. Instruções

Page 37: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Construindo Funções PhoenixPhx.Types.FunctionType funcType = typeTable.GetFunctionType(

Phx.Types.CallingConventionKind.CDecl, intType, null, null, null, null);

funcSym = Phx.Symbols.FunctionSymbol.New(moduleSymbolTable, 0, Phx.Name.New(lifetime, "_main"), funcType, Phx.Symbols.Visibility.GlobalDefinition);

Phx.Lifetime funcLifetime = Phx.Lifetime.New(Phx.LifetimeKind.Function, moduleUnit);

functionUnit = Phx.FunctionUnit.New(funcLifetime, funcSym, Phx.CodeGenerationMode.Native, typeTable,

moduleUnit.Architecture, moduleUnit.Runtime, moduleUnit, 1);

Page 38: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Construindo Funções PhoenixPhx.Symbols.Table funcSymTable =

Phx.Symbols.Table.New(functionUnit, 64, true);

Phx.IR.LabelInstruction enterInstruction = Phx.IR.LabelInstruction.New(functionUnit, Phx.Common.Opcode.EnterFunction, funcSym);

functionUnit.FirstInstruction.InsertAfter(enterInstruction);

Phx.IR.LabelOperand labelOperand = Phx.IR.LabelOperand.New(functionUnit, enterInstruction);

functionUnit.FirstInstruction.AppendLabelSource( Phx.IR.LabelOperandKind.Technical, labelOperand);

Page 39: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Construindo Funções Phoenix

\\ Inserir aqui as instruções que compõem a função

exitInstruction = Phx.IR.LabelInstruction.New(functionUnit,

Phx.Common.Opcode.ExitFunction);

functionUnit.LastInstruction.InsertBefore(

exitInstruction)

Page 40: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Gerando Código

• Diversas arquiteturas (GURL - Grand Unified Retargeting Language )

• LIR e EIR

• EncodePhase

• ObjectWriter

• COFF e PEWriter

Page 41: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Exemplo Prático

• Compilador para uma mini-linguagem de expressões– Uma ModuleUnit e uma FunctionUnit– Arquitetura e Runtime x86– Objeto linkável

• www.cin.ufpe.br/~gaa/phoenix/exemplo

Page 42: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Exemplo Prático1. www.cin.ufpe.br/~gaa/phoenix/exemplo

2. Abrir Visual Studio e criar um projeto vazio

3. Adicionar ao projeto os arquivos frontend.cs e compiler.cs

4. Adicionar referência as bibliotecas phoenix1. Phxd.dll

2. architecture-x86d.dll

3. runtime-vccrt-win32-x86d.dll

5. Habilitar unsafe code nas propriedades do projeto

Page 43: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Exemplo Prático

• Frontend.cs– Parser do código fonte– Messages de erro de sintaxe– Informação para debug

• Compiler.cs– Geração da Representação Intermediária– Geração de código

Page 44: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Exemplo Prático – Passos1. Inicialização do Framework2. Criação da Lista de Fases3. Símbolos externos4. Criação de dados inicializados5. Parser e criação da IR6. Execução da lista de fases7. Geração de código

Page 45: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

ExecícioExtender MiniComp adicionando variáveis e atribuições• Opções:

– Definir escopo utilizando a hierarquia de unidades e tabela de símbolos

– Criar uma lista de mapeamentos. Exemplo : List<Phx.Symbols.NameMap>

• Observações:– Criação de Proxy para variáveis externas– Variáveis globais devem ser armazenadas na seção .data

Page 46: Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino gaa@cin.ufpe.br

Referências

• http://research.microsoft.com/phoenix/

• http://blogs.msdn.com/kangsu/default.aspx

• http://channel9.msdn.com/Showpost.aspx?postid=188589 (Jim Hogg)