Age | Commit message (Collapse) | Author | Files | Lines |
|
When range_of_stmt was adjusted to avoid large recursion depth, we need to
intersect the calculated range whth the any known range to avoid losing
info. Range_of_stmt does this, but the new prefill code missed it.
PR tree-optimization/105276
gcc/
* gimple-range.cc (gimple_ranger::prefill_stmt_dependencies): Include
existing global range with calculated value.
gcc/testsuite/
* g++.dg/pr105276.C: New.
|
|
This patch adjusts uses of nonnull to accurately reflect "somewhere in block".
It also adds the ability to register statement side effects within a block
for ranger which will apply for the rest of the block.
PR tree-optimization/104288
gcc/
* gimple-range-cache.cc (non_null_ref::set_nonnull): New.
(non_null_ref::adjust_range): Move to header.
(ranger_cache::range_of_def): Don't check non-null.
(ranger_cache::entry_range): Don't check non-null.
(ranger_cache::range_on_edge): Check for nonnull on normal edges.
(ranger_cache::update_to_nonnull): New.
(non_null_loadstore): New.
(ranger_cache::block_apply_nonnull): New.
* gimple-range-cache.h (class non_null_ref): Update prototypes.
(non_null_ref::adjust_range): Move to here and inline.
(class ranger_cache): Update prototypes.
* gimple-range-path.cc (path_range_query::range_defined_in_block): Do
not search dominators.
(path_range_query::adjust_for_non_null_uses): Ditto.
* gimple-range.cc (gimple_ranger::range_of_expr): Check on-entry for
def overrides. Do not check nonnull.
(gimple_ranger::range_on_entry): Check dominators for nonnull.
(gimple_ranger::range_on_edge): Check for nonnull on normal edges..
(gimple_ranger::register_side_effects): New.
* gimple-range.h (gimple_ranger::register_side_effects): New.
* tree-vrp.cc (rvrp_folder::fold_stmt): Call register_side_effects.
gcc/testsuite/
* gcc.dg/pr104288.c: New.
|
|
|
|
PR tree-optimization/103464
* gimple-range.cc (gimple_ranger::prefill_name): Process phis also.
(gimple_ranger::prefill_stmt_dependencies): Ditto.
|
|
All ranger API entries eventually call range_of_stmt to ensure there is an
initial global value to work with. This can cause very deep call chains when
satisfied via the normal API. Instead, push any dependencies onto a stack
and evaluate them in a depth first manner, mirroring what would have happened
via the normal API calls.
PR tree-optimization/103231
gcc/
* gimple-range.cc (gimple_ranger::gimple_ranger): Create stmt stack.
(gimple_ranger::gimple_ranger): Delete stmt stack.
(gimple_ranger::range_of_stmt): Process depenedencies if they have no
global cache entry.
(gimple_ranger::prefill_name): New.
(gimple_ranger::prefill_stmt_dependencies): New.
* gimple-range.h (class gimple_ranger): Add prototypes.
|
|
Get_non_stale_global_range returns true only when there is a cache entry that
is not out of date. Change it so that it returns true if there was a cache
value, but return the temporal comparison result in an auxiallary flag.
* gimple-range-cache.cc (ranger_cache::get_global_range): Always
return a range, return if it came from the cache or not.
(get_non_stale_global_range): Rename to get_global_range, and return
the temporal state in a flag.
* gimple-range-cache.h (get_non_stale_global_range): Rename and adjust.
* gimple-range.cc (gimple_ranger::range_of_expr): No need to query
get_global_range.
(gimple_ranger::range_of_stmt): Adjust for global cache temporal state
returned in a flag.
|
|
Trace formatting gets out of sync when range on edge is called with a constant.
* gimple-range.cc (gimple_ranger::range_on_edge): Call trailer when
a constant is encountered to terminate the trace.
|
|
Instead of x_range_query always pointing to an object, have it default to
NULL and return a pointer to the global query in that case.
* function.c (allocate_struct_function): Don't set x_range_query.
* function.h (get_range_query): Move to value-query.h.
* gimple-range.cc (enable_ranger): Check that query is currently NULL.
(disable_ranger): Clear function current query field.
* value-query.cc (get_global_range_query): Relocate to:
* value-query.h (get_global_range_query): Here and inline.
(get_range_query): Relocate here from function.h.
|
|
When using rangers private callback mechanism to provide context
to fold_stmt calls, we are only suppose to be using the cache in read
only mode, never calculate new values.
gcc/
PR tree-optimization/103122
* gimple-range.cc (gimple_ranger::range_of_expr): Request the cache
entry with "calulate new values" set to false.
gcc/testsuite/
* g++.dg/pr103122.C: New.
|
|
Provide an internal mechanism to supply context to range_of_expr for calls
to ::fold_stmt.
* gimple-range.cc (gimple_ranger::gimple_ranger): Initialize current_bb.
(gimple_ranger::range_of_expr): Pick up range_on_entry when there is
no explcit context and current_bb is set.
(gimple_ranger::fold_stmt): New.
* gimple-range.h (current_bb, fold_stmt): New.
* tree-vrp.c (rvrp_folder::fold_stmt): Call ranger's fold_stmt.
|
|
Propagation is automatically done by the temporal cache when defs are
out of date from the names on the RHS, but a gcond has no LHS, and any
updates on the RHS are never propagated. Always propagate them.
gcc/
PR tree-optimization/102983
* gimple-range-cache.h (propagate_updated_value): Make public.
* gimple-range.cc (gimple_ranger::range_of_stmt): Propagate exports
when processing gcond stmts.
gcc/testsuite/
* gcc.dg/pr102983.c: New.
|
|
* gimple-range.cc (gimple_ranger::export_global_ranges): Remove check
for TDF_DETAILS.
|
|
With Ranger being used in more than EVRP, the debug output should no longer
be tied up with the EVRP mode flag.
* doc/invoke.texi (ranger-debug): Document.
* flag-types.h (enum ranger_debug): New.
(enum evrp_mode): Remove debug values.
* gimple-range-cache.cc (DEBUG_RANGE_CACHE): Use new debug flag.
* gimple-range-gori.cc (gori_compute::gori_compute): Ditto.
* gimple-range.cc (gimple_ranger::gimple_ranger): Ditto.
* gimple-ssa-evrp.c (hybrid_folder::choose_value): Ditto.
(execute_early_vrp): Use evrp-mode directly.
* params.opt (enum evrp_mode): Remove debug values.
(ranger-debug): New.
(ranger-logical-depth): Relocate to be in alphabetical order.
|
|
PR tree-optimization/102796
gcc/
* gimple-range.cc (gimple_ranger::range_on_edge): Process EH edges
normally. Return get_tree_range for non gimple_range_ssa_p names.
(gimple_ranger::range_of_stmt): Use get_tree_range for non
gimple_range_ssa_p names.
gcc/testsuite/
* g++.dg/pr102796.C: New.
|
|
* gimple-range-fold.h (gimple_range_ssa_p): Don't process names
that occur in abnormal phis.
* gimple-range.cc (gimple_ranger::range_on_edge): Return false for
abnormal and EH edges.
* gimple-ssa-evrp.c (rvrp_folder::value_of_expr): Ditto.
(rvrp_folder::value_on_edge): Ditto.
(rvrp_folder::value_of_stmt): Ditto.
(hybrid_folder::value_of_expr): Ditto for ranger queries.
(hybrid_folder::value_on_edge): Ditto.
(hybrid_folder::value_of_stmt): Ditto.
* value-query.cc (gimple_range_global): Always return a range if
the type is supported.
|
|
I'm trying to add one debug() for each dump() to the dumping aids.
Tested on x86-64 Linux.
gcc/ChangeLog:
* gimple-range.cc (gimple_ranger::debug): New.
* gimple-range.h (class gimple_ranger): Add debug.
|
|
Instead of repurposing EDGE_EXECUTABLE, ranger creates a local flag and
ultizes it throughout.
* gimple-range-cache.cc (ranger_cache::ranger_cache): Take
non-executable_edge flag as parameter.
* gimple-range-cache.h (ranger_cache): Adjust prototype.
* gimple-range-gori.cc (gori_compute::gori_compute): Take
non-executable_edge flag as parameter.
(gori_compute::outgoing_edge_range_p): Check new flag.
* gimple-range-gori.h (gori_compute): Adjust prototype.
* gimple-range.cc (gimple_ranger::gimple_ranger): Create new flag.
(gimple_ranger::range_on_edge): Check new flag.
* gimple-range.h (gimple_ranger::non_executable_edge_flag): New.
* gimple-ssa-evrp.c (rvrp_folder): Pass ranger flag to simplifer.
(hybrid_folder::hybrid_folder): Set ranger non-executable flag value.
(hybrid_folder::fold_stmt): Set flag value in the simplifer.
* vr-values.c (simplify_using_ranges::set_and_propagate_unexecutable):
Use not_executable flag if provided inmstead of EDGE_EXECUTABLE.
(simplify_using_ranges::simplify_switch_using_ranges): Clear
EDGE_EXECUTABLE like it originally did.
(simplify_using_ranges::cleanup_edges_and_switches): Clear any
NON_EXECUTABLE flags.
(simplify_using_ranges::simplify_using_ranges): Adjust.
* vr-values.h (class simplify_using_ranges): Adjust.
(simplify_using_ranges::set_range_query): Add non-executable flag param.
|
|
If an incoming edge is UNDEFINED, don't process it. Track if other edges
equate to a single value, and add an equivalence if appropriate.
gcc/
* gimple-range-fold.cc (fold_using_range::range_of_phi): Ignore
undefined edges, apply an equivalence if appropriate.
* gimple-range-gori.cc (gori_compute::outgoing_edge_range_p): Return
UNDEFINED if EDGE_EXECUTABLE is not set.
* gimple-range.cc (gimple_ranger::gimple_ranger): Set all edges
as EXECUTABLE upon startup.
(gimple_ranger::range_on_edge): Return UNDEFINED for edges without
EDGE_EXECUTABLE set.
* vr-values.c (set_and_propagate_unexecutable): New.
(simplify_using_ranges::fold_cond): Call set_and_propagate.
(simplify_using_ranges::simplify_switch_using_ranges): Ditto.
* vr-values.h: Add prototype.
gcc/testsuite/
* gcc.dg/tree-ssa/evrp-ignore.c: New.
|
|
gcc/ChangeLog:
* gimple-range-cache.cc (ssa_global_cache::dump): Avoid printing
range table header alone.
* gimple-range.cc (gimple_ranger::export_global_ranges): Same.
|
|
gcc:
* gimple-range.cc: Add comments.
* gimple-range.h: Same.
|
|
Generalize range tracing into a class and integrae it with gimple_ranger.
Remove the old derived trace_ranger class.
* Makefile.in (OBJS): Add gimple-range-trace.o.
* gimple-range-cache.h (enable_new_values): Remove unused prototype.
* gimple-range-fold.cc: Adjust headers.
* gimple-range-trace.cc: New.
* gimple-range-trace.h: New.
* gimple-range.cc (gimple_ranger::gimple_ranger): Enable tracer.
(gimple_ranger::range_of_expr): Add tracing.
(gimple_ranger::range_on_entry): Ditto.
(gimple_ranger::range_on_exit): Ditto.
(gimple_ranger::range_on_edge): Ditto.
(gimple_ranger::fold_range_internal): Ditto.
(gimple_ranger::dump_bb): Do not calculate edge range twice.
(trace_ranger::*): Remove.
(enable_ranger): Never create a trace_ranger.
(debug_seed_ranger): Move to gimple-range-trace.cc.
(dump_ranger): Ditto.
(debug_ranger): Ditto.
* gimple-range.h: Include gimple-range-trace.h.
(range_on_entry, range_on_exit): No longer virtual.
(class trace_ranger): Remove.
(DEBUG_RANGE_CACHE): Move to gimple-range-trace.h.
|
|
There are 4 exact copies of the non-null range adjusting code in the
ranger. This patch abstracts the functionality into a separate method.
As a follow-up I would like to remove the varying_p check, since I have
seen incoming ranges such as [0, 0xff....ef] which are not varying, but
are not-null. Removing the varying restriction catches those.
gcc/ChangeLog:
* gimple-range-cache.cc (non_null_ref::adjust_range): New.
(ranger_cache::range_of_def): Call adjust_range.
(ranger_cache::entry_range): Same.
* gimple-range-cache.h (non_null_ref::adjust_range): New.
* gimple-range.cc (gimple_ranger::range_of_expr): Call
adjust_range.
(gimple_ranger::range_on_entry): Same.
|
|
Split the fold_using_range functions from gimple-range into gimple-range-fold.
Also move the gimple_range_calc* routines into gimple-range-gori.
* Makefile.in (OBJS): Add gimple-range-fold.o
* gimple-range-fold.cc: New.
* gimple-range-fold.h: New.
* gimple-range-gori.cc (gimple_range_calc_op1): Move to here.
(gimple_range_calc_op2): Ditto.
* gimple-range-gori.h: Move prototypes to here.
* gimple-range.cc: Adjust include files.
(fur_source:fur_source): Relocate to gimple-range-fold.cc.
(fur_source::get_operand): Ditto.
(fur_source::get_phi_operand): Ditto.
(fur_source::query_relation): Ditto.
(fur_source::register_relation): Ditto.
(class fur_edge): Ditto.
(fur_edge::fur_edge): Ditto.
(fur_edge::get_operand): Ditto.
(fur_edge::get_phi_operand): Ditto.
(fur_stmt::fur_stmt): Ditto.
(fur_stmt::get_operand): Ditto.
(fur_stmt::get_phi_operand): Ditto.
(fur_stmt::query_relation): Ditto.
(class fur_depend): Relocate to gimple-range-fold.h.
(fur_depend::fur_depend): Relocate to gimple-range-fold.cc.
(fur_depend::register_relation): Ditto.
(fur_depend::register_relation): Ditto.
(class fur_list): Ditto.
(fur_list::fur_list): Ditto.
(fur_list::get_operand): Ditto.
(fur_list::get_phi_operand): Ditto.
(fold_range): Ditto.
(adjust_pointer_diff_expr): Ditto.
(gimple_range_adjustment): Ditto.
(gimple_range_base_of_assignment): Ditto.
(gimple_range_operand1): Ditto.
(gimple_range_operand2): Ditto.
(gimple_range_calc_op1): Relocate to gimple-range-gori.cc.
(gimple_range_calc_op2): Ditto.
(fold_using_range::fold_stmt): Relocate to gimple-range-fold.cc.
(fold_using_range::range_of_range_op): Ditto.
(fold_using_range::range_of_address): Ditto.
(fold_using_range::range_of_phi): Ditto.
(fold_using_range::range_of_call): Ditto.
(fold_using_range::range_of_builtin_ubsan_call): Ditto.
(fold_using_range::range_of_builtin_call): Ditto.
(fold_using_range::range_of_cond_expr): Ditto.
(fold_using_range::range_of_ssa_name_with_loop_info): Ditto.
(fold_using_range::relation_fold_and_or): Ditto.
(fold_using_range::postfold_gcond_edges): Ditto.
* gimple-range.h: Add gimple-range-fold.h to include files. Change
GIMPLE_RANGE_STMT_H to GIMPLE_RANGE_H.
(gimple_range_handler): Relocate to gimple-range-fold.h.
(gimple_range_ssa_p): Ditto.
(range_compatible_p): Ditto.
(class fur_source): Ditto.
(class fur_stmt): Ditto.
(class fold_using_range): Ditto.
(gimple_range_calc_op1): Relocate to gimple-range-gori.h
(gimple_range_calc_op2): Ditto.
|
|
* gimple-range.cc (dump_bb): Use range_on_edge from the cache.
|
|
Enable a relation oracle in ranger, and add full range-op relation support
to fold_using_range.
* gimple-range-cache.cc (ranger_cache::ranger_cache): Create a
relation_oracle if dominators exist.
(ranger_cache::~ranger_cache): Dispose of oracle.
(ranger_cache::dump_bb): Dump oracle.
* gimple-range.cc (fur_source::fur_source): New.
(fur_source::get_operand): Use mmeber query.
(fur_source::get_phi_operand): Use member_query.
(fur_source::query_relation): New.
(fur_source::register_dependency): Delete.
(fur_source::register_relation): New.
(fur_edge::fur_edge): Adjust.
(fur_edge::get_phi_operand): Fix comment.
(fur_edge::query): Delete.
(fur_stmt::fur_stmt): Adjust.
(fur_stmt::query): Delete.
(fur_depend::fur_depend): Adjust.
(fur_depend::register_relation): New.
(fur_depend::register_relation): New.
(fur_list::fur_list): Adjust.
(fur_list::get_operand): Use member query.
(fold_using_range::range_of_range_op): Process and query relations.
(fold_using_range::range_of_address): Adjust dependency call.
(fold_using_range::range_of_phi): Ditto.
(gimple_ranger::gimple_ranger): New. Use ranger_ache oracle.
(fold_using_range::relation_fold_and_or): New.
(fold_using_range::postfold_gcond_edges): New.
* gimple-range.h (class gimple_ranger): Adjust.
(class fur_source): Adjust members.
(class fur_stmt): Ditto.
(class fold_using_range): Ditto.
|
|
Remove the old "poor value" approach which made callbacks into ranger
from the cache. Use only the best available value for all propagation.
PR tree-optimization/101014
* gimple-range-cache.cc (ranger_cache::ranger_cache): Remove poor
value list.
(ranger_cache::~ranger_cache): Ditto.
(ranger_cache::enable_new_values): Delete.
(ranger_cache::push_poor_value): Delete.
(ranger_cache::range_of_def): Remove poor value processing.
(ranger_cache::entry_range): Ditto.
(ranger_cache::fill_block_cache): Ditto.
* gimple-range-cache.h (class ranger_cache): Remove poor value members.
* gimple-range.cc (gimple_ranger::range_of_expr): Remove call.
* gimple-range.h (class gimple_ranger): Adjust.
|
|
* gimple-range-cache.cc: Comment cleanups.
* gimple-range-gori.cc: Comment cleanups.
* gimple-range.cc: Comment/spacing cleanups
* value-range.h: Comment cleanups.
|
|
These are various cleanups to the clz/ctz code.
First, ranges from range_of_expr are always numeric so we
should adjust. Also, the checks for non-zero were assuming the argument
was unsigned, which in the PR's testcase is clearly not. I've cleaned
this up, so that it works either way.
I've also removed the following annoying idiom:
- int newmini = prec - 1 - wi::floor_log2 (r.upper_bound ());
- if (newmini == prec)
This is really a check for r.upper_bound() == 0, as floor_log2(0)
returns -1. It's confusing.
Tested on x86-64 Linux.
gcc/ChangeLog:
PR tree-optimization/100790
* gimple-range.cc (range_of_builtin_call): Cleanup clz and ctz
code.
gcc/testsuite/ChangeLog:
* gcc.dg/pr100790.c: New test.
|
|
These are debugging aids for help in debugging ranger based passes.
gcc/ChangeLog:
* gimple-range.cc (debug_seed_ranger): New.
(dump_ranger): New.
(debug_ranger): New.
|
|
Range_on_edge was implemented in the cache to always return a range, but
only returned true when the edge actally changed the range.
Return true with any range that can be calculated.
* gimple-range-cache.cc (ranger_cache::range_on_edge): Always return
true when a range can be calculated.
* gimple-range.cc (gimple_ranger::dump_bb): Check has_edge_range_p.
|
|
When utilzing poor values during propagation, we mostly care about values that
were undefined/processed directly used in calcualting the SSA_NAME being
processed. 2nd level derivations of such poor values rarely affect the
inital calculation. Leave them to when they are directly encountered.
* gimple-range-cache.cc (ranger_cache::ranger_cache): Adjust.
(ranger_cache::enable_new_values): Set to specified value and
return the old value.
(ranger_cache::disable_new_values): Delete.
(ranger_cache::fill_block_cache): Disable non 1st order derived
poor values.
* gimple-range-cache.h (ranger_cache): Adjust prototypes.
* gimple-range.cc (gimple_ranger::range_of_expr): Adjust.
|
|
No more accessing the local info. Also add fur_source/fold_stmt where ranges
are provided via being specified, or a vector to replace gimple_fold_range.
* gimple-range-gori.cc (gori_compute::outgoing_edge_range_p): Use a
fur_stmt source record.
* gimple-range.cc (fur_source::get_operand): Generic range query.
(fur_source::get_phi_operand): New.
(fur_source::register_dependency): New.
(fur_source::query): New.
(class fur_edge): New. Edge source for operands.
(fur_edge::fur_edge): New.
(fur_edge::get_operand): New.
(fur_edge::get_phi_operand): New.
(fur_edge::query): New.
(fur_stmt::fur_stmt): New.
(fur_stmt::get_operand): New.
(fur_stmt::get_phi_operand): New.
(fur_stmt::query): New.
(class fur_depend): New. Statement source and process dependencies.
(fur_depend::fur_depend): New.
(fur_depend::register_dependency): New.
(class fur_list): New. List source for operands.
(fur_list::fur_list): New.
(fur_list::get_operand): New.
(fur_list::get_phi_operand): New.
(fold_range): New. Instantiate appropriate fur_source class and fold.
(fold_using_range::range_of_range_op): Use new API.
(fold_using_range::range_of_address): Ditto.
(fold_using_range::range_of_phi): Ditto.
(imple_ranger::fold_range_internal): Use fur_depend class.
(fold_using_range::range_of_ssa_name_with_loop_info): Use new API.
* gimple-range.h (class fur_source): Now a base class.
(class fur_stmt): New.
(fold_range): New prototypes.
(fur_source::fur_source): Delete.
|
|
Right now, range_of_expr only works with constants, SSA names, and
pointers. Anything else gets returned as VARYING. This patch adds the
capability to deal with arbitrary expressions, inasmuch as these
tree codes are implemented in range-ops.cc.
This will give us the ability to ask for the range of any tree expression,
not just constants and SSA names, with range_of_expr().
This is a more generic implementation of determine_value_range in VRP.
A follow-up patch will remove all uses of it in favor of the
range_query API.
gcc/ChangeLog:
* function-tests.c (test_ranges): Call gimple_range_tests.
* gimple-range-cache.cc (ranger_cache::range_of_expr): Pass stmt
to get_tree_range.
* gimple-range.cc (fur_source::get_operand): Do not call
get_tree_range or gimple_range_global.
get_tree_range.
(get_tree_range): Move to value-query.cc.
Call get_arith_expr_range.
(gimple_ranger::range_of_expr): Add argument to get_tree_range.
Include gimple-range-tests.cc.
* gimple-range.h (fold_range): Add argument.
(get_tree_range): Remove.
* selftest.h (gimple_range_tests): New.
* value-query.cc (global_range_query::range_of_expr): Add
stmt argument.
(range_query::get_tree_range): Move from gimple-range.cc.
* value-query.h (class range_query): Add get_tree_range and
get_arith_expr_range. Make fur_source a friend.
* vr-values.c (vr_values::range_of_expr): Pass stmt to
get_tree_range.
* gimple-range-tests.cc: New file.
|
|
This patch modifies export_global_ranges to take into account current
global ranges. It also handles enhances said function to export pointer
global ranges as well.
gcc/ChangeLog:
* gimple-range.cc (gimple_ranger::export_global_ranges): Call
update_global_range.
* value-query.cc (update_global_range): New.
* value-query.h (update_global_range): New.
gcc/testsuite/ChangeLog:
* gcc.dg/pr80776-1.c: XFAIL and document the reason why.
|
|
Add a flag to enable/disable immediately improving poor values found during
cache propagation. Then disable it when processing debug statements.
gcc/
PR tree-optimization/100781
* gimple-range-cache.cc (ranger_cache::ranger_cache): Enable new
value calculation by default.
(ranger_cache::enable_new_values): New.
(ranger_cache::disable_new_values): New.
(ranger_cache::push_poor_value): Check if new values are allowed.
* gimple-range-cache.h (class ranger_cache): New member/methods.
* gimple-range.cc (gimple_ranger::range_of_expr): Check for debug
statement, and disable/renable new value calculation.
gcc/testsuite/
PR tree-optimization/100781
* gcc.dg/pr100781.c: New.
|
|
Flatten and simplify gori-computes. Tweak debug output.
range-cache now provides range_of_expr and range_on_edge in the
standard formats, but in a "query what you have" mode rather than
"go figure out anything that is missing" mode.
* gimple-range-cache.cc (ranger_cache::ranger_cache): Adjust for
gori_compute being a member rather than base class.
dervied call to member call.
(ranger_cache::dump): No longer dump gori_map.
(ranger_cache::dump_bb): New.
(ranger_cache::get_non_stale_global_range): Adjust for gori_compute
being a member rather than base class.
(ranger_cache::set_global_range): Ditto.
(ranger_cache::ssa_range_in_bb): Ditto.
(ranger_cache::range_of_expr): New.
(ranger_cache::range_on_edge): New.
(ranger_cache::block_range): Adjust for gori_computes. Debug changes.
(ranger_cache::propagate_cache): Adjust debugging output.
(ranger_cache::fill_block_cache): Adjust for gori_computes. Debug
output changes.
* gimple-range-cache.h (class ranger_cache): Make gori_compute a
member, and inherit from range_query instead.
(ranger_cache::dump_bb): New. split from dump.
* gimple-range-gori.cc (gori_compute::ssa_range_in_bb): Delete.
(gori_compute::expr_range_at_stmt): Delete.
(gori_compute::compute_name_range_op): Delete.
(gori_compute::compute_operand_range_switch): Add fur_source.
(gori_compute::compute_operand_range): Add fur_source param, inline
old compute_name_range_op and optimize_logical_operands.
(struct tf_range): Delete.
(gori_compute::logical_combine): Adjust
(gori_compute::optimize_logical_operands): Delete.
(gori_compute::compute_logical_operands_in_chain): Delete.
(gori_compute::compute_logical_operands): Adjust.
(gori_compute::compute_operand1_range): Adjust to fur_source.
(gori_compute::compute_operand2_range): Ditto.
(gori_compute::compute_operand1_and_operand2_range): Ditto.
(gori_compute::outgoing_edge_range_p): Add range_query parameter,
and adjust to fur_source.
* gimple-range-gori.h (class gori_compute): Simplify and adjust to
range_query and fur_source.
* gimple-range.cc (gimple_ranger::range_on_edge): Query range_on_edge
from the ranger_cache..
(gimple_ranger::fold_range_internal): Adjust to base class change of
ranger_cache.
(gimple_ranger::dump_bb): Adjust dump.
* gimple-range.h (gimple_ranger):export gori computes object.
|
|
This patch moves all the global range code from gimple-range.cc into
value-query.cc. It also moves get_range_info and get_ptr_nonnull from
tree-ssanames.c into their only uses, and removes external access to them.
gcc/ChangeLog:
* gimple-range.cc (get_range_global): Move to value-query.cc.
(gimple_range_global): Same.
(get_global_range_query): Same.
(global_range_query::range_of_expr): Same.
* gimple-range.h (class global_range_query): Move to
value-query.h.
(gimple_range_global): Same.
* tree-ssanames.c (get_range_info): Move to value-query.cc.
(get_ptr_nonnull): Same.
* tree-ssanames.h (get_range_info): Remove.
(get_ptr_nonnull): Remove.
* value-query.cc (get_ssa_name_range_info): Move from
tree-ssanames.c.
(get_ssa_name_ptr_info_nonnull): Same.
(get_range_global): Move from gimple-range.cc.
(gimple_range_global): Same.
(get_global_range_query): Same.
(global_range_query::range_of_expr): Same.
* value-query.h (class global_range_query): Move from
gimple-range.h.
(gimple_range_global): Same.
|
|
This patch provides a generic API for accessing global ranges. It is
meant to replace get_range_info() and get_ptr_nonnull() with one
common interface. It uses the same API as the ranger (class
range_query), so there will now be one API for accessing local and
global ranges alike.
Follow-up patches will convert all users of get_range_info and
get_ptr_nonnull to this API.
For get_range_info, instead of:
if (!POINTER_TYPE_P (TREE_TYPE (name)) && SSA_NAME_RANGE_INFO (name))
get_range_info (name, vr);
You can now do:
get_range_query (cfun)->range_of_expr (vr, name, [stmt]);
...as well as any other of the range_query methods (range_on_edge,
range_of_stmt, value_of_expr, value_on_edge, value_on_stmt, etc).
As per the API, range_of_expr will work on constants, SSA names, and
anything we support in irange::supports_type_p().
For pointers, the interface is the same, so instead of:
else if (POINTER_TYPE_P (TREE_TYPE (name)) && SSA_NAME_PTR_INFO (name))
{
if (get_ptr_nonnull (name))
stuff();
}
One can do:
get_range_query (cfun)->range_of_expr (vr, name, [stmt]);
if (vr.nonzero_p ())
stuff ();
Along with this interface, we are providing a mechanism by which a
pass can use an on-demand ranger transparently, without having to
change its code. Of course, this assumes all get_range_info() and
get_ptr_nonnull() users have been converted to the new API, which
follow-up patches will do.
If a pass would prefer to use an on-demand ranger with finer grained
and context aware ranges, all it would have to do is call
enable_ranger() at the beginning of the pass, and disable_ranger() at
the end of the pass.
Note, that to use context aware ranges, any user of range_of_expr()
would need to pass additional context. For example, the optional
gimple statement (or perhaps use range_on_edge or range_of_stmt).
The observant reader will note that get_range_query is tied to a
struct function, which may not be available in certain contexts, such
as at RTL time, gimple-fold, or some other places where we may or may
not have cfun set.
For cases where we are sure there is no function, you can use
get_global_range_query() instead of get_range_query(fun). The API is
the same.
For cases where a function may be called with or without a function,
you could use the following idiom:
range_query *query = cfun ? get_range_query (cfun)
: get_global_range_query ();
query->range_of_expr (range, expr, [stmt]);
The default range query obtained by get_range_query() is the global
range query, unless the user has enabled an on-demand ranger with
enable_ranger(), in which case it will use the currently active ranger.
That is, until disable_ranger() is called, at which point, we revert
back to global ranges.
We think this provides a generic way of accessing ranges, both
globally and locally, without having to keep track of types,
SSA_NAME_RANGE_INFO, and SSA_NAME_PTR_INFO. We also hope this can be
used to transition passes from global to on-demand ranges when
appropriate.
gcc/ChangeLog:
* function.c (allocate_struct_function): Set cfun->x_range_query.
* function.h (struct function): Declare x_range_query.
(get_range_query): New.
(get_global_range_query): New.
* gimple-range-cache.cc (ssa_global_cache::ssa_global_cache):
Remove call to safe_grow_cleared.
* gimple-range.cc (get_range_global): New.
(gimple_range_global): Move from gimple-range.h.
(get_global_range_query): New.
(global_range_query::range_of_expr): New.
(enable_ranger): New.
(disable_ranger): New.
* gimple-range.h (gimple_range_global): Move to gimple-range.cc.
(class global_range_query): New.
(enable_ranger): New.
(disable_ranger): New.
* gimple-ssa-evrp.c (evrp_folder::~evrp_folder): Rename
dump_all_value_ranges to dump.
* tree-vrp.c (vrp_prop::finalize): Same.
* value-query.cc (range_query::dump): New.
* value-query.h (range_query::dump): New.
* vr-values.c (vr_values::dump_all_value_ranges): Rename to...
(vr_values::dump): ...this.
* vr-values.h (class vr_values): Rename dump_all_value_ranges to
dump and make virtual.
|
|
In order to access the dependencies, the FoldUsingRange source API class
stored a range_cache.. THis is now contained in the base gori_compute class,
so use that now.
* gimple-range.cc (fold_using_range::range_of_range_op): Use m_gori
intead of m_cache.
(fold_using_range::range_of_address): Adjust.
(fold_using_range::range_of_phi): Adjust.
* gimple-range.h (class fur_source): Adjust.
(fur_source::fur_source): Adjust.
|
|
range_on_entry shouldnt be checking non-null, but we sometimes should
after calling it.
change the debug output a bit.
* gimple-range.cc (gimple_ranger::range_of_expr): Non-null should be
checked only after range_of_stmt, not range_on_entry.
(gimple_ranger::range_on_entry): Check for non-null in any
predecessor block, if it is not already non-null.
(gimple_ranger::range_on_exit): DOnt check for non-null after
range on entry call.
(gimple_ranger::dump_bb): New. Split from dump.
(gimple_ranger::dump): Adjust.
* gimple-range.h (class gimple_ranger): Adjust.
|
|
Introduces fold_using_range which folds any kind of gimple statement by
querying argument ranges thru a generic range_query.
This pulls all the statement processing into a client neutral location.
* gimple-range.cc (fur_source::get_operand): New.
(gimple_range_fold): Delete.
(fold_using_range::fold_stmt): Move from gimple_ranger::calc_stmt.
(fold_using_range::range_of_range_op): Move from gimple_ranger.
(fold_using_range::range_of_address): Ditto.
(fold_using_range::range_of_phi): Ditto.
(fold_using_range::range_of_call): Ditto.
(fold_using_range::range_of_builtin_ubsan_call): Move from
range_of_builtin_ubsan_call.
(fold_using_range::range_of_builtin_call): Move from
range_of_builtin_call.
(gimple_ranger::range_of_builtin_call): Delete.
(fold_using_range::range_of_cond_expr): Move from gimple_ranger.
(gimple_ranger::fold_range_internal): New.
(gimple_ranger::range_of_stmt): Use new fold_using_range API.
(fold_using_range::range_of_ssa_name_with_loop_info): Move from
gimple_ranger. Improve ranges of SSA_NAMES when possible.
* gimple-range.h (gimple_ranger): Remove various range_of routines.
(class fur_source): New.
(class fold_using_range): New.
(fur_source::fur_source): New.
(fold_range): New.
* vr-values.c (vr_values::extract_range_basic): Use fold_using_range
instead of range_of_builtin_call.
|
|
Once a range is forced to a constant globally, simply make it invariant.
Unify this with the code which makes non-zero pointer ranges invariant.
gcc/
PR tree-optimization/100512
* gimple-range-cache.cc (ranger_cache::set_global_range): Mark const
and non-zero pointer ranges as invariant.
* gimple-range.cc (gimple_ranger::range_of_stmt): Remove pointer
processing from here.
gcc/testsuite/
PR tree-optimization/100512
* gcc.dg/pr100512.c: New.
|
|
The previous changes to irange::constant_p return TRUE for
VARYING, since VARYING has numerical end points like any other
constant range. The problem is that some users of constant_p
depended on constant_p excluding the full domain. The
range handler for __builtin_clz, that is shared between ranger
and vr_values, is one such user.
This patch excludes varying_p(), to match the original behavior
for clz.
gcc/ChangeLog:
PR c/100521
* gimple-range.cc (range_of_builtin_call): Skip out on
processing __builtin_clz when varying.
|
|
last_stmt(bb) returns NULL for blocks which only have PHI stmts, and
range_on_exit would trigger a cache fill all the way to the top of the
program for the SSA_NAME.
* gimple-range.cc (gimple_ranger::range_on_exit): Handle block with
only PHI nodes better.
|
|
Don't track [1, +INF] for pointer types, treat them as invariant for caching
purposes as they cannot be further refined without evaluating to UNDEFINED.
PR tree-optimization/98866
* gimple-range-gori.h (gori_compute:set_range_invariant): New.
* gimple-range-gori.cc (gori_map::set_range_invariant): New.
(gori_map::m_maybe_invariant): Rename from all_outgoing.
(gori_map::gori_map): Rename all_outgoing to m_maybe_invariant.
(gori_map::is_export_p): Ditto.
(gori_map::calculate_gori): Ditto.
(gori_compute::set_range_invariant): New.
* gimple-range.cc (gimple_ranger::range_of_stmt): Set range
invariant for pointers evaluating to [1, +INF].
|
|
|
|
Align EVRP and ranger for how ranges of ADDR_EXPR are calculated.
gcc/
* gimple-range.cc: (gimple_ranger::range_of_range_op): Check for
ADDR_EXPR and call range_of_address.
(gimple_ranger::range_of_address): Rename from
range_of_non_trivial_assignment and match vrp_stmt_computes_nonzero.
* gimple-range.h: (range_of_address): Renamed.
* range-op.cc: (pointer_table): Add INTEGER_CST handler.
gcc/testsuite/
* gcc.dg/tree-ssa/pr78655.c: New.
|
|
When a range is recalculated, retain what was previously known as IL changes
can produce different results from un-executed code. This also paves
the way for external injection of ranges.
gcc/
PR tree-optimization/97737
PR tree-optimization/97741
* gimple-range.cc: (gimple_ranger::range_of_stmt): Intersect newly
calculated ranges with the existing known global range.
gcc/testsuite/
* gcc.dg/pr97737.c: New.
* gcc.dg/pr97741.c: New.
|
|
Sometimes the overflow flag will leak into the IL. Drop it while
creating ranges.
There are various places we could plug this. This patch just plugs things
at get_tree_range which is the entry point for ranges from tree expressions.
It fixes the PR, and probably fixes the ranger entirely, but we may need
to revisit this.
For example, I looked to see if there were other places that created
ranges with TREE_OVERFLOW set, and there are various. For example,
the following code pattern appears multiple times in vr-values.c:
else if (is_gimple_min_invariant (op0))
vr0.set (op0);
This can pick up TREE_OVERFLOW from the IL if present. However, the
ranger won't see them so we're good.
At some point we should audit all this. Or perhaps just nuke all
TREE_OVERFLOW's at irange::set.
For now, this will do.
gcc/ChangeLog:
PR tree-optimization/97721
* gimple-range.cc (get_tree_range): Drop overflow from constants.
gcc/testsuite/ChangeLog:
* gcc.dg/pr97721.c: New test.
|
|
Add a timestamp to supplement the global range cache to detect when a value
may become stale.
gcc/
PR tree-optimization/97515
* gimple-range-cache.h (class ranger_cache): New prototypes plus
temporal cache pointer.
* gimple-range-cache.cc (struct range_timestamp): New.
(class temporal_cache): New.
(temporal_cache::temporal_cache): New.
(temporal_cache::~temporal_cache): New.
(temporal_cache::get_timestamp): New.
(temporal_cache::set_dependency): New.
(temporal_cache::temporal_value): New.
(temporal_cache::current_p): New.
(temporal_cache::set_timestamp): New.
(temporal_cache::set_always_current): New.
(ranger_cache::ranger_cache): Allocate the temporal cache.
(ranger_cache::~ranger_cache): Free temporal cache.
(ranger_cache::get_non_stale_global_range): New.
(ranger_cache::set_global_range): Add a timestamp.
(ranger_cache::register_dependency): New. Add timestamp dependency.
* gimple-range.cc (gimple_ranger::range_of_range_op): Add operand
dependencies.
(gimple_ranger::range_of_phi): Ditto.
(gimple_ranger::range_of_stmt): Check if global range is stale, and
recalculate if so.
gcc/testsuite/
* gcc.dg/pr97515.c: Check listing for folding of entire function.
|