cvsuser     03/02/21 04:26:43

  Modified:    languages/imcc ChangeLog cfg.c debug.c debug.h imc.c imc.h
                        imcc.y instructions.c main.c optimizer.c
                        optimizer.h parser_util.c pbc.c symreg.h
               languages/imcc/t/imcpasm opt1.t
  Log:
  imcc-opt: s. ChangeLog
  
  Revision  Changes    Path
  1.13      +14 -1     parrot/languages/imcc/ChangeLog
  
  Index: ChangeLog
  ===================================================================
  RCS file: /cvs/public/parrot/languages/imcc/ChangeLog,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -w -r1.12 -r1.13
  --- ChangeLog 20 Feb 2003 08:04:12 -0000      1.12
  +++ ChangeLog 21 Feb 2003 12:26:39 -0000      1.13
  @@ -1,4 +1,17 @@
  -- 2003-02-20 leo / Juergen Boemmel
  +- 2003-02-21 leo
  +
  +     * version 0.0.9.15
  +     * opimized some ugly quadratic timings in cfg building
  +       and branch optimizations by:
  +     * build bb_list earlier and use basic blocks
  +       This improves e.g.  -O2 t/op/stacks_33 from >1m to 2s
  +
  +     * absolute experimental and early stages for using imcc
  +       as JIT optimizer (-Oj) this is broken WRT rx_ops, which
  +       have an inout INT param and can branch, and WRT NCI/invoke
  +       and probably a lot more.
  +
  +- 2003-02-20 leo / Juergen Boemmels
   
        * version 0.0.9.14
        * macro preprocessor - thanks Juergen Boemmels
  
  
  
  1.16      +85 -52    parrot/languages/imcc/cfg.c
  
  Index: cfg.c
  ===================================================================
  RCS file: /cvs/public/parrot/languages/imcc/cfg.c,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -w -r1.15 -r1.16
  --- cfg.c     20 Feb 2003 08:04:13 -0000      1.15
  +++ cfg.c     21 Feb 2003 12:26:39 -0000      1.16
  @@ -22,18 +22,40 @@
       Basic_block *bb;
       Instruction *ins, *lab;
       int nu = 0;
  +    int i;
   
       init_basic_blocks();
  +    for(i = 0; i < HASH_SIZE; i++) {
  +        SymReg * r = hash[i];
  +        if (r && (r->type & VTADDRESS)) {
  +            r->first_ins = r->last_ins = NULL;
  +        }
  +    }
   
       ins = instructions;
  +    ins->index = i = 0;
   
       bb = make_basic_block(ins);
  +    if ( (ins->type & ITLABEL)) {
  +        /* set the labels address (ins) */
  +        ins->r[0]->first_ins = ins;
  +    }
  +    else if (ins->type & ITBRANCH) {
  +        SymReg * addr = get_branch_reg(bb->end);
  +        if (addr)
  +            addr->last_ins = ins;
  +    }
       for(ins=ins->next; ins; ins = ins->next) {
  +        ins->index = ++i;
   
           bb->end = ins;
           ins->bbindex = n_basic_blocks - 1;
           /* a LABEL starts a new basic block, but not, if we have
            * a new one (last was a branch) */
  +        if ( (ins->type & ITLABEL)) {
  +            /* set the labels address (ins) */
  +            ins->r[0]->first_ins = ins;
  +        }
           if (nu)
               nu = 0;
           else if ( (ins->type & ITLABEL)) {
  @@ -42,7 +64,11 @@
           /* a branch is the end of a basic block
            * so start a new with the next ins */
           if (ins->type & ITBRANCH) {
  +            SymReg * addr = get_branch_reg(bb->end);
               int found = 1;
  +
  +            if (addr)
  +                addr->last_ins = ins;
               /* if we have a bsr, then consider it only as a branch,
                * when we have the target here
                * and it doesn't saveall - like P6C recursive bsr's
  @@ -51,6 +77,7 @@
                   char *name =
                       *ins->op == 'b' ? ins->r[0]->name : ins->r[1]->name;
                   found = 0;
  +                /* TODO get_sym */
                   for (lab = instructions; lab; lab = lab->next) {
                       if ((lab->type & ITLABEL) &&
                               !strcmp(lab->r[0]->name, name)) {
  @@ -78,17 +105,12 @@
                   nu = 1;
               }
           }
  -        /* XXX instruction type ITADDR is probably address of a
  -         * CATCH block - we don't optimize them
  -         * XXX they are marked as branch, to avoid dead code removal
  -         * when we are sure, how exception will work, we will see.
  -         */
  -        if (ins->type & ITADDR)
  -            dont_optimize = 1;
       }
   
  -    if (IMCC_DEBUG & DEBUG_CFG)
  +    if (IMCC_DEBUG & DEBUG_CFG) {
        dump_instructions();
  +        dump_labels();
  +    }
   }
   
   /* Once the basic blocks have been computed, build_cfg computes
  @@ -148,6 +170,10 @@
   /* find the placement of the label, and link the two nodes */
   
   void bb_findadd_edge(Basic_block *from, SymReg *label) {
  +#if 0
  +    /* ugly slow quadratic search for a label takes ~35 s for
  +     * ../../t/op/stacks_33
  +     */
       Instruction *ins;
   
       for (ins = instructions; ins; ins = ins->next) {
  @@ -160,6 +186,13 @@
   
        }
       }
  +#else
  +    SymReg *r = get_sym(label->name);
  +
  +    if (r && (r->type & VTADDRESS) && r->first_ins)
  +        bb_add_edge(from, bb_list[r->first_ins->bbindex]);
  +
  +#endif
   }
   
   
  @@ -543,7 +576,6 @@
   
       sort_loops();
       if (IMCC_DEBUG & DEBUG_CFG) {
  -        dump_instructions();
        dump_cfg();
           dump_loops();
       }
  @@ -577,7 +609,8 @@
           if (i==0)
               debug(DEBUG_CFG,"\tdead code\n");
           else
  -            debug(DEBUG_CFG,"\tcan't determine loop entry block (%d found)\n" ,i);
  +            debug(DEBUG_CFG,
  +                    "\tcan't determine loop entry block (%d found)\n" ,i);
       }
   
      loop = set_make(n_basic_blocks);
  
  
  
  1.11      +18 -0     parrot/languages/imcc/debug.c
  
  Index: debug.c
  ===================================================================
  RCS file: /cvs/public/parrot/languages/imcc/debug.c,v
  retrieving revision 1.10
  retrieving revision 1.11
  diff -u -w -r1.10 -r1.11
  --- debug.c   8 Feb 2003 14:41:28 -0000       1.10
  +++ debug.c   21 Feb 2003 12:26:39 -0000      1.11
  @@ -132,6 +132,24 @@
       }
   }
   
  +void
  +dump_labels()
  +{
  +    int i;
  +
  +    fprintf(stderr, "Labels\n");
  +    fprintf(stderr, "name\tpos\tlast ref\n"
  +            "-----------------------\n");
  +    for(i = 0; i < HASH_SIZE; i++) {
  +        SymReg * r = hash[i];
  +        if (r && (r->type & VTADDRESS))
  +            fprintf(stderr, "%s\t%d\t%d\n",
  +                    r->name,
  +                    r->first_ins ? r->first_ins->index : -1,
  +                    r->last_ins ? r->last_ins->index : -1);
  +    }
  +    fprintf(stderr, "\n");
  +}
   
   extern int n_comp_units;
   void dump_symreg() {
  
  
  
  1.7       +1 -0      parrot/languages/imcc/debug.h
  
  Index: debug.h
  ===================================================================
  RCS file: /cvs/public/parrot/languages/imcc/debug.h,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -w -r1.6 -r1.7
  --- debug.h   7 Feb 2003 14:05:51 -0000       1.6
  +++ debug.h   21 Feb 2003 12:26:39 -0000      1.7
  @@ -22,6 +22,7 @@
   void dump_instructions(void);
   void dump_cfg(void);
   void dump_loops(void);
  +void dump_labels(void);
   void dump_symreg(void);
   void dump_interference_graph(void);
   void dump_dominators(void);
  
  
  
  1.35      +169 -24   parrot/languages/imcc/imc.c
  
  Index: imc.c
  ===================================================================
  RCS file: /cvs/public/parrot/languages/imcc/imc.c,v
  retrieving revision 1.34
  retrieving revision 1.35
  diff -u -w -r1.34 -r1.35
  --- imc.c     20 Feb 2003 08:04:13 -0000      1.34
  +++ imc.c     21 Feb 2003 12:26:39 -0000      1.35
  @@ -1,4 +1,4 @@
  -/* Regsster allocator:
  +/* Register allocator:
    *
    * This is a brute force register allocator. It uses a graph-coloring
    * algorithm, but the implementation is very kludgy.
  @@ -14,27 +14,18 @@
   #include <string.h>
   #include "imc.h"
   #include "optimizer.h"
  +#include "parrot/jit.h"
   
   static void make_stat(int *sets, int *cols);
   static void imc_stat_init(void);
   static void print_stat(void);
  +static void allocate_jit(struct Parrot_Interp *interpreter);
   
   extern int pasm_file;
   /* Globals: */
   
   static IMCStack nodeStack;
   
  -/* return the index of a PMC class */
  -int get_pmc_num(struct Parrot_Interp *interp, char *pmc_type)
  -{
  -    STRING * s = string_make(interp, pmc_type,
  -            (UINTVAL) strlen(pmc_type), NULL, 0, NULL);
  -    PMC * key = key_new_string(interp, s);
  -    PMC * cnames = interp->Parrot_base_classname_hash;
  -
  -    return cnames->vtable->get_integer_keyed(interp, cnames, key);
  -}
  -
   /* allocate is the main loop of the allocation algorithm */
   void allocate(struct Parrot_Interp *interpreter) {
       int to_spill;
  @@ -64,14 +55,14 @@
       while (todo) {
           info(2, "find_basic_blocks\n");
           find_basic_blocks();
  +        todo = cfg_optimize(interpreter);
  +    }
  +    todo = 1;
  +    while (todo) {
  +        find_basic_blocks();
           info(2, "build_cfg\n");
  -        build_cfg();
   
  -        if (!dont_optimize && dead_code_remove()) {
  -            info(2, "pre_optimize\n");
  -            pre_optimize(interpreter);
  -            continue;
  -        }
  +        build_cfg();
   
           info(2, "compute_dominators\n");
           compute_dominators();
  @@ -82,9 +73,7 @@
           build_reglist();
           info(2, "life_analysis\n");
           life_analysis();
  -        /* optimize, as long as there is something to do -
  -         * but not, if we found a set_addr, which means
  -         * we have probably a CATCH handler */
  +        /* optimize, as long as there is something to do */
           if (IMCC_DEBUG & DEBUG_IMC)
               dump_symreg();
           if (dont_optimize)
  @@ -116,6 +105,11 @@
       }
       if (IMCC_DEBUG & DEBUG_IMC)
           dump_instructions();
  +    if (optimizer_level & OPT_J) {
  +        allocate_jit(interpreter);
  +        if (IMCC_DEBUG & DEBUG_IMC)
  +            dump_instructions();
  +    }
       if (IMCC_VERBOSE > 1 || (IMCC_DEBUG & DEBUG_IMC))
           print_stat();
       free_reglist();
  @@ -239,7 +233,9 @@
                       reglist[count++] = r->reg;
                   else
                       reglist[count++] = r;
  -                /* rearange I registers */
  +                /* rearange I/N registers
  +                 * XXX not here, do it, when reading the source
  +                 * .nciarg, rx_char, ... !!!1 */
                   if ((optimizer_level & OPT_PASM) && pasm_file &&
                           (reglist[count-1]->set == 'I' ||
                           reglist[count-1]->set == 'N'))
  @@ -376,8 +372,11 @@
   
           depth = bb_list[ins->bbindex]->loop_depth;
   
  -        for (i = 0; ins->r[i] && i < IMCC_MAX_REGS; i++)
  +        for (i = 0; ins->r[i] && i < IMCC_MAX_REGS; i++) {
               ins->r[i]->score += 1 << (depth * 3);
  +            if (ins->flags & ITSPILL)
  +                ins->r[i]->score = 50000000;
  +        }
   
       }
   
  @@ -447,6 +446,9 @@
    * Returns if it has been able to delete at least one node
    * and 0 otherwise.
    *
  + * XXX: this doesn't look at score, so I think this is bogus
  + *      - currently disabled
  + *
    */
   
   int simplify (){
  @@ -531,7 +533,7 @@
   void restore_interference_graph() {
       int i;
       for (i=0; i < n_symbols; i++) {
  -        if (reglist[i]->type & VTPASM)
  +        if ((reglist[i]->type & VTPASM) && !(optimizer_level & OPT_PASM))
               continue;
        reglist[i]->color = -1;
        reglist[i]->simplified = 0;
  @@ -723,6 +725,149 @@
       return cnt;
   }
   
  +/* PASM registers are already in most used order, so now:
  + * - consider the top N registers as processor registers
  + * - look at the instruction stream and insert register load/store ins
  + *   for e.g. calling out to unJITted functions
  + *   This is of course processor dependend
  + *
  + * TODO: rx_ ops may have a inout INT parameter for position/mark.
  + *       Do not assign registers, if any such inout branching
  + *       instruction is encountered.
  + */
  +
  +static void
  +allocate_jit(struct Parrot_Interp *interpreter)
  +{
  +    int i, j, f, k;
  +/* int to_map[] = { INT_REGISTERS_TO_MAP, 0, 0,
  + *      FLOAT_REGISTERS_TO_MAP };
  + *      XXX communicate these with jit_emit.h
  + */
  +    int to_map[] = { 4, 0, 0, 4 };
  +    const char *types = "IPSN";
  +    Instruction * ins, *next, *last, *tmp, *prev;
  +    SymReg * r, *cpu[4+4], *regs[IMCC_MAX_REGS];       /* XXX */
  +    int reads[4+4], writes[4+4], nr, nw;
  +    static SymReg *par[4+4];       /* XXX */
  +    static int ncpu;
  +
  +    for (j = 0; j < ncpu; j++)
  +        free(par[j]);
  +    for(i = ncpu = 0; i < HASH_SIZE; i++) {
  +        r = hash[i];
  +        /* Add each mapped register to cpu reglist */
  +        for(; r; r = r->next) {
  +            if ((r->type & VTREGISTER) && r->set != 'K') {
  +                if (r->color >= 0 &&
  +                        r->color < to_map[strchr(types, r->set) - types]) {
  +                    r->color = -1 - r->color;
  +                    cpu[ncpu++] = r;
  +                }
  +            }
  +        }
  +    }
  +    /* generate a list of parrot registers */
  +    for (j = 0; j < ncpu; j++) {
  +        par[j] = malloc(sizeof(SymReg));
  +        memcpy(par[j], cpu[j], sizeof(SymReg));
  +        par[j]->color = -1 - cpu[j]->color;
  +    }
  +    prev = last = NULL;
  +    nr = nw = 0;
  +    for (ins = instructions; ins; prev = ins, ins = ins->next) {
  +        if (ins->opnum >= 0 &&
  +                op_jit[ins->opnum].extcall == 1) {  /* XXX i386 */
  +            for (k = 0; k < ncpu; k++)
  +                reads[k] = writes[k] = 999;
  +            /* TODO non preserved regs */
  +            for (last = next = ins;
  +                    next && op_jit[next->opnum].extcall == 1;
  +                    next = next->next) {
  +                for (j = 0; j < ncpu; j++) {
  +                    if (instruction_reads(next, cpu[j]) &&
  +                            instruction_writes(next, cpu[j])) {
  +                        /* or set reads[j] - could be faster */
  +                        for (k = f = 0; k < nr; k++) {
  +                            if (reads[k] == j) {
  +                                f = 1;
  +                                break;
  +                            }
  +                        }
  +                        if (!f)
  +                            reads[nr++] = j;
  +                        for (k = f = 0; k < nr; k++) {
  +                            if (writes[k] == j) {
  +                                f = 1;
  +                                break;
  +                            }
  +                        }
  +                        if (!f)
  +                            writes[nw++] = j;
  +                        for (k = 0; next->r[k] && k < IMCC_MAX_REGS; k++)
  +                            if (next->r[k] == cpu[j])
  +                                next->r[k] = par[j];
  +                    }
  +                    else if (instruction_reads(next, cpu[j])) {
  +                        for (k = f = 0; k < nr; k++) {
  +                            if (reads[k] == j) {
  +                                f = 1;
  +                                break;
  +                            }
  +                        }
  +                        if (!f)
  +                            reads[nr++] = j;
  +                        for (k = 0; next->r[k] && k < IMCC_MAX_REGS; k++)
  +                            if (next->r[k] == cpu[j])
  +                                next->r[k] = par[j];
  +                    }
  +                    else if (instruction_writes(next, cpu[j])) {
  +                        for (k = 0; next->r[k] && k < IMCC_MAX_REGS; k++)
  +                            if (next->r[k] == cpu[j])
  +                                next->r[k] = par[j];
  +                        for (k = f = 0; k < nr; k++) {
  +                            if (writes[k] == j) {
  +                                f = 1;
  +                                break;
  +                            }
  +                        }
  +                        if (!f)
  +                            writes[nw++] = j;
  +                    }
  +                }
  +                /* remember last extern opcode, all loads are inserted
  +                 * after this instruction
  +                 */
  +                if (next->type & ITBRANCH) {
  +                    break;
  +                }
  +                last = next;
  +            }
  +        }
  +        /* insert load ins after non JIT block */
  +        if (last && nw) {
  +            for ( ; nw ; nw--) {
  +                j = writes[nw-1];
  +                regs[0] = cpu[j];
  +                regs[1] = par[j];
  +                tmp = INS(interpreter, "set", "%s, %s\t# load",
  +                        regs, 2, 0, 0);
  +                insert_ins(last, tmp);
  +            }
  +            last = NULL;
  +        }
  +        /* insert save ins before extern op */
  +        if (nr) {
  +            for ( ; nr ; nr--) {
  +                j = reads[nr-1];
  +                regs[0] = par[j];
  +                regs[1] = cpu[j];
  +                tmp = INS(interpreter, "set", "%s, %s\t# save", regs, 2, 0, 0);
  +                insert_ins(prev, tmp);
  +            }
  +        }
  +    }
  +}
   
   /*
    * Utility functions
  
  
  
  1.28      +1 -0      parrot/languages/imcc/imc.h
  
  Index: imc.h
  ===================================================================
  RCS file: /cvs/public/parrot/languages/imcc/imc.h,v
  retrieving revision 1.27
  retrieving revision 1.28
  diff -u -w -r1.27 -r1.28
  --- imc.h     20 Feb 2003 08:04:13 -0000      1.27
  +++ imc.h     21 Feb 2003 12:26:39 -0000      1.28
  @@ -79,6 +79,7 @@
   EXTERN int        line;      /* and line */
   EXTERN int optimizer_level;
   EXTERN int dont_optimize;
  +EXTERN int has_compile;
   
   enum {
        OPT_NONE,
  
  
  
  1.47      +5 -1      parrot/languages/imcc/imcc.y
  
  Index: imcc.y
  ===================================================================
  RCS file: /cvs/public/parrot/languages/imcc/imcc.y,v
  retrieving revision 1.46
  retrieving revision 1.47
  diff -u -w -r1.46 -r1.47
  --- imcc.y    18 Feb 2003 12:39:17 -0000      1.46
  +++ imcc.y    21 Feb 2003 12:26:40 -0000      1.47
  @@ -365,6 +365,9 @@
               /* XXX probably a CATCH block */
               ins->type = ITADDR | IF_r1_branch | ITBRANCH;
           }
  +        else if (!strcmp(name, "compile"))
  +            ++has_compile;
  +
           if (emit)
                emitb(ins);
       } else {
  @@ -439,7 +442,8 @@
   emit:
         EMIT                              { open_comp_unit(); }
         pasmcode
  -      EOM                            { emit_flush(interp); $$=0;}
  +      EOM                            { allocate(interp);
  +                                          emit_flush(interp); $$=0;}
       ;
   
   
  
  
  
  1.27      +25 -7     parrot/languages/imcc/instructions.c
  
  Index: instructions.c
  ===================================================================
  RCS file: /cvs/public/parrot/languages/imcc/instructions.c,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -w -r1.26 -r1.27
  --- instructions.c    20 Feb 2003 08:04:13 -0000      1.26
  +++ instructions.c    21 Feb 2003 12:26:40 -0000      1.27
  @@ -229,7 +229,16 @@
   
   void insert_ins(Instruction *ins, Instruction * tmp)
   {
  -    Instruction *next = ins->next;
  +    Instruction *next;
  +    if (!ins) {
  +        next = instructions;
  +        instructions = tmp;
  +        tmp->next = next;
  +        next->prev = tmp;
  +        tmp->line = next->line;
  +    }
  +    else {
  +        next = ins->next;
       ins->next = tmp;
       tmp->prev = ins;
       tmp->next = next;
  @@ -237,6 +246,7 @@
       if (!tmp->line)
           tmp->line = ins->line;
   }
  +}
   
   /*
    * subst tmp for ins
  @@ -316,12 +326,19 @@
            sprintf(regb[i], "%c%d", p->set, p->color);
            regstr[i] = regb[i];
        }
  +        else if (p->set != 'K' && p->color < 0 && (p->type & VTREGISTER)) {
  +         sprintf(regb[i], "r%c%d", tolower(p->set), -1 - p->color);
  +         regstr[i] = regb[i];
  +     }
           else if (p->type & VTREGKEY) {
               SymReg * k = p->nextkey;
               for (*regb[i] = '\0'; k; k = k->nextkey) {
                   if (k->reg && k->reg->color >= 0)
                       sprintf(regb[i]+strlen(regb[i]), "%c%d",
                               k->reg->set, k->reg->color);        /* XXX */
  +                else if (k->reg && k->reg->color < 0)
  +                    sprintf(regb[i]+strlen(regb[i]), "r%c%d",
  +                            tolower(k->reg->set), -1 - k->reg->color);
                   else
                       strcat(regb[i], k->name);   /* XXX */
                   if (k->nextkey)
  @@ -410,6 +427,7 @@
   int emit_open(int type, void *param)
   {
       emitter = type;
  +    has_compile = 0;
       return (emitters[emitter]).open(param);
       return 0;
   }
  
  
  
  1.18      +2 -2      parrot/languages/imcc/main.c
  
  Index: main.c
  ===================================================================
  RCS file: /cvs/public/parrot/languages/imcc/main.c,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -w -r1.17 -r1.18
  --- main.c    20 Feb 2003 08:04:13 -0000      1.17
  +++ main.c    21 Feb 2003 12:26:40 -0000      1.18
  @@ -19,7 +19,7 @@
   #include "pbc.h"
   #include "parser.h"
   
  -#define IMCC_VERSION "0.0.9.14"
  +#define IMCC_VERSION "0.0.9.15"
   
   static int run_pbc, write_pbc;
   static char optimizer_opt[20];
  @@ -210,7 +210,7 @@
           if (strchr(optimizer_opt, '2'))
               optimizer_level |= (OPT_CFG | OPT_PRE);
           if (strchr(optimizer_opt, 'j'))
  -            optimizer_level |= OPT_J;
  +            optimizer_level |= (OPT_J | OPT_PASM);
           if (strchr(optimizer_opt, 'p'))
               optimizer_level |= OPT_PASM;
       }
  
  
  
  1.18      +125 -81   parrot/languages/imcc/optimizer.c
  
  Index: optimizer.c
  ===================================================================
  RCS file: /cvs/public/parrot/languages/imcc/optimizer.c,v
  retrieving revision 1.17
  retrieving revision 1.18
  diff -u -w -r1.17 -r1.18
  --- optimizer.c       20 Feb 2003 08:04:13 -0000      1.17
  +++ optimizer.c       21 Feb 2003 12:26:40 -0000      1.18
  @@ -45,8 +45,11 @@
    *
    */
   static void if_branch(struct Parrot_Interp *);
  -static void branch_branch(void);
  -static void unused_label(void);
  +
  +static int branch_branch(void);
  +static int unused_label(void);
  +static int dead_code_remove(void);
  +
   static void strength_reduce(struct Parrot_Interp *interp);
   static void subst_constants_mix(struct Parrot_Interp *interp);
   static void subst_constants_umix(struct Parrot_Interp *interp);
  @@ -59,7 +62,7 @@
   static int clone_remove(void);
   
   void pre_optimize(struct Parrot_Interp *interp) {
  -    if (optimizer_level & OPT_PRE) {      /* XXX */
  +    if (optimizer_level & OPT_PRE) {
           subst_constants_mix(interp);
           subst_constants_umix(interp);
           subst_constants(interp);
  @@ -67,10 +70,21 @@
           subst_constants_if(interp);
           strength_reduce(interp);
           if_branch(interp);
  -        branch_branch();
  +    }
  +}
  +
  +int cfg_optimize(struct Parrot_Interp *interp) {
  +    UNUSED(interp);
  +    if (optimizer_level & OPT_PRE) {
  +        if (branch_branch())
  +            return 1;
           /* XXX cfg / loop detection breaks e.g. in t/compiler/5_3 */
  -        unused_label();
  +        if (unused_label())
  +            return 1;
  +        if (dead_code_remove())
  +            return 1;
       }
  +    return 0;
   }
   
   int optimize(struct Parrot_Interp *interp) {
  @@ -127,6 +141,7 @@
       last = instructions;
       if (!last->next)
           return;
  +    info(2, "\tif_branch\n");
       for (ins = last->next; ins; ) {
           if ((last->type & ITBRANCH) &&          /* if ...L1 */
                   (ins->type & IF_goto) &&        /* branch L2*/
  @@ -163,81 +178,6 @@
           ins = ins->next;
       }
   }
  -
  -/*
  - * branch L1  => branch L2
  - * ...
  - * L1:
  - * branch L2
  - *
  - */
  -static void branch_branch()
  -{
  -    Instruction *ins1, *ins2, *next;
  -
  -    /* reset statistic globals */
  -    ostat.branch_branch = 0;
  -    for (ins1 = 0, ins1 = instructions; ins1; ins1 = ins1->next) {
  -        if ((ins1->type & IF_goto) && !strcmp(ins1->op, "branch")) {
  -            for (ins2 = 0, ins2 = instructions; ins2; ins2 = ins2->next) {
  -                if ((ins2->type & ITLABEL) &&
  -                        !strcmp(ins1->r[0]->name, ins2->r[0]->name)) {
  -                    next = ins2->next;
  -                    if (!next)
  -                        break;
  -                    if ((next->type & IF_goto) &&
  -                            !strcmp(next->op, "branch")) {
  -                        debug(DEBUG_OPT1, "found branch to branch '%s' %s\n",
  -                                ins2->r[0]->name, ins_string(next));
  -                        ostat.branch_branch++;
  -                        ins1->r[0] = next->r[0];
  -                    }
  -                }
  -            }
  -        }
  -    }
  -
  -}
  -
  -static void unused_label()
  -{
  -    Instruction *ins, *ins2, *last;
  -    SymReg * addr;
  -    int used;
  -
  -    for (last = 0, ins = instructions; ins; ins = ins->next) {
  -        if ((ins->type & ITLABEL) && *ins->r[0]->name != '_') {
  -            SymReg * lab = ins->r[0];
  -            used = 0;
  -            for (ins2 = instructions; ins2; ins2 = ins2->next) {
  -                if ((addr = get_branch_reg(ins2)) != 0) {
  -                    if (addr == lab && addr->type == VTADDRESS) {
  -                        used = 1;
  -                        break;
  -                    }
  -                }
  -                /* if we have compile/eval, we don't know, if this
  -                 * label might be used
  -                 */
  -                else if (!strcmp(ins2->op, "compile")) {
  -                    used = 1;
  -                    break;
  -                }
  -            }
  -            if (!used && last) {
  -                ostat.deleted_labels++;
  -                debug(DEBUG_OPT1, "label %s deleted\n", lab->name);
  -                ostat.deleted_ins++;
  -                delete_ins(ins, 1);
  -                last = ins;
  -                continue;
  -            }
  -
  -        }
  -        last = ins;
  -    }
  -}
  -
   /* these are run after constant simplification, so it is
    * guaranteed, that one operand is non constant, if opsize == 4
    */
  @@ -248,6 +188,7 @@
       int i, found;
       SymReg *r;
   
  +    info(2, "\tstrength_reduce\n");
       for (ins = instructions; ins; ins = ins->next) {
           /*
            * add Ix, Ix, Iy => add Ix, Iy
  @@ -356,6 +297,7 @@
       char b[128];
       SymReg *r;
   
  +    info(2, "\tsubst_constants_mix\n");
       for (ins = instructions; ins; ins = ins->next) {
           for (i = 0; i < sizeof(ops)/sizeof(ops[0]); i++) {
               /* TODO compare ins->opnum with a list of instructions
  @@ -393,6 +335,7 @@
       char b[128];
       SymReg *r;
   
  +    info(2, "\tsubst_constants_umix\n");
       for (ins = instructions; ins; ins = ins->next) {
           for (i = 0; i < sizeof(ops)/sizeof(ops[0]); i++) {
               /* TODO compare ins->opnum with a list of instructions
  @@ -494,6 +437,7 @@
       int found;
   
       /* save interpreter ctx */
  +    info(2, "\tsubst_constants\n");
       ctx = mem_sys_allocate(sizeof(struct Parrot_Context));
       mem_sys_memcopy(ctx, &interp->ctx, sizeof(struct Parrot_Context));
       /* construct a FLOATVAL_FMT with needed precision */
  @@ -574,6 +518,7 @@
       size_t i;
       int res;
   
  +    info(2, "\tsubst_constants_c\n");
       for (ins = instructions; ins; ins = ins->next) {
           for (i = 0; i < sizeof(ops)/sizeof(ops[0]); i++) {
               /* TODO s. above */
  @@ -711,6 +656,7 @@
       int res;
       char *s;
   
  +    info(2, "\tsubst_constants_if\n");
       for (ins = instructions; ins; ins = ins->next) {
           for (i = 0; i < sizeof(ops)/sizeof(ops[0]); i++) {
               /* TODO s. above */
  @@ -761,7 +707,104 @@
   
   
   /* optimizations with CFG built */
  -int dead_code_remove(void)
  +
  +/*
  + * branch L1  => branch L2
  + * ...
  + * L1:
  + * branch L2
  + *
  + */
  +static int branch_branch()
  +{
  +    Instruction *ins, *next;
  +    SymReg * r;
  +
  +    info(2, "\tbranch_branch\n");
  +    /* reset statistic globals */
  +    ostat.branch_branch = 0;
  +    for (ins = instructions; ins; ins = ins->next) {
  +        if ((ins->type & IF_goto) && !strcmp(ins->op, "branch")) {
  +            r = get_sym(ins->r[0]->name);
  +
  +            if (r && (r->type & VTADDRESS) && r->first_ins) {
  +                next = r->first_ins->next;
  +                if (!next)
  +                    break;
  +                if ((next->type & IF_goto) &&
  +                        !strcmp(next->op, "branch")) {
  +                    debug(DEBUG_OPT1, "found branch to branch '%s' %s\n",
  +                            r->first_ins->r[0]->name, ins_string(next));
  +                    ostat.branch_branch++;
  +                    ins->r[0] = next->r[0];
  +                    return 1;
  +                }
  +            }
  +        }
  +    }
  +    return 0;
  +}
  +
  +static int unused_label()
  +{
  +    Instruction *ins;
  +    int used;
  +    int i;
  +
  +    info(2, "\tunused_label\n");
  +    for (i=1; bb_list[i]; i++) {
  +     ins = bb_list[i]->start;
  +        if ((ins->type & ITLABEL) && *ins->r[0]->name != '_') {
  +            SymReg * lab = ins->r[0];
  +            used = 0;
  +            if (has_compile)
  +                used = 1;
  +#if 1
  +            else if (lab->last_ins)
  +                used = 1;
  +#else
  +            else {
  +                Instruction *ins2;
  +                int j;
  +                SymReg * addr;
  +                for (j=0; bb_list[j]; j++) {
  +                    /* a branch can be the first ins in a block
  +                     * (if prev ins was a label)
  +                     * or the last ins in a block
  +                     */
  +                    ins2 = bb_list[j]->start;
  +                    if ((ins2->type & ITBRANCH) &&
  +                            (addr = get_branch_reg(ins2)) != 0) {
  +                        if (addr == lab && addr->type == VTADDRESS) {
  +                            used = 1;
  +                            break;
  +                        }
  +                    }
  +                    ins2 = bb_list[j]->end;
  +                    if ((ins2->type & ITBRANCH) &&
  +                            (addr = get_branch_reg(ins2)) != 0) {
  +                        if (addr == lab && addr->type == VTADDRESS) {
  +                            used = 1;
  +                            break;
  +                        }
  +                    }
  +                }
  +            }
  +#endif
  +            if (!used) {
  +                ostat.deleted_labels++;
  +                debug(DEBUG_OPT1, "label %s deleted\n", lab->name);
  +                ostat.deleted_ins++;
  +                delete_ins(ins, 1);
  +                return 1;
  +            }
  +
  +        }
  +    }
  +    return 0;
  +}
  +
  +static int dead_code_remove(void)
   {
       Basic_block *bb;
       int i;
  @@ -771,6 +814,7 @@
       /* this could be a separate level, now it's done with -O1 */
       if (!(optimizer_level & OPT_PRE))
           return 0;
  +    info(2, "\tdead_code_remove\n");
       for (i=1; bb_list[i]; i++) {
        bb = bb_list[i];
           if ((bb->start->type & ITLABEL) && *bb->start->r[0]->name == '_')
  
  
  
  1.6       +1 -1      parrot/languages/imcc/optimizer.h
  
  Index: optimizer.h
  ===================================================================
  RCS file: /cvs/public/parrot/languages/imcc/optimizer.h,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -w -r1.5 -r1.6
  --- optimizer.h       8 Feb 2003 17:16:16 -0000       1.5
  +++ optimizer.h       21 Feb 2003 12:26:40 -0000      1.6
  @@ -1,7 +1,7 @@
   #ifndef __OPTIMIZER_H
   #define __OPTIMIZER_H
   void pre_optimize(struct Parrot_Interp *);
  -int dead_code_remove(void);
  +int cfg_optimize(struct Parrot_Interp *);
   int optimize(struct Parrot_Interp *);
   void post_optimize(struct Parrot_Interp *);
   
  
  
  
  1.10      +11 -0     parrot/languages/imcc/parser_util.c
  
  Index: parser_util.c
  ===================================================================
  RCS file: /cvs/public/parrot/languages/imcc/parser_util.c,v
  retrieving revision 1.9
  retrieving revision 1.10
  diff -u -w -r1.9 -r1.10
  --- parser_util.c     17 Feb 2003 13:56:36 -0000      1.9
  +++ parser_util.c     21 Feb 2003 12:26:40 -0000      1.10
  @@ -195,6 +195,17 @@
             string_make(interp, "pIt", 3, NULL,0,NULL));
   }
   
  +/* return the index of a PMC class */
  +int get_pmc_num(struct Parrot_Interp *interp, char *pmc_type)
  +{
  +    STRING * s = string_make(interp, pmc_type,
  +            (UINTVAL) strlen(pmc_type), NULL, 0, NULL);
  +    PMC * key = key_new_string(interp, s);
  +    PMC * cnames = interp->Parrot_base_classname_hash;
  +
  +    return cnames->vtable->get_integer_keyed(interp, cnames, key);
  +}
  +
   /*
    * Local variables:
    * c-indentation-style: bsd
  
  
  
  1.28      +0 -3      parrot/languages/imcc/pbc.c
  
  Index: pbc.c
  ===================================================================
  RCS file: /cvs/public/parrot/languages/imcc/pbc.c,v
  retrieving revision 1.27
  retrieving revision 1.28
  diff -u -w -r1.27 -r1.28
  --- pbc.c     20 Feb 2003 08:04:13 -0000      1.27
  +++ pbc.c     21 Feb 2003 12:26:40 -0000      1.28
  @@ -229,7 +229,6 @@
       Instruction * ins;
       int code_size;
       opcode_t pc;
  -    int has_compile = 0;
   
       /* run through instructions,
        * 1. pass
  @@ -267,8 +266,6 @@
               else if (!strcmp(ins->op, "set_addr"))
                   store_bsr(ins->r[1], pc, 2);
           }
  -        else if (!strcmp(ins->op, "compile"))
  -            ++has_compile;
           pc += ins->opsize;
       }
   
  
  
  
  1.14      +2 -1      parrot/languages/imcc/symreg.h
  
  Index: symreg.h
  ===================================================================
  RCS file: /cvs/public/parrot/languages/imcc/symreg.h,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -w -r1.13 -r1.14
  --- symreg.h  21 Jan 2003 10:11:31 -0000      1.13
  +++ symreg.h  21 Feb 2003 12:26:40 -0000      1.14
  @@ -49,7 +49,7 @@
       enum USAGE usage;             /* s. USAGE above */
       char set;                /* Which register set/file it belongs to */
       int color;               /* Color: parrot register number
  -                             and parrot const table index vof VTCONST*/
  +                             and parrot const table index of VTCONST*/
       int score;               /* How costly is to spill this symbol */
       int use_count;        /* how often is this sym used */
       int lhs_use_count;            /* how often is this sym written to */
  @@ -58,6 +58,7 @@
       struct _SymReg * next;   /* used in the symbols hash */
       struct _Instruction * first_ins; /* first and last instruction */
       struct _Instruction * last_ins;  /* this symbol is in */
  +    /* also used by labels as position of label and last reference */
       struct _SymReg * nextkey;        /* keys */
       struct _SymReg * reg;    /* key->register for VTREGKEYs */
   } SymReg;
  
  
  
  1.6       +12 -12    parrot/languages/imcc/t/imcpasm/opt1.t
  
  Index: opt1.t
  ===================================================================
  RCS file: /cvs/public/parrot/languages/imcc/t/imcpasm/opt1.t,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -w -r1.5 -r1.6
  --- opt1.t    17 Feb 2003 15:10:57 -0000      1.5
  +++ opt1.t    21 Feb 2003 12:26:43 -0000      1.6
  @@ -165,18 +165,6 @@
   OUT
   
   ##############################
  -SKIP: {
  -skip("constant concat N/Y", 1);
  -output_is(<<'CODE', <<'OUT', "constant concat");
  -   concat S0, "Parrot ", "rocks"
  -   end
  -CODE
  -   set S0, "Parrot rocks"
  -   end
  -OUT
  -}
  -
  -##############################
   output_is(<<'CODE', <<'OUT', "constant eq taken");
      eq 10, 10, L1
      set I0, 5
  @@ -526,4 +514,16 @@
      end
   OUT
   
  +
  +##############################
  +SKIP: {
  +skip("constant concat N/Y", 1);
  +output_is(<<'CODE', <<'OUT', "constant concat");
  +   concat S0, "Parrot ", "rocks"
  +   end
  +CODE
  +   set S0, "Parrot rocks"
  +   end
  +OUT
  +}
   
  
  
  


Reply via email to