New patch attached. About using mangled name, I'm afraid this will make the command line too long for C++. And also, using bfd_name makes it easier to specify the pattern for common names. E.g. many class many have Log functions, but they are all likely to be cold. Using bfd_name, we only need to specify the pattern once.
Thanks, Dehao Index: gcc/doc/invoke.texi =================================================================== --- gcc/doc/invoke.texi (revision 188050) +++ gcc/doc/invoke.texi (working copy) @@ -362,7 +362,8 @@ -fdelete-null-pointer-checks -fdse -fdevirtualize -fdse @gol -fearly-inlining -fipa-sra -fexpensive-optimizations -ffast-math @gol -ffinite-math-only -ffloat-store -fexcess-precision=@var{style} @gol --fforward-propagate -ffp-contract=@var{style} -ffunction-sections @gol +-fforward-propagate -ffp-contract=@var{style} @gol +-ffunction-attribute-list -ffunction-sections @gol -fgcse -fgcse-after-reload -fgcse-las -fgcse-lm -fgraphite-identity @gol -fgcse-sm -fif-conversion -fif-conversion2 -findirect-inlining @gol -finline-functions -finline-functions-called-once -finline-limit=@var{n} @gol @@ -8585,6 +8586,10 @@ specify this option and you may have problems with debugging if you specify both this option and @option{-g}. +@item -ffunction-attribute-list +@opindex ffunction-attribute-list +List of function name patterns that will be applied specified attribute. + @item -fbranch-target-load-optimize @opindex fbranch-target-load-optimize Perform branch target register load optimization before prologue / epilogue Index: gcc/cgraph.c =================================================================== --- gcc/cgraph.c (revision 188050) +++ gcc/cgraph.c (working copy) @@ -99,6 +99,7 @@ #include "ipa-utils.h" #include "lto-streamer.h" #include "l-ipo.h" +#include "opts.h" const char * const ld_plugin_symbol_resolution_names[]= { @@ -520,6 +521,32 @@ } } +/* Match FNDECL's name with user specified patterns. If match is found, add + attributes to FNDECL. + name matches with pattern, iff one of the following conditions satisfy: + 1. strcmp (name, pattern) == 0 + 2. pattern[len - 1] == '*' && strncmp (name, pattern, len - 1) == 0 */ +static void +cgraph_match_attribute_by_name (tree fndecl) +{ + unsigned i; + attribute_pair_p p; + const char *name = lang_hooks.decl_printable_name(fndecl, 0); + + if (!name) + return; + + FOR_EACH_VEC_ELT (attribute_pair_p, function_attribute_list, i, p) + { + char *n = p->name; + int len = strlen (n); + if ((n[len - 1] == '*' && !strncmp (name, n, len - 1)) + || !strcmp (name, n)) + decl_attributes (&fndecl, tree_cons ( + get_identifier (p->attribute), NULL, NULL), 0); + } +} + /* Return cgraph node assigned to DECL. Create new one when needed. */ struct cgraph_node * @@ -554,6 +581,7 @@ node->origin->nested = node; } cgraph_add_assembler_hash_node (node); + cgraph_match_attribute_by_name (decl); return node; } Index: gcc/opts.c =================================================================== --- gcc/opts.c (revision 188050) +++ gcc/opts.c (working copy) @@ -1647,6 +1647,10 @@ /* Deferred. */ break; + case OPT_ffunction_attribute_list_: + /* Deferred. */ + break; + case OPT_fsched_verbose_: #ifdef INSN_SCHEDULING /* Handled with Var in common.opt. */ Index: gcc/opts.h =================================================================== --- gcc/opts.h (revision 188050) +++ gcc/opts.h (working copy) @@ -272,6 +272,15 @@ struct cl_option_handler_func handlers[3]; }; +typedef struct { + char *name; + char *attribute; +} attribute_pair; +typedef attribute_pair *attribute_pair_p; +DEF_VEC_P(attribute_pair_p); +DEF_VEC_ALLOC_P(attribute_pair_p,heap); +extern VEC(attribute_pair_p,heap) *function_attribute_list; + /* Input file names. */ extern const char **in_fnames; Index: gcc/common.opt =================================================================== --- gcc/common.opt (revision 188050) +++ gcc/common.opt (working copy) @@ -1242,6 +1242,10 @@ Common Report Var(flag_function_sections) Place each function into its own section +ffunction-attribute-list= +Common Joined RejectNegative Var(common_deferred_options) Defer +-ffunction-attribute-list=attribute:name,... Add attribute to named functions + fgcda= Common Joined RejectNegative Var(gcov_da_name) Set the gcov data file name. Index: gcc/opts-global.c =================================================================== --- gcc/opts-global.c (revision 188050) +++ gcc/opts-global.c (working copy) @@ -50,6 +50,8 @@ const char **in_fnames; unsigned num_in_fnames; +VEC(attribute_pair_p,heap) *function_attribute_list; + /* Return a malloced slash-separated list of languages in MASK. */ static char * @@ -79,6 +81,54 @@ return result; } +/* Add strings like attribute_str:name1,name2... to a char_pair_p vector. */ + +static void +add_attribute_list_to_vector (VEC(attribute_pair_p,heap) **pvec, + const char *arg) +{ + char *tmp; + char *r; + char *token_start; + char *attribute; + VEC(attribute_pair_p,heap) *vec = *pvec; + + /* We never free this string. */ + tmp = xstrdup (arg); + attribute = tmp; + + for (r = tmp; *r != '\0' && *r != ':'; ++r) + ; + + if (*r != ':') + return; + + *r = '\0'; + token_start = r + 1; + r = strchr (token_start, ','); + + while (r) + { + attribute_pair_p p = (attribute_pair_p) xmalloc (sizeof (attribute_pair)); + p->name = token_start; + p->attribute = attribute; + VEC_safe_push (attribute_pair_p, heap, vec, p); + *r = '\0'; + token_start = r + 1; + r = strchr (token_start, ','); + } + if (*token_start != '\0') + { + attribute_pair_p p = + (attribute_pair_p) xmalloc (sizeof (attribute_pair)); + p->name = token_start; + p->attribute = attribute; + VEC_safe_push (attribute_pair_p, heap, vec, p); + } + + *pvec = vec; +} + /* Complain that switch DECODED does not apply to this front end (mask LANG_MASK). */ @@ -452,6 +502,10 @@ set_random_seed (opt->arg); break; + case OPT_ffunction_attribute_list_: + add_attribute_list_to_vector(&function_attribute_list, opt->arg); + break; + case OPT_fstack_limit: /* The real switch is -fno-stack-limit. */ if (!opt->value)