/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package middlewares; import API.MiddlewareInterface; import common.Block; import common.Code; import common.Instruction; import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedList; /** * * @author EUGENIO CARVALHO */ public class LoadStoreMiddleware implements MiddlewareInterface { protected BasicBlockMiddleware basicBlocks; private BlockBaseGroup group; public LoadStoreMiddleware() { } @Override public void Exec(Code c, LinkedHashMap cp) throws Exception { this.basicBlocks = (BasicBlockMiddleware) cp.get("ir.basic.blocks"); BlockBaseOcorrences g; Integer leader, limit, lposition; Block block = c.Block(); String blockname = block.getName(); LinkedList instructions = block.Instructions(); ArrayList remove = new ArrayList<>(); Instruction IL, IS; // Group contem a lista de blocos basicos do bloco atual group = basicBlocks.getGroups().get(blockname); Instruction inst; HashMap loaded, stored; String varL, varS; Integer fix = 0; int i, j, fixAllocCount = 0; group.Init(); System.out.println("Inicianado load store processor...." + blockname); String[] ignore = "alloc,label".split(","); for (int ctrl = 1; ctrl < instructions.size(); ctrl++) { if (!instructions.get(ctrl).eq("type", "alloc")) { break; } fixAllocCount++; } while (true) { g = group.getCurrent(); if (g == null) { break; } // check stores // Verifica a possibilidade de remover a instrucao atual considerando: // * A instrucao é um store // * O endereco carregado é uma variavel da pilha // Variaveis globais sempre são gravadas stored = new HashMap<>(); leader = g.getLeader() + fixAllocCount; i = j = (g.getLastPosition() + fixAllocCount); // System.out.println("------------------------------>(" + leader + "|" + i + "|F" + fixAllocCount + "):"); for (; i > leader; j--) { IS = instructions.get(j); if (IS.in("type", ignore)) { continue; } // System.out.println("type :" + IS.Get("type")); switch (IS.Get("type")) { case "store": varS = IS.Get("dst"); // System.out.println("[" + i + "]Era store de " + varS); // Se não for uma variavel global if (!varS.contains("_G")) { // // System.out.println("[" + i + "]Verificando ocorrencia de " + varS + " " + stored.containsKey(varS)); if (stored.containsKey(varS)) { // System.out.println("[" + i + "]Marcada para ser removida"); remove.add(IS); } else { // System.out.println("[" + i + "]Adicionando primeira ocorrencia"); stored.put(varS, Boolean.TRUE); } } break; case "load": varS = IS.Get("p1"); if (stored.containsKey(varS)) { // System.out.println("Remove " + varS + " dos stores"); stored.remove(varS); } break; default: // System.out.println("Instruction " + IS); // for (String param : "dst,dst.indice".split(",")) { // if (IS.Has(param)) { // varS = IS.Get(param); // if (stored.containsKey(varS)) { // stored.remove(varS); // } // } // } // System.out.println("[" + i + "]Nao Era store de " + IS.Get("type")); } i--; } // System.out.println("------------------------------<:"); if (!group.NextBlock()) { break; } } boolean changed = !remove.isEmpty(); // Remove as instruções sinalizadas para remorcao System.out.println("Foram removidas " + remove.size() + " instruções de store."); while (!remove.isEmpty()) { instructions.remove(remove.remove(0)); } // Atualiza os blocos basicos e ocorrencias de variaveis if (changed) { cp.get("ir.basic.blocks").Exec(c, cp); } } private void UpdateBasicBlocksReference() { } } // // Corrige o endereco inicial do leader caso alguma instrucao tenha sido removida // leader = g.getLeader() - fix; // limit = leader + g.Position; // // System.out.println("LoadStoreProcessor:[" + leader + "][" + limit + "]"); // // loaded = new HashMap<>(); // stored = new HashMap<>(); // // for (int i = limit - 1; i > leader; i++, j--) { // // } // for (int i = leader, j = limit - 1; i < limit; i++, j--) { // IL = instructions.get(i); // IS = instructions.get(j); // // varL = IL.Get("p1"); // varS = IS.Get("p1"); // // Verifica a possibilidade de remover a instrucao atual considerando: // // * A instrucao é um load // // * O endereco carregado é uma variavel da pilha // // Variaveis globais sempre são lidas // // if (IL.eq("type", "load") && varL.contains("_V")) { //// System.out.println("Looad:" + instruction); // if (loaded.containsKey(varL)) { // remove.add(IL); // fix++; // } else { // loaded.put(varL, Boolean.TRUE); // } // } // } // Corrige o endereco final do bloco caso alguma instrucao tenha sido removida // g.setLeader(leader); // g.Position -= fix;