MipsRegisterAllocMiddleware.java 9.3 KB

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