This merge simplified some code in the streamer as we no longer need to worry about memory tags. It also exposed a couple of bugs in EH handling (we were assuming that shared EH regions always occurred when the original region was before the aliases in the EH table) and in statement streaming (we were not clearing out pointer fields in the tuple).
There is a new bug exposed by alias-improvements where alias_may_ref_p() returns false on two field references inside the same union. This exposes a problem in get_alias_set() that for gimple is returning two different values for union references. This causes a few execution failures (9) in check-gcc. I will be fixing those separately. 2009-04-08 Diego Novillo <dnovi...@google.com> Mainline merge @145637. * configure.ac (acx_pkgversion): Update revision merge string. * configure: Regenerate. 2009-04-08 Diego Novillo <dnovi...@google.com> * gimple.h (gimple_reset_mem_ops): Remove. Update all users. * ipa-cp.c (ipcp_ltrans_cloning_candidate_p): Remove. Update all users. (ipcp_cloning_candidate_p): Do not check for LTRANS. (ipcp_update_callgraph): Revert handling of cloned caller nodes. (graph_gate_cp): Add FIXME lto note. * lto-function-in.c (input_expr_operand): Do not call build7. Remove handling of NAME_MEMORY_TAG and SYMBOL_MEMORY_TAG. (input_eh_region): Return NULL for LTO_eh_table_shared_region. (fixup_eh_region_pointers): Setup region sharing using AKA bitmap sets. (input_gimple_stmt): Clear tuple fields with pointer values. Mark the statement modified. (input_function): Call update_ssa to update SSA on .MEM. (input_tree_operand): Remove handling of NAME_MEMORY_TAG and SYMBOL_MEMORY_TAG. * lto-function-out.c (output_eh_region): Do not output the region number for LTO_eh_table_shared_region. (output_expr_operand): Remove handling of NAME_MEMORY_TAG and SYMBOL_MEMORY_TAG. (output_bb): Do not write PHI nodes for .MEM. (output_tree_with_context): Remove handling of NAME_MEMORY_TAG and SYMBOL_MEMORY_TAG. * lto-tree-flags.def: Likewise. * tree-into-ssa.c: Call bitmap_obstack_initialize. --- gimple.h 2009/04/07 01:10:39 1.1 +++ gimple.h 2009/04/07 15:22:08 @@ -1520,33 +1520,6 @@ gimple_references_memory_p (gimple stmt) } - -/* Reset all the memory operand vectors in STMT. Note that this makes - no attempt at freeing the existing vectors, it simply clears them. - It is meant to be used when reading GIMPLE from a file. */ - -static inline void -gimple_reset_mem_ops (gimple stmt) -{ - if (!gimple_has_ops (stmt)) - return; - - gimple_set_modified (stmt, true); - - stmt->gsops.opbase.addresses_taken = NULL; - stmt->gsops.opbase.def_ops = NULL; - stmt->gsops.opbase.use_ops = NULL; - - if (gimple_has_mem_ops (stmt)) - { - stmt->gsmem.membase.vdef_ops = NULL; - stmt->gsmem.membase.vuse_ops = NULL; - stmt->gsmem.membase.stores = NULL; - stmt->gsmem.membase.loads = NULL; - } -} - - /* Return the subcode for OMP statement S. */ static inline unsigned --- ipa-cp.c 2009/04/07 01:10:39 1.1 +++ ipa-cp.c 2009/04/07 01:42:53 @@ -379,33 +379,6 @@ ipcp_print_all_lattices (FILE * f) } } -/* Return true if this NODE may be cloned in ltrans. - - FIXME lto: returns false if any caller of NODE is a clone, described - in http://gcc.gnu.org/ml/gcc/2009-02/msg00297.html; this extra check - should be deleted if the underlying issue is resolved. */ - -static bool -ipcp_ltrans_cloning_candidate_p (struct cgraph_node *node) -{ - struct cgraph_edge *e; - - /* Check callers of this node to see if any is a clone. */ - for (e = node->callers; e; e = e->next_caller) - { - if (cgraph_is_clone_node (e->caller)) - break; - } - if (e) - { - if (dump_file) - fprintf (dump_file, "Not considering %s for cloning; has a clone caller.\n", - cgraph_node_name (node)); - return false; - } - return true; -} - /* Return true if this NODE is viable candidate for cloning. */ static bool ipcp_cloning_candidate_p (struct cgraph_node *node) @@ -422,11 +395,6 @@ ipcp_cloning_candidate_p (struct cgraph_ if (!node->needed || !node->analyzed) return false; - /* If reading ltrans, we want an extra check here. - FIXME lto: see ipcp_ltrans_cloning_candidate_p above for details. */ - if (flag_ltrans && !ipcp_ltrans_cloning_candidate_p (node)) - return false; - if (cgraph_function_body_availability (node) <= AVAIL_OVERWRITABLE) { if (dump_file) @@ -970,7 +938,6 @@ ipcp_update_callgraph (void) struct ipa_node_params *info = IPA_NODE_REF (orig_node); int i, count = ipa_get_param_count (info); struct cgraph_edge *cs, *next; - gimple *call_stmt_map; for (i = 0; i < count; i++) { @@ -989,27 +956,13 @@ ipcp_update_callgraph (void) if (lat->type == IPA_CONST_VALUE) bitmap_set_bit (args_to_skip, i); } - - /* Use a map to store all the CALL_STMT replacements we make - in the call edges coming from all the callers to NODE. - This is needed for cases where callers have been cloned, - resulting in two or more call graph nodes for the same - function calling NODE. After doing the first replacement, - we will not be able to find the original statement in the - caller body. */ - for (i = 0, cs = node->callers; cs; cs = cs->next_caller) - gimple_set_uid (cs->call_stmt, i++); - - call_stmt_map = (gimple *) xcalloc (i, sizeof (gimple)); - - /* Traverse all callers for NODE replacing the call to - NODE->DECL with its specialized version. */ for (cs = node->callers; cs; cs = next) { next = cs->next_caller; if (ipcp_node_is_clone (cs->caller) || !ipcp_need_redirect_p (cs)) { gimple new_stmt; + gimple_stmt_iterator gsi; current_function_decl = cs->caller->decl; push_cfun (DECL_STRUCT_FUNCTION (cs->caller->decl)); @@ -1021,6 +974,8 @@ ipcp_update_callgraph (void) gsi = gsi_for_stmt (cs->call_stmt); gsi_replace (&gsi, new_stmt, true); cgraph_set_call_stmt (cs, new_stmt); + pop_cfun (); + current_function_decl = NULL; } else { @@ -1028,8 +983,6 @@ ipcp_update_callgraph (void) gimple_call_set_fndecl (cs->call_stmt, orig_node->decl); } } - - free (call_stmt_map); } } @@ -1241,9 +1194,7 @@ ipcp_insert_stage (void) { struct ipa_node_params *info; /* Propagation of the constant is forbidden in certain conditions. */ - if (!node->analyzed - || !ipcp_node_modifiable_p (node) - || node->global.inlined_to) + if (!node->analyzed || !ipcp_node_modifiable_p (node)) continue; info = IPA_NODE_REF (node); if (ipa_is_called_with_var_arguments (info)) @@ -1325,7 +1276,6 @@ ipcp_insert_stage (void) for (cs = node->callers; cs != NULL; cs = cs->next_caller) VEC_quick_push (cgraph_edge_p, redirect_callers, cs); - gcc_assert (!node->global.inlined_to); /* Redirecting all the callers of the node to the new versioned node. */ node1 = @@ -1417,6 +1367,12 @@ ipcp_generate_summary (void) static bool cgraph_gate_cp (void) { + /* FIXME lto. IPA-CP does not tolerate running when the inlining decisions + have not been applied. This happens when WPA modifies the callgraph. + Since those decisions are not applied until after all the IPA passes + have been run in LTRANS, this means that IPA passes may see partially + modified callgraphs. The solution to this is to apply WPA decisions + early during LTRANS. */ return flag_ipa_cp && !flag_ltrans; } --- lto-function-in.c 2009/04/07 01:10:39 1.1 +++ lto-function-in.c 2009/04/07 20:40:08 @@ -1060,11 +1060,6 @@ input_expr_operand (struct lto_input_blo result = build5 (code, type, ops[0], ops[1], ops[2], ops[3], ops[4]); break; - /* No 'case 6'. */ - case 7: - result = build7 (code, type, ops[0], ops[1], ops[2], ops[3], - ops[4], ops[5], ops[6]); - break; default: gcc_unreachable (); } @@ -1078,7 +1073,6 @@ input_expr_operand (struct lto_input_blo case BLOCK: case CATCH_EXPR: case EH_FILTER_EXPR: - case NAME_MEMORY_TAG: case OMP_CRITICAL: case OMP_FOR: case OMP_MASTER: @@ -1086,7 +1080,6 @@ input_expr_operand (struct lto_input_blo case OMP_PARALLEL: case OMP_SECTIONS: case OMP_SINGLE: - case SYMBOL_MEMORY_TAG: case TARGET_MEM_REF: case TRY_CATCH_EXPR: case TRY_FINALLY_EXPR: @@ -1385,22 +1378,11 @@ input_eh_region (struct lto_input_block if (tag == 0) return NULL; - /* If TAG indicates that this is a shared region, then return the - original region read earlier. */ + /* If TAG indicates that this is a shared region, then return a NULL + region. The caller is responsible for sharing EH regions in the + EH table using the AKA bitmaps. */ if (tag == LTO_eh_table_shared_region) - { - eh_region orig; - int orig_rn; - - orig_rn = lto_input_sleb128 (ib); - orig = VEC_index (eh_region, fn->eh->region_array, orig_rn); - - /* The region that we are trying to read must exist in the AKA - set of the original EH region. */ - gcc_assert (orig->aka && bitmap_bit_p (orig->aka, region_number)); - - return orig; - } + return NULL; r = GGC_CNEW (struct eh_region); r->region_number = lto_input_sleb128 (ib); @@ -1543,6 +1525,17 @@ fixup_eh_region_pointers (struct functio fixup_region (r->u.eh_catch.next_catch); fixup_region (r->u.eh_catch.prev_catch); } + + /* If R has an AKA set, all the table slot for the regions + mentioned in AKA must point to R. */ + if (r->aka) + { + bitmap_iterator bi; + unsigned i; + + EXECUTE_IF_SET_IN_BITMAP (r->aka, 0, i, bi) + VEC_replace (eh_region, array, i, r); + } } #undef fixup_region @@ -1854,7 +1847,9 @@ input_gimple_stmt (struct lto_input_bloc /* Read the number of operands in the statement. */ num_ops = lto_input_uleb128 (ib); - /* Read the tuple header. FIXME lto. This seems unnecessarily slow. */ + /* Read the tuple header. FIXME lto. This seems unnecessarily slow + and it is reading pointers in the tuple that need to be re-built + locally (e.g, basic block, lexical block, operand vectors, etc). */ nbytes = gimple_size (code); stmt = gimple_alloc (code, num_ops); buf = (char *) stmt; @@ -1882,11 +1877,6 @@ input_gimple_stmt (struct lto_input_bloc } } - /* Reset any memory operand vectors in STMT. FIXME lto, we - shouldn't need to do this. The writer should simply not emit - these fields. */ - gimple_reset_mem_ops (stmt); - /* Update the properties of symbols, SSA names and labels associated with STMT. */ if (code == GIMPLE_ASSIGN || code == GIMPLE_CALL) @@ -1910,6 +1900,31 @@ input_gimple_stmt (struct lto_input_bloc } LTO_DEBUG_UNDENT (); + + /* Clear out invalid pointer values read above. FIXME lto, this + should disappear after we fix the unnecessary fields that are + written for every tuple. */ + gimple_set_bb (stmt, NULL); + gimple_set_block (stmt, NULL); + if (gimple_has_ops (stmt)) + { + gimple_set_def_ops (stmt, NULL); + gimple_set_use_ops (stmt, NULL); + /* FIXME lto. We cannot use gimple_set_addresses_taken here + because the previous value for this bitmap is an invalid + pointer. */ + stmt->gsops.opbase.addresses_taken = NULL; + } + + if (gimple_has_mem_ops (stmt)) + { + gimple_set_vdef (stmt, NULL); + gimple_set_vuse (stmt, NULL); + } + + /* Mark the statement modified so its operand vectors can be filled in. */ + gimple_set_modified (stmt, true); + return stmt; } @@ -2073,7 +2088,8 @@ input_function (tree fn_decl, struct dat #ifdef LOCAL_TRACE fprintf (stderr, "\n"); #endif - + + update_ssa (TODO_update_ssa_only_virtuals); free (stmts); LTO_DEBUG_UNDENT(); @@ -3635,7 +3651,6 @@ input_tree_operand (struct lto_input_blo case BLOCK: case CATCH_EXPR: case EH_FILTER_EXPR: - case NAME_MEMORY_TAG: case OMP_CRITICAL: case OMP_FOR: case OMP_MASTER: @@ -3643,7 +3658,6 @@ input_tree_operand (struct lto_input_blo case OMP_PARALLEL: case OMP_SECTIONS: case OMP_SINGLE: - case SYMBOL_MEMORY_TAG: case TARGET_MEM_REF: case TRY_CATCH_EXPR: case TRY_FINALLY_EXPR: --- lto-function-out.c 2009/04/07 01:10:39 1.1 +++ lto-function-out.c 2009/04/07 20:39:40 @@ -791,7 +791,6 @@ output_eh_region (struct output_block *o == VEC_index (eh_region, fn->eh->region_array, curr_rn)); output_record_start (ob, NULL, NULL, LTO_eh_table_shared_region); - output_sleb128 (ob, r->region_number); return; } @@ -1297,7 +1296,6 @@ output_expr_operand (struct output_block case BLOCK: case CATCH_EXPR: case EH_FILTER_EXPR: - case NAME_MEMORY_TAG: case OMP_CRITICAL: case OMP_FOR: case OMP_MASTER: @@ -1305,7 +1303,6 @@ output_expr_operand (struct output_block case OMP_PARALLEL: case OMP_SECTIONS: case OMP_SINGLE: - case SYMBOL_MEMORY_TAG: case TARGET_MEM_REF: case TRY_CATCH_EXPR: case TRY_FINALLY_EXPR: @@ -1754,8 +1751,16 @@ output_bb (struct output_block *ob, basi for (bsi = gsi_start_phis (bb); !gsi_end_p (bsi); gsi_next (&bsi)) { - LTO_DEBUG_INDENT_TOKEN ("phi"); - output_phi (ob, gsi_stmt (bsi)); + gimple phi = gsi_stmt (bsi); + + /* Only emit PHIs for gimple registers. PHI nodes for .MEM + will be filled in on reading when the SSA form is + updated. */ + if (is_gimple_reg (gimple_phi_result (phi))) + { + LTO_DEBUG_INDENT_TOKEN ("phi"); + output_phi (ob, phi); + } } LTO_DEBUG_INDENT_TOKEN ("phi"); @@ -3483,7 +3488,6 @@ output_tree_with_context (struct output_ case BLOCK: case CATCH_EXPR: case EH_FILTER_EXPR: - case NAME_MEMORY_TAG: case OMP_CRITICAL: case OMP_FOR: case OMP_MASTER: @@ -3491,7 +3495,6 @@ output_tree_with_context (struct output_ case OMP_PARALLEL: case OMP_SECTIONS: case OMP_SINGLE: - case SYMBOL_MEMORY_TAG: case TARGET_MEM_REF: case TRY_CATCH_EXPR: case TRY_FINALLY_EXPR: --- lto-tree-flags.def 2009/04/07 01:10:39 1.1 +++ lto-tree-flags.def 2009/04/07 01:48:27 @@ -456,9 +456,6 @@ START_EXPR_CASE (MAX_EXPR) END_EXPR_CASE (MAX_EXPR) - START_EXPR_CASE (MEMORY_PARTITION_TAG) - END_EXPR_CASE (MEMORY_PARTITION_TAG) - START_EXPR_CASE (METHOD_TYPE) END_EXPR_CASE (METHOD_TYPE) @@ -478,9 +475,6 @@ START_EXPR_CASE (MULT_EXPR) END_EXPR_CASE (MULT_EXPR) - START_EXPR_CASE (NAME_MEMORY_TAG) - END_EXPR_CASE (NAME_MEMORY_TAG) - START_EXPR_CASE (NAMESPACE_DECL) ADD_EXPR_FLAG (public_flag) ADD_DECL_FLAG (nonlocal_flag) @@ -695,9 +689,6 @@ START_EXPR_CASE (SWITCH_EXPR) END_EXPR_CASE (SWITCH_EXPR) - START_EXPR_CASE (SYMBOL_MEMORY_TAG) - END_EXPR_CASE (SYMBOL_MEMORY_TAG) - START_EXPR_CASE (TARGET_EXPR) ADD_EXPR_FLAG (static_flag) END_EXPR_CASE (TARGET_EXPR) --- tree-into-ssa.c 2009/04/07 01:10:39 1.1 +++ tree-into-ssa.c 2009/04/07 17:22:26 @@ -2634,6 +2634,7 @@ init_update_ssa (struct function *fn) sbitmap_zero (new_ssa_names); repl_tbl = htab_create (20, repl_map_hash, repl_map_eq, repl_map_free); + bitmap_obstack_initialize (NULL); regs_to_rename = BITMAP_ALLOC (NULL); mem_syms_to_rename = BITMAP_ALLOC (NULL); names_to_release = NULL;