Mercurial > hg > CbC > CbC_gcc
diff gcc/tree-sra.c @ 131:84e7813d76e9
gcc-8.2
author | mir3636 |
---|---|
date | Thu, 25 Oct 2018 07:37:49 +0900 |
parents | 04ced10e8804 |
children | 1830386684a0 |
line wrap: on
line diff
--- a/gcc/tree-sra.c Fri Oct 27 22:46:09 2017 +0900 +++ b/gcc/tree-sra.c Thu Oct 25 07:37:49 2018 +0900 @@ -1,7 +1,7 @@ /* Scalar Replacement of Aggregates (SRA) converts some structure references into scalar references, exposing them to the scalar optimizers. - Copyright (C) 2008-2017 Free Software Foundation, Inc. + Copyright (C) 2008-2018 Free Software Foundation, Inc. Contributed by Martin Jambor <mjambor@suse.cz> This file is part of GCC. @@ -97,6 +97,7 @@ #include "tree-dfa.h" #include "tree-ssa.h" #include "symbol-summary.h" +#include "ipa-param-manipulation.h" #include "ipa-prop.h" #include "params.h" #include "dbgcnt.h" @@ -865,11 +866,20 @@ create_access (tree expr, gimple *stmt, bool write) { struct access *access; + poly_int64 poffset, psize, pmax_size; HOST_WIDE_INT offset, size, max_size; tree base = expr; bool reverse, ptr, unscalarizable_region = false; - base = get_ref_base_and_extent (expr, &offset, &size, &max_size, &reverse); + base = get_ref_base_and_extent (expr, &poffset, &psize, &pmax_size, + &reverse); + if (!poffset.is_constant (&offset) + || !psize.is_constant (&size) + || !pmax_size.is_constant (&max_size)) + { + disqualify_candidate (base, "Encountered a polynomial-sized access."); + return NULL; + } if (sra_mode == SRA_MODE_EARLY_IPA && TREE_CODE (base) == MEM_REF) @@ -1140,6 +1150,33 @@ return false; } +/* Return true if REF contains a VIEW_CONVERT_EXPR or a MEM_REF that performs + type conversion or a COMPONENT_REF with a bit-field field declaration. */ + +static bool +contains_vce_or_bfcref_p (const_tree ref) +{ + while (handled_component_p (ref)) + { + if (TREE_CODE (ref) == VIEW_CONVERT_EXPR + || (TREE_CODE (ref) == COMPONENT_REF + && DECL_BIT_FIELD (TREE_OPERAND (ref, 1)))) + return true; + ref = TREE_OPERAND (ref, 0); + } + + if (TREE_CODE (ref) != MEM_REF + || TREE_CODE (TREE_OPERAND (ref, 0)) != ADDR_EXPR) + return false; + + tree mem = TREE_OPERAND (TREE_OPERAND (ref, 0), 0); + if (TYPE_MAIN_VARIANT (TREE_TYPE (ref)) + != TYPE_MAIN_VARIANT (TREE_TYPE (mem))) + return true; + + return false; +} + /* Search the given tree for a declaration by skipping handled components and exclude it from the candidates. */ @@ -1338,7 +1375,14 @@ racc->grp_assignment_read = 1; if (should_scalarize_away_bitmap && !gimple_has_volatile_ops (stmt) && !is_gimple_reg_type (racc->type)) - bitmap_set_bit (should_scalarize_away_bitmap, DECL_UID (racc->base)); + { + if (contains_vce_or_bfcref_p (rhs)) + bitmap_set_bit (cannot_scalarize_away_bitmap, + DECL_UID (racc->base)); + else + bitmap_set_bit (should_scalarize_away_bitmap, + DECL_UID (racc->base)); + } if (storage_order_barrier_p (lhs)) racc->grp_unscalarizable_region = 1; } @@ -1426,7 +1470,7 @@ tree t; unsigned i; - if (final_bbs && stmt_can_throw_external (stmt)) + if (final_bbs && stmt_can_throw_external (cfun, stmt)) bitmap_set_bit (final_bbs, bb->index); switch (gimple_code (stmt)) { @@ -1454,8 +1498,7 @@ if (dest) { - if (DECL_BUILT_IN_CLASS (dest) == BUILT_IN_NORMAL - && DECL_FUNCTION_CODE (dest) == BUILT_IN_APPLY_ARGS) + if (fndecl_built_in_p (dest, BUILT_IN_APPLY_ARGS)) encountered_apply_args = true; if (recursive_call_p (current_function_decl, dest)) { @@ -1662,14 +1705,14 @@ of handling bitfields. */ tree -build_ref_for_offset (location_t loc, tree base, HOST_WIDE_INT offset, +build_ref_for_offset (location_t loc, tree base, poly_int64 offset, bool reverse, tree exp_type, gimple_stmt_iterator *gsi, bool insert_after) { tree prev_base = base; tree off; tree mem_ref; - HOST_WIDE_INT base_offset; + poly_int64 base_offset; unsigned HOST_WIDE_INT misalign; unsigned int align; @@ -1680,7 +1723,7 @@ TYPE_QUALS (exp_type) | ENCODE_QUAL_ADDR_SPACE (as)); - gcc_checking_assert (offset % BITS_PER_UNIT == 0); + poly_int64 byte_offset = exact_div (offset, BITS_PER_UNIT); get_object_alignment_1 (base, &align, &misalign); base = get_addr_base_and_unit_offset (base, &base_offset); @@ -1702,27 +1745,26 @@ else gsi_insert_before (gsi, stmt, GSI_SAME_STMT); - off = build_int_cst (reference_alias_ptr_type (prev_base), - offset / BITS_PER_UNIT); + off = build_int_cst (reference_alias_ptr_type (prev_base), byte_offset); base = tmp; } else if (TREE_CODE (base) == MEM_REF) { off = build_int_cst (TREE_TYPE (TREE_OPERAND (base, 1)), - base_offset + offset / BITS_PER_UNIT); + base_offset + byte_offset); off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1), off); base = unshare_expr (TREE_OPERAND (base, 0)); } else { off = build_int_cst (reference_alias_ptr_type (prev_base), - base_offset + offset / BITS_PER_UNIT); + base_offset + byte_offset); base = build_fold_addr_expr (unshare_expr (base)); } - misalign = (misalign + offset) & (align - 1); - if (misalign != 0) - align = least_bit_hwi (misalign); + unsigned int align_bound = known_alignment (misalign + offset); + if (align_bound != 0) + align = MIN (align, align_bound); if (align != TYPE_ALIGN (exp_type)) exp_type = build_aligned_type (exp_type, align); @@ -1777,7 +1819,7 @@ build_debug_ref_for_model (location_t loc, tree base, HOST_WIDE_INT offset, struct access *model) { - HOST_WIDE_INT base_offset; + poly_int64 base_offset; tree off; if (TREE_CODE (model->expr) == COMPONENT_REF @@ -2477,7 +2519,7 @@ gcc_checking_assert (!root->grp_scalar_read && !root->grp_assignment_read); sth_created = true; - if (MAY_HAVE_DEBUG_STMTS) + if (MAY_HAVE_DEBUG_BIND_STMTS) { root->grp_to_be_debug_replaced = 1; root->replacement_decl = create_access_replacement (root); @@ -3048,7 +3090,8 @@ static struct access * get_access_for_expr (tree expr) { - HOST_WIDE_INT offset, size, max_size; + poly_int64 poffset, psize, pmax_size; + HOST_WIDE_INT offset, max_size; tree base; bool reverse; @@ -3058,8 +3101,12 @@ if (TREE_CODE (expr) == VIEW_CONVERT_EXPR) expr = TREE_OPERAND (expr, 0); - base = get_ref_base_and_extent (expr, &offset, &size, &max_size, &reverse); - if (max_size == -1 || !DECL_P (base)) + base = get_ref_base_and_extent (expr, &poffset, &psize, &pmax_size, + &reverse); + if (!known_size_p (pmax_size) + || !pmax_size.is_constant (&max_size) + || !poffset.is_constant (&offset) + || !DECL_P (base)) return NULL; if (!bitmap_bit_p (candidate_bitmap, DECL_UID (base))) @@ -3415,24 +3462,6 @@ return get_or_create_ssa_default_def (cfun, racc->replacement_decl); } -/* Return true if REF has an VIEW_CONVERT_EXPR or a COMPONENT_REF with a - bit-field field declaration somewhere in it. */ - -static inline bool -contains_vce_or_bfcref_p (const_tree ref) -{ - while (handled_component_p (ref)) - { - if (TREE_CODE (ref) == VIEW_CONVERT_EXPR - || (TREE_CODE (ref) == COMPONENT_REF - && DECL_BIT_FIELD (TREE_OPERAND (ref, 1)))) - return true; - ref = TREE_OPERAND (ref, 0); - } - - return false; -} - /* Examine both sides of the assignment statement pointed to by STMT, replace them with a scalare replacement if there is one and generate copying of replacements if scalarized aggregates have been used in the assignment. GSI @@ -4452,7 +4481,7 @@ splice_param_accesses (tree parm, bool *ro_grp) { int i, j, access_count, group_count; - int agg_size, total_size = 0; + int total_size = 0; struct access *access, *res, **prev_acc_ptr = &res; vec<access_p> *access_vec; @@ -4519,13 +4548,6 @@ i = j; } - if (POINTER_TYPE_P (TREE_TYPE (parm))) - agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm)))); - else - agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (parm))); - if (total_size >= agg_size) - return NULL; - gcc_assert (group_count > 0); return res; } @@ -4536,7 +4558,7 @@ static int decide_one_param_reduction (struct access *repr) { - int total_size, cur_parm_size, agg_size, new_param_count, parm_size_limit; + HOST_WIDE_INT total_size, cur_parm_size; bool by_ref; tree parm; @@ -4545,15 +4567,9 @@ gcc_assert (cur_parm_size > 0); if (POINTER_TYPE_P (TREE_TYPE (parm))) - { - by_ref = true; - agg_size = tree_to_uhwi (TYPE_SIZE (TREE_TYPE (TREE_TYPE (parm)))); - } + by_ref = true; else - { - by_ref = false; - agg_size = cur_parm_size; - } + by_ref = false; if (dump_file) { @@ -4566,7 +4582,7 @@ } total_size = 0; - new_param_count = 0; + int new_param_count = 0; for (; repr; repr = repr->next_grp) { @@ -4594,22 +4610,28 @@ gcc_assert (new_param_count > 0); - if (optimize_function_for_size_p (cfun)) - parm_size_limit = cur_parm_size; - else - parm_size_limit = (PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR) - * cur_parm_size); - - if (total_size < agg_size - && total_size <= parm_size_limit) + if (!by_ref) { - if (dump_file) - fprintf (dump_file, " ....will be split into %i components\n", - new_param_count); - return new_param_count; + if (total_size >= cur_parm_size) + return 0; } else - return 0; + { + int parm_num_limit; + if (optimize_function_for_size_p (cfun)) + parm_num_limit = 1; + else + parm_num_limit = PARAM_VALUE (PARAM_IPA_SRA_PTR_GROWTH_FACTOR); + + if (new_param_count > parm_num_limit + || total_size > (parm_num_limit * cur_parm_size)) + return 0; + } + + if (dump_file) + fprintf (dump_file, " ....will be split into %i components\n", + new_param_count); + return new_param_count; } /* The order of the following enums is important, we need to do extra work for @@ -5256,7 +5278,7 @@ } for (cs = node->callers; cs; cs = cs->next_caller) - if (bitmap_set_bit (recomputed_callers, cs->caller->uid) + if (bitmap_set_bit (recomputed_callers, cs->caller->get_uid ()) && gimple_in_ssa_p (DECL_STRUCT_FUNCTION (cs->caller->decl))) compute_fn_summary (cs->caller, true); BITMAP_FREE (recomputed_callers); @@ -5375,12 +5397,12 @@ continue; tree offset; - HOST_WIDE_INT bitsize, bitpos; + poly_int64 bitsize, bitpos; machine_mode mode; int unsignedp, reversep, volatilep = 0; get_inner_reference (arg, &bitsize, &bitpos, &offset, &mode, &unsignedp, &reversep, &volatilep); - if (bitpos % BITS_PER_UNIT) + if (!multiple_p (bitpos, BITS_PER_UNIT)) { iscc->bad_arg_alignment = true; return true; @@ -5435,6 +5457,7 @@ } if ((DECL_ONE_ONLY (node->decl) || DECL_EXTERNAL (node->decl)) + && ipa_fn_summaries->get (node) && ipa_fn_summaries->get (node)->size >= MAX_INLINE_INSNS_AUTO) { if (dump_file)