Allocation.java 10 KB

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