cvsuser     03/11/12 23:05:00

  Modified:    imcc     cfg.c debug.c imc.c instructions.c main.c
                        parser_util.c pbc.c reg_alloc.c symreg.c
  Log:
  Fix most of IMCC breakage introduced by last major patch.
  Localize more structures (register list and local symbol hash)
  and modify APIs. No more global "hash" or "reglist" variables.
  Add lots of debugging conditionals.
  
  Revision  Changes    Path
  1.52      +8 -1      parrot/imcc/cfg.c
  
  Index: cfg.c
  ===================================================================
  RCS file: /cvs/public/parrot/imcc/cfg.c,v
  retrieving revision 1.51
  retrieving revision 1.52
  diff -u -w -r1.51 -r1.52
  --- cfg.c     6 Nov 2003 15:56:12 -0000       1.51
  +++ cfg.c     13 Nov 2003 07:05:00 -0000      1.52
  @@ -69,7 +69,7 @@
       info(interpreter, 2, "find_basic_blocks\n");
       init_basic_blocks(unit);
       for(i = 0; i < HASH_SIZE; i++) {
  -        SymReg * r = hash[i];
  +        SymReg * r = unit->hash[i];
           if (r && (r->type & VTADDRESS)) {
               r->last_ins = NULL;
           }
  @@ -480,6 +480,10 @@
   {
       int i;
   
  +#if IMC_TRACE
  +    fprintf(stderr, "cfg.c: analyse_life_symbol(%s)\n", r->name);
  +#endif
  +
       if (r->life_info)
           free_life_info(unit, r);
       r->life_info = calloc(unit->n_basic_blocks,
  @@ -514,6 +518,9 @@
   free_life_info(IMC_Unit * unit, SymReg *r)
   {
       int i;
  +#if IMC_TRACE
  +    fprintf(stderr, "free_life_into(%s)\n", r->name);
  +#endif
       if (r->life_info) {
           for (i=0; i < unit->n_basic_blocks; i++) {
               if (r->life_info[i])
  
  
  
  1.31      +1 -1      parrot/imcc/debug.c
  
  Index: debug.c
  ===================================================================
  RCS file: /cvs/public/parrot/imcc/debug.c,v
  retrieving revision 1.30
  retrieving revision 1.31
  diff -u -w -r1.30 -r1.31
  --- debug.c   4 Nov 2003 07:44:19 -0000       1.30
  +++ debug.c   13 Nov 2003 07:05:00 -0000      1.31
  @@ -158,7 +158,7 @@
       fprintf(stderr, "name\tpos\tlast ref\n"
               "-----------------------\n");
       for(i = 0; i < HASH_SIZE; i++) {
  -        SymReg * r = hash[i];
  +        SymReg * r = unit->hash[i];
           if (r && (r->type & VTADDRESS))
               fprintf(stderr, "%s\t%d\t%d\n",
                       r->name,
  
  
  
  1.63      +124 -28   parrot/imcc/imc.c
  
  Index: imc.c
  ===================================================================
  RCS file: /cvs/public/parrot/imcc/imc.c,v
  retrieving revision 1.62
  retrieving revision 1.63
  diff -u -w -r1.62 -r1.63
  --- imc.c     4 Nov 2003 07:46:18 -0000       1.62
  +++ imc.c     13 Nov 2003 07:05:00 -0000      1.63
  @@ -12,19 +12,83 @@
   #include "optimizer.h"
   
   
  -static IMC_Unit * imc_units;
  -static IMC_Unit * cur_unit;
  +void imc_check_units(struct Parrot_Interp *interp, char * caller);
  +
  +/*
  + * A sanity checking function used for debugging only.
  + * Useful for tracking down memory corruptions by inserting
  + * validation calls between compilation steps.
  + */
  +void imc_check_units(struct Parrot_Interp *interp, char * caller)
  +{
  +    UNUSED(interp);
  +    UNUSED(caller);
  +#if IMC_TRACE
  +    IMC_Unit * unit, *unit_next;
  +    int i = 1;
  +    static int ncheck;
  +    fprintf(stderr, "imc.c: unit check pass %d from %s\n", ++ncheck, caller);
  +    for(unit = interp->imc_info->imc_units; unit; unit = unit_next) {
  +        unit_next = unit->next;
  +        {
  +            Instruction *ins = unit->instructions;
  +            if(ins->r[1] && ins->r[1]->pcc_sub) {
  +                fprintf(stderr, "UNIT[%d] : pcc_sub %s (nargs=%d)\n",
  +                     i, ins->r[1]->name, ins->r[1]->pcc_sub->nargs);
  +            }
  +        }
  +
  +        i++;
  +    }
  +#endif
  +}
   
   
   void
   imc_compile_all_units(struct Parrot_Interp *interp)
   {
  -    IMC_Unit * unit;
  -    for(unit = interp->imc_info->imc_units; unit; unit = unit->next) {
  +    IMC_Unit *unit, *unit_next;
  +    Instruction *ins, *ins_next;
  +#if IMC_TRACE
  +    int i = 1;
  +
  +    fprintf(stderr, "imc.c:  imc_compile_all_units()\n");
  +#endif
  +    UNUSED(ins_next);
  +    UNUSED(ins);
  +    for(unit = interp->imc_info->imc_units; unit; unit = unit_next) {
  +        unit_next = unit->next;
  +#if IMC_TRACE
  +        fprintf(stderr, "compiling unit %d\n", i++);
  +#endif
           imc_compile_unit(interp, unit);
           emit_flush(interp, unit);
           imc_close_unit(interp, unit);
       }
  +
  +    /* All done with compilation, now free instructions and other structures */
  +
  +    /* XXX FIXME: Can't free instructions yet without causing memory problems
  +     * in the symbol tables.
  +     */
  +#if 1
  +    for(unit = interp->imc_info->imc_units; unit;) {
  +        unit_next = unit->next;
  +#if 0
  +        for (ins = unit->instructions; ins; ) {
  +            ins_next = ins->next;
  +            free_ins(ins);
  +            ins = ins_next;
  +        }
  +#endif
  +        imc_free_unit(interp, unit);
  +        unit = unit_next;
  +    }
  +#endif
  +
  +    /* XXX: Memory leak */
  +    interp->imc_info->imc_units = NULL;
  +    interp->imc_info->last_unit = NULL;
   }
   
   /* imc_compile_unit is the main loop of the IMC compiler for each unit. It operates
  @@ -34,18 +98,36 @@
   imc_compile_unit(struct Parrot_Interp *interp, IMC_Unit * unit)
   {
       /* Not much here for now except the allocator */
  +    cur_unit = unit;
  +
  +#if IMC_TRACE
  +    imc_check_units(interp, "imc_compile_unit");
  +#endif
   
       imc_reg_alloc(interp, unit);
   }
   
   
   /*
  + * Any activity required to cleanup the compiler state and be
  + * ready for a new compiler invokation goes here.
  + */
  +void
  +imc_cleanup(struct Parrot_Interp *interp)
  +{
  +     UNUSED(interp);
  +     clear_globals();
  +}
  +
  +
  +/*
    * Create a new IMC_Unit.
    */
   IMC_Unit *
   imc_new_unit(IMC_Unit_Type t)
   {
      IMC_Unit * unit = calloc(1, sizeof(IMC_Unit));
  +   unit->hash = calloc(HASH_SIZE, sizeof(SymReg*));
      unit->type = t;
      return unit;
   }
  @@ -60,48 +142,62 @@
   {
       IMC_Unit * unit;
       unit = imc_new_unit(t);
  -    if(!interp->imc_info->cur_unit)
  +    if(!interp->imc_info->imc_units)
          interp->imc_info->imc_units = unit;
  -    unit->prev = cur_unit;
  -    if(interp->imc_info->cur_unit)
  -       interp->imc_info->cur_unit->next = unit;
  -    interp->imc_info->cur_unit = unit;
  +    unit->prev = interp->imc_info->last_unit;
  +    if(interp->imc_info->last_unit)
  +       interp->imc_info->last_unit->next = unit;
  +    interp->imc_info->last_unit = unit;
       interp->imc_info->n_comp_units++;
  -#if 0
  +#if IMC_TRACE
       fprintf(stderr, "imc_open_unit()\n");
   #endif
  -    return interp->imc_info->cur_unit;
  +    return interp->imc_info->last_unit;
   }
   
  +/*
  + * Close a unit from compilation. 
  + * Does not destroy the unit, leaves it on the
  + * list. Right now this does nothing.
  + */
   void
   imc_close_unit(Parrot_Interp interp, IMC_Unit * unit)
   {
  +    UNUSED(interp);
  +    UNUSED(unit);
  +#if IMC_TRACE
  +    fprintf(stderr, "imc_close_unit()\n");
  +#endif
  +    cur_unit = NULL;
  +}
  +
  +/*
  + * XXX FIXME: Memory leakage. Can't call free_reglist or clear_tables()
  + * yet due to interaction between units. One unit may hold a reference
  + * to another (subs). Garbage collection would solve this.
  + */
  +void
  +imc_free_unit(Parrot_Interp interp, IMC_Unit * unit)
  +{
       imc_info_t *imc = interp->imc_info;
   
  +#if IMC_TRACE
  +    fprintf(stderr, "imc_free_unit()\n");
  +#endif
  +
  +    /* XXX See above
       free_reglist(unit);
  +    */
  +
       clear_basic_blocks(unit);       /* and cfg ... */
       if (!imc->n_comp_units)
  -        fatal(1, "close_comp_unit", "non existent comp_unit\n");
  +        fatal(1, "imc_free_unit", "non existent unit\n");
       imc->n_comp_units--;
  -    clear_tables(unit, hash);
  -#if 0
  -    fprintf(stderr, "imc_close_unit()\n");
  -#endif
  -/*
  -    imc->cur_unit->instructions = imc->cur_unit->last_ins = NULL;
  -*/
  -}
   
  +    clear_locals(unit);
   
  -IMC_Unit *
  -imc_cur_unit(Parrot_Interp interp)
  -{
  -   /* Have to put this here as yacc and bison have problems
  -    * with the null pointer deref
  -    */
  -   return interp->imc_info->cur_unit;
  +    free(unit);
   }
  -
   
   
   
  
  
  
  1.49      +9 -6      parrot/imcc/instructions.c
  
  Index: instructions.c
  ===================================================================
  RCS file: /cvs/public/parrot/imcc/instructions.c,v
  retrieving revision 1.48
  retrieving revision 1.49
  diff -u -w -r1.48 -r1.49
  --- instructions.c    4 Nov 2003 07:46:18 -0000       1.48
  +++ instructions.c    13 Nov 2003 07:05:00 -0000      1.49
  @@ -456,6 +456,9 @@
       emitter = type;
       has_compile = 0;
       dont_optimize = 0;
  +#if IMC_TRACE
  +    fprintf(stderr, "imc.c: emit_open (%d)\n", emitter);
  +#endif
       return (emitters[emitter]).open(param);
   }
   
  @@ -464,24 +467,24 @@
   {
       Instruction * ins, *next;
       struct Parrot_Interp *interpreter = (struct Parrot_Interp *)param;
  +#if IMC_TRACE
  +    fprintf(stderr, "instructions.c: emit_flush\n");
  +#endif
       if (emitters[emitter].new_sub)
           (emitters[emitter]).new_sub(param, unit);
       for (ins = unit->instructions; ins; ins = ins->next) {
           debug(interpreter, DEBUG_IMC, "emit %I\n", ins);
           (emitters[emitter]).emit(param, unit, ins);
       }
  -    for (ins = unit->instructions; ins; ) {
  -        next = ins->next;
  -        free_ins(ins);
  -        ins = next;
  -    }
  -    /*imc_close_unit(interpreter);*/
       return 0;
   }
   
   int
   emit_close(void *param)
   {
  +#if IMC_TRACE
  +    fprintf(stderr, "instructions.c: emit_close()\n");
  +#endif
       return (emitters[emitter]).close(param);
   }
   
  
  
  
  1.61      +1 -0      parrot/imcc/main.c
  
  Index: main.c
  ===================================================================
  RCS file: /cvs/public/parrot/imcc/main.c,v
  retrieving revision 1.60
  retrieving revision 1.61
  diff -u -w -r1.60 -r1.61
  --- main.c    4 Nov 2003 07:46:18 -0000       1.60
  +++ main.c    13 Nov 2003 07:05:00 -0000      1.61
  @@ -493,6 +493,7 @@
           yyparse((void *) interpreter);
   
           imc_compile_all_units(interpreter);
  +        imc_cleanup(interpreter);
   
           emit_close(interpreter);
           fclose(yyin);
  
  
  
  1.47      +13 -1     parrot/imcc/parser_util.c
  
  Index: parser_util.c
  ===================================================================
  RCS file: /cvs/public/parrot/imcc/parser_util.c,v
  retrieving revision 1.46
  retrieving revision 1.47
  diff -u -w -r1.46 -r1.47
  --- parser_util.c     6 Nov 2003 15:57:31 -0000       1.46
  +++ parser_util.c     13 Nov 2003 07:05:00 -0000      1.47
  @@ -401,6 +401,7 @@
       emit_open(1, interp);
       /* XXX where to put constants */
       yyparse((void *) interp);
  +    imc_compile_all_units(interp);
       emit_close(interp);
   
   #ifdef EVAL_TEST
  @@ -427,6 +428,7 @@
       pasm_file = 1;
       expect_pasm = 0;
       pf = imcc_compile(interp, s);
  +    imc_cleanup(interp);
       pasm_file = pasm;
       return pf;
   }
  @@ -440,11 +442,15 @@
       pasm_file = 0;
       expect_pasm = 0;
       pf = imcc_compile(interp, s);
  +    imc_cleanup(interp);
       pasm_file = pasm;
       return pf;
   }
   
   
  +/*
  + * Compile a file by filename (can be either PASM or IMCC code)
  + */
   static void *
   imcc_compile_file (Parrot_Interp interp, const char *s)
   {
  @@ -464,6 +470,11 @@
           fatal(1, "imcc_compile_file", "couldn't open '%s'\n", s);
           return NULL;
       }
  +
  +#if IMC_TRACE
  +    fprintf(stderr, "parser_util.c: imcc_compile_file '%s'\n", s);
  +#endif
  +
       pf = PackFile_new(0);
       interp->code = pf;  /* put new packfile in place */
       sourcefile = const_cast(s);
  @@ -478,6 +489,7 @@
   
       /* see imcc.l */
       compile_file(interp, new);
  +    imc_cleanup(interp);
   
       (void)Parrot_switch_to_cs(interp, pf_save->cur_cs);
       sourcefile = source;
  @@ -486,7 +498,7 @@
       return pf;
   }
   
  -/* tell the parrot core, which compilers we provide */
  +/* Register additional compilers with the interpreter */
   void
   register_compilers(Parrot_Interp interp)
   {
  
  
  
  1.57      +16 -8     parrot/imcc/pbc.c
  
  Index: pbc.c
  ===================================================================
  RCS file: /cvs/public/parrot/imcc/pbc.c,v
  retrieving revision 1.56
  retrieving revision 1.57
  diff -u -w -r1.56 -r1.57
  --- pbc.c     4 Nov 2003 07:47:01 -0000       1.56
  +++ pbc.c     13 Nov 2003 07:05:00 -0000      1.57
  @@ -88,9 +88,9 @@
           while (s) {
               prev_s = s->prev;
               h = s->labels;
  -            clear_tables(NULL, h);
  +            clear_sym_hash(s->labels);
               h = s->bsrs;
  -            clear_tables(NULL, h);
  +            clear_sym_hash(s->bsrs);
               mem_sys_free(s);
               s = prev_s;
           }
  @@ -154,7 +154,7 @@
       /* free previous cached key constants if any */
       if (globals.cs) {
           SymReg **h = globals.cs->key_consts;
  -        clear_tables(NULL, h);
  +        clear_sym_hash(h);
       }
       cs->next = NULL;
       cs->subs = NULL;
  @@ -598,6 +598,10 @@
       opcode_t *rc;
       struct PackFile_Constant *pfc;
   
  +#if IMC_TRACE
  +    PIO_eprintf(interpreter, "pbc.c: add_const_pmc_sub '%s'\n", r->name);
  +#endif
  +
       debug(interpreter, DEBUG_PBC_CONST, "add_const_pmc_sub '%s'\n", r->name);
       /*
        * TODO use serialize api if that is done
  @@ -772,9 +776,10 @@
                   r->name, r->color, r->use_count);
   
   }
  +
   /* store a constants idx for later reuse */
   static void
  -constant_folding(struct Parrot_Interp *interpreter)
  +constant_folding(struct Parrot_Interp *interpreter, IMC_Unit * unit)
   {
       SymReg * r;
       int i;
  @@ -787,10 +792,10 @@
                   add_1_const(interpreter, r);
               }
           }
  -        /* ... but keychains 'K' are in hash, they may contain
  +        /* ... but keychains 'K' are in local hash, they may contain
            * variables and constants
            */
  -        for(r = hash[i]; r; r = r->next) {
  +        for(r = unit->hash[i]; r; r = r->next) {
               if (r->type & VTCONST) {
                   add_1_const(interpreter, r);
               }
  @@ -834,7 +839,7 @@
           code_size = store_labels(interpreter, unit, &ins_size, oldsize);
           debug(interpreter, DEBUG_PBC, "code_size(ops) %d  oldsize %d\n",
                   code_size, oldsize);
  -        constant_folding(interpreter);
  +        constant_folding(interpreter, unit);
           store_sub_size(code_size, ins_size);
           bytes = (oldsize + code_size) * sizeof(opcode_t);
           interpreter->code->byte_code =
  @@ -853,6 +858,9 @@
           }
           /* if item is a PCC_SUB entry then store it constants */
           if (ins->r[1] && ins->r[1]->pcc_sub) {
  +#if IMC_TRACE
  +            PIO_eprintf(NULL, "pbc.c: e_pbc_emit (pcc_sub=%s)\n", ins->r[1]->name);
  +#endif
               add_const_pmc_sub(interpreter, ins->r[1], oldsize,
                       oldsize+code_size);
           }
  @@ -940,7 +948,7 @@
       struct Parrot_Interp *interpreter = (struct Parrot_Interp *)param;
   
       fixup_bsrs(interpreter);
  -    clear_tables(NULL, ghash);
  +    clear_globals();
       return 0;
   }
   
  
  
  
  1.3       +80 -60    parrot/imcc/reg_alloc.c
  
  Index: reg_alloc.c
  ===================================================================
  RCS file: /cvs/public/parrot/imcc/reg_alloc.c,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -w -r1.2 -r1.3
  --- reg_alloc.c       4 Nov 2003 07:47:28 -0000       1.2
  +++ reg_alloc.c       13 Nov 2003 07:05:00 -0000      1.3
  @@ -32,10 +32,10 @@
   # define MAX_COLOR 4
   #endif
   
  -static void make_stat(int *sets, int *cols);
  -static void imc_stat_init(void);
  +static void make_stat(IMC_Unit *, int *sets, int *cols);
  +static void imc_stat_init(IMC_Unit *);
   static void print_stat(Parrot_Interp, IMC_Unit *);
  -static void allocate_wanted_regs(void);
  +static void allocate_wanted_regs(IMC_Unit *);
   static void build_reglist(Parrot_Interp, IMC_Unit * unit);
   static void build_interference_graph(Parrot_Interp, IMC_Unit *);
   static void compute_du_chain(IMC_Unit * unit);
  @@ -43,21 +43,23 @@
   static int interferes(IMC_Unit *, SymReg * r0, SymReg * r1);
   static int map_colors(int x, SymReg ** graph, int colors[], int typ);
   #ifdef DO_SIMPLIFY
  -static int simplify (void);
  +static int simplify (IMC_Unit *);
   #endif
   static void compute_spilling_costs (Parrot_Interp, IMC_Unit *);
  -static void order_spilling (void);
  +static void order_spilling (IMC_Unit *);
   static void spill (struct Parrot_Interp *, IMC_Unit * unit, int);
  -static int try_allocate(Parrot_Interp);
  -static void restore_interference_graph(void);
  +static int try_allocate(Parrot_Interp, IMC_Unit *);
  +static void restore_interference_graph(IMC_Unit *);
   static int neighbours(int node);
   
   extern int pasm_file;
  -/* Globals: */
  +/* XXX FIXME: Globals: */
   
   static IMCStack nodeStack;
   static SymReg** interference_graph;
  +/*
   static SymReg** reglist;
  +*/
   static int n_symbols;
   
   /* imc_reg_alloc is the main loop of the allocation algorithm. It operates
  @@ -77,12 +79,20 @@
       init_tables(interpreter);
       allocated = 0;
   
  +#if IMC_TRACE
  +    fprintf(stderr, "reg_alloc.c: imc_reg_alloc\n");
  +    if(unit->instructions->r[1] && unit->instructions->r[1]->pcc_sub) {
  +        fprintf(stderr, "img_reg_alloc: pcc_sub (nargs = %d)\n",
  +            unit->instructions->r[1]->pcc_sub->nargs);
  +    }
  +#endif
  +
       debug(interpreter, DEBUG_IMC, "\n------------------------\n");
       debug(interpreter, DEBUG_IMC, "processing sub %s\n", function);
       debug(interpreter, DEBUG_IMC, "------------------------\n\n");
       if (IMCC_INFO(interpreter)->verbose ||
               (IMCC_INFO(interpreter)->debug & DEBUG_IMC))
  -        imc_stat_init();
  +        imc_stat_init(unit);
   
       /* consecutive labels, if_branch, unused_labels ... */
       pre_optimize(interpreter, unit);
  @@ -134,15 +144,15 @@
           build_interference_graph(interpreter, unit);
   #endif
           if (optimizer_level & OPT_SUB)
  -            allocate_wanted_regs();
  +            allocate_wanted_regs(unit);
           compute_spilling_costs(interpreter, unit);
   #ifdef DO_SIMPLIFY
           /* simplify until no changes can be made */
  -        while (simplify()) {}
  +        while (simplify(unit)) {}
   #endif
  -        order_spilling();          /* put the remaining items on stack */
  +        order_spilling(unit);          /* put the remaining items on stack */
   
  -        to_spill = try_allocate(interpreter);
  +        to_spill = try_allocate(interpreter, unit);
           allocated = 1;
   
           if ( to_spill >= 0 ) {
  @@ -177,16 +187,19 @@
   void
   free_reglist(IMC_Unit * unit)
   {
  +#if IMC_TRACE
  +    fprintf(stderr, "reg_alloc.c: free_reglist\n");
  +#endif
       if (interference_graph) {
           free(interference_graph);
           unit->interference_graph = interference_graph = 0;
       }
  -    if (reglist) {
  +    if (unit->reglist) {
           int i;
           for (i = 0; i < n_symbols; i++)
  -            free_life_info(unit, reglist[i]);
  -        free(reglist);
  -        unit->reglist = reglist = NULL;
  +            free_life_info(unit, unit->reglist[i]);
  +        free(unit->reglist);
  +        unit->reglist = NULL;
           unit->n_symbols = n_symbols = 0;
       }
   }
  @@ -195,13 +208,13 @@
    * printed with --verbose --verbose
    */
   static void
  -make_stat(int *sets, int *cols)
  +make_stat(IMC_Unit * unit, int *sets, int *cols)
   {
       /* register usage summary */
       char type[] = "INSP";
       int i, j;
       for(i = 0; i < HASH_SIZE; i++) {
  -        SymReg * r = hash[i];
  +        SymReg * r = unit->hash[i];
        for(; r; r = r->next)
               for (j = 0; j < 4; j++)
                   if (r->set == type[j] && (r->type & VTREGISTER)) {
  @@ -214,9 +227,9 @@
   }
   static int imcsets[4];
   /* registes usage of .imc */
  -static void imc_stat_init() {
  +static void imc_stat_init(IMC_Unit * unit) {
       imcsets[0] = imcsets[1] = imcsets[2] = imcsets[3] = 0;
  -    make_stat(imcsets, 0);
  +    make_stat(unit, imcsets, 0);
       memset(&ostat, 0, sizeof(ostat));
   }
   
  @@ -226,7 +239,7 @@
       int sets[4] = {0,0,0,0};
       int cols[4] = {-1,-1,-1,-1};
   
  -    make_stat(sets, cols);
  +    make_stat(unit, sets, cols);
       info(interpreter, 1, "sub %s:\n\tregisters in .imc:\t I%d, N%d, S%d, P%d\n",
               function, imcsets[0], imcsets[1], imcsets[2], imcsets[3]);
       info(interpreter, 1, "\t%d labels, %d lines deleted, %d if_branch, %d 
branch_branch\n",
  @@ -262,10 +275,11 @@
   }
   
   static void
  -sort_reglist(void)
  +sort_reglist(SymReg ** reglist)
   {
       qsort(reglist, n_symbols, sizeof(SymReg*), reg_sort_f);
   }
  +
   /* make a linear list of IDENTs and VARs, set n_symbols */
   
   static void
  @@ -275,10 +289,10 @@
   
       info(interpreter, 2, "build_reglist\n");
       /* count symbols */
  -    if (reglist)
  +    if (unit->reglist)
           free_reglist(unit);
       for(i = count = 0; i < HASH_SIZE; i++) {
  -        SymReg * r = hash[i];
  +        SymReg * r = unit->hash[i];
           for(; r; r = r->next)
               if(r->type & VTREGISTER)
                   count++;
  @@ -289,44 +303,43 @@
       if (n_symbols >= HASH_SIZE)
           warning(interpreter, "build_reglist", "probably too small HASH_SIZE"
                   " (%d symbols)\n");
  -    reglist = calloc(n_symbols, sizeof(SymReg*));
  -    if (reglist == NULL) {
  +    unit->reglist = calloc(n_symbols, sizeof(SymReg*));
  +    if (unit->reglist == NULL) {
           fatal(1, "build_reglist","Out of mem\n");
       }
  -    unit->reglist = reglist;
   
       for(i = count = 0; i < HASH_SIZE; i++) {
  -        SymReg * r = hash[i];
  +        SymReg * r = unit->hash[i];
           /* Add each symbol to reglist  */
           for(; r; r = r->next) {
               if(r->type & VTREGISTER) {
                   if (r->type & VT_REGP)
  -                    reglist[count++] = r->reg;
  +                    unit->reglist[count++] = r->reg;
                   else
  -                    reglist[count++] = r;
  +                    unit->reglist[count++] = r;
                   /* rearange I/N registers
                    * XXX not here, do it, when reading the source
                    * .nciarg, ... !!!1 */
                   if ((optimizer_level & OPT_PASM) && pasm_file &&
  -                        (reglist[count-1]->set == 'I' ||
  -                        reglist[count-1]->set == 'N'))
  -                    reglist[count-1]->color = -1;
  +                        (unit->reglist[count-1]->set == 'I' ||
  +                        unit->reglist[count-1]->set == 'N'))
  +                    unit->reglist[count-1]->color = -1;
               }
           }
       }
       compute_du_chain(unit);
       /* we might have unused symbols here, from spilling */
       for (i = count = unused = 0; i < n_symbols; i++) {
  -        if (!reglist[i]->first_ins)
  +        if (!unit->reglist[i]->first_ins)
               unused++;
           else if (i == count)
               count++;
           else
  -            reglist[count++] = reglist[i];
  +            unit->reglist[count++] = unit->reglist[i];
       }
       n_symbols -= unused;
       unit->n_symbols = n_symbols;
  -    sort_reglist();
  +    sort_reglist(unit->reglist);
   }
   
   /* creates the interference graph between the variables.
  @@ -354,14 +367,14 @@
       /* Calculate interferences between each chain and populate the the Y-axis */
       for (x = 0; x < n_symbols; x++) {
           /* If symbol was never used in a statment, it can't interfere */
  -        if (!reglist[x]->first_ins)
  +        if (!unit->reglist[x]->first_ins)
               continue;
           for (y = x + 1; y < n_symbols; y++) {
  -            if (!reglist[y]->first_ins)
  +            if (!unit->reglist[y]->first_ins)
                   continue;
  -            if (interferes(unit, reglist[x], reglist[y])) {
  -                interference_graph[x*n_symbols+y] = reglist[y];
  -                interference_graph[y*n_symbols+x] = reglist[x];
  +            if (interferes(unit, unit->reglist[x], unit->reglist[y])) {
  +                interference_graph[x*n_symbols+y] = unit->reglist[y];
  +                interference_graph[y*n_symbols+x] = unit->reglist[x];
               }
           }
       }
  @@ -390,7 +403,7 @@
   
       /* Compute du-chains for all symbolics */
       for(i = 0; i < n_symbols; i++) {
  -        SymReg * r = reglist[i];
  +        SymReg * r = unit->reglist[i];
           compute_one_du_chain(r, unit);
           /* what is this used for? -lt */
           if(r->type == VTIDENTIFIER
  @@ -447,7 +460,7 @@
       Instruction * ins;
   
       for(i = 0; i < n_symbols; i++) {
  -        r = reglist[i];
  +        r = unit->reglist[i];
           r->score = r->use_count + (r->lhs_use_count << 2);
           /* TODO score high if -Oj and register is used in
            * JITtable instruction
  @@ -583,12 +596,12 @@
    */
   #ifdef DO_SIMPLIFY
   static int
  -simplify () {
  +simplify (IMC_Unit * unit) {
       int changes = 0;
       int x;
       SymReg **g;
   
  -    g = reglist;
  +    g = unit->reglist;
   
       for(x = 0; x < n_symbols; x++) {
           if (g[x]->color >= 0)   /* VTPASM */
  @@ -623,7 +636,7 @@
    */
   
   static void
  -order_spilling () {
  +order_spilling (IMC_Unit * unit) {
       int min_score = 0, total_score;
       int min_node;
       int x;
  @@ -646,8 +659,8 @@
              *
              * I have no clue of how good it is
             */
  -         if (!(reglist[x]->simplified)) {
  -             total_score = reglist[x]->score - neighbours(x);
  +         if (!(unit->reglist[x]->simplified)) {
  +             total_score = unit->reglist[x]->score - neighbours(x);
   
                   if ( (min_node == -1) || (min_score > total_score) )  {
                   min_node  = x;
  @@ -659,19 +672,19 @@
        if (min_node == -1) return; /* We are finished */
   
        imcstack_push(nodeStack, min_node);
  -     reglist[min_node]->simplified = 1;
  +     unit->reglist[min_node]->simplified = 1;
       }
   }
   
   
   static void
  -restore_interference_graph() {
  +restore_interference_graph(IMC_Unit * unit) {
       int i;
       for (i=0; i < n_symbols; i++) {
  -        if ((reglist[i]->type & VTPASM) && !(optimizer_level & OPT_PASM))
  +        if ((unit->reglist[i]->type & VTPASM) && !(optimizer_level & OPT_PASM))
               continue;
  -     reglist[i]->color = -1;
  -     reglist[i]->simplified = 0;
  +     unit->reglist[i]->color = -1;
  +     unit->reglist[i]->simplified = 0;
       }
   }
   
  @@ -679,14 +692,14 @@
    * try to allocate as much as possible
    */
   static void
  -allocate_wanted_regs(void)
  +allocate_wanted_regs(IMC_Unit * unit)
   {
       int i, y, interf;
       SymReg *r, *s;
       SymReg ** graph = interference_graph;
   
       for (i = 0; i < n_symbols; i++) {
  -        r = reglist[i];
  +        r = unit->reglist[i];
           if (r->color >= 0 || r->want_regno == -1)
               continue;
           interf = 0;
  @@ -711,11 +724,12 @@
    */
   
   static int
  -try_allocate(Parrot_Interp interpreter) {
  +try_allocate(Parrot_Interp interpreter, IMC_Unit * unit) {
       int x = 0;
       int color, colors[MAX_COLOR];
       int free_colors, t;
       SymReg ** graph = interference_graph;
  +    SymReg ** reglist = unit->reglist;
   
       while ((imcstack_depth(nodeStack) > 0) ) {
        x=imcstack_pop(nodeStack);
  @@ -748,7 +762,7 @@
                        * to this node, return it so it gets spilled
                        */
   
  -                 restore_interference_graph();
  +                 restore_interference_graph(unit);
                    /* clean stack */
                    while ((imcstack_depth(nodeStack) > 0) )
                        imcstack_pop(nodeStack);
  @@ -802,13 +816,17 @@
       Instruction *ins2;
       Basic_block **bb_list = unit->bb_list;
   
  +#if IMC_TRACE
  +    fprintf(stderr, "reg_alloc.c: update_life(%s)\n", r->name);
  +#endif
  +
       for(i = 0, ins2 = unit->instructions; ins2; ins2 = ins2->next) {
           ins2->index = i++;
       }
       /* add this sym to reglist, if not there */
       if (add) {
  -        reglist = realloc(reglist, (n_symbols + 1) * sizeof(SymReg *));
  -        reglist[n_symbols++] = r;
  +        unit->reglist = realloc(unit->reglist, (n_symbols + 1) * sizeof(SymReg *));
  +        unit->reglist[n_symbols++] = r;
       }
   
       r->first_ins = r->last_ins = ins;
  @@ -850,6 +868,7 @@
   update_interference(Parrot_Interp interpreter, IMC_Unit * unit, SymReg *old, SymReg 
*new)
   {
       int x, y;
  +    SymReg ** reglist = unit->reglist;
       if (old != new) {
           /* n_symbols is already increased */
           SymReg ** new_graph = calloc(n_symbols * n_symbols, sizeof(SymReg*));
  @@ -898,6 +917,7 @@
       SymReg * old_sym, *p31, *new_sym;
       char * buf;
       SymReg *regs[IMCC_MAX_REGS];
  +    SymReg **reglist = unit->reglist;
   
       buf = malloc(256 * sizeof(char));
       if (buf == NULL) {
  
  
  
  1.38      +40 -12    parrot/imcc/symreg.c
  
  Index: symreg.c
  ===================================================================
  RCS file: /cvs/public/parrot/imcc/symreg.c,v
  retrieving revision 1.37
  retrieving revision 1.38
  diff -u -w -r1.37 -r1.38
  --- symreg.c  6 Nov 2003 07:26:40 -0000       1.37
  +++ symreg.c  13 Nov 2003 07:05:00 -0000      1.38
  @@ -82,7 +82,7 @@
   SymReg *
   mk_symreg(char * name, int t)
   {
  -    return _mk_symreg(hash, name, t);
  +    return _mk_symreg(cur_unit->hash, name, t);
   }
   
   SymReg *
  @@ -96,7 +96,7 @@
   
   SymReg *
   mk_pcc_sub(char * name, int proto) {
  -    SymReg *r = _mk_symreg(hash, name, proto);
  +    SymReg *r = _mk_symreg(cur_unit->hash, name, proto);
       r->type = VT_PCC_SUB;
       r->pcc_sub = calloc(1, sizeof(struct pcc_sub_t));
       return r;
  @@ -165,7 +165,7 @@
   SymReg * mk_pasm_reg(char * name)
   {
       SymReg * r;
  -    if((r = _get_sym(hash, name))) {
  +    if((r = _get_sym(cur_unit->hash, name))) {
        free(name);
           return r;
       }
  @@ -278,7 +278,7 @@
   
   SymReg * mk_address(char * name, int uniq)
   {
  -    SymReg ** h = *name == '_' ? ghash : hash;
  +    SymReg ** h = *name == '_' ? ghash : cur_unit->hash;
       return _mk_address(h, name, uniq);
   }
   
  @@ -429,7 +429,7 @@
   void
   store_symreg(SymReg * r)
   {
  -    _store_symreg(hash, r);
  +    _store_symreg(cur_unit->hash, r);
   }
   
   /* Gets a symbol from the hash */
  @@ -445,10 +445,11 @@
       return 0;
   }
   
  +/* Gets a symbol from the current unit symbol table */
   SymReg *
   get_sym(const char * name)
   {
  -    return _get_sym(hash, name);
  +    return _get_sym(cur_unit->hash, name);
   }
   
   /* find a symbol hash or ghash */
  @@ -478,20 +479,22 @@
   SymReg *
   find_sym(const char * name)
   {
  -    return _find_sym(namespace, hash, name);
  +    if(cur_unit)
  +        return _find_sym(namespace, cur_unit->hash, name);
  +    return NULL;
   }
   
   
   void
  -_delete_sym(IMC_Unit * unit, SymReg * hsh[], const char * name)
  +_delete_sym(IMC_Unit * unit, const char * name)
   {
       SymReg ** p;
       int i = hash_str(name) % HASH_SIZE;
  -    for(p = &hsh[i]; *p; p = &(*p)->next) {
  +    for(p = &unit->hash[i]; *p; p = &(*p)->next) {
           SymReg * deadmeat = *p;
        if(!strcmp(name, deadmeat->name)) {
               *p = deadmeat->next;
  -            if (unit && deadmeat->life_info){
  +            if (deadmeat->life_info){
                free_life_info(unit, deadmeat);
               }
               free_sym(deadmeat);
  @@ -503,15 +506,31 @@
   }
   
   
  -/* Deletes all symbols */
   void
  -clear_tables(IMC_Unit * unit, SymReg * hsh[])
  +clear_sym_hash(SymReg **hsh)
   {
       int i;
       SymReg * p, *next;
       for(i = 0; i < HASH_SIZE; i++) {
        for(p = hsh[i]; p; ) {
            next = p->next;
  +         free_sym(p);
  +         p = next;
  +     }
  +        hsh[i] = NULL;
  +    }
  +}
  +
  +/* Deletes all local symbols and clears life info */
  +void
  +clear_locals(IMC_Unit * unit)
  +{
  +    int i;
  +    SymReg * p, *next;
  +    SymReg **hsh = unit->hash;
  +    for(i = 0; i < HASH_SIZE; i++) {
  +     for(p = hsh[i]; p; ) {
  +         next = p->next;
               if(unit && p->life_info) {
                   free_life_info(unit, p);
               }
  @@ -520,6 +539,15 @@
        }
           hsh[i] = NULL;
       }
  +}
  +
  +/* Clear global symbols */
  +void
  +clear_globals()
  +{
  +    int i;
  +    SymReg * p, *next;
  +
       for(i = 0; i < HASH_SIZE; i++) {
           for(p = ghash[i]; p; p = p->next)
               if (p->type & VTADDRESS)
  
  
  

Reply via email to