From 3b0a7d624e64eeb81e4d5e8c62c46d86ef521857 Mon Sep 17 00:00:00 2001 From: Kito Cheng Date: Tue, 25 May 2021 21:26:12 +0800 Subject: RISC-V: Pass -mno-relax to assembler gcc/ChangeLog: * config/riscv/riscv.h (ASM_SPEC): Pass -mno-relax. --- gcc/config/riscv/riscv.h | 1 + 1 file changed, 1 insertion(+) (limited to 'gcc') diff --git a/gcc/config/riscv/riscv.h b/gcc/config/riscv/riscv.h index f3e8572..f47d5b4 100644 --- a/gcc/config/riscv/riscv.h +++ b/gcc/config/riscv/riscv.h @@ -98,6 +98,7 @@ extern const char *riscv_default_mtune (int argc, const char **argv); %{" FPIE_OR_FPIC_SPEC ":-fpic} \ %{march=*} \ %{mabi=*} \ +%{mno-relax} \ %{mbig-endian} \ %{mlittle-endian} \ %(subtarget_asm_spec)" \ -- cgit v1.1 From 1d3707a52d6b8a3054248b4291719150937db309 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Tue, 25 May 2021 16:51:05 +0200 Subject: Fix thinko in latest change to setup_one_parameter gcc/ * tree-inline.c (setup_one_parameter): Fix thinko in new condition. --- gcc/tree-inline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 8f945b8..1d13e7f 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -3446,7 +3446,7 @@ setup_one_parameter (copy_body_data *id, tree p, tree value, tree fn, sure that it cannot be modified from another path in the callee. */ if ((is_gimple_min_invariant (value) || (DECL_P (value) && TREE_READONLY (value)) - || (auto_var_in_fn_p (value, id->src_fn) + || (auto_var_in_fn_p (value, id->dst_fn) && !TREE_ADDRESSABLE (value))) && useless_type_conversion_p (TREE_TYPE (p), TREE_TYPE (value)) /* We have to be very careful about ADDR_EXPR. Make sure -- cgit v1.1 From ad52d89808a947264397e920d7483090d4108f7b Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 25 May 2021 17:24:38 +0200 Subject: c++: Avoid -Wunused-value false positives on nullptr passed to ellipsis [PR100666] When passing expressions with decltype(nullptr) type with side-effects to ellipsis, we pass (void *)0 instead, but for the side-effects evaluate them on the lhs of a COMPOUND_EXPR. Unfortunately that means we warn about it if the expression is a call to nodiscard marked function, even when the result is really used, just needs to be transformed. Fixed by adding a warning_sentinel. 2021-05-25 Jakub Jelinek PR c++/100666 * call.c (convert_arg_to_ellipsis): For expressions with NULLPTR_TYPE and side-effects, temporarily disable -Wunused-result warning when building COMPOUND_EXPR. * g++.dg/cpp1z/nodiscard8.C: New test. * g++.dg/cpp1z/nodiscard9.C: New test. --- gcc/cp/call.c | 5 ++++- gcc/testsuite/g++.dg/cpp1z/nodiscard8.C | 15 +++++++++++++++ gcc/testsuite/g++.dg/cpp1z/nodiscard9.C | 22 ++++++++++++++++++++++ 3 files changed, 41 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/cpp1z/nodiscard8.C create mode 100644 gcc/testsuite/g++.dg/cpp1z/nodiscard9.C (limited to 'gcc') diff --git a/gcc/cp/call.c b/gcc/cp/call.c index cfccf27..3076fe6 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -8178,7 +8178,10 @@ convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain) { arg = mark_rvalue_use (arg); if (TREE_SIDE_EFFECTS (arg)) - arg = cp_build_compound_expr (arg, null_pointer_node, complain); + { + warning_sentinel w(warn_unused_result); + arg = cp_build_compound_expr (arg, null_pointer_node, complain); + } else arg = null_pointer_node; } diff --git a/gcc/testsuite/g++.dg/cpp1z/nodiscard8.C b/gcc/testsuite/g++.dg/cpp1z/nodiscard8.C new file mode 100644 index 0000000..b5096ac --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/nodiscard8.C @@ -0,0 +1,15 @@ +// PR c++/100666 +// { dg-do compile { target c++11 } } + +[[nodiscard]] decltype(nullptr) bar (); +extern void foo (...); +template void qux (T); + +void +baz () +{ + foo (bar ()); // { dg-bogus "ignoring return value of '\[^\n\r]*', declared with attribute 'nodiscard'" } + bar (); // { dg-warning "ignoring return value of '\[^\n\r]*', declared with attribute 'nodiscard'" } + auto x = bar (); // { dg-bogus "ignoring return value of '\[^\n\r]*', declared with attribute 'nodiscard'" } + qux (bar ()); // { dg-bogus "ignoring return value of '\[^\n\r]*', declared with attribute 'nodiscard'" } +} diff --git a/gcc/testsuite/g++.dg/cpp1z/nodiscard9.C b/gcc/testsuite/g++.dg/cpp1z/nodiscard9.C new file mode 100644 index 0000000..1315ccd --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1z/nodiscard9.C @@ -0,0 +1,22 @@ +// PR c++/100666 +// { dg-do compile { target c++11 } } + +struct S {}; +[[nodiscard]] S bar (); +struct U { S s; }; +[[nodiscard]] U corge (); +extern void foo (...); +template void qux (T); + +void +baz () +{ + foo (bar ()); // { dg-bogus "ignoring return value of '\[^\n\r]*', declared with attribute 'nodiscard'" } + bar (); // { dg-warning "ignoring return value of '\[^\n\r]*', declared with attribute 'nodiscard'" } + auto x = bar (); // { dg-bogus "ignoring return value of '\[^\n\r]*', declared with attribute 'nodiscard'" } + qux (bar ()); // { dg-bogus "ignoring return value of '\[^\n\r]*', declared with attribute 'nodiscard'" } + foo (corge ()); // { dg-bogus "ignoring return value of '\[^\n\r]*', declared with attribute 'nodiscard'" } + corge (); // { dg-warning "ignoring return value of '\[^\n\r]*', declared with attribute 'nodiscard'" } + auto y = corge (); // { dg-bogus "ignoring return value of '\[^\n\r]*', declared with attribute 'nodiscard'" } + qux (corge ()); // { dg-bogus "ignoring return value of '\[^\n\r]*', declared with attribute 'nodiscard'" } +} -- cgit v1.1 From fd97aeb494cdcffe0d21e7f15ab4593662e065bd Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Tue, 25 May 2021 18:30:29 +0200 Subject: Remove stalled TREE_READONLY flag on automatic variable gcc/ * gimplify.c (gimplify_decl_expr): Clear TREE_READONLY on the DECL when really creating an initialization statement for it. --- gcc/gimplify.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'gcc') diff --git a/gcc/gimplify.c b/gcc/gimplify.c index b62ea0e..ed825a9 100644 --- a/gcc/gimplify.c +++ b/gcc/gimplify.c @@ -1828,6 +1828,9 @@ gimplify_decl_expr (tree *stmt_p, gimple_seq *seq_p) init = build2 (INIT_EXPR, void_type_node, decl, init); gimplify_and_add (init, seq_p); ggc_free (init); + /* Clear TREE_READONLY if we really have an initialization. */ + if (!DECL_INITIAL (decl)) + TREE_READONLY (decl) = 0; } else /* We must still examine initializers for static variables -- cgit v1.1 From 41ddc5b0a6b44a9df53a259636fa3b534ae41cbe Mon Sep 17 00:00:00 2001 From: Aldy Hernandez Date: Tue, 25 May 2021 08:36:44 +0200 Subject: Fix selftest for targets where short and int are the same size. avr-elf seems to use HImode for both integer_type_node and signed_char_type_node, which is causing the check for different sized VARYING ranges to fail. gcc/ChangeLog: * value-range.cc (range_tests_legacy): Use build_nonstandard_integer_type instead of int and short. --- gcc/value-range.cc | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'gcc') diff --git a/gcc/value-range.cc b/gcc/value-range.cc index 8d7b46c..f113fd7 100644 --- a/gcc/value-range.cc +++ b/gcc/value-range.cc @@ -2250,11 +2250,13 @@ range_tests_legacy () } // VARYING of different sizes should not be equal. - int_range_max r0 (integer_type_node); - int_range_max r1 (short_integer_type_node); + tree big_type = build_nonstandard_integer_type (32, 1); + tree small_type = build_nonstandard_integer_type (16, 1); + int_range_max r0 (big_type); + int_range_max r1 (small_type); ASSERT_TRUE (r0 != r1); - value_range vr0 (integer_type_node); - int_range_max vr1 (short_integer_type_node); + value_range vr0 (big_type); + int_range_max vr1 (small_type); ASSERT_TRUE (vr0 != vr1); } -- cgit v1.1 From 28ceee1b91f48b5ab09cbd20ea6a9de6ea137af8 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Tue, 25 May 2021 13:45:43 -0400 Subject: Change gori_compute to inherit from gori_map instead of having a gori-map. 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. --- gcc/gimple-range-gori.cc | 76 +++++++----------------------------------------- gcc/gimple-range-gori.h | 48 +++++++++++++++++++++++++++--- 2 files changed, 55 insertions(+), 69 deletions(-) (limited to 'gcc') diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc index 420282d..074c025 100644 --- a/gcc/gimple-range-gori.cc +++ b/gcc/gimple-range-gori.cc @@ -91,21 +91,6 @@ is_gimple_logical_p (const gimple *gs) engine implements operations for. */ -class range_def_chain -{ -public: - range_def_chain (); - ~range_def_chain (); - bool has_def_chain (tree name); - bitmap get_def_chain (tree name); - bool in_chain_p (tree name, tree def); -private: - vec m_def_chain; // SSA_NAME : def chain components. - void build_def_chain (tree name, bitmap result, basic_block bb); - int m_logical_depth; -}; - - // Construct a range_def_chain. range_def_chain::range_def_chain () @@ -264,27 +249,6 @@ range_def_chain::get_def_chain (tree name) entire def_chain of all SSA names used in the last statement of the block which generate ranges. */ -class gori_map : public range_def_chain -{ -public: - gori_map (); - ~gori_map (); - - bool is_export_p (tree name, basic_block bb = NULL); - bool def_chain_in_export_p (tree name, basic_block bb); - bitmap exports (basic_block bb); - void set_range_invariant (tree name); - - void dump (FILE *f); - void dump (FILE *f, basic_block bb); -private: - bitmap_obstack m_bitmaps; - vec m_outgoing; // BB: Outgoing ranges calculatable on edges - bitmap m_maybe_variant; // Names which might have outgoing ranges. - void maybe_add_gori (tree name, basic_block bb); - void calculate_gori (basic_block bb); -}; - // Initialize a gori-map structure. @@ -494,7 +458,6 @@ gori_compute::gori_compute () // Create a boolean_type true and false range. m_bool_zero = int_range<2> (boolean_false_node, boolean_false_node); m_bool_one = int_range<2> (boolean_true_node, boolean_true_node); - m_gori_map = new gori_map; unsigned x, lim = last_basic_block_for_fn (cfun); // Calculate outgoing range info upfront. This will fully populate the // m_maybe_variant bitmap which will help eliminate processing of names @@ -503,17 +466,10 @@ gori_compute::gori_compute () { basic_block bb = BASIC_BLOCK_FOR_FN (cfun, x); if (bb) - m_gori_map->exports (bb); + exports (bb); } } -// Destruct a gori_compute_object. - -gori_compute::~gori_compute () -{ - delete m_gori_map; -} - // Provide a default of VARYING for all incoming SSA names. void @@ -597,7 +553,7 @@ gori_compute::compute_operand_range_switch (irange &r, gswitch *s, } // If op1 is in the defintion chain, pass lhs back. - if (gimple_range_ssa_p (op1) && m_gori_map->in_chain_p (name, op1)) + if (gimple_range_ssa_p (op1) && in_chain_p (name, op1)) return compute_operand_range (r, SSA_NAME_DEF_STMT (op1), lhs, name); return false; @@ -635,8 +591,8 @@ gori_compute::compute_operand_range (irange &r, gimple *stmt, // NAME is not in this stmt, but one of the names in it ought to be // derived from it. - bool op1_in_chain = op1 && m_gori_map->in_chain_p (name, op1); - bool op2_in_chain = op2 && m_gori_map->in_chain_p (name, op2); + bool op1_in_chain = op1 && in_chain_p (name, op1); + bool op2_in_chain = op2 && in_chain_p (name, op2); if (op1_in_chain && op2_in_chain) return compute_operand1_and_operand2_range (r, stmt, lhs, name); if (op1_in_chain) @@ -881,10 +837,8 @@ gori_compute::compute_logical_operands (irange &r, gimple *stmt, tree op2 = gimple_range_operand2 (stmt); gcc_checking_assert (op1 != name && op2 != name); - bool op1_in_chain = (gimple_range_ssa_p (op1) - && m_gori_map->in_chain_p (name, op1)); - bool op2_in_chain = (gimple_range_ssa_p (op2) - && m_gori_map->in_chain_p (name, op2)); + bool op1_in_chain = (gimple_range_ssa_p (op1) && in_chain_p (name, op1)); + bool op2_in_chain = (gimple_range_ssa_p (op2) && in_chain_p (name, op2)); // If neither operand is derived, then this stmt tells us nothing. if (!op1_in_chain && !op2_in_chain) @@ -1014,18 +968,10 @@ gori_compute::has_edge_range_p (tree name, edge e) { // If no edge is specified, check if NAME is an export on any edge. if (!e) - return m_gori_map->is_export_p (name); + return is_export_p (name); - return (m_gori_map->is_export_p (name, e->src) - || m_gori_map->def_chain_in_export_p (name, e->src)); -} - -// Clear the m_maybe_variant bit so ranges will not be tracked for NAME. - -void -gori_compute::set_range_invariant (tree name) -{ - m_gori_map->set_range_invariant (name); + return (is_export_p (name, e->src) + || def_chain_in_export_p (name, e->src)); } // Dump what is known to GORI computes to listing file F. @@ -1033,7 +979,7 @@ gori_compute::set_range_invariant (tree name) void gori_compute::dump (FILE *f) { - m_gori_map->dump (f); + gori_map::dump (f); } // Calculate a range on edge E and return it in R. Try to evaluate a @@ -1052,7 +998,7 @@ gori_compute::outgoing_edge_range_p (irange &r, edge e, tree name) return false; // If NAME can be calculated on the edge, use that. - if (m_gori_map->is_export_p (name, e->src)) + if (is_export_p (name, e->src)) { if (compute_operand_range (r, stmt, lhs, name)) { diff --git a/gcc/gimple-range-gori.h b/gcc/gimple-range-gori.h index 7bb18a9..6208931 100644 --- a/gcc/gimple-range-gori.h +++ b/gcc/gimple-range-gori.h @@ -22,6 +22,49 @@ along with GCC; see the file COPYING3. If not see #ifndef GCC_GIMPLE_RANGE_GORI_H #define GCC_GIMPLE_RANGE_GORI_H +// RANGE_DEF_CHAIN is used to determine which SSA names in a block can +// have range information calculated for them, and what the +// dependencies on each other are. + +class range_def_chain +{ +public: + range_def_chain (); + ~range_def_chain (); + bool has_def_chain (tree name); + bitmap get_def_chain (tree name); + bool in_chain_p (tree name, tree def); +private: + vec m_def_chain; // SSA_NAME : def chain components. + void build_def_chain (tree name, bitmap result, basic_block bb); + int m_logical_depth; +}; + +// GORI_MAP is used to accumulate what SSA names in a block can +// generate range information, and provides tools for the block ranger +// to enable it to efficiently calculate these ranges. + +class gori_map : public range_def_chain +{ +public: + gori_map (); + ~gori_map (); + + bool is_export_p (tree name, basic_block bb = NULL); + bool def_chain_in_export_p (tree name, basic_block bb); + bitmap exports (basic_block bb); + void set_range_invariant (tree name); + + void dump (FILE *f); + void dump (FILE *f, basic_block bb); +private: + bitmap_obstack m_bitmaps; + vec m_outgoing; // BB: Outgoing ranges calculatable on edges + bitmap m_maybe_variant; // Names which might have outgoing ranges. + void maybe_add_gori (tree name, basic_block bb); + void calculate_gori (basic_block bb); +}; + // This class is used to determine which SSA_NAMES can have ranges // calculated for them on outgoing edges from basic blocks. This represents @@ -65,14 +108,12 @@ along with GCC; see the file COPYING3. If not see // // The remaining routines are internal use only. -class gori_compute +class gori_compute : public gori_map { public: gori_compute (); - ~gori_compute (); bool outgoing_edge_range_p (irange &r, edge e, tree name); bool has_edge_range_p (tree name, edge e = NULL); - void set_range_invariant (tree name); void dump (FILE *f); protected: virtual void ssa_range_in_bb (irange &r, tree name, basic_block bb); @@ -107,7 +148,6 @@ private: bool compute_operand1_and_operand2_range (irange &r, gimple *stmt, const irange &lhs, tree name); - class gori_map *m_gori_map; gimple_outgoing_range outgoing; // Edge values for COND_EXPR & SWITCH_EXPR. }; -- cgit v1.1 From cb33af1a62b09576b0782ac36e5f5cff049f1035 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Tue, 25 May 2021 13:53:25 -0400 Subject: fully populate the export list from range_cache, not gori_compute. 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. --- gcc/gimple-range-cache.cc | 10 ++++++++++ gcc/gimple-range-gori.cc | 10 ---------- 2 files changed, 10 insertions(+), 10 deletions(-) (limited to 'gcc') diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc index 2c922e3..8ad7604 100644 --- a/gcc/gimple-range-cache.cc +++ b/gcc/gimple-range-cache.cc @@ -618,6 +618,16 @@ ranger_cache::ranger_cache (gimple_ranger &q) : query (q) m_poor_value_list.safe_grow_cleared (20); m_poor_value_list.truncate (0); m_temporal = new temporal_cache; + unsigned x, lim = last_basic_block_for_fn (cfun); + // Calculate outgoing range info upfront. This will fully populate the + // m_maybe_variant bitmap which will help eliminate processing of names + // which never have their ranges adjusted. + for (x = 0; x < lim ; x++) + { + basic_block bb = BASIC_BLOCK_FOR_FN (cfun, x); + if (bb) + exports (bb); + } } ranger_cache::~ranger_cache () diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc index 074c025..e30049e 100644 --- a/gcc/gimple-range-gori.cc +++ b/gcc/gimple-range-gori.cc @@ -458,16 +458,6 @@ gori_compute::gori_compute () // Create a boolean_type true and false range. m_bool_zero = int_range<2> (boolean_false_node, boolean_false_node); m_bool_one = int_range<2> (boolean_true_node, boolean_true_node); - unsigned x, lim = last_basic_block_for_fn (cfun); - // Calculate outgoing range info upfront. This will fully populate the - // m_maybe_variant bitmap which will help eliminate processing of names - // which never have their ranges adjusted. - for (x = 0; x < lim ; x++) - { - basic_block bb = BASIC_BLOCK_FOR_FN (cfun, x); - if (bb) - exports (bb); - } } // Provide a default of VARYING for all incoming SSA names. -- cgit v1.1 From c21644704160710a17d1ea6c1cd212e079cd5e36 Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Tue, 25 May 2021 14:15:50 -0400 Subject: Add imports and strengthen the export definition in range_def and gori_map. 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. --- gcc/gimple-range-gori.cc | 356 ++++++++++++++++++++++++++++++++++------------- gcc/gimple-range-gori.h | 77 +++++++++- 2 files changed, 327 insertions(+), 106 deletions(-) (limited to 'gcc') diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc index e30049e..94640ad 100644 --- a/gcc/gimple-range-gori.cc +++ b/gcc/gimple-range-gori.cc @@ -56,7 +56,7 @@ is_gimple_logical_p (const gimple *gs) return false; } -/* RANGE_DEF_CHAIN is used to determine what SSA names in a block can +/* RANGE_DEF_CHAIN is used to determine which SSA names in a block can have range information calculated for them, and what the dependencies on each other are. @@ -95,6 +95,7 @@ is_gimple_logical_p (const gimple *gs) range_def_chain::range_def_chain () { + bitmap_obstack_initialize (&m_bitmaps); m_def_chain.create (0); m_def_chain.safe_grow_cleared (num_ssa_names); m_logical_depth = 0; @@ -104,11 +105,8 @@ range_def_chain::range_def_chain () range_def_chain::~range_def_chain () { - unsigned x; - for (x = 0; x < m_def_chain.length (); ++x) - if (m_def_chain[x]) - BITMAP_FREE (m_def_chain[x]); m_def_chain.release (); + bitmap_obstack_release (&m_bitmaps); } // Return true if NAME is in the def chain of DEF. If BB is provided, @@ -128,26 +126,112 @@ range_def_chain::in_chain_p (tree name, tree def) return bitmap_bit_p (chain, SSA_NAME_VERSION (name)); } +// Add either IMP or the import list B to the import set of DATA. + +void +range_def_chain::set_import (struct rdc &data, tree imp, bitmap b) +{ + // If there are no imports, just return + if (imp == NULL_TREE && !b) + return; + if (!data.m_import) + data.m_import = BITMAP_ALLOC (&m_bitmaps); + if (imp != NULL_TREE) + bitmap_set_bit (data.m_import, SSA_NAME_VERSION (imp)); + else + bitmap_ior_into (data.m_import, b); +} + +// Return the import list for NAME. + +bitmap +range_def_chain::get_imports (tree name) +{ + if (!has_def_chain (name)) + get_def_chain (name); + bitmap i = m_def_chain[SSA_NAME_VERSION (name)].m_import; + // Either this is a default def, OR imports must be a subset of exports. + gcc_checking_assert (!get_def_chain (name) || !i + || !bitmap_intersect_compl_p (i, get_def_chain (name))); + return i; +} + +// Return true if IMPORT is an import to NAMEs def chain. + +bool +range_def_chain::chain_import_p (tree name, tree import) +{ + bitmap b = get_imports (name); + if (b) + return bitmap_bit_p (b, SSA_NAME_VERSION (import)); + return false; +} + // Build def_chains for NAME if it is in BB. Copy the def chain into RESULT. void -range_def_chain::build_def_chain (tree name, bitmap result, basic_block bb) +range_def_chain::register_dependency (tree name, tree dep, basic_block bb) { + if (!gimple_range_ssa_p (dep)) + return; + + unsigned v = SSA_NAME_VERSION (name); + struct rdc &src = m_def_chain[v]; + gimple *def_stmt = SSA_NAME_DEF_STMT (dep); + unsigned dep_v = SSA_NAME_VERSION (dep); bitmap b; - gimple *def_stmt = SSA_NAME_DEF_STMT (name); + + // Set the direct dependency cache entries. + if (!src.ssa1) + src.ssa1 = dep; + else if (!src.ssa2 && src.ssa1 != dep) + src.ssa2 = dep; + + // Don't calculate imports or export/dep chains if BB is not provided. + // This is usually the case for when the temporal cache wants the direct + // dependencies of a stmt. + if (!bb) + return; + + if (!src.bm) + src.bm = BITMAP_ALLOC (&m_bitmaps); + // Add this operand into the result. - bitmap_set_bit (result, SSA_NAME_VERSION (name)); + bitmap_set_bit (src.bm, dep_v); if (gimple_bb (def_stmt) == bb && !is_a(def_stmt)) { // Get the def chain for the operand. - b = get_def_chain (name); + b = get_def_chain (dep); // If there was one, copy it into result. if (b) - bitmap_ior_into (result, b); + bitmap_ior_into (src.bm, b); + // And copy the import list. + set_import (src, NULL_TREE, get_imports (dep)); } + else + // Originated outside the block, so it is an import. + set_import (src, dep, NULL); +} + +bool +range_def_chain::def_chain_in_bitmap_p (tree name, bitmap b) +{ + bitmap a = get_def_chain (name); + if (a && b) + return bitmap_intersect_p (a, b); + return false; } +void +range_def_chain::add_def_chain_to_bitmap (bitmap b, tree name) +{ + bitmap r = get_def_chain (name); + if (r) + bitmap_ior_into (b, r); +} + + // Return TRUE if NAME has been processed for a def_chain. inline bool @@ -157,9 +241,11 @@ range_def_chain::has_def_chain (tree name) unsigned v = SSA_NAME_VERSION (name); if (v >= m_def_chain.length ()) m_def_chain.safe_grow_cleared (num_ssa_names + 1); - return (m_def_chain[v] != NULL); + return (m_def_chain[v].ssa1 != 0); } + + // Calculate the def chain for NAME and all of its dependent // operands. Only using names in the same BB. Return the bitmap of // all names in the m_def_chain. This only works for supported range @@ -174,11 +260,15 @@ range_def_chain::get_def_chain (tree name) // If it has already been processed, just return the cached value. if (has_def_chain (name)) - return m_def_chain[v]; + return m_def_chain[v].bm; // No definition chain for default defs. if (SSA_NAME_IS_DEFAULT_DEF (name)) - return NULL; + { + // A Default def is always an import. + set_import (m_def_chain[v], name, NULL); + return NULL; + } gimple *stmt = SSA_NAME_DEF_STMT (name); if (gimple_range_handler (stmt)) @@ -205,30 +295,63 @@ range_def_chain::get_def_chain (tree name) ssa3 = gimple_range_ssa_p (gimple_assign_rhs3 (st)); } else - return NULL; - - basic_block bb = gimple_bb (stmt); - - m_def_chain[v] = BITMAP_ALLOC (NULL); + { + // Stmts not understood are always imports. + set_import (m_def_chain[v], name, NULL); + return NULL; + } - if (ssa1) - build_def_chain (ssa1, m_def_chain[v], bb); - if (ssa2) - build_def_chain (ssa2, m_def_chain[v], bb); - if (ssa3) - build_def_chain (ssa3, m_def_chain[v], bb); + register_dependency (name, ssa1, gimple_bb (stmt)); + register_dependency (name, ssa2, gimple_bb (stmt)); + register_dependency (name, ssa3, gimple_bb (stmt)); + // Stmts with no understandable operands are also imports. + if (!ssa1 && !ssa2 & !ssa3) + set_import (m_def_chain[v], name, NULL); if (is_logical) m_logical_depth--; - // If we run into pathological cases where the defintion chains are - // huge (ie huge basic block fully unrolled) we might be able to limit - // this by deciding here that if some criteria is satisfied, we change the - // def_chain back to be just the ssa-names. That will help prevent chains - // of a_2 = b_6 + a_8 from creating a pathological case. - return m_def_chain[v]; + return m_def_chain[v].bm; +} + +// Dump what we know for basic block BB to file F. + +void +range_def_chain::dump (FILE *f, basic_block bb, const char *prefix) +{ + unsigned x, y; + bitmap_iterator bi; + + // Dump the def chain for each SSA_NAME defined in BB. + for (x = 1; x < num_ssa_names; x++) + { + tree name = ssa_name (x); + if (!name) + continue; + gimple *stmt = SSA_NAME_DEF_STMT (name); + if (!stmt || (bb && gimple_bb (stmt) != bb)) + continue; + bitmap chain = (has_def_chain (name) ? get_def_chain (name) : NULL); + if (chain && !bitmap_empty_p (chain)) + { + fprintf (f, prefix); + print_generic_expr (f, name, TDF_SLIM); + fprintf (f, " : "); + + bitmap imports = get_imports (name); + EXECUTE_IF_SET_IN_BITMAP (chain, 0, y, bi) + { + print_generic_expr (f, ssa_name (y), TDF_SLIM); + if (imports && bitmap_bit_p (imports, y)) + fprintf (f, "(I)"); + fprintf (f, " "); + } + fprintf (f, "\n"); + } + } } + // ------------------------------------------------------------------- /* GORI_MAP is used to accumulate what SSA names in a block can @@ -256,7 +379,8 @@ gori_map::gori_map () { m_outgoing.create (0); m_outgoing.safe_grow_cleared (last_basic_block_for_fn (cfun)); - bitmap_obstack_initialize (&m_bitmaps); + m_incoming.create (0); + m_incoming.safe_grow_cleared (last_basic_block_for_fn (cfun)); m_maybe_variant = BITMAP_ALLOC (&m_bitmaps); } @@ -264,7 +388,7 @@ gori_map::gori_map () gori_map::~gori_map () { - bitmap_obstack_release (&m_bitmaps); + m_incoming.release (); m_outgoing.release (); } @@ -273,11 +397,21 @@ gori_map::~gori_map () bitmap gori_map::exports (basic_block bb) { - if (!m_outgoing[bb->index]) + if (bb->index >= (signed int)m_outgoing.length () || !m_outgoing[bb->index]) calculate_gori (bb); return m_outgoing[bb->index]; } +// Return the bitmap vector of all imports to BB. Calculate if necessary. + +bitmap +gori_map::imports (basic_block bb) +{ + if (bb->index >= (signed int)m_outgoing.length () || !m_outgoing[bb->index]) + calculate_gori (bb); + return m_incoming[bb->index]; +} + // Return true if NAME is can have ranges generated for it from basic // block BB. @@ -298,17 +432,13 @@ gori_map::set_range_invariant (tree name) bitmap_clear_bit (m_maybe_variant, SSA_NAME_VERSION (name)); } -// Return true if any element in the def chain of NAME is in the -// export list for BB. +// Return true if NAME is an import to block BB. bool -gori_map::def_chain_in_export_p (tree name, basic_block bb) +gori_map::is_import_p (tree name, basic_block bb) { - bitmap a = exports (bb); - bitmap b = get_def_chain (name); - if (a && b) - return bitmap_intersect_p (a, b); - return false; + // If no BB is specified, test if it is exported anywhere in the IL. + return bitmap_bit_p (imports (bb), SSA_NAME_VERSION (name)); } // If NAME is non-NULL and defined in block BB, calculate the def @@ -319,11 +449,17 @@ gori_map::maybe_add_gori (tree name, basic_block bb) { if (name) { - gimple *s = SSA_NAME_DEF_STMT (name); - bitmap r = get_def_chain (name); - // Check if there is a def chain, and it is in this block. - if (r && gimple_bb (s) == bb) - bitmap_copy (m_outgoing[bb->index], r); + // Check if there is a def chain, regardless of the block. + add_def_chain_to_bitmap (m_outgoing[bb->index], name); + // Check for any imports. + bitmap imp = get_imports (name); + // If there were imports, add them so we can recompute + if (imp) + bitmap_ior_into (m_incoming[bb->index], imp); + // This name is always an import. + if (gimple_bb (SSA_NAME_DEF_STMT (name)) != bb) + bitmap_set_bit (m_incoming[bb->index], SSA_NAME_VERSION (name)); + // Def chain doesn't include itself, and even if there isn't a // def chain, this name should be added to exports. bitmap_set_bit (m_outgoing[bb->index], SSA_NAME_VERSION (name)); @@ -337,9 +473,13 @@ gori_map::calculate_gori (basic_block bb) { tree name; if (bb->index >= (signed int)m_outgoing.length ()) - m_outgoing.safe_grow_cleared (last_basic_block_for_fn (cfun)); + { + m_outgoing.safe_grow_cleared (last_basic_block_for_fn (cfun)); + m_incoming.safe_grow_cleared (last_basic_block_for_fn (cfun)); + } gcc_checking_assert (m_outgoing[bb->index] == NULL); m_outgoing[bb->index] = BITMAP_ALLOC (&m_bitmaps); + m_incoming[bb->index] = BITMAP_ALLOC (&m_bitmaps); // If this block's last statement may generate range informaiton, go // calculate it. @@ -368,65 +508,42 @@ gori_map::calculate_gori (basic_block bb) // Dump the table information for BB to file F. void -gori_map::dump (FILE *f, basic_block bb) +gori_map::dump (FILE *f, basic_block bb, bool verbose) { - bool header = false; - const char *header_string = "bb%-4d "; - const char *header2 = " "; - bool printed_something = false;; - unsigned x, y; - bitmap_iterator bi; - // BB was not processed. - if (!m_outgoing[bb->index]) + if (!m_outgoing[bb->index] || bitmap_empty_p (m_outgoing[bb->index])) return; - // Dump the def chain for each SSA_NAME defined in BB. - for (x = 1; x < num_ssa_names; x++) + tree name; + + bitmap imp = imports (bb); + if (!bitmap_empty_p (imp)) { - tree name = ssa_name (x); - if (!name) - continue; - gimple *stmt = SSA_NAME_DEF_STMT (name); - bitmap chain = (has_def_chain (name) ? get_def_chain (name) : NULL); - if (stmt && gimple_bb (stmt) == bb && chain && !bitmap_empty_p (chain)) - { - fprintf (f, header_string, bb->index); - header_string = header2; - header = true; + if (verbose) + fprintf (f, "bb<%u> Imports: ",bb->index); + else + fprintf (f, "Imports: "); + FOR_EACH_GORI_IMPORT_NAME (*this, bb, name) + { print_generic_expr (f, name, TDF_SLIM); - fprintf (f, " : "); - EXECUTE_IF_SET_IN_BITMAP (chain, 0, y, bi) - { - print_generic_expr (f, ssa_name (y), TDF_SLIM); - fprintf (f, " "); - } - fprintf (f, "\n"); + fprintf (f, " "); } + fputc ('\n', f); } - printed_something |= header; - - // Now dump the export vector. - header = false; - EXECUTE_IF_SET_IN_BITMAP (m_outgoing[bb->index], 0, y, bi) + if (verbose) + fprintf (f, "bb<%u> Exports: ",bb->index); + else + fprintf (f, "Exports: "); + // Dump the export vector. + FOR_EACH_GORI_EXPORT_NAME (*this, bb, name) { - if (!header) - { - fprintf (f, header_string, bb->index); - fprintf (f, "exports: "); - header_string = header2; - header = true; - } - print_generic_expr (f, ssa_name (y), TDF_SLIM); + print_generic_expr (f, name, TDF_SLIM); fprintf (f, " "); } - if (header) - fputc ('\n', f); + fputc ('\n', f); - printed_something |= header; - if (printed_something) - fprintf (f, "\n"); + range_def_chain::dump (f, bb, " "); } // Dump the entire GORI map structure to file F. @@ -436,11 +553,7 @@ gori_map::dump (FILE *f) { basic_block bb; FOR_EACH_BB_FN (bb, cfun) - { - dump (f, bb); - if (m_outgoing[bb->index]) - fprintf (f, "\n"); - } + dump (f, bb); } DEBUG_FUNCTION void @@ -960,8 +1073,7 @@ gori_compute::has_edge_range_p (tree name, edge e) if (!e) return is_export_p (name); - return (is_export_p (name, e->src) - || def_chain_in_export_p (name, e->src)); + return is_export_p (name, e->src); } // Dump what is known to GORI computes to listing file F. @@ -1006,6 +1118,50 @@ gori_compute::outgoing_edge_range_p (irange &r, edge e, tree name) return false; } + +// ------------------------------------------------------------------------ +// GORI iterator. Although we have bitmap iterators, don't expose that it +// is currently a bitmap. Use an export iterator to hide future changes. + +// Construct a basic iterator over an export bitmap. + +gori_export_iterator::gori_export_iterator (bitmap b) +{ + bm = b; + if (b) + bmp_iter_set_init (&bi, b, 1, &y); +} + + +// Move to the next export bitmap spot. + +void +gori_export_iterator::next () +{ + bmp_iter_next (&bi, &y); +} + + +// Fetch the name of the next export in the export list. Return NULL if +// iteration is done. + +tree +gori_export_iterator::get_name () +{ + if (!bm) + return NULL_TREE; + + while (bmp_iter_set (&bi, &y)) + { + tree t = ssa_name (y); + if (t) + return t; + next (); + } + return NULL_TREE; +} + + // -------------------------------------------------------------------------- // Cache for SSAs that appear on the RHS of a boolean assignment. diff --git a/gcc/gimple-range-gori.h b/gcc/gimple-range-gori.h index 6208931..8f44216 100644 --- a/gcc/gimple-range-gori.h +++ b/gcc/gimple-range-gori.h @@ -31,15 +31,55 @@ class range_def_chain public: range_def_chain (); ~range_def_chain (); + tree depend1 (tree name) const; + tree depend2 (tree name) const; + bool in_chain_p (tree name, tree def); + bool chain_import_p (tree name, tree import); + void register_dependency (tree name, tree ssa1, basic_block bb = NULL); + void dump (FILE *f, basic_block bb, const char *prefix = NULL); +protected: bool has_def_chain (tree name); + bool def_chain_in_bitmap_p (tree name, bitmap b); + void add_def_chain_to_bitmap (bitmap b, tree name); bitmap get_def_chain (tree name); - bool in_chain_p (tree name, tree def); + bitmap get_imports (tree name); + bitmap_obstack m_bitmaps; private: - vec m_def_chain; // SSA_NAME : def chain components. - void build_def_chain (tree name, bitmap result, basic_block bb); + struct rdc { + tree ssa1; // First direct dependency + tree ssa2; // Second direct dependency + bitmap bm; // All dependencies + bitmap m_import; + }; + vec m_def_chain; // SSA_NAME : def chain components. + void set_import (struct rdc &data, tree imp, bitmap b); int m_logical_depth; }; +// Return the first direct dependency for NAME, if there is one. +// Direct dependencies are those which occur on the defintion statement. +// Only the first 2 such names are cached. + +inline tree +range_def_chain::depend1 (tree name) const +{ + unsigned v = SSA_NAME_VERSION (name); + if (v >= m_def_chain.length ()) + return NULL_TREE; + return m_def_chain[v].ssa1; +} + +// Return the second direct dependency for NAME, if there is one. + +inline tree +range_def_chain::depend2 (tree name) const +{ + unsigned v = SSA_NAME_VERSION (name); + if (v >= m_def_chain.length ()) + return NULL_TREE; + return m_def_chain[v].ssa2; +} + // GORI_MAP is used to accumulate what SSA names in a block can // generate range information, and provides tools for the block ranger // to enable it to efficiently calculate these ranges. @@ -51,15 +91,16 @@ public: ~gori_map (); bool is_export_p (tree name, basic_block bb = NULL); - bool def_chain_in_export_p (tree name, basic_block bb); + bool is_import_p (tree name, basic_block bb); bitmap exports (basic_block bb); + bitmap imports (basic_block bb); void set_range_invariant (tree name); void dump (FILE *f); - void dump (FILE *f, basic_block bb); + void dump (FILE *f, basic_block bb, bool verbose = true); private: - bitmap_obstack m_bitmaps; vec m_outgoing; // BB: Outgoing ranges calculatable on edges + vec m_incoming; // BB: Incoming ranges which can affect exports. bitmap m_maybe_variant; // Names which might have outgoing ranges. void maybe_add_gori (tree name, basic_block bb); void calculate_gori (basic_block bb); @@ -152,6 +193,30 @@ private: }; +// For each name that is an import into BB's exports.. +#define FOR_EACH_GORI_IMPORT_NAME(gori, bb, name) \ + for (gori_export_iterator iter ((gori).imports ((bb))); \ + ((name) = iter.get_name ()); \ + iter.next ()) + +// For each name possibly exported from block BB. +#define FOR_EACH_GORI_EXPORT_NAME(gori, bb, name) \ + for (gori_export_iterator iter ((gori).exports ((bb))); \ + ((name) = iter.get_name ()); \ + iter.next ()) + +// Used to assist with iterating over the GORI export list in various ways +class gori_export_iterator { +public: + gori_export_iterator (bitmap b); + void next (); + tree get_name (); +protected: + bitmap bm; + bitmap_iterator bi; + unsigned y; +}; + // This class adds a cache to gori_computes for logical expressions. // bool result = x && y // requires calcuation of both X and Y for both true and false results. -- cgit v1.1 From 10b286ce335cca135a45a92581b28146f3e3209b Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Tue, 25 May 2021 14:34:06 -0400 Subject: Unify temporal cache with gori dependencies. Move the temporal cache to strictly be a timestamp, and query GORI for the dependencies rather than trying to register and maintain them. * gimple-range-cache.cc (struct range_timestamp): Delete. (class temporal_cache): Adjust. (temporal_cache::get_timestamp): Delete. (temporal_cache::set_dependency): Delete. (temporal_cache::temporal_value): Adjust. (temporal_cache::current_p): Take dependencies as params. (temporal_cache::set_timestamp): Adjust. (temporal_cache::set_always_current): Adjust. (ranger_cache::get_non_stale_global_range): Adjust. (ranger_cache::register_dependency): Delete. * gimple-range-cache.h (class range_cache): Adjust. --- gcc/gimple-range-cache.cc | 116 +++++++++++++--------------------------------- gcc/gimple-range-cache.h | 1 - 2 files changed, 32 insertions(+), 85 deletions(-) (limited to 'gcc') diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc index 8ad7604..3969c4d 100644 --- a/gcc/gimple-range-cache.cc +++ b/gcc/gimple-range-cache.cc @@ -474,43 +474,28 @@ ssa_global_cache::dump (FILE *f) // -------------------------------------------------------------------------- -// This struct provides a timestamp for a global range calculation. -// it contains the time counter, as well as a limited number of ssa-names -// that it is dependent upon. If the timestamp for any of the dependent names -// Are newer, then this range could need updating. - -struct range_timestamp -{ - unsigned time; - unsigned ssa1; - unsigned ssa2; -}; - // This class will manage the timestamps for each ssa_name. -// When a value is calcualted, its timestamp is set to the current time. -// The ssanames it is dependent on have already been calculated, so they will -// have older times. If one fo those values is ever calculated again, it -// will get a newer timestamp, and the "current_p" check will fail. +// When a value is calculated, the timestamp is set to the current time. +// Current time is then incremented. Any dependencies will already have +// been calculated, and will thus have older timestamps. +// If one of those values is ever calculated again, it will get a newer +// timestamp, and the "current_p" check will fail. class temporal_cache { public: temporal_cache (); ~temporal_cache (); - bool current_p (tree name) const; + bool current_p (tree name, tree dep1, tree dep2) const; void set_timestamp (tree name); - void set_dependency (tree name, tree dep); void set_always_current (tree name); private: unsigned temporal_value (unsigned ssa) const; - const range_timestamp *get_timestamp (unsigned ssa) const; - range_timestamp *get_timestamp (unsigned ssa); unsigned m_current_time; - vec m_timestamp; + vec m_timestamp; }; - inline temporal_cache::temporal_cache () { @@ -525,65 +510,35 @@ temporal_cache::~temporal_cache () m_timestamp.release (); } -// Return a pointer to the timetamp for ssa-name at index SSA, if there is -// one, otherwise return NULL. - -inline const range_timestamp * -temporal_cache::get_timestamp (unsigned ssa) const -{ - if (ssa >= m_timestamp.length ()) - return NULL; - return &(m_timestamp[ssa]); -} - -// Return a reference to the timetamp for ssa-name at index SSA. If the index -// is past the end of the vector, extend the vector. - -inline range_timestamp * -temporal_cache::get_timestamp (unsigned ssa) -{ - if (ssa >= m_timestamp.length ()) - m_timestamp.safe_grow_cleared (num_ssa_names + 20); - return &(m_timestamp[ssa]); -} - -// This routine will fill NAME's next operand slot with DEP if DEP is a valid -// SSA_NAME and there is a free slot. - -inline void -temporal_cache::set_dependency (tree name, tree dep) -{ - if (dep && TREE_CODE (dep) == SSA_NAME) - { - gcc_checking_assert (get_timestamp (SSA_NAME_VERSION (name))); - range_timestamp& ts = *(get_timestamp (SSA_NAME_VERSION (name))); - if (!ts.ssa1) - ts.ssa1 = SSA_NAME_VERSION (dep); - else if (!ts.ssa2 && ts.ssa1 != SSA_NAME_VERSION (name)) - ts.ssa2 = SSA_NAME_VERSION (dep); - } -} - // Return the timestamp value for SSA, or 0 if there isnt one. + inline unsigned temporal_cache::temporal_value (unsigned ssa) const { - const range_timestamp *ts = get_timestamp (ssa); - return ts ? ts->time : 0; + if (ssa >= m_timestamp.length ()) + return 0; + return m_timestamp[ssa]; } // Return TRUE if the timestampe for NAME is newer than any of its dependents. +// Up to 2 dependencies can be checked. bool -temporal_cache::current_p (tree name) const +temporal_cache::current_p (tree name, tree dep1, tree dep2) const { - const range_timestamp *ts = get_timestamp (SSA_NAME_VERSION (name)); - if (!ts || ts->time == 0) + unsigned ts = temporal_value (SSA_NAME_VERSION (name)); + if (ts == 0) return true; + // Any non-registered dependencies will have a value of 0 and thus be older. // Return true if time is newer than either dependent. - return ts->time > temporal_value (ts->ssa1) - && ts->time > temporal_value (ts->ssa2); + + if (dep1 && ts < temporal_value (SSA_NAME_VERSION (dep1))) + return false; + if (dep2 && ts < temporal_value (SSA_NAME_VERSION (dep2))) + return false; + + return true; } // This increments the global timer and sets the timestamp for NAME. @@ -591,8 +546,10 @@ temporal_cache::current_p (tree name) const inline void temporal_cache::set_timestamp (tree name) { - gcc_checking_assert (get_timestamp (SSA_NAME_VERSION (name))); - get_timestamp (SSA_NAME_VERSION (name))->time = ++m_current_time; + unsigned v = SSA_NAME_VERSION (name); + if (v >= m_timestamp.length ()) + m_timestamp.safe_grow_cleared (num_ssa_names + 20); + m_timestamp[v] = ++m_current_time; } // Set the timestamp to 0, marking it as "always up to date". @@ -600,11 +557,12 @@ temporal_cache::set_timestamp (tree name) inline void temporal_cache::set_always_current (tree name) { - gcc_checking_assert (get_timestamp (SSA_NAME_VERSION (name))); - get_timestamp (SSA_NAME_VERSION (name))->time = 0; + unsigned v = SSA_NAME_VERSION (name); + if (v >= m_timestamp.length ()) + m_timestamp.safe_grow_cleared (num_ssa_names + 20); + m_timestamp[v] = 0; } - // -------------------------------------------------------------------------- ranger_cache::ranger_cache (gimple_ranger &q) : query (q) @@ -682,7 +640,7 @@ ranger_cache::get_non_stale_global_range (irange &r, tree name) { if (m_globals.get_global_range (r, name)) { - if (m_temporal->current_p (name)) + if (m_temporal->current_p (name, depend1 (name), depend2 (name))) return true; } else @@ -728,16 +686,6 @@ ranger_cache::set_global_range (tree name, const irange &r) m_temporal->set_timestamp (name); } -// Register a dependency on DEP to name. If the timestamp for DEP is ever -// greateer than the timestamp for NAME, then it is newer and NAMEs value -// becomes stale. - -void -ranger_cache::register_dependency (tree name, tree dep) -{ - m_temporal->set_dependency (name, dep); -} - // Push a request for a new lookup in block BB of name. Return true if // the request is actually made (ie, isn't a duplicate). diff --git a/gcc/gimple-range-cache.h b/gcc/gimple-range-cache.h index 15e6d0c..fe781e0 100644 --- a/gcc/gimple-range-cache.h +++ b/gcc/gimple-range-cache.h @@ -98,7 +98,6 @@ public: bool get_global_range (irange &r, tree name) const; bool get_non_stale_global_range (irange &r, tree name); void set_global_range (tree name, const irange &r); - void register_dependency (tree name, tree dep); non_null_ref m_non_null; -- cgit v1.1 From 35c78c6fc54721e067ed3a30ddd9184b45c5981d Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Tue, 25 May 2021 14:41:16 -0400 Subject: Tweak location of non-null calls. revamp ranger debug output. 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. --- gcc/gimple-range.cc | 149 +++++++++++++++++++++++++--------------------------- gcc/gimple-range.h | 1 + 2 files changed, 74 insertions(+), 76 deletions(-) (limited to 'gcc') diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc index 06e9804..593ddb1 100644 --- a/gcc/gimple-range.cc +++ b/gcc/gimple-range.cc @@ -976,23 +976,16 @@ gimple_ranger::range_of_expr (irange &r, tree expr, gimple *stmt) // If name is defined in this block, try to get an range from S. if (def_stmt && gimple_bb (def_stmt) == bb) - range_of_stmt (r, def_stmt, expr); + { + range_of_stmt (r, def_stmt, expr); + if (!cfun->can_throw_non_call_exceptions && r.varying_p () && + m_cache.m_non_null.non_null_deref_p (expr, bb)) + r = range_nonzero (TREE_TYPE (expr)); + } else // Otherwise OP comes from outside this block, use range on entry. range_on_entry (r, bb, expr); - // No range yet, see if there is a dereference in the block. - // We don't care if it's between the def and a use within a block - // because the entire block must be executed anyway. - // FIXME:?? For non-call exceptions we could have a statement throw - // which causes an early block exit. - // in which case we may need to walk from S back to the def/top of block - // to make sure the deref happens between S and there before claiming - // there is a deref. Punt for now. - if (!cfun->can_throw_non_call_exceptions && r.varying_p () && - m_cache.m_non_null.non_null_deref_p (expr, bb)) - r = range_nonzero (TREE_TYPE (expr)); - return true; } @@ -1010,6 +1003,10 @@ gimple_ranger::range_on_entry (irange &r, basic_block bb, tree name) // Now see if there is any on_entry value which may refine it. if (m_cache.block_range (entry_range, bb, name)) r.intersect (entry_range); + + if (!cfun->can_throw_non_call_exceptions && r.varying_p () && + m_cache.m_non_null.non_null_deref_p (name, bb)) + r = range_nonzero (TREE_TYPE (name)); } // Calculate the range for NAME at the end of block BB and return it in R. @@ -1032,13 +1029,7 @@ gimple_ranger::range_on_exit (irange &r, basic_block bb, tree name) if (s) range_of_expr (r, name, s); else - { - range_on_entry (r, bb, name); - // See if there was a deref in this block, if applicable - if (!cfun->can_throw_non_call_exceptions && r.varying_p () && - m_cache.m_non_null.non_null_deref_p (name, bb)) - r = range_nonzero (TREE_TYPE (name)); - } + range_on_entry (r, bb, name); gcc_checking_assert (r.undefined_p () || range_compatible_p (r.type (), TREE_TYPE (name))); } @@ -1166,80 +1157,86 @@ gimple_ranger::export_global_ranges () // Print the known table values to file F. void -gimple_ranger::dump (FILE *f) +gimple_ranger::dump_bb (FILE *f, basic_block bb) { - basic_block bb; - - FOR_EACH_BB_FN (bb, cfun) - { - unsigned x; - edge_iterator ei; - edge e; - int_range_max range; - fprintf (f, "\n=========== BB %d ============\n", bb->index); - m_cache.dump (f, bb); + unsigned x; + edge_iterator ei; + edge e; + int_range_max range; + fprintf (f, "\n=========== BB %d ============\n", bb->index); + m_cache.dump (f, bb); - dump_bb (f, bb, 4, TDF_NONE); + ::dump_bb (f, bb, 4, TDF_NONE); - // Now find any globals defined in this block. - for (x = 1; x < num_ssa_names; x++) + // Now find any globals defined in this block. + for (x = 1; x < num_ssa_names; x++) + { + tree name = ssa_name (x); + if (gimple_range_ssa_p (name) && SSA_NAME_DEF_STMT (name) && + gimple_bb (SSA_NAME_DEF_STMT (name)) == bb && + m_cache.get_global_range (range, name)) { - tree name = ssa_name (x); - if (gimple_range_ssa_p (name) && SSA_NAME_DEF_STMT (name) && - gimple_bb (SSA_NAME_DEF_STMT (name)) == bb && - m_cache.get_global_range (range, name)) + if (!range.varying_p ()) { - if (!range.varying_p ()) - { - print_generic_expr (f, name, TDF_SLIM); - fprintf (f, " : "); - range.dump (f); - fprintf (f, "\n"); - } - + print_generic_expr (f, name, TDF_SLIM); + fprintf (f, " : "); + range.dump (f); + fprintf (f, "\n"); } + } + } - // And now outgoing edges, if they define anything. - FOR_EACH_EDGE (e, ei, bb->succs) + // And now outgoing edges, if they define anything. + FOR_EACH_EDGE (e, ei, bb->succs) + { + for (x = 1; x < num_ssa_names; x++) { - for (x = 1; x < num_ssa_names; x++) + tree name = gimple_range_ssa_p (ssa_name (x)); + if (name && m_cache.outgoing_edge_range_p (range, e, name)) { - tree name = gimple_range_ssa_p (ssa_name (x)); - if (name && m_cache.outgoing_edge_range_p (range, e, name)) + gimple *s = SSA_NAME_DEF_STMT (name); + // Only print the range if this is the def block, or + // the on entry cache for either end of the edge is + // set. + if ((s && bb == gimple_bb (s)) || + m_cache.block_range (range, bb, name, false) || + m_cache.block_range (range, e->dest, name, false)) { - gimple *s = SSA_NAME_DEF_STMT (name); - // Only print the range if this is the def block, or - // the on entry cache for either end of the edge is - // set. - if ((s && bb == gimple_bb (s)) || - m_cache.block_range (range, bb, name, false) || - m_cache.block_range (range, e->dest, name, false)) + range_on_edge (range, e, name); + if (!range.varying_p ()) { - range_on_edge (range, e, name); - if (!range.varying_p ()) - { - fprintf (f, "%d->%d ", e->src->index, - e->dest->index); - char c = ' '; - if (e->flags & EDGE_TRUE_VALUE) - fprintf (f, " (T)%c", c); - else if (e->flags & EDGE_FALSE_VALUE) - fprintf (f, " (F)%c", c); - else - fprintf (f, " "); - print_generic_expr (f, name, TDF_SLIM); - fprintf(f, " : \t"); - range.dump(f); - fprintf (f, "\n"); - } + fprintf (f, "%d->%d ", e->src->index, + e->dest->index); + char c = ' '; + if (e->flags & EDGE_TRUE_VALUE) + fprintf (f, " (T)%c", c); + else if (e->flags & EDGE_FALSE_VALUE) + fprintf (f, " (F)%c", c); + else + fprintf (f, " "); + print_generic_expr (f, name, TDF_SLIM); + fprintf(f, " : \t"); + range.dump(f); + fprintf (f, "\n"); } } } } } +} + +// Print the known table values to file F. + +void +gimple_ranger::dump (FILE *f) +{ + basic_block bb; + + FOR_EACH_BB_FN (bb, cfun) + dump_bb (f, bb); - m_cache.dump (dump_file, (dump_flags & TDF_DETAILS) != 0); + m_cache.dump (f, false); } // If SCEV has any information about phi node NAME, return it as a range in R. diff --git a/gcc/gimple-range.h b/gcc/gimple-range.h index 5320506..08035a5 100644 --- a/gcc/gimple-range.h +++ b/gcc/gimple-range.h @@ -66,6 +66,7 @@ public: virtual void range_on_exit (irange &r, basic_block bb, tree name); void export_global_ranges (); void dump (FILE *f); + void dump_bb (FILE *f, basic_block bb); protected: bool fold_range_internal (irange &r, gimple *s, tree name); ranger_cache m_cache; -- cgit v1.1 From 2bccd9154e127909a4cdff5c19904a6562fcd0ff Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Tue, 25 May 2021 14:49:40 -0400 Subject: Make expr_range_in_bb stmt based rather than block based. 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. --- gcc/gimple-range-gori.cc | 36 ++++++++++++++++++------------------ gcc/gimple-range-gori.h | 2 +- 2 files changed, 19 insertions(+), 19 deletions(-) (limited to 'gcc') diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc index 94640ad..1a4ae45 100644 --- a/gcc/gimple-range-gori.cc +++ b/gcc/gimple-range-gori.cc @@ -582,10 +582,10 @@ gori_compute::ssa_range_in_bb (irange &r, tree name, basic_block) } void -gori_compute::expr_range_in_bb (irange &r, tree expr, basic_block bb) +gori_compute::expr_range_at_stmt (irange &r, tree expr, gimple *s) { if (gimple_range_ssa_p (expr)) - ssa_range_in_bb (r, expr, bb); + ssa_range_in_bb (r, expr, gimple_bb (s)); else get_tree_range (r, expr); } @@ -606,7 +606,7 @@ gori_compute::compute_name_range_op (irange &r, gimple *stmt, // Operand 1 is the name being looked for, evaluate it. if (op1 == name) { - expr_range_in_bb (op1_range, op1, gimple_bb (stmt)); + expr_range_at_stmt (op1_range, op1, stmt); if (!op2) { // The second parameter to a unary operation is the range @@ -616,7 +616,7 @@ gori_compute::compute_name_range_op (irange &r, gimple *stmt, return gimple_range_calc_op1 (r, stmt, lhs, op1_range); } // If we need the second operand, get a value and evaluate. - expr_range_in_bb (op2_range, op2, gimple_bb (stmt)); + expr_range_at_stmt (op2_range, op2, stmt); if (gimple_range_calc_op1 (r, stmt, lhs, op2_range)) r.intersect (op1_range); else @@ -626,8 +626,8 @@ gori_compute::compute_name_range_op (irange &r, gimple *stmt, if (op2 == name) { - expr_range_in_bb (op1_range, op1, gimple_bb (stmt)); - expr_range_in_bb (r, op2, gimple_bb (stmt)); + expr_range_at_stmt (op1_range, op1, stmt); + expr_range_at_stmt (r, op2, stmt); if (gimple_range_calc_op2 (op2_range, stmt, lhs, op1_range)) r.intersect (op2_range); return true; @@ -877,7 +877,7 @@ gori_compute::optimize_logical_operands (tf_range &range, { if (!compute_operand_range (range.false_range, SSA_NAME_DEF_STMT (op), m_bool_zero, name)) - expr_range_in_bb (range.false_range, name, gimple_bb (stmt)); + expr_range_at_stmt (range.false_range, name, stmt); range.true_range = range.false_range; return true; } @@ -886,7 +886,7 @@ gori_compute::optimize_logical_operands (tf_range &range, { if (!compute_operand_range (range.true_range, SSA_NAME_DEF_STMT (op), m_bool_one, name)) - expr_range_in_bb (range.true_range, name, gimple_bb (stmt)); + expr_range_at_stmt (range.true_range, name, stmt); range.false_range = range.true_range; return true; } @@ -905,12 +905,12 @@ gori_compute::compute_logical_operands_in_chain (tf_range &range, tree op, bool op_in_chain) { gimple *src_stmt = gimple_range_ssa_p (op) ? SSA_NAME_DEF_STMT (op) : NULL; - basic_block bb = gimple_bb (stmt); - if (!op_in_chain || (src_stmt != NULL && bb != gimple_bb (src_stmt))) + if (!op_in_chain || (src_stmt != NULL + && gimple_bb (stmt) != gimple_bb (src_stmt))) { // If op is not in the def chain, or defined in this block, // use its known value on entry to the block. - expr_range_in_bb (range.true_range, name, gimple_bb (stmt)); + expr_range_at_stmt (range.true_range, name, stmt); range.false_range = range.true_range; return; } @@ -920,9 +920,9 @@ gori_compute::compute_logical_operands_in_chain (tf_range &range, // Calculate ranges for true and false on both sides, since the false // path is not always a simple inversion of the true side. if (!compute_operand_range (range.true_range, src_stmt, m_bool_one, name)) - expr_range_in_bb (range.true_range, name, bb); + expr_range_at_stmt (range.true_range, name, stmt); if (!compute_operand_range (range.false_range, src_stmt, m_bool_zero, name)) - expr_range_in_bb (range.false_range, name, bb); + expr_range_at_stmt (range.false_range, name, stmt); } // Given a logical STMT, calculate true and false for each potential @@ -968,12 +968,12 @@ gori_compute::compute_operand1_range (irange &r, gimple *stmt, tree op1 = gimple_range_operand1 (stmt); tree op2 = gimple_range_operand2 (stmt); - expr_range_in_bb (op1_range, op1, gimple_bb (stmt)); + expr_range_at_stmt (op1_range, op1, stmt); // Now calcuated the operand and put that result in r. if (op2) { - expr_range_in_bb (op2_range, op2, gimple_bb (stmt)); + expr_range_at_stmt (op2_range, op2, stmt); if (!gimple_range_calc_op1 (r, stmt, lhs, op2_range)) return false; } @@ -1015,8 +1015,8 @@ gori_compute::compute_operand2_range (irange &r, gimple *stmt, tree op1 = gimple_range_operand1 (stmt); tree op2 = gimple_range_operand2 (stmt); - expr_range_in_bb (op1_range, op1, gimple_bb (stmt)); - expr_range_in_bb (op2_range, op2, gimple_bb (stmt)); + expr_range_at_stmt (op1_range, op1, stmt); + expr_range_at_stmt (op2_range, op2, stmt); // Intersect with range for op2 based on lhs and op1. if (!gimple_range_calc_op2 (r, stmt, lhs, op1_range)) @@ -1449,7 +1449,7 @@ gori_compute_cache::cache_stmt (gimple *stmt) { range_operator *handler = range_op_handler (code, TREE_TYPE (lhs)); int_range_max op2_range; - expr_range_in_bb (op2_range, op2, gimple_bb (stmt)); + expr_range_at_stmt (op2_range, op2, stmt); tree type = TREE_TYPE (op1); handler->op1_range (r_true_side, type, m_bool_one, op2_range); handler->op1_range (r_false_side, type, m_bool_zero, op2_range); diff --git a/gcc/gimple-range-gori.h b/gcc/gimple-range-gori.h index 8f44216..8a85d6a 100644 --- a/gcc/gimple-range-gori.h +++ b/gcc/gimple-range-gori.h @@ -161,7 +161,7 @@ protected: virtual bool compute_operand_range (irange &r, gimple *stmt, const irange &lhs, tree name); - void expr_range_in_bb (irange &r, tree expr, basic_block bb); + void expr_range_at_stmt (irange &r, tree expr, gimple *s); bool compute_logical_operands (irange &r, gimple *stmt, const irange &lhs, tree name); -- cgit v1.1 From f630797a1ed2f82faf965a47b43b5f995bc6623a Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Tue, 25 May 2021 14:55:04 -0400 Subject: Adjust fur_source internal api to use gori_compute not ranger_cache. 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. --- gcc/gimple-range.cc | 18 +++++++++--------- gcc/gimple-range.h | 12 ++++++------ 2 files changed, 15 insertions(+), 15 deletions(-) (limited to 'gcc') diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc index 593ddb1..e2d24d6 100644 --- a/gcc/gimple-range.cc +++ b/gcc/gimple-range.cc @@ -435,17 +435,17 @@ fold_using_range::range_of_range_op (irange &r, gimple *s, fur_source &src) // Fold range, and register any dependency if available. int_range<2> r2 (type); handler->fold_range (r, type, range1, r2); - if (lhs && src.m_cache) - src.m_cache->register_dependency (lhs, op1); + if (lhs && src.m_gori) + src.m_gori->register_dependency (lhs, op1); } else if (src.get_operand (range2, op2)) { // Fold range, and register any dependency if available. handler->fold_range (r, type, range1, range2); - if (lhs && src.m_cache) + if (lhs && src.m_gori) { - src.m_cache->register_dependency (lhs, op1); - src.m_cache->register_dependency (lhs, op2); + src.m_gori->register_dependency (lhs, op1); + src.m_gori->register_dependency (lhs, op2); } } else @@ -485,8 +485,8 @@ fold_using_range::range_of_address (irange &r, gimple *stmt, fur_source &src) { tree ssa = TREE_OPERAND (base, 0); tree lhs = gimple_get_lhs (stmt); - if (src.m_cache && lhs && gimple_range_ssa_p (ssa)) - src.m_cache->register_dependency (lhs, ssa); + if (src.m_gori && lhs && gimple_range_ssa_p (ssa)) + src.m_gori->register_dependency (lhs, ssa); gcc_checking_assert (irange::supports_type_p (TREE_TYPE (ssa))); src.get_operand (r, ssa); range_cast (r, TREE_TYPE (gimple_assign_rhs1 (stmt))); @@ -563,8 +563,8 @@ fold_using_range::range_of_phi (irange &r, gphi *phi, fur_source &src) edge e = gimple_phi_arg_edge (phi, x); // Register potential dependencies for stale value tracking. - if (src.m_cache && gimple_range_ssa_p (arg)) - src.m_cache->register_dependency (phi_def, arg); + if (src.m_gori && gimple_range_ssa_p (arg)) + src.m_gori->register_dependency (phi_def, arg); // Get the range of the argument on its edge. fur_source e_src (src.m_query, e); diff --git a/gcc/gimple-range.h b/gcc/gimple-range.h index 08035a5..707dcfe 100644 --- a/gcc/gimple-range.h +++ b/gcc/gimple-range.h @@ -84,10 +84,10 @@ class fur_source public: inline fur_source (range_query *q, edge e); inline fur_source (range_query *q, gimple *s); - inline fur_source (range_query *q, class ranger_cache *g, edge e, gimple *s); + inline fur_source (range_query *q, gori_compute *g, edge e, gimple *s); bool get_operand (irange &r, tree expr); protected: - ranger_cache *m_cache; + gori_compute *m_gori; range_query *m_query; edge m_edge; gimple *m_stmt; @@ -124,7 +124,7 @@ inline fur_source::fur_source (range_query *q, edge e) { m_query = q; - m_cache = NULL; + m_gori = NULL; m_edge = e; m_stmt = NULL; } @@ -135,7 +135,7 @@ inline fur_source::fur_source (range_query *q, gimple *s) { m_query = q; - m_cache = NULL; + m_gori = NULL; m_edge = NULL; m_stmt = s; } @@ -144,10 +144,10 @@ fur_source::fur_source (range_query *q, gimple *s) // and can also set the dependency information as appropriate when invoked. inline -fur_source::fur_source (range_query *q, ranger_cache *g, edge e, gimple *s) +fur_source::fur_source (range_query *q, gori_compute *g, edge e, gimple *s) { m_query = q; - m_cache = g; + m_gori = g; m_edge = e; m_stmt = s; } -- cgit v1.1 From a6e94287d31525b3ad0963ad22a92e9f3dbcd3cf Mon Sep 17 00:00:00 2001 From: Andrew MacLeod Date: Tue, 25 May 2021 14:59:54 -0400 Subject: Remove the logical stmt cache for now. 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. --- gcc/gimple-range-gori.cc | 311 ----------------------------------------------- gcc/gimple-range-gori.h | 31 +---- 2 files changed, 2 insertions(+), 340 deletions(-) (limited to 'gcc') diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc index 1a4ae45..a4c4bf5 100644 --- a/gcc/gimple-range-gori.cc +++ b/gcc/gimple-range-gori.cc @@ -1160,314 +1160,3 @@ gori_export_iterator::get_name () } return NULL_TREE; } - - -// -------------------------------------------------------------------------- - -// Cache for SSAs that appear on the RHS of a boolean assignment. -// -// Boolean assignments of logical expressions (i.e. LHS = j_5 > 999) -// have SSA operands whose range depend on the LHS of the assigment. -// That is, the range of j_5 when LHS is true is different than when -// LHS is false. -// -// This class caches the TRUE/FALSE ranges of such SSAs to avoid -// recomputing. - -class logical_stmt_cache -{ -public: - logical_stmt_cache (); - ~logical_stmt_cache (); - void set_range (tree lhs, tree name, const tf_range &); - bool get_range (tf_range &r, tree lhs, tree name) const; - bool cacheable_p (gimple *, const irange *lhs_range = NULL) const; - void dump (FILE *, gimple *stmt) const; - tree same_cached_name (tree lhs1, tree lh2) const; -private: - tree cached_name (tree lhs) const; - void slot_diagnostics (tree lhs, const tf_range &range) const; - struct cache_entry - { - cache_entry (tree name, const irange &t_range, const irange &f_range); - void dump (FILE *out) const; - tree name; - tf_range range; - }; - vec m_ssa_cache; -}; - -logical_stmt_cache::cache_entry::cache_entry (tree name, - const irange &t_range, - const irange &f_range) - : name (name), range (t_range, f_range) -{ -} - -logical_stmt_cache::logical_stmt_cache () -{ - m_ssa_cache.create (num_ssa_names + num_ssa_names / 10); - m_ssa_cache.safe_grow_cleared (num_ssa_names); -} - -logical_stmt_cache::~logical_stmt_cache () -{ - for (unsigned i = 0; i < m_ssa_cache.length (); ++i) - if (m_ssa_cache[i]) - delete m_ssa_cache[i]; - m_ssa_cache.release (); -} - -// Dump cache_entry to OUT. - -void -logical_stmt_cache::cache_entry::dump (FILE *out) const -{ - fprintf (out, "name="); - print_generic_expr (out, name, TDF_SLIM); - fprintf (out, " "); - range.true_range.dump (out); - fprintf (out, ", "); - range.false_range.dump (out); - fprintf (out, "\n"); -} - -// Update range for cache entry of NAME as it appears in the defining -// statement of LHS. - -void -logical_stmt_cache::set_range (tree lhs, tree name, const tf_range &range) -{ - unsigned version = SSA_NAME_VERSION (lhs); - if (version >= m_ssa_cache.length ()) - m_ssa_cache.safe_grow_cleared (num_ssa_names + num_ssa_names / 10); - - cache_entry *slot = m_ssa_cache[version]; - slot_diagnostics (lhs, range); - if (slot) - { - // The IL must have changed. Update the carried SSA name for - // consistency. Testcase is libgomp.fortran/doacross1.f90. - if (slot->name != name) - slot->name = name; - return; - } - m_ssa_cache[version] - = new cache_entry (name, range.true_range, range.false_range); -} - -// If there is a cached entry of NAME, set it in R and return TRUE, -// otherwise return FALSE. LHS is the defining statement where NAME -// appeared. - -bool -logical_stmt_cache::get_range (tf_range &r, tree lhs, tree name) const -{ - gcc_checking_assert (cacheable_p (SSA_NAME_DEF_STMT (lhs))); - if (cached_name (lhs) == name) - { - unsigned version = SSA_NAME_VERSION (lhs); - if (m_ssa_cache[version]) - { - r = m_ssa_cache[version]->range; - return true; - } - } - return false; -} - -// If the defining statement of LHS is in the cache, return the SSA -// operand being cached. That is, return SSA for LHS = SSA .RELOP. OP2. - -tree -logical_stmt_cache::cached_name (tree lhs) const -{ - unsigned version = SSA_NAME_VERSION (lhs); - - if (version >= m_ssa_cache.length ()) - return NULL; - - if (m_ssa_cache[version]) - return m_ssa_cache[version]->name; - return NULL; -} - -// Return TRUE if the cached name for LHS1 is the same as the -// cached name for LHS2. - -tree -logical_stmt_cache::same_cached_name (tree lhs1, tree lhs2) const -{ - tree name = cached_name (lhs1); - if (name && name == cached_name (lhs2)) - return name; - return NULL; -} - -// Return TRUE if STMT is a statement we are interested in caching. -// LHS_RANGE is any known range for the LHS of STMT. - -bool -logical_stmt_cache::cacheable_p (gimple *stmt, const irange *lhs_range) const -{ - if (gimple_code (stmt) == GIMPLE_ASSIGN - && types_compatible_p (TREE_TYPE (gimple_assign_lhs (stmt)), - boolean_type_node) - && TREE_CODE (gimple_assign_rhs1 (stmt)) == SSA_NAME) - { - switch (gimple_expr_code (stmt)) - { - case TRUTH_AND_EXPR: - case BIT_AND_EXPR: - case TRUTH_OR_EXPR: - case BIT_IOR_EXPR: - return !lhs_range || range_is_either_true_or_false (*lhs_range); - default: - return false; - } - } - return false; -} - -// Output debugging diagnostics for the cache entry for LHS. RANGE is -// the new range that is being cached. - -void -logical_stmt_cache::slot_diagnostics (tree lhs, const tf_range &range) const -{ - gimple *stmt = SSA_NAME_DEF_STMT (lhs); - unsigned version = SSA_NAME_VERSION (lhs); - cache_entry *slot = m_ssa_cache[version]; - - if (!slot) - { - if (DEBUG_RANGE_CACHE) - { - fprintf (dump_file ? dump_file : stderr, "registering range for: "); - dump (dump_file ? dump_file : stderr, stmt); - } - return; - } - if (DEBUG_RANGE_CACHE) - fprintf (dump_file ? dump_file : stderr, - "reusing range for SSA #%d\n", version); - if (CHECKING_P && (slot->range.true_range != range.true_range - || slot->range.false_range != range.false_range)) - { - fprintf (stderr, "FATAL: range altered for cached: "); - dump (stderr, stmt); - fprintf (stderr, "Attempt to change to:\n"); - fprintf (stderr, "TRUE="); - range.true_range.dump (stderr); - fprintf (stderr, ", FALSE="); - range.false_range.dump (stderr); - fprintf (stderr, "\n"); - gcc_unreachable (); - } -} - -// Dump the cache information for STMT. - -void -logical_stmt_cache::dump (FILE *out, gimple *stmt) const -{ - tree lhs = gimple_assign_lhs (stmt); - cache_entry *entry = m_ssa_cache[SSA_NAME_VERSION (lhs)]; - - print_gimple_stmt (out, stmt, 0, TDF_SLIM); - if (entry) - { - fprintf (out, "\tname = "); - print_generic_expr (out, entry->name); - fprintf (out, " lhs(%d)= ", SSA_NAME_VERSION (lhs)); - print_generic_expr (out, lhs); - fprintf (out, "\n\tTRUE="); - entry->range.true_range.dump (out); - fprintf (out, ", FALSE="); - entry->range.false_range.dump (out); - fprintf (out, "\n"); - } - else - fprintf (out, "[EMPTY]\n"); -} - -gori_compute_cache::gori_compute_cache () -{ - m_cache = new logical_stmt_cache; -} - -gori_compute_cache::~gori_compute_cache () -{ - delete m_cache; -} - -// Caching version of compute_operand_range. If NAME, as it appears -// in STMT, has already been cached return it from the cache, -// otherwise compute the operand range as normal and cache it. - -bool -gori_compute_cache::compute_operand_range (irange &r, gimple *stmt, - const irange &lhs_range, tree name) -{ - bool cacheable = m_cache->cacheable_p (stmt, &lhs_range); - if (cacheable) - { - tree lhs = gimple_assign_lhs (stmt); - tf_range range; - if (m_cache->get_range (range, lhs, name)) - { - if (lhs_range.zero_p ()) - r = range.false_range; - else - r = range.true_range; - return true; - } - } - if (super::compute_operand_range (r, stmt, lhs_range, name)) - { - if (cacheable) - cache_stmt (stmt); - return true; - } - return false; -} - -// Cache STMT if possible. - -void -gori_compute_cache::cache_stmt (gimple *stmt) -{ - gcc_checking_assert (m_cache->cacheable_p (stmt)); - enum tree_code code = gimple_expr_code (stmt); - tree lhs = gimple_assign_lhs (stmt); - tree op1 = gimple_range_operand1 (stmt); - tree op2 = gimple_range_operand2 (stmt); - int_range_max r_true_side, r_false_side; - - // LHS = s_5 && 999. - if (TREE_CODE (op2) == INTEGER_CST) - { - range_operator *handler = range_op_handler (code, TREE_TYPE (lhs)); - int_range_max op2_range; - expr_range_at_stmt (op2_range, op2, stmt); - tree type = TREE_TYPE (op1); - handler->op1_range (r_true_side, type, m_bool_one, op2_range); - handler->op1_range (r_false_side, type, m_bool_zero, op2_range); - m_cache->set_range (lhs, op1, tf_range (r_true_side, r_false_side)); - } - // LHS = s_5 && b_8. - else if (tree cached_name = m_cache->same_cached_name (op1, op2)) - { - tf_range op1_range, op2_range; - bool ok = m_cache->get_range (op1_range, op1, cached_name); - ok = ok && m_cache->get_range (op2_range, op2, cached_name); - ok = ok && logical_combine (r_true_side, code, m_bool_one, - op1_range, op2_range); - ok = ok && logical_combine (r_false_side, code, m_bool_zero, - op1_range, op2_range); - gcc_checking_assert (ok); - if (ok) - m_cache->set_range (lhs, cached_name, - tf_range (r_true_side, r_false_side)); - } -} diff --git a/gcc/gimple-range-gori.h b/gcc/gimple-range-gori.h index 8a85d6a..f41dee3 100644 --- a/gcc/gimple-range-gori.h +++ b/gcc/gimple-range-gori.h @@ -158,8 +158,8 @@ public: void dump (FILE *f); protected: virtual void ssa_range_in_bb (irange &r, tree name, basic_block bb); - virtual bool compute_operand_range (irange &r, gimple *stmt, - const irange &lhs, tree name); + bool compute_operand_range (irange &r, gimple *stmt, + const irange &lhs, tree name); void expr_range_at_stmt (irange &r, tree expr, gimple *s); bool compute_logical_operands (irange &r, gimple *stmt, @@ -217,31 +217,4 @@ protected: unsigned y; }; -// This class adds a cache to gori_computes for logical expressions. -// bool result = x && y -// requires calcuation of both X and Y for both true and false results. -// There are 4 combinations [0,0][0,0] [0,0][1,1] [1,1][0,0] and [1,1][1,1]. -// Note that each pair of possible results for X and Y are used twice, and -// the calcuation of those results are the same each time. -// -// The cache simply checks if a stmt is cachable, and if so, saves both the -// true and false results for the next time the query is made. -// -// This is used to speed up long chains of logical operations which -// quickly become exponential. - -class gori_compute_cache : public gori_compute -{ -public: - gori_compute_cache (); - ~gori_compute_cache (); -protected: - virtual bool compute_operand_range (irange &r, gimple *stmt, - const irange &lhs, tree name); -private: - void cache_stmt (gimple *); - typedef gori_compute super; - class logical_stmt_cache *m_cache; -}; - #endif // GCC_GIMPLE_RANGE_GORI_H -- cgit v1.1 From 2bc6dacecb2ba60f1f06f310c6887a26b09cdba8 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Wed, 26 May 2021 00:16:41 +0000 Subject: Daily bump. --- gcc/ChangeLog | 294 ++++++++++++++++++++++++++++++++++++++++++++++++ gcc/DATESTAMP | 2 +- gcc/ada/ChangeLog | 4 + gcc/c-family/ChangeLog | 20 ++++ gcc/cp/ChangeLog | 7 ++ gcc/fortran/ChangeLog | 6 + gcc/testsuite/ChangeLog | 62 ++++++++++ 7 files changed, 394 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d3c90e2..897c704 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,297 @@ +2021-05-25 Andrew MacLeod + + * 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. + +2021-05-25 Andrew MacLeod + + * 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. + +2021-05-25 Andrew MacLeod + + * 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. + +2021-05-25 Andrew MacLeod + + * 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. + +2021-05-25 Andrew MacLeod + + * gimple-range-cache.cc (struct range_timestamp): Delete. + (class temporal_cache): Adjust. + (temporal_cache::get_timestamp): Delete. + (temporal_cache::set_dependency): Delete. + (temporal_cache::temporal_value): Adjust. + (temporal_cache::current_p): Take dependencies as params. + (temporal_cache::set_timestamp): Adjust. + (temporal_cache::set_always_current): Adjust. + (ranger_cache::get_non_stale_global_range): Adjust. + (ranger_cache::register_dependency): Delete. + * gimple-range-cache.h (class range_cache): Adjust. + +2021-05-25 Andrew MacLeod + + * 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. + +2021-05-25 Andrew MacLeod + + * 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. + +2021-05-25 Andrew MacLeod + + * 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. + +2021-05-25 Aldy Hernandez + + * value-range.cc (range_tests_legacy): Use + build_nonstandard_integer_type instead of int and short. + +2021-05-25 Eric Botcazou + + * gimplify.c (gimplify_decl_expr): Clear TREE_READONLY on the DECL + when really creating an initialization statement for it. + +2021-05-25 Eric Botcazou + + * tree-inline.c (setup_one_parameter): Fix thinko in new condition. + +2021-05-25 Kito Cheng + + * config/riscv/riscv.h (ASM_SPEC): Pass -mno-relax. + +2021-05-25 Martin Liska + + PR tree-optimization/92860 + PR target/99592 + * optc-save-gen.awk: Remove exceptions. + +2021-05-25 Martin Liska + + * asan.h (sanitize_coverage_p): New function. + * doc/extend.texi: Document it. + * fold-const.c (fold_range_test): Use sanitize_flags_p + instead of flag_sanitize_coverage. + (fold_truth_andor): Likewise. + * sancov.c: Likewise. + * tree-ssa-ifcombine.c (ifcombine_ifandif): Likewise. + * ipa-inline.c (sanitize_attrs_match_for_inline_p): Handle + -fsanitize-coverage when inlining. + +2021-05-25 Cooper Qu + + * config/csky/csky-modes.def : Fix copyright. + +2021-05-25 Cooper Qu + + * config/csky/csky-modes.def : Amend copyright. + * config/csky/csky_insn_fpuv2.md : Likewise. + * config/csky/csky_insn_fpuv3.md : Likewise. + +2021-05-25 Richard Biener + + PR middle-end/100727 + * calls.c (initialize_argument_information): Explicitely test + for WITH_SIZE_EXPR. + * gimple-expr.c (mark_addressable): Skip outer WITH_SIZE_EXPR. + +2021-05-25 Geng Qi + + * config/csky/csky.h (FRAME_POINTER_REGNUM): Use + HARD_FRAME_POINTER_REGNUM and FRAME_POINTER_REGNUM instead of + the signle definition. The signle definition may not work well + at simplify_subreg_regno(). + (HARD_FRAME_POINTER_REGNUM): New. + (ELIMINABLE_REGS): Add for HARD_FRAME_POINTER_REGNUM. + * config/csky/csky.c (get_csky_live_regs, csky_can_eliminate, + csky_initial_elimination_offset, csky_expand_prologue, + csky_expand_epilogue): Add for HARD_FRAME_POINTER_REGNUM. + +2021-05-25 Geng Qi + + * config/csky/csky.c (csky_option_override): + Init csky_arch_isa_features[] in advance, so TARGET_DSP + and TARGET_DIV can be set well. + +2021-05-25 Geng Qi + + * config/csky/constraints.md ("l", "h"): Delete. + * config/csky/csky.h (reg_class, REG_CLASS_NAMES, + REG_CLASS_CONTENTS): Delete LO_REGS and HI_REGS. + * config/csky/csky.c (regno_reg_classm, + csky_secondary_reload, csky_register_move_cost): + Use HILO_REGS instead of LO_REGS and HI_REGS. + +2021-05-25 Geng Qi + + * config/csky/constraints.md ("W"): New constriant for mem operand + with base reg, index register. + ("Q"): Renamed and modified "csky_valid_fpuv2_mem_operand" to + "csky_valid_mem_constraint_operand" to deal with both "Q" and "W" + constraint. + ("Dv"): New constraint for const double value that can be used at + fmovi instruction. + * config/csky/csky-modes.def (HFmode): New mode. + * config/csky/csky-protos.h (csky_valid_fpuv2_mem_operand): Rename + to "csky_valid_mem_constraint_operand" and support new constraint + "W". + (csky_get_movedouble_length): New. + (fpuv3_output_move): New. + (fpuv3_const_double): New. + * config/csky/csky.c (csky_option_override): New arch CK860 with fpv3. + (decompose_csky_address): Refine. + (csky_print_operand): New "CONST_DOUBLE" operand. + (csky_output_move): Support fpv3 instructions. + (csky_get_movedouble_length): New. + (fpuv3_output_move): New. + (fpuv3_const_double): New. + (csky_emit_compare): Cover float comparsion. + (csky_emit_compare_float): Refine. + (csky_vaild_fpuv2_mem_operand): Rename to + "csky_valid_mem_constraint_operand" and support new constraint "W". + (ck860_rtx_costs): New. + (csky_rtx_costs): Add the cost calculation of CK860. + (regno_reg_class): New vregs for fpuv3. + (csky_dbx_regno): Likewise. + (csky_cpu_cpp_builtins): New builtin macro for fpuv3. + (csky_conditional_register_usage): Suporrot fpuv3. + (csky_dwarf_register_span): Suporrot fpuv3. + (csky_init_builtins, csky_mangle_type): Support "__fp16" type. + (ck810_legitimate_index_p): Support fp16. + * config/csky/csky.h (TARGET_TLS): ADD CK860. + (CSKY_VREG_P, CSKY_VREG_LO_P, CSKY_VREG_HI_P): Support fpuv3. + (TARGET_SINGLE_FPU): Support fpuv3. + (TARGET_SUPPORT_FPV3): New. + (FIRST_PSEUDO_REGISTER): Change to 202 to hold the new fpuv3 registers. + (FIXED_REGISTERS, CALL_REALLY_USED_REGISTERS, REGISTER_NAMES, + REG_CLASS_CONTENTS): Support fpuv3. + * config/csky/csky.md (movsf): Move to cksy_insn_fpu.md and refine. + (csky_movsf_fpv2): Likewise. + (ck801_movsf): Likewise. + (csky_movsf): Likewise. + (movdf): Likewise. + (csky_movdf_fpv2): Likewise. + (ck801_movdf): Likewise. + (csky_movdf): Likewise. + (movsicc): Refine. Use "comparison_operatior" instead of + "ordered_comparison_operatior". + (addsicc): Likewise. + (CSKY_FIRST_VFP3_REGNUM, CSKY_LAST_VFP3_REGNUM): New constant. + (call_value_internal_vh): New. + * config/csky/csky_cores.def (CK860): New arch and cpu. + (fpv3_hf): New. + (fpv3_hsf): New. + (fpv3_sdf): New. + (fpv3): New. + * config/csky/csky_insn_fpu.md: Refactor. Separate all float patterns + into emit-patterns and match-patterns, remain the emit-patterns here, + and move the match-patterns to csky_insn_fpuv2.md or + csky_insn_fpuv3.md. + * config/csky/csky_insn_fpuv2.md: New file for fpuv2 instructions. + * config/csky/csky_insn_fpuv3.md: New file and new patterns for fpuv3 + isntructions. + * config/csky/csky_isa.def (fcr): New. + (fpv3_hi): New. + (fpv3_hf): New. + (fpv3_sf): New. + (fpv3_df): New. + (CK860): New definition for ck860. + * config/csky/csky_tables.opt (ck860): New processors ck860, + ck860f. And new arch ck860. + (fpv3_hf): New. + (fpv3_hsf): New. + (fpv3_hdf): New. + (fpv3): New. + * config/csky/predicates.md (csky_float_comparsion_operator): Delete + "geu", "gtu", "leu", "ltu", which will never appear at float comparison. + * config/csky/t-csky-elf: Support 860. + * config/csky/t-csky-linux: Likewise. + * doc/md.texi: Add "Q" and "W" constraints for C-SKY. + 2021-05-24 Aaron Sawdey * config/rs6000/genfusion.pl (gen_logical_addsubf): Refactor to diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index e64bfab..f3c7e4f 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20210525 +20210526 diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index b5ba177..14a8c58 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,7 @@ +2021-05-25 Martin Liska + + * doc/share/conf.py: Fix Sphinx 4.0.x error. + 2021-05-21 Piotr Trojanek * gcc-interface/trans.c (Raise_Error_to_gnu): Add an assertion. diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 43d4c5e..28544c7 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,23 @@ +2021-05-25 Martin Liska + + PR tree-optimization/92860 + PR target/99592 + * c-attribs.c (handle_optimize_attribute): Save target node + before calling parse_optimize_options and save it in case + it changes. + * c-pragma.c (handle_pragma_target): Similarly for pragma. + (handle_pragma_pop_options): Likewise here. + +2021-05-25 Martin Liska + + * c-attribs.c (handle_no_sanitize_coverage_attribute): New. + +2021-05-25 Jakub Jelinek + + PR middle-end/99928 + * c-omp.c (c_omp_split_clauses): Copy reduction to teams when teams is + combined with simd and not with taskloop or for. + 2021-05-21 Jakub Jelinek PR middle-end/99928 diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2eb793e..1cbd043 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2021-05-25 Jakub Jelinek + + PR c++/100666 + * call.c (convert_arg_to_ellipsis): For expressions with NULLPTR_TYPE + and side-effects, temporarily disable -Wunused-result warning when + building COMPOUND_EXPR. + 2021-05-21 Jakub Jelinek PR middle-end/99928 diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index e614039..b30db1c 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,9 @@ +2021-05-25 Tobias Burnus + Johannes Nendwich + + * intrinsic.texi (GERROR, GETARGS, GETLOG, NORM2, PARITY, RANDOM_INIT, + RANDOM_NUMBER): Fix typos and copy'n'paste errors. + 2021-05-24 Tobias Burnus PR fortran/86470 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 00550f6..72d4f58 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,65 @@ +2021-05-25 Jakub Jelinek + + PR c++/100666 + * g++.dg/cpp1z/nodiscard8.C: New test. + * g++.dg/cpp1z/nodiscard9.C: New test. + +2021-05-25 Martin Liska + + * gcc.dg/sancov/attribute.c: New test. + +2021-05-25 Cooper Qu + + * gcc.target/csky/fpuv3/fpuv3.exp : Amend copyright. + +2021-05-25 Jakub Jelinek + + PR middle-end/99928 + * c-c++-common/gomp/pr99928-8.c: Remove xfails from omp teams r21 and + r28 checks. + * c-c++-common/gomp/pr99928-9.c: Likewise. + * c-c++-common/gomp/pr99928-10.c: Likewise. + +2021-05-25 Geng Qi + + * gcc.target/csky/fpuv3/fpuv3.exp: New. + * gcc.target/csky/fpuv3/fpv3_div.c: New. + * gcc.target/csky/fpuv3/fpv3_fadd.c: New. + * gcc.target/csky/fpuv3/fpv3_fdtos.c: New. + * gcc.target/csky/fpuv3/fpv3_fftoi_rm.c: New. + * gcc.target/csky/fpuv3/fpv3_fftoi_rz.c: New. + * gcc.target/csky/fpuv3/fpv3_fhtos.c: New. + * gcc.target/csky/fpuv3/fpv3_fitof.c: New. + * gcc.target/csky/fpuv3/fpv3_fmov.c: New. + * gcc.target/csky/fpuv3/fpv3_fmovi.c: New. + * gcc.target/csky/fpuv3/fpv3_fmula.c: New. + * gcc.target/csky/fpuv3/fpv3_fmuls.c: New. + * gcc.target/csky/fpuv3/fpv3_fneg.c: New. + * gcc.target/csky/fpuv3/fpv3_fnmula.c: New. + * gcc.target/csky/fpuv3/fpv3_fnmuls.c: New. + * gcc.target/csky/fpuv3/fpv3_fstod.c: New. + * gcc.target/csky/fpuv3/fpv3_fstoh.c: New. + * gcc.target/csky/fpuv3/fpv3_fsub.c: New. + * gcc.target/csky/fpuv3/fpv3_fxtof.c: New. + * gcc.target/csky/fpuv3/fpv3_h.c: New. + * gcc.target/csky/fpuv3/fpv3_hs.c: New. + * gcc.target/csky/fpuv3/fpv3_hsz.c: New. + * gcc.target/csky/fpuv3/fpv3_hz.c: New. + * gcc.target/csky/fpuv3/fpv3_ls.c: New. + * gcc.target/csky/fpuv3/fpv3_lsz.c: New. + * gcc.target/csky/fpuv3/fpv3_lt.c: New. + * gcc.target/csky/fpuv3/fpv3_ltz.c: New. + * gcc.target/csky/fpuv3/fpv3_max.c: New. + * gcc.target/csky/fpuv3/fpv3_min.c: New. + * gcc.target/csky/fpuv3/fpv3_mul.c: New. + * gcc.target/csky/fpuv3/fpv3_mula.c: New. + * gcc.target/csky/fpuv3/fpv3_muls.c: New. + * gcc.target/csky/fpuv3/fpv3_ne.c: New. + * gcc.target/csky/fpuv3/fpv3_nez.c: New. + * gcc.target/csky/fpuv3/fpv3_recip.c: New. + * gcc.target/csky/fpuv3/fpv3_sqrt.c: New. + * gcc.target/csky/fpuv3/fpv3_unordered.c: New. + 2021-05-24 Aaron Sawdey * gcc.target/powerpc/fusion-p10-logadd.c: New file. -- cgit v1.1 From b6bdd7a4cb41ee057f2d064fffcb00f23ce6b497 Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Sun, 16 May 2021 13:07:06 -0700 Subject: Add a couple of A?CST1:CST2 match and simplify optimizations Instead of some of the more manual optimizations inside phi-opt, it would be good idea to do a lot of the heavy lifting inside match and simplify instead. In the process, this moves the three simple A?CST1:CST2 (where CST1 or CST2 is zero) simplifications. OK? Boostrapped and tested on x86_64-linux-gnu with no regressions. Differences from V1: * Use bit_xor 1 instead of bit_not to fix the problem with boolean types which are not 1 bit precision. Thanks, Andrew Pinski gcc: * match.pd (A?CST1:CST2): Add simplifcations for A?0:+-1, A?+-1:0, A?POW2:0 and A?0:POW2. --- gcc/match.pd | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) (limited to 'gcc') diff --git a/gcc/match.pd b/gcc/match.pd index 1fc6b7b..ad6b057 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -3711,6 +3711,47 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (if (integer_all_onesp (@1) && integer_zerop (@2)) @0)))) +/* A few simplifications of "a ? CST1 : CST2". */ +/* NOTE: Only do this on gimple as the if-chain-to-switch + optimization depends on the gimple to have if statements in it. */ +#if GIMPLE +(simplify + (cond @0 INTEGER_CST@1 INTEGER_CST@2) + (switch + (if (integer_zerop (@2)) + (switch + /* a ? 1 : 0 -> a if 0 and 1 are integral types. */ + (if (integer_onep (@1)) + (convert (convert:boolean_type_node @0))) + /* a ? -1 : 0 -> -a. */ + (if (integer_all_onesp (@1)) + (negate (convert (convert:boolean_type_node @0)))) + /* a ? powerof2cst : 0 -> a << (log2(powerof2cst)) */ + (if (!POINTER_TYPE_P (type) && integer_pow2p (@1)) + (with { + tree shift = build_int_cst (integer_type_node, tree_log2 (@1)); + } + (lshift (convert (convert:boolean_type_node @0)) { shift; }))))) + (if (integer_zerop (@1)) + (with { + tree booltrue = constant_boolean_node (true, boolean_type_node); + } + (switch + /* a ? 0 : 1 -> !a. */ + (if (integer_onep (@2)) + (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } ))) + /* a ? -1 : 0 -> -(!a). */ + (if (integer_all_onesp (@2)) + (negate (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } )))) + /* a ? powerof2cst : 0 -> (!a) << (log2(powerof2cst)) */ + (if (!POINTER_TYPE_P (type) && integer_pow2p (@2)) + (with { + tree shift = build_int_cst (integer_type_node, tree_log2 (@2)); + } + (lshift (convert (bit_xor (convert:boolean_type_node @0) { booltrue; } )) + { shift; })))))))) +#endif + /* Simplification moved from fold_cond_expr_with_comparison. It may also be extended. */ /* This pattern implements two kinds simplification: -- cgit v1.1 From 1fd76b24306ed4df4cf9e797d900699ed59ce7f7 Mon Sep 17 00:00:00 2001 From: Andrew Pinski Date: Sat, 22 May 2021 19:49:50 +0000 Subject: Optimize x < 0 ? ~y : y to (x >> 31) ^ y in match.pd This copies the optimization that is done in phiopt for "x < 0 ? ~y : y to (x >> 31) ^ y" into match.pd. The code for phiopt is kept around until phiopt uses match.pd (which I am working towards). Note the original testcase is now optimized early on and I added a new testcase to optimize during phiopt. OK? Bootstrapped and tested on x86_64-linux-gnu with no regressions. Thanks, Andrew Pinski Differences from v1: V2: Add check for integeral type to make sure vector types are not done. gcc: * match.pd (x < 0 ? ~y : y): New patterns. gcc/testsuite: * gcc.dg/tree-ssa/pr96928.c: Update test for slightly different IR. * gcc.dg/tree-ssa/pr96928-1.c: New testcase. --- gcc/match.pd | 32 +++++++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c | 48 +++++++++++++++++++++++++++++++ gcc/testsuite/gcc.dg/tree-ssa/pr96928.c | 7 +++-- 3 files changed, 85 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c (limited to 'gcc') diff --git a/gcc/match.pd b/gcc/match.pd index ad6b057..dd73081 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -4875,6 +4875,38 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (cmp (bit_and@2 @0 integer_pow2p@1) @1) (icmp @2 { build_zero_cst (TREE_TYPE (@0)); }))) +(for cmp (ge lt) +/* x < 0 ? ~y : y into (x >> (prec-1)) ^ y. */ +/* x >= 0 ? ~y : y into ~((x >> (prec-1)) ^ y). */ + (simplify + (cond (cmp @0 integer_zerop) (bit_not @1) @1) + (if (INTEGRAL_TYPE_P (type) + && INTEGRAL_TYPE_P (TREE_TYPE (@0)) + && !TYPE_UNSIGNED (TREE_TYPE (@0)) + && TYPE_PRECISION (TREE_TYPE (@0)) == TYPE_PRECISION (type)) + (with + { + tree shifter = build_int_cst (integer_type_node, TYPE_PRECISION (type) - 1); + } + (if (cmp == LT_EXPR) + (bit_xor (convert (rshift @0 {shifter;})) @1) + (bit_not (bit_xor (convert (rshift @0 {shifter;})) @1)))))) +/* x < 0 ? y : ~y into ~((x >> (prec-1)) ^ y). */ +/* x >= 0 ? y : ~y into (x >> (prec-1)) ^ y. */ + (simplify + (cond (cmp @0 integer_zerop) @1 (bit_not @1)) + (if (INTEGRAL_TYPE_P (type) + && INTEGRAL_TYPE_P (TREE_TYPE (@0)) + && !TYPE_UNSIGNED (TREE_TYPE (@0)) + && TYPE_PRECISION (TREE_TYPE (@0)) == TYPE_PRECISION (type)) + (with + { + tree shifter = build_int_cst (integer_type_node, TYPE_PRECISION (type) - 1); + } + (if (cmp == GE_EXPR) + (bit_xor (convert (rshift @0 {shifter;})) @1) + (bit_not (bit_xor (convert (rshift @0 {shifter;})) @1))))))) + /* If we have (A & C) != 0 ? D : 0 where C and D are powers of 2, convert this into a shift followed by ANDing with D. */ (simplify diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c new file mode 100644 index 0000000..a2770e5 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c @@ -0,0 +1,48 @@ +/* PR tree-optimization/96928 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -fdump-tree-phiopt2" } */ +/* { dg-final { scan-tree-dump-times " = a_\[0-9]*\\\(D\\\) >> " 5 "phiopt2" } } */ +/* { dg-final { scan-tree-dump-times " = ~c_\[0-9]*\\\(D\\\);" 1 "phiopt2" } } */ +/* { dg-final { scan-tree-dump-times " = ~" 1 "phiopt2" } } */ +/* { dg-final { scan-tree-dump-times " = \[abc_0-9\\\(\\\)D]* \\\^ " 5 "phiopt2" } } */ +/* { dg-final { scan-tree-dump-not "a < 0" "phiopt2" } } */ + +int +foo (int a) +{ + if (a < 0) + return ~a; + return a; +} + +int +bar (int a, int b) +{ + if (a < 0) + return ~b; + return b; +} + +unsigned +baz (int a, unsigned int b) +{ + if (a < 0) + return ~b; + return b; +} + +unsigned +qux (int a, unsigned int c) +{ + if (a >= 0) + return ~c; + return c; +} + +int +corge (int a, int b) +{ + if (a >= 0) + return b; + return ~b; +} diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96928.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96928.c index 2091357..e8fd82f 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/pr96928.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96928.c @@ -1,8 +1,11 @@ /* PR tree-optimization/96928 */ /* { dg-do compile } */ -/* { dg-options "-O2 -fdump-tree-phiopt2" } */ +/* { dg-options "-O2 -fdump-tree-phiopt2 -fdump-tree-optimized" } */ /* { dg-final { scan-tree-dump-times " = a_\[0-9]*\\\(D\\\) >> " 5 "phiopt2" } } */ -/* { dg-final { scan-tree-dump-times " = ~c_\[0-9]*\\\(D\\\);" 1 "phiopt2" } } */ +/* The following check is done at optimized because a ^ (~b) is rewritten as ~(a^b) + and in the case of match.pd optimizing these ?:, the ~ is moved out already + by the time we get to phiopt2. */ +/* { dg-final { scan-tree-dump-times "\\\^ c_\[0-9]*\\\(D\\\);" 1 "optimized" } } */ /* { dg-final { scan-tree-dump-times " = ~" 1 "phiopt2" } } */ /* { dg-final { scan-tree-dump-times " = \[abc_0-9\\\(\\\)D]* \\\^ " 5 "phiopt2" } } */ /* { dg-final { scan-tree-dump-not "a < 0" "phiopt2" } } */ -- cgit v1.1 From 94079e642d95ba4bcb75354d6cd628a473a94479 Mon Sep 17 00:00:00 2001 From: Geng Qi Date: Tue, 25 May 2021 18:45:25 +0800 Subject: C-SKY: Add instruction "ld.bs". gcc/ * config/csky/csky.md (cskyv2_sextend_ldbs): New. gcc/testsuite/ * gcc.target/csky/ldbs.c: New. --- gcc/config/csky/csky.md | 10 ++++++++++ gcc/testsuite/gcc.target/csky/ldbs.c | 11 +++++++++++ 2 files changed, 21 insertions(+) create mode 100644 gcc/testsuite/gcc.target/csky/ldbs.c (limited to 'gcc') diff --git a/gcc/config/csky/csky.md b/gcc/config/csky/csky.md index c27d627..b980d4c 100644 --- a/gcc/config/csky/csky.md +++ b/gcc/config/csky/csky.md @@ -1533,6 +1533,7 @@ }" ) +;; hi -> si (define_insn "extendhisi2" [(set (match_operand:SI 0 "register_operand" "=r") (sign_extend:SI (match_operand:HI 1 "register_operand" "r")))] @@ -1557,6 +1558,15 @@ "sextb %0, %1" ) +(define_insn "*cskyv2_sextend_ldbs" + [(set (match_operand:SI 0 "register_operand" "=r") + (sign_extend:SI (match_operand:QI 1 "csky_simple_mem_operand" "m")))] + "CSKY_ISA_FEATURE (E2)" + "ld.bs\t%0, %1" + [(set_attr "length" "4") + (set_attr "type" "load")] +) + ;; qi -> hi (define_insn "extendqihi2" [(set (match_operand:HI 0 "register_operand" "=r") diff --git a/gcc/testsuite/gcc.target/csky/ldbs.c b/gcc/testsuite/gcc.target/csky/ldbs.c new file mode 100644 index 0000000..27a0254 --- /dev/null +++ b/gcc/testsuite/gcc.target/csky/ldbs.c @@ -0,0 +1,11 @@ +/* { dg-do compile } */ +/* { dg-skip-if "" { *-*-* } { "-mcpu=ck801" "-march=ck801" } { "*" } } */ +/* { dg-csky-options "-O1" } */ + +int foo (signed char *pb) +{ + return *pb; +} + +/* { dg-final { scan-assembler "ld.bs" } } */ + -- cgit v1.1 From 155d3038c23002581eb29d59ea23e44b3758c6dc Mon Sep 17 00:00:00 2001 From: Geng Qi Date: Fri, 30 Apr 2021 21:02:37 +0800 Subject: C-SKY: Fix FAIL of gcc.dg/torture/stackalign/builtin-return-2.c. gcc/ChangeLog: * config/csky/csky.md (untyped_call): Emit clobber for return registers to mark them used. --- gcc/config/csky/csky.md | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'gcc') diff --git a/gcc/config/csky/csky.md b/gcc/config/csky/csky.md index b980d4c..f91d851 100644 --- a/gcc/config/csky/csky.md +++ b/gcc/config/csky/csky.md @@ -3258,6 +3258,10 @@ emit_call_insn (gen_call (operands[0], const0_rtx)); + for (int i = 0; i < XVECLEN (operands[2], 0); i++) + emit_clobber (SET_SRC (XVECEXP (operands[2], 0, i))); + emit_insn (gen_blockage ()); + for (i = 0; i < XVECLEN (operands[2], 0); i++) { rtx set = XVECEXP (operands[2], 0, i); -- cgit v1.1 From 4553b95516176d578aa6ce81499509f6ec099bdb Mon Sep 17 00:00:00 2001 From: Geng Qi Date: Fri, 30 Apr 2021 21:03:33 +0800 Subject: C-SKY: Delete definition TARGET_PROMOTE_PROTOTYPES, just use the default definition. gcc/ChangeLog: * config/csky/csky.c (TARGET_PROMOTE_PROTOTYPES): Delete. --- gcc/config/csky/csky.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'gcc') diff --git a/gcc/config/csky/csky.c b/gcc/config/csky/csky.c index 7f2af82..2b44edf 100644 --- a/gcc/config/csky/csky.c +++ b/gcc/config/csky/csky.c @@ -512,9 +512,6 @@ csky_cpu_cpp_builtins (cpp_reader *pfile) #undef TARGET_SPLIT_COMPLEX_ARG #define TARGET_SPLIT_COMPLEX_ARG hook_bool_const_tree_true -#undef TARGET_PROMOTE_PROTOTYPES -#define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true - #undef TARGET_MUST_PASS_IN_STACK #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size -- cgit v1.1 From 41eba35b08a9bbd1f06b15e74942a94ea838d8cf Mon Sep 17 00:00:00 2001 From: Geng Qi Date: Wed, 26 May 2021 11:29:19 +0800 Subject: C-SKY: Support fldrd/fstrd for fpuv2 and fldr.64/fstr.64 for fpuv3. gcc/ChangeLog: * config/csky/csky.c (ck810_legitimate_index_p): Support "base + index" with DF mode. * config/csky/constraints.md ("Y"): New constraint for memory operands without index register. * config/csky/csky_insn_fpuv2.md (fpuv3_movdf): Use "Y" instead of "m" when mov between memory and general registers, and lower their priority. * config/csky/csky_insn_fpuv3.md (fpuv2_movdf): Likewise. gcc/testsuite/ChangeLog: * gcc.target/csky/fldrd_fstrd.c: New. * gcc.target/csky/fpuv3/fldr64_fstr64.c: New. --- gcc/config/csky/constraints.md | 4 ++++ gcc/config/csky/csky.c | 3 ++- gcc/config/csky/csky_insn_fpuv2.md | 4 ++-- gcc/config/csky/csky_insn_fpuv3.md | 16 ++++++++-------- gcc/testsuite/gcc.target/csky/fldrd_fstrd.c | 17 +++++++++++++++++ gcc/testsuite/gcc.target/csky/fpuv3/fldr64_fstr64.c | 18 ++++++++++++++++++ 6 files changed, 51 insertions(+), 11 deletions(-) create mode 100644 gcc/testsuite/gcc.target/csky/fldrd_fstrd.c create mode 100644 gcc/testsuite/gcc.target/csky/fpuv3/fldr64_fstr64.c (limited to 'gcc') diff --git a/gcc/config/csky/constraints.md b/gcc/config/csky/constraints.md index c9bc9f2..2641ab3 100644 --- a/gcc/config/csky/constraints.md +++ b/gcc/config/csky/constraints.md @@ -38,6 +38,10 @@ "Memory operands with base register, index register" (match_test "csky_valid_mem_constraint_operand (op, \"W\")")) +(define_memory_constraint "Y" + "Memory operands without index register" + (not (match_test "csky_valid_mem_constraint_operand (op, \"W\")"))) + (define_constraint "R" "Memory operands whose address is a label_ref" (and (match_code "mem") diff --git a/gcc/config/csky/csky.c b/gcc/config/csky/csky.c index 2b44edf..c0e42a2 100644 --- a/gcc/config/csky/csky.c +++ b/gcc/config/csky/csky.c @@ -3152,7 +3152,8 @@ ck810_legitimate_index_p (machine_mode mode, rtx index, int strict_p) /* The follow index is for ldr instruction, the ldr cannot load dword data, so the mode size should not be larger than 4. */ - else if (GET_MODE_SIZE (mode) <= 4) + else if (GET_MODE_SIZE (mode) <= 4 + || (TARGET_HARD_FLOAT && CSKY_VREG_MODE_P (mode))) { if (is_csky_address_register_rtx_p (index, strict_p)) return 1; diff --git a/gcc/config/csky/csky_insn_fpuv2.md b/gcc/config/csky/csky_insn_fpuv2.md index d56b61f..7bab99e 100644 --- a/gcc/config/csky/csky_insn_fpuv2.md +++ b/gcc/config/csky/csky_insn_fpuv2.md @@ -480,8 +480,8 @@ ) (define_insn "*fpuv2_movdf" - [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r, r,m, v,?r,Q,v,v,v") - (match_operand:DF 1 "general_operand" " r,m,mF,r,?r, v,v,Q,v,m"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=r, v,?r,Q,v,v,v,r, r,Y") + (match_operand:DF 1 "general_operand" " r,?r, v,v,Q,v,m,Y,YF,r"))] "CSKY_ISA_FEATURE (fpv2_df)" "* return csky_output_movedouble(operands, DFmode);" [(set (attr "length") diff --git a/gcc/config/csky/csky_insn_fpuv3.md b/gcc/config/csky/csky_insn_fpuv3.md index b5f4798..7b9d4a7 100644 --- a/gcc/config/csky/csky_insn_fpuv3.md +++ b/gcc/config/csky/csky_insn_fpuv3.md @@ -90,27 +90,27 @@ ) (define_insn "*fpv3_movdf" - [(set (match_operand:DF 0 "nonimmediate_operand" "=r,r, r,m,v,?r,Q,v,v,v, v") - (match_operand:DF 1 "general_operand" " r,m,mF,r,?r,v,v,Q,v,m,Dv"))] + [(set (match_operand:DF 0 "nonimmediate_operand" "=r, v,?r,Q,v,v,v, v,r, r,Y") + (match_operand:DF 1 "general_operand" " r,?r, v,v,Q,v,m,Dv,Y,YF,r"))] "CSKY_ISA_FEATURE(fpv3_df)" "* switch (which_alternative) { - case 4: + case 1: if (TARGET_BIG_ENDIAN) return \"fmtvr.64\\t%0, %R1, %1\"; return \"fmtvr.64\\t%0, %1, %R1\"; - case 5: + case 2: if (TARGET_BIG_ENDIAN) return \"fmfvr.64\\t%R0, %0, %1\"; return \"fmfvr.64\\t%0, %R0, %1\"; + case 3: + case 4: case 6: - case 7: - case 9: return fpuv3_output_move(operands); - case 8: + case 5: return \"fmov.64\\t%0, %1\"; - case 10: + case 7: return \"fmovi.64\\t%0, %1\"; default: return csky_output_movedouble(operands, DFmode); diff --git a/gcc/testsuite/gcc.target/csky/fldrd_fstrd.c b/gcc/testsuite/gcc.target/csky/fldrd_fstrd.c new file mode 100644 index 0000000..024de18 --- /dev/null +++ b/gcc/testsuite/gcc.target/csky/fldrd_fstrd.c @@ -0,0 +1,17 @@ +/* { dg-do compile } */ +/* { dg-csky-options "-mcpu=ck810f -O1 -mhard-float" } */ + +double fldrd (double *pd, int index) +{ + return pd[index]; +} + +/* { dg-final { scan-assembler "fldrd" } } */ + +void fstrd (double *pd, int index, double d) +{ + pd[index] = d; +} + +/* { dg-final { scan-assembler "fstrd" } } */ + diff --git a/gcc/testsuite/gcc.target/csky/fpuv3/fldr64_fstr64.c b/gcc/testsuite/gcc.target/csky/fpuv3/fldr64_fstr64.c new file mode 100644 index 0000000..cd367e5 --- /dev/null +++ b/gcc/testsuite/gcc.target/csky/fpuv3/fldr64_fstr64.c @@ -0,0 +1,18 @@ +/* { dg-do compile } */ +/* { dg-skip-if "test is specific to ck860f" { csky-*-* } { "*" } { "-mcpu=ck860*f* -mfloat-abi=hard" "-mcpu=ck860*f* -mhard-float" } } */ +/* { dg-options "-O1 -mfpu=fpv3" } */ + +double fldr64 (double *pd, int index) +{ + return pd[index]; +} + +/* { dg-final { scan-assembler "fldr.64" } } */ + +void fstr64 (double *pd, int index, double d) +{ + pd[index] = d; +} + +/* { dg-final { scan-assembler "fstr.64" } } */ + -- cgit v1.1 From 431d26e1dd18c1146d3d4dcd3b45a3b04f7f7d59 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Mon, 17 May 2021 12:57:08 +0200 Subject: Remove install-old.texi gcc/ChangeLog: * Makefile.in: Remove it. * doc/include/fdl.texi: Update next/previous chapters. * doc/install.texi: Likewise. * doc/install-old.texi: Removed. --- gcc/Makefile.in | 2 +- gcc/doc/include/fdl.texi | 2 +- gcc/doc/install-old.texi | 184 ----------------------------------------------- gcc/doc/install.texi | 20 +----- 4 files changed, 3 insertions(+), 205 deletions(-) delete mode 100644 gcc/doc/install-old.texi (limited to 'gcc') diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 1164554..da2ef24 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -3314,7 +3314,7 @@ TEXI_GCCINT_FILES = gccint.texi gcc-common.texi gcc-vers.texi \ loop.texi generic.texi gimple.texi plugins.texi optinfo.texi \ match-and-simplify.texi analyzer.texi ux.texi poly-int.texi -TEXI_GCCINSTALL_FILES = install.texi install-old.texi fdl.texi \ +TEXI_GCCINSTALL_FILES = install.texi fdl.texi \ gcc-common.texi gcc-vers.texi TEXI_CPPINT_FILES = cppinternals.texi gcc-common.texi gcc-vers.texi diff --git a/gcc/doc/include/fdl.texi b/gcc/doc/include/fdl.texi index 4e3457f..7fa222c 100644 --- a/gcc/doc/include/fdl.texi +++ b/gcc/doc/include/fdl.texi @@ -19,7 +19,7 @@ of this license document, but changing it is not allowed. @ifset gfdlhtml @ifnothtml @comment node-name, next, previous, up -@node GNU Free Documentation License, Concept Index, Old, Top +@node GNU Free Documentation License, Concept Index, Specific, Top @end ifnothtml @html

