RemoveUnusedLabelsProcessor.java 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /*
  2. * To change this license header, choose License Headers in Project Properties.
  3. * To change this template file, choose Tools | Templates
  4. * and open the template in the editor.
  5. */
  6. package Processors;
  7. import API.CodeProcessorInterface;
  8. import API.Utils;
  9. import common.Block;
  10. import common.Code;
  11. import common.Instruction;
  12. import java.util.ArrayList;
  13. import java.util.HashMap;
  14. import java.util.Iterator;
  15. import java.util.LinkedHashMap;
  16. import java.util.LinkedList;
  17. /**
  18. *
  19. * @author EUGENIO CARVALHO
  20. */
  21. public class RemoveUnusedLabelsProcessor implements CodeProcessorInterface {
  22. protected HashMap<String, HashMap<String, ArrayList<Instruction>>> labelMap = new HashMap<>();
  23. protected String currentBlock;
  24. private Block block;
  25. public RemoveUnusedLabelsProcessor() {
  26. }
  27. @Override
  28. public void Exec(Code c, LinkedHashMap<String, CodeProcessorInterface> cp) throws Exception {
  29. String label;
  30. Instruction instruction = null;
  31. block = c.Block();
  32. currentBlock = block.getName();
  33. HashMap<String, Integer> referenceCount = c.labelsReferenceCount;
  34. LinkedList<Instruction> instructions = block.Instructions();
  35. ArrayList<Instruction> remover = new ArrayList();
  36. Iterator<Instruction> interator = instructions.iterator();
  37. String[] ignore = new String[]{"block", "user"};
  38. Instruction branch = null, last = null;
  39. int position = 0;
  40. System.out.println("block:" + block.getName() + "-------------------------------");
  41. // System.out.println("\n\n####referenceCount:" + referenceCount + "\n\n");
  42. // Salta o primeiro label
  43. if (interator.hasNext()) {
  44. interator.next();
  45. }
  46. // Remove todos os labels não referenciados
  47. while (interator.hasNext()) {
  48. position++;
  49. last = instruction;
  50. instruction = interator.next();
  51. if (instruction.eq("type", "branch")) {
  52. branch = instruction;
  53. position = 0;
  54. }
  55. // Quando salta um jump altera o enredeco para o endereco do jump e inverte o teste
  56. if (branch != null && last.eq("type", "jump") && instruction.eq("label", branch.Get("label"))) {
  57. // position == 3 &&
  58. branch.Set("op", Utils.ComplementOperation(branch.Get("op")))
  59. .Set("label", last.Get("label"));
  60. branch = null;
  61. remover.add(last);
  62. remover.add(instruction);
  63. continue;
  64. }
  65. if (!instruction.eq("type", "label") || instruction.in("label_type", ignore)) {
  66. continue;
  67. // Unifica labels sequenciais e atualiza as chamadas dos outros labels
  68. }
  69. // A instrucão é um label
  70. label = instruction.Get("label");
  71. // Se o label não existe ou não foi referenciado remove
  72. if (!referenceCount.containsKey(label) || referenceCount.get(label) == 0) {
  73. // System.out.println("Removendo o label " + label);
  74. interator.remove();
  75. }
  76. }
  77. Instruction r;
  78. // Remove as instruções sinalizadas
  79. while (!remover.isEmpty()) {
  80. block.Remove(remover.remove(0));
  81. }
  82. // Remove labels sequenciais
  83. for (Instruction i : block.Instructions()) {
  84. if (last != null) {
  85. if (i.eq("type", "label") && last.eq("type", "label")) {
  86. UpdateLabel(c, last.Get("label"), i.Get("label"));
  87. last.copy("label", i);
  88. remover.add(last);
  89. }
  90. }
  91. last = i;
  92. }
  93. while (!remover.isEmpty()) {
  94. block.Remove(remover.remove(0));
  95. }
  96. }
  97. protected void UpdateLabel(Code c, String old, String newl) {
  98. HashMap<String, ArrayList<Instruction>> lab;
  99. // ArrayList<Instruction> labelInstructions;
  100. String label;
  101. // Cria o mapa de labels para o bloco atual caso não exista
  102. if (!labelMap.containsKey(currentBlock)) {
  103. lab = new HashMap<String, ArrayList<Instruction>>();
  104. labelMap.put(currentBlock, lab);
  105. // Popula a lista de cada de instrucao de cada label
  106. for (Instruction instruction : block.Instructions()) {
  107. if (instruction.Has("label") || instruction.eq("type", "label")) {
  108. label = instruction.Get("label");
  109. if (!lab.containsKey(label)) {
  110. lab.put(label, new ArrayList<Instruction>());
  111. }
  112. lab.get(label).add(instruction);
  113. }
  114. }
  115. } else {
  116. lab = labelMap.get(currentBlock);
  117. }
  118. // System.out.println("lab:" + lab);
  119. // System.out.println("update label:" + old + "----" + newl);
  120. if (lab.containsKey(old)) {
  121. // c.RegisterLabelAddress(old);
  122. for (Instruction instruction : lab.get(old)) {
  123. instruction.Set("label", newl);
  124. }
  125. }
  126. //labelInstructions
  127. }
  128. }