Ejemplo n.º 1
0
int
print_rtl_single (FILE *outf, rtx x)
{
  outfile = outf;
  sawclose = 0;
  if (! flag_dump_unnumbered
      || !NOTE_P (x) || NOTE_LINE_NUMBER (x) < 0)
    {
      fputs (print_rtx_head, outfile);
      print_rtx (x);
      putc ('\n', outf);
      return 1;
    }
  return 0;
}
Ejemplo n.º 2
0
static void
record_effective_endpoints (void)
{
  rtx next_insn;
  basic_block bb;
  rtx insn;

  for (insn = get_insns ();
       insn
       && NOTE_P (insn)
       && NOTE_LINE_NUMBER (insn) != NOTE_INSN_BASIC_BLOCK;
       insn = NEXT_INSN (insn))
    continue;
  /* No basic blocks at all?  */
  gcc_assert (insn);

  if (PREV_INSN (insn))
    cfg_layout_function_header =
	    unlink_insn_chain (get_insns (), PREV_INSN (insn));
  else
    cfg_layout_function_header = NULL_RTX;

  next_insn = get_insns ();
  FOR_EACH_BB (bb)
    {
      rtx end;

      if (PREV_INSN (BB_HEAD (bb)) && next_insn != BB_HEAD (bb))
	bb->il.rtl->header = unlink_insn_chain (next_insn,
					      PREV_INSN (BB_HEAD (bb)));
      end = skip_insns_after_block (bb);
      if (NEXT_INSN (BB_END (bb)) && BB_END (bb) != end)
	bb->il.rtl->footer = unlink_insn_chain (NEXT_INSN (BB_END (bb)), end);
      next_insn = NEXT_INSN (BB_END (bb));
    }

  cfg_layout_function_footer = next_insn;
  if (cfg_layout_function_footer)
    cfg_layout_function_footer = unlink_insn_chain (cfg_layout_function_footer, get_last_insn ());
}
Ejemplo n.º 3
0
void
print_rtl (FILE *outf, rtx rtx_first)
{
  rtx tmp_rtx;

  outfile = outf;
  sawclose = 0;

  if (rtx_first == 0)
    {
      fputs (print_rtx_head, outf);
      fputs ("(nil)\n", outf);
    }
  else
    switch (GET_CODE (rtx_first))
      {
      case INSN:
      case JUMP_INSN:
      case CALL_INSN:
      case NOTE:
      case CODE_LABEL:
      case BARRIER:
        for (tmp_rtx = rtx_first; tmp_rtx != 0; tmp_rtx = NEXT_INSN (tmp_rtx))
          if (! flag_dump_unnumbered
              || !NOTE_P (tmp_rtx) || NOTE_LINE_NUMBER (tmp_rtx) < 0)
            {
              fputs (print_rtx_head, outfile);
              print_rtx (tmp_rtx);
              fprintf (outfile, "\n");
            }
        break;

      default:
        fputs (print_rtx_head, outfile);
        print_rtx (rtx_first);
      }
}
Ejemplo n.º 4
0
void
print_insn (char *buf, rtx x, int verbose)
{
  char t[BUF_LEN];
  rtx insn = x;

  switch (GET_CODE (x))
    {
    case INSN:
      print_pattern (t, PATTERN (x), verbose);
      if (verbose)
	sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1),
		 t);
      else
	sprintf (buf, "%-4d %s", INSN_UID (x), t);
      break;
    case JUMP_INSN:
      print_pattern (t, PATTERN (x), verbose);
      if (verbose)
	sprintf (buf, "%s: jump %s", (*current_sched_info->print_insn) (x, 1),
		 t);
      else
	sprintf (buf, "%-4d %s", INSN_UID (x), t);
      break;
    case CALL_INSN:
      x = PATTERN (insn);
      if (GET_CODE (x) == PARALLEL)
	{
	  x = XVECEXP (x, 0, 0);
	  print_pattern (t, x, verbose);
	}
      else
	strcpy (t, "call <...>");
      if (verbose)
	sprintf (buf, "%s: %s", (*current_sched_info->print_insn) (x, 1), t);
      else
	sprintf (buf, "%-4d %s", INSN_UID (insn), t);
      break;
    case CODE_LABEL:
      sprintf (buf, "L%d:", INSN_UID (x));
      break;
    case BARRIER:
      sprintf (buf, "i% 4d: barrier", INSN_UID (x));
      break;
    case NOTE:
      if (NOTE_LINE_NUMBER (x) > 0)
	{
	  expanded_location xloc;
	  NOTE_EXPANDED_LOCATION (xloc, x);
	  sprintf (buf, "%4d note \"%s\" %d", INSN_UID (x),
		   xloc.file, xloc.line);
	}
      else
	sprintf (buf, "%4d %s", INSN_UID (x),
		 GET_NOTE_INSN_NAME (NOTE_LINE_NUMBER (x)));
      break;
    default:
      if (verbose)
	{
	  sprintf (buf, "Not an INSN at all\n");
	  debug_rtx (x);
	}
      else
	sprintf (buf, "i%-4d  <What?>", INSN_UID (x));
    }
}				/* print_insn */
Ejemplo n.º 5
0
static void
print_rtx (rtx in_rtx)
{
  int i = 0;
  int j;
  const char *format_ptr;
  int is_insn;

  if (sawclose)
    {
      if (flag_simple)
        fputc (' ', outfile);
      else
        fprintf (outfile, "\n%s%*s", print_rtx_head, indent * 2, "");
      sawclose = 0;
    }

  if (in_rtx == 0)
    {
      fputs ("(nil)", outfile);
      sawclose = 1;
      return;
    }
  else if (GET_CODE (in_rtx) > NUM_RTX_CODE)
    {
       fprintf (outfile, "(??? bad code %d\n)", GET_CODE (in_rtx));
       sawclose = 1;
       return;
    }

  is_insn = INSN_P (in_rtx);

  /* When printing in VCG format we write INSNs, NOTE, LABEL, and BARRIER
     in separate nodes and therefore have to handle them special here.  */
  if (dump_for_graph
      && (is_insn || NOTE_P (in_rtx)
          || LABEL_P (in_rtx) || BARRIER_P (in_rtx)))
    {
      i = 3;
      indent = 0;
    }
  else
    {
      /* Print name of expression code.  */
      if (flag_simple && GET_CODE (in_rtx) == CONST_INT)
        fputc ('(', outfile);
      else
        fprintf (outfile, "(%s", GET_RTX_NAME (GET_CODE (in_rtx)));

      if (! flag_simple)
        {
          if (RTX_FLAG (in_rtx, in_struct))
            fputs ("/s", outfile);

          if (RTX_FLAG (in_rtx, volatil))
            fputs ("/v", outfile);

          if (RTX_FLAG (in_rtx, unchanging))
            fputs ("/u", outfile);

          if (RTX_FLAG (in_rtx, frame_related))
            fputs ("/f", outfile);

          if (RTX_FLAG (in_rtx, jump))
            fputs ("/j", outfile);

          if (RTX_FLAG (in_rtx, call))
            fputs ("/c", outfile);

          if (RTX_FLAG (in_rtx, return_val))
            fputs ("/i", outfile);

          /* Print REG_NOTE names for EXPR_LIST and INSN_LIST.  */
          if (GET_CODE (in_rtx) == EXPR_LIST
              || GET_CODE (in_rtx) == INSN_LIST)
            fprintf (outfile, ":%s",
                     GET_REG_NOTE_NAME (GET_MODE (in_rtx)));

          /* For other rtl, print the mode if it's not VOID.  */
          else if (GET_MODE (in_rtx) != VOIDmode)
            fprintf (outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx)));
        }
    }