Installing GCC: GNU Free Documentation License

diff --git a/gcc/doc/install-old.texi b/gcc/doc/install-old.texi deleted file mode 100644 index b425971..0000000 --- a/gcc/doc/install-old.texi +++ /dev/null @@ -1,184 +0,0 @@ -@c Copyright (C) 1988-2021 Free Software Foundation, Inc. -@c This is part of the GCC manual. -@c For copying conditions, see the file install.texi. - -@ifnothtml -@comment node-name, next, previous, up -@node Old, GNU Free Documentation License, Specific, Top -@end ifnothtml -@html -

Old installation documentation

-@end html -@ifnothtml -@chapter Old installation documentation -@end ifnothtml - -Note most of this information is out of date and superseded by the -previous chapters of this manual. It is provided for historical -reference only, because of a lack of volunteers to merge it into the -main manual. - -@ifnothtml -@menu -* Configurations:: Configurations Supported by GCC. -@end menu -@end ifnothtml - -Here is the procedure for installing GCC on a GNU or Unix system. - -@enumerate -@item -If you have chosen a configuration for GCC which requires other GNU -tools (such as GAS or the GNU linker) instead of the standard system -tools, install the required tools in the build directory under the names -@file{as}, @file{ld} or whatever is appropriate. - -Alternatively, you can do subsequent compilation using a value of the -@code{PATH} environment variable such that the necessary GNU tools come -before the standard system tools. - -@item -Specify the host, build and target machine configurations. You do this -when you run the @file{configure} script. - -The @dfn{build} machine is the system which you are using, the -@dfn{host} machine is the system where you want to run the resulting -compiler (normally the build machine), and the @dfn{target} machine is -the system for which you want the compiler to generate code. - -If you are building a compiler to produce code for the machine it runs -on (a native compiler), you normally do not need to specify any operands -to @file{configure}; it will try to guess the type of machine you are on -and use that as the build, host and target machines. So you don't need -to specify a configuration when building a native compiler unless -@file{configure} cannot figure out what your configuration is or guesses -wrong. - -In those cases, specify the build machine's @dfn{configuration name} -with the @option{--host} option; the host and target will default to be -the same as the host machine. - -Here is an example: - -@smallexample -./configure --host=sparc-sun-sunos4.1 -@end smallexample - -A configuration name may be canonical or it may be more or less -abbreviated. - -A canonical configuration name has three parts, separated by dashes. -It looks like this: @samp{@var{cpu}-@var{company}-@var{system}}. -(The three parts may themselves contain dashes; @file{configure} -can figure out which dashes serve which purpose.) For example, -@samp{m68k-sun-sunos4.1} specifies a Sun 3. - -You can also replace parts of the configuration by nicknames or aliases. -For example, @samp{sun3} stands for @samp{m68k-sun}, so -@samp{sun3-sunos4.1} is another way to specify a Sun 3. - -You can specify a version number after any of the system types, and some -of the CPU types. In most cases, the version is irrelevant, and will be -ignored. So you might as well specify the version if you know it. - -See @ref{Configurations}, for a list of supported configuration names and -notes on many of the configurations. You should check the notes in that -section before proceeding any further with the installation of GCC@. - -@end enumerate - -@ifnothtml -@node Configurations, , , Old -@section Configurations Supported by GCC -@end ifnothtml -@html -

