pike.git / src / peep.c

version» Context lines:

pike.git/src/peep.c:1:   /*   || This file is part of Pike. For copyright information see COPYRIGHT.   || Pike is distributed under GPL, LGPL and MPL. See the file COPYING   || for more information. - || $Id: peep.c,v 1.110 2006/09/16 16:50:08 grubba Exp $ + || $Id: peep.c,v 1.111 2006/09/17 15:53:31 grubba Exp $   */      #include "global.h"   #include "stralloc.h"   #include "dynamic_buffer.h"   #include "program.h"   #include "las.h"   #include "docode.h"   #include "pike_embed.h"   #include "pike_error.h"
pike.git/src/peep.c:50:   }   #endif         static int asm_opt(void);      /* Output buffer. The optimization eye is at the end of the buffer. */   dynamic_buffer instrbuf;   long num_instrs = 0;    - /* Stack holding pending instructions. -  * Note that instructions must be pushed in reverse order. -  * -  * FIXME: Consider making the stack fixed size. -  * /grubba 2006-09-16 -  */ - dynamic_buffer instrstack; - long stack_depth = 0; +     -  +    void init_bytecode(void)   {    initialize_buf(&instrbuf);    num_instrs = 0;   }      void exit_bytecode(void)   {    ptrdiff_t e, length;    p_instr *c;
pike.git/src/peep.c:327: Inside #if undefined(INS_ENTRY)
   /* Replace F_ENTRY with F_NOP if we have no entry prologue. */    for (c = (p_instr *) instrbuf.s.str, e = 0; e < length; e++, c++)    if (c->opcode == F_ENTRY) c->opcode = F_NOP;   #endif       labels=(INT32 *)xalloc(sizeof(INT32) * 4 * (max_label+2));    jumps = labels + max_label + 2;    uses = jumps + max_label + 2;    aliases = uses + max_label + 2;    -  initialize_buf(&instrstack); -  stack_depth = 0; -  +     while(relabel)    {    /* First do the relabel pass. */    for(e=0;e<=max_label;e++)    {    labels[e]=jumps[e]= aliases[e] = -1;    uses[e]=0;    }       c=(p_instr *)instrbuf.s.str;
pike.git/src/peep.c:464: Inside #if 1 and #if defined(PIKE_DEBUG)
  #if 1   #ifdef PIKE_DEBUG    if (a_flag > 3)    fprintf(stderr, "Rerunning optimizer.\n");   #endif   #else /* !1 */    relabel = 0;   #endif /* 1 */    }    - #ifdef PIKE_DEBUG -  if (instrstack.s.len) { -  Pike_fatal("PEEP: %d left over instructions on stack.\n", -  instrstack.s.len / sizeof(p_instr)); -  } - #endif -  toss_buffer(&instrstack); -  stack_depth = 0; -  +     /* Time to create the actual bytecode. */       c=(p_instr *)instrbuf.s.str;    length=instrbuf.s.len / sizeof(p_instr);       for(e=0;e<=max_label;e++) labels[e]=jumps[e]=-1;      #ifdef ALIGN_PIKE_FUNCTION_BEGINNINGS    while( ( (((INT32) PIKE_PC)+2) & (ALIGN_PIKE_JUMPS-1)))    ins_byte(0);
pike.git/src/peep.c:796:    }   #endif /* PIKE_DEBUG */       exit_bytecode();       return entry_point;   }      /**** Peephole optimizer ****/    - static void do_optimization(int topop, ...); + static void do_optimization(int topop, int topush, ...);   static INLINE int opcode(int offset);   static INLINE int argument(int offset);   static INLINE int argument2(int offset);      #include "peep_engine.c"    -  + #ifndef PEEP_STACK_SIZE + #define PEEP_STACK_SIZE 256 + #endif +  + /* Stack holding pending instructions. +  * Note that instructions must be pushed in reverse order. +  */ + static long stack_depth = 0; + static p_instr instrstack[PEEP_STACK_SIZE]; +    int remove_clear_locals=0x7fffffff;   static ptrdiff_t eye, len;   static p_instr *instructions;      /* insopt{0,1,2} push an instruction on instrstack. */      static INLINE p_instr *insopt2(int f, INT32 a, INT32 b,    int cl, struct pike_string *cf)   {    p_instr *p;      #ifdef PIKE_DEBUG    if(!hasarg2(f) && b)    Pike_fatal("hasarg2(%d /*%s */) is wrong!\n",f,get_f_name(f));   #endif    -  p=(p_instr *)low_make_buf_space(sizeof(p_instr), &instrstack); +  p = instrstack + stack_depth++;      #ifdef PIKE_DEBUG -  if(!instrstack.s.len) -  Pike_fatal("Low make buf space failed!!!!!!\n"); +  if(stack_depth > PEEP_STACK_SIZE) +  Pike_fatal("Instructions stacked too high!!!!!!\n");   #endif       p->opcode=f;    p->line=cl;    copy_shared_string(p->file, dmalloc_touch_named(struct pike_string *,    cf, "insopt2"));    p->arg=a;    p->arg2=b;    -  stack_depth++; -  +     return p;   }      static INLINE p_instr *insopt1(int f, INT32 a, int cl, struct pike_string *cf)   {   #ifdef PIKE_DEBUG    if(!hasarg(f) && a)    Pike_fatal("hasarg(%d /* %s */) is wrong!\n",f,get_f_name(f));   #endif   
pike.git/src/peep.c:860: Inside #if defined(PIKE_DEBUG)
  #ifdef PIKE_DEBUG    if(hasarg(f))    Pike_fatal("hasarg(%d /* %s */) is wrong!\n",f,get_f_name(f));   #endif    return insopt2(f,0,0,cl, cf);   }      #ifdef PIKE_DEBUG   static void debug(void)   { -  if(stack_depth != (long)instrstack.s.len / (long)sizeof(p_instr)) { -  Pike_fatal("PEEP: instrstack out of whack (%d != %d)\n", -  stack_depth, (long)instrstack.s.len / (long)sizeof(p_instr)); -  } +     if (num_instrs != (long)instrbuf.s.len / (long)sizeof(p_instr)) {    Pike_fatal("PEEP: instrbuf lost count (%d != %d)\n",    num_instrs, (long)instrbuf.s.len / (long)sizeof(p_instr));    }    if(instrbuf.s.len)    {    p_instr *p;    p=(p_instr *)low_make_buf_space(0, &instrbuf);    if(!p[-1].file)    Pike_fatal("No file name on last instruction!\n");
