gcc源代码分析,rtx_alloc函数分析

有了print_rtx()函数和gen_rtx()函数以及insn结构和rtx结构

【主要是fmt格式化字符串和GET_RTX_LENGTH】的定义。

对于rtx或者说insn我们已经能游刃有余了!


/* Allocate an rtx of code CODE.  The CODE is stored in the rtx;

   all the rest is initialized to zero.  */

rtx
rtx_alloc (code)
  RTX_CODE code;
{
  rtx rt;
  register int nelts = GET_RTX_LENGTH (code);
  register int length = sizeof (struct rtx_def)
    + (nelts - 1) * sizeof (rtunion);

  rt = (rtx) obstack_alloc (rtl_obstack, length);

  * (int *) rt = 0;
  PUT_CODE (rt, code);

  return rt;

}

非常简单的函数,最主要的是得到code对应的长度比如我们的call_insn的长度为7

那么除了分配一个rtx_def结构的长度外,还要分配指定长度的空间以便存放其他的rtx的地址!

当然每个空间是四个字节。当然这四个字节不是一定是指针,比如对于我们研究的call_insn来说

第一个空间是表示此insn的编号,而第二个第三个空间表示前一个insn和后一个insn。

前一个insn的编号INSN_UID (XEXP (in_rtx, i))

#define INSN_UID(INSN)    ((INSN)->fld[0].rtint)    在rtl.h头 文件里。


typedef union rtunion_def
{
  int rtint;
  char *rtstr;
  struct rtx_def *rtx;
  struct rtvec_def *rtvec;
  enum machine_mode rttype;
} rtunion;



/* Emit an insn of given code and pattern
   at a specified place within the doubly-linked list.  */

/* Make an instruction with body PATTERN
   and output it before the instruction BEFORE.  */

rtx
emit_insn_before (pattern, before)
     register rtx pattern, before;
{
  register rtx insn;

  if (GET_CODE (pattern) == SEQUENCE)
    {
      register int i;
      /* For an empty sequence, emit nothing.  */
      if (XVEC (pattern, 0))
    for (i = 0; i < XVECLEN (pattern, 0); i++)
      add_insn_after (XVECEXP (pattern, 0, i), PREV_INSN (before));
      return PREV_INSN (before);
    }

  insn = make_insn_raw (pattern, 0);

  PREV_INSN (insn) = PREV_INSN (before);
  NEXT_INSN (insn) = before;

/*全局变量before,如果我们新建了一个insn则把before指向的地址赋给我们,

然后我们的下一个insn的地址是before*/

  if (PREV_INSN (insn))
    NEXT_INSN (PREV_INSN (insn)) = insn;
  else
    first_insn = insn;
  PREV_INSN (before) = insn;

  return insn;
}


/* Make an instruction with body PATTERN and code CALL_INSN
   and output it before the instruction BEFORE.  */

rtx
emit_call_insn_before (pattern, before)
     register rtx pattern, before;
{
  rtx insn = emit_insn_before (pattern, before);
  PUT_CODE (insn, CALL_INSN);
  return insn;
}

GET_RTX_LENGTH

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