123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354 |
- /*
- * Andrea Di Biagio
- * Politecnico di Milano, 2007
- *
- * axe_debug.c
- * Formal Languages & Compilers Machine, 2007/2008
- *
- */
- #include "axe_debug.h"
- #include "collections.h"
- #include "reg_alloc_constants.h"
- #include "cflow_constants.h"
- static void printListOfVariables(t_list *variables, FILE *fout);
- static void printBBlockInfos(t_basic_block *block, FILE *fout, int verbose);
- static void printLiveIntervals(t_list *intervals, FILE *fout);
- static void printBindings(int *bindings, int numVars, FILE *fout);
- void printBindings(int *bindings, int numVars, FILE *fout)
- {
- int counter;
-
- if (bindings == NULL)
- return;
- if (fout == NULL)
- return;
- /* initialize counter */
- counter = 0;
- fprintf(fout, "BINDINGS : \n");
- while(counter <= numVars)
- {
- if (bindings[counter] != RA_SPILL_REQUIRED)
- {
- fprintf(fout, "VAR T%d will be assigned to register R%d \n"
- , counter, bindings[counter]);
- }
- else
- {
- fprintf(fout, "VAR T%d will be spilled \n", counter);
- }
-
- counter++;
- }
- }
- void printRegAllocInfos(t_reg_allocator *RA, FILE *fout)
- {
- if (RA == NULL)
- return;
- if (fout == NULL)
- return;
- fprintf(fout, "\n\n*************************\n");
- fprintf(fout, "REGISTER ALLOCATION INFOS\n");
- fprintf(fout, "*************************\n");
- fprintf(fout, "AVAILABLE REGISTERS : %d \n", RA->regNum + 3);
- fprintf(fout, "USED VARIABLES : %d \n", RA->varNum);
- fprintf(fout, "-------------------------\n");
- printLiveIntervals(RA->live_intervals, fout);
- fprintf(fout, "-------------------------\n");
- printBindings(RA->bindings, RA->varNum, fout);
- fprintf(fout, "*************************\n\n");
- }
- void printLiveIntervals(t_list *intervals, FILE *fout)
- {
- t_list *current_element;
- t_live_interval *interval;
- /* precondition */
- if (fout == NULL)
- return;
- fprintf(fout, "LIVE_INTERVALS:\n");
- /* retireve the first element of the list */
- current_element = intervals;
- while (current_element != NULL)
- {
- interval = (t_live_interval *) LDATA(current_element);
- fprintf(fout, "\tLIVE_INTERVAL of T%d : [%d, %d] \n"
- , interval->varID, interval->startPoint, interval->endPoint);
-
- /* retrieve the next element in the list of intervals */
- current_element = LNEXT(current_element);
- }
- }
- void printBBlockInfos(t_basic_block *block, FILE *fout, int verbose)
- {
- t_list *current_element;
- t_cflow_Node *current_node;
- int count;
-
- /* preconditions */
- if (block == NULL)
- return;
- if (fout == NULL)
- return;
- fprintf(fout,"NUMBER OF PREDECESSORS : %d \n"
- , getLength(block->pred) );
- fprintf(fout,"NUMBER OF SUCCESSORS : %d \n"
- , getLength(block->succ) );
- fprintf(fout,"NUMBER OF INSTRUCTIONS : %d \n"
- , getLength(block->nodes) );
- count = 1;
- current_element = block->nodes;
- while(current_element != NULL)
- {
- current_node = (t_cflow_Node *) LDATA(current_element);
- fprintf(fout,"\t%d. ", count);
- debug_printInstruction(current_node->instr, fout);
- if (verbose != 0)
- {
- if (current_node->def != NULL)
- fprintf(fout, "\n\t\t\tDEF = [R%d]", (current_node->def)->ID);
- if (current_node->uses[0] != NULL)
- {
- fprintf(fout, "\n\t\t\tUSES = [R%d", ((current_node->uses)[0])->ID);
- if (current_node->uses[1] != NULL)
- fprintf(fout, ", R%d", ((current_node->uses)[1])->ID);
- if (current_node->uses[2] != NULL)
- fprintf(fout, ", R%d", ((current_node->uses)[2])->ID);
- fprintf(fout, "]");
- }
- fprintf(fout, "\n\t\t\tLIVE IN = [");
- printListOfVariables(current_node->in, fout);
- fprintf(fout, "]");
- fprintf(fout, "\n\t\t\tLIVE OUT = [");
- printListOfVariables(current_node->out, fout);
- fprintf(fout, "]");
- }
-
- fprintf(fout, "\n");
- count++;
- current_element = LNEXT(current_element);
- }
- }
- void printListOfVariables(t_list *variables, FILE *fout)
- {
- t_list *current_element;
- t_cflow_var *current_variable;
-
- if (variables == NULL)
- return;
- if (fout == NULL)
- return;
- current_element = variables;
- while(current_element != NULL)
- {
- current_variable = (t_cflow_var *) LDATA(current_element);
- fprintf(fout, "R%d", current_variable->ID);
- if (LNEXT(current_element) != NULL)
- fprintf(fout, ", ");
-
- current_element = LNEXT(current_element);
- }
- }
- void printGraphInfos(t_cflow_Graph *graph, FILE *fout, int verbose)
- {
- int counter;
- t_list *current_element;
- t_basic_block *current_bblock;
-
- /* preconditions */
- if (graph == NULL)
- return;
- if (fout == NULL)
- return;
- /* initialization of the local variables */
- counter = 1;
-
- fprintf(fout,"NOTE : Temporary registers are considered as\n"
- " variables of the intermediate language. \n");
- #if CFLOW_ALWAYS_LIVEIN_R0 == (1)
- fprintf(fout," Variable \'R0\' (that refers to the \n"
- " physical register \'RO\') is always \n"
- " considered LIVE-IN for each node of \n"
- " a basic block. \n"
- " Thus, in the following control flow graph, \n"
- " \'R0\' will never appear as LIVE-IN or LIVE-OUT\n"
- " variable for a statement.\n\n"
- " If you want to consider \'R0\' as\n"
- " a normal variable, you have to set\n"
- " to 0 the value of the macro CFLOW_ALWAYS_LIVEIN_R0\n"
- " defined in \"cflow_constants.h\".\n\n");
- #endif
- fprintf(fout,"\n");
- fprintf(fout,"**************************\n");
- fprintf(fout," CONTROL FLOW GRAPH \n");
- fprintf(fout,"**************************\n");
- fprintf(fout,"NUMBER OF BASIC BLOCKS : %d \n"
- , getLength(graph->blocks));
- fprintf(fout,"NUMBER OF USED VARIABLES : %d \n"
- , getLength(graph->cflow_variables));
- fprintf(fout,"--------------------------\n");
- fprintf(fout,"START BASIC BLOCK INFOS. \n");
- fprintf(fout,"--------------------------\n");
- /* initialize `current_block' */
- current_element = graph->blocks;
- while(current_element != NULL)
- {
- current_bblock = (t_basic_block *) LDATA(current_element);
- fprintf(fout,"[BLOCK %d] \n", counter);
- printBBlockInfos(current_bblock, fout, verbose);
- if (LNEXT(current_element) != NULL)
- fprintf(fout,"--------------------------\n");
- else
- fprintf(fout,"**************************\n");
- counter++;
- current_element = LNEXT(current_element);
- }
-
- fprintf(fout,"\n\n");
- }
- void debug_printInstruction(t_axe_instruction *instr, FILE *fout)
- {
- /* preconditions */
- if (fout == NULL)
- return;
-
- if (instr == NULL)
- {
- fprintf(fout, "[NULL] \n");
- return;
- }
- if (instr->labelID != NULL)
- fprintf(fout, "L%d\t", (instr->labelID)->labelID);
- else
- fprintf(fout, "\t");
-
- switch(instr->opcode)
- {
- case ADD : fprintf(fout, "ADD "); break;
- case SUB : fprintf(fout, "SUB "); break;
- case ANDL : fprintf(fout, "ANDL "); break;
- case ORL : fprintf(fout, "ORL "); break;
- case EORL : fprintf(fout, "EORL "); break;
- case ANDB : fprintf(fout, "ANDB "); break;
- case ORB : fprintf(fout, "ORB "); break;
- case EORB : fprintf(fout, "EORB "); break;
- case MUL : fprintf(fout, "MUL "); break;
- case DIV : fprintf(fout, "DIV "); break;
- case SHL : fprintf(fout, "SHL "); break;
- case SHR : fprintf(fout, "SHR "); break;
- case ROTL : fprintf(fout, "ROTL "); break;
- case ROTR : fprintf(fout, "ROTR "); break;
- case NEG : fprintf(fout, "NEG "); break;
- case SPCL : fprintf(fout, "SPCL "); break;
- case ADDI : fprintf(fout, "ADDI "); break;
- case SUBI : fprintf(fout, "SUBI "); break;
- case ANDLI : fprintf(fout, "ANDLI "); break;
- case ORLI : fprintf(fout, "ORLI "); break;
- case EORLI : fprintf(fout, "EORLI "); break;
- case ANDBI : fprintf(fout, "ANDBI "); break;
- case ORBI : fprintf(fout, "ORBI "); break;
- case EORBI : fprintf(fout, "EORBI "); break;
- case MULI : fprintf(fout, "MULI "); break;
- case DIVI : fprintf(fout, "DIVI "); break;
- case SHLI : fprintf(fout, "SHLI "); break;
- case SHRI : fprintf(fout, "SHRI "); break;
- case ROTLI : fprintf(fout, "ROTLI "); break;
- case ROTRI : fprintf(fout, "ROTRI "); break;
- case NOTL : fprintf(fout, "NOTL "); break;
- case NOTB : fprintf(fout, "NOTB "); break;
- case NOP : fprintf(fout, "NOP "); break;
- case MOVA : fprintf(fout, "MOVA "); break;
- case JSR : fprintf(fout, "JSR "); break;
- case RET : fprintf(fout, "RET "); break;
- case HALT : fprintf(fout, "HALT "); break;
- case SEQ : fprintf(fout, "SEQ "); break;
- case SGE : fprintf(fout, "SGE "); break;
- case SGT : fprintf(fout, "SGT "); break;
- case SLE : fprintf(fout, "SLE "); break;
- case SLT : fprintf(fout, "SLT "); break;
- case SNE : fprintf(fout, "SNE "); break;
- case BT : fprintf(fout, "BT "); break;
- case BF : fprintf(fout, "BF "); break;
- case BHI : fprintf(fout, "BHI "); break;
- case BLS : fprintf(fout, "BLS "); break;
- case BCC : fprintf(fout, "BCC "); break;
- case BCS : fprintf(fout, "BCS "); break;
- case BNE : fprintf(fout, "BNE "); break;
- case BEQ : fprintf(fout, "BEQ "); break;
- case BVC : fprintf(fout, "BVC "); break;
- case BVS : fprintf(fout, "BVS "); break;
- case BPL : fprintf(fout, "BPL "); break;
- case BMI : fprintf(fout, "BMI "); break;
- case BGE : fprintf(fout, "BGE "); break;
- case BLT : fprintf(fout, "BLT "); break;
- case BGT : fprintf(fout, "BGT "); break;
- case BLE : fprintf(fout, "BLE "); break;
- case LOAD : fprintf(fout, "LOAD "); break;
- case STORE : fprintf(fout, "STORE "); break;
- case AXE_READ : fprintf(fout, "READ "); break;
- case AXE_WRITE : fprintf(fout, "WRITE "); break;
- case INVALID_OPCODE : fprintf(fout, "[INVALID] ");
- }
- if (instr->reg_1 != NULL)
- {
- if (!(instr->reg_1)->indirect)
- fprintf(fout, "R%d ", (instr->reg_1)->ID);
- else
- fprintf(fout, "(R%d) ", (instr->reg_1)->ID);
- }
- if (instr->reg_2 != NULL)
- {
- if (!(instr->reg_2)->indirect)
- fprintf(fout, "R%d ", (instr->reg_2)->ID);
- else
- fprintf(fout, "(R%d) ", (instr->reg_2)->ID);
- if (instr->reg_3 != NULL)
- {
- if (!(instr->reg_3)->indirect)
- fprintf(fout, "R%d ", (instr->reg_3)->ID);
- else
- fprintf(fout, "(R%d) ", (instr->reg_3)->ID);
- }
- else
- fprintf(fout, "#%d ", instr->immediate);
- }
-
- if (instr->address != NULL)
- {
- if ((instr->address)->type == LABEL_TYPE)
- fprintf(fout, "L%d ", ((instr->address)->labelID)->labelID);
- else
- fprintf(fout, "%d ", (instr->address)->addr);
- }
- }
- char * dataTypeToString(int codedType)
- {
- switch (codedType)
- {
- case INTEGER_TYPE : return "INTEGER";
- default : return "<INVALID_TYPE>";
- }
- }
|