pike.git / src / peep.c

version» Context lines:

pike.git/src/peep.c:7:   #include "docode.h"   #include "main.h"   #include "error.h"   #include "lex.h"   #include "pike_memory.h"   #include "peep.h"   #include "dmalloc.h"   #include "stuff.h"   #include "bignum.h"    - RCSID("$Id: peep.c,v 1.29 2000/04/18 17:23:35 hubbe Exp $"); + RCSID("$Id: peep.c,v 1.30 2000/04/20 02:41:45 hubbe Exp $");      struct p_instr_s   {    short opcode;    short line;    struct pike_string *file;    INT32 arg; -  +  INT32 arg2;   };      typedef struct p_instr_s p_instr;   static void asm_opt(void);      dynamic_buffer instrbuf;      static int hasarg(int opcode)   {    return instrs[opcode-F_OFFSET].flags & I_HASARG;   }    -  + static int hasarg2(int opcode) + { +  return instrs[opcode-F_OFFSET].flags & I_HASARG2; + } +  + #ifdef PIKE_DEBUG + static void dump_instr(p_instr *p) + { +  if(!p) return; +  fprintf(stderr,"%s",get_token_name(p->opcode)); +  if(hasarg(p->opcode)) +  { +  fprintf(stderr,"(%d",p->arg); +  if(hasarg2(p->opcode)) +  fprintf(stderr,",%d",p->arg2); +  fprintf(stderr,")"); +  } + } + #endif +  +  +    void init_bytecode(void)   {    low_reinit_buf(&instrbuf);   }      void exit_bytecode(void)   {    INT32 e,length;    p_instr *c;       c=(p_instr *)instrbuf.s.str;    length=instrbuf.s.len / sizeof(p_instr);       for(e=0;e<length;e++) free_string(c->file);       toss_buffer(&instrbuf);   }    - int insert_opcode(unsigned int f, + int insert_opcode2(unsigned int f,    INT32 b, -  +  INT32 c,    INT32 current_line,    struct pike_string *current_file)   {    p_instr *p;      #ifdef PIKE_DEBUG -  if(!hasarg(f) && b) -  fatal("hasarg(%d) is wrong!\n",f); +  if(!hasarg2(f) && c) +  fatal("hasarg2(%d) is wrong!\n",f);   #endif       p=(p_instr *)low_make_buf_space(sizeof(p_instr), &instrbuf);         #ifdef PIKE_DEBUG    if(!instrbuf.s.len)    fatal("Low make buf space failed!!!!!!\n");   #endif       p->opcode=f;    p->line=current_line;    copy_shared_string(p->file, current_file);    p->arg=b; -  +  p->arg2=c;       return p - (p_instr *)instrbuf.s.str;   }    - int insert_opcode2(int f,int current_line, struct pike_string *current_file) + int insert_opcode1(unsigned int f, +  INT32 b, +  INT32 current_line, +  struct pike_string *current_file)   {   #ifdef PIKE_DEBUG -  +  if(!hasarg(f) && b) +  fatal("hasarg(%d) is wrong!\n",f); + #endif +  +  return insert_opcode2(f,b,0,current_line,current_file); + } +  + int insert_opcode0(int f,int current_line, struct pike_string *current_file) + { + #ifdef PIKE_DEBUG    if(hasarg(f))    fatal("hasarg(%d) is wrong!\n",f);   #endif -  return insert_opcode(f,0,current_line, current_file); +  return insert_opcode1(f,0,current_line, current_file);   }         void update_arg(int instr,INT32 arg)   {    p_instr *p;   #ifdef PIKE_DEBUG    if(instr > (long)instrbuf.s.len / (long)sizeof(p_instr) || instr < 0)    fatal("update_arg outside known space.\n");   #endif
pike.git/src/peep.c:141:    ins_f_byte(F_PREFIX_24BITX256);    add_to_program(b>>24);    add_to_program(b>>16);    add_to_program(b>>8);    }    }    ins_f_byte(a);    add_to_program(b);   }    + static void ins_f_byte_with_2_args(unsigned int a, +  unsigned INT32 c, +  unsigned INT32 b) + { +  +  switch(b >> 8) +  { +  case 0 : break; +  case 1 : ins_f_byte(F_PREFIX2_256); break; +  case 2 : ins_f_byte(F_PREFIX2_512); break; +  case 3 : ins_f_byte(F_PREFIX2_768); break; +  case 4 : ins_f_byte(F_PREFIX2_1024); break; +  default: +  if( b < 256*256) +  { +  ins_f_byte(F_PREFIX2_CHARX256); +  add_to_program(b>>8); +  }else if(b < 256*256*256) { +  ins_f_byte(F_PREFIX2_WORDX256); +  add_to_program(b>>16); +  add_to_program(b>>8); +  }else{ +  ins_f_byte(F_PREFIX2_24BITX256); +  add_to_program(b>>24); +  add_to_program(b>>16); +  add_to_program(b>>8); +  } +  } +  ins_f_byte_with_arg(a,c); +  add_to_program(b); + } +    void assemble(void)   {    INT32 e,d,length,max_label,tmp;    INT32 *labels, *jumps, *uses;    p_instr *c;       c=(p_instr *)instrbuf.s.str;    length=instrbuf.s.len / sizeof(p_instr);       max_label=-1;
pike.git/src/peep.c:232:    length=instrbuf.s.len / sizeof(p_instr);       for(e=0;e<=max_label;e++) labels[e]=jumps[e]=-1;       c=(p_instr *)instrbuf.s.str;    for(e=0;e<length;e++)    {   #ifdef PIKE_DEBUG    if((a_flag > 2 && store_linenumbers) || a_flag > 3)    { -  if(hasarg(c->opcode)) -  fprintf(stderr,"===%3d %4x %s(%d)\n",c->line,PC,get_token_name(c->opcode),c->arg); -  else -  fprintf(stderr,"===%3d %4x %s\n",c->line,PC,get_token_name(c->opcode)); +  fprintf(stderr,"===%3d %4x ",c->line,PC); +  dump_instr(c); +  fprintf(stderr,"\n");    }   #endif       if(store_linenumbers)    store_linenumber(c->line, c->file);       switch(c->opcode)    {    case F_NOP: break;    case F_ALIGN:    while(PC % c->arg) add_to_program(0);    break;    -  case F_BYTE: -  add_to_program(c->arg); -  break; -  +     case F_DATA:    ins_int(c->arg, (void(*)(char))add_to_program);    break;       case F_LABEL:   #ifdef PIKE_DEBUG    if(c->arg > max_label || c->arg < 0)    fatal("max_label calculation failed!\n");       if(labels[c->arg] != -1)
pike.git/src/peep.c:283: Inside #if defined(PIKE_DEBUG)
   case I_ISPOINTER:   #ifdef PIKE_DEBUG    if(c->arg > max_label || c->arg < 0) fatal("Jump to unknown label?\n");   #endif    tmp=PC;    ins_int(jumps[c->arg], (void(*)(char))add_to_program);    jumps[c->arg]=tmp;    break;       case I_TWO_ARGS: -  /* */ +  ins_f_byte_with_2_args(c->opcode, c->arg,c->arg2); +  break; +     case I_HASARG:    ins_f_byte_with_arg(c->opcode, c->arg);    break;       case 0:    ins_f_byte(c->opcode);    break;      #ifdef PIKE_DEBUG    default:
pike.git/src/peep.c:310:    }       for(e=0;e<=max_label;e++)    {    int tmp2=labels[e];       while(jumps[e]!=-1)    {   #ifdef PIKE_DEBUG    if(labels[e]==-1) -  fatal("Hyperspace error: unknown jump point.\n"); +  fatal("Hyperspace error: unknown jump point %d at %d (%d).\n",e,labels[e],jumps[e]);   #endif    tmp=read_int(jumps[e]);    upd_int(jumps[e], tmp2 - jumps[e]);    jumps[e]=tmp;    }    }       free((char *)labels);    free((char *)jumps);    free((char *)uses);
pike.git/src/peep.c:332:       exit_bytecode();   }      /**** Peephole optimizer ****/      int remove_clear_locals=0x7fffffff;   static int fifo_len, eye,len;   static p_instr *instructions;    - int insopt(int f, INT32 b, int cl, struct pike_string *cf) + int insopt2(int f, INT32 a, INT32 b, int cl, struct pike_string *cf)   {    p_instr *p;      #ifdef PIKE_DEBUG -  if(!hasarg(f) && b) +  if(!hasarg2(f) && b)    fatal("hasarg(%d) is wrong!\n",f);   #endif       p=(p_instr *)low_make_buf_space(sizeof(p_instr), &instrbuf);       if(fifo_len)    {    MEMMOVE(p-fifo_len+1,p-fifo_len,fifo_len*sizeof(p_instr));    p-=fifo_len;    }      #ifdef PIKE_DEBUG    if(!instrbuf.s.len)    fatal("Low make buf space failed!!!!!!\n");   #endif       p->opcode=f;    p->line=cl;    copy_shared_string(p->file, lex.current_file); -  p->arg=b; +  p->arg=a; +  p->arg2=b;       return p - (p_instr *)instrbuf.s.str;   }    - int insopt2(int f, int cl, struct pike_string *cf) + int insopt1(int f, INT32 a, int cl, struct pike_string *cf)   {   #ifdef PIKE_DEBUG -  +  if(!hasarg(f) && a) +  fatal("hasarg(%d) is wrong!\n",f); + #endif +  +  return insopt2(f,a,0,cl, cf); + } +  + int insopt0(int f, int cl, struct pike_string *cf) + { + #ifdef PIKE_DEBUG    if(hasarg(f))    fatal("hasarg(%d) is wrong!\n",f);   #endif -  return insopt(f,0,cl, cf); +  return insopt2(f,0,0,cl, cf);   }      static void debug(void)   {    if(fifo_len > (long)instrbuf.s.len / (long)sizeof(p_instr))    fifo_len=(long)instrbuf.s.len / (long)sizeof(p_instr);   #ifdef PIKE_DEBUG    if(eye < 0)    fatal("Popped beyond start of code.\n");   
pike.git/src/peep.c:427:   }      static INLINE int argument(int offset)   {    p_instr *a;    a=instr(offset);    if(a) return a->arg;    return -1;   }    + static INLINE int argument2(int offset) + { +  p_instr *a; +  a=instr(offset); +  if(a) return a->arg2; +  return -1; + } +    static void advance(void)   {    if(fifo_len)    {    fifo_len--;    }else{    p_instr *p;    if((p=instr(0))) -  insert_opcode(p->opcode, p->arg, p->line, p->file); +  insert_opcode2(p->opcode, p->arg, p->arg2, p->line, p->file);    eye++;    }    debug();   }      static void pop_n_opcodes(int n)   {    int e,d;    if(fifo_len)    {
pike.git/src/peep.c:466:    p-=fifo_len;    for(e=0;e<d;e++) free_string(p[e].file);    fifo_len-=d;    if(fifo_len) MEMMOVE(p,p+d,fifo_len*sizeof(p_instr));    n-=d;    low_make_buf_space(-((INT32)sizeof(p_instr))*d, &instrbuf);    }    eye+=n;   }    +    static void do_optimization(int topop, ...)   {    va_list arglist;    struct pike_string *cf;    int q=-1;    INT32 cl=instr(0)->line; -  +  + #ifdef PIKE_DEBUG +  if(a_flag>5) +  { +  int e; +  fprintf(stderr,"PEEP at %d:",cl); +  for(e=0;e<topop;e++) +  { +  fprintf(stderr," "); +  dump_instr(instr(e)); +  } +  fprintf(stderr," => "); +  } + #endif +     copy_shared_string(cf,instr(0)->file);    pop_n_opcodes(topop);    va_start(arglist, topop);       while(1)    {    q++;    switch(va_arg(arglist, int))    {    case 0:    break;    case 1:    {    int i=va_arg(arglist, int); -  insopt2(i,cl,cf); +  insopt0(i,cl,cf);    continue;    }    case 2:    {    int i=va_arg(arglist, int);    int j=va_arg(arglist, int); -  insopt(i,j,cl,cf); +  insopt1(i,j,cl,cf);    continue;    } -  +  case 3: +  { +  int i=va_arg(arglist, int); +  int j=va_arg(arglist, int); +  int k=va_arg(arglist, int); +  insopt2(i,j,k,cl,cf); +  continue;    } -  +  }    break;    }       va_end(arglist);    fifo_len+=q;    free_string(cf);    debug(); -  +  + #ifdef PIKE_DEBUG +  if(a_flag>5) +  { +  int e; +  for(e=0;e<q;e++) +  { +  fprintf(stderr," "); +  dump_instr(instr(e)); +  } +  fprintf(stderr,"\n"); +  } + #endif +     fifo_len+=q + 3;   }         static void asm_opt(void)   {   #ifdef PIKE_DEBUG    if(a_flag > 3)    {    p_instr *c;    INT32 e,length;    c=(p_instr *)instrbuf.s.str;    length=instrbuf.s.len / sizeof(p_instr);       fprintf(stderr,"Optimization begins: \n");    for(e=0;e<length;e++,c++)    { -  if(hasarg(c->opcode)) -  fprintf(stderr,"---%3d: %s(%d)\n",c->line,get_token_name(c->opcode),c->arg); -  else -  fprintf(stderr,"---%3d: %s\n",c->line,get_token_name(c->opcode)); +  fprintf(stderr,"---%3d: ",c->line); +  dump_instr(c); +  fprintf(stderr,"\n");    }    }   #endif      #ifndef IN_TPIKE   #include "peep_engine.c"   #endif /* IN_TPIKE */      #ifdef PIKE_DEBUG    if(a_flag > 4)    {    p_instr *c;    INT32 e,length;    c=(p_instr *)instrbuf.s.str;    length=instrbuf.s.len / sizeof(p_instr);       fprintf(stderr,"Optimization begins: \n");    for(e=0;e<length;e++,c++)    { -  if(hasarg(c->opcode)) -  fprintf(stderr,">>>%3d: %s(%d)\n",c->line,get_token_name(c->opcode),c->arg); -  else -  fprintf(stderr,">>>%3d: %s\n",c->line,get_token_name(c->opcode)); +  fprintf(stderr,">>>%3d: ",c->line); +  dump_instr(c); +  fprintf(stderr,"\n");    }    }   #endif   }