pike.git/src/peep.c:917:    a=instr(offset);    if(a) return a->arg2;    return -1;   }      static int advance(void)   {    p_instr *p;    if(stack_depth)    { -  p = ((p_instr *)low_make_buf_space(0, &instrstack)) - 1; -  stack_depth--; -  instrstack.s.len -= sizeof(p_instr); +  p = instrstack + --stack_depth;    }else{    if (eye >= len) return 0;    p = instructions + eye;    eye++;    }    insert_opcode(p); -  dmalloc_touch_named(struct pike_string *, p->file, "advance"); +  debug_malloc_touch_named(p->file, "advance");    debug();    return 1;   }      static void pop_n_opcodes(int n)   {    int e;      #ifdef PIKE_DEBUG    if (n > num_instrs)
pike.git/src/peep.c:951:    for (e = 0; e < n; e++) {    free_string(dmalloc_touch_named(struct pike_string *, p[e].file,    "pop_n_opcodes"));    }    num_instrs -= n;    low_make_buf_space(-((INT32)sizeof(p_instr))*n, &instrbuf);   }         /* NOTE: Called with opcodes in reverse order! */ - static void do_optimization(int topop, ...) + static void do_optimization(int topop, int topush, ...)   {    va_list arglist;    int q=0;    int oplen;    struct pike_string *cf;    INT32 cl=instr(0)->line;      #ifdef PIKE_DEBUG    if(a_flag>5)    {
pike.git/src/peep.c:973: Inside #if defined(PIKE_DEBUG)
   fprintf(stderr,"PEEP at %d:",cl);    for(e = topop; e--;)    {    fprintf(stderr," ");    dump_instr(instr(e));    }    fprintf(stderr," => ");    }   #endif    +  if (stack_depth + topush > PEEP_STACK_SIZE) { +  /* No place left on stack. Ignore the optimization. */ + #ifdef PIKE_DEBUG +  if (a_flag) { +  fprintf(stderr, "PEEP stack full.\n"); +  } + #endif +  return; +  } +     copy_shared_string(cf,dmalloc_touch_named(struct pike_string *,    instr(0)->file,    "do_optimization"));    pop_n_opcodes(topop);    -  va_start(arglist, topop); +  va_start(arglist, topush);       while((oplen = va_arg(arglist, int)))    {    q++;    switch(oplen)    {   #ifdef PIKE_DEBUG    default:    Pike_fatal("Unsupported argument number: %d\n", oplen);    break;
pike.git/src/peep.c:1027:    va_end(arglist);       /*fifo_len+=q;*/    free_string(dmalloc_touch_named(struct pike_string *, cf,    "do_optimization"));    debug();      #ifdef PIKE_DEBUG    if(a_flag>5)    { -  p_instr *p = (p_instr *)low_make_buf_space(0, &instrstack); +  p_instr *p = instrstack + stack_depth;    int e;    for(e=0;e<q;e++)    {    fprintf(stderr," ");    dump_instr(p-(e+1));    }    fprintf(stderr,"\n");    } -  +  if (q != topush) { +  Pike_fatal("PEEP: Lost track of instructions to push (%d != %d)\n", +  q, topush); +  }   #endif       /* Note: The 5 below is the longest    * match prefix in the ruleset    */    /*fifo_len += q + 5;*/   }      static int asm_opt(void)   {