#ifndef GENERATOR_FILE
  if (GET_CODE (in_rtx) == CONST_DOUBLE && FLOAT_MODE_P (GET_MODE (in_rtx)))
    i = 5;
#endif

  /* Get the format string and skip the first elements if we have handled
     them already.  */
  format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx)) + i;
  for (; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++)
    switch (*format_ptr++)
      {
        const char *str;

      case 'T':
        str = XTMPL (in_rtx, i);
        goto string;

      case 'S':
      case 's':
        str = XSTR (in_rtx, i);
      string:

        if (str == 0)
          fputs (dump_for_graph ? " \\\"\\\"" : " \"\"", outfile);
        else
          {
            if (dump_for_graph)
              fprintf (outfile, " (\\\"%s\\\")", str);
            else
              fprintf (outfile, " (\"%s\")", str);
          }
        sawclose = 1;
        break;

        /* 0 indicates a field for internal use that should not be printed.
           An exception is the third field of a NOTE, where it indicates
           that the field has several different valid contents.  */
      case '0':
        if (i == 1 && REG_P (in_rtx))
          {
            if (REGNO (in_rtx) != ORIGINAL_REGNO (in_rtx))
              fprintf (outfile, " [%d]", ORIGINAL_REGNO (in_rtx));
          }
#ifndef GENERATOR_FILE
        else if (i == 1 && GET_CODE (in_rtx) == SYMBOL_REF)
          {
            int flags = SYMBOL_REF_FLAGS (in_rtx);
            if (flags)
              fprintf (outfile, " [flags 0x%x]", flags);
          }
        else if (i == 2 && GET_CODE (in_rtx) == SYMBOL_REF)
          {
            tree decl = SYMBOL_REF_DECL (in_rtx);
            if (decl)
              print_node_brief (outfile, "", decl, 0);
          }
#endif
        else if (i == 4 && NOTE_P (in_rtx))
          {
            switch (NOTE_LINE_NUMBER (in_rtx))
              {
              case NOTE_INSN_EH_REGION_BEG:
              case NOTE_INSN_EH_REGION_END:
                if (flag_dump_unnumbered)
                  fprintf (outfile, " #");
                else
                  fprintf (outfile, " %d", NOTE_EH_HANDLER (in_rtx));
                sawclose = 1;
                break;

              case NOTE_INSN_BLOCK_BEG:
              case NOTE_INSN_BLOCK_END:
#ifndef GENERATOR_FILE
                dump_addr (outfile, " ", NOTE_BLOCK (in_rtx));
#endif
                sawclose = 1;
                break;

              case NOTE_INSN_BASIC_BLOCK:
                {
#ifndef GENERATOR_FILE
                  basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
                  if (bb != 0)
                    fprintf (outfile, " [bb %d]", bb->index);
#endif
                  break;
                }

              case NOTE_INSN_EXPECTED_VALUE:
                indent += 2;
                if (!sawclose)
                  fprintf (outfile, " ");
                print_rtx (NOTE_EXPECTED_VALUE (in_rtx));
                indent -= 2;
                break;

              case NOTE_INSN_DELETED_LABEL:
                {
                  const char *label = NOTE_DELETED_LABEL_NAME (in_rtx);
                  if (label)
                    fprintf (outfile, " (\"%s\")", label);
                  else
                    fprintf (outfile, " \"\"");
                }
                break;

              case NOTE_INSN_SWITCH_TEXT_SECTIONS:
                {
#ifndef GENERATOR_FILE
                  basic_block bb = NOTE_BASIC_BLOCK (in_rtx);
                  if (bb != 0)
                    fprintf (outfile, " [bb %d]", bb->index);
#endif
                  break;
                }
                
              case NOTE_INSN_VAR_LOCATION:
#ifndef GENERATOR_FILE
                fprintf (outfile, " (");
                print_mem_expr (outfile, NOTE_VAR_LOCATION_DECL (in_rtx));
                fprintf (outfile, " ");
                print_rtx (NOTE_VAR_LOCATION_LOC (in_rtx));
                fprintf (outfile, ")");
#endif
                break;

              default:
                {
                  const char * const str = X0STR (in_rtx, i);

                  if (NOTE_LINE_NUMBER (in_rtx) < 0)
                    ;
                  else if (str == 0)
                    fputs (dump_for_graph ? " \\\"\\\"" : " \"\"", outfile);
                  else
                    {
                      if (dump_for_graph)
                        fprintf (outfile, " (\\\"%s\\\")", str);
                      else
                        fprintf (outfile, " (\"%s\")", str);
                    }
                  break;
                }
              }
          }
        break;

      case 'e':
      do_e:
        indent += 2;
        if (!sawclose)
          fprintf (outfile, " ");
        print_rtx (XEXP (in_rtx, i));
        indent -= 2;
        break;

      case 'E':
      case 'V':
        indent += 2;
        if (sawclose)
          {
            fprintf (outfile, "\n%s%*s",
                     print_rtx_head, indent * 2, "");
            sawclose = 0;
          }
        fputs (" [", outfile);
        if (NULL != XVEC (in_rtx, i))
          {
            indent += 2;
            if (XVECLEN (in_rtx, i))
              sawclose = 1;

            for (j = 0; j < XVECLEN (in_rtx, i); j++)
              print_rtx (XVECEXP (in_rtx, i, j));

            indent -= 2;
          }
        if (sawclose)
          fprintf (outfile, "\n%s%*s", print_rtx_head, indent * 2, "");

        fputs ("]", outfile);
        sawclose = 1;
        indent -= 2;
        break;

      case 'w':
        if (! flag_simple)
          fprintf (outfile, " ");
        fprintf (outfile, HOST_WIDE_INT_PRINT_DEC, XWINT (in_rtx, i));
        if (! flag_simple)
          fprintf (outfile, " [" HOST_WIDE_INT_PRINT_HEX "]",
                   XWINT (in_rtx, i));
        break;

      case 'i':
        if (i == 4 && INSN_P (in_rtx))
          {
#ifndef GENERATOR_FILE
            /*  Pretty-print insn locators.  Ignore scoping as it is mostly
                redundant with line number information and do not print anything
                when there is no location information available.  */
            if (INSN_LOCATOR (in_rtx) && insn_file (in_rtx))
              fprintf(outfile, " %s:%i", insn_file (in_rtx), insn_line (in_rtx));
#endif
          }
        else if (i == 6 && NOTE_P (in_rtx))
          {
            /* This field is only used for NOTE_INSN_DELETED_LABEL, and
               other times often contains garbage from INSN->NOTE death.  */
            if (NOTE_LINE_NUMBER (in_rtx) == NOTE_INSN_DELETED_LABEL)
              fprintf (outfile, " %d",  XINT (in_rtx, i));
          }
        else
          {
            int value = XINT (in_rtx, i);
            const char *name;

#ifndef GENERATOR_FILE
            if (REG_P (in_rtx) && value < FIRST_PSEUDO_REGISTER)
              fprintf (outfile, " %d %s", REGNO (in_rtx),
                       reg_names[REGNO (in_rtx)]);
            else if (REG_P (in_rtx)
                     && value <= LAST_VIRTUAL_REGISTER)
              {
                if (value == VIRTUAL_INCOMING_ARGS_REGNUM)
                  fprintf (outfile, " %d virtual-incoming-args", value);
                else if (value == VIRTUAL_STACK_VARS_REGNUM)
                  fprintf (outfile, " %d virtual-stack-vars", value);
                else if (value == VIRTUAL_STACK_DYNAMIC_REGNUM)
                  fprintf (outfile, " %d virtual-stack-dynamic", value);
                else if (value == VIRTUAL_OUTGOING_ARGS_REGNUM)
                  fprintf (outfile, " %d virtual-outgoing-args", value);
                else if (value == VIRTUAL_CFA_REGNUM)
                  fprintf (outfile, " %d virtual-cfa", value);
                else
                  fprintf (outfile, " %d virtual-reg-%d", value,
                           value-FIRST_VIRTUAL_REGISTER);
              }
            else
#endif
              if (flag_dump_unnumbered
                     && (is_insn || NOTE_P (in_rtx)))
              fputc ('#', outfile);
            else
              fprintf (outfile, " %d", value);

#ifndef GENERATOR_FILE
            if (REG_P (in_rtx) && REG_ATTRS (in_rtx))
              {
                fputs (" [", outfile);
                if (ORIGINAL_REGNO (in_rtx) != REGNO (in_rtx))
                  fprintf (outfile, "orig:%i", ORIGINAL_REGNO (in_rtx));
                if (REG_EXPR (in_rtx))
                  print_mem_expr (outfile, REG_EXPR (in_rtx));

                if (REG_OFFSET (in_rtx))
                  fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC,
                           REG_OFFSET (in_rtx));
                fputs (" ]", outfile);
              }
#endif

            if (is_insn && &INSN_CODE (in_rtx) == &XINT (in_rtx, i)
                && XINT (in_rtx, i) >= 0
                && (name = get_insn_name (XINT (in_rtx, i))) != NULL)
              fprintf (outfile, " {%s}", name);
            sawclose = 0;
          }
        break;

      /* Print NOTE_INSN names rather than integer codes.  */

      case 'n':
        if (XINT (in_rtx, i) >= (int) NOTE_INSN_BIAS
            && XINT (in_rtx, i) < (int) NOTE_INSN_MAX)
          fprintf (outfile, " %s", GET_NOTE_INSN_NAME (XINT (in_rtx, i)));
        else
          fprintf (outfile, " %d", XINT (in_rtx, i));
        sawclose = 0;
        break;

      case 'u':
        if (XEXP (in_rtx, i) != NULL)
          {
            rtx sub = XEXP (in_rtx, i);
            enum rtx_code subc = GET_CODE (sub);

            if (GET_CODE (in_rtx) == LABEL_REF)
              {
                if (subc == NOTE
                    && NOTE_LINE_NUMBER (sub) == NOTE_INSN_DELETED_LABEL)
                  {
                    if (flag_dump_unnumbered)
                      fprintf (outfile, " [# deleted]");
                    else
                      fprintf (outfile, " [%d deleted]", INSN_UID (sub));
                    sawclose = 0;
                    break;
                  }

                if (subc != CODE_LABEL)
                  goto do_e;
              }

            if (flag_dump_unnumbered)
              fputs (" #", outfile);
            else
              fprintf (outfile, " %d", INSN_UID (sub));
          }
        else
          fputs (" 0", outfile);
        sawclose = 0;
        break;

      case 'b':