@anchor{Configurations}Configurations Supported by GCC

-@end html -@cindex configurations supported by GCC - -Here are the possible CPU types: - -@quotation -@c gmicro, fx80, spur and tahoe omitted since they don't work. -1750a, a29k, alpha, arm, avr, c@var{n}, clipper, dsp16xx, elxsi, fr30, h8300, -hppa1.0, hppa1.1, i370, i386, i486, i586, i686, i786, i860, i960, ip2k, m32r, -m68000, m68k, m88k, mcore, mips, mipsel, mips64, mips64el, -mn10200, mn10300, ns32k, pdp11, powerpc, powerpcle, romp, rs6000, sh, sparc, -sparclite, sparc64, v850, vax, we32k. -@end quotation - -Here are the recognized company names. As you can see, customary -abbreviations are used rather than the longer official names. - -@c What should be done about merlin, tek*, dolphin? -@quotation -acorn, alliant, altos, apollo, apple, att, bull, -cbm, convergent, convex, crds, dec, dg, dolphin, -elxsi, encore, harris, hitachi, hp, ibm, intergraph, isi, -mips, motorola, ncr, next, ns, omron, plexus, -sequent, sgi, sony, sun, tti, unicom, wrs. -@end quotation - -The company name is meaningful only to disambiguate when the rest of -the information supplied is insufficient. You can omit it, writing -just @samp{@var{cpu}-@var{system}}, if it is not needed. For example, -@samp{vax-ultrix4.2} is equivalent to @samp{vax-dec-ultrix4.2}. - -Here is a list of system types: - -@quotation -386bsd, aix, acis, amigaos, aos, aout, aux, bosx, bsd, clix, coff, ctix, cxux, -dgux, dynix, ebmon, ecoff, elf, esix, freebsd, hms, genix, gnu, linux, -linux-gnu, hiux, hpux, iris, irix, isc, luna, lynxos, mach, minix, msdos, mvs, -netbsd, newsos, nindy, ns, osf, osfrose, ptx, riscix, riscos, rtu, sco, sim, -solaris, sunos, sym, sysv, udi, ultrix, unicos, uniplus, unos, vms, vsta, -vxworks, winnt, xenix. -@end quotation - -@noindent -You can omit the system type; then @file{configure} guesses the -operating system from the CPU and company. - -You can add a version number to the system type; this may or may not -make a difference. For example, you can write @samp{bsd4.3} or -@samp{bsd4.4} to distinguish versions of BSD@. In practice, the version -number is most needed for @samp{sysv3} and @samp{sysv4}, which are often -treated differently. - -@samp{linux-gnu} is the canonical name for the GNU/Linux target; however -GCC will also accept @samp{linux}. The version of the kernel in use is -not relevant on these systems. A suffix such as @samp{libc1} or @samp{aout} -distinguishes major versions of the C library; all of the suffixed versions -are obsolete. - -If you specify an impossible combination such as @samp{i860-dg-vms}, -then you may get an error message from @file{configure}, or it may -ignore part of the information and do the best it can with the rest. -@file{configure} always prints the canonical name for the alternative -that it used. GCC does not support all possible alternatives. - -Often a particular model of machine has a name. Many machine names are -recognized as aliases for CPU/company combinations. Thus, the machine -name @samp{sun3}, mentioned above, is an alias for @samp{m68k-sun}. -Sometimes we accept a company name as a machine name, when the name is -popularly used for a particular machine. Here is a table of the known -machine names: - -@quotation -3300, 3b1, 3b@var{n}, 7300, altos3068, altos, -apollo68, att-7300, balance, -convex-c@var{n}, crds, decstation-3100, -decstation, delta, encore, -fx2800, gmicro, hp7@var{nn}, hp8@var{nn}, -hp9k2@var{nn}, hp9k3@var{nn}, hp9k7@var{nn}, -hp9k8@var{nn}, iris4d, iris, isi68, -m3230, magnum, merlin, miniframe, -mmax, news-3600, news800, news, next, -pbd, pc532, pmax, powerpc, powerpcle, ps2, risc-news, -rtpc, sun2, sun386i, sun386, sun3, -sun4, symmetry, tower-32, tower. -@end quotation - -@noindent -Remember that a machine name specifies both the cpu type and the company -name. diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi index 2619518..f0591e0 100644 --- a/gcc/doc/install.texi +++ b/gcc/doc/install.texi @@ -36,9 +36,6 @@ @ifset binarieshtml @settitle Installing GCC: Binaries @end ifset -@ifset oldhtml -@settitle Installing GCC: Old documentation -@end ifset @ifset gfdlhtml @settitle Installing GCC: GNU Free Documentation License @end ifset @@ -62,7 +59,6 @@ @set testhtml @set finalinstallhtml @set binarieshtml -@set oldhtml @set gfdlhtml @end ifnothtml @@ -120,8 +116,6 @@ Free Documentation License}''. * Specific:: Host/target specific installation notes for GCC. * Binaries:: Where to get pre-compiled binaries. -* Old:: Old installation documentation. - * GNU Free Documentation License:: How you can copy and share this manual. * Concept Index:: This index has two entries. @end menu @@ -3446,7 +3440,7 @@ links to GNU Fortran binaries for several platforms. @c ***Specific**************************************************************** @ifnothtml @comment node-name, next, previous, up -@node Specific, Old, Binaries, Top +@node Specific, GNU Free Documentation License, Binaries, Top @end ifnothtml @ifset specifichtml @ifnothtml @@ -5140,18 +5134,6 @@ automatically. @end ifhtml @end ifset -@c ***Old documentation****************************************************** -@ifset oldhtml -@include install-old.texi -@html -
-

