aboutsummaryrefslogtreecommitdiff
path: root/gcc/gimple-predicate-analysis.cc
AgeCommit message (Collapse)AuthorFilesLines
2024-06-03Remove value_range typedef.Aldy Hernandez1-1/+1
Now that pointers and integers have been disambiguated from irange, and all the pointer range temporaries use prange, we can reclaim value_range as a general purpose range container. This patch removes the typedef, in favor of int_range_max, thus providing slightly better ranges in places. I have also used int_range<1> or <2> when it's known ahead of time how big the range will be, thus saving a few words. In a follow-up patch I will rename the Value_Range temporary to value_range. No change in performance. gcc/ChangeLog: * builtins.cc (expand_builtin_strnlen): Replace value_range use with int_range_max or irange when appropriate. (determine_block_size): Same. * fold-const.cc (minmax_from_comparison): Same. * gimple-array-bounds.cc (check_out_of_bounds_and_warn): Same. (array_bounds_checker::check_array_ref): Same. * gimple-fold.cc (size_must_be_zero_p): Same. * gimple-predicate-analysis.cc (find_var_cmp_const): Same. * gimple-ssa-sprintf.cc (get_int_range): Same. (format_integer): Same. (try_substitute_return_value): Same. (handle_printf_call): Same. * gimple-ssa-warn-restrict.cc (builtin_memref::extend_offset_range): Same. * graphite-sese-to-poly.cc (add_param_constraints): Same. * internal-fn.cc (get_min_precision): Same. * match.pd: Same. * pointer-query.cc (get_size_range): Same. * range-op.cc (get_shift_range): Same. (operator_trunc_mod::op1_range): Same. (operator_trunc_mod::op2_range): Same. * range.cc (range_negatives): Same. * range.h (range_positives): Same. (range_negatives): Same. * tree-affine.cc (expr_to_aff_combination): Same. * tree-data-ref.cc (compute_distributive_range): Same. (nop_conversion_for_offset_p): Same. (split_constant_offset): Same. (split_constant_offset_1): Same. (dr_step_indicator): Same. * tree-dfa.cc (get_ref_base_and_extent): Same. * tree-scalar-evolution.cc (iv_can_overflow_p): Same. * tree-ssa-math-opts.cc (optimize_spaceship): Same. * tree-ssa-pre.cc (insert_into_preds_of_block): Same. * tree-ssa-reassoc.cc (optimize_range_tests_to_bit_test): Same. * tree-ssa-strlen.cc (compare_nonzero_chars): Same. (dump_strlen_info): Same. (get_range_strlen_dynamic): Same. (set_strlen_range): Same. (maybe_diag_stxncpy_trunc): Same. (strlen_pass::get_len_or_size): Same. (strlen_pass::handle_builtin_string_cmp): Same. (strlen_pass::count_nonzero_bytes_addr): Same. (strlen_pass::handle_integral_assign): Same. * tree-switch-conversion.cc (bit_test_cluster::emit): Same. * tree-vect-loop-manip.cc (vect_gen_vector_loop_niters): Same. (vect_do_peeling): Same. * tree-vect-patterns.cc (vect_get_range_info): Same. (vect_recog_divmod_pattern): Same. * tree.cc (get_range_pos_neg): Same. * value-range.cc (debug): Remove value_range variants. * value-range.h (value_range): Remove typedef. * vr-values.cc (simplify_using_ranges::op_with_boolean_value_range_p): Replace value_range use with int_range_max or irange when appropriate. (check_for_binary_op_overflow): Same. (simplify_using_ranges::legacy_fold_cond_overflow): Same. (find_case_label_ranges): Same. (simplify_using_ranges::simplify_abs_using_ranges): Same. (test_for_singularity): Same. (simplify_using_ranges::simplify_compare_using_ranges_1): Same. (simplify_using_ranges::simplify_casted_compare): Same. (simplify_using_ranges::simplify_switch_using_ranges): Same. (simplify_conversion_using_ranges): Same. (simplify_using_ranges::two_valued_val_range_p): Same.
2024-01-03Update copyright years.Jakub Jelinek1-1/+1
2023-11-30tree-optimization/112766 - improve pruning of uninit diagnosticsRichard Biener1-48/+30
Uninit diagnostics has code to prune based on incoming PHI args that prove the uninit code is never executed. But that only looks at the first found flag candidate while in the PRs case only the second candidate would be the one to prune on. The following patch makes us consider all of the flag candidates which is cycles well spent IMHO. PR tree-optimization/112766 * gimple-predicate-analysis.cc (find_var_cmp_const): Support continuing the iteration and report every candidate. (uninit_analysis::overlap): Iterate over all flag var candidates. * g++.dg/torture/uninit-pr112766.C: New testcase.
2023-09-20tree-optimization/111489 - turn uninit limits to paramsRichard Biener1-5/+8
The following turns MAX_NUM_CHAINS and MAX_CHAIN_LEN to params which allows to experiment with raising them. For the testcase in PR111489 raising MAX_CHAIN_LEN from 5 to 8 avoids the bogus diagnostics at -O2, at -O3 we need a MAX_CHAIN_LEN of 6. PR tree-optimization/111489 * doc/invoke.texi (--param uninit-max-chain-len): Document. (--param uninit-max-num-chains): Likewise. * params.opt (-param=uninit-max-chain-len=): New. (-param=uninit-max-num-chains=): Likewise. * gimple-predicate-analysis.cc (MAX_NUM_CHAINS): Define to param_uninit_max_num_chains. (MAX_CHAIN_LEN): Define to param_uninit_max_chain_len. (uninit_analysis::init_use_preds): Avoid VLA. (uninit_analysis::init_from_phi_def): Likewise. (compute_control_dep_chain): Avoid using MAX_CHAIN_LEN in template parameter.
2023-06-26tree-optimization/110392 - ICE with predicate analysisRichard Biener1-2/+2
Feeding not optimized IL can result in predicate normalization to simplify things so a predicate can get true or false. The following re-orders the early exit in that case to come after simplification and normalization to take care of that. PR tree-optimization/110392 * gimple-predicate-analysis.cc (uninit_analysis::is_use_guarded): Do early exits on true/false predicate only after normalization.
2023-04-26Remove some uses of deprecated irange API.Aldy Hernandez1-1/+2
gcc/ChangeLog: * builtins.cc (expand_builtin_strnlen): Rewrite deprecated irange API uses to new API. * gimple-predicate-analysis.cc (find_var_cmp_const): Same. * internal-fn.cc (get_min_precision): Same. * match.pd: Same. * tree-affine.cc (expr_to_aff_combination): Same. * tree-data-ref.cc (dr_step_indicator): Same. * tree-dfa.cc (get_ref_base_and_extent): Same. * tree-scalar-evolution.cc (iv_can_overflow_p): Same. * tree-ssa-phiopt.cc (two_value_replacement): Same. * tree-ssa-pre.cc (insert_into_preds_of_block): Same. * tree-ssa-reassoc.cc (optimize_range_tests_to_bit_test): Same. * tree-ssa-strlen.cc (compare_nonzero_chars): Same. * tree-switch-conversion.cc (bit_test_cluster::emit): Same. * tree-vect-patterns.cc (vect_recog_divmod_pattern): Same. * tree.cc (get_range_pos_neg): Same.
2023-04-24This replaces uses of last_stmt where we do not require debug skippingRichard Biener1-1/+1
There are quite some cases which want to access the control stmt ending a basic-block. Since there cannot be debug stmts after such stmt there's no point in using last_stmt which skips debug stmts and can be a compile-time hog for larger testcases. * gimple-ssa-split-paths.cc (is_feasible_trace): Avoid last_stmt. * graphite-scop-detection.cc (single_pred_cond_non_loop_exit): Likewise. * ipa-fnsummary.cc (set_cond_stmt_execution_predicate): Likewise. (set_switch_stmt_execution_predicate): Likewise. (phi_result_unknown_predicate): Likewise. * ipa-prop.cc (compute_complex_ancestor_jump_func): Likewise. (ipa_analyze_indirect_call_uses): Likewise. * predict.cc (predict_iv_comparison): Likewise. (predict_extra_loop_exits): Likewise. (predict_loops): Likewise. (tree_predict_by_opcode): Likewise. * gimple-predicate-analysis.cc (predicate::init_from_control_deps): Likewise. * gimple-pretty-print.cc (dump_implicit_edges): Likewise. * tree-ssa-phiopt.cc (tree_ssa_phiopt_worker): Likewise. (replace_phi_edge_with_variable): Likewise. (two_value_replacement): Likewise. (value_replacement): Likewise. (minmax_replacement): Likewise. (spaceship_replacement): Likewise. (cond_removal_in_builtin_zero_pattern): Likewise. * tree-ssa-reassoc.cc (maybe_optimize_range_tests): Likewise. * tree-ssa-sccvn.cc (vn_phi_eq): Likewise. (vn_phi_lookup): Likewise. (vn_phi_insert): Likewise. * tree-ssa-structalias.cc (compute_points_to_sets): Likewise. * tree-ssa-threadbackward.cc (back_threader::maybe_thread_block): Likewise. (back_threader_profitability::possibly_profitable_path_p): Likewise. * tree-ssa-threadedge.cc (jump_threader::thread_outgoing_edges): Likewise. * tree-switch-conversion.cc (pass_convert_switch::execute): Likewise. (pass_lower_switch<O0>::execute): Likewise. * tree-tailcall.cc (tree_optimize_tail_calls_1): Likewise. * tree-vect-loop-manip.cc (vect_loop_versioning): Likewise. * tree-vect-slp.cc (vect_slp_function): Likewise. * tree-vect-stmts.cc (cfun_returns): Likewise. * tree-vectorizer.cc (vect_loop_vectorized_call): Likewise. (vect_loop_dist_alias_call): Likewise.
2023-01-26tree-optimization/108547 - robustify uninit predicate analysisRichard Biener1-3/+3
Predicate analysis, when looking through casts doesn't bother to convert boundary constants to the type of the bounded variables. The following robustifies value_sat_pred_p to use widest_ints to deal with this, like other code in predicate analysis. PR tree-optimization/108547 * gimple-predicate-analysis.cc (value_sat_pred_p): Use widest_int. * gcc.dg/uninit-pr108547.c: New testcase.
2023-01-02Update copyright years.Jakub Jelinek1-1/+1
2022-12-01tree-optimization/107937 - uninit predicate simplification fixupRichard Biener1-5/+19
The following changes the predicate representation to record the value of a predicate with an empty set of AND predicates. That's necessary to properly represent the conservative fallback for the def vs use predicates. Since simplification now can result in such an empty set this distinction becomes important and we need to check for this as we otherwise ICE. PR tree-optimization/107937 * gimple-predicate-analysis.h (predicate::is_true): New. (predicate::is_false): Likewise. (predicate::empty_val): Likewise. (uninit_analysis::uninit_analysis): Properly initialize def_preds. * gimple-predicate-analysis.cc (simplify_1b): Indicate whether the chain became empty. (predicate::simplify): Release emptied chain before removing it. (predicate::normalize): Replace temporary object with assertion. (uninit_analysis::is_use_guarded): Deal with predicates that simplify to true/false. * gcc.dg/pr107937.c: New testcase.
2022-11-30tree-optimization/107919 - predicate simplification in uninitRichard Biener1-7/+76
The testcase from the PR at -O2 shows ((_277 == 2) AND (_79 == 0)) OR ((NOT (_277 == 0)) AND (NOT (_277 > 2)) AND (NOT (_277 == 2)) AND (_79 == 0)) OR ((NOT (pretmp_300 == 255)) AND (_277 == 0) AND (NOT (_277 > 2)) AND (NOT (_277 == 2)) AND (_79 == 0)) which we fail to simplify. The following patch makes us simplify the relations on _277, producing ((_79 == 0) AND (_277 == 2)) OR ((_79 == 0) AND (_277 <= 1) AND (NOT (_277 == 0))) OR ((_79 == 0) AND (_277 == 0) AND (NOT (pretmp_300 == 255))) which might be an incremental step to resolve a bogus uninit diagnostic at -O2. The patch uses maybe_fold_and_comparison for this. PR tree-optimization/107919 * gimple-predicate-analysis.cc (simplify_1): Rename to ... (simplify_1a): .. this. (simplify_1b): New. (predicate::simplify): Call both simplify_1a and simplify_1b.
2022-11-30tree-optimization/107919 - uninit diagnostic predicate simplificationRichard Biener1-43/+28
We fail to simplify ((_145 != 0B) AND (_531 == 2) AND (_109 == 0)) OR ((NOT (_145 != 0B)) AND (_531 == 2) AND (_109 == 0)) OR ((NOT (_531 == 2)) AND (_109 == 0)) because the existing simplification of !A && B || A && B is implemented too simplistic. The following re-implements that which fixes the bogus uninit diagnostic when using -O1 but not yet at -O2. PR tree-optimization/107919 * gimple-predicate-analysis.cc (predicate::simplify_2): Handle predicates of arbitrary length. * g++.dg/warn/Wuninitialized-pr107919-1.C: New testcase.
2022-10-07Fix comment typosJakub Jelinek1-1/+1
When looking at tree-inline.cc I've noticed a comment typo and grepped for similar typos elsewhere. 2022-10-07 Jakub Jelinek <jakub@redhat.com> * ipa-prop.h (ipa_constant_data): Fix comment typo. * value-range.cc (irange::irange_contains_p): Likewise. * value-relation.cc (dom_oracle::set_one_relation): Likewise. * gimple-predicate-analysis.cc (predicate::simplify_4): Likewise. * tree-inline.cc (remap_ssa_name): Likewise.
2022-09-09tree-optimization/106881 - fix simple_control_dep_chain partRichard Biener1-4/+8
This adjusts simple_control_dep_chain in the same way I adjusted compute_control_dep_chain_pdom to avoid adding fallthru edges to the predicate chain. PR tree-optimization/106881 * gimple-predicate-analysis.cc (simple_control_dep_chain): Add only non-fallthru edges and avoid the same set of edges as compute_control_dep_chain_pdom does.
2022-09-08tree-optimization/106881 - constrain uninit control edge addRichard Biener1-3/+6
The following avoids adding fallthru edges to the control chain from the post-dominator walk. PR tree-optimization/106881 * gimple-predicate-analysis.cc (compute_control_dep_chain_pdom): Add only non-fallthru edges and avoid the same set of edges as the caller does. * gcc.dg/uninit-pr106881.c: New testcase.
2022-09-07mark region also for USE predicate discoveryRichard Biener1-8/+19
The following makes sure to mark the dominating region also for USE predicate discovery, avoiding compute_control_dep_chain to walk to unrelated areas, eating up walking budget. * gimple-predicate-analysis.cc (dfs_mark_dominating_region): Adjust to take the region exit source as argument. (uninit_analysis::init_from_phi_def): Adjust. (uninit_analysis::init_use_preds): Mark the dominating region before computing control dependences.
2022-09-06tree-optimization/106754 - fix compute_control_dep_chain defectRichard Biener1-80/+106
The following handles the situation of a loop exit along the control path to the PHI def or from there to the use in a different way, aoviding premature abort of the walks as noticed in the two cases where the exit is outermost (gcc.dg/uninit-pred-11.c) or wrapped in a condition that is on the path (gcc.dg/uninit-pred-12.c). Instead of handling such exits during recursion we now pick them up in the parent when walking post-dominators. That requires an additional post-dominator walk at the outermost level which is facilitated by splitting out the walk to a helper function and the existing wrapper added earlier. The patch also removes the bogus early exit from uninit_analysis::init_use_preds, fixing a simplified version of the PR106155 testcase. PR tree-optimization/106754 * gimple-predicate-analysis.cc (compute_control_dep_chain_pdom): New function, split out from compute_control_dep_chain. Handle loop-exit like conditions here by pushing to the control vector. (compute_control_dep_chain): Adjust and streamline dumping. In the wrapper perform a post-dominator walk as well. (uninit_analysis::init_use_preds): Remove premature early exit. * gcc.dg/uninit-pred-12.c: New testcase. * gcc.dg/uninit-pr106155-1.c: Likewise.
2022-09-06Fix use predicate computation for uninit analysisRichard Biener1-15/+39
In uninit analysis we try to prove that a use is always properly guarded so it is never reached when the used value is not initialized. This fails to be conservative when during the computation of the use predicate components of the || .. || .. chain are dropped so we have to detect this case and fall back to the conservative computation. * gimple-predicate-analysis.cc (compute_control_dep_chain): Add output flag to indicate whether we possibly have dropped any chains. Return whether the info is complete from the wrapping overload. (uninit_analysis::init_use_preds): Adjust accordingly, with a workaround for PR106754. (uninit_analysis::init_from_phi_def): Properly guard the case where we complete an empty chain.
2022-09-06tree-optimization/106844 - fix ICE in init_use_predsRichard Biener1-1/+1
The following fixes an oversight in the last change to compute_control_dep_chain where we have to return whether we found a chain. PR tree-optimization/106844 * gimple-predicate-analysis.cc (compute_control_dep_chain): Return whether we found a chain. * gcc.dg/pr106844.c: New testcase.
2022-09-05Remove MAX_SWITCH_CASES limitRichard Biener1-22/+2
The following removes the MAX_SWITCH_CASES limit to fight quadraticness when looking up case labels from edges. Instead use the {start,end}_recording_case_labels facility for that. For it to be usable I've exported get_cases_for_edge from tree-cfg.cc. * tree-cfg.h (get_cases_for_edge): Declare. * tree-cfg.cc (get_cases_for_edge): Export. * tree-ssa-uninit.cc (execute_late_warn_uninitialized): Start and end recording case labels. * gimple-predicate-analysis.cc (MAX_SWITCH_CASES): Remove. (predicate::init_from_control_deps): Use get_cases_for_edge.
2022-09-05Unify MAX_POSTDOM_CHECK and --param uninit-control-dep-attemptsRichard Biener1-17/+12
The following unifies both limits, in particular the MAX_POSTDOM_CHECK tends to be too low and is not user-controllable. * gimple-predicate-analysis.cc (MAX_POSTDOM_CHECK): Remove. (compute_control_dep_chain): Move uninit-control-dep-attempts checking where it also counts the post-dominator check invocations.
2022-09-05debug () for predicatesRichard Biener1-33/+49
The following adds a debug () member to the predicate class. * gimple-predicate-analysis.h (predicate::debug): New. (predicate::dump): Add FILE * argument, add base overload. * gimple-predicate-analysis.cc (debug): New. (dump_pred_info): Add FILE * argument. (dump_pred_chain): Likewise. (predicate::dump): Split out preamble into overload. Add FILE * argument. (predicate::debug): New. (predicate::simplify): Adjust. (predicate::normalize): Likewise. (predicate::init_from_control_deps): Likewise.
2022-09-01Remove cycle checking from compute_control_dep_chainRichard Biener1-13/+7
Now that we have DFS_BACK_EDGE marks we can simply avoid walking those instead of repeatedly looking for a cycle on the current chain. * gimple-predicate-analysis.cc (compute_control_dep_chain): Remove cycle detection, instead avoid walking backedges.
2022-09-01Some predicate analysis TLCRichard Biener1-7/+14
The following hides some internal details of compute_control_dep_chain. * gimple-predicate-analysis.cc (compute_control_dep_chain): New wrapping overload. (uninit_analysis::init_use_preds): Simplify. (uninit_analysis::init_from_phi_def): Likewise.
2022-08-31Avoid fatal fails in predicate::init_from_control_depsRichard Biener1-64/+55
When processing USE predicates we can drop from the AND chain, when procsssing DEF predicates we can drop from the OR chain. Do that instead of giving up completely. This also removes cases that should never trigger. * gimple-predicate-analysis.cc (predicate::init_from_control_deps): Assert the guard_bb isn't empty and has more than one successor. Drop appropriate parts of the predicate when an edge fails to register a predicate. (predicate::dump): Dump empty predicate as TRUE.
2022-08-31tree-optimization/90994 - fix uninit diagnostics with EHRichard Biener1-5/+8
r12-3640-g94c12ffac234b2 sneaked in a hack to avoid the diagnostic for the testcase in PR90994 which sees non-call EH control flow confusing predicate analysis. The following patch instead adjusts the existing code handling EH to handle non-calls and do what I think was intented. PR tree-optimization/90994 * gimple-predicate-analysis.cc (predicate::init_from_control_deps): Ignore exceptional control flow and skip the edge for the purpose of predicate generation also for non-calls. * g++.dg/torture/pr90994.C: New testcase.
2022-08-31tree-optimization/65244 - include asserts in predicates for uninitRichard Biener1-6/+11
When uninit computes the actual predicates from the control dependence edges it currently skips those that are assert-like (where one edge leads to a block which ends in a noreturn call). That leads to bogus uninit diagnostics when applied on the USE side. PR tree-optimization/65244 * gimple-predicate-analysis.h (predicate::init_from_control_deps): Add argument to specify whether the predicate is for the USE. * gimple-predicate-analysis.cc (predicate::init_from_control_deps): Also include predicates effective fallthru control edges when the predicate is for the USE. * gcc.dg/uninit-pr65244-2.c: New testcase.
2022-08-31tree-optimization/73550 - more switch handling improvements for uninitRichard Biener1-27/+50
The following makes predicate analysis handle case labels with a non-singleton contiguous range. PR tree-optimization/73550 * gimple-predicate-analysis.cc (predicate::init_from_control_deps): Sanitize debug dumping. Handle case labels with a CASE_HIGH. (predicate::dump): Adjust for better readability.
2022-08-30tree-optimization/73550 - apply MAX_NUM_CHAINS consistentlyRichard Biener1-7/+0
The MAX_NUM_CHAINS is applied once with <= and once with < which results in the chains not limited but analyis dropped completely. That's one issue in the PR. PR tree-optimization/73550 * gimple-predicate-analysis.cc (predicate::init_from_control_deps): Do not apply MAX_NUM_CHAINS again.
2022-08-30Improve uninit pass dumpingRichard Biener1-30/+4
This produces less redundancy and more complete info dumping the control dependence chains. * gimple-predicate-analysis.cc (format_edge_vec): Dump both source and destination. (dump_dep_chains): Remove. (uninit_analysis::init_use_preds): Remove redundant dumping of chains.
2022-08-30tree-optimization/67196 - normalize use predicates earlierRichard Biener1-3/+3
The following makes sure to have use predicates simplified and normalized before doing uninit_analysis::overlap because that otherwise cannot pick up all flag setting cases. This fixes half of the issue in PR67196 and conveniently resolves the XFAIL in gcc.dg/uninit-pred-7_a.c. PR tree-optimization/67196 * gimple-predicate-analysis.cc (uninit_analysis::is_use_guarded): Simplify and normalize use prediates before first use. * gcc.dg/uninit-pred-7_a.c: Un-XFAIL.
2022-08-30Remove GENERIC expr building from predicate analysis, improve dumpsRichard Biener1-67/+10
The following removes duplicate dumping and makes the predicate dumping more readable. That makes the GENERIC predicate build routines unused which is also nice. * gimple-predicate-analysis.cc (dump_pred_chain): Fix parentizing and AND prepending. (predicate::dump): Do not dump the GENERIC expanded predicate, properly parentize and prepend ORs to the piecewise predicate dump. (build_pred_expr): Remove.
2022-08-30Make uninit PHI processing more consistentRichard Biener1-29/+20
Currently the main working of the maybe-uninit pass is to scan over all PHIs with possibly undefined arguments, diagnosing whether there's a direct not guarded use. For not guarded uses in PHIs those are queued for later processing and to make the uninit analysis PHI def handling work, mark the PHI def as possibly uninitialized. But this happens only for those PHI uses that happen to be seen before a direct not guarded use and whether all arguments of a PHI node which are defined by a PHI are properly marked as maybe uninitialized depends on the processing order. The following changes the uninit pass to perform an RPO walk over the function, ensuring that PHI argument defs are visited before the PHI node (besides backedge uses which we ignore already), getting rid of the worklist. It also makes sure to process all PHI uses, but recording those that are properly guarded so they are not treated as maybe undefined when processing the PHI use later. Overall this should make behavior more consistent, avoid some false negative because of the previous early out and order issue, and avoid some false positive because of the missed recording of guarded PHI uses. The patch correctly diagnoses an uninitalized use of 'regnum' in store_bit_field_1 and also diagnoses an uninitialized use of best_match::m_best_candidate_len in c-decl.cc which I've chosen to silence by initializing m_best_candidate_len. The warning is a false positive but GCC cannot see that m_best_candidate_len is initialized when m_best_candidate is not NULL so from this perspective this was a false negative. I've added g++.dg/uninit-pred-5.C with a reduced testcase that nicely shows how the previous behavior missed the diagnostic because the worklist ended up visiting the PHI with the dependend uninit value before visiting the PHIs producing it. * gimple-predicate-analysis.h (uninit_analysis::operator()): Remove. * gimple-predicate-analysis.cc (uninit_analysis::collect_phi_def_edges): Use phi_arg_set, simplify a bit. * tree-ssa-uninit.cc (defined_args): New global. (compute_uninit_opnds_pos): Mask with the recorded set of guarded maybe-uninitialized uses. (uninit_undef_val_t::operator()): Remove. (find_uninit_use): Process all PHI uses, recording the guarded ones and marking the PHI result as uninitialized consistently. (warn_uninitialized_phi): Adjust. (execute_late_warn_uninitialized): Get rid of the PHI worklist and instead walk the function in RPO order. * spellcheck.h (best_match::m_best_candidate_len): Initialize. * g++.dg/uninit-pred-5.C: New testcase.
2022-08-29Refactor init_use_preds and find_control_equiv_blockRichard Biener1-39/+16
The following inlines find_control_equiv_block and is_loop_exit into init_use_preds and refactors that for better readability and similarity with the post-dominator walk in compute_control_dep_chain. * gimple-predicate-analysis.cc (is_loop_exit, find_control_equiv_block): Inline into single caller ... (uninit_analysis::init_use_preds): ... here and refactor.
2022-08-29Improve compute_control_dep_chain documentationRichard Biener1-4/+23
The following refactors compute_control_dep_chain slightly by inlining is_loop_exit and factoring the check on the loop invariant condition. It also adds a comment as of how I understand the code and it's current problem. * gimple-predicate-analysis.cc (compute_control_dep_chain): Inline is_loop_exit and refactor, add comment about loop exits.
2022-08-26Remove uninit_analysis::use_cannot_happenRichard Biener1-212/+0
As written earlier uninit_analysis::use_cannot_happen is duplicate functionality implemented in a complement way, not adhering to the idea of disproving a may-uninit use and eventually (I have not yet found a testcase it helps to avoid false positives) avoiding false positives because of this or different ways it imposes limits on the predicate computations. This patch removes it. * gimple-predicate-analysis.h (uninit_analysis::use_cannot_happen): Remove. * gimple-predicate-analysis.cc (can_be_invalidated_p): Remove. (uninit_analysis::use_cannot_happen): Likewise. (uninit_analysis::is_use_guarded): Do not call use_cannot_happen. (dump_predicates): Remove. (simple_control_dep_chain): Remove edge overload.
2022-08-26Improve compute_control_dep_chain path findingRichard Biener1-3/+78
This improves the compute_control_dep_chain path finding by first marking the dominating region we search and then making sure to not walk outside if it when enumerating all paths from the dominating block to the interesting PHI edge source. I have limited the DFS walk done for the marking in similar ways as we limit the walking in compute_control_dep_chain, more careful limiting might be necessary though - the --param uninit-control-dep-attempts param I re-use has a rather high default of 1000 which we might be able to reduce with this patch as well (I think we'll usually hit some of the other limits before ever reaching this). * gimple-predicate-analysis.cc (dfs_mark_dominating_region): New helper. (compute_control_dep_chain): Adjust to honor marked region if provided. (uninit_analysis::init_from_phi_def): Pre-mark the dominating region to improve compute_control_dep_chain walking. * vec.h (vec<T, va_heap, vl_ptr>::allocated): Add forwarder.
2022-08-26Improve uninit_analysis::collect_phi_def_edgesRichard Biener1-5/+5
This avoids expanding an edge to those of a PHI def if it is not may-undefined, reducing the number of compute_control_dep_chain calls. * gimple-predicate-analysis.cc (uninit_analysis::collect_phi_def_edges): Only expand a PHI def edge when it is possibly undefined.
2022-08-24Move things around in predicate analysisRichard Biener1-286/+286
This moves a few functions, notably normalization after a big comment documenting it. I've left the rest unorganized for now. * gimple-predicate-analysis.cc: Move predicate normalization after the comment documenting it.
2022-08-24Split uninit analysis from predicate analysisRichard Biener1-57/+59
This splits the API collected in gimple-predicate-analysis.h into what I'd call a predicate and assorted functionality plus utility used by the uninit pass that happens to use that. I've tried to be minimalistic with refactoring, there's still recursive instantiation of uninit_analysis, the new class encapsulating a series of uninit analysis queries from the uninit pass. But it at least should make the predicate part actually reusable and what predicate is dealt with is a little bit more clear in the uninit_analysis part. I will followup with moving the predicate implementation bits together in the gimple-predicate-analysis.cc file. * gimple-predicate-analysis.h (predicate): Split out non-predicate related functionality into .. (uninit_analysis): .. this new class. * gimple-predicate-analysis.cc: Refactor into two classes. * tree-ssa-uninit.cc (find_uninit_use): Use uninit_analysis.
2022-08-24Some more predicate analysis TLCRichard Biener1-19/+12
This limits the simple control dep also to the cd_root plus avoids filling the lazily computed PHI def predicate in the early out path which would leave it not simplified and normalized if it were re-used. It also avoids computing the use predicates when the post-dominance early out doesn't need it. It also syncs predicate::use_cannot_happen with init_from_phi_def, adding the missing PHI edge to the computed chains (the simple control dep code already adds it). * gimple-predicate-analysis.cc (predicate::use_cannot_happen): Do simple_control_dep_chain only up to cd_root, add the PHI operand edge to the chains like init_from_phi_def does. (predicate::is_use_guarded): Speedup early out, avoid half-way initializing the PHI def predicate.
2022-08-24Speedup path discovery in predicate::use_cannot_happenRichard Biener1-1/+7
The following reverts a hunk from r8-5789-g11ef0b22d68cd1 that made compute_control_dep_chain start from function entry rather than the immediate dominator of the source block of the edge with the undefined value on the PHI node. Reverting at that point does not reveal any testsuite FAIL, in particular the added testcase still passes. The following adjusts this to the other function that computes predicates that hold on the PHI incoming edges with undefined values, predicate::init_from_phi_def, which starts at the immediate dominator of the PHI. That's much less likely to run into the CFG walking limit. * gimple-predicate-analysis.cc (predicate::use_cannot_happen): Start the compute_control_dep_chain walk from the immediate dominator of the PHI.
2022-08-23tree-optimization/106722 - uninit analysis with long def -> use pathRichard Biener1-16/+52
The following applies similar measures as r13-2133-ge66cf626c72d58 to the computation of the use predicate when the path from PHI def to use is too long and we run into compute_control_dep_chain limits. It also moves the preprocessor define limits internal. This resolves the reduced testcase but not the original one. PR tree-optimization/106722 * gimple-predicate-analysis.h (MAX_NUM_CHAINS, MAX_CHAIN_LEN, MAX_POSTDOM_CHECK, MAX_SWITCH_CASES): Move ... * gimple-predicate-analysis.cc: ... here and document. (simple_control_dep_chain): New function, factored from predicate::use_cannot_happen. (predicate::use_cannot_happen): Adjust. (predicate::predicate): Use simple_control_dep_chain as fallback. * g++.dg/uninit-pr106722-1.C: New testcase.
2022-08-23Refactor is_non_loop_exit_postdominatingRichard Biener1-13/+7
That's a weird function in predicate analysis that currently looks like /* Return true if BB1 is postdominating BB2 and BB1 is not a loop exit bb. The loop exit bb check is simple and does not cover all cases. */ static bool is_non_loop_exit_postdominating (basic_block bb1, basic_block bb2) { if (!dominated_by_p (CDI_POST_DOMINATORS, bb2, bb1)) return false; if (single_pred_p (bb1) && !single_succ_p (bb2)) return false; return true; } One can refactor this to return (dominated_by_p (CDI_POST_DOMINATORS, bb2, bb1) && !(single_pred_p (bb1) && !single_succ_p (bb2))); Notable is that the comment refers to BB1 with respect to a loop exit but the test seems to be written with an exit edge bb1 -> bb2 in mind. None of the three callers are guaranteed to have bb1 and bb2 connected directly with an edge. The patch now introduces a is_loop_exit function and inlines the post-dominance check which makes the find_control_equiv_block case simpler because the post-dominance check can be elided. It also avoids the double negation in compute_control_dep_chain and makes it obvious this is the case where we do look at an edge. For the main is_use_guarded API I chose to elide the loop exit test, if the use block post-dominates the definition block of the PHI node the use is always unconditional. I don't quite understand the loop exit special-casing of the remaining two uses though. * gimple-predicate-analysis.cc (is_loop_exit): Split out from ... (is_non_loop_exit_postdominating): ... here. Remove after inlining ... (find_control_equiv_block): ... here. (compute_control_dep_chain): ... and here. (predicate::is_use_guarded): Do not excempt loop exits from short-cutting the case of the use post-dominating the PHI definition.
2022-08-22Remove dead predicate analysis GENERIC expr building codeRichard Biener1-39/+0
The following removes the unused def_expr, use_expr and expr APIs from the predicate class including the unconditional build of the GENERIC use_expr on each uninit analysis run. * gimple-predicate-analysis.h (predicate::m_use_expr): Remove. (predicate::def_expr): Likewise. (predicate::use_expr): Likewise. (predicate::expr): Likewise. * gimple-predicate-analysis.cc (predicate::def_expr): Remove. (predicate::use_expr): Likewise. (predicate::expr): Likewise. (predicate::is_use_guarded): Do not build m_use_expr.
2022-08-22Improve uninit analysisRichard Biener1-8/+56
The following reduces the number of false positives in uninit analysis by providing fallback for situations the current analysis gives up and thus warns because it cannot prove initialization. The first situation is when compute_control_dep_chain gives up walking because it runs into either param_uninit_control_dep_attempts or MAX_CHAIN_LEN. If in the process it did not collect a single path from function entry to the interesting PHI edge then we'll give up and diagnose. The following patch insteads provides a sparse path including only those predicates that always hold when the PHI edge is reached in that case. That's cheap to produce but may in some odd cases prove less precise than what the code tries now (enumerating all possible paths from function entry to the PHI edge, but only use the first N of those and only require unreachability of those N). The second situation is when the set of predicates computed to hold on the use stmt was formed from multiple paths (there's a similar enumeration of all paths and their predicates from the PHI def to the use). In that case use_preds.use_cannot_happen gives up because it doesn't know which of the predicates from which path from PHI to the use it can use to prove unreachability of the PHI edge that has the uninitialized def. The patch for this case simply computes the intersection of the predicates and uses that for further analysis, but in a crude way since the predicate vectors are not sorted. Fortunately the total size is limited - we have max MAX_NUM_CHAINS number of predicates each of length MAX_CHAIN_LEN so the brute force intersection code should behave quite reasonable in practice. * gimple-predicate-analysis.cc (predicate::use_cannot_happen): If the use is guarded with multiple predicate paths compute the predicates intersection before going forward. When compute_control_dep_chain wasn't able to come up with at least one path from function entry to the PHI edge compute a conservative sparse path instead.
2022-01-03Update copyright years.Jakub Jelinek1-1/+1
2021-11-29Restore can_be_invalidated_p semantics to before refactoringRichard Biener1-3/+5
This restores the semantics of can_be_invalidated_p to the original semantics of the function this was split out from tree-ssa-uninit.c. The current semantics only ever look at the first predicate which cannot be correct. 2021-11-26 Richard Biener <rguenther@suse.de> * gimple-predicate-analysis.cc (can_be_invalidated_p): Restore semantics to the one before the split from tree-ssa-uninit.c.
2021-11-12Remove unused function.Martin Liska1-61/+0
PR tree-optimization/102497 gcc/ChangeLog: * gimple-predicate-analysis.cc (add_pred): Remove unused function:
2021-11-11Remove find_pdom and find_domRichard Biener1-33/+3
This removes now useless wrappers around get_immediate_dominator. 2021-11-11 Richard Biener <rguenther@suse.de> * cfganal.c (find_pdom): Remove. (control_dependences::find_control_dependence): Remove special-casing of entry block, call get_immediate_dominator directly. * gimple-predicate-analysis.cc (find_pdom): Remove. (find_dom): Likewise. (find_control_equiv_block): Call get_immediate_dominator directly. (compute_control_dep_chain): Likewise. (predicate::init_from_phi_def): Likewise.