cvsuser     03/11/15 20:31:40

  Modified:    imcc     imc.h imc.c cfg.c parser_util.c pcc.c reg_alloc.c
                        unit.h
  Log:
  More IMCC rearchitecture.
  * .sub directive now deprecates .pcc_sub directive.
    .sub now uses PCC convention by default.
  * All other .pcc directives are still used but will
    be eventually deprecated.
  * Modularize calling conventions and add generic API.
    sub.c is the generic API and wraps pcc.c and fastcall.c
  * Add stubs for a 2nd FASTCALL convention which can be enabled by
    compiler pragma.  Currently fastcall does not work.
  * Add .pragma directive to the lexer.
  * Add check for 0 arguments in PCC subs to skip code generate for proto/nonproto
    argument checking if there are no args. (Leo check this if it is the right
    thing to do?)
  * Various comments and optional tracing added to existing code.
  
  Revision  Changes    Path
  1.56      +32 -2     parrot/imcc/imc.h
  
  Index: imc.h
  ===================================================================
  RCS file: /cvs/public/parrot/imcc/imc.h,v
  retrieving revision 1.55
  retrieving revision 1.56
  diff -u -w -r1.55 -r1.56
  --- imc.h     13 Nov 2003 07:03:23 -0000      1.55
  +++ imc.h     16 Nov 2003 04:31:39 -0000      1.56
  @@ -59,6 +59,7 @@
   void imc_close_unit(struct Parrot_Interp *, IMC_Unit *);
   void imc_free_unit(struct Parrot_Interp *, IMC_Unit *);
   void imc_cleanup(struct Parrot_Interp *);
  +void imc_pragma(char * str);
   
   /*
    * instructions.c
  @@ -88,21 +89,50 @@
   int imcc_vfprintf(FILE *fd, const char *format, va_list ap);
   int imcc_fprintf(FILE *fd, const char *fmt, ...);
   
  +
  +/* Call convention independant API */
  +
  +/*
  + * sub.c
  + */
  +void expand_sub(Parrot_Interp interpreter, IMC_Unit *, Instruction *ins);
  +void expand_sub_ret(Parrot_Interp interpreter, IMC_Unit *, Instruction *ins);
  +void expand_sub_call(Parrot_Interp interpreter, IMC_Unit *, Instruction *ins);
  +void sub_optimize(Parrot_Interp interpreter, IMC_Unit *);
  +
  +/* Call convention specific implementations (currently 2, FASTSUB and PCCSUB)*/
  +
   /* 
    * pcc.c
    */
   void expand_pcc_sub(Parrot_Interp interpreter, IMC_Unit *, Instruction *ins);
  -void expand_pcc_sub_call(Parrot_Interp interpreter, IMC_Unit *, Instruction *ins);
   void expand_pcc_sub_ret(Parrot_Interp interpreter, IMC_Unit *, Instruction *ins);
  -void pcc_optimize(Parrot_Interp interpreter, IMC_Unit *);
  +void expand_pcc_sub_call(Parrot_Interp interpreter, IMC_Unit *, Instruction *ins);
  +void pcc_sub_optimize(Parrot_Interp interpreter, IMC_Unit *);
   
   int pcc_sub_reads(Instruction* ins, SymReg* r);
   int pcc_sub_writes(Instruction* ins, SymReg* r);
   
  +/*
  + * fastcall.c
  + */    
  +void expand_fast_sub(Parrot_Interp interpreter, IMC_Unit *, Instruction *ins);
  +void expand_fast_sub_ret(Parrot_Interp interpreter, IMC_Unit *, Instruction *ins);
  +void expand_fast_sub_call(Parrot_Interp interpreter, IMC_Unit *, Instruction *ins);
  +void fast_sub_optimize(Parrot_Interp interpreter, IMC_Unit *);
  +    
  +
   
   /* globals */
   
  +/* Compiler pragma options that may affect the whole module being compiled */
  +struct _imc_pragmas {
  +  int fastcall;          /* Use low level branch op, pass/return on stack 
  +                          * as opposed to pcc convention and invoke */
  +                         /* more to come */
  +};
   
  +EXTERN struct _imc_pragmas pragmas;
   
   EXTERN char * sourcefile;    /* current file */
   EXTERN char * function;      /* current function */
  
  
  
  1.64      +13 -0     parrot/imcc/imc.c
  
  Index: imc.c
  ===================================================================
  RCS file: /cvs/public/parrot/imcc/imc.c,v
  retrieving revision 1.63
  retrieving revision 1.64
  diff -u -w -r1.63 -r1.64
  --- imc.c     13 Nov 2003 07:05:00 -0000      1.63
  +++ imc.c     16 Nov 2003 04:31:40 -0000      1.64
  @@ -199,6 +199,19 @@
       free(unit);
   }
   
  +/*
  + * Set a global compiler option. No fancy parsing needed.
  + */
  +void
  +imc_pragma(char * str)
  +{
  +#if IMC_TRACE
  +    fprintf(stderr, "imc_pragma %s\n", str);
  +#endif
  +    if(!strcmp(str, "fastcall")) pragmas.fastcall = 1;
  +    else return;
  +    /* More options here */
  +}
   
   
   /*
  
  
  
  1.53      +6 -4      parrot/imcc/cfg.c
  
  Index: cfg.c
  ===================================================================
  RCS file: /cvs/public/parrot/imcc/cfg.c,v
  retrieving revision 1.52
  retrieving revision 1.53
  diff -u -w -r1.52 -r1.53
  --- cfg.c     13 Nov 2003 07:05:00 -0000      1.52
  +++ cfg.c     16 Nov 2003 04:31:40 -0000      1.53
  @@ -75,11 +75,12 @@
           }
       }
   
  +    /* XXX FIXME: Now the way to check for a sub is unit->type */
       ins = unit->instructions;
       if (first && ins->type == ITLABEL && ins->r[1]) {
           debug(interpreter, DEBUG_CFG, "pcc_sub %s nparams %d\n",
                   ins->r[0]->name, ins->r[1]->pcc_sub->nargs);
  -        expand_pcc_sub(interpreter, unit, ins);
  +        expand_sub(interpreter, unit, ins);
       }
       ins->index = i = 0;
   
  @@ -114,13 +115,14 @@
           }
           if (ins->opnum == -1 && (ins->type & ITPCCSUB)) {
               if (first) {
  +                /* XXX FIXME: Now the way to check for a sub is unit->type */
                   if (ins->type & ITLABEL) {
  -                    expand_pcc_sub_ret(interpreter, unit, ins);
  +                    expand_sub_ret(interpreter, unit, ins);
                       ins->type &= ~ITLABEL;
                   }
                   else {
  -                    /* if this is a pcc_sub_call expand it */
  -                    expand_pcc_sub_call(interpreter, unit, ins);
  +                    /* if this is a sub call expand it */
  +                    expand_sub_call(interpreter, unit, ins);
                   }
                   ins->type &= ~ITPCCSUB;
               }
  
  
  
  1.48      +6 -1      parrot/imcc/parser_util.c
  
  Index: parser_util.c
  ===================================================================
  RCS file: /cvs/public/parrot/imcc/parser_util.c,v
  retrieving revision 1.47
  retrieving revision 1.48
  diff -u -w -r1.47 -r1.48
  --- parser_util.c     13 Nov 2003 07:05:00 -0000      1.47
  +++ parser_util.c     16 Nov 2003 04:31:40 -0000      1.48
  @@ -199,6 +199,9 @@
       return k;
   }
   
  +/*
  + * Return opcode value for op name
  + */
   int
   check_op(struct Parrot_Interp *interpreter, char *fullname,
           char *name, SymReg *r[], int narg, int keyvec)
  @@ -208,9 +211,11 @@
       op_fullname(fullname, name, r, narg, keyvec);
       op = interpreter->op_lib->op_code(fullname, 1);
       return op;
  -
   }
   
  +/*
  + * Is instruction a parrot opcode?
  + */
   int
   is_op(struct Parrot_Interp *interpreter, char *name)
   {
  
  
  
  1.32      +82 -10    parrot/imcc/pcc.c
  
  Index: pcc.c
  ===================================================================
  RCS file: /cvs/public/parrot/imcc/pcc.c,v
  retrieving revision 1.31
  retrieving revision 1.32
  diff -u -w -r1.31 -r1.32
  --- pcc.c     4 Nov 2003 07:47:27 -0000       1.31
  +++ pcc.c     16 Nov 2003 04:31:40 -0000      1.32
  @@ -1,16 +1,37 @@
  +/*
  + * pcc.c
  + *
  + * A specific call convention implementation. Called by the generic
  + * API for subs (see sub.c).
  + *
  + * FASTCALL convention can be enabled with: 
  + * .pragma fastcall
  + * at the start of an IMC module.
  + *
  + * This will allow library developers (or non-Perl languages) to turn
  + * on very efficient optimizations and a lightweight calling convention. 
  + * It could also be used for internal libs that do not callout to PCC 
  + * routines, but present PCC entry points for the module itself.
  + *
  + * XXX FIXME: FASTCALL is not currently finished and may not be completely
  + * compatible with PCC convention. (ie. you can't mix and match, for now at least)
  + *
  + * see: docs/pdds/pdd03_calling_conventions.pod
  + *
  + * PCC Implementation by Leopold Toetsch
  + */
  +
   #include <stdlib.h>
   #include <string.h>
   #include <assert.h>
   #include "imc.h"
   #include "parser.h"
   
  +
   /*
  - * pcc.c - parrot calling conventions stuff
  - *
  - * s. docs/pdds/pdd03_calling_conventions.pod
  - *
  + * Utilty instruction routine. Creates and inserts an instruction
  + * into the current block in one call.
    */
  -
   static Instruction *
   insINS(struct Parrot_Interp *interpreter, IMC_Unit * unit, Instruction *ins,
           char *name, SymReg **regs, int n)
  @@ -183,6 +204,12 @@
       return ins;
   }
   
  +
  +/*
  + * Expand a PCC (Parrot Calling Convention) subroutine
  + * by generating the appropriate prologue and epilogue
  + * for parameter passing/returning.
  + */
   void
   expand_pcc_sub(Parrot_Interp interpreter, IMC_Unit * unit, Instruction *ins)
   {
  @@ -194,7 +221,18 @@
       SymReg *p3, *i0, *regs[IMCC_MAX_REGS], *label1, *label2;
       char buf[128];
   
  +#if IMC_TRACE
  +    PIO_eprintf("expand_pcc_sub\n");
  +#endif
  +
       sub = ins->r[1];
  +
  +    /* Don't generate any parameter checking code if there
  +     * are no named arguments.
  +     */
  +    if(sub->pcc_sub->nargs <= 0)
  +        goto NONAMEDPARAMS;
  +    
       p3 = i0 = NULL;
       label1 = label2 = NULL;
       ps = pe = sub->pcc_sub->prototyped;
  @@ -231,9 +269,9 @@
                                       ins, sub, i0, NULL, i == 0, 0);
                        /* assign register to that param
                            *
  -                         * if this subroutine calls another one,
  -                         * new registers are ssigned, so that
  -                         * they don't interfer with this subs params
  +                         * if this subroutine calls another subroutine
  +                         * new registers are assigned so that
  +                         * they don't interfer with this sub's params
                            */
                           if (sub->pcc_sub->calls_a_sub) {
                               regs[0] = arg;
  @@ -301,6 +339,8 @@
           }
       } /* proto */
   
  +NONAMEDPARAMS: /* If no named params, don't generate any param code */
  +
       /*
        * if we call out, the return cc in P1 must be saved
        */
  @@ -311,6 +351,10 @@
       }
   }
   
  +
  +/*
  + * Expand a PCC sub return directive into its PASM instructions
  + */
   void
   expand_pcc_sub_ret(Parrot_Interp interpreter, IMC_Unit * unit, Instruction *ins)
   {
  @@ -321,6 +365,10 @@
       char buf[128];
       int n_p3;
   
  +#if IMC_TRACE
  +    PIO_eprintf("expand_pcc_sub_ret\n");
  +#endif
  +
       arg_count = ins->type & ITPCCYIELD ? 0 : 1;
       for (i = 0; i < 4; i++)
           next[i] = 5;
  @@ -671,6 +719,11 @@
       return ins;
   }
   
  +
  +/*
  + * Expand a PCC subroutine call (IMC) into its PASM instructions
  + * This is the nuts and bolts of Perl6/Parrot routine call style
  + */
   void
   expand_pcc_sub_call(Parrot_Interp interpreter, IMC_Unit * unit, Instruction *ins)
   {
  @@ -685,6 +738,10 @@
       int tail_call;
       int flatten;
   
  +#if IMC_TRACE
  +    PIO_eprintf("expand_pcc_sub_call\n");
  +#endif
  +
       tail_call = check_tail_call(interpreter, unit, ins);
       if (tail_call)
           debug(interpreter, DEBUG_OPT1, "found tail call %I \n", ins);
  @@ -982,15 +1039,16 @@
               break;
       }
   }
  +
   /*
    * special peephole optimizer for code generated mainly by
    * above functions
    */
   void
  -pcc_optimize(Parrot_Interp interpreter, IMC_Unit * unit)
  +pcc_sub_optimize(Parrot_Interp interpreter, IMC_Unit * unit)
   {
       Instruction *ins, *tmp;
  -    info(interpreter, 2, "\tpcc_optimize\n");
  +    info(interpreter, 2, "\tpcc_sub_optimize\n");
       for (ins = unit->instructions; ins; ins = ins->next) {
           if (ins->opsize == 3 &&
                   ins->r[1]->type == VTCONST &&
  @@ -1033,6 +1091,10 @@
       }
   }
   
  +/*
  + * Check argument symbols of a sub and see which are used
  + * Return 0 if none are used, 1 if at least 1 symbol is used.
  + */
   static int
   pcc_args(Instruction* ins, SymReg* r)
   {
  @@ -1049,6 +1111,10 @@
       return 0;
   }
   
  +/*
  + * Check return symbols of a sub and see which are used
  + * Return 0 if none are used, 1 if at least 1 symbol is used.
  + */
   static int
   pcc_ret(Instruction* ins, SymReg* r)
   {
  @@ -1065,6 +1131,9 @@
       return 0;
   }
   
  +/*
  + * See if the sub writes to the symbol, checks args and returns
  + */
   int
   pcc_sub_writes(Instruction* ins, SymReg* r)
   {
  @@ -1073,6 +1142,9 @@
       return pcc_ret(ins, r) || pcc_args(ins, r);
   }
   
  +/*
  + * See if the sub reads the symbol, checks args and returns
  + */
   int
   pcc_sub_reads(Instruction* ins, SymReg* r)
   {
  
  
  
  1.4       +1 -1      parrot/imcc/reg_alloc.c
  
  Index: reg_alloc.c
  ===================================================================
  RCS file: /cvs/public/parrot/imcc/reg_alloc.c,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -w -r1.3 -r1.4
  --- reg_alloc.c       13 Nov 2003 07:05:00 -0000      1.3
  +++ reg_alloc.c       16 Nov 2003 04:31:40 -0000      1.4
  @@ -175,7 +175,7 @@
           }
       }
       if (optimizer_level & OPT_SUB)
  -        pcc_optimize(interpreter, unit);
  +        sub_optimize(interpreter, unit);
       if (IMCC_INFO(interpreter)->debug & DEBUG_IMC)
           dump_instructions(unit);
       if (IMCC_INFO(interpreter)->verbose  ||
  
  
  
  1.5       +3 -2      parrot/imcc/unit.h
  
  Index: unit.h
  ===================================================================
  RCS file: /cvs/public/parrot/imcc/unit.h,v
  retrieving revision 1.4
  retrieving revision 1.5
  diff -u -w -r1.4 -r1.5
  --- unit.h    13 Nov 2003 07:03:23 -0000      1.4
  +++ unit.h    16 Nov 2003 04:31:40 -0000      1.5
  @@ -11,8 +11,9 @@
   
   typedef enum {
       IMC_PASM = 0,
  -    IMC_SUB = 1,
  -    IMC_CLASS = 2
  +    IMC_PCCSUB = 1,
  +    IMC_FASTSUB = 2,
  +    IMC_CLASS = 3
   } IMC_Unit_Type;
   
   
  
  
  

Reply via email to