1 /* Interprocedural Identical Code Folding pass 2 Copyright (C) 2014-2020 Free Software Foundation, Inc. 3 4 Contributed by Jan Hubicka <hubicka@ucw.cz> and Martin Liska <mliska@suse.cz> 5 6 This file is part of GCC. 7 8 GCC is free software; you can redistribute it and/or modify it under 9 the terms of the GNU General Public License as published by the Free 10 Software Foundation; either version 3, or (at your option) any later 11 version. 12 13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY 14 WARRANTY; without even the implied warranty of MERCHANTABILITY or 15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 16 for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with GCC; see the file COPYING3. If not see 20 <http://www.gnu.org/licenses/>. */ 21 22 #include "config.h" 23 #include "system.h" 24 #include "coretypes.h" 25 #include "backend.h" 26 #include "rtl.h" 27 #include "tree.h" 28 #include "gimple.h" 29 #include "tree-pass.h" 30 #include "ssa.h" 31 #include "cgraph.h" 32 #include "data-streamer.h" 33 #include "gimple-pretty-print.h" 34 #include "fold-const.h" 35 #include "gimple-iterator.h" 36 #include "ipa-utils.h" 37 #include "tree-eh.h" 38 #include "builtins.h" 39 #include "cfgloop.h" 40 #include "attribs.h" 41 42 #include "ipa-icf-gimple.h" 43 44 namespace ipa_icf_gimple { 45 46 /* Initialize internal structures for a given SOURCE_FUNC_DECL and 47 TARGET_FUNC_DECL. Strict polymorphic comparison is processed if 48 an option COMPARE_POLYMORPHIC is true. For special cases, one can 49 set IGNORE_LABELS to skip label comparison. 50 Similarly, IGNORE_SOURCE_DECLS and IGNORE_TARGET_DECLS are sets 51 of declarations that can be skipped. */ 52 53 func_checker::func_checker (tree source_func_decl, tree target_func_decl, 54 bool ignore_labels, 55 hash_set<symtab_node *> *ignored_source_nodes, 56 hash_set<symtab_node *> *ignored_target_nodes) 57 : m_source_func_decl (source_func_decl), m_target_func_decl (target_func_decl), 58 m_ignored_source_nodes (ignored_source_nodes), 59 m_ignored_target_nodes (ignored_target_nodes), 60 m_ignore_labels (ignore_labels) 61 { 62 function *source_func = DECL_STRUCT_FUNCTION (source_func_decl); 63 function *target_func = DECL_STRUCT_FUNCTION (target_func_decl); 64 65 unsigned ssa_source = SSANAMES (source_func)->length (); 66 unsigned ssa_target = SSANAMES (target_func)->length (); 67 68 m_source_ssa_names.create (ssa_source); 69 m_target_ssa_names.create (ssa_target); 70 71 for (unsigned i = 0; i < ssa_source; i++) 72 m_source_ssa_names.safe_push (-1); 73 74 for (unsigned i = 0; i < ssa_target; i++) 75 m_target_ssa_names.safe_push (-1); 76 } 77 78 /* Memory release routine. */ 79 80 func_checker::~func_checker () 81 { 82 m_source_ssa_names.release(); 83 m_target_ssa_names.release(); 84 } 85 86 /* Verifies that trees T1 and T2 are equivalent from perspective of ICF. */ 87 88 bool 89 func_checker::compare_ssa_name (const_tree t1, const_tree t2) 90 { 91 gcc_assert (TREE_CODE (t1) == SSA_NAME); 92 gcc_assert (TREE_CODE (t2) == SSA_NAME); 93 94 unsigned i1 = SSA_NAME_VERSION (t1); 95 unsigned i2 = SSA_NAME_VERSION (t2); 96 97 if (m_source_ssa_names[i1] == -1) 98 m_source_ssa_names[i1] = i2; 99 else if (m_source_ssa_names[i1] != (int) i2) 100 return false; 101 102 if(m_target_ssa_names[i2] == -1) 103 m_target_ssa_names[i2] = i1; 104 else if (m_target_ssa_names[i2] != (int) i1) 105 return false; 106 107 if (SSA_NAME_IS_DEFAULT_DEF (t1)) 108 { 109 tree b1 = SSA_NAME_VAR (t1); 110 tree b2 = SSA_NAME_VAR (t2); 111 112 return compare_operand (b1, b2); 113 } 114 115 return true; 116 } 117 118 /* Verification function for edges E1 and E2. */ 119 120 bool 121 func_checker::compare_edge (edge e1, edge e2) 122 { 123 if (e1->flags != e2->flags) 124 return false; 125 126 bool existed_p; 127 128 edge &slot = m_edge_map.get_or_insert (e1, &existed_p); 129 if (existed_p) 130 return return_with_debug (slot == e2); 131 else 132 slot = e2; 133 134 /* TODO: filter edge probabilities for profile feedback match. */ 135 136 return true; 137 } 138 139 /* Verification function for declaration trees T1 and T2 that 140 come from functions FUNC1 and FUNC2. */ 141 142 bool 143 func_checker::compare_decl (const_tree t1, const_tree t2) 144 { 145 if (!auto_var_in_fn_p (t1, m_source_func_decl) 146 || !auto_var_in_fn_p (t2, m_target_func_decl)) 147 return return_with_debug (t1 == t2); 148 149 tree_code t = TREE_CODE (t1); 150 if ((t == VAR_DECL || t == PARM_DECL || t == RESULT_DECL) 151 && DECL_BY_REFERENCE (t1) != DECL_BY_REFERENCE (t2)) 152 return return_false_with_msg ("DECL_BY_REFERENCE flags are different"); 153 154 if (!compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2))) 155 return return_false (); 156 157 bool existed_p; 158 const_tree &slot = m_decl_map.get_or_insert (t1, &existed_p); 159 if (existed_p) 160 return return_with_debug (slot == t2); 161 else 162 slot = t2; 163 164 return true; 165 } 166 167 /* Return true if T1 and T2 are same for purposes of ipa-polymorphic-call 168 analysis. COMPARE_PTR indicates if types of pointers needs to be 169 considered. */ 170 171 bool 172 func_checker::compatible_polymorphic_types_p (tree t1, tree t2, 173 bool compare_ptr) 174 { 175 gcc_assert (TREE_CODE (t1) != FUNCTION_TYPE && TREE_CODE (t1) != METHOD_TYPE); 176 177 /* Pointer types generally give no information. */ 178 if (POINTER_TYPE_P (t1)) 179 { 180 if (!compare_ptr) 181 return true; 182 return func_checker::compatible_polymorphic_types_p (TREE_TYPE (t1), 183 TREE_TYPE (t2), 184 false); 185 } 186 187 /* If types contain a polymorphic types, match them. */ 188 bool c1 = contains_polymorphic_type_p (t1); 189 bool c2 = contains_polymorphic_type_p (t2); 190 if (!c1 && !c2) 191 return true; 192 if (!c1 || !c2) 193 return return_false_with_msg ("one type is not polymorphic"); 194 if (!types_must_be_same_for_odr (t1, t2)) 195 return return_false_with_msg ("types are not same for ODR"); 196 return true; 197 } 198 199 /* Return true if types are compatible from perspective of ICF. */ 200 bool 201 func_checker::compatible_types_p (tree t1, tree t2) 202 { 203 if (TREE_CODE (t1) != TREE_CODE (t2)) 204 return return_false_with_msg ("different tree types"); 205 206 if (TYPE_RESTRICT (t1) != TYPE_RESTRICT (t2)) 207 return return_false_with_msg ("restrict flags are different"); 208 209 if (!types_compatible_p (t1, t2)) 210 return return_false_with_msg ("types are not compatible"); 211 212 return true; 213 } 214 215 /* Function compare for equality given trees T1 and T2 which 216 can be either a constant or a declaration type. */ 217 218 void 219 func_checker::hash_operand (const_tree arg, inchash::hash &hstate, 220 unsigned int flags) 221 { 222 if (arg == NULL_TREE) 223 { 224 hstate.merge_hash (0); 225 return; 226 } 227 228 switch (TREE_CODE (arg)) 229 { 230 case FUNCTION_DECL: 231 case VAR_DECL: 232 case LABEL_DECL: 233 case PARM_DECL: 234 case RESULT_DECL: 235 case CONST_DECL: 236 case SSA_NAME: 237 return; 238 case FIELD_DECL: 239 inchash::add_expr (DECL_FIELD_OFFSET (arg), hstate, flags); 240 inchash::add_expr (DECL_FIELD_BIT_OFFSET (arg), hstate, flags); 241 return; 242 default: 243 break; 244 } 245 246 return operand_compare::hash_operand (arg, hstate, flags); 247 } 248 249 bool 250 func_checker::operand_equal_p (const_tree t1, const_tree t2, 251 unsigned int flags) 252 { 253 bool r; 254 if (verify_hash_value (t1, t2, flags, &r)) 255 return r; 256 257 if (t1 == t2) 258 return true; 259 else if (!t1 || !t2) 260 return false; 261 262 if (TREE_CODE (t1) != TREE_CODE (t2)) 263 return return_false (); 264 265 switch (TREE_CODE (t1)) 266 { 267 case FUNCTION_DECL: 268 /* All function decls are in the symbol table and known to match 269 before we start comparing bodies. */ 270 return true; 271 case VAR_DECL: 272 return return_with_debug (compare_variable_decl (t1, t2)); 273 case LABEL_DECL: 274 { 275 int *bb1 = m_label_bb_map.get (t1); 276 int *bb2 = m_label_bb_map.get (t2); 277 /* Labels can point to another function (non-local GOTOs). */ 278 return return_with_debug (bb1 != NULL && bb2 != NULL && *bb1 == *bb2); 279 } 280 281 case PARM_DECL: 282 case RESULT_DECL: 283 case CONST_DECL: 284 return compare_decl (t1, t2); 285 case SSA_NAME: 286 return compare_ssa_name (t1, t2); 287 default: 288 break; 289 } 290 291 return operand_compare::operand_equal_p (t1, t2, flags); 292 } 293 294 /* Function responsible for comparison of various operands T1 and T2. 295 If these components, from functions FUNC1 and FUNC2, are equal, true 296 is returned. */ 297 298 bool 299 func_checker::compare_operand (tree t1, tree t2) 300 { 301 if (!t1 && !t2) 302 return true; 303 else if (!t1 || !t2) 304 return false; 305 if (operand_equal_p (t1, t2, OEP_MATCH_SIDE_EFFECTS)) 306 return true; 307 return return_false_with_msg ("operand_equal_p failed"); 308 } 309 310 bool 311 func_checker::compare_asm_inputs_outputs (tree t1, tree t2) 312 { 313 gcc_assert (TREE_CODE (t1) == TREE_LIST); 314 gcc_assert (TREE_CODE (t2) == TREE_LIST); 315 316 for (; t1; t1 = TREE_CHAIN (t1)) 317 { 318 if (!t2) 319 return false; 320 321 if (!compare_operand (TREE_VALUE (t1), TREE_VALUE (t2))) 322 return return_false (); 323 324 tree p1 = TREE_PURPOSE (t1); 325 tree p2 = TREE_PURPOSE (t2); 326 327 gcc_assert (TREE_CODE (p1) == TREE_LIST); 328 gcc_assert (TREE_CODE (p2) == TREE_LIST); 329 330 if (strcmp (TREE_STRING_POINTER (TREE_VALUE (p1)), 331 TREE_STRING_POINTER (TREE_VALUE (p2))) != 0) 332 return return_false (); 333 334 t2 = TREE_CHAIN (t2); 335 } 336 337 if (t2) 338 return return_false (); 339 340 return true; 341 } 342 343 /* Verifies that trees T1 and T2 do correspond. */ 344 345 bool 346 func_checker::compare_variable_decl (const_tree t1, const_tree t2) 347 { 348 bool ret = false; 349 350 if (t1 == t2) 351 return true; 352 353 if (DECL_ALIGN (t1) != DECL_ALIGN (t2)) 354 return return_false_with_msg ("alignments are different"); 355 356 if (DECL_HARD_REGISTER (t1) != DECL_HARD_REGISTER (t2)) 357 return return_false_with_msg ("DECL_HARD_REGISTER are different"); 358 359 if (DECL_HARD_REGISTER (t1) 360 && DECL_ASSEMBLER_NAME_RAW (t1) != DECL_ASSEMBLER_NAME_RAW (t2)) 361 return return_false_with_msg ("HARD REGISTERS are different"); 362 363 /* Symbol table variables are known to match before we start comparing 364 bodies. */ 365 if (decl_in_symtab_p (t1)) 366 return decl_in_symtab_p (t2); 367 ret = compare_decl (t1, t2); 368 369 return return_with_debug (ret); 370 } 371 372 /* Compare loop information for basic blocks BB1 and BB2. */ 373 374 bool 375 func_checker::compare_loops (basic_block bb1, basic_block bb2) 376 { 377 if ((bb1->loop_father == NULL) != (bb2->loop_father == NULL)) 378 return return_false (); 379 380 class loop *l1 = bb1->loop_father; 381 class loop *l2 = bb2->loop_father; 382 if (l1 == NULL) 383 return true; 384 385 if ((bb1 == l1->header) != (bb2 == l2->header)) 386 return return_false_with_msg ("header"); 387 if ((bb1 == l1->latch) != (bb2 == l2->latch)) 388 return return_false_with_msg ("latch"); 389 if (l1->simdlen != l2->simdlen) 390 return return_false_with_msg ("simdlen"); 391 if (l1->safelen != l2->safelen) 392 return return_false_with_msg ("safelen"); 393 if (l1->can_be_parallel != l2->can_be_parallel) 394 return return_false_with_msg ("can_be_parallel"); 395 if (l1->dont_vectorize != l2->dont_vectorize) 396 return return_false_with_msg ("dont_vectorize"); 397 if (l1->force_vectorize != l2->force_vectorize) 398 return return_false_with_msg ("force_vectorize"); 399 if (l1->finite_p != l2->finite_p) 400 return return_false_with_msg ("finite_p"); 401 if (l1->unroll != l2->unroll) 402 return return_false_with_msg ("unroll"); 403 if (!compare_variable_decl (l1->simduid, l2->simduid)) 404 return return_false_with_msg ("simduid"); 405 406 return true; 407 } 408 409 /* Function visits all gimple labels and creates corresponding 410 mapping between basic blocks and labels. */ 411 412 void 413 func_checker::parse_labels (sem_bb *bb) 414 { 415 for (gimple_stmt_iterator gsi = gsi_start_bb (bb->bb); !gsi_end_p (gsi); 416 gsi_next (&gsi)) 417 { 418 gimple *stmt = gsi_stmt (gsi); 419 420 if (glabel *label_stmt = dyn_cast <glabel *> (stmt)) 421 { 422 const_tree t = gimple_label_label (label_stmt); 423 gcc_assert (TREE_CODE (t) == LABEL_DECL); 424 425 m_label_bb_map.put (t, bb->bb->index); 426 } 427 } 428 } 429 430 /* Basic block equivalence comparison function that returns true if 431 basic blocks BB1 and BB2 (from functions FUNC1 and FUNC2) correspond. 432 433 In general, a collection of equivalence dictionaries is built for types 434 like SSA names, declarations (VAR_DECL, PARM_DECL, ..). This infrastructure 435 is utilized by every statement-by-statement comparison function. */ 436 437 bool 438 func_checker::compare_bb (sem_bb *bb1, sem_bb *bb2) 439 { 440 gimple_stmt_iterator gsi1, gsi2; 441 gimple *s1, *s2; 442 443 gsi1 = gsi_start_nondebug_bb (bb1->bb); 444 gsi2 = gsi_start_nondebug_bb (bb2->bb); 445 446 while (!gsi_end_p (gsi1)) 447 { 448 if (gsi_end_p (gsi2)) 449 return return_false (); 450 451 s1 = gsi_stmt (gsi1); 452 s2 = gsi_stmt (gsi2); 453 454 int eh1 = lookup_stmt_eh_lp_fn 455 (DECL_STRUCT_FUNCTION (m_source_func_decl), s1); 456 int eh2 = lookup_stmt_eh_lp_fn 457 (DECL_STRUCT_FUNCTION (m_target_func_decl), s2); 458 459 if (eh1 != eh2) 460 return return_false_with_msg ("EH regions are different"); 461 462 if (gimple_code (s1) != gimple_code (s2)) 463 return return_false_with_msg ("gimple codes are different"); 464 465 switch (gimple_code (s1)) 466 { 467 case GIMPLE_CALL: 468 if (!compare_gimple_call (as_a <gcall *> (s1), 469 as_a <gcall *> (s2))) 470 return return_different_stmts (s1, s2, "GIMPLE_CALL"); 471 break; 472 case GIMPLE_ASSIGN: 473 if (!compare_gimple_assign (s1, s2)) 474 return return_different_stmts (s1, s2, "GIMPLE_ASSIGN"); 475 break; 476 case GIMPLE_COND: 477 if (!compare_gimple_cond (s1, s2)) 478 return return_different_stmts (s1, s2, "GIMPLE_COND"); 479 break; 480 case GIMPLE_SWITCH: 481 if (!compare_gimple_switch (as_a <gswitch *> (s1), 482 as_a <gswitch *> (s2))) 483 return return_different_stmts (s1, s2, "GIMPLE_SWITCH"); 484 break; 485 case GIMPLE_DEBUG: 486 break; 487 case GIMPLE_EH_DISPATCH: 488 if (gimple_eh_dispatch_region (as_a <geh_dispatch *> (s1)) 489 != gimple_eh_dispatch_region (as_a <geh_dispatch *> (s2))) 490 return return_different_stmts (s1, s2, "GIMPLE_EH_DISPATCH"); 491 break; 492 case GIMPLE_RESX: 493 if (!compare_gimple_resx (as_a <gresx *> (s1), 494 as_a <gresx *> (s2))) 495 return return_different_stmts (s1, s2, "GIMPLE_RESX"); 496 break; 497 case GIMPLE_LABEL: 498 if (!compare_gimple_label (as_a <glabel *> (s1), 499 as_a <glabel *> (s2))) 500 return return_different_stmts (s1, s2, "GIMPLE_LABEL"); 501 break; 502 case GIMPLE_RETURN: 503 if (!compare_gimple_return (as_a <greturn *> (s1), 504 as_a <greturn *> (s2))) 505 return return_different_stmts (s1, s2, "GIMPLE_RETURN"); 506 break; 507 case GIMPLE_GOTO: 508 if (!compare_gimple_goto (s1, s2)) 509 return return_different_stmts (s1, s2, "GIMPLE_GOTO"); 510 break; 511 case GIMPLE_ASM: 512 if (!compare_gimple_asm (as_a <gasm *> (s1), 513 as_a <gasm *> (s2))) 514 return return_different_stmts (s1, s2, "GIMPLE_ASM"); 515 break; 516 case GIMPLE_PREDICT: 517 case GIMPLE_NOP: 518 break; 519 default: 520 return return_false_with_msg ("Unknown GIMPLE code reached"); 521 } 522 523 gsi_next_nondebug (&gsi1); 524 gsi_next_nondebug (&gsi2); 525 } 526 527 if (!gsi_end_p (gsi2)) 528 return return_false (); 529 530 if (!compare_loops (bb1->bb, bb2->bb)) 531 return return_false (); 532 533 return true; 534 } 535 536 /* Verifies for given GIMPLEs S1 and S2 that 537 call statements are semantically equivalent. */ 538 539 bool 540 func_checker::compare_gimple_call (gcall *s1, gcall *s2) 541 { 542 unsigned i; 543 tree t1, t2; 544 545 if (gimple_call_num_args (s1) != gimple_call_num_args (s2)) 546 return false; 547 548 t1 = gimple_call_fn (s1); 549 t2 = gimple_call_fn (s2); 550 if (!compare_operand (t1, t2)) 551 return return_false (); 552 553 /* Compare flags. */ 554 if (gimple_call_internal_p (s1) != gimple_call_internal_p (s2) 555 || gimple_call_ctrl_altering_p (s1) != gimple_call_ctrl_altering_p (s2) 556 || gimple_call_tail_p (s1) != gimple_call_tail_p (s2) 557 || gimple_call_return_slot_opt_p (s1) != gimple_call_return_slot_opt_p (s2) 558 || gimple_call_from_thunk_p (s1) != gimple_call_from_thunk_p (s2) 559 || gimple_call_va_arg_pack_p (s1) != gimple_call_va_arg_pack_p (s2) 560 || gimple_call_alloca_for_var_p (s1) != gimple_call_alloca_for_var_p (s2)) 561 return false; 562 563 if (gimple_call_internal_p (s1) 564 && gimple_call_internal_fn (s1) != gimple_call_internal_fn (s2)) 565 return false; 566 567 tree fntype1 = gimple_call_fntype (s1); 568 tree fntype2 = gimple_call_fntype (s2); 569 if ((fntype1 && !fntype2) 570 || (!fntype1 && fntype2) 571 || (fntype1 && !types_compatible_p (fntype1, fntype2))) 572 return return_false_with_msg ("call function types are not compatible"); 573 574 if (fntype1 && fntype2 && comp_type_attributes (fntype1, fntype2) != 1) 575 return return_false_with_msg ("different fntype attributes"); 576 577 tree chain1 = gimple_call_chain (s1); 578 tree chain2 = gimple_call_chain (s2); 579 if ((chain1 && !chain2) 580 || (!chain1 && chain2) 581 || !compare_operand (chain1, chain2)) 582 return return_false_with_msg ("static call chains are different"); 583 584 /* Checking of argument. */ 585 for (i = 0; i < gimple_call_num_args (s1); ++i) 586 { 587 t1 = gimple_call_arg (s1, i); 588 t2 = gimple_call_arg (s2, i); 589 590 if (!compare_operand (t1, t2)) 591 return return_false_with_msg ("GIMPLE call operands are different"); 592 } 593 594 /* Return value checking. */ 595 t1 = gimple_get_lhs (s1); 596 t2 = gimple_get_lhs (s2); 597 598 /* For internal calls, lhs types need to be verified, as neither fntype nor 599 callee comparisons can catch that. */ 600 if (gimple_call_internal_p (s1) 601 && t1 602 && t2 603 && !compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2))) 604 return return_false_with_msg ("GIMPLE internal call LHS type mismatch"); 605 606 return compare_operand (t1, t2); 607 } 608 609 610 /* Verifies for given GIMPLEs S1 and S2 that 611 assignment statements are semantically equivalent. */ 612 613 bool 614 func_checker::compare_gimple_assign (gimple *s1, gimple *s2) 615 { 616 tree arg1, arg2; 617 tree_code code1, code2; 618 unsigned i; 619 620 code1 = gimple_expr_code (s1); 621 code2 = gimple_expr_code (s2); 622 623 if (code1 != code2) 624 return false; 625 626 code1 = gimple_assign_rhs_code (s1); 627 code2 = gimple_assign_rhs_code (s2); 628 629 if (code1 != code2) 630 return false; 631 632 for (i = 0; i < gimple_num_ops (s1); i++) 633 { 634 arg1 = gimple_op (s1, i); 635 arg2 = gimple_op (s2, i); 636 637 /* Compare types for LHS. */ 638 if (i == 0) 639 { 640 if (!compatible_types_p (TREE_TYPE (arg1), TREE_TYPE (arg2))) 641 return return_false_with_msg ("GIMPLE NOP LHS type mismatch"); 642 } 643 644 if (!compare_operand (arg1, arg2)) 645 return return_false_with_msg ("GIMPLE assignment operands " 646 "are different"); 647 } 648 649 650 return true; 651 } 652 653 /* Verifies for given GIMPLEs S1 and S2 that 654 condition statements are semantically equivalent. */ 655 656 bool 657 func_checker::compare_gimple_cond (gimple *s1, gimple *s2) 658 { 659 tree t1, t2; 660 tree_code code1, code2; 661 662 code1 = gimple_expr_code (s1); 663 code2 = gimple_expr_code (s2); 664 665 if (code1 != code2) 666 return false; 667 668 t1 = gimple_cond_lhs (s1); 669 t2 = gimple_cond_lhs (s2); 670 671 if (!compare_operand (t1, t2)) 672 return false; 673 674 t1 = gimple_cond_rhs (s1); 675 t2 = gimple_cond_rhs (s2); 676 677 return compare_operand (t1, t2); 678 } 679 680 /* Verifies for given GIMPLE_LABEL stmts S1 and S2 that 681 label statements are semantically equivalent. */ 682 683 bool 684 func_checker::compare_gimple_label (const glabel *g1, const glabel *g2) 685 { 686 if (m_ignore_labels) 687 return true; 688 689 tree t1 = gimple_label_label (g1); 690 tree t2 = gimple_label_label (g2); 691 692 if (FORCED_LABEL (t1) || FORCED_LABEL (t2)) 693 return return_false_with_msg ("FORCED_LABEL"); 694 695 /* As the pass build BB to label mapping, no further check is needed. */ 696 return true; 697 } 698 699 /* Verifies for given GIMPLE_SWITCH stmts S1 and S2 that 700 switch statements are semantically equivalent. */ 701 702 bool 703 func_checker::compare_gimple_switch (const gswitch *g1, const gswitch *g2) 704 { 705 unsigned lsize1, lsize2, i; 706 707 lsize1 = gimple_switch_num_labels (g1); 708 lsize2 = gimple_switch_num_labels (g2); 709 710 if (lsize1 != lsize2) 711 return false; 712 713 tree t1 = gimple_switch_index (g1); 714 tree t2 = gimple_switch_index (g2); 715 716 if (!compare_operand (t1, t2)) 717 return false; 718 719 for (i = 0; i < lsize1; i++) 720 { 721 tree label1 = gimple_switch_label (g1, i); 722 tree label2 = gimple_switch_label (g2, i); 723 724 /* Label LOW and HIGH comparison. */ 725 tree low1 = CASE_LOW (label1); 726 tree low2 = CASE_LOW (label2); 727 728 if (!tree_int_cst_equal (low1, low2)) 729 return return_false_with_msg ("case low values are different"); 730 731 tree high1 = CASE_HIGH (label1); 732 tree high2 = CASE_HIGH (label2); 733 734 if (!tree_int_cst_equal (high1, high2)) 735 return return_false_with_msg ("case high values are different"); 736 737 if (TREE_CODE (label1) == CASE_LABEL_EXPR 738 && TREE_CODE (label2) == CASE_LABEL_EXPR) 739 { 740 label1 = CASE_LABEL (label1); 741 label2 = CASE_LABEL (label2); 742 743 if (!compare_operand (label1, label2)) 744 return return_false_with_msg ("switch label_exprs are different"); 745 } 746 else if (!tree_int_cst_equal (label1, label2)) 747 return return_false_with_msg ("switch labels are different"); 748 } 749 750 return true; 751 } 752 753 /* Verifies for given GIMPLE_RETURN stmts S1 and S2 that 754 return statements are semantically equivalent. */ 755 756 bool 757 func_checker::compare_gimple_return (const greturn *g1, const greturn *g2) 758 { 759 tree t1, t2; 760 761 t1 = gimple_return_retval (g1); 762 t2 = gimple_return_retval (g2); 763 764 /* Void return type. */ 765 if (t1 == NULL && t2 == NULL) 766 return true; 767 else 768 return compare_operand (t1, t2); 769 } 770 771 /* Verifies for given GIMPLEs S1 and S2 that 772 goto statements are semantically equivalent. */ 773 774 bool 775 func_checker::compare_gimple_goto (gimple *g1, gimple *g2) 776 { 777 tree dest1, dest2; 778 779 dest1 = gimple_goto_dest (g1); 780 dest2 = gimple_goto_dest (g2); 781 782 if (TREE_CODE (dest1) != TREE_CODE (dest2) || TREE_CODE (dest1) != SSA_NAME) 783 return false; 784 785 return compare_operand (dest1, dest2); 786 } 787 788 /* Verifies for given GIMPLE_RESX stmts S1 and S2 that 789 resx statements are semantically equivalent. */ 790 791 bool 792 func_checker::compare_gimple_resx (const gresx *g1, const gresx *g2) 793 { 794 return gimple_resx_region (g1) == gimple_resx_region (g2); 795 } 796 797 /* Verifies for given GIMPLEs S1 and S2 that ASM statements are equivalent. 798 For the beginning, the pass only supports equality for 799 '__asm__ __volatile__ ("", "", "", "memory")'. */ 800 801 bool 802 func_checker::compare_gimple_asm (const gasm *g1, const gasm *g2) 803 { 804 if (gimple_asm_volatile_p (g1) != gimple_asm_volatile_p (g2)) 805 return false; 806 807 if (gimple_asm_input_p (g1) != gimple_asm_input_p (g2)) 808 return false; 809 810 if (gimple_asm_inline_p (g1) != gimple_asm_inline_p (g2)) 811 return false; 812 813 if (gimple_asm_ninputs (g1) != gimple_asm_ninputs (g2)) 814 return false; 815 816 if (gimple_asm_noutputs (g1) != gimple_asm_noutputs (g2)) 817 return false; 818 819 /* We do not suppport goto ASM statement comparison. */ 820 if (gimple_asm_nlabels (g1) || gimple_asm_nlabels (g2)) 821 return false; 822 823 if (gimple_asm_nclobbers (g1) != gimple_asm_nclobbers (g2)) 824 return false; 825 826 if (strcmp (gimple_asm_string (g1), gimple_asm_string (g2)) != 0) 827 return return_false_with_msg ("ASM strings are different"); 828 829 for (unsigned i = 0; i < gimple_asm_ninputs (g1); i++) 830 { 831 tree input1 = gimple_asm_input_op (g1, i); 832 tree input2 = gimple_asm_input_op (g2, i); 833 834 if (!compare_asm_inputs_outputs (input1, input2)) 835 return return_false_with_msg ("ASM input is different"); 836 } 837 838 for (unsigned i = 0; i < gimple_asm_noutputs (g1); i++) 839 { 840 tree output1 = gimple_asm_output_op (g1, i); 841 tree output2 = gimple_asm_output_op (g2, i); 842 843 if (!compare_asm_inputs_outputs (output1, output2)) 844 return return_false_with_msg ("ASM output is different"); 845 } 846 847 for (unsigned i = 0; i < gimple_asm_nclobbers (g1); i++) 848 { 849 tree clobber1 = gimple_asm_clobber_op (g1, i); 850 tree clobber2 = gimple_asm_clobber_op (g2, i); 851 852 if (!operand_equal_p (TREE_VALUE (clobber1), TREE_VALUE (clobber2), 853 OEP_ONLY_CONST)) 854 return return_false_with_msg ("ASM clobber is different"); 855 } 856 857 return true; 858 } 859 860 } // ipa_icf_gimple namespace 861