Allocation.java 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374
  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 IntermediaryCode;
  7. import java.util.ArrayList;
  8. import java.util.HashMap;
  9. import java.util.Map;
  10. /**
  11. *
  12. * @author Eugenio
  13. */
  14. public class Allocation {
  15. protected static int registerCount = 32;
  16. protected int lastLine = 0;
  17. protected HashMap<String, Ocorrence> vars;
  18. // HashMap<String, HashMap<Integer, Integer>> vars;
  19. HashMap<String, ArrayList<ArrayList<Integer>>> intervals;
  20. protected static ArrayList<String> labels;
  21. protected ArrayList<Boolean> registers;
  22. protected HashMap<String, Integer> assigns;
  23. protected HashMap<String, String> regAssigns;
  24. protected Integer swapRegister;
  25. protected Integer currentRegister;
  26. protected ArrayList<Integer> interval;
  27. public Allocation(int sizeOfBlock, HashMap<String, Ocorrence> varOcorrences) {
  28. vars = varOcorrences;
  29. lastLine = sizeOfBlock;
  30. intervals = new HashMap<>();
  31. labels = new ArrayList<>();
  32. registers = new ArrayList<>();
  33. assigns = new HashMap<>();
  34. regAssigns = new HashMap<>();
  35. initRegisters();
  36. }
  37. @Override
  38. public String toString() {
  39. return "Allocation:\n"
  40. + "Registers\n" + registers.toString()
  41. + "\nAssigns\n" + assigns.toString()
  42. + "\nReg->Var\n" + regAssigns.toString();
  43. }
  44. public static String reg2Str(int reg) {
  45. return labels.get(reg);
  46. }
  47. public static int reg2Int(String regis) {
  48. return labels.indexOf(regis);
  49. }
  50. public void put(int line, String var, int reg) {
  51. // System.out.println("Put:" + var + ":" + line + ":" + reg);
  52. assigns.put(var + "." + line, reg);
  53. regAssigns.put(reg + "." + line, var);
  54. // System.out.println("assigns:" + assigns + ":" + regAssigns);
  55. }
  56. public void remove(int line, String var, int reg) {
  57. assigns.remove(var + "." + line);
  58. regAssigns.remove(reg + "." + line);
  59. }
  60. public String get(int line, String var) {
  61. String key = var + "." + line;
  62. if (assigns.containsKey(key)) {
  63. return reg2Str(assigns.get(key));
  64. }
  65. return "undefined";
  66. }
  67. public String var(int line, String reg) {
  68. String key = reg + "." + line;
  69. if (regAssigns.containsKey(key)) {
  70. return regAssigns.get(key);
  71. }
  72. return "undefined";
  73. }
  74. public void register(int line, String var) throws Exception {
  75. if (!var.matches("^_.*")) {
  76. return;
  77. }
  78. // System.out.println("Register:" + line + ":" + var);
  79. Integer reg;
  80. /*Se não existe um registrador associado a variavel retorna*/
  81. if (!alive(line, var)) {
  82. /*Tenta alocar um registrador para variavel*/
  83. reg = assign(line, var);
  84. /*Se não existem registradores disponiveis executa a troca*/
  85. if (reg == null) {
  86. reg = swap(line, var);
  87. }
  88. /*Atribui o registrador ao intervalo atual*/
  89. interval.set(2, reg);
  90. } else {
  91. /* atribui o registrador do intervalo*/
  92. reg = interval.get(2);
  93. }
  94. System.out.println("put_register:" + line + ":" + var + ":" + reg);
  95. put(line, var, reg);
  96. }
  97. protected ArrayList<Integer> newInterval(int line, String var) {
  98. interval = new ArrayList<>();
  99. interval.add(line);//inicio do intervalo
  100. interval.add(vars.get(var).last());//fim do intervalo
  101. interval.add(-1);//não possui registrador
  102. intervals.get(var).add(interval);
  103. return interval;
  104. }
  105. /**
  106. * Verifica se a variavel possui um registrador associado na a um intervalo
  107. *
  108. * @param line
  109. * @param var
  110. * @return
  111. * @throws java.lang.Exception
  112. */
  113. public boolean alive(int line, String var) throws Exception {
  114. // return !dead(line, var);
  115. // return vars.get(var).last() >= line;
  116. interval = interval(line, var);
  117. return interval.get(2) >= 0;
  118. }
  119. protected boolean dead(int line, String var) throws Exception {
  120. if (!vars.containsKey(var)) {
  121. throw new Exception("Var '" + var + "' not found!");
  122. }
  123. return vars.get(var).last() < line;
  124. }
  125. protected ArrayList<ArrayList<Integer>> intervals(int line, int regb, int rege) {
  126. for (Map.Entry<String, ArrayList<ArrayList<Integer>>> entry : intervals.entrySet()) {
  127. String string = entry.getKey();
  128. // Ocorrence ocorrence = entry.getValue();
  129. }
  130. return null;
  131. }
  132. protected ArrayList<Integer> interval(int line, String var) {
  133. if (!intervals.containsKey(var)) {
  134. intervals.put(var, new ArrayList<ArrayList<Integer>>());
  135. return newInterval(line, var);
  136. }
  137. /*Verifica se o intervalo existe*/
  138. ArrayList<ArrayList<Integer>> itens = intervals.get(var);
  139. ArrayList<Integer> i;
  140. for (int count = itens.size() - 1; count >= 0; count--) {
  141. i = itens.get(count);
  142. if (line >= i.get(0) && line <= i.get(1)) {
  143. return i;
  144. }
  145. }
  146. /*Cria o intervalo caso não exista */
  147. return newInterval(line, var);
  148. }
  149. protected int coust(int line, String var) throws Exception {
  150. if (!vars.containsKey(var)) {
  151. throw new Exception("[Coust] Var '" + var + "' not found!");
  152. }
  153. return vars.get(var).nextOcorrenceAfter(line);
  154. }
  155. protected Integer swap(int line, String var) throws Exception {
  156. // int[] result = {0, -1};
  157. // Integer reg = free(regType(var), true, line);
  158. //
  159. // if (reg != null) {
  160. // result[0] = 1;
  161. // result[1] = reg;
  162. // }
  163. return free(regType(var), true, line, var);
  164. /*Verifica se existe alguma variavel que não possui mais ocorrencia apos a linha atual.
  165. * Retorno é um vetor de inteiros. o primeiro indice indica se encontrou ou não e o segundo
  166. * é o valor do registrador.
  167. */ // int[] result = ;
  168. // Integer reg = null;
  169. // if (result[0] == 0) {
  170. // /*Se não encontrou um registrador disponivel forca a troca*/
  171. // reg = swapRegister;
  172. // } else {
  173. // reg = result[1];
  174. // }
  175. }
  176. protected Integer assign(int line, String var) throws Exception {
  177. return free(regType(var), false, line, var);
  178. }
  179. protected Integer free(String base, boolean recicle, int line, String var) throws Exception {
  180. int start, end;
  181. switch (base) {
  182. case "v":
  183. start = 2;
  184. end = 3;
  185. break;
  186. case "a":
  187. start = 4;
  188. end = 7;
  189. break;
  190. case "s":
  191. start = 16;
  192. end = 23;
  193. break;
  194. case "k":
  195. start = 26;
  196. end = 27;
  197. break;
  198. case "t":
  199. Integer result = free(8, 15, recicle, line, var);
  200. if (result == null) {
  201. result = free(24, 25, recicle, line, var);
  202. }
  203. return result;
  204. default:
  205. throw new Exception("Register type " + base + " not defined!");
  206. }
  207. return free(start, end, recicle, line, var);
  208. }
  209. protected Integer recicle(int begin, int end, int line, String var) throws Exception {
  210. int[] result = {0, 0};
  211. int limit = 0, coust;
  212. return 1;
  213. // ArrayList<Integer> lowCoust;
  214. //
  215. //// for (int reg = begin; reg <= end; reg++) {
  216. // try {
  217. //
  218. // for (ArrayList<Integer> interval : intervals(line, begin, end)) {
  219. //
  220. // }
  221. //
  222. // } catch (DeadInterval e) {
  223. // return e.getRegister();
  224. // }
  225. ////
  226. //// if (dead(line, var)) {
  227. //// return interval.get(2);
  228. //// }
  229. //
  230. //// var = regAssigns.get(reg + "." + line);
  231. ////
  232. ////
  233. ////
  234. //// coust = coust(line, var);
  235. ////
  236. //// if (coust > limit) {
  237. //// limit = coust;
  238. //// swapRegister = reg;
  239. //// }
  240. }
  241. protected Integer free(int begin, int end, boolean recicle, int line, String var) throws Exception {
  242. if (recicle) {
  243. return recicle(begin, end, line, var);
  244. }
  245. for (int i = begin; i <= end; i++) {
  246. if (!registers.get(i)) {
  247. registers.set(i, true);
  248. return i;
  249. }
  250. }
  251. return null;
  252. }
  253. protected String regType(String var) throws Exception {
  254. var = var.replace("*", "")
  255. .replace("&", "")
  256. .substring(0, 2);
  257. switch (var) {
  258. case "_T":
  259. case "_C":
  260. return "t";
  261. case "_I":
  262. case "_V":
  263. case "_P":
  264. case "_Y":
  265. case "_X":
  266. case "_G":
  267. return "s";
  268. case "_A":
  269. return "a";
  270. }
  271. throw new Exception("Invalid label '" + var + "'!");
  272. }
  273. protected void initRegisters() {
  274. for (int i = 0; i < registerCount; i++) {
  275. registers.add(false);
  276. }
  277. //Zero
  278. labels.add("zero");
  279. //Assembler
  280. labels.add("$at");
  281. //Returns
  282. labels.add("$v0");
  283. labels.add("$v1");
  284. //Arguments
  285. labels.add("$a0");
  286. labels.add("$a1");
  287. labels.add("$a2");
  288. labels.add("$a3");
  289. //Temporary
  290. labels.add("$t0");
  291. labels.add("$t1");
  292. labels.add("$t2");
  293. labels.add("$t3");
  294. labels.add("$t4");
  295. labels.add("$t5");
  296. labels.add("$t6");
  297. labels.add("$t7");
  298. //Saved
  299. labels.add("$s0");
  300. labels.add("$s1");
  301. labels.add("$s2");
  302. labels.add("$s3");
  303. labels.add("$s4");
  304. labels.add("$s5");
  305. labels.add("$s6");
  306. labels.add("$s7");
  307. //Temporary
  308. labels.add("$t8");
  309. labels.add("$t9");
  310. //Kernel
  311. labels.add("$k0");
  312. labels.add("$k1");
  313. //Stack control
  314. labels.add("$gp");
  315. labels.add("$sp");
  316. labels.add("$fp");
  317. //Return address
  318. labels.add("$ra");
  319. }
  320. }