aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2017-06-13 14:26:53 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2017-06-13 14:26:53 +0000
commitfad96109a42625b9c6881e4c1b703b4aee7f64ce (patch)
tree98094fe155b81e6d4c38e19597491ceb91755cdd
parent875d2ea2b87818e1e88b0135796f788e492969d2 (diff)
parent09a871c46619af0461d2c079d4de953745a11b68 (diff)
downloadgcc-fad96109a42625b9c6881e4c1b703b4aee7f64ce.zip
gcc-fad96109a42625b9c6881e4c1b703b4aee7f64ce.tar.gz
gcc-fad96109a42625b9c6881e4c1b703b4aee7f64ce.tar.bz2
Merge from trunk revision 249156.
From-SVN: r249160
-rw-r--r--ChangeLog4
-rw-r--r--fixincludes/ChangeLog5
-rw-r--r--fixincludes/fixincl.x132
-rw-r--r--fixincludes/inclhack.def116
-rw-r--r--gcc/ChangeLog164
-rw-r--r--gcc/DATESTAMP2
-rw-r--r--gcc/ada/ChangeLog11
-rw-r--r--gcc/ada/exp_ch3.adb2
-rw-r--r--gcc/ada/gcc-interface/Makefile.in2
-rw-r--r--gcc/ada/s-interr-hwint.adb1110
-rw-r--r--gcc/cgraph.c35
-rw-r--r--gcc/combine.c2
-rw-r--r--gcc/config.gcc22
-rw-r--r--gcc/config/avr/avr-arch.h19
-rw-r--r--gcc/config/avr/avr-c.c19
-rw-r--r--gcc/config/avr/avr-devices.c50
-rw-r--r--gcc/config/avr/avr-mcus.def17
-rw-r--r--gcc/config/avr/avr.c18
-rw-r--r--gcc/config/avr/avr.h6
-rw-r--r--gcc/config/avr/avr.opt4
-rw-r--r--gcc/config/avr/gen-avr-mmcu-specs.c19
-rw-r--r--gcc/config/avr/genmultilib.awk9
-rw-r--r--gcc/config/avr/t-multilib6
-rw-r--r--gcc/config/sparc/sparc.md5
-rw-r--r--gcc/config/vxworks-stdint.h53
-rwxr-xr-xgcc/configure55
-rw-r--r--gcc/configure.ac36
-rw-r--r--gcc/doc/avr-mmcu.texi4
-rw-r--r--gcc/doc/extend.texi68
-rw-r--r--gcc/doc/invoke.texi34
-rw-r--r--gcc/fold-const.c50
-rw-r--r--gcc/gimple-pretty-print.c22
-rw-r--r--gcc/go/gofrontend/MERGE2
-rw-r--r--gcc/go/gofrontend/expressions.cc12
-rw-r--r--gcc/match.pd28
-rw-r--r--gcc/testsuite/ChangeLog65
-rw-r--r--gcc/testsuite/c-c++-common/fold-masked-cmp-1.c41
-rw-r--r--gcc/testsuite/c-c++-common/fold-masked-cmp-2.c42
-rw-r--r--gcc/testsuite/c-c++-common/fold-masked-cmp-3.c16
-rw-r--r--gcc/testsuite/c-c++-common/ubsan/pr81065.c13
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/pr81003.c10
-rw-r--r--gcc/testsuite/gcc.dg/pr46309-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/pr46309.c2
-rw-r--r--gcc/testsuite/gcc.dg/torture/pr81053.c12
-rw-r--r--gcc/testsuite/gcc.dg/tree-prof/split-1.c6
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-2.c4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/dump-2.c2
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr80803.c72
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/pr81063.c28
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/vrp101.c2
-rw-r--r--gcc/testsuite/gcc.target/aarch64/inline-lrint_1.c6
-rw-r--r--gcc/testsuite/gcc.target/aarch64/inline-lrint_2.c8
-rw-r--r--gcc/testsuite/gcc.target/aarch64/no-inline-lrint_1.c3
-rw-r--r--gcc/testsuite/gcc.target/aarch64/no-inline-lrint_2.c3
-rw-r--r--gcc/testsuite/gcc.target/arm/sdiv_costs_1.c1
-rw-r--r--gcc/tree-profile.c8
-rw-r--r--gcc/tree-sra.c114
-rw-r--r--gcc/tree-ssa-reassoc.c29
-rw-r--r--gcc/tree-vect-loop.c111
-rw-r--r--gcc/tree-vrp.c94
-rw-r--r--libgo/go/runtime/cgo_gccgo.go2
-rw-r--r--libgo/go/runtime/proc.go3
-rw-r--r--libgo/go/runtime/traceback_gccgo.go2
-rw-r--r--libstdc++-v3/ChangeLog41
-rw-r--r--libstdc++-v3/doc/xml/manual/status_cxx2017.xml5
-rw-r--r--libstdc++-v3/include/bits/char_traits.h101
-rw-r--r--libstdc++-v3/include/bits/stl_tree.h15
-rw-r--r--libstdc++-v3/src/c++11/thread.cc30
-rw-r--r--libstdc++-v3/testsuite/21_strings/char_traits/requirements/constexpr_functions_c++17.cc16
-rw-r--r--libstdc++-v3/testsuite/23_containers/map/allocator/default_init.cc67
-rw-r--r--libstdc++-v3/testsuite/23_containers/set/allocator/default_init.cc67
-rw-r--r--libstdc++-v3/testsuite/30_threads/thread/cons/terminate.cc48
-rw-r--r--libstdc++-v3/testsuite/util/testsuite_allocator.h32
73 files changed, 2690 insertions, 576 deletions
diff --git a/ChangeLog b/ChangeLog
index 4794e5e..b6112c7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2017-06-12 Segher Boessenkool <segher@kernel.crashing.org>
+
+ * config.gcc: Remove rs6000/e500.h from tm_file for all targets.
+
2017-06-03 Eric Botcazou <ebotcazou@adacore.com>
* configure.ac (*-*-linux-android*): Set target_makefile_frag.
diff --git a/fixincludes/ChangeLog b/fixincludes/ChangeLog
index 4f729db..ffd1718 100644
--- a/fixincludes/ChangeLog
+++ b/fixincludes/ChangeLog
@@ -1,3 +1,8 @@
+2017-06-12 Doug Rupp <rupp@adacore.com>
+
+ * inclhack.def (AAB_vxworks_stdint): Remove hack.
+ * fixincl.x: Regenerate.
+
2017-02-25 John David Anglin <danglin@gcc.gnu.org>
PR target/68739
diff --git a/fixincludes/fixincl.x b/fixincludes/fixincl.x
index c5be74f..8d8be9c 100644
--- a/fixincludes/fixincl.x
+++ b/fixincludes/fixincl.x
@@ -1,12 +1,12 @@
/* -*- buffer-read-only: t -*- vi: set ro:
- *
+ *
* DO NOT EDIT THIS FILE (fixincl.x)
- *
- * It has been AutoGen-ed Saturday February 25, 2017 at 03:25:44 PM EST
+ *
+ * It has been AutoGen-ed June 8, 2017 at 10:50:04 AM by AutoGen 5.18.4
* From the definitions inclhack.def
* and the template file fixincl
*/
-/* DO NOT SVN-MERGE THIS FILE, EITHER Sat 25 Feb 2017 15:25:44 EST
+/* DO NOT SVN-MERGE THIS FILE, EITHER Thu Jun 8 10:50:04 CEST 2017
*
* You must regenerate it. Use the ./genfixes script.
*
@@ -15,7 +15,7 @@
* certain ANSI-incompatible system header files which are fixed to work
* correctly with ANSI C and placed in a directory that GNU C will search.
*
- * This file contains 248 fixup descriptions.
+ * This file contains 247 fixup descriptions.
*
* See README for more information.
*
@@ -581,120 +581,6 @@ static const char* apzAab_Vxworks_Regs_VxtypesPatch[] = {
/* * * * * * * * * * * * * * * * * * * * * * * * * *
*
- * Description of Aab_Vxworks_Stdint fix
- */
-tSCC zAab_Vxworks_StdintName[] =
- "AAB_vxworks_stdint";
-
-/*
- * File name selection pattern
- */
-tSCC zAab_Vxworks_StdintList[] =
- "stdint.h\0";
-/*
- * Machine/OS name selection pattern
- */
-tSCC* apzAab_Vxworks_StdintMachs[] = {
- "*-*-vxworks*",
- (const char*)NULL };
-#define AAB_VXWORKS_STDINT_TEST_CT 0
-#define aAab_Vxworks_StdintTests (tTestDesc*)NULL
-
-/*
- * Fix Command Arguments for Aab_Vxworks_Stdint
- */
-static const char* apzAab_Vxworks_StdintPatch[] = {
-"#ifndef _STDINT_H\n\
-#define _STDINT_H\n\
-/* get int*_t, uint*_t */\n\
-#include <types/vxTypes.h>\n\n\
-/* get legacy vxworks types for compatibility */\n\
-#include <types/vxTypesOld.h>\n\n\
-typedef long intptr_t;\n\
-typedef unsigned long uintptr_t;\n\n\
-typedef int64_t intmax_t;\n\
-typedef uint64_t uintmax_t;\n\n\
-typedef int8_t int_least8_t;\n\
-typedef int16_t int_least16_t;\n\
-typedef int32_t int_least32_t;\n\
-typedef int64_t int_least64_t;\n\n\
-typedef uint8_t uint_least8_t;\n\
-typedef uint16_t uint_least16_t;\n\
-typedef uint32_t uint_least32_t;\n\
-typedef uint64_t uint_least64_t;\n\n\
-typedef int8_t int_fast8_t;\n\
-typedef int int_fast16_t;\n\
-typedef int32_t int_fast32_t;\n\
-typedef int64_t int_fast64_t;\n\n\
-typedef uint8_t uint_fast8_t;\n\
-typedef unsigned int uint_fast16_t;\n\
-typedef uint32_t uint_fast32_t;\n\
-typedef uint64_t uint_fast64_t;\n\n\
-/* Ranges */\n\
-#define UINT8_MAX (~(uint8_t)0)\n\
-#define UINT8_MIN 0\n\
-#define UINT16_MAX (~(uint16_t)0)\n\
-#define UINT16_MIN 0\n\
-#define UINT32_MAX (~(uint32_t)0)\n\
-#define UINT32_MIN 0\n\
-#define UINT64_MAX (~(uint64_t)0)\n\
-#define UINT64_MIN 0\n\n\
-#define UINTPTR_MAX (~(uintptr_t)0)\n\
-#define UINTPTR_MIN 0\n\n\
-/* Need to do int_fast16_t as well, as type\n\
- size may be architecture dependent */\n\
-#define UINT_FAST16_MAX (~(uint_fast16_t)0)\n\
-#define UINT_FAST16_MAX 0\n\n\
-#define INT8_MAX (UINT8_MAX>>1)\n\
-#define INT8_MIN (INT8_MAX+1)\n\
-#define INT16_MAX (UINT16_MAX>>1)\n\
-#define INT16_MIN (INT16_MAX+1)\n\
-#define INT32_MAX (UINT32_MAX>>1)\n\
-#define INT32_MIN (INT32_MAX+1)\n\
-#define INT64_MAX (UINT64_MAX>>1)\n\
-#define INT64_MIN (INT64_MAX+1)\n\n\
-#define INTPTR_MAX (UINTPTR_MAX>>1)\n\
-#define INTPTR_MIN (INTPTR_MAX+1)\t\n\n\
-#define INT_FAST16_MAX (UINT_FAST16_MAX>>1)\n\
-#define INT_FAST16_MIN (INT_FAST16_MAX+1)\n\n\
-/* now define equiv. constants */\n\
-#define UINT_FAST8_MAX UINT8_MAX\n\
-#define UINT_FAST8_MIN UINT_FAST8_MIN\n\
-#define INT_FAST8_MAX INT8_MAX\n\
-#define INT_FAST8_MIN INT8_MIN\n\
-#define UINT_FAST32_MAX UINT32_MAX\n\
-#define UINT_FAST32_MIN UINT32_MIN\n\
-#define INT_FAST32_MAX INT32_MAX\n\
-#define INT_FAST32_MIN INT32_MIN\n\
-#define UINT_FAST64_MAX UINT64_MAX\n\
-#define UINT_FAST64_MIN UINT64_MIN\n\
-#define INT_FAST64_MAX INT64_MAX\n\
-#define INT_FAST64_MIN INT64_MIN\n\n\
-#define UINT_LEAST8_MAX UINT8_MAX\n\
-#define UINT_LEAST8_MIN UINT8_MIN\n\
-#define INT_LEAST8_MAX INT8_MAX\n\
-#define INT_LEAST8_MIN INT8_MIN\n\
-#define UINT_LEAST16_MAX UINT16_MAX\n\
-#define UINT_LEAST16_MIN UINT16_MIN\n\
-#define INT_LEAST16_MAX INT16_MAX\n\
-#define INT_LEAST16_MIN INT16_MIN\n\
-#define UINT_LEAST32_MAX UINT32_MAX\n\
-#define UINT_LEAST32_MIN UINT32_MIN\n\
-#define INT_LEAST32_MAX INT32_MAX\n\
-#define INT_LEAST32_MIN INT32_MIN\n\
-#define UINT_LEAST64_MAX UINT64_MAX\n\
-#define UINT_LEAST64_MIN UINT64_MIN\n\
-#define INT_LEAST64_MAX INT64_MAX\n\
-#define INT_LEAST64_MIN INT64_MIN\n\n\
-#define UINTMAX_MAX UINT64_MAX\n\
-#define UINTMAX_MIN UINT64_MIN\n\
-#define INTMAX_MAX INT64_MAX\n\
-#define INTMAX_MIN INT64_MIN\n\n\
-#endif",
- (char*)NULL };
-
-/* * * * * * * * * * * * * * * * * * * * * * * * * *
- *
* Description of Aab_Vxworks_Unistd fix
*/
tSCC zAab_Vxworks_UnistdName[] =
@@ -10141,7 +10027,7 @@ static const char* apzX11_SprintfPatch[] = {
*/
#define REGEX_COUNT 285
#define MACH_LIST_SIZE_LIMIT 187
-#define FIX_COUNT 248
+#define FIX_COUNT 247
/*
* Enumerate the fixes
@@ -10157,7 +10043,6 @@ typedef enum {
AAB_SUN_MEMCPY_FIXIDX,
AAB_VXWORKS_ASSERT_FIXIDX,
AAB_VXWORKS_REGS_VXTYPES_FIXIDX,
- AAB_VXWORKS_STDINT_FIXIDX,
AAB_VXWORKS_UNISTD_FIXIDX,
AIX_ASSERT_FIXIDX,
AIX_COMPLEX_FIXIDX,
@@ -10448,11 +10333,6 @@ tFixDesc fixDescList[ FIX_COUNT ] = {
AAB_VXWORKS_REGS_VXTYPES_TEST_CT, FD_MACH_ONLY | FD_REPLACEMENT,
aAab_Vxworks_Regs_VxtypesTests, apzAab_Vxworks_Regs_VxtypesPatch, 0 },
- { zAab_Vxworks_StdintName, zAab_Vxworks_StdintList,
- apzAab_Vxworks_StdintMachs,
- AAB_VXWORKS_STDINT_TEST_CT, FD_MACH_ONLY | FD_REPLACEMENT,
- aAab_Vxworks_StdintTests, apzAab_Vxworks_StdintPatch, 0 },
-
{ zAab_Vxworks_UnistdName, zAab_Vxworks_UnistdList,
apzAab_Vxworks_UnistdMachs,
AAB_VXWORKS_UNISTD_TEST_CT, FD_MACH_ONLY | FD_REPLACEMENT,
diff --git a/fixincludes/inclhack.def b/fixincludes/inclhack.def
index 8a5514f..fd0034f 100644
--- a/fixincludes/inclhack.def
+++ b/fixincludes/inclhack.def
@@ -427,122 +427,6 @@ fix = {
};
/*
- * Make VxWorks stdint.h a bit more compliant - add typedefs
- */
-fix = {
- hackname = AAB_vxworks_stdint;
- files = stdint.h;
- mach = "*-*-vxworks*";
-
- replace = <<- _EndOfHeader_
- #ifndef _STDINT_H
- #define _STDINT_H
- /* get int*_t, uint*_t */
- #include <types/vxTypes.h>
-
- /* get legacy vxworks types for compatibility */
- #include <types/vxTypesOld.h>
-
- typedef long intptr_t;
- typedef unsigned long uintptr_t;
-
- typedef int64_t intmax_t;
- typedef uint64_t uintmax_t;
-
- typedef int8_t int_least8_t;
- typedef int16_t int_least16_t;
- typedef int32_t int_least32_t;
- typedef int64_t int_least64_t;
-
- typedef uint8_t uint_least8_t;
- typedef uint16_t uint_least16_t;
- typedef uint32_t uint_least32_t;
- typedef uint64_t uint_least64_t;
-
- typedef int8_t int_fast8_t;
- typedef int int_fast16_t;
- typedef int32_t int_fast32_t;
- typedef int64_t int_fast64_t;
-
- typedef uint8_t uint_fast8_t;
- typedef unsigned int uint_fast16_t;
- typedef uint32_t uint_fast32_t;
- typedef uint64_t uint_fast64_t;
-
- /* Ranges */
- #define UINT8_MAX (~(uint8_t)0)
- #define UINT8_MIN 0
- #define UINT16_MAX (~(uint16_t)0)
- #define UINT16_MIN 0
- #define UINT32_MAX (~(uint32_t)0)
- #define UINT32_MIN 0
- #define UINT64_MAX (~(uint64_t)0)
- #define UINT64_MIN 0
-
- #define UINTPTR_MAX (~(uintptr_t)0)
- #define UINTPTR_MIN 0
-
- /* Need to do int_fast16_t as well, as type
- size may be architecture dependent */
- #define UINT_FAST16_MAX (~(uint_fast16_t)0)
- #define UINT_FAST16_MAX 0
-
- #define INT8_MAX (UINT8_MAX>>1)
- #define INT8_MIN (INT8_MAX+1)
- #define INT16_MAX (UINT16_MAX>>1)
- #define INT16_MIN (INT16_MAX+1)
- #define INT32_MAX (UINT32_MAX>>1)
- #define INT32_MIN (INT32_MAX+1)
- #define INT64_MAX (UINT64_MAX>>1)
- #define INT64_MIN (INT64_MAX+1)
-
- #define INTPTR_MAX (UINTPTR_MAX>>1)
- #define INTPTR_MIN (INTPTR_MAX+1)
-
- #define INT_FAST16_MAX (UINT_FAST16_MAX>>1)
- #define INT_FAST16_MIN (INT_FAST16_MAX+1)
-
- /* now define equiv. constants */
- #define UINT_FAST8_MAX UINT8_MAX
- #define UINT_FAST8_MIN UINT_FAST8_MIN
- #define INT_FAST8_MAX INT8_MAX
- #define INT_FAST8_MIN INT8_MIN
- #define UINT_FAST32_MAX UINT32_MAX
- #define UINT_FAST32_MIN UINT32_MIN
- #define INT_FAST32_MAX INT32_MAX
- #define INT_FAST32_MIN INT32_MIN
- #define UINT_FAST64_MAX UINT64_MAX
- #define UINT_FAST64_MIN UINT64_MIN
- #define INT_FAST64_MAX INT64_MAX
- #define INT_FAST64_MIN INT64_MIN
-
- #define UINT_LEAST8_MAX UINT8_MAX
- #define UINT_LEAST8_MIN UINT8_MIN
- #define INT_LEAST8_MAX INT8_MAX
- #define INT_LEAST8_MIN INT8_MIN
- #define UINT_LEAST16_MAX UINT16_MAX
- #define UINT_LEAST16_MIN UINT16_MIN
- #define INT_LEAST16_MAX INT16_MAX
- #define INT_LEAST16_MIN INT16_MIN
- #define UINT_LEAST32_MAX UINT32_MAX
- #define UINT_LEAST32_MIN UINT32_MIN
- #define INT_LEAST32_MAX INT32_MAX
- #define INT_LEAST32_MIN INT32_MIN
- #define UINT_LEAST64_MAX UINT64_MAX
- #define UINT_LEAST64_MIN UINT64_MIN
- #define INT_LEAST64_MAX INT64_MAX
- #define INT_LEAST64_MIN INT64_MIN
-
- #define UINTMAX_MAX UINT64_MAX
- #define UINTMAX_MIN UINT64_MIN
- #define INTMAX_MAX INT64_MAX
- #define INTMAX_MIN INT64_MIN
-
- #endif
- _EndOfHeader_;
-};
-
-/*
* This hack makes makes unistd.h more POSIX-compliant on VxWorks
*/
fix = {
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 192e869..e0a894f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,167 @@
+2017-06-13 Martin Jambor <mjambor@suse.cz>
+
+ PR tree-optimization/80803
+ PR tree-optimization/81063
+ * tree-sra.c (subtree_mark_written_and_enqueue): Move up in the file.
+ (propagate_subaccesses_across_link): Enqueue subtree whenever
+ necessary instead of relying on the caller.
+
+2017-06-13 Martin Jambor <mjambor@suse.cz>
+
+ * tree-sra.c (add_access_to_work_queue): Only enqueue accesses
+ that have a first_link.
+ (sort_and_splice_var_accesses): Do not check first_link before
+ enquing.
+ (subtree_mark_written_and_enqueue): Likewise.
+ (propagate_all_subaccesses): Likewise and do not stop at first
+ parent with a first_link.
+
+2017-06-13 Martin Jambor <mjambor@suse.cz>
+
+ * tree-sra.c (dump_access_tree_1): Fix accidental dumping to stderr
+ instead of f.
+
+2017-06-13 Yury Gribov <tetra2005@gmail.com>
+
+ * match.pd: New pattern.
+
+2017-06-13 Yury Gribov <tetra2005@gmail.com>
+
+ * tree-vrp.c (is_masked_range_test): New function.
+ (register_edge_assert_for): Determine ranges for
+ some bit tests.
+
+2017-06-13 Yury Gribov <tetra2005@gmail.com>
+
+ PR tree-optimization/67328
+ * fold-const.c (maskable_range_p): New function.
+ (build_range_check): Generate bittests if possible.
+
+2017-06-13 Martin Liska <mliska@suse.cz>
+
+ * gimple-pretty-print.c (dump_probability): Add new argument.
+ (dump_edge_probability): Dump both probability and count.
+ (dump_gimple_label): Likewise.
+ (dump_gimple_bb_header): Likewise.
+
+2017-06-13 Georg-Johann Lay <avr@gjlay.de>
+
+ PR target/81072
+ * config/avr/avr-devices.c: Fix indentation.
+ * config/avr/gen-avr-mmcu-specs.c: Dito.
+
+2017-06-13 Richard Biener <rguenther@suse.de>
+
+ * tree-vect-loop.c (vect_model_reduction_cost): Do not fail,
+ instead get vector type from stmt_info.
+ (vectorizable_reduction): Adjust. Remove dead code.
+
+2017-06-13 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/81065
+ * fold-const.c (extract_muldiv_1): Remove bogus distribution
+ case of C * (x * C2 + C3).
+ (fold_addr_of_array_ref_difference): Properly fold index difference.
+
+2017-06-12 David S. Miller <davem@davemloft.net>
+
+ PR target/80968
+ * config/sparc/sparc.md (return expander): Emit frame blockage if
+ function uses alloca.
+
+2017-06-12 Richard Sandiford <richard.sandiford@linaro.org>
+
+ * combine.c (make_field_assignment): Check len rather than the mode
+ precision when calling force_to_mode.
+
+2017-06-12 Georg-Johann Lay <avr@gjlay.de>
+
+ Support multilibs and devices that see flash in RAM address range.
+
+ PR target/81072
+ * config/avr/avr-arch.h (avr_arch_id) <ARCH_AVRXMEGA3>: New enum.
+ (avr_mcu_t) <flash_pm_offset>: New field.
+ (avr_device_specific_features) <AVR_ISA_RCALL>: New enum.
+ * config/avr/avr.h (AVR_SHORT_CALLS): New define.
+ (AVR_HAVE_JMP_CALL): Don't set if AVR_SHORT_CALLS.
+ (AVR_TINY_PM_OFFSET): Remove macro.
+ * config/avr/avr.opt (-mshort-calls): New option.
+ * config/avr/gen-avr-mmcu-specs.c (print_mcu)
+ [*self_spec]: Add / remove -mshort-calls depending on AVR_ISA_RCALL.
+ * config/avr/avr-c.c (avr_cpu_cpp_builtins)
+ <__AVR_SHORT_CALLS__>: Built-in define if AVR_SHORT_CALLS.
+ <__AVR_HAVE_JMP_CALL__>: Use AVR_HAVE_JMP_CALL as condition
+ instead of avr_arch->have_jmp_call.
+ <__AVR_PM_BASE_ADDRESS__>: Built-in define if avr_arch->flash_pm_offset.
+ [AVR_TINY] <__AVR_TINY_PM_BASE_ADDRESS__>: Use
+ avr_arch->flash_pm_offset to define.
+ * config/avr/avr-devices.c (avr_arch_types): Add initializers for
+ new field flash_pm_offset. Add entry for avrxmega3.
+ (avr_texinfo): Add entry for avrxmega3.
+ * config/avr/avr-mcus.def: Add entries for: avrxmega3,
+ attiny212, attiny214,
+ attiny412, attiny414, attiny416, attiny417,
+ attiny814, attiny816, attiny817,
+ attiny1614, attiny1616, attiny1617,
+ attiny3214, attiny3216, attiny3217.
+ * config/avr/avr.c (avr_assemble_integer)[AVR_TINY]: Use
+ avr_arch->flash_pm_offset instead of AVR_TINY_PM_OFFSET.
+ (avr_print_operand_address) [AVR_TINY]: Same.
+ (avr_asm_init_sections) <readonly_data_section>: Only patch
+ callback if avr_arch->flash_pm_offset = 0.
+ (avr_asm_named_section) <avr_need_copy_data_p>: Skip setting it
+ for rodata if avr_arch->flash_pm_offset != 0.
+ (avr_encode_section_info) [AVR_TINY]: Adjust comment.
+ * config/avr/genmultilib.awk (dir_rcall, opt_rcall): New vars.
+ (opts) [AVR_ISA_RCALL]: Append opt_rcall.
+ (m_options): Append opt_rcall.
+ (m_dirnames): Append dir_rcall.
+ * config/avr/t-multilib: Regenerate.
+
+ * configure.ac [target=avr]: Check whether avrxmega3 default
+ linker description file works as needed.
+ * configure: Regenerate.
+ * doc/avr-mmcu.texi: Regenerate.
+ * doc/invoke.texi (AVR Options) <-mshort-calls>: Document it.
+ <__AVR_ARCH__>: Document avrxmega3 and 103.
+ <__AVR_HAVE_JMP_CALL__>: Adjust documentation.
+ <__AVR_SHORT_CALLS__>: Document it.
+ <__AVR_PM_BASE_ADDRESS__>: Document it.
+ * doc/extend.texi (AVR Options) <-mshort-calls>: Document it.
+ (AVR Variable Attributes) <progmem>: Document this is
+ not needed for avrxmega3.
+ (AVR Named Address Spaces) <__flash>: Dito.
+
+2017-06-12 Jan Hubicka <hubicka@ucw.cz>
+
+ * cgraph.c (cgraph_node::dump): Complain about profile insanities.
+
+2017-06-12 Doug Rupp <rupp@adacore.com>
+
+ * config.gcc (*-*-vxworks*): Set use_gcc_stdint to "provide".
+ Append vxworks-stdint.h to the tm_file list.
+ * config/vxworks-stdint.h: New file.
+
+2017-06-12 Martin Liska <mliska@suse.cz>
+
+ PR tree-optimization/81041
+ * tree-profile.c (gimple_gen_ic_func_profiler):
+ Create an extra BB in profile-generate
+ (gimple_gen_time_profiler): Likewise.
+
+2017-06-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/81003
+ * tree-ssa-reassoc.c (force_into_ssa_name): New function.
+ (update_range_test): Use it instead of force_gimple_operand_gsi.
+
+2017-06-12 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/81053
+ * tree-vect-loop.c (vect_is_simple_reduction): Handle PHI
+ with backedge value not defined in loop. Simplify def stmt
+ compute.
+
2017-06-11 Tom de Vries <tom@codesourcery.com>
PR target/79939
diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP
index eed0e9e..0cdf576 100644
--- a/gcc/DATESTAMP
+++ b/gcc/DATESTAMP
@@ -1 +1 @@
-20170612
+20170613
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index e7f2b86..30290fa 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,14 @@
+2017-06-12 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR bootstrap/80897
+ * exp_ch3.adb (Make_Predefined_Primitive_Specs): Use Positive index.
+
+2017-06-12 Eric Botcazou <ebotcazou@adacore.com>
+
+ PR ada/81070
+ * s-interr-hwint.adb: Reinstate.
+ * gcc-interface/Makefile.in (RTEMS): Use it again.
+
2017-06-08 Olivier Hainque <hainque@adacore.com>
* vx_crtbegin_auto.c: Update year in copyright notice.
diff --git a/gcc/ada/exp_ch3.adb b/gcc/ada/exp_ch3.adb
index 6d9bdaa..00d74c5 100644
--- a/gcc/ada/exp_ch3.adb
+++ b/gcc/ada/exp_ch3.adb
@@ -9216,7 +9216,7 @@ package body Exp_Ch3 is
declare
Stream_Op_TSS_Names :
- constant array (Integer range <>) of TSS_Name_Type :=
+ constant array (Positive range <>) of TSS_Name_Type :=
(TSS_Stream_Read,
TSS_Stream_Write,
TSS_Stream_Input,
diff --git a/gcc/ada/gcc-interface/Makefile.in b/gcc/ada/gcc-interface/Makefile.in
index d44d68a..1030a67 100644
--- a/gcc/ada/gcc-interface/Makefile.in
+++ b/gcc/ada/gcc-interface/Makefile.in
@@ -1747,7 +1747,7 @@ ifeq ($(strip $(filter-out rtems%,$(target_os))),)
s-taspri.ads<s-taspri-posix.ads \
s-tpopsp.adb<s-tpopsp-tls.adb \
s-stchop.adb<s-stchop-rtems.adb \
- s-interr.adb<s-interr-vxworks.adb
+ s-interr.adb<s-interr-hwint.adb
endif
# PikeOS
diff --git a/gcc/ada/s-interr-hwint.adb b/gcc/ada/s-interr-hwint.adb
new file mode 100644
index 0000000..8e2950f
--- /dev/null
+++ b/gcc/ada/s-interr-hwint.adb
@@ -0,0 +1,1110 @@
+------------------------------------------------------------------------------
+-- --
+-- GNAT RUN-TIME LIBRARY (GNARL) COMPONENTS --
+-- --
+-- S Y S T E M . I N T E R R U P T S --
+-- --
+-- B o d y --
+-- --
+-- Copyright (C) 1992-2014, Free Software Foundation, Inc. --
+-- --
+-- GNARL is free software; you can redistribute it and/or modify it under --
+-- terms of the GNU General Public License as published by the Free Soft- --
+-- ware Foundation; either version 3, or (at your option) any later ver- --
+-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
+-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
+-- or FITNESS FOR A PARTICULAR PURPOSE. --
+-- --
+-- As a special exception under Section 7 of GPL version 3, you are granted --
+-- additional permissions described in the GCC Runtime Library Exception, --
+-- version 3.1, as published by the Free Software Foundation. --
+-- --
+-- You should have received a copy of the GNU General Public License and --
+-- a copy of the GCC Runtime Library Exception along with this program; --
+-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
+-- <http://www.gnu.org/licenses/>. --
+-- --
+-- GNARL was developed by the GNARL team at Florida State University. --
+-- Extensive contributions were provided by Ada Core Technologies, Inc. --
+-- --
+------------------------------------------------------------------------------
+
+-- Invariants:
+
+-- All user-handlable signals are masked at all times in all tasks/threads
+-- except possibly for the Interrupt_Manager task.
+
+-- When a user task wants to have the effect of masking/unmasking an signal,
+-- it must call Block_Interrupt/Unblock_Interrupt, which will have the effect
+-- of unmasking/masking the signal in the Interrupt_Manager task. These
+-- comments do not apply to vectored hardware interrupts, which may be masked
+-- or unmasked using routined interfaced to the relevant embedded RTOS system
+-- calls.
+
+-- Once we associate a Signal_Server_Task with an signal, the task never goes
+-- away, and we never remove the association. On the other hand, it is more
+-- convenient to terminate an associated Interrupt_Server_Task for a vectored
+-- hardware interrupt (since we use a binary semaphore for synchronization
+-- with the umbrella handler).
+
+-- There is no more than one signal per Signal_Server_Task and no more than
+-- one Signal_Server_Task per signal. The same relation holds for hardware
+-- interrupts and Interrupt_Server_Task's at any given time. That is, only
+-- one non-terminated Interrupt_Server_Task exists for a give interrupt at
+-- any time.
+
+-- Within this package, the lock L is used to protect the various status
+-- tables. If there is a Server_Task associated with a signal or interrupt,
+-- we use the per-task lock of the Server_Task instead so that we protect the
+-- status between Interrupt_Manager and Server_Task. Protection among service
+-- requests are ensured via user calls to the Interrupt_Manager entries.
+
+-- This is reasonably generic version of this package, supporting vectored
+-- hardware interrupts using non-RTOS specific adapter routines which should
+-- easily implemented on any RTOS capable of supporting GNAT.
+
+with Ada.Unchecked_Conversion;
+with Ada.Task_Identification;
+
+with Interfaces.C; use Interfaces.C;
+with System.OS_Interface; use System.OS_Interface;
+with System.Interrupt_Management;
+with System.Task_Primitives.Operations;
+with System.Storage_Elements;
+with System.Tasking.Utilities;
+
+with System.Tasking.Rendezvous;
+pragma Elaborate_All (System.Tasking.Rendezvous);
+
+package body System.Interrupts is
+
+ use Tasking;
+
+ package POP renames System.Task_Primitives.Operations;
+
+ function To_Ada is new Ada.Unchecked_Conversion
+ (System.Tasking.Task_Id, Ada.Task_Identification.Task_Id);
+
+ function To_System is new Ada.Unchecked_Conversion
+ (Ada.Task_Identification.Task_Id, Task_Id);
+
+ -----------------
+ -- Local Tasks --
+ -----------------
+
+ -- WARNING: System.Tasking.Stages performs calls to this task with low-
+ -- level constructs. Do not change this spec without synchronizing it.
+
+ task Interrupt_Manager is
+ entry Detach_Interrupt_Entries (T : Task_Id);
+
+ entry Attach_Handler
+ (New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean;
+ Restoration : Boolean := False);
+
+ entry Exchange_Handler
+ (Old_Handler : out Parameterless_Handler;
+ New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean);
+
+ entry Detach_Handler
+ (Interrupt : Interrupt_ID;
+ Static : Boolean);
+
+ entry Bind_Interrupt_To_Entry
+ (T : Task_Id;
+ E : Task_Entry_Index;
+ Interrupt : Interrupt_ID);
+
+ pragma Interrupt_Priority (System.Interrupt_Priority'First);
+ end Interrupt_Manager;
+
+ task type Interrupt_Server_Task
+ (Interrupt : Interrupt_ID;
+ Int_Sema : Binary_Semaphore_Id)
+ is
+ -- Server task for vectored hardware interrupt handling
+
+ pragma Interrupt_Priority (System.Interrupt_Priority'First + 2);
+ end Interrupt_Server_Task;
+
+ type Interrupt_Task_Access is access Interrupt_Server_Task;
+
+ -------------------------------
+ -- Local Types and Variables --
+ -------------------------------
+
+ type Entry_Assoc is record
+ T : Task_Id;
+ E : Task_Entry_Index;
+ end record;
+
+ type Handler_Assoc is record
+ H : Parameterless_Handler;
+ Static : Boolean; -- Indicates static binding;
+ end record;
+
+ User_Handler : array (Interrupt_ID) of Handler_Assoc :=
+ (others => (null, Static => False));
+ pragma Volatile_Components (User_Handler);
+ -- Holds the protected procedure handler (if any) and its Static
+ -- information for each interrupt or signal. A handler is static iff it
+ -- is specified through the pragma Attach_Handler.
+
+ User_Entry : array (Interrupt_ID) of Entry_Assoc :=
+ (others => (T => Null_Task, E => Null_Task_Entry));
+ pragma Volatile_Components (User_Entry);
+ -- Holds the task and entry index (if any) for each interrupt / signal
+
+ -- Type and Head, Tail of the list containing Registered Interrupt
+ -- Handlers. These definitions are used to register the handlers
+ -- specified by the pragma Interrupt_Handler.
+
+ type Registered_Handler;
+ type R_Link is access all Registered_Handler;
+
+ type Registered_Handler is record
+ H : System.Address := System.Null_Address;
+ Next : R_Link := null;
+ end record;
+
+ Registered_Handler_Head : R_Link := null;
+ Registered_Handler_Tail : R_Link := null;
+
+ Server_ID : array (Interrupt_ID) of System.Tasking.Task_Id :=
+ (others => System.Tasking.Null_Task);
+ pragma Atomic_Components (Server_ID);
+ -- Holds the Task_Id of the Server_Task for each interrupt / signal.
+ -- Task_Id is needed to accomplish locking per interrupt base. Also
+ -- is needed to determine whether to create a new Server_Task.
+
+ Semaphore_ID_Map : array
+ (Interrupt_ID range 0 .. System.OS_Interface.Max_HW_Interrupt) of
+ Binary_Semaphore_Id := (others => 0);
+ -- Array of binary semaphores associated with vectored interrupts. Note
+ -- that the last bound should be Max_HW_Interrupt, but this will raise
+ -- Storage_Error if Num_HW_Interrupts is null so use extra 4 bytes instead.
+
+ Interrupt_Access_Hold : Interrupt_Task_Access;
+ -- Variable for allocating an Interrupt_Server_Task
+
+ Handler_Installed : array (HW_Interrupt) of Boolean := (others => False);
+ -- True if Notify_Interrupt was connected to the interrupt. Handlers can
+ -- be connected but disconnection is not possible on VxWorks. Therefore
+ -- we ensure Notify_Installed is connected at most once.
+
+ -----------------------
+ -- Local Subprograms --
+ -----------------------
+
+ procedure Check_Reserved_Interrupt (Interrupt : Interrupt_ID);
+ -- Check if Id is a reserved interrupt, and if so raise Program_Error
+ -- with an appropriate message, otherwise return.
+
+ procedure Finalize_Interrupt_Servers;
+ -- Unbind the handlers for hardware interrupt server tasks at program
+ -- termination.
+
+ function Is_Registered (Handler : Parameterless_Handler) return Boolean;
+ -- See if Handler has been "pragma"ed using Interrupt_Handler.
+ -- Always consider a null handler as registered.
+
+ procedure Notify_Interrupt (Param : System.Address);
+ pragma Convention (C, Notify_Interrupt);
+ -- Umbrella handler for vectored interrupts (not signals)
+
+ procedure Install_Umbrella_Handler
+ (Interrupt : HW_Interrupt;
+ Handler : System.OS_Interface.Interrupt_Handler);
+ -- Install the runtime umbrella handler for a vectored hardware
+ -- interrupt
+
+ procedure Unimplemented (Feature : String);
+ pragma No_Return (Unimplemented);
+ -- Used to mark a call to an unimplemented function. Raises Program_Error
+ -- with an appropriate message noting that Feature is unimplemented.
+
+ --------------------
+ -- Attach_Handler --
+ --------------------
+
+ -- Calling this procedure with New_Handler = null and Static = True
+ -- means we want to detach the current handler regardless of the previous
+ -- handler's binding status (i.e. do not care if it is a dynamic or static
+ -- handler).
+
+ -- This option is needed so that during the finalization of a PO, we can
+ -- detach handlers attached through pragma Attach_Handler.
+
+ procedure Attach_Handler
+ (New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean := False) is
+ begin
+ Check_Reserved_Interrupt (Interrupt);
+ Interrupt_Manager.Attach_Handler (New_Handler, Interrupt, Static);
+ end Attach_Handler;
+
+ -----------------------------
+ -- Bind_Interrupt_To_Entry --
+ -----------------------------
+
+ -- This procedure raises a Program_Error if it tries to
+ -- bind an interrupt to which an Entry or a Procedure is
+ -- already bound.
+
+ procedure Bind_Interrupt_To_Entry
+ (T : Task_Id;
+ E : Task_Entry_Index;
+ Int_Ref : System.Address)
+ is
+ Interrupt : constant Interrupt_ID :=
+ Interrupt_ID (Storage_Elements.To_Integer (Int_Ref));
+ begin
+ Check_Reserved_Interrupt (Interrupt);
+ Interrupt_Manager.Bind_Interrupt_To_Entry (T, E, Interrupt);
+ end Bind_Interrupt_To_Entry;
+
+ ---------------------
+ -- Block_Interrupt --
+ ---------------------
+
+ procedure Block_Interrupt (Interrupt : Interrupt_ID) is
+ begin
+ Unimplemented ("Block_Interrupt");
+ end Block_Interrupt;
+
+ ------------------------------
+ -- Check_Reserved_Interrupt --
+ ------------------------------
+
+ procedure Check_Reserved_Interrupt (Interrupt : Interrupt_ID) is
+ begin
+ if Is_Reserved (Interrupt) then
+ raise Program_Error with
+ "interrupt" & Interrupt_ID'Image (Interrupt) & " is reserved";
+ else
+ return;
+ end if;
+ end Check_Reserved_Interrupt;
+
+ ---------------------
+ -- Current_Handler --
+ ---------------------
+
+ function Current_Handler
+ (Interrupt : Interrupt_ID) return Parameterless_Handler
+ is
+ begin
+ Check_Reserved_Interrupt (Interrupt);
+
+ -- ??? Since Parameterless_Handler is not Atomic, the current
+ -- implementation is wrong. We need a new service in Interrupt_Manager
+ -- to ensure atomicity.
+
+ return User_Handler (Interrupt).H;
+ end Current_Handler;
+
+ --------------------
+ -- Detach_Handler --
+ --------------------
+
+ -- Calling this procedure with Static = True means we want to Detach the
+ -- current handler regardless of the previous handler's binding status
+ -- (i.e. do not care if it is a dynamic or static handler).
+
+ -- This option is needed so that during the finalization of a PO, we can
+ -- detach handlers attached through pragma Attach_Handler.
+
+ procedure Detach_Handler
+ (Interrupt : Interrupt_ID;
+ Static : Boolean := False)
+ is
+ begin
+ Check_Reserved_Interrupt (Interrupt);
+ Interrupt_Manager.Detach_Handler (Interrupt, Static);
+ end Detach_Handler;
+
+ ------------------------------
+ -- Detach_Interrupt_Entries --
+ ------------------------------
+
+ procedure Detach_Interrupt_Entries (T : Task_Id) is
+ begin
+ Interrupt_Manager.Detach_Interrupt_Entries (T);
+ end Detach_Interrupt_Entries;
+
+ ----------------------
+ -- Exchange_Handler --
+ ----------------------
+
+ -- Calling this procedure with New_Handler = null and Static = True
+ -- means we want to detach the current handler regardless of the previous
+ -- handler's binding status (i.e. we do not care if it is a dynamic or
+ -- static handler).
+
+ -- This option is needed so that during the finalization of a PO, we can
+ -- detach handlers attached through pragma Attach_Handler.
+
+ procedure Exchange_Handler
+ (Old_Handler : out Parameterless_Handler;
+ New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean := False)
+ is
+ begin
+ Check_Reserved_Interrupt (Interrupt);
+ Interrupt_Manager.Exchange_Handler
+ (Old_Handler, New_Handler, Interrupt, Static);
+ end Exchange_Handler;
+
+ --------------
+ -- Finalize --
+ --------------
+
+ procedure Finalize (Object : in out Static_Interrupt_Protection) is
+ begin
+ -- ??? loop to be executed only when we're not doing library level
+ -- finalization, since in this case all interrupt / signal tasks are
+ -- gone.
+
+ if not Interrupt_Manager'Terminated then
+ for N in reverse Object.Previous_Handlers'Range loop
+ Interrupt_Manager.Attach_Handler
+ (New_Handler => Object.Previous_Handlers (N).Handler,
+ Interrupt => Object.Previous_Handlers (N).Interrupt,
+ Static => Object.Previous_Handlers (N).Static,
+ Restoration => True);
+ end loop;
+ end if;
+
+ Tasking.Protected_Objects.Entries.Finalize
+ (Tasking.Protected_Objects.Entries.Protection_Entries (Object));
+ end Finalize;
+
+ --------------------------------
+ -- Finalize_Interrupt_Servers --
+ --------------------------------
+
+ -- Restore default handlers for interrupt servers
+
+ -- This is called by the Interrupt_Manager task when it receives the abort
+ -- signal during program finalization.
+
+ procedure Finalize_Interrupt_Servers is
+ HW_Interrupts : constant Boolean := HW_Interrupt'Last >= 0;
+ begin
+ if HW_Interrupts then
+ for Int in HW_Interrupt loop
+ if Server_ID (Interrupt_ID (Int)) /= null
+ and then
+ not Ada.Task_Identification.Is_Terminated
+ (To_Ada (Server_ID (Interrupt_ID (Int))))
+ then
+ Interrupt_Manager.Attach_Handler
+ (New_Handler => null,
+ Interrupt => Interrupt_ID (Int),
+ Static => True,
+ Restoration => True);
+ end if;
+ end loop;
+ end if;
+ end Finalize_Interrupt_Servers;
+
+ -------------------------------------
+ -- Has_Interrupt_Or_Attach_Handler --
+ -------------------------------------
+
+ function Has_Interrupt_Or_Attach_Handler
+ (Object : access Dynamic_Interrupt_Protection)
+ return Boolean
+ is
+ pragma Unreferenced (Object);
+ begin
+ return True;
+ end Has_Interrupt_Or_Attach_Handler;
+
+ function Has_Interrupt_Or_Attach_Handler
+ (Object : access Static_Interrupt_Protection)
+ return Boolean
+ is
+ pragma Unreferenced (Object);
+ begin
+ return True;
+ end Has_Interrupt_Or_Attach_Handler;
+
+ ----------------------
+ -- Ignore_Interrupt --
+ ----------------------
+
+ procedure Ignore_Interrupt (Interrupt : Interrupt_ID) is
+ begin
+ Unimplemented ("Ignore_Interrupt");
+ end Ignore_Interrupt;
+
+ ----------------------
+ -- Install_Handlers --
+ ----------------------
+
+ procedure Install_Handlers
+ (Object : access Static_Interrupt_Protection;
+ New_Handlers : New_Handler_Array)
+ is
+ begin
+ for N in New_Handlers'Range loop
+
+ -- We need a lock around this ???
+
+ Object.Previous_Handlers (N).Interrupt := New_Handlers (N).Interrupt;
+ Object.Previous_Handlers (N).Static := User_Handler
+ (New_Handlers (N).Interrupt).Static;
+
+ -- We call Exchange_Handler and not directly Interrupt_Manager.
+ -- Exchange_Handler so we get the Is_Reserved check.
+
+ Exchange_Handler
+ (Old_Handler => Object.Previous_Handlers (N).Handler,
+ New_Handler => New_Handlers (N).Handler,
+ Interrupt => New_Handlers (N).Interrupt,
+ Static => True);
+ end loop;
+ end Install_Handlers;
+
+ ---------------------------------
+ -- Install_Restricted_Handlers --
+ ---------------------------------
+
+ procedure Install_Restricted_Handlers
+ (Prio : Any_Priority;
+ Handlers : New_Handler_Array)
+ is
+ pragma Unreferenced (Prio);
+ begin
+ for N in Handlers'Range loop
+ Attach_Handler (Handlers (N).Handler, Handlers (N).Interrupt, True);
+ end loop;
+ end Install_Restricted_Handlers;
+
+ ------------------------------
+ -- Install_Umbrella_Handler --
+ ------------------------------
+
+ procedure Install_Umbrella_Handler
+ (Interrupt : HW_Interrupt;
+ Handler : System.OS_Interface.Interrupt_Handler)
+ is
+ Vec : constant Interrupt_Vector :=
+ Interrupt_Number_To_Vector (int (Interrupt));
+
+ Status : int;
+
+ begin
+ -- Only install umbrella handler when no Ada handler has already been
+ -- installed. Note that the interrupt number is passed as a parameter
+ -- when an interrupt occurs, so the umbrella handler has a different
+ -- wrapper generated by intConnect for each interrupt number.
+
+ if not Handler_Installed (Interrupt) then
+ Status :=
+ Interrupt_Connect (Vec, Handler, System.Address (Interrupt));
+ pragma Assert (Status = 0);
+
+ Handler_Installed (Interrupt) := True;
+ end if;
+ end Install_Umbrella_Handler;
+
+ ----------------
+ -- Is_Blocked --
+ ----------------
+
+ function Is_Blocked (Interrupt : Interrupt_ID) return Boolean is
+ begin
+ Unimplemented ("Is_Blocked");
+ return False;
+ end Is_Blocked;
+
+ -----------------------
+ -- Is_Entry_Attached --
+ -----------------------
+
+ function Is_Entry_Attached (Interrupt : Interrupt_ID) return Boolean is
+ begin
+ Check_Reserved_Interrupt (Interrupt);
+ return User_Entry (Interrupt).T /= Null_Task;
+ end Is_Entry_Attached;
+
+ -------------------------
+ -- Is_Handler_Attached --
+ -------------------------
+
+ function Is_Handler_Attached (Interrupt : Interrupt_ID) return Boolean is
+ begin
+ Check_Reserved_Interrupt (Interrupt);
+ return User_Handler (Interrupt).H /= null;
+ end Is_Handler_Attached;
+
+ ----------------
+ -- Is_Ignored --
+ ----------------
+
+ function Is_Ignored (Interrupt : Interrupt_ID) return Boolean is
+ begin
+ Unimplemented ("Is_Ignored");
+ return False;
+ end Is_Ignored;
+
+ -------------------
+ -- Is_Registered --
+ -------------------
+
+ function Is_Registered (Handler : Parameterless_Handler) return Boolean is
+ type Fat_Ptr is record
+ Object_Addr : System.Address;
+ Handler_Addr : System.Address;
+ end record;
+
+ function To_Fat_Ptr is new Ada.Unchecked_Conversion
+ (Parameterless_Handler, Fat_Ptr);
+
+ Ptr : R_Link;
+ Fat : Fat_Ptr;
+
+ begin
+ if Handler = null then
+ return True;
+ end if;
+
+ Fat := To_Fat_Ptr (Handler);
+
+ Ptr := Registered_Handler_Head;
+ while Ptr /= null loop
+ if Ptr.H = Fat.Handler_Addr then
+ return True;
+ end if;
+
+ Ptr := Ptr.Next;
+ end loop;
+
+ return False;
+ end Is_Registered;
+
+ -----------------
+ -- Is_Reserved --
+ -----------------
+
+ function Is_Reserved (Interrupt : Interrupt_ID) return Boolean is
+ use System.Interrupt_Management;
+ begin
+ return Reserve (System.Interrupt_Management.Interrupt_ID (Interrupt));
+ end Is_Reserved;
+
+ ----------------------
+ -- Notify_Interrupt --
+ ----------------------
+
+ -- Umbrella handler for vectored hardware interrupts (as opposed to signals
+ -- and exceptions). As opposed to the signal implementation, this handler
+ -- is installed in the vector table when the first Ada handler is attached
+ -- to the interrupt. However because VxWorks don't support disconnecting
+ -- handlers, this subprogram always test whether or not an Ada handler is
+ -- effectively attached.
+
+ -- Otherwise, the handler that existed prior to program startup is in the
+ -- vector table. This ensures that handlers installed by the BSP are active
+ -- unless explicitly replaced in the program text.
+
+ -- Each Interrupt_Server_Task has an associated binary semaphore on which
+ -- it pends once it's been started. This routine determines The appropriate
+ -- semaphore and issues a semGive call, waking the server task. When
+ -- a handler is unbound, System.Interrupts.Unbind_Handler issues a
+ -- Binary_Semaphore_Flush, and the server task deletes its semaphore
+ -- and terminates.
+
+ procedure Notify_Interrupt (Param : System.Address) is
+ Interrupt : constant Interrupt_ID := Interrupt_ID (Param);
+ Id : constant Binary_Semaphore_Id := Semaphore_ID_Map (Interrupt);
+ Status : int;
+ begin
+ if Id /= 0 then
+ Status := Binary_Semaphore_Release (Id);
+ pragma Assert (Status = 0);
+ end if;
+ end Notify_Interrupt;
+
+ ---------------
+ -- Reference --
+ ---------------
+
+ function Reference (Interrupt : Interrupt_ID) return System.Address is
+ begin
+ Check_Reserved_Interrupt (Interrupt);
+ return Storage_Elements.To_Address
+ (Storage_Elements.Integer_Address (Interrupt));
+ end Reference;
+
+ --------------------------------
+ -- Register_Interrupt_Handler --
+ --------------------------------
+
+ procedure Register_Interrupt_Handler (Handler_Addr : System.Address) is
+ New_Node_Ptr : R_Link;
+
+ begin
+ -- This routine registers a handler as usable for dynamic interrupt
+ -- handler association. Routines attaching and detaching handlers
+ -- dynamically should determine whether the handler is registered.
+ -- Program_Error should be raised if it is not registered.
+
+ -- Pragma Interrupt_Handler can only appear in a library level PO
+ -- definition and instantiation. Therefore, we do not need to implement
+ -- an unregister operation. Nor do we need to protect the queue
+ -- structure with a lock.
+
+ pragma Assert (Handler_Addr /= System.Null_Address);
+
+ New_Node_Ptr := new Registered_Handler;
+ New_Node_Ptr.H := Handler_Addr;
+
+ if Registered_Handler_Head = null then
+ Registered_Handler_Head := New_Node_Ptr;
+ Registered_Handler_Tail := New_Node_Ptr;
+ else
+ Registered_Handler_Tail.Next := New_Node_Ptr;
+ Registered_Handler_Tail := New_Node_Ptr;
+ end if;
+ end Register_Interrupt_Handler;
+
+ -----------------------
+ -- Unblock_Interrupt --
+ -----------------------
+
+ procedure Unblock_Interrupt (Interrupt : Interrupt_ID) is
+ begin
+ Unimplemented ("Unblock_Interrupt");
+ end Unblock_Interrupt;
+
+ ------------------
+ -- Unblocked_By --
+ ------------------
+
+ function Unblocked_By
+ (Interrupt : Interrupt_ID) return System.Tasking.Task_Id
+ is
+ begin
+ Unimplemented ("Unblocked_By");
+ return Null_Task;
+ end Unblocked_By;
+
+ ------------------------
+ -- Unignore_Interrupt --
+ ------------------------
+
+ procedure Unignore_Interrupt (Interrupt : Interrupt_ID) is
+ begin
+ Unimplemented ("Unignore_Interrupt");
+ end Unignore_Interrupt;
+
+ -------------------
+ -- Unimplemented --
+ -------------------
+
+ procedure Unimplemented (Feature : String) is
+ begin
+ raise Program_Error with Feature & " not implemented on VxWorks";
+ end Unimplemented;
+
+ -----------------------
+ -- Interrupt_Manager --
+ -----------------------
+
+ task body Interrupt_Manager is
+ -- By making this task independent of any master, when the process goes
+ -- away, the Interrupt_Manager will terminate gracefully.
+
+ Ignore : constant Boolean := System.Tasking.Utilities.Make_Independent;
+ pragma Unreferenced (Ignore);
+
+ --------------------
+ -- Local Routines --
+ --------------------
+
+ procedure Bind_Handler (Interrupt : Interrupt_ID);
+ -- This procedure does not do anything if a signal is blocked.
+ -- Otherwise, we have to interrupt Server_Task for status change
+ -- through a wakeup signal.
+
+ procedure Unbind_Handler (Interrupt : Interrupt_ID);
+ -- This procedure does not do anything if a signal is blocked.
+ -- Otherwise, we have to interrupt Server_Task for status change
+ -- through an abort signal.
+
+ procedure Unprotected_Exchange_Handler
+ (Old_Handler : out Parameterless_Handler;
+ New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean;
+ Restoration : Boolean := False);
+
+ procedure Unprotected_Detach_Handler
+ (Interrupt : Interrupt_ID;
+ Static : Boolean);
+
+ ------------------
+ -- Bind_Handler --
+ ------------------
+
+ procedure Bind_Handler (Interrupt : Interrupt_ID) is
+ begin
+ Install_Umbrella_Handler
+ (HW_Interrupt (Interrupt), Notify_Interrupt'Access);
+ end Bind_Handler;
+
+ --------------------
+ -- Unbind_Handler --
+ --------------------
+
+ procedure Unbind_Handler (Interrupt : Interrupt_ID) is
+ Status : int;
+
+ begin
+ -- Flush server task off semaphore, allowing it to terminate
+
+ Status := Binary_Semaphore_Flush (Semaphore_ID_Map (Interrupt));
+ pragma Assert (Status = 0);
+ end Unbind_Handler;
+
+ --------------------------------
+ -- Unprotected_Detach_Handler --
+ --------------------------------
+
+ procedure Unprotected_Detach_Handler
+ (Interrupt : Interrupt_ID;
+ Static : Boolean)
+ is
+ Old_Handler : Parameterless_Handler;
+ begin
+ if User_Entry (Interrupt).T /= Null_Task then
+
+ -- If an interrupt entry is installed raise Program_Error
+ -- (propagate it to the caller).
+
+ raise Program_Error with
+ "an interrupt entry is already installed";
+ end if;
+
+ -- Note : Static = True will pass the following check. This is the
+ -- case when we want to detach a handler regardless of the static
+ -- status of the Current_Handler.
+
+ if not Static and then User_Handler (Interrupt).Static then
+
+ -- Trying to detach a static Interrupt Handler, raise
+ -- Program_Error.
+
+ raise Program_Error with
+ "trying to detach a static Interrupt Handler";
+ end if;
+
+ Old_Handler := User_Handler (Interrupt).H;
+
+ -- The new handler
+
+ User_Handler (Interrupt).H := null;
+ User_Handler (Interrupt).Static := False;
+
+ if Old_Handler /= null then
+ Unbind_Handler (Interrupt);
+ end if;
+ end Unprotected_Detach_Handler;
+
+ ----------------------------------
+ -- Unprotected_Exchange_Handler --
+ ----------------------------------
+
+ procedure Unprotected_Exchange_Handler
+ (Old_Handler : out Parameterless_Handler;
+ New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean;
+ Restoration : Boolean := False)
+ is
+ begin
+ if User_Entry (Interrupt).T /= Null_Task then
+
+ -- If an interrupt entry is already installed, raise
+ -- Program_Error (propagate it to the caller).
+
+ raise Program_Error with "an interrupt is already installed";
+ end if;
+
+ -- Note : A null handler with Static = True will pass the following
+ -- check. This is the case when we want to detach a handler
+ -- regardless of the Static status of Current_Handler.
+
+ -- We don't check anything if Restoration is True, since we may be
+ -- detaching a static handler to restore a dynamic one.
+
+ if not Restoration and then not Static
+ and then (User_Handler (Interrupt).Static
+
+ -- Trying to overwrite a static Interrupt Handler with a dynamic
+ -- Handler
+
+ -- The new handler is not specified as an Interrupt Handler by a
+ -- pragma.
+
+ or else not Is_Registered (New_Handler))
+ then
+ raise Program_Error with
+ "trying to overwrite a static interrupt handler with a "
+ & "dynamic handler";
+ end if;
+
+ -- Save the old handler
+
+ Old_Handler := User_Handler (Interrupt).H;
+
+ -- The new handler
+
+ User_Handler (Interrupt).H := New_Handler;
+
+ if New_Handler = null then
+
+ -- The null handler means we are detaching the handler
+
+ User_Handler (Interrupt).Static := False;
+
+ else
+ User_Handler (Interrupt).Static := Static;
+ end if;
+
+ -- Invoke a corresponding Server_Task if not yet created. Place
+ -- Task_Id info in Server_ID array.
+
+ if New_Handler /= null
+ and then
+ (Server_ID (Interrupt) = Null_Task
+ or else
+ Ada.Task_Identification.Is_Terminated
+ (To_Ada (Server_ID (Interrupt))))
+ then
+ Interrupt_Access_Hold :=
+ new Interrupt_Server_Task (Interrupt, Binary_Semaphore_Create);
+ Server_ID (Interrupt) :=
+ To_System (Interrupt_Access_Hold.all'Identity);
+ end if;
+
+ if (New_Handler = null) and then Old_Handler /= null then
+
+ -- Restore default handler
+
+ Unbind_Handler (Interrupt);
+
+ elsif Old_Handler = null then
+
+ -- Save default handler
+
+ Bind_Handler (Interrupt);
+ end if;
+ end Unprotected_Exchange_Handler;
+
+ -- Start of processing for Interrupt_Manager
+
+ begin
+ loop
+ -- A block is needed to absorb Program_Error exception
+
+ declare
+ Old_Handler : Parameterless_Handler;
+
+ begin
+ select
+ accept Attach_Handler
+ (New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean;
+ Restoration : Boolean := False)
+ do
+ Unprotected_Exchange_Handler
+ (Old_Handler, New_Handler, Interrupt, Static, Restoration);
+ end Attach_Handler;
+
+ or
+ accept Exchange_Handler
+ (Old_Handler : out Parameterless_Handler;
+ New_Handler : Parameterless_Handler;
+ Interrupt : Interrupt_ID;
+ Static : Boolean)
+ do
+ Unprotected_Exchange_Handler
+ (Old_Handler, New_Handler, Interrupt, Static);
+ end Exchange_Handler;
+
+ or
+ accept Detach_Handler
+ (Interrupt : Interrupt_ID;
+ Static : Boolean)
+ do
+ Unprotected_Detach_Handler (Interrupt, Static);
+ end Detach_Handler;
+
+ or
+ accept Bind_Interrupt_To_Entry
+ (T : Task_Id;
+ E : Task_Entry_Index;
+ Interrupt : Interrupt_ID)
+ do
+ -- If there is a binding already (either a procedure or an
+ -- entry), raise Program_Error (propagate it to the caller).
+
+ if User_Handler (Interrupt).H /= null
+ or else User_Entry (Interrupt).T /= Null_Task
+ then
+ raise Program_Error with
+ "a binding for this interrupt is already present";
+ end if;
+
+ User_Entry (Interrupt) := Entry_Assoc'(T => T, E => E);
+
+ -- Indicate the attachment of interrupt entry in the ATCB.
+ -- This is needed so when an interrupt entry task terminates
+ -- the binding can be cleaned. The call to unbinding must be
+ -- make by the task before it terminates.
+
+ T.Interrupt_Entry := True;
+
+ -- Invoke a corresponding Server_Task if not yet created.
+ -- Place Task_Id info in Server_ID array.
+
+ if Server_ID (Interrupt) = Null_Task
+ or else
+ Ada.Task_Identification.Is_Terminated
+ (To_Ada (Server_ID (Interrupt)))
+ then
+ Interrupt_Access_Hold := new Interrupt_Server_Task
+ (Interrupt, Binary_Semaphore_Create);
+ Server_ID (Interrupt) :=
+ To_System (Interrupt_Access_Hold.all'Identity);
+ end if;
+
+ Bind_Handler (Interrupt);
+ end Bind_Interrupt_To_Entry;
+
+ or
+ accept Detach_Interrupt_Entries (T : Task_Id) do
+ for Int in Interrupt_ID'Range loop
+ if not Is_Reserved (Int) then
+ if User_Entry (Int).T = T then
+ User_Entry (Int) :=
+ Entry_Assoc'
+ (T => Null_Task, E => Null_Task_Entry);
+ Unbind_Handler (Int);
+ end if;
+ end if;
+ end loop;
+
+ -- Indicate in ATCB that no interrupt entries are attached
+
+ T.Interrupt_Entry := False;
+ end Detach_Interrupt_Entries;
+ end select;
+
+ exception
+ -- If there is a Program_Error we just want to propagate it to
+ -- the caller and do not want to stop this task.
+
+ when Program_Error =>
+ null;
+
+ when others =>
+ pragma Assert (False);
+ null;
+ end;
+ end loop;
+
+ exception
+ when Standard'Abort_Signal =>
+
+ -- Flush interrupt server semaphores, so they can terminate
+
+ Finalize_Interrupt_Servers;
+ raise;
+ end Interrupt_Manager;
+
+ ---------------------------
+ -- Interrupt_Server_Task --
+ ---------------------------
+
+ -- Server task for vectored hardware interrupt handling
+
+ task body Interrupt_Server_Task is
+ Ignore : constant Boolean := System.Tasking.Utilities.Make_Independent;
+
+ Self_Id : constant Task_Id := Self;
+ Tmp_Handler : Parameterless_Handler;
+ Tmp_ID : Task_Id;
+ Tmp_Entry_Index : Task_Entry_Index;
+ Status : int;
+
+ begin
+ Semaphore_ID_Map (Interrupt) := Int_Sema;
+
+ loop
+ -- Pend on semaphore that will be triggered by the umbrella handler
+ -- when the associated interrupt comes in.
+
+ Status := Binary_Semaphore_Obtain (Int_Sema);
+ pragma Assert (Status = 0);
+
+ if User_Handler (Interrupt).H /= null then
+
+ -- Protected procedure handler
+
+ Tmp_Handler := User_Handler (Interrupt).H;
+ Tmp_Handler.all;
+
+ elsif User_Entry (Interrupt).T /= Null_Task then
+
+ -- Interrupt entry handler
+
+ Tmp_ID := User_Entry (Interrupt).T;
+ Tmp_Entry_Index := User_Entry (Interrupt).E;
+ System.Tasking.Rendezvous.Call_Simple
+ (Tmp_ID, Tmp_Entry_Index, System.Null_Address);
+
+ else
+ -- Semaphore has been flushed by an unbind operation in the
+ -- Interrupt_Manager. Terminate the server task.
+
+ -- Wait for the Interrupt_Manager to complete its work
+
+ POP.Write_Lock (Self_Id);
+
+ -- Unassociate the interrupt handler
+
+ Semaphore_ID_Map (Interrupt) := 0;
+
+ -- Delete the associated semaphore
+
+ Status := Binary_Semaphore_Delete (Int_Sema);
+
+ pragma Assert (Status = 0);
+
+ -- Set status for the Interrupt_Manager
+
+ Server_ID (Interrupt) := Null_Task;
+ POP.Unlock (Self_Id);
+
+ exit;
+ end if;
+ end loop;
+ end Interrupt_Server_Task;
+
+begin
+ -- Get Interrupt_Manager's ID so that Abort_Interrupt can be sent
+
+ Interrupt_Manager_ID := To_System (Interrupt_Manager'Identity);
+end System.Interrupts;
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 213587e..81aed5c 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -2094,7 +2094,7 @@ cgraph_node::dump (FILE *f)
fprintf (f, " Function flags:");
if (count.initialized_p ())
{
- fprintf (f, " profile_count ");
+ fprintf (f, " count: ");
count.dump (f);
}
if (origin)
@@ -2172,10 +2172,13 @@ cgraph_node::dump (FILE *f)
fprintf (f, " Called by: ");
+ profile_count sum = profile_count::zero ();
for (edge = callers; edge; edge = edge->next_caller)
{
fprintf (f, "%s ", edge->caller->dump_name ());
edge->dump_edge_flags (f);
+ if (edge->count.initialized_p ())
+ sum += edge->count;
}
fprintf (f, "\n Calls: ");
@@ -2186,6 +2189,36 @@ cgraph_node::dump (FILE *f)
}
fprintf (f, "\n");
+ if (count.initialized_p ())
+ {
+ bool ok = true;
+ bool min = false;
+ ipa_ref *ref;
+
+ FOR_EACH_ALIAS (this, ref)
+ if (dyn_cast <cgraph_node *> (ref->referring)->count.initialized_p ())
+ sum += dyn_cast <cgraph_node *> (ref->referring)->count;
+
+ if (global.inlined_to
+ || (symtab->state < EXPANSION
+ && ultimate_alias_target () == this && only_called_directly_p ()))
+ ok = !count.differs_from_p (sum);
+ else if (count > profile_count::from_gcov_type (100)
+ && count < sum.apply_scale (99, 100))
+ ok = false, min = true;
+ if (!ok)
+ {
+ fprintf (f, " Invalid sum of caller counts ");
+ sum.dump (f);
+ if (min)
+ fprintf (f, ", should be at most ");
+ else
+ fprintf (f, ", should be ");
+ count.dump (f);
+ fprintf (f, "\n");
+ }
+ }
+
for (edge = indirect_calls; edge; edge = edge->next_callee)
{
if (edge->indirect_info->polymorphic)
diff --git a/gcc/combine.c b/gcc/combine.c
index 39ef3c6..2d49bc2 100644
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -9634,7 +9634,7 @@ make_field_assignment (rtx x)
other, pos),
dest);
src = force_to_mode (src, mode,
- GET_MODE_PRECISION (mode) >= HOST_BITS_PER_WIDE_INT
+ len >= HOST_BITS_PER_WIDE_INT
? HOST_WIDE_INT_M1U
: (HOST_WIDE_INT_1U << len) - 1,
0);
diff --git a/gcc/config.gcc b/gcc/config.gcc
index a311cd95..8b00e66 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -917,6 +917,8 @@ case ${target} in
xm_defines=POSIX
extra_options="${extra_options} vxworks.opt"
extra_objs="$extra_objs vxworks.o"
+ use_gcc_stdint=provide
+ tm_file="${tm_file} vxworks-stdint.h"
case ${enable_threads} in
no) ;;
"" | yes | vxworks) thread_file='vxworks' ;;
@@ -2388,13 +2390,13 @@ powerpc-*-eabispe*)
use_gcc_stdint=wrap
;;
powerpc-*-eabisimaltivec*)
- tm_file="${tm_file} dbxelf.h elfos.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h rs6000/eabisim.h rs6000/eabialtivec.h"
+ tm_file="${tm_file} dbxelf.h elfos.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/eabi.h rs6000/eabisim.h rs6000/eabialtivec.h"
extra_options="${extra_options} rs6000/sysv4.opt"
tmake_file="rs6000/t-fprules rs6000/t-ppcendian rs6000/t-ppccomm"
use_gcc_stdint=wrap
;;
powerpc-*-eabisim*)
- tm_file="${tm_file} dbxelf.h elfos.h usegas.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h rs6000/eabisim.h"
+ tm_file="${tm_file} dbxelf.h elfos.h usegas.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/eabi.h rs6000/eabisim.h"
extra_options="${extra_options} rs6000/sysv4.opt"
tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
use_gcc_stdint=wrap
@@ -2405,7 +2407,7 @@ powerpc-*-elf*)
tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
;;
powerpc-*-eabialtivec*)
- tm_file="${tm_file} dbxelf.h elfos.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h rs6000/eabialtivec.h"
+ tm_file="${tm_file} dbxelf.h elfos.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/eabi.h rs6000/eabialtivec.h"
extra_options="${extra_options} rs6000/sysv4.opt"
tmake_file="rs6000/t-fprules rs6000/t-ppcendian rs6000/t-ppccomm"
use_gcc_stdint=wrap
@@ -2417,7 +2419,7 @@ powerpc-xilinx-eabi*)
use_gcc_stdint=wrap
;;
powerpc-*-eabi*)
- tm_file="${tm_file} dbxelf.h elfos.h usegas.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h"
+ tm_file="${tm_file} dbxelf.h elfos.h usegas.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/eabi.h"
extra_options="${extra_options} rs6000/sysv4.opt"
tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
use_gcc_stdint=wrap
@@ -2428,7 +2430,7 @@ powerpc-*-rtems*spe*)
tmake_file="${tmake_file} powerpcspe/t-fprules powerpcspe/t-rtems powerpcspe/t-ppccomm"
;;
powerpc-*-rtems*)
- tm_file="${tm_file} dbxelf.h elfos.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/eabi.h rs6000/e500.h rs6000/rtems.h rtems.h"
+ tm_file="${tm_file} dbxelf.h elfos.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/eabi.h rs6000/rtems.h rtems.h"
extra_options="${extra_options} rs6000/sysv4.opt"
tmake_file="${tmake_file} rs6000/t-fprules rs6000/t-rtems rs6000/t-ppccomm"
;;
@@ -2544,15 +2546,15 @@ powerpc-wrs-vxworks|powerpc-wrs-vxworksae|powerpc-wrs-vxworksmils)
extra_headers=ppc-asm.h
case ${target} in
*-vxworksmils*)
- tm_file="${tm_file} vx-common.h vxworksae.h rs6000/vxworks.h rs6000/e500.h rs6000/vxworksmils.h"
+ tm_file="${tm_file} vx-common.h vxworksae.h rs6000/vxworks.h rs6000/vxworksmils.h"
tmake_file="${tmake_file} rs6000/t-vxworksmils"
;;
*-vxworksae*)
- tm_file="${tm_file} vx-common.h vxworksae.h rs6000/vxworks.h rs6000/e500.h rs6000/vxworksae.h"
+ tm_file="${tm_file} vx-common.h vxworksae.h rs6000/vxworks.h rs6000/vxworksae.h"
tmake_file="${tmake_file} rs6000/t-vxworksae"
;;
*-vxworks*)
- tm_file="${tm_file} vx-common.h vxworks.h rs6000/vxworks.h rs6000/e500.h"
+ tm_file="${tm_file} vx-common.h vxworks.h rs6000/vxworks.h"
;;
esac
;;
@@ -2571,13 +2573,13 @@ powerpcle-*-elf*)
extra_options="${extra_options} rs6000/sysv4.opt"
;;
powerpcle-*-eabisim*)
- tm_file="${tm_file} dbxelf.h elfos.h usegas.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/sysv4le.h rs6000/eabi.h rs6000/e500.h rs6000/eabisim.h"
+ tm_file="${tm_file} dbxelf.h elfos.h usegas.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/sysv4le.h rs6000/eabi.h rs6000/eabisim.h"
tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
extra_options="${extra_options} rs6000/sysv4.opt"
use_gcc_stdint=wrap
;;
powerpcle-*-eabi*)
- tm_file="${tm_file} dbxelf.h elfos.h usegas.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/sysv4le.h rs6000/eabi.h rs6000/e500.h"
+ tm_file="${tm_file} dbxelf.h elfos.h usegas.h freebsd-spec.h newlib-stdint.h rs6000/sysv4.h rs6000/sysv4le.h rs6000/eabi.h"
tmake_file="rs6000/t-fprules rs6000/t-ppcgas rs6000/t-ppccomm"
extra_options="${extra_options} rs6000/sysv4.opt"
use_gcc_stdint=wrap
diff --git a/gcc/config/avr/avr-arch.h b/gcc/config/avr/avr-arch.h
index 9463735..e38345b 100644
--- a/gcc/config/avr/avr-arch.h
+++ b/gcc/config/avr/avr-arch.h
@@ -41,6 +41,7 @@ enum avr_arch_id
ARCH_AVR6,
ARCH_AVRTINY,
ARCH_AVRXMEGA2,
+ ARCH_AVRXMEGA3,
ARCH_AVRXMEGA4,
ARCH_AVRXMEGA5,
ARCH_AVRXMEGA6,
@@ -86,6 +87,9 @@ typedef struct
/* Default start of data section address for architecture. */
int default_data_section_start;
+ /* Offset where flash memory is seen in RAM address range or 0. */
+ int flash_pm_offset;
+
/* Offset between SFR address and RAM address:
SFR-address = RAM-address - sfr_offset */
int sfr_offset;
@@ -150,7 +154,16 @@ AVR_ERRATA_SKIP
For information please refer the following respective errata links
http://www.atmel.com/dyn/resources/prod_documents/doc2494.pdf
- http://www.atmel.com/dyn/resources/prod_documents/doc1436.pdf */
+ http://www.atmel.com/dyn/resources/prod_documents/doc1436.pdf
+
+AVR_ISA_RCALL
+ Always use RJMP / RCALL and assume JMP / CALL are not available.
+ This affects multilib selection via specs generation and -mshort-calls.
+ Even if a device like ATtiny417 from avrxmega3 supports JMP / CALL, we
+ assume these instructions are not available and we set the built-in
+ macro __AVR_HAVE_JMP_CALL__ accordingly. This macro is used to
+ determine a rough estimate of flash size in libgcc, and AVR-LibC uses
+ this macro to determine vector sizes. */
enum avr_device_specific_features
{
@@ -158,8 +171,10 @@ enum avr_device_specific_features
AVR_ISA_RMW = 0x1, /* device has RMW instructions. */
AVR_SHORT_SP = 0x2, /* Stack Pointer has 8 bits width. */
AVR_ERRATA_SKIP = 0x4, /* device has a core erratum. */
- AVR_ISA_LDS = 0x8 /* whether LDS / STS is valid for all data in static
+ AVR_ISA_LDS = 0x8, /* whether LDS / STS is valid for all data in static
storage. Only useful for reduced Tiny. */
+ AVR_ISA_RCALL = 0x10 /* Use RJMP / RCALL even though JMP / CALL
+ are available (-mshort-calls). */
};
/* Map architecture to its texinfo string. */
diff --git a/gcc/config/avr/avr-c.c b/gcc/config/avr/avr-c.c
index 9a3a190..81ffc4e 100644
--- a/gcc/config/avr/avr-c.c
+++ b/gcc/config/avr/avr-c.c
@@ -313,11 +313,16 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile)
cpp_define (pfile, "__AVR_ENHANCED__");
cpp_define (pfile, "__AVR_HAVE_MUL__");
}
+
+ if (AVR_HAVE_JMP_CALL)
+ cpp_define (pfile, "__AVR_HAVE_JMP_CALL__");
+
if (avr_arch->have_jmp_call)
- {
- cpp_define (pfile, "__AVR_MEGA__");
- cpp_define (pfile, "__AVR_HAVE_JMP_CALL__");
- }
+ cpp_define (pfile, "__AVR_MEGA__");
+
+ if (AVR_SHORT_CALLS)
+ cpp_define (pfile, "__AVR_SHORT_CALLS__");
+
if (AVR_XMEGA)
cpp_define (pfile, "__AVR_XMEGA__");
@@ -335,9 +340,13 @@ avr_cpu_cpp_builtins (struct cpp_reader *pfile)
(ATtiny4/5/9/10/20 and 40) mapped program memory starts at 0x4000. */
cpp_define_formatted (pfile, "__AVR_TINY_PM_BASE_ADDRESS__=0x%x",
- AVR_TINY_PM_OFFSET);
+ avr_arch->flash_pm_offset);
}
+ if (avr_arch->flash_pm_offset)
+ cpp_define_formatted (pfile, "__AVR_PM_BASE_ADDRESS__=0x%x",
+ avr_arch->flash_pm_offset);
+
if (AVR_HAVE_EIJMP_EICALL)
{
cpp_define (pfile, "__AVR_HAVE_EIJMP_EICALL__");
diff --git a/gcc/config/avr/avr-devices.c b/gcc/config/avr/avr-devices.c
index ad92e97..c391ef9 100644
--- a/gcc/config/avr/avr-devices.c
+++ b/gcc/config/avr/avr-devices.c
@@ -34,30 +34,31 @@ const avr_arch_t
avr_arch_types[] =
{
/* unknown device specified */
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, NULL, AVR_MMCU_DEFAULT },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 0, 32, NULL, AVR_MMCU_DEFAULT },
/*
- A M J LM E E E X R T d S S O A
- S U M PO L L I M A I a t F ff r
- M L P MV P P J E M N t a R s c
- XW M M M G P Y a r e h
- X P A D t t ID */
- { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, "1", "avr1" },
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, "2", "avr2" },
- { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0x0060, 32, "25", "avr25" },
- { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0x0060, 32, "3", "avr3" },
- { 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0x0060, 32, "31", "avr31" },
- { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0x0060, 32, "35", "avr35" },
- { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0x0060, 32, "4", "avr4" },
- { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0x0060, 32, "5", "avr5" },
- { 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0x0060, 32, "51", "avr51" },
- { 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0x0060, 32, "6", "avr6" },
-
- { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0x0040, 0, "100", "avrtiny" },
- { 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0x2000, 0, "102", "avrxmega2" },
- { 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0x2000, 0, "104", "avrxmega4" },
- { 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0x2000, 0, "105", "avrxmega5" },
- { 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0x2000, 0, "106", "avrxmega6" },
- { 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0x2000, 0, "107", "avrxmega7" }
+ A M J LM E E E X R T d S FPO S O A
+ S U M PO L L I M A I a t lMff F ff r
+ M L P MV P P J E M N t a a s R s c
+ XW M M M G P Y a r s e e h
+ X P A D t h t t ID */
+ { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 0, 32, "1", "avr1" },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x0060, 0, 32, "2", "avr2" },
+ { 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0x0060, 0, 32, "25", "avr25" },
+ { 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0x0060, 0, 32, "3", "avr3" },
+ { 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0x0060, 0, 32, "31", "avr31" },
+ { 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0x0060, 0, 32, "35", "avr35" },
+ { 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0x0060, 0, 32, "4", "avr4" },
+ { 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0x0060, 0, 32, "5", "avr5" },
+ { 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0x0060, 0, 32, "51", "avr51" },
+ { 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0x0060, 0, 32, "6", "avr6" },
+
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0x0040, 0x4000, 0, "100", "avrtiny" },
+ { 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0x2000, 0, 0, "102", "avrxmega2" },
+ { 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0x2000, 0x8000, 0, "103", "avrxmega3" },
+ { 0, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0x2000, 0, 0, "104", "avrxmega4" },
+ { 0, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0x2000, 0, 0, "105", "avrxmega5" },
+ { 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0x2000, 0, 0, "106", "avrxmega6" },
+ { 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0x2000, 0, 0, "107", "avrxmega7" }
};
const avr_arch_info_t
@@ -95,6 +96,9 @@ avr_texinfo[] =
{ ARCH_AVRXMEGA2,
"``XMEGA'' devices with more than 8@tie{}KiB and up to 64@tie{}KiB "
"of program memory." },
+ { ARCH_AVRXMEGA3,
+ "``XMEGA'' devices with up to 64@tie{}KiB of combined program memory "
+ "and RAM, and with program memory visible in the RAM address space." },
{ ARCH_AVRXMEGA4,
"``XMEGA'' devices with more than 64@tie{}KiB and up to 128@tie{}KiB "
"of program memory." },
diff --git a/gcc/config/avr/avr-mcus.def b/gcc/config/avr/avr-mcus.def
index 68d0d81..08a8b69 100644
--- a/gcc/config/avr/avr-mcus.def
+++ b/gcc/config/avr/avr-mcus.def
@@ -299,6 +299,23 @@ AVR_MCU ("atxmega16c4", ARCH_AVRXMEGA2, AVR_ISA_RMW, "__AVR_ATxmega16C4__"
AVR_MCU ("atxmega32a4u", ARCH_AVRXMEGA2, AVR_ISA_RMW, "__AVR_ATxmega32A4U__", 0x2000, 0x0, 0x9000)
AVR_MCU ("atxmega32c4", ARCH_AVRXMEGA2, AVR_ISA_RMW, "__AVR_ATxmega32C4__", 0x2000, 0x0, 0x9000)
AVR_MCU ("atxmega32e5", ARCH_AVRXMEGA2, AVR_ISA_NONE, "__AVR_ATxmega32E5__", 0x2000, 0x0, 0x9000)
+/* Xmega, Flash + RAM < 64K, flash visible in RAM address space */
+AVR_MCU ("avrxmega3", ARCH_AVRXMEGA3, AVR_ISA_NONE, NULL, 0x3f00, 0x0, 0x8000)
+AVR_MCU ("attiny212", ARCH_AVRXMEGA3, AVR_ISA_RCALL, "__AVR_ATtiny212__", 0x3f80, 0x0, 0x800)
+AVR_MCU ("attiny214", ARCH_AVRXMEGA3, AVR_ISA_RCALL, "__AVR_ATtiny214__", 0x3f80, 0x0, 0x800)
+AVR_MCU ("attiny412", ARCH_AVRXMEGA3, AVR_ISA_RCALL, "__AVR_ATtiny412__", 0x3f00, 0x0, 0x1000)
+AVR_MCU ("attiny414", ARCH_AVRXMEGA3, AVR_ISA_RCALL, "__AVR_ATtiny414__", 0x3f00, 0x0, 0x1000)
+AVR_MCU ("attiny416", ARCH_AVRXMEGA3, AVR_ISA_RCALL, "__AVR_ATtiny416__", 0x3f00, 0x0, 0x1000)
+AVR_MCU ("attiny417", ARCH_AVRXMEGA3, AVR_ISA_RCALL, "__AVR_ATtiny417__", 0x3f00, 0x0, 0x1000)
+AVR_MCU ("attiny814", ARCH_AVRXMEGA3, AVR_ISA_RCALL, "__AVR_ATtiny814__", 0x3e00, 0x0, 0x2000)
+AVR_MCU ("attiny816", ARCH_AVRXMEGA3, AVR_ISA_RCALL, "__AVR_ATtiny816__", 0x3e00, 0x0, 0x2000)
+AVR_MCU ("attiny817", ARCH_AVRXMEGA3, AVR_ISA_RCALL, "__AVR_ATtiny817__", 0x3e00, 0x0, 0x2000)
+AVR_MCU ("attiny1614", ARCH_AVRXMEGA3, AVR_ISA_NONE, "__AVR_ATtiny1614__", 0x3800, 0x0, 0x4000)
+AVR_MCU ("attiny1616", ARCH_AVRXMEGA3, AVR_ISA_NONE, "__AVR_ATtiny1616__", 0x3800, 0x0, 0x4000)
+AVR_MCU ("attiny1617", ARCH_AVRXMEGA3, AVR_ISA_NONE, "__AVR_ATtiny1617__", 0x3800, 0x0, 0x4000)
+AVR_MCU ("attiny3214", ARCH_AVRXMEGA3, AVR_ISA_NONE, "__AVR_ATtiny3214__", 0x3800, 0x0, 0x8000)
+AVR_MCU ("attiny3216", ARCH_AVRXMEGA3, AVR_ISA_NONE, "__AVR_ATtiny3216__", 0x3800, 0x0, 0x8000)
+AVR_MCU ("attiny3217", ARCH_AVRXMEGA3, AVR_ISA_NONE, "__AVR_ATtiny3217__", 0x3800, 0x0, 0x8000)
/* Xmega, 64K < Flash <= 128K, RAM <= 64K */
AVR_MCU ("avrxmega4", ARCH_AVRXMEGA4, AVR_ISA_NONE, NULL, 0x2000, 0x0, 0x11000)
AVR_MCU ("atxmega64a3", ARCH_AVRXMEGA4, AVR_ISA_NONE, "__AVR_ATxmega64A3__", 0x2000, 0x0, 0x11000)
diff --git a/gcc/config/avr/avr.c b/gcc/config/avr/avr.c
index 648a125..4f385d5 100644
--- a/gcc/config/avr/avr.c
+++ b/gcc/config/avr/avr.c
@@ -2502,7 +2502,7 @@ avr_print_operand_address (FILE *file, machine_mode /*mode*/, rtx addr)
if (AVR_TINY
&& avr_address_tiny_pm_p (addr))
{
- addr = plus_constant (Pmode, addr, AVR_TINY_PM_OFFSET);
+ addr = plus_constant (Pmode, addr, avr_arch->flash_pm_offset);
}
switch (GET_CODE (addr))
@@ -9398,7 +9398,7 @@ avr_assemble_integer (rtx x, unsigned int size, int aligned_p)
if (AVR_TINY
&& avr_address_tiny_pm_p (x))
{
- x = plus_constant (Pmode, x, AVR_TINY_PM_OFFSET);
+ x = plus_constant (Pmode, x, avr_arch->flash_pm_offset);
}
return default_assemble_integer (x, size, aligned_p);
@@ -9998,9 +9998,11 @@ static void
avr_asm_init_sections (void)
{
/* Override section callbacks to keep track of `avr_need_clear_bss_p'
- resp. `avr_need_copy_data_p'. */
+ resp. `avr_need_copy_data_p'. If flash is not mapped to RAM then
+ we have also to track .rodata because it is located in RAM then. */
- readonly_data_section->unnamed.callback = avr_output_data_section_asm_op;
+ if (0 == avr_arch->flash_pm_offset)
+ readonly_data_section->unnamed.callback = avr_output_data_section_asm_op;
data_section->unnamed.callback = avr_output_data_section_asm_op;
bss_section->unnamed.callback = avr_output_bss_section_asm_op;
}
@@ -10032,9 +10034,13 @@ avr_asm_named_section (const char *name, unsigned int flags, tree decl)
if (!avr_need_copy_data_p)
avr_need_copy_data_p = (STR_PREFIX_P (name, ".data")
- || STR_PREFIX_P (name, ".rodata")
|| STR_PREFIX_P (name, ".gnu.linkonce.d"));
+ if (!avr_need_copy_data_p
+ && 0 == avr_arch->flash_pm_offset)
+ avr_need_copy_data_p = (STR_PREFIX_P (name, ".rodata")
+ || STR_PREFIX_P (name, ".gnu.linkonce.r"));
+
if (!avr_need_clear_bss_p)
avr_need_clear_bss_p = STR_PREFIX_P (name, ".bss");
@@ -10201,7 +10207,7 @@ avr_encode_section_info (tree decl, rtx rtl, int new_decl_p)
if (progmem_p)
{
- // Tag symbols for later addition of 0x4000 (AVR_TINY_PM_OFFSET).
+ // Tag symbols for addition of 0x4000 (avr_arch->flash_pm_offset).
SYMBOL_REF_FLAGS (sym) |= AVR_SYMBOL_FLAG_TINY_PM;
}
diff --git a/gcc/config/avr/avr.h b/gcc/config/avr/avr.h
index 3dfa8c3..3158887 100644
--- a/gcc/config/avr/avr.h
+++ b/gcc/config/avr/avr.h
@@ -60,7 +60,9 @@ enum
#define TARGET_CPU_CPP_BUILTINS() avr_cpu_cpp_builtins (pfile)
-#define AVR_HAVE_JMP_CALL (avr_arch->have_jmp_call)
+#define AVR_SHORT_CALLS (TARGET_SHORT_CALLS \
+ && avr_arch == &avr_arch_types[ARCH_AVRXMEGA3])
+#define AVR_HAVE_JMP_CALL (avr_arch->have_jmp_call && ! AVR_SHORT_CALLS)
#define AVR_HAVE_MUL (avr_arch->have_mul)
#define AVR_HAVE_MOVW (avr_arch->have_movw_lpmx)
#define AVR_HAVE_LPM (!AVR_TINY)
@@ -74,8 +76,6 @@ enum
|| avr_arch->have_rampd)
#define AVR_HAVE_EIJMP_EICALL (avr_arch->have_eijmp_eicall)
-#define AVR_TINY_PM_OFFSET (0x4000)
-
/* Handling of 8-bit SP versus 16-bit SP is as follows:
FIXME: DRIVER_SELF_SPECS has changed.
diff --git a/gcc/config/avr/avr.opt b/gcc/config/avr/avr.opt
index a1edec9..1efb1c0 100644
--- a/gcc/config/avr/avr.opt
+++ b/gcc/config/avr/avr.opt
@@ -44,6 +44,10 @@ Target Report Undocumented Mask(ALL_DEBUG)
mlog=
Target RejectNegative Joined Undocumented Var(avr_log_details)
+mshort-calls
+Target Report RejectNegative Mask(SHORT_CALLS)
+Use RJMP / RCALL even though CALL / JMP are available.
+
mint8
Target Report Mask(INT8)
Use an 8-bit 'int' type.
diff --git a/gcc/config/avr/gen-avr-mmcu-specs.c b/gcc/config/avr/gen-avr-mmcu-specs.c
index 4cf9114..db17eeb 100644
--- a/gcc/config/avr/gen-avr-mmcu-specs.c
+++ b/gcc/config/avr/gen-avr-mmcu-specs.c
@@ -113,6 +113,7 @@ static void
print_mcu (const avr_mcu_t *mcu)
{
const char *sp8_spec;
+ const char *rcall_spec;
const avr_mcu_t *arch_mcu;
const avr_arch_t *arch;
enum avr_arch_id arch_id = mcu->arch_id;
@@ -134,6 +135,7 @@ print_mcu (const avr_mcu_t *mcu)
bool errata_skip = 0 != (mcu->dev_attribute & AVR_ERRATA_SKIP);
bool rmw = 0 != (mcu->dev_attribute & AVR_ISA_RMW);
bool sp8 = 0 != (mcu->dev_attribute & AVR_SHORT_SP);
+ bool rcall = (mcu->dev_attribute & AVR_ISA_RCALL);
bool is_arch = NULL == mcu->macro;
bool is_device = ! is_arch;
@@ -150,13 +152,25 @@ print_mcu (const avr_mcu_t *mcu)
sp8_spec = sp8 ? "-msp8" :"%<msp8";
}
+ if (is_arch
+ && ARCH_AVRXMEGA3 == arch_id)
+ {
+ // Leave "avrxmega3" alone. This architectures is the only one
+ // that mixes devices with and without JMP / CALL.
+ rcall_spec = "";
+ }
+ else
+ {
+ rcall_spec = rcall ? "-mshort-calls" : "%<mshort-calls";
+ }
+
fprintf (f, "#\n"
"# Auto-generated specs for AVR ");
if (is_arch)
fprintf (f, "core architecture %s\n", arch->name);
else
- fprintf (f, "device %s (core %s, %d-bit SP)\n",
- mcu->name, arch->name, sp8 ? 8 : 16);
+ fprintf (f, "device %s (core %s, %d-bit SP%s)\n", mcu->name,
+ arch->name, sp8 ? 8 : 16, rcall ? ", short-calls" : "");
fprintf (f, "%s\n", header);
if (is_device)
@@ -255,6 +269,7 @@ print_mcu (const avr_mcu_t *mcu)
{
fprintf (f, "*self_spec:\n");
fprintf (f, "\t%%{!mmcu=avr*: %%<mmcu=* -mmcu=%s} ", arch->name);
+ fprintf (f, "%s ", rcall_spec);
fprintf (f, "%s\n\n", sp8_spec);
#if defined (WITH_AVRLIBC)
diff --git a/gcc/config/avr/genmultilib.awk b/gcc/config/avr/genmultilib.awk
index 2451087..e657e55 100644
--- a/gcc/config/avr/genmultilib.awk
+++ b/gcc/config/avr/genmultilib.awk
@@ -35,6 +35,9 @@ BEGIN {
dir_tiny = "tiny-stack"
opt_tiny = "msp8"
+ dir_rcall = "short-calls"
+ opt_rcall = "mshort-calls"
+
# awk Variable Makefile Variable
# ------------------------------------------
# m_options <-> MULTILIB_OPTIONS
@@ -116,6 +119,8 @@ BEGIN {
{
if (dev_attribute[i] == "AVR_SHORT_SP")
opts = opts "/" opt_tiny
+ if (dev_attribute[i] == "AVR_ISA_RCALL")
+ opts = opts "/" opt_rcall
}
if (!have[opts])
@@ -140,7 +145,7 @@ END {
# Intended Target: ./gcc/config/avr/t-multilib
- print m_options " " opt_tiny
- print m_dirnames " " dir_tiny
+ print m_options " " opt_tiny " " opt_rcall
+ print m_dirnames " " dir_tiny " " dir_rcall
print m_required
}
diff --git a/gcc/config/avr/t-multilib b/gcc/config/avr/t-multilib
index dbbf3bc..6a6eebc 100644
--- a/gcc/config/avr/t-multilib
+++ b/gcc/config/avr/t-multilib
@@ -21,9 +21,9 @@
# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>.
-MULTILIB_OPTIONS = mmcu=avr2/mmcu=avr25/mmcu=avr3/mmcu=avr31/mmcu=avr35/mmcu=avr4/mmcu=avr5/mmcu=avr51/mmcu=avr6/mmcu=avrxmega2/mmcu=avrxmega4/mmcu=avrxmega5/mmcu=avrxmega6/mmcu=avrxmega7/mmcu=avrtiny msp8
+MULTILIB_OPTIONS = mmcu=avr2/mmcu=avr25/mmcu=avr3/mmcu=avr31/mmcu=avr35/mmcu=avr4/mmcu=avr5/mmcu=avr51/mmcu=avr6/mmcu=avrxmega2/mmcu=avrxmega3/mmcu=avrxmega4/mmcu=avrxmega5/mmcu=avrxmega6/mmcu=avrxmega7/mmcu=avrtiny msp8 mshort-calls
-MULTILIB_DIRNAMES = avr2 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega2 avrxmega4 avrxmega5 avrxmega6 avrxmega7 avrtiny tiny-stack
+MULTILIB_DIRNAMES = avr2 avr25 avr3 avr31 avr35 avr4 avr5 avr51 avr6 avrxmega2 avrxmega3 avrxmega4 avrxmega5 avrxmega6 avrxmega7 avrtiny tiny-stack short-calls
MULTILIB_REQUIRED = \
msp8 \
@@ -37,6 +37,8 @@ MULTILIB_REQUIRED = \
mmcu=avr51 \
mmcu=avr6 \
mmcu=avrxmega2 \
+ mmcu=avrxmega3/mshort-calls \
+ mmcu=avrxmega3 \
mmcu=avrxmega4 \
mmcu=avrxmega5 \
mmcu=avrxmega6 \
diff --git a/gcc/config/sparc/sparc.md b/gcc/config/sparc/sparc.md
index 737bdb3..5c5096b 100644
--- a/gcc/config/sparc/sparc.md
+++ b/gcc/config/sparc/sparc.md
@@ -7098,7 +7098,10 @@
(define_expand "return"
[(return)]
"sparc_can_use_return_insn_p ()"
- "")
+{
+ if (cfun->calls_alloca)
+ emit_insn (gen_frame_blockage ());
+})
(define_insn "*return_internal"
[(return)]
diff --git a/gcc/config/vxworks-stdint.h b/gcc/config/vxworks-stdint.h
new file mode 100644
index 0000000..2595e83
--- /dev/null
+++ b/gcc/config/vxworks-stdint.h
@@ -0,0 +1,53 @@
+/* Definitions for <stdint.h> types on systems using VxWorks.
+ Copyright (C) 2017 Free Software Foundation, Inc.
+
+This file is part of GCC.
+
+GCC is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 3, or (at your option)
+any later version.
+
+GCC is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+Under Section 7 of GPL version 3, you are granted additional
+permissions described in the GCC Runtime Library Exception, version
+3.1, as published by the Free Software Foundation.
+
+You should have received a copy of the GNU General Public License and
+a copy of the GCC Runtime Library Exception along with this program;
+see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
+<http://www.gnu.org/licenses/>. */
+
+#define SIG_ATOMIC_TYPE "unsigned char"
+
+#define INT8_TYPE "signed char"
+#define INT16_TYPE "short int"
+#define INT32_TYPE "int"
+#define INT64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "long long int")
+#define UINT8_TYPE "unsigned char"
+#define UINT16_TYPE "short unsigned int"
+#define UINT32_TYPE "unsigned int"
+#define UINT64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "long long unsigned int")
+#define INT_LEAST8_TYPE "signed char"
+#define INT_LEAST16_TYPE "short int"
+#define INT_LEAST32_TYPE "int"
+#define INT_LEAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "long long int")
+#define UINT_LEAST8_TYPE "unsigned char"
+#define UINT_LEAST16_TYPE "short unsigned int"
+#define UINT_LEAST32_TYPE "unsigned int"
+#define UINT_LEAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "long long unsigned int")
+#define INT_FAST8_TYPE "signed char"
+#define INT_FAST16_TYPE "int"
+#define INT_FAST32_TYPE "int"
+#define INT_FAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "long long int")
+#define UINT_FAST8_TYPE "unsigned char"
+#define UINT_FAST16_TYPE "unsigned int"
+#define UINT_FAST32_TYPE "unsigned int"
+#define UINT_FAST64_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "long long unsigned int")
+
+#define INTPTR_TYPE (LONG_TYPE_SIZE == 64 ? "long int" : "int")
+#define UINTPTR_TYPE (LONG_TYPE_SIZE == 64 ? "long unsigned int" : "unsigned int")
diff --git a/gcc/configure b/gcc/configure
index c823ffe..cc542ac 100755
--- a/gcc/configure
+++ b/gcc/configure
@@ -24819,6 +24819,61 @@ $as_echo "#define HAVE_AS_AVR_MRMW_OPTION 1" >>confdefs.h
fi
+
+ # Check how default linker description file implements .rodata for
+ # avrxmega3 (PR21472). avr-gcc assumes .rodata is *not* loaded to
+ # RAM so avr-gcc skips __do_copy_data for .rodata objects.
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking binutils for avrxmega3 .rodata support" >&5
+$as_echo_n "checking binutils for avrxmega3 .rodata support... " >&6; }
+ cat > conftest.s <<EOF
+ .section .rodata,"a",@progbits
+ .global xxvaryy
+ ;; avr-nm should print "... R xxvaryy", not "... D xxvaryy".
+ xxvaryy:
+ .word 1
+EOF
+ rm -f conftest.nm
+ { ac_try='$gcc_cv_as -mmcu=avrxmega3 conftest.s -o conftest.o'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }
+ { ac_try='$gcc_cv_ld -mavrxmega3 conftest.o -o conftest.elf'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }
+ { ac_try='$gcc_cv_nm conftest.elf > conftest.nm'
+ { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_try\""; } >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+ test $ac_status = 0; }; }
+ if test -f conftest.nm
+ then
+ if grep ' R xxvaryy' conftest.nm > /dev/null; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+ rm -f conftest.s conftest.o conftest.elf conftest.nm
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no: avrxmega3 .rodata located in RAM" >&5
+$as_echo "no: avrxmega3 .rodata located in RAM" >&6; }
+ echo "$as_me: nm output was" >&5
+ cat conftest.nm >&5
+ rm -f conftest.s conftest.o conftest.elf conftest.nm
+ avr_ld_ver="`$gcc_cv_ld -v | sed -e 's:^.* ::'`"
+ as_fn_error "support for avrxmega3 needs Binutils 2.29 or higher (have $avr_ld_ver)" "$LINENO" 5
+ fi
+ else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: test failed" >&5
+$as_echo "test failed" >&6; }
+ echo "$as_me: failed program was" >&5
+ cat conftest.s >&5
+ rm -f conftest.s conftest.o conftest.elf
+ as_fn_error "see \`config.log' for details" "$LINENO" 5
+ fi
;;
cris-*-*)
diff --git a/gcc/configure.ac b/gcc/configure.ac
index acfe979..b54f797 100644
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -3816,6 +3816,42 @@ AS_HELP_STRING([--disable-fix-cortex-a53-843419],
[-mrmw], [.text],,
[AC_DEFINE(HAVE_AS_AVR_MRMW_OPTION, 1,
[Define if your avr assembler supports -mrmw option.])])
+
+ # Check how default linker description file implements .rodata for
+ # avrxmega3 (PR21472). avr-gcc assumes .rodata is *not* loaded to
+ # RAM so avr-gcc skips __do_copy_data for .rodata objects.
+ AC_MSG_CHECKING(binutils for avrxmega3 .rodata support)
+ cat > conftest.s <<EOF
+ .section .rodata,"a",@progbits
+ .global xxvaryy
+ ;; avr-nm should print "... R xxvaryy", not "... D xxvaryy".
+ xxvaryy:
+ .word 1
+EOF
+ rm -f conftest.nm
+ AC_TRY_COMMAND([$gcc_cv_as -mmcu=avrxmega3 conftest.s -o conftest.o])
+ AC_TRY_COMMAND([$gcc_cv_ld -mavrxmega3 conftest.o -o conftest.elf])
+ AC_TRY_COMMAND([$gcc_cv_nm conftest.elf > conftest.nm])
+ if test -f conftest.nm
+ then
+ if grep ' R xxvaryy' conftest.nm > /dev/null; then
+ AC_MSG_RESULT(yes)
+ rm -f conftest.s conftest.o conftest.elf conftest.nm
+ else
+ AC_MSG_RESULT(no: avrxmega3 .rodata located in RAM)
+ echo "$as_me: nm output was" >&AS_MESSAGE_LOG_FD
+ cat conftest.nm >&AS_MESSAGE_LOG_FD
+ rm -f conftest.s conftest.o conftest.elf conftest.nm
+ avr_ld_ver="`$gcc_cv_ld -v | sed -e 's:^.* ::'`"
+ AC_MSG_ERROR([[support for avrxmega3 needs Binutils 2.29 or higher (have $avr_ld_ver)]])
+ fi
+ else
+ AC_MSG_RESULT(test failed)
+ echo "$as_me: failed program was" >&AS_MESSAGE_LOG_FD
+ cat conftest.s >&AS_MESSAGE_LOG_FD
+ rm -f conftest.s conftest.o conftest.elf
+ AC_MSG_ERROR([[see `config.log' for details]])
+ fi
;;
cris-*-*)
diff --git a/gcc/doc/avr-mmcu.texi b/gcc/doc/avr-mmcu.texi
index deb0dd3..15fd414 100644
--- a/gcc/doc/avr-mmcu.texi
+++ b/gcc/doc/avr-mmcu.texi
@@ -52,6 +52,10 @@
``XMEGA'' devices with more than 8@tie{}KiB and up to 64@tie{}KiB of program memory.
@*@var{mcu}@tie{}= @code{atxmega16a4}, @code{atxmega16a4u}, @code{atxmega16c4}, @code{atxmega16d4}, @code{atxmega16e5}, @code{atxmega32a4}, @code{atxmega32a4u}, @code{atxmega32c3}, @code{atxmega32c4}, @code{atxmega32d3}, @code{atxmega32d4}, @code{atxmega32e5}, @code{atxmega8e5}.
+@item avrxmega3
+``XMEGA'' devices with up to 64@tie{}KiB of combined program memory and RAM, and with program memory visible in the RAM address space.
+@*@var{mcu}@tie{}= @code{attiny1614}, @code{attiny1616}, @code{attiny1617}, @code{attiny212}, @code{attiny214}, @code{attiny3214}, @code{attiny3216}, @code{attiny3217}, @code{attiny412}, @code{attiny414}, @code{attiny416}, @code{attiny417}, @code{attiny814}, @code{attiny816}, @code{attiny817}.
+
@item avrxmega4
``XMEGA'' devices with more than 64@tie{}KiB and up to 128@tie{}KiB of program memory.
@*@var{mcu}@tie{}= @code{atxmega64a3}, @code{atxmega64a3u}, @code{atxmega64a4u}, @code{atxmega64b1}, @code{atxmega64b3}, @code{atxmega64c3}, @code{atxmega64d3}, @code{atxmega64d4}.
diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi
index d467a16..ef1ae73 100644
--- a/gcc/doc/extend.texi
+++ b/gcc/doc/extend.texi
@@ -1312,11 +1312,24 @@ in order to put read-only data into the flash memory and access that
data by means of the special instructions @code{LPM} or @code{ELPM}
needed to read from flash.
-Per default, any data including read-only data is located in RAM
-(the generic address space) so that non-generic address spaces are
-needed to locate read-only data in flash memory
-@emph{and} to generate the right instructions to access this data
-without using (inline) assembler code.
+Devices belonging to @code{avrtiny} and @code{avrxmega3} can access
+flash memory by means of @code{LD*} instructions because the flash
+memory is mapped into the RAM address space. There is @emph{no need}
+for language extensions like @code{__flash} or attribute
+@ref{AVR Variable Attributes,,@code{progmem}}.
+The default linker description files for these devices cater for that
+feature and @code{.rodata} stays in flash: The compiler just generates
+@code{LD*} instructions, and the linker script adds core specific
+offsets to all @code{.rodata} symbols: @code{0x4000} in the case of
+@code{avrtiny} and @code{0x8000} in the case of @code{avrxmega3}.
+See @ref{AVR Options} for a list of respective devices.
+
+For devices not in @code{avrtiny} or @code{avrxmega3},
+any data including read-only data is located in RAM (the generic
+address space) because flash memory is not visible in the RAM address
+space. In order to locate read-only data in flash memory @emph{and}
+to generate the right instructions to access this data without
+using (inline) assembler code, special address spaces are needed.
@table @code
@item __flash
@@ -1447,14 +1460,11 @@ extern const __memx char foo;
const __memx void *pfoo = &foo;
@end smallexample
-@noindent
-Such code requires at least binutils 2.23, see
-@w{@uref{https://sourceware.org/PR13503,PR13503}}.
-
@item
On the reduced Tiny devices like ATtiny40, no address spaces are supported.
-Data can be put into and read from flash memory by means of
-attribute @code{progmem}, see @ref{AVR Variable Attributes}.
+Just use vanilla C / C++ code without overhead as outlined above.
+Attribute @code{progmem} is supported but works differently,
+see @ref{AVR Variable Attributes}.
@end itemize
@@ -5936,6 +5946,19 @@ normally resides in the data memory (RAM).
See also the @ref{AVR Named Address Spaces} section for
an alternate way to locate and access data in flash memory.
+@item @bullet{}@tie{} AVR cores with flash memory visible in the RAM address range:
+On such devices, there is no need for attribute @code{progmem} or
+@ref{AVR Named Address Spaces,,@code{__flash}} qualifier at all.
+Just use standard C / C++. The compiler will generate @code{LD*}
+instructions. As flash memory is visible in the RAM address range,
+and the default linker script does @emph{not} locate @code{.rodata} in
+RAM, no special features are needed in order not to waste RAM for
+read-only data or to read from flash. You might even get slightly better
+performance by
+avoiding @code{progmem} and @code{__flash}. This applies to devices from
+families @code{avrtiny} and @code{avrxmega3}, see @ref{AVR Options} for
+an overview.
+
@item @bullet{}@tie{}Reduced AVR Tiny cores like ATtiny40:
The compiler adds @code{0x4000}
to the addresses of objects and declarations in @code{progmem} and locates
@@ -5957,28 +5980,7 @@ int read_var (int i)
@end smallexample
Please notice that on these devices, there is no need for @code{progmem}
-at all. Just use an appropriate linker description file like outlined below.
-
-@smallexample
- .text :
- @{ ...
- @} > text
- /* Leave .rodata in flash and add an offset of 0x4000 to all
- addresses so that respective objects can be accessed by
- LD instructions and open coded C/C++. This means there
- is no need for progmem in the source and no overhead by
- read-only data in RAM. */
- .rodata ADDR(.text) + SIZEOF (.text) + 0x4000 :
- @{
- *(.rodata)
- *(.rodata*)
- *(.gnu.linkonce.r*)
- @} AT> text
- /* No more need to put .rodata into .data:
- Removed all .rodata entries from .data. */
- .data :
- @{ ...
-@end smallexample
+at all.
@end table
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 5d41649..653bc07 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -662,7 +662,7 @@ Objective-C and Objective-C++ Dialects}.
-mbranch-cost=@var{cost} @gol
-mcall-prologues -mint8 -mn_flash=@var{size} -mno-interrupts @gol
-mrelax -mrmw -mstrict-X -mtiny-stack -mfract-convert-truncate @gol
--nodevicelib @gol
+-mshort-calls -nodevicelib @gol
-Waddr-space-convert -Wmisspelled-isr}
@emph{Blackfin Options}
@@ -15637,6 +15637,15 @@ section on @code{EIND} and linker stubs below.
Assume that the device supports the Read-Modify-Write
instructions @code{XCH}, @code{LAC}, @code{LAS} and @code{LAT}.
+@item -mshort-calls
+@opindex mshort-calls
+
+Assume that @code{RJMP} and @code{RCALL} can target the whole
+program memory.
+
+This option is used internally for multilib selection. It is
+not an optimization option, and you don't need to set it by hand.
+
@item -msp8
@opindex msp8
Treat the stack pointer register as an 8-bit register,
@@ -15897,10 +15906,12 @@ for @var{mcu}=@code{avr2}, @code{avr25}, @code{avr3}, @code{avr31},
respectively and
-@code{100}, @code{102}, @code{104},
+@code{100},
+@code{102}, @code{103}, @code{104},
@code{105}, @code{106}, @code{107}
-for @var{mcu}=@code{avrtiny}, @code{avrxmega2}, @code{avrxmega4},
+for @var{mcu}=@code{avrtiny},
+@code{avrxmega2}, @code{avrxmega3}, @code{avrxmega4},
@code{avrxmega5}, @code{avrxmega6}, @code{avrxmega7}, respectively.
If @var{mcu} specifies a device, this built-in macro is set
accordingly. For example, with @option{-mmcu=atmega8} the macro is
@@ -15952,7 +15963,7 @@ The device has a hardware multiplier.
@item __AVR_HAVE_JMP_CALL__
The device has the @code{JMP} and @code{CALL} instructions.
-This is the case for devices with at least 16@tie{}KiB of program
+This is the case for devices with more than 8@tie{}KiB of program
memory.
@item __AVR_HAVE_EIJMP_EICALL__
@@ -16009,6 +16020,21 @@ or @code{STS}. This offset depends on the device architecture and has
to be subtracted from the RAM address in order to get the
respective I/O@tie{}address.
+@item __AVR_SHORT_CALLS__
+The @option{-mshort-calls} command line option is set.
+
+@item __AVR_PM_BASE_ADDRESS__=@var{addr}
+Some devices support reading from flash memory by means of @code{LD*}
+instructions. The flash memory is seen in the data address space
+at an offset of @code{__AVR_PM_BASE_ADDRESS__}. If this macro
+is not defined, this feature is not available. If defined,
+the address space is linear and there is no need to put
+@code{.rodata} into RAM. This is handled by the default linker
+description file, and is currently available for
+@code{avrtiny} and @code{avrxmega3}. Even more convenient,
+there is no need to use address spaces like @code{__flash} or
+features like attribute @code{progmem} and @code{pgm_read_*}.
+
@item __WITH_AVRLIBC__
The compiler is configured to be used together with AVR-Libc.
See the @option{--with-avrlibc} configure option.
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index f3975c7..74bbdb0 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -4745,6 +4745,40 @@ make_range (tree exp, int *pin_p, tree *plow, tree *phigh,
*pin_p = in_p, *plow = low, *phigh = high;
return exp;
}
+
+/* Returns TRUE if [LOW, HIGH] range check can be optimized to
+ a bitwise check i.e. when
+ LOW == 0xXX...X00...0
+ HIGH == 0xXX...X11...1
+ Return corresponding mask in MASK and stem in VALUE. */
+
+static bool
+maskable_range_p (const_tree low, const_tree high, tree type, tree *mask,
+ tree *value)
+{
+ if (TREE_CODE (low) != INTEGER_CST
+ || TREE_CODE (high) != INTEGER_CST)
+ return false;
+
+ unsigned prec = TYPE_PRECISION (type);
+ wide_int lo = wi::to_wide (low, prec);
+ wide_int hi = wi::to_wide (high, prec);
+
+ wide_int end_mask = lo ^ hi;
+ if ((end_mask & (end_mask + 1)) != 0
+ || (lo & end_mask) != 0)
+ return false;
+
+ wide_int stem_mask = ~end_mask;
+ wide_int stem = lo & stem_mask;
+ if (stem != (hi & stem_mask))
+ return false;
+
+ *mask = wide_int_to_tree (type, stem_mask);
+ *value = wide_int_to_tree (type, stem);
+
+ return true;
+}
/* Given a range, LOW, HIGH, and IN_P, an expression, EXP, and a result
type, TYPE, return an expression to test if EXP is in (or out of, depending
@@ -4754,7 +4788,7 @@ tree
build_range_check (location_t loc, tree type, tree exp, int in_p,
tree low, tree high)
{
- tree etype = TREE_TYPE (exp), value;
+ tree etype = TREE_TYPE (exp), mask, value;
/* Disable this optimization for function pointer expressions
on targets that require function pointer canonicalization. */
@@ -4787,6 +4821,13 @@ build_range_check (location_t loc, tree type, tree exp, int in_p,
return fold_build2_loc (loc, EQ_EXPR, type, exp,
fold_convert_loc (loc, etype, low));
+ if (TREE_CODE (exp) == BIT_AND_EXPR
+ && maskable_range_p (low, high, etype, &mask, &value))
+ return fold_build2_loc (loc, EQ_EXPR, type,
+ fold_build2_loc (loc, BIT_AND_EXPR, etype,
+ exp, mask),
+ value);
+
if (integer_zerop (low))
{
if (! TYPE_UNSIGNED (etype))
@@ -6241,11 +6282,6 @@ extract_muldiv_1 (tree t, tree c, enum tree_code code, tree wide_type,
if (TYPE_UNSIGNED (ctype) && ctype != type)
break;
- /* If we were able to eliminate our operation from the first side,
- apply our operation to the second side and reform the PLUS. */
- if (t1 != 0 && (TREE_CODE (t1) != code || code == MULT_EXPR))
- return fold_build2 (tcode, ctype, fold_convert (ctype, t1), op1);
-
/* The last case is if we are a multiply. In that case, we can
apply the distributive law to commute the multiply and addition
if the multiplication of the constants doesn't overflow
@@ -8908,7 +8944,7 @@ fold_addr_of_array_ref_difference (location_t loc, tree type,
tree op0 = fold_convert_loc (loc, type, TREE_OPERAND (aref0, 1));
tree op1 = fold_convert_loc (loc, type, TREE_OPERAND (aref1, 1));
tree esz = fold_convert_loc (loc, type, array_ref_element_size (aref0));
- tree diff = build2 (MINUS_EXPR, type, op0, op1);
+ tree diff = fold_build2_loc (loc, MINUS_EXPR, type, op0, op1);
return fold_build2_loc (loc, PLUS_EXPR, type,
base_offset,
fold_build2_loc (loc, MULT_EXPR, type,
diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c
index 5ff63a1..447921be 100644
--- a/gcc/gimple-pretty-print.c
+++ b/gcc/gimple-pretty-print.c
@@ -80,17 +80,22 @@ debug_gimple_stmt (gimple *gs)
by xstrdup_for_dump. */
static const char *
-dump_probability (int value)
+dump_probability (int frequency, profile_count &count)
{
float minimum = 0.01f;
- gcc_assert (0 <= value && value <= REG_BR_PROB_BASE);
- float fvalue = value * 100.0f / REG_BR_PROB_BASE;
- if (fvalue < minimum && value > 0)
+ gcc_assert (0 <= frequency && frequency <= REG_BR_PROB_BASE);
+ float fvalue = frequency * 100.0f / REG_BR_PROB_BASE;
+ if (fvalue < minimum && frequency > 0)
return "[0.01%]";
char *buf;
- asprintf (&buf, "[%.2f%%]", fvalue);
+ if (count.initialized_p ())
+ asprintf (&buf, "[%.2f%%] [count: %" PRId64 "]", fvalue,
+ count.to_gcov_type ());
+ else
+ asprintf (&buf, "[%.2f%%] [count: INV]", fvalue);
+
const char *ret = xstrdup_for_dump (buf);
free (buf);
@@ -102,7 +107,7 @@ dump_probability (int value)
static void
dump_edge_probability (pretty_printer *buffer, edge e)
{
- pp_scalar (buffer, " %s", dump_probability (e->probability));
+ pp_scalar (buffer, " %s", dump_probability (e->probability, e->count));
}
/* Print GIMPLE statement G to FILE using SPC indentation spaces and
@@ -1085,7 +1090,7 @@ dump_gimple_label (pretty_printer *buffer, glabel *gs, int spc,
dump_generic_node (buffer, label, spc, flags, false);
basic_block bb = gimple_bb (gs);
if (bb && !(flags & TDF_GIMPLE))
- pp_scalar (buffer, " %s", dump_probability (bb->frequency));
+ pp_scalar (buffer, " %s", dump_probability (bb->frequency, bb->count));
pp_colon (buffer);
}
if (flags & TDF_GIMPLE)
@@ -2665,7 +2670,8 @@ dump_gimple_bb_header (FILE *outf, basic_block bb, int indent,
fprintf (outf, "%*sbb_%d:\n", indent, "", bb->index);
else
fprintf (outf, "%*s<bb %d> %s:\n",
- indent, "", bb->index, dump_probability (bb->frequency));
+ indent, "", bb->index, dump_probability (bb->frequency,
+ bb->count));
}
}
}
diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE
index 1bfac59..78bd057 100644
--- a/gcc/go/gofrontend/MERGE
+++ b/gcc/go/gofrontend/MERGE
@@ -1,4 +1,4 @@
-d4875b19266d5f726e0e32843b903075f5c50b4c
+c4ecdd3edb9febe72b5527481ae3d7310105ca67
The first line of this file holds the git revision number of the last
merge done from the gofrontend repository.
diff --git a/gcc/go/gofrontend/expressions.cc b/gcc/go/gofrontend/expressions.cc
index d6d27ee..5eec731 100644
--- a/gcc/go/gofrontend/expressions.cc
+++ b/gcc/go/gofrontend/expressions.cc
@@ -3410,11 +3410,13 @@ Type_conversion_expression::do_get_backend(Translate_context* context)
Gogo* gogo = context->gogo();
Btype* btype = type->get_backend(gogo);
- Bexpression* bexpr = this->expr_->get_backend(context);
Location loc = this->location();
if (Type::are_identical(type, expr_type, false, NULL))
- return gogo->backend()->convert_expression(btype, bexpr, loc);
+ {
+ Bexpression* bexpr = this->expr_->get_backend(context);
+ return gogo->backend()->convert_expression(btype, bexpr, loc);
+ }
else if (type->interface_type() != NULL
|| expr_type->interface_type() != NULL)
{
@@ -3483,6 +3485,7 @@ Type_conversion_expression::do_get_backend(Translate_context* context)
else if (type->is_numeric_type())
{
go_assert(Type::are_convertible(type, expr_type, NULL));
+ Bexpression* bexpr = this->expr_->get_backend(context);
return gogo->backend()->convert_expression(btype, bexpr, loc);
}
else if ((type->is_unsafe_pointer_type()
@@ -3493,7 +3496,10 @@ Type_conversion_expression::do_get_backend(Translate_context* context)
|| (this->may_convert_function_types_
&& type->function_type() != NULL
&& expr_type->function_type() != NULL))
- return gogo->backend()->convert_expression(btype, bexpr, loc);
+ {
+ Bexpression* bexpr = this->expr_->get_backend(context);
+ return gogo->backend()->convert_expression(btype, bexpr, loc);
+ }
else
{
Expression* conversion =
diff --git a/gcc/match.pd b/gcc/match.pd
index 54a8e04..244e9eb 100644
--- a/gcc/match.pd
+++ b/gcc/match.pd
@@ -2741,6 +2741,34 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT)
|| VECTOR_INTEGER_TYPE_P (TREE_TYPE (@0)))
{ constant_boolean_node (false, type); })))
+/* A & (2**N - 1) <= 2**K - 1 -> A & (2**N - 2**K) == 0
+ A & (2**N - 1) > 2**K - 1 -> A & (2**N - 2**K) != 0
+
+ Note that comparisons
+ A & (2**N - 1) < 2**K -> A & (2**N - 2**K) == 0
+ A & (2**N - 1) >= 2**K -> A & (2**N - 2**K) != 0
+ will be canonicalized to above so there's no need to
+ consider them here.
+ */
+
+(for cmp (le gt)
+ eqcmp (eq ne)
+ (simplify
+ (cmp (bit_and@0 @1 INTEGER_CST@2) INTEGER_CST@3)
+ (if (INTEGRAL_TYPE_P (TREE_TYPE (@0)))
+ (with
+ {
+ tree ty = TREE_TYPE (@0);
+ unsigned prec = TYPE_PRECISION (ty);
+ wide_int mask = wi::to_wide (@2, prec);
+ wide_int rhs = wi::to_wide (@3, prec);
+ signop sgn = TYPE_SIGN (ty);
+ }
+ (if ((mask & (mask + 1)) == 0 && wi::gt_p (rhs, 0, sgn)
+ && (rhs & (rhs + 1)) == 0 && wi::ge_p (mask, rhs, sgn))
+ (eqcmp (bit_and @1 { wide_int_to_tree (ty, mask - rhs); })
+ { build_zero_cst (ty); }))))))
+
/* -A CMP -B -> B CMP A. */
(for cmp (tcc_comparison)
scmp (swapped_tcc_comparison)
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 531c787..d9a9fb2 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,68 @@
+2017-06-13 Martin Jambor <mjambor@suse.cz>
+
+ PR tree-optimization/80803
+ PR tree-optimization/81063
+ gcc.dg/tree-ssa/pr80803.c: New test.
+ gcc.dg/tree-ssa/pr81063.c: Likewise.
+
+2017-06-12 Yury Gribov <tetra2005@gmail.com>
+
+ * c-c++-common/fold-masked-cmp-3.c: New test.
+
+2017-06-13 Yury Gribov <tetra2005@gmail.com>
+
+ PR tree-optimization/67328
+ * c-c++-common/fold-masked-cmp-1.c: New test.
+ * c-c++-common/fold-masked-cmp-2.c: Likewise.
+ * gcc.dg/pr46309.c: Fix pattern.
+ * gcc.dg/pr46309-2.c: Likewise.
+
+2017-06-13 Tamar Christina <tamar.christina@arm.com>
+
+ * gcc.target/arm/sdiv_costs_1.c:
+ Require arm_arch_v8a_ok and add march option.
+
+2017-06-13 Martin Liska <mliska@suse.cz>
+
+ * gcc.dg/tree-ssa/builtin-sprintf-2.c: Adjust scanned pattern.
+ * gcc.dg/tree-ssa/dump-2.c: Likewise.
+ * gcc.dg/tree-ssa/vrp101.c: Likewise.
+
+2017-06-13 Richard Biener <rguenther@suse.de>
+
+ PR middle-end/81065
+ * c-c++-common/ubsan/pr81065.c: New testcase.
+
+2017-06-12 Ian Lance Taylor <iant@golang.org>
+
+ * gcc.dg/tree-prof/split-1.c: Require split_stack, don't require
+ freorder. Update comment to explain test.
+
+2017-06-12 Tamar Christina <tamar.christina@arm.com>
+
+ * gcc.target/aarch64/inline-lrint_1.c: Broaden regexp.
+ * gcc.target/aarch64/inline-lrint_2.c: Likewise.
+ * gcc.target/aarch64/no-inline-lrint_1.c: Likewise.
+ * gcc.target/aarch64/no-inline-lrint_2.c: Likewise.
+
+2017-06-12 Tamar Christina <tamar.christina@arm.com>
+
+ * gcc.target/arm/sdiv_costs_1.c: Require arm_v8_vfp_ok.
+
+2017-06-12 Tamar Christina <tamar.christina@arm.com>
+
+ * gcc.target/arm/sdiv_costs_1.c: Disable on softfloat.
+
+2017-06-12 Jakub Jelinek <jakub@redhat.com>
+
+ PR tree-optimization/81003
+ * gcc.c-torture/compile/pr81003.c: New test.
+
+2017-06-12 Richard Biener <rguenther@suse.de>
+
+ PR tree-optimization/81053
+ * gcc.dg/torture/pr81053.c: New testcase.
+
2017-06-10 Thomas Koenig <tkoenig@gcc.gnu.org>
PR fortran/80988
diff --git a/gcc/testsuite/c-c++-common/fold-masked-cmp-1.c b/gcc/testsuite/c-c++-common/fold-masked-cmp-1.c
new file mode 100644
index 0000000..a0e9083
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/fold-masked-cmp-1.c
@@ -0,0 +1,41 @@
+/* Based on PR 67328 */
+
+/* { dg-do compile { target x86_64-*-* } } */
+/* { dg-options "-O2" } */
+
+enum output_type
+{
+ type_pde,
+ type_pie,
+ type_relocatable,
+ type_dll,
+};
+
+struct bfd_link_info
+{
+ enum output_type type : 2;
+ unsigned int pad : 30;
+};
+
+#define bfd_link_pde(info) ((info)->type == type_pde)
+#define bfd_link_dll(info) ((info)->type == type_dll)
+#define bfd_link_relocatable(info) ((info)->type == type_relocatable)
+#define bfd_link_pie(info) ((info)->type == type_pie)
+#define bfd_link_executable(info) (bfd_link_pde (info) || bfd_link_pie (info))
+#define bfd_link_pic(info) (bfd_link_dll (info) || bfd_link_pie (info))
+
+int result;
+
+void test_pic (struct bfd_link_info *info)
+{
+ if (bfd_link_pic (info))
+ result++;
+}
+
+int test_exe (struct bfd_link_info *info)
+{
+ if (bfd_link_executable (info))
+ result++;
+}
+
+/* { dg-final { scan-assembler-times "testn?b" 2 } } */
diff --git a/gcc/testsuite/c-c++-common/fold-masked-cmp-2.c b/gcc/testsuite/c-c++-common/fold-masked-cmp-2.c
new file mode 100644
index 0000000..13d068a
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/fold-masked-cmp-2.c
@@ -0,0 +1,42 @@
+/* Based on PR 67328 */
+
+/* { dg-do compile { target x86_64-*-* } } */
+/* { dg-options "-O2" } */
+
+enum output_type
+{
+ type_pde,
+ type_relocatable,
+ type_pie,
+ type_dll,
+};
+
+struct bfd_link_info
+{
+ enum output_type type : 2;
+ unsigned int pad : 30;
+};
+
+#define bfd_link_pde(info) ((info)->type == type_pde)
+#define bfd_link_dll(info) ((info)->type == type_dll)
+#define bfd_link_relocatable(info) ((info)->type == type_relocatable)
+#define bfd_link_pie(info) ((info)->type == type_pie)
+#define bfd_link_executable(info) (bfd_link_pde (info) || bfd_link_pie (info))
+#define bfd_link_pic(info) (bfd_link_dll (info) || bfd_link_pie (info))
+
+int result;
+
+void test_pic (struct bfd_link_info *info)
+{
+ if (bfd_link_pic (info))
+ result++;
+}
+
+int test_exe (struct bfd_link_info *info)
+{
+ if (bfd_link_executable (info))
+ result++;
+}
+
+/* { dg-final { scan-assembler-times "testn?b" 2 } } */
+
diff --git a/gcc/testsuite/c-c++-common/fold-masked-cmp-3.c b/gcc/testsuite/c-c++-common/fold-masked-cmp-3.c
new file mode 100644
index 0000000..98900ec3
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/fold-masked-cmp-3.c
@@ -0,0 +1,16 @@
+/* { dg-do compile { target x86_64-*-* } } */
+/* { dg-options "-fdump-tree-original" } */
+
+void foo (int *p, int x)
+{
+ if ((x & 0xff) <= 7)
+ *p = 0;
+}
+
+void bar (int *p, int x)
+{
+ if ((x & 0xff) < 8)
+ *p = 0;
+}
+
+/* { dg-final { scan-tree-dump-times "(x & .*) == 0" 2 "original" } } */
diff --git a/gcc/testsuite/c-c++-common/ubsan/pr81065.c b/gcc/testsuite/c-c++-common/ubsan/pr81065.c
new file mode 100644
index 0000000..1b34227
--- /dev/null
+++ b/gcc/testsuite/c-c++-common/ubsan/pr81065.c
@@ -0,0 +1,13 @@
+/* { dg-do run } */
+/* { dg-options "-fsanitize=undefined -fsanitize-undefined-trap-on-error" } */
+
+unsigned char x = 154;
+int foo() {
+ // 8575 * (254408 - 9057) = 8575 * 245351 = 2103884825 = 0x7d66bc19
+ return 8575 * (1652 * x - 9057);
+}
+
+int main() {
+ foo();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.c-torture/compile/pr81003.c b/gcc/testsuite/gcc.c-torture/compile/pr81003.c
new file mode 100644
index 0000000..26117b6
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/pr81003.c
@@ -0,0 +1,10 @@
+/* PR tree-optimization/81003 */
+
+unsigned int a, b;
+
+void
+foo (void)
+{
+ for (b = 0; b < 13; b += 2)
+ a &= !!b;
+}
diff --git a/gcc/testsuite/gcc.dg/pr46309-2.c b/gcc/testsuite/gcc.dg/pr46309-2.c
index 39b9b83..f56df42 100644
--- a/gcc/testsuite/gcc.dg/pr46309-2.c
+++ b/gcc/testsuite/gcc.dg/pr46309-2.c
@@ -142,4 +142,4 @@ f10 (int a)
/* { dg-final { scan-tree-dump-times "Optimizing range tests a_\[0-9\]*.D. -.0, 31. and -.64, 95.\[\n\r\]* into" 1 "reassoc1" } } */
/* { dg-final { scan-tree-dump-times "Optimizing range tests a_\[0-9\]*.D. -.128, 159. and -.192, 223.\[\n\r\]* into" 1 "reassoc1" } } */
/* { dg-final { scan-tree-dump-times "Optimizing range tests a_\[0-9\]*.D. -.1, 1. and -.2, 2. and -.3, 3. and -.4, 4. and -.5, 5. and -.6, 6. and -.7, 7. and -.8, 8.\[\n\r\]* into" 7 "reassoc1" } } */
-/* { dg-final { scan-tree-dump-times "Optimizing range tests \[^\r\n\]*_\[0-9\]* -.0, 31. and -.128, 159.\[\n\r\]* into" 1 "reassoc2" } } */
+/* { dg-final { scan-tree-dump-times "Optimizing range tests \[^\r\n\]*_\[0-9\]* -.0, 0. and -.128, 128.\[\n\r\]* into" 1 "reassoc2" } } */
diff --git a/gcc/testsuite/gcc.dg/pr46309.c b/gcc/testsuite/gcc.dg/pr46309.c
index f362ac3..68229cf 100644
--- a/gcc/testsuite/gcc.dg/pr46309.c
+++ b/gcc/testsuite/gcc.dg/pr46309.c
@@ -65,4 +65,4 @@ f6 (unsigned int a)
/* { dg-final { scan-tree-dump-times "Optimizing range tests a_\[0-9\]*.D. -.1, 1. and -.2, 2.\[\n\r\]* into" 1 "reassoc1" } } */
/* { dg-final { scan-tree-dump-times "Optimizing range tests a_\[0-9\]*.D. -.0, 31. and -.64, 95.\[\n\r\]* into" 2 "reassoc1" } } */
/* { dg-final { scan-tree-dump-times "Optimizing range tests a_\[0-9\]*.D. -.128, 159. and -.192, 223.\[\n\r\]* into" 1 "reassoc1" } } */
-/* { dg-final { scan-tree-dump-times "Optimizing range tests \[^\r\n\]*_\[0-9\]* -.0, 31. and -.128, 159.\[\n\r\]* into" 1 "reassoc2" } } */
+/* { dg-final { scan-tree-dump-times "Optimizing range tests \[^\r\n\]*_\[0-9\]* -.0, 0. and -.128, 128.\[\n\r\]* into" 1 "reassoc2" } } */
diff --git a/gcc/testsuite/gcc.dg/torture/pr81053.c b/gcc/testsuite/gcc.dg/torture/pr81053.c
new file mode 100644
index 0000000..98ab95d
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/torture/pr81053.c
@@ -0,0 +1,12 @@
+/* { dg-do compile } */
+
+int a, b[2], c, d;
+
+void fn1 ()
+{
+ for (; d < 2; d++)
+ {
+ b[d] = a;
+ a = c;
+ }
+}
diff --git a/gcc/testsuite/gcc.dg/tree-prof/split-1.c b/gcc/testsuite/gcc.dg/tree-prof/split-1.c
index a42fccf..6986f7a 100644
--- a/gcc/testsuite/gcc.dg/tree-prof/split-1.c
+++ b/gcc/testsuite/gcc.dg/tree-prof/split-1.c
@@ -1,6 +1,6 @@
-/* Test case that we don't get a link-time error when using
- -fsplit-stack with -freorder-blocks-and-partition. */
-/* { dg-require-effective-target freorder } */
+/* Test that we don't get a link-time error when using -fsplit-stack
+ due to implicit enabling of -freorder-blocks-and-partition. */
+/* { dg-require-effective-target split_stack } */
/* { dg-options "-O2 -fsplit-stack" } */
extern unsigned int sleep (unsigned int);
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-2.c b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-2.c
index 8a13f33..e15d88b 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/builtin-sprintf-2.c
@@ -290,7 +290,7 @@ RNG (0, 6, 8, "%s%ls", "1", L"2");
/* Only conditional calls to must_not_eliminate must be made (with
any probability):
- { dg-final { scan-tree-dump-times "> \\\[\[0-9.\]+%\\\]:\n *must_not_eliminate" 127 "optimized" { target { ilp32 || lp64 } } } }
- { dg-final { scan-tree-dump-times "> \\\[\[0-9.\]+%\\\]:\n *must_not_eliminate" 96 "optimized" { target { { ! ilp32 } && { ! lp64 } } } } }
+ { dg-final { scan-tree-dump-times "> \\\[\[0-9.\]+%\\\]\\ \\\[count:\\[^:\\]*\\\]:\n *must_not_eliminate" 127 "optimized" { target { ilp32 || lp64 } } } }
+ { dg-final { scan-tree-dump-times "> \\\[\[0-9.\]+%\\\]\\ \\\[count:\\[^:\\]*\\\]:\n *must_not_eliminate" 96 "optimized" { target { { ! ilp32 } && { ! lp64 } } } } }
No unconditional calls to abort should be made:
{ dg-final { scan-tree-dump-not ";\n *must_not_eliminate" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/dump-2.c b/gcc/testsuite/gcc.dg/tree-ssa/dump-2.c
index 8a63af4..6ae2ef5 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/dump-2.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/dump-2.c
@@ -6,4 +6,4 @@ int f(void)
return 0;
}
-/* { dg-final { scan-tree-dump "<bb \[0-9\]> \\\[100\\\.00%\\\]:" "optimized" } } */
+/* { dg-final { scan-tree-dump "<bb \[0-9\]> \\\[100\\\.00%\\\] \\\[count: INV\\\]:" "optimized" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr80803.c b/gcc/testsuite/gcc.dg/tree-ssa/pr80803.c
new file mode 100644
index 0000000..66834fb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr80803.c
@@ -0,0 +1,72 @@
+/* { dg-do run } */
+/* { dg-options "-O" } */
+
+struct S0
+{
+ unsigned a : 15;
+ int b;
+ int c;
+};
+
+struct S1
+{
+ struct S0 s0;
+ int e;
+};
+
+struct Z
+{
+ char c;
+ int z;
+} __attribute__((packed));
+
+union U
+{
+ struct S1 s1;
+ struct Z z;
+};
+
+
+int __attribute__((noinline, noclone))
+return_zero (void)
+{
+ return 0;
+}
+
+volatile union U gu;
+struct S0 gs;
+
+int __attribute__((noinline, noclone))
+check_outcome ()
+{
+ if (gs.a != 6
+ || gs.b != 80000)
+ __builtin_abort ();
+}
+
+int
+main (int argc, char *argv[])
+{
+ union U u;
+ struct S1 m,n;
+ struct S0 l;
+
+ if (return_zero ())
+ u.z.z = 20000;
+ else
+ {
+ u.s1.s0.a = 6;
+ u.s1.s0.b = 80000;
+ u.s1.e = 2;
+
+ n = u.s1;
+ m = n;
+ m.s0.c = 0;
+ l = m.s0;
+ gs = l;
+ }
+
+ gu = u;
+ check_outcome ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr81063.c b/gcc/testsuite/gcc.dg/tree-ssa/pr81063.c
new file mode 100644
index 0000000..399e2d1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/pr81063.c
@@ -0,0 +1,28 @@
+/* { dg-do run } */
+/* { dg-options "-O" } */
+
+struct A
+{
+ int b;
+ int c:2;
+};
+
+struct B
+{
+ int e;
+ struct A f;
+} g = {0, {0, 1}}, j;
+
+struct A *h = &g.f;
+
+int main ()
+{
+ struct A k;
+ struct B l = j, i = l;
+ if (!i.f.b)
+ k = i.f;
+ *h = k;
+ if (g.f.c != 0)
+ __builtin_abort ();
+ return 0;
+}
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/vrp101.c b/gcc/testsuite/gcc.dg/tree-ssa/vrp101.c
index bf4109f..e7cad28 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/vrp101.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/vrp101.c
@@ -10,4 +10,4 @@ int main ()
return 0;
}
-/* { dg-final { scan-tree-dump "<bb 2> \\\[\[0-9.\]+%\\\]:\[\n\r \]*return 0;" "optimized" } } */
+/* { dg-final { scan-tree-dump "<bb 2> \\\[\[0-9.\]+%\\\] \\\[count: \\[^:\\]*\\\]:\[\n\r \]*return 0;" "optimized" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/inline-lrint_1.c b/gcc/testsuite/gcc.target/aarch64/inline-lrint_1.c
index 876cecd..478875f 100644
--- a/gcc/testsuite/gcc.target/aarch64/inline-lrint_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/inline-lrint_1.c
@@ -13,8 +13,6 @@ TEST (fif, float , int, )
TEST (dlld, double, long long, l)
TEST (fllf, float , long long, l)
-/* { dg-final { scan-assembler-times "frintx\td\[0-9\]+, d\[0-9\]+" 3 } } */
-/* { dg-final { scan-assembler-times "frintx\ts\[0-9\]+, s\[0-9\]+" 3 } } */
-/* { dg-final { scan-assembler-times "fcvtzs\tx\[0-9\]+, d\[0-9\]+" 3 } } */
-/* { dg-final { scan-assembler-times "fcvtzs\tx\[0-9\]+, s\[0-9\]+" 3 } } */
+/* { dg-final { scan-assembler-times "frintx\t\[d,s\]\[0-9\]+, \[d,s\]\[0-9\]+" 6 } } */
+/* { dg-final { scan-assembler-times "fcvtzs\tx\[0-9\]+, \[d,s\]\[0-9\]+" 6 } } */
/* { dg-final { scan-assembler-not "bl" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/inline-lrint_2.c b/gcc/testsuite/gcc.target/aarch64/inline-lrint_2.c
index baa5aee..6080e18 100644
--- a/gcc/testsuite/gcc.target/aarch64/inline-lrint_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/inline-lrint_2.c
@@ -13,10 +13,6 @@ TEST (fif, float , int, )
TEST (dlld, double, long long, l)
TEST (fllf, float , long long, l)
-/* { dg-final { scan-assembler-times "frintx\td\[0-9\]+, d\[0-9\]+" 3 } } */
-/* { dg-final { scan-assembler-times "frintx\ts\[0-9\]+, s\[0-9\]+" 3 } } */
-/* { dg-final { scan-assembler-times "fcvtzs\tx\[0-9\]+, d\[0-9\]+" 1 } } */
-/* { dg-final { scan-assembler-times "fcvtzs\tx\[0-9\]+, s\[0-9\]+" 1 } } */
-/* { dg-final { scan-assembler-times "fcvtzs\tw\[0-9\]+, d\[0-9\]+" 2 } } */
-/* { dg-final { scan-assembler-times "fcvtzs\tw\[0-9\]+, s\[0-9\]+" 2 } } */
+/* { dg-final { scan-assembler-times "frintx\t\[d,s\]\[0-9\]+, \[d,s\]\[0-9\]+" 6 } } */
+/* { dg-final { scan-assembler-times "fcvtzs\t\[w,x\]\[0-9\]+, \[d,s\]\[0-9\]+" 6 } } */
/* { dg-final { scan-assembler-not "bl" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_1.c b/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_1.c
index fb7f065..d5e9200 100644
--- a/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_1.c
+++ b/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_1.c
@@ -13,8 +13,7 @@ TEST (fif, float , int, )
TEST (dlld, double, long long, l)
TEST (fllf, float , long long, l)
-/* { dg-final { scan-assembler-times "frintx\td\[0-9\]+, d\[0-9\]+" 3 } } */
-/* { dg-final { scan-assembler-times "frintx\ts\[0-9\]+, s\[0-9\]+" 3 } } */
+/* { dg-final { scan-assembler-times "frintx\t\[d,s\]\[0-9\]+, \[d,s\]\[0-9\]+" 6 } } */
/* { dg-final { scan-assembler-times "bl\tlrint" 4 } } */
/* { dg-final { scan-assembler-times "bl\tllrint" 2 } } */
/* { dg-final { scan-assembler-not "fcvtzs" } } */
diff --git a/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_2.c b/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_2.c
index c99843c..05c0a2a 100644
--- a/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_2.c
+++ b/gcc/testsuite/gcc.target/aarch64/no-inline-lrint_2.c
@@ -13,8 +13,7 @@ TEST (fif, float , int, )
TEST (dlld, double, long long, l)
TEST (fllf, float , long long, l)
-/* { dg-final { scan-assembler-times "frintx\td\[0-9\]+, d\[0-9\]+" 3 } } */
-/* { dg-final { scan-assembler-times "frintx\ts\[0-9\]+, s\[0-9\]+" 3 } } */
+/* { dg-final { scan-assembler-times "frintx\t\[d,s\]\[0-9\]+, \[d,s\]\[0-9\]+" 6 } } */
/* { dg-final { scan-assembler-times "bl\tlrint" 4 } } */
/* { dg-final { scan-assembler-times "bl\tllrint" 2 } } */
/* { dg-final { scan-assembler-not "fcvtzs" } } */
diff --git a/gcc/testsuite/gcc.target/arm/sdiv_costs_1.c b/gcc/testsuite/gcc.target/arm/sdiv_costs_1.c
index 76086ab..9d094ac 100644
--- a/gcc/testsuite/gcc.target/arm/sdiv_costs_1.c
+++ b/gcc/testsuite/gcc.target/arm/sdiv_costs_1.c
@@ -1,5 +1,6 @@
/* { dg-do compile } */
/* { dg-options "-O3 -march=armv8-a" } */
+/* { dg-require-effective-target arm_arch_v8a_ok } */
/* Both sdiv and udiv can be used here, so prefer udiv. */
int f1 (unsigned char *p)
diff --git a/gcc/tree-profile.c b/gcc/tree-profile.c
index f5c0668..2ae4b69 100644
--- a/gcc/tree-profile.c
+++ b/gcc/tree-profile.c
@@ -429,6 +429,10 @@ gimple_gen_ic_func_profiler (void)
basic_block cond_bb = split_edge (single_succ_edge (entry));
basic_block update_bb = split_edge (single_succ_edge (cond_bb));
+ /* We need to do an extra split in order to not create an input
+ for a possible PHI node. */
+ split_edge (single_succ_edge (update_bb));
+
edge true_edge = single_succ_edge (cond_bb);
true_edge->flags = EDGE_TRUE_VALUE;
@@ -487,6 +491,10 @@ gimple_gen_time_profiler (unsigned tag, unsigned base)
basic_block cond_bb = split_edge (single_succ_edge (entry));
basic_block update_bb = split_edge (single_succ_edge (cond_bb));
+ /* We need to do an extra split in order to not create an input
+ for a possible PHI node. */
+ split_edge (single_succ_edge (update_bb));
+
edge true_edge = single_succ_edge (cond_bb);
true_edge->flags = EDGE_TRUE_VALUE;
true_edge->probability = PROB_UNLIKELY;
diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c
index f25818f..c9865c6 100644
--- a/gcc/tree-sra.c
+++ b/gcc/tree-sra.c
@@ -470,7 +470,7 @@ dump_access_tree_1 (FILE *f, struct access *access, int level)
int i;
for (i = 0; i < level; i++)
- fputs ("* ", dump_file);
+ fputs ("* ", f);
dump_access (f, access, true);
@@ -627,7 +627,7 @@ relink_to_new_repr (struct access *new_racc, struct access *old_racc)
static void
add_access_to_work_queue (struct access *access)
{
- if (!access->grp_queued)
+ if (access->first_link && !access->grp_queued)
{
gcc_assert (!access->next_queued);
access->next_queued = work_queue_head;
@@ -2112,8 +2112,7 @@ sort_and_splice_var_accesses (tree var)
access->grp_total_scalarization = total_scalarization;
access->grp_partial_lhs = grp_partial_lhs;
access->grp_unscalarizable_region = unscalarizable_region;
- if (access->first_link)
- add_access_to_work_queue (access);
+ add_access_to_work_queue (access);
*prev_acc_ptr = access;
prev_acc_ptr = &access->next_grp;
@@ -2559,9 +2558,28 @@ create_artificial_child_access (struct access *parent, struct access *model,
}
-/* Propagate all subaccesses of RACC across an assignment link to LACC. Return
- true if any new subaccess was created. Additionally, if RACC is a scalar
- access but LACC is not, change the type of the latter, if possible. */
+/* Beginning with ACCESS, traverse its whole access subtree and mark all
+ sub-trees as written to. If any of them has not been marked so previously
+ and has assignment links leading from it, re-enqueue it. */
+
+static void
+subtree_mark_written_and_enqueue (struct access *access)
+{
+ if (access->grp_write)
+ return;
+ access->grp_write = true;
+ add_access_to_work_queue (access);
+
+ struct access *child;
+ for (child = access->first_child; child; child = child->next_sibling)
+ subtree_mark_written_and_enqueue (child);
+}
+
+/* Propagate subaccesses and grp_write flags of RACC across an assignment link
+ to LACC. Enqueue sub-accesses as necessary so that the write flag is
+ propagated transitively. Return true if anything changed. Additionally, if
+ RACC is a scalar access but LACC is not, change the type of the latter, if
+ possible. */
static bool
propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
@@ -2577,7 +2595,7 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
gcc_checking_assert (!comes_initialized_p (racc->base));
if (racc->grp_write)
{
- lacc->grp_write = true;
+ subtree_mark_written_and_enqueue (lacc);
ret = true;
}
}
@@ -2586,13 +2604,21 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
|| lacc->grp_unscalarizable_region
|| racc->grp_unscalarizable_region)
{
- ret |= !lacc->grp_write;
- lacc->grp_write = true;
+ if (!lacc->grp_write)
+ {
+ ret = true;
+ subtree_mark_written_and_enqueue (lacc);
+ }
return ret;
}
if (is_gimple_reg_type (racc->type))
{
+ if (!lacc->grp_write)
+ {
+ ret = true;
+ subtree_mark_written_and_enqueue (lacc);
+ }
if (!lacc->first_child && !racc->first_child)
{
tree t = lacc->base;
@@ -2617,21 +2643,15 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
struct access *new_acc = NULL;
HOST_WIDE_INT norm_offset = rchild->offset + norm_delta;
- if (rchild->grp_unscalarizable_region)
- {
- lacc->grp_write = true;
- continue;
- }
-
if (child_would_conflict_in_lacc (lacc, norm_offset, rchild->size,
&new_acc))
{
if (new_acc)
{
- if (!new_acc->grp_write
- && (lacc->grp_write || rchild->grp_write))
+ if (!new_acc->grp_write && rchild->grp_write)
{
- new_acc ->grp_write = true;
+ gcc_assert (!lacc->grp_write);
+ subtree_mark_written_and_enqueue (new_acc);
ret = true;
}
@@ -2641,7 +2661,23 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
ret |= propagate_subaccesses_across_link (new_acc, rchild);
}
else
- lacc->grp_write = true;
+ {
+ if (rchild->grp_write && !lacc->grp_write)
+ {
+ ret = true;
+ subtree_mark_written_and_enqueue (lacc);
+ }
+ }
+ continue;
+ }
+
+ if (rchild->grp_unscalarizable_region)
+ {
+ if (rchild->grp_write && !lacc->grp_write)
+ {
+ ret = true;
+ subtree_mark_written_and_enqueue (lacc);
+ }
continue;
}
@@ -2649,37 +2685,17 @@ propagate_subaccesses_across_link (struct access *lacc, struct access *racc)
new_acc = create_artificial_child_access (lacc, rchild, norm_offset,
lacc->grp_write
|| rchild->grp_write);
- if (new_acc)
- {
- ret = true;
- if (racc->first_child)
- propagate_subaccesses_across_link (new_acc, rchild);
- }
+ gcc_checking_assert (new_acc);
+ if (racc->first_child)
+ propagate_subaccesses_across_link (new_acc, rchild);
+
+ add_access_to_work_queue (lacc);
+ ret = true;
}
return ret;
}
-/* Beginning with ACCESS, traverse its whole access subtree and mark all
- sub-trees as written to. If any of them has not been marked so previously
- and has assignment links leading from it, re-enqueue it. */
-
-static void
-subtree_mark_written_and_enqueue (struct access *access)
-{
- if (access->grp_write)
- return;
- access->grp_write = true;
- if (access->first_link)
- add_access_to_work_queue (access);
-
- struct access *child;
- for (child = access->first_child; child; child = child->next_sibling)
- subtree_mark_written_and_enqueue (child);
-}
-
-
-
/* Propagate all subaccesses across assignment links. */
static void
@@ -2715,11 +2731,7 @@ propagate_all_subaccesses (void)
if (reque_parents)
do
{
- if (lacc->first_link)
- {
- add_access_to_work_queue (lacc);
- break;
- }
+ add_access_to_work_queue (lacc);
lacc = lacc->parent;
}
while (lacc);
diff --git a/gcc/tree-ssa-reassoc.c b/gcc/tree-ssa-reassoc.c
index 6831f44..35eb72c 100644
--- a/gcc/tree-ssa-reassoc.c
+++ b/gcc/tree-ssa-reassoc.c
@@ -2282,6 +2282,26 @@ range_entry_cmp (const void *a, const void *b)
}
}
+/* Helper function for update_range_test. Force EXPR into an SSA_NAME,
+ insert needed statements BEFORE or after GSI. */
+
+static tree
+force_into_ssa_name (gimple_stmt_iterator *gsi, tree expr, bool before)
+{
+ enum gsi_iterator_update m = before ? GSI_SAME_STMT : GSI_CONTINUE_LINKING;
+ tree ret = force_gimple_operand_gsi (gsi, expr, true, NULL_TREE, before, m);
+ if (TREE_CODE (ret) != SSA_NAME)
+ {
+ gimple *g = gimple_build_assign (make_ssa_name (TREE_TYPE (ret)), ret);
+ if (before)
+ gsi_insert_before (gsi, g, GSI_SAME_STMT);
+ else
+ gsi_insert_after (gsi, g, GSI_CONTINUE_LINKING);
+ ret = gimple_assign_lhs (g);
+ }
+ return ret;
+}
+
/* Helper routine of optimize_range_test.
[EXP, IN_P, LOW, HIGH, STRICT_OVERFLOW_P] is a merged range for
RANGE and OTHERRANGE through OTHERRANGE + COUNT - 1 ranges,
@@ -2393,15 +2413,13 @@ update_range_test (struct range_entry *range, struct range_entry *otherrange,
else if (op != range->exp)
{
gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
- tem = force_gimple_operand_gsi (&gsi, tem, true, NULL_TREE, true,
- GSI_SAME_STMT);
+ tem = force_into_ssa_name (&gsi, tem, true);
gsi_prev (&gsi);
}
else if (gimple_code (stmt) != GIMPLE_PHI)
{
gsi_insert_seq_after (&gsi, seq, GSI_CONTINUE_LINKING);
- tem = force_gimple_operand_gsi (&gsi, tem, true, NULL_TREE, false,
- GSI_CONTINUE_LINKING);
+ tem = force_into_ssa_name (&gsi, tem, false);
}
else
{
@@ -2419,8 +2437,7 @@ update_range_test (struct range_entry *range, struct range_entry *otherrange,
}
}
gsi_insert_seq_before (&gsi, seq, GSI_SAME_STMT);
- tem = force_gimple_operand_gsi (&gsi, tem, true, NULL_TREE, true,
- GSI_SAME_STMT);
+ tem = force_into_ssa_name (&gsi, tem, true);
if (gsi_end_p (gsi))
gsi = gsi_last_bb (gimple_bb (stmt));
else
diff --git a/gcc/tree-vect-loop.c b/gcc/tree-vect-loop.c
index 64cf05d..b8b49c9 100644
--- a/gcc/tree-vect-loop.c
+++ b/gcc/tree-vect-loop.c
@@ -2790,15 +2790,17 @@ vect_is_simple_reduction (loop_vec_info loop_info, gimple *phi,
}
def_stmt = SSA_NAME_DEF_STMT (loop_arg);
- if (gimple_nop_p (def_stmt))
+ if (is_gimple_assign (def_stmt))
{
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "reduction: no def_stmt\n");
- return NULL;
+ name = gimple_assign_lhs (def_stmt);
+ phi_def = false;
}
-
- if (!is_gimple_assign (def_stmt) && gimple_code (def_stmt) != GIMPLE_PHI)
+ else if (gimple_code (def_stmt) == GIMPLE_PHI)
+ {
+ name = PHI_RESULT (def_stmt);
+ phi_def = true;
+ }
+ else
{
if (dump_enabled_p ())
{
@@ -2809,37 +2811,27 @@ vect_is_simple_reduction (loop_vec_info loop_info, gimple *phi,
return NULL;
}
- if (is_gimple_assign (def_stmt))
- {
- name = gimple_assign_lhs (def_stmt);
- phi_def = false;
- }
- else
- {
- name = PHI_RESULT (def_stmt);
- phi_def = true;
- }
-
nloop_uses = 0;
auto_vec<gphi *, 3> lcphis;
- FOR_EACH_IMM_USE_FAST (use_p, imm_iter, name)
- {
- gimple *use_stmt = USE_STMT (use_p);
- if (is_gimple_debug (use_stmt))
- continue;
- if (flow_bb_inside_loop_p (loop, gimple_bb (use_stmt)))
- nloop_uses++;
- else
- /* We can have more than one loop-closed PHI. */
- lcphis.safe_push (as_a <gphi *> (use_stmt));
- if (nloop_uses > 1)
- {
- if (dump_enabled_p ())
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "reduction used in loop.\n");
- return NULL;
- }
- }
+ if (flow_bb_inside_loop_p (loop, gimple_bb (def_stmt)))
+ FOR_EACH_IMM_USE_FAST (use_p, imm_iter, name)
+ {
+ gimple *use_stmt = USE_STMT (use_p);
+ if (is_gimple_debug (use_stmt))
+ continue;
+ if (flow_bb_inside_loop_p (loop, gimple_bb (use_stmt)))
+ nloop_uses++;
+ else
+ /* We can have more than one loop-closed PHI. */
+ lcphis.safe_push (as_a <gphi *> (use_stmt));
+ if (nloop_uses > 1)
+ {
+ if (dump_enabled_p ())
+ dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
+ "reduction used in loop.\n");
+ return NULL;
+ }
+ }
/* If DEF_STMT is a phi node itself, we expect it to have a single argument
defined in the inner loop. */
@@ -3698,16 +3690,15 @@ get_reduction_op (gimple *stmt, int reduc_index)
generated within the strip-mine loop, the initial definition before
the loop, and the epilogue code that must be generated. */
-static bool
+static void
vect_model_reduction_cost (stmt_vec_info stmt_info, enum tree_code reduc_code,
- int ncopies, int reduc_index)
+ int ncopies)
{
int prologue_cost = 0, epilogue_cost = 0;
enum tree_code code;
optab optab;
tree vectype;
- gimple *stmt, *orig_stmt;
- tree reduction_op;
+ gimple *orig_stmt;
machine_mode mode;
loop_vec_info loop_vinfo = STMT_VINFO_LOOP_VINFO (stmt_info);
struct loop *loop = NULL;
@@ -3728,24 +3719,8 @@ vect_model_reduction_cost (stmt_vec_info stmt_info, enum tree_code reduc_code,
/* Cost of reduction op inside loop. */
unsigned inside_cost = add_stmt_cost (target_cost_data, ncopies, vector_stmt,
stmt_info, 0, vect_body);
- stmt = STMT_VINFO_STMT (stmt_info);
-
- reduction_op = get_reduction_op (stmt, reduc_index);
-
- vectype = get_vectype_for_scalar_type (TREE_TYPE (reduction_op));
- if (!vectype)
- {
- if (dump_enabled_p ())
- {
- dump_printf_loc (MSG_MISSED_OPTIMIZATION, vect_location,
- "unsupported data-type ");
- dump_generic_expr (MSG_MISSED_OPTIMIZATION, TDF_SLIM,
- TREE_TYPE (reduction_op));
- dump_printf (MSG_MISSED_OPTIMIZATION, "\n");
- }
- return false;
- }
+ vectype = STMT_VINFO_VECTYPE (stmt_info);
mode = TYPE_MODE (vectype);
orig_stmt = STMT_VINFO_RELATED_STMT (stmt_info);
@@ -3837,8 +3812,6 @@ vect_model_reduction_cost (stmt_vec_info stmt_info, enum tree_code reduc_code,
"vect_model_reduction_cost: inside_cost = %d, "
"prologue_cost = %d, epilogue_cost = %d .\n", inside_cost,
prologue_cost, epilogue_cost);
-
- return true;
}
@@ -5296,20 +5269,6 @@ vectorizable_reduction (gimple *stmt, gimple_stmt_iterator *gsi,
/* Flatten RHS. */
switch (get_gimple_rhs_class (gimple_assign_rhs_code (stmt)))
{
- case GIMPLE_SINGLE_RHS:
- op_type = TREE_OPERAND_LENGTH (gimple_assign_rhs1 (stmt));
- if (op_type == ternary_op)
- {
- tree rhs = gimple_assign_rhs1 (stmt);
- ops[0] = TREE_OPERAND (rhs, 0);
- ops[1] = TREE_OPERAND (rhs, 1);
- ops[2] = TREE_OPERAND (rhs, 2);
- code = TREE_CODE (rhs);
- }
- else
- return false;
- break;
-
case GIMPLE_BINARY_RHS:
code = gimple_assign_rhs_code (stmt);
op_type = TREE_CODE_LENGTH (code);
@@ -5789,10 +5748,8 @@ vectorizable_reduction (gimple *stmt, gimple_stmt_iterator *gsi,
if (!vec_stmt) /* transformation not required. */
{
- if (first_p
- && !vect_model_reduction_cost (stmt_info, epilog_reduc_code, ncopies,
- reduc_index))
- return false;
+ if (first_p)
+ vect_model_reduction_cost (stmt_info, epilog_reduc_code, ncopies);
STMT_VINFO_TYPE (stmt_info) = reduc_vec_info_type;
return true;
}
diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c
index 716a7c2..a7424a3 100644
--- a/gcc/tree-vrp.c
+++ b/gcc/tree-vrp.c
@@ -5628,6 +5628,82 @@ register_edge_assert_for_1 (tree op, enum tree_code code,
}
}
+/* Check if comparison
+ NAME COND_OP INTEGER_CST
+ has a form of
+ (X & 11...100..0) COND_OP XX...X00...0
+ Such comparison can yield assertions like
+ X >= XX...X00...0
+ X <= XX...X11...1
+ in case of COND_OP being NE_EXPR or
+ X < XX...X00...0
+ X > XX...X11...1
+ in case of EQ_EXPR. */
+
+static bool
+is_masked_range_test (tree name, tree valt, enum tree_code cond_code,
+ tree *new_name, tree *low, enum tree_code *low_code,
+ tree *high, enum tree_code *high_code)
+{
+ gimple *def_stmt = SSA_NAME_DEF_STMT (name);
+
+ if (!is_gimple_assign (def_stmt)
+ || gimple_assign_rhs_code (def_stmt) != BIT_AND_EXPR)
+ return false;
+
+ tree maskt = gimple_assign_rhs2 (def_stmt);
+ if (TREE_CODE (maskt) != INTEGER_CST)
+ return false;
+
+ wide_int mask = maskt;
+ wide_int inv_mask = ~mask;
+ wide_int val = valt; // Assume VALT is INTEGER_CST
+
+ if ((inv_mask & (inv_mask + 1)) != 0
+ || (val & mask) != val)
+ return false;
+
+ tree t = gimple_assign_rhs1 (def_stmt);
+ tree type = TREE_TYPE (t);
+
+ bool is_range = cond_code == EQ_EXPR;
+
+ wide_int min = wi::min_value (type),
+ max = wi::max_value (type);
+
+ if (is_range)
+ {
+ *low_code = val == min ? ERROR_MARK : GE_EXPR;
+ *high_code = val == max ? ERROR_MARK : LE_EXPR;
+ }
+ else
+ {
+ /* We can still generate assertion if one of alternatives
+ is known to always be false. */
+ if (val == min)
+ {
+ *low_code = (enum tree_code) 0;
+ *high_code = GT_EXPR;
+ }
+ else if ((val | inv_mask) == max)
+ {
+ *low_code = LT_EXPR;
+ *high_code = (enum tree_code) 0;
+ }
+ else
+ return false;
+ }
+
+ *new_name = t;
+ *low = wide_int_to_tree (type, val);
+ *high = wide_int_to_tree (type, val | inv_mask);
+
+ if (wi::neg_p (val, TYPE_SIGN (type)))
+ std::swap (*low, *high);
+
+ return true;
+}
+
/* Try to register an edge assertion for SSA name NAME on edge E for
the condition COND contributing to the conditional jump pointed to by
SI. */
@@ -5700,6 +5776,24 @@ register_edge_assert_for (tree name, edge e,
register_edge_assert_for_1 (op1, EQ_EXPR, e, asserts);
}
}
+
+ /* Sometimes we can infer ranges from (NAME & MASK) == VALUE. */
+ if ((comp_code == EQ_EXPR || comp_code == NE_EXPR)
+ && TREE_CODE (val) == INTEGER_CST)
+ {
+ enum tree_code low_code, high_code;
+ tree low, high;
+ if (is_masked_range_test (name, val, comp_code, &name, &low,
+ &low_code, &high, &high_code))
+ {
+ if (low_code != ERROR_MARK)
+ register_edge_assert_for_2 (name, e, low_code, name,
+ low, /*invert*/false, asserts);
+ if (high_code != ERROR_MARK)
+ register_edge_assert_for_2 (name, e, high_code, name,
+ high, /*invert*/false, asserts);
+ }
+ }
}
/* Finish found ASSERTS for E and register them at GSI. */
diff --git a/libgo/go/runtime/cgo_gccgo.go b/libgo/go/runtime/cgo_gccgo.go
index a55fb43..b0ad2f1 100644
--- a/libgo/go/runtime/cgo_gccgo.go
+++ b/libgo/go/runtime/cgo_gccgo.go
@@ -54,7 +54,7 @@ func CgocallDone() {
// If we are invoked because the C function called _cgo_panic,
// then _cgo_panic will already have exited syscall mode.
- if gp.atomicstatus == _Gsyscall {
+ if readgstatus(gp)&^_Gscan == _Gsyscall {
exitsyscall(0)
}
diff --git a/libgo/go/runtime/proc.go b/libgo/go/runtime/proc.go
index 64735e2..32bc148 100644
--- a/libgo/go/runtime/proc.go
+++ b/libgo/go/runtime/proc.go
@@ -1459,7 +1459,7 @@ func dropm() {
// gccgo sets the stack to Gdead here, because the splitstack
// context is not initialized.
- mp.curg.atomicstatus = _Gdead
+ atomic.Store(&mp.curg.atomicstatus, _Gdead)
mp.curg.gcstack = nil
mp.curg.gcnextsp = nil
@@ -2251,6 +2251,7 @@ func goexit0(gp *g) {
casgstatus(gp, _Grunning, _Gdead)
if isSystemGoroutine(gp) {
atomic.Xadd(&sched.ngsys, -1)
+ gp.isSystemGoroutine = false
}
gp.m = nil
gp.lockedm = nil
diff --git a/libgo/go/runtime/traceback_gccgo.go b/libgo/go/runtime/traceback_gccgo.go
index fb51043..0da5171 100644
--- a/libgo/go/runtime/traceback_gccgo.go
+++ b/libgo/go/runtime/traceback_gccgo.go
@@ -94,7 +94,7 @@ func showframe(name string, gp *g) bool {
// We want to print those in the traceback.
// But unless GOTRACEBACK > 1 (checked below), still skip
// internal C functions and cgo-generated functions.
- if !contains(name, ".") && !hasprefix(name, "__go_") && !hasprefix(name, "_cgo_") {
+ if name != "" && !contains(name, ".") && !hasprefix(name, "__go_") && !hasprefix(name, "_cgo_") {
return true
}
diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog
index 0408210..05efaa0 100644
--- a/libstdc++-v3/ChangeLog
+++ b/libstdc++-v3/ChangeLog
@@ -1,3 +1,44 @@
+2017-06-12 Pedro Alves <palves@redhat.com>
+
+ * doc/xml/manual/status_cxx2017.xml: Update C++17 constexpr
+ char_traits status.
+ * doc/html/*: Regenerate.
+
+ * include/bits/char_traits.h (_GLIBCXX_ALWAYS_INLINE): Define if
+ not already defined.
+ (__cpp_lib_constexpr_char_traits): Uncomment.
+ (__constant_string_p, __constant_char_array_p): New.
+ (std::char_traits<char>, std::char_traits<wchar_t>): Add
+ _GLIBCXX17_CONSTEXPR on compare, length and find and use
+ __constant_string_p, __constant_char_array_p and
+ __builtin_constant_p to defer to __gnu_cxx::char_traits at compile
+ time.
+
+ * testsuite/21_strings/char_traits/requirements/
+ constexpr_functions_c++17.cc: Uncomment
+ __cpp_lib_constexpr_char_traits tests. Uncomment
+ test_compare<char>, test_length<char>, test_find<char>,
+ test_compare<wchar_t>, test_length<wchar_t> and test_find<wchar_t>
+ static_assert tests.
+
+2017-06-12 François Dumont <fdumont@gcc.gnu.org>
+
+ * include/bits/stl_tree.h (_Rb_tree_impl()): Restore _Node_allocator
+ default init.
+ * testsuite/util/testsuite_allocator.h
+ (__gnu_test::default_init_allocator<>) New.
+ * testsuite/23_containers/set/allocator/default_init.cc: New.
+ * testsuite/23_containers/map/allocator/default_init.cc: New.
+
+2017-06-12 Jonathan Wakely <jwakely@redhat.com>
+
+ PR libstdc++/55917
+ * src/c++11/thread.cc (execute_native_thread_routine): Remove
+ try-block so that exceptions propagate out of the thread and terminate
+ is called by the exception-handling runtime.
+ (execute_native_thread_routine_compat): Likewise.
+ * testsuite/30_threads/thread/cons/terminate.cc: New.
+
2017-06-09 Jonathan Wakely <jwakely@redhat.com>
* doc/xml/manual/intro.xml: Document LWG 2802, 2873 and 2942 changes.
diff --git a/libstdc++-v3/doc/xml/manual/status_cxx2017.xml b/libstdc++-v3/doc/xml/manual/status_cxx2017.xml
index a208238..85e193d 100644
--- a/libstdc++-v3/doc/xml/manual/status_cxx2017.xml
+++ b/libstdc++-v3/doc/xml/manual/status_cxx2017.xml
@@ -482,15 +482,14 @@ Feature-testing recommendations for C++</link>.
</row>
<row>
- <?dbhtml bgcolor="#B0B0B0" ?>
<entry> Constexpr for <code>std::char_traits</code> </entry>
<entry>
<link xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0426r1.html">
P0426R1
</link>
</entry>
- <entry align="center"> 7 (partial) </entry>
- <entry><code> ??? </code></entry>
+ <entry align="center"> 8 </entry>
+ <entry><code> __cpp_lib_constexpr_char_traits >= 201611 </code></entry>
</row>
<row>
diff --git a/libstdc++-v3/include/bits/char_traits.h b/libstdc++-v3/include/bits/char_traits.h
index f19120b..5ccb439 100644
--- a/libstdc++-v3/include/bits/char_traits.h
+++ b/libstdc++-v3/include/bits/char_traits.h
@@ -40,6 +40,10 @@
#include <bits/postypes.h> // For streampos
#include <cwchar> // For WEOF, wmemmove, wmemset, etc.
+#ifndef _GLIBCXX_ALWAYS_INLINE
+#define _GLIBCXX_ALWAYS_INLINE inline __attribute__((__always_inline__))
+#endif
+
namespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -139,7 +143,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{ return !eq_int_type(__c, eof()) ? __c : to_int_type(char_type()); }
};
-// #define __cpp_lib_constexpr_char_traits 201611
+#define __cpp_lib_constexpr_char_traits 201611
template<typename _CharT>
_GLIBCXX14_CONSTEXPR int
@@ -212,6 +216,42 @@ namespace std _GLIBCXX_VISIBILITY(default)
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
+#if __cplusplus > 201402
+ /**
+ * @brief Determine whether the characters of a NULL-terminated
+ * string are known at compile time.
+ * @param __s The string.
+ *
+ * Assumes that _CharT is a built-in character type.
+ */
+ template<typename _CharT>
+ static _GLIBCXX_ALWAYS_INLINE constexpr bool
+ __constant_string_p(const _CharT* __s)
+ {
+ while (__builtin_constant_p(*__s) && *__s)
+ __s++;
+ return __builtin_constant_p(*__s);
+ }
+
+ /**
+ * @brief Determine whether the characters of a character array are
+ * known at compile time.
+ * @param __a The character array.
+ * @param __n Number of characters.
+ *
+ * Assumes that _CharT is a built-in character type.
+ */
+ template<typename _CharT>
+ static _GLIBCXX_ALWAYS_INLINE constexpr bool
+ __constant_char_array_p(const _CharT* __a, size_t __n)
+ {
+ size_t __i = 0;
+ while (__builtin_constant_p(__a[__i]) && __i < __n)
+ __i++;
+ return __i == __n;
+ }
+#endif
+
// 21.1
/**
* @brief Basis for explicit traits specializations.
@@ -256,21 +296,39 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
< static_cast<unsigned char>(__c2));
}
- static /* _GLIBCXX17_CONSTEXPR */ int
+ static _GLIBCXX17_CONSTEXPR int
compare(const char_type* __s1, const char_type* __s2, size_t __n)
{
+#if __cplusplus > 201402
+ if (__builtin_constant_p(__n)
+ && __constant_char_array_p(__s1, __n)
+ && __constant_char_array_p(__s2, __n))
+ return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
+#endif
if (__n == 0)
return 0;
return __builtin_memcmp(__s1, __s2, __n);
}
- static /* _GLIBCXX17_CONSTEXPR */ size_t
+ static _GLIBCXX17_CONSTEXPR size_t
length(const char_type* __s)
- { return __builtin_strlen(__s); }
+ {
+#if __cplusplus > 201402
+ if (__constant_string_p(__s))
+ return __gnu_cxx::char_traits<char_type>::length(__s);
+#endif
+ return __builtin_strlen(__s);
+ }
- static /* _GLIBCXX17_CONSTEXPR */ const char_type*
+ static _GLIBCXX17_CONSTEXPR const char_type*
find(const char_type* __s, size_t __n, const char_type& __a)
{
+#if __cplusplus > 201402
+ if (__builtin_constant_p(__n)
+ && __builtin_constant_p(__a)
+ && __constant_char_array_p(__s, __n))
+ return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
+#endif
if (__n == 0)
return 0;
return static_cast<const char_type*>(__builtin_memchr(__s, __a, __n));
@@ -347,24 +405,45 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
lt(const char_type& __c1, const char_type& __c2) _GLIBCXX_NOEXCEPT
{ return __c1 < __c2; }
- static /* _GLIBCXX17_CONSTEXPR */ int
+ static _GLIBCXX17_CONSTEXPR int
compare(const char_type* __s1, const char_type* __s2, size_t __n)
{
+#if __cplusplus > 201402
+ if (__builtin_constant_p(__n)
+ && __constant_char_array_p(__s1, __n)
+ && __constant_char_array_p(__s2, __n))
+ return __gnu_cxx::char_traits<char_type>::compare(__s1, __s2, __n);
+#endif
if (__n == 0)
return 0;
- return wmemcmp(__s1, __s2, __n);
+ else
+ return wmemcmp(__s1, __s2, __n);
}
- static /* _GLIBCXX17_CONSTEXPR */ size_t
+ static _GLIBCXX17_CONSTEXPR size_t
length(const char_type* __s)
- { return wcslen(__s); }
+ {
+#if __cplusplus > 201402
+ if (__constant_string_p(__s))
+ return __gnu_cxx::char_traits<char_type>::length(__s);
+ else
+#endif
+ return wcslen(__s);
+ }
- static /* _GLIBCXX17_CONSTEXPR */ const char_type*
+ static _GLIBCXX17_CONSTEXPR const char_type*
find(const char_type* __s, size_t __n, const char_type& __a)
{
+#if __cplusplus > 201402
+ if (__builtin_constant_p(__n)
+ && __builtin_constant_p(__a)
+ && __constant_char_array_p(__s, __n))
+ return __gnu_cxx::char_traits<char_type>::find(__s, __n, __a);
+#endif
if (__n == 0)
return 0;
- return wmemchr(__s, __a, __n);
+ else
+ return wmemchr(__s, __a, __n);
}
static char_type*
diff --git a/libstdc++-v3/include/bits/stl_tree.h b/libstdc++-v3/include/bits/stl_tree.h
index 3f133b0..c2417f1 100644
--- a/libstdc++-v3/include/bits/stl_tree.h
+++ b/libstdc++-v3/include/bits/stl_tree.h
@@ -572,11 +572,11 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
_Node_allocator&
_M_get_Node_allocator() _GLIBCXX_NOEXCEPT
- { return *static_cast<_Node_allocator*>(&this->_M_impl); }
+ { return this->_M_impl; }
const _Node_allocator&
_M_get_Node_allocator() const _GLIBCXX_NOEXCEPT
- { return *static_cast<const _Node_allocator*>(&this->_M_impl); }
+ { return this->_M_impl; }
allocator_type
get_allocator() const _GLIBCXX_NOEXCEPT
@@ -685,13 +685,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
{
typedef _Rb_tree_key_compare<_Key_compare> _Base_key_compare;
-#if __cplusplus < 201103L
_Rb_tree_impl()
+ _GLIBCXX_NOEXCEPT_IF(
+ is_nothrow_default_constructible<_Node_allocator>::value
+ && is_nothrow_default_constructible<_Base_key_compare>::value )
+ : _Node_allocator()
{ }
-#else
- _Rb_tree_impl() = default;
- _Rb_tree_impl(_Rb_tree_impl&&) = default;
-#endif
_Rb_tree_impl(const _Rb_tree_impl& __x)
: _Node_allocator(_Alloc_traits::_S_select_on_copy(__x))
@@ -703,6 +702,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
: _Node_allocator(__a), _Base_key_compare(__comp)
{ }
#else
+ _Rb_tree_impl(_Rb_tree_impl&&) = default;
+
_Rb_tree_impl(const _Key_compare& __comp, _Node_allocator&& __a)
: _Node_allocator(std::move(__a)), _Base_key_compare(__comp)
{ }
diff --git a/libstdc++-v3/src/c++11/thread.cc b/libstdc++-v3/src/c++11/thread.cc
index 44a230a..4a94bdd 100644
--- a/libstdc++-v3/src/c++11/thread.cc
+++ b/libstdc++-v3/src/c++11/thread.cc
@@ -77,20 +77,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
execute_native_thread_routine(void* __p)
{
thread::_State_ptr __t{ static_cast<thread::_State*>(__p) };
-
- __try
- {
- __t->_M_run();
- }
- __catch(const __cxxabiv1::__forced_unwind&)
- {
- __throw_exception_again;
- }
- __catch(...)
- {
- std::terminate();
- }
-
+ __t->_M_run();
return nullptr;
}
@@ -104,20 +91,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
// the thread state to a local object, breaking the reference cycle
// created in thread::_M_start_thread.
__local.swap(__t->_M_this_ptr);
-
- __try
- {
- __t->_M_run();
- }
- __catch(const __cxxabiv1::__forced_unwind&)
- {
- __throw_exception_again;
- }
- __catch(...)
- {
- std::terminate();
- }
-
+ __t->_M_run();
return nullptr;
}
#endif
diff --git a/libstdc++-v3/testsuite/21_strings/char_traits/requirements/constexpr_functions_c++17.cc b/libstdc++-v3/testsuite/21_strings/char_traits/requirements/constexpr_functions_c++17.cc
index 014caa0..efd280f 100644
--- a/libstdc++-v3/testsuite/21_strings/char_traits/requirements/constexpr_functions_c++17.cc
+++ b/libstdc++-v3/testsuite/21_strings/char_traits/requirements/constexpr_functions_c++17.cc
@@ -74,20 +74,20 @@ template<typename CT>
}
#ifndef __cpp_lib_constexpr_char_traits
-// #error Feature-test macro for constexpr char_traits is missing
+# error Feature-test macro for constexpr char_traits is missing
#elif __cpp_lib_constexpr_char_traits != 201611
-// #error Feature-test macro for constexpr char_traits has the wrong value
+# error Feature-test macro for constexpr char_traits has the wrong value
#endif
static_assert( test_assign<std::char_traits<char>>() );
-// static_assert( test_compare<std::char_traits<char>>() );
-// static_assert( test_length<std::char_traits<char>>() );
-// static_assert( test_find<std::char_traits<char>>() );
+static_assert( test_compare<std::char_traits<char>>() );
+static_assert( test_length<std::char_traits<char>>() );
+static_assert( test_find<std::char_traits<char>>() );
#ifdef _GLIBCXX_USE_WCHAR_T
static_assert( test_assign<std::char_traits<wchar_t>>() );
-// static_assert( test_compare<std::char_traits<wchar_t>>() );
-// static_assert( test_length<std::char_traits<wchar_t>>() );
-// static_assert( test_find<std::char_traits<wchar_t>>() );
+static_assert( test_compare<std::char_traits<wchar_t>>() );
+static_assert( test_length<std::char_traits<wchar_t>>() );
+static_assert( test_find<std::char_traits<wchar_t>>() );
#endif
static_assert( test_assign<std::char_traits<char16_t>>() );
static_assert( test_compare<std::char_traits<char16_t>>() );
diff --git a/libstdc++-v3/testsuite/23_containers/map/allocator/default_init.cc b/libstdc++-v3/testsuite/23_containers/map/allocator/default_init.cc
new file mode 100644
index 0000000..1ef13d9
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/map/allocator/default_init.cc
@@ -0,0 +1,67 @@
+// Copyright (C) 2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+// { dg-options "-O0" }
+// { dg-xfail-run-if "PR c++/65816" { *-*-* } }
+
+#include <map>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+#include <ext/aligned_buffer.h>
+
+using T = int;
+
+using __gnu_test::default_init_allocator;
+
+void test01()
+{
+ typedef default_init_allocator<std::pair<const T, T>> alloc_type;
+ typedef std::map<T, T, std::less<T>, alloc_type> test_type;
+
+ __gnu_cxx::__aligned_buffer<test_type> buf;
+ __builtin_memset(buf._M_addr(), ~0, sizeof(test_type));
+
+ test_type *tmp = ::new(buf._M_addr()) test_type;
+
+ VERIFY( tmp->get_allocator().state == 0 );
+
+ tmp->~test_type();
+}
+
+void test02()
+{
+ typedef default_init_allocator<std::pair<const T, T>> alloc_type;
+ typedef std::map<T, T, std::less<T>, alloc_type> test_type;
+
+ __gnu_cxx::__aligned_buffer<test_type> buf;
+ __builtin_memset(buf._M_addr(), ~0, sizeof(test_type));
+
+ test_type *tmp = ::new(buf._M_addr()) test_type();
+
+ VERIFY( tmp->get_allocator().state == 0 );
+
+ tmp->~test_type();
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/23_containers/set/allocator/default_init.cc b/libstdc++-v3/testsuite/23_containers/set/allocator/default_init.cc
new file mode 100644
index 0000000..4e14e18
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/set/allocator/default_init.cc
@@ -0,0 +1,67 @@
+// Copyright (C) 2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target c++11 } }
+// { dg-options "-O0" }
+// { dg-xfail-run-if "PR c++/65816" { *-*-* } }
+
+#include <set>
+#include <testsuite_hooks.h>
+#include <testsuite_allocator.h>
+
+#include <ext/aligned_buffer.h>
+
+using T = int;
+
+using __gnu_test::default_init_allocator;
+
+void test01()
+{
+ typedef default_init_allocator<T> alloc_type;
+ typedef std::set<T, std::less<T>, alloc_type> test_type;
+
+ __gnu_cxx::__aligned_buffer<test_type> buf;
+ __builtin_memset(buf._M_addr(), ~0, sizeof(test_type));
+
+ test_type *tmp = ::new(buf._M_addr()) test_type;
+
+ VERIFY( tmp->get_allocator().state == 0 );
+
+ tmp->~test_type();
+}
+
+void test02()
+{
+ typedef default_init_allocator<T> alloc_type;
+ typedef std::set<T, std::less<T>, alloc_type> test_type;
+
+ __gnu_cxx::__aligned_buffer<test_type> buf;
+ __builtin_memset(buf._M_addr(), ~0, sizeof(test_type));
+
+ test_type *tmp = ::new(buf._M_addr()) test_type();
+
+ VERIFY( tmp->get_allocator().state == 0 );
+
+ tmp->~test_type();
+}
+
+int main()
+{
+ test01();
+ test02();
+ return 0;
+}
diff --git a/libstdc++-v3/testsuite/30_threads/thread/cons/terminate.cc b/libstdc++-v3/testsuite/30_threads/thread/cons/terminate.cc
new file mode 100644
index 0000000..4b35b6c
--- /dev/null
+++ b/libstdc++-v3/testsuite/30_threads/thread/cons/terminate.cc
@@ -0,0 +1,48 @@
+// Copyright (C) 2017 Free Software Foundation, Inc.
+//
+// This file is part of the GNU ISO C++ Library. This library is free
+// software; you can redistribute it and/or modify it under the
+// terms of the GNU General Public License as published by the
+// Free Software Foundation; either version 3, or (at your option)
+// any later version.
+
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+
+// You should have received a copy of the GNU General Public License along
+// with this library; see the file COPYING3. If not see
+// <http://www.gnu.org/licenses/>.
+
+// { dg-do run { target *-*-freebsd* *-*-dragonfly* *-*-netbsd* *-*-linux* *-*-gnu* *-*-solaris* *-*-cygwin *-*-rtems* *-*-darwin* powerpc-ibm-aix* } }
+// { dg-options "-pthread" { target *-*-freebsd* *-*-dragonfly* *-*-netbsd* *-*-linux* *-*-gnu* *-*-solaris* powerpc-ibm-aix* } }
+// { dg-require-effective-target c++11 }
+// { dg-require-cstdint "" }
+// { dg-require-gthreads "" }
+
+#include <thread>
+#include <exception>
+#include <cstdlib>
+
+void handle_terminate()
+{
+ std::_Exit(0);
+}
+
+void f() { throw 1; }
+
+void
+test01()
+{
+ std::set_terminate(handle_terminate);
+ std::thread t(f);
+ t.join();
+ std::abort();
+}
+
+int
+main()
+{
+ test01();
+}
diff --git a/libstdc++-v3/testsuite/util/testsuite_allocator.h b/libstdc++-v3/testsuite/util/testsuite_allocator.h
index 56c2708..233ea0b 100644
--- a/libstdc++-v3/testsuite/util/testsuite_allocator.h
+++ b/libstdc++-v3/testsuite/util/testsuite_allocator.h
@@ -508,6 +508,38 @@ namespace __gnu_test
bool operator!=(const SimpleAllocator<T>&, const SimpleAllocator<U>&)
{ return false; }
+ template<typename T>
+ struct default_init_allocator
+ {
+ using value_type = T;
+
+ default_init_allocator() = default;
+
+ template<typename U>
+ default_init_allocator(const default_init_allocator<U>& a)
+ : state(a.state)
+ { }
+
+ T*
+ allocate(std::size_t n)
+ { return std::allocator<T>().allocate(n); }
+
+ void
+ deallocate(T* p, std::size_t n)
+ { std::allocator<T>().deallocate(p, n); }
+
+ int state;
+ };
+
+ template<typename T, typename U>
+ bool operator==(const default_init_allocator<T>& t,
+ const default_init_allocator<U>& u)
+ { return t.state == u.state; }
+
+ template<typename T, typename U>
+ bool operator!=(const default_init_allocator<T>& t,
+ const default_init_allocator<U>& u)
+ { return !(t == u); }
#endif
template<typename Tp>