MipsRegisterAllocProcessor.java 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  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 targets.mips;
  7. import API.Api;
  8. import API.CodeProcessorInterface;
  9. import Processors.BasicBlockProcessor;
  10. import Processors.BlockBaseGroup;
  11. import Processors.BlockBaseOcorrences;
  12. import Processors.Interval;
  13. import common.AllocatorInterface;
  14. import common.Code;
  15. import common.Instruction;
  16. import java.util.LinkedHashMap;
  17. import java.util.LinkedList;
  18. /**
  19. *
  20. * @author EUGENIO CARVALHO
  21. */
  22. public class MipsRegisterAllocProcessor implements AllocatorInterface, CodeProcessorInterface {
  23. protected int instructionPosition;
  24. protected Code tac;
  25. protected Registers registers;
  26. protected BlockBaseGroup group;
  27. protected LinkedList<String> free = new LinkedList<>();
  28. protected BasicBlockProcessor blockProcessor;
  29. public MipsRegisterAllocProcessor() {
  30. }
  31. @Override
  32. public void Exec(Code c, LinkedHashMap<String, CodeProcessorInterface> cp) throws Exception {
  33. System.out.println("AllocatorMipsProcessor:");
  34. String blockname = c.Block().getName();
  35. Code IR = c.Parent;
  36. IR.Use(blockname);
  37. BlockBaseOcorrences bb;
  38. registers = new Registers();
  39. blockProcessor = (BasicBlockProcessor) cp.get("ir.basic.blocks");
  40. instructionPosition = 0;
  41. group = blockProcessor.getBasicBlockGroup(IR.Block().getName());
  42. group.Init();
  43. for (Instruction inst : IR.Block().Instructions()) {
  44. // System.out.println("Alloc:(" + IR.Block().getName() + ")" + inst);
  45. // tipos onde não se usa registrador
  46. switch (inst.Get("type")) {
  47. case "jump":
  48. case "call":
  49. case "return":
  50. instructionPosition++;
  51. case "label":
  52. continue;
  53. default:
  54. // Se a instruncao pertence ao proximo bloco basico atualiza o grupo
  55. bb = group.getBasicBlocks(1);
  56. // System.out.println("###ASSIGN:(" + instructionPosition + ")(" + group.getBasicBlocks(1).getLeader() + ")");
  57. if (bb != null && instructionPosition >= bb.getLeader()) {
  58. group.NextBlock();
  59. // System.out.println(">>>>> Mudei para bloco basico:" + group.Current().getName());
  60. }
  61. // Libera registradores alocados temporariamente
  62. while (!free.isEmpty()) {
  63. registers.Free(free.pop());
  64. }
  65. // Atribui os registradores a instrucao
  66. Assign(inst);
  67. // Incrimenta o ponteiro para a proxima instrucao
  68. instructionPosition++;
  69. }
  70. }
  71. System.out.println(group);
  72. }
  73. @Override
  74. public void Alloc(Code code) {
  75. this.tac = code;
  76. }
  77. protected void Assign(Instruction inst) throws Exception {
  78. String reg;
  79. String[] opDeslocamento = "<<,>>".split(",");
  80. for (String param : new String[]{"p1", "p2", "dst.indice", "p1.indice"}) {
  81. if (!inst.Has(param) || (inst.in("op", opDeslocamento) && param.equals("p2"))) {
  82. continue;
  83. }
  84. // System.out.println("PARAM:[" + param + "value" + "]" + x.eq(param + "value", "true"));
  85. // if (!x.in("op", opDeslocamento)) {
  86. // } else
  87. if (inst.eq(param + "value", "true") || inst.isNumber(param)) {
  88. reg = registers.Lock("t");
  89. free.push(reg);
  90. Load(inst, param);
  91. // System.out.println("Push:" + reg + "-");
  92. // } else if () {
  93. } else {
  94. // System.out.println("GX:" + param + "->" + x);
  95. reg = GetRegister(inst, param);
  96. }
  97. inst.Set("reg." + param, reg);
  98. // System.out.println("Assign:[" + param + "]" + inst);
  99. }
  100. if (inst.Has("dst")) {
  101. inst.Set("reg.dst", GetRegister(inst, "dst"));
  102. }
  103. }
  104. protected void Load(Instruction x, String param) {
  105. x.Set("reg." + param + ".load", "true");
  106. }
  107. protected String GetRegister(Instruction x, String address) throws Exception {
  108. BlockBaseOcorrences bb = group.Current();
  109. String reg, addr = bb.ToAliase(x, address);
  110. int position = x.getInt("block.position"), leader = bb.getLeader();
  111. // Corrige a posicao para iniciar de 0 para cada bloco basico referente ao lider de cada bloco.
  112. position = (leader == 0) ? position : position - leader;
  113. boolean dst = address.equals("dst");
  114. // System.out.println("GetRegister: (" + address + "):(" + addr + ") : ["
  115. // + instructionPosition
  116. // + " : "
  117. // + position
  118. // + " : "
  119. // + leader + "] {");
  120. // System.out.println(x);
  121. Interval interval = bb.Get(addr, position);
  122. // System.out.println(bb);
  123. // System.out.println(interval);
  124. // System.out.println("}");
  125. // Define um registrador se não possuir um definido no intervalo
  126. if (!interval.RegisterDefined()) {
  127. // System.out.println("Não tinha definido: Carregar da memoria(" + (!dst) + ")");
  128. // Verifica a existencia de um registrador disponivel
  129. reg = AvaliableRegister(addr);
  130. // System.out.println("[" + dst + "]GerRegister não definido: (" + address + ")/add: " + addr);
  131. if (!dst) {
  132. // Parametro define que o valor deve ser carregado em registrador;
  133. Load(x, address);
  134. }
  135. // Libera um registrador ocupado
  136. if (reg == null) {
  137. reg = bb.Spill(position).getRegister();
  138. }
  139. // Vincula o registrador com o intervalo
  140. interval.setRegister(reg);
  141. } else {
  142. reg = interval.getRegister();
  143. // Se escreve no registrador e não é o ultimo intervalo marca para
  144. // ser salvo marca para ser salvo.
  145. // if (dst && !group.Last(addr).equals(interval)) {
  146. // Libera o registrador
  147. // System.out.println("Tinha definido::" + reg + ":Liberadp{" + addr + "}:" + (interval.End == position));
  148. }
  149. if (dst) {
  150. interval.Perisist(true);
  151. }
  152. // Se for
  153. // -> A ultima ocorrencia do intervalo e
  154. // -> O registrador é saved e
  155. // -> Ocorreu escrita no registrador
  156. // -> Ponteiros e variaveis globais devem persistidas apos cada operacao de escrita
  157. // marca para gravar em memoria
  158. if (interval.End == position) {
  159. registers.Free(reg);
  160. // System.out.println("reg(" + reg + ")persist(" + interval.Perisist() + ")");
  161. if (reg.substring(0, 1).equals("s")
  162. && interval.Perisist()) {
  163. x.Set("reg." + address + ".store", "true");
  164. }
  165. }
  166. // System.out.println("}" + reg + "::" + position);
  167. return reg;
  168. }
  169. protected String AvaliableRegister(String alias) throws Exception {
  170. String reg = "";
  171. switch (Api.clearID(alias).substring(1, 2)) {
  172. case "V":
  173. case "G":
  174. reg = "s";
  175. break;
  176. case "T":
  177. case "C":
  178. reg = "t";
  179. break;
  180. default:
  181. throw new Exception(String.format("Not avaliable register to alias '%s'", alias));
  182. }
  183. return registers.Lock(reg);
  184. }
  185. protected String PopReturnRegister() {
  186. return null;
  187. }
  188. @Override
  189. public void Get(String id, int position) {
  190. throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
  191. }
  192. }
  193. //leadersList:[0, 3, 7, 8]
  194. // : <bitCount>:
  195. //13: 0: pop_param _V4 T< pop_param >
  196. //14: 1: _V5 := 0 T< copy >
  197. //15: 2: if _V4 <= 0 goto <bitCount+_i4> T< branch >
  198. // : <bitCount+_i6>:
  199. //16: 3: _V5 := _V5 + 1 T< assign >
  200. //17: 4: _T6 := _V4 - 1 T< assign >
  201. //18: 5: _V4 := _V4 & _T6 T< assign >
  202. //19: 6: if _V4 == 0 goto <bitCount+_i7> T< branch >
  203. //20: 7: goto <bitCount+_i6> T< jump >
  204. // : <bitCount+_i7>:
  205. // : <bitCount+_i4>:
  206. //21: 8: push_return _V5 T< push_return >
  207. //22: 9: return 1 T< return >
  208. // : <bitCount-end>: