cvsuser     03/02/07 09:04:20

  Modified:    languages/imcc ChangeLog cfg.c imcc.y
               languages/imcc/docs operation.pod
  Added:       languages/imcc/t/syn bsr.t
  Log:
  imcc-bsr
  
  Revision  Changes    Path
  1.9       +7 -0      parrot/languages/imcc/ChangeLog
  
  Index: ChangeLog
  ===================================================================
  RCS file: /cvs/public/parrot/languages/imcc/ChangeLog,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -w -r1.8 -r1.9
  --- ChangeLog 7 Feb 2003 14:05:51 -0000       1.8
  +++ ChangeLog 7 Feb 2003 17:04:13 -0000       1.9
  @@ -1,4 +1,11 @@
   - 2003-02-07         leo
  +     * first step for bsr handling in the CFG
  +       local bsrs (target in the same compilation unit) can
  +       preserve registers.
  +
  +       s. docs/operation.pod
  +
  +- 2003-02-07         leo
        * version 0.0.9.12
        * changed -d (--debug) options and made more granular
          debug output. s. docs/running.pod
  
  
  
  1.13      +67 -9     parrot/languages/imcc/cfg.c
  
  Index: cfg.c
  ===================================================================
  RCS file: /cvs/public/parrot/languages/imcc/cfg.c,v
  retrieving revision 1.12
  retrieving revision 1.13
  diff -u -w -r1.12 -r1.13
  --- cfg.c     7 Feb 2003 14:05:51 -0000       1.12
  +++ cfg.c     7 Feb 2003 17:04:13 -0000       1.13
  @@ -20,7 +20,7 @@
   
   void find_basic_blocks () {
       Basic_block *bb;
  -    Instruction *ins;
  +    Instruction *ins, *lab;
       int nu = 0;
   
       init_basic_blocks();
  @@ -42,10 +42,41 @@
           /* a branch is the end of a basic block
            * so start a new with the next ins */
           if (ins->type & ITBRANCH) {
  +            int found = 1;
  +            /* 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
  +             */
  +            if (!strcmp(ins->op, "bsr")) {
  +                char *name = ins->r[0]->name;
  +                found = 0;
  +                for (lab = instructions; lab; lab = lab->next) {
  +                    if ((lab->type & ITLABEL) &&
  +                            !strcmp(lab->r[0]->name, name)) {
  +                        int j = 0;
  +                        found = 1;
  +                        /* XXX look if first 5 ins have saveall
  +                         * this is a ugly but working hack ;-)
  +                         */
  +                        for (lab = lab->next; j < 5 && lab;
  +                                lab = lab->next, j++) {
  +                            if (!strcmp(lab->op, "saveall")) {
  +                                found = 0;
  +                                break;
  +                            }
  +                        }
  +                        break;
  +                    }
  +                }
  +                debug(DEBUG_CFG, "bsr %s local:%s\n",
  +                        name, found ? "yes": "no");
  +            }
  +            if (found) {
               if (ins->next)
                   bb = make_basic_block(ins->next);
            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
  @@ -63,9 +94,10 @@
      the dependences between them. */
   
   void build_cfg() {
  -    int i;
  +    int i, j;
       SymReg * addr;
       Basic_block *last, *bb;
  +    Edge *pred;
   
       for (i = 0; bb_list[i]; i++) {
           bb = bb_list[i];
  @@ -77,6 +109,32 @@
           addr = get_branch_reg(bb->end);
           if (addr)
               bb_findadd_edge(bb, addr);
  +        if (!strcmp(bb->end->op, "ret")) {
  +            debug(DEBUG_CFG, "found ret in bb %d\n", i);
  +            /* now go back, find labels and connect these with
  +             * bsrs
  +             */
  +            for (pred = bb->pred_list; pred; pred=pred->pred_next) {
  +                if (!strcmp(pred->from->end->op, "bsr")) {
  +                    SymReg *r = pred->from->end->r[0];
  +                    int found = 0;
  +
  +                    j = pred->from->index;
  +                    debug(DEBUG_CFG, "\tcalled from bb %d label '%s'? - ",
  +                            j, r->name);
  +                    if ((bb->start->type & ITLABEL) &&
  +                            (!strcmp(bb->start->r[0]->name, r->name)))
  +                        found = 1;
  +                    if (found) {
  +                        debug(DEBUG_CFG, "yep!\n");
  +                        bb_add_edge(bb, bb_list[j+1]);
  +                    }
  +                    else
  +                        debug(DEBUG_CFG, "na!\n");
  +
  +                }
  +            }
  +        }
   
           last = bb;
       }
  
  
  
  1.42      +8 -3      parrot/languages/imcc/imcc.y
  
  Index: imcc.y
  ===================================================================
  RCS file: /cvs/public/parrot/languages/imcc/imcc.y,v
  retrieving revision 1.41
  retrieving revision 1.42
  diff -u -w -r1.41 -r1.42
  --- imcc.y    7 Feb 2003 14:05:51 -0000       1.41
  +++ imcc.y    7 Feb 2003 17:04:13 -0000       1.42
  @@ -360,18 +360,23 @@
           ins->opnum = op;
           ins->opsize = op_info->arg_count;
           /* set up branch flags */
  -        if (op_info->jump) {
  +        if (op_info->jump || !strcmp(name, "end")) {
  +
  +#if 0
               if (!strcmp(name, "bsr") || !strcmp(name, "ret")) {
                   /* ignore subcalls and ret
                    * because they saveall
                    */
               }
  -            else {
  +            else
  +#endif
  +            {
  +
                   /* XXX: assume the jump is relative and to the last arg.
                    * usually true.
                    */
                   ins->type = ITBRANCH | (1 << (nargs-1));
  -                if (!strcmp(name, "branch"))
  +                if (!strcmp(name, "branch") || !strcmp(name, "end"))
                       ins->type |= IF_goto;
               }
           }
  
  
  
  1.2       +15 -0     parrot/languages/imcc/docs/operation.pod
  
  Index: operation.pod
  ===================================================================
  RCS file: /cvs/public/parrot/languages/imcc/docs/operation.pod,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -w -r1.1 -r1.2
  --- operation.pod     10 Dec 2002 08:55:11 -0000      1.1
  +++ operation.pod     7 Feb 2003 17:04:15 -0000       1.2
  @@ -63,6 +63,17 @@
   pieces, called B<basic block>s. A B<basic block> starts at a label,
   which can get jumped to, and ends at a branch instruction.
   
  +=head2 Special case: subroutine calls (bsr)
  +
  +Currently, imcc assumes, that a subroutine saves all registers on entry,
  +as P6C does per B<saveall>, and thus a B<bsr> doesn't count as a branch.
  +
  +But there is one exception to this rule: When the target of the
  +subroutine is known (the label is in the same compilation unit, and when
  +no B<saveall> instruction is found in the first 5 instructions after the
  +label, then the control flow from the B<bsr> call to the label and from
  +the B<ret> to the next basic block is calculated.
  +
   =head2 Call graph
   
   All connection between the B<basic block>s are calculated. This allows
  @@ -82,6 +93,10 @@
   
   Variables used as B<IN> parameters must keep their parrot register
   over their usage range.
  +
  +Note: imcc does currently not know, that certain register operations do
  +globber registers: mainly B<restoreall> and friends, which have no hint
  +in core.ops, that they do what they do.
   
   =head2 Interference graph
   
  
  
  
  1.1                  parrot/languages/imcc/t/syn/bsr.t
  
  Index: bsr.t
  ===================================================================
  #!perl
  use strict;
  use TestCompiler tests => 2;
  use Test::More qw(skip);
  
  ##############################
  # this tests register allocation/preserving of local bsr calls
  #
  output_is(<<'CODE', <<'OUT', "bsr 1");
  .sub _test
     $I0 = 2
     $I1 = 3
     bsr L
     print $I0
     print $I1
     print "\n"
     end
     noop
  L: $I2 = 4
     $I3 = 5
     ret
  .end
  CODE
  23
  OUT
  
  ##############################
  # this is considered a non local bsr
  #
  output_is(<<'CODE', <<'OUT', "recursive bsr with saveall");
  .sub _test
     $I0 = 5
     $I1 = $I0
     bsr fact
     print $I1
     print "\n"
     end
  fact:
     save $I0
     save $I1
     saveall
     restore $I1
     restore $I0
     if $I0 <= 1 goto fin
     dec $I0
     $I1 = $I1 * $I0
     bsr fact
  fin:
     save $I1
     restoreall
     restore $I1
     ret
  .end
  
  CODE
  120
  OUT
  
  
  
  
  


Reply via email to