/* * 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.Iterator; import java.util.LinkedHashMap; import java.util.LinkedList; /** * * @author EUGENIO CARVALHO */ public class RemoveUnusedLabelsMiddleware implements MiddlewareInterface { protected HashMap>> labelMap = new HashMap<>(); protected String currentBlock; private Block block; public RemoveUnusedLabelsMiddleware() { } @Override public void Exec(Code c, LinkedHashMap cp) throws Exception { String label; Instruction instruction = null; block = c.Block(); currentBlock = block.getName(); HashMap referenceCount = c.labelsReferenceCount; LinkedList instructions = block.Instructions(); ArrayList remover = new ArrayList(); Iterator interator = instructions.iterator(); String[] ignore = new String[]{"block", "user"}; Instruction branch = null, last = null; int position = 0; // System.out.println("block:" + block.getName() + "-------------------------------"); // System.out.println("\n\n####referenceCount:" + referenceCount + "\n\n"); // Salta o primeiro label if (interator.hasNext()) { last = interator.next(); } // Remove todos os labels não referenciados while (interator.hasNext()) { position++; last = instruction; instruction = interator.next(); // if (instruction.eq("type", "branch")) { // branch = instruction; //// position = 0; // } // // // Quando salta um jump altera o enredeco para o endereco do jump e inverte o teste // if (branch != null && last.eq("type", "jump")) { // if (instruction.eq("label", branch.Get("label"))) { // // position == 3 && // // branch.Set("op", Utils.ComplementOperation(branch.Get("op"))) // .Set("label", last.Get("label")); // branch = null; // // remover.add(last); // remover.add(instruction); // // continue; // } // } if (!instruction.eq("type", "label") || instruction.in("label_type", ignore)) { continue; // Unifica labels sequenciais e atualiza as chamadas dos outros labels } // A instrucão é um label label = instruction.Get("label"); // System.out.println("Last:(label:" + label + ")" + last); if (last != null && last.eq("label", instruction.Get("label"))) { remover.add(last); } // Se o label não existe ou não foi referenciado remove if (!referenceCount.containsKey(label) || referenceCount.get(label) == 0) { // System.out.println("Removendo o label " + label); interator.remove(); } } // Remove as instruções sinalizadas while (!remover.isEmpty()) { block.Remove(remover.remove(0)); } // Remove labels sequenciais for (Instruction i : block.Instructions()) { if (last != null) { if (i.eq("type", "label") && last.eq("type", "label")) { UpdateLabel(c, last.Get("label"), i.Get("label")); last.copy("label", i); remover.add(last); } } last = i; } while (!remover.isEmpty()) { block.Remove(remover.remove(0)); } } protected void UpdateLabel(Code c, String old, String newl) { HashMap> lab; // ArrayList labelInstructions; String label; // Cria o mapa de labels para o bloco atual caso não exista if (!labelMap.containsKey(currentBlock)) { lab = new HashMap<>(); labelMap.put(currentBlock, lab); // Popula a lista de cada de instrucao de cada label for (Instruction instruction : block.Instructions()) { if (instruction.Has("label") || instruction.eq("type", "label")) { label = instruction.Get("label"); if (!lab.containsKey(label)) { lab.put(label, new ArrayList<>()); } lab.get(label).add(instruction); } } } else { lab = labelMap.get(currentBlock); } // System.out.println("lab:" + lab); // System.out.println("update label:" + old + "----" + newl); if (lab.containsKey(old)) { // c.RegisterLabelAddress(old); lab.get(old).forEach((instruction) -> { instruction.Set("label", newl); }); } //labelInstructions } }