您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

344 行
8.8KB

  1. /* Gimple simplify definitions.
  2. Copyright (C) 2011-2020 Free Software Foundation, Inc.
  3. Contributed by Richard Guenther <rguenther@suse.de>
  4. This file is part of GCC.
  5. GCC is free software; you can redistribute it and/or modify it under
  6. the terms of the GNU General Public License as published by the Free
  7. Software Foundation; either version 3, or (at your option) any later
  8. version.
  9. GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  12. for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with GCC; see the file COPYING3. If not see
  15. <http://www.gnu.org/licenses/>. */
  16. #ifndef GCC_GIMPLE_MATCH_H
  17. #define GCC_GIMPLE_MATCH_H
  18. /* Helper to transparently allow tree codes and builtin function codes
  19. exist in one storage entity. */
  20. class code_helper
  21. {
  22. public:
  23. code_helper () {}
  24. code_helper (tree_code code) : rep ((int) code) {}
  25. code_helper (combined_fn fn) : rep (-(int) fn) {}
  26. operator tree_code () const { return (tree_code) rep; }
  27. operator combined_fn () const { return (combined_fn) -rep; }
  28. bool is_tree_code () const { return rep > 0; }
  29. bool is_fn_code () const { return rep < 0; }
  30. int get_rep () const { return rep; }
  31. private:
  32. int rep;
  33. };
  34. /* Represents the condition under which an operation should happen,
  35. and the value to use otherwise. The condition applies elementwise
  36. (as for VEC_COND_EXPR) if the values are vectors. */
  37. class gimple_match_cond
  38. {
  39. public:
  40. enum uncond { UNCOND };
  41. /* Build an unconditional op. */
  42. gimple_match_cond (uncond) : cond (NULL_TREE), else_value (NULL_TREE) {}
  43. gimple_match_cond (tree, tree);
  44. gimple_match_cond any_else () const;
  45. /* The condition under which the operation occurs, or NULL_TREE
  46. if the operation is unconditional. */
  47. tree cond;
  48. /* The value to use when the condition is false. This is NULL_TREE if
  49. the operation is unconditional or if the value doesn't matter. */
  50. tree else_value;
  51. };
  52. inline
  53. gimple_match_cond::gimple_match_cond (tree cond_in, tree else_value_in)
  54. : cond (cond_in), else_value (else_value_in)
  55. {
  56. }
  57. /* Return a gimple_match_cond with the same condition but with an
  58. arbitrary ELSE_VALUE. */
  59. inline gimple_match_cond
  60. gimple_match_cond::any_else () const
  61. {
  62. return gimple_match_cond (cond, NULL_TREE);
  63. }
  64. /* Represents an operation to be simplified, or the result of the
  65. simplification. */
  66. class gimple_match_op
  67. {
  68. public:
  69. gimple_match_op ();
  70. gimple_match_op (const gimple_match_cond &, code_helper, tree, unsigned int);
  71. gimple_match_op (const gimple_match_cond &,
  72. code_helper, tree, tree);
  73. gimple_match_op (const gimple_match_cond &,
  74. code_helper, tree, tree, tree);
  75. gimple_match_op (const gimple_match_cond &,
  76. code_helper, tree, tree, tree, tree);
  77. gimple_match_op (const gimple_match_cond &,
  78. code_helper, tree, tree, tree, tree, tree);
  79. gimple_match_op (const gimple_match_cond &,
  80. code_helper, tree, tree, tree, tree, tree, tree);
  81. void set_op (code_helper, tree, unsigned int);
  82. void set_op (code_helper, tree, tree);
  83. void set_op (code_helper, tree, tree, tree);
  84. void set_op (code_helper, tree, tree, tree, tree);
  85. void set_op (code_helper, tree, tree, tree, tree, bool);
  86. void set_op (code_helper, tree, tree, tree, tree, tree);
  87. void set_op (code_helper, tree, tree, tree, tree, tree, tree);
  88. void set_value (tree);
  89. tree op_or_null (unsigned int) const;
  90. bool resimplify (gimple_seq *, tree (*)(tree));
  91. /* The maximum value of NUM_OPS. */
  92. static const unsigned int MAX_NUM_OPS = 5;
  93. /* The conditions under which the operation is performed, and the value to
  94. use as a fallback. */
  95. gimple_match_cond cond;
  96. /* The operation being performed. */
  97. code_helper code;
  98. /* The type of the result. */
  99. tree type;
  100. /* For a BIT_FIELD_REF, whether the group of bits is stored in reverse order
  101. from the target order. */
  102. bool reverse;
  103. /* The number of operands to CODE. */
  104. unsigned int num_ops;
  105. /* The operands to CODE. Only the first NUM_OPS entries are meaningful. */
  106. tree ops[MAX_NUM_OPS];
  107. };
  108. inline
  109. gimple_match_op::gimple_match_op ()
  110. : cond (gimple_match_cond::UNCOND), type (NULL_TREE), reverse (false),
  111. num_ops (0)
  112. {
  113. }
  114. /* Constructor that takes the condition, code, type and number of
  115. operands, but leaves the caller to fill in the operands. */
  116. inline
  117. gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
  118. code_helper code_in, tree type_in,
  119. unsigned int num_ops_in)
  120. : cond (cond_in), code (code_in), type (type_in), reverse (false),
  121. num_ops (num_ops_in)
  122. {
  123. }
  124. /* Constructors for various numbers of operands. */
  125. inline
  126. gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
  127. code_helper code_in, tree type_in,
  128. tree op0)
  129. : cond (cond_in), code (code_in), type (type_in), reverse (false),
  130. num_ops (1)
  131. {
  132. ops[0] = op0;
  133. }
  134. inline
  135. gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
  136. code_helper code_in, tree type_in,
  137. tree op0, tree op1)
  138. : cond (cond_in), code (code_in), type (type_in), reverse (false),
  139. num_ops (2)
  140. {
  141. ops[0] = op0;
  142. ops[1] = op1;
  143. }
  144. inline
  145. gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
  146. code_helper code_in, tree type_in,
  147. tree op0, tree op1, tree op2)
  148. : cond (cond_in), code (code_in), type (type_in), reverse (false),
  149. num_ops (3)
  150. {
  151. ops[0] = op0;
  152. ops[1] = op1;
  153. ops[2] = op2;
  154. }
  155. inline
  156. gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
  157. code_helper code_in, tree type_in,
  158. tree op0, tree op1, tree op2, tree op3)
  159. : cond (cond_in), code (code_in), type (type_in), reverse (false),
  160. num_ops (4)
  161. {
  162. ops[0] = op0;
  163. ops[1] = op1;
  164. ops[2] = op2;
  165. ops[3] = op3;
  166. }
  167. inline
  168. gimple_match_op::gimple_match_op (const gimple_match_cond &cond_in,
  169. code_helper code_in, tree type_in,
  170. tree op0, tree op1, tree op2, tree op3,
  171. tree op4)
  172. : cond (cond_in), code (code_in), type (type_in), reverse (false),
  173. num_ops (5)
  174. {
  175. ops[0] = op0;
  176. ops[1] = op1;
  177. ops[2] = op2;
  178. ops[3] = op3;
  179. ops[4] = op4;
  180. }
  181. /* Change the operation performed to CODE_IN, the type of the result to
  182. TYPE_IN, and the number of operands to NUM_OPS_IN. The caller needs
  183. to set the operands itself. */
  184. inline void
  185. gimple_match_op::set_op (code_helper code_in, tree type_in,
  186. unsigned int num_ops_in)
  187. {
  188. code = code_in;
  189. type = type_in;
  190. num_ops = num_ops_in;
  191. }
  192. /* Functions for changing the operation performed, for various numbers
  193. of operands. */
  194. inline void
  195. gimple_match_op::set_op (code_helper code_in, tree type_in, tree op0)
  196. {
  197. code = code_in;
  198. type = type_in;
  199. num_ops = 1;
  200. ops[0] = op0;
  201. }
  202. inline void
  203. gimple_match_op::set_op (code_helper code_in, tree type_in, tree op0, tree op1)
  204. {
  205. code = code_in;
  206. type = type_in;
  207. num_ops = 2;
  208. ops[0] = op0;
  209. ops[1] = op1;
  210. }
  211. inline void
  212. gimple_match_op::set_op (code_helper code_in, tree type_in,
  213. tree op0, tree op1, tree op2)
  214. {
  215. code = code_in;
  216. type = type_in;
  217. num_ops = 3;
  218. ops[0] = op0;
  219. ops[1] = op1;
  220. ops[2] = op2;
  221. }
  222. inline void
  223. gimple_match_op::set_op (code_helper code_in, tree type_in,
  224. tree op0, tree op1, tree op2, bool reverse_in)
  225. {
  226. code = code_in;
  227. type = type_in;
  228. reverse = reverse_in;
  229. num_ops = 3;
  230. ops[0] = op0;
  231. ops[1] = op1;
  232. ops[2] = op2;
  233. }
  234. inline void
  235. gimple_match_op::set_op (code_helper code_in, tree type_in,
  236. tree op0, tree op1, tree op2, tree op3)
  237. {
  238. code = code_in;
  239. type = type_in;
  240. num_ops = 4;
  241. ops[0] = op0;
  242. ops[1] = op1;
  243. ops[2] = op2;
  244. ops[3] = op3;
  245. }
  246. inline void
  247. gimple_match_op::set_op (code_helper code_in, tree type_in,
  248. tree op0, tree op1, tree op2, tree op3, tree op4)
  249. {
  250. code = code_in;
  251. type = type_in;
  252. num_ops = 5;
  253. ops[0] = op0;
  254. ops[1] = op1;
  255. ops[2] = op2;
  256. ops[3] = op3;
  257. ops[4] = op4;
  258. }
  259. /* Set the "operation" to be the single value VALUE, such as a constant
  260. or SSA_NAME. */
  261. inline void
  262. gimple_match_op::set_value (tree value)
  263. {
  264. set_op (TREE_CODE (value), TREE_TYPE (value), value);
  265. }
  266. /* Return the value of operand I, or null if there aren't that many
  267. operands. */
  268. inline tree
  269. gimple_match_op::op_or_null (unsigned int i) const
  270. {
  271. return i < num_ops ? ops[i] : NULL_TREE;
  272. }
  273. /* Return whether OP is a non-expression result and a gimple value. */
  274. inline bool
  275. gimple_simplified_result_is_gimple_val (const gimple_match_op *op)
  276. {
  277. return (op->code.is_tree_code ()
  278. && (TREE_CODE_LENGTH ((tree_code) op->code) == 0
  279. || ((tree_code) op->code) == ADDR_EXPR)
  280. && is_gimple_val (op->ops[0]));
  281. }
  282. extern tree (*mprts_hook) (gimple_match_op *);
  283. bool gimple_simplify (gimple *, gimple_match_op *, gimple_seq *,
  284. tree (*)(tree), tree (*)(tree));
  285. tree maybe_push_res_to_seq (gimple_match_op *, gimple_seq *,
  286. tree res = NULL_TREE);
  287. void maybe_build_generic_op (gimple_match_op *);
  288. #endif /* GCC_GIMPLE_MATCH_H */