From a4296998322d3bb3b53c7412715cc2169f1d4f61 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Thu, 8 Feb 2018 16:11:39 +0000 Subject: [C++ PATCH] initializer_list diagnostic https://gcc.gnu.org/ml/gcc-patches/2018-02/msg00434.html * class.c (finish_struct): Fix std:initializer_list diagnostic formatting. * g++.dg/cpp0x/initlist93.C: Adjust diagnostic. From-SVN: r257496 --- gcc/cp/ChangeLog | 5 +++++ gcc/cp/class.c | 7 +++---- gcc/testsuite/ChangeLog | 4 ++++ gcc/testsuite/g++.dg/cpp0x/initlist93.C | 2 +- 4 files changed, 13 insertions(+), 5 deletions(-) (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index b898ba1..2fc35d2 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2018-02-08 Nathan Sidwell + + * class.c (finish_struct): Fix std:initializer_list diagnostic + formatting. + 2018-02-08 Paolo Carlini PR c++/83204 diff --git a/gcc/cp/class.c b/gcc/cp/class.c index 4417020..e48a04a 100644 --- a/gcc/cp/class.c +++ b/gcc/cp/class.c @@ -7062,7 +7062,7 @@ finish_struct (tree t, tree attributes) /* People keep complaining that the compiler crashes on an invalid definition of initializer_list, so I guess we should explicitly reject it. What the compiler internals care about is that it's a - template and has a pointer field followed by an integer field. */ + template and has a pointer field followed by size_type field. */ bool ok = false; if (processing_template_decl) { @@ -7075,9 +7075,8 @@ finish_struct (tree t, tree attributes) } } if (!ok) - fatal_error (input_location, - "definition of std::initializer_list does not match " - "#include "); + fatal_error (input_location, "definition of %qD does not match " + "%<#include %>", TYPE_NAME (t)); } input_location = saved_loc; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e989c94..6d45195 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2018-02-08 Nathan Sidwell + + * g++.dg/cpp0x/initlist93.C: Adjust diagnostic. + 2018-02-08 Richard Sandiford PR tree-optimization/84265 diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist93.C b/gcc/testsuite/g++.dg/cpp0x/initlist93.C index 84a4738..7a0b021 100644 --- a/gcc/testsuite/g++.dg/cpp0x/initlist93.C +++ b/gcc/testsuite/g++.dg/cpp0x/initlist93.C @@ -3,7 +3,7 @@ namespace std { -template class initializer_list // { dg-error "definition of std::initializer_list does not match" } +template class initializer_list // { dg-error "definition of .*std::initializer_list.* does not match" } { int *_M_array; int _M_len; -- cgit v1.1 From c6ba596b58e458391ed015e26b763e72ec725600 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Thu, 8 Feb 2018 16:18:04 +0000 Subject: re PR tree-optimization/84238 (ICE tree check: expected integer_cst, have plus_expr in to_wide, at tree.h:5527) PR tree-optimization/84238 * tree-ssa-strlen.c (maybe_diag_stxncpy_trunc): Verify the result of get_range_strlen. * gcc.dg/Wstringop-overflow-3.c: New test. From-SVN: r257497 --- gcc/ChangeLog | 6 ++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/Wstringop-overflow-3.c | 13 +++++++++++++ gcc/tree-ssa-strlen.c | 5 ++++- 4 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/Wstringop-overflow-3.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d9c45c9..461656b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2018-02-08 Marek Polacek + + PR tree-optimization/84238 + * tree-ssa-strlen.c (maybe_diag_stxncpy_trunc): Verify the result of + get_range_strlen. + 2018-02-08 Richard Sandiford PR tree-optimization/84265 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 6d45195..92e9e34 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-02-08 Marek Polacek + + PR tree-optimization/84238 + * gcc.dg/Wstringop-overflow-3.c: New test. + 2018-02-08 Nathan Sidwell * g++.dg/cpp0x/initlist93.C: Adjust diagnostic. diff --git a/gcc/testsuite/gcc.dg/Wstringop-overflow-3.c b/gcc/testsuite/gcc.dg/Wstringop-overflow-3.c new file mode 100644 index 0000000..5901844 --- /dev/null +++ b/gcc/testsuite/gcc.dg/Wstringop-overflow-3.c @@ -0,0 +1,13 @@ +/* PR tree-optimization/84238 */ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ + +char a[1]; +int b; +char *strncpy (char *, char *, __SIZE_TYPE__); +void +c () +{ + char d[b]; + strncpy (a, &d[3], 3); /* { dg-warning "writing 3 bytes into a region of size 1" } */ +} diff --git a/gcc/tree-ssa-strlen.c b/gcc/tree-ssa-strlen.c index f0f6535..94ed2be 100644 --- a/gcc/tree-ssa-strlen.c +++ b/gcc/tree-ssa-strlen.c @@ -1899,7 +1899,10 @@ maybe_diag_stxncpy_trunc (gimple_stmt_iterator gsi, tree src, tree cnt) { tree range[2]; get_range_strlen (src, range); - if (range[0]) + if (range[0] != NULL_TREE + && TREE_CODE (range[0]) == INTEGER_CST + && range[1] != NULL_TREE + && TREE_CODE (range[1]) == INTEGER_CST) { lenrange[0] = wi::to_wide (range[0], prec); lenrange[1] = wi::to_wide (range[1], prec); -- cgit v1.1 From b00dcb136ea594997c35108903782142849d6ac8 Mon Sep 17 00:00:00 2001 From: Mike Stump Date: Thu, 8 Feb 2018 18:39:43 +0000 Subject: Mark previous change with: PR target/84113 From-SVN: r257500 --- gcc/ChangeLog | 1 + 1 file changed, 1 insertion(+) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 461656b..4c22855 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -155,6 +155,7 @@ 2018-02-07 Iain Sandoe + PR target/84113 * config/rs6000/altivec.md (*restore_world): Remove LR use. * config/rs6000/predicates.md (restore_world_operation): Adjust op count, remove one USE. -- cgit v1.1 From 739745618a4202f3bf515494175eacae6ff05d2d Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Thu, 8 Feb 2018 18:54:39 +0000 Subject: re PR c++/83806 (Spurious -Wunused-but-set-parameter with nullptr) /cp 2018-02-08 Paolo Carlini PR c++/83806 * typeck.c (decay_conversion): Use mark_rvalue_use for the special case of nullptr too. /testsuite 2018-02-08 Paolo Carlini PR c++/83806 * g++.dg/warn/Wunused-parm-11.C: New. From-SVN: r257502 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/typeck.c | 5 ++++- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/warn/Wunused-parm-11.C | 13 +++++++++++++ 4 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/g++.dg/warn/Wunused-parm-11.C (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 2fc35d2..c68b590 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2018-02-08 Paolo Carlini + + PR c++/83806 + * typeck.c (decay_conversion): Use mark_rvalue_use for the special + case of nullptr too. + 2018-02-08 Nathan Sidwell * class.c (finish_struct): Fix std:initializer_list diagnostic diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index 83e7678..fe18ea9 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -2009,7 +2009,10 @@ decay_conversion (tree exp, return error_mark_node; if (NULLPTR_TYPE_P (type) && !TREE_SIDE_EFFECTS (exp)) - return nullptr_node; + { + mark_rvalue_use (exp, loc, reject_builtin); + return nullptr_node; + } /* build_c_cast puts on a NOP_EXPR to make the result not an lvalue. Leave such NOP_EXPRs, since RHS is being used in non-lvalue context. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 92e9e34..c51d2dd 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-02-08 Paolo Carlini + + PR c++/83806 + * g++.dg/warn/Wunused-parm-11.C: New. + 2018-02-08 Marek Polacek PR tree-optimization/84238 diff --git a/gcc/testsuite/g++.dg/warn/Wunused-parm-11.C b/gcc/testsuite/g++.dg/warn/Wunused-parm-11.C new file mode 100644 index 0000000..35896df --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/Wunused-parm-11.C @@ -0,0 +1,13 @@ +// PR c++/83806 +// { dg-do compile { target c++11 } } +// { dg-options "-Wunused-but-set-parameter" } + +template +bool equals(X x, Y y) { + return (x == y); +} + +int main() { + const char* p = nullptr; + equals(p, nullptr); +} -- cgit v1.1 From a7f8415c05fa2ba336a071c211f09c0e76f2bb0a Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Thu, 8 Feb 2018 18:56:17 +0000 Subject: constexpr.c (cxx_eval_component_reference): Use INDIRECT_REF_P. 2018-02-08 Paolo Carlini * constexpr.c (cxx_eval_component_reference): Use INDIRECT_REF_P. * lambda.c (build_capture_proxy): Likewise. * search.c (field_access_p): Likewise. * semantics.c (omp_clause_decl, omp_privatize_field, finish_omp_clauses): Likewise. From-SVN: r257503 --- gcc/cp/ChangeLog | 8 ++++++++ gcc/cp/constexpr.c | 2 +- gcc/cp/lambda.c | 2 +- gcc/cp/search.c | 2 +- gcc/cp/semantics.c | 6 +++--- 5 files changed, 14 insertions(+), 6 deletions(-) (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index c68b590..be4db4b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,5 +1,13 @@ 2018-02-08 Paolo Carlini + * constexpr.c (cxx_eval_component_reference): Use INDIRECT_REF_P. + * lambda.c (build_capture_proxy): Likewise. + * search.c (field_access_p): Likewise. + * semantics.c (omp_clause_decl, omp_privatize_field, + finish_omp_clauses): Likewise. + +2018-02-08 Paolo Carlini + PR c++/83806 * typeck.c (decay_conversion): Use mark_rvalue_use for the special case of nullptr too. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 93dd8ae..39a2e1a 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -2463,7 +2463,7 @@ cxx_eval_component_reference (const constexpr_ctx *ctx, tree t, tree whole = cxx_eval_constant_expression (ctx, orig_whole, lval, non_constant_p, overflow_p); - if (TREE_CODE (whole) == INDIRECT_REF + if (INDIRECT_REF_P (whole) && integer_zerop (TREE_OPERAND (whole, 0)) && !ctx->quiet) error ("dereferencing a null pointer in %qE", orig_whole); diff --git a/gcc/cp/lambda.c b/gcc/cp/lambda.c index ff8236a..2545eae 100644 --- a/gcc/cp/lambda.c +++ b/gcc/cp/lambda.c @@ -450,7 +450,7 @@ build_capture_proxy (tree member, tree init) { if (PACK_EXPANSION_P (init)) init = PACK_EXPANSION_PATTERN (init); - if (TREE_CODE (init) == INDIRECT_REF) + if (INDIRECT_REF_P (init)) init = TREE_OPERAND (init, 0); STRIP_NOPS (init); } diff --git a/gcc/cp/search.c b/gcc/cp/search.c index 920fc15..796209f 100644 --- a/gcc/cp/search.c +++ b/gcc/cp/search.c @@ -1636,7 +1636,7 @@ field_access_p (tree component_ref, tree field_decl, tree field_type) return false; tree indirect_ref = TREE_OPERAND (component_ref, 0); - if (TREE_CODE (indirect_ref) != INDIRECT_REF) + if (!INDIRECT_REF_P (indirect_ref)) return false; tree ptr = STRIP_NOPS (TREE_OPERAND (indirect_ref, 0)); diff --git a/gcc/cp/semantics.c b/gcc/cp/semantics.c index ea92da3..f0cee68 100644 --- a/gcc/cp/semantics.c +++ b/gcc/cp/semantics.c @@ -4391,7 +4391,7 @@ omp_clause_decl_field (tree decl) && DECL_OMP_PRIVATIZED_MEMBER (decl)) { tree f = DECL_VALUE_EXPR (decl); - if (TREE_CODE (f) == INDIRECT_REF) + if (INDIRECT_REF_P (f)) f = TREE_OPERAND (f, 0); if (TREE_CODE (f) == COMPONENT_REF) { @@ -4446,7 +4446,7 @@ omp_privatize_field (tree t, bool shared) omp_private_member_map = new hash_map; if (TREE_CODE (TREE_TYPE (t)) == REFERENCE_TYPE) { - gcc_assert (TREE_CODE (m) == INDIRECT_REF); + gcc_assert (INDIRECT_REF_P (m)); m = TREE_OPERAND (m, 0); } tree vb = NULL_TREE; @@ -5864,7 +5864,7 @@ finish_omp_clauses (tree clauses, enum c_omp_region_type ort) if (TREE_CODE (t) == POINTER_PLUS_EXPR) t = TREE_OPERAND (t, 0); if (TREE_CODE (t) == ADDR_EXPR - || TREE_CODE (t) == INDIRECT_REF) + || INDIRECT_REF_P (t)) t = TREE_OPERAND (t, 0); } tree n = omp_clause_decl_field (t); -- cgit v1.1 From 2318f3b46ed94cde0bd04d82dd1eccd483c23e5d Mon Sep 17 00:00:00 2001 From: Peter Bergner Date: Thu, 8 Feb 2018 14:40:32 -0600 Subject: re PR target/81143 (New test case gcc.target/powerpc/pr79799-2.c fails on powerpc BE) PR target/81143 * gcc.target/powerpc/pr79799-2.c: Use __LITTLE_ENDIAN__. From-SVN: r257504 --- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.target/powerpc/pr79799-2.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c51d2dd..522af52 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-02-08 Peter Bergner + + PR target/81143 + * gcc.target/powerpc/pr79799-2.c: Use __LITTLE_ENDIAN__. + 2018-02-08 Paolo Carlini PR c++/83806 diff --git a/gcc/testsuite/gcc.target/powerpc/pr79799-2.c b/gcc/testsuite/gcc.target/powerpc/pr79799-2.c index 793e3b9..b1a0b09 100644 --- a/gcc/testsuite/gcc.target/powerpc/pr79799-2.c +++ b/gcc/testsuite/gcc.target/powerpc/pr79799-2.c @@ -8,7 +8,7 @@ /* Optimize x = vec_insert (vec_extract (v2, N), v1, M) for SFmode if N is the default scalar position. */ -#if __ORDER_LITTLE_ENDIAN__ +#if __LITTLE_ENDIAN__ #define ELE 2 #else #define ELE 1 -- cgit v1.1 From 001e73373e6d2e7c756141e0d7ac8e24ae1574ad Mon Sep 17 00:00:00 2001 From: Sergey Shalnov Date: Thu, 8 Feb 2018 23:31:15 +0100 Subject: re PR target/83008 ([performance] Is it better to avoid extra instructions in data passing between loops?) PR target/83008 * config/i386/x86-tune-costs.h (skylake_cost): Fix cost of storing integer register in SImode. Fix cost of 256 and 512 byte aligned SSE register store. * config/i386/i386.c (ix86_multiplication_cost): Fix multiplication cost for TARGET_AVX512DQ. testsuite/ChangeLog: PR target/83008 * gcc.target/i386/pr83008.c: New test. From-SVN: r257505 --- gcc/ChangeLog | 12 ++++++++++ gcc/config/i386/i386.c | 4 ++++ gcc/config/i386/x86-tune-costs.h | 4 ++-- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.target/i386/pr83008.c | 40 +++++++++++++++++++++++++++++++++ 5 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr83008.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4c22855..dd78a34 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2018-02-08 Sergey Shalnov + + PR target/83008 + * config/i386/x86-tune-costs.h (skylake_cost): Fix cost of + storing integer register in SImode. Fix cost of 256 and 512 + byte aligned SSE register store. + +2018-02-08 Sergey Shalnov + + * config/i386/i386.c (ix86_multiplication_cost): Fix + multiplication cost for TARGET_AVX512DQ. + 2018-02-08 Marek Polacek PR tree-optimization/84238 diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index fc3d6f0..a870997 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -40402,6 +40402,10 @@ ix86_multiplication_cost (const struct processor_costs *cost, ? cost->mulsd : cost->mulss, true); else if (GET_MODE_CLASS (mode) == MODE_VECTOR_INT) { + /* vpmullq is used in this case. No emulation is needed. */ + if (TARGET_AVX512DQ) + return ix86_vec_cost (mode, cost->mulss, true); + /* V*QImode is emulated with 7-13 insns. */ if (mode == V16QImode || mode == V32QImode) { diff --git a/gcc/config/i386/x86-tune-costs.h b/gcc/config/i386/x86-tune-costs.h index e943d13..8409a5f 100644 --- a/gcc/config/i386/x86-tune-costs.h +++ b/gcc/config/i386/x86-tune-costs.h @@ -1557,7 +1557,7 @@ struct processor_costs skylake_cost = { {4, 4, 4}, /* cost of loading integer registers in QImode, HImode and SImode. Relative to reg-reg move (2). */ - {6, 6, 6}, /* cost of storing integer registers */ + {6, 6, 3}, /* cost of storing integer registers */ 2, /* cost of reg,reg fld/fst */ {6, 6, 8}, /* cost of loading fp registers in SFmode, DFmode and XFmode */ @@ -1572,7 +1572,7 @@ struct processor_costs skylake_cost = { {6, 6, 6, 10, 20}, /* cost of loading SSE registers in 32,64,128,256 and 512-bit */ {6, 6, 6, 10, 20}, /* cost of unaligned loads. */ - {8, 8, 8, 8, 16}, /* cost of storing SSE registers + {8, 8, 8, 12, 24}, /* cost of storing SSE registers in 32,64,128,256 and 512-bit */ {8, 8, 8, 8, 16}, /* cost of unaligned stores. */ 2, 2, /* SSE->integer and integer->SSE moves */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 522af52..d9ed50c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-02-08 Sergey Shalnov + + PR target/83008 + * gcc.target/i386/pr83008.c: New test. + 2018-02-08 Peter Bergner PR target/81143 diff --git a/gcc/testsuite/gcc.target/i386/pr83008.c b/gcc/testsuite/gcc.target/i386/pr83008.c new file mode 100644 index 0000000..87a4bea --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr83008.c @@ -0,0 +1,40 @@ +/* PR target/83008 */ +/* { dg-do compile } */ +/* { dg-options "-Ofast -funroll-loops -march=skylake-avx512 -mfpmath=sse" } */ +/* { dg-final { scan-assembler-not "vmovdq(a|u)(32|64)" } } */ + +int +pr83008 (unsigned char *pix1, int i_pix1, unsigned char *pix2, int i_pix2) +{ + unsigned int tmp[4][4]; + unsigned int a0, a1, a2, a3; + int sum = 0; + for (int i = 0; i < 4; i++, pix1 += i_pix1, pix2 += i_pix2) + { + a0 = (pix1[0] - pix2[0]) + ((pix1[4] - pix2[4]) << 16); + a1 = (pix1[1] - pix2[1]) + ((pix1[5] - pix2[5]) << 16); + a2 = (pix1[2] - pix2[2]) + ((pix1[6] - pix2[6]) << 16); + a3 = (pix1[3] - pix2[3]) + ((pix1[7] - pix2[7]) << 16); + int t0 = a0 + a1; + int t1 = a0 - a1; + int t2 = a2 + a3; + int t3 = a2 - a3; + tmp[i][0] = t0 + t2; + tmp[i][2] = t0 - t2; + tmp[i][1] = t1 + t3; + tmp[i][3] = t1 - t3; + } + for (int i = 0; i < 4; i++) + { + int t0 = tmp[0][i] + tmp[1][i]; + int t1 = tmp[0][i] - tmp[1][i]; + int t2 = tmp[2][i] + tmp[3][i]; + int t3 = tmp[2][i] - tmp[3][i]; + a0 = t0 + t2; + a2 = t0 - t2; + a1 = t1 + t3; + a3 = t1 - t3; + sum += (a0) + (a1) + (a2) + (a3); + } + return (sum + ((unsigned int) sum >> 16)) >> 1; +} -- cgit v1.1 From 7e64287b36bc9501cf8e214367b6d4dcfeeaae46 Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Fri, 9 Feb 2018 00:16:14 +0000 Subject: Daily bump. From-SVN: r257508 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 3a0b1e3..de1dc49 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20180208 +20180209 -- cgit v1.1 From 6d3aa24cd6535dcfc9f0701579eca53aa191768c Mon Sep 17 00:00:00 2001 From: David Malcolm Date: Fri, 9 Feb 2018 01:07:11 +0000 Subject: Fix ICE in find_taken_edge_computed_goto (PR 84136) PR 84136 reports an ICE within sccvn_dom_walker when handling a C/C++ source file that overuses the labels-as-values extension. The code in question stores a jump label into a global, and then jumps to it from another function, which ICEs after inlining: void* a; void foo() { if ((a = &&l)) return; l:; } int main() { foo(); goto *a; return 0; } This appears to be far beyond what we claim to support in this extension - but we shouldn't ICE. What's happening is that, after inlining, we have usage of a *copy* of the label, which optimizes away the if-return logic, turning it into an infinite loop. On entry to the sccvn_dom_walker we have this gimple: main () { void * a.0_1; [count: 0]: a = &l; [count: 0]: l: a.0_1 = a; goto a.0_1; } and: edge taken = find_taken_edge (bb, vn_valueize (val)); reasonably valueizes the: goto a.0_1; after the: a = &l; a.0_1 = a; as if it were: goto *&l; find_taken_edge_computed_goto then has: 2380 dest = label_to_block (val); 2381 if (dest) 2382 { 2383 e = find_edge (bb, dest); 2384 gcc_assert (e != NULL); 2385 } which locates dest as a self-jump from block 3 back to itself. However, the find_edge call returns NULL - it has a predecessor edge from block 2, but no successor edges. Hence the assertion fails and we ICE. A successor edge from the computed goto could have been created by make_edges if the label stmt had been in the function, but make_edges only looks in the current function when handling computed gotos, and the label only appeared after inlining. The following patch removes the assertion, fixing the ICE. gcc/testsuite/ChangeLog: PR tree-optimization/84136 * gcc.c-torture/compile/pr84136.c: New test. gcc/ChangeLog: PR tree-optimization/84136 * tree-cfg.c (find_taken_edge_computed_goto): Remove assertion that the result of find_edge is non-NULL. From-SVN: r257509 --- gcc/ChangeLog | 6 ++++++ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.c-torture/compile/pr84136.c | 15 +++++++++++++++ gcc/tree-cfg.c | 12 ++++++++---- 4 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/pr84136.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index dd78a34..8212952 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2018-02-08 David Malcolm + + PR tree-optimization/84136 + * tree-cfg.c (find_taken_edge_computed_goto): Remove assertion + that the result of find_edge is non-NULL. + 2018-02-08 Sergey Shalnov PR target/83008 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d9ed50c..dfa8cb8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-02-08 David Malcolm + + PR tree-optimization/84136 + * gcc.c-torture/compile/pr84136.c: New test. + 2018-02-08 Sergey Shalnov PR target/83008 diff --git a/gcc/testsuite/gcc.c-torture/compile/pr84136.c b/gcc/testsuite/gcc.c-torture/compile/pr84136.c new file mode 100644 index 0000000..0a70e4e --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/pr84136.c @@ -0,0 +1,15 @@ +void* a; + +void foo() { + if ((a = &&l)) + return; + + l:; +} + +int main() { + foo(); + goto *a; + + return 0; +} diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index c5318b9..b87e48d 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -2379,10 +2379,14 @@ find_taken_edge_computed_goto (basic_block bb, tree val) dest = label_to_block (val); if (dest) - { - e = find_edge (bb, dest); - gcc_assert (e != NULL); - } + e = find_edge (bb, dest); + + /* It's possible for find_edge to return NULL here on invalid code + that abuses the labels-as-values extension (e.g. code that attempts to + jump *between* functions via stored labels-as-values; PR 84136). + If so, then we simply return that NULL for the edge. + We don't currently have a way of detecting such invalid code, so we + can't assert that it was the case when a NULL edge occurs here. */ return e; } -- cgit v1.1 From bd2b9f1e2d67ec8e88c977154ecfee34fa2bebe3 Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Fri, 9 Feb 2018 02:21:57 +0000 Subject: [LVU] Introduce location views This patch introduces an option to enable the generation of location views along with location lists. The exact format depends on the DWARF version: it can be a separate attribute (DW_AT_GNU_locviews) or (DW_LLE_view_pair) entries in DWARF5+ loclists. Line number tables are also affected. If the assembler is found, at compiler build time, to support .loc views, we use them and assembler-computed view labels, otherwise we output compiler-generated line number programs with conservatively-computed view labels. In either case, we output view information next to line number changes when verbose assembly output is requested. This patch requires an LVU patch that modifies the exported API of final_scan_insn. It also expects the entire SFN patchset to be installed first, although SFN is not a requirement for LVU. for include/ChangeLog * dwarf2.def (DW_AT_GNU_locviews): New. * dwarf2.h (enum dwarf_location_list_entry_type): Add DW_LLE_GNU_view_pair. (DW_LLE_view_pair): Define. for gcc/ChangeLog * common.opt (gvariable-location-views): New. (gvariable-location-views=incompat5): New. * config.in: Rebuilt. * configure: Rebuilt. * configure.ac: Test assembler for view support. * dwarf2asm.c (dw2_asm_output_symname_uleb128): New. * dwarf2asm.h (dw2_asm_output_symname_uleb128): Declare. * dwarf2out.c (var_loc_view): New typedef. (struct dw_loc_list_struct): Add vl_symbol, vbegin, vend. (dwarf2out_locviews_in_attribute): New. (dwarf2out_locviews_in_loclist): New. (dw_val_equal_p): Compare val_view_list of dw_val_class_view_lists. (enum dw_line_info_opcode): Add LI_adv_address. (struct dw_line_info_table): Add view. (RESET_NEXT_VIEW, RESETTING_VIEW_P): New macros. (DWARF2_ASM_VIEW_DEBUG_INFO): Define default. (zero_view_p): New variable. (ZERO_VIEW_P): New macro. (output_asm_line_debug_info): New. (struct var_loc_node): Add view. (add_AT_view_list, AT_loc_list): New. (add_var_loc_to_decl): Add view param. Test it against last. (new_loc_list): Add view params. Record them. (AT_loc_list_ptr): Handle loc and view lists. (view_list_to_loc_list_val_node): New. (print_dw_val): Handle dw_val_class_view_list. (size_of_die): Likewise. (value_format): Likewise. (loc_list_has_views): New. (gen_llsym): Set vl_symbol too. (maybe_gen_llsym, skip_loc_list_entry): New. (dwarf2out_maybe_output_loclist_view_pair): New. (output_loc_list): Output view list or entries too. (output_view_list_offset): New. (output_die): Handle dw_val_class_view_list. (output_dwarf_version): New. (output_compilation_unit_header): Use it. (output_skeleton_debug_sections): Likewise. (output_rnglists, output_line_info): Likewise. (output_pubnames, output_aranges): Update version comments. (output_one_line_info_table): Output view numbers in asm comments. (dw_loc_list): Determine current endview, pass it to new_loc_list. Call maybe_gen_llsym. (loc_list_from_tree_1): Adjust. (add_AT_location_description): Create view list attribute if needed, check it's absent otherwise. (convert_cfa_to_fb_loc_list): Adjust. (maybe_emit_file): Call output_asm_line_debug_info for test. (dwarf2out_var_location): Reset views as needed. Precompute add_var_loc_to_decl args. Call get_attr_min_length only if we have the attribute. Set view. (new_line_info_table): Reset next view. (set_cur_line_info_table): Call output_asm_line_debug_info for test. (dwarf2out_source_line): Likewise. Output view resets and labels to the assembler, or select appropriate line info opcodes. (prune_unused_types_walk_attribs): Handle dw_val_class_view_list. (optimize_string_length): Catch it. Adjust. (resolve_addr): Copy vl_symbol along with ll_symbol. Handle dw_val_class_view_list, and remove it if no longer needed. (hash_loc_list): Hash view numbers. (loc_list_hasher::equal): Compare them. (optimize_location_lists): Check whether a view list symbol is needed, and whether the locview attribute is present, and whether they match. Remove the locview attribute if no longer needed. (index_location_lists): Call skip_loc_list_entry for test. (dwarf2out_finish): Call output_asm_line_debug_info for test. Use output_dwarf_version. * dwarf2out.h (enum dw_val_class): Add dw_val_class_view_list. (struct dw_val_node): Add val_view_list. * final.c (SEEN_NEXT_VIEW): New. (set_next_view_needed): New. (clear_next_view_needed): New. (maybe_output_next_view): New. (final_start_function): Rename to... (final_start_function_1): ... this. Take pointer to FIRST, add SEEN parameter. Emit param bindings in the initial view. (final_start_function): Reintroduce SEEN-less interface. (final): Rename to... (final_1): ... this. Take SEEN parameter. Output final pending next view at the end. (final): Reintroduce seen-less interface. (final_scan_insn): Output pending next view before switching sections or ending a block. Mark the next view as needed when outputting variable locations. Notify debug backend of section changes, and of location view changes. (rest_of_handle_final): Adjust. * toplev.c (process_options): Autodetect value for debug variable location views option. Warn on incompat5 without -gdwarf-5. * doc/invoke.texi (gvariable-location-views): New. (gvariable-location-views=incompat5): New. (gno-variable-location-views): New. From-SVN: r257510 --- gcc/ChangeLog | 95 +++++++ gcc/common.opt | 7 + gcc/config.in | 6 + gcc/configure | 46 ++++ gcc/configure.ac | 18 +- gcc/doc/invoke.texi | 29 +++ gcc/dwarf2asm.c | 29 +++ gcc/dwarf2asm.h | 4 + gcc/dwarf2out.c | 700 +++++++++++++++++++++++++++++++++++++++++++++++----- gcc/dwarf2out.h | 4 +- gcc/final.c | 149 ++++++++++- gcc/toplev.c | 16 ++ 12 files changed, 1022 insertions(+), 81 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8212952..1d9c9729 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,98 @@ +2018-02-09 Alexandre Oliva + + * common.opt (gvariable-location-views): New. + (gvariable-location-views=incompat5): New. + * config.in: Rebuilt. + * configure: Rebuilt. + * configure.ac: Test assembler for view support. + * dwarf2asm.c (dw2_asm_output_symname_uleb128): New. + * dwarf2asm.h (dw2_asm_output_symname_uleb128): Declare. + * dwarf2out.c (var_loc_view): New typedef. + (struct dw_loc_list_struct): Add vl_symbol, vbegin, vend. + (dwarf2out_locviews_in_attribute): New. + (dwarf2out_locviews_in_loclist): New. + (dw_val_equal_p): Compare val_view_list of dw_val_class_view_lists. + (enum dw_line_info_opcode): Add LI_adv_address. + (struct dw_line_info_table): Add view. + (RESET_NEXT_VIEW, RESETTING_VIEW_P): New macros. + (DWARF2_ASM_VIEW_DEBUG_INFO): Define default. + (zero_view_p): New variable. + (ZERO_VIEW_P): New macro. + (output_asm_line_debug_info): New. + (struct var_loc_node): Add view. + (add_AT_view_list, AT_loc_list): New. + (add_var_loc_to_decl): Add view param. Test it against last. + (new_loc_list): Add view params. Record them. + (AT_loc_list_ptr): Handle loc and view lists. + (view_list_to_loc_list_val_node): New. + (print_dw_val): Handle dw_val_class_view_list. + (size_of_die): Likewise. + (value_format): Likewise. + (loc_list_has_views): New. + (gen_llsym): Set vl_symbol too. + (maybe_gen_llsym, skip_loc_list_entry): New. + (dwarf2out_maybe_output_loclist_view_pair): New. + (output_loc_list): Output view list or entries too. + (output_view_list_offset): New. + (output_die): Handle dw_val_class_view_list. + (output_dwarf_version): New. + (output_compilation_unit_header): Use it. + (output_skeleton_debug_sections): Likewise. + (output_rnglists, output_line_info): Likewise. + (output_pubnames, output_aranges): Update version comments. + (output_one_line_info_table): Output view numbers in asm comments. + (dw_loc_list): Determine current endview, pass it to new_loc_list. + Call maybe_gen_llsym. + (loc_list_from_tree_1): Adjust. + (add_AT_location_description): Create view list attribute if + needed, check it's absent otherwise. + (convert_cfa_to_fb_loc_list): Adjust. + (maybe_emit_file): Call output_asm_line_debug_info for test. + (dwarf2out_var_location): Reset views as needed. Precompute + add_var_loc_to_decl args. Call get_attr_min_length only if we have the + attribute. Set view. + (new_line_info_table): Reset next view. + (set_cur_line_info_table): Call output_asm_line_debug_info for test. + (dwarf2out_source_line): Likewise. Output view resets and labels to + the assembler, or select appropriate line info opcodes. + (prune_unused_types_walk_attribs): Handle dw_val_class_view_list. + (optimize_string_length): Catch it. Adjust. + (resolve_addr): Copy vl_symbol along with ll_symbol. Handle + dw_val_class_view_list, and remove it if no longer needed. + (hash_loc_list): Hash view numbers. + (loc_list_hasher::equal): Compare them. + (optimize_location_lists): Check whether a view list symbol is + needed, and whether the locview attribute is present, and + whether they match. Remove the locview attribute if no longer + needed. + (index_location_lists): Call skip_loc_list_entry for test. + (dwarf2out_finish): Call output_asm_line_debug_info for test. + Use output_dwarf_version. + * dwarf2out.h (enum dw_val_class): Add dw_val_class_view_list. + (struct dw_val_node): Add val_view_list. + * final.c (SEEN_NEXT_VIEW): New. + (set_next_view_needed): New. + (clear_next_view_needed): New. + (maybe_output_next_view): New. + (final_start_function): Rename to... + (final_start_function_1): ... this. Take pointer to FIRST, + add SEEN parameter. Emit param bindings in the initial view. + (final_start_function): Reintroduce SEEN-less interface. + (final): Rename to... + (final_1): ... this. Take SEEN parameter. Output final pending + next view at the end. + (final): Reintroduce seen-less interface. + (final_scan_insn): Output pending next view before switching + sections or ending a block. Mark the next view as needed when + outputting variable locations. Notify debug backend of section + changes, and of location view changes. + (rest_of_handle_final): Adjust. + * toplev.c (process_options): Autodetect value for debug variable + location views option. Warn on incompat5 without -gdwarf-5. + * doc/invoke.texi (gvariable-location-views): New. + (gvariable-location-views=incompat5): New. + (gno-variable-location-views): New. + 2018-02-08 David Malcolm PR tree-optimization/84136 diff --git a/gcc/common.opt b/gcc/common.opt index 3e9e310..40ec008 100644 --- a/gcc/common.opt +++ b/gcc/common.opt @@ -2956,6 +2956,13 @@ gtoggle Common Driver Report Var(flag_gtoggle) Toggle debug information generation. +gvariable-location-views +Common Driver Var(debug_variable_location_views, 1) Init(2) +Augment variable location lists with progressive views. + +gvariable-location-views=incompat5 +Common Driver RejectNegative Var(debug_variable_location_views, -1) Init(2) + gvms Common Driver JoinedOrMissing Negative(gxcoff) Generate debug information in VMS format. diff --git a/gcc/config.in b/gcc/config.in index 8dc4531..5bccb40 100644 --- a/gcc/config.in +++ b/gcc/config.in @@ -358,6 +358,12 @@ #endif +/* Define if your assembler supports views in dwarf2 .loc directives. */ +#ifndef USED_FOR_TARGET +#undef HAVE_AS_DWARF2_DEBUG_VIEW +#endif + + /* Define if your assembler supports the R_PPC64_ENTRY relocation. */ #ifndef USED_FOR_TARGET #undef HAVE_AS_ENTRY_MARKERS diff --git a/gcc/configure b/gcc/configure index 3360209..b126287 100755 --- a/gcc/configure +++ b/gcc/configure @@ -27825,6 +27825,52 @@ $as_echo "$gcc_cv_as_dwarf2_file_buggy" >&6; } $as_echo "#define HAVE_AS_DWARF2_DEBUG_LINE 1" >>confdefs.h + + if test $gcc_cv_as_leb128 = yes; then + conftest_s="\ + .file 1 \"conftest.s\" + .loc 1 3 0 view .LVU1 + $insn + .data + .uleb128 .LVU1 + .uleb128 .LVU1 +" + { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for dwarf2 debug_view support" >&5 +$as_echo_n "checking assembler for dwarf2 debug_view support... " >&6; } +if test "${gcc_cv_as_dwarf2_debug_view+set}" = set; then : + $as_echo_n "(cached) " >&6 +else + gcc_cv_as_dwarf2_debug_view=no + if test $in_tree_gas = yes; then + if test $in_tree_gas_is_elf = yes \ + && test $gcc_cv_gas_vers -ge `expr \( \( 2 \* 1000 \) + 27 \) \* 1000 + 0` + then gcc_cv_as_dwarf2_debug_view=yes +fi + elif test x$gcc_cv_as != x; then + $as_echo "$conftest_s" > conftest.s + if { ac_try='$gcc_cv_as $gcc_cv_as_flags -o conftest.o conftest.s >&5' + { { 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; }; } + then + gcc_cv_as_dwarf2_debug_view=yes + else + echo "configure: failed program was" >&5 + cat conftest.s >&5 + fi + rm -f conftest.o conftest.s + fi +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $gcc_cv_as_dwarf2_debug_view" >&5 +$as_echo "$gcc_cv_as_dwarf2_debug_view" >&6; } +if test $gcc_cv_as_dwarf2_debug_view = yes; then + +$as_echo "#define HAVE_AS_DWARF2_DEBUG_VIEW 1" >>confdefs.h + +fi + fi fi { $as_echo "$as_me:${as_lineno-$LINENO}: checking assembler for --gdwarf2 option" >&5 diff --git a/gcc/configure.ac b/gcc/configure.ac index 1019b31..140c804 100644 --- a/gcc/configure.ac +++ b/gcc/configure.ac @@ -4902,9 +4902,25 @@ if test x"$insn" != x; then if test $gcc_cv_as_dwarf2_debug_line = yes \ && test $gcc_cv_as_dwarf2_file_buggy = no; then - AC_DEFINE(HAVE_AS_DWARF2_DEBUG_LINE, 1, + AC_DEFINE(HAVE_AS_DWARF2_DEBUG_LINE, 1, [Define if your assembler supports dwarf2 .file/.loc directives, and preserves file table indices exactly as given.]) + + if test $gcc_cv_as_leb128 = yes; then + conftest_s="\ + .file 1 \"conftest.s\" + .loc 1 3 0 view .LVU1 + $insn + .data + .uleb128 .LVU1 + .uleb128 .LVU1 +" + gcc_GAS_CHECK_FEATURE([dwarf2 debug_view support], + gcc_cv_as_dwarf2_debug_view, + [elf,2,27,0],,[$conftest_s],, + [AC_DEFINE(HAVE_AS_DWARF2_DEBUG_VIEW, 1, + [Define if your assembler supports views in dwarf2 .loc directives.])]) + fi fi gcc_GAS_CHECK_FEATURE([--gdwarf2 option], diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 367b99b..df357be 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -348,6 +348,7 @@ Objective-C and Objective-C++ Dialects}. -gstabs -gstabs+ -gstrict-dwarf -gno-strict-dwarf @gol -gcolumn-info -gno-column-info @gol -gstatement-frontiers -gno-statement-frontiers @gol +-gvariable-location-views -gno-variable-location-views @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 @@ -7255,6 +7256,34 @@ markers in the line number table. This is enabled by default when 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 +@opindex gvariable-location-views +@opindex gvariable-location-views=incompat5 +@opindex gno-variable-location-views +Augment variable location lists with progressive view numbers implied +from the line number table. This enables debug information consumers to +inspect state at certain points of the program, even if no instructions +associated with the corresponding source locations are present at that +point. If the assembler lacks support for view numbers in line number +tables, this will cause the compiler to emit the line number table, +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. + +There is a proposed representation for view numbers that is not backward +compatible with the location list format introduced in DWARF 5, that can +be enabled with @option{-gvariable-location-views=incompat5}. This +option may be removed in the future, is only provided as a reference +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 -gz@r{[}=@var{type}@r{]} @opindex gz Produce compressed debug sections in DWARF format, if that is supported. diff --git a/gcc/dwarf2asm.c b/gcc/dwarf2asm.c index 9952e0a..e9b18b8 100644 --- a/gcc/dwarf2asm.c +++ b/gcc/dwarf2asm.c @@ -767,6 +767,35 @@ dw2_asm_output_data_sleb128 (HOST_WIDE_INT value, va_end (ap); } +/* Output symbol LAB1 as an unsigned LEB128 quantity. LAB1 should be + an assembler-computed constant, e.g. a view number, because we + can't have relocations in LEB128 quantities. */ + +void +dw2_asm_output_symname_uleb128 (const char *lab1 ATTRIBUTE_UNUSED, + const char *comment, ...) +{ + va_list ap; + + va_start (ap, comment); + +#ifdef HAVE_AS_LEB128 + fputs ("\t.uleb128 ", asm_out_file); + assemble_name (asm_out_file, lab1); +#else + gcc_unreachable (); +#endif + + if (flag_debug_asm && comment) + { + fprintf (asm_out_file, "\t%s ", ASM_COMMENT_START); + vfprintf (asm_out_file, comment, ap); + } + fputc ('\n', asm_out_file); + + va_end (ap); +} + void dw2_asm_output_delta_uleb128 (const char *lab1 ATTRIBUTE_UNUSED, const char *lab2 ATTRIBUTE_UNUSED, diff --git a/gcc/dwarf2asm.h b/gcc/dwarf2asm.h index b5ed449..1b76909 100644 --- a/gcc/dwarf2asm.h +++ b/gcc/dwarf2asm.h @@ -70,6 +70,10 @@ extern void dw2_asm_output_data_sleb128 (HOST_WIDE_INT, const char *, ...) ATTRIBUTE_NULL_PRINTF_2; +extern void dw2_asm_output_symname_uleb128 (const char *, + const char *, ...) + ATTRIBUTE_NULL_PRINTF_2; + extern void dw2_asm_output_delta_uleb128 (const char *, const char *, const char *, ...) ATTRIBUTE_NULL_PRINTF_3; diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 948b3cb..56d3e14 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -1291,6 +1291,8 @@ struct GTY((for_user)) addr_table_entry { GTY ((desc ("%1.kind"))) addr; }; +typedef unsigned int var_loc_view; + /* Location lists are ranges + location descriptions for that range, so you can track variables that are in different places over their entire life. */ @@ -1300,9 +1302,11 @@ typedef struct GTY(()) dw_loc_list_struct { addr_table_entry *begin_entry; const char *end; /* Label for end of range */ char *ll_symbol; /* Label for beginning of location list. - Only on head of list */ + Only on head of list. */ + char *vl_symbol; /* Label for beginning of view list. Ditto. */ const char *section; /* Section this loclist is relative to */ dw_loc_descr_ref expr; + var_loc_view vbegin, vend; hashval_t hash; /* True if all addresses in this and subsequent lists are known to be resolved. */ @@ -1339,6 +1343,29 @@ dwarf_stack_op_name (unsigned int op) return "OP_"; } +/* Return TRUE iff we're to output location view lists as a separate + attribute next to the location lists, as an extension compatible + with DWARF 2 and above. */ + +static inline bool +dwarf2out_locviews_in_attribute () +{ + return debug_variable_location_views == 1; +} + +/* Return TRUE iff we're to output location view lists as part of the + location lists, as proposed for standardization after DWARF 5. */ + +static inline bool +dwarf2out_locviews_in_loclist () +{ +#ifndef DW_LLE_view_pair + return false; +#else + return debug_variable_location_views == -1; +#endif +} + /* Return a pointer to a newly allocated location description. Location descriptions are simple expression terms that can be strung together to form more complicated location (address) descriptions. */ @@ -1401,6 +1428,8 @@ dw_val_equal_p (dw_val_node *a, dw_val_node *b) return a->v.val_loc == b->v.val_loc; case dw_val_class_loc_list: return a->v.val_loc_list == b->v.val_loc_list; + case dw_val_class_view_list: + return a->v.val_view_list == b->v.val_view_list; case dw_val_class_die_ref: return a->v.val_die_ref.die == b->v.val_die_ref.die; case dw_val_class_fde_ref: @@ -2875,7 +2904,15 @@ enum dw_line_info_opcode { LI_set_epilogue_begin, /* Emit a DW_LNE_set_discriminator. */ - LI_set_discriminator + LI_set_discriminator, + + /* Output a Fixed Advance PC; the target PC is the label index; the + base PC is the previous LI_adv_address or LI_set_address entry. + We only use this when emitting debug views without assembler + support, at explicit user request. Ideally, we should only use + it when the offset might be zero but we can't tell: it's the only + way to maybe change the PC without resetting the view number. */ + LI_adv_address }; typedef struct GTY(()) dw_line_info_struct { @@ -2897,6 +2934,25 @@ struct GTY(()) dw_line_info_table { bool is_stmt; bool in_use; + /* This denotes the NEXT view number. + + If it is 0, it is known that the NEXT view will be the first view + at the given PC. + + If it is -1, we've advanced PC but we haven't emitted a line location yet, + so we shouldn't use this view number. + + The meaning of other nonzero values depends on whether we're + computing views internally or leaving it for the assembler to do + so. If we're emitting them internally, view denotes the view + number since the last known advance of PC. If we're leaving it + for the assembler, it denotes the LVU label number that we're + going to ask the assembler to assign. */ + var_loc_view view; + +#define RESET_NEXT_VIEW(x) ((x) = (var_loc_view)0) +#define RESETTING_VIEW_P(x) ((x) == (var_loc_view)0) + vec *entries; }; @@ -3098,6 +3154,71 @@ skeleton_chain_node; #endif #endif +/* Use assembler views in line directives if available. */ +#ifndef DWARF2_ASM_VIEW_DEBUG_INFO +#ifdef HAVE_AS_DWARF2_DEBUG_VIEW +#define DWARF2_ASM_VIEW_DEBUG_INFO 1 +#else +#define DWARF2_ASM_VIEW_DEBUG_INFO 0 +#endif +#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 + zero. We won't allocate the bitmap if we're not using assembler + support for location views, but we have to make the variable + visible for GGC and for code that will be optimized out for lack of + support but that's still parsed and compiled. We could abstract it + out with macros, but it's not worth it. */ +static GTY(()) bitmap zero_view_p; + +/* Evaluate to TRUE iff N is known to identify the first location view + at its PC. When not using assembler location view computation, + that must be view number zero. Otherwise, ZERO_VIEW_P is allocated + and views label numbers recorded in it are the ones known to be + zero. */ +#define ZERO_VIEW_P(N) (zero_view_p \ + ? bitmap_bit_p (zero_view_p, (N)) \ + : (N) == 0) + +/* Return true iff we're to emit .loc directives for the assembler to + generate line number sections. + + When we're not emitting views, all we need from the assembler is + support for .loc directives. + + If we are emitting views, we can only use the assembler's .loc + support if it also supports views. + + When the compiler is emitting the line number programs and + computing view numbers itself, it resets view numbers at known PC + changes and counts from that, and then it emits view numbers as + literal constants in locviewlists. There are cases in which the + compiler is not sure about PC changes, e.g. when extra alignment is + requested for a label. In these cases, the compiler may not reset + the view counter, and the potential PC advance in the line number + program will use an opcode that does not reset the view counter + even if the PC actually changes, so that compiler and debug info + consumer can keep view numbers in sync. + + When the compiler defers view computation to the assembler, it + emits symbolic view numbers in locviewlists, with the exception of + views known to be zero (forced resets, or reset after + compiler-visible PC changes): instead of emitting symbols for + these, we emit literal zero and assert the assembler agrees with + the compiler's assessment. We could use symbolic views everywhere, + instead of special-casing zero views, but then we'd be unable to + optimize out locviewlists that contain only zeros. */ + +static bool +output_asm_line_debug_info (void) +{ + return (DWARF2_ASM_VIEW_DEBUG_INFO + || (DWARF2_ASM_LINE_DEBUG_INFO + && !debug_variable_location_views)); +} + /* Minimum line offset in a special line info. opcode. This value was chosen to give a reasonable range of values. */ #define DWARF_LINE_BASE -10 @@ -3207,6 +3328,7 @@ struct GTY ((chain_next ("%h.next"))) var_loc_node { rtx GTY (()) loc; const char * GTY (()) label; struct var_loc_node * GTY (()) next; + var_loc_view view; }; /* Variable location list. */ @@ -3415,6 +3537,8 @@ static inline dw_loc_descr_ref AT_loc (dw_attr_node *); static void add_AT_loc_list (dw_die_ref, enum dwarf_attribute, dw_loc_list_ref); static inline dw_loc_list_ref AT_loc_list (dw_attr_node *); +static void add_AT_view_list (dw_die_ref, enum dwarf_attribute); +static inline dw_loc_list_ref AT_loc_list (dw_attr_node *); static addr_table_entry *add_addr_table_entry (void *, enum ate_kind); static void remove_addr_table_entry (addr_table_entry *); static void add_AT_addr (dw_die_ref, enum dwarf_attribute, rtx, bool); @@ -3451,7 +3575,7 @@ static void equate_type_number_to_die (tree, dw_die_ref); static dw_die_ref lookup_decl_die (tree); static var_loc_list *lookup_decl_loc (const_tree); static void equate_decl_number_to_die (tree, dw_die_ref); -static struct var_loc_node *add_var_loc_to_decl (tree, rtx, const char *); +static struct var_loc_node *add_var_loc_to_decl (tree, rtx, const char *, var_loc_view); static void print_spaces (FILE *); static void print_die (dw_die_ref, FILE *); static void loc_checksum (dw_loc_descr_ref, struct md5_ctx *); @@ -3651,8 +3775,8 @@ static void gen_tagged_type_die (tree, dw_die_ref, enum debug_info_usage); static void gen_type_die_with_usage (tree, dw_die_ref, enum debug_info_usage); static void splice_child_die (dw_die_ref, dw_die_ref); static int file_info_cmp (const void *, const void *); -static dw_loc_list_ref new_loc_list (dw_loc_descr_ref, const char *, - const char *, const char *); +static dw_loc_list_ref new_loc_list (dw_loc_descr_ref, const char *, var_loc_view, + const char *, var_loc_view, const char *); static void output_loc_list (dw_loc_list_ref); static char *gen_internal_sym (const char *); static bool want_pubnames (void); @@ -4648,11 +4772,65 @@ AT_loc_list (dw_attr_node *a) return a->dw_attr_val.v.val_loc_list; } +/* Add a view list attribute to DIE. It must have a DW_AT_location + attribute, because the view list complements the location list. */ + +static inline void +add_AT_view_list (dw_die_ref die, enum dwarf_attribute attr_kind) +{ + dw_attr_node attr; + + if (XCOFF_DEBUGGING_INFO && !HAVE_XCOFF_DWARF_EXTRAS) + return; + + attr.dw_attr = attr_kind; + attr.dw_attr_val.val_class = dw_val_class_view_list; + attr.dw_attr_val.val_entry = NULL; + attr.dw_attr_val.v.val_view_list = die; + add_dwarf_attr (die, &attr); + gcc_checking_assert (get_AT (die, DW_AT_location)); + gcc_assert (have_location_lists); +} + +/* Return a pointer to the location list referenced by the attribute. + If the named attribute is a view list, look up the corresponding + DW_AT_location attribute and return its location list. */ + static inline dw_loc_list_ref * AT_loc_list_ptr (dw_attr_node *a) { - gcc_assert (a && AT_class (a) == dw_val_class_loc_list); - return &a->dw_attr_val.v.val_loc_list; + gcc_assert (a); + switch (AT_class (a)) + { + case dw_val_class_loc_list: + return &a->dw_attr_val.v.val_loc_list; + case dw_val_class_view_list: + { + dw_attr_node *l; + l = get_AT (a->dw_attr_val.v.val_view_list, DW_AT_location); + if (!l) + return NULL; + gcc_checking_assert (l + 1 == a); + return AT_loc_list_ptr (l); + } + default: + gcc_unreachable (); + } +} + +/* Return the location attribute value associated with a view list + attribute value. */ + +static inline dw_val_node * +view_list_to_loc_list_val_node (dw_val_node *val) +{ + gcc_assert (val->val_class == dw_val_class_view_list); + dw_attr_node *loc = get_AT (val->v.val_view_list, DW_AT_location); + if (!loc) + return NULL; + gcc_checking_assert (&(loc + 1)->dw_attr_val == val); + gcc_assert (AT_class (loc) == dw_val_class_loc_list); + return &loc->dw_attr_val; } struct addr_hasher : ggc_ptr_hash @@ -5907,7 +6085,7 @@ adjust_piece_list (rtx *dest, rtx *src, rtx *inner, /* Add a variable location node to the linked list for DECL. */ static struct var_loc_node * -add_var_loc_to_decl (tree decl, rtx loc_note, const char *label) +add_var_loc_to_decl (tree decl, rtx loc_note, const char *label, var_loc_view view) { unsigned int decl_id; var_loc_list *temp; @@ -5996,7 +6174,7 @@ add_var_loc_to_decl (tree decl, rtx loc_note, const char *label) /* TEMP->LAST here is either pointer to the last but one or last element in the chained list, LAST is pointer to the last element. */ - if (label && strcmp (last->label, label) == 0) + if (label && strcmp (last->label, label) == 0 && last->view == view) { /* For SRA optimized variables if there weren't any real insns since last note, just modify the last node. */ @@ -6012,7 +6190,7 @@ add_var_loc_to_decl (tree decl, rtx loc_note, const char *label) temp->last->next = NULL; unused = last; last = temp->last; - gcc_assert (strcmp (last->label, label) != 0); + gcc_assert (strcmp (last->label, label) != 0 || last->view != view); } else { @@ -6147,6 +6325,12 @@ print_dw_val (dw_val_node *val, bool recurse, FILE *outfile) fprintf (outfile, "location list -> label:%s", val->v.val_loc_list->ll_symbol); break; + case dw_val_class_view_list: + val = view_list_to_loc_list_val_node (val); + fprintf (outfile, "location list with views -> labels:%s and %s", + val->v.val_loc_list->ll_symbol, + val->v.val_loc_list->vl_symbol); + break; case dw_val_class_range_list: fprintf (outfile, "range list"); break; @@ -9007,6 +9191,7 @@ size_of_die (dw_die_ref die) } break; case dw_val_class_loc_list: + case dw_val_class_view_list: if (dwarf_split_debug_info && dwarf_version >= 5) { gcc_assert (AT_loc_list (a)->num_assigned); @@ -9378,6 +9563,7 @@ value_format (dw_attr_node *a) gcc_unreachable (); } case dw_val_class_loc_list: + case dw_val_class_view_list: if (dwarf_split_debug_info && dwarf_version >= 5 && AT_loc_list (a)->num_assigned) @@ -9652,7 +9838,8 @@ output_abbrev_section (void) expression. */ static inline dw_loc_list_ref -new_loc_list (dw_loc_descr_ref expr, const char *begin, const char *end, +new_loc_list (dw_loc_descr_ref expr, const char *begin, var_loc_view vbegin, + const char *end, var_loc_view vend, const char *section) { dw_loc_list_ref retlist = ggc_cleared_alloc (); @@ -9662,10 +9849,28 @@ new_loc_list (dw_loc_descr_ref expr, const char *begin, const char *end, retlist->end = end; retlist->expr = expr; retlist->section = section; + retlist->vbegin = vbegin; + retlist->vend = vend; return retlist; } +/* Return true iff there's any nonzero view number in the loc list. */ + +static bool +loc_list_has_views (dw_loc_list_ref list) +{ + if (!debug_variable_location_views) + return false; + + for (dw_loc_list_ref loc = list; + loc != NULL; loc = loc->dw_loc_next) + if (!ZERO_VIEW_P (loc->vbegin) || !ZERO_VIEW_P (loc->vend)) + return true; + + return false; +} + /* Generate a new internal symbol for this location list node, if it hasn't got one yet. */ @@ -9674,6 +9879,98 @@ gen_llsym (dw_loc_list_ref list) { gcc_assert (!list->ll_symbol); list->ll_symbol = gen_internal_sym ("LLST"); + + if (!loc_list_has_views (list)) + return; + + if (dwarf2out_locviews_in_attribute ()) + { + /* Use the same label_num for the view list. */ + label_num--; + list->vl_symbol = gen_internal_sym ("LVUS"); + } + else + list->vl_symbol = list->ll_symbol; +} + +/* Generate a symbol for the list, but only if we really want to emit + it as a list. */ + +static inline void +maybe_gen_llsym (dw_loc_list_ref list) +{ + if (!list || (!list->dw_loc_next && !loc_list_has_views (list))) + return; + + gen_llsym (list); +} + +/* Determine whether or not to skip loc_list entry CURR. If we're not + to skip it, and SIZEP is non-null, store the size of CURR->expr's + representation in *SIZEP. */ + +static bool +skip_loc_list_entry (dw_loc_list_ref curr, unsigned long *sizep = 0) +{ + /* Don't output an entry that starts and ends at the same address. */ + if (strcmp (curr->begin, curr->end) == 0 + && curr->vbegin == curr->vend && !curr->force) + return true; + + unsigned long size = size_of_locs (curr->expr); + + /* If the expression is too large, drop it on the floor. We could + perhaps put it into DW_TAG_dwarf_procedure and refer to that + in the expression, but >= 64KB expressions for a single value + in a single range are unlikely very useful. */ + if (dwarf_version < 5 && size > 0xffff) + return true; + + if (sizep) + *sizep = size; + + return false; +} + +/* Output a view pair loclist entry for CURR, if it requires one. */ + +static void +dwarf2out_maybe_output_loclist_view_pair (dw_loc_list_ref curr) +{ + if (!dwarf2out_locviews_in_loclist ()) + return; + + if (ZERO_VIEW_P (curr->vbegin) && ZERO_VIEW_P (curr->vend)) + return; + +#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 + { + 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"); + 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 /* !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; } /* Output the location list given to us. */ @@ -9681,34 +9978,85 @@ gen_llsym (dw_loc_list_ref list) static void output_loc_list (dw_loc_list_ref list_head) { + int vcount = 0, lcount = 0; + if (list_head->emitted) return; list_head->emitted = true; + if (list_head->vl_symbol && dwarf2out_locviews_in_attribute ()) + { + ASM_OUTPUT_LABEL (asm_out_file, list_head->vl_symbol); + + for (dw_loc_list_ref curr = list_head; curr != NULL; + curr = curr->dw_loc_next) + { + if (skip_loc_list_entry (curr)) + continue; + + vcount++; + + /* ?? dwarf_split_debug_info? */ +#if DWARF2_ASM_VIEW_DEBUG_INFO + 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 /* !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 + } + } + ASM_OUTPUT_LABEL (asm_out_file, list_head->ll_symbol); - dw_loc_list_ref curr = list_head; const char *last_section = NULL; const char *base_label = NULL; /* Walk the location list, and output each range + expression. */ - for (curr = list_head; curr != NULL; curr = curr->dw_loc_next) + for (dw_loc_list_ref curr = list_head; curr != NULL; + curr = curr->dw_loc_next) { unsigned long size; - /* Don't output an entry that starts and ends at the same address. */ - if (strcmp (curr->begin, curr->end) == 0 && !curr->force) - continue; - size = size_of_locs (curr->expr); - /* If the expression is too large, drop it on the floor. We could - perhaps put it into DW_TAG_dwarf_procedure and refer to that - in the expression, but >= 64KB expressions for a single value - in a single range are unlikely very useful. */ - if (dwarf_version < 5 && size > 0xffff) + + /* Skip this entry? If we skip it here, we must skip it in the + view list above as well. */ + if (skip_loc_list_entry (curr, &size)) continue; + + lcount++; + if (dwarf_version >= 5) { if (dwarf_split_debug_info) { + dwarf2out_maybe_output_loclist_view_pair (curr); /* For -gsplit-dwarf, emit DW_LLE_starx_length, which has uleb128 index into .debug_addr and uleb128 length. */ dw2_asm_output_data (1, DW_LLE_startx_length, @@ -9726,6 +10074,7 @@ output_loc_list (dw_loc_list_ref list_head) } else if (!have_multiple_function_sections && HAVE_AS_LEB128) { + dwarf2out_maybe_output_loclist_view_pair (curr); /* If all code is in .text section, the base address is already provided by the CU attributes. Use DW_LLE_offset_pair where both addresses are uleb128 encoded @@ -9776,6 +10125,7 @@ output_loc_list (dw_loc_list_ref list_head) length. */ if (last_section == NULL) { + dwarf2out_maybe_output_loclist_view_pair (curr); dw2_asm_output_data (1, DW_LLE_start_length, "DW_LLE_start_length (%s)", list_head->ll_symbol); @@ -9790,6 +10140,7 @@ output_loc_list (dw_loc_list_ref list_head) DW_LLE_base_address. */ else { + dwarf2out_maybe_output_loclist_view_pair (curr); dw2_asm_output_data (1, DW_LLE_offset_pair, "DW_LLE_offset_pair (%s)", list_head->ll_symbol); @@ -9805,6 +10156,7 @@ output_loc_list (dw_loc_list_ref list_head) DW_LLE_start_end with a pair of absolute addresses. */ else { + dwarf2out_maybe_output_loclist_view_pair (curr); dw2_asm_output_data (1, DW_LLE_start_end, "DW_LLE_start_end (%s)", list_head->ll_symbol); @@ -9883,6 +10235,9 @@ output_loc_list (dw_loc_list_ref list_head) "Location list terminator end (%s)", list_head->ll_symbol); } + + gcc_assert (!list_head->vl_symbol + || vcount == lcount * (dwarf2out_locviews_in_attribute () ? 1 : 0)); } /* Output a range_list offset into the .debug_ranges or .debug_rnglists @@ -9947,6 +10302,22 @@ output_loc_list_offset (dw_attr_node *a) "%s", dwarf_attr_name (a->dw_attr)); } +/* Output the offset into the debug_loc section. */ + +static void +output_view_list_offset (dw_attr_node *a) +{ + char *sym = (*AT_loc_list_ptr (a))->vl_symbol; + + gcc_assert (sym); + if (dwarf_split_debug_info) + dw2_asm_output_delta (DWARF_OFFSET_SIZE, sym, loc_section_label, + "%s", dwarf_attr_name (a->dw_attr)); + else + dw2_asm_output_offset (DWARF_OFFSET_SIZE, sym, debug_loc_section, + "%s", dwarf_attr_name (a->dw_attr)); +} + /* Output an attribute's index or value appropriately. */ static void @@ -10172,6 +10543,10 @@ output_die (dw_die_ref die) output_loc_list_offset (a); break; + case dw_val_class_view_list: + output_view_list_offset (a); + break; + case dw_val_class_die_ref: if (AT_ref_external (a)) { @@ -10356,6 +10731,28 @@ output_die (dw_die_ref die) (unsigned long) die->die_offset); } +/* Output the dwarf version number. */ + +static void +output_dwarf_version () +{ + /* ??? For now, if -gdwarf-6 is specified, we output version 5 with + views in loclist. That will change eventually. */ + if (dwarf_version == 6) + { + static bool once; + if (!once) + { + warning (0, + "-gdwarf-6 is output as version 5 with incompatibilities"); + once = true; + } + dw2_asm_output_data (2, 5, "DWARF version number"); + } + else + dw2_asm_output_data (2, dwarf_version, "DWARF version number"); +} + /* Output the compilation unit that appears at the beginning of the .debug_info section, and precedes the DIE descriptions. */ @@ -10372,7 +10769,7 @@ output_compilation_unit_header (enum dwarf_unit_type ut) "Length of Compilation Unit Info"); } - dw2_asm_output_data (2, dwarf_version, "DWARF version number"); + output_dwarf_version (); if (dwarf_version >= 5) { const char *name; @@ -10584,7 +10981,7 @@ output_skeleton_debug_sections (dw_die_ref comp_unit, - DWARF_INITIAL_LENGTH_SIZE + size_of_die (comp_unit), "Length of Compilation Unit Info"); - dw2_asm_output_data (2, dwarf_version, "DWARF version number"); + output_dwarf_version (); if (dwarf_version >= 5) { dw2_asm_output_data (1, DW_UT_skeleton, "DW_UT_skeleton"); @@ -10883,7 +11280,7 @@ output_pubnames (vec *names) } /* Version number for pubnames/pubtypes is independent of dwarf version. */ - dw2_asm_output_data (2, 2, "DWARF Version"); + dw2_asm_output_data (2, 2, "DWARF pubnames/pubtypes version"); if (dwarf_split_debug_info) dw2_asm_output_offset (DWARF_OFFSET_SIZE, debug_skeleton_info_section_label, @@ -10965,7 +11362,7 @@ output_aranges (void) } /* Version number for aranges is still 2, even up to DWARF5. */ - dw2_asm_output_data (2, 2, "DWARF Version"); + dw2_asm_output_data (2, 2, "DWARF aranges version"); if (dwarf_split_debug_info) dw2_asm_output_offset (DWARF_OFFSET_SIZE, debug_skeleton_info_section_label, debug_skeleton_info_section, @@ -11230,7 +11627,7 @@ output_rnglists (unsigned generation) dw2_asm_output_delta (DWARF_OFFSET_SIZE, l2, l1, "Length of Range Lists"); ASM_OUTPUT_LABEL (asm_out_file, l1); - dw2_asm_output_data (2, dwarf_version, "DWARF Version"); + output_dwarf_version (); dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Address Size"); dw2_asm_output_data (1, 0, "Segment Size"); /* Emit the offset table only for -gsplit-dwarf. If we don't care @@ -11864,8 +12261,11 @@ output_one_line_info_table (dw_line_info_table *table) char line_label[MAX_ARTIFICIAL_LABEL_BYTES]; unsigned int current_line = 1; bool current_is_stmt = DWARF_LINE_DEFAULT_IS_STMT_START; - dw_line_info_entry *ent; + dw_line_info_entry *ent, *prev_addr; size_t i; + unsigned int view; + + view = 0; FOR_EACH_VEC_SAFE_ELT (table->entries, i, ent) { @@ -11880,14 +12280,36 @@ output_one_line_info_table (dw_line_info_table *table) to determine when it is safe to use DW_LNS_fixed_advance_pc. */ ASM_GENERATE_INTERNAL_LABEL (line_label, LINE_CODE_LABEL, ent->val); + view = 0; + /* This can handle any delta. This takes 4+DWARF2_ADDR_SIZE bytes. */ - dw2_asm_output_data (1, 0, "set address %s", line_label); + dw2_asm_output_data (1, 0, "set address %s%s", line_label, + debug_variable_location_views + ? ", reset view to 0" : ""); dw2_asm_output_data_uleb128 (1 + DWARF2_ADDR_SIZE, NULL); dw2_asm_output_data (1, DW_LNE_set_address, NULL); dw2_asm_output_addr (DWARF2_ADDR_SIZE, line_label, NULL); + + prev_addr = ent; break; + case LI_adv_address: + { + ASM_GENERATE_INTERNAL_LABEL (line_label, LINE_CODE_LABEL, ent->val); + char prev_label[MAX_ARTIFICIAL_LABEL_BYTES]; + ASM_GENERATE_INTERNAL_LABEL (prev_label, LINE_CODE_LABEL, prev_addr->val); + + view++; + + dw2_asm_output_data (1, DW_LNS_fixed_advance_pc, "fixed advance PC, increment view to %i", view); + dw2_asm_output_delta (2, line_label, prev_label, + "from %s to %s", prev_label, line_label); + + prev_addr = ent; + break; + } + case LI_set_line: if (ent->val == current_line) { @@ -11995,7 +12417,7 @@ output_line_info (bool prologue_only) ASM_OUTPUT_LABEL (asm_out_file, l1); - dw2_asm_output_data (2, dwarf_version, "DWARF Version"); + output_dwarf_version (); if (dwarf_version >= 5) { dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Address Size"); @@ -16453,6 +16875,7 @@ static dw_loc_list_ref dw_loc_list (var_loc_list *loc_list, tree decl, int want_address) { const char *endname, *secname; + var_loc_view endview; rtx varloc; enum var_init_status initialized; struct var_loc_node *node; @@ -16517,24 +16940,27 @@ dw_loc_list (var_loc_list *loc_list, tree decl, int want_address) && current_function_decl) { endname = cfun->fde->dw_fde_end; + endview = 0; range_across_switch = true; } /* The variable has a location between NODE->LABEL and NODE->NEXT->LABEL. */ else if (node->next) - endname = node->next->label; + endname = node->next->label, endview = node->next->view; /* If the variable has a location at the last label it keeps its location until the end of function. */ else if (!current_function_decl) - endname = text_end_label; + endname = text_end_label, endview = 0; else { ASM_GENERATE_INTERNAL_LABEL (label_id, FUNC_END_LABEL, current_function_funcdef_no); endname = ggc_strdup (label_id); + endview = 0; } - *listp = new_loc_list (descr, node->label, endname, secname); + *listp = new_loc_list (descr, node->label, node->view, + endname, endview, secname); if (TREE_CODE (decl) == PARM_DECL && node == loc_list->first && NOTE_P (node->loc) @@ -16569,11 +16995,11 @@ dw_loc_list (var_loc_list *loc_list, tree decl, int want_address) /* The variable has a location between NODE->LABEL and NODE->NEXT->LABEL. */ if (node->next) - endname = node->next->label; + endname = node->next->label, endview = node->next->view; else - endname = cfun->fde->dw_fde_second_end; - *listp = new_loc_list (descr, cfun->fde->dw_fde_second_begin, - endname, secname); + endname = cfun->fde->dw_fde_second_end, endview = 0; + *listp = new_loc_list (descr, cfun->fde->dw_fde_second_begin, 0, + endname, endview, secname); listp = &(*listp)->dw_loc_next; } } @@ -16584,8 +17010,7 @@ dw_loc_list (var_loc_list *loc_list, tree decl, int want_address) representable, we don't want to pretend a single entry that was applies to the entire scope in which the variable is available. */ - if (list && loc_list->first->next) - gen_llsym (list); + maybe_gen_llsym (list); return list; } @@ -17404,7 +17829,7 @@ loc_list_from_tree_1 (tree loc, int want_address, { if (dwarf_version >= 3 || !dwarf_strict) return new_loc_list (new_loc_descr (DW_OP_push_object_address, 0, 0), - NULL, NULL, NULL); + NULL, 0, NULL, 0, NULL); else return NULL; } @@ -18220,7 +18645,7 @@ loc_list_from_tree_1 (tree loc, int want_address, add_loc_descr_to_each (list_ret, new_loc_descr (op, size, 0)); } if (ret) - list_ret = new_loc_list (ret, NULL, NULL, NULL); + list_ret = new_loc_list (ret, NULL, 0, NULL, 0, NULL); return list_ret; } @@ -18544,12 +18969,25 @@ static inline void add_AT_location_description (dw_die_ref die, enum dwarf_attribute attr_kind, dw_loc_list_ref descr) { + bool check_no_locviews = true; if (descr == 0) return; if (single_element_loc_list_p (descr)) add_AT_loc (die, attr_kind, descr->expr); else - add_AT_loc_list (die, attr_kind, descr); + { + add_AT_loc_list (die, attr_kind, descr); + gcc_assert (descr->ll_symbol); + if (attr_kind == DW_AT_location && descr->vl_symbol + && dwarf2out_locviews_in_attribute ()) + { + add_AT_view_list (die, DW_AT_GNU_locviews); + check_no_locviews = false; + } + } + + if (check_no_locviews) + gcc_assert (!get_AT (die, DW_AT_GNU_locviews)); } /* Add DW_AT_accessibility attribute to DIE if needed. */ @@ -19738,7 +20176,7 @@ convert_cfa_to_fb_loc_list (HOST_WIDE_INT offset) /* If the first partition contained no CFI adjustments, the CIE opcodes apply to the whole first partition. */ *list_tail = new_loc_list (build_cfa_loc (&last_cfa, offset), - fde->dw_fde_begin, fde->dw_fde_end, section); + fde->dw_fde_begin, 0, fde->dw_fde_end, 0, section); list_tail =&(*list_tail)->dw_loc_next; start_label = last_label = fde->dw_fde_second_begin; } @@ -19754,7 +20192,7 @@ convert_cfa_to_fb_loc_list (HOST_WIDE_INT offset) if (!cfa_equal_p (&last_cfa, &next_cfa)) { *list_tail = new_loc_list (build_cfa_loc (&last_cfa, offset), - start_label, last_label, section); + start_label, 0, last_label, 0, section); list_tail = &(*list_tail)->dw_loc_next; last_cfa = next_cfa; @@ -19776,14 +20214,14 @@ convert_cfa_to_fb_loc_list (HOST_WIDE_INT offset) if (!cfa_equal_p (&last_cfa, &next_cfa)) { *list_tail = new_loc_list (build_cfa_loc (&last_cfa, offset), - start_label, last_label, section); + start_label, 0, last_label, 0, section); list_tail = &(*list_tail)->dw_loc_next; last_cfa = next_cfa; start_label = last_label; } *list_tail = new_loc_list (build_cfa_loc (&last_cfa, offset), - start_label, fde->dw_fde_end, section); + start_label, 0, fde->dw_fde_end, 0, section); list_tail = &(*list_tail)->dw_loc_next; start_label = last_label = fde->dw_fde_second_begin; } @@ -19792,19 +20230,18 @@ convert_cfa_to_fb_loc_list (HOST_WIDE_INT offset) if (!cfa_equal_p (&last_cfa, &next_cfa)) { *list_tail = new_loc_list (build_cfa_loc (&last_cfa, offset), - start_label, last_label, section); + start_label, 0, last_label, 0, section); list_tail = &(*list_tail)->dw_loc_next; start_label = last_label; } *list_tail = new_loc_list (build_cfa_loc (&next_cfa, offset), - start_label, + start_label, 0, fde->dw_fde_second_begin - ? fde->dw_fde_second_end : fde->dw_fde_end, + ? fde->dw_fde_second_end : fde->dw_fde_end, 0, section); - if (list && list->dw_loc_next) - gen_llsym (list); + maybe_gen_llsym (list); return list; } @@ -26164,7 +26601,7 @@ maybe_emit_file (struct dwarf_file_data * fd) fd->emitted_number = 1; last_emitted_file = fd; - if (DWARF2_ASM_LINE_DEBUG_INFO) + if (output_asm_line_debug_info ()) { fprintf (asm_out_file, "\t.file %u ", fd->emitted_number); output_quoted_string (asm_out_file, @@ -26358,11 +26795,13 @@ dwarf2out_var_location (rtx_insn *loc_note) static rtx_insn *expected_next_loc_note; tree decl; bool var_loc_p; + var_loc_view view = 0; if (!NOTE_P (loc_note)) { if (CALL_P (loc_note)) { + RESET_NEXT_VIEW (cur_line_info_table->view); call_site_count++; if (SIBLING_CALL_P (loc_note)) tail_call_site_count++; @@ -26396,6 +26835,18 @@ 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); + return; } @@ -26459,10 +26910,11 @@ create_label: if (var_loc_p) { + const char *label + = NOTE_DURING_CALL_P (loc_note) ? last_postcall_label : last_label; + view = cur_line_info_table->view; decl = NOTE_VAR_LOCATION_DECL (loc_note); - newloc = add_var_loc_to_decl (decl, loc_note, - NOTE_DURING_CALL_P (loc_note) - ? last_postcall_label : last_label); + newloc = add_var_loc_to_decl (decl, loc_note, label, view); if (newloc == NULL) return; } @@ -26503,8 +26955,8 @@ create_label: else if (GET_CODE (body) == ASM_INPUT || asm_noperands (body) >= 0) continue; -#ifdef HAVE_attr_length - else if (get_attr_min_length (insn) == 0) +#ifdef HAVE_ATTR_length /* ??? We don't include insn-attr.h. */ + else if (HAVE_ATTR_length && get_attr_min_length (insn) == 0) continue; #endif else @@ -26572,7 +27024,10 @@ create_label: call_arg_loc_last = ca_loc; } else if (loc_note != NULL_RTX && !NOTE_DURING_CALL_P (loc_note)) - newloc->label = last_label; + { + newloc->label = last_label; + newloc->view = view; + } else { if (!last_postcall_label) @@ -26581,6 +27036,7 @@ create_label: last_postcall_label = ggc_strdup (loclabel); } newloc->label = last_postcall_label; + newloc->view = view; } if (var_loc_p && flag_debug_asm) @@ -26652,6 +27108,7 @@ new_line_info_table (void) table->file_num = 1; table->line_num = 1; table->is_stmt = DWARF_LINE_DEFAULT_IS_STMT_START; + RESET_NEXT_VIEW (table->view); return table; } @@ -26700,7 +27157,7 @@ set_cur_line_info_table (section *sec) vec_safe_push (separate_line_info, table); } - if (DWARF2_ASM_LINE_DEBUG_INFO) + if (output_asm_line_debug_info ()) table->is_stmt = (cur_line_info_table ? cur_line_info_table->is_stmt : DWARF_LINE_DEFAULT_IS_STMT_START); @@ -26881,7 +27338,7 @@ dwarf2out_source_line (unsigned int line, unsigned int column, filename, line); } - if (DWARF2_ASM_LINE_DEBUG_INFO) + if (output_asm_line_debug_info ()) { /* Emit the .loc directive understood by GNU as. */ /* "\t.loc %u %u 0 is_stmt %u discriminator %u", @@ -26904,6 +27361,50 @@ dwarf2out_source_line (unsigned int line, unsigned int column, fputs (" discriminator ", asm_out_file); fprint_ul (asm_out_file, (unsigned long) discriminator); } + if (debug_variable_location_views) + { + static var_loc_view lvugid; + if (!lvugid) + { + gcc_assert (!zero_view_p); + zero_view_p = BITMAP_GGC_ALLOC (); + bitmap_set_bit (zero_view_p, 0); + } + if (!RESETTING_VIEW_P (table->view)) + { + /* When we're using the assembler to compute view + numbers, we output symbolic labels after "view" in + .loc directives, and the assembler will set them for + us, so that we can refer to the view numbers in + location lists. The only exceptions are when we know + a view will be zero: "-0" is a forced reset, used + e.g. in the beginning of functions, whereas "0" tells + the assembler to check that there was a PC change + since the previous view, in a way that implicitly + resets the next view. */ + fputs (" view ", asm_out_file); + char label[MAX_ARTIFICIAL_LABEL_BYTES]; + ASM_GENERATE_INTERNAL_LABEL (label, "LVU", table->view); + assemble_name (asm_out_file, label); + table->view = ++lvugid; + } + else + { + if (!table->in_use) + fputs (" view -0", asm_out_file); + else + fputs (" view 0", asm_out_file); + /* Mark the present view as a zero view. Earlier debug + binds may have already added its id to loclists to be + emitted later, so we can't reuse the id for something + else. However, it's good to know whether a view is + known to be zero, because then we may be able to + optimize out locviews that are all zeros, so take + note of it in zero_view_p. */ + bitmap_set_bit (zero_view_p, lvugid); + table->view = ++lvugid; + } + } putc ('\n', asm_out_file); } else @@ -26912,7 +27413,19 @@ dwarf2out_source_line (unsigned int line, unsigned int column, targetm.asm_out.internal_label (asm_out_file, LINE_CODE_LABEL, label_num); - push_dw_line_info_entry (table, LI_set_address, label_num); + if (debug_variable_location_views && table->view) + push_dw_line_info_entry (table, LI_adv_address, label_num); + else + push_dw_line_info_entry (table, LI_set_address, label_num); + if (debug_variable_location_views) + { + if (flag_debug_asm) + fprintf (asm_out_file, "\t%s view %s%d\n", + ASM_COMMENT_START, + table->in_use ? "" : "-", + table->view); + table->view++; + } if (file_num != table->file_num) push_dw_line_info_entry (table, LI_set_file, file_num); if (discriminator != table->discrim_num) @@ -27588,9 +28101,10 @@ init_sections_and_labels (bool early_lto_debug) SECTION_DEBUG, NULL); debug_str_section = get_section (DEBUG_STR_SECTION, DEBUG_STR_SECTION_FLAGS, NULL); - if (!dwarf_split_debug_info && !DWARF2_ASM_LINE_DEBUG_INFO) + if (!dwarf_split_debug_info && !output_asm_line_debug_info ()) debug_line_str_section = get_section (DEBUG_LINE_STR_SECTION, DEBUG_STR_SECTION_FLAGS, NULL); + debug_ranges_section = get_section (dwarf_version >= 5 ? DEBUG_RNGLISTS_SECTION : DEBUG_RANGES_SECTION, @@ -27976,6 +28490,11 @@ prune_unused_types_walk_attribs (dw_die_ref die) prune_unused_types_walk_loc_descr (list->expr); break; + case dw_val_class_view_list: + /* This points to a loc_list in another attribute, so it's + already covered. */ + break; + case dw_val_class_die_ref: /* A reference to another DIE. Make sure that it will get emitted. @@ -29075,6 +29594,8 @@ optimize_string_length (dw_attr_node *a) if (d->expr && non_dwarf_expression (d->expr)) non_dwarf_expr = true; break; + case dw_val_class_view_list: + gcc_unreachable (); case dw_val_class_loc: lv = AT_loc (av); if (lv == NULL) @@ -29119,7 +29640,7 @@ optimize_string_length (dw_attr_node *a) lv = copy_deref_exprloc (d->expr); if (lv) { - *p = new_loc_list (lv, d->begin, d->end, d->section); + *p = new_loc_list (lv, d->begin, d->vbegin, d->end, d->vend, d->section); p = &(*p)->dw_loc_next; } else if (!dwarf_strict && d->expr) @@ -29189,6 +29710,7 @@ resolve_addr (dw_die_ref die) { gcc_assert (!next->ll_symbol); next->ll_symbol = (*curr)->ll_symbol; + next->vl_symbol = (*curr)->vl_symbol; } if (dwarf_split_debug_info) remove_loc_list_addr_table_entries (l); @@ -29214,6 +29736,21 @@ resolve_addr (dw_die_ref die) ix--; } break; + case dw_val_class_view_list: + { + gcc_checking_assert (a->dw_attr == DW_AT_GNU_locviews); + gcc_checking_assert (dwarf2out_locviews_in_attribute ()); + dw_val_node *llnode + = view_list_to_loc_list_val_node (&a->dw_attr_val); + /* If we no longer have a loclist, or it no longer needs + views, drop this attribute. */ + if (!llnode || !llnode->v.val_loc_list->vl_symbol) + { + remove_AT (die, a->dw_attr); + ix--; + } + break; + } case dw_val_class_loc: { dw_loc_descr_ref l = AT_loc (a); @@ -29610,6 +30147,8 @@ hash_loc_list (dw_loc_list_ref list_head) { hstate.add (curr->begin, strlen (curr->begin) + 1); hstate.add (curr->end, strlen (curr->end) + 1); + hstate.add_object (curr->vbegin); + hstate.add_object (curr->vend); if (curr->section) hstate.add (curr->section, strlen (curr->section) + 1); hash_locs (curr->expr, hstate); @@ -29831,6 +30370,7 @@ loc_list_hasher::equal (const dw_loc_list_struct *a, || strcmp (a->end, b->end) != 0 || (a->section == NULL) != (b->section == NULL) || (a->section && strcmp (a->section, b->section) != 0) + || a->vbegin != b->vbegin || a->vend != b->vend || !compare_locs (a->expr, b->expr)) break; return a == NULL && b == NULL; @@ -29849,6 +30389,8 @@ optimize_location_lists_1 (dw_die_ref die, loc_list_hash_type *htab) dw_attr_node *a; unsigned ix; dw_loc_list_struct **slot; + bool drop_locviews = false; + bool has_locviews = false; FOR_EACH_VEC_SAFE_ELT (die->die_attr, ix, a) if (AT_class (a) == dw_val_class_loc_list) @@ -29859,11 +30401,33 @@ optimize_location_lists_1 (dw_die_ref die, loc_list_hash_type *htab) hash_loc_list (list); slot = htab->find_slot_with_hash (list, list->hash, INSERT); if (*slot == NULL) - *slot = list; + { + *slot = list; + if (loc_list_has_views (list)) + gcc_assert (list->vl_symbol); + else if (list->vl_symbol) + { + drop_locviews = true; + list->vl_symbol = NULL; + } + } else - a->dw_attr_val.v.val_loc_list = *slot; + { + if (list->vl_symbol && !(*slot)->vl_symbol) + drop_locviews = true; + a->dw_attr_val.v.val_loc_list = *slot; + } + } + else if (AT_class (a) == dw_val_class_view_list) + { + gcc_checking_assert (a->dw_attr == DW_AT_GNU_locviews); + has_locviews = true; } + + if (drop_locviews && has_locviews) + remove_AT (die, DW_AT_GNU_locviews); + FOR_EACH_CHILD (die, c, optimize_location_lists_1 (c, htab)); } @@ -29888,7 +30452,7 @@ index_location_lists (dw_die_ref die) /* Don't index an entry that has already been indexed or won't be output. */ if (curr->begin_entry != NULL - || (strcmp (curr->begin, curr->end) == 0 && !curr->force)) + || skip_loc_list_entry (curr)) continue; curr->begin_entry @@ -30312,7 +30876,7 @@ dwarf2out_finish (const char *) dw2_asm_output_delta (DWARF_OFFSET_SIZE, l2, l1, "Length of Location Lists"); ASM_OUTPUT_LABEL (asm_out_file, l1); - dw2_asm_output_data (2, dwarf_version, "DWARF Version"); + output_dwarf_version (); dw2_asm_output_data (1, DWARF2_ADDR_SIZE, "Address Size"); dw2_asm_output_data (1, 0, "Segment Size"); dw2_asm_output_data (4, dwarf_split_debug_info ? loc_list_idx : 0, @@ -30371,7 +30935,7 @@ dwarf2out_finish (const char *) used by the debug_info section are marked as 'used'. */ switch_to_section (debug_line_section); ASM_OUTPUT_LABEL (asm_out_file, debug_line_section_label); - if (! DWARF2_ASM_LINE_DEBUG_INFO) + if (! output_asm_line_debug_info ()) output_line_info (false); if (dwarf_split_debug_info && info_section_emitted) diff --git a/gcc/dwarf2out.h b/gcc/dwarf2out.h index bc2ae4d..a1856a5 100644 --- a/gcc/dwarf2out.h +++ b/gcc/dwarf2out.h @@ -160,7 +160,8 @@ enum dw_val_class dw_val_class_discr_list, dw_val_class_const_implicit, dw_val_class_unsigned_const_implicit, - dw_val_class_file_implicit + dw_val_class_file_implicit, + dw_val_class_view_list }; /* Describe a floating point constant value, or a vector constant value. */ @@ -203,6 +204,7 @@ struct GTY(()) dw_val_node { rtx GTY ((tag ("dw_val_class_addr"))) val_addr; unsigned HOST_WIDE_INT GTY ((tag ("dw_val_class_offset"))) val_offset; dw_loc_list_ref GTY ((tag ("dw_val_class_loc_list"))) val_loc_list; + dw_die_ref GTY ((tag ("dw_val_class_view_list"))) val_view_list; dw_loc_descr_ref GTY ((tag ("dw_val_class_loc"))) val_loc; HOST_WIDE_INT GTY ((default)) val_int; unsigned HOST_WIDE_INT diff --git a/gcc/final.c b/gcc/final.c index 578e5d6..68397b3 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -110,6 +110,7 @@ along with GCC; see the file COPYING3. If not see /* Bitflags used by final_scan_insn. */ #define SEEN_NOTE 1 #define SEEN_EMITTED 2 +#define SEEN_NEXT_VIEW 4 /* Last insn processed by final_scan_insn. */ static rtx_insn *debug_insn; @@ -1692,6 +1693,67 @@ get_some_local_dynamic_name () return 0; } +/* Arrange for us to emit a source location note before any further + real insns or section changes, by setting the SEEN_NEXT_VIEW bit in + *SEEN, as long as we are keeping track of location views. The bit + indicates we have referenced the next view at the current PC, so we + have to emit it. This should be called next to the var_location + debug hook. */ + +static inline void +set_next_view_needed (int *seen) +{ + if (debug_variable_location_views) + *seen |= SEEN_NEXT_VIEW; +} + +/* Clear the flag in *SEEN indicating we need to emit the next view. + This should be called next to the source_line debug hook. */ + +static inline void +clear_next_view_needed (int *seen) +{ + *seen &= ~SEEN_NEXT_VIEW; +} + +/* Test whether we have a pending request to emit the next view in + *SEEN, and emit it if needed, clearing the request bit. */ + +static inline void +maybe_output_next_view (int *seen) +{ + if ((*seen & SEEN_NEXT_VIEW) != 0) + { + clear_next_view_needed (seen); + (*debug_hooks->source_line) (last_linenum, last_columnnum, + last_filename, last_discriminator, + false); + } +} + +/* We want to emit param bindings (before the first begin_stmt) in the + initial view, if we are emitting views. To that end, we may + consume initial notes in the function, processing them in + final_start_function, before signaling the beginning of the + prologue, rather than in final. + + We don't test whether the DECLs are PARM_DECLs: the assumption is + that there will be a NOTE_INSN_BEGIN_STMT marker before any + non-parameter NOTE_INSN_VAR_LOCATION. It's ok if the marker is not + there, we'll just have more variable locations bound in the initial + view, which is consistent with their being bound without any code + that would give them a value. */ + +static inline bool +in_initial_view_p (rtx_insn *insn) +{ + return (!DECL_IGNORED_P (current_function_decl) + && debug_variable_location_views + && insn && GET_CODE (insn) == NOTE + && (NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION + || NOTE_KIND (insn) == NOTE_INSN_DELETED)); +} + /* Output assembler code for the start of a function, and initialize some of the variables in this file for the new function. The label for the function and associated @@ -1699,12 +1761,15 @@ get_some_local_dynamic_name () FIRST is the first insn of the rtl for the function being compiled. FILE is the file to write assembler code to. + SEEN should be initially set to zero, and it may be updated to + indicate we have references to the next location view, that would + require us to emit it at the current PC. OPTIMIZE_P is nonzero if we should eliminate redundant test and compare insns. */ -void -final_start_function (rtx_insn *first, FILE *file, - int optimize_p ATTRIBUTE_UNUSED) +static void +final_start_function_1 (rtx_insn **firstp, FILE *file, int *seen, + int optimize_p ATTRIBUTE_UNUSED) { block_depth = 0; @@ -1722,8 +1787,21 @@ final_start_function (rtx_insn *first, FILE *file, if (flag_sanitize & SANITIZE_ADDRESS) asan_function_start (); + rtx_insn *first = *firstp; + if (in_initial_view_p (first)) + { + do + { + final_scan_insn (first, file, 0, 0, seen); + first = NEXT_INSN (first); + } + while (in_initial_view_p (first)); + *firstp = first; + } + if (!DECL_IGNORED_P (current_function_decl)) - debug_hooks->begin_prologue (last_linenum, last_columnnum, last_filename); + debug_hooks->begin_prologue (last_linenum, last_columnnum, + last_filename); if (!dwarf2_debug_info_emitted_p (current_function_decl)) dwarf2out_begin_prologue (0, 0, NULL); @@ -1799,6 +1877,17 @@ final_start_function (rtx_insn *first, FILE *file, profile_after_prologue (file); } +/* This is an exported final_start_function_1, callable without SEEN. */ + +void +final_start_function (rtx_insn *first, FILE *file, + int optimize_p ATTRIBUTE_UNUSED) +{ + int seen = 0; + final_start_function_1 (&first, file, &seen, optimize_p); + gcc_assert (seen == 0); +} + static void profile_after_prologue (FILE *file ATTRIBUTE_UNUSED) { @@ -1928,11 +2017,10 @@ dump_basic_block_info (FILE *file, rtx_insn *insn, basic_block *start_to_bb, /* Output assembler code for some insns: all or part of a function. For description of args, see `final_start_function', above. */ -void -final (rtx_insn *first, FILE *file, int optimize_p) +static void +final_1 (rtx_insn *first, FILE *file, int seen, int optimize_p) { rtx_insn *insn, *next; - int seen = 0; /* Used for -dA dump. */ basic_block *start_to_bb = NULL; @@ -1999,6 +2087,8 @@ final (rtx_insn *first, FILE *file, int optimize_p) insn = final_scan_insn (insn, file, optimize_p, 0, &seen); } + maybe_output_next_view (&seen); + if (flag_debug_asm) { free (start_to_bb); @@ -2015,6 +2105,23 @@ final (rtx_insn *first, FILE *file, int optimize_p) delete_insn (insn); } } + +/* This is an exported final_1, callable without SEEN. */ + +void +final (rtx_insn *first, FILE *file, int optimize_p) +{ + /* Those that use the internal final_start_function_1/final_1 API + skip initial debug bind notes in final_start_function_1, and pass + the modified FIRST to final_1. But those that use the public + final_start_function/final APIs, final_start_function can't move + FIRST because it's not passed by reference, so if they were + skipped there, skip them again here. */ + while (in_initial_view_p (first)) + first = NEXT_INSN (first); + + final_1 (first, file, 0, optimize_p); +} const char * get_insn_template (int code, rtx insn) @@ -2155,6 +2262,8 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, break; case NOTE_INSN_SWITCH_TEXT_SECTIONS: + maybe_output_next_view (seen); + in_cold_section_p = !in_cold_section_p; if (in_cold_section_p) @@ -2301,6 +2410,8 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, break; case NOTE_INSN_BLOCK_END: + maybe_output_next_view (seen); + if (debug_info_level == DINFO_LEVEL_NORMAL || debug_info_level == DINFO_LEVEL_VERBOSE || write_symbols == DWARF2_DEBUG @@ -2357,7 +2468,10 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, case NOTE_INSN_VAR_LOCATION: case NOTE_INSN_CALL_ARG_LOCATION: if (!DECL_IGNORED_P (current_function_decl)) - debug_hooks->var_location (insn); + { + debug_hooks->var_location (insn); + set_next_view_needed (seen); + } break; case NOTE_INSN_BEGIN_STMT: @@ -2368,6 +2482,7 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, (*debug_hooks->source_line) (last_linenum, last_columnnum, last_filename, last_discriminator, true); + clear_next_view_needed (seen); } break; @@ -2563,6 +2678,10 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, switch_to_section (current_function_section ()); + if (debug_variable_location_views + && !DECL_IGNORED_P (current_function_decl)) + debug_hooks->var_location (insn); + break; } /* Output this line note if it is the first or the last line @@ -2575,7 +2694,12 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, (*debug_hooks->source_line) (last_linenum, last_columnnum, last_filename, last_discriminator, is_stmt); + clear_next_view_needed (seen); } + else + maybe_output_next_view (seen); + + gcc_checking_assert (!DEBUG_INSN_P (insn)); if (GET_CODE (body) == PARALLEL && GET_CODE (XVECEXP (body, 0, 0)) == ASM_INPUT) @@ -3042,7 +3166,8 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, /* Let the debug info back-end know about this call. We do this only after the instruction has been emitted because labels that may be created to reference the call instruction must appear after it. */ - if (call_insn != NULL && !DECL_IGNORED_P (current_function_decl)) + if ((debug_variable_location_views || call_insn != NULL) + && !DECL_IGNORED_P (current_function_decl)) debug_hooks->var_location (insn); current_output_insn = debug_insn = 0; @@ -4481,8 +4606,10 @@ rest_of_handle_final (void) delete_vta_debug_insns (false); assemble_start_function (current_function_decl, fnname); - final_start_function (get_insns (), asm_out_file, optimize); - final (get_insns (), asm_out_file, optimize); + rtx_insn *first = get_insns (); + int seen = 0; + final_start_function_1 (&first, asm_out_file, &seen, optimize); + final_1 (first, asm_out_file, seen, optimize); if (flag_ipa_ra && !lookup_attribute ("noipa", DECL_ATTRIBUTES (current_function_decl))) collect_fn_hard_reg_usage (); diff --git a/gcc/toplev.c b/gcc/toplev.c index 35d7968..23db063 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1558,6 +1558,22 @@ process_options (void) || write_symbols == VMS_AND_DWARF2_DEBUG) && !(flag_selective_scheduling || flag_selective_scheduling2)); + 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; + } + else if (debug_variable_location_views == -1 && dwarf_version != 5) + { + warning_at (UNKNOWN_LOCATION, 0, + "without -gdwarf-5, -gvariable-location-views=incompat5 " + "is equivalent to -gvariable-location-views"); + debug_variable_location_views = 1; + } + if (flag_tree_cselim == AUTODETECT_VALUE) { if (HAVE_conditional_move) -- cgit v1.1 From 5800666390320080558b2766738c21e82bf570e7 Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Fri, 9 Feb 2018 02:22:11 +0000 Subject: [IEPM] Introduce inline entry point markers Output DW_AT_entry_pc based on markers. Introduce DW_AT_GNU_entry_view as a DWARF extension. If views are enabled are we're not in strict compliance mode, output DW_AT_GNU_entry_view if it might be nonzero. This patch depends on SFN and LVU patchsets, and on the IEPM patch that introduces the inline_entry debug hook. for include/ChangeLog * dwarf2.def (DW_AT_GNU_entry_view): New. for gcc/ChangeLog * cfgexpand.c (expand_gimple_basic_block): Handle inline entry markers. * dwarf2out.c (dwarf2_debug_hooks): Enable inline_entry hook. (BLOCK_INLINE_ENTRY_LABEL): New. (dwarf2out_var_location): Disregard inline entry markers. (inline_entry_data): New struct. (inline_entry_data_hasher): New hashtable type. (inline_entry_data_hasher::hash): New. (inline_entry_data_hasher::equal): New. (inline_entry_data_table): New variable. (add_high_low_attributes): Add DW_AT_entry_pc and DW_AT_GNU_entry_view attributes if a pending entry is found in inline_entry_data_table. Add old entry_pc attribute only if debug nonbinding markers are disabled. (gen_inlined_subroutine_die): Set BLOCK_DIE if nonbinding markers are enabled. (block_within_block_p, dwarf2out_inline_entry): New. (dwarf2out_finish): Check that no entries remained in inline_entry_data_table. * final.c (reemit_insn_block_notes): Handle inline entry notes. (final_scan_insn, notice_source_line): Likewise. (rest_of_clean_state): Skip inline entry markers. * gimple-pretty-print.c (dump_gimple_debug): Handle inline entry markers. * gimple.c (gimple_build_debug_inline_entry): New. * gimple.h (enum gimple_debug_subcode): Add GIMPLE_DEBUG_INLINE_ENTRY. (gimple_build_debug_inline_entry): Declare. (gimple_debug_inline_entry_p): New. (gimple_debug_nonbind_marker_p): Adjust. * insn-notes.def (INLINE_ENTRY): New. * print-rtl.c (rtx_writer::print_rtx_operand_code_0): Handle inline entry marker notes. (print_insn): Likewise. * rtl.h (NOTE_MARKER_P): Add INLINE_ENTRY support. (INSN_DEBUG_MARKER_KIND): Likewise. (GEN_RTX_DEBUG_MARKER_INLINE_ENTRY_PAT): New. * tree-inline.c (expand_call_inline): Build and insert debug_inline_entry stmt. * tree-ssa-live.c (remove_unused_scope_block_p): Preserve inline entry blocks early, if nonbind markers are enabled. (dump_scope_block): Dump fragment info. * var-tracking.c (reemit_marker_as_note): Handle inline entry note. * doc/gimple.texi (gimple_debug_inline_entry_p): New. (gimple_build_debug_inline_entry): New. * doc/invoke.texi (gstatement-frontiers, gno-statement-frontiers): Enable/disable inline entry points too. * doc/rtl.texi (NOTE_INSN_INLINE_ENTRY): New. (DEBUG_INSN): Describe inline entry markers. From-SVN: r257511 --- gcc/ChangeLog | 50 ++++++++++++ gcc/cfgexpand.c | 9 +++ gcc/doc/gimple.texi | 18 +++++ gcc/doc/rtl.texi | 24 ++++-- gcc/dwarf2out.c | 199 +++++++++++++++++++++++++++++++++++++++++++++- gcc/final.c | 26 ++++++ gcc/gimple-pretty-print.c | 13 +++ gcc/gimple.c | 21 +++++ gcc/gimple.h | 18 ++++- gcc/insn-notes.def | 4 + gcc/print-rtl.c | 5 ++ gcc/rtl.h | 7 +- gcc/tree-inline.c | 7 ++ gcc/tree-ssa-live.c | 27 +++++-- gcc/var-tracking.c | 1 + 15 files changed, 413 insertions(+), 16 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1d9c9729..b5e19ed 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,55 @@ 2018-02-09 Alexandre Oliva + * cfgexpand.c (expand_gimple_basic_block): Handle inline entry + markers. + * dwarf2out.c (dwarf2_debug_hooks): Enable inline_entry hook. + (BLOCK_INLINE_ENTRY_LABEL): New. + (dwarf2out_var_location): Disregard inline entry markers. + (inline_entry_data): New struct. + (inline_entry_data_hasher): New hashtable type. + (inline_entry_data_hasher::hash): New. + (inline_entry_data_hasher::equal): New. + (inline_entry_data_table): New variable. + (add_high_low_attributes): Add DW_AT_entry_pc and + DW_AT_GNU_entry_view attributes if a pending entry is found + in inline_entry_data_table. Add old entry_pc attribute only + if debug nonbinding markers are disabled. + (gen_inlined_subroutine_die): Set BLOCK_DIE if nonbinding + markers are enabled. + (block_within_block_p, dwarf2out_inline_entry): New. + (dwarf2out_finish): Check that no entries remained in + inline_entry_data_table. + * final.c (reemit_insn_block_notes): Handle inline entry notes. + (final_scan_insn, notice_source_line): Likewise. + (rest_of_clean_state): Skip inline entry markers. + * gimple-pretty-print.c (dump_gimple_debug): Handle inline entry + markers. + * gimple.c (gimple_build_debug_inline_entry): New. + * gimple.h (enum gimple_debug_subcode): Add + GIMPLE_DEBUG_INLINE_ENTRY. + (gimple_build_debug_inline_entry): Declare. + (gimple_debug_inline_entry_p): New. + (gimple_debug_nonbind_marker_p): Adjust. + * insn-notes.def (INLINE_ENTRY): New. + * print-rtl.c (rtx_writer::print_rtx_operand_code_0): Handle + inline entry marker notes. + (print_insn): Likewise. + * rtl.h (NOTE_MARKER_P): Add INLINE_ENTRY support. + (INSN_DEBUG_MARKER_KIND): Likewise. + (GEN_RTX_DEBUG_MARKER_INLINE_ENTRY_PAT): New. + * tree-inline.c (expand_call_inline): Build and insert + debug_inline_entry stmt. + * tree-ssa-live.c (remove_unused_scope_block_p): Preserve + inline entry blocks early, if nonbind markers are enabled. + (dump_scope_block): Dump fragment info. + * var-tracking.c (reemit_marker_as_note): Handle inline entry note. + * doc/gimple.texi (gimple_debug_inline_entry_p): New. + (gimple_build_debug_inline_entry): New. + * doc/invoke.texi (gstatement-frontiers, gno-statement-frontiers): + Enable/disable inline entry points too. + * doc/rtl.texi (NOTE_INSN_INLINE_ENTRY): New. + (DEBUG_INSN): Describe inline entry markers. + * common.opt (gvariable-location-views): New. (gvariable-location-views=incompat5): New. * config.in: Rebuilt. diff --git a/gcc/cfgexpand.c b/gcc/cfgexpand.c index 2ee6fba..deab929 100644 --- a/gcc/cfgexpand.c +++ b/gcc/cfgexpand.c @@ -5731,6 +5731,15 @@ expand_gimple_basic_block (basic_block bb, bool disable_tail_calls) goto delink_debug_stmt; else if (gimple_debug_begin_stmt_p (stmt)) val = GEN_RTX_DEBUG_MARKER_BEGIN_STMT_PAT (); + else if (gimple_debug_inline_entry_p (stmt)) + { + tree block = gimple_block (stmt); + + if (block) + val = GEN_RTX_DEBUG_MARKER_INLINE_ENTRY_PAT (); + else + goto delink_debug_stmt; + } else gcc_unreachable (); diff --git a/gcc/doc/gimple.texi b/gcc/doc/gimple.texi index 6d920ae..1f9449f 100644 --- a/gcc/doc/gimple.texi +++ b/gcc/doc/gimple.texi @@ -836,6 +836,11 @@ Return true if g is a @code{GIMPLE_DEBUG} that marks the beginning of a source statement. @end deftypefn +@deftypefn {GIMPLE function} gimple_debug_inline_entry_p (gimple g) +Return true if g is a @code{GIMPLE_DEBUG} that marks the entry +point of an inlined function. +@end deftypefn + @deftypefn {GIMPLE function} gimple_debug_nonbind_marker_p (gimple g) Return true if g is a @code{GIMPLE_DEBUG} that marks a program location, without any variable binding. @@ -1541,6 +1546,7 @@ Set the conditional @code{COND_STMT} to be of the form 'if (1 == 1)'. @cindex @code{GIMPLE_DEBUG} @cindex @code{GIMPLE_DEBUG_BIND} @cindex @code{GIMPLE_DEBUG_BEGIN_STMT} +@cindex @code{GIMPLE_DEBUG_INLINE_ENTRY} @deftypefn {GIMPLE function} gdebug *gimple_build_debug_bind (tree var, @ tree value, gimple stmt) @@ -1626,6 +1632,18 @@ observable, and that none of the side effects of subsequent user statements are. @end deftypefn +@deftypefn {GIMPLE function} gimple gimple_build_debug_inline_entry (tree block, location_t location) +Build a @code{GIMPLE_DEBUG} statement with +@code{GIMPLE_DEBUG_INLINE_ENTRY} @code{subcode}. The effect of this +statement is to tell debug information generation machinery that a +function call at @code{location} underwent inline substitution, that +@code{block} is the enclosing lexical block created for the +substitution, and that at the point of the program in which the stmt is +inserted, all parameters for the inlined function are bound to the +respective arguments, and none of the side effects of its stmts are +observable. +@end deftypefn + @node @code{GIMPLE_EH_FILTER} @subsection @code{GIMPLE_EH_FILTER} @cindex @code{GIMPLE_EH_FILTER} diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi index 2523f63..43d5405 100644 --- a/gcc/doc/rtl.texi +++ b/gcc/doc/rtl.texi @@ -3670,7 +3670,10 @@ Refers to a parameter that was completely optimized out. @item (debug_marker:@var{mode}) Marks a program location. With @code{VOIDmode}, it stands for the beginning of a statement, a recommended inspection point logically after -all prior side effects, and before any subsequent side effects. +all prior side effects, and before any subsequent side effects. With +@code{BLKmode}, it indicates an inline entry point: the lexical block +encoded in the @code{INSN_LOCATION} is the enclosing block that encloses +the inlined function. @end table @@ -3954,6 +3957,13 @@ This note is used to generate @code{is_stmt} markers in line number debuggign information. It indicates the beginning of a user statement. +@findex NOTE_INSN_INLINE_ENTRY +@item NOTE_INSN_INLINE_ENTRY +This note is used to generate @code{entry_pc} for inlined subroutines in +debugging information. It indicates an inspection point at which all +arguments for the inlined function have been bound, and before its first +statement. + @end table These codes are printed symbolically when they appear in debugging dumps. @@ -3971,8 +3981,12 @@ binds a user variable tree to an RTL representation of the it stands for the value bound to the corresponding @code{DEBUG_EXPR_DECL}. -@code{GIMPLE_DEBUG_BEGIN_STMT} is expanded to RTL as a @code{DEBUG_INSN} -with a @code{VOIDmode} @code{DEBUG_MARKER} @code{PATTERN}. These +@code{GIMPLE_DEBUG_BEGIN_STMT} and @code{GIMPLE_DEBUG_INLINE_ENTRY} are +expanded to RTL as a @code{DEBUG_INSN} with a @code{DEBUG_MARKER} +@code{PATTERN}; the difference is the RTL mode: the former's +@code{DEBUG_MARKER} is @code{VOIDmode}, whereas the latter is +@code{BLKmode}; information about the inlined function can be taken from +the lexical block encoded in the @code{INSN_LOCATION}. These @code{DEBUG_INSN}s, that do not carry @code{VAR_LOCATION} information, just @code{DEBUG_MARKER}s, can be detected by testing @code{DEBUG_MARKER_INSN_P}, whereas those that do can be recognized as @@ -3983,8 +3997,8 @@ with respect to each other, particularly during scheduling. Binding information is kept in pseudo-instruction form, so that, unlike notes, it gets the same treatment and adjustments that regular instructions would. It is the variable tracking pass that turns these -pseudo-instructions into @code{NOTE_INSN_VAR_LOCATION} and -@code{NOTE_INSN_BEGIN_STMT} notes, +pseudo-instructions into @code{NOTE_INSN_VAR_LOCATION}, +@code{NOTE_INSN_BEGIN_STMT} and @code{NOTE_INSN_INLINE_ENTRY} notes, analyzing control flow, value equivalences and changes to registers and memory referenced in value expressions, propagating the values of debug temporaries and determining expressions that can be used to compute the diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 56d3e14..749c7e3 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -2747,6 +2747,7 @@ static void dwarf2out_imported_module_or_decl_1 (tree, tree, tree, dw_die_ref); static void dwarf2out_abstract_function (tree); static void dwarf2out_var_location (rtx_insn *); +static void dwarf2out_inline_entry (tree); static void dwarf2out_size_function (tree); static void dwarf2out_begin_function (tree); static void dwarf2out_end_function (unsigned int); @@ -2800,7 +2801,7 @@ const struct gcc_debug_hooks dwarf2_debug_hooks = debug_nothing_rtx_code_label, /* label */ debug_nothing_int, /* handle_pch */ dwarf2out_var_location, - debug_nothing_tree, /* inline_entry */ + dwarf2out_inline_entry, /* inline_entry */ dwarf2out_size_function, /* size_function */ dwarf2out_switch_text_section, dwarf2out_set_name, @@ -4068,6 +4069,9 @@ static char ranges_base_label[2 * MAX_ARTIFICIAL_LABEL_BYTES]; #ifndef BLOCK_BEGIN_LABEL #define BLOCK_BEGIN_LABEL "LBB" #endif +#ifndef BLOCK_INLINE_ENTRY_LABEL +#define BLOCK_INLINE_ENTRY_LABEL "LBI" +#endif #ifndef BLOCK_END_LABEL #define BLOCK_END_LABEL "LBE" #endif @@ -23215,6 +23219,48 @@ block_die_hasher::equal (die_struct *x, die_struct *y) return x->decl_id == y->decl_id && x->die_parent == y->die_parent; } +/* Hold information about markers for inlined entry points. */ +struct GTY ((for_user)) inline_entry_data +{ + /* The block that's the inlined_function_outer_scope for an inlined + function. */ + tree block; + + /* The label at the inlined entry point. */ + const char *label_pfx; + unsigned int label_num; + + /* The view number to be used as the inlined entry point. */ + var_loc_view view; +}; + +struct inline_entry_data_hasher : ggc_ptr_hash +{ + typedef tree compare_type; + static inline hashval_t hash (const inline_entry_data *); + static inline bool equal (const inline_entry_data *, const_tree); +}; + +/* Hash table routines for inline_entry_data. */ + +inline hashval_t +inline_entry_data_hasher::hash (const inline_entry_data *data) +{ + return htab_hash_pointer (data->block); +} + +inline bool +inline_entry_data_hasher::equal (const inline_entry_data *data, + const_tree block) +{ + return data->block == block; +} + +/* Inlined entry points pending DIE creation in this compilation unit. */ + +static GTY(()) hash_table *inline_entry_data_table; + + /* Return TRUE if DECL, which may have been previously generated as OLD_DIE, is a candidate for a DW_AT_specification. DECLARATION is true if decl (or its origin) is either an extern declaration or a @@ -23667,6 +23713,42 @@ add_high_low_attributes (tree stmt, dw_die_ref die) { char label[MAX_ARTIFICIAL_LABEL_BYTES]; + if (inline_entry_data **iedp + = !inline_entry_data_table ? NULL + : inline_entry_data_table->find_slot_with_hash (stmt, + htab_hash_pointer (stmt), + NO_INSERT)) + { + inline_entry_data *ied = *iedp; + gcc_assert (MAY_HAVE_DEBUG_MARKER_INSNS); + 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 (!output_asm_line_debug_info ()) + add_AT_unsigned (die, DW_AT_GNU_entry_view, ied->view); + else + { + ASM_GENERATE_INTERNAL_LABEL (label, "LVU", ied->view); + /* FIXME: this will resolve to a small number. Could we + possibly emit smaller data? Ideally we'd emit a + uleb128, but that would make the size of DIEs + impossible for the compiler to compute, since it's + the assembler that computes the value of the view + label in this case. Ideally, we'd have a single form + encompassing both the address and the view, and + indirecting them through a table might make things + easier, but even that would be more wasteful, + space-wise, than what we have now. */ + add_AT_lbl_id (die, DW_AT_GNU_entry_view, label); + } + } + + inline_entry_data_table->clear_slot (iedp); + } + if (BLOCK_FRAGMENT_CHAIN (stmt) && (dwarf_version >= 3 || !dwarf_strict)) { @@ -23674,7 +23756,7 @@ add_high_low_attributes (tree stmt, dw_die_ref die) dw_die_ref pdie; dw_attr_node *attr = NULL; - if (inlined_function_outer_scope_p (stmt)) + if (!MAY_HAVE_DEBUG_MARKER_INSNS && inlined_function_outer_scope_p (stmt)) { ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_BEGIN_LABEL, BLOCK_NUMBER (stmt)); @@ -23839,7 +23921,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) + if (call_arg_locations || MAY_HAVE_DEBUG_MARKER_INSNS) BLOCK_DIE (stmt) = subr_die; add_abstract_origin_attribute (subr_die, decl); if (TREE_ASM_WRITTEN (stmt)) @@ -26871,6 +26953,7 @@ dwarf2out_var_location (rtx_insn *loc_note) || ! NOTE_P (next_note) || (NOTE_KIND (next_note) != NOTE_INSN_VAR_LOCATION && NOTE_KIND (next_note) != NOTE_INSN_BEGIN_STMT + && NOTE_KIND (next_note) != NOTE_INSN_INLINE_ENTRY && NOTE_KIND (next_note) != NOTE_INSN_CALL_ARG_LOCATION)) next_note = NULL; @@ -27064,6 +27147,113 @@ create_label: last_in_cold_section_p = in_cold_section_p; } +/* Check whether BLOCK, a lexical block, is nested within OUTER, or is + OUTER itself. If BOTHWAYS, check not only that BLOCK can reach + OUTER through BLOCK_SUPERCONTEXT links, but also that there is a + path from OUTER to BLOCK through BLOCK_SUBBLOCKs and + BLOCK_FRAGMENT_ORIGIN links. */ +static bool +block_within_block_p (tree block, tree outer, bool bothways) +{ + if (block == outer) + return true; + + /* Quickly check that OUTER is up BLOCK's supercontext chain. */ + for (tree context = BLOCK_SUPERCONTEXT (block); + context != outer; + context = BLOCK_SUPERCONTEXT (context)) + if (!context || TREE_CODE (context) != BLOCK) + return false; + + if (!bothways) + return true; + + /* Now check that each block is actually referenced by its + parent. */ + for (tree context = BLOCK_SUPERCONTEXT (block); ; + context = BLOCK_SUPERCONTEXT (context)) + { + if (BLOCK_FRAGMENT_ORIGIN (context)) + { + gcc_assert (!BLOCK_SUBBLOCKS (context)); + context = BLOCK_FRAGMENT_ORIGIN (context); + } + for (tree sub = BLOCK_SUBBLOCKS (context); + sub != block; + sub = BLOCK_CHAIN (sub)) + if (!sub) + return false; + if (context == outer) + return true; + else + block = context; + } +} + +/* Called during final while assembling the marker of the entry point + for an inlined function. */ + +static void +dwarf2out_inline_entry (tree block) +{ + /* If we can't represent it, don't bother. */ + if (!(dwarf_version >= 3 || !dwarf_strict)) + return; + + gcc_assert (DECL_P (block_ultimate_origin (block))); + + /* Sanity check the block tree. This would catch a case in which + BLOCK got removed from the tree reachable from the outermost + lexical block, but got retained in markers. It would still link + back to its parents, but some ancestor would be missing a link + down the path to the sub BLOCK. If the block got removed, its + BLOCK_NUMBER will not be a usable value. */ + if (flag_checking) + gcc_assert (block_within_block_p (block, + DECL_INITIAL (current_function_decl), + true)); + + gcc_assert (inlined_function_outer_scope_p (block)); + gcc_assert (!BLOCK_DIE (block)); + + if (BLOCK_FRAGMENT_ORIGIN (block)) + block = BLOCK_FRAGMENT_ORIGIN (block); + /* Can the entry point ever not be at the beginning of an + unfragmented lexical block? */ + else if (!(BLOCK_FRAGMENT_CHAIN (block) + || (cur_line_info_table + && !ZERO_VIEW_P (cur_line_info_table->view)))) + return; + + if (!inline_entry_data_table) + inline_entry_data_table + = hash_table::create_ggc (10); + + + inline_entry_data **iedp + = inline_entry_data_table->find_slot_with_hash (block, + htab_hash_pointer (block), + INSERT); + if (*iedp) + /* ??? Ideally, we'd record all entry points for the same inlined + function (some may have been duplicated by e.g. unrolling), but + we have no way to represent that ATM. */ + return; + + inline_entry_data *ied = *iedp = ggc_cleared_alloc (); + ied->block = block; + ied->label_pfx = BLOCK_INLINE_ENTRY_LABEL; + ied->label_num = BLOCK_NUMBER (block); + if (cur_line_info_table) + ied->view = cur_line_info_table->view; + + char label[MAX_ARTIFICIAL_LABEL_BYTES]; + + ASM_GENERATE_INTERNAL_LABEL (label, BLOCK_INLINE_ENTRY_LABEL, + BLOCK_NUMBER (block)); + ASM_OUTPUT_LABEL (asm_out_file, label); +} + /* Called from finalize_size_functions for size functions so that their body can be encoded in the debug info to describe the layout of variable-length structures. */ @@ -30560,6 +30750,9 @@ dwarf2out_finish (const char *) /* Flush out any latecomers to the limbo party. */ flush_limbo_die_list (); + if (inline_entry_data_table) + gcc_assert (inline_entry_data_table->elements () == 0); + if (flag_checking) { verify_die (comp_unit_die ()); diff --git a/gcc/final.c b/gcc/final.c index 68397b3..99a7cad 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -1611,6 +1611,7 @@ reemit_insn_block_notes (void) break; case NOTE_INSN_BEGIN_STMT: + case NOTE_INSN_INLINE_ENTRY: this_block = LOCATION_BLOCK (NOTE_MARKER_LOCATION (insn)); goto set_cur_block_to_this_block; @@ -2479,6 +2480,7 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, if (!DECL_IGNORED_P (current_function_decl) && notice_source_line (insn, NULL)) { + output_source_line: (*debug_hooks->source_line) (last_linenum, last_columnnum, last_filename, last_discriminator, true); @@ -2486,6 +2488,18 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, } break; + case NOTE_INSN_INLINE_ENTRY: + gcc_checking_assert (cfun->debug_nonbind_markers); + if (!DECL_IGNORED_P (current_function_decl)) + { + if (!notice_source_line (insn, NULL)) + break; + (*debug_hooks->inline_entry) (LOCATION_BLOCK + (NOTE_MARKER_LOCATION (insn))); + goto output_source_line; + } + break; + default: gcc_unreachable (); break; @@ -3189,6 +3203,17 @@ notice_source_line (rtx_insn *insn, bool *is_stmt) if (NOTE_MARKER_P (insn)) { location_t loc = NOTE_MARKER_LOCATION (insn); + /* The inline entry markers (gimple, insn, note) carry the + location of the call, because that's what we want to carry + during compilation, but the location we want to output in + debug information for the inline entry point is the location + of the function itself. */ + if (NOTE_KIND (insn) == NOTE_INSN_INLINE_ENTRY) + { + tree block = LOCATION_BLOCK (loc); + tree fn = block_ultimate_origin (block); + loc = DECL_SOURCE_LOCATION (fn); + } expanded_location xloc = expand_location (loc); if (xloc.line == 0) { @@ -4795,6 +4820,7 @@ rest_of_clean_state (void) && (!NOTE_P (insn) || (NOTE_KIND (insn) != NOTE_INSN_VAR_LOCATION && NOTE_KIND (insn) != NOTE_INSN_BEGIN_STMT + && NOTE_KIND (insn) != NOTE_INSN_INLINE_ENTRY && NOTE_KIND (insn) != NOTE_INSN_CALL_ARG_LOCATION && NOTE_KIND (insn) != NOTE_INSN_BLOCK_BEG && NOTE_KIND (insn) != NOTE_INSN_BLOCK_END diff --git a/gcc/gimple-pretty-print.c b/gcc/gimple-pretty-print.c index 374bd45..6695526 100644 --- a/gcc/gimple-pretty-print.c +++ b/gcc/gimple-pretty-print.c @@ -1371,6 +1371,19 @@ dump_gimple_debug (pretty_printer *buffer, gdebug *gs, int spc, dump_gimple_fmt (buffer, spc, flags, "# DEBUG BEGIN_STMT"); break; + case GIMPLE_DEBUG_INLINE_ENTRY: + if (flags & TDF_RAW) + dump_gimple_fmt (buffer, spc, flags, "%G INLINE_ENTRY %T", gs, + gimple_block (gs) + ? block_ultimate_origin (gimple_block (gs)) + : NULL_TREE); + else + dump_gimple_fmt (buffer, spc, flags, "# DEBUG INLINE_ENTRY %T", + gimple_block (gs) + ? block_ultimate_origin (gimple_block (gs)) + : NULL_TREE); + break; + default: gcc_unreachable (); } diff --git a/gcc/gimple.c b/gcc/gimple.c index c1b7229..9dc4911 100644 --- a/gcc/gimple.c +++ b/gcc/gimple.c @@ -874,6 +874,27 @@ gimple_build_debug_begin_stmt (tree block, location_t location } +/* Build a new GIMPLE_DEBUG_INLINE_ENTRY statement in BLOCK at + LOCATION. The BLOCK links to the inlined function. */ + +gdebug * +gimple_build_debug_inline_entry (tree block, location_t location + MEM_STAT_DECL) +{ + gdebug *p + = as_a ( + gimple_build_with_ops_stat (GIMPLE_DEBUG, + (unsigned)GIMPLE_DEBUG_INLINE_ENTRY, 0 + PASS_MEM_STAT)); + + gimple_set_location (p, location); + gimple_set_block (p, block); + cfun->debug_marker_count++; + + return p; +} + + /* Build a GIMPLE_OMP_CRITICAL statement. BODY is the sequence of statements for which only one thread can execute. diff --git a/gcc/gimple.h b/gcc/gimple.h index 7460586..265e3e2 100644 --- a/gcc/gimple.h +++ b/gcc/gimple.h @@ -202,7 +202,8 @@ enum gf_mask { enum gimple_debug_subcode { GIMPLE_DEBUG_BIND = 0, GIMPLE_DEBUG_SOURCE_BIND = 1, - GIMPLE_DEBUG_BEGIN_STMT = 2 + GIMPLE_DEBUG_BEGIN_STMT = 2, + GIMPLE_DEBUG_INLINE_ENTRY = 3 }; /* Masks for selecting a pass local flag (PLF) to work on. These @@ -1454,6 +1455,7 @@ geh_dispatch *gimple_build_eh_dispatch (int); gdebug *gimple_build_debug_bind (tree, tree, gimple * CXX_MEM_STAT_INFO); gdebug *gimple_build_debug_source_bind (tree, tree, gimple * CXX_MEM_STAT_INFO); gdebug *gimple_build_debug_begin_stmt (tree, location_t CXX_MEM_STAT_INFO); +gdebug *gimple_build_debug_inline_entry (tree, location_t CXX_MEM_STAT_INFO); gomp_critical *gimple_build_omp_critical (gimple_seq, tree, tree); gomp_for *gimple_build_omp_for (gimple_seq, int, tree, size_t, gimple_seq); gomp_parallel *gimple_build_omp_parallel (gimple_seq, tree, tree, tree); @@ -4784,13 +4786,25 @@ gimple_debug_begin_stmt_p (const gimple *s) return false; } +/* Return true if S is a GIMPLE_DEBUG INLINE_ENTRY statement. */ + +static inline bool +gimple_debug_inline_entry_p (const gimple *s) +{ + if (is_gimple_debug (s)) + return s->subcode == GIMPLE_DEBUG_INLINE_ENTRY; + + return false; +} + /* Return true if S is a GIMPLE_DEBUG non-binding marker statement. */ static inline bool gimple_debug_nonbind_marker_p (const gimple *s) { if (is_gimple_debug (s)) - return s->subcode == GIMPLE_DEBUG_BEGIN_STMT; + return s->subcode == GIMPLE_DEBUG_BEGIN_STMT + || s->subcode == GIMPLE_DEBUG_INLINE_ENTRY; return false; } diff --git a/gcc/insn-notes.def b/gcc/insn-notes.def index 5186d58..9cac5f1 100644 --- a/gcc/insn-notes.def +++ b/gcc/insn-notes.def @@ -71,6 +71,10 @@ INSN_NOTE (CALL_ARG_LOCATION) /* The beginning of a statement. */ INSN_NOTE (BEGIN_STMT) +/* The entry point for an inlined function. Its NOTE_BLOCK references + the lexical block whose abstract origin is the inlined function. */ +INSN_NOTE (INLINE_ENTRY) + /* Record the struct for the following basic block. Uses NOTE_BASIC_BLOCK. FIXME: Redundant with the basic block pointer now included in every insn. NOTE: If there's no CFG anymore, in other words, diff --git a/gcc/print-rtl.c b/gcc/print-rtl.c index c26e46c..3ad11dc 100644 --- a/gcc/print-rtl.c +++ b/gcc/print-rtl.c @@ -276,6 +276,7 @@ rtx_writer::print_rtx_operand_code_0 (const_rtx in_rtx ATTRIBUTE_UNUSED, break; case NOTE_INSN_BEGIN_STMT: + case NOTE_INSN_INLINE_ENTRY: #ifndef GENERATOR_FILE { expanded_location xloc @@ -1879,6 +1880,10 @@ print_insn (pretty_printer *pp, const rtx_insn *x, int verbose) pp_string (pp, "debug begin stmt marker"); break; + case NOTE_INSN_INLINE_ENTRY: + pp_string (pp, "debug inline entry marker"); + break; + default: gcc_unreachable (); } diff --git a/gcc/rtl.h b/gcc/rtl.h index fcad6a7..c9dd7dd 100644 --- a/gcc/rtl.h +++ b/gcc/rtl.h @@ -1654,7 +1654,8 @@ extern const char * const reg_note_name[]; for which NOTE_MARKER_LOCATION can be used. */ #define NOTE_MARKER_P(INSN) \ (NOTE_P (INSN) && \ - (NOTE_KIND (INSN) == NOTE_INSN_BEGIN_STMT)) + (NOTE_KIND (INSN) == NOTE_INSN_BEGIN_STMT \ + || NOTE_KIND (INSN) == NOTE_INSN_INLINE_ENTRY)) /* Variable declaration and the location of a variable. */ #define PAT_VAR_LOCATION_DECL(PAT) (XCTREE ((PAT), 0, VAR_LOCATION)) @@ -1692,6 +1693,8 @@ extern const char * const reg_note_name[]; (GET_CODE (PATTERN (INSN)) == DEBUG_MARKER \ ? (GET_MODE (PATTERN (INSN)) == VOIDmode \ ? NOTE_INSN_BEGIN_STMT \ + : GET_MODE (PATTERN (INSN)) == BLKmode \ + ? NOTE_INSN_INLINE_ENTRY \ : (enum insn_note)-1) \ : (enum insn_note)-1) /* Create patterns for debug markers. These and the above abstract @@ -1701,6 +1704,8 @@ extern const char * const reg_note_name[]; wouldn't be a problem. */ #define GEN_RTX_DEBUG_MARKER_BEGIN_STMT_PAT() \ gen_rtx_DEBUG_MARKER (VOIDmode) +#define GEN_RTX_DEBUG_MARKER_INLINE_ENTRY_PAT() \ + gen_rtx_DEBUG_MARKER (BLKmode) /* The VAR_LOCATION rtx in a DEBUG_INSN. */ #define INSN_VAR_LOCATION(INSN) \ diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index b0d9beb..7f9ec77 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -4605,6 +4605,13 @@ 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 + && inlined_function_outer_scope_p (id->block)) + { + gimple_stmt_iterator si = gsi_last_bb (bb); + gsi_insert_after (&si, gimple_build_debug_inline_entry + (id->block, input_location), GSI_NEW_STMT); + } if (DECL_INITIAL (fn)) { diff --git a/gcc/tree-ssa-live.c b/gcc/tree-ssa-live.c index 08ac678..26da31f 100644 --- a/gcc/tree-ssa-live.c +++ b/gcc/tree-ssa-live.c @@ -520,6 +520,11 @@ remove_unused_scope_block_p (tree scope, bool in_ctor_dtor_block) else if (!BLOCK_SUPERCONTEXT (scope) || TREE_CODE (BLOCK_SUPERCONTEXT (scope)) == FUNCTION_DECL) unused = false; + /* Preserve the block, it is referenced by at least the inline + entry point marker. */ + else if (debug_nonbind_markers_p + && inlined_function_outer_scope_p (scope)) + unused = false; /* Innermost blocks with no live variables nor statements can be always eliminated. */ else if (!nsubblocks) @@ -548,11 +553,13 @@ remove_unused_scope_block_p (tree scope, bool in_ctor_dtor_block) } else if (BLOCK_VARS (scope) || BLOCK_NUM_NONLOCALIZED_VARS (scope)) unused = false; - /* See if this block is important for representation of inlined function. - Inlined functions are always represented by block with - block_ultimate_origin being set to FUNCTION_DECL and DECL_SOURCE_LOCATION - set... */ - else if (inlined_function_outer_scope_p (scope)) + /* See if this block is important for representation of inlined + function. Inlined functions are always represented by 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 + && inlined_function_outer_scope_p (scope)) unused = false; else /* Verfify that only blocks with source location set @@ -640,6 +647,16 @@ dump_scope_block (FILE *file, int indent, tree scope, dump_flags_t flags) fprintf (file, "#%i", BLOCK_NUMBER (origin)); } } + if (BLOCK_FRAGMENT_ORIGIN (scope)) + fprintf (file, " Fragment of : #%i", + BLOCK_NUMBER (BLOCK_FRAGMENT_ORIGIN (scope))); + else if (BLOCK_FRAGMENT_CHAIN (scope)) + { + fprintf (file, " Fragment chain :"); + for (t = BLOCK_FRAGMENT_CHAIN (scope); t ; + t = BLOCK_FRAGMENT_CHAIN (t)) + fprintf (file, " #%i", BLOCK_NUMBER (t)); + } fprintf (file, " \n"); for (var = BLOCK_VARS (scope); var; var = DECL_CHAIN (var)) { diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c index fbb63db..c3d4dac 100644 --- a/gcc/var-tracking.c +++ b/gcc/var-tracking.c @@ -9959,6 +9959,7 @@ reemit_marker_as_note (rtx_insn *insn) switch (kind) { case NOTE_INSN_BEGIN_STMT: + case NOTE_INSN_INLINE_ENTRY: { rtx_insn *note = NULL; if (cfun->debug_nonbind_markers) -- cgit v1.1 From ebe4bf41d2b96a6b2f1de6a184eb0a7f5c2e5d00 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Fri, 9 Feb 2018 05:46:18 +0000 Subject: re PR c++/83659 (ICE on compilable C++ code: in tree_to_shwi, at tree.c:6821) PR c++/83659 * fold-const.c (fold_indirect_ref_1): Use VECTOR_TYPE_P macro. Formatting fixes. Verify first that tree_fits_poly_int64_p (op01). Sync some changes from cxx_fold_indirect_ref. * constexpr.c (cxx_fold_indirect_ref): Sync some changes from fold_indirect_ref_1, including poly_*int64. Verify first that tree_fits_poly_int64_p (op01). Formatting fixes. * g++.dg/torture/pr83659.C: New test. Co-Authored-By: Jakub Jelinek From-SVN: r257512 --- gcc/ChangeLog | 8 ++++++ gcc/cp/ChangeLog | 8 ++++++ gcc/cp/constexpr.c | 51 +++++++++++++++++++++------------- gcc/fold-const.c | 27 ++++++++++++------ gcc/testsuite/ChangeLog | 6 ++++ gcc/testsuite/g++.dg/torture/pr83659.C | 18 ++++++++++++ 6 files changed, 90 insertions(+), 28 deletions(-) create mode 100644 gcc/testsuite/g++.dg/torture/pr83659.C (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b5e19ed..d9c5443 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2018-02-09 Marek Polacek + Jakub Jelinek + + PR c++/83659 + * fold-const.c (fold_indirect_ref_1): Use VECTOR_TYPE_P macro. + Formatting fixes. Verify first that tree_fits_poly_int64_p (op01). + Sync some changes from cxx_fold_indirect_ref. + 2018-02-09 Alexandre Oliva * cfgexpand.c (expand_gimple_basic_block): Handle inline entry diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index be4db4b..ac53a74 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2018-02-09 Marek Polacek + Jakub Jelinek + + PR c++/83659 + * constexpr.c (cxx_fold_indirect_ref): Sync some changes from + fold_indirect_ref_1, including poly_*int64. Verify first that + tree_fits_poly_int64_p (op01). Formatting fixes. + 2018-02-08 Paolo Carlini * constexpr.c (cxx_eval_component_reference): Use INDIRECT_REF_P. diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index 39a2e1a..7292441 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -3025,9 +3025,10 @@ cxx_eval_vec_init (const constexpr_ctx *ctx, tree t, static tree cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base) { - tree sub, subtype; + tree sub = op0; + tree subtype; + poly_uint64 const_op01; - sub = op0; STRIP_NOPS (sub); subtype = TREE_TYPE (sub); if (!POINTER_TYPE_P (subtype)) @@ -3082,7 +3083,8 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base) { tree part_width = TYPE_SIZE (type); tree index = bitsize_int (0); - return fold_build3_loc (loc, BIT_FIELD_REF, type, op, part_width, index); + return fold_build3_loc (loc, BIT_FIELD_REF, type, op, part_width, + index); } /* Also handle conversion to an empty base class, which is represented with a NOP_EXPR. */ @@ -3107,7 +3109,7 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base) } } else if (TREE_CODE (sub) == POINTER_PLUS_EXPR - && TREE_CODE (TREE_OPERAND (sub, 1)) == INTEGER_CST) + && poly_int_tree_p (TREE_OPERAND (sub, 1), &const_op01)) { tree op00 = TREE_OPERAND (sub, 0); tree op01 = TREE_OPERAND (sub, 1); @@ -3121,29 +3123,37 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base) /* ((foo*)&vectorfoo)[1] => BIT_FIELD_REF */ if (VECTOR_TYPE_P (op00type) - && (same_type_ignoring_top_level_qualifiers_p - (type, TREE_TYPE (op00type)))) + && same_type_ignoring_top_level_qualifiers_p + (type, TREE_TYPE (op00type)) + /* POINTER_PLUS_EXPR second operand is sizetype, unsigned, + but we want to treat offsets with MSB set as negative. + For the code below negative offsets are invalid and + TYPE_SIZE of the element is something unsigned, so + check whether op01 fits into poly_int64, which implies + it is from 0 to INTTYPE_MAXIMUM (HOST_WIDE_INT), and + then just use poly_uint64 because we want to treat the + value as unsigned. */ + && tree_fits_poly_int64_p (op01)) { - HOST_WIDE_INT offset = tree_to_shwi (op01); tree part_width = TYPE_SIZE (type); - unsigned HOST_WIDE_INT part_widthi = tree_to_shwi (part_width)/BITS_PER_UNIT; - unsigned HOST_WIDE_INT indexi = offset * BITS_PER_UNIT; - tree index = bitsize_int (indexi); - - if (known_lt (offset / part_widthi, - TYPE_VECTOR_SUBPARTS (op00type))) - return fold_build3_loc (loc, - BIT_FIELD_REF, type, op00, - part_width, index); - + poly_uint64 max_offset + = (tree_to_uhwi (part_width) / BITS_PER_UNIT + * TYPE_VECTOR_SUBPARTS (op00type)); + if (known_lt (const_op01, max_offset)) + { + tree index = bitsize_int (const_op01 * BITS_PER_UNIT); + return fold_build3_loc (loc, + BIT_FIELD_REF, type, op00, + part_width, index); + } } /* ((foo*)&complexfoo)[1] => __imag__ complexfoo */ else if (TREE_CODE (op00type) == COMPLEX_TYPE && (same_type_ignoring_top_level_qualifiers_p (type, TREE_TYPE (op00type)))) { - tree size = TYPE_SIZE_UNIT (type); - if (tree_int_cst_equal (size, op01)) + if (known_eq (wi::to_poly_offset (TYPE_SIZE_UNIT (type)), + const_op01)) return fold_build1_loc (loc, IMAGPART_EXPR, type, op00); } /* ((foo *)&fooarray)[1] => fooarray[1] */ @@ -3198,7 +3208,8 @@ cxx_fold_indirect_ref (location_t loc, tree type, tree op0, bool *empty_base) { tree type_domain; tree min_val = size_zero_node; - tree newsub = cxx_fold_indirect_ref (loc, TREE_TYPE (subtype), sub, NULL); + tree newsub + = cxx_fold_indirect_ref (loc, TREE_TYPE (subtype), sub, NULL); if (newsub) sub = newsub; else diff --git a/gcc/fold-const.c b/gcc/fold-const.c index c86c3f9..87d00a5 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -14115,6 +14115,7 @@ fold_indirect_ref_1 (location_t loc, tree type, tree op0) { tree op = TREE_OPERAND (sub, 0); tree optype = TREE_TYPE (op); + /* *&CONST_DECL -> to the value of the const decl. */ if (TREE_CODE (op) == CONST_DECL) return DECL_INITIAL (op); @@ -14148,12 +14149,13 @@ fold_indirect_ref_1 (location_t loc, tree type, tree op0) && type == TREE_TYPE (optype)) return fold_build1_loc (loc, REALPART_EXPR, type, op); /* *(foo *)&vectorfoo => BIT_FIELD_REF */ - else if (TREE_CODE (optype) == VECTOR_TYPE + else if (VECTOR_TYPE_P (optype) && type == TREE_TYPE (optype)) { tree part_width = TYPE_SIZE (type); tree index = bitsize_int (0); - return fold_build3_loc (loc, BIT_FIELD_REF, type, op, part_width, index); + return fold_build3_loc (loc, BIT_FIELD_REF, type, op, part_width, + index); } } @@ -14171,8 +14173,17 @@ fold_indirect_ref_1 (location_t loc, tree type, tree op0) op00type = TREE_TYPE (op00); /* ((foo*)&vectorfoo)[1] => BIT_FIELD_REF */ - if (TREE_CODE (op00type) == VECTOR_TYPE - && type == TREE_TYPE (op00type)) + if (VECTOR_TYPE_P (op00type) + && type == TREE_TYPE (op00type) + /* POINTER_PLUS_EXPR second operand is sizetype, unsigned, + but we want to treat offsets with MSB set as negative. + For the code below negative offsets are invalid and + TYPE_SIZE of the element is something unsigned, so + check whether op01 fits into poly_int64, which implies + it is from 0 to INTTYPE_MAXIMUM (HOST_WIDE_INT), and + then just use poly_uint64 because we want to treat the + value as unsigned. */ + && tree_fits_poly_int64_p (op01)) { tree part_width = TYPE_SIZE (type); poly_uint64 max_offset @@ -14199,16 +14210,16 @@ fold_indirect_ref_1 (location_t loc, tree type, tree op0) && type == TREE_TYPE (op00type)) { tree type_domain = TYPE_DOMAIN (op00type); - tree min = size_zero_node; + tree min_val = size_zero_node; if (type_domain && TYPE_MIN_VALUE (type_domain)) - min = TYPE_MIN_VALUE (type_domain); + min_val = TYPE_MIN_VALUE (type_domain); offset_int off = wi::to_offset (op01); offset_int el_sz = wi::to_offset (TYPE_SIZE_UNIT (type)); offset_int remainder; off = wi::divmod_trunc (off, el_sz, SIGNED, &remainder); - if (remainder == 0 && TREE_CODE (min) == INTEGER_CST) + if (remainder == 0 && TREE_CODE (min_val) == INTEGER_CST) { - off = off + wi::to_offset (min); + off = off + wi::to_offset (min_val); op01 = wide_int_to_tree (sizetype, off); return build4_loc (loc, ARRAY_REF, type, op00, op01, NULL_TREE, NULL_TREE); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index dfa8cb8..49a2275 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2018-02-09 Marek Polacek + Jakub Jelinek + + PR c++/83659 + * g++.dg/torture/pr83659.C: New test. + 2018-02-08 David Malcolm PR tree-optimization/84136 diff --git a/gcc/testsuite/g++.dg/torture/pr83659.C b/gcc/testsuite/g++.dg/torture/pr83659.C new file mode 100644 index 0000000..bdcdca2 --- /dev/null +++ b/gcc/testsuite/g++.dg/torture/pr83659.C @@ -0,0 +1,18 @@ +// PR c++/83659 +// { dg-do compile } + +typedef int V __attribute__ ((__vector_size__ (16))); +V a; +V b[2]; + +int +foo () +{ + return reinterpret_cast (&a)[-1] += 1; +} + +int +bar () +{ + return reinterpret_cast (&a[1])[-1]; +} -- cgit v1.1 From ebd06e5ca705e69711eb58277b6f820132bb7b67 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 9 Feb 2018 06:47:24 +0100 Subject: re PR middle-end/84237 (xen build faiulre only zero initializers are allowed in section '.bss.page_aligned.const') PR middle-end/84237 * output.h (bss_initializer_p): Add NAMED argument, defaulted to false. * varasm.c (bss_initializer_p): Add NAMED argument, if true, ignore TREE_READONLY bit. (get_variable_section): For decls in named .bss* sections pass true as second argument to bss_initializer_p. * gcc.dg/pr84237.c: New test. From-SVN: r257513 --- gcc/ChangeLog | 9 +++++++++ gcc/output.h | 2 +- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/pr84237.c | 5 +++++ gcc/varasm.c | 9 +++++---- 5 files changed, 25 insertions(+), 5 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/pr84237.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index d9c5443..cacb10e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2018-02-09 Jakub Jelinek + + PR middle-end/84237 + * output.h (bss_initializer_p): Add NAMED argument, defaulted to false. + * varasm.c (bss_initializer_p): Add NAMED argument, if true, ignore + TREE_READONLY bit. + (get_variable_section): For decls in named .bss* sections pass true as + second argument to bss_initializer_p. + 2018-02-09 Marek Polacek Jakub Jelinek diff --git a/gcc/output.h b/gcc/output.h index 51ac149..f708cc7 100644 --- a/gcc/output.h +++ b/gcc/output.h @@ -552,7 +552,7 @@ extern void output_file_directive (FILE *, const char *); extern unsigned int default_section_type_flags (tree, const char *, int); extern bool have_global_bss_p (void); -extern bool bss_initializer_p (const_tree); +extern bool bss_initializer_p (const_tree, bool = false); extern void default_no_named_section (const char *, unsigned int, tree); extern void default_elf_asm_named_section (const char *, unsigned int, tree); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 49a2275..0177e2b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-02-09 Jakub Jelinek + + PR middle-end/84237 + * gcc.dg/pr84237.c: New test. + 2018-02-09 Marek Polacek Jakub Jelinek diff --git a/gcc/testsuite/gcc.dg/pr84237.c b/gcc/testsuite/gcc.dg/pr84237.c new file mode 100644 index 0000000..5a2697f --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr84237.c @@ -0,0 +1,5 @@ +/* PR middle-end/84237 */ +/* { dg-do compile { target *-*-linux* } } */ +/* { dg-options "" } */ + +const char __attribute__((__section__(".bss.page_aligned.const"), __aligned__(4096))) zero_page[4096]; diff --git a/gcc/varasm.c b/gcc/varasm.c index b045efa..6e345d3 100644 --- a/gcc/varasm.c +++ b/gcc/varasm.c @@ -983,11 +983,11 @@ decode_reg_name (const char *name) /* Return true if DECL's initializer is suitable for a BSS section. */ bool -bss_initializer_p (const_tree decl) +bss_initializer_p (const_tree decl, bool named) { /* Do not put non-common constants into the .bss section, they belong in - a readonly section. */ - return ((!TREE_READONLY (decl) || DECL_COMMON (decl)) + a readonly section, except when NAMED is true. */ + return ((!TREE_READONLY (decl) || DECL_COMMON (decl) || named) && (DECL_INITIAL (decl) == NULL /* In LTO we have no errors in program; error_mark_node is used to mark offlined constructors. */ @@ -1165,7 +1165,8 @@ get_variable_section (tree decl, bool prefer_noswitch_p) { section *sect = get_named_section (decl, NULL, reloc); - if ((sect->common.flags & SECTION_BSS) && !bss_initializer_p (decl)) + if ((sect->common.flags & SECTION_BSS) + && !bss_initializer_p (decl, true)) { error_at (DECL_SOURCE_LOCATION (decl), "only zero initializers are allowed in section %qs", -- cgit v1.1 From e47aebb33fd5372bcb437aba1cc3a078608c388d Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 9 Feb 2018 06:48:33 +0100 Subject: re PR debug/84252 (ICE in get_tracked_reg_offset when building libvpx for aarch64) PR debug/84252 * var-tracking.c (vt_add_function_parameter): Punt for non-onepart PARALLEL incoming that failed vt_get_decl_and_offset check. * gcc.target/aarch64/pr84252.c: New test. From-SVN: r257514 --- gcc/ChangeLog | 4 ++++ gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/gcc.target/aarch64/pr84252.c | 10 ++++++++++ gcc/var-tracking.c | 6 ++++++ 4 files changed, 23 insertions(+) create mode 100644 gcc/testsuite/gcc.target/aarch64/pr84252.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cacb10e..e1945fe 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,9 @@ 2018-02-09 Jakub Jelinek + PR debug/84252 + * var-tracking.c (vt_add_function_parameter): Punt for non-onepart + PARALLEL incoming that failed vt_get_decl_and_offset check. + PR middle-end/84237 * output.h (bss_initializer_p): Add NAMED argument, defaulted to false. * varasm.c (bss_initializer_p): Add NAMED argument, if true, ignore diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 0177e2b..12ccc31 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2018-02-09 Jakub Jelinek + PR debug/84252 + * gcc.target/aarch64/pr84252.c: New test. + PR middle-end/84237 * gcc.dg/pr84237.c: New test. diff --git a/gcc/testsuite/gcc.target/aarch64/pr84252.c b/gcc/testsuite/gcc.target/aarch64/pr84252.c new file mode 100644 index 0000000..fc66a26 --- /dev/null +++ b/gcc/testsuite/gcc.target/aarch64/pr84252.c @@ -0,0 +1,10 @@ +/* PR debug/84252 */ +/* { dg-do compile } */ +/* { dg-options "-g -O2" } */ + +struct S { __Int32x4_t b[2]; }; + +void +foo (struct S x) +{ +} diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c index c3d4dac..fb30ec2 100644 --- a/gcc/var-tracking.c +++ b/gcc/var-tracking.c @@ -9653,6 +9653,7 @@ vt_add_function_parameter (tree parm) poly_int64 offset; dataflow_set *out; decl_or_value dv; + bool incoming_ok = true; if (TREE_CODE (parm) != PARM_DECL) return; @@ -9743,6 +9744,7 @@ vt_add_function_parameter (tree parm) if (!vt_get_decl_and_offset (incoming, &decl, &offset)) { + incoming_ok = false; if (MEM_P (incoming)) { /* This means argument is passed by invisible reference. */ @@ -9861,6 +9863,10 @@ vt_add_function_parameter (tree parm) { int i; + /* The following code relies on vt_get_decl_and_offset returning true for + incoming, which might not be always the case. */ + if (!incoming_ok) + return; for (i = 0; i < XVECLEN (incoming, 0); i++) { rtx reg = XEXP (XVECEXP (incoming, 0, i), 0); -- cgit v1.1 From 9abed7fa75069487de59f84c242d9d11bd276c8d Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 9 Feb 2018 07:44:06 +0100 Subject: re PR sanitizer/84285 (Fail to statically link with -fsanitize=undefined) PR sanitizer/84285 * gcc.c (STATIC_LIBASAN_LIBS, STATIC_LIBTSAN_LIBS, STATIC_LIBLSAN_LIBS, STATIC_LIBUBSAN_LIBS): Handle -static like -static-lib*san. From-SVN: r257515 --- gcc/ChangeLog | 5 +++++ gcc/gcc.c | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index e1945fe..f255810 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,10 @@ 2018-02-09 Jakub Jelinek + PR sanitizer/84285 + * gcc.c (STATIC_LIBASAN_LIBS, STATIC_LIBTSAN_LIBS, + STATIC_LIBLSAN_LIBS, STATIC_LIBUBSAN_LIBS): Handle -static like + -static-lib*san. + PR debug/84252 * var-tracking.c (vt_add_function_parameter): Punt for non-onepart PARALLEL incoming that failed vt_get_decl_and_offset check. diff --git a/gcc/gcc.c b/gcc/gcc.c index f55883a..a716f70 100644 --- a/gcc/gcc.c +++ b/gcc/gcc.c @@ -684,7 +684,7 @@ proper position among the other output files. */ #ifndef LIBASAN_SPEC #define STATIC_LIBASAN_LIBS \ - " %{static-libasan:%:include(libsanitizer.spec)%(link_libasan)}" + " %{static-libasan|static:%:include(libsanitizer.spec)%(link_libasan)}" #ifdef LIBASAN_EARLY_SPEC #define LIBASAN_SPEC STATIC_LIBASAN_LIBS #elif defined(HAVE_LD_STATIC_DYNAMIC) @@ -702,7 +702,7 @@ proper position among the other output files. */ #ifndef LIBTSAN_SPEC #define STATIC_LIBTSAN_LIBS \ - " %{static-libtsan:%:include(libsanitizer.spec)%(link_libtsan)}" + " %{static-libtsan|static:%:include(libsanitizer.spec)%(link_libtsan)}" #ifdef LIBTSAN_EARLY_SPEC #define LIBTSAN_SPEC STATIC_LIBTSAN_LIBS #elif defined(HAVE_LD_STATIC_DYNAMIC) @@ -720,7 +720,7 @@ proper position among the other output files. */ #ifndef LIBLSAN_SPEC #define STATIC_LIBLSAN_LIBS \ - " %{static-liblsan:%:include(libsanitizer.spec)%(link_liblsan)}" + " %{static-liblsan|static:%:include(libsanitizer.spec)%(link_liblsan)}" #ifdef LIBLSAN_EARLY_SPEC #define LIBLSAN_SPEC STATIC_LIBLSAN_LIBS #elif defined(HAVE_LD_STATIC_DYNAMIC) @@ -738,7 +738,7 @@ proper position among the other output files. */ #ifndef LIBUBSAN_SPEC #define STATIC_LIBUBSAN_LIBS \ - " %{static-libubsan:%:include(libsanitizer.spec)%(link_libubsan)}" + " %{static-libubsan|static:%:include(libsanitizer.spec)%(link_libubsan)}" #ifdef HAVE_LD_STATIC_DYNAMIC #define LIBUBSAN_SPEC "%{static-libubsan:" LD_STATIC_OPTION \ "} -lubsan %{static-libubsan:" LD_DYNAMIC_OPTION "}" \ -- cgit v1.1 From 91eb884d75e9007e73855e44a7df83b3721d0825 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 9 Feb 2018 07:44:43 +0100 Subject: re PR tree-optimization/84232 (gcc.dg/tree-ssa/ssa-dom-cse-2.c fail with -march=silvermont) PR tree-optimization/84232 * gcc.dg/tree-ssa/ssa-dom-cse-2.c: Add -mtune-generic on x86. From-SVN: r257516 --- gcc/testsuite/ChangeLog | 3 +++ gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c | 6 ++++-- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 12ccc31..f92919c 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,8 @@ 2018-02-09 Jakub Jelinek + PR tree-optimization/84232 + * gcc.dg/tree-ssa/ssa-dom-cse-2.c: Add -mtune-generic on x86. + PR debug/84252 * gcc.target/aarch64/pr84252.c: New test. diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c index 8606969..e4daa9d 100644 --- a/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-dom-cse-2.c @@ -2,8 +2,10 @@ /* { dg-options "-O3 -fno-tree-fre -fno-tree-pre -fdump-tree-optimized --param sra-max-scalarization-size-Ospeed=32" } */ /* System Z needs hardware vector support for this to work (the optimization gets too complex without it. - { dg-additional-options "-march=z13" { target { s390x-*-* } } } */ - + { dg-additional-options "-march=z13" { target s390x-*-* } } */ +/* Use generic tuning on x86 for the same reasons as why alpha, powerpc etc. are + xfailed below. + { dg-additional-options "-mtune=generic" { target i?86-*-* x86_64-*-* } } */ int foo () -- cgit v1.1 From 8c8b7be5da3fd7a26bdeca99cf307af504543cf3 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Fri, 9 Feb 2018 08:54:54 +0000 Subject: c-ada-spec.c (dump_ada_declaration): Do not generate the 'constant' keyword for components. * c-ada-spec.c (dump_ada_declaration): Do not generate the 'constant' keyword for components. From-SVN: r257517 --- gcc/c-family/ChangeLog | 5 +++++ gcc/c-family/c-ada-spec.c | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 02b2b1a..881df2c 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,8 @@ +2018-02-09 Eric Botcazou + + * c-ada-spec.c (dump_ada_declaration): Do not generate the 'constant' + keyword for components. + 2018-02-02 Paolo Carlini * c-common.h (DECL_UNNAMED_BIT_FIELD): New. diff --git a/gcc/c-family/c-ada-spec.c b/gcc/c-family/c-ada-spec.c index 914ded9..1c1cadc 100644 --- a/gcc/c-family/c-ada-spec.c +++ b/gcc/c-family/c-ada-spec.c @@ -3131,7 +3131,7 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc) { pp_string (buffer, "aliased "); - if (TREE_READONLY (t)) + if (TREE_READONLY (t) && TREE_CODE (t) != FIELD_DECL) pp_string (buffer, "constant "); if (TYPE_NAME (TREE_TYPE (t))) @@ -3147,7 +3147,7 @@ dump_ada_declaration (pretty_printer *buffer, tree t, tree type, int spc) || TREE_CODE (TREE_TYPE (t)) != INTEGER_TYPE)) pp_string (buffer, "aliased "); - if (TREE_READONLY (t)) + if (TREE_READONLY (t) && TREE_CODE (t) != FIELD_DECL) pp_string (buffer, "constant "); dump_generic_ada_node -- cgit v1.1 From cc17f338264be226e2349254cd8db9a35632d2bf Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 9 Feb 2018 09:19:34 +0000 Subject: re PR target/84278 (claims initv4sfv2sf is available but inits through stack) 2018-02-09 Richard Biener PR tree-optimization/84278 * gcc.target/i386/pr84278.c: Adjust regex. From-SVN: r257518 --- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.target/i386/pr84278.c | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f92919c..8772c42 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-02-09 Richard Biener + + PR tree-optimization/84278 + * gcc.target/i386/pr84278.c: Adjust regex. + 2018-02-09 Jakub Jelinek PR tree-optimization/84232 diff --git a/gcc/testsuite/gcc.target/i386/pr84278.c b/gcc/testsuite/gcc.target/i386/pr84278.c index 31e6288..d100dff 100644 --- a/gcc/testsuite/gcc.target/i386/pr84278.c +++ b/gcc/testsuite/gcc.target/i386/pr84278.c @@ -15,4 +15,4 @@ void foo(void) } } -/* { dg-final { scan-assembler-not "\(%.sp\)" } } */ +/* { dg-final { scan-assembler-not "\\\(%.sp\\\)" } } */ -- cgit v1.1 From 8ed6f54304aac6a08b6d14663cbe46e3c47ce25e Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Fri, 9 Feb 2018 09:50:14 +0000 Subject: * expr.c (optimize_bitfield_assignment_op): Remove obsolete assertion. From-SVN: r257519 --- gcc/ChangeLog | 4 ++++ gcc/expr.c | 2 -- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gnat.dg/sso8.adb | 15 +++++++++++++++ gcc/testsuite/gnat.dg/sso8_pkg.ads | 32 ++++++++++++++++++++++++++++++++ 5 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/sso8.adb create mode 100644 gcc/testsuite/gnat.dg/sso8_pkg.ads (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f255810..7ed08fa 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2018-02-09 Eric Botcazou + + * expr.c (optimize_bitfield_assignment_op): Remove obsolete assertion. + 2018-02-09 Jakub Jelinek PR sanitizer/84285 diff --git a/gcc/expr.c b/gcc/expr.c index 36a6c72..876883e 100644 --- a/gcc/expr.c +++ b/gcc/expr.c @@ -4726,8 +4726,6 @@ optimize_bitfield_assignment_op (poly_uint64 pbitsize, } else if (!REG_P (str_rtx) && GET_CODE (str_rtx) != SUBREG) return false; - else - gcc_assert (!reverse); /* If the bit field covers the whole REG/MEM, store_field will likely generate better code. */ diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8772c42..544ebef 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-02-09 Eric Botcazou + + * gnat.dg/sso8.adb: New test. + * gnat.dg/sso8_pkg.ads: New helper. + 2018-02-09 Richard Biener PR tree-optimization/84278 diff --git a/gcc/testsuite/gnat.dg/sso8.adb b/gcc/testsuite/gnat.dg/sso8.adb new file mode 100644 index 0000000..003077c --- /dev/null +++ b/gcc/testsuite/gnat.dg/sso8.adb @@ -0,0 +1,15 @@ +-- { dg-do run } +-- { dg-options "-O" } + +with Interfaces; use Interfaces; +with SSO8_Pkg; use SSO8_Pkg; + +procedure SSO8 is + Data : Rec; +begin + Data.Array_Data (2) := True; + Val8 := Conv (Data); + if Val8 /= 32 then + raise Program_Error; + end if; +end; diff --git a/gcc/testsuite/gnat.dg/sso8_pkg.ads b/gcc/testsuite/gnat.dg/sso8_pkg.ads new file mode 100644 index 0000000..e9227e6 --- /dev/null +++ b/gcc/testsuite/gnat.dg/sso8_pkg.ads @@ -0,0 +1,32 @@ +with Interfaces; +with System; +with Unchecked_Conversion; + +package SSO8_Pkg is + + Val8 : Interfaces.Unsigned_8; + + type Two_Bit_Int is range 0 .. 3; + for Two_Bit_Int'size use 2; + + type Arr is array (1 .. 5) of Boolean; + for Arr'scalar_storage_order use System.High_Order_First; + pragma Pack (Arr); + + type Rec is record + Boolean_Data : Boolean; + Array_Data : Arr; + Two_Bit_Data : Two_Bit_Int; + end record; + for Rec use record + Boolean_Data at 0 range 0 .. 0; + Array_Data at 0 range 1 .. 5; + Two_Bit_Data at 0 range 6 .. 7; + end record; + for Rec'size use 8; + for Rec'bit_order use System.High_Order_First; + for Rec'scalar_storage_order use System.High_Order_First; + + function Conv is new Unchecked_Conversion (Rec, Interfaces.Unsigned_8); + +end SSO8_Pkg; -- cgit v1.1 From c29529aa3dba5ef4e4f6e10452c53af4d25b6454 Mon Sep 17 00:00:00 2001 From: Alexandre Oliva Date: Fri, 9 Feb 2018 10:39:28 +0000 Subject: [LVU] set ppc64 blockage's length to zero LVU requires the zero-length (pseudo) insns's length to reflect reality. If they don't, it may assume there's a PC change where there isn't any, and then a view-aware assembler will detect the problem and complain about out-of-sync views. ppc blockage pseudo-insns did not have the length attribute explicitly set in them, so they inherited the attribute's default value, and that was nonzero. for gcc/ChangeLog * config/rs6000/rs6000.md (blockage): Set length to zero. From-SVN: r257520 --- gcc/ChangeLog | 4 ++++ gcc/config/rs6000/rs6000.md | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7ed08fa..fc3d80c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,7 @@ +2018-02-09 Alexandre Oliva + + * config/rs6000/rs6000.md (blockage): Set length to zero. + 2018-02-09 Eric Botcazou * expr.c (optimize_bitfield_assignment_op): Remove obsolete assertion. diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 33f0d95..8aa4e0e 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -11063,7 +11063,8 @@ (define_insn "blockage" [(unspec_volatile [(const_int 0)] UNSPECV_BLOCK)] "" - "") + "" + [(set_attr "length" "0")]) (define_expand "probe_stack_address" [(use (match_operand 0 "address_operand"))] -- cgit v1.1 From 0805a34d5f2a42052452ccc3ea45fde7975ff417 Mon Sep 17 00:00:00 2001 From: Paolo Carlini Date: Fri, 9 Feb 2018 11:37:14 +0000 Subject: re PR c++/77522 (ICE on invalid code C++14 code: in tsubst_decl, at cp/pt.c:12447) 2018-02-09 Paolo Carlini PR c++/77522 * g++.dg/cpp1y/lambda-init16.C: New. From-SVN: r257521 --- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/cpp1y/lambda-init16.C | 13 +++++++++++++ 2 files changed, 18 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp1y/lambda-init16.C (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 544ebef..ff8136e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-02-09 Paolo Carlini + + PR c++/77522 + * g++.dg/cpp1y/lambda-init16.C: New. + 2018-02-09 Eric Botcazou * gnat.dg/sso8.adb: New test. diff --git a/gcc/testsuite/g++.dg/cpp1y/lambda-init16.C b/gcc/testsuite/g++.dg/cpp1y/lambda-init16.C new file mode 100644 index 0000000..0a40ebb --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/lambda-init16.C @@ -0,0 +1,13 @@ +// PR c++/77522 +// { dg-do compile { target c++14 } } + +template < class T = int > void f (T) +{ + auto g = [&a = f] () {}; // { dg-error "invalid initialization" } +} + +int main () +{ + f (0); + return 0; +} -- cgit v1.1 From c704706201e54b922001b86ecfd81df60772563f Mon Sep 17 00:00:00 2001 From: Andreas Krebbel Date: Fri, 9 Feb 2018 11:42:34 +0000 Subject: S/390: Fix PR84295 gcc/ChangeLog: 2018-02-09 Andreas Krebbel PR target/PR84295 * config/s390/s390.c (s390_set_current_function): Invoke s390_indirect_branch_settings also if fndecl didn't change. gcc/testsuite/ChangeLog: 2018-02-09 Andreas Krebbel PR target/PR84295 * gcc.target/s390/pr84295.c: New test. From-SVN: r257522 --- gcc/ChangeLog | 6 ++++++ gcc/config/s390/s390.c | 5 ++++- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.target/s390/pr84295.c | 14 ++++++++++++++ 4 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/s390/pr84295.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index fc3d80c..7a01d21 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2018-02-09 Andreas Krebbel + + PR target/PR84295 + * config/s390/s390.c (s390_set_current_function): Invoke + s390_indirect_branch_settings also if fndecl didn't change. + 2018-02-09 Alexandre Oliva * config/rs6000/rs6000.md (blockage): Set length to zero. diff --git a/gcc/config/s390/s390.c b/gcc/config/s390/s390.c index 62a60e2..298fdd1 100644 --- a/gcc/config/s390/s390.c +++ b/gcc/config/s390/s390.c @@ -16135,7 +16135,10 @@ s390_set_current_function (tree fndecl) several times in the course of compiling a function, and we don't want to slow things down too much or call target_reinit when it isn't safe. */ if (fndecl == s390_previous_fndecl) - return; + { + s390_indirect_branch_settings (fndecl); + return; + } tree old_tree; if (s390_previous_fndecl == NULL_TREE) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index ff8136e..25c8afc 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-02-09 Andreas Krebbel + + PR target/PR84295 + * gcc.target/s390/pr84295.c: New test. + 2018-02-09 Paolo Carlini PR c++/77522 diff --git a/gcc/testsuite/gcc.target/s390/pr84295.c b/gcc/testsuite/gcc.target/s390/pr84295.c new file mode 100644 index 0000000..4da43c3 --- /dev/null +++ b/gcc/testsuite/gcc.target/s390/pr84295.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* { dg-options "-O3 -march=z900 -fgnu89-inline --save-temps -mfunction-return-reg=thunk -mindirect-branch-table" } */ + +extern void foo (void); +extern __inline void foo (void) {} +void foo (void) {} + +/* { dg-final { scan-assembler-times "jg\t__s390_indirect_jump" 1 } } */ +/* { dg-final { scan-assembler "ex\t" } } */ + +/* { dg-final { scan-assembler-not "section\t.s390_indirect_jump" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_indirect_call" } } */ +/* { dg-final { scan-assembler "section\t.s390_return_reg" } } */ +/* { dg-final { scan-assembler-not "section\t.s390_return_mem" } } */ -- cgit v1.1 From 0079ae8877dfb4be135ac26c21819f4a094f0289 Mon Sep 17 00:00:00 2001 From: Tamar Christina Date: Fri, 9 Feb 2018 12:23:46 +0000 Subject: re PR target/82641 (Unable to enable crc32 for a certain function with target attribute on ARM (aarch32)) 2018-02-09 Tamar Christina PR target/82641 * config/arm/arm-c.c (arm_cpu_builtins): Un-define __ARM_FEATURE_LDREX, __ARM_ARCH_PROFILE, __ARM_ARCH_ISA_THUMB, __ARM_FP and __ARM_NEON_FP. gcc/testsuite 2018-02-09 Tamar Christina PR target/82641 * gcc.target/arm/pragma_arch_switch_2.c: Use armv6 and armv5t. From-SVN: r257524 --- gcc/ChangeLog | 6 ++++++ gcc/config/arm/arm-c.c | 12 ++++++------ gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.target/arm/pragma_arch_switch_2.c | 16 ++++++++-------- 4 files changed, 25 insertions(+), 14 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7a01d21..b112b81 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2018-02-09 Tamar Christina + + PR target/82641 + * config/arm/arm-c.c (arm_cpu_builtins): Un-define __ARM_FEATURE_LDREX, + __ARM_ARCH_PROFILE, __ARM_ARCH_ISA_THUMB, __ARM_FP and __ARM_NEON_FP. + 2018-02-09 Andreas Krebbel PR target/PR84295 diff --git a/gcc/config/arm/arm-c.c b/gcc/config/arm/arm-c.c index 9a16172..7c741e9 100644 --- a/gcc/config/arm/arm-c.c +++ b/gcc/config/arm/arm-c.c @@ -87,11 +87,10 @@ arm_cpu_builtins (struct cpp_reader* pfile) builtin_define ("__ARM_FEATURE_CMSE"); } + cpp_undef (pfile, "__ARM_FEATURE_LDREX"); if (TARGET_ARM_FEATURE_LDREX) builtin_define_with_int_value ("__ARM_FEATURE_LDREX", TARGET_ARM_FEATURE_LDREX); - else - cpp_undef (pfile, "__ARM_FEATURE_LDREX"); def_or_undef_macro (pfile, "__ARM_FEATURE_CLZ", ((TARGET_ARM_ARCH >= 5 && !TARGET_THUMB) @@ -105,6 +104,8 @@ arm_cpu_builtins (struct cpp_reader* pfile) builtin_define_with_int_value ("__ARM_SIZEOF_MINIMAL_ENUM", flag_short_enums ? 1 : 4); builtin_define_type_sizeof ("__ARM_SIZEOF_WCHAR_T", wchar_type_node); + + cpp_undef (pfile, "__ARM_ARCH_PROFILE"); if (TARGET_ARM_ARCH_PROFILE) builtin_define_with_int_value ("__ARM_ARCH_PROFILE", TARGET_ARM_ARCH_PROFILE); @@ -128,6 +129,7 @@ arm_cpu_builtins (struct cpp_reader* pfile) else def_or_undef_macro (pfile, "__THUMBEL__", TARGET_THUMB); + cpp_undef (pfile, "__ARM_ARCH_ISA_THUMB"); if (TARGET_ARM_ARCH_ISA_THUMB) builtin_define_with_int_value ("__ARM_ARCH_ISA_THUMB", TARGET_ARM_ARCH_ISA_THUMB); @@ -147,10 +149,9 @@ arm_cpu_builtins (struct cpp_reader* pfile) builtin_define ("__VFP_FP__"); + cpp_undef (pfile, "__ARM_FP"); if (TARGET_ARM_FP) builtin_define_with_int_value ("__ARM_FP", TARGET_ARM_FP); - else - cpp_undef (pfile, "__ARM_FP"); def_or_undef_macro (pfile, "__ARM_FP16_FORMAT_IEEE", arm_fp16_format == ARM_FP16_FORMAT_IEEE); @@ -169,10 +170,9 @@ arm_cpu_builtins (struct cpp_reader* pfile) def_or_undef_macro (pfile, "__ARM_NEON__", TARGET_NEON); def_or_undef_macro (pfile, "__ARM_NEON", TARGET_NEON); + cpp_undef (pfile, "__ARM_NEON_FP"); if (TARGET_NEON_FP) builtin_define_with_int_value ("__ARM_NEON_FP", TARGET_NEON_FP); - else - cpp_undef (pfile, "__ARM_NEON_FP"); /* Add a define for interworking. Needed when building libgcc.a. */ if (arm_cpp_interwork) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 25c8afc..24751af 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-02-09 Tamar Christina + + PR target/82641 + * gcc.target/arm/pragma_arch_switch_2.c: Use armv6 and armv5t. + 2018-02-09 Andreas Krebbel PR target/PR84295 diff --git a/gcc/testsuite/gcc.target/arm/pragma_arch_switch_2.c b/gcc/testsuite/gcc.target/arm/pragma_arch_switch_2.c index fe52191..7f29755 100644 --- a/gcc/testsuite/gcc.target/arm/pragma_arch_switch_2.c +++ b/gcc/testsuite/gcc.target/arm/pragma_arch_switch_2.c @@ -2,16 +2,16 @@ /* { dg-skip-if "instruction not valid on thumb" { *-*-* } { "-mthumb" } { "" } } */ /* { dg-do assemble } */ /* { dg-require-effective-target arm_arm_ok } */ -/* { dg-additional-options "-Wall -O2 -march=armv4t -std=gnu99 -marm" } */ +/* { dg-additional-options "-Wall -O2 -march=armv5t -std=gnu99 -marm" } */ -#pragma GCC target ("arch=armv5te") -void cpu_has_iwmmxt (void) +#pragma GCC target ("arch=armv6") +int test_assembly (int hi, int lo) { - int lo; - int hi; + int res; __asm__ __volatile__ ( - "mcrr p0, 0, %2, %3, c0\n" - : "=r" (lo), "=r" (hi) - : "r" (0), "r" (0x100)); + "uxtah %0, %1, %2\n" + : "=r" (res) + : "r" (hi), "r" (lo)); + return res; } -- cgit v1.1 From 183187053d0222477cff678be5360597a57ccc6f Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Fri, 9 Feb 2018 12:33:40 +0000 Subject: optabs.c (prepare_cmp_insn): Try harder to emit a direct comparison instead of a libcall for UNORDERED. * optabs.c (prepare_cmp_insn): Try harder to emit a direct comparison instead of a libcall for UNORDERED. From-SVN: r257525 --- gcc/ChangeLog | 5 +++++ gcc/optabs.c | 17 ++++++++++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b112b81..858ad9d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2018-02-09 Eric Botcazou + + * optabs.c (prepare_cmp_insn): Try harder to emit a direct comparison + instead of a libcall for UNORDERED. + 2018-02-09 Tamar Christina PR target/82641 diff --git a/gcc/optabs.c b/gcc/optabs.c index daac545..5f61e4e 100644 --- a/gcc/optabs.c +++ b/gcc/optabs.c @@ -3935,7 +3935,20 @@ prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size, if (methods != OPTAB_LIB_WIDEN) goto fail; - if (!SCALAR_FLOAT_MODE_P (mode)) + if (SCALAR_FLOAT_MODE_P (mode)) + { + /* Small trick if UNORDERED isn't implemented by the hardware. */ + if (comparison == UNORDERED && rtx_equal_p (x, y)) + { + prepare_cmp_insn (x, y, UNLT, NULL_RTX, unsignedp, OPTAB_WIDEN, + ptest, pmode); + if (*ptest) + return; + } + + prepare_float_lib_cmp (x, y, comparison, ptest, pmode); + } + else { rtx result; machine_mode ret_mode; @@ -3982,8 +3995,6 @@ prepare_cmp_insn (rtx x, rtx y, enum rtx_code comparison, rtx size, prepare_cmp_insn (x, y, comparison, NULL_RTX, unsignedp, methods, ptest, pmode); } - else - prepare_float_lib_cmp (x, y, comparison, ptest, pmode); return; -- cgit v1.1 From 7b5925a816f6548e4e49a7947ecedc612d260947 Mon Sep 17 00:00:00 2001 From: Pierre-Marie de Rodat Date: Fri, 9 Feb 2018 14:02:37 +0000 Subject: DWARF: no location for non-definition DECLs with non-trivial DECL_VALUE_EXPR This patch restricts the set of cases in which we allow the generation of location attributes for variables that are not defined in the current unit. For such variables with complex DECL_VALUE_EXPR trees, generating a location attribute can end up creating relocations to text symbols in the debug section of LTO object files, which is not valid. gcc/ PR lto/84213 * dwarf2out.c (is_trivial_indirect_ref): New function. (dwarf2out_late_global_decl): Do not generate a location attribute for variables that have a non-trivial DECL_VALUE_EXPR and that are not defined in the current unit. From-SVN: r257526 --- gcc/ChangeLog | 8 ++++++++ gcc/dwarf2out.c | 31 +++++++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 4 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 858ad9d..1d4a3ee 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2018-02-09 Pierre-Marie de Rodat + + PR lto/84213 + * dwarf2out.c (is_trivial_indirect_ref): New function. + (dwarf2out_late_global_decl): Do not generate a location + attribute for variables that have a non-trivial DECL_VALUE_EXPR + and that are not defined in the current unit. + 2018-02-09 Eric Botcazou * optabs.c (prepare_cmp_insn): Try harder to emit a direct comparison diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 749c7e3..984df9f 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -26235,6 +26235,23 @@ dwarf2out_early_global_decl (tree decl) symtab->global_info_ready = save; } +/* Return whether EXPR is an expression with the following pattern: + INDIRECT_REF (NOP_EXPR (INTEGER_CST)). */ + +static bool +is_trivial_indirect_ref (tree expr) +{ + if (expr == NULL_TREE || TREE_CODE (expr) != INDIRECT_REF) + return false; + + tree nop = TREE_OPERAND (expr, 0); + if (nop == NULL_TREE || TREE_CODE (nop) != NOP_EXPR) + return false; + + tree int_cst = TREE_OPERAND (nop, 0); + return int_cst != NULL_TREE && TREE_CODE (int_cst) == INTEGER_CST; +} + /* Output debug information for global decl DECL. Called from toplev.c after compilation proper has finished. */ @@ -26259,11 +26276,17 @@ dwarf2out_late_global_decl (tree decl) if (die) { /* We get called via the symtab code invoking late_global_decl - for symbols that are optimized out. Do not add locations - for those, except if they have a DECL_VALUE_EXPR, in which case - they are relevant for debuggers. */ + for symbols that are optimized out. + + Do not add locations for those, except if they have a + DECL_VALUE_EXPR, in which case they are relevant for debuggers. + Still don't add a location if the DECL_VALUE_EXPR is not a trivial + INDIRECT_REF expression, as this could generate relocations to + text symbols in LTO object files, which is invalid. */ varpool_node *node = varpool_node::get (decl); - if ((! node || ! node->definition) && ! DECL_HAS_VALUE_EXPR_P (decl)) + if ((! node || ! node->definition) + && ! (DECL_HAS_VALUE_EXPR_P (decl) + && is_trivial_indirect_ref (DECL_VALUE_EXPR (decl)))) tree_add_const_value_attribute_for_decl (die, decl); else add_location_or_const_value_attribute (die, decl, false); -- cgit v1.1 From cc60cad6155362fe0eca87937bccd75d9fca3ec6 Mon Sep 17 00:00:00 2001 From: Sebastian Perta Date: Fri, 9 Feb 2018 16:17:13 +0000 Subject: constraints.md: added new constraint CALL_OP_SYMBOL_REF to allow or block "symbol_ref"... 2018-02-09 Sebastian Perta * config/rx/constraints.md: added new constraint CALL_OP_SYMBOL_REF to allow or block "symbol_ref" depending on value of TARGET_JSR * config/rx/rx.md: use CALL_OP_SYMBOL_REF in call_internal and call_value_internal insns From-SVN: r257529 --- gcc/ChangeLog | 7 ++ gcc/config/rx/constraints.md | 6 ++ gcc/config/rx/rx.md | 4 +- gcc/testsuite/gcc.target/rx/mjsr.c | 134 +++++++++++++++++++++++++++++++++++++ 4 files changed, 149 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/rx/mjsr.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1d4a3ee..02a7ea0 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2018-02-09 Sebastian Perta + + * config/rx/constraints.md: added new constraint CALL_OP_SYMBOL_REF + to allow or block "symbol_ref" depending on value of TARGET_JSR + * config/rx/rx.md: use CALL_OP_SYMBOL_REF in call_internal and + call_value_internal insns + 2018-02-09 Pierre-Marie de Rodat PR lto/84213 diff --git a/gcc/config/rx/constraints.md b/gcc/config/rx/constraints.md index 448fc46..d981f66 100644 --- a/gcc/config/rx/constraints.md +++ b/gcc/config/rx/constraints.md @@ -106,3 +106,9 @@ ) ) ) + +(define_constraint "CALL_OP_SYMBOL_REF" +"constraint for call instructions using symbol ref" +(and (match_test "!TARGET_JSR") + (match_code "symbol_ref")) +) diff --git a/gcc/config/rx/rx.md b/gcc/config/rx/rx.md index e642d73..35263b1 100644 --- a/gcc/config/rx/rx.md +++ b/gcc/config/rx/rx.md @@ -438,7 +438,7 @@ ) (define_insn "call_internal" - [(call (mem:QI (match_operand:SI 0 "rx_call_operand" "r,Symbol")) + [(call (mem:QI (match_operand:SI 0 "rx_call_operand" "r,CALL_OP_SYMBOL_REF")) (const_int 0)) (clobber (reg:CC CC_REG))] "" @@ -466,7 +466,7 @@ (define_insn "call_value_internal" [(set (match_operand 0 "register_operand" "=r,r") - (call (mem:QI (match_operand:SI 1 "rx_call_operand" "r,Symbol")) + (call (mem:QI (match_operand:SI 1 "rx_call_operand" "r,CALL_OP_SYMBOL_REF")) (const_int 0))) (clobber (reg:CC CC_REG))] "" diff --git a/gcc/testsuite/gcc.target/rx/mjsr.c b/gcc/testsuite/gcc.target/rx/mjsr.c new file mode 100644 index 0000000..c73a01b --- /dev/null +++ b/gcc/testsuite/gcc.target/rx/mjsr.c @@ -0,0 +1,134 @@ +/* { dg-do compile } */ +/* { dg-options "-O2 -mjsr" } */ + +void *malloc (__SIZE_TYPE__); +void *realloc (void *, __SIZE_TYPE__); + +struct A { double x, y; }; +struct B { double x0, y0, x1, y1; }; +struct C { int n_points; int dir; struct B bbox; struct A *points; }; +struct D { int n_segs; struct C segs[1]; }; + +void foo (int, int, int *, int, int *, struct A **, int *, int *, + struct D *, int *, struct D **, int *, int **); +int baz (struct A, struct A, struct A, struct A); + +static void +bar (struct D *svp, int *n_points_max, + struct A p, int *seg_map, int *active_segs, int i) +{ + int asi, n_points; + struct C *seg; + + asi = seg_map[active_segs[i]]; + seg = &svp->segs[asi]; + n_points = seg->n_points; + seg->points = ((struct A *) + realloc (seg->points, (n_points_max[asi] <<= 1) * sizeof (struct A))); + seg->points[n_points] = p; + seg->bbox.y1 = p.y; + seg->n_points++; +} + +struct D * +test (struct D *vp) +{ + int *active_segs, n_active_segs, *cursor, seg_idx; + double y, share_x; + int tmp1, tmp2, asi, i, j, *n_ips, *n_ips_max, n_segs_max; + struct A **ips, p_curs, *pts; + struct D *new_vp; + int *n_points_max, *seg_map, first_share; + + n_segs_max = 16; + new_vp = (struct D *) malloc (sizeof (struct D) + + (n_segs_max - 1) * sizeof (struct C)); + new_vp->n_segs = 0; + + if (vp->n_segs == 0) + return new_vp; + + active_segs = ((int *) malloc ((vp->n_segs) * sizeof (int))); + cursor = ((int *) malloc ((vp->n_segs) * sizeof (int))); + + seg_map = ((int *) malloc ((vp->n_segs) * sizeof (int))); + n_ips = ((int *) malloc ((vp->n_segs) * sizeof (int))); + n_ips_max = ((int *) malloc ((vp->n_segs) * sizeof (int))); + ips = ((struct A * *) malloc ((vp->n_segs) * sizeof (struct A *))); + + n_points_max = ((int *) malloc ((n_segs_max) * sizeof (int))); + + n_active_segs = 0; + seg_idx = 0; + y = vp->segs[0].points[0].y; + while (seg_idx < vp->n_segs || n_active_segs > 0) + { + for (i = 0; i < n_active_segs; i++) + { + asi = active_segs[i]; + if (vp->segs[asi].n_points - 1 == cursor[asi] && + vp->segs[asi].points[cursor[asi]].y == y) + i--; + } + + while (seg_idx < vp->n_segs && y == vp->segs[seg_idx].points[0].y) + { + cursor[seg_idx] = 0; + n_ips[seg_idx] = 1; + n_ips_max[seg_idx] = 2; + ips[seg_idx] = + ((struct A *) malloc ((n_ips_max[seg_idx]) * sizeof (struct A))); + ips[seg_idx][0] = vp->segs[seg_idx].points[0]; + pts = ((struct A *) malloc ((16) * sizeof (struct A))); + pts[0] = vp->segs[seg_idx].points[0]; + tmp1 = seg_idx; + for (j = i; j < n_active_segs; j++) + { + tmp2 = active_segs[j]; + active_segs[j] = tmp1; + tmp1 = tmp2; + } + active_segs[n_active_segs] = tmp1; + n_active_segs++; + seg_idx++; + } + first_share = -1; + share_x = 0; + + for (i = 0; i < n_active_segs; i++) + { + asi = active_segs[i]; + p_curs = ips[asi][1]; + if (p_curs.y == y) + { + bar (new_vp, n_points_max, + p_curs, seg_map, active_segs, i); + + n_ips[asi]--; + for (j = 0; j < n_ips[asi]; j++) + ips[asi][j] = ips[asi][j + 1]; + + if (first_share < 0 || p_curs.x != share_x) + { + foo (first_share, i, + active_segs, n_active_segs, + cursor, ips, n_ips, n_ips_max, vp, seg_map, + &new_vp, &n_segs_max, &n_points_max); + first_share = i; + share_x = p_curs.x; + } + } + else + { + foo (first_share, i, + active_segs, n_active_segs, + cursor, ips, n_ips, n_ips_max, vp, seg_map, + &new_vp, &n_segs_max, &n_points_max); + first_share = -1; + } + } + } + return new_vp; +} + +/* { dg-final { scan-assembler-not "bsr" } } */ -- cgit v1.1 From da86c81e6522f9b27cffd04f728e0edd937d09fc Mon Sep 17 00:00:00 2001 From: Peter Bergner Date: Fri, 9 Feb 2018 10:32:37 -0600 Subject: re PR target/83926 (ICE during RTL pass: ira, in elimination_costs_in_insn, at reload1.c:3633) gcc/ PR target/83926 * config/rs6000/vsx.md (vsx_mul_v2di): Handle generating a 64-bit multiply in 32-bit mode. (vsx_div_v2di): Handle generating a 64-bit signed divide in 32-bit mode. (vsx_udiv_v2di): Handle generating a 64-bit unsigned divide in 32-bit mode. gcc/testsuite/ PR target/83926 * gcc.target/powerpc/pr83926.c: New test. * gcc.target/powerpc/builtins-1-be.c: Filter out gimple folding disabled message. Fix test for running in 32-bit mode. From-SVN: r257531 --- gcc/ChangeLog | 9 ++++ gcc/config/rs6000/vsx.md | 64 +++++++++++++++++++--- gcc/testsuite/ChangeLog | 7 +++ gcc/testsuite/gcc.target/powerpc/builtins-1-be.c | 68 +++++++++++++----------- gcc/testsuite/gcc.target/powerpc/pr83926.c | 22 ++++++++ 5 files changed, 133 insertions(+), 37 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/pr83926.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 02a7ea0..c42ffa6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2018-02-09 Peter Bergner + + PR target/83926 + * config/rs6000/vsx.md (vsx_mul_v2di): Handle generating a 64-bit + multiply in 32-bit mode. + (vsx_div_v2di): Handle generating a 64-bit signed divide in 32-bit mode. + (vsx_udiv_v2di): Handle generating a 64-bit unsigned divide in 32-bit + mode. + 2018-02-09 Sebastian Perta * config/rx/constraints.md: added new constraint CALL_OP_SYMBOL_REF diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md index c2016f1..86efdce 100644 --- a/gcc/config/rs6000/vsx.md +++ b/gcc/config/rs6000/vsx.md @@ -1650,10 +1650,22 @@ rtx op5 = gen_reg_rtx (DImode); emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (0))); emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (0))); - emit_insn (gen_muldi3 (op5, op3, op4)); + if (TARGET_POWERPC64) + emit_insn (gen_muldi3 (op5, op3, op4)); + else + { + rtx ret = expand_mult (DImode, op3, op4, NULL, 0, false); + emit_move_insn (op5, ret); + } emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (1))); emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (1))); - emit_insn (gen_muldi3 (op3, op3, op4)); + if (TARGET_POWERPC64) + emit_insn (gen_muldi3 (op3, op3, op4)); + else + { + rtx ret = expand_mult (DImode, op3, op4, NULL, 0, false); + emit_move_insn (op3, ret); + } emit_insn (gen_vsx_concat_v2di (op0, op5, op3)); DONE; }" @@ -1688,10 +1700,30 @@ rtx op5 = gen_reg_rtx (DImode); emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (0))); emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (0))); - emit_insn (gen_divdi3 (op5, op3, op4)); + if (TARGET_POWERPC64) + emit_insn (gen_divdi3 (op5, op3, op4)); + else + { + rtx libfunc = optab_libfunc (sdiv_optab, DImode); + rtx target = emit_library_call_value (libfunc, + op5, LCT_NORMAL, DImode, + op3, DImode, + op4, DImode); + emit_move_insn (op5, target); + } emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (1))); emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (1))); - emit_insn (gen_divdi3 (op3, op3, op4)); + if (TARGET_POWERPC64) + emit_insn (gen_divdi3 (op3, op3, op4)); + else + { + rtx libfunc = optab_libfunc (sdiv_optab, DImode); + rtx target = emit_library_call_value (libfunc, + op3, LCT_NORMAL, DImode, + op3, DImode, + op4, DImode); + emit_move_insn (op3, target); + } emit_insn (gen_vsx_concat_v2di (op0, op5, op3)); DONE; }" @@ -1716,10 +1748,30 @@ rtx op5 = gen_reg_rtx (DImode); emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (0))); emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (0))); - emit_insn (gen_udivdi3 (op5, op3, op4)); + if (TARGET_POWERPC64) + emit_insn (gen_udivdi3 (op5, op3, op4)); + else + { + rtx libfunc = optab_libfunc (udiv_optab, DImode); + rtx target = emit_library_call_value (libfunc, + op5, LCT_NORMAL, DImode, + op3, DImode, + op4, DImode); + emit_move_insn (op5, target); + } emit_insn (gen_vsx_extract_v2di (op3, op1, GEN_INT (1))); emit_insn (gen_vsx_extract_v2di (op4, op2, GEN_INT (1))); - emit_insn (gen_udivdi3 (op3, op3, op4)); + if (TARGET_POWERPC64) + emit_insn (gen_udivdi3 (op3, op3, op4)); + else + { + rtx libfunc = optab_libfunc (udiv_optab, DImode); + rtx target = emit_library_call_value (libfunc, + op3, LCT_NORMAL, DImode, + op3, DImode, + op4, DImode); + emit_move_insn (op3, target); + } emit_insn (gen_vsx_concat_v2di (op0, op5, op3)); DONE; }" diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 24751af..f381e22 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2018-02-09 Peter Bergner + + PR target/83926 + * gcc.target/powerpc/pr83926.c: New test. + * gcc.target/powerpc/builtins-1-be.c: Filter out gimple folding disabled + message. Fix test for running in 32-bit mode. + 2018-02-09 Tamar Christina PR target/82641 diff --git a/gcc/testsuite/gcc.target/powerpc/builtins-1-be.c b/gcc/testsuite/gcc.target/powerpc/builtins-1-be.c index aaaf79d..fb80766 100644 --- a/gcc/testsuite/gcc.target/powerpc/builtins-1-be.c +++ b/gcc/testsuite/gcc.target/powerpc/builtins-1-be.c @@ -1,6 +1,7 @@ /* { dg-do compile { target { powerpc64-*-* } } } */ /* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ -/* { dg-options "-mcpu=power8 -O0 -mno-fold-gimple" } */ +/* { dg-options "-mcpu=power8 -O0 -mno-fold-gimple -dp" } */ +/* { dg-prune-output "gimple folding of rs6000 builtins has been disabled." } */ /* Test that a number of newly added builtin overloads are accepted by the compiler. */ @@ -22,10 +23,10 @@ vec_ctf xvmuldp vec_cts xvcvdpsxds, vctsxs vec_ctu xvcvdpuxds, vctuxs - vec_div divd, divdu + vec_div divd, divdu | __divdi3(), __udivdi3() vec_mergel vmrghb, vmrghh, xxmrghw vec_mergeh xxmrglw, vmrglh - vec_mul mulld + vec_mul mulld | mullw, mulhwu vec_nor xxlnor vec_or xxlor vec_packsu vpksdus @@ -36,34 +37,39 @@ vec_rsqrt xvrsqrtesp vec_rsqrte xvrsqrtesp */ -/* { dg-final { scan-assembler-times "vcmpequd." 4 } } */ -/* { dg-final { scan-assembler-times "vcmpgtud." 8 } } */ -/* { dg-final { scan-assembler-times "xxland" 29 } } */ -/* { dg-final { scan-assembler-times "vclzb" 2 } } */ -/* { dg-final { scan-assembler-times "vclzb" 2 } } */ -/* { dg-final { scan-assembler-times "vclzw" 2 } } */ -/* { dg-final { scan-assembler-times "vclzh" 2 } } */ -/* { dg-final { scan-assembler-times "xvcpsgnsp" 1 } } */ -/* { dg-final { scan-assembler-times "xvmuldp" 6 } } */ -/* { dg-final { scan-assembler-times "xvcvdpsxds" 1 } } */ -/* { dg-final { scan-assembler-times "vctsxs" 1 } } */ -/* { dg-final { scan-assembler-times "xvcvdpuxds" 1 } } */ -/* { dg-final { scan-assembler-times "vctuxs" 1 } } */ -/* { dg-final { scan-assembler-times "divd" 4 } } */ -/* { dg-final { scan-assembler-times "divdu" 2 } } */ -/* { dg-final { scan-assembler-times "vmrghb" 0 } } */ -/* { dg-final { scan-assembler-times "vmrghh" 3 } } */ -/* { dg-final { scan-assembler-times "xxmrghw" 1 } } */ -/* { dg-final { scan-assembler-times "xxmrglw" 4 } } */ -/* { dg-final { scan-assembler-times "vmrglh" 4 } } */ -/* { dg-final { scan-assembler-times "mulld" 4 } } */ -/* { dg-final { scan-assembler-times "xxlnor" 19 } } */ -/* { dg-final { scan-assembler-times "xxlor" 14 } } */ -/* { dg-final { scan-assembler-times "vpksdus" 1 } } */ -/* { dg-final { scan-assembler-times "vperm" 2 } } */ -/* { dg-final { scan-assembler-times "xvrdpi" 1 } } */ -/* { dg-final { scan-assembler-times "xxsel" 6 } } */ -/* { dg-final { scan-assembler-times "xxlxor" 6 } } */ +/* { dg-final { scan-assembler-times {\mvcmpequd\M\.} 4 } } */ +/* { dg-final { scan-assembler-times {\mvcmpgtud\M\.} 8 } } */ +/* { dg-final { scan-assembler-times {\mxxland\M} 16 } } */ +/* { dg-final { scan-assembler-times {\mxxlandc\M} 13 } } */ +/* { dg-final { scan-assembler-times {\mvclzb\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mvclzb\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mvclzw\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mvclzh\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mxvcpsgnsp\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvmuldp\M} 6 } } */ +/* { dg-final { scan-assembler-times {\mxvcvdpsxds\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mvctsxs\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxvcvdpuxds\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mvctuxs\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mvmrghb\M} 0 } } */ +/* { dg-final { scan-assembler-times {\mvmrghh\M} 3 } } */ +/* { dg-final { scan-assembler-times {\mxxmrghw\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxxmrglw\M} 4 } } */ +/* { dg-final { scan-assembler-times {\mvmrglh\M} 4 } } */ +/* { dg-final { scan-assembler-times {\mxxlnor\M} 6 } } */ +/* { dg-final { scan-assembler-times {(?n)\mxxlor\M.*\mboolv4si3_internal\M} 6 } } */ +/* { dg-final { scan-assembler-times {\mvpksdus\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mvperm\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mxvrdpi\M} 1 } } */ +/* { dg-final { scan-assembler-times {\mxxsel\M} 6 } } */ +/* { dg-final { scan-assembler-times {\mxxlxor\M} 6 } } */ +/* { dg-final { scan-assembler-times {\mdivd\M} 2 { target lp64 } } } */ +/* { dg-final { scan-assembler-times {\mdivdu\M} 2 { target lp64 } } } */ +/* { dg-final { scan-assembler-times {\mmulld\M} 4 { target lp64 } } } */ +/* { dg-final { scan-assembler-times {\mbl __divdi3\M} 2 { target ilp32 } } } */ +/* { dg-final { scan-assembler-times {\mbl __udivdi3\M} 2 { target ilp32 } } } */ +/* { dg-final { scan-assembler-times {\mmullw\M} 12 { target ilp32 } } } */ +/* { dg-final { scan-assembler-times {\mmulhwu\M} 4 { target ilp32 } } } */ /* The source code for the test is in builtins-1.h. */ #include "builtins-1.h" diff --git a/gcc/testsuite/gcc.target/powerpc/pr83926.c b/gcc/testsuite/gcc.target/powerpc/pr83926.c new file mode 100644 index 0000000..3188ade --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr83926.c @@ -0,0 +1,22 @@ +/* { dg-do compile { target { powerpc*-*-* } } } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ +/* { dg-options "-O2 -mcpu=power8 -mno-fold-gimple" } */ + +__attribute__ ((altivec(vector__))) long long +sdiv (__attribute__ ((altivec(vector__))) long long a, + __attribute__ ((altivec(vector__))) long long b) +{ + return __builtin_vsx_div_2di (a, b); +} +__attribute__ ((altivec(vector__))) unsigned long long +udiv (__attribute__ ((altivec(vector__))) unsigned long long a, + __attribute__ ((altivec(vector__))) unsigned long long b) +{ + return __builtin_vsx_udiv_2di (a, b); +} +__attribute__ ((altivec(vector__))) long long +smul (__attribute__ ((altivec(vector__))) long long a, + __attribute__ ((altivec(vector__))) long long b) +{ + return __builtin_vsx_mul_2di (a, b); +} -- cgit v1.1 From cad5b07905fb24447dced464b6f60b70178f2fea Mon Sep 17 00:00:00 2001 From: Sebastian Perta Date: Fri, 9 Feb 2018 17:43:11 +0000 Subject: rx.md: updated "movsicc" expand to be matched by GCC 2018-02-09 Sebastian Perta *config/rx.md: updated "movsicc" expand to be matched by GCC *testsuite/gcc.target/rx/movsicc.c: new test case From-SVN: r257533 --- gcc/ChangeLog | 5 ++ gcc/config/rx/rx.md | 7 ++- gcc/testsuite/gcc.target/rx/movsicc.c | 94 +++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.target/rx/movsicc.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index c42ffa6..7f19858 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2018-02-09 Sebastian Perta + + *config/rx.md: updated "movsicc" expand to be matched by GCC + *testsuite/gcc.target/rx/movsicc.c: new test case + 2018-02-09 Peter Bergner PR target/83926 diff --git a/gcc/config/rx/rx.md b/gcc/config/rx/rx.md index 35263b1..3fb2ac8 100644 --- a/gcc/config/rx/rx.md +++ b/gcc/config/rx/rx.md @@ -733,12 +733,17 @@ (define_expand "movsicc" [(parallel [(set (match_operand:SI 0 "register_operand") - (if_then_else:SI (match_operand:SI 1 "comparison_operator") + (if_then_else:SI (match_operand 1 "comparison_operator") (match_operand:SI 2 "nonmemory_operand") (match_operand:SI 3 "nonmemory_operand"))) (clobber (reg:CC CC_REG))])] "" { + /* Make sure that we have an integer comparison... */ + if (GET_MODE (XEXP (operands[1], 0)) != CCmode + && GET_MODE (XEXP (operands[1], 0)) != SImode) + FAIL; + /* One operand must be a constant or a register, the other must be a register. */ if ( ! CONSTANT_P (operands[2]) && ! CONSTANT_P (operands[3]) diff --git a/gcc/testsuite/gcc.target/rx/movsicc.c b/gcc/testsuite/gcc.target/rx/movsicc.c new file mode 100644 index 0000000..d8e6bcc --- /dev/null +++ b/gcc/testsuite/gcc.target/rx/movsicc.c @@ -0,0 +1,94 @@ +/* { dg-do compile } */ +/* { dg-options "-Os" } */ + +typedef unsigned char u8; +typedef unsigned short u16; +signed int Xa, Xb; + +signed int stzreg_beq(int i, int a, int b) +{ + signed int x; + x = a; + if (i) + x = b; + return x; +} + +/* { dg-final { scan-assembler "bne 1f" } } */ + +signed int stzreg_bge(int i, int a, int b, int c) +{ + signed int x; + x = a; + if (i0) + x = b; + return x; +} + +/* { dg-final { scan-assembler "bgt 1f" } } */ + +signed int stzreg_blt(int i, int a, int b) +{ + signed int x; + x = a; + if (i<0) + x = b; + return x; +} + +/* { dg-final { scan-assembler "blt 1f" } } */ + +signed int stzreg_bne(int i, int a, int b) +{ + signed int x; + x = a; + if (!i) + x = b; + return x; +} + +/* { dg-final { scan-assembler "beq 1f" } } */ + +signed int stzimm_le( int i, int a ) +{ + signed int x; + x = a; + if (i>0) + x = 5; + return x; +} + +/* { dg-final { scan-assembler "ble 1f" } } */ + +signed int stzimm_le_r( int i, int a ) +{ + signed int x; + x = a; + if (i<0) + x = 5; + return x; +} + +/* { dg-final { scan-assembler "bge 1f" } } */ -- cgit v1.1 From cea71f0a97520aeeba6509688047311a75f35421 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Fri, 9 Feb 2018 17:58:54 +0000 Subject: PR lto/84212 - -Wno-* does not disable warnings from -flto link stage gcc/c-family/ChangeLog: PR lto/84212 * c.opt (-Wstringop-overflow, -Warray-bounds): Add LTO. (-Walloc-size-larger-than, -Wformat-truncation=): Same. (-Wmaybe-uninitialized, -Wnonnull, -Wrestrict): Same. (-Wstrict-overflow, -Wsuggest-attribute): Same. (-Wuninitialized): Same. gcc/testsuite/ChangeLog: PR lto/84212 * gcc.dg/lto/pr84212_0.c: New test file. * gcc.dg/lto/pr84212_1.c: Same. From-SVN: r257534 --- gcc/c-family/ChangeLog | 9 +++++++++ gcc/c-family/c.opt | 24 ++++++++++++------------ gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/gcc.dg/lto/pr84212_0.c | 11 +++++++++++ gcc/testsuite/gcc.dg/lto/pr84212_1.c | 11 +++++++++++ 5 files changed, 49 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/lto/pr84212_0.c create mode 100644 gcc/testsuite/gcc.dg/lto/pr84212_1.c (limited to 'gcc') diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 881df2c..2378181 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,12 @@ +2018-02-09 Martin Sebor + + PR lto/84212 + * c.opt (-Wstringop-overflow, -Warray-bounds): Add LTO. + (-Walloc-size-larger-than, -Wformat-truncation=): Same. + (-Wmaybe-uninitialized, -Wnonnull, -Wrestrict): Same. + (-Wstrict-overflow, -Wsuggest-attribute): Same. + (-Wuninitialized): Same. + 2018-02-09 Eric Botcazou * c-ada-spec.c (dump_ada_declaration): Do not generate the 'constant' diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt index 9c71726..7fb386d 100644 --- a/gcc/c-family/c.opt +++ b/gcc/c-family/c.opt @@ -304,7 +304,7 @@ C ObjC C++ ObjC++ Var(warn_alloca) Warning Warn on any use of alloca. Walloc-size-larger-than= -C ObjC C++ ObjC++ Var(warn_alloc_size_limit) Warning Joined LangEnabledBy(C ObjC C++ ObjC++,Wall) +C ObjC C++ LTO ObjC++ Var(warn_alloc_size_limit) Warning Joined LangEnabledBy(C ObjC C++ LTO ObjC++,Wall) -Walloc-size-larger-than= Warn for calls to allocation functions that attempt to allocate objects larger than the specified number of bytes. @@ -319,11 +319,11 @@ alloca, and on bounded uses of alloca whose bound can be larger than bytes. Warray-bounds -LangEnabledBy(C ObjC C++ ObjC++,Wall) +LangEnabledBy(C ObjC C++ LTO ObjC++,Wall) ; in common.opt Warray-bounds= -LangEnabledBy(C ObjC C++ ObjC++,Wall,1,0) +LangEnabledBy(C ObjC C++ LTO ObjC++,Wall,1,0) ; in common.opt Wassign-intercept @@ -575,12 +575,12 @@ C ObjC C++ ObjC++ Joined RejectNegative UInteger Var(warn_format) Warning LangEn Warn about printf/scanf/strftime/strfmon format string anomalies. Wformat-overflow= -C ObjC C++ LTO ObjC++ Joined RejectNegative UInteger Var(warn_format_overflow) Warning LangEnabledBy(C ObjC C++ ObjC++,Wformat=, warn_format >= 1, 0) IntegerRange(0, 2) +C ObjC C++ LTO ObjC++ Joined RejectNegative UInteger Var(warn_format_overflow) Warning LangEnabledBy(C ObjC C++ LTO ObjC++,Wformat=, warn_format >= 1, 0) IntegerRange(0, 2) Warn about function calls with format strings that write past the end of the destination region. Wformat-truncation= -C ObjC C++ ObjC++ Joined RejectNegative UInteger Var(warn_format_trunc) Warning LangEnabledBy(C ObjC C++ ObjC++,Wformat=, warn_format >= 1, 0) IntegerRange(0, 2) +C ObjC C++ LTO ObjC++ Joined RejectNegative UInteger Var(warn_format_trunc) Warning LangEnabledBy(C ObjC C++ LTO ObjC++,Wformat=, warn_format >= 1, 0) IntegerRange(0, 2) Warn about calls to snprintf and similar functions that truncate output. Wif-not-aligned @@ -739,17 +739,17 @@ C ObjC C++ ObjC++ Var(warn_sizeof_array_argument) Warning Init(1) Warn when sizeof is applied on a parameter declared as an array. Wstringop-overflow -C ObjC C++ ObjC++ Warning Alias(Wstringop-overflow=, 2, 0) +C ObjC C++ LTO ObjC++ Warning Alias(Wstringop-overflow=, 2, 0) Warn about buffer overflow in string manipulation functions like memcpy and strcpy. Wstringop-overflow= -C ObjC C++ ObjC++ Joined RejectNegative UInteger Var(warn_stringop_overflow) Init(2) Warning LangEnabledBy(C ObjC C++ ObjC++, Wall, 2, 0) IntegerRange(0, 4) +C ObjC C++ LTO ObjC++ Joined RejectNegative UInteger Var(warn_stringop_overflow) Init(2) Warning LangEnabledBy(C ObjC C++ LTO ObjC++, Wall, 2, 0) IntegerRange(0, 4) Under the control of Object Size type, warn about buffer overflow in string manipulation functions like memcpy and strcpy. Wstringop-truncation -C ObjC C++ ObjC++ Var(warn_stringop_truncation) Warning Init (1) LangEnabledBy(C ObjC C++ ObjC++, Wall) +C ObjC C++ LTO ObjC++ Var(warn_stringop_truncation) Warning Init (1) LangEnabledBy(C ObjC C++ LTO ObjC++, Wall) Warn about truncation in string manipulation functions like strncat and strncpy. Wsuggest-attribute=format @@ -833,11 +833,11 @@ C++ ObjC++ Var(warn_nonvdtor) Warning LangEnabledBy(C++ ObjC++,Weffc++) Warn about non-virtual destructors. Wnonnull -C ObjC C++ ObjC++ Var(warn_nonnull) Warning LangEnabledBy(C ObjC C++ ObjC++,Wformat=,warn_format >= 1,0) +C ObjC C++ LTO ObjC++ Var(warn_nonnull) Warning LangEnabledBy(C ObjC C++ LTO ObjC++,Wformat=,warn_format >= 1,0) Warn about NULL being passed to argument slots marked as requiring non-NULL. Wnonnull -C ObjC C++ ObjC++ LangEnabledBy(C ObjC C++ ObjC++,Wall) +C ObjC C++ LTO ObjC++ LangEnabledBy(C ObjC C++ LTO ObjC++,Wall) ; Wnonnull-compare @@ -1084,11 +1084,11 @@ C ObjC C++ ObjC++ CPP(warn_undef) CppReason(CPP_W_UNDEF) Var(cpp_warn_undef) Ini Warn if an undefined macro is used in an #if directive. Wuninitialized -C ObjC C++ ObjC++ LangEnabledBy(C ObjC C++ ObjC++,Wall) +C ObjC C++ ObjC++ LTO LangEnabledBy(C ObjC C++ ObjC++ LTO,Wall) ; Wmaybe-uninitialized -C ObjC C++ ObjC++ LangEnabledBy(C ObjC C++ ObjC++,Wall) +C ObjC C++ ObjC++ LTO LangEnabledBy(C ObjC C++ ObjC++ LTO,Wall) ; Wunknown-pragmas diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index f381e22..c303895 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2018-02-09 Martin Sebor + + PR lto/84212 + * gcc.dg/lto/pr84212_0.c: New test file. + * gcc.dg/lto/pr84212_1.c: Same. + 2018-02-09 Peter Bergner PR target/83926 diff --git a/gcc/testsuite/gcc.dg/lto/pr84212_0.c b/gcc/testsuite/gcc.dg/lto/pr84212_0.c new file mode 100644 index 0000000..859b2fa --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr84212_0.c @@ -0,0 +1,11 @@ +/* PR lto/84212 - -Wno-stringop-verflow does not disable warnings from + -flto link stage + { dg-lto-do link } + { dg-lto-options { { -O2 -Werror -Wno-stringop-overflow -flto } } } */ + +#include + +void clear (char *p, unsigned n) +{ + memset (p, 0, n); +} diff --git a/gcc/testsuite/gcc.dg/lto/pr84212_1.c b/gcc/testsuite/gcc.dg/lto/pr84212_1.c new file mode 100644 index 0000000..7ad8a7d --- /dev/null +++ b/gcc/testsuite/gcc.dg/lto/pr84212_1.c @@ -0,0 +1,11 @@ +/* PR lto/84212 - -Wno-stringop-verflow does not disable warnings from + -flto link stage */ + +extern void clear (char*, unsigned); + +int main (void) +{ + char x[3]; + + clear (x, 4); +} -- cgit v1.1 From e3056dd850922fe1d13d3a69ceb6ea24f1fbac1d Mon Sep 17 00:00:00 2001 From: Peter Bergner Date: Fri, 9 Feb 2018 12:02:15 -0600 Subject: builtins-1-be.c: Rename duplicate test from this to... * gcc.target/powerpc/builtins-1-be.c : Rename duplicate test from this to... : ...this. From-SVN: r257535 --- gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/gcc.target/powerpc/builtins-1-be.c | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index c303895..4536b53 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2018-02-09 Peter Bergner + + * gcc.target/powerpc/builtins-1-be.c : Rename duplicate test + from this to... + : ...this. + 2018-02-09 Martin Sebor PR lto/84212 diff --git a/gcc/testsuite/gcc.target/powerpc/builtins-1-be.c b/gcc/testsuite/gcc.target/powerpc/builtins-1-be.c index fb80766..9de8baf 100644 --- a/gcc/testsuite/gcc.target/powerpc/builtins-1-be.c +++ b/gcc/testsuite/gcc.target/powerpc/builtins-1-be.c @@ -42,7 +42,7 @@ /* { dg-final { scan-assembler-times {\mxxland\M} 16 } } */ /* { dg-final { scan-assembler-times {\mxxlandc\M} 13 } } */ /* { dg-final { scan-assembler-times {\mvclzb\M} 2 } } */ -/* { dg-final { scan-assembler-times {\mvclzb\M} 2 } } */ +/* { dg-final { scan-assembler-times {\mvclzd\M} 2 } } */ /* { dg-final { scan-assembler-times {\mvclzw\M} 2 } } */ /* { dg-final { scan-assembler-times {\mvclzh\M} 2 } } */ /* { dg-final { scan-assembler-times {\mxvcpsgnsp\M} 1 } } */ -- cgit v1.1 From d6126f8b8250b857f3e0edfd42f3c33d8534b9a4 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 9 Feb 2018 19:19:08 +0100 Subject: re PR target/84226 (ICE in simplify_const_unary_operation, at simplify-rtx.c:1974 on ppc64le) PR target/84226 * config/rs6000/vsx.md (p9_xxbrq_v16qi): Change input operand constraint from =wa to wa. Avoid a subreg on the output operand, instead use a pseudo and subreg it in a move. (p9_xxbrd_): Changed to ... (p9_xxbrd_v2di): ... this insn, without VSX_D iterator. (p9_xxbrd_v2df): New expander. (p9_xxbrw_): Changed to ... (p9_xxbrw_v4si): ... this insn, without VSX_W iterator. (p9_xxbrw_v4sf): New expander. * gcc.target/powerpc/pr84226.c: New test. From-SVN: r257536 --- gcc/ChangeLog | 17 +++++++++-- gcc/config/rs6000/vsx.md | 45 +++++++++++++++++++++++------- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.target/powerpc/pr84226.c | 6 ++++ 4 files changed, 61 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/pr84226.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 7f19858..4ac7fff 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,7 +1,20 @@ +2018-02-09 Jakub Jelinek + + PR target/84226 + * config/rs6000/vsx.md (p9_xxbrq_v16qi): Change input operand + constraint from =wa to wa. Avoid a subreg on the output operand, + instead use a pseudo and subreg it in a move. + (p9_xxbrd_): Changed to ... + (p9_xxbrd_v2di): ... this insn, without VSX_D iterator. + (p9_xxbrd_v2df): New expander. + (p9_xxbrw_): Changed to ... + (p9_xxbrw_v4si): ... this insn, without VSX_W iterator. + (p9_xxbrw_v4sf): New expander. + 2018-02-09 Sebastian Perta - *config/rx.md: updated "movsicc" expand to be matched by GCC - *testsuite/gcc.target/rx/movsicc.c: new test case + * config/rx.md: updated "movsicc" expand to be matched by GCC + * testsuite/gcc.target/rx/movsicc.c: new test case 2018-02-09 Peter Bergner diff --git a/gcc/config/rs6000/vsx.md b/gcc/config/rs6000/vsx.md index 86efdce..6f0bd09 100644 --- a/gcc/config/rs6000/vsx.md +++ b/gcc/config/rs6000/vsx.md @@ -5363,35 +5363,60 @@ (define_expand "p9_xxbrq_v16qi" [(use (match_operand:V16QI 0 "vsx_register_operand" "=wa")) - (use (match_operand:V16QI 1 "vsx_register_operand" "=wa"))] + (use (match_operand:V16QI 1 "vsx_register_operand" "wa"))] "TARGET_P9_VECTOR" { - rtx op0 = gen_lowpart (V1TImode, operands[0]); + rtx op0 = gen_reg_rtx (V1TImode); rtx op1 = gen_lowpart (V1TImode, operands[1]); emit_insn (gen_p9_xxbrq_v1ti (op0, op1)); + emit_move_insn (operands[0], gen_lowpart (V16QImode, op0)); DONE; }) ;; Swap all bytes in each 64-bit element -(define_insn "p9_xxbrd_" - [(set (match_operand:VSX_D 0 "vsx_register_operand" "=wa") - (bswap:VSX_D (match_operand:VSX_D 1 "vsx_register_operand" "wa")))] +(define_insn "p9_xxbrd_v2di" + [(set (match_operand:V2DI 0 "vsx_register_operand" "=wa") + (bswap:V2DI (match_operand:V2DI 1 "vsx_register_operand" "wa")))] "TARGET_P9_VECTOR" "xxbrd %x0,%x1" [(set_attr "type" "vecperm")]) +(define_expand "p9_xxbrd_v2df" + [(use (match_operand:V2DF 0 "vsx_register_operand" "=wa")) + (use (match_operand:V2DF 1 "vsx_register_operand" "wa"))] + "TARGET_P9_VECTOR" +{ + rtx op0 = gen_reg_rtx (V2DImode); + rtx op1 = gen_lowpart (V2DImode, operands[1]); + emit_insn (gen_p9_xxbrd_v2di (op0, op1)); + emit_move_insn (operands[0], gen_lowpart (V2DFmode, op0)); + DONE; +}) + ;; Swap all bytes in each 32-bit element -(define_insn "p9_xxbrw_" - [(set (match_operand:VSX_W 0 "vsx_register_operand" "=wa") - (bswap:VSX_W (match_operand:VSX_W 1 "vsx_register_operand" "wa")))] +(define_insn "p9_xxbrw_v4si" + [(set (match_operand:V4SI 0 "vsx_register_operand" "=wa") + (bswap:V4SI (match_operand:V4SI 1 "vsx_register_operand" "wa")))] "TARGET_P9_VECTOR" "xxbrw %x0,%x1" [(set_attr "type" "vecperm")]) +(define_expand "p9_xxbrw_v4sf" + [(use (match_operand:V4SF 0 "vsx_register_operand" "=wa")) + (use (match_operand:V4SF 1 "vsx_register_operand" "wa"))] + "TARGET_P9_VECTOR" +{ + rtx op0 = gen_reg_rtx (V4SImode); + rtx op1 = gen_lowpart (V4SImode, operands[1]); + emit_insn (gen_p9_xxbrw_v4si (op0, op1)); + emit_move_insn (operands[0], gen_lowpart (V4SFmode, op0)); + DONE; +}) + ;; Swap all bytes in each element of vector (define_expand "revb_" - [(set (match_operand:VEC_REVB 0 "vsx_register_operand") - (bswap:VEC_REVB (match_operand:VEC_REVB 1 "vsx_register_operand")))] + [(use (match_operand:VEC_REVB 0 "vsx_register_operand")) + (use (match_operand:VEC_REVB 1 "vsx_register_operand"))] "" { if (TARGET_P9_VECTOR) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 4536b53..64018db 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-02-09 Jakub Jelinek + + PR target/84226 + * gcc.target/powerpc/pr84226.c: New test. + 2018-02-09 Peter Bergner * gcc.target/powerpc/builtins-1-be.c : Rename duplicate test diff --git a/gcc/testsuite/gcc.target/powerpc/pr84226.c b/gcc/testsuite/gcc.target/powerpc/pr84226.c new file mode 100644 index 0000000..aae922b --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/pr84226.c @@ -0,0 +1,6 @@ +/* PR target/84226 */ +/* { dg-do compile { target { powerpc*-*-* && lp64 } } } */ +/* { dg-require-effective-target powerpc_p9vector_ok } */ +/* { dg-options "-mpower9-misc -O1" } */ + +#include "builtins-revb-runnable.c" -- cgit v1.1 From 8c67920556efc5fa97c2080098c202e75b93e2a0 Mon Sep 17 00:00:00 2001 From: Vladimir Makarov Date: Fri, 9 Feb 2018 18:23:58 +0000 Subject: re PR rtl-optimization/57193 (suboptimal register allocation for SSE registers) 2018-02-09 Vladimir Makarov PR rtl-optimization/57193 * ira-color.c (struct allocno_color_data): Add member conflict_allocno_hard_prefs. (update_conflict_allocno_hard_prefs): New. (bucket_allocno_compare_func): Add a preference based on conflict_allocno_hard_prefs. (push_allocno_to_stack): Update conflict_allocno_hard_prefs. (color_allocnos): Remove a dead code. Initiate conflict_allocno_hard_prefs. Call update_costs_from_prefs. 2018-02-09 Vladimir Makarov PR rtl-optimization/57193 * gcc.target/i386/57193.c: New. From-SVN: r257537 --- gcc/ChangeLog | 12 ++++++ gcc/ira-color.c | 66 +++++++++++++++++++++++++-------- gcc/testsuite/ChangeLog | 5 +++ gcc/testsuite/gcc.target/i386/pr57193.c | 16 ++++++++ 4 files changed, 84 insertions(+), 15 deletions(-) create mode 100644 gcc/testsuite/gcc.target/i386/pr57193.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 4ac7fff..043972e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2018-02-09 Vladimir Makarov + + PR rtl-optimization/57193 + * ira-color.c (struct allocno_color_data): Add member + conflict_allocno_hard_prefs. + (update_conflict_allocno_hard_prefs): New. + (bucket_allocno_compare_func): Add a preference based on + conflict_allocno_hard_prefs. + (push_allocno_to_stack): Update conflict_allocno_hard_prefs. + (color_allocnos): Remove a dead code. Initiate + conflict_allocno_hard_prefs. Call update_costs_from_prefs. + 2018-02-09 Jakub Jelinek PR target/84226 diff --git a/gcc/ira-color.c b/gcc/ira-color.c index 26b18f3..7087fb9 100644 --- a/gcc/ira-color.c +++ b/gcc/ira-color.c @@ -112,6 +112,9 @@ struct allocno_color_data available for the allocno allocation. It is number of the profitable hard regs. */ int available_regs_num; + /* Sum of frequencies of hard register preferences of all + conflicting allocnos which are not the coloring stack yet. */ + int conflict_allocno_hard_prefs; /* Allocnos in a bucket (used in coloring) chained by the following two members. */ ira_allocno_t next_bucket_allocno; @@ -1435,6 +1438,36 @@ update_costs_from_copies (ira_allocno_t allocno, bool decr_p, bool record_p) update_costs_from_allocno (allocno, hard_regno, 1, decr_p, record_p); } +/* Update conflict_allocno_hard_prefs of allocnos conflicting with + ALLOCNO. */ +static void +update_conflict_allocno_hard_prefs (ira_allocno_t allocno) +{ + int l, nr = ALLOCNO_NUM_OBJECTS (allocno); + + for (l = 0; l < nr; l++) + { + ira_object_t conflict_obj, obj = ALLOCNO_OBJECT (allocno, l); + ira_object_conflict_iterator oci; + + FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci) + { + ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj); + allocno_color_data_t conflict_data = ALLOCNO_COLOR_DATA (conflict_a); + ira_pref_t pref; + + if (!(hard_reg_set_intersect_p + (ALLOCNO_COLOR_DATA (allocno)->profitable_hard_regs, + conflict_data->profitable_hard_regs))) + continue; + for (pref = ALLOCNO_PREFS (allocno); + pref != NULL; + pref = pref->next_pref) + conflict_data->conflict_allocno_hard_prefs += pref->freq; + } + } +} + /* Restore costs of allocnos connected to ALLOCNO by copies as it was before updating costs of these allocnos from given allocno. This is a wise thing to do as if given allocno did not get an expected @@ -2223,7 +2256,7 @@ bucket_allocno_compare_func (const void *v1p, const void *v2p) { ira_allocno_t a1 = *(const ira_allocno_t *) v1p; ira_allocno_t a2 = *(const ira_allocno_t *) v2p; - int diff, freq1, freq2, a1_num, a2_num; + int diff, freq1, freq2, a1_num, a2_num, pref1, pref2; ira_allocno_t t1 = ALLOCNO_COLOR_DATA (a1)->first_thread_allocno; ira_allocno_t t2 = ALLOCNO_COLOR_DATA (a2)->first_thread_allocno; int cl1 = ALLOCNO_CLASS (a1), cl2 = ALLOCNO_CLASS (a2); @@ -2253,6 +2286,11 @@ bucket_allocno_compare_func (const void *v1p, const void *v2p) a2_num = ALLOCNO_COLOR_DATA (a2)->available_regs_num; if ((diff = a2_num - a1_num) != 0) return diff; + /* Push allocnos with minimal conflict_allocno_hard_prefs first. */ + pref1 = ALLOCNO_COLOR_DATA (a1)->conflict_allocno_hard_prefs; + pref2 = ALLOCNO_COLOR_DATA (a2)->conflict_allocno_hard_prefs; + if ((diff = pref1 - pref2) != 0) + return diff; return ALLOCNO_NUM (a2) - ALLOCNO_NUM (a1); } @@ -2339,7 +2377,8 @@ delete_allocno_from_bucket (ira_allocno_t allocno, ira_allocno_t *bucket_ptr) /* Put allocno A onto the coloring stack without removing it from its bucket. Pushing allocno to the coloring stack can result in moving conflicting allocnos from the uncolorable bucket to the colorable - one. */ + one. Update conflict_allocno_hard_prefs of the conflicting + allocnos which are not on stack yet. */ static void push_allocno_to_stack (ira_allocno_t a) { @@ -2369,15 +2408,19 @@ push_allocno_to_stack (ira_allocno_t a) FOR_EACH_OBJECT_CONFLICT (obj, conflict_obj, oci) { ira_allocno_t conflict_a = OBJECT_ALLOCNO (conflict_obj); - + ira_pref_t pref; + conflict_data = ALLOCNO_COLOR_DATA (conflict_a); - if (conflict_data->colorable_p - || ! conflict_data->in_graph_p + if (! conflict_data->in_graph_p || ALLOCNO_ASSIGNED_P (conflict_a) || !(hard_reg_set_intersect_p (ALLOCNO_COLOR_DATA (a)->profitable_hard_regs, conflict_data->profitable_hard_regs))) continue; + for (pref = ALLOCNO_PREFS (a); pref != NULL; pref = pref->next_pref) + conflict_data->conflict_allocno_hard_prefs -= pref->freq; + if (conflict_data->colorable_p) + continue; ira_assert (bitmap_bit_p (coloring_allocno_bitmap, ALLOCNO_NUM (conflict_a))); if (update_left_conflict_sizes_p (conflict_a, a, size)) @@ -3048,21 +3091,12 @@ color_allocnos (void) setup_profitable_hard_regs (); EXECUTE_IF_SET_IN_BITMAP (coloring_allocno_bitmap, 0, i, bi) { - int l, nr; - HARD_REG_SET conflict_hard_regs; allocno_color_data_t data; ira_pref_t pref, next_pref; a = ira_allocnos[i]; - nr = ALLOCNO_NUM_OBJECTS (a); - CLEAR_HARD_REG_SET (conflict_hard_regs); - for (l = 0; l < nr; l++) - { - ira_object_t obj = ALLOCNO_OBJECT (a, l); - IOR_HARD_REG_SET (conflict_hard_regs, - OBJECT_CONFLICT_HARD_REGS (obj)); - } data = ALLOCNO_COLOR_DATA (a); + data->conflict_allocno_hard_prefs = 0; for (pref = ALLOCNO_PREFS (a); pref != NULL; pref = next_pref) { next_pref = pref->next_pref; @@ -3072,6 +3106,7 @@ color_allocnos (void) ira_remove_pref (pref); } } + if (flag_ira_algorithm == IRA_ALGORITHM_PRIORITY) { n = 0; @@ -3134,6 +3169,7 @@ color_allocnos (void) { ALLOCNO_COLOR_DATA (a)->in_graph_p = true; update_costs_from_prefs (a); + update_conflict_allocno_hard_prefs (a); } else { diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 64018db..9d80ab8 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-02-09 Vladimir Makarov + + PR rtl-optimization/57193 + * gcc.target/i386/57193.c: New. + 2018-02-09 Jakub Jelinek PR target/84226 diff --git a/gcc/testsuite/gcc.target/i386/pr57193.c b/gcc/testsuite/gcc.target/i386/pr57193.c new file mode 100644 index 0000000..70e2612 --- /dev/null +++ b/gcc/testsuite/gcc.target/i386/pr57193.c @@ -0,0 +1,16 @@ +/* { dg-do compile { target { ! ia32 } } } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler-times "movdqa" 2 } } */ + +#include + +void test1(const __m128i* in1, const __m128i* in2, __m128i* out, + __m128i f, __m128i zero) +{ + __m128i c = _mm_avg_epu8(*in1, *in2); + __m128i l = _mm_unpacklo_epi8(c, zero); + __m128i h = _mm_unpackhi_epi8(c, zero); + __m128i m = _mm_mulhi_epu16(l, f); + __m128i n = _mm_mulhi_epu16(h, f); + *out = _mm_packus_epi16(m, n); +} -- cgit v1.1 From dd2799cc2212a72a1b31828918f9bb9287ab9780 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 9 Feb 2018 14:10:42 -0500 Subject: PR c++/84296 - ICE with qualified-id in template. PR c++/83714 * pt.c (unknown_base_ref_p): New. (instantiation_dependent_scope_ref_p): Use it instead of any_dependent_bases_p. From-SVN: r257538 --- gcc/cp/ChangeLog | 8 +++++ gcc/cp/pt.c | 28 +++++++++++++-- gcc/testsuite/g++.dg/template/scope5.C | 66 ++++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 gcc/testsuite/g++.dg/template/scope5.C (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index ac53a74..fa66e1b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,11 @@ +2018-02-09 Jason Merrill + + PR c++/84296 - ICE with qualified-id in template. + PR c++/83714 + * pt.c (unknown_base_ref_p): New. + (instantiation_dependent_scope_ref_p): Use it instead of + any_dependent_bases_p. + 2018-02-09 Marek Polacek Jakub Jelinek diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index a9e4770..9c57709 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -24012,6 +24012,30 @@ dependent_scope_p (tree scope) && !currently_open_class (scope)); } +/* T is a SCOPE_REF. Return whether it represents a non-static member of + an unknown base of 'this' (and is therefore instantiation-dependent). */ + +static bool +unknown_base_ref_p (tree t) +{ + if (!current_class_ptr) + return false; + + tree mem = TREE_OPERAND (t, 1); + if (shared_member_p (mem)) + return false; + + tree cur = current_nonlambda_class_type (); + if (!any_dependent_bases_p (cur)) + return false; + + tree ctx = TREE_OPERAND (t, 0); + if (DERIVED_FROM_P (ctx, cur)) + return false; + + return true; +} + /* T is a SCOPE_REF; return whether we need to consider it instantiation-dependent so that we can check access at instantiation time even though we know which member it resolves to. */ @@ -24021,9 +24045,7 @@ instantiation_dependent_scope_ref_p (tree t) { if (DECL_P (TREE_OPERAND (t, 1)) && CLASS_TYPE_P (TREE_OPERAND (t, 0)) - /* A dependent base could make a member inaccessible in the current - class. */ - && !any_dependent_bases_p () + && !unknown_base_ref_p (t) && accessible_in_template_p (TREE_OPERAND (t, 0), TREE_OPERAND (t, 1))) return false; diff --git a/gcc/testsuite/g++.dg/template/scope5.C b/gcc/testsuite/g++.dg/template/scope5.C new file mode 100644 index 0000000..629225c --- /dev/null +++ b/gcc/testsuite/g++.dg/template/scope5.C @@ -0,0 +1,66 @@ +// PR c++/84296 + +namespace b {} +namespace c { +using namespace b; +} +namespace b { +template struct e { static const int f = d; }; +} +template struct g; +template +struct g : h::template ab {}; +struct k { + template struct m { typedef typename g::n o; }; +}; +template struct ac; +struct r { + typedef ac p; +}; +template struct s : k { + template + struct ab : q::template t::template ab {}; +}; +struct ad { + typedef int u; +}; +template struct ae; +template struct ah { + typedef ae ai; + typedef typename ai::template w::o n; +}; +struct x { + template struct ab : ah {}; +}; +struct y { + struct z { + template struct t : x {}; + }; + struct aj : s {}; +}; +template struct ak { + typedef y::aj al; + typedef typename al::m::o o; +}; +struct am { + enum { an }; +}; +template struct ao {}; +template struct ap : af::aq {}; +template <> struct ae { + template struct w; + template struct w { + typedef typename as::p o; + }; +}; +enum { a = b::e<0>::f }; +template class au; +template struct ac : ao { typedef c::e aq; }; +template void ay(aw, i, ax) { + au::o>::f> > az(); +} +void v() { + ad a; + void az(); + ay(az, a, v); +} -- cgit v1.1 From 0444aa9c0a3357707624263ec2fd13d8f156016e Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Fri, 9 Feb 2018 19:31:10 +0000 Subject: [PR c/84293] Unexpected strict-alias warning https://gcc.gnu.org/ml/gcc-patches/2018-02/msg00510.html PR c/84293 gcc/c/ * c-typeck.c (build_indirect_ref, build_c_cast): Pass expr location to strict_aliasing_warning. gcc/c-family/ * c-common.h (strict_aliasing_warning): Drop OTYPE arg, insert LOC arg. * c-warn.c (strict_aliasing_warning): Drop OTYPE arg, require LOC arg. Adjust. gcc/cp/ * typeck.c (cp_build_indirect_ref_1, build_reinterpret_cast_1): Pass expr location to strict_aliasing_warning. gcc/testsuite/ * c-c++-common/pr84293.h: New. * c-c++-common/pr84293.c: New. From-SVN: r257539 --- gcc/c-family/ChangeLog | 8 ++++++++ gcc/c-family/c-common.h | 2 +- gcc/c-family/c-warn.c | 36 ++++++++++++++++++++++-------------- gcc/c/ChangeLog | 6 ++++++ gcc/c/c-typeck.c | 4 ++-- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/typeck.c | 12 ++++-------- gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/c-c++-common/pr84293.c | 10 ++++++++++ gcc/testsuite/c-c++-common/pr84293.h | 7 +++++++ 10 files changed, 72 insertions(+), 25 deletions(-) create mode 100644 gcc/testsuite/c-c++-common/pr84293.c create mode 100644 gcc/testsuite/c-c++-common/pr84293.h (limited to 'gcc') diff --git a/gcc/c-family/ChangeLog b/gcc/c-family/ChangeLog index 2378181..1f536d1 100644 --- a/gcc/c-family/ChangeLog +++ b/gcc/c-family/ChangeLog @@ -1,3 +1,11 @@ +2018-02-09 Nathan Sidwell + + PR c/84293 + * c-common.h (strict_aliasing_warning): Drop OTYPE arg, insert LOC + arg. + * c-warn.c (strict_aliasing_warning): Drop OTYPE arg, require LOC + arg. Adjust. + 2018-02-09 Martin Sebor PR lto/84212 diff --git a/gcc/c-family/c-common.h b/gcc/c-family/c-common.h index 775d468..95bb0fd 100644 --- a/gcc/c-family/c-common.h +++ b/gcc/c-family/c-common.h @@ -1260,7 +1260,7 @@ extern void warn_tautological_cmp (location_t, enum tree_code, tree, tree); extern void warn_logical_not_parentheses (location_t, enum tree_code, tree, tree); extern bool warn_if_unused_value (const_tree, location_t); -extern bool strict_aliasing_warning (tree, tree, tree); +extern bool strict_aliasing_warning (location_t, tree, tree); extern void sizeof_pointer_memaccess_warning (location_t *, tree, vec *, tree *, bool (*) (tree, tree)); diff --git a/gcc/c-family/c-warn.c b/gcc/c-family/c-warn.c index 7d87c45..f3fb62c 100644 --- a/gcc/c-family/c-warn.c +++ b/gcc/c-family/c-warn.c @@ -599,17 +599,21 @@ warn_if_unused_value (const_tree exp, location_t locus) } } -/* Print a warning about casts that might indicate violation - of strict aliasing rules if -Wstrict-aliasing is used and - strict aliasing mode is in effect. OTYPE is the original - TREE_TYPE of EXPR, and TYPE the type we're casting to. */ +/* Print a warning about casts that might indicate violation of strict + aliasing rules if -Wstrict-aliasing is used and strict aliasing + mode is in effect. LOC is the location of the expression being + cast, EXPR might be from inside it. TYPE is the type we're casting + to. */ bool -strict_aliasing_warning (tree otype, tree type, tree expr) +strict_aliasing_warning (location_t loc, tree type, tree expr) { + if (loc == UNKNOWN_LOCATION) + loc = input_location; + /* Strip pointer conversion chains and get to the correct original type. */ STRIP_NOPS (expr); - otype = TREE_TYPE (expr); + tree otype = TREE_TYPE (expr); if (!(flag_strict_aliasing && POINTER_TYPE_P (type) @@ -628,8 +632,9 @@ strict_aliasing_warning (tree otype, tree type, tree expr) if the cast breaks type based aliasing. */ if (!COMPLETE_TYPE_P (TREE_TYPE (type)) && warn_strict_aliasing == 2) { - warning (OPT_Wstrict_aliasing, "type-punning to incomplete type " - "might break strict-aliasing rules"); + warning_at (loc, OPT_Wstrict_aliasing, + "type-punning to incomplete type " + "might break strict-aliasing rules"); return true; } else @@ -645,15 +650,17 @@ strict_aliasing_warning (tree otype, tree type, tree expr) && !alias_set_subset_of (set2, set1) && !alias_sets_conflict_p (set1, set2)) { - warning (OPT_Wstrict_aliasing, "dereferencing type-punned " - "pointer will break strict-aliasing rules"); + warning_at (loc, OPT_Wstrict_aliasing, + "dereferencing type-punned " + "pointer will break strict-aliasing rules"); return true; } else if (warn_strict_aliasing == 2 && !alias_sets_must_conflict_p (set1, set2)) { - warning (OPT_Wstrict_aliasing, "dereferencing type-punned " - "pointer might break strict-aliasing rules"); + warning_at (loc, OPT_Wstrict_aliasing, + "dereferencing type-punned " + "pointer might break strict-aliasing rules"); return true; } } @@ -669,8 +676,9 @@ strict_aliasing_warning (tree otype, tree type, tree expr) if (!COMPLETE_TYPE_P (type) || !alias_sets_must_conflict_p (set1, set2)) { - warning (OPT_Wstrict_aliasing, "dereferencing type-punned " - "pointer might break strict-aliasing rules"); + warning_at (loc, OPT_Wstrict_aliasing, + "dereferencing type-punned " + "pointer might break strict-aliasing rules"); return true; } } diff --git a/gcc/c/ChangeLog b/gcc/c/ChangeLog index 97ae43c..bca7268 100644 --- a/gcc/c/ChangeLog +++ b/gcc/c/ChangeLog @@ -1,3 +1,9 @@ +2018-02-09 Nathan Sidwell + + PR c/84293 + * c-typeck.c (build_indirect_ref, build_c_cast): Pass expr location + to strict_aliasing_warning. + 2018-02-02 Paolo Carlini * c-typeck.c (really_start_incremental_init, push_init_level, diff --git a/gcc/c/c-typeck.c b/gcc/c/c-typeck.c index b35c2c0..1eae4ea 100644 --- a/gcc/c/c-typeck.c +++ b/gcc/c/c-typeck.c @@ -2524,7 +2524,7 @@ build_indirect_ref (location_t loc, tree ptr, ref_operator errstring) the backend. This only needs to be done at warn_strict_aliasing > 2. */ if (warn_strict_aliasing > 2) - if (strict_aliasing_warning (TREE_TYPE (TREE_OPERAND (pointer, 0)), + if (strict_aliasing_warning (EXPR_LOCATION (pointer), type, TREE_OPERAND (pointer, 0))) TREE_NO_WARNING (pointer) = 1; } @@ -5696,7 +5696,7 @@ build_c_cast (location_t loc, tree type, tree expr) "of different size"); if (warn_strict_aliasing <= 2) - strict_aliasing_warning (otype, type, expr); + strict_aliasing_warning (EXPR_LOCATION (value), type, expr); /* If pedantic, warn for conversions between function and object pointer types, except for converting a null pointer constant diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index fa66e1b..cea51ff 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2018-02-09 Nathan Sidwell + + PR c/84293 + * typeck.c (cp_build_indirect_ref_1, build_reinterpret_cast_1): + Pass expr location to strict_aliasing_warning. + 2018-02-09 Jason Merrill PR c++/84296 - ICE with qualified-id in template. diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index fe18ea9..dfcf716 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -3136,7 +3136,7 @@ cp_build_indirect_ref_1 (tree ptr, ref_operator errorstring, the backend. This only needs to be done at warn_strict_aliasing > 2. */ if (warn_strict_aliasing > 2) - if (strict_aliasing_warning (TREE_TYPE (TREE_OPERAND (ptr, 0)), + if (strict_aliasing_warning (EXPR_LOCATION (ptr), type, TREE_OPERAND (ptr, 0))) TREE_NO_WARNING (ptr) = 1; } @@ -7334,7 +7334,7 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p, expr = cp_build_addr_expr (expr, complain); if (warn_strict_aliasing > 2) - strict_aliasing_warning (TREE_TYPE (expr), type, expr); + strict_aliasing_warning (EXPR_LOCATION (expr), type, expr); if (expr != error_mark_node) expr = build_reinterpret_cast_1 @@ -7428,8 +7428,6 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p, else if ((TYPE_PTRDATAMEM_P (type) && TYPE_PTRDATAMEM_P (intype)) || (TYPE_PTROBV_P (type) && TYPE_PTROBV_P (intype))) { - tree sexpr = expr; - if (!c_cast_p && check_for_casting_away_constness (intype, type, REINTERPRET_CAST_EXPR, @@ -7447,11 +7445,9 @@ build_reinterpret_cast_1 (tree type, tree expr, bool c_cast_p, warning (OPT_Wcast_align, "cast from %qH to %qI " "increases required alignment of target type", intype, type); - /* We need to strip nops here, because the front end likes to - create (int *)&a for array-to-pointer decay, instead of &a[0]. */ - STRIP_NOPS (sexpr); if (warn_strict_aliasing <= 2) - strict_aliasing_warning (intype, type, sexpr); + /* strict_aliasing_warning STRIP_NOPs its expr. */ + strict_aliasing_warning (EXPR_LOCATION (expr), type, expr); return build_nop (type, expr); } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 9d80ab8..edafd88 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2018-02-09 Nathan Sidwell + + PR c/84293 + * c-c++-common/pr84293.h: New. + * c-c++-common/pr84293.c: New. + 2018-02-09 Vladimir Makarov PR rtl-optimization/57193 diff --git a/gcc/testsuite/c-c++-common/pr84293.c b/gcc/testsuite/c-c++-common/pr84293.c new file mode 100644 index 0000000..dfcc859 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr84293.c @@ -0,0 +1,10 @@ +/* PR c/84293 unexpected warning from system header. */ +#include "./pr84293.h" +struct typeobject thing; + +#pragma GCC diagnostic warning "-Wstrict-aliasing" +void __attribute__ ((optimize (2))) init () +{ + INCREF_TDEF (&thing); + INCREF_STAG (&thing); +} diff --git a/gcc/testsuite/c-c++-common/pr84293.h b/gcc/testsuite/c-c++-common/pr84293.h new file mode 100644 index 0000000..c129896 --- /dev/null +++ b/gcc/testsuite/c-c++-common/pr84293.h @@ -0,0 +1,7 @@ +/* PR c/84293 unexpected warning from system header expansion. */ +#pragma GCC system_header +struct typeobject { unsigned refs; }; +typedef struct object { unsigned refs; } Object; + +#define INCREF_TDEF(op) (((Object*)(op))->refs++) +#define INCREF_STAG(op) (((struct object*)(op))->refs++) -- cgit v1.1 From 8221fb01d690820cb4e9fe4a8b4e33ddcf686029 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Fri, 9 Feb 2018 19:39:14 +0000 Subject: compiler: track //go:nointerface in export data The magic //go:nointerface comment, used for field tracking, was only implemented for conversions to interface types in the same package. Record it in the export data, so that it works as expected for types imported from a different package. Reviewed-on: https://go-review.googlesource.com/93075 From-SVN: r257540 --- gcc/go/gofrontend/MERGE | 2 +- gcc/go/gofrontend/gogo.cc | 50 ++++++++++++++++++++++++++++++++++++++++++--- gcc/go/gofrontend/gogo.h | 24 +++++++++++++++++++--- gcc/go/gofrontend/import.cc | 7 ++++++- gcc/go/gofrontend/types.cc | 7 ++++++- 5 files changed, 81 insertions(+), 9 deletions(-) (limited to 'gcc') diff --git a/gcc/go/gofrontend/MERGE b/gcc/go/gofrontend/MERGE index edffc11..3d73330 100644 --- a/gcc/go/gofrontend/MERGE +++ b/gcc/go/gofrontend/MERGE @@ -1,4 +1,4 @@ -7e94bac5676afc8188677c98ecb263c78c1a7f8d +89105404f94005ffa8e2b08df78015dc9ac91362 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/gogo.cc b/gcc/go/gofrontend/gogo.cc index ab0c27b..11ac338 100644 --- a/gcc/go/gofrontend/gogo.cc +++ b/gcc/go/gofrontend/gogo.cc @@ -5189,17 +5189,24 @@ Function::defer_stack(Location location) void Function::export_func(Export* exp, const std::string& name) const { - Function::export_func_with_type(exp, name, this->type_); + Function::export_func_with_type(exp, name, this->type_, + this->is_method() && this->nointerface()); } // Export a function with a type. void Function::export_func_with_type(Export* exp, const std::string& name, - const Function_type* fntype) + const Function_type* fntype, bool nointerface) { exp->write_c_string("func "); + if (nointerface) + { + go_assert(fntype->is_method()); + exp->write_c_string("/*nointerface*/ "); + } + if (fntype->is_method()) { exp->write_c_string("("); @@ -5280,10 +5287,21 @@ Function::import_func(Import* imp, std::string* pname, Typed_identifier** preceiver, Typed_identifier_list** pparameters, Typed_identifier_list** presults, - bool* is_varargs) + bool* is_varargs, + bool* nointerface) { imp->require_c_string("func "); + *nointerface = false; + if (imp->match_c_string("/*")) + { + imp->require_c_string("/*nointerface*/ "); + *nointerface = true; + + // Only a method can be nointerface. + go_assert(imp->peek_char() == '('); + } + *preceiver = NULL; if (imp->peek_char() == '(') { @@ -6213,6 +6231,32 @@ Bindings_snapshot::check_goto_defs(Location loc, const Block* block, // Class Function_declaration. +// Whether this declares a method. + +bool +Function_declaration::is_method() const +{ + return this->fntype_->is_method(); +} + +// Whether this method should not be included in the type descriptor. + +bool +Function_declaration::nointerface() const +{ + go_assert(this->is_method()); + return (this->pragmas_ & GOPRAGMA_NOINTERFACE) != 0; +} + +// Record that this method should not be included in the type +// descriptor. + +void +Function_declaration::set_nointerface() +{ + this->pragmas_ |= GOPRAGMA_NOINTERFACE; +} + // Return the function descriptor. Expression* diff --git a/gcc/go/gofrontend/gogo.h b/gcc/go/gofrontend/gogo.h index dfff5c1..139df17 100644 --- a/gcc/go/gofrontend/gogo.h +++ b/gcc/go/gofrontend/gogo.h @@ -1476,13 +1476,14 @@ class Function // Export a function with a type. static void export_func_with_type(Export*, const std::string& name, - const Function_type*); + const Function_type*, bool nointerface); // Import a function. static void import_func(Import*, std::string* pname, Typed_identifier** receiver, Typed_identifier_list** pparameters, - Typed_identifier_list** presults, bool* is_varargs); + Typed_identifier_list** presults, bool* is_varargs, + bool* nointerface); private: // Type for mapping from label names to Label objects. @@ -1607,6 +1608,10 @@ class Function_declaration location() const { return this->location_; } + // Return whether this function declaration is a method. + bool + is_method() const; + const std::string& asm_name() const { return this->asm_name_; } @@ -1628,6 +1633,16 @@ class Function_declaration this->pragmas_ = pragmas; } + // Whether this method should not be included in the type + // descriptor. + bool + nointerface() const; + + // Record that this method should not be included in the type + // descriptor. + void + set_nointerface(); + // Return an expression for the function descriptor, given the named // object for this function. This may only be called for functions // without a closure. This will be an immutable struct with one @@ -1652,7 +1667,10 @@ class Function_declaration // Export a function declaration. void export_func(Export* exp, const std::string& name) const - { Function::export_func_with_type(exp, name, this->fntype_); } + { + Function::export_func_with_type(exp, name, this->fntype_, + this->is_method() && this->nointerface()); + } // Check that the types used in this declaration's signature are defined. void diff --git a/gcc/go/gofrontend/import.cc b/gcc/go/gofrontend/import.cc index 2a3ea83..7e06a3c 100644 --- a/gcc/go/gofrontend/import.cc +++ b/gcc/go/gofrontend/import.cc @@ -607,8 +607,9 @@ Import::import_func(Package* package) Typed_identifier_list* parameters; Typed_identifier_list* results; bool is_varargs; + bool nointerface; Function::import_func(this, &name, &receiver, - ¶meters, &results, &is_varargs); + ¶meters, &results, &is_varargs, &nointerface); Function_type *fntype = Type::make_function_type(receiver, parameters, results, this->location_); if (is_varargs) @@ -648,6 +649,10 @@ Import::import_func(Package* package) if (this->add_to_globals_) this->gogo_->add_dot_import_object(no); } + + if (nointerface) + no->func_declaration_value()->set_nointerface(); + return no; } diff --git a/gcc/go/gofrontend/types.cc b/gcc/go/gofrontend/types.cc index eb04fe1..40eccfc 100644 --- a/gcc/go/gofrontend/types.cc +++ b/gcc/go/gofrontend/types.cc @@ -9742,7 +9742,12 @@ bool Named_method::do_nointerface() const { Named_object* no = this->named_object_; - return no->is_function() && no->func_value()->nointerface(); + if (no->is_function()) + return no->func_value()->nointerface(); + else if (no->is_function_declaration()) + return no->func_declaration_value()->nointerface(); + else + go_unreachable(); } // Class Interface_method. -- cgit v1.1 From c028d589e94a67795a25763bc95b778e1480f106 Mon Sep 17 00:00:00 2001 From: Will Schmidt Date: Fri, 9 Feb 2018 20:59:40 +0000 Subject: vsx-vector-6-le.c: Update CPU target. [testsuite] 2018-02-07 Will Schmidt * gcc.target/powerpc/vsx-vector-6-le.c: Update CPU target. * gcc.target/powerpc/vsx-vector-6-le.p9.c: New. From-SVN: r257541 --- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gcc.target/powerpc/vsx-vector-6-le.c | 5 ++-- .../gcc.target/powerpc/vsx-vector-6-le.p9.c | 33 ++++++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/vsx-vector-6-le.p9.c (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index edafd88..752857b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-02-09 Will Schmidt + + * gcc.target/powerpc/vsx-vector-6-le.c: Update CPU target. + * gcc.target/powerpc/vsx-vector-6-le.p9.c: New. + 2018-02-09 Nathan Sidwell PR c/84293 diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-le.c b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-le.c index ddb0089..c3f795c 100644 --- a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-le.c +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-le.c @@ -1,9 +1,10 @@ /* { dg-do compile { target { powerpc64le-*-* && lp64 } } } */ /* { dg-skip-if "" { powerpc*-*-darwin* } } */ /* { dg-require-effective-target powerpc_vsx_ok } */ -/* { dg-options "-mvsx -O2" } */ +/* { dg-options "-mvsx -O2 -mcpu=power8" } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ -/* Expected instruction counts for Little Endian */ +/* Expected instruction counts for Little Endian targeting Power8. */ /* { dg-final { scan-assembler-times "xvabsdp" 1 } } */ /* { dg-final { scan-assembler-times "xvadddp" 1 } } */ diff --git a/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-le.p9.c b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-le.p9.c new file mode 100644 index 0000000..290d4b4 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/vsx-vector-6-le.p9.c @@ -0,0 +1,33 @@ +/* { dg-do compile { target { powerpc64le-*-* && lp64 } } } */ +/* { dg-skip-if "" { powerpc*-*-darwin* } } */ +/* { dg-require-effective-target powerpc_p9vector_ok } */ +/* { dg-options "-mvsx -O2 -mcpu=power9" } */ +/* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power9" } } */ + +/* Expected instruction counts for Little Endian targeting Power9. */ + +/* { dg-final { scan-assembler-times "xvabsdp" 1 } } */ +/* { dg-final { scan-assembler-times "xvadddp" 1 } } */ +/* { dg-final { scan-assembler-times "xxlnor" 7 } } */ +/* { dg-final { scan-assembler-times "xxlor" 20 } } */ +/* { dg-final { scan-assembler-times "xvcmpeqdp" 5 } } */ +/* { dg-final { scan-assembler-times "xvcmpgtdp" 8 } } */ +/* { dg-final { scan-assembler-times "xvcmpgedp" 8 } } */ +/* { dg-final { scan-assembler-times "xvrdpim" 1 } } */ +/* { dg-final { scan-assembler-times "xvmaddadp" 1 } } */ +/* { dg-final { scan-assembler-times "xvmsubadp" 1 } } */ +/* { dg-final { scan-assembler-times "xvsubdp" 1 } } */ +/* { dg-final { scan-assembler-times "xvmaxdp" 1 } } */ +/* { dg-final { scan-assembler-times "xvmindp" 1 } } */ +/* { dg-final { scan-assembler-times "xvmuldp" 1 } } */ +/* { dg-final { scan-assembler-times "vperm" 1 } } */ +/* { dg-final { scan-assembler-times "xvrdpic" 1 } } */ +/* { dg-final { scan-assembler-times "xvsqrtdp" 1 } } */ +/* { dg-final { scan-assembler-times "xvrdpiz" 1 } } */ +/* { dg-final { scan-assembler-times "xvmsubasp" 1 } } */ +/* { dg-final { scan-assembler-times "xvnmaddasp" 1 } } */ +/* { dg-final { scan-assembler-times "vmsumshs" 1 } } */ +/* { dg-final { scan-assembler-times "xxland" 13 } } */ + +/* Source code for the test in vsx-vector-6.h */ +#include "vsx-vector-6.h" -- cgit v1.1 From 83fe399c27e269e48c54bf5d505973b5c03da072 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 9 Feb 2018 16:01:49 -0500 Subject: PR c++/81917 - ICE with void_t and partial specialization. * pt.c (instantiate_class_template_1): Set TYPE_BEING_DEFINED before calling most_specialized_partial_spec. From-SVN: r257542 --- gcc/cp/ChangeLog | 6 ++++++ gcc/cp/pt.c | 18 +++++++++--------- gcc/testsuite/g++.dg/cpp0x/alias-decl-62.C | 22 ++++++++++++++++++++++ gcc/testsuite/g++.dg/cpp0x/initlist-template2.C | 7 ++----- gcc/testsuite/g++.dg/template/crash125.C | 4 +--- gcc/testsuite/g++.dg/template/pr51488.C | 4 +--- gcc/testsuite/g++.dg/template/pr55843.C | 11 +++-------- 7 files changed, 44 insertions(+), 28 deletions(-) create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-62.C (limited to 'gcc') diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index cea51ff..9df4c29 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,9 @@ +2018-02-09 Jason Merrill + + PR c++/81917 - ICE with void_t and partial specialization. + * pt.c (instantiate_class_template_1): Set TYPE_BEING_DEFINED before + calling most_specialized_partial_spec. + 2018-02-09 Nathan Sidwell PR c/84293 diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 9c57709..2816045 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -10347,14 +10347,14 @@ instantiate_class_template_1 (tree type) templ = most_general_template (CLASSTYPE_TI_TEMPLATE (type)); gcc_assert (TREE_CODE (templ) == TEMPLATE_DECL); + /* Mark the type as in the process of being defined. */ + TYPE_BEING_DEFINED (type) = 1; + /* Determine what specialization of the original template to instantiate. */ t = most_specialized_partial_spec (type, tf_warning_or_error); if (t == error_mark_node) - { - TYPE_BEING_DEFINED (type) = 1; - return error_mark_node; - } + return error_mark_node; else if (t) { /* This TYPE is actually an instantiation of a partial @@ -10379,16 +10379,16 @@ instantiate_class_template_1 (tree type) /* If the template we're instantiating is incomplete, then clearly there's nothing we can do. */ if (!COMPLETE_TYPE_P (pattern)) - return type; + { + /* We can try again later. */ + TYPE_BEING_DEFINED (type) = 0; + return type; + } /* If we've recursively instantiated too many templates, stop. */ if (! push_tinst_level (type)) return type; - /* Now we're really doing the instantiation. Mark the type as in - the process of being defined. */ - TYPE_BEING_DEFINED (type) = 1; - /* We may be in the middle of deferred access check. Disable it now. */ push_deferring_access_checks (dk_no_deferred); diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-62.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-62.C new file mode 100644 index 0000000..6f1fa45 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-62.C @@ -0,0 +1,22 @@ +// PR c++/81917 +// { dg-do compile { target c++11 } } + +template using a = void; +template struct b +{ + typedef int c; +}; +template class b>; +template ::c> class f; +template class g { }; +template class h +{ + class i; + typedef g> j; + class i + { + j k; // { dg-error "incomplete" } + }; +}; +h H; + diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-template2.C b/gcc/testsuite/g++.dg/cpp0x/initlist-template2.C index 40e3075..0df0d4e 100644 --- a/gcc/testsuite/g++.dg/cpp0x/initlist-template2.C +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-template2.C @@ -1,6 +1,5 @@ // PR c++/71747 // { dg-do compile { target c++11 } } -// { dg-options -ftemplate-depth=20 } template < bool > struct A { @@ -14,10 +13,8 @@ template < bool > struct A template < bool, typename = int > struct F; template < bool X > // should be: struct F < X, typename A < A < X > {} () >::type > -struct F < X, typename A < F < X > {} () >::type > // { dg-error "" } +struct F < X, typename A < F < X > {} () >::type > { }; -F < true > f; - -// { dg-prune-output "compilation terminated" } +F < true > f; // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/template/crash125.C b/gcc/testsuite/g++.dg/template/crash125.C index 448f746..de41b99 100644 --- a/gcc/testsuite/g++.dg/template/crash125.C +++ b/gcc/testsuite/g++.dg/template/crash125.C @@ -13,6 +13,4 @@ struct TraitCheckImpl > { typedef void Complete; }; -Swappable s; // { dg-error "depth" } - -// { dg-prune-output "compilation terminated" } +Swappable s; // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/template/pr51488.C b/gcc/testsuite/g++.dg/template/pr51488.C index 4979a22..794a6cf 100644 --- a/gcc/testsuite/g++.dg/template/pr51488.C +++ b/gcc/testsuite/g++.dg/template/pr51488.C @@ -2,6 +2,4 @@ template struct s; template struct s::a> {}; -s ca; // { dg-error "depth" } - -// { dg-prune-output "compilation terminated" } +s ca; // { dg-error "" } diff --git a/gcc/testsuite/g++.dg/template/pr55843.C b/gcc/testsuite/g++.dg/template/pr55843.C index 467dd82..04079ed 100644 --- a/gcc/testsuite/g++.dg/template/pr55843.C +++ b/gcc/testsuite/g++.dg/template/pr55843.C @@ -1,5 +1,3 @@ -// { dg-options "-ftemplate-depth-8" } - template< typename T > struct type_wrapper { }; typedef char (&yes_tag)[2]; @@ -7,11 +5,11 @@ template struct if_c { }; template< typename T > struct has_type { struct gcc_3_2_wknd { - template< typename U > static yes_tag test( type_wrapper const volatile* // { dg-message "required" } + template< typename U > static yes_tag test( type_wrapper const volatile* // { dg-message "" } , type_wrapper* = 0 ); }; typedef type_wrapper t_; - static const bool value = sizeof(gcc_3_2_wknd::test(static_cast(0))) == // { dg-message "required" } + static const bool value = sizeof(gcc_3_2_wknd::test(static_cast(0))) == // { dg-message "" } sizeof(yes_tag); }; template struct Get_type { @@ -22,7 +20,4 @@ template struct Get_type >::value >::type> { }; // { dg-message "required" } template struct Get_type >::value >::type> { }; // { dg-message "required" } -typedef Get_type::type P; - -// { dg-prune-output "-ftemplate-depth" } -// { dg-prune-output "compilation terminated" } +typedef Get_type::type P; // { dg-message "" } -- cgit v1.1 From 86a568a358306ba5cb9b0b6d8bef1927566b1e74 Mon Sep 17 00:00:00 2001 From: Peter Bergner Date: Fri, 9 Feb 2018 16:03:43 -0600 Subject: re PR target/83926 (ICE during RTL pass: ira, in elimination_costs_in_insn, at reload1.c:3633) PR target/83926 * gcc.target/powerpc/pr83926.c: Filter out gimple folding disabled message. From-SVN: r257543 --- gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/gcc.target/powerpc/pr83926.c | 1 + 2 files changed, 7 insertions(+) (limited to 'gcc') diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 752857b..fdbb549 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2018-02-09 Peter Bergner + + PR target/83926 + * gcc.target/powerpc/pr83926.c: Filter out gimple folding disabled + message. + 2018-02-09 Will Schmidt * gcc.target/powerpc/vsx-vector-6-le.c: Update CPU target. diff --git a/gcc/testsuite/gcc.target/powerpc/pr83926.c b/gcc/testsuite/gcc.target/powerpc/pr83926.c index 3188ade..8accb2d 100644 --- a/gcc/testsuite/gcc.target/powerpc/pr83926.c +++ b/gcc/testsuite/gcc.target/powerpc/pr83926.c @@ -1,6 +1,7 @@ /* { dg-do compile { target { powerpc*-*-* } } } */ /* { dg-skip-if "do not override -mcpu" { powerpc*-*-* } { "-mcpu=*" } { "-mcpu=power8" } } */ /* { dg-options "-O2 -mcpu=power8 -mno-fold-gimple" } */ +/* { dg-prune-output "gimple folding of rs6000 builtins has been disabled." } */ __attribute__ ((altivec(vector__))) long long sdiv (__attribute__ ((altivec(vector__))) long long a, -- cgit v1.1 From 5ca8e744641e1b03cc6e4cdbc46e7ece0750240d Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sat, 10 Feb 2018 00:21:35 +0100 Subject: re PR rtl-optimization/84308 (Memory leak in spread_components) PR rtl-optimization/84308 * shrink-wrap.c (spread_components): Release todo vector. From-SVN: r257544 --- gcc/ChangeLog | 5 +++++ gcc/shrink-wrap.c | 2 ++ 2 files changed, 7 insertions(+) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 043972e..5766bc5 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2018-02-10 Jakub Jelinek + + PR rtl-optimization/84308 + * shrink-wrap.c (spread_components): Release todo vector. + 2018-02-09 Vladimir Makarov PR rtl-optimization/57193 diff --git a/gcc/shrink-wrap.c b/gcc/shrink-wrap.c index eda0f06..fd19ace 100644 --- a/gcc/shrink-wrap.c +++ b/gcc/shrink-wrap.c @@ -1370,6 +1370,8 @@ spread_components (sbitmap components) bitmap_clear_bit (seen, bb->index); } + todo.release (); + /* Finally, mark everything not not needed both forwards and backwards. */ FOR_EACH_BB_FN (bb, cfun) -- cgit v1.1 From 6724f8a61d49dfdfaa11995765b85ee170e48ac7 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sat, 10 Feb 2018 00:22:43 +0100 Subject: re PR sanitizer/83987 (ICE with OpenMP, sanitizer and virtual bases) PR sanitizer/83987 * omp-low.c (maybe_remove_omp_member_access_dummy_vars, remove_member_access_dummy_vars): New functions. (lower_omp_for, lower_omp_taskreg, lower_omp_target, lower_omp_1, execute_lower_omp): Use them. * tree.c (cp_free_lang_data): Revert 2018-01-23 change. * g++.dg/ubsan/pr83987-2.C: New test. From-SVN: r257545 --- gcc/ChangeLog | 6 ++++ gcc/cp/ChangeLog | 5 ++++ gcc/cp/tree.c | 10 ------- gcc/omp-low.c | 51 ++++++++++++++++++++++++++++++++++ gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/g++.dg/ubsan/pr83987-2.C | 24 ++++++++++++++++ 6 files changed, 91 insertions(+), 10 deletions(-) create mode 100644 gcc/testsuite/g++.dg/ubsan/pr83987-2.C (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 5766bc5..0ee4f1c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,5 +1,11 @@ 2018-02-10 Jakub Jelinek + PR sanitizer/83987 + * omp-low.c (maybe_remove_omp_member_access_dummy_vars, + remove_member_access_dummy_vars): New functions. + (lower_omp_for, lower_omp_taskreg, lower_omp_target, + lower_omp_1, execute_lower_omp): Use them. + PR rtl-optimization/84308 * shrink-wrap.c (spread_components): Release todo vector. diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 9df4c29..e01e73b 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,8 @@ +2018-02-10 Jakub Jelinek + + PR sanitizer/83987 + * tree.c (cp_free_lang_data): Revert 2018-01-23 change. + 2018-02-09 Jason Merrill PR c++/81917 - ICE with void_t and partial specialization. diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index d85f934..a53bddf 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -5273,16 +5273,6 @@ cp_free_lang_data (tree t) /* We do not need the leftover chaining of namespaces from the binding level. */ DECL_CHAIN (t) = NULL_TREE; - /* Set DECL_VALUE_EXPRs of OpenMP privatized member artificial - decls to error_mark_node. These are DECL_IGNORED_P and after - OpenMP lowering they aren't useful anymore. Clearing DECL_VALUE_EXPR - doesn't work, as expansion could then consider them as something - to be expanded. */ - if (VAR_P (t) - && DECL_LANG_SPECIFIC (t) - && DECL_OMP_PRIVATIZED_MEMBER (t) - && DECL_IGNORED_P (t)) - SET_DECL_VALUE_EXPR (t, error_mark_node); } /* Stub for c-common. Please keep in sync with c-decl.c. diff --git a/gcc/omp-low.c b/gcc/omp-low.c index ebbf88e..d8588b9 100644 --- a/gcc/omp-low.c +++ b/gcc/omp-low.c @@ -3208,6 +3208,43 @@ scan_omp (gimple_seq *body_p, omp_context *ctx) /* Re-gimplification and code generation routines. */ +/* Remove omp_member_access_dummy_var variables from gimple_bind_vars + of BIND if in a method. */ + +static void +maybe_remove_omp_member_access_dummy_vars (gbind *bind) +{ + if (DECL_ARGUMENTS (current_function_decl) + && DECL_ARTIFICIAL (DECL_ARGUMENTS (current_function_decl)) + && (TREE_CODE (TREE_TYPE (DECL_ARGUMENTS (current_function_decl))) + == POINTER_TYPE)) + { + tree vars = gimple_bind_vars (bind); + for (tree *pvar = &vars; *pvar; ) + if (omp_member_access_dummy_var (*pvar)) + *pvar = DECL_CHAIN (*pvar); + else + pvar = &DECL_CHAIN (*pvar); + gimple_bind_set_vars (bind, vars); + } +} + +/* Remove omp_member_access_dummy_var variables from BLOCK_VARS of + block and its subblocks. */ + +static void +remove_member_access_dummy_vars (tree block) +{ + for (tree *pvar = &BLOCK_VARS (block); *pvar; ) + if (omp_member_access_dummy_var (*pvar)) + *pvar = DECL_CHAIN (*pvar); + else + pvar = &DECL_CHAIN (*pvar); + + for (block = BLOCK_SUBBLOCKS (block); block; block = BLOCK_CHAIN (block)) + remove_member_access_dummy_vars (block); +} + /* If a context was created for STMT when it was scanned, return it. */ static omp_context * @@ -6961,6 +6998,7 @@ lower_omp_for (gimple_stmt_iterator *gsi_p, omp_context *ctx) pop_gimplify_context (new_stmt); gimple_bind_append_vars (new_stmt, ctx->block_vars); + maybe_remove_omp_member_access_dummy_vars (new_stmt); BLOCK_VARS (block) = gimple_bind_vars (new_stmt); if (BLOCK_VARS (block)) TREE_USED (block) = 1; @@ -7413,6 +7451,7 @@ lower_omp_taskreg (gimple_stmt_iterator *gsi_p, omp_context *ctx) /* Declare all the variables created by mapping and the variables declared in the scope of the parallel body. */ record_vars_into (ctx->block_vars, child_fn); + maybe_remove_omp_member_access_dummy_vars (par_bind); record_vars_into (gimple_bind_vars (par_bind), child_fn); if (ctx->record_type) @@ -7781,6 +7820,7 @@ lower_omp_target (gimple_stmt_iterator *gsi_p, omp_context *ctx) /* Declare all the variables created by mapping and the variables declared in the scope of the target body. */ record_vars_into (ctx->block_vars, child_fn); + maybe_remove_omp_member_access_dummy_vars (tgt_bind); record_vars_into (gimple_bind_vars (tgt_bind), child_fn); } @@ -8772,6 +8812,7 @@ lower_omp_1 (gimple_stmt_iterator *gsi_p, omp_context *ctx) break; case GIMPLE_BIND: lower_omp (gimple_bind_body_ptr (as_a (stmt)), ctx); + maybe_remove_omp_member_access_dummy_vars (as_a (stmt)); break; case GIMPLE_OMP_PARALLEL: case GIMPLE_OMP_TASK: @@ -8976,6 +9017,16 @@ execute_lower_omp (void) all_contexts = NULL; } BITMAP_FREE (task_shared_vars); + + /* If current function is a method, remove artificial dummy VAR_DECL created + for non-static data member privatization, they aren't needed for + debuginfo nor anything else, have been already replaced everywhere in the + IL and cause problems with LTO. */ + if (DECL_ARGUMENTS (current_function_decl) + && DECL_ARTIFICIAL (DECL_ARGUMENTS (current_function_decl)) + && (TREE_CODE (TREE_TYPE (DECL_ARGUMENTS (current_function_decl))) + == POINTER_TYPE)) + remove_member_access_dummy_vars (DECL_INITIAL (current_function_decl)); return 0; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index fdbb549..1688f5a 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-02-10 Jakub Jelinek + + PR sanitizer/83987 + * g++.dg/ubsan/pr83987-2.C: New test. + 2018-02-09 Peter Bergner PR target/83926 diff --git a/gcc/testsuite/g++.dg/ubsan/pr83987-2.C b/gcc/testsuite/g++.dg/ubsan/pr83987-2.C new file mode 100644 index 0000000..a70b7b2 --- /dev/null +++ b/gcc/testsuite/g++.dg/ubsan/pr83987-2.C @@ -0,0 +1,24 @@ +// PR sanitizer/83987 +// { dg-do compile { target fopenmp } } +// { dg-options "-fopenmp -fsanitize=vptr" } + +struct A +{ + int i; +}; + +struct B : virtual A +{ + void foo(); +}; + +void B::foo() +{ +#pragma omp parallel + { + #pragma omp sections lastprivate (i) + { + i = 0; + } + } +} -- cgit v1.1 From f99507a70e4f1500d3a295a448052011572efe5c Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sat, 10 Feb 2018 00:16:12 +0000 Subject: Daily bump. From-SVN: r257548 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index de1dc49..7e62ece 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20180209 +20180210 -- cgit v1.1 From cb2e8560f9d446c60610934b8d28b810f8396189 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Sat, 10 Feb 2018 15:19:15 +1030 Subject: PR84300, ICE in dwarf2cfi on ppc64le with -fsplit-stack -fno-omit-frame-pointer PR target/84300 gcc/ * config/rs6000/rs6000.md (split_stack_return): Remove (use ..). Specify LR as an input. gcc/testsuite/ * gcc.dg/pr84300.c: New. From-SVN: r257549 --- gcc/ChangeLog | 6 ++++++ gcc/config/rs6000/rs6000.md | 2 +- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gcc.dg/pr84300.c | 5 +++++ 4 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/gcc.dg/pr84300.c (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0ee4f1c..9e4682e 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,9 @@ +2018-02-10 Alan Modra + + PR target/84300 + * config/rs6000/rs6000.md (split_stack_return): Remove (use ..). + Specify LR as an input. + 2018-02-10 Jakub Jelinek PR sanitizer/83987 diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 8aa4e0e..5f44d80 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -13360,7 +13360,7 @@ ;; Use r0 to stop regrename twiddling with lr restore insns emitted ;; after the call to __morestack. (define_insn "split_stack_return" - [(unspec_volatile [(use (reg:SI 0))] UNSPECV_SPLIT_STACK_RETURN)] + [(unspec_volatile [(reg:SI 0) (reg:SI LR_REGNO)] UNSPECV_SPLIT_STACK_RETURN)] "" "blr" [(set_attr "type" "jmpreg")]) diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1688f5a..e899f56 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-02-10 Alan Modra + + PR target/84300 + * gcc.dg/pr84300.c: New. + 2018-02-10 Jakub Jelinek PR sanitizer/83987 diff --git a/gcc/testsuite/gcc.dg/pr84300.c b/gcc/testsuite/gcc.dg/pr84300.c new file mode 100644 index 0000000..6016799 --- /dev/null +++ b/gcc/testsuite/gcc.dg/pr84300.c @@ -0,0 +1,5 @@ +/* { dg-do compile } */ +/* { dg-require-effective-target split_stack } */ +/* { dg-options "-g -O2 -fsplit-stack -fno-omit-frame-pointer" } */ + +void trap () { __builtin_trap (); } -- cgit v1.1 From 950ab3f1419619d6e4bec7d2f029b9aff00813e9 Mon Sep 17 00:00:00 2001 From: Paul Thomas Date: Sat, 10 Feb 2018 18:16:14 +0000 Subject: re PR fortran/84141 (Internal error: type_name(): Bad type) 2018-02-10 Paul Thomas PR fortran/84141 PR fortran/84155 * trans-array.c (gfc_array_init_size): Revert the change made in revision 257356 setting the dtype. * trans-types.c (gfc_get_dtype): Do not use the cached dtype. Call gfc_get_dtype_rank_type every time. PR fortran/56691 * trans-array.c (gfc_conv_expr_descriptor): If the source array is a descriptor type, use its offset, removing the condition that is be a class expression. 2018-02-10 Paul Thomas PR fortran/56691 * gfortran.dg/type_to_class_4.f03: New test. From-SVN: r257550 --- gcc/fortran/ChangeLog | 14 +++++++++++ gcc/fortran/trans-array.c | 10 ++++---- gcc/fortran/trans-types.c | 3 --- gcc/testsuite/ChangeLog | 5 ++++ gcc/testsuite/gfortran.dg/type_to_class_4.f03 | 35 +++++++++++++++++++++++++++ 5 files changed, 59 insertions(+), 8 deletions(-) create mode 100644 gcc/testsuite/gfortran.dg/type_to_class_4.f03 (limited to 'gcc') diff --git a/gcc/fortran/ChangeLog b/gcc/fortran/ChangeLog index a87c48a..b0bd14f 100644 --- a/gcc/fortran/ChangeLog +++ b/gcc/fortran/ChangeLog @@ -1,3 +1,17 @@ +2018-02-10 Paul Thomas + + PR fortran/84141 + PR fortran/84155 + * trans-array.c (gfc_array_init_size): Revert the change made + in revision 257356 setting the dtype. + * trans-types.c (gfc_get_dtype): Do not use the cached dtype. + Call gfc_get_dtype_rank_type every time. + + PR fortran/56691 + * trans-array.c (gfc_conv_expr_descriptor): If the source array + is a descriptor type, use its offset, removing the condition + that is be a class expression. + 2018-02-07 Steven G. Kargl PR fortran/82994 diff --git a/gcc/fortran/trans-array.c b/gcc/fortran/trans-array.c index c845bef..d8b4381 100644 --- a/gcc/fortran/trans-array.c +++ b/gcc/fortran/trans-array.c @@ -5354,8 +5354,8 @@ gfc_array_init_size (tree descriptor, int rank, int corank, tree * poffset, } else { - tmp = gfc_get_dtype_rank_type (rank, gfc_get_element_type (type)); - gfc_add_modify (pblock, gfc_conv_descriptor_dtype (descriptor), tmp); + tmp = gfc_conv_descriptor_dtype (descriptor); + gfc_add_modify (pblock, tmp, gfc_get_dtype (type)); } or_expr = logical_false_node; @@ -7529,9 +7529,9 @@ gfc_conv_expr_descriptor (gfc_se *se, gfc_expr *expr) : base; gfc_conv_descriptor_offset_set (&loop.pre, parm, tmp); } - else if (IS_CLASS_ARRAY (expr) && !se->data_not_needed - && (!rank_remap || se->use_offset) - && GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc))) + else if (GFC_DESCRIPTOR_TYPE_P (TREE_TYPE (desc)) + && !se->data_not_needed + && (!rank_remap || se->use_offset)) { gfc_conv_descriptor_offset_set (&loop.pre, parm, gfc_conv_descriptor_offset_get (desc)); diff --git a/gcc/fortran/trans-types.c b/gcc/fortran/trans-types.c index b15a4b2..697b735 100644 --- a/gcc/fortran/trans-types.c +++ b/gcc/fortran/trans-types.c @@ -1593,9 +1593,6 @@ gfc_get_dtype (tree type) gcc_assert (GFC_DESCRIPTOR_TYPE_P (type) || GFC_ARRAY_TYPE_P (type)); - if (GFC_TYPE_ARRAY_DTYPE (type)) - return GFC_TYPE_ARRAY_DTYPE (type); - rank = GFC_TYPE_ARRAY_RANK (type); etype = gfc_get_element_type (type); dtype = gfc_get_dtype_rank_type (rank, etype); diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index e899f56..a14db69 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2018-02-10 Paul Thomas + + PR fortran/56691 + * gfortran.dg/type_to_class_4.f03: New test. + 2018-02-10 Alan Modra PR target/84300 diff --git a/gcc/testsuite/gfortran.dg/type_to_class_4.f03 b/gcc/testsuite/gfortran.dg/type_to_class_4.f03 new file mode 100644 index 0000000..196e448 --- /dev/null +++ b/gcc/testsuite/gfortran.dg/type_to_class_4.f03 @@ -0,0 +1,35 @@ +! { dg-do run } +! +! Test the fix for PR56691 comment #7 (and comment #0). +! +! Reduced from the original of Marco Restelli +! by Janus Weil +! +module m2 + implicit none + type :: t_stv + real :: f1 + end type +contains + subroutine lcb(y) + class(t_stv), intent(in) :: y(:) + integer :: k + do k=1,size(y) + if (int(y(k)%f1) .ne. k) call abort + enddo + end subroutine +end module + +program test + use m2 + implicit none + + type(t_stv), allocatable :: work(:) + + allocate(work(4)) + work(:)%f1 = (/ 1.,2.,3.,4./) + + call lcb(work) + call lcb(work(:4)) ! Indexing used to be offset by 1. + +end program -- cgit v1.1 From 123eaa467145a5a5749aba150e07cf254fd8c69a Mon Sep 17 00:00:00 2001 From: John David Anglin Date: Sat, 10 Feb 2018 23:15:53 +0000 Subject: pa.c (hppa_profile_hook): Mark SYMBOL_REF for _mcount as function label. * config/pa/pa.c (hppa_profile_hook): Mark SYMBOL_REF for _mcount as function label. From-SVN: r257554 --- gcc/ChangeLog | 5 +++++ gcc/config/pa/pa.c | 8 ++++++-- 2 files changed, 11 insertions(+), 2 deletions(-) (limited to 'gcc') diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9e4682e..677c316 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2018-02-10 John David Anglin + + * config/pa/pa.c (hppa_profile_hook): Mark SYMBOL_REF for _mcount as + function label. + 2018-02-10 Alan Modra PR target/84300 diff --git a/gcc/config/pa/pa.c b/gcc/config/pa/pa.c index 0809a79..13d5777 100644 --- a/gcc/config/pa/pa.c +++ b/gcc/config/pa/pa.c @@ -4578,13 +4578,17 @@ hppa_profile_hook (int label_no) lcla2 and load_offset_label_address insn patterns. */ rtx reg = gen_reg_rtx (SImode); rtx_code_label *label_rtx = gen_label_rtx (); - rtx mcount = gen_rtx_MEM (Pmode, gen_rtx_SYMBOL_REF (Pmode, "_mcount")); int reg_parm_stack_space = REG_PARM_STACK_SPACE (NULL_TREE); - rtx arg_bytes, begin_label_rtx; + rtx arg_bytes, begin_label_rtx, mcount, sym; rtx_insn *call_insn; char begin_label_name[16]; bool use_mcount_pcrel_call; + /* Set up call destination. */ + sym = gen_rtx_SYMBOL_REF (Pmode, "_mcount"); + pa_encode_label (sym); + mcount = gen_rtx_MEM (Pmode, sym); + /* If we can reach _mcount with a pc-relative call, we can optimize loading the address of the current function. This requires linker long branch stub support. */ -- cgit v1.1 From e5a6b70e88b852b5a1932d4cefd619b6d82a02ba Mon Sep 17 00:00:00 2001 From: GCC Administrator Date: Sun, 11 Feb 2018 00:16:13 +0000 Subject: Daily bump. From-SVN: r257559 --- gcc/DATESTAMP | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc') diff --git a/gcc/DATESTAMP b/gcc/DATESTAMP index 7e62ece..d1c73de 100644 --- a/gcc/DATESTAMP +++ b/gcc/DATESTAMP @@ -1 +1 @@ -20180210 +20180211 -- cgit v1.1