/* * 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 Processors; import API.CodeProcessorInterface; import API.Utils; 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 RemoveUnusedLabelsProcessor implements CodeProcessorInterface { protected HashMap>> labelMap = new HashMap<>(); protected String currentBlock; private Block block; public RemoveUnusedLabelsProcessor() { } @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()) { 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") && 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"); // 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(); } } Instruction r; // 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); for (Instruction instruction : lab.get(old)) { instruction.Set("label", newl); } } //labelInstructions } }