cvsuser     04/12/10 21:38:37

  Modified:    imcc     pcc.c reg_alloc.c
               imcc/t/reg spill.t
  Log:
  [perl #32996] Register coloring not dirtying registers for method
    calls properly
  
  * backport preserved register check from new allocator
  * work around continuation bug by allocating temps 16..5
  * add bug code as a test case
  
  Revision  Changes    Path
  1.85      +0 -2      parrot/imcc/pcc.c
  
  Index: pcc.c
  ===================================================================
  RCS file: /cvs/public/parrot/imcc/pcc.c,v
  retrieving revision 1.84
  retrieving revision 1.85
  diff -u -r1.84 -r1.85
  --- pcc.c     7 Dec 2004 10:50:38 -0000       1.84
  +++ pcc.c     11 Dec 2004 05:38:35 -0000      1.85
  @@ -449,8 +449,6 @@
           sprintf(buf, "%d", CURRENT_OBJECT);
           regs[1] = get_const(interp, buf, 'I');
           ins = insINS(interp, unit, ins, "interpinfo", regs, 2);
  -        regs[1] = get_pasm_reg(interp, "P2");
  -        ins = insINS(interp, unit, ins, "set", regs, 2);
       }
       /*
        * check if there is a return
  
  
  
  1.27      +66 -33    parrot/imcc/reg_alloc.c
  
  Index: reg_alloc.c
  ===================================================================
  RCS file: /cvs/public/parrot/imcc/reg_alloc.c,v
  retrieving revision 1.26
  retrieving revision 1.27
  diff -u -r1.26 -r1.27
  --- reg_alloc.c       30 Nov 2004 10:28:51 -0000      1.26
  +++ reg_alloc.c       11 Dec 2004 05:38:35 -0000      1.27
  @@ -41,7 +41,7 @@
   static void compute_du_chain(IMC_Unit * unit);
   static void compute_one_du_chain(SymReg * r, IMC_Unit * unit);
   static int interferes(Interp *, IMC_Unit *, SymReg * r0, SymReg * r1);
  -static int map_colors(IMC_Unit *, int x, unsigned int * graph, int colors[], 
int typ);
  +static void map_colors(IMC_Unit *, int x, unsigned int * graph, char 
colors[], int typ);
   #ifdef DO_SIMPLIFY
   static int simplify (IMC_Unit *);
   #endif
  @@ -893,6 +893,48 @@
       }
   }
   /*
  + * find available color for register #x in available colors
  + */
  +static int
  +ig_find_color(Interp* interpreter, IMC_Unit *unit, int x, char *avail)
  +{
  +    int c, t;
  +    SymReg *r;
  +    static const char types[] = "ISPN";
  +
  +    static const char assignable[4][5] = {
  +       /* 0  1  2  3  4  */
  +        { 0, 0, 0, 0, 0, },     /* I */
  +        { 0, 1, 1, 1, 1, },     /* S */
  +        { 0, 0, 0, 1, 1, },     /* P */
  +        { 1, 1, 1, 1, 1, },     /* N */
  +    };
  +
  +
  +    UNUSED(interpreter);
  +    r = unit->reglist[x];
  +    t = strchr(types, r->set) - types;
  +
  +    /* please note: c is starting at 1 for R0 */
  +    if (!(r->usage & U_NON_VOLATILE)) {
  +        /* 1) 5-15 volatile range
  +         * XXX allocate down to work around continuation bug
  +         * */
  +        for (c = 16; c >= 6; c--)
  +            if (avail[c])
  +                return c;
  +        /* some lower regs are usable too 0...4 */
  +        for (c = 1; c <= 5; c++)
  +            if (avail[c] && assignable[t][c - 1])
  +                return c;
  +    }
  +    /* 2) try upper non-volatiles, 16...31 */
  +    for (c = 17; c <= 32; c++)
  +        if (avail[c])
  +            return c;
  +    return 0;
  +}
  +/*
    * Color the graph assigning registers to each symbol:
    *
    * We just proceed poping items from the stack, and assigning
  @@ -905,8 +947,9 @@
   try_allocate(Parrot_Interp interpreter, IMC_Unit * unit)
   {
       int x = 0;
  -    int color, colors[MAX_COLOR];
  -    int free_colors, t;
  +    int color;
  +    char avail[MAX_COLOR + 1];
  +    int t;
       unsigned int *graph = unit->interference_graph;
       SymReg ** reglist = unit->reglist;
   
  @@ -915,28 +958,23 @@
   
        for (t = 0; t < 4; t++) {
            int typ = "INSP"[t];
  -         memset(colors, 0, sizeof(colors));
            if (reglist[x]->set == typ && reglist[x]->color == -1) {
  -             free_colors = map_colors(unit, x, graph, colors, typ);
  -             if (free_colors > 0) {
  -                 for (color = 0; color < MAX_COLOR; color++) {
  -                        int c = (color + MAX_COLOR/2) % MAX_COLOR;
  -                     if (!colors[c]) {
  -                         reglist[x]->color = c;
  -
  -                            IMCC_debug(interpreter, DEBUG_IMC,
  -                                    "#[%s] provisionally gets color [%d]"
  -                                     "(%d free colors, score %d)\n",
  -                                     reglist[x]->name, c,
  -                                        free_colors, reglist[x]->score);
  -                         break;
  -                     }
  -                 }
  +                map_colors(unit, x, graph, avail, typ);
  +                color = ig_find_color(interpreter, unit, x, avail);
  +                if (color) {
  +                    reglist[x]->color = color - 1;
  +
  +                    IMCC_debug(interpreter, DEBUG_IMC,
  +                            "#[%s] provisionally gets color [%d]"
  +                            "(score %d)\n",
  +                            reglist[x]->name, color - 1,
  +                            reglist[x]->score);
  +                    break;
                }
   
                if (reglist[x]->color == -1) {
                       IMCC_debug(interpreter, DEBUG_IMC,
  -                            "# no more colors free = %d\n", free_colors);
  +                            "# no more colors\n");
   
                    /* It has been impossible to assign a color
                        * to this node, return it so it gets spilled
  @@ -958,22 +996,21 @@
   /*
    * map_colors: calculates what colors can be assigned to the x-th symbol.
    */
  -static int
  -map_colors(IMC_Unit* unit, int x, unsigned int *graph, int colors[], int typ)
  +static void
  +map_colors(IMC_Unit* unit, int x, unsigned int *graph, char avail[], int typ)
   {
       int y = 0, n_symbols;
       SymReg * r;
  -    int color, free_colors;
   
       n_symbols = unit->n_symbols;
  -    memset(colors, 0, sizeof(colors[0]) * MAX_COLOR);
  +    memset(avail, 1, MAX_COLOR + 1);
       /* reserved for spilling */
       if (typ == 'P')
  -        colors[31] = 1;
  +        avail[31+1] = 0;
   #ifdef ALLOCATE_HACK
  -    colors[28] = 1;     /* for immediate allocation */
  -    colors[29] = 1;     /* for immediate allocation */
  -    colors[30] = 1;     /* for immediate allocation */
  +    avail[28+1] = 0;     /* for immediate allocation */
  +    avail[29+1] = 0;     /* for immediate allocation */
  +    avail[30+1] = 0;     /* for immediate allocation */
   #endif
       for (y = 0; y < n_symbols; y++) {
           if (! ig_test(x, y, n_symbols, graph))
  @@ -982,13 +1019,9 @@
           if (   r
            && r->color != -1
            && r->set == typ) {
  -         colors[r->color] = 1;
  +         avail[r->color+1] = 0;
        }
       }
  -    for (color = free_colors = 0; color < MAX_COLOR; color++)
  -     if (!colors[color])
  -         free_colors++;
  -    return free_colors;
   }
   
   #if ! DOIT_AGAIN_SAM
  
  
  
  1.9       +176 -1    parrot/imcc/t/reg/spill.t
  
  Index: spill.t
  ===================================================================
  RCS file: /cvs/public/parrot/imcc/t/reg/spill.t,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- spill.t   5 Aug 2004 09:49:49 -0000       1.8
  +++ spill.t   11 Dec 2004 05:38:37 -0000      1.9
  @@ -1,6 +1,6 @@
   #!perl
   use strict;
  -use TestCompiler tests => 4;
  +use TestCompiler tests => 5;
   
   ##############################
   
  @@ -424,3 +424,178 @@
   CODE
   ok
   OUT
  +
  +output_is(<<'CODE', <<'OUT', "bug #32996");
  +
  +.namespace ["Foo"]
  +
  +.sub __biginit prototyped, @MAIN
  +     newclass $P0, "Foo"
  +     $I1 = find_type "Foo"
  +     $P1 = new $I1
  +     $P1.method1()
  +     $P1.method2()
  +
  +     $P2 = new $I1
  +     $P2.method1()
  +     $P2.method2()
  +
  +     $P3 = new $I1
  +     $P3.method1()
  +     $P3.method2()
  +
  +     $P4 = new $I1
  +     $P4.method1()
  +     $P4.method2()
  +
  +     $P5 = new $I1
  +     $P5.method1()
  +     $P5.method2()
  +
  +     $P6 = new $I1
  +     $P6.method1()
  +     $P6.method2()
  +
  +     $P7 = new $I1
  +     $P7.method1()
  +     $P7.method2()
  +
  +     $P8 = new $I1
  +     $P8.method1()
  +     $P8.method2()
  +
  +     $P9 = new $I1
  +     $P9.method1()
  +     $P9.method2()
  +
  +     $P10 = new $I1
  +     $P10.method1()
  +     $P10.method2()
  +
  +     $P11 = new $I1
  +     $P11.method1()
  +     $P11.method2()
  +
  +     $P12 = new $I1
  +     $P12.method1()
  +     $P12.method2()
  +
  +     $P13 = new $I1
  +     $P13.method1()
  +     $P13.method2()
  +
  +     $P14 = new $I1
  +     $P14.method1()
  +     $P14.method2()
  +
  +     $P15 = new $I1
  +     $P15.method1()
  +     $P15.method2()
  +
  +     $P1.method1()
  +     $P1.method2()
  +     $P2.method1()
  +     $P2.method2()
  +     $P3.method1()
  +     $P3.method2()
  +     $P4.method1()
  +     $P4.method2()
  +     $P5.method1()
  +     $P5.method2()
  +     $P6.method1()
  +     $P6.method2()
  +     $P7.method1()
  +     $P7.method2()
  +     $P8.method1()
  +     $P8.method2()
  +     $P9.method1()
  +     $P9.method2()
  +     $P10.method1()
  +     $P10.method2()
  +     $P11.method1()
  +     $P11.method2()
  +     $P12.method1()
  +     $P12.method2()
  +     $P13.method1()
  +     $P13.method2()
  +     $P14.method1()
  +     $P14.method2()
  +     $P15.method1()
  +     $P15.method2()
  +
  +     end
  +.end
  +
  +.sub method1 prototyped, method
  +     print "In method 1\n"
  +     .pcc_begin_return
  +     .pcc_end_return
  +.end
  +
  +.sub method2 prototyped, method
  +     print "In method 2\n"
  +     .pcc_begin_return
  +     .pcc_end_return
  +.end
  +CODE
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +In method 1
  +In method 2
  +OUT
  
  
  

Reply via email to