comparison gcc/ipa-icf-gimple.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
comparison
equal deleted inserted replaced
131:84e7813d76e9 145:1830386684a0
1 /* Interprocedural Identical Code Folding pass 1 /* Interprocedural Identical Code Folding pass
2 Copyright (C) 2014-2018 Free Software Foundation, Inc. 2 Copyright (C) 2014-2020 Free Software Foundation, Inc.
3 3
4 Contributed by Jan Hubicka <hubicka@ucw.cz> and Martin Liska <mliska@suse.cz> 4 Contributed by Jan Hubicka <hubicka@ucw.cz> and Martin Liska <mliska@suse.cz>
5 5
6 This file is part of GCC. 6 This file is part of GCC.
7 7
29 #include "tree-pass.h" 29 #include "tree-pass.h"
30 #include "ssa.h" 30 #include "ssa.h"
31 #include "cgraph.h" 31 #include "cgraph.h"
32 #include "data-streamer.h" 32 #include "data-streamer.h"
33 #include "gimple-pretty-print.h" 33 #include "gimple-pretty-print.h"
34 #include "alias.h"
35 #include "fold-const.h" 34 #include "fold-const.h"
36 #include "gimple-iterator.h" 35 #include "gimple-iterator.h"
37 #include "ipa-utils.h" 36 #include "ipa-utils.h"
38 #include "tree-eh.h" 37 #include "tree-eh.h"
39 #include "builtins.h" 38 #include "builtins.h"
39 #include "cfgloop.h"
40 40
41 #include "ipa-icf-gimple.h" 41 #include "ipa-icf-gimple.h"
42 42
43 namespace ipa_icf_gimple { 43 namespace ipa_icf_gimple {
44 44
48 set IGNORE_LABELS to skip label comparison. 48 set IGNORE_LABELS to skip label comparison.
49 Similarly, IGNORE_SOURCE_DECLS and IGNORE_TARGET_DECLS are sets 49 Similarly, IGNORE_SOURCE_DECLS and IGNORE_TARGET_DECLS are sets
50 of declarations that can be skipped. */ 50 of declarations that can be skipped. */
51 51
52 func_checker::func_checker (tree source_func_decl, tree target_func_decl, 52 func_checker::func_checker (tree source_func_decl, tree target_func_decl,
53 bool compare_polymorphic,
54 bool ignore_labels, 53 bool ignore_labels,
55 hash_set<symtab_node *> *ignored_source_nodes, 54 hash_set<symtab_node *> *ignored_source_nodes,
56 hash_set<symtab_node *> *ignored_target_nodes) 55 hash_set<symtab_node *> *ignored_target_nodes)
57 : m_source_func_decl (source_func_decl), m_target_func_decl (target_func_decl), 56 : m_source_func_decl (source_func_decl), m_target_func_decl (target_func_decl),
58 m_ignored_source_nodes (ignored_source_nodes), 57 m_ignored_source_nodes (ignored_source_nodes),
59 m_ignored_target_nodes (ignored_target_nodes), 58 m_ignored_target_nodes (ignored_target_nodes),
60 m_compare_polymorphic (compare_polymorphic),
61 m_ignore_labels (ignore_labels) 59 m_ignore_labels (ignore_labels)
62 { 60 {
63 function *source_func = DECL_STRUCT_FUNCTION (source_func_decl); 61 function *source_func = DECL_STRUCT_FUNCTION (source_func_decl);
64 function *target_func = DECL_STRUCT_FUNCTION (target_func_decl); 62 function *target_func = DECL_STRUCT_FUNCTION (target_func_decl);
65 63
85 } 83 }
86 84
87 /* Verifies that trees T1 and T2 are equivalent from perspective of ICF. */ 85 /* Verifies that trees T1 and T2 are equivalent from perspective of ICF. */
88 86
89 bool 87 bool
90 func_checker::compare_ssa_name (tree t1, tree t2) 88 func_checker::compare_ssa_name (const_tree t1, const_tree t2)
91 { 89 {
92 gcc_assert (TREE_CODE (t1) == SSA_NAME); 90 gcc_assert (TREE_CODE (t1) == SSA_NAME);
93 gcc_assert (TREE_CODE (t2) == SSA_NAME); 91 gcc_assert (TREE_CODE (t2) == SSA_NAME);
94 92
95 unsigned i1 = SSA_NAME_VERSION (t1); 93 unsigned i1 = SSA_NAME_VERSION (t1);
108 if (SSA_NAME_IS_DEFAULT_DEF (t1)) 106 if (SSA_NAME_IS_DEFAULT_DEF (t1))
109 { 107 {
110 tree b1 = SSA_NAME_VAR (t1); 108 tree b1 = SSA_NAME_VAR (t1);
111 tree b2 = SSA_NAME_VAR (t2); 109 tree b2 = SSA_NAME_VAR (t2);
112 110
113 if (b1 == NULL && b2 == NULL) 111 return compare_operand (b1, b2);
114 return true;
115
116 if (b1 == NULL || b2 == NULL || TREE_CODE (b1) != TREE_CODE (b2))
117 return return_false ();
118
119 return compare_cst_or_decl (b1, b2);
120 } 112 }
121 113
122 return true; 114 return true;
123 } 115 }
124 116
145 137
146 /* Verification function for declaration trees T1 and T2 that 138 /* Verification function for declaration trees T1 and T2 that
147 come from functions FUNC1 and FUNC2. */ 139 come from functions FUNC1 and FUNC2. */
148 140
149 bool 141 bool
150 func_checker::compare_decl (tree t1, tree t2) 142 func_checker::compare_decl (const_tree t1, const_tree t2)
151 { 143 {
152 if (!auto_var_in_fn_p (t1, m_source_func_decl) 144 if (!auto_var_in_fn_p (t1, m_source_func_decl)
153 || !auto_var_in_fn_p (t2, m_target_func_decl)) 145 || !auto_var_in_fn_p (t2, m_target_func_decl))
154 return return_with_debug (t1 == t2); 146 return return_with_debug (t1 == t2);
155 147
159 return return_false_with_msg ("DECL_BY_REFERENCE flags are different"); 151 return return_false_with_msg ("DECL_BY_REFERENCE flags are different");
160 152
161 if (!compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2))) 153 if (!compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2)))
162 return return_false (); 154 return return_false ();
163 155
164 /* TODO: we are actually too strict here. We only need to compare if
165 T1 can be used in polymorphic call. */
166 if (TREE_ADDRESSABLE (t1)
167 && m_compare_polymorphic
168 && !compatible_polymorphic_types_p (TREE_TYPE (t1), TREE_TYPE (t2),
169 false))
170 return return_false ();
171
172 if ((t == VAR_DECL || t == PARM_DECL || t == RESULT_DECL)
173 && DECL_BY_REFERENCE (t1)
174 && m_compare_polymorphic
175 && !compatible_polymorphic_types_p (TREE_TYPE (t1), TREE_TYPE (t2),
176 true))
177 return return_false ();
178
179 bool existed_p; 156 bool existed_p;
180 157 const_tree &slot = m_decl_map.get_or_insert (t1, &existed_p);
181 tree &slot = m_decl_map.get_or_insert (t1, &existed_p);
182 if (existed_p) 158 if (existed_p)
183 return return_with_debug (slot == t2); 159 return return_with_debug (slot == t2);
184 else 160 else
185 slot = t2; 161 slot = t2;
186 162
230 return return_false_with_msg ("restrict flags are different"); 206 return return_false_with_msg ("restrict flags are different");
231 207
232 if (!types_compatible_p (t1, t2)) 208 if (!types_compatible_p (t1, t2))
233 return return_false_with_msg ("types are not compatible"); 209 return return_false_with_msg ("types are not compatible");
234 210
235 /* We do a lot of unnecesary matching of types that are not being 211 return true;
236 accessed and thus do not need to be compatible. In longer term we should 212 }
237 remove these checks on all types which are not accessed as memory 213
238 locations. 214 /* Function compare for equality given trees T1 and T2 which
239 215 can be either a constant or a declaration type. */
240 For time being just avoid calling get_alias_set on types that are not 216
241 having alias sets defined at all. */ 217 void
242 if (type_with_alias_set_p (t1) && type_with_alias_set_p (t2) 218 func_checker::hash_operand (const_tree arg, inchash::hash &hstate,
243 && get_alias_set (t1) != get_alias_set (t2)) 219 unsigned int flags)
244 return return_false_with_msg ("alias sets are different"); 220 {
245 221 if (arg == NULL_TREE)
246 return true; 222 {
247 } 223 hstate.merge_hash (0);
248 224 return;
249 /* Function compare for equality given memory operands T1 and T2. */ 225 }
250 226
251 bool 227 switch (TREE_CODE (arg))
252 func_checker::compare_memory_operand (tree t1, tree t2) 228 {
253 { 229 case FUNCTION_DECL:
254 if (!t1 && !t2) 230 case VAR_DECL:
231 case LABEL_DECL:
232 case PARM_DECL:
233 case RESULT_DECL:
234 case CONST_DECL:
235 case SSA_NAME:
236 return;
237 case FIELD_DECL:
238 inchash::add_expr (DECL_FIELD_OFFSET (arg), hstate, flags);
239 inchash::add_expr (DECL_FIELD_BIT_OFFSET (arg), hstate, flags);
240 return;
241 default:
242 break;
243 }
244
245 return operand_compare::hash_operand (arg, hstate, flags);
246 }
247
248 bool
249 func_checker::operand_equal_p (const_tree t1, const_tree t2,
250 unsigned int flags)
251 {
252 bool r;
253 if (verify_hash_value (t1, t2, flags, &r))
254 return r;
255
256 if (t1 == t2)
255 return true; 257 return true;
256 else if (!t1 || !t2) 258 else if (!t1 || !t2)
257 return false; 259 return false;
258 260
259 ao_ref r1, r2; 261 if (TREE_CODE (t1) != TREE_CODE (t2))
260 ao_ref_init (&r1, t1); 262 return return_false ();
261 ao_ref_init (&r2, t2);
262
263 tree b1 = ao_ref_base (&r1);
264 tree b2 = ao_ref_base (&r2);
265
266 bool source_is_memop = DECL_P (b1) || INDIRECT_REF_P (b1)
267 || TREE_CODE (b1) == MEM_REF
268 || TREE_CODE (b1) == TARGET_MEM_REF;
269
270 bool target_is_memop = DECL_P (b2) || INDIRECT_REF_P (b2)
271 || TREE_CODE (b2) == MEM_REF
272 || TREE_CODE (b2) == TARGET_MEM_REF;
273
274 /* Compare alias sets for memory operands. */
275 if (source_is_memop && target_is_memop)
276 {
277 if (TREE_THIS_VOLATILE (t1) != TREE_THIS_VOLATILE (t2))
278 return return_false_with_msg ("different operand volatility");
279
280 if (ao_ref_alias_set (&r1) != ao_ref_alias_set (&r2)
281 || ao_ref_base_alias_set (&r1) != ao_ref_base_alias_set (&r2))
282 return return_false_with_msg ("ao alias sets are different");
283
284 /* We can't simply use get_object_alignment_1 on the full
285 reference as for accesses with variable indexes this reports
286 too conservative alignment. We also can't use the ao_ref_base
287 base objects as ao_ref_base happily strips MEM_REFs around
288 decls even though that may carry alignment info. */
289 b1 = t1;
290 while (handled_component_p (b1))
291 b1 = TREE_OPERAND (b1, 0);
292 b2 = t2;
293 while (handled_component_p (b2))
294 b2 = TREE_OPERAND (b2, 0);
295 unsigned int align1, align2;
296 unsigned HOST_WIDE_INT tem;
297 get_object_alignment_1 (b1, &align1, &tem);
298 get_object_alignment_1 (b2, &align2, &tem);
299 if (align1 != align2)
300 return return_false_with_msg ("different access alignment");
301
302 /* Similarly we have to compare dependence info where equality
303 tells us we are safe (even some unequal values would be safe
304 but then we have to maintain a map of bases and cliques). */
305 unsigned short clique1 = 0, base1 = 0, clique2 = 0, base2 = 0;
306 if (TREE_CODE (b1) == MEM_REF)
307 {
308 clique1 = MR_DEPENDENCE_CLIQUE (b1);
309 base1 = MR_DEPENDENCE_BASE (b1);
310 }
311 if (TREE_CODE (b2) == MEM_REF)
312 {
313 clique2 = MR_DEPENDENCE_CLIQUE (b2);
314 base2 = MR_DEPENDENCE_BASE (b2);
315 }
316 if (clique1 != clique2 || base1 != base2)
317 return return_false_with_msg ("different dependence info");
318 }
319
320 return compare_operand (t1, t2);
321 }
322
323 /* Function compare for equality given trees T1 and T2 which
324 can be either a constant or a declaration type. */
325
326 bool
327 func_checker::compare_cst_or_decl (tree t1, tree t2)
328 {
329 bool ret;
330 263
331 switch (TREE_CODE (t1)) 264 switch (TREE_CODE (t1))
332 { 265 {
333 case INTEGER_CST:
334 case COMPLEX_CST:
335 case VECTOR_CST:
336 case STRING_CST:
337 case REAL_CST:
338 {
339 ret = compatible_types_p (TREE_TYPE (t1), TREE_TYPE (t2))
340 && operand_equal_p (t1, t2, OEP_ONLY_CONST);
341 return return_with_debug (ret);
342 }
343 case FUNCTION_DECL: 266 case FUNCTION_DECL:
344 /* All function decls are in the symbol table and known to match 267 /* All function decls are in the symbol table and known to match
345 before we start comparing bodies. */ 268 before we start comparing bodies. */
346 return true; 269 return true;
347 case VAR_DECL: 270 case VAR_DECL:
348 return return_with_debug (compare_variable_decl (t1, t2)); 271 return return_with_debug (compare_variable_decl (t1, t2));
349 case FIELD_DECL:
350 {
351 tree offset1 = DECL_FIELD_OFFSET (t1);
352 tree offset2 = DECL_FIELD_OFFSET (t2);
353
354 tree bit_offset1 = DECL_FIELD_BIT_OFFSET (t1);
355 tree bit_offset2 = DECL_FIELD_BIT_OFFSET (t2);
356
357 ret = compare_operand (offset1, offset2)
358 && compare_operand (bit_offset1, bit_offset2);
359
360 return return_with_debug (ret);
361 }
362 case LABEL_DECL: 272 case LABEL_DECL:
363 { 273 {
364 if (t1 == t2)
365 return true;
366
367 int *bb1 = m_label_bb_map.get (t1); 274 int *bb1 = m_label_bb_map.get (t1);
368 int *bb2 = m_label_bb_map.get (t2); 275 int *bb2 = m_label_bb_map.get (t2);
369
370 /* Labels can point to another function (non-local GOTOs). */ 276 /* Labels can point to another function (non-local GOTOs). */
371 return return_with_debug (bb1 != NULL && bb2 != NULL && *bb1 == *bb2); 277 return return_with_debug (bb1 != NULL && bb2 != NULL && *bb1 == *bb2);
372 } 278 }
279
373 case PARM_DECL: 280 case PARM_DECL:
374 case RESULT_DECL: 281 case RESULT_DECL:
375 case CONST_DECL: 282 case CONST_DECL:
376 { 283 return compare_decl (t1, t2);
377 ret = compare_decl (t1, t2); 284 case SSA_NAME:
378 return return_with_debug (ret); 285 return compare_ssa_name (t1, t2);
379 }
380 default: 286 default:
381 gcc_unreachable (); 287 break;
382 } 288 }
289
290 return operand_compare::operand_equal_p (t1, t2, flags);
383 } 291 }
384 292
385 /* Function responsible for comparison of various operands T1 and T2. 293 /* Function responsible for comparison of various operands T1 and T2.
386 If these components, from functions FUNC1 and FUNC2, are equal, true 294 If these components, from functions FUNC1 and FUNC2, are equal, true
387 is returned. */ 295 is returned. */
388 296
389 bool 297 bool
390 func_checker::compare_operand (tree t1, tree t2) 298 func_checker::compare_operand (tree t1, tree t2)
391 { 299 {
392 tree x1, x2, y1, y2, z1, z2;
393 bool ret;
394
395 if (!t1 && !t2) 300 if (!t1 && !t2)
396 return true; 301 return true;
397 else if (!t1 || !t2) 302 else if (!t1 || !t2)
398 return false; 303 return false;
399 304 if (operand_equal_p (t1, t2, OEP_MATCH_SIDE_EFFECTS))
400 tree tt1 = TREE_TYPE (t1); 305 return true;
401 tree tt2 = TREE_TYPE (t2); 306 return return_false_with_msg ("operand_equal_p failed");
402
403 if (!func_checker::compatible_types_p (tt1, tt2))
404 return false;
405
406 if (TREE_CODE (t1) != TREE_CODE (t2))
407 return return_false ();
408
409 switch (TREE_CODE (t1))
410 {
411 case CONSTRUCTOR:
412 {
413 unsigned length1 = CONSTRUCTOR_NELTS (t1);
414 unsigned length2 = CONSTRUCTOR_NELTS (t2);
415
416 if (length1 != length2)
417 return return_false ();
418
419 for (unsigned i = 0; i < length1; i++)
420 if (!compare_operand (CONSTRUCTOR_ELT (t1, i)->value,
421 CONSTRUCTOR_ELT (t2, i)->value))
422 return return_false();
423
424 return true;
425 }
426 case ARRAY_REF:
427 case ARRAY_RANGE_REF:
428 /* First argument is the array, second is the index. */
429 x1 = TREE_OPERAND (t1, 0);
430 x2 = TREE_OPERAND (t2, 0);
431 y1 = TREE_OPERAND (t1, 1);
432 y2 = TREE_OPERAND (t2, 1);
433
434 if (!compare_operand (array_ref_low_bound (t1),
435 array_ref_low_bound (t2)))
436 return return_false_with_msg ("");
437 if (!compare_operand (array_ref_element_size (t1),
438 array_ref_element_size (t2)))
439 return return_false_with_msg ("");
440
441 if (!compare_operand (x1, x2))
442 return return_false_with_msg ("");
443 return compare_operand (y1, y2);
444 case MEM_REF:
445 {
446 x1 = TREE_OPERAND (t1, 0);
447 x2 = TREE_OPERAND (t2, 0);
448 y1 = TREE_OPERAND (t1, 1);
449 y2 = TREE_OPERAND (t2, 1);
450
451 /* See if operand is an memory access (the test originate from
452 gimple_load_p).
453
454 In this case the alias set of the function being replaced must
455 be subset of the alias set of the other function. At the moment
456 we seek for equivalency classes, so simply require inclussion in
457 both directions. */
458
459 if (!func_checker::compatible_types_p (TREE_TYPE (x1), TREE_TYPE (x2)))
460 return return_false ();
461
462 if (!compare_operand (x1, x2))
463 return return_false_with_msg ("");
464
465 /* Type of the offset on MEM_REF does not matter. */
466 return known_eq (wi::to_poly_offset (y1), wi::to_poly_offset (y2));
467 }
468 case COMPONENT_REF:
469 {
470 x1 = TREE_OPERAND (t1, 0);
471 x2 = TREE_OPERAND (t2, 0);
472 y1 = TREE_OPERAND (t1, 1);
473 y2 = TREE_OPERAND (t2, 1);
474
475 ret = compare_operand (x1, x2)
476 && compare_cst_or_decl (y1, y2);
477
478 return return_with_debug (ret);
479 }
480 /* Virtual table call. */
481 case OBJ_TYPE_REF:
482 {
483 if (!compare_ssa_name (OBJ_TYPE_REF_EXPR (t1), OBJ_TYPE_REF_EXPR (t2)))
484 return return_false ();
485 if (opt_for_fn (m_source_func_decl, flag_devirtualize)
486 && virtual_method_call_p (t1))
487 {
488 if (tree_to_uhwi (OBJ_TYPE_REF_TOKEN (t1))
489 != tree_to_uhwi (OBJ_TYPE_REF_TOKEN (t2)))
490 return return_false_with_msg ("OBJ_TYPE_REF token mismatch");
491 if (!types_same_for_odr (obj_type_ref_class (t1),
492 obj_type_ref_class (t2)))
493 return return_false_with_msg ("OBJ_TYPE_REF OTR type mismatch");
494 if (!compare_operand (OBJ_TYPE_REF_OBJECT (t1),
495 OBJ_TYPE_REF_OBJECT (t2)))
496 return return_false_with_msg ("OBJ_TYPE_REF object mismatch");
497 }
498
499 return return_with_debug (true);
500 }
501 case IMAGPART_EXPR:
502 case REALPART_EXPR:
503 case ADDR_EXPR:
504 {
505 x1 = TREE_OPERAND (t1, 0);
506 x2 = TREE_OPERAND (t2, 0);
507
508 ret = compare_operand (x1, x2);
509 return return_with_debug (ret);
510 }
511 case BIT_FIELD_REF:
512 {
513 x1 = TREE_OPERAND (t1, 0);
514 x2 = TREE_OPERAND (t2, 0);
515 y1 = TREE_OPERAND (t1, 1);
516 y2 = TREE_OPERAND (t2, 1);
517 z1 = TREE_OPERAND (t1, 2);
518 z2 = TREE_OPERAND (t2, 2);
519
520 ret = compare_operand (x1, x2)
521 && compare_cst_or_decl (y1, y2)
522 && compare_cst_or_decl (z1, z2);
523
524 return return_with_debug (ret);
525 }
526 case SSA_NAME:
527 return compare_ssa_name (t1, t2);
528 case INTEGER_CST:
529 case COMPLEX_CST:
530 case VECTOR_CST:
531 case STRING_CST:
532 case REAL_CST:
533 case FUNCTION_DECL:
534 case VAR_DECL:
535 case FIELD_DECL:
536 case LABEL_DECL:
537 case PARM_DECL:
538 case RESULT_DECL:
539 case CONST_DECL:
540 return compare_cst_or_decl (t1, t2);
541 default:
542 return return_false_with_msg ("Unknown TREE code reached");
543 }
544 } 307 }
545 308
546 bool 309 bool
547 func_checker::compare_asm_inputs_outputs (tree t1, tree t2) 310 func_checker::compare_asm_inputs_outputs (tree t1, tree t2)
548 { 311 {
577 } 340 }
578 341
579 /* Verifies that trees T1 and T2 do correspond. */ 342 /* Verifies that trees T1 and T2 do correspond. */
580 343
581 bool 344 bool
582 func_checker::compare_variable_decl (tree t1, tree t2) 345 func_checker::compare_variable_decl (const_tree t1, const_tree t2)
583 { 346 {
584 bool ret = false; 347 bool ret = false;
585 348
586 if (t1 == t2) 349 if (t1 == t2)
587 return true; 350 return true;
591 354
592 if (DECL_HARD_REGISTER (t1) != DECL_HARD_REGISTER (t2)) 355 if (DECL_HARD_REGISTER (t1) != DECL_HARD_REGISTER (t2))
593 return return_false_with_msg ("DECL_HARD_REGISTER are different"); 356 return return_false_with_msg ("DECL_HARD_REGISTER are different");
594 357
595 if (DECL_HARD_REGISTER (t1) 358 if (DECL_HARD_REGISTER (t1)
596 && DECL_ASSEMBLER_NAME (t1) != DECL_ASSEMBLER_NAME (t2)) 359 && DECL_ASSEMBLER_NAME_RAW (t1) != DECL_ASSEMBLER_NAME_RAW (t2))
597 return return_false_with_msg ("HARD REGISTERS are different"); 360 return return_false_with_msg ("HARD REGISTERS are different");
598 361
599 /* Symbol table variables are known to match before we start comparing 362 /* Symbol table variables are known to match before we start comparing
600 bodies. */ 363 bodies. */
601 if (decl_in_symtab_p (t1)) 364 if (decl_in_symtab_p (t1))
603 ret = compare_decl (t1, t2); 366 ret = compare_decl (t1, t2);
604 367
605 return return_with_debug (ret); 368 return return_with_debug (ret);
606 } 369 }
607 370
371 /* Compare loop information for basic blocks BB1 and BB2. */
372
373 bool
374 func_checker::compare_loops (basic_block bb1, basic_block bb2)
375 {
376 if ((bb1->loop_father == NULL) != (bb2->loop_father == NULL))
377 return return_false ();
378
379 class loop *l1 = bb1->loop_father;
380 class loop *l2 = bb2->loop_father;
381 if (l1 == NULL)
382 return true;
383
384 if ((bb1 == l1->header) != (bb2 == l2->header))
385 return return_false_with_msg ("header");
386 if ((bb1 == l1->latch) != (bb2 == l2->latch))
387 return return_false_with_msg ("latch");
388 if (l1->simdlen != l2->simdlen)
389 return return_false_with_msg ("simdlen");
390 if (l1->safelen != l2->safelen)
391 return return_false_with_msg ("safelen");
392 if (l1->can_be_parallel != l2->can_be_parallel)
393 return return_false_with_msg ("can_be_parallel");
394 if (l1->dont_vectorize != l2->dont_vectorize)
395 return return_false_with_msg ("dont_vectorize");
396 if (l1->force_vectorize != l2->force_vectorize)
397 return return_false_with_msg ("force_vectorize");
398 if (l1->unroll != l2->unroll)
399 return return_false_with_msg ("unroll");
400 if (!compare_variable_decl (l1->simduid, l2->simduid))
401 return return_false_with_msg ("simduid");
402
403 return true;
404 }
608 405
609 /* Function visits all gimple labels and creates corresponding 406 /* Function visits all gimple labels and creates corresponding
610 mapping between basic blocks and labels. */ 407 mapping between basic blocks and labels. */
611 408
612 void 409 void
617 { 414 {
618 gimple *stmt = gsi_stmt (gsi); 415 gimple *stmt = gsi_stmt (gsi);
619 416
620 if (glabel *label_stmt = dyn_cast <glabel *> (stmt)) 417 if (glabel *label_stmt = dyn_cast <glabel *> (stmt))
621 { 418 {
622 tree t = gimple_label_label (label_stmt); 419 const_tree t = gimple_label_label (label_stmt);
623 gcc_assert (TREE_CODE (t) == LABEL_DECL); 420 gcc_assert (TREE_CODE (t) == LABEL_DECL);
624 421
625 m_label_bb_map.put (t, bb->bb->index); 422 m_label_bb_map.put (t, bb->bb->index);
626 } 423 }
627 } 424 }
723 gsi_next_nondebug (&gsi1); 520 gsi_next_nondebug (&gsi1);
724 gsi_next_nondebug (&gsi2); 521 gsi_next_nondebug (&gsi2);
725 } 522 }
726 523
727 if (!gsi_end_p (gsi2)) 524 if (!gsi_end_p (gsi2))
525 return return_false ();
526
527 if (!compare_loops (bb1->bb, bb2->bb))
728 return return_false (); 528 return return_false ();
729 529
730 return true; 530 return true;
731 } 531 }
732 532
779 for (i = 0; i < gimple_call_num_args (s1); ++i) 579 for (i = 0; i < gimple_call_num_args (s1); ++i)
780 { 580 {
781 t1 = gimple_call_arg (s1, i); 581 t1 = gimple_call_arg (s1, i);
782 t2 = gimple_call_arg (s2, i); 582 t2 = gimple_call_arg (s2, i);
783 583
784 if (!compare_memory_operand (t1, t2)) 584 if (!compare_operand (t1, t2))
785 return return_false_with_msg ("memory operands are different"); 585 return return_false_with_msg ("GIMPLE call operands are different");
786 } 586 }
787 587
788 /* Return value checking. */ 588 /* Return value checking. */
789 t1 = gimple_get_lhs (s1); 589 t1 = gimple_get_lhs (s1);
790 t2 = gimple_get_lhs (s2); 590 t2 = gimple_get_lhs (s2);
791 591
792 return compare_memory_operand (t1, t2); 592 return compare_operand (t1, t2);
793 } 593 }
794 594
795 595
796 /* Verifies for given GIMPLEs S1 and S2 that 596 /* Verifies for given GIMPLEs S1 and S2 that
797 assignment statements are semantically equivalent. */ 597 assignment statements are semantically equivalent. */
818 for (i = 0; i < gimple_num_ops (s1); i++) 618 for (i = 0; i < gimple_num_ops (s1); i++)
819 { 619 {
820 arg1 = gimple_op (s1, i); 620 arg1 = gimple_op (s1, i);
821 arg2 = gimple_op (s2, i); 621 arg2 = gimple_op (s2, i);
822 622
823 if (!compare_memory_operand (arg1, arg2)) 623 /* LHS types of NOP_EXPR must be compatible. */
824 return return_false_with_msg ("memory operands are different"); 624 if (CONVERT_EXPR_CODE_P (code1) && i == 0)
625 {
626 if (!compatible_types_p (TREE_TYPE (arg1), TREE_TYPE (arg2)))
627 return return_false_with_msg ("GIMPLE NOP LHS type mismatch");
628 }
629
630 if (!compare_operand (arg1, arg2))
631 return return_false_with_msg ("GIMPLE assignment operands "
632 "are different");
825 } 633 }
826 634
827 635
828 return true; 636 return true;
829 } 637 }
850 return false; 658 return false;
851 659
852 t1 = gimple_cond_rhs (s1); 660 t1 = gimple_cond_rhs (s1);
853 t2 = gimple_cond_rhs (s2); 661 t2 = gimple_cond_rhs (s2);
854 662
855 return compare_operand (t1, t2);
856 }
857
858 /* Verifies that tree labels T1 and T2 correspond in FUNC1 and FUNC2. */
859
860 bool
861 func_checker::compare_tree_ssa_label (tree t1, tree t2)
862 {
863 return compare_operand (t1, t2); 663 return compare_operand (t1, t2);
864 } 664 }
865 665
866 /* Verifies for given GIMPLE_LABEL stmts S1 and S2 that 666 /* Verifies for given GIMPLE_LABEL stmts S1 and S2 that
867 label statements are semantically equivalent. */ 667 label statements are semantically equivalent. */
991 return false; 791 return false;
992 792
993 if (gimple_asm_input_p (g1) != gimple_asm_input_p (g2)) 793 if (gimple_asm_input_p (g1) != gimple_asm_input_p (g2))
994 return false; 794 return false;
995 795
796 if (gimple_asm_inline_p (g1) != gimple_asm_inline_p (g2))
797 return false;
798
996 if (gimple_asm_ninputs (g1) != gimple_asm_ninputs (g2)) 799 if (gimple_asm_ninputs (g1) != gimple_asm_ninputs (g2))
997 return false; 800 return false;
998 801
999 if (gimple_asm_noutputs (g1) != gimple_asm_noutputs (g2)) 802 if (gimple_asm_noutputs (g1) != gimple_asm_noutputs (g2))
1000 return false; 803 return false;