Age | Commit message (Collapse) | Author | Files | Lines |
|
There are 3 possible relations range-ops might care about, but only the one
most likely to be needed is supplied. This patch provides a new class
relation_trio which allows 3 relations to be passed in a single word.
fold_range (), op1_range (), and op2_range () are adjusted to take a
relation_trio class instead of a relation_kind, then the routine can
extract which relation it wants to work with.
* gimple-range-fold.cc (fold_using_range::range_of_range_op):
Provide relation_trio class.
* gimple-range-gori.cc (gori_compute::refine_using_relation):
Provide relation_trio class.
(gori_compute::refine_using_relation): Ditto.
(gori_compute::compute_operand1_range): Provide lhs_op2 and
op1_op2 relations via relation_trio class.
(gori_compute::compute_operand2_range): Ditto.
* gimple-range-op.cc (gimple_range_op_handler::calc_op1): Use
relation_trio instead of relation_kind.
(gimple_range_op_handler::calc_op2): Ditto.
(*::fold_range): Ditto.
* gimple-range-op.h (gimple_range_op::calc_op1): Adjust prototypes.
(gimple_range_op::calc_op2): Adjust prototypes.
* range-op-float.cc (*::fold_range): Use relation_trio instead of
relation_kind.
(*::op1_range): Ditto.
(*::op2_range): Ditto.
* range-op.cc (*::fold_range): Use relation_trio instead of
relation_kind.
(*::op1_range): Ditto.
(*::op2_range): Ditto.
* range-op.h (class range_operator): Adjust prototypes.
(class range_operator_float): Ditto.
(class range_op_handler): Adjust prototypes.
(relop_early_resolve): Pickup op1_op2 relation from relation_trio.
* value-relation.cc (VREL_LAST): Adjust use to be one past the end of
the enum.
(relation_oracle::validate_relation): Use relation_trio in call
to fold_range.
* value-relation.h (enum relation_kind_t): Add VREL_LAST as
final element.
(class relation_trio): New.
(TRIO_VARYING, TRIO_SHIFT, TRIO_MASK): New.
|
|
gcc/ChangeLog:
* gimple-range-gori.cc (gori_compute::logical_combine): Avoid
calling tracer.trailer().
|
|
This allows GORI to recognize when a relation passed in applies to the
2 operands of the current statement. Check to see if further range
refinement is possible before proceeding.
* gimple-range-gori.cc (gori_compute::refine_using_relation): New.
(gori_compute::compute_operand1_range): Invoke
refine_using_relation when applicable.
(gori_compute::compute_operand2_range): Ditto.
* gimple-range-gori.h (class gori_compute): Adjust prototypes.
|
|
This allows GORI to recognize and pass relations along the calculation chain.
This will allow relations between the LHS and the operand being calculated
to be utilized in op1_range and op2_range.
* gimple-range-gori.cc (ori_compute::compute_operand_range):
Create a relation record and pass it along when possible.
(gori_compute::compute_operand1_range): Pass relation along.
(gori_compute::compute_operand2_range): Ditto.
(gori_compute::compute_operand1_and_operand2_range): Ditto.
* gimple-range-gori.h (class gori_compute): Adjust prototypes.
* gimple-range-op.cc (gimple_range_op_handler::calc_op1): Pass
relation to op1_range call.
(gimple_range_op_handler::calc_op2): Pass relation to op2_range call.
* gimple-range-op.h (class gimple_range_op_handler): Adjust
prototypes.
|
|
Range-ops is meant to be IL independent. Some gimple processing has
be placed in range-ops, and some is located in gori. Split it all into
a file and isolate it in a new class gimple_range_op_handler.
* Makefile.in (OBJS): Add gimple-range-op.o.
* gimple-range-edge.cc (gimple_outgoing_range_stmt_p): Use
gimple_range_op_handler.
* gimple-range-fold.cc (gimple_range_base_of_assignment): Move
to a method in gimple_range_op_handler.
(gimple_range_operand1): Ditto.
(gimple_range_operand2): Ditto.
(fold_using_range::fold_stmt): Use gimple_range_op_handler.
(fold_using_range::range_of_range_op): Ditto.
(fold_using_range::relation_fold_and_or): Ditto.
(fur_source::register_outgoing_edges): Ditto.
(gimple_range_ssa_names): Relocate to gimple-range-op.cc.
* gimple-range-fold.h: Adjust prototypes.
* gimple-range-gori.cc (gimple_range_calc_op1): Move
to a method in gimple_range_op_handler.
(gimple_range_calc_op2): Ditto.
(gori_compute::compute_operand_range): Use
gimple_range_op_handler.
(gori_compute::compute_logical_operands): Ditto.
(compute_operand1_range): Ditto.
(gori_compute::compute_operand2_range): Ditto.
(gori_compute::compute_operand1_and_operand2_range): Ditto.
* gimple-range-gori.h: Adjust protoypes.
* gimple-range-op.cc: New. Supply gimple_range_op_handler methods.
* gimple-range-op.h: New. Supply gimple_range_op_handler class.
* gimple-range.cc (gimple_ranger::prefill_name): Use
gimple_range_op_handler.
(gimple_ranger::prefill_stmt_dependencies): Ditto.
* gimple-range.h: Include gimple-range-op.h.
* range-op.cc (range_op_handler::range_op_handler): Adjust and
remove gimple * parameter option.
* range-op.h: Adjust prototypes.
|
|
Provide a routine to pick out the ssa-names from interesting statements.
* gimple-range-fold.cc (gimple_range_ssa_names): New.
* gimple-range-fold.h (gimple_range_ssa_names): New prototype.
* gimple-range-gori.cc (range_def_chain::get_def_chain): Move
code to new routine.
|
|
Processing of a cond_expr requires that a range of the correct type for the
operands of the cond_expr is passed in.
PR tree-optimization/106556
gcc/
* gimple-range-gori.cc (gori_compute::condexpr_adjust): Use the
type of the cond_expr operands being evaluted.
gcc/testsuite/
* gfortran.dg/pr106556.f90: New.
|
|
The range of an invariant SSA (no outgoing edge range anywhere) is not tracked.
If an inferred range is registered, remove the invariant flag.
* gimple-range-cache.cc (ranger_cache::apply_inferred_ranges): If name
was invaraint before, clear the invariant bit.
* gimple-range-gori.cc (gori_map::set_range_invariant): Add a flag.
* gimple-range-gori.h (gori_map::set_range_invariant): Adjust prototype.
|
|
Finally, the meat of the work. Convert ranger and associated clients
to vrange.
Everything's relatively mechanical given the previous patches. I did
include a minor cleanup in the edge code. There's no need to check
that the type of the switch is an integer as non-integer switches are
invalid. I verified this with an appropriately coded assert.
Tested on x86-64 & ppc64le Linux.
gcc/ChangeLog:
* gimple-range-cache.cc (ssa_block_ranges::dump): Convert to vrange.
(sbr_vector::sbr_vector): Same.
(sbr_vector::grow): Same.
(sbr_vector::set_bb_range): Same.
(sbr_vector::get_bb_range): Same.
(sbr_sparse_bitmap::sbr_sparse_bitmap): Same.
(sbr_sparse_bitmap::set_bb_range): Same.
(sbr_sparse_bitmap::get_bb_range): Same.
(block_range_cache::set_bb_range): Same.
(block_range_cache::get_bb_range): Same.
(block_range_cache::dump): Same.
(ssa_global_cache::get_global_range): Same.
(ssa_global_cache::set_global_range): Same.
(ssa_global_cache::clear): Same.
(ssa_global_cache::dump): Same.
(ranger_cache::get_global_range): Same.
(ranger_cache::set_global_range): Same.
(ranger_cache::range_of_def): Same.
(ranger_cache::entry_range): Same.
(ranger_cache::exit_range): Same.
(ranger_cache::edge_range): Same.
(ranger_cache::range_of_expr): Same.
(ranger_cache::range_on_edge): Same.
(ranger_cache::block_range): Same.
(ranger_cache::propagate_cache): Same.
(ranger_cache::fill_block_cache): Same.
(ranger_cache::range_from_dom): Same.
* gimple-range-cache.h: Same.
* gimple-range-edge.cc (gimple_outgoing_range::get_edge_range):
Same.
(gimple_outgoing_range::switch_edge_range): Same.
(gimple_outgoing_range::edge_range_p): Same.
* gimple-range-edge.h: Same.
* gimple-range-fold.cc (fur_source::get_operand): Same.
(fur_source::get_phi_operand): Same.
(fur_edge::get_operand): Same.
(fur_edge::get_phi_operand): Same.
(fur_stmt::get_operand): Same.
(fur_stmt::get_phi_operand): Same.
(fur_list::fur_list): Same.
(fur_list::get_operand): Same.
(fur_list::get_phi_operand): Same.
(fold_range): Same.
(adjust_imagpart_expr): Same.
(adjust_realpart_expr): Same.
(gimple_range_adjustment): Same.
(fold_using_range::fold_stmt): Same.
(fold_using_range::range_of_range_op): Same.
(fold_using_range::range_of_address): Same.
(fold_using_range::range_of_phi): Same.
(fold_using_range::range_of_call): Same.
(fold_using_range::range_of_builtin_call): Same.
(fold_using_range::range_of_builtin_int_call): Same.
(fold_using_range::range_of_cond_expr): Same.
(fur_source::register_outgoing_edges): Same.
* gimple-range-fold.h (fold_range): Same.
(gimple_range_type): Same.
(gimple_range_ssa_p): Same.
* gimple-range-gori.cc (gimple_range_calc_op1): Same.
(gimple_range_calc_op2): Same.
(gori_compute::compute_operand_range_switch): Same.
(gori_compute::compute_operand_range): Same.
(gori_compute::logical_combine): Same.
(gori_compute::compute_logical_operands): Same.
(gori_compute::compute_operand1_range): Same.
(gori_compute::compute_operand2_range): Same.
(gori_compute::compute_operand1_and_operand2_range): Same.
(gori_compute::outgoing_edge_range_p): Same.
(gori_compute::condexpr_adjust): Same.
* gimple-range-gori.h (gimple_range_calc_op1): Same.
(gimple_range_calc_op2): Same.
* gimple-range-path.cc (path_range_query::get_cache): Same.
(path_range_query::set_cache): Same.
(path_range_query::range_on_path_entry): Same.
(path_range_query::internal_range_of_expr): Same.
(path_range_query::range_of_expr): Same.
(path_range_query::ssa_range_in_phi): Same.
(path_range_query::range_defined_in_block): Same.
(path_range_query::compute_ranges_in_phis): Same.
(path_range_query::compute_ranges_in_block): Same.
(path_range_query::add_to_imports): Same.
(path_range_query::range_of_stmt): Same.
* gimple-range-path.h: Same.
* gimple-range-infer.cc (gimple_infer_range::add_range): Same.
(gimple_infer_range::~side_effect_manager): Same.
(gimple_infer_range::get_nonzero): Same.
(gimple_infer_range::maybe_adjust_range): Same.
(gimple_infer_range::add_range): Same.
* gimple-range-infer.h: Same.
* gimple-range-tests.cc: Same.
* gimple-range-trace.cc (range_tracer::trailer): Same.
(debug_seed_ranger): Same.
* gimple-range-trace.h: Same.
* gimple-range.cc (gimple_ranger::range_of_expr): Same.
(gimple_ranger::range_on_entry): Same.
(gimple_ranger::range_on_exit): Same.
(gimple_ranger::range_on_edge): Same.
(gimple_ranger::fold_range_internal): Same.
(gimple_ranger::range_of_stmt): Same.
(gimple_ranger::prefill_name): Same.
(gimple_ranger::prefill_stmt_dependencies): Same.
(gimple_ranger::export_global_ranges): Same.
(gimple_ranger::dump_bb): Same.
* gimple-range.h: Same.
* gimple-ssa-warn-access.cc (check_nul_terminated_array): Same.
(memmodel_to_uhwi): Same.
* tree-ssa-loop-niter.cc (refine_value_range_using_guard): Same.
(determine_value_range): Same.
(record_nonwrapping_iv): Same.
(infer_loop_bounds_from_signedness): Same.
(scev_var_range_cant_overflow): Same.
* tree-ssa-threadedge.cc (hybrid_jt_simplifier::simplify): Same.
* value-query.cc (range_query::range_on_edge): Same.
(range_query::range_of_stmt): Same.
(range_query::value_of_expr): Same.
(range_query::value_on_edge): Same.
(range_query::value_of_stmt): Same.
(range_query::get_tree_range): Same.
(update_global_range): Same.
(get_range_global): Same.
(gimple_range_global): Same.
(global_range_query::range_of_expr): Same.
(range_query::query_relation): Same.
* value-query.h (gimple_range_global): Same.
(update_global_range): Same.
* vr-values.cc (vr_values::range_of_expr): Same.
(bounds_of_var_in_loop): Same.
(simplify_using_ranges::vrp_visit_cond_stmt): Same.
* vr-values.h (class vr_values): Same.
* tree-ssa-loop-unswitch.cc (unswitch_predicate): Same.
|
|
This patch provides the infrastructure to make range-ops type agnostic.
First, the range_op_handler function has been replaced with an object
of the same name. It's coded in such a way to minimize changes to the
code base, and to encapsulate the dispatch code.
Instead of:
range_operator *op = range_op_handler (code, type);
if (op)
op->fold_range (...);
We now do:
range_op_handler op (code, type);
if (op)
op->fold_range (...);
I've folded gimple_range_handler into the range_op_handler class,
since it's also a query into the range operators.
Instead of:
range_operator *handler = gimple_range_handler (stmt);
We now do:
range_op_handler handler (stmt);
This all has the added benefit of moving all the dispatch code into an
independent class and avoid polluting range_operator (which we'll
further split later when frange and prange come live).
There's this annoying "using" keyword that's been added to each
operator due to hiding rules in C++. The issue is that we will have
different virtual versions of fold_range() for each combination of
operands. For example:
// Traditional binary op on irange's.
fold_range (irange &lhs, const irange &op1, const irange &op2);
// For POINTER_DIFF_EXPR:
fold_range (irange &lhs, const prange &op1, const prange &op2);
// Cast from irange to prange.
fold_range (prange &lhs, const irange &op1, const irange &op2);
Overloading virtuals when there are multiple same named methods causes
hidden virtuals warnings from -Woverloaded-virtual, thus the using
keyword. An alternative would be to have different names:
fold_range_III, fold_range_IPP, fold_range_PII, but that's uglier
still.
Tested on x86-64 & ppc64le Linux.
gcc/ChangeLog:
* gimple-range-edge.cc (gimple_outgoing_range_stmt_p): Adjust for
vrange and convert range_op_handler function calls to use the
identically named object.
* gimple-range-fold.cc (gimple_range_operand1): Same.
(gimple_range_operand2): Same.
(fold_using_range::fold_stmt): Same.
(fold_using_range::range_of_range_op): Same.
(fold_using_range::range_of_builtin_ubsan_call): Same.
(fold_using_range::relation_fold_and_or): Same.
(fur_source::register_outgoing_edges): Same.
* gimple-range-fold.h (gimple_range_handler): Remove.
* gimple-range-gori.cc (gimple_range_calc_op1): Adjust for vrange.
(gimple_range_calc_op2): Same.
(range_def_chain::get_def_chain): Same.
(gori_compute::compute_operand_range): Same.
(gori_compute::condexpr_adjust): Same.
* gimple-range.cc (gimple_ranger::prefill_name): Same.
(gimple_ranger::prefill_stmt_dependencies): Same.
* range-op.cc (get_bool_state): Same.
(class operator_equal): Add using clause.
(class operator_not_equal): Same.
(class operator_lt): Same.
(class operator_le): Same.
(class operator_gt): Same.
(class operator_ge): Same.
(class operator_plus): Same.
(class operator_minus): Same.
(class operator_mult): Same.
(class operator_exact_divide): Same.
(class operator_lshift): Same.
(class operator_rshift): Same.
(class operator_cast): Same.
(class operator_logical_and): Same.
(class operator_bitwise_and): Same.
(class operator_logical_or): Same.
(class operator_bitwise_or): Same.
(class operator_bitwise_xor): Same.
(class operator_trunc_mod): Same.
(class operator_logical_not): Same.
(class operator_bitwise_not): Same.
(class operator_cst): Same.
(class operator_identity): Same.
(class operator_unknown): Same.
(class operator_abs): Same.
(class operator_negate): Same.
(class operator_addr_expr): Same.
(class pointer_or_operator): Same.
(operator_plus::op1_range): Adjust for vrange.
(operator_minus::op1_range): Same.
(operator_mult::op1_range): Same.
(operator_cast::op1_range): Same.
(operator_bitwise_not::fold_range): Same.
(operator_negate::fold_range): Same.
(range_op_handler): Rename to...
(get_handler): ...this.
(range_op_handler::range_op_handler): New.
(range_op_handler::fold_range): New.
(range_op_handler::op1_range): New.
(range_op_handler::op2_range): New.
(range_op_handler::lhs_op1_relation): New.
(range_op_handler::lhs_op2_relation): New.
(range_op_handler::op1_op2_relation): New.
(range_cast): Adjust for vrange.
* range-op.h (range_op_handler): Remove function.
(range_cast): Adjust for vrange.
(class range_op_handler): New.
(get_bool_state): Adjust for vrange.
(empty_range_varying): Same.
(relop_early_resolve): Same.
* tree-data-ref.cc (compute_distributive_range): Same.
* tree-vrp.cc (get_range_op_handler): Remove.
(range_fold_binary_symbolics_p): Use range_op_handler class
instead of get_range_op_handler.
(range_fold_unary_symbolics_p): Same.
(range_fold_binary_expr): Same.
(range_fold_unary_expr): Same.
* value-query.cc (range_query::get_tree_range): Adjust for vrange.
|
|
This goes away with the selection operand allowed to be a GENERIC
tcc_comparison tree. It keeps those for vectorizer pattern recog,
those are short lived and removing this instance is a bigger task.
The patch doesn't yet remove dead code and functionality, that's
left for a followup. Instead the patch makes sure to produce
valid GIMPLE IL and continue to optimize COND_EXPRs where the
previous IL allowed and the new IL showed regressions in the testsuite.
2022-05-16 Richard Biener <rguenther@suse.de>
* gimple-expr.cc (is_gimple_condexpr): Equate to is_gimple_val.
* gimplify.cc (gimplify_pure_cond_expr): Gimplify the condition
as is_gimple_val.
* gimple-fold.cc (valid_gimple_rhs_p): Simplify.
* tree-cfg.cc (verify_gimple_assign_ternary): Likewise.
* gimple-loop-interchange.cc (loop_cand::undo_simple_reduction):
Build the condition of the COND_EXPR separately.
* tree-ssa-loop-im.cc (move_computations_worker): Likewise.
* tree-vect-generic.cc (expand_vector_condition): Likewise.
* tree-vect-loop.cc (vect_create_epilog_for_reduction):
Likewise.
* vr-values.cc (simplify_using_ranges::simplify): Likewise.
* tree-vect-patterns.cc: Add comment indicating we are
building invalid COND_EXPRs and why.
* omp-expand.cc (expand_omp_simd): Gimplify the condition
to the COND_EXPR separately.
(expand_omp_atomic_cas): Note part that should be unreachable
now.
* tree-ssa-forwprop.cc (forward_propagate_into_cond): Adjust
condition for valid replacements.
* tree-if-conv.cc (predicate_bbs): Simulate previous
re-folding of the condition in folded COND_EXPRs which
is necessary because of unfolded GIMPLE_CONDs in the IL
as in for example gcc.dg/fold-bopcond-1.c.
* gimple-range-gori.cc (gori_compute::condexpr_adjust):
Handle that the comparison is now in the def stmt of
the select operand. Required by gcc.dg/pr104526.c.
* gcc.dg/gimplefe-27.c: Adjust.
* gcc.dg/gimplefe-45.c: Likewise.
* gcc.dg/pr101145-2.c: Likewise.
* gcc.dg/pr98211.c: Likewise.
* gcc.dg/torture/pr89595.c: Likewise.
* gcc.dg/tree-ssa/divide-7.c: Likewise.
* gcc.dg/tree-ssa/ssa-lim-12.c: Likewise.
|
|
Like in r10-7215-g700d4cb08c88aec37c13e21e63dd61fd698baabc 2 years ago,
I've run
grep -v 'long long\|optab optab\|template template\|double double' *.{[chS],cc} */*.{[chS],cc} *.def config/*/* 2>/dev/null | grep ' \([a-zA-Z]\+\) \1 '
and for the cases that looked clearly wrong changed them, mostly by removing
one of the duplicated words but in some cases with other changes.
2022-03-07 Jakub Jelinek <jakub@redhat.com>
gcc/
* tree-ssa-propagate.cc: Fix up duplicated word issue in a comment.
* config/riscv/riscv.cc: Likewise.
* config/darwin.h: Likewise.
* config/i386/i386.cc: Likewise.
* config/aarch64/thunderx3t110.md: Likewise.
* config/aarch64/fractional-cost.h: Likewise.
* config/vax/vax.cc: Likewise.
* config/rs6000/pcrel-opt.md: Likewise.
* config/rs6000/predicates.md: Likewise.
* ctfc.h: Likewise.
* tree-ssa-uninit.cc: Likewise.
* value-relation.h: Likewise.
* gimple-range-gori.cc: Likewise.
* ipa-polymorphic-call.cc: Likewise.
* pointer-query.cc: Likewise.
* ipa-sra.cc: Likewise.
* internal-fn.cc: Likewise.
* varasm.cc: Likewise.
* gimple-ssa-warn-access.cc: Likewise.
gcc/analyzer/
* store.cc: Fix up duplicated word issue in a comment.
* analyzer.cc: Likewise.
* engine.cc: Likewise.
* sm-taint.cc: Likewise.
gcc/c-family/
* c-attribs.cc: Fix up duplicated word issue in a comment.
gcc/cp/
* cvt.cc: Fix up duplicated word issue in a comment.
* pt.cc: Likewise.
* module.cc: Likewise.
* coroutines.cc: Likewise.
gcc/fortran/
* trans-expr.cc: Fix up duplicated word issue in a comment.
* gfortran.h: Likewise.
* scanner.cc: Likewise.
gcc/jit/
* libgccjit.h: Fix up duplicated word issue in a comment.
|
|
* gimple-range-gori.cc (gori_compute::condexpr_adjust): Use
range_compatible_p instead of direct type comparison.
|
|
Provide an API into gori to perform a basic evaluation of the arguments of a
COND_EXPR if they are in the dependency chain of the condition.
PR tree-optimization/104526
gcc/
* gimple-range-fold.cc (fold_using_range::range_of_cond_expr): Call
new routine.
* gimple-range-gori.cc (range_def_chain::get_def_chain): Force a build
of dependency chain if there isn't one.
(gori_compute::condexpr_adjust): New.
* gimple-range-gori.h (class gori_compute): New prototype.
gcc/testsuite/
* gcc.dg/pr104526.c: New.
|
|
|
|
When compiling an optabs.ii at -O2 with a release-checking build,
there were 6,643,575 calls to gimple_outgoing_range_stmt_p. 96.8% of
them were for blocks with a single successor, which never have a control
statement that generates new range info. This patch therefore adds a
shortcut for that case.
This gives a ~1% compile-time improvement for the test.
I tried making the function inline (in the header) so that the
single_succ_p didn't need to be repeated, but it seemed to make things
slightly worse.
gcc/
* gimple-range-edge.cc (gimple_outgoing_range::edge_range_p): Add
a shortcut for blocks with single successors.
* gimple-range-gori.cc (gori_map::calculate_gori): Likewise.
|
|
There are times we only need to know if any edge from a block can calculate
a range.
* gimple-range-gori.h (class gori_compute):: Add prototypes.
* gimple-range-gori.cc (gori_compute::has_edge_range_p): Add alternate
API for basic block. Call for edge alterantive.
(gori_compute::may_recompute_p): Ditto.
|
|
When a new def chain is requested, any existing reference may no longer
be valid, so just use the object directly.
PR tree-optimization/103467
* gimple-range-gori.cc (range_def_chain::register_dependency): Don't
use an object reference after a potential resize.
|
|
Apply the logical_depth limit ranger uses to all stmts with multiple ssa-names
to avoid excessive outgoing calculations.
gcc/
PR tree-optimization/103254
* gimple-range-gori.cc (range_def_chain::get_def_chain): Limit the
depth for all statements with multple ssa names.
gcc/testsuite/
* gcc.dg/pr103254.c: New.
|
|
When the IL has changed, any new ssa-names import calculations may not jive
with existing ssa-names, so just remove the assert.
gcc/
PR tree-optimization/103093
* gimple-range-gori.cc (range_def_chain::get_imports): Remove assert.
gcc/testsuite/
* gcc.dg/pr103093.c: New.
|
|
If the LHS is UNDEFINED simply stop calculating. Treat op1 and op2
as VARYING if they are UNDEFINED.
PR tree-optimization/103079
gcc/
* gimple-range-gori.cc (gimple_range_calc_op1): Treat undefined as
varying.
(gimple_range_calc_op2): Ditto.
gcc/testsuite/
* gcc.dg/pr103079.c: New.
|
|
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.
|
|
Very large switches cause a lot of range calculations with multiple subranges
to happen. This can cause quadratic or even exponetial time increases in
large testcases. This patch introduces a param variable to limit
the size of switches EVRP will process.
* gimple-range-edge.cc (gimple_outgoing_range::gimple_outgoing_range):
Add parameter to limit size when recognizing switches.
(gimple_outgoing_range::edge_range_p): Check size limit.
* gimple-range-edge.h (gimple_outgoing_range): Add size field.
* gimple-range-gori.cc (gori_map::calculate_gori): Ignore switches
that exceed the size limit.
(gori_compute::gori_compute): Add initializer.
* params.opt (evrp-switch-limit): New.
* doc/invoke.texi: Update docs.
|
|
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.
|
|
Debugging range-ops and gori unwinding needed some help.
* gimple-range-gori.cc (gori_compute::gori_compute): Enable tracing.
(gori_compute::compute_operand_range): Add tracing.
(gori_compute::logical_combine): Ditto.
(gori_compute::compute_logical_operands): Ditto.
(gori_compute::compute_operand1_range): Ditto.
(gori_compute::compute_operand2_range): Ditto.
(gori_compute::outgoing_edge_range_p): Ditto.
* gimple-range-gori.h (class gori_compute): Add range_tracer.
|
|
When a branch has been folded, mark any range requests on the unexecutable edge as
UNDEFINED.
* gimple-range-gori.cc (gori_compute::outgoing_edge_range_p): Check for
cond_false and cond_true on branches.
|
|
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-cache.cc: Comment cleanups.
* gimple-range-gori.cc: Comment cleanups.
* gimple-range.cc: Comment/spacing cleanups
* value-range.h: Comment cleanups.
|
|
The gori engine can calculate outgoing ranges for exported values. This
change allows 1st degree recomputation. If a name is not exported from a
block, but one of the ssa_names used directly in computing it is, then
we can recompute the ssa_name on the edge using the edge values for its
operands.
* gimple-range-gori.cc (gori_compute::has_edge_range_p): Check with
may_recompute_p.
(gori_compute::may_recompute_p): New.
(gori_compute::outgoing_edge_range_p): Perform recomputations.
* gimple-range-gori.h (class gori_compute): Add prototype.
|
|
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.
|
|
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.
|
|
... or at least try to.
2021-05-26 Bernd Edlinger <bernd.edlinger@hotmail.de>
* gimple-range-gori.cc (range_def_chain::register_dependency):
Resize m_def_chain when needed.
|
|
With the depth limiting, we are not currently using the logical stmt cache.
* gimple-range-gori.cc (class logical_stmt_cache): Delete
(logical_stmt_cache::logical_stmt_cache ): Delete.
(logical_stmt_cache::~logical_stmt_cache): Delete.
(logical_stmt_cache::cache_entry::dump): Delete.
(logical_stmt_cache::get_range): Delete.
(logical_stmt_cache::cached_name ): Delete.
(logical_stmt_cache::same_cached_name): Delete.
(logical_stmt_cache::cacheable_p): Delete.
(logical_stmt_cache::slot_diagnostics ): Delete.
(logical_stmt_cache::dump): Delete.
(gori_compute_cache::gori_compute_cache): Delete.
(gori_compute_cache::~gori_compute_cache): Delete.
(gori_compute_cache::compute_operand_range): Delete.
(gori_compute_cache::cache_stmt): Delete.
* gimple-range-gori.h (gori_compute::compute_operand_range): Remove
virtual.
(class gori_compute_cache): Delete.
|
|
prerequisite to moving to a range_query model, make it stmt based.
* gimple-range-gori.cc (gori_compute::expr_range_at_stmt): Rename
from expr_range_in_bb and adjust.
(gori_compute::compute_name_range_op): Adjust.
(gori_compute::optimize_logical_operands): Adjust.
(gori_compute::compute_logical_operands_in_chain): Adjust.
(gori_compute::compute_operand1_range): Adjust.
(gori_compute::compute_operand2_range): Adjust.
(ori_compute_cache::cache_stmt): Adjust.
* gimple-range-gori.h (gori_compute): Rename prototype.
|
|
All add up to 2 direct dependencies for each ssa-name.
Add gori import/export iterators.
* gimple-range-gori.cc (range_def_chain::range_def_chain): init
bitmap obstack.
(range_def_chain::~range_def_chain): Dispose of obstack rather than
each individual bitmap.
(range_def_chain::set_import): New.
(range_def_chain::get_imports): New.
(range_def_chain::chain_import_p): New.
(range_def_chain::register_dependency): Rename from build_def_chain
and set imports.
(range_def_chain::def_chain_in_bitmap_p): New.
(range_def_chain::add_def_chain_to_bitmap): New.
(range_def_chain::has_def_chain): Just check first depenedence.
(range_def_chain::get_def_chain): Process imports, use generic
register_dependency routine.
(range_def_chain::dump): New.
(gori_map::gori_map): Allocate import list.
(gori_map::~gori_map): Release imports.
(gori_map::exports): Check for past allocated block size.
(gori_map::imports): New.
(gori_map::def_chain_in_export_p): Delete.
(gori_map::is_import_p): New.
(gori_map::maybe_add_gori): Handle imports.
(gori_map::dump): Adjust output, add imports.
(gori_compute::has_edge_range_p): Remove def_chain_in_export call.
(gori_export_iterator::gori_export_iterator): New.
(gori_export_iterator::next): New.
(gori_export_iterator::get_name): New.
* gimple-range-gori.h (range_def_chain): Add imports and direct
dependecies via struct rdc.
(range_def_chain::depend1): New.
(range_def_chain::depend2): New.
(class gori_map): Adjust.
(FOR_EACH_GORI_IMPORT_NAME): New.
(FOR_EACH_GORI_EXPORT_NAME): New.
(class gori_export_iterator): New.
|
|
Ranger wants to prepopulate all the export blocks so that it has an initial
invariant set of names. GORI consumers shouldn't be penalized for ranger
requirements. This way any gori client remains lightweight.
* gimple-range-cache.cc (ranger_cache::ranger_cache): Move initial
export cache filling to here.
* gimple-range-gori.cc (gori_compute::gori_compute) : From Here.
|
|
Move the classes to the header file and inherit instead of instantiating.
* gimple-range-gori.cc (range_def_chain): Move to gimple-range-gori.h.
(gori_map): Move to gimple-range-gori.h.
(gori_compute::gori_compute): Adjust.
(gori_compute::~gori_compute): Delete.
(gori_compute::compute_operand_range_switch): Adjust.
(gori_compute::compute_operand_range): Adjust.
(gori_compute::compute_logical_operands): Adjust.
(gori_compute::has_edge_range_p ): Adjust.
(gori_compute::set_range_invariant): Delete.
(gori_compute::dump): Adjust.
(gori_compute::outgoing_edge_range_p): Adjust.
* gimple-range-gori.h (class range_def_chain): Relocate here.
(class gori_map): Relocate here.
(class gori_compute): Inherit from gori_map, and adjust.
|
|
Limit how many logical expressions GORI will look back through when
evaluating outgoing edge range.
PR tree-optimization/100081
* gimple-range-cache.h (ranger_cache): Inherit from gori_compute
rather than gori_compute_cache.
* gimple-range-gori.cc (is_gimple_logical_p): Move to top of file.
(range_def_chain::m_logical_depth): New member.
(range_def_chain::range_def_chain): Initialize m_logical_depth.
(range_def_chain::get_def_chain): Don't build defchains through more
than LOGICAL_LIMIT logical expressions.
* params.opt (param_ranger_logical_depth): New.
|
|
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].
|
|
|
|
Calculate block exit info upfront, and then any SSA_NAME which is never
used in an outgoing range calculation is a pure global and can bypass the
on-entry cache.
PR tree-optimization/98174
* gimple-range-cache.cc (ranger_cache::ssa_range_in_bb): Only push
poor values to be examined if it isn't a pure global.
(ranger_cache::block_range): Don't process pure globals.
(ranger_cache::fill_block_cache): Adjust has_edge_range call.
* gimple-range-gori.cc (gori_map::all_outgoing): New bitmap.
(gori_map::gori_map): Allocate all_outgoing.
(gori_map::is_export_p): No specified BB returns global context.
(gori_map::calculate_gori): Accumulate each block into global.
(gori_compute::gori_compute): Preprocess each block for exports.
(gori_compute::has_edge_range_p): No edge returns global context.
* gimple-range-gori.h (has_edge_range_p): Provide default parameter.
|
|
The original fix was incorrect and results in loss of opportunities.
Revert the original fix. When processing logical chains, do not
follow chains outside of the current basic block. Use the import
value instead.
gcc/
PR tree-optimization/97567
* gimple-range-gori.cc: (gori_compute::logical_combine): False
OR operations should intersect the 2 results.
(gori_compute::compute_logical_operands_in_chain): If def chains
are outside the current basic block, don't follow them.
gcc/testsuite/
* gcc.dg/pr97567-2.c: New.
|
|
Remove the gcc_assert wrappers that contain statements that need to be
executed.
Audit routines to ensure range is set to UNDEFINED when false is returned.
* gimple-range-gori.cc (gori_compute_cache::cache_stmt): Accumulate
return values and only set cache when everything returned true.
* gimple-range.cc (get_tree_range): Set the return range to UNDEFINED
when the range isn't supported.
(gimple_ranger::calc_stmt): Return varying if the type is supported,
even if the stmt processing failed. False otherwise.
(range_of_builtin_ubsan_call): Don't use gcc_assert.
(range_of_builtin_call): Ditto.
(gimple_ranger::range_of_cond_expr): Ditto.
(gimple_ranger::range_of_expr): Ditto
(gimple_ranger::range_on_entry): Ditto.
(gimple_ranger::range_on_exit): Ditto.
(gimple_ranger::range_on_edge): DItto.
(gimple_ranger::range_of_stmt): Don't use gcc_assert, and initialize
return value to UNDEFINED.
|
|
When combining logical OR operands with a FALSE result, union the false
ranges for operand1 and operand2... not intersection.
gcc/
PR tree-optimization/97567
* gimple-range-gori.cc (gori_compute::logical_combine): Union the
ranges of operand1 and operand2, not intersect.
gcc/testsuite/
* gcc.dg/pr97567.c: New.
|
|
Updated to only use range_compatible_p in range assert sanity checks,
not for actual type cmpatibility.
* gimple-range-gori.cc (is_gimple_logical_p): Use types_compatible_p
for logical compatibility.
(logical_stmt_cache::cacheable_p): Ditto.
|
|
Sanity check ranges by comparing just SIGN and PRECISION.
gcc/
PR tree-optimization/97360
* gimple-range.h (range_compatible_p): New.
* gimple-range-gori.cc (is_gimple_logical_p): Use range_compatible_p.
(range_is_either_true_or_false): Ditto.
(gori_compute::outgoing_edge_range_p): Cast result to the correct
type if necessary.
(logical_stmt_cache::cacheable_p): Use range_compatible_p.
* gimple-range.cc (gimple_ranger::calc_stmt): Check range_compatible_p
before casting the range.
(gimple_ranger::range_on_exit): Use range_compatible_p.
(gimple_ranger::range_on_edge): Ditto.
gcc/testsuite/
* gcc.dg/pr97360-2.c: New test.
|
|
We were ignoring the return value if op2 returned false and getting garbage ranges propagated.
gcc/ChangeLog:
PR tree-optimization/97381
* gimple-range-gori.cc (gori_compute::compute_operand2_range): If a range cannot be
calculated through operand 2, return false.
gcc/testsuite/ChangeLog:
* gcc.dg/pr97381.c: New test.
|
|
logical_stmt_cache::cacheable_p() returns true for relops, but
logical_combine (which does the caching) doesn't handle them and ICEs.
This patch fixes the inconsistency by returning false for relops.
This was working before because even though logical_combine doesn't
handle relops, statements with only one SSA are handled in cache_stmt,
which seems like the only statement we've ever encountered (even through
a full Fedora build).
lhs = s_5 > 999;
However, with two SSA operands we ICE because logical_combine doesn't
handle them:
lhs = s_5 > y_8;
We can either return false for relops in cacheable_p, or fix
logical_combine to handle them. The original idea was to only cache
ANDs and ORs, so I've done the former to unbreak trunk.
We can decide later if there was ever any benefit in caching relops.
gcc/ChangeLog:
PR tree-optimization/97359
* gimple-range-gori.cc (logical_stmt_cache::cacheable_p): Only
handle ANDs and ORs.
(gori_compute_cache::cache_stmt): Adjust comment.
gcc/testsuite/ChangeLog:
* gcc.dg/pr97359.c: New test.
|
|
Add the 8 ranger files and the Makefile changes to build it.
2020-10-06 Andrew MacLeod <amacleod@redhat.com>
* Makefile.in (OBJS): Add gimple-range*.o.
* gimple-range.h: New file.
* gimple-range.cc: New file.
* gimple-range-cache.h: New file.
* gimple-range-cache.cc: New file.
* gimple-range-edge.h: New file.
* gimple-range-edge.cc: New file.
* gimple-range-gori.h: New file.
* gimple-range-gori.cc: New file.
|