RemoveUnusedLabelsMiddleware.java 5.5 KB

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