From: Martin Sebor Date: Tue, 25 Jan 2022 21:20:51 +0000 (-0700) Subject: Avoid recomputing PHI results after failure (PR104203). X-Git-Tag: upstream/12.2.0~1828 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=58ec0964b1d2f2ab197916cd661728f6a7a1736b;p=platform%2Fupstream%2Fgcc.git Avoid recomputing PHI results after failure (PR104203). Resolves: PR tree-optimization/104203 - huge compile-time regression in pointer_query gcc/ChangeLog: PR tree-optimization/104203 * gimple-ssa-warn-access.cc (pass_data pass_data_waccess): Use TV_WARN_ACCESS. * pointer-query.cc (access_ref::merge_ref): Change return type. Convert failure to a conservative success. (access_ref::get_ref): Adjust to the change above. Short-circuit PHI evaluation after first failure turned into conservative success. * pointer-query.h (access_ref::merge_ref): Change return type. * timevar.def (TV_WARN_ACCESS): New timer variable. --- diff --git a/gcc/gimple-ssa-warn-access.cc b/gcc/gimple-ssa-warn-access.cc index 8bc33ee..afcf0f7 100644 --- a/gcc/gimple-ssa-warn-access.cc +++ b/gcc/gimple-ssa-warn-access.cc @@ -2053,7 +2053,7 @@ const pass_data pass_data_waccess = { GIMPLE_PASS, "waccess", OPTGROUP_NONE, - TV_NONE, + TV_WARN_ACCESS, /* timer variable */ PROP_cfg, /* properties_required */ 0, /* properties_provided */ 0, /* properties_destroyed */ diff --git a/gcc/pointer-query.cc b/gcc/pointer-query.cc index 5b723e9..b092ef4 100644 --- a/gcc/pointer-query.cc +++ b/gcc/pointer-query.cc @@ -629,7 +629,7 @@ access_ref::phi () const ARG refers to the null pointer. Return true on success and false on failure. */ -bool +void access_ref::merge_ref (vec *all_refs, tree arg, gimple *stmt, int ostype, bool skip_null, ssa_name_limit_t &snlim, pointer_query &qry) @@ -637,8 +637,16 @@ access_ref::merge_ref (vec *all_refs, tree arg, gimple *stmt, access_ref aref; if (!compute_objsize_r (arg, stmt, false, ostype, &aref, snlim, &qry) || aref.sizrng[0] < 0) - /* This may be a PHI with all null pointer arguments. */ - return false; + { + /* This may be a PHI with all null pointer arguments. Handle it + conservatively by setting all properties to the most permissive + values. */ + base0 = false; + offrng[0] = offrng[1] = 0; + add_max_offset (); + set_max_size_range (); + return; + } if (all_refs) { @@ -675,13 +683,13 @@ access_ref::merge_ref (vec *all_refs, tree arg, gimple *stmt, if (arg_known_size) sizrng[0] = aref.sizrng[0]; - return true; + return; } /* Disregard null pointers in PHIs with two or more arguments. TODO: Handle this better! */ if (nullp) - return true; + return; const bool known_size = (sizrng[0] != 0 || sizrng[1] != maxobjsize); @@ -717,7 +725,7 @@ access_ref::merge_ref (vec *all_refs, tree arg, gimple *stmt, sizrng[0] = minsize; parmarray = merged_parmarray; - return true; + return; } /* Determine and return the largest object to which *THIS refers. If @@ -755,14 +763,12 @@ access_ref::get_ref (vec *all_refs, access_ref aref; tree arg1 = gimple_assign_rhs1 (def_stmt); - if (!aref.merge_ref (all_refs, arg1, def_stmt, ostype, false, - *psnlim, *qry)) - return NULL_TREE; + aref.merge_ref (all_refs, arg1, def_stmt, ostype, false, + *psnlim, *qry); tree arg2 = gimple_assign_rhs2 (def_stmt); - if (!aref.merge_ref (all_refs, arg2, def_stmt, ostype, false, - *psnlim, *qry)) - return NULL_TREE; + aref.merge_ref (all_refs, arg2, def_stmt, ostype, false, + *psnlim, *qry); if (pref && pref != this) { @@ -801,15 +807,23 @@ access_ref::get_ref (vec *all_refs, phi_ref = *pref; } + const offset_int maxobjsize = wi::to_offset (max_object_size ()); const unsigned nargs = gimple_phi_num_args (phi_stmt); for (unsigned i = 0; i < nargs; ++i) { access_ref phi_arg_ref; bool skip_null = i || i + 1 < nargs; tree arg = gimple_phi_arg_def (phi_stmt, i); - if (!phi_ref.merge_ref (all_refs, arg, phi_stmt, ostype, skip_null, - *psnlim, *qry)) - return NULL_TREE; + phi_ref.merge_ref (all_refs, arg, phi_stmt, ostype, skip_null, + *psnlim, *qry); + + if (!phi_ref.base0 + && phi_ref.sizrng[0] == 0 + && phi_ref.sizrng[1] >= maxobjsize) + /* When an argument results in the most permissive result, + the remaining arguments cannot constrain it. Short-circuit + the evaluation. */ + break; } if (phi_ref.sizrng[0] < 0) diff --git a/gcc/pointer-query.h b/gcc/pointer-query.h index 7dc965b..dbdcd59 100644 --- a/gcc/pointer-query.h +++ b/gcc/pointer-query.h @@ -67,7 +67,7 @@ struct access_ref gphi *phi () const; /* Merge the result for a pointer with *THIS. */ - bool merge_ref (vec *all_refs, tree, gimple *, int, bool, + void merge_ref (vec *all_refs, tree, gimple *, int, bool, ssa_name_limit_t &, pointer_query &); /* Return the object to which REF refers. */ diff --git a/gcc/timevar.def b/gcc/timevar.def index c239e8e..2dae5e1 100644 --- a/gcc/timevar.def +++ b/gcc/timevar.def @@ -307,6 +307,7 @@ DEFTIMEVAR (TV_TREE_UBSAN , "tree ubsan") DEFTIMEVAR (TV_INITIALIZE_RTL , "initialize rtl") DEFTIMEVAR (TV_GIMPLE_LADDRESS , "address lowering") DEFTIMEVAR (TV_TREE_LOOP_IFCVT , "tree loop if-conversion") +DEFTIMEVAR (TV_WARN_ACCESS , "access analysis") /* Everything else in rest_of_compilation not included above. */ DEFTIMEVAR (TV_EARLY_LOCAL , "early local passes")