diff options
author | Ian Lance Taylor <ian@gcc.gnu.org> | 2018-02-13 22:04:09 +0000 |
---|---|---|
committer | Ian Lance Taylor <ian@gcc.gnu.org> | 2018-02-13 22:04:09 +0000 |
commit | cb1ee43f1c87cc08bb7f930138fba0476879499a (patch) | |
tree | f5e4bbb1924e4046c38bbf624a3a029efd08be5f | |
parent | e1233632f292cc85f7fd669a1964b2dd914fee9d (diff) | |
parent | a2f5a78214edc4716e6f97b97fb7839a211e8ff7 (diff) | |
download | gcc-cb1ee43f1c87cc08bb7f930138fba0476879499a.zip gcc-cb1ee43f1c87cc08bb7f930138fba0476879499a.tar.gz gcc-cb1ee43f1c87cc08bb7f930138fba0476879499a.tar.bz2 |
Merge from trunk revision 257637.
From-SVN: r257643
64 files changed, 1292 insertions, 254 deletions
@@ -1,3 +1,8 @@ +2018-02-13 Maciej W. Rozycki <macro@mips.com> + + * configure.ac <wasm32-*-*> (noconfigdirs): Add `ld'. + * configure: Regenerate. + 2018-01-18 Boris Kolpackov <boris@codesynthesis.com> * MAINTAINERS (write after approval): Add myself. @@ -3860,6 +3860,9 @@ case "${target}" in vax-*-*) noconfigdirs="$noconfigdirs target-newlib target-libgloss" ;; + wasm32-*-*) + noconfigdirs="$noconfigdirs ld" + ;; esac # If we aren't building newlib, then don't build libgloss, since libgloss diff --git a/configure.ac b/configure.ac index aae9450..c343333 100644 --- a/configure.ac +++ b/configure.ac @@ -1191,6 +1191,9 @@ case "${target}" in vax-*-*) noconfigdirs="$noconfigdirs target-newlib target-libgloss" ;; + wasm32-*-*) + noconfigdirs="$noconfigdirs ld" + ;; esac # If we aren't building newlib, then don't build libgloss, since libgloss diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d5913d0..c58d419 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,135 @@ +2018-02-13 Jakub Jelinek <jakub@redhat.com> + + PR c/82210 + * stor-layout.c (place_field): For variable length fields, adjust + offset_align afterwards not just based on the field's alignment, + but also on the size. + + PR middle-end/84309 + * match.pd (pow(C,x) -> exp(log(C)*x)): Use exp2s and log2s instead + of exps and logs in the use_exp2 case. + +2018-02-13 Jeff Law <law@redhat.com> + + * config/rl/rl78.c (rl78_attribute_table): Fix terminator and + entry for "vector". + + * config/rl78/rl78.c (rl78_handle_func_attribute): Mark + ARGS as unused. + +2018-02-13 Alexandre Oliva <aoliva@redhat.com> + + * common.opt (gas-loc-support, gas-locview-support): New. + (ginline-points, ginternal-reset-location-views): New. + * doc/invoke.texi: Document them. Use @itemx where intended. + (gvariable-location-views): Adjust. + * target.def (reset_location_view): New. + * doc/tm.texi.in (DWARF2_ASM_VIEW_DEBUG_INFO): New. + (TARGET_RESET_LOCATION_VIEW): New. + * doc/tm.texi: Rebuilt. + * dwarf2out.c (dwarf2out_default_as_loc_support): New. + (dwarf2out_default_as_locview_support): New. + (output_asm_line_debug_info): Use option variables. + (dwarf2out_maybe_output_loclist_view_pair): Likewise. + (output_loc_list): Likewise. + (add_high_low_attributes): Check option variables. + Don't output entry view attribute in strict mode. + (gen_inlined_subroutine_die): Check option variables. + (dwarf2out_inline_entry): Likewise. + (init_sections_and_labels): Likewise. + (dwarf2out_early_finish): Likewise. + (maybe_reset_location_view): New, from... + (dwarf2out_var_location): ... here. Call it. + * debug.h (dwarf2out_default_as_loc_support): Declare. + (dwarf2out_default_as_locview_support): Declare. + * hooks.c (hook_int_rtx_insn_0): New. + * hooks.h (hook_int_rtx_insn_0): Declare. + * toplev.c (process_options): Take -gas-loc-support and + -gas-locview-support from dwarf2out. Enable + -gvariable-location-views by default only with locview + assembler support. Enable -ginternal-reset-location-views by + default only if the target defines the corresponding hook. + Enable -ginline-points by default if location views are + enabled; force it disabled if statement frontiers are + disabled. + * tree-inline.c (expand_call_inline): Check option variables. + * tree-ssa-live.c (remove_unused_scope_block_p): Likewise. + +2018-02-13 Richard Sandiford <richard.sandiford@linaro.org> + + PR tree-optimization/84321 + * tree-vrp.c (intersect_range_with_nonzero_bits): Fix VR_ANTI_RANGE + handling. Also check whether the anti-range contains any values + that satisfy the mask; switch to a VR_RANGE if not. + +2018-02-13 Paolo Bonzini <bonzini@gnu.org> + + PR sanitizer/84340 + * internal-fn.def (ASAN_CHECK, ASAN_MARK): Revert changes to fnspec. + +2018-02-13 Martin Jambor <mjambor@suse.cz> + + PR c++/83990 + * ipa-param-manipulation.c (ipa_modify_call_arguments): Use location + of call statements, also set location of a load to a temporary. + +2018-02-13 Sebastian Perta <sebastian.perta@renesas.com> + + * config/rl78/rl78.c (add_vector_labels): New function. + * config/rl78/rl78.c (rl78_handle_vector_attribute): New function. + * config/rl78/rl78.c (rl78_start_function): Call add_vector_labels. + * config/rl78/rl78.c (rl78_handle_func_attribute): Removed the assert + which checks that no arguments are passed. + * config/rl78/rl78.c (rl78_attribute_table): Add "vector" attribute. + * doc/extend.texi: Documentation for the new attribute. + +2018-02-13 Andreas Schwab <schwab@suse.de> + + * config/riscv/linux.h (CPP_SPEC): Define. + +2018-02-13 Jakub Jelinek <jakub@redhat.com> + + PR target/84335 + * config/i386/i386.c (ix86_init_mmx_sse_builtins): Pass + OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2 instead of + OPTION_MASK_ISA_AES as first argument to def_builtin_const + for AES builtins. Pass OPTION_MASK_ISA_PCLMUL | OPTION_MASK_ISA_SSE2 + instead of OPTION_MASK_ISA_PCLMUL as first argument to + def_builtin_const for __builtin_ia32_pclmulqdq128 builtin. + * config/i386/wmmintrin.h: If __SSE2__ is not defined, enable it + temporarily for AES and PCLMUL builtins. + + PR tree-optimization/84339 + * gimple-fold.c (get_range_strlen): Set *FLEXP to true when handling + ARRAY_REF where first operand is array_at_struct_end_p COMPONENT_REF. + Formatting fixes. + + PR middle-end/84309 + * match.pd (pow(C,x) -> exp(log(C)*x)): Optimize instead into + exp2(log2(C)*x) if C is a power of 2 and c99 runtime is available. + * generic-match-head.c (canonicalize_math_after_vectorization_p): New + inline function. + * gimple-match-head.c (canonicalize_math_after_vectorization_p): New + inline function. + * omp-simd-clone.h: New file. + * omp-simd-clone.c: Include omp-simd-clone.h. + (expand_simd_clones): No longer static. + * tree-vect-patterns.c: Include fold-const-call.h, attribs.h, + cgraph.h and omp-simd-clone.h. + (vect_recog_pow_pattern): Optimize pow(C,x) to exp(log(C)*x). + (vect_recog_widen_shift_pattern): Formatting fix. + (vect_pattern_recog_1): Don't check optab for calls. + + PR target/84336 + * config/i386/sse.md (<avx512>_vpermi2var<mode>3_mask): Force + operands[2] into a REG before using gen_lowpart on it. + 2018-02-12 Jeff Law <law@redhat.com> + PR target/83760 + * config/sh/sh.c (find_barrier): Consider a sibling call + a barrier as well. + * cse.c (try_back_substitute_reg): Move any REG_ARGS_SIZE note when successfully back substituting a reg. diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index bca7268..f0fd33e 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,11 @@ +2018-02-13 Richard Sandiford <richard.sandiford@linaro.org> + + PR c/84305 + * c-decl.c (grokdeclarator): Create an anonymous TYPE_DECL + in PARM and TYPENAME contexts too, but attach it to a BIND_EXPR + and include the BIND_EXPR in the list of things that need to be + pre-evaluated. + 2018-02-09 Nathan Sidwell <nathan@acm.org> PR c/84293 diff --git a/gcc/c/c-decl.c b/gcc/c/c-decl.c index f800464..f0198ec 100644 --- a/gcc/c/c-decl.c +++ b/gcc/c/c-decl.c @@ -6479,28 +6479,53 @@ grokdeclarator (const struct c_declarator *declarator, type has a name/declaration of it's own, but special attention is required if the type is anonymous. - We handle the NORMAL and FIELD contexts here by attaching an - artificial TYPE_DECL to such pointed-to type. This forces the - sizes evaluation at a safe point and ensures it is not deferred - until e.g. within a deeper conditional context. - - We expect nothing to be needed here for PARM or TYPENAME. - Pushing a TYPE_DECL at this point for TYPENAME would actually - be incorrect, as we might be in the middle of an expression - with side effects on the pointed-to type size "arguments" prior - to the pointer declaration point and the fake TYPE_DECL in the - enclosing context would force the size evaluation prior to the - side effects. */ - + We attach an artificial TYPE_DECL to such pointed-to type + and arrange for it to be included in a DECL_EXPR. This + forces the sizes evaluation at a safe point and ensures it + is not deferred until e.g. within a deeper conditional context. + + PARM contexts have no enclosing statement list that + can hold the DECL_EXPR, so we need to use a BIND_EXPR + instead, and add it to the list of expressions that + need to be evaluated. + + TYPENAME contexts do have an enclosing statement list, + but it would be incorrect to use it, as the size should + only be evaluated if the containing expression is + evaluated. We might also be in the middle of an + expression with side effects on the pointed-to type size + "arguments" prior to the pointer declaration point and + the fake TYPE_DECL in the enclosing context would force + the size evaluation prior to the side effects. We therefore + use BIND_EXPRs in TYPENAME contexts too. */ if (!TYPE_NAME (type) - && (decl_context == NORMAL || decl_context == FIELD) && variably_modified_type_p (type, NULL_TREE)) { + tree bind = NULL_TREE; + if (decl_context == TYPENAME || decl_context == PARM) + { + bind = build3 (BIND_EXPR, void_type_node, NULL_TREE, + NULL_TREE, NULL_TREE); + TREE_SIDE_EFFECTS (bind) = 1; + BIND_EXPR_BODY (bind) = push_stmt_list (); + push_scope (); + } tree decl = build_decl (loc, TYPE_DECL, NULL_TREE, type); DECL_ARTIFICIAL (decl) = 1; pushdecl (decl); finish_decl (decl, loc, NULL_TREE, NULL_TREE, NULL_TREE); TYPE_NAME (type) = decl; + if (bind) + { + pop_scope (); + BIND_EXPR_BODY (bind) + = pop_stmt_list (BIND_EXPR_BODY (bind)); + if (*expr) + *expr = build2 (COMPOUND_EXPR, void_type_node, *expr, + bind); + else + *expr = bind; + } } type = c_build_pointer_type (type); diff --git a/gcc/common.opt b/gcc/common.opt index 40ec008..e0bc4d1 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -2880,6 +2880,14 @@ g Common Driver RejectNegative JoinedOrMissing Generate debug information in default format. +gas-loc-support +Common Driver Var(dwarf2out_as_loc_support) Init(2) +Assume assembler support for (DWARF2+) .loc directives + +gas-locview-support +Common Driver Var(dwarf2out_as_locview_support) Init(2) +Assume assembler support for view in (DWARF2+) .loc directives + gcoff Common Driver Ignore Warn(switch %qs no longer supported) Does nothing. Preserved for backward compatibility. @@ -2912,6 +2920,14 @@ ggdb Common Driver JoinedOrMissing Generate debug information in default extended format. +ginline-points +Common Driver Var(debug_inline_points) Init(2) +Generate extended entry point information for inlined functions + +ginternal-reset-location-views +Common Driver Var(debug_internal_reset_location_views) Init(2) +Compute locview reset points based on insn length estimates + gno- RejectNegative Joined Undocumented ; Catch the gno- prefix, so it doesn't backtrack to g<level>. diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index a870997..020eef9 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -31282,21 +31282,28 @@ ix86_init_mmx_sse_builtins (void) VOID_FTYPE_UNSIGNED_UNSIGNED, IX86_BUILTIN_MWAIT); /* AES */ - def_builtin_const (OPTION_MASK_ISA_AES, "__builtin_ia32_aesenc128", + def_builtin_const (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2, + "__builtin_ia32_aesenc128", V2DI_FTYPE_V2DI_V2DI, IX86_BUILTIN_AESENC128); - def_builtin_const (OPTION_MASK_ISA_AES, "__builtin_ia32_aesenclast128", + def_builtin_const (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2, + "__builtin_ia32_aesenclast128", V2DI_FTYPE_V2DI_V2DI, IX86_BUILTIN_AESENCLAST128); - def_builtin_const (OPTION_MASK_ISA_AES, "__builtin_ia32_aesdec128", + def_builtin_const (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2, + "__builtin_ia32_aesdec128", V2DI_FTYPE_V2DI_V2DI, IX86_BUILTIN_AESDEC128); - def_builtin_const (OPTION_MASK_ISA_AES, "__builtin_ia32_aesdeclast128", + def_builtin_const (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2, + "__builtin_ia32_aesdeclast128", V2DI_FTYPE_V2DI_V2DI, IX86_BUILTIN_AESDECLAST128); - def_builtin_const (OPTION_MASK_ISA_AES, "__builtin_ia32_aesimc128", + def_builtin_const (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2, + "__builtin_ia32_aesimc128", V2DI_FTYPE_V2DI, IX86_BUILTIN_AESIMC128); - def_builtin_const (OPTION_MASK_ISA_AES, "__builtin_ia32_aeskeygenassist128", + def_builtin_const (OPTION_MASK_ISA_AES | OPTION_MASK_ISA_SSE2, + "__builtin_ia32_aeskeygenassist128", V2DI_FTYPE_V2DI_INT, IX86_BUILTIN_AESKEYGENASSIST128); /* PCLMUL */ - def_builtin_const (OPTION_MASK_ISA_PCLMUL, "__builtin_ia32_pclmulqdq128", + def_builtin_const (OPTION_MASK_ISA_PCLMUL | OPTION_MASK_ISA_SSE2, + "__builtin_ia32_pclmulqdq128", V2DI_FTYPE_V2DI_V2DI_INT, IX86_BUILTIN_PCLMULQDQ128); /* RDRND */ diff --git a/gcc/config/i386/sse.md b/gcc/config/i386/sse.md index da9af23..26c4f52 100644 --- a/gcc/config/i386/sse.md +++ b/gcc/config/i386/sse.md @@ -18183,7 +18183,10 @@ (match_dup 5) (match_operand:<avx512fmaskmode> 4 "register_operand")))] "TARGET_AVX512F" - "operands[5] = gen_lowpart (<MODE>mode, operands[2]);") +{ + operands[2] = force_reg (<sseintvecmode>mode, operands[2]); + operands[5] = gen_lowpart (<MODE>mode, operands[2]); +}) (define_insn "*<avx512>_vpermi2var<mode>3_mask" [(set (match_operand:VPERMI2I 0 "register_operand" "=v") diff --git a/gcc/config/i386/wmmintrin.h b/gcc/config/i386/wmmintrin.h index 5eabf69..61837f3 100644 --- a/gcc/config/i386/wmmintrin.h +++ b/gcc/config/i386/wmmintrin.h @@ -32,9 +32,9 @@ /* AES */ -#ifndef __AES__ +#if !defined(__AES__) || !defined(__SSE2__) #pragma GCC push_options -#pragma GCC target("aes") +#pragma GCC target("aes,sse2") #define __DISABLE_AES__ #endif /* __AES__ */ @@ -101,9 +101,9 @@ _mm_aeskeygenassist_si128 (__m128i __X, const int __C) /* PCLMUL */ -#ifndef __PCLMUL__ +#if !defined(__PCLMUL__) || !defined(__SSE2__) #pragma GCC push_options -#pragma GCC target("pclmul") +#pragma GCC target("pclmul,sse2") #define __DISABLE_PCLMUL__ #endif /* __PCLMUL__ */ diff --git a/gcc/config/riscv/linux.h b/gcc/config/riscv/linux.h index 1da1b0a..ad03654 100644 --- a/gcc/config/riscv/linux.h +++ b/gcc/config/riscv/linux.h @@ -47,6 +47,8 @@ along with GCC; see the file COPYING3. If not see #define ICACHE_FLUSH_FUNC "__riscv_flush_icache" +#define CPP_SPEC "%{pthread:-D_REENTRANT}" + #define LINK_SPEC "\ -melf" XLEN_SPEC "lriscv \ %{shared} \ diff --git a/gcc/config/rl78/rl78.c b/gcc/config/rl78/rl78.c index b8c1e7b..8346c9c 100644 --- a/gcc/config/rl78/rl78.c +++ b/gcc/config/rl78/rl78.c @@ -804,12 +804,11 @@ is_brk_interrupt_func (const_tree decl) static tree rl78_handle_func_attribute (tree * node, tree name, - tree args, + tree args ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED, bool * no_add_attrs) { gcc_assert (DECL_P (* node)); - gcc_assert (args == NULL_TREE); if (TREE_CODE (* node) != FUNCTION_DECL) { @@ -868,6 +867,28 @@ rl78_handle_saddr_attribute (tree * node, return NULL_TREE; } +/* Check "vector" attribute. */ + +static tree +rl78_handle_vector_attribute (tree * node, + tree name, + tree args, + int flags ATTRIBUTE_UNUSED, + bool * no_add_attrs) +{ + gcc_assert (DECL_P (* node)); + gcc_assert (args != NULL_TREE); + + if (TREE_CODE (* node) != FUNCTION_DECL) + { + warning (OPT_Wattributes, "%qE attribute only applies to functions", + name); + * no_add_attrs = true; + } + + return NULL_TREE; +} + #undef TARGET_ATTRIBUTE_TABLE #define TARGET_ATTRIBUTE_TABLE rl78_attribute_table @@ -876,7 +897,7 @@ const struct attribute_spec rl78_attribute_table[] = { /* Name, min_len, max_len, decl_req, type_req, fn_type_req, affects_type_identity, handler, exclude. */ - { "interrupt", 0, 0, true, false, false, false, + { "interrupt", 0, -1, true, false, false, false, rl78_handle_func_attribute, NULL }, { "brk_interrupt", 0, 0, true, false, false, false, rl78_handle_func_attribute, NULL }, @@ -884,6 +905,8 @@ const struct attribute_spec rl78_attribute_table[] = rl78_handle_naked_attribute, NULL }, { "saddr", 0, 0, true, false, false, false, rl78_handle_saddr_attribute, NULL }, + { "vector", 1, -1, true, false, false, false, + rl78_handle_vector_attribute, NULL }, { NULL, 0, 0, false, false, false, false, NULL, NULL } }; @@ -1583,6 +1606,62 @@ rl78_expand_eh_epilogue (rtx x ATTRIBUTE_UNUSED) #undef TARGET_ASM_FUNCTION_PROLOGUE #define TARGET_ASM_FUNCTION_PROLOGUE rl78_start_function +static void +add_vector_labels (FILE *file, const char *aname) +{ + tree vec_attr; + tree val_attr; + const char *vname = "vect"; + const char *s; + int vnum; + + /* This node is for the vector/interrupt tag itself */ + vec_attr = lookup_attribute (aname, DECL_ATTRIBUTES (current_function_decl)); + if (!vec_attr) + return; + + /* Now point it at the first argument */ + vec_attr = TREE_VALUE (vec_attr); + + /* Iterate through the arguments. */ + while (vec_attr) + { + val_attr = TREE_VALUE (vec_attr); + switch (TREE_CODE (val_attr)) + { + case STRING_CST: + s = TREE_STRING_POINTER (val_attr); + goto string_id_common; + + case IDENTIFIER_NODE: + s = IDENTIFIER_POINTER (val_attr); + + string_id_common: + if (strcmp (s, "$default") == 0) + { + fprintf (file, "\t.global\t$tableentry$default$%s\n", vname); + fprintf (file, "$tableentry$default$%s:\n", vname); + } + else + vname = s; + break; + + case INTEGER_CST: + vnum = TREE_INT_CST_LOW (val_attr); + + fprintf (file, "\t.global\t$tableentry$%d$%s\n", vnum, vname); + fprintf (file, "$tableentry$%d$%s:\n", vnum, vname); + break; + + default: + ; + } + + vec_attr = TREE_CHAIN (vec_attr); + } + +} + /* We don't use this to actually emit the function prologue. We use this to insert a comment in the asm file describing the function. */ @@ -1590,6 +1669,9 @@ static void rl78_start_function (FILE *file) { int i; + + add_vector_labels (file, "interrupt"); + add_vector_labels (file, "vector"); if (cfun->machine->framesize == 0) return; diff --git a/gcc/config/sh/sh.c b/gcc/config/sh/sh.c index 48e99a3..90d6c73 100644 --- a/gcc/config/sh/sh.c +++ b/gcc/config/sh/sh.c @@ -5233,10 +5233,22 @@ find_barrier (int num_mova, rtx_insn *mova, rtx_insn *from) CALL_ARG_LOCATION note. */ if (CALL_P (from)) { + bool sibcall_p = SIBLING_CALL_P (from); + rtx_insn *next = NEXT_INSN (from); if (next && NOTE_P (next) && NOTE_KIND (next) == NOTE_INSN_CALL_ARG_LOCATION) from = next; + + /* If FROM was a sibling call, then we know that control + will not return. In fact, we were guaranteed to hit + a barrier before another real insn. + + The jump around the constant pool is unnecessary. It + costs space, but more importantly it confuses dwarf2cfi + generation. */ + if (sibcall_p) + return emit_barrier_after (from); } from = emit_jump_insn_after (gen_jump (label), from); diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c2b19d8..7c52ede 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,25 @@ +2018-02-13 Jason Merrill <jason@redhat.com> + + PR c++/84080 - ICE with return type deduction and specialization. + * pt.c (determine_specialization): Check uses_template_parms. + + Fix more variadic capture issues. + * pt.c (find_parameter_packs_r): Also look at explicit captures. + (check_for_bare_parameter_packs): Check current_class_type for + lambda context. + (extract_locals_r): Handle seeing a full instantiation of a pack. + (tsubst_pack_expansion): Likewise. Force lambda capture. + * parser.c (cp_parser_lambda_introducer): Don't + check_for_bare_parameter_packs. + + PR c++/84338 - wrong variadic sizeof. + * pt.c (argument_pack_select_arg): Like the macro, but look through + a pack expansion. + (tsubst, tsubst_copy, dependent_template_arg_p): Use it. + (extract_fnparm_pack): Do make_pack_expansion. + (extract_locals_r): Do strip a pack expansion. + * cp-tree.h (ARGUMENT_PACK_SELECT_ARG): Remove. + 2018-02-12 Jakub Jelinek <jakub@redhat.com> PR c++/84341 diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index a6c75ae..9a9e9f0 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3558,12 +3558,6 @@ extern void decl_shadowed_for_var_insert (tree, tree); #define ARGUMENT_PACK_SELECT_INDEX(NODE) \ (((struct tree_argument_pack_select *)ARGUMENT_PACK_SELECT_CHECK (NODE))->index) -/* In an ARGUMENT_PACK_SELECT, the actual underlying argument that the - ARGUMENT_PACK_SELECT represents. */ -#define ARGUMENT_PACK_SELECT_ARG(NODE) \ - TREE_VEC_ELT (ARGUMENT_PACK_ARGS (ARGUMENT_PACK_SELECT_FROM_PACK (NODE)), \ - ARGUMENT_PACK_SELECT_INDEX (NODE)) - #define FOLD_EXPR_CHECK(NODE) \ TREE_CHECK4 (NODE, UNARY_LEFT_FOLD_EXPR, UNARY_RIGHT_FOLD_EXPR, \ BINARY_LEFT_FOLD_EXPR, BINARY_RIGHT_FOLD_EXPR) diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 9a05e4f..81c6f01 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -10412,8 +10412,6 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr) cp_lexer_consume_token (parser->lexer); capture_init_expr = make_pack_expansion (capture_init_expr); } - else - check_for_bare_parameter_packs (capture_init_expr); } if (LAMBDA_EXPR_DEFAULT_CAPTURE_MODE (lambda_expr) != CPLD_NONE diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index b58c60f..222084d 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -2203,6 +2203,11 @@ determine_specialization (tree template_id, specialize TMPL will produce DECL. */ continue; + if (uses_template_parms (targs)) + /* We deduced something involving 'auto', which isn't a valid + template argument. */ + continue; + /* Remove, from the set of candidates, all those functions whose constraints are not satisfied. */ if (flag_concepts && !constraints_satisfied_p (fn, targs)) @@ -3394,6 +3399,34 @@ get_template_argument_pack_elems (const_tree t) return ARGUMENT_PACK_ARGS (t); } +/* In an ARGUMENT_PACK_SELECT, the actual underlying argument that the + ARGUMENT_PACK_SELECT represents. */ + +static tree +argument_pack_select_arg (tree t) +{ + tree args = ARGUMENT_PACK_ARGS (ARGUMENT_PACK_SELECT_FROM_PACK (t)); + tree arg = TREE_VEC_ELT (args, ARGUMENT_PACK_SELECT_INDEX (t)); + + /* If the selected argument is an expansion E, that most likely means we were + called from gen_elem_of_pack_expansion_instantiation during the + substituting of an argument pack (of which the Ith element is a pack + expansion, where I is ARGUMENT_PACK_SELECT_INDEX) into a pack expansion. + In this case, the Ith element resulting from this substituting is going to + be a pack expansion, which pattern is the pattern of E. Let's return the + pattern of E, and gen_elem_of_pack_expansion_instantiation will build the + resulting pack expansion from it. */ + if (PACK_EXPANSION_P (arg)) + { + /* Make sure we aren't throwing away arg info. */ + gcc_assert (!PACK_EXPANSION_EXTRA_ARGS (arg)); + arg = PACK_EXPANSION_PATTERN (arg); + } + + return arg; +} + + /* True iff FN is a function representing a built-in variadic parameter pack. */ @@ -3559,7 +3592,6 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data) } break; - /* Look through a lambda capture proxy to the field pack. */ case VAR_DECL: if (DECL_PACK_P (t)) { @@ -3679,6 +3711,12 @@ find_parameter_packs_r (tree *tp, int *walk_subtrees, void* data) case LAMBDA_EXPR: { + /* Look at explicit captures. */ + for (tree cap = LAMBDA_EXPR_CAPTURE_LIST (t); + cap; cap = TREE_CHAIN (cap)) + cp_walk_tree (&TREE_VALUE (cap), &find_parameter_packs_r, ppd, + ppd->visited); + /* Since we defer implicit capture, look in the body as well. */ tree fn = lambda_function (t); cp_walk_tree (&DECL_SAVED_TREE (fn), &find_parameter_packs_r, ppd, ppd->visited); @@ -3879,7 +3917,7 @@ check_for_bare_parameter_packs (tree t) return false; /* A lambda might use a parameter pack from the containing context. */ - if (current_function_decl && LAMBDA_FUNCTION_P (current_function_decl)) + if (current_class_type && LAMBDA_TYPE_P (current_class_type)) return false; if (TREE_CODE (t) == TYPE_DECL) @@ -10933,7 +10971,12 @@ extract_fnparm_pack (tree tmpl_parm, tree *spec_p) parmvec = make_tree_vec (len); spec_parm = *spec_p; for (i = 0; i < len; i++, spec_parm = DECL_CHAIN (spec_parm)) - TREE_VEC_ELT (parmvec, i) = spec_parm; + { + tree elt = spec_parm; + if (DECL_PACK_P (elt)) + elt = make_pack_expansion (elt); + TREE_VEC_ELT (parmvec, i) = elt; + } /* Build the argument packs. */ SET_ARGUMENT_PACK_ARGS (argpack, parmvec); @@ -11377,29 +11420,72 @@ tsubst_binary_right_fold (tree t, tree args, tsubst_flags_t complain, /* Walk through the pattern of a pack expansion, adding everything in local_specializations to a list. */ +struct el_data +{ + tree extra; + tsubst_flags_t complain; +}; static tree -extract_locals_r (tree *tp, int */*walk_subtrees*/, void *data) +extract_locals_r (tree *tp, int */*walk_subtrees*/, void *data_) { - tree *extra = reinterpret_cast<tree*>(data); + el_data &data = *reinterpret_cast<el_data*>(data_); + tree *extra = &data.extra; + tsubst_flags_t complain = data.complain; if (tree spec = retrieve_local_specialization (*tp)) { if (TREE_CODE (spec) == NONTYPE_ARGUMENT_PACK) { - /* Pull out the actual PARM_DECL for the partial instantiation. */ + /* Maybe pull out the PARM_DECL for a partial instantiation. */ tree args = ARGUMENT_PACK_ARGS (spec); - gcc_assert (TREE_VEC_LENGTH (args) == 1); - spec = TREE_VEC_ELT (args, 0); + if (TREE_VEC_LENGTH (args) == 1) + { + tree elt = TREE_VEC_ELT (args, 0); + if (PACK_EXPANSION_P (elt)) + elt = PACK_EXPANSION_PATTERN (elt); + if (DECL_PACK_P (elt)) + spec = elt; + } + if (TREE_CODE (spec) == NONTYPE_ARGUMENT_PACK) + { + /* Handle lambda capture here, since we aren't doing any + substitution now, and so tsubst_copy won't call + process_outer_var_ref. */ + tree args = ARGUMENT_PACK_ARGS (spec); + int len = TREE_VEC_LENGTH (args); + for (int i = 0; i < len; ++i) + { + tree arg = TREE_VEC_ELT (args, i); + tree carg = arg; + if (outer_automatic_var_p (arg)) + carg = process_outer_var_ref (arg, complain); + if (carg != arg) + { + /* Make a new NONTYPE_ARGUMENT_PACK of the capture + proxies. */ + if (i == 0) + { + spec = copy_node (spec); + args = copy_node (args); + SET_ARGUMENT_PACK_ARGS (spec, args); + register_local_specialization (spec, *tp); + } + TREE_VEC_ELT (args, i) = carg; + } + } + } } + if (outer_automatic_var_p (spec)) + spec = process_outer_var_ref (spec, complain); *extra = tree_cons (*tp, spec, *extra); } return NULL_TREE; } static tree -extract_local_specs (tree pattern) +extract_local_specs (tree pattern, tsubst_flags_t complain) { - tree extra = NULL_TREE; - cp_walk_tree_without_duplicates (&pattern, extract_locals_r, &extra); - return extra; + el_data data = { NULL_TREE, complain }; + cp_walk_tree_without_duplicates (&pattern, extract_locals_r, &data); + return data.extra; } /* Substitute ARGS into T, which is an pack expansion @@ -11434,8 +11520,10 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, extract_local_specs; map from the general template to our local context. */ tree gen = TREE_PURPOSE (elt); - tree partial = TREE_VALUE (elt); - tree inst = retrieve_local_specialization (partial); + tree inst = TREE_VALUE (elt); + if (DECL_PACK_P (inst)) + inst = retrieve_local_specialization (inst); + /* else inst is already a full instantiation of the pack. */ register_local_specialization (inst, gen); } gcc_assert (!TREE_PURPOSE (extra)); @@ -11617,7 +11705,7 @@ tsubst_pack_expansion (tree t, tree args, tsubst_flags_t complain, t = make_pack_expansion (pattern, complain); tree extra = args; if (local_specializations) - if (tree locals = extract_local_specs (pattern)) + if (tree locals = extract_local_specs (pattern, complain)) extra = tree_cons (NULL_TREE, extra, locals); PACK_EXPANSION_EXTRA_ARGS (t) = extra; return t; @@ -13747,29 +13835,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl) { arg = TMPL_ARG (args, level, idx); + /* See through ARGUMENT_PACK_SELECT arguments. */ if (arg && TREE_CODE (arg) == ARGUMENT_PACK_SELECT) - { - /* See through ARGUMENT_PACK_SELECT arguments. */ - arg = ARGUMENT_PACK_SELECT_ARG (arg); - /* If the selected argument is an expansion E, that most - likely means we were called from - gen_elem_of_pack_expansion_instantiation during the - substituting of pack an argument pack (which Ith - element is a pack expansion, where I is - ARGUMENT_PACK_SELECT_INDEX) into a pack expansion. - In this case, the Ith element resulting from this - substituting is going to be a pack expansion, which - pattern is the pattern of E. Let's return the - pattern of E, and - gen_elem_of_pack_expansion_instantiation will - build the resulting pack expansion from it. */ - if (PACK_EXPANSION_P (arg)) - { - /* Make sure we aren't throwing away arg info. */ - gcc_assert (!PACK_EXPANSION_EXTRA_ARGS (arg)); - arg = PACK_EXPANSION_PATTERN (arg); - } - } + arg = argument_pack_select_arg (arg); } if (arg == error_mark_node) @@ -14734,7 +14802,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) } if (TREE_CODE (r) == ARGUMENT_PACK_SELECT) - r = ARGUMENT_PACK_SELECT_ARG (r); + r = argument_pack_select_arg (r); if (!mark_used (r, complain) && !(complain & tf_error)) return error_mark_node; return r; @@ -14866,7 +14934,7 @@ tsubst_copy (tree t, tree args, tsubst_flags_t complain, tree in_decl) register_local_specialization (r, t); } if (TREE_CODE (r) == ARGUMENT_PACK_SELECT) - r = ARGUMENT_PACK_SELECT_ARG (r); + r = argument_pack_select_arg (r); } else r = t; @@ -24701,7 +24769,7 @@ dependent_template_arg_p (tree arg) return true; if (TREE_CODE (arg) == ARGUMENT_PACK_SELECT) - arg = ARGUMENT_PACK_SELECT_ARG (arg); + arg = argument_pack_select_arg (arg); if (TREE_CODE (arg) == TEMPLATE_TEMPLATE_PARM) return true; diff --git a/gcc/debug.h b/gcc/debug.h index e1dfe4b..126e56e 100644 --- a/gcc/debug.h +++ b/gcc/debug.h @@ -248,6 +248,8 @@ extern bool dwarf2out_do_eh_frame (void); extern bool dwarf2out_do_frame (void); extern bool dwarf2out_do_cfi_asm (void); extern void dwarf2out_switch_text_section (void); +extern bool dwarf2out_default_as_loc_support (void); +extern bool dwarf2out_default_as_locview_support (void); /* For -fdump-go-spec. */ diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index cb9df97..4f79a92 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -5182,7 +5182,7 @@ that the specified function is an interrupt handler. The compiler generates function entry and exit sequences suitable for use in an interrupt handler when this attribute is present. -On RX targets, you may specify one or more vector numbers as arguments +On RX and RL78 targets, you may specify one or more vector numbers as arguments to the attribute, as well as naming an alternate table name. Parameters are handled sequentially, so one handler can be assigned to multiple entries in multiple tables. One may also pass the magic diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 9db9d08..48194c8 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -346,9 +346,13 @@ Objective-C and Objective-C++ Dialects}. @gccoptlist{-g -g@var{level} -gdwarf -gdwarf-@var{version} @gol -ggdb -grecord-gcc-switches -gno-record-gcc-switches @gol -gstabs -gstabs+ -gstrict-dwarf -gno-strict-dwarf @gol +-gas-loc-support -gno-as-loc-support @gol +-gas-locview-support -gno-as-locview-support @gol -gcolumn-info -gno-column-info @gol -gstatement-frontiers -gno-statement-frontiers @gol -gvariable-location-views -gno-variable-location-views @gol +-ginternal-reset-location-views -gno-internal-reset-location-views @gol +-ginline-points -gno-inline-points @gol -gvms -gxcoff -gxcoff+ -gz@r{[}=@var{type}@r{]} @gol -fdebug-prefix-map=@var{old}=@var{new} -fdebug-types-section @gol -fno-eliminate-unused-debug-types @gol @@ -4159,7 +4163,7 @@ result in false positives. @table @gcctabopt @item -Wformat-overflow -@item -Wformat-overflow=1 +@itemx -Wformat-overflow=1 @opindex Wformat-overflow @opindex Wno-format-overflow Level @var{1} of @option{-Wformat-overflow} enabled by @option{-Wformat} @@ -4278,7 +4282,7 @@ logic @option{-Wformat-overflow}. @table @gcctabopt @item -Wformat-truncation -@item -Wformat-truncation=1 +@itemx -Wformat-truncation=1 @opindex Wformat-truncation @opindex Wno-format-overflow Level @var{1} of @option{-Wformat-truncation} enabled by @option{-Wformat} @@ -5239,7 +5243,7 @@ Option @option{-Wstringop-overflow=2} is enabled by default. @table @gcctabopt @item -Wstringop-overflow -@item -Wstringop-overflow=1 +@itemx -Wstringop-overflow=1 @opindex Wstringop-overflow @opindex Wno-stringop-overflow The @option{-Wstringop-overflow=1} option uses type-zero Object Size Checking @@ -7214,7 +7218,7 @@ and on some objects @code{.debug_types} produces larger instead of smaller debugging information. @item -grecord-gcc-switches -@item -gno-record-gcc-switches +@itemx -gno-record-gcc-switches @opindex grecord-gcc-switches @opindex gno-record-gcc-switches This switch causes the command-line options used to invoke the @@ -7237,8 +7241,38 @@ DWARF extensions from later standard versions is allowed. Allow using extensions of later DWARF standard version than selected with @option{-gdwarf-@var{version}}. +@item -gas-loc-support +@opindex gas-loc-support +Inform the compiler that the assembler supports @code{.loc} directives. +It may then use them for the assembler to generate DWARF2+ line number +tables. + +This is generally desirable, because assembler-generated line-number +tables are a lot more compact than those the compiler can generate +itself. + +This option will be enabled by default if, at GCC configure time, the +assembler was found to support such directives. + +@item -gno-as-loc-support +@opindex gno-as-loc-support +Force GCC to generate DWARF2+ line number tables internally, if DWARF2+ +line number tables are to be generated. + +@item gas-locview-support +@opindex gas-locview-support +Inform the compiler that the assembler supports @code{view} assignment +and reset assertion checking in @code{.loc} directives. + +This option will be enabled by default if, at GCC configure time, the +assembler was found to support them. + +@item gno-as-locview-support +Force GCC to assign view numbers internally, if +@option{-gvariable-location-views} are explicitly requested. + @item -gcolumn-info -@item -gno-column-info +@itemx -gno-column-info @opindex gcolumn-info @opindex gno-column-info Emit location column information into DWARF debugging information, rather @@ -7246,7 +7280,7 @@ than just file and line. This option is enabled by default. @item -gstatement-frontiers -@item -gno-statement-frontiers +@itemx -gno-statement-frontiers @opindex gstatement-frontiers @opindex gno-statement-frontiers This option causes GCC to create markers in the internal representation @@ -7257,8 +7291,8 @@ compiling with optimization (@option{-Os}, @option{-O}, @option{-O2}, @dots{}), and outputting DWARF 2 debug information at the normal level. @item -gvariable-location-views -@item -gvariable-location-views=incompat5 -@item -gno-variable-location-views +@itemx -gvariable-location-views=incompat5 +@itemx -gno-variable-location-views @opindex gvariable-location-views @opindex gvariable-location-views=incompat5 @opindex gno-variable-location-views @@ -7272,9 +7306,15 @@ which generally makes them somewhat less compact. The augmented line number tables and location lists are fully backward-compatible, so they can be consumed by debug information consumers that are not aware of these augmentations, but they won't derive any benefit from them either. + This is enabled by default when outputting DWARF 2 debug information at -the normal level, as long as @option{-fvar-tracking-assignments} is -enabled and @option{-gstrict-dwarf} is not. +the normal level, as long as there is assembler support, +@option{-fvar-tracking-assignments} is enabled and +@option{-gstrict-dwarf} is not. When assembler support is not +available, this may still be enabled, but it will force GCC to output +internal line number tables, and if +@option{-ginternal-reset-location-views} is not enabled, that will most +certainly lead to silently mismatching location views. There is a proposed representation for view numbers that is not backward compatible with the location list format introduced in DWARF 5, that can @@ -7284,6 +7324,30 @@ implementation of the proposed representation. Debug information consumers are not expected to support this extended format, and they would be rendered unable to decode location lists using it. +@item -ginternal-reset-location-views +@itemx -gnointernal-reset-location-views +@opindex ginternal-reset-location-views +@opindex gno-internal-reset-location-views +Attempt to determine location views that can be omitted from location +view lists. This requires the compiler to have very accurate insn +length estimates, which isn't always the case, and it may cause +incorrect view lists to be generated silently when using an assembler +that does not support location view lists. The GNU assembler will flag +any such error as a @code{view number mismatch}. This is only enabled +on ports that define a reliable estimation function. + +@item -ginline-points +@itemx -gno-inline-points +@opindex ginline-points +@opindex gno-inline-points +Generate extended debug information for inlined functions. Location +view tracking markers are inserted at inlined entry points, so that +address and view numbers can be computed and output in debug +information. This can be enabled independently of location views, in +which case the view numbers won't be output, but it can only be enabled +along with statement frontiers, and it is only enabled by default if +location views are enabled. + @item -gz@r{[}=@var{type}@r{]} @opindex gz Produce compressed debug sections in DWARF format, if that is supported. @@ -10043,7 +10107,7 @@ also use other heuristics to decide whether if-conversion is likely to be profitable. @item max-rtl-if-conversion-predictable-cost -@item max-rtl-if-conversion-unpredictable-cost +@itemx max-rtl-if-conversion-unpredictable-cost RTL if-conversion will try to remove conditional branches around a block and replace them with conditionally executed instructions. These parameters give the maximum permissible cost for the sequence that would be generated @@ -10768,7 +10832,7 @@ parameters only when their cumulative size is less or equal to pointer parameter. @item sra-max-scalarization-size-Ospeed -@item sra-max-scalarization-size-Osize +@itemx sra-max-scalarization-size-Osize The two Scalar Reduction of Aggregates passes (SRA and IPA-SRA) aim to replace scalar parts of aggregates with uses of independent scalar variables. These parameters control the maximum size, in storage units, @@ -14545,7 +14609,7 @@ This erratum workaround is made at link time and this will only pass the corresponding flag to the linker. @item -mlow-precision-recip-sqrt -@item -mno-low-precision-recip-sqrt +@itemx -mno-low-precision-recip-sqrt @opindex mlow-precision-recip-sqrt @opindex mno-low-precision-recip-sqrt Enable or disable the reciprocal square root approximation. @@ -14555,7 +14619,7 @@ precision of reciprocal square root results to about 16 bits for single precision and to 32 bits for double precision. @item -mlow-precision-sqrt -@item -mno-low-precision-sqrt +@itemx -mno-low-precision-sqrt @opindex -mlow-precision-sqrt @opindex -mno-low-precision-sqrt Enable or disable the square root approximation. @@ -14566,7 +14630,7 @@ single precision and to 32 bits for double precision. If enabled, it implies @option{-mlow-precision-recip-sqrt}. @item -mlow-precision-div -@item -mno-low-precision-div +@itemx -mno-low-precision-div @opindex -mlow-precision-div @opindex -mno-low-precision-div Enable or disable the division approximation. @@ -20194,7 +20258,7 @@ for regression testing of mixed MIPS16/non-MIPS16 code generation, and is not intended for ordinary use in compiling user code. @item -minterlink-compressed -@item -mno-interlink-compressed +@itemx -mno-interlink-compressed @opindex minterlink-compressed @opindex mno-interlink-compressed Require (do not require) that code using the standard (uncompressed) MIPS ISA @@ -20775,7 +20839,7 @@ Tell the MIPS assembler to not run its preprocessor over user assembler files (with a @samp{.s} suffix) when assembling them. @item -mfix-24k -@item -mno-fix-24k +@itemx -mno-fix-24k @opindex mfix-24k @opindex mno-fix-24k Work around the 24K E48 (lost data on stores during refill) errata. @@ -21535,7 +21599,7 @@ into the small data or BSS sections instead of the normal data or BSS sections. The default value of @var{num} is 8. @item -mgpopt=@var{option} -@item -mgpopt +@itemx -mgpopt @itemx -mno-gpopt @opindex mgpopt @opindex mno-gpopt @@ -23094,7 +23158,7 @@ or 32 bits (@option{-m32bit-doubles}) in size. The default is @option{-m32bit-doubles}. @item -msave-mduc-in-interrupts -@item -mno-save-mduc-in-interrupts +@itemx -mno-save-mduc-in-interrupts @opindex msave-mduc-in-interrupts @opindex mno-save-mduc-in-interrupts Specifies that interrupt handler functions should preserve the @@ -26727,13 +26791,13 @@ comparisons. These correctly handle the case where the result of a comparison is unordered. @item -m80387 -@item -mhard-float +@itemx -mhard-float @opindex 80387 @opindex mhard-float Generate output containing 80387 instructions for floating point. @item -mno-80387 -@item -msoft-float +@itemx -msoft-float @opindex no-80387 @opindex msoft-float Generate output containing library calls for floating point. diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index ddf48cb4..bd8b917 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -9966,6 +9966,29 @@ line debug info sections. This will result in much more compact line number tables, and hence is desirable if it works. @end defmac +@defmac DWARF2_ASM_VIEW_DEBUG_INFO +Define this macro to be a nonzero value if the assembler supports view +assignment and verification in @code{.loc}. If it does not, but the +user enables location views, the compiler may have to fallback to +internal line number tables. +@end defmac + +@deftypefn {Target Hook} int TARGET_RESET_LOCATION_VIEW (rtx_insn *@var{}) +This hook, if defined, enables -ginternal-reset-location-views, and +uses its result to override cases in which the estimated min insn +length might be nonzero even when a PC advance (i.e., a view reset) +cannot be taken for granted. + +If the hook is defined, it must return a positive value to indicate +the insn definitely advances the PC, and so the view number can be +safely assumed to be reset; a negative value to mean the insn +definitely does not advance the PC, and os the view number must not +be reset; or zero to decide based on the estimated insn length. + +If insn length is to be regarded as reliable, set the hook to +@code{hook_int_rtx_insn_0}. +@end deftypefn + @deftypevr {Target Hook} bool TARGET_WANT_DEBUG_PUB_SECTIONS True if the @code{.debug_pubtypes} and @code{.debug_pubnames} sections should be emitted. These sections are not used on most platforms, and in particular GDB does not use them. @end deftypevr diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 0aab45f..b020714 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -6921,6 +6921,15 @@ line debug info sections. This will result in much more compact line number tables, and hence is desirable if it works. @end defmac +@defmac DWARF2_ASM_VIEW_DEBUG_INFO +Define this macro to be a nonzero value if the assembler supports view +assignment and verification in @code{.loc}. If it does not, but the +user enables location views, the compiler may have to fallback to +internal line number tables. +@end defmac + +@hook TARGET_RESET_LOCATION_VIEW + @hook TARGET_WANT_DEBUG_PUB_SECTIONS @hook TARGET_DELAY_SCHED2 diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 984df9f..4e2bf3b 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -2957,6 +2957,37 @@ struct GTY(()) dw_line_info_table { vec<dw_line_info_entry, va_gc> *entries; }; +/* If we're keep track of location views and their reset points, and + INSN is a reset point (i.e., it necessarily advances the PC), mark + the next view in TABLE as reset. */ + +static void +maybe_reset_location_view (rtx_insn *insn, dw_line_info_table *table) +{ + if (!debug_internal_reset_location_views) + return; + + /* Maybe turn (part of?) this test into a default target hook. */ + int reset = 0; + + if (targetm.reset_location_view) + reset = targetm.reset_location_view (insn); + + if (reset) + ; + else if (JUMP_TABLE_DATA_P (insn)) + reset = 1; + else if (GET_CODE (insn) == USE + || GET_CODE (insn) == CLOBBER + || GET_CODE (insn) == ASM_INPUT + || asm_noperands (insn) >= 0) + ; + else if (get_attr_min_length (insn) > 0) + reset = 1; + + if (reset > 0) + RESET_NEXT_VIEW (table->view); +} /* Each DIE attribute has a field specifying the attribute kind, a link to the next attribute in the chain, and an attribute value. @@ -3164,6 +3195,31 @@ skeleton_chain_node; #endif #endif +/* Return true if GCC configure detected assembler support for .loc. */ + +bool +dwarf2out_default_as_loc_support (void) +{ + return DWARF2_ASM_LINE_DEBUG_INFO; +#if (GCC_VERSION >= 3000) +# undef DWARF2_ASM_LINE_DEBUG_INFO +# pragma GCC poison DWARF2_ASM_LINE_DEBUG_INFO +#endif +} + +/* Return true if GCC configure detected assembler support for views + in .loc directives. */ + +bool +dwarf2out_default_as_locview_support (void) +{ + return DWARF2_ASM_VIEW_DEBUG_INFO; +#if (GCC_VERSION >= 3000) +# undef DWARF2_ASM_VIEW_DEBUG_INFO +# pragma GCC poison DWARF2_ASM_VIEW_DEBUG_INFO +#endif +} + /* A bit is set in ZERO_VIEW_P if we are using the assembler-supported view computation, and it refers to a view identifier for which we will not emit a label because it is known to map to a view number @@ -3215,9 +3271,9 @@ static GTY(()) bitmap zero_view_p; static bool output_asm_line_debug_info (void) { - return (DWARF2_ASM_VIEW_DEBUG_INFO - || (DWARF2_ASM_LINE_DEBUG_INFO - && !debug_variable_location_views)); + return (dwarf2out_as_loc_support + && (dwarf2out_as_locview_support + || !debug_variable_location_views)); } /* Minimum line offset in a special line info. opcode. @@ -9950,28 +10006,31 @@ dwarf2out_maybe_output_loclist_view_pair (dw_loc_list_ref curr) #ifdef DW_LLE_view_pair dw2_asm_output_data (1, DW_LLE_view_pair, "DW_LLE_view_pair"); -# if DWARF2_ASM_VIEW_DEBUG_INFO - if (ZERO_VIEW_P (curr->vbegin)) - dw2_asm_output_data_uleb128 (0, "Location view begin"); - else + if (dwarf2out_as_locview_support) { - char label[MAX_ARTIFICIAL_LABEL_BYTES]; - ASM_GENERATE_INTERNAL_LABEL (label, "LVU", curr->vbegin); - dw2_asm_output_symname_uleb128 (label, "Location view begin"); - } + if (ZERO_VIEW_P (curr->vbegin)) + dw2_asm_output_data_uleb128 (0, "Location view begin"); + else + { + char label[MAX_ARTIFICIAL_LABEL_BYTES]; + ASM_GENERATE_INTERNAL_LABEL (label, "LVU", curr->vbegin); + dw2_asm_output_symname_uleb128 (label, "Location view begin"); + } - if (ZERO_VIEW_P (curr->vend)) - dw2_asm_output_data_uleb128 (0, "Location view end"); + if (ZERO_VIEW_P (curr->vend)) + dw2_asm_output_data_uleb128 (0, "Location view end"); + else + { + char label[MAX_ARTIFICIAL_LABEL_BYTES]; + ASM_GENERATE_INTERNAL_LABEL (label, "LVU", curr->vend); + dw2_asm_output_symname_uleb128 (label, "Location view end"); + } + } else { - char label[MAX_ARTIFICIAL_LABEL_BYTES]; - ASM_GENERATE_INTERNAL_LABEL (label, "LVU", curr->vend); - dw2_asm_output_symname_uleb128 (label, "Location view end"); + dw2_asm_output_data_uleb128 (curr->vbegin, "Location view begin"); + dw2_asm_output_data_uleb128 (curr->vend, "Location view end"); } -# else /* !DWARF2_ASM_VIEW_DEBUG_INFO */ - dw2_asm_output_data_uleb128 (curr->vbegin, "Location view begin"); - dw2_asm_output_data_uleb128 (curr->vend, "Location view end"); -# endif /* DWARF2_ASM_VIEW_DEBUG_INFO */ #endif /* DW_LLE_view_pair */ return; @@ -10001,40 +10060,43 @@ output_loc_list (dw_loc_list_ref list_head) vcount++; /* ?? dwarf_split_debug_info? */ -#if DWARF2_ASM_VIEW_DEBUG_INFO - char label[MAX_ARTIFICIAL_LABEL_BYTES]; - - if (!ZERO_VIEW_P (curr->vbegin)) + if (dwarf2out_as_locview_support) { - ASM_GENERATE_INTERNAL_LABEL (label, "LVU", curr->vbegin); - dw2_asm_output_symname_uleb128 (label, - "View list begin (%s)", - list_head->vl_symbol); + char label[MAX_ARTIFICIAL_LABEL_BYTES]; + + if (!ZERO_VIEW_P (curr->vbegin)) + { + ASM_GENERATE_INTERNAL_LABEL (label, "LVU", curr->vbegin); + dw2_asm_output_symname_uleb128 (label, + "View list begin (%s)", + list_head->vl_symbol); + } + else + dw2_asm_output_data_uleb128 (0, + "View list begin (%s)", + list_head->vl_symbol); + + if (!ZERO_VIEW_P (curr->vend)) + { + ASM_GENERATE_INTERNAL_LABEL (label, "LVU", curr->vend); + dw2_asm_output_symname_uleb128 (label, + "View list end (%s)", + list_head->vl_symbol); + } + else + dw2_asm_output_data_uleb128 (0, + "View list end (%s)", + list_head->vl_symbol); } else - dw2_asm_output_data_uleb128 (0, - "View list begin (%s)", - list_head->vl_symbol); - - if (!ZERO_VIEW_P (curr->vend)) { - ASM_GENERATE_INTERNAL_LABEL (label, "LVU", curr->vend); - dw2_asm_output_symname_uleb128 (label, - "View list end (%s)", - list_head->vl_symbol); + dw2_asm_output_data_uleb128 (curr->vbegin, + "View list begin (%s)", + list_head->vl_symbol); + dw2_asm_output_data_uleb128 (curr->vend, + "View list end (%s)", + list_head->vl_symbol); } - else - dw2_asm_output_data_uleb128 (0, - "View list end (%s)", - list_head->vl_symbol); -#else /* !DWARF2_ASM_VIEW_DEBUG_INFO */ - dw2_asm_output_data_uleb128 (curr->vbegin, - "View list begin (%s)", - list_head->vl_symbol); - dw2_asm_output_data_uleb128 (curr->vend, - "View list end (%s)", - list_head->vl_symbol); -#endif } } @@ -23721,11 +23783,14 @@ add_high_low_attributes (tree stmt, dw_die_ref die) { inline_entry_data *ied = *iedp; gcc_assert (MAY_HAVE_DEBUG_MARKER_INSNS); + gcc_assert (debug_inline_points); gcc_assert (inlined_function_outer_scope_p (stmt)); + ASM_GENERATE_INTERNAL_LABEL (label, ied->label_pfx, ied->label_num); add_AT_lbl_id (die, DW_AT_entry_pc, label); - if (debug_variable_location_views && !ZERO_VIEW_P (ied->view)) + if (debug_variable_location_views && !ZERO_VIEW_P (ied->view) + && !dwarf_strict) { if (!output_asm_line_debug_info ()) add_AT_unsigned (die, DW_AT_GNU_entry_view, ied->view); @@ -23756,7 +23821,7 @@ add_high_low_attributes (tree stmt, dw_die_ref die) dw_die_ref pdie; dw_attr_node *attr = NULL; - if (!MAY_HAVE_DEBUG_MARKER_INSNS && inlined_function_outer_scope_p (stmt)) + if (!debug_inline_points && inlined_function_outer_scope_p (stmt)) { ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_BEGIN_LABEL, BLOCK_NUMBER (stmt)); @@ -23921,7 +23986,7 @@ gen_inlined_subroutine_die (tree stmt, dw_die_ref context_die) dw_die_ref subr_die = new_die (DW_TAG_inlined_subroutine, context_die, stmt); - if (call_arg_locations || MAY_HAVE_DEBUG_MARKER_INSNS) + if (call_arg_locations || debug_inline_points) BLOCK_DIE (stmt) = subr_die; add_abstract_origin_attribute (subr_die, decl); if (TREE_ASM_WRITTEN (stmt)) @@ -26906,7 +26971,7 @@ dwarf2out_var_location (rtx_insn *loc_note) { if (CALL_P (loc_note)) { - RESET_NEXT_VIEW (cur_line_info_table->view); + maybe_reset_location_view (loc_note, cur_line_info_table); call_site_count++; if (SIBLING_CALL_P (loc_note)) tail_call_site_count++; @@ -26942,15 +27007,8 @@ dwarf2out_var_location (rtx_insn *loc_note) } else if (!debug_variable_location_views) gcc_unreachable (); - else if (JUMP_TABLE_DATA_P (loc_note)) - RESET_NEXT_VIEW (cur_line_info_table->view); - else if (GET_CODE (loc_note) == USE - || GET_CODE (loc_note) == CLOBBER - || GET_CODE (loc_note) == ASM_INPUT - || asm_noperands (loc_note) >= 0) - ; - else if (get_attr_min_length (loc_note) > 0) - RESET_NEXT_VIEW (cur_line_info_table->view); + else + maybe_reset_location_view (loc_note, cur_line_info_table); return; } @@ -27219,6 +27277,8 @@ block_within_block_p (tree block, tree outer, bool bothways) static void dwarf2out_inline_entry (tree block) { + gcc_assert (debug_inline_points); + /* If we can't represent it, don't bother. */ if (!(dwarf_version >= 3 || !dwarf_strict)) return; @@ -28233,7 +28293,7 @@ init_sections_and_labels (bool early_lto_debug) debug_str_section = get_section (DEBUG_LTO_STR_SECTION, DEBUG_STR_SECTION_FLAGS | SECTION_EXCLUDE, NULL); - if (!dwarf_split_debug_info && !DWARF2_ASM_LINE_DEBUG_INFO) + if (!dwarf_split_debug_info && !dwarf2out_as_loc_support) debug_line_str_section = get_section (DEBUG_LTO_LINE_STR_SECTION, DEBUG_STR_SECTION_FLAGS | SECTION_EXCLUDE, NULL); @@ -31468,7 +31528,7 @@ dwarf2out_early_finish (const char *filename) /* When emitting DWARF5 .debug_line_str, move DW_AT_name and DW_AT_comp_dir into .debug_line_str section. */ - if (!DWARF2_ASM_LINE_DEBUG_INFO + if (!dwarf2out_as_loc_support && dwarf_version >= 5 && DWARF5_USE_DEBUG_LINE_STR) { diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index 6f416b3..01e2a90 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,14 @@ +2018-02-13 Janus Weil <janus@gcc.gnu.org> + + PR fortran/84313 + * symbol.c (check_conflict): Reject procedure pointers in common blocks. + +2018-02-13 Alastair McKinstry <alastair.mckinstry@sceal.ie> + Janne Blomqvist <jb@gcc.gnu.org> + + * module.c (dump_module): Use lbasename to ensure that module + files are reproducible. + 2018-02-12 Janus Weil <janus@gcc.gnu.org> PR fortran/84273 diff --git a/gcc/fortran/module.c b/gcc/fortran/module.c index b120501..c833e67 100644 --- a/gcc/fortran/module.c +++ b/gcc/fortran/module.c @@ -6148,8 +6148,10 @@ dump_module (const char *name, int dump_flag) gfc_fatal_error ("Can't open module file %qs for writing at %C: %s", filename_tmp, xstrerror (errno)); + /* Use lbasename to ensure module files are reproducible regardless + of the build path (see the reproducible builds project). */ gzprintf (module_fp, "GFORTRAN module version '%s' created from %s\n", - MOD_VERSION, gfc_source_file); + MOD_VERSION, lbasename (gfc_source_file)); /* Write the module itself. */ iomode = IO_OUTPUT; diff --git a/gcc/fortran/symbol.c b/gcc/fortran/symbol.c index 344c644..ce6b1e9 100644 --- a/gcc/fortran/symbol.c +++ b/gcc/fortran/symbol.c @@ -809,7 +809,9 @@ check_conflict (symbol_attribute *attr, const char *name, locus *where) conf2 (threadprivate); } - if (!attr->proc_pointer) + /* Procedure pointers in COMMON blocks are allowed in F03, + * but forbidden per F08:C5100. */ + if (!attr->proc_pointer || (gfc_option.allow_std & GFC_STD_F2008)) conf2 (in_common); conf2 (omp_declare_target_link); diff --git a/gcc/generic-match-head.c b/gcc/generic-match-head.c index b79f70e..f7b6b1f 100644 --- a/gcc/generic-match-head.c +++ b/gcc/generic-match-head.c @@ -68,3 +68,12 @@ canonicalize_math_p () { return true; } + +/* Return true if math operations that are beneficial only after + vectorization should be canonicalized. */ + +static inline bool +canonicalize_math_after_vectorization_p () +{ + return false; +} diff --git a/gcc/gimple-fold.c b/gcc/gimple-fold.c index 3861692..e556f05 100644 --- a/gcc/gimple-fold.c +++ b/gcc/gimple-fold.c @@ -1380,9 +1380,15 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited, int type, /* Set the minimum size to zero since the string in the array could have zero length. */ *minlen = ssize_int (0); + + if (TREE_CODE (TREE_OPERAND (arg, 0)) == COMPONENT_REF + && type == TREE_TYPE (TREE_OPERAND (arg, 0)) + && array_at_struct_end_p (TREE_OPERAND (arg, 0))) + *flexp = true; } else if (TREE_CODE (arg) == COMPONENT_REF - && TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 1))) == ARRAY_TYPE) + && (TREE_CODE (TREE_TYPE (TREE_OPERAND (arg, 1))) + == ARRAY_TYPE)) { /* Use the type of the member array to determine the upper bound on the length of the array. This may be overly @@ -1428,7 +1434,7 @@ get_range_strlen (tree arg, tree length[2], bitmap *visited, int type, || integer_zerop (val)) return false; val = wide_int_to_tree (TREE_TYPE (val), - wi::sub(wi::to_wide (val), 1)); + wi::sub (wi::to_wide (val), 1)); /* Set the minimum size to zero since the string in the array could have zero length. */ *minlen = ssize_int (0); diff --git a/gcc/gimple-match-head.c b/gcc/gimple-match-head.c index 25fa667..172ef0a 100644 --- a/gcc/gimple-match-head.c +++ b/gcc/gimple-match-head.c @@ -831,3 +831,12 @@ canonicalize_math_p () { return !cfun || (cfun->curr_properties & PROP_gimple_opt_math) == 0; } + +/* Return true if math operations that are beneficial only after + vectorization should be canonicalized. */ + +static inline bool +canonicalize_math_after_vectorization_p () +{ + return !cfun || (cfun->curr_properties & PROP_gimple_lvec) != 0; +} diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index ea7ae4b..baf77e3 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -7998e29eec43ede1cee925d87eef0b09da67d90b +5d5ea2fd05dbf369ccc53c93d4846623cdea0c47 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 f50de0a..9792faa 100644 --- a/gcc/go/gofrontend/expressions.cc +++ b/gcc/go/gofrontend/expressions.cc @@ -1330,9 +1330,24 @@ Func_descriptor_expression::do_get_backend(Translate_context* context) else { Location bloc = Linemap::predeclared_location(); + + // The runtime package has hash/equality functions that are + // referenced by type descriptors outside of the runtime, so the + // function descriptors must be visible even though they are not + // exported. + bool is_exported_runtime = false; + if (gogo->compiling_runtime() + && gogo->package_name() == "runtime" + && (no->name().find("hash") != std::string::npos + || no->name().find("equal") != std::string::npos)) + is_exported_runtime = true; + bool is_hidden = ((no->is_function() && no->func_value()->enclosing() != NULL) + || (Gogo::is_hidden_name(no->name()) + && !is_exported_runtime) || Gogo::is_thunk(no)); + bvar = context->backend()->immutable_struct(var_name, asm_name, is_hidden, false, btype, bloc); diff --git a/gcc/hooks.c b/gcc/hooks.c index 6171960..780cc1e 100644 --- a/gcc/hooks.c +++ b/gcc/hooks.c @@ -236,6 +236,12 @@ hook_int_rtx_1 (rtx) } int +hook_int_rtx_insn_0 (rtx_insn *) +{ + return 0; +} + +int hook_int_rtx_insn_unreachable (rtx_insn *) { gcc_unreachable (); diff --git a/gcc/hooks.h b/gcc/hooks.h index 8caedd4..0ed5b95 100644 --- a/gcc/hooks.h +++ b/gcc/hooks.h @@ -93,6 +93,7 @@ extern int hook_int_const_tree_0 (const_tree); extern int hook_int_const_tree_const_tree_1 (const_tree, const_tree); extern int hook_int_rtx_0 (rtx); extern int hook_int_rtx_1 (rtx); +extern int hook_int_rtx_insn_0 (rtx_insn *); extern int hook_int_rtx_insn_unreachable (rtx_insn *); extern int hook_int_rtx_bool_0 (rtx, bool); extern int hook_int_rtx_mode_as_bool_0 (rtx, machine_mode, addr_space_t, diff --git a/gcc/internal-fn.def b/gcc/internal-fn.def index deacc1e..5970d0e 100644 --- a/gcc/internal-fn.def +++ b/gcc/internal-fn.def @@ -255,8 +255,8 @@ DEF_INTERNAL_FN (UBSAN_PTR, ECF_LEAF | ECF_NOTHROW, ".R.") DEF_INTERNAL_FN (UBSAN_OBJECT_SIZE, ECF_LEAF | ECF_NOTHROW, NULL) DEF_INTERNAL_FN (ABNORMAL_DISPATCHER, ECF_NORETURN, NULL) DEF_INTERNAL_FN (BUILTIN_EXPECT, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL) -DEF_INTERNAL_FN (ASAN_CHECK, ECF_TM_PURE | ECF_LEAF | ECF_NOTHROW, "..R..") -DEF_INTERNAL_FN (ASAN_MARK, ECF_LEAF | ECF_NOTHROW, "..W.") +DEF_INTERNAL_FN (ASAN_CHECK, ECF_TM_PURE | ECF_LEAF | ECF_NOTHROW, ".R...") +DEF_INTERNAL_FN (ASAN_MARK, ECF_LEAF | ECF_NOTHROW, ".R..") DEF_INTERNAL_FN (ASAN_POISON, ECF_LEAF | ECF_NOTHROW | ECF_NOVOPS, NULL) DEF_INTERNAL_FN (ASAN_POISON_USE, ECF_LEAF | ECF_NOTHROW | ECF_NOVOPS, NULL) DEF_INTERNAL_FN (ADD_OVERFLOW, ECF_CONST | ECF_LEAF | ECF_NOTHROW, NULL) diff --git a/gcc/ipa-param-manipulation.c b/gcc/ipa-param-manipulation.c index 3629070..1ab1fcc 100644 --- a/gcc/ipa-param-manipulation.c +++ b/gcc/ipa-param-manipulation.c @@ -295,8 +295,7 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gcall *stmt, poly_int64 byte_offset = exact_div (adj->offset, BITS_PER_UNIT); base = gimple_call_arg (stmt, adj->base_index); - loc = DECL_P (base) ? DECL_SOURCE_LOCATION (base) - : EXPR_LOCATION (base); + loc = gimple_location (stmt); if (TREE_CODE (base) != ADDR_EXPR && POINTER_TYPE_P (TREE_TYPE (base))) @@ -385,6 +384,7 @@ ipa_modify_call_arguments (struct cgraph_edge *cs, gcall *stmt, else expr = create_tmp_reg (TREE_TYPE (expr)); gimple_assign_set_lhs (tem, expr); + gimple_set_location (tem, loc); gsi_insert_before (&gsi, tem, GSI_SAME_STMT); } } diff --git a/gcc/match.pd b/gcc/match.pd index 8631153..f759711 100644 --- a/gcc/match.pd +++ b/gcc/match.pd @@ -3992,15 +3992,36 @@ DEFINE_INT_AND_FLOAT_ROUND_FN (RINT) (logs (pows @0 @1)) (mult @1 (logs @0)))) - /* pow(C,x) -> exp(log(C)*x) if C > 0. */ + /* pow(C,x) -> exp(log(C)*x) if C > 0, + or if C is a positive power of 2, + pow(C,x) -> exp2(log2(C)*x). */ (for pows (POW) exps (EXP) logs (LOG) + exp2s (EXP2) + log2s (LOG2) (simplify (pows REAL_CST@0 @1) - (if (real_compare (GT_EXPR, TREE_REAL_CST_PTR (@0), &dconst0) - && real_isfinite (TREE_REAL_CST_PTR (@0))) - (exps (mult (logs @0) @1))))) + (if (real_compare (GT_EXPR, TREE_REAL_CST_PTR (@0), &dconst0) + && real_isfinite (TREE_REAL_CST_PTR (@0))) + (with { + const REAL_VALUE_TYPE *const value = TREE_REAL_CST_PTR (@0); + bool use_exp2 = false; + if (targetm.libc_has_function (function_c99_misc) + && value->cl == rvc_normal) + { + REAL_VALUE_TYPE frac_rvt = *value; + SET_REAL_EXP (&frac_rvt, 1); + if (real_equal (&frac_rvt, &dconst1)) + use_exp2 = true; + } + } + (if (!use_exp2) + (exps (mult (logs @0) @1)) + /* As libmvec doesn't have a vectorized exp2, defer optimizing + this until after vectorization. */ + (if (canonicalize_math_after_vectorization_p ()) + (exp2s (mult (log2s @0) @1)))))))) (for sqrts (SQRT) cbrts (CBRT) diff --git a/gcc/omp-simd-clone.c b/gcc/omp-simd-clone.c index b7737a2..56832eb 100644 --- a/gcc/omp-simd-clone.c +++ b/gcc/omp-simd-clone.c @@ -50,6 +50,7 @@ along with GCC; see the file COPYING3. If not see #include "varasm.h" #include "stringpool.h" #include "attribs.h" +#include "omp-simd-clone.h" /* Return the number of elements in vector type VECTYPE, which is associated with a SIMD clone. At present these always have a constant length. */ @@ -1568,7 +1569,7 @@ simd_clone_adjust (struct cgraph_node *node) /* If the function in NODE is tagged as an elemental SIMD function, create the appropriate SIMD clones. */ -static void +void expand_simd_clones (struct cgraph_node *node) { tree attr = lookup_attribute ("omp declare simd", diff --git a/gcc/omp-simd-clone.h b/gcc/omp-simd-clone.h new file mode 100644 index 0000000..c4833e2 --- /dev/null +++ b/gcc/omp-simd-clone.h @@ -0,0 +1,26 @@ +/* OMP constructs' SIMD clone supporting code. + + Copyright (C) 2005-2018 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. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#ifndef GCC_OMP_SIMD_CLONE_H +#define GCC_OMP_SIMD_CLONE_H + +extern void expand_simd_clones (struct cgraph_node *); + +#endif /* GCC_OMP_SIMD_CLONE_H */ diff --git a/gcc/stor-layout.c b/gcc/stor-layout.c index 8c415ebb..5fdf81a 100644 --- a/gcc/stor-layout.c +++ b/gcc/stor-layout.c @@ -1622,6 +1622,30 @@ place_field (record_layout_info rli, tree field) = size_binop (PLUS_EXPR, rli->offset, DECL_SIZE_UNIT (field)); rli->bitpos = bitsize_zero_node; rli->offset_align = MIN (rli->offset_align, desired_align); + + if (!multiple_of_p (bitsizetype, DECL_SIZE (field), + bitsize_int (rli->offset_align))) + { + tree type = strip_array_types (TREE_TYPE (field)); + /* The above adjusts offset_align just based on the start of the + field. The field might not have a size that is a multiple of + that offset_align though. If the field is an array of fixed + sized elements, assume there can be any multiple of those + sizes. If it is a variable length aggregate or array of + variable length aggregates, assume worst that the end is + just BITS_PER_UNIT aligned. */ + if (TREE_CODE (TYPE_SIZE (type)) == INTEGER_CST) + { + if (TREE_INT_CST_LOW (TYPE_SIZE (type))) + { + unsigned HOST_WIDE_INT sz + = least_bit_hwi (TREE_INT_CST_LOW (TYPE_SIZE (type))); + rli->offset_align = MIN (rli->offset_align, sz); + } + } + else + rli->offset_align = MIN (rli->offset_align, BITS_PER_UNIT); + } } else if (targetm.ms_bitfield_layout_p (rli->t)) { diff --git a/gcc/target.def b/gcc/target.def index aeb41df..c5b2a1e 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -6447,6 +6447,23 @@ This will suppress generation of the normal debug frame unwind information.", enum unwind_info_type, (void), default_debug_unwind_info) +DEFHOOK +(reset_location_view, "\ +This hook, if defined, enables -ginternal-reset-location-views, and\n\ +uses its result to override cases in which the estimated min insn\n\ +length might be nonzero even when a PC advance (i.e., a view reset)\n\ +cannot be taken for granted.\n\ +\n\ +If the hook is defined, it must return a positive value to indicate\n\ +the insn definitely advances the PC, and so the view number can be\n\ +safely assumed to be reset; a negative value to mean the insn\n\ +definitely does not advance the PC, and os the view number must not\n\ +be reset; or zero to decide based on the estimated insn length.\n\ +\n\ +If insn length is to be regarded as reliable, set the hook to\n\ +@code{hook_int_rtx_insn_0}.", + int, (rtx_insn *), NULL) + /* The code parameter should be of type enum rtx_code but this is not defined at this time. */ DEFHOOK diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4026175..e0edbe5 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,57 @@ +2018-02-13 Janus Weil <janus@gcc.gnu.org> + + PR fortran/84313 + * gfortran.dg/proc_ptr_common_1.f90: Fix invalid test case, + add necessary compiler options. + * gfortran.dg/proc_ptr_common_2.f90: Add missing error message. + +2018-02-13 Jakub Jelinek <jakub@redhat.com> + + PR c/82210 + * gcc.c-torture/execute/pr82210.c: New test. + + PR middle-end/84309 + * gcc.dg/pr84309-2.c: New test. + +2018-02-12 Richard Sandiford <richard.sandiford@linaro.org> + + PR tree-optimization/84321 + * gcc.dg/pr84321.c: New test. + +2018-02-13 Vladimir Makarov <vmakarov@redhat.com> + + PR target/84359 + * gcc.target/i386/57193.c: Add -march=x86-64. + +2018-02-13 Paolo Bonzini <bonzini@gnu.org> + + PR sanitizer/84340 + * gcc.dg/asan/pr84307.c: Remove test. + +2018-02-13 Sebastian Perta <sebastian.perta@renesas.com> + + * gcc.target/rl78/test_auto_vector.c: New test. + +2018-02-13 Richard Sandiford <richard.sandiford@linaro.org> + + PR c/84305 + * gcc.c-torture/compile/pr84305.c: New test. + +2018-02-13 Jakub Jelinek <jakub@redhat.com> + + PR target/84335 + * gcc.target/i386/pr84335.c: New test. + + PR tree-optimization/84339 + * gcc.c-torture/execute/pr84339.c: New test. + + PR middle-end/84309 + * gcc.dg/pr84309.c: New test. + * gcc.target/i386/pr84309.c: New test. + + PR target/84336 + * gcc.target/i386/pr84336.c: New test. + 2018-02-12 Jakub Jelinek <jakub@redhat.com> PR c++/84341 diff --git a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic5.C b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic5.C index 5196a18..97f64cd 100644 --- a/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic5.C +++ b/gcc/testsuite/g++.dg/cpp0x/lambda/lambda-variadic5.C @@ -11,6 +11,7 @@ template<class... T> void print_all(const T&... t) { accept_all([&]()->int { print(t); return 0; }...); + accept_all([&t]()->int { print(t); return 0; }...); } int main() diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn47.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn47.C new file mode 100644 index 0000000..7de2d9f --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn47.C @@ -0,0 +1,6 @@ +// PR c++/84080 +// { dg-do compile { target c++14 } } + +template <int i, typename T> T foo(); + +template <> auto foo<0>() { return 42; } // { dg-error "does not match" } diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic12.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic12.C new file mode 100644 index 0000000..8113320 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic12.C @@ -0,0 +1,16 @@ +// { dg-do compile { target c++14 } } + +template < typename... T > void sink(T ...){} + +template < typename... T > +auto f(T... t){ + [=](auto ... j){ + sink((t + j)...); + }(t...); +} + +int main(){ + f(0); + f(); + f(0.1,0.2); +} diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic13.C b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic13.C new file mode 100644 index 0000000..92fd34c --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-generic-variadic13.C @@ -0,0 +1,15 @@ +// PR c++/84338 +// { dg-do compile { target c++14 } } + +template < typename ... T > +auto f(T ... i){ + [](auto ... i){ + // // wrongly true in current trunk + // static_assert(sizeof...(i) == 1, ""); + static_assert(sizeof...(i) == 2, ""); + }(i ...); +} + +int main(){ + f(0, 1); +} diff --git a/gcc/testsuite/gcc.c-torture/compile/pr84305.c b/gcc/testsuite/gcc.c-torture/compile/pr84305.c new file mode 100644 index 0000000..374fa67 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr84305.c @@ -0,0 +1,4 @@ +int res, a, b; +void *foo; +static void f2 (int arg) { res = ((int (*)[arg][b]) foo)[0][0][0]; } +void f1 (void) { f2 (a); } diff --git a/gcc/testsuite/gcc.c-torture/execute/pr82210.c b/gcc/testsuite/gcc.c-torture/execute/pr82210.c new file mode 100644 index 0000000..48fb715 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr82210.c @@ -0,0 +1,26 @@ +/* PR c/82210 */ + +void +foo (int size) +{ + int i; + struct S { + __attribute__((aligned (16))) struct T { short c; } a[size]; + int b[size]; + } s; + + for (i = 0; i < size; i++) + s.a[i].c = 0x1234; + for (i = 0; i < size; i++) + s.b[i] = 0; + for (i = 0; i < size; i++) + if (s.a[i].c != 0x1234 || s.b[i] != 0) + __builtin_abort (); +} + +int +main () +{ + foo (15); + return 0; +} diff --git a/gcc/testsuite/gcc.c-torture/execute/pr84339.c b/gcc/testsuite/gcc.c-torture/execute/pr84339.c new file mode 100644 index 0000000..06fa3a0 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/execute/pr84339.c @@ -0,0 +1,30 @@ +/* PR tree-optimization/84339 */ + +struct S { int a; char b[1]; }; + +__attribute__((noipa)) int +foo (struct S *p) +{ + return __builtin_strlen (&p->b[0]); +} + +__attribute__((noipa)) int +bar (struct S *p) +{ + return __builtin_strlen (p->b); +} + +int +main () +{ + struct S *p = __builtin_malloc (sizeof (struct S) + 16); + if (p) + { + p->a = 1; + __builtin_strcpy (p->b, "abcdefg"); + if (foo (p) != 7 || bar (p) != 7) + __builtin_abort (); + __builtin_free (p); + } + return 0; +} diff --git a/gcc/testsuite/gcc.dg/asan/pr84307.c b/gcc/testsuite/gcc.dg/asan/pr84307.c deleted file mode 100644 index 6e1a197..0000000 --- a/gcc/testsuite/gcc.dg/asan/pr84307.c +++ /dev/null @@ -1,21 +0,0 @@ -/* PR middle-end/83185 */ -/* { dg-do link } */ -/* { dg-options "-O1" } */ - -struct f { - void (*func)(void); -}; - -extern void link_error(void); -extern int printf(const char *f, ...); - -static inline struct f *gimme_null(struct f *result) -{ - return 0; -} - -int main(int argc, char **argv) -{ - struct f *x = gimme_null(&(struct f) { .func = link_error }); - printf("%p", x); -} diff --git a/gcc/testsuite/gcc.dg/pr84309-2.c b/gcc/testsuite/gcc.dg/pr84309-2.c new file mode 100644 index 0000000..ced55d4 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr84309-2.c @@ -0,0 +1,11 @@ +/* PR middle-end/84309 */ +/* { dg-do compile } */ +/* { dg-options "-Ofast -fdump-tree-optimized" } */ + +double +foo (double x) +{ + return __builtin_pow (2.0, x); +} + +/* { dg-final { scan-tree-dump "__builtin_exp2 " "optimized" { target *-*-linux* *-*-gnu* } } } */ diff --git a/gcc/testsuite/gcc.dg/pr84309.c b/gcc/testsuite/gcc.dg/pr84309.c new file mode 100644 index 0000000..6fe774e --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr84309.c @@ -0,0 +1,14 @@ +/* PR middle-end/84309 */ +/* { dg-do run { target c99_runtime } } */ +/* { dg-options "-O2 -ffast-math" } */ + +int +main () +{ + unsigned long a = 1024; + unsigned long b = 16 * 1024; + unsigned long c = __builtin_pow (2, (__builtin_log2 (a) + __builtin_log2 (b)) / 2); + if (c != 4096) + __builtin_abort (); + return 0; +} diff --git a/gcc/testsuite/gcc.dg/pr84321.c b/gcc/testsuite/gcc.dg/pr84321.c new file mode 100644 index 0000000..8f8186b --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr84321.c @@ -0,0 +1,16 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -fwrapv" } */ + +int c; + +void +foo (int *a, int b) +{ + int e; + if (b == 1) + return; + for (e = 0; e < (b & ~7); e += 8) + ; + for (++e; e < b;) + c = a[e]; +} diff --git a/gcc/testsuite/gcc.target/i386/pr57193.c b/gcc/testsuite/gcc.target/i386/pr57193.c index 70e2612..ef209c9 100644 --- a/gcc/testsuite/gcc.target/i386/pr57193.c +++ b/gcc/testsuite/gcc.target/i386/pr57193.c @@ -1,5 +1,5 @@ /* { dg-do compile { target { ! ia32 } } } */ -/* { dg-options "-O2" } */ +/* { dg-options "-O2 -march=x86-64" } */ /* { dg-final { scan-assembler-times "movdqa" 2 } } */ #include <emmintrin.h> diff --git a/gcc/testsuite/gcc.target/i386/pr84309.c b/gcc/testsuite/gcc.target/i386/pr84309.c new file mode 100644 index 0000000..d1dd6ce --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr84309.c @@ -0,0 +1,16 @@ +/* PR middle-end/84309 */ +/* { dg-do compile } */ +/* { dg-options "-Ofast -mavx" } */ + +double pow (double, double) __attribute__((simd)); +double exp (double) __attribute__((simd)); +extern double a[1024], b[1024]; + +void +foo (void) +{ + for (int i = 0; i < 1024; ++i) + a[i] = pow (2.0, b[i]); +} + +/* { dg-final { scan-assembler "_ZGVcN4v_exp" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr84335.c b/gcc/testsuite/gcc.target/i386/pr84335.c new file mode 100644 index 0000000..c8d2a71 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr84335.c @@ -0,0 +1,10 @@ +/* PR target/84335 */ +/* { dg-do compile } */ +/* { dg-options "-O2 -maes -mno-sse2" } */ +typedef long long V __attribute__ ((__vector_size__ (16))); + +V +foo (V *a, V *b) +{ + return __builtin_ia32_aesenc128 (*a, *b); /* { dg-error "needs isa option" } */ +} diff --git a/gcc/testsuite/gcc.target/i386/pr84336.c b/gcc/testsuite/gcc.target/i386/pr84336.c new file mode 100644 index 0000000..3218116 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr84336.c @@ -0,0 +1,13 @@ +/* PR target/84336 */ +/* { dg-do compile } */ +/* { dg-options "-O0 -ftree-ter -mavx512f" } */ + +#include <x86intrin.h> + +struct S { __m512i h; } b; + +__m512 +foo (__m512 a, __mmask16 c, __m512 d) +{ + return _mm512_mask2_permutex2var_ps (a, b.h, c, d); +} diff --git a/gcc/testsuite/gcc.target/rl78/test_auto_vector.c b/gcc/testsuite/gcc.target/rl78/test_auto_vector.c new file mode 100644 index 0000000..7055363 --- /dev/null +++ b/gcc/testsuite/gcc.target/rl78/test_auto_vector.c @@ -0,0 +1,21 @@ +/* { dg-do compile } */
+
+void __attribute__ ((interrupt (5))) interrupt_5_handler ();
+
+void interrupt_5_handler ()
+{
+}
+
+void __attribute__ ((vector (4))) interrupt_4_handler ();
+
+void interrupt_4_handler ()
+{
+}
+
+void __attribute__ ((interrupt)) interrupt_handler ();
+
+void interrupt_handler ()
+{
+}
+
+/* { dg-final { scan-assembler "tableentry" } } */
diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_common_1.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_common_1.f90 index df2ef0b..c6a4e6a 100644 --- a/gcc/testsuite/gfortran.dg/proc_ptr_common_1.f90 +++ b/gcc/testsuite/gfortran.dg/proc_ptr_common_1.f90 @@ -1,16 +1,18 @@ ! { dg-do run } - +! { dg-options "-std=f2003 -fall-intrinsics" } +! ! PR fortran/36592 ! ! Procedure Pointers inside COMMON blocks. +! (Allowed in F03, but forbidden in F08.) ! ! Contributed by Janus Weil <janus@gcc.gnu.org>. subroutine one() implicit none - common /com/ p1,p2,a,b procedure(real), pointer :: p1,p2 integer :: a,b + common /com/ p1,p2,a,b if (a/=5 .or. b/=-9 .or. p1(0.0)/=1.0 .or. p2(0.0)/=0.0) call abort() end subroutine one diff --git a/gcc/testsuite/gfortran.dg/proc_ptr_common_2.f90 b/gcc/testsuite/gfortran.dg/proc_ptr_common_2.f90 index f401c3a..f49c0a3 100644 --- a/gcc/testsuite/gfortran.dg/proc_ptr_common_2.f90 +++ b/gcc/testsuite/gfortran.dg/proc_ptr_common_2.f90 @@ -12,7 +12,7 @@ abstract interface end interface procedure(foo), pointer, bind(C) :: proc -common /com/ proc,r +common /com/ proc,r ! { dg-error "PROCEDURE attribute conflicts with COMMON attribute" } common s call s() ! { dg-error "PROCEDURE attribute conflicts with COMMON attribute" } diff --git a/gcc/toplev.c b/gcc/toplev.c index 23db063..b066bcc 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1558,13 +1558,23 @@ process_options (void) || write_symbols == VMS_AND_DWARF2_DEBUG) && !(flag_selective_scheduling || flag_selective_scheduling2)); + if (dwarf2out_as_loc_support == AUTODETECT_VALUE) + dwarf2out_as_loc_support + = dwarf2out_default_as_loc_support (); + if (dwarf2out_as_locview_support == AUTODETECT_VALUE) + dwarf2out_as_locview_support + = dwarf2out_default_as_locview_support (); + if (debug_variable_location_views == AUTODETECT_VALUE) { - debug_variable_location_views = flag_var_tracking - && debug_info_level >= DINFO_LEVEL_NORMAL - && (write_symbols == DWARF2_DEBUG - || write_symbols == VMS_AND_DWARF2_DEBUG) - && !dwarf_strict; + debug_variable_location_views + = (flag_var_tracking + && debug_info_level >= DINFO_LEVEL_NORMAL + && (write_symbols == DWARF2_DEBUG + || write_symbols == VMS_AND_DWARF2_DEBUG) + && !dwarf_strict + && dwarf2out_as_loc_support + && dwarf2out_as_locview_support); } else if (debug_variable_location_views == -1 && dwarf_version != 5) { @@ -1574,6 +1584,31 @@ process_options (void) debug_variable_location_views = 1; } + if (debug_internal_reset_location_views == 2) + { + debug_internal_reset_location_views + = (debug_variable_location_views + && targetm.reset_location_view); + } + else if (debug_internal_reset_location_views + && !debug_variable_location_views) + { + warning_at (UNKNOWN_LOCATION, 0, + "-ginternal-reset-location-views is forced disabled " + "without -gvariable-location-views"); + debug_internal_reset_location_views = 0; + } + + if (debug_inline_points == AUTODETECT_VALUE) + debug_inline_points = debug_variable_location_views; + else if (debug_inline_points && !debug_nonbind_markers_p) + { + warning_at (UNKNOWN_LOCATION, 0, + "-ginline-points is forced disabled without " + "-gstatement-frontiers"); + debug_inline_points = 0; + } + if (flag_tree_cselim == AUTODETECT_VALUE) { if (HAVE_conditional_move) diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 7f9ec77..811829e 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -4605,7 +4605,7 @@ expand_call_inline (basic_block bb, gimple *stmt, copy_body_data *id) GSI_NEW_STMT); } initialize_inlined_parameters (id, stmt, fn, bb); - if (debug_nonbind_markers_p && id->block + if (debug_nonbind_markers_p && debug_inline_points && id->block && inlined_function_outer_scope_p (id->block)) { gimple_stmt_iterator si = gsi_last_bb (bb); diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c index 26da31f..62bb3c5 100644 --- a/gcc/tree-ssa-live.c +++ b/gcc/tree-ssa-live.c @@ -522,7 +522,7 @@ remove_unused_scope_block_p (tree scope, bool in_ctor_dtor_block) unused = false; /* Preserve the block, it is referenced by at least the inline entry point marker. */ - else if (debug_nonbind_markers_p + else if (debug_inline_points && inlined_function_outer_scope_p (scope)) unused = false; /* Innermost blocks with no live variables nor statements can be always @@ -558,7 +558,7 @@ remove_unused_scope_block_p (tree scope, bool in_ctor_dtor_block) with block_ultimate_origin being set to FUNCTION_DECL and DECL_SOURCE_LOCATION set, unless they expand to nothing... But see above for the case of statement frontiers. */ - else if (!debug_nonbind_markers_p + else if (!debug_inline_points && inlined_function_outer_scope_p (scope)) unused = false; else diff --git a/gcc/tree-vect-patterns.c b/gcc/tree-vect-patterns.c index 1279352..25a2efb 100644 --- a/gcc/tree-vect-patterns.c +++ b/gcc/tree-vect-patterns.c @@ -41,6 +41,10 @@ along with GCC; see the file COPYING3. If not see #include "builtins.h" #include "internal-fn.h" #include "case-cfn-macros.h" +#include "fold-const-call.h" +#include "attribs.h" +#include "cgraph.h" +#include "omp-simd-clone.h" /* Pattern recognition functions */ static gimple *vect_recog_widen_sum_pattern (vec<gimple *> *, tree *, @@ -1049,7 +1053,7 @@ vect_recog_pow_pattern (vec<gimple *> *stmts, tree *type_in, tree *type_out) { gimple *last_stmt = (*stmts)[0]; - tree base, exp = NULL; + tree base, exp; gimple *stmt; tree var; @@ -1060,17 +1064,77 @@ vect_recog_pow_pattern (vec<gimple *> *stmts, tree *type_in, { CASE_CFN_POW: CASE_CFN_POWI: - base = gimple_call_arg (last_stmt, 0); - exp = gimple_call_arg (last_stmt, 1); - if (TREE_CODE (exp) != REAL_CST - && TREE_CODE (exp) != INTEGER_CST) - return NULL; break; default: return NULL; } + base = gimple_call_arg (last_stmt, 0); + exp = gimple_call_arg (last_stmt, 1); + if (TREE_CODE (exp) != REAL_CST + && TREE_CODE (exp) != INTEGER_CST) + { + if (flag_unsafe_math_optimizations + && TREE_CODE (base) == REAL_CST + && !gimple_call_internal_p (last_stmt)) + { + combined_fn log_cfn; + built_in_function exp_bfn; + switch (DECL_FUNCTION_CODE (gimple_call_fndecl (last_stmt))) + { + case BUILT_IN_POW: + log_cfn = CFN_BUILT_IN_LOG; + exp_bfn = BUILT_IN_EXP; + break; + case BUILT_IN_POWF: + log_cfn = CFN_BUILT_IN_LOGF; + exp_bfn = BUILT_IN_EXPF; + break; + case BUILT_IN_POWL: + log_cfn = CFN_BUILT_IN_LOGL; + exp_bfn = BUILT_IN_EXPL; + break; + default: + return NULL; + } + tree logc = fold_const_call (log_cfn, TREE_TYPE (base), base); + tree exp_decl = builtin_decl_implicit (exp_bfn); + /* Optimize pow (C, x) as exp (log (C) * x). Normally match.pd + does that, but if C is a power of 2, we want to use + exp2 (log2 (C) * x) in the non-vectorized version, but for + vectorization we don't have vectorized exp2. */ + if (logc + && TREE_CODE (logc) == REAL_CST + && exp_decl + && lookup_attribute ("omp declare simd", + DECL_ATTRIBUTES (exp_decl))) + { + cgraph_node *node = cgraph_node::get_create (exp_decl); + if (node->simd_clones == NULL) + { + if (node->definition) + return NULL; + expand_simd_clones (node); + if (node->simd_clones == NULL) + return NULL; + } + stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt); + tree def = vect_recog_temp_ssa_var (TREE_TYPE (base), NULL); + gimple *g = gimple_build_assign (def, MULT_EXPR, exp, logc); + new_pattern_def_seq (stmt_vinfo, g); + *type_in = TREE_TYPE (base); + *type_out = NULL_TREE; + tree res = vect_recog_temp_ssa_var (TREE_TYPE (base), NULL); + g = gimple_build_call (exp_decl, 1, def); + gimple_call_set_lhs (g, res); + return g; + } + } + + return NULL; + } + /* We now have a pow or powi builtin function call with a constant exponent. */ @@ -1744,8 +1808,8 @@ vect_recog_widen_shift_pattern (vec<gimple *> *stmts, /* Pattern supported. Create a stmt to be used to replace the pattern. */ var = vect_recog_temp_ssa_var (type, NULL); - pattern_stmt = - gimple_build_assign (var, WIDEN_LSHIFT_EXPR, oprnd0, oprnd1); + pattern_stmt + = gimple_build_assign (var, WIDEN_LSHIFT_EXPR, oprnd0, oprnd1); if (wstmt) { stmt_vec_info stmt_vinfo = vinfo_for_stmt (last_stmt); @@ -4439,10 +4503,6 @@ vect_pattern_recog_1 (vect_recog_func *recog_func, } else { - machine_mode vec_mode; - enum insn_code icode; - optab optab; - /* Check target support */ type_in = get_vectype_for_scalar_type (type_in); if (!type_in) @@ -4456,19 +4516,18 @@ vect_pattern_recog_1 (vect_recog_func *recog_func, pattern_vectype = type_out; if (is_gimple_assign (pattern_stmt)) - code = gimple_assign_rhs_code (pattern_stmt); - else - { - gcc_assert (is_gimple_call (pattern_stmt)); - code = CALL_EXPR; + { + enum insn_code icode; + code = gimple_assign_rhs_code (pattern_stmt); + optab optab = optab_for_tree_code (code, type_in, optab_default); + machine_mode vec_mode = TYPE_MODE (type_in); + if (!optab + || (icode = optab_handler (optab, vec_mode)) == CODE_FOR_nothing + || (insn_data[icode].operand[0].mode != TYPE_MODE (type_out))) + return false; } - - optab = optab_for_tree_code (code, type_in, optab_default); - vec_mode = TYPE_MODE (type_in); - if (!optab - || (icode = optab_handler (optab, vec_mode)) == CODE_FOR_nothing - || (insn_data[icode].operand[0].mode != TYPE_MODE (type_out))) - return false; + else + gcc_assert (is_gimple_call (pattern_stmt)); } /* Found a vectorizable pattern. */ diff --git a/gcc/tree-vrp.c b/gcc/tree-vrp.c index cba58e0..625e65b 100644 --- a/gcc/tree-vrp.c +++ b/gcc/tree-vrp.c @@ -184,37 +184,61 @@ intersect_range_with_nonzero_bits (enum value_range_type vr_type, const wide_int &nonzero_bits, signop sgn) { - if (vr_type == VR_RANGE) - { - *max = wi::round_down_for_mask (*max, nonzero_bits); - - /* Check that the range contains at least one valid value. */ - if (wi::gt_p (*min, *max, sgn)) - return VR_UNDEFINED; - - *min = wi::round_up_for_mask (*min, nonzero_bits); - gcc_checking_assert (wi::le_p (*min, *max, sgn)); - } if (vr_type == VR_ANTI_RANGE) { - *max = wi::round_up_for_mask (*max, nonzero_bits); + /* The VR_ANTI_RANGE is equivalent to the union of the ranges + A: [-INF, *MIN) and B: (*MAX, +INF]. First use NONZERO_BITS + to create an inclusive upper bound for A and an inclusive lower + bound for B. */ + wide_int a_max = wi::round_down_for_mask (*min - 1, nonzero_bits); + wide_int b_min = wi::round_up_for_mask (*max + 1, nonzero_bits); + + /* If the calculation of A_MAX wrapped, A is effectively empty + and A_MAX is the highest value that satisfies NONZERO_BITS. + Likewise if the calculation of B_MIN wrapped, B is effectively + empty and B_MIN is the lowest value that satisfies NONZERO_BITS. */ + bool a_empty = wi::ge_p (a_max, *min, sgn); + bool b_empty = wi::le_p (b_min, *max, sgn); + + /* If both A and B are empty, there are no valid values. */ + if (a_empty && b_empty) + return VR_UNDEFINED; - /* If the calculation wrapped, we now have a VR_RANGE whose - lower bound is *MAX and whose upper bound is *MIN. */ - if (wi::gt_p (*min, *max, sgn)) + /* If exactly one of A or B is empty, return a VR_RANGE for the + other one. */ + if (a_empty || b_empty) { - std::swap (*min, *max); - *max = wi::round_down_for_mask (*max, nonzero_bits); + *min = b_min; + *max = a_max; gcc_checking_assert (wi::le_p (*min, *max, sgn)); return VR_RANGE; } - *min = wi::round_down_for_mask (*min, nonzero_bits); + /* Update the VR_ANTI_RANGE bounds. */ + *min = a_max + 1; + *max = b_min - 1; gcc_checking_assert (wi::le_p (*min, *max, sgn)); - /* Check whether we now have an empty set of values. */ - if (*min - 1 == *max) + /* Now check whether the excluded range includes any values that + satisfy NONZERO_BITS. If not, switch to a full VR_RANGE. */ + if (wi::round_up_for_mask (*min, nonzero_bits) == b_min) + { + unsigned int precision = min->get_precision (); + *min = wi::min_value (precision, sgn); + *max = wi::max_value (precision, sgn); + vr_type = VR_RANGE; + } + } + if (vr_type == VR_RANGE) + { + *max = wi::round_down_for_mask (*max, nonzero_bits); + + /* Check that the range contains at least one valid value. */ + if (wi::gt_p (*min, *max, sgn)) return VR_UNDEFINED; + + *min = wi::round_up_for_mask (*min, nonzero_bits); + gcc_checking_assert (wi::le_p (*min, *max, sgn)); } return vr_type; } |