RemoveUnusedLabelsMiddleware.java 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  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 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 RemoveUnusedLabelsMiddleware implements MiddlewareInterface {
  22. protected HashMap<String, HashMap<String, ArrayList<Instruction>>> labelMap = new HashMap<>();
  23. protected String currentBlock;
  24. private Block block;
  25. public RemoveUnusedLabelsMiddleware() {
  26. }
  27. @Override
  28. public void Exec(Code c, LinkedHashMap<String, MiddlewareInterface> 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")) {
  57. if (instruction.eq("label", branch.Get("label"))) {
  58. // position == 3 &&
  59. branch.Set("op", Utils.ComplementOperation(branch.Get("op")))
  60. .Set("label", last.Get("label"));
  61. branch = null;
  62. remover.add(last);
  63. remover.add(instruction);
  64. continue;
  65. }
  66. }
  67. if (!instruction.eq("type", "label") || instruction.in("label_type", ignore)) {
  68. continue;
  69. // Unifica labels sequenciais e atualiza as chamadas dos outros labels
  70. }
  71. // A instrucão é um label
  72. label = instruction.Get("label");
  73. // Se o label não existe ou não foi referenciado remove
  74. if (!referenceCount.containsKey(label) || referenceCount.get(label) == 0) {
  75. // System.out.println("Removendo o label " + label);
  76. interator.remove();
  77. }
  78. }
  79. Instruction r;
  80. // Remove as instruções sinalizadas
  81. while (!remover.isEmpty()) {
  82. block.Remove(remover.remove(0));
  83. }
  84. // Remove labels sequenciais
  85. for (Instruction i : block.Instructions()) {
  86. if (last != null) {
  87. if (i.eq("type", "label") && last.eq("type", "label")) {
  88. UpdateLabel(c, last.Get("label"), i.Get("label"));
  89. last.copy("label", i);
  90. remover.add(last);
  91. }
  92. }
  93. last = i;
  94. }
  95. while (!remover.isEmpty()) {
  96. block.Remove(remover.remove(0));
  97. }
  98. }
  99. protected void UpdateLabel(Code c, String old, String newl) {
  100. HashMap<String, ArrayList<Instruction>> lab;
  101. // ArrayList<Instruction> labelInstructions;
  102. String label;
  103. // Cria o mapa de labels para o bloco atual caso não exista
  104. if (!labelMap.containsKey(currentBlock)) {
  105. lab = new HashMap<>();
  106. labelMap.put(currentBlock, lab);
  107. // Popula a lista de cada de instrucao de cada label
  108. for (Instruction instruction : block.Instructions()) {
  109. if (instruction.Has("label") || instruction.eq("type", "label")) {
  110. label = instruction.Get("label");
  111. if (!lab.containsKey(label)) {
  112. lab.put(label, new ArrayList<>());
  113. }
  114. lab.get(label).add(instruction);
  115. }
  116. }
  117. } else {
  118. lab = labelMap.get(currentBlock);
  119. }
  120. // System.out.println("lab:" + lab);
  121. // System.out.println("update label:" + old + "----" + newl);
  122. if (lab.containsKey(old)) {
  123. // c.RegisterLabelAddress(old);
  124. lab.get(old).forEach((instruction) -> {
  125. instruction.Set("label", newl);
  126. });
  127. }
  128. //labelInstructions
  129. }
  130. }