From 38a8aecfb882072900434499696b5c32a2274515 Mon Sep 17 00:00:00 2001 From: Rong Xu Date: Mon, 21 Jul 2014 16:47:22 -0700 Subject: [4.9] Switch gcc-4.9 to use google/gcc-4_9 branch. This source drop uses svn version r212828 of google/gcc-4.9 branch. We also cherry-picked r213062, r213063 and r213064 to fix windows build issues. All gcc-4.9 patches before July 3rd are ported to google/gcc-4.9. The following prior commits has not been merged to google branch yet. (They are included in this commit). e7af147f979e657fe2df00808e5b4319b0e088c6, baf87df3cb2683649ba7e9872362a7e721117c23, and c231900e5dcc14d8296bd9f62b45997a49d4d5e7. Change-Id: I4bea3ea470387ff751c2be4cb0d4a12059b9299b --- gcc-4.9/gcc/tree-cfg.c | 127 +++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 118 insertions(+), 9 deletions(-) (limited to 'gcc-4.9/gcc/tree-cfg.c') diff --git a/gcc-4.9/gcc/tree-cfg.c b/gcc-4.9/gcc/tree-cfg.c index 56b6c3595..d9896e76f 100644 --- a/gcc-4.9/gcc/tree-cfg.c +++ b/gcc-4.9/gcc/tree-cfg.c @@ -30,6 +30,7 @@ along with GCC; see the file COPYING3. If not see #include "tm_p.h" #include "basic-block.h" #include "flags.h" +#include "input.h" #include "function.h" #include "gimple-pretty-print.h" #include "pointer-set.h" @@ -64,6 +65,7 @@ along with GCC; see the file COPYING3. If not see #include "tree-ssa-propagate.h" #include "value-prof.h" #include "tree-inline.h" +#include "l-ipo.h" #include "target.h" #include "tree-ssa-live.h" #include "omp-low.h" @@ -958,6 +960,32 @@ same_line_p (location_t locus1, location_t locus2) && filename_cmp (from.file, to.file) == 0); } +/* Assign a unique discriminator value to instructions in block BB that + have the same LOCUS as its predecessor block. */ + +static void +assign_discriminator (location_t locus, basic_block bb) +{ + gimple_stmt_iterator gsi; + int discriminator; + + locus = map_discriminator_location (locus); + + if (locus == UNKNOWN_LOCATION) + return; + + discriminator = next_discriminator_for_locus (locus); + + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple stmt = gsi_stmt (gsi); + location_t stmt_locus = gimple_location (stmt); + if (same_line_p (locus, stmt_locus)) + gimple_set_location (stmt, + location_with_discriminator (stmt_locus, discriminator)); + } +} + /* Assign discriminators to each basic block. */ static void @@ -969,8 +997,36 @@ assign_discriminators (void) { edge e; edge_iterator ei; + gimple_stmt_iterator gsi; gimple last = last_stmt (bb); location_t locus = last ? gimple_location (last) : UNKNOWN_LOCATION; + location_t curr_locus = UNKNOWN_LOCATION; + int curr_discr = 0; + + /* Traverse the basic block, if two function calls within a basic block + are mapped to a same line, assign a new discriminator because a call + stmt could be a split point of a basic block. */ + for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi)) + { + gimple stmt = gsi_stmt (gsi); + if (curr_locus == UNKNOWN_LOCATION) + { + curr_locus = gimple_location (stmt); + } + else if (!same_line_p (curr_locus, gimple_location (stmt))) + { + curr_locus = gimple_location (stmt); + curr_discr = 0; + } + else if (curr_discr != 0) + { + gimple_set_location (stmt, location_with_discriminator ( + gimple_location (stmt), curr_discr)); + } + /* Allocate a new discriminator for CALL stmt. */ + if (gimple_code (stmt) == GIMPLE_CALL) + curr_discr = next_discriminator_for_locus (curr_locus); + } if (locus == UNKNOWN_LOCATION) continue; @@ -982,10 +1038,12 @@ assign_discriminators (void) if ((first && same_line_p (locus, gimple_location (first))) || (last && same_line_p (locus, gimple_location (last)))) { - if (e->dest->discriminator != 0 && bb->discriminator == 0) - bb->discriminator = next_discriminator_for_locus (locus); + if (((first && has_discriminator (gimple_location (first))) + || (last && has_discriminator (gimple_location (last)))) + && !has_discriminator (locus)) + assign_discriminator (locus, bb); else - e->dest->discriminator = next_discriminator_for_locus (locus); + assign_discriminator (locus, e->dest); } } } @@ -1864,6 +1922,15 @@ gimple_merge_blocks (basic_block a, basic_block b) } } + /* When merging two BBs, if their counts are different, the larger count + is selected as the new bb count. This is to handle inconsistent + profiles. */ + if (a->loop_father == b->loop_father) + { + a->count = MAX (a->count, b->count); + a->frequency = MAX (a->frequency, b->frequency); + } + /* Merge the sequences. */ last = gsi_last_bb (a); gsi_insert_seq_after (&last, bb_seq (b), GSI_NEW_STMT); @@ -3032,7 +3099,8 @@ verify_types_in_gimple_reference (tree expr, bool require_lvalue) /* Verify if the reference array element types are compatible. */ if (TREE_CODE (expr) == ARRAY_REF && !useless_type_conversion_p (TREE_TYPE (expr), - TREE_TYPE (TREE_TYPE (op)))) + TREE_TYPE (TREE_TYPE (op))) + && !L_IPO_COMP_MODE) { error ("type mismatch in array reference"); debug_generic_stmt (TREE_TYPE (expr)); @@ -3247,7 +3315,8 @@ verify_gimple_call (gimple stmt) returning java.lang.Object. For now simply allow arbitrary pointer type conversions. */ && !(POINTER_TYPE_P (TREE_TYPE (gimple_call_lhs (stmt))) - && POINTER_TYPE_P (TREE_TYPE (fntype)))) + && POINTER_TYPE_P (TREE_TYPE (fntype))) + && !L_IPO_COMP_MODE) { error ("invalid conversion in gimple call"); debug_generic_stmt (TREE_TYPE (gimple_call_lhs (stmt))); @@ -3946,6 +4015,36 @@ verify_gimple_assign_ternary (gimple stmt) return false; + case SAD_EXPR: + if (!useless_type_conversion_p (rhs1_type, rhs2_type) + || !useless_type_conversion_p (lhs_type, rhs3_type) + || 2 * GET_MODE_BITSIZE (GET_MODE_INNER + (TYPE_MODE (TREE_TYPE (rhs1_type)))) + > GET_MODE_BITSIZE (GET_MODE_INNER + (TYPE_MODE (TREE_TYPE (lhs_type))))) + { + error ("type mismatch in sad expression"); + debug_generic_expr (lhs_type); + debug_generic_expr (rhs1_type); + debug_generic_expr (rhs2_type); + debug_generic_expr (rhs3_type); + return true; + } + + if (TREE_CODE (rhs1_type) != VECTOR_TYPE + || TREE_CODE (rhs2_type) != VECTOR_TYPE + || TREE_CODE (rhs3_type) != VECTOR_TYPE) + { + error ("vector types expected in sad expression"); + debug_generic_expr (lhs_type); + debug_generic_expr (rhs1_type); + debug_generic_expr (rhs2_type); + debug_generic_expr (rhs3_type); + return true; + } + + return false; + case DOT_PROD_EXPR: case REALIGN_LOAD_EXPR: /* FIXME. */ @@ -3970,7 +4069,9 @@ verify_gimple_assign_single (gimple stmt) tree rhs1_type = TREE_TYPE (rhs1); bool res = false; - if (!useless_type_conversion_p (lhs_type, rhs1_type)) + if (!useless_type_conversion_p (lhs_type, rhs1_type) + /* Relax for LIPO. TODO add structural or name check. */ + && !L_IPO_COMP_MODE) { error ("non-trivial conversion at assignment"); debug_generic_expr (lhs_type); @@ -4214,7 +4315,8 @@ verify_gimple_return (gimple stmt) && DECL_BY_REFERENCE (SSA_NAME_VAR (op)))) op = TREE_TYPE (op); - if (!useless_type_conversion_p (restype, TREE_TYPE (op))) + if (!useless_type_conversion_p (restype, TREE_TYPE (op)) + && !L_IPO_COMP_MODE) { error ("invalid conversion in return statement"); debug_generic_stmt (restype); @@ -5070,7 +5172,13 @@ gimple_verify_flow_info (void) if (gimple_code (stmt) == GIMPLE_LABEL) continue; - err |= verify_eh_edges (stmt); + /* FIXME: there does seem to be an overassertion in eh + edge verification -- triggered by -fdyn-ipa: after eh + cleanup, there might not be an direct edge from a BB + to the parent try block's catch region, but the catch + region is still reachable. */ + if (!flag_dyn_ipa) + err |= verify_eh_edges (stmt); if (is_ctrl_stmt (stmt)) { @@ -7476,7 +7584,8 @@ need_fake_edge_p (gimple t) if (is_gimple_call (t) && fndecl && DECL_BUILT_IN (fndecl) - && (call_flags & ECF_NOTHROW) + && ((call_flags & ECF_NOTHROW) + || DECL_BUILT_IN_CLASS (fndecl) == BUILT_IN_MD) && !(call_flags & ECF_RETURNS_TWICE) /* fork() doesn't really return twice, but the effect of wrapping it in __gcov_fork() which calls __gcov_flush() -- cgit v1.2.3