#ifndef GENERATOR_FILE
        if (XBITMAP (in_rtx, i) == NULL)
          fputs (" {null}", outfile);
        else
          bitmap_print (outfile, XBITMAP (in_rtx, i), " {", "}");
#endif
        sawclose = 0;
        break;

      case 't':
#ifndef GENERATOR_FILE
        dump_addr (outfile, " ", XTREE (in_rtx, i));
#endif
        break;

      case '*':
        fputs (" Unknown", outfile);
        sawclose = 0;
        break;

      case 'B':
#ifndef GENERATOR_FILE
        if (XBBDEF (in_rtx, i))
          fprintf (outfile, " %i", XBBDEF (in_rtx, i)->index);
#endif
        break;

      default:
        gcc_unreachable ();
      }

  switch (GET_CODE (in_rtx))
    {
#ifndef GENERATOR_FILE
    case MEM:
      fprintf (outfile, " [" HOST_WIDE_INT_PRINT_DEC, MEM_ALIAS_SET (in_rtx));

      if (MEM_EXPR (in_rtx))
        print_mem_expr (outfile, MEM_EXPR (in_rtx));

      if (MEM_OFFSET (in_rtx))
        fprintf (outfile, "+" HOST_WIDE_INT_PRINT_DEC,
                 INTVAL (MEM_OFFSET (in_rtx)));

      if (MEM_SIZE (in_rtx))
        fprintf (outfile, " S" HOST_WIDE_INT_PRINT_DEC,
                 INTVAL (MEM_SIZE (in_rtx)));

      if (MEM_ALIGN (in_rtx) != 1)
        fprintf (outfile, " A%u", MEM_ALIGN (in_rtx));

      fputc (']', outfile);
      break;

    case CONST_DOUBLE:
      if (FLOAT_MODE_P (GET_MODE (in_rtx)))
        {
          char s[60];

          real_to_decimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx),
                           sizeof (s), 0, 1);
          fprintf (outfile, " %s", s);

          real_to_hexadecimal (s, CONST_DOUBLE_REAL_VALUE (in_rtx),
                               sizeof (s), 0, 1);
          fprintf (outfile, " [%s]", s);
        }
      break;
