axe_debug.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. /*
  2. * Andrea Di Biagio
  3. * Politecnico di Milano, 2007
  4. *
  5. * axe_debug.c
  6. * Formal Languages & Compilers Machine, 2007/2008
  7. *
  8. */
  9. #include "axe_debug.h"
  10. #include "collections.h"
  11. #include "reg_alloc_constants.h"
  12. #include "cflow_constants.h"
  13. static void printListOfVariables(t_list *variables, FILE *fout);
  14. static void printBBlockInfos(t_basic_block *block, FILE *fout, int verbose);
  15. static void printLiveIntervals(t_list *intervals, FILE *fout);
  16. static void printBindings(int *bindings, int numVars, FILE *fout);
  17. void printBindings(int *bindings, int numVars, FILE *fout)
  18. {
  19. int counter;
  20. if (bindings == NULL)
  21. return;
  22. if (fout == NULL)
  23. return;
  24. /* initialize counter */
  25. counter = 0;
  26. fprintf(fout, "BINDINGS : \n");
  27. while(counter <= numVars)
  28. {
  29. if (bindings[counter] != RA_SPILL_REQUIRED)
  30. {
  31. fprintf(fout, "VAR T%d will be assigned to register R%d \n"
  32. , counter, bindings[counter]);
  33. }
  34. else
  35. {
  36. fprintf(fout, "VAR T%d will be spilled \n", counter);
  37. }
  38. counter++;
  39. }
  40. }
  41. void printRegAllocInfos(t_reg_allocator *RA, FILE *fout)
  42. {
  43. if (RA == NULL)
  44. return;
  45. if (fout == NULL)
  46. return;
  47. fprintf(fout, "\n\n*************************\n");
  48. fprintf(fout, "REGISTER ALLOCATION INFOS\n");
  49. fprintf(fout, "*************************\n");
  50. fprintf(fout, "AVAILABLE REGISTERS : %d \n", RA->regNum + 3);
  51. fprintf(fout, "USED VARIABLES : %d \n", RA->varNum);
  52. fprintf(fout, "-------------------------\n");
  53. printLiveIntervals(RA->live_intervals, fout);
  54. fprintf(fout, "-------------------------\n");
  55. printBindings(RA->bindings, RA->varNum, fout);
  56. fprintf(fout, "*************************\n\n");
  57. }
  58. void printLiveIntervals(t_list *intervals, FILE *fout)
  59. {
  60. t_list *current_element;
  61. t_live_interval *interval;
  62. /* precondition */
  63. if (fout == NULL)
  64. return;
  65. fprintf(fout, "LIVE_INTERVALS:\n");
  66. /* retireve the first element of the list */
  67. current_element = intervals;
  68. while (current_element != NULL)
  69. {
  70. interval = (t_live_interval *) LDATA(current_element);
  71. fprintf(fout, "\tLIVE_INTERVAL of T%d : [%d, %d] \n"
  72. , interval->varID, interval->startPoint, interval->endPoint);
  73. /* retrieve the next element in the list of intervals */
  74. current_element = LNEXT(current_element);
  75. }
  76. }
  77. void printBBlockInfos(t_basic_block *block, FILE *fout, int verbose)
  78. {
  79. t_list *current_element;
  80. t_cflow_Node *current_node;
  81. int count;
  82. /* preconditions */
  83. if (block == NULL)
  84. return;
  85. if (fout == NULL)
  86. return;
  87. fprintf(fout,"NUMBER OF PREDECESSORS : %d \n"
  88. , getLength(block->pred) );
  89. fprintf(fout,"NUMBER OF SUCCESSORS : %d \n"
  90. , getLength(block->succ) );
  91. fprintf(fout,"NUMBER OF INSTRUCTIONS : %d \n"
  92. , getLength(block->nodes) );
  93. count = 1;
  94. current_element = block->nodes;
  95. while(current_element != NULL)
  96. {
  97. current_node = (t_cflow_Node *) LDATA(current_element);
  98. fprintf(fout,"\t%d. ", count);
  99. debug_printInstruction(current_node->instr, fout);
  100. if (verbose != 0)
  101. {
  102. if (current_node->def != NULL)
  103. fprintf(fout, "\n\t\t\tDEF = [R%d]", (current_node->def)->ID);
  104. if (current_node->uses[0] != NULL)
  105. {
  106. fprintf(fout, "\n\t\t\tUSES = [R%d", ((current_node->uses)[0])->ID);
  107. if (current_node->uses[1] != NULL)
  108. fprintf(fout, ", R%d", ((current_node->uses)[1])->ID);
  109. if (current_node->uses[2] != NULL)
  110. fprintf(fout, ", R%d", ((current_node->uses)[2])->ID);
  111. fprintf(fout, "]");
  112. }
  113. fprintf(fout, "\n\t\t\tLIVE IN = [");
  114. printListOfVariables(current_node->in, fout);
  115. fprintf(fout, "]");
  116. fprintf(fout, "\n\t\t\tLIVE OUT = [");
  117. printListOfVariables(current_node->out, fout);
  118. fprintf(fout, "]");
  119. }
  120. fprintf(fout, "\n");
  121. count++;
  122. current_element = LNEXT(current_element);
  123. }
  124. }
  125. void printListOfVariables(t_list *variables, FILE *fout)
  126. {
  127. t_list *current_element;
  128. t_cflow_var *current_variable;
  129. if (variables == NULL)
  130. return;
  131. if (fout == NULL)
  132. return;
  133. current_element = variables;
  134. while(current_element != NULL)
  135. {
  136. current_variable = (t_cflow_var *) LDATA(current_element);
  137. fprintf(fout, "R%d", current_variable->ID);
  138. if (LNEXT(current_element) != NULL)
  139. fprintf(fout, ", ");
  140. current_element = LNEXT(current_element);
  141. }
  142. }
  143. void printGraphInfos(t_cflow_Graph *graph, FILE *fout, int verbose)
  144. {
  145. int counter;
  146. t_list *current_element;
  147. t_basic_block *current_bblock;
  148. /* preconditions */
  149. if (graph == NULL)
  150. return;
  151. if (fout == NULL)
  152. return;
  153. /* initialization of the local variables */
  154. counter = 1;
  155. fprintf(fout,"NOTE : Temporary registers are considered as\n"
  156. " variables of the intermediate language. \n");
  157. #if CFLOW_ALWAYS_LIVEIN_R0 == (1)
  158. fprintf(fout," Variable \'R0\' (that refers to the \n"
  159. " physical register \'RO\') is always \n"
  160. " considered LIVE-IN for each node of \n"
  161. " a basic block. \n"
  162. " Thus, in the following control flow graph, \n"
  163. " \'R0\' will never appear as LIVE-IN or LIVE-OUT\n"
  164. " variable for a statement.\n\n"
  165. " If you want to consider \'R0\' as\n"
  166. " a normal variable, you have to set\n"
  167. " to 0 the value of the macro CFLOW_ALWAYS_LIVEIN_R0\n"
  168. " defined in \"cflow_constants.h\".\n\n");
  169. #endif
  170. fprintf(fout,"\n");
  171. fprintf(fout,"**************************\n");
  172. fprintf(fout," CONTROL FLOW GRAPH \n");
  173. fprintf(fout,"**************************\n");
  174. fprintf(fout,"NUMBER OF BASIC BLOCKS : %d \n"
  175. , getLength(graph->blocks));
  176. fprintf(fout,"NUMBER OF USED VARIABLES : %d \n"
  177. , getLength(graph->cflow_variables));
  178. fprintf(fout,"--------------------------\n");
  179. fprintf(fout,"START BASIC BLOCK INFOS. \n");
  180. fprintf(fout,"--------------------------\n");
  181. /* initialize `current_block' */
  182. current_element = graph->blocks;
  183. while(current_element != NULL)
  184. {
  185. current_bblock = (t_basic_block *) LDATA(current_element);
  186. fprintf(fout,"[BLOCK %d] \n", counter);
  187. printBBlockInfos(current_bblock, fout, verbose);
  188. if (LNEXT(current_element) != NULL)
  189. fprintf(fout,"--------------------------\n");
  190. else
  191. fprintf(fout,"**************************\n");
  192. counter++;
  193. current_element = LNEXT(current_element);
  194. }
  195. fprintf(fout,"\n\n");
  196. }
  197. void debug_printInstruction(t_axe_instruction *instr, FILE *fout)
  198. {
  199. /* preconditions */
  200. if (fout == NULL)
  201. return;
  202. if (instr == NULL)
  203. {
  204. fprintf(fout, "[NULL] \n");
  205. return;
  206. }
  207. if (instr->labelID != NULL)
  208. fprintf(fout, "L%d\t", (instr->labelID)->labelID);
  209. else
  210. fprintf(fout, "\t");
  211. switch(instr->opcode)
  212. {
  213. case ADD : fprintf(fout, "ADD "); break;
  214. case SUB : fprintf(fout, "SUB "); break;
  215. case ANDL : fprintf(fout, "ANDL "); break;
  216. case ORL : fprintf(fout, "ORL "); break;
  217. case EORL : fprintf(fout, "EORL "); break;
  218. case ANDB : fprintf(fout, "ANDB "); break;
  219. case ORB : fprintf(fout, "ORB "); break;
  220. case EORB : fprintf(fout, "EORB "); break;
  221. case MUL : fprintf(fout, "MUL "); break;
  222. case DIV : fprintf(fout, "DIV "); break;
  223. case SHL : fprintf(fout, "SHL "); break;
  224. case SHR : fprintf(fout, "SHR "); break;
  225. case ROTL : fprintf(fout, "ROTL "); break;
  226. case ROTR : fprintf(fout, "ROTR "); break;
  227. case NEG : fprintf(fout, "NEG "); break;
  228. case SPCL : fprintf(fout, "SPCL "); break;
  229. case ADDI : fprintf(fout, "ADDI "); break;
  230. case SUBI : fprintf(fout, "SUBI "); break;
  231. case ANDLI : fprintf(fout, "ANDLI "); break;
  232. case ORLI : fprintf(fout, "ORLI "); break;
  233. case EORLI : fprintf(fout, "EORLI "); break;
  234. case ANDBI : fprintf(fout, "ANDBI "); break;
  235. case ORBI : fprintf(fout, "ORBI "); break;
  236. case EORBI : fprintf(fout, "EORBI "); break;
  237. case MULI : fprintf(fout, "MULI "); break;
  238. case DIVI : fprintf(fout, "DIVI "); break;
  239. case SHLI : fprintf(fout, "SHLI "); break;
  240. case SHRI : fprintf(fout, "SHRI "); break;
  241. case ROTLI : fprintf(fout, "ROTLI "); break;
  242. case ROTRI : fprintf(fout, "ROTRI "); break;
  243. case NOTL : fprintf(fout, "NOTL "); break;
  244. case NOTB : fprintf(fout, "NOTB "); break;
  245. case NOP : fprintf(fout, "NOP "); break;
  246. case MOVA : fprintf(fout, "MOVA "); break;
  247. case JSR : fprintf(fout, "JSR "); break;
  248. case RET : fprintf(fout, "RET "); break;
  249. case HALT : fprintf(fout, "HALT "); break;
  250. case SEQ : fprintf(fout, "SEQ "); break;
  251. case SGE : fprintf(fout, "SGE "); break;
  252. case SGT : fprintf(fout, "SGT "); break;
  253. case SLE : fprintf(fout, "SLE "); break;
  254. case SLT : fprintf(fout, "SLT "); break;
  255. case SNE : fprintf(fout, "SNE "); break;
  256. case BT : fprintf(fout, "BT "); break;
  257. case BF : fprintf(fout, "BF "); break;
  258. case BHI : fprintf(fout, "BHI "); break;
  259. case BLS : fprintf(fout, "BLS "); break;
  260. case BCC : fprintf(fout, "BCC "); break;
  261. case BCS : fprintf(fout, "BCS "); break;
  262. case BNE : fprintf(fout, "BNE "); break;
  263. case BEQ : fprintf(fout, "BEQ "); break;
  264. case BVC : fprintf(fout, "BVC "); break;
  265. case BVS : fprintf(fout, "BVS "); break;
  266. case BPL : fprintf(fout, "BPL "); break;
  267. case BMI : fprintf(fout, "BMI "); break;
  268. case BGE : fprintf(fout, "BGE "); break;
  269. case BLT : fprintf(fout, "BLT "); break;
  270. case BGT : fprintf(fout, "BGT "); break;
  271. case BLE : fprintf(fout, "BLE "); break;
  272. case LOAD : fprintf(fout, "LOAD "); break;
  273. case STORE : fprintf(fout, "STORE "); break;
  274. case AXE_READ : fprintf(fout, "READ "); break;
  275. case AXE_WRITE : fprintf(fout, "WRITE "); break;
  276. case INVALID_OPCODE : fprintf(fout, "[INVALID] ");
  277. }
  278. if (instr->reg_1 != NULL)
  279. {
  280. if (!(instr->reg_1)->indirect)
  281. fprintf(fout, "R%d ", (instr->reg_1)->ID);
  282. else
  283. fprintf(fout, "(R%d) ", (instr->reg_1)->ID);
  284. }
  285. if (instr->reg_2 != NULL)
  286. {
  287. if (!(instr->reg_2)->indirect)
  288. fprintf(fout, "R%d ", (instr->reg_2)->ID);
  289. else
  290. fprintf(fout, "(R%d) ", (instr->reg_2)->ID);
  291. if (instr->reg_3 != NULL)
  292. {
  293. if (!(instr->reg_3)->indirect)
  294. fprintf(fout, "R%d ", (instr->reg_3)->ID);
  295. else
  296. fprintf(fout, "(R%d) ", (instr->reg_3)->ID);
  297. }
  298. else
  299. fprintf(fout, "#%d ", instr->immediate);
  300. }
  301. if (instr->address != NULL)
  302. {
  303. if ((instr->address)->type == LABEL_TYPE)
  304. fprintf(fout, "L%d ", ((instr->address)->labelID)->labelID);
  305. else
  306. fprintf(fout, "%d ", (instr->address)->addr);
  307. }
  308. }
  309. char * dataTypeToString(int codedType)
  310. {
  311. switch (codedType)
  312. {
  313. case INTEGER_TYPE : return "INTEGER";
  314. default : return "<INVALID_TYPE>";
  315. }
  316. }