GCC's bacl-end & assemble emission (3)

2.2. Output condition part of instruction defining patterns

Following genconditions will generate array insn_conditions which contains conditional test part of instrucitons description patterns. This array will be used to help optimizing the generation of backend functionalities, as we will see in later sections.

 

main (continued, genconditions)

 

199    /* Read the machine description.  */

200 

201    while (1)

202    {

203      desc = read_md_rtx (&pattern_lineno, &code);

204      if (desc == NULL)

205        break ;

206 

207       /* N.B. define_insn_and_split, define_cond_exec are handled

208         entirely within read_md_rtx; we never see them.  */

209      switch (GET_CODE (desc))

210      {

211        default :

212           break ;

213 

214        case DEFINE_INSN:

215        case DEFINE_EXPAND:

216            add_condition (XSTR (desc, 2));

217            /* except.h needs to know whether there is an eh_return

218               pattern in the machine description.  */

219            if (!strcmp (XSTR (desc, 0), "eh_return"))

220               saw_eh_return = 1;

221            break ;

222 

223        case DEFINE_SPLIT:

224        case DEFINE_PEEPHOLE:

225        case DEFINE_PEEPHOLE2:

226              add_condition (XSTR (desc, 1));

227             break ;

228      }

229    }

230 

231    write_header ();

232    write_conditions ();

233 

234    fflush (stdout);

235    return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);

236  }

 

Here, at line 203, read_md_rtx nearly does nothing, as insn_elision_unavailable is 1 – we just creating it. read_md_rtx just returns rtx object from define_attr_queue , define_insn_queue , or other_queue accordingly.

 

52    static void

53    add_condition (const char *expr)                                                          in genconditions.c

54    {

55      struct c_test *test;

56   

57      if (expr[0] == 0)

58        return ;

59   

60      test = xmalloc (sizeof (struct c_test));

61      test->expr = expr;

62   

63      *(htab_find_slot (condition_table , test, INSERT)) = test;

64    }

 

All patterns will be put into hash table of condition_table via funciton add_condition . Pay attention to the parameter passed to add_condition , it is the condition part of the pattern. At line 231, write_header just outputs the constant part of the output file.

 

163  static void

164  write_conditions (void)                                                                              in genconditions.c

165  {

166    puts ("/

167  /* This table lists each condition found in the machine description./n/

168     Each condition is mapped to its truth value (0 or 1), or -1 if that/n/

169     cannot be calculated at compile time. *//n/

170  /n/

171  const struct c_test insn_conditions[] = {");

172 

173    htab_traverse (condition_table , write_one_condition , 0);

174 

175    puts ("};/n");

176 

177    printf ("const size_t n_insn_conditions = %lu;/n",

178           (unsigned long) htab_elements (condition_table ));

179    puts ("const int insn_elision_unavailable = 0;");

180  }

 

Above, at line 173, htab_traverse will invoke write_one_condition for every member in the condition_table . Here the function constructs the array of insn_conditions . And notice that at line 179, when creating insn-recog.c, maybe_eval_c_test will do the evaluation as now insn_elision_unavailable is zero.

 

140  static int

141  write_one_condition (void **slot, void *dummy ATTRIBUTE_UNUSED)       in genconditions.c

142  {

143    const struct c_test *test = * (const struct c_test **) slot;

144    const char *p;

145 

146    fputs ("  { /"", stdout);

147    for (p = test->expr; *p; p++)

148    {

149      if (*p == '/n')

150        fputs ("//n///n", stdout);

151      else if (*p == '"')

152        fputs ("///"", stdout);

153      else

154        putchar (*p);

155    }

156 

157    printf ("/",/n    MAYBE_EVAL (%s) },/n", test->expr);

158    return 1;

159  }

 

Above at line 157, MAYBE_EVAL has definition as below. It also appears in the generated file insn-conditions.c (output by write_header ).

 

#if (GCC_VERSION >= 3001) || ((GCC_VERSION == 3000) && !__OPTIMIZE__)

# define MAYBE_EVAL(expr) (__builtin_constant_p(expr) ? (int) (expr) : -1)

#else

# define MAYBE_EVAL(expr) -1

#endif

 

__builtin_constant_p is the builtin function provided by GCC after release V3.0.1, it returns 1 if the expr is constant known at the time of compilation, otherwise returns 0. So MAYBE_EVAL returns the value of expression if it is constant; or -1 if it is not. This macro is used heavily with insn-conditions for other tools as we see later. It does helpful to reduce the size of generated code and save the processing time as the tools can skip those patterns known unmatched during handling at certain point of time.

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值