Hi, This patch adds 4 flags to enable user to type in a list of name patterns. Compiler will match the function name with the given patterns, and add "hot", "cold", "likely_hot", "likely_cold" attributes to function declaration. The static branch prediction checks if a basic block contains call to a annotated function, and set the branch probability accordingly.
Bootstrapped and passed gcc testsuites. Ok for google branches? Thanks, Dehao gcc/ChangeLog.google-4_6 2012-06-01 Dehao Chen <de...@google.com> * gcc/cgraph.c (cgraph_match_hotness_by_name): New function. (cgraph_add_hotness_attribute): New function. (cgraph_node): Add hotness attribute to function decl. * gcc/opts.c (common_handle_option): Handle new options. * gcc/predict.c (tree_bb_level_predictions): New prediction. * gcc/predict.def (PRED_LIKELY_COLD_FUNCTION): New prediction. * gcc/common.opt (flag_function_hot_list): New option. (flag_function_cold_list): New option. (flag_function_likely_hot_list): New option. (flag_function_likely_cold_list): New option. Index: gcc/doc/invoke.texi =================================================================== --- gcc/doc/invoke.texi (revision 188050) +++ gcc/doc/invoke.texi (working copy) @@ -362,7 +362,9 @@ -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-cold-list -ffunction-hot-list -ffunction-likely-cold-list @gol +-ffunction-likely-hot-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 +8587,22 @@ specify this option and you may have problems with debugging if you specify both this option and @option{-g}. +@item -ffunction-cold-list +@opindex ffunction-cold-list +List of function name patterns that will be applied "cold" attribute. + +@item -ffunction-hot-list +@opindex ffunction-hot-list +List of function name patterns that will be applied "hot" attribute. + +@item -ffunction-likely-cold-list +@opindex ffunction-likely-cold-list +List of function name patterns that will be applied "likely_cold" attribute. + +@item -ffunction-likely-hot-list +@opindex ffunction-likely-hot-list +List of function name patterns that will be applied "likely_hot" 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) @@ -520,6 +520,70 @@ } } +typedef char *char_pointer; +DEF_VEC_P(char_pointer); +DEF_VEC_ALLOC_P(char_pointer,heap); + +/* Match FNDECL's name with PATTERNS. If matched, add HOTNESS attribute + 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 bool +cgraph_match_hotness_by_name (tree fndecl, + VEC(char_pointer, heap) *patterns, + const char *hotness) +{ + unsigned i; + char_pointer n; + const char *name = lang_hooks.decl_printable_name(fndecl, 0); + + if (!name) + return false; + + FOR_EACH_VEC_ELT (char_pointer, patterns, i, n) + { + int len = strlen (n); + if ((n[len - 1] == '*' && !strncmp (name, n, len - 1)) + || !strcmp (name, n)) + { + decl_attributes (&fndecl, tree_cons ( + get_identifier (hotness), NULL, NULL), 0); + return true; + } + } + return false; +} + +/* Add hotness attributes to FNDECL. */ +static void +cgraph_add_hotness_attribute (tree fndecl) +{ + if (lookup_attribute ("cold", DECL_ATTRIBUTES (fndecl)) + || lookup_attribute ("hot", DECL_ATTRIBUTES (fndecl)) + || lookup_attribute ("likely_cold", DECL_ATTRIBUTES (fndecl)) + || lookup_attribute ("likely_hot", DECL_ATTRIBUTES (fndecl))) + return; + + if (cgraph_match_hotness_by_name (fndecl, + (VEC(char_pointer, heap) *) flag_function_cold_list, "cold")) + return; + + if (cgraph_match_hotness_by_name (fndecl, + (VEC(char_pointer, heap) *) flag_function_hot_list, "hot")) + return; + + if (cgraph_match_hotness_by_name (fndecl, + (VEC(char_pointer, heap) *) flag_function_likely_cold_list, + "likely_cold")) + return; + + if (cgraph_match_hotness_by_name (fndecl, + (VEC(char_pointer, heap) *) flag_function_likely_hot_list, + "likely_hot")) + return; +} + /* Return cgraph node assigned to DECL. Create new one when needed. */ struct cgraph_node * @@ -554,6 +618,7 @@ node->origin->nested = node; } cgraph_add_assembler_hash_node (node); + cgraph_add_hotness_attribute (decl); return node; } Index: gcc/opts.c =================================================================== --- gcc/opts.c (revision 188050) +++ gcc/opts.c (working copy) @@ -1539,6 +1539,26 @@ (&opts->x_flag_instrument_functions_exclude_files, arg); break; + case OPT_ffunction_hot_list_: + add_comma_separated_to_vector + (&opts->x_flag_function_hot_list, arg); + break; + + case OPT_ffunction_cold_list_: + add_comma_separated_to_vector + (&opts->x_flag_function_cold_list, arg); + break; + + case OPT_ffunction_likely_hot_list_: + add_comma_separated_to_vector + (&opts->x_flag_function_likely_hot_list, arg); + break; + + case OPT_ffunction_likely_cold_list_: + add_comma_separated_to_vector + (&opts->x_flag_function_likely_cold_list, arg); + break; + case OPT_fmessage_length_: pp_set_line_maximum_length (dc->printer, value); break; Index: gcc/predict.c =================================================================== --- gcc/predict.c (revision 188050) +++ gcc/predict.c (working copy) @@ -2070,11 +2070,22 @@ predict_paths_leading_to (bb, PRED_NORETURN, NOT_TAKEN); decl = gimple_call_fndecl (stmt); - if (decl - && lookup_attribute ("cold", - DECL_ATTRIBUTES (decl))) - predict_paths_leading_to (bb, PRED_COLD_FUNCTION, - NOT_TAKEN); + if (decl) + { + tree attr = DECL_ATTRIBUTES (decl); + if (lookup_attribute ("cold", attr)) + predict_paths_leading_to (bb, PRED_COLD_FUNCTION, + NOT_TAKEN); + else if (lookup_attribute ("hot", attr)) + predict_paths_leading_to (bb, PRED_COLD_FUNCTION, + TAKEN); + else if (lookup_attribute ("likely_cold", attr)) + predict_paths_leading_to (bb, PRED_LIKELY_COLD_FUNCTION, + NOT_TAKEN); + else if (lookup_attribute ("likely_hot", attr)) + predict_paths_leading_to (bb, PRED_LIKELY_COLD_FUNCTION, + TAKEN); + } } else if (gimple_code (stmt) == GIMPLE_PREDICT) { Index: gcc/ChangeLog.google-4_6 =================================================================== --- gcc/ChangeLog.google-4_6 (revision 188050) +++ gcc/ChangeLog.google-4_6 (working copy) @@ -1,3 +1,16 @@ +2012-06-01 Dehao Chen <de...@google.com> + + * gcc/cgraph.c (cgraph_match_hotness_by_name): New function. + (cgraph_add_hotness_attribute): New function. + (cgraph_node): Add hotness attribute to function decl. + * gcc/opts.c (common_handle_option): Handle new options. + * gcc/predict.c (tree_bb_level_predictions): New prediction. + * gcc/predict.def (PRED_LIKELY_COLD_FUNCTION): New prediction. + * gcc/common.opt (flag_function_hot_list): New option. + (flag_function_cold_list): New option. + (flag_function_likely_hot_list): New option. + (flag_function_likely_cold_list): New option. + 2012-05-30 Cary Coutant <ccout...@google.com> * gcc/dwarf2out.c (index_location_lists): Don't index location Index: gcc/predict.def =================================================================== --- gcc/predict.def (revision 188050) +++ gcc/predict.def (working copy) @@ -76,6 +76,10 @@ DEF_PREDICTOR (PRED_COLD_FUNCTION, "cold function call", PROB_VERY_LIKELY, PRED_FLAG_FIRST_MATCH) +/* Branch to basic block containing call marked by likely_cold function attribute. */ +DEF_PREDICTOR (PRED_LIKELY_COLD_FUNCTION, "likely cold function call", + HITRATE (75), PRED_FLAG_FIRST_MATCH) + /* Loopback edge is taken. */ DEF_PREDICTOR (PRED_LOOP_BRANCH, "loop branch", HITRATE (86), PRED_FLAG_FIRST_MATCH) Index: gcc/common.opt =================================================================== --- gcc/common.opt (revision 188050) +++ gcc/common.opt (working copy) @@ -92,6 +92,20 @@ Variable void *flag_instrument_functions_exclude_files +; These four are VEC(char_p,heap) * that indicate function hotness. + +Variable +void *flag_function_hot_list + +Variable +void *flag_function_cold_list + +Variable +void *flag_function_likely_hot_list + +Variable +void *flag_function_likely_cold_list + ; Generic structs (e.g. templates not explicitly specialized) ; may not have a compilation unit associated with them, and so ; may need to be treated differently from ordinary structs. @@ -1242,6 +1256,22 @@ Common Report Var(flag_function_sections) Place each function into its own section +ffunction-hot-list= +Common RejectNegative Joined +-ffunction-hot-list=name,... Predict listed functions as hot + +ffunction-cold-list= +Common RejectNegative Joined +-ffunction-cold-list=name,... Predict listed functions as cold + +ffunction-likely-hot-list= +Common RejectNegative Joined +-ffunction-likely-hot-list=name,... Predict listed functions as likely_hot + +ffunction-likely-cold-list= +Common RejectNegative Joined +-ffunction-likely-cold-list=name,... Predict listed functions as likely_cold + fgcda= Common Joined RejectNegative Var(gcov_da_name) Set the gcov data file name.