2009-07-17 Olatunji Ruwase * builtins.c (build_va_arg_indirect_ref): Remove mf_mark, flag_mudflap. * toplev.c (compile_file): Rename mudflap_finish_file to mudflap_finish_unit. * c-cppbuiltin.c (c_cpp_builtins): Remove flag_mudflap. * tree-nomudflap.c (mudflap_enqueue_decl): Remove. (mudflap_enqueue_constant): Remove. (mf_marked_p): Remove. (mf_mark): Remove. (mf_mudflap_finish_unit): Rename from mudflap_finish_file. * c-pragma.c (handle_pragma_redefine_extname): Remove flag_mudflap. * tree-mudflap.c: Remove deferred_static_decls, marked_trees, mf_mark, mf_marked_p. (mf_make_builtin): Replace UNKNOWN_LOCATION with BUILTINS_LOCATION. (mf_make_mf_cache_struct_type): Likewise. (mudflap_init): Enable pragma redefines for current target. (mudflap_enqueue_decl): Make static. (mudflap_enqueue_constant): Make static, change return type. (mf_ssa_eligible_p): New function. (mf_xform_derefs_1): Use mf_ssa_eligbile_p. (mudflap_finish_unit): Rename from mudflap_finish_file. Use varpool and constant_pool_htab. * tree-mudflap.h: Remove mf_mark, mf_marked_p, mudflap_enqueue_decl, mudflap_enqueue_constant. Rename mudflap_finish_file to mudflap_finish_unit. * varasm.c (make_decl_rtl): Remove mudflap_enqueue_decl. (build_constant_desc): Remove mf_mark, mf_marked_p, flag_mudflap. (categorize_decl_for_section): Remove flag_mudflap. * tree-inline.c (copy_tree_r): Remove mf_mark, mf_marked_p, flag_mudflap. Index: gcc/builtins.c =================================================================== --- gcc/builtins.c (revision 149693) +++ gcc/builtins.c (working copy) @@ -4958,12 +4958,7 @@ std_gimplify_va_arg_expr (tree valist, t tree build_va_arg_indirect_ref (tree addr) { - addr = build_fold_indirect_ref (addr); - - if (flag_mudflap) /* Don't instrument va_arg INDIRECT_REF. */ - mf_mark (addr); - - return addr; + return build_fold_indirect_ref (addr); } /* Return a dummy expression of type TYPE in order to keep going after an Index: gcc/toplev.c =================================================================== --- gcc/toplev.c (revision 149693) +++ gcc/toplev.c (working copy) @@ -1044,7 +1044,7 @@ compile_file (void) /* Likewise for mudflap static object registrations. */ if (flag_mudflap) - mudflap_finish_file (); + mudflap_finish_unit (); /* Likewise for emulated thread-local storage. */ if (!targetm.have_tls) Index: gcc/c-cppbuiltin.c =================================================================== --- gcc/c-cppbuiltin.c (revision 149693) +++ gcc/c-cppbuiltin.c (working copy) @@ -782,7 +782,7 @@ c_cpp_builtins (cpp_reader *pfile) cpp_define (pfile, "__NEXT_RUNTIME__"); /* Show the availability of some target pragmas. */ - if (flag_mudflap || targetm.handle_pragma_redefine_extname) + if (targetm.handle_pragma_redefine_extname) cpp_define (pfile, "__PRAGMA_REDEFINE_EXTNAME"); if (targetm.handle_pragma_extern_prefix) Index: gcc/tree-nomudflap.c =================================================================== --- gcc/tree-nomudflap.c (revision 149693) +++ gcc/tree-nomudflap.c (working copy) @@ -50,37 +50,11 @@ nogo (void) } void -mudflap_enqueue_decl (tree obj ATTRIBUTE_UNUSED) +mudflap_finish_unit (void) { nogo (); } -void -mudflap_enqueue_constant (tree obj ATTRIBUTE_UNUSED) -{ - nogo (); -} - -void -mudflap_finish_file (void) -{ - nogo (); -} - -int -mf_marked_p (tree t ATTRIBUTE_UNUSED) -{ - nogo (); - return 0; -} - -tree -mf_mark (tree t ATTRIBUTE_UNUSED) -{ - nogo (); - return NULL; -} - /* The pass structures must exist, but need not do anything. */ static bool Index: gcc/c-pragma.c =================================================================== --- gcc/c-pragma.c (revision 149693) +++ gcc/c-pragma.c (working copy) @@ -561,7 +561,7 @@ handle_pragma_redefine_extname (cpp_read if (t != CPP_EOF) warning (OPT_Wpragmas, "junk at end of %<#pragma redefine_extname%>"); - if (!flag_mudflap && !targetm.handle_pragma_redefine_extname) + if (!targetm.handle_pragma_redefine_extname) { if (warn_unknown_pragmas > in_system_header) warning (OPT_Wunknown_pragmas, Index: gcc/tree-mudflap.c =================================================================== --- gcc/tree-mudflap.c (revision 149693) +++ gcc/tree-mudflap.c (working copy) @@ -47,6 +47,8 @@ along with GCC; see the file COPYING3. #include "cgraph.h" #include "toplev.h" #include "gimple.h" +#include "c-common.h" +#include "target.h" /* Internal function decls */ @@ -72,6 +74,8 @@ static tree mx_xfn_xform_decls (gimple_s static gimple_seq mx_register_decls (tree, gimple_seq, location_t); static unsigned int execute_mudflap_function_decls (void); +static void mudflap_enqueue_decl (tree); +static int mudflap_enqueue_constant (void **, void *); /* ------------------------------------------------------------------------ */ /* Some generally helpful functions for mudflap instrumentation. */ @@ -81,7 +85,7 @@ static tree mf_build_string (const char *string) { size_t len = strlen (string); - tree result = mf_mark (build_string (len + 1, string)); + tree result = build_string (len + 1, string); TREE_TYPE (result) = build_array_type (char_type_node, build_index_type (build_int_cst (NULL_TREE, len))); @@ -89,9 +93,7 @@ mf_build_string (const char *string) TREE_READONLY (result) = 1; TREE_STATIC (result) = 1; - result = build1 (ADDR_EXPR, build_pointer_type (char_type_node), result); - - return mf_mark (result); + return build1 (ADDR_EXPR, build_pointer_type (char_type_node), result); } /* Create a properly typed STRING_CST node that describes the given @@ -295,8 +297,7 @@ static GTY (()) tree mf_set_options_fnde static inline tree mf_make_builtin (enum tree_code category, const char *name, tree type) { - tree decl = mf_mark (build_decl (UNKNOWN_LOCATION, - category, get_identifier (name), type)); + tree decl = build_decl (BUILTINS_LOCATION, category, get_identifier (name), type); TREE_PUBLIC (decl) = 1; DECL_EXTERNAL (decl) = 1; lang_hooks.decls.pushdecl (decl); @@ -316,9 +317,9 @@ mf_make_mf_cache_struct_type (tree field /* There is, abominably, no language-independent way to construct a RECORD_TYPE. So we have to call the basic type construction primitives by hand. */ - tree fieldlo = build_decl (UNKNOWN_LOCATION, + tree fieldlo = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("low"), field_type); - tree fieldhi = build_decl (UNKNOWN_LOCATION, + tree fieldhi = build_decl (BUILTINS_LOCATION, FIELD_DECL, get_identifier ("high"), field_type); tree struct_type = make_node (RECORD_TYPE); @@ -367,6 +368,9 @@ mudflap_init (void) return; done = true; + /* Enable pragma redefines. */ + targetm.handle_pragma_redefine_extname = true; + mf_uintptr_type = lang_hooks.types.type_for_mode (ptr_mode, /*unsignedp=*/true); mf_const_string_type @@ -393,11 +397,6 @@ mudflap_init (void) unsigned_char_type_node); mf_cache_mask_decl = mf_make_builtin (VAR_DECL, "__mf_lc_mask", mf_uintptr_type); - /* Don't process these in mudflap_enqueue_decl, should they come by - there for some reason. */ - mf_mark (mf_cache_array_decl); - mf_mark (mf_cache_shift_decl); - mf_mark (mf_cache_mask_decl); mf_check_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_check", mf_check_register_fntype); mf_register_fndecl = mf_make_builtin (FUNCTION_DECL, "__mf_register", @@ -435,10 +434,9 @@ execute_mudflap_function_ops (void) { struct gimplify_ctx gctx; - /* Don't instrument functions such as the synthetic constructor - built during mudflap_finish_file. */ - if (mf_marked_p (current_function_decl) || - DECL_ARTIFICIAL (current_function_decl)) + /* Don't instrument synthetic functions such as the + constructor built during mudflap_finish_unit. */ + if (DECL_ARTIFICIAL (current_function_decl)) return 0; push_gimplify_context (&gctx); @@ -488,12 +486,12 @@ mf_decl_cache_locals (void) /* Build the cache vars. */ mf_cache_shift_decl_l - = mf_mark (make_rename_temp (TREE_TYPE (mf_cache_shift_decl), - "__mf_lookup_shift_l")); + = make_rename_temp (TREE_TYPE (mf_cache_shift_decl), + "__mf_lookup_shift_l"); mf_cache_mask_decl_l - = mf_mark (make_rename_temp (TREE_TYPE (mf_cache_mask_decl), - "__mf_lookup_mask_l")); + = make_rename_temp (TREE_TYPE (mf_cache_mask_decl), + "__mf_lookup_mask_l"); /* Build initialization nodes for the cache vars. We just load the globals into the cache variables. */ @@ -748,6 +746,30 @@ mf_decl_eligible_p (tree decl) && !DECL_HAS_VALUE_EXPR_P (decl)); } +/* An SSA expression is eligible for instrumentation if + composed of at least one non-artificial subexpression/var. +*/ + +static bool +mf_ssa_eligible_p (tree t) +{ + int i, num_ops; + tree *ops; + + ops = gimple_ops (SSA_NAME_DEF_STMT (t)); + num_ops = gimple_num_ops (SSA_NAME_DEF_STMT (t)); + + for (i = 0; i < num_ops; i++) { + if (ops[i] == NULL_TREE) { + continue; + } + if ((TREE_CODE (ops[i]) == SSA_NAME) && !DECL_ARTIFICIAL (SSA_NAME_VAR (ops[i]))) { + return true; + } + else if ((TREE_CODE (ops[i]) == VAR_DECL) && !DECL_ARTIFICIAL (ops[i])) { + return true; + } + } + return false; +} static void mf_xform_derefs_1 (gimple_stmt_iterator *iter, tree *tp, @@ -759,10 +781,6 @@ mf_xform_derefs_1 (gimple_stmt_iterator if (dirflag == integer_zero_node && flag_mudflap_ignore_reads) return; - /* Don't instrument marked nodes. */ - if (mf_marked_p (*tp)) - return; - t = *tp; type = TREE_TYPE (t); @@ -881,6 +899,9 @@ mf_xform_derefs_1 (gimple_stmt_iterator case INDIRECT_REF: addr = TREE_OPERAND (t, 0); + if ((TREE_CODE (addr) == SSA_NAME) && !mf_ssa_eligible_p (addr)) { + return; + } base = addr; limit = fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, fold_build2 (POINTER_PLUS_EXPR, ptr_type_node, base, @@ -1014,10 +1035,9 @@ execute_mudflap_function_decls (void) { struct gimplify_ctx gctx; - /* Don't instrument functions such as the synthetic constructor - built during mudflap_finish_file. */ - if (mf_marked_p (current_function_decl) || - DECL_ARTIFICIAL (current_function_decl)) + /* Don't instrument synthetic functions such as the + constructor built during mudflap_finish_unit. */ + if (DECL_ARTIFICIAL (current_function_decl)) return 0; push_gimplify_context (&gctx); @@ -1051,8 +1071,6 @@ mx_register_decls (tree decl, gimple_seq while (decl != NULL_TREE) { if (mf_decl_eligible_p (decl) - /* Not already processed. */ - && ! mf_marked_p (decl) /* Automatic variable. */ && ! DECL_EXTERNAL (decl) && ! TREE_STATIC (decl)) @@ -1068,9 +1086,9 @@ mx_register_decls (tree decl, gimple_seq unregister_fncall_param = - mf_mark (build1 (ADDR_EXPR, + build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (decl)), - decl)); + decl); /* __mf_unregister (&VARIABLE, sizeof (VARIABLE), __MF_TYPE_STACK) */ unregister_fncall = gimple_build_call (mf_unregister_fndecl, 3, unregister_fncall_param, @@ -1080,9 +1098,9 @@ mx_register_decls (tree decl, gimple_seq variable_name = mf_varname_tree (decl); register_fncall_param = - mf_mark (build1 (ADDR_EXPR, + build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (decl)), - decl)); + decl); /* __mf_register (&VARIABLE, sizeof (VARIABLE), __MF_TYPE_STACK, "name") */ register_fncall = gimple_build_call (mf_register_fndecl, 4, @@ -1112,7 +1130,6 @@ mx_register_decls (tree decl, gimple_seq /* Accumulate the FINALLY piece. */ gimple_seq_add_stmt (&finally_stmts, unregister_fncall); } - mf_mark (decl); } decl = TREE_CHAIN (decl); @@ -1192,52 +1209,6 @@ mf_xform_decls (gimple_seq fnbody, tree pointer_set_destroy (pset); } - -/* ------------------------------------------------------------------------ */ -/* Externally visible mudflap functions. */ - - -/* Mark and return the given tree node to prevent further mudflap - transforms. */ -static GTY ((param_is (union tree_node))) htab_t marked_trees = NULL; - -tree -mf_mark (tree t) -{ - void **slot; - - if (marked_trees == NULL) - marked_trees = htab_create_ggc (31, htab_hash_pointer, htab_eq_pointer, - NULL); - - slot = htab_find_slot (marked_trees, t, INSERT); - *slot = t; - return t; -} - -int -mf_marked_p (tree t) -{ - void *entry; - - if (marked_trees == NULL) - return 0; - - entry = htab_find (marked_trees, t); - return (entry != NULL); -} - -/* Remember given node as a static of some kind: global data, - function-scope static, or an anonymous constant. Its assembler - label is given. */ - -/* A list of globals whose incomplete declarations we encountered. - Instead of emitting the __mf_register call for them here, it's - delayed until program finish time. If they're still incomplete by - then, warnings are emitted. */ - -static GTY (()) VEC(tree,gc) *deferred_static_decls; - /* A list of statements for calling __mf_register() at startup time. */ static GTY (()) tree enqueued_call_stmt_chain; @@ -1259,12 +1230,9 @@ mudflap_register_call (tree obj, tree ob append_to_statement_list (call_stmt, &enqueued_call_stmt_chain); } -void +static void mudflap_enqueue_decl (tree obj) { - if (mf_marked_p (obj)) - return; - /* We don't need to process variable decls that are internally generated extern. If we did, we'd end up with warnings for them - during mudflap_finish_file (). That would confuse the user, + during mudflap_finish_unit (). That would confuse the user, since the text would refer to variables that don't show up in the user's source code. */ if (DECL_P (obj) && DECL_EXTERNAL (obj) && DECL_ARTIFICIAL (obj)) return; - VEC_safe_push (tree, gc, deferred_static_decls, obj); + /* Omit registration for static unaddressed objects. NB: + Perform registration for non-static objects regardless of + TREE_USED or TREE_ADDRESSABLE, because they may be used + from other compilation units. */ + if (! TREE_PUBLIC (obj) && ! TREE_ADDRESSABLE (obj)) + return; + + if (! COMPLETE_TYPE_P (TREE_TYPE (obj))) + { + warning (OPT_Wmudflap, + "mudflap cannot track unknown size extern %qE", + DECL_NAME (obj)); + return; + } + + mudflap_register_call (obj, + size_in_bytes (TREE_TYPE (obj)), + mf_varname_tree (obj)); } -void -mudflap_enqueue_constant (tree obj) +static int +mudflap_enqueue_constant (void **slot, void *data ATTRIBUTE_UNUSED) { + tree obj; tree object_size, varname; + struct constant_descriptor_tree *desc; - if (mf_marked_p (obj)) - return; + desc = ((struct constant_descriptor_tree *)(*slot)); + obj = desc->value; if (TREE_CODE (obj) == STRING_CST) object_size = build_int_cst (NULL_TREE, TREE_STRING_LENGTH (obj)); @@ -1296,6 +1283,7 @@ mudflap_enqueue_constant (tree obj) varname = mf_build_string ("constant"); mudflap_register_call (obj, object_size, varname); + return 1; } /* Emit any file-wide instrumentation. */ void -mudflap_finish_file (void) +mudflap_finish_unit (void) { tree ctor_statements = NULL_TREE; + struct varpool_node *node; /* No need to continue when there were errors. */ if (errorcount != 0 || sorrycount != 0) @@ -1323,39 +1314,15 @@ mudflap_finish_file (void) append_to_statement_list (call_stmt, &ctor_statements); } - /* Process all enqueued object decls. */ - if (deferred_static_decls) - { - size_t i; - tree obj; - for (i = 0; VEC_iterate (tree, deferred_static_decls, i, obj); i++) - { - gcc_assert (DECL_P (obj)); - - if (mf_marked_p (obj)) - continue; - - /* Omit registration for static unaddressed objects. NB: - Perform registration for non-static objects regardless of - TREE_USED or TREE_ADDRESSABLE, because they may be used - from other compilation units. */ - if (! TREE_PUBLIC (obj) && ! TREE_ADDRESSABLE (obj)) - continue; - - if (! COMPLETE_TYPE_P (TREE_TYPE (obj))) - { - warning (OPT_Wmudflap, - "mudflap cannot track unknown size extern %qE", - DECL_NAME (obj)); - continue; - } - - mudflap_register_call (obj, - size_in_bytes (TREE_TYPE (obj)), - mf_varname_tree (obj)); + /* Instrument constants. */ + htab_traverse_noresize (constant_pool_htab (), + mudflap_enqueue_constant, NULL); + + /* Instrument global variables. */ + for (node = varpool_nodes; node; node = node->next) { + if (node->needed) { + mudflap_enqueue_decl (node->decl); } - - VEC_truncate (tree, deferred_static_decls, 0); } /* Append all the enqueued registration calls. */ Index: gcc/tree-mudflap.h =================================================================== --- gcc/tree-mudflap.h (revision 149693) +++ gcc/tree-mudflap.h (working copy) @@ -23,12 +23,6 @@ along with GCC; see the file COPYING3. /* Instrumentation. */ extern void mudflap_init (void); -extern void mudflap_enqueue_decl (tree); -extern void mudflap_enqueue_constant (tree); -extern void mudflap_finish_file (void); - -/* Tree node marking. */ -extern int mf_marked_p (tree); -extern tree mf_mark (tree); +extern void mudflap_finish_unit (void); #endif /* TREE_MUDFLAP_H */ Index: gcc/varasm.c =================================================================== --- gcc/varasm.c (revision 149693) +++ gcc/varasm.c (working copy) @@ -1341,10 +1341,6 @@ make_decl_rtl (tree decl) && SYMBOL_REF_HAS_BLOCK_INFO_P (XEXP (x, 0))) change_symbol_block (XEXP (x, 0), get_block_for_decl (decl)); - /* Make this function static known to the mudflap runtime. */ - if (flag_mudflap && TREE_CODE (decl) == VAR_DECL) - mudflap_enqueue_decl (decl); - return; } @@ -1455,9 +1451,6 @@ make_decl_rtl (tree decl) will have to know how to strip this information. */ targetm.encode_section_info (decl, DECL_RTL (decl), true); - /* Make this function static known to the mudflap runtime. */ - if (flag_mudflap && TREE_CODE (decl) == VAR_DECL) - mudflap_enqueue_decl (decl); } /* Output a string of literal assembler code @@ -3174,10 +3167,6 @@ build_constant_desc (tree exp) desc = GGC_NEW (struct constant_descriptor_tree); desc->value = copy_constant (exp); - /* Propagate marked-ness to copied constant. */ - if (flag_mudflap && mf_marked_p (exp)) - mf_mark (desc->value); - /* Create a string containing the label name, in LABEL. */ labelno = const_labelno++; ASM_GENERATE_INTERNAL_LABEL (label, "LC", labelno); @@ -3339,8 +3328,6 @@ output_constant_def_contents (rtx symbol ASM_OUTPUT_ALIGN (asm_out_file, floor_log2 (align / BITS_PER_UNIT)); assemble_constant_contents (exp, XSTR (symbol, 0), align); } - if (flag_mudflap) - mudflap_enqueue_constant (exp); } /* Look up EXP in the table of constant descriptors. Return the rtl @@ -6053,7 +6040,7 @@ categorize_decl_for_section (const_tree return SECCAT_TEXT; else if (TREE_CODE (decl) == STRING_CST) { - if (flag_mudflap) /* or !flag_merge_constants */ + if (!flag_merge_constants) return SECCAT_RODATA; else return SECCAT_RODATA_MERGE_STR; Index: gcc/tree-inline.c =================================================================== --- gcc/tree-inline.c (revision 149693) +++ gcc/tree-inline.c (working copy) @@ -3759,10 +3759,6 @@ copy_tree_r (tree *tp, int *walk_subtree /* Copy the node. */ new_tree = copy_node (*tp); - /* Propagate mudflap marked-ness. */ - if (flag_mudflap && mf_marked_p (*tp)) - mf_mark (new_tree); - *tp = new_tree; /* Now, restore the chain, if appropriate. That will cause @@ -3785,10 +3781,6 @@ copy_tree_r (tree *tp, int *walk_subtree new_tree = copy_node (*tp); - /* Propagate mudflap marked-ness. */ - if (flag_mudflap && mf_marked_p (*tp)) - mf_mark (new_tree); - CONSTRUCTOR_ELTS (new_tree) = VEC_copy (constructor_elt, gc, CONSTRUCTOR_ELTS (*tp)); *tp = new_tree;