A apresentação está carregando. Por favor, espere

A apresentação está carregando. Por favor, espere

Infra-estrutura para construção de compiladores

Apresentações semelhantes


Apresentação em tema: "Infra-estrutura para construção de compiladores"— Transcrição da apresentação:

1 Infra-estrutura para construção de compiladores
Phoenix Framework Infra-estrutura para construção de compiladores Guilherme Amaral Avelino

2 Agenda Introdução Core Componentes Mapeando Estruturas Gerando Código
Exemplo Prático

3 Phoenix - Proposta VS

4 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

5 Phoenix

6 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

7 Core Componentes Intermediate Representation (IR) Phases
Instruções Unidades e Lifetimes Sistema de símbolos Sistema de tipos Phases Plugins e Controls

8 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

9 IR - Instruções Operador (opcode) Lista Operandos
Origem Destino Apresenta explicitamente todos os recursos (efeitos colaterais)

10 IR - Instruções

11 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)

12 IR - Instruções Instruções reais Pseudo instruções
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)

13 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);

14 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

15

16 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

17 IR – Unidades e Lifetimes
Phx.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);

18 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

19 IR – Sistema de Símbolos
// Criando a tabela Phx.Symbols.Table moduleSymTable = Phx.Symbols.Table.New(moduleUnit, 256, true); // Adicionando mapeamento Phx.Symbols.Map moduleNameMap = Phx.Symbols.NameMap.New(moduleSymTable, 256); //Adicionando símbolo Phx.Symbols.GlobalVariableSymbol xSym = Phx.Symbols.GlobalVariableSymbol.New( moduleSymTable, externId, symName, symType, Phx.Symbols.Visibility.GlobalReference); //Fazendo busca por nome Phx.Symbols.Symbol sym = moduleSymTable.NameMap.Lookup(symName);

20 IR – Criando um Proxy //Símbolo da variável externa
Phx.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);

21 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

22 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)

23 Controls Manipulam opções de linha de comando Tipos Deve ser stático
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" );

24 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

25 Phases

26 Phases – Criando uma Phase
class 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());

27 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)

28 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)

29 Plugins

30 Plugins – Criando um Plugin
public 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); }

31 Plugins - Demo

32 Plugins - Teste Main.c #include <stdio.h> main() { int i = 2;
i = 8+6*i; printf ("i= %d",i); } cl –d2plugin:<caminho p/ o plugin> main.c

33 Mapeando Estruturas O que foi visto? Próximas estruturas
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

34 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);

35 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ção Phx.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ção functionUnit.LastInstruction.InsertBefore(instr);

36 Construindo Funções Phoenix
Criar o Tipo Função Phx.Types.Table.GetFunctionType Phx.Types.FunctionTypeBuilder Símbolo, lifetime e unidade que representem a função Tabela de símbolos da função Instruções

37 Construindo Funções Phoenix
Phx.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);

38 Construindo Funções Phoenix
Phx.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);

39 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)

40 Gerando Código Diversas arquiteturas (GURL - Grand Unified Retargeting Language ) LIR e EIR EncodePhase ObjectWriter COFF e PEWriter

41 Exemplo Prático Compilador para uma mini-linguagem de expressões
Uma ModuleUnit e uma FunctionUnit Arquitetura e Runtime x86 Objeto linkável

42 Exemplo Prático www.cin.ufpe.br/~gaa/phoenix/exemplo
Abrir Visual Studio e criar um projeto vazio Adicionar ao projeto os arquivos frontend.cs e compiler.cs Adicionar referência as bibliotecas phoenix Phxd.dll architecture-x86d.dll runtime-vccrt-win32-x86d.dll Habilitar unsafe code nas propriedades do projeto

43 Exemplo Prático Frontend.cs Compiler.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

44 Exemplo Prático – Passos
Inicialização do Framework Criação da Lista de Fases Símbolos externos Criação de dados inicializados Parser e criação da IR Execução da lista de fases Geração de código

45 Execício Extender 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

46 Referências http://research.microsoft.com/phoenix/
(Jim Hogg)


Carregar ppt "Infra-estrutura para construção de compiladores"

Apresentações semelhantes


Anúncios Google