From 091fe099ba9093b8577ad4a10b56e18c6ea3daea Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Sat, 25 Jan 2020 23:09:57 -0500 Subject: checking: avoid verify_type_variant crash on incomplete type. Here, we end up calling gen_type_die_with_usage for a type that's in the middle of finish_struct_1, after we set TYPE_NEEDS_CONSTRUCTING on it but before we copy all the flags to the variants--and, significantly, before we set its TYPE_SIZE. It seems reasonable to only look at TYPE_NEEDS_CONSTRUCTING on complete types, since we aren't going to try to create an object of an incomplete type any other way. PR c++/92601 * tree.c (verify_type_variant): Only verify TYPE_NEEDS_CONSTRUCTING of complete types. --- gcc/tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index 0ddf002..298499f 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -13881,9 +13881,9 @@ verify_type_variant (const_tree t, tree tv) debug_tree (TYPE_SIZE_UNIT (t)); return false; } + verify_variant_match (TYPE_NEEDS_CONSTRUCTING); } verify_variant_match (TYPE_PRECISION); - verify_variant_match (TYPE_NEEDS_CONSTRUCTING); if (RECORD_OR_UNION_TYPE_P (t)) verify_variant_match (TYPE_TRANSPARENT_AGGR); else if (TREE_CODE (t) == ARRAY_TYPE) -- cgit v1.1 From 8def1d525c52f0f7fccd90f3c4624a8fe6c42882 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 18 Feb 2020 08:54:52 +0100 Subject: Typo fixes - functoin -> function [PR93796] 2020-02-18 Jakub Jelinek PR driver/93796 * params.opt (-param=ipa-max-switch-predicate-bounds=): Fix help typo, functoin -> function. * tree.c (free_lang_data_in_decl): Fix comment typo, functoin -> function. * ipa-visibility.c (cgraph_externally_visible_p): Likewise. --- gcc/tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index 298499f..66d52c7 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -5803,7 +5803,7 @@ free_lang_data_in_decl (tree decl, class free_lang_data_d *fld) } else if (VAR_P (decl)) { - /* See comment above why we set the flag for functoins. */ + /* See comment above why we set the flag for functions. */ if (TREE_PUBLIC (decl)) TREE_ADDRESSABLE (decl) = true; if ((DECL_EXTERNAL (decl) -- cgit v1.1 From e835226bab5b3575c8a55c048dcfed3d4cde5e0e Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Wed, 11 Mar 2020 11:29:39 +0100 Subject: Fix GIMPLE verification failure in LTO mode on Ada code The issue is that tree_is_indexable doesn't return the same result for a FIELD_DECL with QUAL_UNION_TYPE and the QUAL_UNION_TYPE, resulting in two instances of the QUAL_UNION_TYPE in the bytecode. The result for the type is the correct one (false, since it is variably modified) while the result for the field is falsely true because: else if (TREE_CODE (t) == FIELD_DECL && lto_variably_modified_type_p (DECL_CONTEXT (t))) return false; is not satisfied. The reason for this is that the DECL_QUALIFIER of fields of a QUAL_UNION_TYPE depends on a discriminant in Ada, which means that the size of the type does too (CONTAINS_PLACEHOLDER_P), which in turn means that it is reset to a mere PLACEHOLDER_EXPR by free_lang_data, which finally means that the size of DECL_CONTEXT is too, so RETURN_TRUE_IF_VAR is false. In other words, the CONTAINS_PLACEHOLDER_P property of the DECL_QUALIFIER of fields of a QUAL_UNION_TYPE hides the variably_modified_type_p property of these fields, if you look from the outside. PR middle-end/93961 * tree.c (variably_modified_type_p) : Recurse into fields whose type is a qualified union. --- gcc/tree.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index 66d52c7..905563f 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -9206,8 +9206,18 @@ variably_modified_type_p (tree type, tree fn) RETURN_TRUE_IF_VAR (DECL_SIZE (t)); RETURN_TRUE_IF_VAR (DECL_SIZE_UNIT (t)); + /* If the type is a qualified union, then the DECL_QUALIFIER + of fields can also be an expression containing a variable. */ if (TREE_CODE (type) == QUAL_UNION_TYPE) RETURN_TRUE_IF_VAR (DECL_QUALIFIER (t)); + + /* If the field is a qualified union, then it's only a container + for what's inside so we look into it. That's necessary in LTO + mode because the sizes of the field tested above have been set + to PLACEHOLDER_EXPRs by free_lang_data. */ + if (TREE_CODE (TREE_TYPE (t)) == QUAL_UNION_TYPE + && variably_modified_type_p (TREE_TYPE (t), fn)) + return true; } break; -- cgit v1.1 From 700d4cb08c88aec37c13e21e63dd61fd698baabc Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 17 Mar 2020 13:52:19 +0100 Subject: Fix up duplicated duplicated words mostly in comments In the r10-7197-gbae7b38cf8a21e068ad5c0bab089dedb78af3346 commit I've noticed duplicated word in a message, which lead me to grep for those and we have a tons of them. I've used grep -v 'long long\|optab optab\|template template\|double double' *.[chS] */*.[chS] *.def config/*/* 2>/dev/null | grep ' \([a-zA-Z]\+\) \1 ' Note, the command will not detect the doubled words at the start or end of line or when one of the words is at the end of line and the next one at the start of another one. Some of it is fairly obvious, e.g. all the "the the" cases which is something I've posted and committed patch for already e.g. in 2016, other cases are often valid, e.g. "that that" seems to look mostly ok to me. Some cases are quite hard to figure out, I've left out some of them from the patch (e.g. "and and" in some cases isn't talking about bitwise/logical and and so looks incorrect, but in other cases it is talking about those operations). In most cases the right solution seems to be to remove one of the duplicated words, but not always. I think most important are the ones with user visible messages (in the patch 3 of the first 4 hunks), the rest is just comments (and internal documentation; for that see the doc/tm.texi changes). 2020-03-17 Jakub Jelinek * lra-spills.c (remove_pseudos): Fix up duplicated word issue in a dump message. * tree-sra.c (create_access_replacement): Fix up duplicated word issue in a comment. * read-rtl-function.c (find_param_by_name, function_reader::parse_enum_value, function_reader::get_insn_by_uid): Likewise. * spellcheck.c (get_edit_distance_cutoff): Likewise. * tree-data-ref.c (create_ifn_alias_checks): Likewise. * tree.def (SWITCH_EXPR): Likewise. * selftest.c (assert_str_contains): Likewise. * ipa-param-manipulation.h (class ipa_param_body_adjustments): Likewise. * tree-ssa-math-opts.c (convert_expand_mult_copysign): Likewise. * tree-ssa-loop-split.c (find_vdef_in_loop): Likewise. * langhooks.h (struct lang_hooks_for_decls): Likewise. * ipa-prop.h (struct ipa_param_descriptor): Likewise. * tree-ssa-strlen.c (handle_builtin_string_cmp, handle_store): Likewise. * tree-ssa-dom.c (simplify_stmt_for_jump_threading): Likewise. * tree-ssa-reassoc.c (reassociate_bb): Likewise. * tree.c (component_ref_size): Likewise. * hsa-common.c (hsa_init_compilation_unit_data): Likewise. * gimple-ssa-sprintf.c (get_string_length, format_string, format_directive): Likewise. * omp-grid.c (grid_process_kernel_body_copy): Likewise. * input.c (string_concat_db::get_string_concatenation, test_lexer_string_locations_ucn4): Likewise. * cfgexpand.c (pass_expand::execute): Likewise. * gimple-ssa-warn-restrict.c (builtin_memref::offset_out_of_bounds, maybe_diag_overlap): Likewise. * rtl.c (RTX_CODE_HWINT_P_1): Likewise. * shrink-wrap.c (spread_components): Likewise. * tree-ssa-dse.c (initialize_ao_ref_for_dse, valid_ao_ref_for_dse): Likewise. * tree-call-cdce.c (shrink_wrap_one_built_in_call_with_conds): Likewise. * dwarf2out.c (dwarf2out_early_finish): Likewise. * gimple-ssa-store-merging.c: Likewise. * ira-costs.c (record_operand_costs): Likewise. * tree-vect-loop.c (vectorizable_reduction): Likewise. * target.def (dispatch): Likewise. (validate_dims, gen_ccmp_first): Fix up duplicated word issue in documentation text. * doc/tm.texi: Regenerated. * config/i386/x86-tune.def (X86_TUNE_PARTIAL_FLAG_REG_STALL): Fix up duplicated word issue in a comment. * config/i386/i386.c (ix86_test_loading_unspec): Likewise. * config/i386/i386-features.c (remove_partial_avx_dependency): Likewise. * config/msp430/msp430.c (msp430_select_section): Likewise. * config/gcn/gcn-run.c (load_image): Likewise. * config/aarch64/aarch64-sve.md (sve_ld1r): Likewise. * config/aarch64/aarch64.c (aarch64_gen_adjusted_ldpstp): Likewise. * config/aarch64/falkor-tag-collision-avoidance.c (single_dest_per_chain): Likewise. * config/nvptx/nvptx.c (nvptx_record_fndecl): Likewise. * config/fr30/fr30.c (fr30_arg_partial_bytes): Likewise. * config/rs6000/rs6000-string.c (expand_cmp_vec_sequence): Likewise. * config/rs6000/rs6000-p8swap.c (replace_swapped_load_constant): Likewise. * config/rs6000/rs6000-c.c (rs6000_target_modify_macros): Likewise. * config/rs6000/rs6000.c (rs6000_option_override_internal): Likewise. * config/rs6000/rs6000-logue.c (rs6000_emit_probe_stack_range_stack_clash): Likewise. * config/nds32/nds32-md-auxiliary.c (nds32_split_ashiftdi3): Likewise. Fix various other issues in the comment. c-family/ * c-common.c (resolve_overloaded_builtin): Fix up duplicated word issue in a diagnostic message. cp/ * pt.c (tsubst): Fix up duplicated word issue in a diagnostic message. (lookup_template_class_1, tsubst_expr): Fix up duplicated word issue in a comment. * parser.c (cp_parser_statement, cp_parser_linkage_specification, cp_parser_placeholder_type_specifier, cp_parser_constraint_requires_parens): Likewise. * name-lookup.c (suggest_alternative_in_explicit_scope): Likewise. fortran/ * array.c (gfc_check_iter_variable): Fix up duplicated word issue in a comment. * arith.c (gfc_arith_concat): Likewise. * resolve.c (gfc_resolve_ref): Likewise. * frontend-passes.c (matmul_lhs_realloc): Likewise. * module.c (gfc_match_submodule, load_needed): Likewise. * trans-expr.c (gfc_init_se): Likewise. --- gcc/tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index 905563f..ee45193 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -13663,7 +13663,7 @@ component_ref_size (tree ref, bool *interior_zero_length /* = NULL */) } /* BASE is the declared object of which MEMBER is either a member - or that is is cast to REFTYPE (e.g., a char buffer used to store + or that is cast to REFTYPE (e.g., a char buffer used to store a REFTYPE object). */ tree reftype = TREE_TYPE (TREE_OPERAND (ref, 0)); tree basetype = TREE_TYPE (base); -- cgit v1.1 From ca6c722561ce9b9dc7b59cfd9d29c9b466732721 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Mon, 23 Mar 2020 19:47:24 +0100 Subject: c++: Handle COMPOUND_EXPRs in get_narrower and warnings_for_convert_and_check [PR91993] As the testcases shows, the -Wconversion warning behaves quite differently when -fsanitize=undefined vs. when not sanitizing, but in the end it is not something specific to sanitizing, if a user uses return static_cast(static_cast((d++, a) << 1U) | b) | c; instead of return static_cast(static_cast(a << 1U) | b) | c; and thus there is some COMPOUND_EXPR involved, cp_build_binary_op behaves significantly different, e.g. shorten_binary_op will have different result (uc for the case without COMPOUND_EXPR, int with it), but it isn't limited to that. > How about improving get_narrower to handle COMPOUND_EXPR? I'd think that > would do the trick without affecting evaluation order. Not completely, had to change also warnings_for_convert_and_check, but with that it works. The float-cast-overflow* changes are needed because now with -O1+ we emit lots of -Woverflow warnings on the testcase, but we do emit those warnings on the testcase even when compiling just with -O1 and without -fsanitize=float-cast-overflow, so it seems to me a change in the right direction, having -fsanitize= or explicit comma expressions smaller effect on the warnings that are emitted. 2020-03-23 Jakub Jelinek PR c++/91993 * tree.c (get_narrower): Handle COMPOUND_EXPR by recursing on ultimate rhs and if returned something different, reconstructing the COMPOUND_EXPRs. * c-warn.c (warnings_for_convert_and_check): For expr and/or result being COMPOUND_EXPRs, skip to ultimate rhs. * g++.dg/warn/Wconversion-pr91993.C: New test. * g++.dg/ubsan/pr91993.C: New test. * c-c++-common/ubsan/float-cast-overflow-1.c: Add -Wno-overflow to dg-options. * c-c++-common/ubsan/float-cast-overflow-2.c: Likewise. * c-c++-common/ubsan/float-cast-overflow-4.c: Likewise. --- gcc/tree.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index ee45193..f38dfff 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -8862,6 +8862,21 @@ get_narrower (tree op, int *unsignedp_ptr) tree win = op; bool integral_p = INTEGRAL_TYPE_P (TREE_TYPE (op)); + if (TREE_CODE (op) == COMPOUND_EXPR) + { + while (TREE_CODE (op) == COMPOUND_EXPR) + op = TREE_OPERAND (op, 1); + tree ret = get_narrower (op, unsignedp_ptr); + if (ret == op) + return win; + op = win; + for (tree *p = &win; TREE_CODE (op) == COMPOUND_EXPR; + op = TREE_OPERAND (op, 1), p = &TREE_OPERAND (*p, 1)) + *p = build2_loc (EXPR_LOCATION (op), COMPOUND_EXPR, + TREE_TYPE (ret), TREE_OPERAND (op, 0), + ret); + return win; + } while (TREE_CODE (op) == NOP_EXPR) { int bitschange -- cgit v1.1 From da920d0c46c38fe25ee0b597a8698d3a4d098f3c Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 26 Mar 2020 10:35:52 +0100 Subject: tree: Fix -fcompare-debug issues due to protected_set_expr_location [PR94323] The following testcase FAILs since recently when the C++ FE started calling protected_set_expr_location more often. With -g, it is called on a STATEMENT_LIST that contains a DEBUG_BEGIN_STMT and CLEANUP_POINT_EXPR, and as STATEMENT_LISTs have !CAN_HAVE_LOCATION_P, nothing is set. Without -g, it is called instead on the CLEANUP_POINT_EXPR directly and changes its location. The following patch recurses on the single non-DEBUG_BEGIN_STMT statement of a STATEMENT_LIST if any to make the two behave the same. 2020-03-26 Jakub Jelinek PR debug/94323 * tree.c (protected_set_expr_location): Recurse on STATEMENT_LIST that contains exactly one non-DEBUG_BEGIN_STMT statement. * g++.dg/debug/pr94323.C: New test. --- gcc/tree.c | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index f38dfff..63dc673 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -5146,6 +5146,33 @@ protected_set_expr_location (tree t, location_t loc) { if (CAN_HAVE_LOCATION_P (t)) SET_EXPR_LOCATION (t, loc); + else if (t && TREE_CODE (t) == STATEMENT_LIST) + { + /* With -gstatement-frontiers we could have a STATEMENT_LIST with + DEBUG_BEGIN_STMT(s) and only a single other stmt, which with + -g wouldn't be present and we'd have that single other stmt + directly instead. */ + struct tree_statement_list_node *n = STATEMENT_LIST_HEAD (t); + if (!n) + return; + while (TREE_CODE (n->stmt) == DEBUG_BEGIN_STMT) + { + n = n->next; + if (!n) + return; + } + tree t2 = n->stmt; + do + { + n = n->next; + if (!n) + { + protected_set_expr_location (t2, loc); + return; + } + } + while (TREE_CODE (n->stmt) == DEBUG_BEGIN_STMT); + } } /* Data used when collecting DECLs and TYPEs for language data removal. */ -- cgit v1.1 From ef6631051d4bb9519f3f0dd5f3b3eadbd67bc10a Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Fri, 3 Apr 2020 13:46:49 +0200 Subject: middle-end/94465 - handle released SSA names in array_ref_low_bound array_ref_low_bound is used in dumping ARRAY_REFs which in turn is called when basic blocks are deleted. cleanup_control_flow_pre consciously decides to remove unreachable basic-blocks in arbitrary order so the following makes array_ref_low_bound forgiving in the case the SSA name with the index definition has been released already. 2020-04-03 Richard Biener PR middle-end/94465 * tree.c (array_ref_low_bound): Deal with released SSA names in index position. --- gcc/tree.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index 63dc673..0fe3afc 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -13426,7 +13426,9 @@ array_ref_low_bound (tree exp) return SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_MIN_VALUE (domain_type), exp); /* Otherwise, return a zero of the appropriate type. */ - return build_int_cst (TREE_TYPE (TREE_OPERAND (exp, 1)), 0); + tree idxtype = TREE_TYPE (TREE_OPERAND (exp, 1)); + return (idxtype == error_mark_node + ? integer_zero_node : build_int_cst (idxtype, 0)); } /* Return a tree representing the upper bound of the array mentioned in -- cgit v1.1 From aae5d08a8d4dcee576a85ea76febe56c53675ef2 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Sat, 4 Apr 2020 09:16:07 +0200 Subject: c++: Fix further protected_set_expr_location related -fcompare-debug issues [PR94441] My recent protected_set_expr_location changes work well when that function is called unconditionally, but as the testcase shows, the C++ FE has a few spots that do: if (!EXPR_HAS_LOCATION (stmt)) protected_set_expr_location (stmt, locus); or similar. Now, if we have for -g0 stmt of some expression that can have location and has != UNKNOWN_LOCATION, while -g instead has a STATEMENT_LIST containing some DEBUG_BEGIN_STMTs + that expression with that location, we don't call protected_set_expr_location in the -g0 case, but do call it in the -g case, because on the STATEMENT_LIST !EXPR_HAS_LOCATION. The following patch introduces a helper function which digs up the single expression of a STATEMENT_LIST and uses that expression in the EXPR_HAS_LOCATION check (plus changes protected_set_expr_location to also use that helper). Or do we want a further wrapper, perhaps C++ FE only, that would do this protected_set_expr_location_if_unset (stmt, locus)? 2020-04-04 Jakub Jelinek PR debug/94441 * tree-iterator.h (expr_single): Declare. * tree-iterator.c (expr_single): New function. * tree.h (protected_set_expr_location_if_unset): Declare. * tree.c (protected_set_expr_location): Use expr_single. (protected_set_expr_location_if_unset): New function. * parser.c (cp_parser_omp_for_loop): Use protected_set_expr_location_if_unset. * cp-gimplify.c (genericize_if_stmt, genericize_cp_loop): Likewise. * g++.dg/opt/pr94441.C: New test. --- gcc/tree.c | 38 ++++++++++++++------------------------ 1 file changed, 14 insertions(+), 24 deletions(-) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index 0fe3afc..fa956da 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -5148,33 +5148,23 @@ protected_set_expr_location (tree t, location_t loc) SET_EXPR_LOCATION (t, loc); else if (t && TREE_CODE (t) == STATEMENT_LIST) { - /* With -gstatement-frontiers we could have a STATEMENT_LIST with - DEBUG_BEGIN_STMT(s) and only a single other stmt, which with - -g wouldn't be present and we'd have that single other stmt - directly instead. */ - struct tree_statement_list_node *n = STATEMENT_LIST_HEAD (t); - if (!n) - return; - while (TREE_CODE (n->stmt) == DEBUG_BEGIN_STMT) - { - n = n->next; - if (!n) - return; - } - tree t2 = n->stmt; - do - { - n = n->next; - if (!n) - { - protected_set_expr_location (t2, loc); - return; - } - } - while (TREE_CODE (n->stmt) == DEBUG_BEGIN_STMT); + t = expr_single (t); + if (t && CAN_HAVE_LOCATION_P (t)) + SET_EXPR_LOCATION (t, loc); } } +/* Like PROTECTED_SET_EXPR_LOCATION, but only do that if T has + UNKNOWN_LOCATION. */ + +void +protected_set_expr_location_if_unset (tree t, location_t loc) +{ + t = expr_single (t); + if (t && !EXPR_HAS_LOCATION (t)) + protected_set_expr_location (t, loc); +} + /* Data used when collecting DECLs and TYPEs for language data removal. */ class free_lang_data_d -- cgit v1.1 From bca558de2a24b2a78c6a321d6cec384e07759d77 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Thu, 23 Apr 2020 21:11:36 +0200 Subject: tree: Fix up get_narrower [PR94724] In the recent get_narrower change, I wanted it to be efficient and avoid recursion if there are many nested COMPOUND_EXPRs. That builds the COMPOUND_EXPR nest with the right arguments, but as build2_loc computes some flags like TREE_SIDE_EFFECTS, TREE_CONSTANT and TREE_READONLY, when it is called with something that will not be the argument in the end, those flags are computed incorrectly. So, this patch instead uses an auto_vec and builds them in the reverse order so when they are built, they are built with the correct operands. 2020-04-23 Jakub Jelinek PR middle-end/94724 * tree.c (get_narrower): Instead of creating COMPOUND_EXPRs temporarily with non-final second operand and updating it later, push COMPOUND_EXPRs into a vector and process it in reverse, creating COMPOUND_EXPRs with the final operands. * gcc.c-torture/execute/pr94724.c: New test. --- gcc/tree.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index fa956da..da6b8e2 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -8881,18 +8881,22 @@ get_narrower (tree op, int *unsignedp_ptr) if (TREE_CODE (op) == COMPOUND_EXPR) { - while (TREE_CODE (op) == COMPOUND_EXPR) + do op = TREE_OPERAND (op, 1); + while (TREE_CODE (op) == COMPOUND_EXPR); tree ret = get_narrower (op, unsignedp_ptr); if (ret == op) return win; - op = win; - for (tree *p = &win; TREE_CODE (op) == COMPOUND_EXPR; - op = TREE_OPERAND (op, 1), p = &TREE_OPERAND (*p, 1)) - *p = build2_loc (EXPR_LOCATION (op), COMPOUND_EXPR, - TREE_TYPE (ret), TREE_OPERAND (op, 0), - ret); - return win; + auto_vec v; + unsigned int i; + for (tree op = win; TREE_CODE (op) == COMPOUND_EXPR; + op = TREE_OPERAND (op, 1)) + v.safe_push (op); + FOR_EACH_VEC_ELT_REVERSE (v, i, op) + ret = build2_loc (EXPR_LOCATION (op), COMPOUND_EXPR, + TREE_TYPE (win), TREE_OPERAND (op, 0), + ret); + return ret; } while (TREE_CODE (op) == NOP_EXPR) { -- cgit v1.1 From 34f6b14ff33e0c64b3a4a1a2cd871df715d69151 Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Tue, 28 Apr 2020 11:26:56 +0200 Subject: tree: Fix up TREE_SIDE_EFFECTS on internal calls [PR94809] On the following testcase, match.pd during GENERIC folding changes the -1U / x < y into __imag__ .MUL_OVERFLOW (x, y), but unfortunately unlike for normal calls nothing sets TREE_SIDE_EFFECTS on the call. There is the process_call_operands function that non-internal call creation calls and it is usable for internal calls too, e.g. TREE_SIDE_EFFECTS is derived from checking whether the call has side-effects (non-ECF_{CONST,PURE}; we have those for internal calls) and from whether any of the arguments has TREE_SIDE_EFFECTS. 2020-04-28 Jakub Jelinek PR tree-optimization/94809 * tree.c (build_call_expr_internal_loc_array): Call process_call_operands. * gcc.c-torture/execute/pr94809.c: New test. --- gcc/tree.c | 1 + 1 file changed, 1 insertion(+) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index da6b8e2..e28b295 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -11523,6 +11523,7 @@ build_call_expr_internal_loc_array (location_t loc, internal_fn ifn, CALL_EXPR_ARG (t, i) = args[i]; SET_EXPR_LOCATION (t, loc); CALL_EXPR_IFN (t) = ifn; + process_call_operands (t); return t; } -- cgit v1.1 From e6e616074f02b81c397a2848ab242b54ef21efbc Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Wed, 29 Apr 2020 12:21:23 +0200 Subject: lto/94822 - fix ICE in component_ref_size This ICE appears because gcc will stream it to the function_body section when processing the variable with the initial value of the constructor type, and the error_mark_node to the decls section. When recompiling, the value obtained with DECL_INITIAL will be error_mark. 2020-04-29 Richard Biener Li Zekun PR lto/94822 * tree.c (component_ref_size): Guard against error_mark_node DECL_INITIAL as it happens with LTO. * gcc.dg/lto/pr94822_0.c: New testcase. * gcc.dg/lto/pr94822_1.c: Alternate file. * gcc.dg/lto/pr94822.h: Likewise. --- gcc/tree.c | 35 ++++++++++++++++++----------------- 1 file changed, 18 insertions(+), 17 deletions(-) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index e28b295..e451401 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -13723,24 +13723,25 @@ component_ref_size (tree ref, bool *interior_zero_length /* = NULL */) /* MEMBER is a true flexible array member. Compute its size from the initializer of the BASE object if it has one. */ if (tree init = DECL_P (base) ? DECL_INITIAL (base) : NULL_TREE) - { - init = get_initializer_for (init, member); - if (init) - { - memsize = TYPE_SIZE_UNIT (TREE_TYPE (init)); - if (tree refsize = TYPE_SIZE_UNIT (reftype)) - { - /* Use the larger of the initializer size and the tail - padding in the enclosing struct. */ - poly_int64 rsz = tree_to_poly_int64 (refsize); - rsz -= baseoff; - if (known_lt (tree_to_poly_int64 (memsize), rsz)) - memsize = wide_int_to_tree (TREE_TYPE (memsize), rsz); - } + if (init != error_mark_node) + { + init = get_initializer_for (init, member); + if (init) + { + memsize = TYPE_SIZE_UNIT (TREE_TYPE (init)); + if (tree refsize = TYPE_SIZE_UNIT (reftype)) + { + /* Use the larger of the initializer size and the tail + padding in the enclosing struct. */ + poly_int64 rsz = tree_to_poly_int64 (refsize); + rsz -= baseoff; + if (known_lt (tree_to_poly_int64 (memsize), rsz)) + memsize = wide_int_to_tree (TREE_TYPE (memsize), rsz); + } - baseoff = 0; - } - } + baseoff = 0; + } + } if (!memsize) { -- cgit v1.1 From 6318fe77395fc0dd59419bc4d69cd06ac0158e54 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Wed, 29 Apr 2020 15:36:35 -0400 Subject: tree: Don't reuse types if TYPE_USER_ALIGN differ [PR94775] Here we trip on the TYPE_USER_ALIGN (t) assert in strip_typedefs: it gets "const d[0]" with TYPE_USER_ALIGN=0 but the result built by build_cplus_array_type is "const char[0]" with TYPE_USER_ALIGN=1. When we strip_typedefs the element of the array "const d", we see it's a typedef_variant_p, so we look at its DECL_ORIGINAL_TYPE, which is char, but we need to add the const qualifier, so we call cp_build_qualified_type -> build_qualified_type where get_qualified_type checks to see if we already have such a type by walking the variants list, which in this case is: char -> c -> const char -> const char -> d -> const d Because check_base_type only checks TYPE_ALIGN and not TYPE_USER_ALIGN, we choose the first const char, which has TYPE_USER_ALIGN set. If the element type of an array has TYPE_USER_ALIGN, the array type gets it too. So we can make check_base_type stricter. I was afraid that it might make us reuse types less often, but measuring showed that we build the same amount of types with and without the patch, while bootstrapping. PR c++/94775 * tree.c (check_base_type): Return true only if TYPE_USER_ALIGN match. (check_aligned_type): Check if TYPE_USER_ALIGN match. * g++.dg/warn/Warray-bounds-10.C: New test. --- gcc/tree.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index e451401..341766c 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -6493,7 +6493,8 @@ check_base_type (const_tree cand, const_tree base) TYPE_ATTRIBUTES (base))) return false; /* Check alignment. */ - if (TYPE_ALIGN (cand) == TYPE_ALIGN (base)) + if (TYPE_ALIGN (cand) == TYPE_ALIGN (base) + && TYPE_USER_ALIGN (cand) == TYPE_USER_ALIGN (base)) return true; /* Atomic types increase minimal alignment. We must to do so as well or we get duplicated canonical types. See PR88686. */ @@ -6528,6 +6529,7 @@ check_aligned_type (const_tree cand, const_tree base, unsigned int align) && TYPE_CONTEXT (cand) == TYPE_CONTEXT (base) /* Check alignment. */ && TYPE_ALIGN (cand) == align + && TYPE_USER_ALIGN (cand) == TYPE_USER_ALIGN (base) && attribute_list_equal (TYPE_ATTRIBUTES (cand), TYPE_ATTRIBUTES (base)) && check_lang_type (cand, base)); -- cgit v1.1 From 05be85b649173b10d0bf10255eb15275c2dcf509 Mon Sep 17 00:00:00 2001 From: Marek Polacek Date: Mon, 4 May 2020 10:26:43 -0400 Subject: Revert "tree: Don't reuse types if TYPE_USER_ALIGN differ [PR94775]" This reverts commit 6318fe77395fc0dd59419bc4d69cd06ac0158e54. Revert: 2020-04-30 Marek Polacek PR c++/94775 * tree.c (check_base_type): Return true only if TYPE_USER_ALIGN match. (check_aligned_type): Check if TYPE_USER_ALIGN match. --- gcc/tree.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index 341766c..e451401 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -6493,8 +6493,7 @@ check_base_type (const_tree cand, const_tree base) TYPE_ATTRIBUTES (base))) return false; /* Check alignment. */ - if (TYPE_ALIGN (cand) == TYPE_ALIGN (base) - && TYPE_USER_ALIGN (cand) == TYPE_USER_ALIGN (base)) + if (TYPE_ALIGN (cand) == TYPE_ALIGN (base)) return true; /* Atomic types increase minimal alignment. We must to do so as well or we get duplicated canonical types. See PR88686. */ @@ -6529,7 +6528,6 @@ check_aligned_type (const_tree cand, const_tree base, unsigned int align) && TYPE_CONTEXT (cand) == TYPE_CONTEXT (base) /* Check alignment. */ && TYPE_ALIGN (cand) == align - && TYPE_USER_ALIGN (cand) == TYPE_USER_ALIGN (base) && attribute_list_equal (TYPE_ATTRIBUTES (cand), TYPE_ATTRIBUTES (base)) && check_lang_type (cand, base)); -- cgit v1.1 From a139bc2b492de8a761890a5d299951dede3d8f7b Mon Sep 17 00:00:00 2001 From: Jakub Jelinek Date: Fri, 8 May 2020 09:37:09 +0200 Subject: tree: Avoid variable sharing in get_narrower [PR94724] On Thu, May 07, 2020 at 02:45:29PM +0200, Thomas Schwinge wrote: > >>+ for (tree op = win; TREE_CODE (op) == COMPOUND_EXPR; > > ..., and new 'op' variable here. > > >>+ op = TREE_OPERAND (op, 1)) > >>+ v.safe_push (op); > >>+ FOR_EACH_VEC_ELT_REVERSE (v, i, op) > >>+ ret = build2_loc (EXPR_LOCATION (op), COMPOUND_EXPR, > >>+ TREE_TYPE (win), TREE_OPERAND (op, 0), > >>+ ret); > >>+ return ret; > >> } > >> while (TREE_CODE (op) == NOP_EXPR) > >> { There is no reason for the shadowing and op at this point acts as a temporary and will be overwritten in FOR_EACH_VEC_ELT_REVERSE anyway. So, we can just s/tree // here. 2020-05-08 Jakub Jelinek PR middle-end/94724 * tree.c (get_narrower): Reuse the op temporary instead of shadowing it. --- gcc/tree.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index e451401..3974749 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -8889,7 +8889,7 @@ get_narrower (tree op, int *unsignedp_ptr) return win; auto_vec v; unsigned int i; - for (tree op = win; TREE_CODE (op) == COMPOUND_EXPR; + for (op = win; TREE_CODE (op) == COMPOUND_EXPR; op = TREE_OPERAND (op, 1)) v.safe_push (op); FOR_EACH_VEC_ELT_REVERSE (v, i, op) -- cgit v1.1 From 65ba91b79e1664ba7e7f60f68e4cb956453b692e Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Sat, 9 May 2020 21:37:13 +0200 Subject: Remove last use of expr_align It was in the ada/gcc-interface repository and is outdated. * tree.h (expr_align): Delete. * tree.c (expr_align): Likewise. ada/ * gcc-interface/utils2.c: Include builtins.h. (known_alignment) : Use DECL_ALIGN for DECL_P operands and get_object_alignment for the rest. --- gcc/tree.c | 45 --------------------------------------------- 1 file changed, 45 deletions(-) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index 3974749..5b7d3fd 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -3351,51 +3351,6 @@ int_byte_position (const_tree field) return tree_to_shwi (byte_position (field)); } -/* Return the strictest alignment, in bits, that T is known to have. */ - -unsigned int -expr_align (const_tree t) -{ - unsigned int align0, align1; - - switch (TREE_CODE (t)) - { - CASE_CONVERT: case NON_LVALUE_EXPR: - /* If we have conversions, we know that the alignment of the - object must meet each of the alignments of the types. */ - align0 = expr_align (TREE_OPERAND (t, 0)); - align1 = TYPE_ALIGN (TREE_TYPE (t)); - return MAX (align0, align1); - - case SAVE_EXPR: case COMPOUND_EXPR: case MODIFY_EXPR: - case INIT_EXPR: case TARGET_EXPR: case WITH_CLEANUP_EXPR: - case CLEANUP_POINT_EXPR: - /* These don't change the alignment of an object. */ - return expr_align (TREE_OPERAND (t, 0)); - - case COND_EXPR: - /* The best we can do is say that the alignment is the least aligned - of the two arms. */ - align0 = expr_align (TREE_OPERAND (t, 1)); - align1 = expr_align (TREE_OPERAND (t, 2)); - return MIN (align0, align1); - - /* FIXME: LABEL_DECL and CONST_DECL never have DECL_ALIGN set - meaningfully, it's always 1. */ - case LABEL_DECL: case CONST_DECL: - case VAR_DECL: case PARM_DECL: case RESULT_DECL: - case FUNCTION_DECL: - gcc_assert (DECL_ALIGN (t) != 0); - return DECL_ALIGN (t); - - default: - break; - } - - /* Otherwise take the alignment from that of the type. */ - return TYPE_ALIGN (TREE_TYPE (t)); -} - /* Return, as a tree node, the number of elements for TYPE (which is an ARRAY_TYPE) minus one. This counts only elements of the top array. */ -- cgit v1.1 From d17a896da1e898928d337596d029f0ece0039d55 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Tue, 12 May 2020 09:01:10 +0100 Subject: tree: Add vector_element_bits(_tree) [PR94980 1/3] A lot of code that wants to know the number of bits in a vector element gets that information from the element's TYPE_SIZE, which is always equal to TYPE_SIZE_UNIT * BITS_PER_UNIT. This doesn't work for SVE and AVX512-style packed boolean vectors, where several elements can occupy a single byte. This patch introduces a new pair of helpers for getting the true (possibly sub-byte) size. I made a token attempt to convert obvious element size calculations, but I'm sure I missed some. 2020-05-12 Richard Sandiford gcc/ PR tree-optimization/94980 * tree.h (vector_element_bits, vector_element_bits_tree): Declare. * tree.c (vector_element_bits, vector_element_bits_tree): New. * match.pd: Use the new functions instead of determining the vector element size directly from TYPE_SIZE(_UNIT). * tree-vect-data-refs.c (vect_gather_scatter_fn_p): Likewise. * tree-vect-patterns.c (vect_recog_mask_conversion_pattern): Likewise. * tree-vect-stmts.c (vect_is_simple_cond): Likewise. * tree-vect-generic.c (expand_vector_piecewise): Likewise. (expand_vector_conversion): Likewise. (expand_vector_addition): Likewise for a TYPE_SIZE_UNIT used as a divisor. Convert the dividend to bits to compensate. * tree-vect-loop.c (vectorizable_live_operation): Call vector_element_bits instead of open-coding it. --- gcc/tree.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index 5b7d3fd..1aabffe 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -13806,6 +13806,30 @@ vector_type_mode (const_tree t) return mode; } +/* Return the size in bits of each element of vector type TYPE. */ + +unsigned int +vector_element_bits (const_tree type) +{ + gcc_checking_assert (VECTOR_TYPE_P (type)); + if (VECTOR_BOOLEAN_TYPE_P (type)) + return vector_element_size (tree_to_poly_uint64 (TYPE_SIZE (type)), + TYPE_VECTOR_SUBPARTS (type)); + return tree_to_uhwi (TYPE_SIZE (TREE_TYPE (type))); +} + +/* Calculate the size in bits of each element of vector type TYPE + and return the result as a tree of type bitsizetype. */ + +tree +vector_element_bits_tree (const_tree type) +{ + gcc_checking_assert (VECTOR_TYPE_P (type)); + if (VECTOR_BOOLEAN_TYPE_P (type)) + return bitsize_int (vector_element_bits (type)); + return TYPE_SIZE (TREE_TYPE (type)); +} + /* Verify that basic properties of T match TV and thus T can be a variant of TV. TV should be the more specified variant (i.e. the main variant). */ -- cgit v1.1 From 3956244c58acceebf1ef2cf9a63e99f0f82abcb7 Mon Sep 17 00:00:00 2001 From: Martin Sebor Date: Mon, 18 May 2020 15:07:48 -0600 Subject: PR middle-end/94940 - spurious -Warray-bounds for a zero length array member of union gcc/testsuite/ChangeLog: PR middle-end/94940 * gcc.dg/Warray-bounds-61.c: New test. gcc/ChangeLog: PR middle-end/94940 * tree-vrp.c (vrp_prop::check_mem_ref): Remove unreachable code. * tree.c (component_ref_size): Correct the handling or array members of unions. Drop a pointless test. Rename a local variable. --- gcc/tree.c | 28 ++++++++++++++++++---------- 1 file changed, 18 insertions(+), 10 deletions(-) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index 1aabffe..54e471a 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -13600,6 +13600,10 @@ component_ref_size (tree ref, bool *interior_zero_length /* = NULL */) if (!interior_zero_length) interior_zero_length = &int_0_len; + /* The object/argument referenced by the COMPONENT_REF and its type. */ + tree arg = TREE_OPERAND (ref, 0); + tree argtype = TREE_TYPE (arg); + /* The referenced member. */ tree member = TREE_OPERAND (ref, 1); tree memsize = DECL_SIZE_UNIT (member); @@ -13611,7 +13615,7 @@ component_ref_size (tree ref, bool *interior_zero_length /* = NULL */) bool trailing = array_at_struct_end_p (ref); bool zero_length = integer_zerop (memsize); - if (!trailing && (!interior_zero_length || !zero_length)) + if (!trailing && !zero_length) /* MEMBER is either an interior array or is an array with more than one element. */ return memsize; @@ -13630,9 +13634,14 @@ component_ref_size (tree ref, bool *interior_zero_length /* = NULL */) offset_int minidx = wi::to_offset (min); offset_int maxidx = wi::to_offset (max); if (maxidx - minidx > 0) - /* MEMBER is an array with more than 1 element. */ + /* MEMBER is an array with more than one element. */ return memsize; } + + /* For a refernce to a zero- or one-element array member of a union + use the size of the union instead of the size of the member. */ + if (TREE_CODE (argtype) == UNION_TYPE) + memsize = TYPE_SIZE_UNIT (argtype); } /* MEMBER is either a bona fide flexible array member, or a zero-length @@ -13647,28 +13656,27 @@ component_ref_size (tree ref, bool *interior_zero_length /* = NULL */) if (!*interior_zero_length) return NULL_TREE; - if (TREE_CODE (TREE_OPERAND (ref, 0)) != COMPONENT_REF) + if (TREE_CODE (arg) != COMPONENT_REF) return NULL_TREE; - base = TREE_OPERAND (ref, 0); + base = arg; while (TREE_CODE (base) == COMPONENT_REF) base = TREE_OPERAND (base, 0); baseoff = tree_to_poly_int64 (byte_position (TREE_OPERAND (ref, 1))); } /* BASE is the declared object of which MEMBER is either a member - or that is cast to REFTYPE (e.g., a char buffer used to store - a REFTYPE object). */ - tree reftype = TREE_TYPE (TREE_OPERAND (ref, 0)); + or that is cast to ARGTYPE (e.g., a char buffer used to store + an ARGTYPE object). */ tree basetype = TREE_TYPE (base); /* Determine the base type of the referenced object. If it's - the same as REFTYPE and MEMBER has a known size, return it. */ + the same as ARGTYPE and MEMBER has a known size, return it. */ tree bt = basetype; if (!*interior_zero_length) while (TREE_CODE (bt) == ARRAY_TYPE) bt = TREE_TYPE (bt); - bool typematch = useless_type_conversion_p (reftype, bt); + bool typematch = useless_type_conversion_p (argtype, bt); if (memsize && typematch) return memsize; @@ -13684,7 +13692,7 @@ component_ref_size (tree ref, bool *interior_zero_length /* = NULL */) if (init) { memsize = TYPE_SIZE_UNIT (TREE_TYPE (init)); - if (tree refsize = TYPE_SIZE_UNIT (reftype)) + if (tree refsize = TYPE_SIZE_UNIT (argtype)) { /* Use the larger of the initializer size and the tail padding in the enclosing struct. */ -- cgit v1.1 From 5c8344e7289969e1ee3103beaf9631b284f5ebc3 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Tue, 26 May 2020 10:14:38 +0200 Subject: Simplify types of TYPE_VALUES in enumeral types streaming code assumes that INTEGER_CST never appears in non-trivial component. This is not true and we sometimes stream such components which sort of silently works but breaks our IL invariant about tree sharing. This patch fixes one instance of this problem where ENUMERAL_TYPE lists all its valids in TYPE_VALUES that with some FEs (like Ada and C++) are having the enumeral type as a type while in other FEs (like C) are simple integer types. I convert them all to integers which also increases chance that they will be shared with other integer constants at stream time. gcc/ * tree.c (free_lang_data_in_type): Simpify types of TYPE_VALUES in enumeral types. --- gcc/tree.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index 54e471a..ea66924 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -5556,6 +5556,7 @@ free_lang_data_in_type (tree type, class free_lang_data_d *fld) { if (TREE_CODE (type) == ENUMERAL_TYPE) { + tree it = NULL_TREE; ENUM_IS_OPAQUE (type) = 0; ENUM_IS_SCOPED (type) = 0; /* Type values are used only for C++ ODR checking. Drop them @@ -5568,8 +5569,27 @@ free_lang_data_in_type (tree type, class free_lang_data_d *fld) /* Simplify representation by recording only values rather than const decls. */ for (tree e = TYPE_VALUES (type); e; e = TREE_CHAIN (e)) - if (TREE_CODE (TREE_VALUE (e)) == CONST_DECL) - TREE_VALUE (e) = DECL_INITIAL (TREE_VALUE (e)); + { + if (TREE_CODE (TREE_VALUE (e)) == CONST_DECL) + { + TREE_VALUE (e) = DECL_INITIAL (TREE_VALUE (e)); + /* We can not stream values whose TREE_TYPE is type itself + because that would create non-trivial CSS. Canonicalize + them to integer types. */ + } + /* Some frontends use ENUMERAL_TYPE to represent the constants. + This leads to nontrivial SCC components containing + INTEGER_CST which is not good for streaming. Convert them + all to corresponding integer type. */ + if (TREE_CODE (TREE_TYPE (TREE_VALUE (e))) != INTEGER_TYPE) + { + if (!it) + it = lang_hooks.types.type_for_size + (TYPE_PRECISION (TREE_TYPE (TREE_VALUE (e))), + TYPE_UNSIGNED (TREE_TYPE (TREE_VALUE (e)))); + TREE_VALUE (e) = fold_convert (it, TREE_VALUE (e)); + } + } } free_lang_data_in_one_sizepos (&TYPE_MIN_VALUE (type)); free_lang_data_in_one_sizepos (&TYPE_MAX_VALUE (type)); -- cgit v1.1 From fe7ebef7fe4f9acb79658ed9db0749b07efc3105 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Thu, 28 May 2020 00:31:15 +0200 Subject: Add support for __builtin_bswap128 This patch introduces a new builtin named __builtin_bswap128 on targets where TImode is supported, i.e. 64-bit targets only in practice. The implementation simply reuses the existing double word path in optab, so no routine is added to libgcc (which means that you get two calls to _bswapdi2 in the worst case). gcc/ChangeLog: * builtin-types.def (BT_UINT128): New primitive type. (BT_FN_UINT128_UINT128): New function type. * builtins.def (BUILT_IN_BSWAP128): New GCC builtin. * doc/extend.texi (__builtin_bswap128): Document it. * builtins.c (expand_builtin): Deal with BUILT_IN_BSWAP128. (is_inexpensive_builtin): Likewise. * fold-const-call.c (fold_const_call_ss): Likewise. * fold-const.c (tree_call_nonnegative_warnv_p): Likewise. * tree-ssa-ccp.c (evaluate_stmt): Likewise. * tree-vect-stmts.c (vect_get_data_ptr_increment): Likewise. (vectorizable_call): Likewise. * optabs.c (expand_unop): Always use the double word path for it. * tree-core.h (enum tree_index): Add TI_UINT128_TYPE. * tree.h (uint128_type_node): New global type. * tree.c (build_common_tree_nodes): Build it if TImode is supported. gcc/testsuite/ChangeLog: * gcc.dg/builtin-bswap-10.c: New test. * gcc.dg/builtin-bswap-11.c: Likewise. * gcc.dg/builtin-bswap-12.c: Likewise. * gcc.target/i386/builtin-bswap-5.c: Likewise. --- gcc/tree.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index ea66924..2cc9e4f 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -10350,6 +10350,8 @@ build_common_tree_nodes (bool signed_char) uint16_type_node = make_or_reuse_type (16, 1); uint32_type_node = make_or_reuse_type (32, 1); uint64_type_node = make_or_reuse_type (64, 1); + if (targetm.scalar_mode_supported_p (TImode)) + uint128_type_node = make_or_reuse_type (128, 1); /* Decimal float types. */ if (targetm.decimal_float_supported_p ()) -- cgit v1.1 From 3fb68f2e666d9de7e0326af9f43b12c9e98f19a6 Mon Sep 17 00:00:00 2001 From: Jan Hubicka Date: Wed, 3 Jun 2020 21:16:43 +0200 Subject: Optimize ODR enum streaming it turns out that half of the global decl stream of cc1 LTO build consits TREE_LISTS, identifiers and integer cosntats representing TYPE_VALUES of enums. Those are streamed only to produce ODR warning and used otherwise, so this patch moves the info to a separate section that is represented and streamed more effectively. This also adds place for more info that may be used for ODR diagnostics (i.e. at the moment we do not warn when the declarations differs i.e. by the associated member functions and their types) and the type inheritance graph rather then poluting the global stream. I was bit unsure what enums we want to store into the section. All parsed enums is probably too expensive, only those enums streamed to represent IL is bit hard to get, so I went for those seen by free lang data. As a plus we now get bit more precise warning because also the location of mismatched enum CONST_DECL is streamed. It changes: [WPA] read 4608466 unshared trees [WPA] read 2942094 mergeable SCCs of average size 1.365328 [WPA] 8625389 tree bodies read in total [WPA] tree SCC table: size 524287, 247652 elements, collision ratio: 0.383702 [WPA] tree SCC max chain length 2 (size 1) [WPA] Compared 2694442 SCCs, 228 collisions (0.000085) [WPA] Merged 2694419 SCCs [WPA] Merged 3731982 tree bodies [WPA] Merged 633335 types [WPA] 122077 types prevailed (155548 associated trees) ... [WPA] Compression: 110593119 input bytes, 287696614 uncompressed bytes (ratio: 2.601397) [WPA] Size of mmap'd section decls: 85628556 bytes [WPA] Size of mmap'd section function_body: 13842928 bytes [WPA] read 1720989 unshared trees [WPA] read 1252217 mergeable SCCs of average size 1.858507 [WPA] 4048243 tree bodies read in total [WPA] tree SCC table: size 524287, 226524 elements, collision ratio: 0.491759 [WPA] tree SCC max chain length 2 (size 1) [WPA] Compared 1025693 SCCs, 196 collisions (0.000191) [WPA] Merged 1025670 SCCs [WPA] Merged 2063373 tree bodies [WPA] Merged 633497 types [WPA] 122299 types prevailed (155827 associated trees) ... [WPA] Compression: 103428770 input bytes, 281151423 uncompressed bytes (ratio: 2.718310) [WPA] Size of mmap'd section decls: 49390917 bytes [WPA] Size of mmap'd section function_body: 13858258 bytes ... [WPA] Size of mmap'd section odr_types: 29054816 bytes So number of SCCs streamed drops to 38% and the number of unshared trees (that are bit misnamed since it is mostly integer_cst) to 37%. Things speeds up correspondingly, but I did not save time report from previous build. The enum values are still quite surprisingly large. I may take a look into ways getting it smaller incrementally, but it streams reasonably fast: Time variable usr sys wall GGC phase opt and generate : 25.20 ( 68%) 10.88 ( 72%) 36.13 ( 69%) 868060 kB ( 52%) phase stream in : 4.46 ( 12%) 0.90 ( 6%) 5.38 ( 10%) 790724 kB ( 48%) phase stream out : 6.69 ( 18%) 3.32 ( 22%) 10.03 ( 19%) 8 kB ( 0%) ipa lto gimple in : 0.79 ( 2%) 1.86 ( 12%) 2.39 ( 5%) 252612 kB ( 15%) ipa lto gimple out : 2.48 ( 7%) 0.78 ( 5%) 3.26 ( 6%) 0 kB ( 0%) ipa lto decl in : 1.71 ( 5%) 0.46 ( 3%) 2.34 ( 4%) 417883 kB ( 25%) ipa lto decl out : 3.28 ( 9%) 0.07 ( 0%) 3.27 ( 6%) 0 kB ( 0%) whopr wpa I/O : 0.40 ( 1%) 2.24 ( 15%) 2.77 ( 5%) 8 kB ( 0%) lto stream decompression : 1.38 ( 4%) 0.31 ( 2%) 1.36 ( 3%) 0 kB ( 0%) ipa ODR types : 0.18 ( 0%) 0.02 ( 0%) 0.25 ( 0%) 0 kB ( 0%) ipa inlining heuristics : 11.64 ( 31%) 1.45 ( 10%) 13.12 ( 25%) 453160 kB ( 27%) ipa pure const : 1.74 ( 5%) 0.00 ( 0%) 1.76 ( 3%) 0 kB ( 0%) ipa icf : 1.72 ( 5%) 5.33 ( 35%) 7.06 ( 13%) 16593 kB ( 1%) whopr partitioning : 2.22 ( 6%) 0.01 ( 0%) 2.23 ( 4%) 5689 kB ( 0%) TOTAL : 37.17 15.20 52.46 1660886 kB LTO-bootstrapped/regtested x86_64-linux, will comit it shortly. gcc/ChangeLog: 2020-06-03 Jan Hubicka * ipa-devirt.c: Include data-streamer.h, lto-streamer.h and streamer-hooks.h. (odr_enums): New static var. (struct odr_enum_val): New struct. (class odr_enum): New struct. (odr_enum_map): New hashtable. (odr_types_equivalent_p): Drop code testing TYPE_VALUES. (add_type_duplicate): Likewise. (free_odr_warning_data): Do not free TYPE_VALUES. (register_odr_enum): New function. (ipa_odr_summary_write): New function. (ipa_odr_read_section): New function. (ipa_odr_summary_read): New function. (class pass_ipa_odr): New pass. (make_pass_ipa_odr): New function. * ipa-utils.h (register_odr_enum): Declare. * lto-section-in.c: (lto_section_name): Add odr_types section. * lto-streamer.h (enum lto_section_type): Add odr_types section. * passes.def: Add odr_types pass. * lto-streamer-out.c (DFS::DFS_write_tree_body): Do not stream TYPE_VALUES. (hash_tree): Likewise. * tree-streamer-in.c (lto_input_ts_type_non_common_tree_pointers): Likewise. * tree-streamer-out.c (write_ts_type_non_common_tree_pointers): Likewise. * timevar.def (TV_IPA_ODR): New timervar. * tree-pass.h (make_pass_ipa_odr): Declare. * tree.c (free_lang_data_in_type): Regiser ODR types. gcc/lto/ChangeLog: 2020-06-03 Jan Hubicka * lto-common.c (compare_tree_sccs_1): Do not compare TYPE_VALUES. gcc/testsuite/ChangeLog: 2020-06-03 Jan Hubicka * g++.dg/lto/pr84805_0.C: Update. --- gcc/tree.c | 33 ++++++--------------------------- 1 file changed, 6 insertions(+), 27 deletions(-) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index 2cc9e4f..7197b47 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -5556,40 +5556,19 @@ free_lang_data_in_type (tree type, class free_lang_data_d *fld) { if (TREE_CODE (type) == ENUMERAL_TYPE) { - tree it = NULL_TREE; ENUM_IS_OPAQUE (type) = 0; ENUM_IS_SCOPED (type) = 0; /* Type values are used only for C++ ODR checking. Drop them for all type variants and non-ODR types. For ODR types the data is freed in free_odr_warning_data. */ - if (TYPE_MAIN_VARIANT (type) != type - || !type_with_linkage_p (type)) + if (!TYPE_VALUES (type)) + ; + else if (TYPE_MAIN_VARIANT (type) != type + || !type_with_linkage_p (type) + || type_in_anonymous_namespace_p (type)) TYPE_VALUES (type) = NULL; else - /* Simplify representation by recording only values rather - than const decls. */ - for (tree e = TYPE_VALUES (type); e; e = TREE_CHAIN (e)) - { - if (TREE_CODE (TREE_VALUE (e)) == CONST_DECL) - { - TREE_VALUE (e) = DECL_INITIAL (TREE_VALUE (e)); - /* We can not stream values whose TREE_TYPE is type itself - because that would create non-trivial CSS. Canonicalize - them to integer types. */ - } - /* Some frontends use ENUMERAL_TYPE to represent the constants. - This leads to nontrivial SCC components containing - INTEGER_CST which is not good for streaming. Convert them - all to corresponding integer type. */ - if (TREE_CODE (TREE_TYPE (TREE_VALUE (e))) != INTEGER_TYPE) - { - if (!it) - it = lang_hooks.types.type_for_size - (TYPE_PRECISION (TREE_TYPE (TREE_VALUE (e))), - TYPE_UNSIGNED (TREE_TYPE (TREE_VALUE (e)))); - TREE_VALUE (e) = fold_convert (it, TREE_VALUE (e)); - } - } + register_odr_enum (type); } free_lang_data_in_one_sizepos (&TYPE_MIN_VALUE (type)); free_lang_data_in_one_sizepos (&TYPE_MAX_VALUE (type)); -- cgit v1.1 From 77103685ff4b50b3c4d7ee76688bdf452acc82c7 Mon Sep 17 00:00:00 2001 From: Jason Merrill Date: Fri, 5 Jun 2020 16:36:27 -0400 Subject: tree-inline: Fix VLA handling [PR95552] The problem in this testcase comes from cloning the constructor into complete and base variants. When we clone the body the first time, walk_tree_1 calls copy_tree_body_r on the type of the artificial TYPE_DECL we made for the VLA type without calling it on the decl itself, so we overwrite the type of the TYPE_DECL without copying the decl first. This has been broken since we started inserting a TYPE_DECL for anonymous VLAs in r7-457. This patch fixes walk_tree_1 to call the function on the TYPE_DECL, as we do for other decls of a DECL_EXPR. gcc/ChangeLog: PR c++/95552 * tree.c (walk_tree_1): Call func on the TYPE_DECL of a DECL_EXPR. gcc/testsuite/ChangeLog: PR c++/95552 * g++.dg/ext/vla23.C: New test. --- gcc/tree.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'gcc/tree.c') diff --git a/gcc/tree.c b/gcc/tree.c index 7197b47..805f669 100644 --- a/gcc/tree.c +++ b/gcc/tree.c @@ -12212,6 +12212,12 @@ walk_tree_1 (tree *tp, walk_tree_fn func, void *data, Note that DECLs get walked as part of processing the BIND_EXPR. */ if (TREE_CODE (DECL_EXPR_DECL (*tp)) == TYPE_DECL) { + /* Call the function for the decl so e.g. copy_tree_body_r can + replace it with the remapped one. */ + result = (*func) (&DECL_EXPR_DECL (*tp), &walk_subtrees, data); + if (result || !walk_subtrees) + return result; + tree *type_p = &TREE_TYPE (DECL_EXPR_DECL (*tp)); if (TREE_CODE (*type_p) == ERROR_MARK) return NULL_TREE; -- cgit v1.1