comparison gcc/tree-ssa-ccp.c @ 131:84e7813d76e9

gcc-8.2
author mir3636
date Thu, 25 Oct 2018 07:37:49 +0900
parents 04ced10e8804
children 1830386684a0
comparison
equal deleted inserted replaced
111:04ced10e8804 131:84e7813d76e9
1 /* Conditional constant propagation pass for the GNU compiler. 1 /* Conditional constant propagation pass for the GNU compiler.
2 Copyright (C) 2000-2017 Free Software Foundation, Inc. 2 Copyright (C) 2000-2018 Free Software Foundation, Inc.
3 Adapted from original RTL SSA-CCP by Daniel Berlin <dberlin@dberlin.org> 3 Adapted from original RTL SSA-CCP by Daniel Berlin <dberlin@dberlin.org>
4 Adapted to GIMPLE trees by Diego Novillo <dnovillo@redhat.com> 4 Adapted to GIMPLE trees by Diego Novillo <dnovillo@redhat.com>
5 5
6 This file is part of GCC. 6 This file is part of GCC.
7 7
136 #include "tree-cfg.h" 136 #include "tree-cfg.h"
137 #include "tree-ssa-propagate.h" 137 #include "tree-ssa-propagate.h"
138 #include "dbgcnt.h" 138 #include "dbgcnt.h"
139 #include "params.h" 139 #include "params.h"
140 #include "builtins.h" 140 #include "builtins.h"
141 #include "tree-chkp.h"
142 #include "cfgloop.h" 141 #include "cfgloop.h"
143 #include "stor-layout.h" 142 #include "stor-layout.h"
144 #include "optabs-query.h" 143 #include "optabs-query.h"
145 #include "tree-ssa-ccp.h" 144 #include "tree-ssa-ccp.h"
146 #include "tree-dfa.h" 145 #include "tree-dfa.h"
147 #include "diagnostic-core.h" 146 #include "diagnostic-core.h"
148 #include "stringpool.h" 147 #include "stringpool.h"
149 #include "attribs.h" 148 #include "attribs.h"
149 #include "tree-vector-builder.h"
150 150
151 /* Possible lattice values. */ 151 /* Possible lattice values. */
152 typedef enum 152 typedef enum
153 { 153 {
154 UNINITIALIZED, 154 UNINITIALIZED,
167 /* Mask that applies to the propagated value during CCP. For X 167 /* Mask that applies to the propagated value during CCP. For X
168 with a CONSTANT lattice value X & ~mask == value & ~mask. The 168 with a CONSTANT lattice value X & ~mask == value & ~mask. The
169 zero bits in the mask cover constant values. The ones mean no 169 zero bits in the mask cover constant values. The ones mean no
170 information. */ 170 information. */
171 widest_int mask; 171 widest_int mask;
172 };
173
174 class ccp_propagate : public ssa_propagation_engine
175 {
176 public:
177 enum ssa_prop_result visit_stmt (gimple *, edge *, tree *) FINAL OVERRIDE;
178 enum ssa_prop_result visit_phi (gphi *) FINAL OVERRIDE;
172 }; 179 };
173 180
174 /* Array of propagated constant values. After propagation, 181 /* Array of propagated constant values. After propagation,
175 CONST_VAL[I].VALUE holds the constant value for SSA_NAME(I). If 182 CONST_VAL[I].VALUE holds the constant value for SSA_NAME(I). If
176 the constant is held in an SSA name representing a memory store 183 the constant is held in an SSA name representing a memory store
179 doing the store). */ 186 doing the store). */
180 static ccp_prop_value_t *const_val; 187 static ccp_prop_value_t *const_val;
181 static unsigned n_const_val; 188 static unsigned n_const_val;
182 189
183 static void canonicalize_value (ccp_prop_value_t *); 190 static void canonicalize_value (ccp_prop_value_t *);
184 static bool ccp_fold_stmt (gimple_stmt_iterator *);
185 static void ccp_lattice_meet (ccp_prop_value_t *, ccp_prop_value_t *); 191 static void ccp_lattice_meet (ccp_prop_value_t *, ccp_prop_value_t *);
186 192
187 /* Dump constant propagation value VAL to file OUTF prefixed by PREFIX. */ 193 /* Dump constant propagation value VAL to file OUTF prefixed by PREFIX. */
188 194
189 static void 195 static void
457 return true; 463 return true;
458 } 464 }
459 else if (VECTOR_FLOAT_TYPE_P (type) 465 else if (VECTOR_FLOAT_TYPE_P (type)
460 && !HONOR_NANS (type)) 466 && !HONOR_NANS (type))
461 { 467 {
462 for (unsigned i = 0; i < VECTOR_CST_NELTS (old_val.value); ++i) 468 unsigned int count
469 = tree_vector_builder::binary_encoded_nelts (old_val.value,
470 new_val.value);
471 for (unsigned int i = 0; i < count; ++i)
463 if (!REAL_VALUE_ISNAN 472 if (!REAL_VALUE_ISNAN
464 (TREE_REAL_CST (VECTOR_CST_ELT (old_val.value, i))) 473 (TREE_REAL_CST (VECTOR_CST_ENCODED_ELT (old_val.value, i)))
465 && !operand_equal_p (VECTOR_CST_ELT (old_val.value, i), 474 && !operand_equal_p (VECTOR_CST_ENCODED_ELT (old_val.value, i),
466 VECTOR_CST_ELT (new_val.value, i), 0)) 475 VECTOR_CST_ENCODED_ELT (new_val.value, i), 0))
467 return false; 476 return false;
468 return true; 477 return true;
469 } 478 }
470 else if (COMPLEX_FLOAT_TYPE_P (type) 479 else if (COMPLEX_FLOAT_TYPE_P (type)
471 && !HONOR_NANS (type)) 480 && !HONOR_NANS (type))
796 if (is_gimple_call (stmt)) 805 if (is_gimple_call (stmt))
797 { 806 {
798 tree fndecl, fntype = gimple_call_fntype (stmt); 807 tree fndecl, fntype = gimple_call_fntype (stmt);
799 if (!gimple_call_lhs (stmt) 808 if (!gimple_call_lhs (stmt)
800 || ((fndecl = gimple_call_fndecl (stmt)) != NULL_TREE 809 || ((fndecl = gimple_call_fndecl (stmt)) != NULL_TREE
801 && !DECL_BUILT_IN (fndecl) 810 && !fndecl_built_in_p (fndecl)
802 && !lookup_attribute ("assume_aligned", 811 && !lookup_attribute ("assume_aligned",
803 TYPE_ATTRIBUTES (fntype)) 812 TYPE_ATTRIBUTES (fntype))
804 && !lookup_attribute ("alloc_align", 813 && !lookup_attribute ("alloc_align",
805 TYPE_ATTRIBUTES (fntype)))) 814 TYPE_ATTRIBUTES (fntype))))
806 return true; 815 return true;
899 const_val[i].value = NULL_TREE; 908 const_val[i].value = NULL_TREE;
900 } 909 }
901 } 910 }
902 } 911 }
903 912
913
914 /* We want to provide our own GET_VALUE and FOLD_STMT virtual methods. */
915 class ccp_folder : public substitute_and_fold_engine
916 {
917 public:
918 tree get_value (tree) FINAL OVERRIDE;
919 bool fold_stmt (gimple_stmt_iterator *) FINAL OVERRIDE;
920 };
921
922 /* This method just wraps GET_CONSTANT_VALUE for now. Over time
923 naked calls to GET_CONSTANT_VALUE should be eliminated in favor
924 of calling member functions. */
925
926 tree
927 ccp_folder::get_value (tree op)
928 {
929 return get_constant_value (op);
930 }
904 931
905 /* Do final substitution of propagated values, cleanup the flowgraph and 932 /* Do final substitution of propagated values, cleanup the flowgraph and
906 free allocated storage. If NONZERO_P, record nonzero bits. 933 free allocated storage. If NONZERO_P, record nonzero bits.
907 934
908 Return TRUE when something was optimized. */ 935 Return TRUE when something was optimized. */
958 set_nonzero_bits (name, nonzero_bits); 985 set_nonzero_bits (name, nonzero_bits);
959 } 986 }
960 } 987 }
961 988
962 /* Perform substitutions based on the known constant values. */ 989 /* Perform substitutions based on the known constant values. */
963 something_changed = substitute_and_fold (get_constant_value, ccp_fold_stmt); 990 class ccp_folder ccp_folder;
991 something_changed = ccp_folder.substitute_and_fold ();
964 992
965 free (const_val); 993 free (const_val);
966 const_val = NULL; 994 const_val = NULL;
967 return something_changed;; 995 return something_changed;
968 } 996 }
969 997
970 998
971 /* Compute the meet operator between *VAL1 and *VAL2. Store the result 999 /* Compute the meet operator between *VAL1 and *VAL2. Store the result
972 in VAL1. 1000 in VAL1.
1062 /* Loop through the PHI_NODE's parameters for BLOCK and compare their 1090 /* Loop through the PHI_NODE's parameters for BLOCK and compare their
1063 lattice values to determine PHI_NODE's lattice value. The value of a 1091 lattice values to determine PHI_NODE's lattice value. The value of a
1064 PHI node is determined calling ccp_lattice_meet with all the arguments 1092 PHI node is determined calling ccp_lattice_meet with all the arguments
1065 of the PHI node that are incoming via executable edges. */ 1093 of the PHI node that are incoming via executable edges. */
1066 1094
1067 static enum ssa_prop_result 1095 enum ssa_prop_result
1068 ccp_visit_phi_node (gphi *phi) 1096 ccp_propagate::visit_phi (gphi *phi)
1069 { 1097 {
1070 unsigned i; 1098 unsigned i;
1071 ccp_prop_value_t new_val; 1099 ccp_prop_value_t new_val;
1072 1100
1073 if (dump_file && (dump_flags & TDF_DETAILS)) 1101 if (dump_file && (dump_flags & TDF_DETAILS))
1089 edge e = gimple_phi_arg_edge (phi, i); 1117 edge e = gimple_phi_arg_edge (phi, i);
1090 1118
1091 if (dump_file && (dump_flags & TDF_DETAILS)) 1119 if (dump_file && (dump_flags & TDF_DETAILS))
1092 { 1120 {
1093 fprintf (dump_file, 1121 fprintf (dump_file,
1094 "\n Argument #%d (%d -> %d %sexecutable)\n", 1122 "\tArgument #%d (%d -> %d %sexecutable)\n",
1095 i, e->src->index, e->dest->index, 1123 i, e->src->index, e->dest->index,
1096 (e->flags & EDGE_EXECUTABLE) ? "" : "not "); 1124 (e->flags & EDGE_EXECUTABLE) ? "" : "not ");
1097 } 1125 }
1098 1126
1099 /* If the incoming edge is executable, Compute the meet operator for 1127 /* If the incoming edge is executable, Compute the meet operator for
2049 visited); 2077 visited);
2050 } 2078 }
2051 else if (gimple_assign_ssa_name_copy_p (stmt)) 2079 else if (gimple_assign_ssa_name_copy_p (stmt))
2052 insert_clobber_before_stack_restore (gimple_assign_lhs (stmt), var, 2080 insert_clobber_before_stack_restore (gimple_assign_lhs (stmt), var,
2053 visited); 2081 visited);
2054 else if (chkp_gimple_call_builtin_p (stmt, BUILT_IN_CHKP_BNDRET))
2055 continue;
2056 else 2082 else
2057 gcc_assert (is_gimple_debug (stmt)); 2083 gcc_assert (is_gimple_debug (stmt));
2058 } 2084 }
2059 2085
2060 /* Advance the iterator to the previous non-debug gimple statement in the same 2086 /* Advance the iterator to the previous non-debug gimple statement in the same
2167 } 2193 }
2168 2194
2169 /* Fold the stmt at *GSI with CCP specific information that propagating 2195 /* Fold the stmt at *GSI with CCP specific information that propagating
2170 and regular folding does not catch. */ 2196 and regular folding does not catch. */
2171 2197
2172 static bool 2198 bool
2173 ccp_fold_stmt (gimple_stmt_iterator *gsi) 2199 ccp_folder::fold_stmt (gimple_stmt_iterator *gsi)
2174 { 2200 {
2175 gimple *stmt = gsi_stmt (*gsi); 2201 gimple *stmt = gsi_stmt (*gsi);
2176 2202
2177 switch (gimple_code (stmt)) 2203 switch (gimple_code (stmt))
2178 { 2204 {
2376 2402
2377 If STMT is a conditional branch and we can determine its truth 2403 If STMT is a conditional branch and we can determine its truth
2378 value, set *TAKEN_EDGE_P accordingly. If STMT produces a varying 2404 value, set *TAKEN_EDGE_P accordingly. If STMT produces a varying
2379 value, return SSA_PROP_VARYING. */ 2405 value, return SSA_PROP_VARYING. */
2380 2406
2381 static enum ssa_prop_result 2407 enum ssa_prop_result
2382 ccp_visit_stmt (gimple *stmt, edge *taken_edge_p, tree *output_p) 2408 ccp_propagate::visit_stmt (gimple *stmt, edge *taken_edge_p, tree *output_p)
2383 { 2409 {
2384 tree def; 2410 tree def;
2385 ssa_op_iter iter; 2411 ssa_op_iter iter;
2386 2412
2387 if (dump_file && (dump_flags & TDF_DETAILS)) 2413 if (dump_file && (dump_flags & TDF_DETAILS))
2439 { 2465 {
2440 unsigned int todo = 0; 2466 unsigned int todo = 0;
2441 calculate_dominance_info (CDI_DOMINATORS); 2467 calculate_dominance_info (CDI_DOMINATORS);
2442 2468
2443 ccp_initialize (); 2469 ccp_initialize ();
2444 ssa_propagate (ccp_visit_stmt, ccp_visit_phi_node); 2470 class ccp_propagate ccp_propagate;
2471 ccp_propagate.ssa_propagate ();
2445 if (ccp_finalize (nonzero_p || flag_ipa_bit_cp)) 2472 if (ccp_finalize (nonzero_p || flag_ipa_bit_cp))
2446 { 2473 {
2447 todo = (TODO_cleanup_cfg | TODO_update_ssa); 2474 todo = (TODO_cleanup_cfg | TODO_update_ssa);
2448 2475
2449 /* ccp_finalize does not preserve loop-closed ssa. */ 2476 /* ccp_finalize does not preserve loop-closed ssa. */
2531 if (gimple_code (stmt) != GIMPLE_CALL) 2558 if (gimple_code (stmt) != GIMPLE_CALL)
2532 continue; 2559 continue;
2533 2560
2534 callee = gimple_call_fndecl (stmt); 2561 callee = gimple_call_fndecl (stmt);
2535 if (!callee 2562 if (!callee
2536 || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL 2563 || !fndecl_built_in_p (callee, BUILT_IN_NORMAL)
2537 /* All regular builtins are ok, just obviously not alloca. */ 2564 /* All regular builtins are ok, just obviously not alloca. */
2538 || ALLOCA_FUNCTION_CODE_P (DECL_FUNCTION_CODE (callee))) 2565 || ALLOCA_FUNCTION_CODE_P (DECL_FUNCTION_CODE (callee)))
2539 return NULL_TREE; 2566 return NULL_TREE;
2540 2567
2541 if (DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_RESTORE) 2568 if (DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_RESTORE)
2567 { 2594 {
2568 gimple *stack_save = SSA_NAME_DEF_STMT (gimple_call_arg (call, 0)); 2595 gimple *stack_save = SSA_NAME_DEF_STMT (gimple_call_arg (call, 0));
2569 if (is_gimple_call (stack_save)) 2596 if (is_gimple_call (stack_save))
2570 { 2597 {
2571 callee = gimple_call_fndecl (stack_save); 2598 callee = gimple_call_fndecl (stack_save);
2572 if (callee 2599 if (callee && fndecl_built_in_p (callee, BUILT_IN_STACK_SAVE))
2573 && DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL
2574 && DECL_FUNCTION_CODE (callee) == BUILT_IN_STACK_SAVE)
2575 { 2600 {
2576 gimple_stmt_iterator stack_save_gsi; 2601 gimple_stmt_iterator stack_save_gsi;
2577 tree rhs; 2602 tree rhs;
2578 2603
2579 stack_save_gsi = gsi_for_stmt (stack_save); 2604 stack_save_gsi = gsi_for_stmt (stack_save);
2904 bit, flag); 2929 bit, flag);
2905 gimple_call_set_lhs (g, new_lhs); 2930 gimple_call_set_lhs (g, new_lhs);
2906 gimple_set_location (g, gimple_location (call)); 2931 gimple_set_location (g, gimple_location (call));
2907 gimple_set_vuse (g, gimple_vuse (call)); 2932 gimple_set_vuse (g, gimple_vuse (call));
2908 gimple_set_vdef (g, gimple_vdef (call)); 2933 gimple_set_vdef (g, gimple_vdef (call));
2909 bool throws = stmt_can_throw_internal (call); 2934 bool throws = stmt_can_throw_internal (cfun, call);
2910 gimple_call_set_nothrow (as_a <gcall *> (g), 2935 gimple_call_set_nothrow (as_a <gcall *> (g),
2911 gimple_call_nothrow_p (as_a <gcall *> (call))); 2936 gimple_call_nothrow_p (as_a <gcall *> (call)));
2912 SSA_NAME_DEF_STMT (gimple_vdef (call)) = g; 2937 SSA_NAME_DEF_STMT (gimple_vdef (call)) = g;
2913 gimple_stmt_iterator gsi = *gsip; 2938 gimple_stmt_iterator gsi = *gsip;
2914 gsi_insert_after (&gsi, g, GSI_NEW_STMT); 2939 gsi_insert_after (&gsi, g, GSI_NEW_STMT);
3000 if (vuse == NULL) 3025 if (vuse == NULL)
3001 return; 3026 return;
3002 3027
3003 gimple *defstmt = SSA_NAME_DEF_STMT (vuse); 3028 gimple *defstmt = SSA_NAME_DEF_STMT (vuse);
3004 tree src2 = NULL_TREE, len2 = NULL_TREE; 3029 tree src2 = NULL_TREE, len2 = NULL_TREE;
3005 HOST_WIDE_INT offset, offset2; 3030 poly_int64 offset, offset2;
3006 tree val = integer_zero_node; 3031 tree val = integer_zero_node;
3007 if (gimple_store_p (defstmt) 3032 if (gimple_store_p (defstmt)
3008 && gimple_assign_single_p (defstmt) 3033 && gimple_assign_single_p (defstmt)
3009 && TREE_CODE (gimple_assign_rhs1 (defstmt)) == CONSTRUCTOR 3034 && TREE_CODE (gimple_assign_rhs1 (defstmt)) == CONSTRUCTOR
3010 && !gimple_clobber_p (defstmt)) 3035 && !gimple_clobber_p (defstmt))
3032 if (len2 == NULL_TREE) 3057 if (len2 == NULL_TREE)
3033 len2 = (TREE_CODE (src2) == COMPONENT_REF 3058 len2 = (TREE_CODE (src2) == COMPONENT_REF
3034 ? DECL_SIZE_UNIT (TREE_OPERAND (src2, 1)) 3059 ? DECL_SIZE_UNIT (TREE_OPERAND (src2, 1))
3035 : TYPE_SIZE_UNIT (TREE_TYPE (src2))); 3060 : TYPE_SIZE_UNIT (TREE_TYPE (src2)));
3036 if (len == NULL_TREE 3061 if (len == NULL_TREE
3037 || TREE_CODE (len) != INTEGER_CST 3062 || !poly_int_tree_p (len)
3038 || len2 == NULL_TREE 3063 || len2 == NULL_TREE
3039 || TREE_CODE (len2) != INTEGER_CST) 3064 || !poly_int_tree_p (len2))
3040 return; 3065 return;
3041 3066
3042 src = get_addr_base_and_unit_offset (src, &offset); 3067 src = get_addr_base_and_unit_offset (src, &offset);
3043 src2 = get_addr_base_and_unit_offset (src2, &offset2); 3068 src2 = get_addr_base_and_unit_offset (src2, &offset2);
3044 if (src == NULL_TREE 3069 if (src == NULL_TREE
3045 || src2 == NULL_TREE 3070 || src2 == NULL_TREE
3046 || offset < offset2) 3071 || maybe_lt (offset, offset2))
3047 return; 3072 return;
3048 3073
3049 if (!operand_equal_p (src, src2, 0)) 3074 if (!operand_equal_p (src, src2, 0))
3050 return; 3075 return;
3051 3076
3052 /* [ src + offset2, src + offset2 + len2 - 1 ] is set to val. 3077 /* [ src + offset2, src + offset2 + len2 - 1 ] is set to val.
3053 Make sure that 3078 Make sure that
3054 [ src + offset, src + offset + len - 1 ] is a subset of that. */ 3079 [ src + offset, src + offset + len - 1 ] is a subset of that. */
3055 if (wi::to_offset (len) + (offset - offset2) > wi::to_offset (len2)) 3080 if (maybe_gt (wi::to_poly_offset (len) + (offset - offset2),
3081 wi::to_poly_offset (len2)))
3056 return; 3082 return;
3057 3083
3058 if (dump_file && (dump_flags & TDF_DETAILS)) 3084 if (dump_file && (dump_flags & TDF_DETAILS))
3059 { 3085 {
3060 fprintf (dump_file, "Simplified\n "); 3086 fprintf (dump_file, "Simplified\n ");
3165 gsi_next (&i); 3191 gsi_next (&i);
3166 continue; 3192 continue;
3167 } 3193 }
3168 3194
3169 callee = gimple_call_fndecl (stmt); 3195 callee = gimple_call_fndecl (stmt);
3170 if (!callee || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL) 3196 if (!callee || !fndecl_built_in_p (callee, BUILT_IN_NORMAL))
3171 { 3197 {
3172 gsi_next (&i); 3198 gsi_next (&i);
3173 continue; 3199 continue;
3174 } 3200 }
3175 3201
3340 gsi_next (&i); 3366 gsi_next (&i);
3341 continue; 3367 continue;
3342 } 3368 }
3343 callee = gimple_call_fndecl (stmt); 3369 callee = gimple_call_fndecl (stmt);
3344 if (!callee 3370 if (!callee
3345 || DECL_BUILT_IN_CLASS (callee) != BUILT_IN_NORMAL 3371 || !fndecl_built_in_p (callee, fcode))
3346 || DECL_FUNCTION_CODE (callee) == fcode)
3347 gsi_next (&i); 3372 gsi_next (&i);
3348 } 3373 }
3349 } 3374 }
3350 3375
3351 /* Delete unreachable blocks. */ 3376 /* Delete unreachable blocks. */
3424 if (!bitmap_empty_p (nonnullargs) 3449 if (!bitmap_empty_p (nonnullargs)
3425 && !bitmap_bit_p (nonnullargs, i)) 3450 && !bitmap_bit_p (nonnullargs, i))
3426 continue; 3451 continue;
3427 3452
3428 location_t loc = gimple_location (stmt); 3453 location_t loc = gimple_location (stmt);
3454 auto_diagnostic_group d;
3429 if (warning_at (loc, OPT_Wnonnull, 3455 if (warning_at (loc, OPT_Wnonnull,
3430 "argument %u null where non-null " 3456 "%Gargument %u null where non-null "
3431 "expected", i + 1)) 3457 "expected", stmt, i + 1))
3432 { 3458 {
3433 tree fndecl = gimple_call_fndecl (stmt); 3459 tree fndecl = gimple_call_fndecl (stmt);
3434 if (fndecl && DECL_IS_BUILTIN (fndecl)) 3460 if (fndecl && DECL_IS_BUILTIN (fndecl))
3435 inform (loc, "in a call to built-in function %qD", 3461 inform (loc, "in a call to built-in function %qD",
3436 fndecl); 3462 fndecl);