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.86 2003/10/10 01:18:25 mast Exp $ + || $Id: peep.c,v 1.87 2003/12/02 13:49:58 grubba Exp $   */      #include "global.h"   #include "language.h"   #include "stralloc.h"   #include "dynamic_buffer.h"   #include "program.h"   #include "las.h"   #include "docode.h"   #include "main.h"
pike.git/src/peep.c:19:   #include "peep.h"   #include "dmalloc.h"   #include "stuff.h"   #include "bignum.h"   #include "opcodes.h"   #include "builtin_functions.h"   #include "constants.h"   #include "interpret.h"   #include "pikecode.h"    - RCSID("$Id: peep.c,v 1.86 2003/10/10 01:18:25 mast Exp $"); + RCSID("$Id: peep.c,v 1.87 2003/12/02 13:49:58 grubba Exp $");      static void asm_opt(void);      dynamic_buffer instrbuf;    -  + #ifdef PIKE_DEBUG   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,")");
pike.git/src/peep.c:140:    p=(p_instr *)instrbuf.s.str;    p[instr].arg=arg;   }      #ifndef FLUSH_CODE_GENERATOR_STATE   #define FLUSH_CODE_GENERATOR_STATE()   #endif      /**** Bytecode Generator *****/    - void assemble(void) + INT32 assemble(int store_linenumbers)   { -  +  INT32 entry_point;    INT32 max_label=-1,tmp;    INT32 *labels, *jumps, *uses;    ptrdiff_t e, length;    p_instr *c;    int reoptimize=!(debug_options & NO_PEEP_OPTIMIZING); -  + #ifdef PIKE_PORTABLE_BYTECODE +  struct pike_string *tripples = NULL; + #endif /* PIKE_PORTABLE_BYTECODE */   #ifdef PIKE_DEBUG -  int max_pointer=-1; +  INT32 max_pointer=-1;    int synch_depth = 0;    size_t fun_start = Pike_compiler->new_program->num_program;   #endif       c=(p_instr *)instrbuf.s.str;    length=instrbuf.s.len / sizeof(p_instr);      #ifdef PIKE_DEBUG    if((a_flag > 1 && store_linenumbers) || a_flag > 2)    {
pike.git/src/peep.c:174: Inside #if defined(PIKE_DEBUG)
   fprintf(stderr,"\n");    if (c[e].opcode == F_SYNCH_MARK) synch_depth++;    }    if (synch_depth) {    Pike_fatal("Unbalanced sync_mark/pop_sync_mark: %d\n",    synch_depth);    }    }   #endif    + #ifdef PIKE_PORTABLE_BYTECODE +  /* No need to do this for constant evaluations. */ +  if (store_linenumbers) { +  p_wchar2 *current_tripple; +  struct pike_string *previous_file = NULL; +  int previous_line = 0; +  ptrdiff_t num_linedirectives = 0; +  +  /* Count the number of F_FILENAME/F_LINE pseudo-ops we need to add. */ +  for (e=0; e < length; e++) { +  if (c[e].file != previous_file) { +  previous_file = c[e].file; +  num_linedirectives++; +  } +  if (c[e].line != previous_line) { +  previous_line = c[e].line; +  num_linedirectives++; +  } +  } +  +  /* fprintf(stderr, "length:%d directives:%d\n", +  * length, num_linedirectives); +  */ +  +  if (!(tripples = begin_wide_shared_string(3*(length+num_linedirectives), +  2))) { +  Pike_fatal("Failed to allocate wide string of length %d 3*(%d + %d).\n", +  3*(length+num_linedirectives), length, num_linedirectives); +  } +  previous_file = NULL; +  previous_line = 0; +  current_tripple = STR2(tripples); +  for (e = 0; e < length; e++) { +  if (c[e].file != previous_file) { +  current_tripple[0] = F_FILENAME; +  current_tripple[1] = store_prog_string(c[e].file); +  current_tripple[2] = 0; +  current_tripple += 3; +  previous_file = c[e].file; +  } +  if (c[e].line != previous_line) { +  current_tripple[0] = F_LINE; +  current_tripple[1] = c[e].line; +  current_tripple[2] = 0; +  current_tripple += 3; +  previous_line = c[e].line; +  } +  current_tripple[0] = c[e].opcode; +  current_tripple[1] = c[e].arg; +  current_tripple[2] = c[e].arg2; +  current_tripple += 3; +  } + #ifdef PIKE_DEBUG +  if (current_tripple != STR2(tripples) + 3*(length + num_linedirectives)) { +  Pike_fatal("Tripple length mismatch %d != %d 3*(%d + %d)\n", +  current_tripple - STR2(tripples), +  3*(length + num_linedirectives), +  length, num_linedirectives); +  } + #endif /* PIKE_DEBUG */ +  tripples = end_shared_string(tripples); +  } +  + #endif /* PIKE_PORTABLE_BYTECODE */ +     for(e=0;e<length;e++,c++) {    if(c->opcode == F_LABEL) {    if(c->arg > max_label)    max_label = c->arg;    }   #ifdef PIKE_DEBUG    else if (instrs[c->opcode - F_OFFSET].flags & I_POINTER) {    if (c->arg > max_pointer)    max_pointer = c->arg;    }
