Gcc源代码分析,rtl.c源代码分析

Gcc源代码分析,insn和rtx的关系

下面是gcc -dr hello.c产生的hello.dr文件的一部分

(insn 6 4 7 (set (mem:SI (pre_dec:SI (reg:SI 7)))
       (symbol_ref:SI ("*LC0"))) -1 (nil)
   (nil))

(call_insn 7 6 9 (set (reg:SI 0)
       (call (mem:QI (symbol_ref/v:SI ("printf")))
           (const_int 4))) -1 (nil)
   (nil))


(insn 9 7 10 (set (reg/i:SI 0)
       (const_int 0)) -1 (nil)
   (nil))


下面是rtl.h头文件的部分内容

#define XEXP(RTX, N)    ((RTX)->fld[N].rtx)
#define XINT(RTX, N)    ((RTX)->fld[N].rtint)


/* Holds a unique number for each insn.
   These are not necessarily sequentially increasing.  */
#define INSN_UID(INSN)    ((INSN)->fld[0].rtint)

/* Chain insns together in sequence.  */
#define PREV_INSN(INSN)    ((INSN)->fld[1].rtx)
#define NEXT_INSN(INSN)    ((INSN)->fld[2].rtx)

/* The body of an insn.  */
#define PATTERN(INSN)    ((INSN)->fld[3].rtx)

对于上面call_insn来说第一个,7是本条指令的号码,对应的格式符是i

第二个,6是上一条指令的号码,对应的格式符是u

第三个,9是下一条指令的号码。对应的格式符是u。

(set (reg:SI 0)
       (call (mem:QI (symbol_ref/v:SI ("printf")))
           (const_int 4)))

对应的格式符是e。所以要递归调用。





/* Print IN_RTX onto OUTFILE.  This is the recursive part of printing.  */

static void
print_rtx (in_rtx)
     register rtx in_rtx;
{
  static int indent;
  register int i, j;
  register char *format_ptr;

  if (sawclose)
    {
      fprintf (outfile, "\n%s",
           (spaces + (sizeof spaces - indent * 2)));
      sawclose = 0;
    }

  if (in_rtx == 0)
    {
      fprintf (outfile, "(nil)");
      sawclose = 1;
      return;
    }

  /* print name of expression code */

/*打印表达式的名字,比如(call_insn,再比如(set,再比如(reg:SI  */
  fprintf (outfile, "(%s", GET_RTX_NAME (GET_CODE (in_rtx)));

  if (in_rtx->in_struct)
    fprintf (outfile, "/s");

  if (in_rtx->volatil)
    fprintf (outfile, "/v");

  if (in_rtx->unchanging)
    fprintf (outfile, "/u");

  if (in_rtx->integrated)
    fprintf (outfile, "/i");

  if (GET_MODE (in_rtx) != VOIDmode)
    {
      /* 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)));
      else
    fprintf (outfile, ":%s", GET_MODE_NAME (GET_MODE (in_rtx)));
    }

  format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx));

  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++)
    switch (*format_ptr++)
      {
      case 'S':
      case 's':
    if (XSTR (in_rtx, i) == 0)
      fprintf (outfile, " \"\"");
    else
      fprintf (outfile, " (\"%s\")", XSTR (in_rtx, i));
    sawclose = 1;
    break;

    /* 0 indicates a field for internal use that should not be printed.  */
      case '0':
    break;

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

/*这里是递归调用啊,比如call_insn,

DEF_RTL_EXPR(CALL_INSN, "call_insn", "iuueiee")

*/
    indent -= 2;
    break;

      case 'E':
    indent += 2;
    if (sawclose)
      {
        fprintf (outfile, "\n%s",
             (spaces + (sizeof spaces - indent * 2)));
        sawclose = 0;
      }
    fprintf (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",
           (spaces + (sizeof spaces - indent * 2)));

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

      case 'i':
    fprintf (outfile, " %d", XINT (in_rtx, i));
    sawclose = 0;
    break;

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

      case 'n':
    if (XINT (in_rtx, i) <= 0)
      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)
      fprintf(outfile, " %d", INSN_UID (XEXP (in_rtx, i)));
    else
      fprintf(outfile, " 0");
    sawclose = 0;
    break;

      default:
    fprintf (stderr,
         "switch format wrong in rtl.print_rtx(). format was: %c.\n",
         format_ptr[-1]);
    abort ();
      }

  fprintf (outfile, ")");
  sawclose = 1;
}


Gcc源代码分析,rtl.c源代码分析_第1张图片

你可能感兴趣的:(gcc,源代码,分析)