aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Liska <mliska@suse.cz>2021-05-26 09:18:21 +0200
committerMartin Liska <mliska@suse.cz>2021-05-26 09:18:21 +0200
commitb1edeaddf3b48278724f3175983b9f357d437874 (patch)
treeca0f4fbad20f6d9cba1662acb1bb507f3341835c
parent2f7ea01554b7d202f169fc4268d8c9ee2fabbad2 (diff)
parent0eac9c60ac1f28eeb7bb0a56e533865d984015f6 (diff)
downloadgcc-b1edeaddf3b48278724f3175983b9f357d437874.zip
gcc-b1edeaddf3b48278724f3175983b9f357d437874.tar.gz
gcc-b1edeaddf3b48278724f3175983b9f357d437874.tar.bz2
Merge branch 'master' into devel/sphinx
-rw-r--r--c++tools/ChangeLog19
-rw-r--r--c++tools/server.cc1
-rw-r--r--contrib/ChangeLog4
-rw-r--r--gcc/ChangeLog294
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/Makefile.in2
-rw-r--r--gcc/ada/ChangeLog4
-rw-r--r--gcc/c-family/ChangeLog20
-rw-r--r--gcc/config/csky/constraints.md4
-rw-r--r--gcc/config/csky/csky.c6
-rw-r--r--gcc/config/csky/csky.md14
-rw-r--r--gcc/config/csky/csky_insn_fpuv2.md4
-rw-r--r--gcc/config/csky/csky_insn_fpuv3.md16
-rw-r--r--gcc/config/riscv/riscv.h1
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/call.c5
-rw-r--r--gcc/doc/install-old.texi184
-rw-r--r--gcc/doc/install.texi90
-rw-r--r--gcc/fortran/ChangeLog6
-rw-r--r--gcc/gimple-range-cache.cc126
-rw-r--r--gcc/gimple-range-cache.h1
-rw-r--r--gcc/gimple-range-gori.cc737
-rw-r--r--gcc/gimple-range-gori.h136
-rw-r--r--gcc/gimple-range.cc167
-rw-r--r--gcc/gimple-range.h13
-rw-r--r--gcc/gimplify.c3
-rw-r--r--gcc/match.pd73
-rw-r--r--gcc/testsuite/ChangeLog62
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/nodiscard8.C15
-rw-r--r--gcc/testsuite/g++.dg/cpp1z/nodiscard9.C22
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr96928-1.c48
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr96928.c7
-rw-r--r--gcc/testsuite/gcc.target/csky/fldrd_fstrd.c17
-rw-r--r--gcc/testsuite/gcc.target/csky/fpuv3/fldr64_fstr64.c18
-rw-r--r--gcc/testsuite/gcc.target/csky/ldbs.c11
-rw-r--r--gcc/tree-inline.c2
-rw-r--r--gcc/value-range.cc10
-rw-r--r--libgomp/ChangeLog5
-rw-r--r--liboffloadmic/ChangeLog6
39 files changed, 1239 insertions, 923 deletions
diff --git a/c++tools/ChangeLog b/c++tools/ChangeLog
index 0fa6214..c0228cb 100644
--- a/c++tools/ChangeLog
+++ b/c++tools/ChangeLog
@@ -1,3 +1,22 @@
+2021-05-25 Jakub Jelinek <jakub@redhat.com>
+
+ PR bootstrap/100731
+ * server.cc: Include <cstdlib>.
+
+2021-05-25 Eric Botcazou <ebotcazou@adacore.com>
+
+ * configure.ac (--enable-maintainer-mode): Fix typo and weird syntax.
+ * configure: Regenerate.
+
+2021-05-25 Jakub Jelinek <jakub@redhat.com>
+
+ * Makefile.in: Update copyright year.
+ * configure.ac: Likewise.
+ * resolver.cc: Likewise.
+ * resolver.h: Likewise.
+ * server.cc: Likewise.
+ (print_version): Update copyright notice date.
+
2021-05-10 Martin Liska <mliska@suse.cz>
* Makefile.in: Include also ../gcc folder.
diff --git a/c++tools/server.cc b/c++tools/server.cc
index 709955e..fae3e78 100644
--- a/c++tools/server.cc
+++ b/c++tools/server.cc
@@ -29,6 +29,7 @@ along with GCC; see the file COPYING3. If not see
#include <csignal>
#include <cstring>
#include <cstdarg>
+#include <cstdlib>
// OS
#include <unistd.h>
#include <sys/types.h>
diff --git a/contrib/ChangeLog b/contrib/ChangeLog
index 0498c0f..a07fc19 100644
--- a/contrib/ChangeLog
+++ b/contrib/ChangeLog
@@ -1,3 +1,7 @@
+2021-05-25 Jakub Jelinek <jakub@redhat.com>
+
+ * update-copyright.py: Add c++tools.
+
2021-05-24 Martin Liska <mliska@suse.cz>
* gcc-changelog/git_commit.py: Add note that ChangeLog entries
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 <amacleod@redhat.com>
+
+ * 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 <amacleod@redhat.com>
+
+ * 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 <amacleod@redhat.com>
+
+ * 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 <amacleod@redhat.com>
+
+ * 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 <amacleod@redhat.com>
+
+ * 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 <amacleod@redhat.com>
+
+ * 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 <amacleod@redhat.com>
+
+ * 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 <amacleod@redhat.com>
+
+ * 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 <aldyh@redhat.com>
+
+ * value-range.cc (range_tests_legacy): Use
+ build_nonstandard_integer_type instead of int and short.
+
+2021-05-25 Eric Botcazou <ebotcazou@adacore.com>
+
+ * gimplify.c (gimplify_decl_expr): Clear TREE_READONLY on the DECL
+ when really creating an initialization statement for it.
+
+2021-05-25 Eric Botcazou <ebotcazou@adacore.com>
+
+ * tree-inline.c (setup_one_parameter): Fix thinko in new condition.
+
+2021-05-25 Kito Cheng <kito.cheng@sifive.com>
+
+ * config/riscv/riscv.h (ASM_SPEC): Pass -mno-relax.
+
+2021-05-25 Martin Liska <mliska@suse.cz>
+
+ PR tree-optimization/92860
+ PR target/99592
+ * optc-save-gen.awk: Remove exceptions.
+
+2021-05-25 Martin Liska <mliska@suse.cz>
+
+ * 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 <cooper.qu@linux.alibaba.com>
+
+ * config/csky/csky-modes.def : Fix copyright.
+
+2021-05-25 Cooper Qu <cooper.qu@linux.alibaba.com>
+
+ * 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 <rguenther@suse.de>
+
+ 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 <gengqi@linux.alibaba.com>
+
+ * 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 <gengqi@linux.alibaba.com>
+
+ * 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 <gengqi@linux.alibaba.com>
+
+ * 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 <gengqi@linux.alibaba.com>
+
+ * 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 <acsawdey@linux.ibm.com>
* 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/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/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 <mliska@suse.cz>
+
+ * doc/share/conf.py: Fix Sphinx 4.0.x error.
+
2021-05-21 Piotr Trojanek <trojanek@adacore.com>
* 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 <mliska@suse.cz>
+
+ 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 <mliska@suse.cz>
+
+ * c-attribs.c (handle_no_sanitize_coverage_attribute): New.
+
+2021-05-25 Jakub Jelinek <jakub@redhat.com>
+
+ 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 <jakub@redhat.com>
PR middle-end/99928
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 7f2af82..c0e42a2 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
@@ -3155,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.md b/gcc/config/csky/csky.md
index c27d627..f91d851 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")
@@ -3248,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);
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/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)" \
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 <jakub@redhat.com>
+
+ 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 <jakub@redhat.com>
PR middle-end/99928
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/doc/install-old.texi b/gcc/doc/install-old.texi
deleted file mode 100644
index 419e38d..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
-@end ifnothtml
-@html
-<h1 align="center">Old installation documentation</h1>
-@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
-<h2>@anchor{Configurations}Configurations Supported by GCC</h2>
-@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 e294494..4066347 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
@@ -122,8 +118,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
@@ -705,23 +699,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
@@ -5142,18 +5180,6 @@ automatically.
@end ifhtml
@end ifset
-@c ***Old documentation******************************************************
-@ifset oldhtml
-@include install-old.texi
-@html
-<hr />
-<p>
-@end html
-@ifhtml
-@uref{./index.html,,Return to the GCC Installation page}
-@end ifhtml
-@end ifset
-
@c ***GFDL********************************************************************
@ifset gfdlhtml
@include fdl.texi
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 <tobias@codesourcery.com>
+ Johannes Nendwich <a08727063@unet.univie.ac.at>
+
+ * intrinsic.texi (GERROR, GETARGS, GETLOG, NORM2, PARITY, RANDOM_INIT,
+ RANDOM_NUMBER): Fix typos and copy'n'paste errors.
+
2021-05-24 Tobias Burnus <tobias@codesourcery.com>
PR fortran/86470
diff --git a/gcc/gimple-range-cache.cc b/gcc/gimple-range-cache.cc
index 2c922e3..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 <range_timestamp> m_timestamp;
+ vec <unsigned> 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)
@@ -618,6 +576,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 ()
@@ -672,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
@@ -718,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;
diff --git a/gcc/gimple-range-gori.cc b/gcc/gimple-range-gori.cc
index 420282d..a4c4bf5 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.
@@ -91,25 +91,11 @@ 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<bitmap> 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 ()
{
+ bitmap_obstack_initialize (&m_bitmaps);
m_def_chain.create (0);
m_def_chain.safe_grow_cleared (num_ssa_names);
m_logical_depth = 0;
@@ -119,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,
@@ -143,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<gphi *>(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
@@ -172,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
@@ -189,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))
@@ -220,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
@@ -264,27 +372,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<bitmap> 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.
@@ -292,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);
}
@@ -300,7 +388,7 @@ gori_map::gori_map ()
gori_map::~gori_map ()
{
- bitmap_obstack_release (&m_bitmaps);
+ m_incoming.release ();
m_outgoing.release ();
}
@@ -309,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.
@@ -334,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
@@ -355,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));
@@ -373,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.
@@ -404,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.
@@ -472,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
@@ -494,24 +571,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
- // which never have their ranges adjusted.
- for (x = 0; x < lim ; x++)
- {
- basic_block bb = BASIC_BLOCK_FOR_FN (cfun, x);
- if (bb)
- m_gori_map->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.
@@ -523,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);
}
@@ -547,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
@@ -557,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
@@ -567,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;
@@ -597,7 +656,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 +694,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)
@@ -818,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;
}
@@ -827,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;
}
@@ -846,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;
}
@@ -861,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
@@ -881,10 +940,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)
@@ -911,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;
}
@@ -958,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))
@@ -1014,18 +1071,9 @@ 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 (m_gori_map->is_export_p (name, e->src)
- || m_gori_map->def_chain_in_export_p (name, e->src));
-}
+ return is_export_p (name);
-// 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);
}
// Dump what is known to GORI computes to listing file F.
@@ -1033,7 +1081,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 +1100,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))
{
@@ -1070,312 +1118,45 @@ gori_compute::outgoing_edge_range_p (irange &r, edge e, tree name)
return false;
}
-// --------------------------------------------------------------------------
-// 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.
+// ------------------------------------------------------------------------
+// GORI iterator. Although we have bitmap iterators, don't expose that it
+// is currently a bitmap. Use an export iterator to hide future changes.
-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<cache_entry *> m_ssa_cache;
-};
+// Construct a basic iterator over an export bitmap.
-logical_stmt_cache::cache_entry::cache_entry (tree name,
- const irange &t_range,
- const irange &f_range)
- : name (name), range (t_range, f_range)
+gori_export_iterator::gori_export_iterator (bitmap b)
{
+ bm = b;
+ if (b)
+ bmp_iter_set_init (&bi, b, 1, &y);
}
-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.
+// Move to the next export bitmap spot.
void
-logical_stmt_cache::set_range (tree lhs, tree name, const tf_range &range)
+gori_export_iterator::next ()
{
- 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;
+ bmp_iter_next (&bi, &y);
}
-// 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.
+// Fetch the name of the next export in the export list. Return NULL if
+// iteration is done.
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)
+gori_export_iterator::get_name ()
{
- 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;
+ if (!bm)
+ return NULL_TREE;
- // 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_in_bb (op2_range, op2, gimple_bb (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))
+ while (bmp_iter_set (&bi, &y))
{
- 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));
+ tree t = ssa_name (y);
+ if (t)
+ return t;
+ next ();
}
+ return NULL_TREE;
}
diff --git a/gcc/gimple-range-gori.h b/gcc/gimple-range-gori.h
index 7bb18a9..f41dee3 100644
--- a/gcc/gimple-range-gori.h
+++ b/gcc/gimple-range-gori.h
@@ -22,6 +22,90 @@ 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 ();
+ 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);
+ bitmap get_imports (tree name);
+ bitmap_obstack m_bitmaps;
+private:
+ struct rdc {
+ tree ssa1; // First direct dependency
+ tree ssa2; // Second direct dependency
+ bitmap bm; // All dependencies
+ bitmap m_import;
+ };
+ vec<rdc> 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.
+
+class gori_map : public range_def_chain
+{
+public:
+ gori_map ();
+ ~gori_map ();
+
+ bool is_export_p (tree name, basic_block bb = NULL);
+ 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, bool verbose = true);
+private:
+ vec<bitmap> m_outgoing; // BB: Outgoing ranges calculatable on edges
+ vec<bitmap> 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);
+};
+
// This class is used to determine which SSA_NAMES can have ranges
// calculated for them on outgoing edges from basic blocks. This represents
@@ -65,21 +149,19 @@ 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);
- 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_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);
@@ -107,36 +189,32 @@ 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.
};
-// 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.
+// 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 ())
-class gori_compute_cache : public gori_compute
-{
+// 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_compute_cache ();
- ~gori_compute_cache ();
+ gori_export_iterator (bitmap b);
+ void next ();
+ tree get_name ();
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;
+ bitmap bm;
+ bitmap_iterator bi;
+ unsigned y;
};
#endif // GCC_GIMPLE_RANGE_GORI_H
diff --git a/gcc/gimple-range.cc b/gcc/gimple-range.cc
index 06e9804..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);
@@ -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..707dcfe 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;
@@ -83,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;
@@ -123,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;
}
@@ -134,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;
}
@@ -143,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;
}
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
diff --git a/gcc/match.pd b/gcc/match.pd
index 1fc6b7b..dd73081 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:
@@ -4834,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/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 <jakub@redhat.com>
+
+ PR c++/100666
+ * g++.dg/cpp1z/nodiscard8.C: New test.
+ * g++.dg/cpp1z/nodiscard9.C: New test.
+
+2021-05-25 Martin Liska <mliska@suse.cz>
+
+ * gcc.dg/sancov/attribute.c: New test.
+
+2021-05-25 Cooper Qu <cooper.qu@linux.alibaba.com>
+
+ * gcc.target/csky/fpuv3/fpuv3.exp : Amend copyright.
+
+2021-05-25 Jakub Jelinek <jakub@redhat.com>
+
+ 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 <gengqi@linux.alibaba.com>
+
+ * 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 <acsawdey@linux.ibm.com>
* gcc.target/powerpc/fusion-p10-logadd.c: New file.
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 <typename T> 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 <typename T> 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'" }
+}
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" } } */
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" } } */
+
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" } } */
+
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
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);
}
diff --git a/libgomp/ChangeLog b/libgomp/ChangeLog
index 8a5289a..accd3df 100644
--- a/libgomp/ChangeLog
+++ b/libgomp/ChangeLog
@@ -1,3 +1,8 @@
+2021-05-25 Jakub Jelinek <jakub@redhat.com>
+
+ PR middle-end/99928
+ * testsuite/libgomp.c-c++-common/reduction-17.c: New test.
+
2021-05-24 Tobias Burnus <tobias@codesourcery.com>
PR fortran/86470
diff --git a/liboffloadmic/ChangeLog b/liboffloadmic/ChangeLog
index c048f91..b027ed7 100644
--- a/liboffloadmic/ChangeLog
+++ b/liboffloadmic/ChangeLog
@@ -1,3 +1,9 @@
+2021-05-25 Richard Biener <rguenther@suse.de>
+
+ PR libgomp/100747
+ * configure: Make executable.
+ * plugin/configure: Likewise.
+
2021-01-05 Samuel Thibault <samuel.thibault@ens-lyon.org>
* configure: Re-generate.