1 Selecção de Instruções Compilação 2003/04 2004 Salvador Abreu
2 Resumo Objectivo: A partir da IR, Gerar código para uma arquitectura concreta máquinas CISC máquinas load/store (RISC) Ainda não resolver todo o problema Meios: omitir alocação de registos deixar as optimizações de fora Emparelhamento de padrões com a árvore de IR
3 Padrões Ideia emparelhar os padrões correspondentes às instruções da máquina com os que ocorrem na IR. Requisito especificação detalhada da arquitectura objecto registos (temporários) organização de memória instruções casos especiais
A Arquitectura Jouette Baseada em arquitecturas reais load/store (ala RISC) movimentos entre registos e memória operações só sobre registos muitos registos um só tipo de dados inteiro de X bits (tamanho fixo) Compilação 2003/04 T12 4
5 Instruções Nome Semântica Padrões - Ri temp(_) ADD Ri = Rj + Rk _+_ MUL Ri = Rj * Rk _*_ SUB Ri = Rj Rk _-_ DIV Ri = Rj / Rk _/_ ADDI Ri = Rj + a _+const(_) const(_)+_ SUBI Ri = Rj a _-const(_) LOAD Ri = M[Rj + c] mem(_+const(_)) mem(const(_)+_) mem(const(_)) STORE M[Rj + c] = Ri move(mem(_,const(_)), _) etc. MOVEM M[Rj] = M[Ri] move(mem(_), mem(_))
6 Exemplo Um mesmo padrão IR pode ser preenchido com diversas sequências de código: move mem mem + + mem * temp(fp) const(x) load R1 = M[fp + a] addi R2 = R0 + 4 mul R2 = R1 * R2 add R1 = R1 + R2 load R2 = M[fp + x] store M[R1 + 0] = R2 + temp(i) const(4) temp(fp) const(a)
7 Exemplo Outra sequência com a mesma semântica: move mem mem + + mem * temp(fp) const(x) load R1 = M[fp + a] addi R2 = R0 + 4 mul R2 = R1 * R2 add R1 = R1 + R2 addi R2 = fp + x movem M[R1] = M[R2] + temp(i) const(4) temp(fp) const(a)
8 Mural: tiling Um mural (o quadro feito pela árvore IR) pode ser preenchido com azulejos o azulejo é a instrução, na sua representação de fragmento de IR o objectivo é cobrir integralmente o programa (ie. o mural ) Casos particulares fazem aparecer constantes particulares, p/ex. 0
9 Tilings optimos e optimais Associar um custo a cada instrução optimo um tiling com custo mínimo optimal um tiling com custo que não pode ser minorado juntando dois azulejos num maior modelo simplista custo duma instrução depende do contexto (p/ex pipelining)
10 Algoritmos de Selecção de Instruções Maximal munch mais simples top-down para cada sub-árvore IR ainda não coberta: encontrar a instrução que engole (daí o nome) o maior número de nós IR marcar as suas sub-árvores ainda não cobertas para a próxima passagem deve garantir cobertura de todos os nós elementares da IR com algum padrão de instrução, para evitar o fracasso do processo.
11 Algoritmos de Selecção de Instruções Programação Dinâmica mais complexa bottom-up cálculo com base em custos de sub-árvores é escolhido o tiling que oferece o menor custo total, dado por: custo do nó soma dos custos das sub-árvores
12 Algoritmos de Selecção de Gramáticas de Árvores Instruções Especificam padrões de árvore e as instruções associadas Diversos tipos de gramática dão diversos tipos de algoritmo: bottom-up (ala LR) top-down (ala LL, DCG) Algoritmos podem ser não-determinísticos aumenta expressividade permite combinar estrutura da árvore condições arbitrárias
13 Máquinas reais CISC e RISC Máquinas RISC típicas muitos registos (32 ou múltiplos) registos indiferenciados (inteiros/endereços) operações com 3 operandos (Rd = Rs OP Rt) instruções load/store com M[R+const] instruções de tamanho fixo um só resultado/efeito por instrução T(design) > 1990
14 Máquinas reais CISC e RISC Máquinas CISC... poucos registos (entre 5/6 e 8 ou 16 no máximo) registos classificados, com usos particulares ou implícitos operações que podem aceder à memória, geralmente com muitos modos de endereçamento operações com 2 operandos (Rd( = Rd OP Rs) instruções de tamanho variável instruções com efeitos secundários (p/ex modos auto- incremento ) T(design) < 1990
15 Geração de Código para CISC (1) Poucos registos continuar como anteriormente e assumir que o alocador de registos irá funcionar bem Classes de registos (especializadas) decompor as operações genéricas em múltiplas, assumindo que o alocador de registos irá suprimir movimentos evitáveis Operações com 2 operandos: desdobrar com um move adicional
16 Geração de Código para CISC (2) Operações com operandos em memória pouco pertinente código que movimenta entre a memória e os registos, opera sobre os registos e volta a movimentar não é mais lento que código que opera sobre a memória, embora possa ser mais comprido. Modos de endereçamento como anteriormente mais compactos mas não mais eficientes
17 Geração de Código para CISC (3) Operações com efeitos secundários difíceis de enquadrar na árvore de IR várias abordagens possíveis: ignorar a sua existência (não gerar esse código!) apanhar casos particulares usar um modelo de selecção de instruções diferente, p/ex um baseado em padrões dum DAG de IR em vez duma árvore de IR