1 /* Preamble and helpers for the autogenerated gimple-match.c file. 2 Copyright (C) 2014-2018 Free Software Foundation, Inc. 3 4 This file is part of GCC. 5 6 GCC is free software; you can redistribute it and/or modify it under 7 the terms of the GNU General Public License as published by the Free 8 Software Foundation; either version 3, or (at your option) any later 9 version. 10 11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 12 WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GCC; see the file COPYING3. If not see 18 <http://www.gnu.org/licenses/>. */ 19 20 #include "config.h" 21 #include "system.h" 22 #include "coretypes.h" 23 #include "backend.h" 24 #include "target.h" 25 #include "rtl.h" 26 #include "tree.h" 27 #include "gimple.h" 28 #include "ssa.h" 29 #include "cgraph.h" 30 #include "fold-const.h" 31 #include "fold-const-call.h" 32 #include "stor-layout.h" 33 #include "gimple-fold.h" 34 #include "calls.h" 35 #include "tree-dfa.h" 36 #include "builtins.h" 37 #include "gimple-match.h" 38 #include "tree-pass.h" 39 #include "internal-fn.h" 40 #include "case-cfn-macros.h" 41 #include "gimplify.h" 42 #include "optabs-tree.h" 43 44 45 /* Forward declarations of the private auto-generated matchers. 46 They expect valueized operands in canonical order and do not 47 perform simplification of all-constant operands. */ 48 static bool gimple_simplify (code_helper *, tree *, 49 gimple_seq *, tree (*)(tree), 50 code_helper, tree, tree); 51 static bool gimple_simplify (code_helper *, tree *, 52 gimple_seq *, tree (*)(tree), 53 code_helper, tree, tree, tree); 54 static bool gimple_simplify (code_helper *, tree *, 55 gimple_seq *, tree (*)(tree), 56 code_helper, tree, tree, tree, tree); 57 58 59 /* Return whether T is a constant that we'll dispatch to fold to 60 evaluate fully constant expressions. */ 61 62 static inline bool 63 constant_for_folding (tree t) 64 { 65 return (CONSTANT_CLASS_P (t) 66 /* The following is only interesting to string builtins. */ 67 || (TREE_CODE (t) == ADDR_EXPR 68 && TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST)); 69 } 70 71 72 /* Helper that matches and simplifies the toplevel result from 73 a gimple_simplify run (where we don't want to build 74 a stmt in case it's used in in-place folding). Replaces 75 *RES_CODE and *RES_OPS with a simplified and/or canonicalized 76 result and returns whether any change was made. */ 77 78 bool 79 gimple_resimplify1 (gimple_seq *seq, 80 code_helper *res_code, tree type, tree *res_ops, 81 tree (*valueize)(tree)) 82 { 83 if (constant_for_folding (res_ops[0])) 84 { 85 tree tem = NULL_TREE; 86 if (res_code->is_tree_code ()) 87 tem = const_unop (*res_code, type, res_ops[0]); 88 else 89 tem = fold_const_call (combined_fn (*res_code), type, res_ops[0]); 90 if (tem != NULL_TREE 91 && CONSTANT_CLASS_P (tem)) 92 { 93 if (TREE_OVERFLOW_P (tem)) 94 tem = drop_tree_overflow (tem); 95 res_ops[0] = tem; 96 res_ops[1] = NULL_TREE; 97 res_ops[2] = NULL_TREE; 98 *res_code = TREE_CODE (res_ops[0]); 99 return true; 100 } 101 } 102 103 code_helper res_code2; 104 tree res_ops2[3] = {}; 105 if (gimple_simplify (&res_code2, res_ops2, seq, valueize, 106 *res_code, type, res_ops[0])) 107 { 108 *res_code = res_code2; 109 res_ops[0] = res_ops2[0]; 110 res_ops[1] = res_ops2[1]; 111 res_ops[2] = res_ops2[2]; 112 return true; 113 } 114 115 return false; 116 } 117 118 /* Helper that matches and simplifies the toplevel result from 119 a gimple_simplify run (where we don't want to build 120 a stmt in case it's used in in-place folding). Replaces 121 *RES_CODE and *RES_OPS with a simplified and/or canonicalized 122 result and returns whether any change was made. */ 123 124 bool 125 gimple_resimplify2 (gimple_seq *seq, 126 code_helper *res_code, tree type, tree *res_ops, 127 tree (*valueize)(tree)) 128 { 129 if (constant_for_folding (res_ops[0]) && constant_for_folding (res_ops[1])) 130 { 131 tree tem = NULL_TREE; 132 if (res_code->is_tree_code ()) 133 tem = const_binop (*res_code, type, res_ops[0], res_ops[1]); 134 else 135 tem = fold_const_call (combined_fn (*res_code), type, 136 res_ops[0], res_ops[1]); 137 if (tem != NULL_TREE 138 && CONSTANT_CLASS_P (tem)) 139 { 140 if (TREE_OVERFLOW_P (tem)) 141 tem = drop_tree_overflow (tem); 142 res_ops[0] = tem; 143 res_ops[1] = NULL_TREE; 144 res_ops[2] = NULL_TREE; 145 *res_code = TREE_CODE (res_ops[0]); 146 return true; 147 } 148 } 149 150 /* Canonicalize operand order. */ 151 bool canonicalized = false; 152 if (res_code->is_tree_code () 153 && (TREE_CODE_CLASS ((enum tree_code) *res_code) == tcc_comparison 154 || commutative_tree_code (*res_code)) 155 && tree_swap_operands_p (res_ops[0], res_ops[1])) 156 { 157 std::swap (res_ops[0], res_ops[1]); 158 if (TREE_CODE_CLASS ((enum tree_code) *res_code) == tcc_comparison) 159 *res_code = swap_tree_comparison (*res_code); 160 canonicalized = true; 161 } 162 163 code_helper res_code2; 164 tree res_ops2[3] = {}; 165 if (gimple_simplify (&res_code2, res_ops2, seq, valueize, 166 *res_code, type, res_ops[0], res_ops[1])) 167 { 168 *res_code = res_code2; 169 res_ops[0] = res_ops2[0]; 170 res_ops[1] = res_ops2[1]; 171 res_ops[2] = res_ops2[2]; 172 return true; 173 } 174 175 return canonicalized; 176 } 177 178 /* Helper that matches and simplifies the toplevel result from 179 a gimple_simplify run (where we don't want to build 180 a stmt in case it's used in in-place folding). Replaces 181 *RES_CODE and *RES_OPS with a simplified and/or canonicalized 182 result and returns whether any change was made. */ 183 184 bool 185 gimple_resimplify3 (gimple_seq *seq, 186 code_helper *res_code, tree type, tree *res_ops, 187 tree (*valueize)(tree)) 188 { 189 if (constant_for_folding (res_ops[0]) && constant_for_folding (res_ops[1]) 190 && constant_for_folding (res_ops[2])) 191 { 192 tree tem = NULL_TREE; 193 if (res_code->is_tree_code ()) 194 tem = fold_ternary/*_to_constant*/ (*res_code, type, res_ops[0], 195 res_ops[1], res_ops[2]); 196 else 197 tem = fold_const_call (combined_fn (*res_code), type, 198 res_ops[0], res_ops[1], res_ops[2]); 199 if (tem != NULL_TREE 200 && CONSTANT_CLASS_P (tem)) 201 { 202 if (TREE_OVERFLOW_P (tem)) 203 tem = drop_tree_overflow (tem); 204 res_ops[0] = tem; 205 res_ops[1] = NULL_TREE; 206 res_ops[2] = NULL_TREE; 207 *res_code = TREE_CODE (res_ops[0]); 208 return true; 209 } 210 } 211 212 /* Canonicalize operand order. */ 213 bool canonicalized = false; 214 if (res_code->is_tree_code () 215 && commutative_ternary_tree_code (*res_code) 216 && tree_swap_operands_p (res_ops[0], res_ops[1])) 217 { 218 std::swap (res_ops[0], res_ops[1]); 219 canonicalized = true; 220 } 221 222 code_helper res_code2; 223 tree res_ops2[3] = {}; 224 if (gimple_simplify (&res_code2, res_ops2, seq, valueize, 225 *res_code, type, 226 res_ops[0], res_ops[1], res_ops[2])) 227 { 228 *res_code = res_code2; 229 res_ops[0] = res_ops2[0]; 230 res_ops[1] = res_ops2[1]; 231 res_ops[2] = res_ops2[2]; 232 return true; 233 } 234 235 return canonicalized; 236 } 237 238 239 /* If in GIMPLE expressions with CODE go as single-rhs build 240 a GENERIC tree for that expression into *OP0. */ 241 242 void 243 maybe_build_generic_op (enum tree_code code, tree type, tree *ops) 244 { 245 switch (code) 246 { 247 case REALPART_EXPR: 248 case IMAGPART_EXPR: 249 case VIEW_CONVERT_EXPR: 250 ops[0] = build1 (code, type, ops[0]); 251 break; 252 case BIT_FIELD_REF: 253 ops[0] = build3 (code, type, ops[0], ops[1], ops[2]); 254 ops[1] = ops[2] = NULL_TREE; 255 break; 256 default:; 257 } 258 } 259 260 tree (*mprts_hook) (code_helper, tree, tree *); 261 262 /* Try to build a call to FN with return type TYPE and the NARGS 263 arguments given in OPS. Return null if the target doesn't support 264 the function. */ 265 266 static gcall * 267 build_call_internal (internal_fn fn, tree type, unsigned int nargs, tree *ops) 268 { 269 if (direct_internal_fn_p (fn)) 270 { 271 tree_pair types = direct_internal_fn_types (fn, type, ops); 272 if (!direct_internal_fn_supported_p (fn, types, OPTIMIZE_FOR_BOTH)) 273 return NULL; 274 } 275 return gimple_build_call_internal (fn, nargs, ops[0], ops[1], ops[2]); 276 } 277 278 /* Push the exploded expression described by RCODE, TYPE and OPS 279 as a statement to SEQ if necessary and return a gimple value 280 denoting the value of the expression. If RES is not NULL 281 then the result will be always RES and even gimple values are 282 pushed to SEQ. */ 283 284 tree 285 maybe_push_res_to_seq (code_helper rcode, tree type, tree *ops, 286 gimple_seq *seq, tree res) 287 { 288 if (rcode.is_tree_code ()) 289 { 290 if (!res 291 && gimple_simplified_result_is_gimple_val (rcode, ops)) 292 return ops[0]; 293 if (mprts_hook) 294 { 295 tree tem = mprts_hook (rcode, type, ops); 296 if (tem) 297 return tem; 298 } 299 if (!seq) 300 return NULL_TREE; 301 /* Play safe and do not allow abnormals to be mentioned in 302 newly created statements. */ 303 if ((TREE_CODE (ops[0]) == SSA_NAME 304 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[0])) 305 || (ops[1] 306 && TREE_CODE (ops[1]) == SSA_NAME 307 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[1])) 308 || (ops[2] 309 && TREE_CODE (ops[2]) == SSA_NAME 310 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[2])) 311 || (COMPARISON_CLASS_P (ops[0]) 312 && ((TREE_CODE (TREE_OPERAND (ops[0], 0)) == SSA_NAME 313 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (ops[0], 314 0))) 315 || (TREE_CODE (TREE_OPERAND (ops[0], 1)) == SSA_NAME 316 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (TREE_OPERAND (ops[0], 317 1)))))) 318 return NULL_TREE; 319 if (!res) 320 { 321 if (gimple_in_ssa_p (cfun)) 322 res = make_ssa_name (type); 323 else 324 res = create_tmp_reg (type); 325 } 326 maybe_build_generic_op (rcode, type, ops); 327 gimple *new_stmt = gimple_build_assign (res, rcode, 328 ops[0], ops[1], ops[2]); 329 gimple_seq_add_stmt_without_update (seq, new_stmt); 330 return res; 331 } 332 else 333 { 334 if (!seq) 335 return NULL_TREE; 336 combined_fn fn = rcode; 337 /* Play safe and do not allow abnormals to be mentioned in 338 newly created statements. */ 339 unsigned nargs; 340 for (nargs = 0; nargs < 3; ++nargs) 341 { 342 if (!ops[nargs]) 343 break; 344 if (TREE_CODE (ops[nargs]) == SSA_NAME 345 && SSA_NAME_OCCURS_IN_ABNORMAL_PHI (ops[nargs])) 346 return NULL_TREE; 347 } 348 gcc_assert (nargs != 0); 349 gcall *new_stmt = NULL; 350 if (internal_fn_p (fn)) 351 { 352 /* Generate the given function if we can. */ 353 internal_fn ifn = as_internal_fn (fn); 354 new_stmt = build_call_internal (ifn, type, nargs, ops); 355 if (!new_stmt) 356 return NULL_TREE; 357 } 358 else 359 { 360 /* Find the function we want to call. */ 361 tree decl = builtin_decl_implicit (as_builtin_fn (fn)); 362 if (!decl) 363 return NULL; 364 365 /* We can't and should not emit calls to non-const functions. */ 366 if (!(flags_from_decl_or_type (decl) & ECF_CONST)) 367 return NULL; 368 369 new_stmt = gimple_build_call (decl, nargs, ops[0], ops[1], ops[2]); 370 } 371 if (!res) 372 { 373 if (gimple_in_ssa_p (cfun)) 374 res = make_ssa_name (type); 375 else 376 res = create_tmp_reg (type); 377 } 378 gimple_call_set_lhs (new_stmt, res); 379 gimple_seq_add_stmt_without_update (seq, new_stmt); 380 return res; 381 } 382 } 383 384 385 /* Public API overloads follow for operation being tree_code or 386 built_in_function and for one to three operands or arguments. 387 They return NULL_TREE if nothing could be simplified or 388 the resulting simplified value with parts pushed to SEQ. 389 If SEQ is NULL then if the simplification needs to create 390 new stmts it will fail. If VALUEIZE is non-NULL then all 391 SSA names will be valueized using that hook prior to 392 applying simplifications. */ 393 394 /* Unary ops. */ 395 396 tree 397 gimple_simplify (enum tree_code code, tree type, 398 tree op0, 399 gimple_seq *seq, tree (*valueize)(tree)) 400 { 401 if (constant_for_folding (op0)) 402 { 403 tree res = const_unop (code, type, op0); 404 if (res != NULL_TREE 405 && CONSTANT_CLASS_P (res)) 406 return res; 407 } 408 409 code_helper rcode; 410 tree ops[3] = {}; 411 if (!gimple_simplify (&rcode, ops, seq, valueize, 412 code, type, op0)) 413 return NULL_TREE; 414 return maybe_push_res_to_seq (rcode, type, ops, seq); 415 } 416 417 /* Binary ops. */ 418 419 tree 420 gimple_simplify (enum tree_code code, tree type, 421 tree op0, tree op1, 422 gimple_seq *seq, tree (*valueize)(tree)) 423 { 424 if (constant_for_folding (op0) && constant_for_folding (op1)) 425 { 426 tree res = const_binop (code, type, op0, op1); 427 if (res != NULL_TREE 428 && CONSTANT_CLASS_P (res)) 429 return res; 430 } 431 432 /* Canonicalize operand order both for matching and fallback stmt 433 generation. */ 434 if ((commutative_tree_code (code) 435 || TREE_CODE_CLASS (code) == tcc_comparison) 436 && tree_swap_operands_p (op0, op1)) 437 { 438 std::swap (op0, op1); 439 if (TREE_CODE_CLASS (code) == tcc_comparison) 440 code = swap_tree_comparison (code); 441 } 442 443 code_helper rcode; 444 tree ops[3] = {}; 445 if (!gimple_simplify (&rcode, ops, seq, valueize, 446 code, type, op0, op1)) 447 return NULL_TREE; 448 return maybe_push_res_to_seq (rcode, type, ops, seq); 449 } 450 451 /* Ternary ops. */ 452 453 tree 454 gimple_simplify (enum tree_code code, tree type, 455 tree op0, tree op1, tree op2, 456 gimple_seq *seq, tree (*valueize)(tree)) 457 { 458 if (constant_for_folding (op0) && constant_for_folding (op1) 459 && constant_for_folding (op2)) 460 { 461 tree res = fold_ternary/*_to_constant */ (code, type, op0, op1, op2); 462 if (res != NULL_TREE 463 && CONSTANT_CLASS_P (res)) 464 return res; 465 } 466 467 /* Canonicalize operand order both for matching and fallback stmt 468 generation. */ 469 if (commutative_ternary_tree_code (code) 470 && tree_swap_operands_p (op0, op1)) 471 std::swap (op0, op1); 472 473 code_helper rcode; 474 tree ops[3] = {}; 475 if (!gimple_simplify (&rcode, ops, seq, valueize, 476 code, type, op0, op1, op2)) 477 return NULL_TREE; 478 return maybe_push_res_to_seq (rcode, type, ops, seq); 479 } 480 481 /* Builtin function with one argument. */ 482 483 tree 484 gimple_simplify (enum built_in_function fn, tree type, 485 tree arg0, 486 gimple_seq *seq, tree (*valueize)(tree)) 487 { 488 if (constant_for_folding (arg0)) 489 { 490 tree res = fold_const_call (as_combined_fn (fn), type, arg0); 491 if (res && CONSTANT_CLASS_P (res)) 492 return res; 493 } 494 495 code_helper rcode; 496 tree ops[3] = {}; 497 if (!gimple_simplify (&rcode, ops, seq, valueize, 498 as_combined_fn (fn), type, arg0)) 499 return NULL_TREE; 500 return maybe_push_res_to_seq (rcode, type, ops, seq); 501 } 502 503 /* Builtin function with two arguments. */ 504 505 tree 506 gimple_simplify (enum built_in_function fn, tree type, 507 tree arg0, tree arg1, 508 gimple_seq *seq, tree (*valueize)(tree)) 509 { 510 if (constant_for_folding (arg0) 511 && constant_for_folding (arg1)) 512 { 513 tree res = fold_const_call (as_combined_fn (fn), type, arg0, arg1); 514 if (res && CONSTANT_CLASS_P (res)) 515 return res; 516 } 517 518 code_helper rcode; 519 tree ops[3] = {}; 520 if (!gimple_simplify (&rcode, ops, seq, valueize, 521 as_combined_fn (fn), type, arg0, arg1)) 522 return NULL_TREE; 523 return maybe_push_res_to_seq (rcode, type, ops, seq); 524 } 525 526 /* Builtin function with three arguments. */ 527 528 tree 529 gimple_simplify (enum built_in_function fn, tree type, 530 tree arg0, tree arg1, tree arg2, 531 gimple_seq *seq, tree (*valueize)(tree)) 532 { 533 if (constant_for_folding (arg0) 534 && constant_for_folding (arg1) 535 && constant_for_folding (arg2)) 536 { 537 tree res = fold_const_call (as_combined_fn (fn), type, arg0, arg1, arg2); 538 if (res && CONSTANT_CLASS_P (res)) 539 return res; 540 } 541 542 code_helper rcode; 543 tree ops[3] = {}; 544 if (!gimple_simplify (&rcode, ops, seq, valueize, 545 as_combined_fn (fn), type, arg0, arg1, arg2)) 546 return NULL_TREE; 547 return maybe_push_res_to_seq (rcode, type, ops, seq); 548 } 549 550 /* Helper for gimple_simplify valueizing OP using VALUEIZE and setting 551 VALUEIZED to true if valueization changed OP. */ 552 553 static inline tree 554 do_valueize (tree op, tree (*valueize)(tree), bool &valueized) 555 { 556 if (valueize && TREE_CODE (op) == SSA_NAME) 557 { 558 tree tem = valueize (op); 559 if (tem && tem != op) 560 { 561 op = tem; 562 valueized = true; 563 } 564 } 565 return op; 566 } 567 568 /* The main STMT based simplification entry. It is used by the fold_stmt 569 and the fold_stmt_to_constant APIs. */ 570 571 bool 572 gimple_simplify (gimple *stmt, 573 code_helper *rcode, tree *ops, 574 gimple_seq *seq, 575 tree (*valueize)(tree), tree (*top_valueize)(tree)) 576 { 577 switch (gimple_code (stmt)) 578 { 579 case GIMPLE_ASSIGN: 580 { 581 enum tree_code code = gimple_assign_rhs_code (stmt); 582 tree type = TREE_TYPE (gimple_assign_lhs (stmt)); 583 switch (gimple_assign_rhs_class (stmt)) 584 { 585 case GIMPLE_SINGLE_RHS: 586 if (code == REALPART_EXPR 587 || code == IMAGPART_EXPR 588 || code == VIEW_CONVERT_EXPR) 589 { 590 tree op0 = TREE_OPERAND (gimple_assign_rhs1 (stmt), 0); 591 bool valueized = false; 592 op0 = do_valueize (op0, top_valueize, valueized); 593 *rcode = code; 594 ops[0] = op0; 595 return (gimple_resimplify1 (seq, rcode, type, ops, valueize) 596 || valueized); 597 } 598 else if (code == BIT_FIELD_REF) 599 { 600 tree rhs1 = gimple_assign_rhs1 (stmt); 601 tree op0 = TREE_OPERAND (rhs1, 0); 602 bool valueized = false; 603 op0 = do_valueize (op0, top_valueize, valueized); 604 *rcode = code; 605 ops[0] = op0; 606 ops[1] = TREE_OPERAND (rhs1, 1); 607 ops[2] = TREE_OPERAND (rhs1, 2); 608 return (gimple_resimplify3 (seq, rcode, type, ops, valueize) 609 || valueized); 610 } 611 else if (code == SSA_NAME 612 && top_valueize) 613 { 614 tree op0 = gimple_assign_rhs1 (stmt); 615 tree valueized = top_valueize (op0); 616 if (!valueized || op0 == valueized) 617 return false; 618 ops[0] = valueized; 619 *rcode = TREE_CODE (op0); 620 return true; 621 } 622 break; 623 case GIMPLE_UNARY_RHS: 624 { 625 tree rhs1 = gimple_assign_rhs1 (stmt); 626 bool valueized = false; 627 rhs1 = do_valueize (rhs1, top_valueize, valueized); 628 *rcode = code; 629 ops[0] = rhs1; 630 return (gimple_resimplify1 (seq, rcode, type, ops, valueize) 631 || valueized); 632 } 633 case GIMPLE_BINARY_RHS: 634 { 635 tree rhs1 = gimple_assign_rhs1 (stmt); 636 tree rhs2 = gimple_assign_rhs2 (stmt); 637 bool valueized = false; 638 rhs1 = do_valueize (rhs1, top_valueize, valueized); 639 rhs2 = do_valueize (rhs2, top_valueize, valueized); 640 *rcode = code; 641 ops[0] = rhs1; 642 ops[1] = rhs2; 643 return (gimple_resimplify2 (seq, rcode, type, ops, valueize) 644 || valueized); 645 } 646 case GIMPLE_TERNARY_RHS: 647 { 648 bool valueized = false; 649 tree rhs1 = gimple_assign_rhs1 (stmt); 650 /* If this is a [VEC_]COND_EXPR first try to simplify an 651 embedded GENERIC condition. */ 652 if (code == COND_EXPR 653 || code == VEC_COND_EXPR) 654 { 655 if (COMPARISON_CLASS_P (rhs1)) 656 { 657 tree lhs = TREE_OPERAND (rhs1, 0); 658 tree rhs = TREE_OPERAND (rhs1, 1); 659 lhs = do_valueize (lhs, top_valueize, valueized); 660 rhs = do_valueize (rhs, top_valueize, valueized); 661 code_helper rcode2 = TREE_CODE (rhs1); 662 tree ops2[3] = {}; 663 ops2[0] = lhs; 664 ops2[1] = rhs; 665 if ((gimple_resimplify2 (seq, &rcode2, TREE_TYPE (rhs1), 666 ops2, valueize) 667 || valueized) 668 && rcode2.is_tree_code ()) 669 { 670 valueized = true; 671 if (TREE_CODE_CLASS ((enum tree_code)rcode2) 672 == tcc_comparison) 673 rhs1 = build2 (rcode2, TREE_TYPE (rhs1), 674 ops2[0], ops2[1]); 675 else if (rcode2 == SSA_NAME 676 || rcode2 == INTEGER_CST 677 || rcode2 == VECTOR_CST) 678 rhs1 = ops2[0]; 679 else 680 valueized = false; 681 } 682 } 683 } 684 tree rhs2 = gimple_assign_rhs2 (stmt); 685 tree rhs3 = gimple_assign_rhs3 (stmt); 686 rhs1 = do_valueize (rhs1, top_valueize, valueized); 687 rhs2 = do_valueize (rhs2, top_valueize, valueized); 688 rhs3 = do_valueize (rhs3, top_valueize, valueized); 689 *rcode = code; 690 ops[0] = rhs1; 691 ops[1] = rhs2; 692 ops[2] = rhs3; 693 return (gimple_resimplify3 (seq, rcode, type, ops, valueize) 694 || valueized); 695 } 696 default: 697 gcc_unreachable (); 698 } 699 break; 700 } 701 702 case GIMPLE_CALL: 703 /* ??? This way we can't simplify calls with side-effects. */ 704 if (gimple_call_lhs (stmt) != NULL_TREE 705 && gimple_call_num_args (stmt) >= 1 706 && gimple_call_num_args (stmt) <= 3) 707 { 708 bool valueized = false; 709 if (gimple_call_internal_p (stmt)) 710 *rcode = as_combined_fn (gimple_call_internal_fn (stmt)); 711 else 712 { 713 tree fn = gimple_call_fn (stmt); 714 if (!fn) 715 return false; 716 717 fn = do_valueize (fn, top_valueize, valueized); 718 if (TREE_CODE (fn) != ADDR_EXPR 719 || TREE_CODE (TREE_OPERAND (fn, 0)) != FUNCTION_DECL) 720 return false; 721 722 tree decl = TREE_OPERAND (fn, 0); 723 if (DECL_BUILT_IN_CLASS (decl) != BUILT_IN_NORMAL 724 || !gimple_builtin_call_types_compatible_p (stmt, decl)) 725 return false; 726 727 *rcode = as_combined_fn (DECL_FUNCTION_CODE (decl)); 728 } 729 730 tree type = TREE_TYPE (gimple_call_lhs (stmt)); 731 for (unsigned i = 0; i < gimple_call_num_args (stmt); ++i) 732 { 733 tree arg = gimple_call_arg (stmt, i); 734 ops[i] = do_valueize (arg, top_valueize, valueized); 735 } 736 switch (gimple_call_num_args (stmt)) 737 { 738 case 1: 739 return (gimple_resimplify1 (seq, rcode, type, ops, valueize) 740 || valueized); 741 case 2: 742 return (gimple_resimplify2 (seq, rcode, type, ops, valueize) 743 || valueized); 744 case 3: 745 return (gimple_resimplify3 (seq, rcode, type, ops, valueize) 746 || valueized); 747 default: 748 gcc_unreachable (); 749 } 750 } 751 break; 752 753 case GIMPLE_COND: 754 { 755 tree lhs = gimple_cond_lhs (stmt); 756 tree rhs = gimple_cond_rhs (stmt); 757 bool valueized = false; 758 lhs = do_valueize (lhs, top_valueize, valueized); 759 rhs = do_valueize (rhs, top_valueize, valueized); 760 *rcode = gimple_cond_code (stmt); 761 ops[0] = lhs; 762 ops[1] = rhs; 763 return (gimple_resimplify2 (seq, rcode, 764 boolean_type_node, ops, valueize) 765 || valueized); 766 } 767 768 default: 769 break; 770 } 771 772 return false; 773 } 774 775 776 /* Helper for the autogenerated code, valueize OP. */ 777 778 inline tree 779 do_valueize (tree (*valueize)(tree), tree op) 780 { 781 if (valueize && TREE_CODE (op) == SSA_NAME) 782 { 783 tree tem = valueize (op); 784 if (tem) 785 return tem; 786 } 787 return op; 788 } 789 790 /* Helper for the autogenerated code, get at the definition of NAME when 791 VALUEIZE allows that. */ 792 793 inline gimple * 794 get_def (tree (*valueize)(tree), tree name) 795 { 796 if (valueize && ! valueize (name)) 797 return NULL; 798 return SSA_NAME_DEF_STMT (name); 799 } 800 801 /* Routine to determine if the types T1 and T2 are effectively 802 the same for GIMPLE. If T1 or T2 is not a type, the test 803 applies to their TREE_TYPE. */ 804 805 static inline bool 806 types_match (tree t1, tree t2) 807 { 808 if (!TYPE_P (t1)) 809 t1 = TREE_TYPE (t1); 810 if (!TYPE_P (t2)) 811 t2 = TREE_TYPE (t2); 812 813 return types_compatible_p (t1, t2); 814 } 815 816 /* Return if T has a single use. For GIMPLE, we also allow any 817 non-SSA_NAME (ie constants) and zero uses to cope with uses 818 that aren't linked up yet. */ 819 820 static inline bool 821 single_use (tree t) 822 { 823 return TREE_CODE (t) != SSA_NAME || has_zero_uses (t) || has_single_use (t); 824 } 825 826 /* Return true if math operations should be canonicalized, 827 e.g. sqrt(sqrt(x)) -> pow(x, 0.25). */ 828 829 static inline bool 830 canonicalize_math_p () 831 { 832 return !cfun || (cfun->curr_properties & PROP_gimple_opt_math) == 0; 833 } 834 835 /* Return true if math operations that are beneficial only after 836 vectorization should be canonicalized. */ 837 838 static inline bool 839 canonicalize_math_after_vectorization_p () 840 { 841 return !cfun || (cfun->curr_properties & PROP_gimple_lvec) != 0; 842 } 843 844 /* Return true if pow(cst, x) should be optimized into exp(log(cst) * x). 845 As a workaround for SPEC CPU2017 628.pop2_s, don't do it if arg0 846 is an exact integer, arg1 = phi_res +/- cst1 and phi_res = PHI <cst2, ...> 847 where cst2 +/- cst1 is an exact integer, because then pow (arg0, arg1) 848 will likely be exact, while exp (log (arg0) * arg1) might be not. 849 Also don't do it if arg1 is phi_res above and cst2 is an exact integer. */ 850 851 static bool 852 optimize_pow_to_exp (tree arg0, tree arg1) 853 { 854 gcc_assert (TREE_CODE (arg0) == REAL_CST); 855 if (!real_isinteger (TREE_REAL_CST_PTR (arg0), TYPE_MODE (TREE_TYPE (arg0)))) 856 return true; 857 858 if (TREE_CODE (arg1) != SSA_NAME) 859 return true; 860 861 gimple *def = SSA_NAME_DEF_STMT (arg1); 862 gphi *phi = dyn_cast <gphi *> (def); 863 tree cst1 = NULL_TREE; 864 enum tree_code code = ERROR_MARK; 865 if (!phi) 866 { 867 if (!is_gimple_assign (def)) 868 return true; 869 code = gimple_assign_rhs_code (def); 870 switch (code) 871 { 872 case PLUS_EXPR: 873 case MINUS_EXPR: 874 break; 875 default: 876 return true; 877 } 878 if (TREE_CODE (gimple_assign_rhs1 (def)) != SSA_NAME 879 || TREE_CODE (gimple_assign_rhs2 (def)) != REAL_CST) 880 return true; 881 882 cst1 = gimple_assign_rhs2 (def); 883 884 phi = dyn_cast <gphi *> (SSA_NAME_DEF_STMT (gimple_assign_rhs1 (def))); 885 if (!phi) 886 return true; 887 } 888 889 tree cst2 = NULL_TREE; 890 int n = gimple_phi_num_args (phi); 891 for (int i = 0; i < n; i++) 892 { 893 tree arg = PHI_ARG_DEF (phi, i); 894 if (TREE_CODE (arg) != REAL_CST) 895 continue; 896 else if (cst2 == NULL_TREE) 897 cst2 = arg; 898 else if (!operand_equal_p (cst2, arg, 0)) 899 return true; 900 } 901 902 if (cst1 && cst2) 903 cst2 = const_binop (code, TREE_TYPE (cst2), cst2, cst1); 904 if (cst2 905 && TREE_CODE (cst2) == REAL_CST 906 && real_isinteger (TREE_REAL_CST_PTR (cst2), 907 TYPE_MODE (TREE_TYPE (cst2)))) 908 return false; 909 return true; 910 } 911