-@end html -@ifhtml -@uref{./index.html,,Return to the GCC Installation page} -@end ifhtml -@end ifset - @c ***GFDL******************************************************************** @ifset gfdlhtml @include fdl.texi -- cgit v1.1 From 0eac9c60ac1f28eeb7bb0a56e533865d984015f6 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Tue, 18 May 2021 11:57:47 +0200 Subject: docs: port old-intall.texi part to install.texi gcc/ChangeLog: * doc/install.texi: Port relevant part from install-old.texi and re-generate list of CPUs and systems. --- gcc/doc/install.texi | 72 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 58 insertions(+), 14 deletions(-) (limited to 'gcc') diff --git a/gcc/doc/install.texi b/gcc/doc/install.texi index f0591e0..591ccaa 100644 --- a/gcc/doc/install.texi +++ b/gcc/doc/install.texi @@ -697,23 +697,67 @@ The default value is @uref{https://gcc.gnu.org/,,https://gcc.gnu.org/}. @end table -@heading Target specification -@itemize @bullet -@item -GCC has code to correctly determine the correct value for @var{target} -for nearly all native systems. Therefore, we highly recommend you do -not provide a configure target when configuring a native compiler. +@heading Host, Build and Target specification -@item -@var{target} must be specified as @option{--target=@var{target}} -when configuring a cross compiler; examples of valid targets would be -m68k-elf, sh-elf, etc. +Specify the host, build and target machine configurations. You do this +when you run the @file{configure} script. -@item -Specifying just @var{target} instead of @option{--target=@var{target}} -implies that the host defaults to @var{target}. -@end itemize +The @dfn{build} machine is the system which you are using, the +@dfn{host} machine is the system where you want to run the resulting +compiler (normally the build machine), and the @dfn{target} machine is +the system for which you want the compiler to generate code. + +If you are building a compiler to produce code for the machine it runs +on (a native compiler), you normally do not need to specify any operands +to @file{configure}; it will try to guess the type of machine you are on +and use that as the build, host and target machines. So you don't need +to specify a configuration when building a native compiler unless +@file{configure} cannot figure out what your configuration is or guesses +wrong. + +In those cases, specify the build machine's @dfn{configuration name} +with the @option{--host} option; the host and target will default to be +the same as the host machine. + +Here is an example: + +@smallexample +./configure --host=x86_64-pc-linux-gnu +@end smallexample +A configuration name may be canonical or it may be more or less +abbreviated (@file{config.sub} script produces canonical versions). + +A canonical configuration name has three parts, separated by dashes. +It looks like this: @samp{@var{cpu}-@var{company}-@var{system}}. + +Here are the possible CPU types: + +@quotation +aarch64, aarch64_be, alpha, alpha64, amdgcn, arc, arceb, arm, armeb, avr, bfin, +bpf, cr16, cris, csky, epiphany, fido, fr30, frv, ft32, h8300, hppa, hppa2.0, +hppa64, i486, i686, ia64, iq2000, lm32, m32c, m32r, m32rle, m68k, mcore, +microblaze, microblazeel, mips, mips64, mips64el, mips64octeon, mips64orion, +mips64vr, mipsel, mipsisa32, mipsisa32r2, mipsisa64, mipsisa64r2, +mipsisa64r2el, mipsisa64sb1, mipsisa64sr71k, mipstx39, mmix, mn10300, moxie, +msp430, nds32be, nds32le, nios2, nvptx, or1k, pdp11, powerpc, powerpc64, +powerpc64le, powerpcle, pru, riscv32, riscv32be, riscv64, riscv64be, rl78, rx, +s390, s390x, sh, shle, sparc, sparc64, tic6x, tilegx, tilegxbe, tilepro, v850, +v850e, v850e1, vax, visium, x86_64, xstormy16, xtensa +@end quotation + +Here is a list of system types: + +@quotation +aix@var{version}, amdhsa, aout, cygwin, darwin@var{version}, +eabi, eabialtivec, eabisim, eabisimaltivec, elf, elf32, +elfbare, elfoabi, freebsd@var{version}, gnu, hpux, hpux@var{version}, +kfreebsd-gnu, kopensolaris-gnu, linux-androideabi, linux-gnu, +linux-gnu_altivec, linux-musl, linux-uclibc, lynxos, mingw32, mingw32crt, +mmixware, msdosdjgpp, netbsd, netbsdelf@var{version}, nto-qnx, openbsd, +rtems, solaris@var{version}, symbianelf, tpf, uclinux, uclinux_eabi, vms, +vxworks, vxworksae, vxworksmils +@end quotation @heading Options specification -- cgit v1.1