cvsuser 02/07/15 13:13:10
Modified: languages/imcc cfg.c cfg.h debug.c debug.h imc.c imc.h
instructions.c instructions.h symreg.c symreg.h
Log:
More patches from Angel Faus and Sean O'Rourke for IMCC.
Revision Changes Path
1.2 +204 -5 parrot/languages/imcc/cfg.c
Index: cfg.c
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/cfg.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -w -r1.1 -r1.2
--- cfg.c 4 Jul 2002 02:58:30 -0000 1.1
+++ cfg.c 15 Jul 2002 20:13:10 -0000 1.2
@@ -28,6 +28,7 @@
bb = make_basic_block(last);
nu = 0;
+ ins = NULL;
for(j = 1; instructions[j]; j++) {
@@ -38,9 +39,11 @@
nu = 0;
}
else if (next->type == ITLABEL) {
+ if (ins != NULL) {
bb->end = ins;
bb = make_basic_block(next);
}
+ }
else if (next->type == ITBRANCH) {
next->basic_block = bb;
bb->end = next;
@@ -119,6 +122,10 @@
of 'to'. */
e = malloc(sizeof(Edge));
+ if (e==NULL) {
+ fprintf(stderr, "Memory error at bb_add_edge\n");
+ abort();
+ }
e->succ_next = from->succ_list;
e->from = from;
@@ -129,11 +136,183 @@
from->succ_list = to->pred_list = e;
}
+
+void life_analysis() {
+ int i;
+
+ for(i = 0; i < HASH_SIZE; i++) {
+ SymReg * r = hash[i];
+ for(; r; r = r->next) {
+ if (r->type == VTIDENTIFIER)
+ analyse_life_symbol(r);
+ }
+ }
+}
+
+void analyse_life_symbol(SymReg* r) {
+ int i;
+
+ r->life_info = calloc(n_basic_blocks, sizeof(Life_range*));
+ if (r->life_info == NULL) {
+ fprintf(stderr, "Memory error at analyse_life_symbol");
+ abort();
+ }
+
+ /* First we make a pass to each block to gather the information
+ * that can be obtained locally */
+
+ for (i=0; i < n_basic_blocks; i++) {
+ analyse_life_block(bb_list[i], r);
+ }
+
+ /* Now we need to consider the relations between blocks */
+
+ for (i=0; i < n_basic_blocks; i++) {
+ if (r->life_info[i]->flags & LF_use) {
+
+ /* This block uses r, so it must be live at
+ the beggining */
+ r->life_info[i]->flags |= LF_lv_in;
+
+ /* propagate this info to every predecessor */
+ propagate_need (bb_list[i], r);
+ }
+ }
+}
+
+/* analyse_life_block studies the state of the var r
+ * in the block bb.
+ *
+ * Its job is to set the flags LF_use, or LF_read,
+ * and record the intervals inside the block where
+ * the var is alive.
+ */
+
+void analyse_life_block(Basic_block* bb, SymReg* r) {
+ int i, write_pos, read_pos;
+ Instruction* ins;
+ Life_range* l;
+
+ l = make_life_range(r, bb->index);
+ write_pos = -1;
+ read_pos = -1;
+
+ for (i=bb->start->index; i < bb->end->index; i++) {
+ ins = instructions[i];
+ if (ins==NULL) {
+ fprintf(stderr, "Index %i of %i has NULL instruction\n",
+ i, bb->end->index);
+ fprintf(stderr, "Total numb. of instructions = %li\n",
+ n_instructions);
+ abort();
+ }
+ if (instruction_reads(ins, r)) {
+ if (l->flags != LF_def) {
+
+ /* we read before having written before, so the var was
+ * live at the beggining of the block */
+ write_pos = bb->start->index;
+ l->flags = LF_use;
+ }
+ read_pos = i;
+ }
+
+ if (instruction_writes(ins, r)) {
+ if (write_pos < 0) {
+ l->flags = LF_def;
+ write_pos = i;
+ }
+ else if (read_pos < 0) {
+ /* there has not been any read until here, so the previous write
+ * is irrelevant */
+ write_pos = i;
+ }
+ else {
+ /* this is new writing, after some reading */
+ add_life_interval(l, write_pos, read_pos);
+ read_pos = -1;
+ write_pos = i;
+ }
+ }
+ }
+
+ /* At the end, we need to add the last range */
+ if (read_pos < 0) read_pos = write_pos;
+
+ if (write_pos >= 0)
+ add_life_interval(l, write_pos, read_pos);
+
+
+ /* The read_pos can latter be extended if it turns out
+ * that another block needs the value resulting of this
+ * computation */
+}
+
+/* add_life_interval records a new range of use of the var
+ * and set the LF_lv_inside flag
+ */
+
+void add_life_interval(Life_range *l, int from, int to) {
+ int length = l->n_intervals;
+
+ l->intervals = realloc(l->intervals, (length + 2) * sizeof(int) + 1);
+ if (l->intervals == NULL) {
+ fprintf(stderr, "Memory error at add_life_interval\n");
+ abort();
+ }
+
+ l->intervals[length*2] = from;
+ l->intervals[length*2 + 1] = to;
+
+ l->n_intervals = length + 1;
+
+ l->flags |= LF_lv_inside;
+
+}
+
+
+void propagate_need(Basic_block *bb, SymReg* r) {
+ Edge *edge;
+ Basic_block *pred;
+ Life_range *l;
+
+ /* every predecessor of a LF_lv_in block must be in LF_lv_out
+ and, unless itself is LV_def, this should be propagated to
+ its predecessors themselves */
+
+ for (edge=bb->pred_list; edge!=NULL; edge=edge->pred_next) {
+ pred = edge->from;
+ l = r->life_info[pred->index];
+
+ if (l->flags & LF_lv_out) {
+ /* this node has already been visited. Ignore it */
+ }
+ else {
+ l->flags |= LF_lv_out;
+
+ if (l->flags & LF_lv_inside) {
+ /* we expand the last interval to the end */
+ l->intervals[l->n_intervals * 2 - 1] = pred->end->index;
+ }
+
+ if (! (l->flags & LF_def) ) {
+ l->flags |= LF_lv_in;
+ if (! (l->flags & LF_lv_inside) ) {
+ l->flags |= LF_lv_all | LF_lv_inside;
+ }
+
+ propagate_need(pred, r);
+ }
+ }
+ }
+}
+
+
/*** Utility functions ***/
void init_basic_blocks() {
- if (bb_list == NULL) {
+ if (bb_list != NULL) {
free(bb_list);
}
@@ -155,6 +334,10 @@
}
bb = malloc(sizeof(Basic_block));
+ if (bb==NULL) {
+ fprintf(stderr, "Memory error at make_basic_block\n");
+ abort();
+ }
bb->start = ins;
bb->end = NULL;
@@ -169,3 +352,19 @@
return bb;
}
+Life_range* make_life_range(SymReg *r, int index) {
+ Life_range *l;
+
+ l = malloc(sizeof(Life_range));
+ if (l==NULL) {
+ fprintf(stderr, "Memory Error at make_life_range\n");
+ abort();
+ }
+
+ l->flags = 0;
+ l->n_intervals = 0;
+ l->intervals = NULL;
+
+ r->life_info[index] = l;
+ return l;
+}
1.2 +7 -1 parrot/languages/imcc/cfg.h
Index: cfg.h
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/cfg.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -w -r1.1 -r1.2
--- cfg.h 4 Jul 2002 02:58:30 -0000 1.1
+++ cfg.h 15 Jul 2002 20:13:10 -0000 1.2
@@ -20,7 +20,6 @@
int index; /*on bb_list*/
} Basic_block;
-
/* Globals: */
Basic_block **bb_list;
int n_basic_blocks;
@@ -33,6 +32,13 @@
void bb_findadd_edge(Basic_block*, SymReg*);
void bb_add_edge();
+void life_analysis();
+void analyse_life_symbol(SymReg*);
+void analyse_life_block(Basic_block*, SymReg*);
+void add_life_interval(Life_range*, int, int);
+void propagate_need(Basic_block*, SymReg*);
+
void init_basic_blocks();
Basic_block* make_basic_block(Instruction*);
void clear_basic_blocks();
+Life_range* make_life_range(SymReg*, int);
1.2 +46 -2 parrot/languages/imcc/debug.c
Index: debug.c
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/debug.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -w -r1.1 -r1.2
--- debug.c 4 Jul 2002 02:58:30 -0000 1.1
+++ debug.c 15 Jul 2002 20:13:10 -0000 1.2
@@ -12,7 +12,7 @@
bb = ins->basic_block;
if (bb) {
- fprintf(stderr, "%d\t", bb->index);
+ fprintf(stderr, "%i\t%d\t", ins->index, bb->index);
}
else {
fprintf(stderr, "\t");
@@ -58,6 +58,50 @@
}
}
fprintf(stderr, "\n");
+ dump_liveness_status();
+
+}
+
+void dump_liveness_status() {
+ int i;
+
+ fprintf(stderr, "\nSymbols:\n--------------------------------------\n");
+ for(i = 0; i < HASH_SIZE; i++) {
+ SymReg * r = hash[i];
+ for(; r; r = r->next) {
+ if (r->type == VTIDENTIFIER) dump_liveness_status_var(r);
+ }
+ }
+ fprintf(stderr, "\n");
+
+}
+
+
+void dump_liveness_status_var(SymReg* r) {
+ int i, j;
+ Life_range *l;
+
+ fprintf(stderr, "\nSymbol %s:", r->name);
+ if (r->life_info==NULL) return;
+ for (i=0; i<n_basic_blocks; i++) {
+ l = r->life_info[i];
+
+ if (l->flags & LF_lv_all) {
+ fprintf(stderr, "\n\t%i:ALL\t", i);
+ }
+ else if (l->flags & LF_lv_inside) {
+ fprintf(stderr, "\n\t%i:", i);
+
+ if (l->flags & LF_lv_in) fprintf(stderr, "IN\t");
+ if (l->flags & LF_lv_out) fprintf(stderr, "OUT\t");
+
+ for (j=0; j < l->n_intervals; j++) {
+ fprintf(stderr, "[%d,%d]\t",
+ l->intervals[2*j], l->intervals[2*j+1] );
+ }
+ }
+ }
+ fprintf(stderr, "\n");
}
void dump_interference_graph() {
1.2 +2 -0 parrot/languages/imcc/debug.h
Index: debug.h
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/debug.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -w -r1.1 -r1.2
--- debug.h 4 Jul 2002 02:58:30 -0000 1.1
+++ debug.h 15 Jul 2002 20:13:10 -0000 1.2
@@ -3,3 +3,5 @@
void dump_cfg();
void dump_symreg();
void dump_interference_graph();
+void dump_liveness_status();
+void dump_liveness_status_var();
1.10 +102 -58 parrot/languages/imcc/imc.c
Index: imc.c
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/imc.c,v
retrieving revision 1.9
retrieving revision 1.10
diff -u -w -r1.9 -r1.10
--- imc.c 4 Jul 2002 02:58:30 -0000 1.9
+++ imc.c 15 Jul 2002 20:13:10 -0000 1.10
@@ -38,7 +38,7 @@
find_basic_blocks();
build_cfg();
- /*life_analysis();*/
+ life_analysis();
build_interference_graph();
@@ -95,6 +95,11 @@
{
int count = 0;
interference_graph = calloc(n_symbols*n_symbols*n_symbols+1,
sizeof(SymReg*));
+ if (interference_graph == NULL) {
+ fprintf(stderr, "Memory error at build_interference_graph\n");
+ abort();
+ }
+
for(i = 0; i < HASH_SIZE; i++) {
SymReg * r = hash[i];
/* Add each symbol to its slot on the X axis of the graph */
@@ -120,7 +125,7 @@
if (IMCC_DEBUG) {
dump_symreg();
- dump_interference_graph();
+ /*dump_interference_graph();*/
}
}
@@ -147,7 +152,14 @@
/* See if r0's chain interferes with r1. */
+/* We currently decide that two vars interfere if they are both alive
+ * at any point. This could be improved, requiring that one is alive
+ * at the point of _definition_ of the other.
+ */
+
int interferes(SymReg * r0, SymReg * r1) {
+ int i;
+
/* Register doesn't interfere with itself, and register sets
* don't interfere with each other.
*/
@@ -168,6 +180,35 @@
/* If symbol was never used in a statment, it can't interfere */
if(r0->first < 0 || r1->first < 0) return 0;
+ /* Now: */
+
+ for (i=0; i <n_basic_blocks; i++) {
+ Life_range *l0, *l1;
+
+ if ( (l0->flags & LF_lv_all && l1->flags & LF_lv_inside)
+ || (l0->flags & LF_lv_inside && l1->flags & LF_lv_all)
+ || (l0->flags & LF_lv_in && l1->flags & LF_lv_in)
+ || (l0->flags & LF_lv_out && l1->flags & LF_lv_out)
+ )
+ return 1;
+
+ if (l0->flags & LF_lv_inside && l1->flags & LF_lv_inside) {
+ /* we need to compare the intervals */
+ int i, j;
+ for (i=0; i < l0->n_intervals; i++) {
+ for (j=0; j < l1->n_intervals; j++) {
+ if (l0->intervals[i] >= l1->intervals[j+1] )
+ continue;
+
+ if (l0->intervals[i+1] <= l1->intervals[j] )
+ continue;
+
+ return 1;
+ }
+ }
+ }
+ }
+
return 1;
}
@@ -180,9 +221,12 @@
*
*/
-int simplify (SymReg **g){
+int simplify (){
int changes = 0;
int x;
+ SymReg **g;
+
+ g = interference_graph;
for(x = 0; x < n_symbols; x++) {
if (g[x]->simplified) {
@@ -342,96 +386,86 @@
*/
void spill (int spilled) {
- Instruction ** new_instructions;
-
+ Instruction ** old_instructions;
+ int old_n_instructions;
Instruction * tmp;
- int i, j, needs_fetch, needs_store, needs_spilling, after_spilled,
after_needs_store;
+ int i, j;
+ int needs_fetch, needs_store, needs_spilling, after_spilled, after_needs_store;
SymReg *new_symbol, *old_symbol;
char* buf;
- SymReg **g = interference_graph;
buf = malloc(256 * sizeof(char));
+ if (buf == NULL) {
+ fprintf(stderr, "Memory error at spill\n");
+ abort();
+ }
if (IMCC_DEBUG)
- fprintf(stderr, "#Spilling [%s]:\n", g[spilled]->name);
+ fprintf(stderr, "#Spilling [%s]:\n", interference_graph[spilled]->name);
- old_symbol = g[spilled];
+ old_symbol = interference_graph[spilled];
+ old_instructions = instructions;
+ old_n_instructions = n_instructions;
+ instructions = NULL;
sprintf(buf, "%s_%d", old_symbol->name, 0);
new_symbol = mk_symreg(buf, old_symbol->set);
- new_instructions = calloc(4096, sizeof(Instruction *));
n_spilled++;
after_spilled = 0;
after_needs_store = 0;
j = 0;
- for(i = 0; i < n_instructions; i++) {
- tmp = instructions[i];
+ for(i = 0; i < old_n_instructions; i++) {
+ tmp = old_instructions[i];
needs_store = 0;
needs_fetch = 0;
- if (tmp->r0 == old_symbol) {
- if (tmp->flags & IF_r0_read) needs_fetch = 1;
- if (tmp->flags & IF_r0_write) needs_store = 1;
-
- tmp->r0 = new_symbol;
- }
-
- if (tmp->r1 == old_symbol) {
- if (tmp->flags & IF_r1_read) needs_fetch = 1;
- if (tmp->flags & IF_r1_write) needs_store = 1;
-
- tmp->r1 = new_symbol;
- }
-
-
- if (tmp->r2 == old_symbol) {
- if (tmp->flags & IF_r2_read) needs_fetch = 1;
- if (tmp->flags & IF_r2_write) needs_store = 1;
+ if (instruction_reads (tmp, old_symbol) )
+ needs_fetch = 1;
- tmp->r2 = new_symbol;
- }
-
-
- if (tmp->r3 == old_symbol) {
- if (tmp->flags & IF_r3_read) needs_fetch = 1;
- if (tmp->flags & IF_r3_write) needs_store = 1;
-
- tmp->r3 = new_symbol;
- }
+ if (instruction_writes (tmp, old_symbol) )
+ needs_store = 1;
needs_spilling = needs_fetch || needs_store;
if (needs_fetch && !after_spilled) {
- sprintf(buf, "set %s, P31, %d #FETCH", "%s", n_spilled); /*ouch*/
-
- new_instructions[j++] = mk_instruction(
- buf, new_symbol, NULL, NULL, NULL, IF_r1_write);
-
+ sprintf(buf, "set %s, P31[%d], #FETCH", "%s", n_spilled); /*ouch*/
+ emitb( mk_instruction(buf, new_symbol, NULL, NULL, NULL, IF_r1_write));
}
if (!needs_spilling && after_needs_store) {
- sprintf(buf, "set P31, %d, %s #STORE", n_spilled, "%s"); /*ouch, ouch*/
-
- new_instructions[j++] = mk_instruction(
- buf, new_symbol, NULL, NULL, NULL, IF_r1_write);
+ sprintf(buf, "set P31[%d], %s #STORE", n_spilled, "%s"); /*ouch, ouch*/
+ emitb ( mk_instruction(buf, new_symbol, NULL, NULL, NULL, IF_r1_read));
sprintf(buf, "%s_%d", old_symbol->name, n_spilled);
- new_symbol = mk_symreg(buf, old_symbol->set);
+ new_symbol = mk_ident(buf, old_symbol->set);
}
- new_instructions[j++] = tmp;
+ /* Emit the old instruction, with the symbol changed */
+ {
+ SymReg *r0, *r1, *r2, *r3;
+
+ r0 = tmp->r0;
+ r1 = tmp->r1;
+ r2 = tmp->r2;
+ r3 = tmp->r3;
+
+ if (r0==old_symbol) r0=new_symbol;
+ if (r1==old_symbol) r1=new_symbol;
+ if (r2==old_symbol) r2=new_symbol;
+ if (r3==old_symbol) r3=new_symbol;
+
+ emitb( mk_instruction(tmp->fmt, r0, r1, r2, r3, tmp->flags) );
+ }
after_needs_store = needs_store;
after_spilled = needs_spilling;
}
- free(instructions);
- instructions = new_instructions;
- n_instructions = j;
+ free(old_instructions);
/* old_symbol does'nt get deleted. It simply loses all references from
instructions. So this means that the symbol table gets polluted with
@@ -439,6 +473,8 @@
We should clear, or at least reuse, them.
*/
+
+ dump_instructions();
}
int neighbours(int node) {
@@ -465,6 +501,10 @@
char * str_dup(const char * old) {
char * copy = (char *)malloc(strlen(old) + 1);
+ if (copy == NULL) {
+ fprintf(stderr, "Memory error at str_dup\n");
+ abort();
+ }
strcpy(copy, old);
return copy;
}
@@ -472,6 +512,10 @@
char * str_cat(const char * s1, const char * s2) {
int len = strlen(s1) + strlen(s2) + 1;
char * s3 = malloc(len);
+ if (s3 == NULL) {
+ fprintf(stderr, "Memory error at str_cat\n");
+ abort();
+ }
strcpy(s3, s1);
strcat(s3, s2);
return s3;
1.9 +1 -1 parrot/languages/imcc/imc.h
Index: imc.h
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/imc.h,v
retrieving revision 1.8
retrieving revision 1.9
diff -u -w -r1.8 -r1.9
--- imc.h 4 Jul 2002 02:58:30 -0000 1.8
+++ imc.h 15 Jul 2002 20:13:10 -0000 1.9
@@ -36,7 +36,7 @@
char *str_cat(const char *, const char *);
int IMCC_DEBUG;
-int n_spill;
+int n_spilled;
SymReg** interference_graph;
1.2 +50 -2 parrot/languages/imcc/instructions.c
Index: instructions.c
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/instructions.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -w -r1.1 -r1.2
--- instructions.c 4 Jul 2002 02:58:30 -0000 1.1
+++ instructions.c 15 Jul 2002 20:13:10 -0000 1.2
@@ -29,6 +29,10 @@
{
static SymReg * nullreg;
Instruction * i = calloc(1, sizeof(Instruction));
+ if (i == NULL) {
+ fprintf(stderr, "Memory error at mk_instruction\n");
+ abort();
+ }
if(!nullreg)
nullreg = mk_symreg("", 'I');
@@ -49,10 +53,50 @@
}
+int instruction_reads(Instruction* ins, SymReg* r) {
+ int f;
+
+ if (ins == NULL) {
+ fprintf(stderr, "Internal error: instruction_reads called with NULL
argument\n");
+ abort();
+ }
+
+ f = ins->flags;
+
+ if ((ins->r0 == r) && f & IF_r0_read) return 1;
+ if ((ins->r1 == r) && f & IF_r1_read) return 1;
+ if ((ins->r2 == r) && f & IF_r2_read) return 1;
+ if ((ins->r3 == r) && f & IF_r3_read) return 1;
+
+ return 0;
+}
+
+int instruction_writes(Instruction* ins, SymReg* r) {
+ int f;
+
+ if (ins == NULL) {
+ fprintf(stderr, "Internal error: instruction_reads called with NULL
argument\n");
+ abort();
+ }
+
+ f = ins->flags;
+
+ if ((ins->r0 == r) && f & IF_r0_write) return 1;
+ if ((ins->r1 == r) && f & IF_r1_write) return 1;
+ if ((ins->r2 == r) && f & IF_r2_write) return 1;
+ if ((ins->r3 == r) && f & IF_r3_write) return 1;
+
+ return 0;
+}
+
+
/* Resizes the array of instructions */
Instruction ** resize_instructions(Instruction ** i, int num) {
i = realloc(i, num * sizeof(Instruction *));
+ if (i == NULL) {
+ fprintf(stderr, "Memory error at resize_instructions\n");
+ }
return i;
}
@@ -65,12 +109,16 @@
#endif
if(!instructions) {
instructions = calloc(4096, sizeof(Instruction *));
+ if (instructions == NULL) {
+ fprintf(stderr, "Memory error at emitb\n");
+ abort();
+ }
n_instructions = 0;
}
+ i->index = n_instructions;
instructions[n_instructions++] = i;
- i->basic_block = NULL;
return i;
}
@@ -82,7 +130,7 @@
void emit_flush() {
int i;
- if (n_spill > 0) {
+ if (n_spilled > 0) {
printf("new P31, .PerlArray\n");
}
1.2 +5 -2 parrot/languages/imcc/instructions.h
Index: instructions.h
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/instructions.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -w -r1.1 -r1.2
--- instructions.h 4 Jul 2002 02:58:30 -0000 1.1
+++ instructions.h 15 Jul 2002 20:13:10 -0000 1.2
@@ -17,6 +17,7 @@
long flags; /* how the instruction affects each of the values */
int type;
void * basic_block; /* basic block */
+ int index; /* index on instructions[] */
} Instruction;
@@ -48,6 +49,8 @@
Instruction * emitb(Instruction *);
Instruction * emit(Instruction *);
void emit_flush();
+int instruction_reads(Instruction *, SymReg *);
+int instruction_writes(Instruction *, SymReg *);
/* Globals */
1.2 +15 -0 parrot/languages/imcc/symreg.c
Index: symreg.c
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/symreg.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -w -r1.1 -r1.2
--- symreg.c 4 Jul 2002 02:58:30 -0000 1.1
+++ symreg.c 15 Jul 2002 20:13:10 -0000 1.2
@@ -17,6 +17,10 @@
if((r = get_sym(name)))
return r;
r = calloc(1, sizeof(SymReg));
+ if (r==NULL) {
+ fprintf(stderr, "Memory error at mk_symreg\n");
+ abort();
+ }
r->name = str_dup(name);
r->reg = str_dup(name);
if(t == 'I') r->fmt = str_dup("I%d");
@@ -29,6 +33,7 @@
r->set = t;
r->type = VTREG;
r->simplified = 0;
+ r->life_info = NULL;
if(name[0])
store_symreg(r);
@@ -48,6 +53,10 @@
if((r = get_sym(name)))
return r;
r = calloc(1, sizeof(SymReg));
+ if (r==NULL) {
+ fprintf(stderr, "Memory error at mk_const\n");
+ abort();
+ }
r->name = str_dup(name);
r->reg = str_dup(name);
r->first = -1;
@@ -56,6 +65,7 @@
r->set = t;
r->type = VTCONST;
r->simplified = 0;
+ r->life_info = NULL;
if(name[0])
store_symreg(r);
return r;
@@ -67,12 +77,17 @@
if((r = get_sym(name)))
return r;
r = calloc(1, sizeof(SymReg));
+ if (r==NULL) {
+ fprintf(stderr, "Memory error at mk_address\n");
+ abort();
+ }
r->name = str_dup(name);
r->reg = str_dup(name);
r->first = -1;
r->color = -1;
r->score = 0;
r->type = VTADDRESS;
+ r->life_info = NULL;
r->simplified = 0;
if(name[0])
store_symreg(r);
1.2 +19 -1 parrot/languages/imcc/symreg.h
Index: symreg.h
===================================================================
RCS file: /cvs/public/parrot/languages/imcc/symreg.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -w -r1.1 -r1.2
--- symreg.h 4 Jul 2002 02:58:30 -0000 1.1
+++ symreg.h 15 Jul 2002 20:13:10 -0000 1.2
@@ -13,6 +13,24 @@
VTADDRESS /* address */
};
+enum LIFEFLAG { /* The status of a var inside a basic block can be */
+ LF_use = 1 << 0, /* block uses the the var before defining it */
+ LF_def = 1 << 1, /* block defines the variable */
+ LF_lv_in = 1 << 2, /* variable is alive at the beggining of the block */
+ LF_lv_out = 1 << 3, /* variable is alive at the end of the block */
+ LF_lv_inside = 1 << 4, /* variable is alive at some momement in the block */
+ LF_lv_all = 1 << 5 /* alive during all the block */
+};
+
+/* Liveness represents the usage of a var inside a basic block
+ This is represented by pairs of [definition, usage] in *intervals:
+*/
+typedef struct _Life_range {
+ int flags;
+ int n_intervals;
+ int *intervals;
+} Life_range;
+
typedef struct _SymReg {
char * name;
char * reg; /* Real register */
@@ -25,9 +43,9 @@
int last; /* Last ocurrance of this symbol (in instructions) */
int score; /* How costly is to spill this symbol */
int simplified; /* Has it been simplified during the process? */
+ Life_range **life_info; /* Each block has its Life_range status */
struct _SymReg * next; /* used in the symbols hash */
} SymReg;
-
/* functions */