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 */ 
  
  
  


Reply via email to