#endif

    case CODE_LABEL:
      fprintf (outfile, " [%d uses]", LABEL_NUSES (in_rtx));
      switch (LABEL_KIND (in_rtx))
        {
          case LABEL_NORMAL: break;
          case LABEL_STATIC_ENTRY: fputs (" [entry]", outfile); break;
          case LABEL_GLOBAL_ENTRY: fputs (" [global entry]", outfile); break;
          case LABEL_WEAK_ENTRY: fputs (" [weak entry]", outfile); break;
          default: gcc_unreachable ();
        }
      break;

    default:
      break;
    }

  if (dump_for_graph
      && (is_insn || NOTE_P (in_rtx)
          || LABEL_P (in_rtx) || BARRIER_P (in_rtx)))
    sawclose = 0;
  else
    {
      fputc (')', outfile);
      sawclose = 1;
    }
}
Ejemplo n.º 6
0
static rtx
duplicate_insn_chain (rtx from, rtx to)
{
  rtx insn, last;

  /* Avoid updating of boundaries of previous basic block.  The
     note will get removed from insn stream in fixup.  */
  last = emit_note (NOTE_INSN_DELETED);

  /* Create copy at the end of INSN chain.  The chain will
     be reordered later.  */
  for (insn = from; insn != NEXT_INSN (to); insn = NEXT_INSN (insn))
    {
      switch (GET_CODE (insn))
	{
	case INSN:
	case CALL_INSN:
	case JUMP_INSN:
	  /* Avoid copying of dispatch tables.  We never duplicate
	     tablejumps, so this can hit only in case the table got
	     moved far from original jump.  */
	  if (GET_CODE (PATTERN (insn)) == ADDR_VEC
	      || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
	    break;
	  emit_copy_of_insn_after (insn, get_last_insn ());
	  break;

	case CODE_LABEL:
	  break;

	case BARRIER:
	  emit_barrier ();
	  break;

	case NOTE:
	  switch (NOTE_LINE_NUMBER (insn))
	    {
	      /* In case prologue is empty and function contain label
	         in first BB, we may want to copy the block.  */
	    case NOTE_INSN_PROLOGUE_END:

	    case NOTE_INSN_LOOP_VTOP:
	    case NOTE_INSN_LOOP_CONT:
	    case NOTE_INSN_LOOP_BEG:
	    case NOTE_INSN_LOOP_END:
	      /* Strip down the loop notes - we don't really want to keep
	         them consistent in loop copies.  */
	    case NOTE_INSN_DELETED:
	    case NOTE_INSN_DELETED_LABEL:
	      /* No problem to strip these.  */
	    case NOTE_INSN_EPILOGUE_BEG:
	    case NOTE_INSN_FUNCTION_END:
	      /* Debug code expect these notes to exist just once.
	         Keep them in the master copy.
	         ??? It probably makes more sense to duplicate them for each
	         epilogue copy.  */
	    case NOTE_INSN_FUNCTION_BEG:
	      /* There is always just single entry to function.  */
	    case NOTE_INSN_BASIC_BLOCK:
	      break;

	      /* There is no purpose to duplicate prologue.  */
	    case NOTE_INSN_BLOCK_BEG:
	    case NOTE_INSN_BLOCK_END:
	      /* The BLOCK_BEG/BLOCK_END notes should be eliminated when BB
	         reordering is in the progress.  */
	    case NOTE_INSN_EH_REGION_BEG:
	    case NOTE_INSN_EH_REGION_END:
	      /* Should never exist at BB duplication time.  */
	      abort ();
	      break;
	    case NOTE_INSN_REPEATED_LINE_NUMBER:
	      emit_note_copy (insn);
	      break;

	    default:
	      if (NOTE_LINE_NUMBER (insn) < 0)
		abort ();
	      /* It is possible that no_line_number is set and the note
	         won't be emitted.  */
	      emit_note_copy (insn);
	    }
	  break;
	default:
	  abort ();
	}
    }
  insn = NEXT_INSN (last);
  delete_insn (last);
  return insn;
}
Ejemplo n.º 7
0
static rtx
skip_insns_after_block (basic_block bb)
{
  rtx insn, last_insn, next_head, prev;

  next_head = NULL_RTX;
  if (bb->next_bb != EXIT_BLOCK_PTR)
    next_head = BB_HEAD (bb->next_bb);

  for (last_insn = insn = BB_END (bb); (insn = NEXT_INSN (insn)) != 0; )
    {
      if (insn == next_head)
	break;

      switch (GET_CODE (insn))
	{
	case BARRIER:
	  last_insn = insn;
	  continue;

	case NOTE:
	  switch (NOTE_LINE_NUMBER (insn))
	    {
	    case NOTE_INSN_LOOP_END:
	    case NOTE_INSN_BLOCK_END:
	      last_insn = insn;
	      continue;
	    case NOTE_INSN_DELETED:
	    case NOTE_INSN_DELETED_LABEL:
	      continue;

	    default:
	      continue;
	      break;
	    }
	  break;

	case CODE_LABEL:
	  if (NEXT_INSN (insn)
	      && GET_CODE (NEXT_INSN (insn)) == JUMP_INSN
	      && (GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_VEC
	          || GET_CODE (PATTERN (NEXT_INSN (insn))) == ADDR_DIFF_VEC))
	    {
	      insn = NEXT_INSN (insn);
	      last_insn = insn;
	      continue;
	    }
	  break;

	default:
	  break;
	}

      break;
    }

  /* It is possible to hit contradictory sequence.  For instance:

     jump_insn
     NOTE_INSN_LOOP_BEG
     barrier

     Where barrier belongs to jump_insn, but the note does not.  This can be
     created by removing the basic block originally following
     NOTE_INSN_LOOP_BEG.  In such case reorder the notes.  */

  for (insn = last_insn; insn != BB_END (bb); insn = prev)
    {
      prev = PREV_INSN (insn);
      if (GET_CODE (insn) == NOTE)
	switch (NOTE_LINE_NUMBER (insn))
	  {
	  case NOTE_INSN_LOOP_END:
	  case NOTE_INSN_BLOCK_END:
	  case NOTE_INSN_DELETED:
	  case NOTE_INSN_DELETED_LABEL:
	    continue;
	  default:
	    reorder_insns (insn, insn, last_insn);
	  }
    }

  return last_insn;
}
Ejemplo n.º 8
0
void
insn_locators_initialize (void)
{
  tree block = NULL;
  tree last_block = NULL;
  rtx insn, next;
  int loc = 0;
  int line_number = 0, last_line_number = 0;
  char *file_name = NULL, *last_file_name = NULL;

  prologue_locator = epilogue_locator = 0;

  VARRAY_INT_INIT (block_locators_locs, 32, "block_locators_locs");
  VARRAY_TREE_INIT (block_locators_blocks, 32, "block_locators_blocks");
  VARRAY_INT_INIT (line_locators_locs, 32, "line_locators_locs");
  VARRAY_INT_INIT (line_locators_lines, 32, "line_locators_lines");
  VARRAY_INT_INIT (file_locators_locs, 32, "file_locators_locs");
  VARRAY_CHAR_PTR_INIT (file_locators_files, 32, "file_locators_files");

  for (insn = get_insns (); insn; insn = next)
    {
      next = NEXT_INSN (insn);

      if ((active_insn_p (insn)
	   && GET_CODE (PATTERN (insn)) != ADDR_VEC
	   && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC)
	  || !NEXT_INSN (insn)
	  || (!prologue_locator && file_name))
	{
	  if (last_block != block)
	    {
	      loc++;
	      VARRAY_PUSH_INT (block_locators_locs, loc);
	      VARRAY_PUSH_TREE (block_locators_blocks, block);
	      last_block = block;
	    }
	  if (last_line_number != line_number)
	    {
	      loc++;
	      VARRAY_PUSH_INT (line_locators_locs, loc);
	      VARRAY_PUSH_INT (line_locators_lines, line_number);
	      last_line_number = line_number;
	    }
	  if (last_file_name != file_name)
	    {
	      loc++;
	      VARRAY_PUSH_INT (file_locators_locs, loc);
	      VARRAY_PUSH_CHAR_PTR (file_locators_files, file_name);
	      last_file_name = file_name;
	    }
	}
      if (!prologue_locator && file_name)
	prologue_locator = loc;
      if (!NEXT_INSN (insn))
	epilogue_locator = loc;
      if (active_insn_p (insn))
        INSN_LOCATOR (insn) = loc;
      else if (GET_CODE (insn) == NOTE)
	{
	  switch (NOTE_LINE_NUMBER (insn))
	    {
	    case NOTE_INSN_BLOCK_BEG:
	      block = NOTE_BLOCK (insn);
	      delete_insn (insn);
	      break;
	    case NOTE_INSN_BLOCK_END:
	      block = BLOCK_SUPERCONTEXT (block);
	      if (block && TREE_CODE (block) == FUNCTION_DECL)
		block = 0;
	      delete_insn (insn);
	      break;
	    default:
	      if (NOTE_LINE_NUMBER (insn) > 0)
		{
		  line_number = NOTE_LINE_NUMBER (insn);
		  file_name = (char *)NOTE_SOURCE_FILE (insn);
		}
	      break;
	    }
	}
    }

  /* Tag the blocks with a depth number so that change_scope can find
     the common parent easily.  */
  set_block_levels (DECL_INITIAL (cfun->decl), 0);
}
Ejemplo n.º 9
0
unsigned int
insn_locators_initialize (void)
{
  tree block = NULL;
  tree last_block = NULL;
  rtx insn, next;
  int loc = 0;
  int line_number = 0, last_line_number = 0;
  const char *file_name = NULL, *last_file_name = NULL;

  prologue_locator = epilogue_locator = 0;

  block_locators_locs = VEC_alloc (int, heap, 32);
  block_locators_blocks = VEC_alloc (tree, gc, 32);
  line_locators_locs = VEC_alloc (int, heap, 32);
  line_locators_lines = VEC_alloc (int, heap, 32);
  file_locators_locs = VEC_alloc (int, heap, 32);
  VARRAY_CHAR_PTR_INIT (file_locators_files, 32, "file_locators_files");

  for (insn = get_insns (); insn; insn = next)
    {
      int active = 0;

      next = NEXT_INSN (insn);

      if (NOTE_P (insn))
	{
	  gcc_assert (NOTE_LINE_NUMBER (insn) != NOTE_INSN_BLOCK_BEG
		      && NOTE_LINE_NUMBER (insn) != NOTE_INSN_BLOCK_END);
	  if (NOTE_LINE_NUMBER (insn) > 0)
	    {
	      expanded_location xloc;
	      NOTE_EXPANDED_LOCATION (xloc, insn);
	      line_number = xloc.line;
	      file_name = xloc.file;
	    }
	}
      else
	active = (active_insn_p (insn)
		  && GET_CODE (PATTERN (insn)) != ADDR_VEC
		  && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC);

      check_block_change (insn, &block);

      if (active
	  || !next
	  || (!prologue_locator && file_name))
	{
	  if (last_block != block)
	    {
	      loc++;
	      VEC_safe_push (int, heap, block_locators_locs, loc);
	      VEC_safe_push (tree, gc, block_locators_blocks, block);
	      last_block = block;
	    }
	  if (last_line_number != line_number)
	    {
	      loc++;
	      VEC_safe_push (int, heap, line_locators_locs, loc);
	      VEC_safe_push (int, heap, line_locators_lines, line_number);
	      last_line_number = line_number;
	    }
	  if (last_file_name != file_name)
	    {
	      loc++;
	      VEC_safe_push (int, heap, file_locators_locs, loc);
	      VARRAY_PUSH_CHAR_PTR (file_locators_files, (char *) file_name);
	      last_file_name = file_name;
	    }
	  if (!prologue_locator && file_name)
	    prologue_locator = loc;
	  if (!next)
	    epilogue_locator = loc;
	  if (active)
	    INSN_LOCATOR (insn) = loc;
	}
    }

  /* Tag the blocks with a depth number so that change_scope can find
     the common parent easily.  */
  set_block_levels (DECL_INITIAL (cfun->decl), 0);

  free_block_changes ();
  return 0;
}