gimple-match-head.c 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863
  1. /* Preamble and helpers for the autogenerated gimple-match.c file.
  2. Copyright (C) 2014-2015 Free Software Foundation, Inc.
  3. This file is part of GCC.
  4. GCC is free software; you can redistribute it and/or modify it under
  5. the terms of the GNU General Public License as published by the Free
  6. Software Foundation; either version 3, or (at your option) any later
  7. version.
  8. GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  9. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  10. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  11. for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with GCC; see the file COPYING3. If not see
  14. <http://www.gnu.org/licenses/>. */
  15. #include "config.h"
  16. #include "system.h"
  17. #include "coretypes.h"
  18. #include "tm.h"
  19. #include "hash-set.h"
  20. #include "machmode.h"
  21. #include "vec.h"
  22. #include "double-int.h"
  23. #include "input.h"
  24. #include "alias.h"
  25. #include "symtab.h"
  26. #include "options.h"
  27. #include "wide-int.h"
  28. #include "inchash.h"
  29. #include "tree.h"
  30. #include "fold-const.h"
  31. #include "stringpool.h"
  32. #include "stor-layout.h"
  33. #include "flags.h"
  34. #include "hard-reg-set.h"
  35. #include "function.h"
  36. #include "predict.h"
  37. #include "basic-block.h"
  38. #include "tree-ssa-alias.h"
  39. #include "internal-fn.h"
  40. #include "gimple-expr.h"
  41. #include "is-a.h"
  42. #include "gimple.h"
  43. #include "gimple-ssa.h"
  44. #include "tree-ssanames.h"
  45. #include "gimple-fold.h"
  46. #include "gimple-iterator.h"
  47. #include "hashtab.h"
  48. #include "rtl.h"
  49. #include "statistics.h"
  50. #include "real.h"
  51. #include "fixed-value.h"
  52. #include "insn-config.h"
  53. #include "expmed.h"
  54. #include "dojump.h"
  55. #include "explow.h"
  56. #include "calls.h"
  57. #include "emit-rtl.h"
  58. #include "varasm.h"
  59. #include "stmt.h"
  60. #include "expr.h"
  61. #include "tree-dfa.h"
  62. #include "builtins.h"
  63. #include "tree-phinodes.h"
  64. #include "ssa-iterators.h"
  65. #include "dumpfile.h"
  66. #include "gimple-match.h"
  67. /* Forward declarations of the private auto-generated matchers.
  68. They expect valueized operands in canonical order and do not
  69. perform simplification of all-constant operands. */
  70. static bool gimple_simplify (code_helper *, tree *,
  71. gimple_seq *, tree (*)(tree),
  72. code_helper, tree, tree);
  73. static bool gimple_simplify (code_helper *, tree *,
  74. gimple_seq *, tree (*)(tree),
  75. code_helper, tree, tree, tree);
  76. static bool gimple_simplify (code_helper *, tree *,
  77. gimple_seq *, tree (*)(tree),
  78. code_helper, tree, tree, tree, tree);
  79. /* Return whether T is a constant that we'll dispatch to fold to
  80. evaluate fully constant expressions. */
  81. static inline bool
  82. constant_for_folding (tree t)
  83. {
  84. return (CONSTANT_CLASS_P (t)
  85. /* The following is only interesting to string builtins. */
  86. || (TREE_CODE (t) == ADDR_EXPR
  87. && TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST));
  88. }
  89. /* Helper that matches and simplifies the toplevel result from
  90. a gimple_simplify run (where we don't want to build
  91. a stmt in case it's used in in-place folding). Replaces
  92. *RES_CODE and *RES_OPS with a simplified and/or canonicalized
  93. result and returns whether any change was made. */
  94. static bool
  95. gimple_resimplify1 (gimple_seq *seq,
  96. code_helper *res_code, tree type, tree *res_ops,
  97. tree (*valueize)(tree))
  98. {
  99. if (constant_for_folding (res_ops[0]))
  100. {
  101. tree tem = NULL_TREE;
  102. if (res_code->is_tree_code ())
  103. tem = const_unop (*res_code, type, res_ops[0]);
  104. else
  105. {
  106. tree decl = builtin_decl_implicit (*res_code);
  107. if (decl)
  108. {
  109. tem = fold_builtin_n (UNKNOWN_LOCATION, decl, res_ops, 1, false);
  110. if (tem)
  111. {
  112. /* fold_builtin_n wraps the result inside a NOP_EXPR. */
  113. STRIP_NOPS (tem);
  114. tem = fold_convert (type, tem);
  115. }
  116. }
  117. }
  118. if (tem != NULL_TREE
  119. && CONSTANT_CLASS_P (tem))
  120. {
  121. res_ops[0] = tem;
  122. res_ops[1] = NULL_TREE;
  123. res_ops[2] = NULL_TREE;
  124. *res_code = TREE_CODE (res_ops[0]);
  125. return true;
  126. }
  127. }
  128. code_helper res_code2;
  129. tree res_ops2[3] = {};
  130. if (gimple_simplify (&res_code2, res_ops2, seq, valueize,
  131. *res_code, type, res_ops[0]))
  132. {
  133. *res_code = res_code2;
  134. res_ops[0] = res_ops2[0];
  135. res_ops[1] = res_ops2[1];
  136. res_ops[2] = res_ops2[2];
  137. return true;
  138. }
  139. return false;
  140. }
  141. /* Helper that matches and simplifies the toplevel result from
  142. a gimple_simplify run (where we don't want to build
  143. a stmt in case it's used in in-place folding). Replaces
  144. *RES_CODE and *RES_OPS with a simplified and/or canonicalized
  145. result and returns whether any change was made. */
  146. static bool
  147. gimple_resimplify2 (gimple_seq *seq,
  148. code_helper *res_code, tree type, tree *res_ops,
  149. tree (*valueize)(tree))
  150. {
  151. if (constant_for_folding (res_ops[0]) && constant_for_folding (res_ops[1]))
  152. {
  153. tree tem = NULL_TREE;
  154. if (res_code->is_tree_code ())
  155. tem = const_binop (*res_code, type, res_ops[0], res_ops[1]);
  156. else
  157. {
  158. tree decl = builtin_decl_implicit (*res_code);
  159. if (decl)
  160. {
  161. tem = fold_builtin_n (UNKNOWN_LOCATION, decl, res_ops, 2, false);
  162. if (tem)
  163. {
  164. /* fold_builtin_n wraps the result inside a NOP_EXPR. */
  165. STRIP_NOPS (tem);
  166. tem = fold_convert (type, tem);
  167. }
  168. }
  169. }
  170. if (tem != NULL_TREE
  171. && CONSTANT_CLASS_P (tem))
  172. {
  173. res_ops[0] = tem;
  174. res_ops[1] = NULL_TREE;
  175. res_ops[2] = NULL_TREE;
  176. *res_code = TREE_CODE (res_ops[0]);
  177. return true;
  178. }
  179. }
  180. /* Canonicalize operand order. */
  181. bool canonicalized = false;
  182. if (res_code->is_tree_code ()
  183. && (TREE_CODE_CLASS ((enum tree_code) *res_code) == tcc_comparison
  184. || commutative_tree_code (*res_code))
  185. && tree_swap_operands_p (res_ops[0], res_ops[1], false))
  186. {
  187. tree tem = res_ops[0];
  188. res_ops[0] = res_ops[1];
  189. res_ops[1] = tem;
  190. if (TREE_CODE_CLASS ((enum tree_code) *res_code) == tcc_comparison)
  191. *res_code = swap_tree_comparison (*res_code);
  192. canonicalized = true;
  193. }
  194. code_helper res_code2;
  195. tree res_ops2[3] = {};
  196. if (gimple_simplify (&res_code2, res_ops2, seq, valueize,
  197. *res_code, type, res_ops[0], res_ops[1]))
  198. {
  199. *res_code = res_code2;
  200. res_ops[0] = res_ops2[0];
  201. res_ops[1] = res_ops2[1];
  202. res_ops[2] = res_ops2[2];
  203. return true;
  204. }
  205. return canonicalized;
  206. }
  207. /* Helper that matches and simplifies the toplevel result from
  208. a gimple_simplify run (where we don't want to build
  209. a stmt in case it's used in in-place folding). Replaces
  210. *RES_CODE and *RES_OPS with a simplified and/or canonicalized
  211. result and returns whether any change was made. */
  212. static bool
  213. gimple_resimplify3 (gimple_seq *seq,
  214. code_helper *res_code, tree type, tree *res_ops,
  215. tree (*valueize)(tree))
  216. {
  217. if (constant_for_folding (res_ops[0]) && constant_for_folding (res_ops[1])
  218. && constant_for_folding (res_ops[2]))
  219. {
  220. tree tem = NULL_TREE;
  221. if (res_code->is_tree_code ())
  222. tem = fold_ternary/*_to_constant*/ (*res_code, type, res_ops[0],
  223. res_ops[1], res_ops[2]);
  224. else
  225. {
  226. tree decl = builtin_decl_implicit (*res_code);
  227. if (decl)
  228. {
  229. tem = fold_builtin_n (UNKNOWN_LOCATION, decl, res_ops, 3, false);
  230. if (tem)
  231. {
  232. /* fold_builtin_n wraps the result inside a NOP_EXPR. */
  233. STRIP_NOPS (tem);
  234. tem = fold_convert (type, tem);
  235. }
  236. }
  237. }
  238. if (tem != NULL_TREE
  239. && CONSTANT_CLASS_P (tem))
  240. {
  241. res_ops[0] = tem;
  242. res_ops[1] = NULL_TREE;
  243. res_ops[2] = NULL_TREE;
  244. *res_code = TREE_CODE (res_ops[0]);
  245. return true;
  246. }
  247. }
  248. /* Canonicalize operand order. */
  249. bool canonicalized = false;
  250. if (res_code->is_tree_code ()
  251. && commutative_ternary_tree_code (*res_code)
  252. && tree_swap_operands_p (res_ops[0], res_ops[1], false))
  253. {
  254. tree tem = res_ops[0];
  255. res_ops[0] = res_ops[1];
  256. res_ops[1] = tem;
  257. canonicalized = true;
  258. }
  259. code_helper res_code2;
  260. tree res_ops2[3] = {};
  261. if (gimple_simplify (&res_code2, res_ops2, seq, valueize,
  262. *res_code, type,
  263. res_ops[0], res_ops[1], res_ops[2]))
  264. {
  265. *res_code = res_code2;
  266. res_ops[0] = res_ops2[0];
  267. res_ops[1] = res_ops2[1];
  268. res_ops[2] = res_ops2[2];
  269. return true;
  270. }
  271. return canonicalized;
  272. }
  273. /* If in GIMPLE expressions with CODE go as single-rhs build
  274. a GENERIC tree for that expression into *OP0. */
  275. void
  276. maybe_build_generic_op (enum tree_code code, tree type,
  277. tree *op0, tree op1, tree op2)
  278. {
  279. switch (code)
  280. {
  281. case REALPART_EXPR:
  282. case IMAGPART_EXPR:
  283. case VIEW_CONVERT_EXPR:
  284. *op0 = build1 (code, type, *op0);
  285. break;
  286. case BIT_FIELD_REF:
  287. *op0 = build3 (code, type, *op0, op1, op2);
  288. break;
  289. default:;
  290. }
  291. }
  292. /* Push the exploded expression described by RCODE, TYPE and OPS
  293. as a statement to SEQ if necessary and return a gimple value
  294. denoting the value of the expression. If RES is not NULL
  295. then the result will be always RES and even gimple values are
  296. pushed to SEQ. */
  297. tree
  298. maybe_push_res_to_seq (code_helper rcode, tree type, tree *ops,
  299. gimple_seq *seq, tree res)
  300. {
  301. if (rcode.is_tree_code ())
  302. {
  303. if (!res
  304. && (TREE_CODE_LENGTH ((tree_code) rcode) == 0
  305. || ((tree_code) rcode) == ADDR_EXPR)
  306. && is_gimple_val (ops[0]))
  307. return ops[0];
  308. if (!seq)
  309. return NULL_TREE;
  310. /* Play safe and do not allow abnormals to be mentioned in
  311. newly created statements. */
  312. if ((TREE_CODE (ops[0]) == SSA_NAME
  313. && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[0]))
  314. || (ops[1]
  315. && TREE_CODE (ops[1]) == SSA_NAME
  316. && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[1]))
  317. || (ops[2]
  318. && TREE_CODE (ops[2]) == SSA_NAME
  319. && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2])))
  320. return NULL_TREE;
  321. if (!res)
  322. res = make_ssa_name (type);
  323. maybe_build_generic_op (rcode, type, &ops[0], ops[1], ops[2]);
  324. gimple new_stmt = gimple_build_assign (res, rcode,
  325. ops[0], ops[1], ops[2]);
  326. gimple_seq_add_stmt_without_update (seq, new_stmt);
  327. return res;
  328. }
  329. else
  330. {
  331. if (!seq)
  332. return NULL_TREE;
  333. tree decl = builtin_decl_implicit (rcode);
  334. if (!decl)
  335. return NULL_TREE;
  336. unsigned nargs = type_num_arguments (TREE_TYPE (decl));
  337. gcc_assert (nargs <= 3);
  338. /* Play safe and do not allow abnormals to be mentioned in
  339. newly created statements. */
  340. if ((TREE_CODE (ops[0]) == SSA_NAME
  341. && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[0]))
  342. || (nargs >= 2
  343. && TREE_CODE (ops[1]) == SSA_NAME
  344. && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[1]))
  345. || (nargs == 3
  346. && TREE_CODE (ops[2]) == SSA_NAME
  347. && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2])))
  348. return NULL_TREE;
  349. if (!res)
  350. res = make_ssa_name (type);
  351. gimple new_stmt = gimple_build_call (decl, nargs, ops[0], ops[1], ops[2]);
  352. gimple_call_set_lhs (new_stmt, res);
  353. gimple_seq_add_stmt_without_update (seq, new_stmt);
  354. return res;
  355. }
  356. }
  357. /* Public API overloads follow for operation being tree_code or
  358. built_in_function and for one to three operands or arguments.
  359. They return NULL_TREE if nothing could be simplified or
  360. the resulting simplified value with parts pushed to SEQ.
  361. If SEQ is NULL then if the simplification needs to create
  362. new stmts it will fail. If VALUEIZE is non-NULL then all
  363. SSA names will be valueized using that hook prior to
  364. applying simplifications. */
  365. /* Unary ops. */
  366. tree
  367. gimple_simplify (enum tree_code code, tree type,
  368. tree op0,
  369. gimple_seq *seq, tree (*valueize)(tree))
  370. {
  371. if (constant_for_folding (op0))
  372. {
  373. tree res = const_unop (code, type, op0);
  374. if (res != NULL_TREE
  375. && CONSTANT_CLASS_P (res))
  376. return res;
  377. }
  378. code_helper rcode;
  379. tree ops[3] = {};
  380. if (!gimple_simplify (&rcode, ops, seq, valueize,
  381. code, type, op0))
  382. return NULL_TREE;
  383. return maybe_push_res_to_seq (rcode, type, ops, seq);
  384. }
  385. /* Binary ops. */
  386. tree
  387. gimple_simplify (enum tree_code code, tree type,
  388. tree op0, tree op1,
  389. gimple_seq *seq, tree (*valueize)(tree))
  390. {
  391. if (constant_for_folding (op0) && constant_for_folding (op1))
  392. {
  393. tree res = const_binop (code, type, op0, op1);
  394. if (res != NULL_TREE
  395. && CONSTANT_CLASS_P (res))
  396. return res;
  397. }
  398. /* Canonicalize operand order both for matching and fallback stmt
  399. generation. */
  400. if ((commutative_tree_code (code)
  401. || TREE_CODE_CLASS (code) == tcc_comparison)
  402. && tree_swap_operands_p (op0, op1, false))
  403. {
  404. tree tem = op0;
  405. op0 = op1;
  406. op1 = tem;
  407. if (TREE_CODE_CLASS (code) == tcc_comparison)
  408. code = swap_tree_comparison (code);
  409. }
  410. code_helper rcode;
  411. tree ops[3] = {};
  412. if (!gimple_simplify (&rcode, ops, seq, valueize,
  413. code, type, op0, op1))
  414. return NULL_TREE;
  415. return maybe_push_res_to_seq (rcode, type, ops, seq);
  416. }
  417. /* Ternary ops. */
  418. tree
  419. gimple_simplify (enum tree_code code, tree type,
  420. tree op0, tree op1, tree op2,
  421. gimple_seq *seq, tree (*valueize)(tree))
  422. {
  423. if (constant_for_folding (op0) && constant_for_folding (op1)
  424. && constant_for_folding (op2))
  425. {
  426. tree res = fold_ternary/*_to_constant */ (code, type, op0, op1, op2);
  427. if (res != NULL_TREE
  428. && CONSTANT_CLASS_P (res))
  429. return res;
  430. }
  431. /* Canonicalize operand order both for matching and fallback stmt
  432. generation. */
  433. if (commutative_ternary_tree_code (code)
  434. && tree_swap_operands_p (op0, op1, false))
  435. {
  436. tree tem = op0;
  437. op0 = op1;
  438. op1 = tem;
  439. }
  440. code_helper rcode;
  441. tree ops[3] = {};
  442. if (!gimple_simplify (&rcode, ops, seq, valueize,
  443. code, type, op0, op1, op2))
  444. return NULL_TREE;
  445. return maybe_push_res_to_seq (rcode, type, ops, seq);
  446. }
  447. /* Builtin function with one argument. */
  448. tree
  449. gimple_simplify (enum built_in_function fn, tree type,
  450. tree arg0,
  451. gimple_seq *seq, tree (*valueize)(tree))
  452. {
  453. if (constant_for_folding (arg0))
  454. {
  455. tree decl = builtin_decl_implicit (fn);
  456. if (decl)
  457. {
  458. tree res = fold_builtin_n (UNKNOWN_LOCATION, decl, &arg0, 1, false);
  459. if (res)
  460. {
  461. /* fold_builtin_n wraps the result inside a NOP_EXPR. */
  462. STRIP_NOPS (res);
  463. res = fold_convert (type, res);
  464. if (CONSTANT_CLASS_P (res))
  465. return res;
  466. }
  467. }
  468. }
  469. code_helper rcode;
  470. tree ops[3] = {};
  471. if (!gimple_simplify (&rcode, ops, seq, valueize,
  472. fn, type, arg0))
  473. return NULL_TREE;
  474. return maybe_push_res_to_seq (rcode, type, ops, seq);
  475. }
  476. /* Builtin function with two arguments. */
  477. tree
  478. gimple_simplify (enum built_in_function fn, tree type,
  479. tree arg0, tree arg1,
  480. gimple_seq *seq, tree (*valueize)(tree))
  481. {
  482. if (constant_for_folding (arg0)
  483. && constant_for_folding (arg1))
  484. {
  485. tree decl = builtin_decl_implicit (fn);
  486. if (decl)
  487. {
  488. tree args[2];
  489. args[0] = arg0;
  490. args[1] = arg1;
  491. tree res = fold_builtin_n (UNKNOWN_LOCATION, decl, args, 2, false);
  492. if (res)
  493. {
  494. /* fold_builtin_n wraps the result inside a NOP_EXPR. */
  495. STRIP_NOPS (res);
  496. res = fold_convert (type, res);
  497. if (CONSTANT_CLASS_P (res))
  498. return res;
  499. }
  500. }
  501. }
  502. code_helper rcode;
  503. tree ops[3] = {};
  504. if (!gimple_simplify (&rcode, ops, seq, valueize,
  505. fn, type, arg0, arg1))
  506. return NULL_TREE;
  507. return maybe_push_res_to_seq (rcode, type, ops, seq);
  508. }
  509. /* Builtin function with three arguments. */
  510. tree
  511. gimple_simplify (enum built_in_function fn, tree type,
  512. tree arg0, tree arg1, tree arg2,
  513. gimple_seq *seq, tree (*valueize)(tree))
  514. {
  515. if (constant_for_folding (arg0)
  516. && constant_for_folding (arg1)
  517. && constant_for_folding (arg2))
  518. {
  519. tree decl = builtin_decl_implicit (fn);
  520. if (decl)
  521. {
  522. tree args[3];
  523. args[0] = arg0;
  524. args[1] = arg1;
  525. args[2] = arg2;
  526. tree res = fold_builtin_n (UNKNOWN_LOCATION, decl, args, 3, false);
  527. if (res)
  528. {
  529. /* fold_builtin_n wraps the result inside a NOP_EXPR. */
  530. STRIP_NOPS (res);
  531. res = fold_convert (type, res);
  532. if (CONSTANT_CLASS_P (res))
  533. return res;
  534. }
  535. }
  536. }
  537. code_helper rcode;
  538. tree ops[3] = {};
  539. if (!gimple_simplify (&rcode, ops, seq, valueize,
  540. fn, type, arg0, arg1, arg2))
  541. return NULL_TREE;
  542. return maybe_push_res_to_seq (rcode, type, ops, seq);
  543. }
  544. /* The main STMT based simplification entry. It is used by the fold_stmt
  545. and the fold_stmt_to_constant APIs. */
  546. bool
  547. gimple_simplify (gimple stmt,
  548. code_helper *rcode, tree *ops,
  549. gimple_seq *seq, tree (*valueize)(tree))
  550. {
  551. switch (gimple_code (stmt))
  552. {
  553. case GIMPLE_ASSIGN:
  554. {
  555. enum tree_code code = gimple_assign_rhs_code (stmt);
  556. tree type = TREE_TYPE (gimple_assign_lhs (stmt));
  557. switch (gimple_assign_rhs_class (stmt))
  558. {
  559. case GIMPLE_SINGLE_RHS:
  560. if (code == REALPART_EXPR
  561. || code == IMAGPART_EXPR
  562. || code == VIEW_CONVERT_EXPR)
  563. {
  564. tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0);
  565. if (valueize && TREE_CODE (op0) == SSA_NAME)
  566. {
  567. tree tem = valueize (op0);
  568. if (tem)
  569. op0 = tem;
  570. }
  571. *rcode = code;
  572. ops[0] = op0;
  573. return gimple_resimplify1 (seq, rcode, type, ops, valueize);
  574. }
  575. else if (code == BIT_FIELD_REF)
  576. {
  577. tree rhs1 = gimple_assign_rhs1 (stmt);
  578. tree op0 = TREE_OPERAND (rhs1, 0);
  579. if (valueize && TREE_CODE (op0) == SSA_NAME)
  580. {
  581. tree tem = valueize (op0);
  582. if (tem)
  583. op0 = tem;
  584. }
  585. *rcode = code;
  586. ops[0] = op0;
  587. ops[1] = TREE_OPERAND (rhs1, 1);
  588. ops[2] = TREE_OPERAND (rhs1, 2);
  589. return gimple_resimplify3 (seq, rcode, type, ops, valueize);
  590. }
  591. else if (code == SSA_NAME
  592. && valueize)
  593. {
  594. tree op0 = gimple_assign_rhs1 (stmt);
  595. tree valueized = valueize (op0);
  596. if (!valueized || op0 == valueized)
  597. return false;
  598. ops[0] = valueized;
  599. *rcode = TREE_CODE (op0);
  600. return true;
  601. }
  602. break;
  603. case GIMPLE_UNARY_RHS:
  604. {
  605. tree rhs1 = gimple_assign_rhs1 (stmt);
  606. if (valueize && TREE_CODE (rhs1) == SSA_NAME)
  607. {
  608. tree tem = valueize (rhs1);
  609. if (tem)
  610. rhs1 = tem;
  611. }
  612. *rcode = code;
  613. ops[0] = rhs1;
  614. return gimple_resimplify1 (seq, rcode, type, ops, valueize);
  615. }
  616. case GIMPLE_BINARY_RHS:
  617. {
  618. tree rhs1 = gimple_assign_rhs1 (stmt);
  619. if (valueize && TREE_CODE (rhs1) == SSA_NAME)
  620. {
  621. tree tem = valueize (rhs1);
  622. if (tem)
  623. rhs1 = tem;
  624. }
  625. tree rhs2 = gimple_assign_rhs2 (stmt);
  626. if (valueize && TREE_CODE (rhs2) == SSA_NAME)
  627. {
  628. tree tem = valueize (rhs2);
  629. if (tem)
  630. rhs2 = tem;
  631. }
  632. *rcode = code;
  633. ops[0] = rhs1;
  634. ops[1] = rhs2;
  635. return gimple_resimplify2 (seq, rcode, type, ops, valueize);
  636. }
  637. case GIMPLE_TERNARY_RHS:
  638. {
  639. tree rhs1 = gimple_assign_rhs1 (stmt);
  640. if (valueize && TREE_CODE (rhs1) == SSA_NAME)
  641. {
  642. tree tem = valueize (rhs1);
  643. if (tem)
  644. rhs1 = tem;
  645. }
  646. tree rhs2 = gimple_assign_rhs2 (stmt);
  647. if (valueize && TREE_CODE (rhs2) == SSA_NAME)
  648. {
  649. tree tem = valueize (rhs2);
  650. if (tem)
  651. rhs2 = tem;
  652. }
  653. tree rhs3 = gimple_assign_rhs3 (stmt);
  654. if (valueize && TREE_CODE (rhs3) == SSA_NAME)
  655. {
  656. tree tem = valueize (rhs3);
  657. if (tem)
  658. rhs3 = tem;
  659. }
  660. *rcode = code;
  661. ops[0] = rhs1;
  662. ops[1] = rhs2;
  663. ops[2] = rhs3;
  664. return gimple_resimplify3 (seq, rcode, type, ops, valueize);
  665. }
  666. default:
  667. gcc_unreachable ();
  668. }
  669. break;
  670. }
  671. case GIMPLE_CALL:
  672. /* ??? This way we can't simplify calls with side-effects. */
  673. if (gimple_call_lhs (stmt) != NULL_TREE)
  674. {
  675. tree fn = gimple_call_fn (stmt);
  676. /* ??? Internal function support missing. */
  677. if (!fn)
  678. return false;
  679. if (valueize && TREE_CODE (fn) == SSA_NAME)
  680. {
  681. tree tem = valueize (fn);
  682. if (tem)
  683. fn = tem;
  684. }
  685. if (!fn
  686. || TREE_CODE (fn) != ADDR_EXPR
  687. || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL
  688. || DECL_BUILT_IN_CLASS (TREE_OPERAND (fn, 0)) != BUILT_IN_NORMAL
  689. || !builtin_decl_implicit (DECL_FUNCTION_CODE (TREE_OPERAND (fn, 0)))
  690. || !gimple_builtin_call_types_compatible_p (stmt,
  691. TREE_OPERAND (fn, 0)))
  692. return false;
  693. tree decl = TREE_OPERAND (fn, 0);
  694. tree type = TREE_TYPE (gimple_call_lhs (stmt));
  695. switch (gimple_call_num_args (stmt))
  696. {
  697. case 1:
  698. {
  699. tree arg1 = gimple_call_arg (stmt, 0);
  700. if (valueize && TREE_CODE (arg1) == SSA_NAME)
  701. {
  702. tree tem = valueize (arg1);
  703. if (tem)
  704. arg1 = tem;
  705. }
  706. *rcode = DECL_FUNCTION_CODE (decl);
  707. ops[0] = arg1;
  708. return gimple_resimplify1 (seq, rcode, type, ops, valueize);
  709. }
  710. case 2:
  711. {
  712. tree arg1 = gimple_call_arg (stmt, 0);
  713. if (valueize && TREE_CODE (arg1) == SSA_NAME)
  714. {
  715. tree tem = valueize (arg1);
  716. if (tem)
  717. arg1 = tem;
  718. }
  719. tree arg2 = gimple_call_arg (stmt, 1);
  720. if (valueize && TREE_CODE (arg2) == SSA_NAME)
  721. {
  722. tree tem = valueize (arg2);
  723. if (tem)
  724. arg2 = tem;
  725. }
  726. *rcode = DECL_FUNCTION_CODE (decl);
  727. ops[0] = arg1;
  728. ops[1] = arg2;
  729. return gimple_resimplify2 (seq, rcode, type, ops, valueize);
  730. }
  731. case 3:
  732. {
  733. tree arg1 = gimple_call_arg (stmt, 0);
  734. if (valueize && TREE_CODE (arg1) == SSA_NAME)
  735. {
  736. tree tem = valueize (arg1);
  737. if (tem)
  738. arg1 = tem;
  739. }
  740. tree arg2 = gimple_call_arg (stmt, 1);
  741. if (valueize && TREE_CODE (arg2) == SSA_NAME)
  742. {
  743. tree tem = valueize (arg2);
  744. if (tem)
  745. arg2 = tem;
  746. }
  747. tree arg3 = gimple_call_arg (stmt, 2);
  748. if (valueize && TREE_CODE (arg3) == SSA_NAME)
  749. {
  750. tree tem = valueize (arg3);
  751. if (tem)
  752. arg3 = tem;
  753. }
  754. *rcode = DECL_FUNCTION_CODE (decl);
  755. ops[0] = arg1;
  756. ops[1] = arg2;
  757. ops[2] = arg3;
  758. return gimple_resimplify3 (seq, rcode, type, ops, valueize);
  759. }
  760. default:
  761. return false;
  762. }
  763. }
  764. break;
  765. case GIMPLE_COND:
  766. {
  767. tree lhs = gimple_cond_lhs (stmt);
  768. if (valueize && TREE_CODE (lhs) == SSA_NAME)
  769. {
  770. tree tem = valueize (lhs);
  771. if (tem)
  772. lhs = tem;
  773. }
  774. tree rhs = gimple_cond_rhs (stmt);
  775. if (valueize && TREE_CODE (rhs) == SSA_NAME)
  776. {
  777. tree tem = valueize (rhs);
  778. if (tem)
  779. rhs = tem;
  780. }
  781. *rcode = gimple_cond_code (stmt);
  782. ops[0] = lhs;
  783. ops[1] = rhs;
  784. return gimple_resimplify2 (seq, rcode, boolean_type_node, ops, valueize);
  785. }
  786. default:
  787. break;
  788. }
  789. return false;
  790. }
  791. /* Helper for the autogenerated code, valueize OP. */
  792. inline tree
  793. do_valueize (tree (*valueize)(tree), tree op)
  794. {
  795. if (valueize && TREE_CODE (op) == SSA_NAME)
  796. return valueize (op);
  797. return op;
  798. }