pike.git/src/peep.c:213: Inside #if defined(PIKE_DEBUG)
   fprintf(stderr, "\n");    }    if (c->opcode == F_SYNCH_MARK) synch_depth++;    }       Pike_fatal("Reference to undefined label %d > %d\n",    max_pointer, max_label);    }   #endif /* PIKE_DEBUG */    -  labels=(INT32 *)xalloc(sizeof(INT32) * (max_label+2)); -  jumps=(INT32 *)xalloc(sizeof(INT32) * (max_label+2)); -  uses=(INT32 *)xalloc(sizeof(INT32) * (max_label+2)); +  labels=(INT32 *)xalloc(sizeof(INT32) * 3 * (max_label+2)); +  jumps = labels + max_label + 2; +  uses = jumps + max_label + 2;       while(reoptimize)    {    reoptimize=0;    for(e=0;e<=max_label;e++)    {    labels[e]=jumps[e]=-1;    uses[e]=0;    }   
pike.git/src/peep.c:315: 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 */    reoptimize=0;   #endif /* 1 */    }    +  /* 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;    -  c=(p_instr *)instrbuf.s.str; + #ifdef ALIGN_PIKE_FUNCTION_BEGINNINGS +  while( ( (((INT32) PIKE_PC)+2) & (ALIGN_PIKE_JUMPS-1))) +  ins_byte(0); + #endif +  + #ifdef PIKE_PORTABLE_BYTECODE +  if (store_linenumbers) { +  ins_data(store_prog_string(tripples)); +  free_string(tripples); +  } else { +  ins_data(NULL); +  } + #endif /* PIKE_PORTABLE_BYTECODE */ +  +  entry_point = PIKE_PC; +    #ifdef PIKE_DEBUG    synch_depth = 0;   #endif    FLUSH_CODE_GENERATOR_STATE();    for(e=0;e<length;e++)    { -  int linenumbers_stored=0; +    #ifdef PIKE_DEBUG    if (c != (((p_instr *)instrbuf.s.str)+e)) {    Pike_fatal("Instruction loop deviates. 0x%04x != 0x%04x\n",    e, DO_NOT_WARN((INT32)(c - ((p_instr *)instrbuf.s.str))));    }    if((a_flag > 2 && store_linenumbers) || a_flag > 3)    {    if (c->opcode == F_POP_SYNCH_MARK) synch_depth--;    fprintf(stderr, "===%4d %4lx %*s", c->line,    DO_NOT_WARN((unsigned long)PIKE_PC), synch_depth, "");    dump_instr(c);    fprintf(stderr,"\n");    if (c->opcode == F_SYNCH_MARK) synch_depth++;    }   #endif    -  if(store_linenumbers) +  if(store_linenumbers) {    store_linenumber(c->line, c->file); -  + #ifdef PIKE_DEBUG +  if (c->opcode < F_MAX_OPCODE) +  ADD_COMPILED(c->opcode); + #endif /* PIKE_DEBUG */ +  }       switch(c->opcode)    {    case F_NOP:    case F_NOTREACHED:    case F_START_FUNCTION:    break;    case F_ALIGN:    ins_align(c->arg);    break;
pike.git/src/peep.c:411:    tmp = DO_NOT_WARN((INT32)PIKE_PC);    ins_pointer(jumps[c->arg]);    jumps[c->arg]=tmp;    break;       default:    switch(instrs[c->opcode - F_OFFSET].flags & I_IS_MASK)    {    case I_ISJUMP:   #ifdef INS_F_JUMP -  tmp=INS_F_JUMP(c->opcode); +  tmp=INS_F_JUMP(c->opcode, (labels[c->arg] != -1));    if(tmp != -1)    {    UPDATE_F_JUMP(tmp, jumps[c->arg]);    jumps[c->arg]=~tmp;    break;    }   #endif       ins_f_byte(c->opcode);   
pike.git/src/peep.c:433: Inside #if defined(PIKE_DEBUG)
   if(c->arg > max_label || c->arg < 0)    Pike_fatal("Jump to unknown label?\n");   #endif    tmp = DO_NOT_WARN((INT32)PIKE_PC);    ins_pointer(jumps[c->arg]);    jumps[c->arg]=tmp;    break;       case I_ISJUMPARGS:   #ifdef INS_F_JUMP_WITH_TWO_ARGS -  tmp = INS_F_JUMP_WITH_TWO_ARGS(c->opcode, c->arg, c->arg2); +  tmp = INS_F_JUMP_WITH_TWO_ARGS(c->opcode, c->arg, c->arg2, +  (labels[c[1].arg] != -1));    if(tmp != -1)    {   #ifdef ADJUST_PIKE_PC    if (instrs[c->opcode - F_OFFSET].flags & I_PC_AT_NEXT)    ADJUST_PIKE_PC (PIKE_PC);   #endif       /* Step ahead to the pointer instruction, and inline it. */   #ifdef PIKE_DEBUG    if (c[1].opcode != F_POINTER) {
pike.git/src/peep.c:468:    * Note that the pointer in this case will be handled by the    * next turn through the loop.    */       case I_TWO_ARGS:    ins_f_byte_with_2_args(c->opcode, c->arg, c->arg2);    break;       case I_ISJUMPARG:   #ifdef INS_F_JUMP_WITH_ARG -  tmp = INS_F_JUMP_WITH_ARG(c->opcode, c->arg); +  tmp = INS_F_JUMP_WITH_ARG(c->opcode, c->arg, (labels[c[1].arg] != -1));    if(tmp != -1)    {   #ifdef ADJUST_PIKE_PC    if (instrs[c->opcode - F_OFFSET].flags & I_PC_AT_NEXT)    ADJUST_PIKE_PC (PIKE_PC);   #endif       /* Step ahead to the pointer instruction, and inline it. */   #ifdef PIKE_DEBUG    if (c[1].opcode != F_POINTER) {
pike.git/src/peep.c:593:    }   #endif       tmp = read_pointer(jumps[e]);    upd_pointer(jumps[e], tmp2 - jumps[e]);    jumps[e]=tmp;    }    }       free((char *)labels); -  free((char *)jumps); -  free((char *)uses); +       #ifdef PIKE_DEBUG    if (a_flag > 6) {    size_t len = (Pike_compiler->new_program->num_program - fun_start)*    sizeof(PIKE_OPCODE_T);    fprintf(stderr, "Code at offset %d through %d:\n",    fun_start, Pike_compiler->new_program->num_program-1);   #ifdef DISASSEMBLE_CODE    DISASSEMBLE_CODE(Pike_compiler->new_program->program + fun_start, len);   #else /* !DISASSEMBLE_CODE */    {    /* FIXME: Hexdump here. */    }   #endif /* DISASSEMBLE_CODE */    }   #endif /* PIKE_DEBUG */       exit_bytecode(); -  +  +  return entry_point;   }      /**** Peephole optimizer ****/      int remove_clear_locals=0x7fffffff;   static int fifo_len;   static ptrdiff_t eye, len;   static p_instr *instructions;      static INLINE ptrdiff_t insopt2(int f, INT32 a, INT32 b,