123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- /*
- * 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<String, HashMap<String, ArrayList<Instruction>>> labelMap = new HashMap<>();
- protected String currentBlock;
- private Block block;
- public RemoveUnusedLabelsMiddleware() {
- }
- @Override
- public void Exec(Code c, LinkedHashMap<String, MiddlewareInterface> cp) throws Exception {
- String label;
- Instruction instruction = null;
- block = c.Block();
- currentBlock = block.getName();
- HashMap<String, Integer> referenceCount = c.labelsReferenceCount;
- LinkedList<Instruction> instructions = block.Instructions();
- ArrayList<Instruction> remover = new ArrayList();
- Iterator<Instruction> 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<String, ArrayList<Instruction>> lab;
- // ArrayList<Instruction> 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
- }
- }
|