diff options
author | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-03-06 18:57:27 +0000 |
---|---|---|
committer | hubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4> | 2007-03-06 18:57:27 +0000 |
commit | 5de92639376d02c091b93418f3d4a0b25b92c26f (patch) | |
tree | 6db0f16a08d3e0f5d8feea8a59bd2d27420fa52d /gcc | |
parent | 4ea69e9efb4ab33b0ce910662afedbc496d319fa (diff) | |
download | gcc-5de92639376d02c091b93418f3d4a0b25b92c26f.tar.gz |
* errors.h (warning, error, fatal, internal_error): Mark as cold.
* predict.c (maybe_hot_bb): Cold functions are never hot; hot functions
are hot.
(probably_cold_bb_p): Cold functions are cold.
(probably_never_executed_bb_p): Cold functions are cold.
(tree_bb_level_predictions): Predict calls to cold functions as not
taken.
(compute_function_frequency): Check hot/cold attributes.
* function.h (function_frequency): Update comments.
* predict.def (PRED_COLD_FUNCTION): Predict cold function.
* c-common.c (handle_hot_attribute, handle_cold_attribute): New.
(c_common_att): Add cold and hot.
* doc/extend.texi (hot,cold attributes): Document.
* ansidecl.h (ATTRIBUTE_COLD, ATTRIBUTE_HOT): New.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@122632 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/c-common.c | 59 | ||||
-rw-r--r-- | gcc/doc/extend.texi | 38 | ||||
-rw-r--r-- | gcc/errors.h | 8 | ||||
-rw-r--r-- | gcc/function.h | 4 | ||||
-rw-r--r-- | gcc/predict.c | 30 | ||||
-rw-r--r-- | gcc/predict.def | 4 |
7 files changed, 149 insertions, 11 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 0e6de0b30bc..125b6fff9d7 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2007-03-06 Jan Hubicka <jh@suse.cz> + + * errors.h (warning, error, fatal, internal_error): Mark as cold. + * predict.c (maybe_hot_bb): Cold functions are never hot; hot functions + are hot. + (probably_cold_bb_p): Cold functions are cold. + (probably_never_executed_bb_p): Cold functions are cold. + (tree_bb_level_predictions): Predict calls to cold functions as not + taken. + (compute_function_frequency): Check hot/cold attributes. + * function.h (function_frequency): Update comments. + * predict.def (PRED_COLD_FUNCTION): Predict cold function. + * c-common.c (handle_hot_attribute, handle_cold_attribute): New. + (c_common_att): Add cold and hot. + + * doc/extend.texi (hot,cold attributes): Document. + 2007-03-06 Andrew Haley <aph@redhat.com> * function.c (expand_function_end): Move blockage to just after we diff --git a/gcc/c-common.c b/gcc/c-common.c index 1a35af79ffa..db64da59c03 100644 --- a/gcc/c-common.c +++ b/gcc/c-common.c @@ -511,6 +511,8 @@ static tree handle_packed_attribute (tree *, tree, tree, int, bool *); static tree handle_nocommon_attribute (tree *, tree, tree, int, bool *); static tree handle_common_attribute (tree *, tree, tree, int, bool *); static tree handle_noreturn_attribute (tree *, tree, tree, int, bool *); +static tree handle_hot_attribute (tree *, tree, tree, int, bool *); +static tree handle_cold_attribute (tree *, tree, tree, int, bool *); static tree handle_noinline_attribute (tree *, tree, tree, int, bool *); static tree handle_always_inline_attribute (tree *, tree, tree, int, bool *); @@ -648,6 +650,10 @@ const struct attribute_spec c_common_attribute_table[] = handle_warn_unused_result_attribute }, { "sentinel", 0, 1, false, true, true, handle_sentinel_attribute }, + { "cold", 0, 0, true, false, false, + handle_cold_attribute }, + { "hot", 0, 0, true, false, false, + handle_hot_attribute }, { NULL, 0, 0, false, false, false, NULL } }; @@ -4432,6 +4438,59 @@ handle_noreturn_attribute (tree *node, tree name, tree ARG_UNUSED (args), return NULL_TREE; } +/* Handle a "hot" and attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_hot_attribute (tree *node, tree name, tree ARG_UNUSED (args), + int ARG_UNUSED (flags), bool *no_add_attrs) +{ + if (TREE_CODE (*node) == FUNCTION_DECL) + { + if (lookup_attribute ("cold", DECL_ATTRIBUTES (*node)) != NULL) + { + warning (OPT_Wattributes, "%qE attribute conflicts with attribute %s", + name, "cold"); + *no_add_attrs = true; + } + /* Do nothing else, just set the attribute. We'll get at + it later with lookup_attribute. */ + } + else + { + warning (OPT_Wattributes, "%qE attribute ignored", name); + *no_add_attrs = true; + } + + return NULL_TREE; +} +/* Handle a "cold" and attribute; arguments as in + struct attribute_spec.handler. */ + +static tree +handle_cold_attribute (tree *node, tree name, tree ARG_UNUSED (args), + int ARG_UNUSED (flags), bool *no_add_attrs) +{ + if (TREE_CODE (*node) == FUNCTION_DECL) + { + if (lookup_attribute ("hot", DECL_ATTRIBUTES (*node)) != NULL) + { + warning (OPT_Wattributes, "%qE attribute conflicts with attribute %s", + name, "hot"); + *no_add_attrs = true; + } + /* Do nothing else, just set the attribute. We'll get at + it later with lookup_attribute. */ + } + else + { + warning (OPT_Wattributes, "%qE attribute ignored", name); + *no_add_attrs = true; + } + + return NULL_TREE; +} + /* Handle a "noinline" attribute; arguments as in struct attribute_spec.handler. */ diff --git a/gcc/doc/extend.texi b/gcc/doc/extend.texi index dfa4f5d4aa3..788cbfc14a0 100644 --- a/gcc/doc/extend.texi +++ b/gcc/doc/extend.texi @@ -1578,10 +1578,11 @@ attributes are currently defined for functions on all targets: @code{section}, @code{constructor}, @code{destructor}, @code{used}, @code{unused}, @code{deprecated}, @code{weak}, @code{malloc}, @code{alias}, @code{warn_unused_result}, @code{nonnull}, -@code{gnu_inline} and @code{externally_visible}. Several other -attributes are defined for functions on particular target systems. Other -attributes, including @code{section} are supported for variables declarations -(@pxref{Variable Attributes}) and for types (@pxref{Type Attributes}). +@code{gnu_inline} and @code{externally_visible}, @code{hot}, @code{cold}. +Several other attributes are defined for functions on particular target +systems. Other attributes, including @code{section} are supported for +variables declarations (@pxref{Variable Attributes}) and for types (@pxref{Type +Attributes}). You may also specify attributes with @samp{__} preceding and following each keyword. This allows you to use them in header files without @@ -2242,6 +2243,35 @@ two consecutive calls (such as @code{feof} in a multithreading environment). The attribute @code{pure} is not implemented in GCC versions earlier than 2.96. +@item hot +@cindex @code{hot} function attribute +The @code{hot} attribute is used to inform the compiler that a function is a +hot spot of the compiled program. The function is optimized more aggressively +and on many target it is placed into special subsection of the text section so +all hot functions appears close together improving locality. + +When profile feedback is available, via @option{-fprofile-use}, hot functions +are automatically detected and this attribute is ignored. + +The @code{hot} attribute is not implemented in GCC versions earlier than 4.3. + +@item cold +@cindex @code{cold} function attribute +The @code{cold} attribute is used to inform the compiler that a function is +unlikely executed. The function is optimized for size rather than speed and on +many targets it is placed into special subsection of the text section so all +cold functions appears close together improving code locality of non-cold parts +of program. The paths leading to call of cold functions within code are marked +as unlikely by the branch prediction mechanizm. It is thus useful to mark +functions used to handle unlikely conditions, such as @code{perror}, as cold to +improve optimization of hot functions that do call marked functions in rare +occasions. + +When profile feedback is available, via @option{-fprofile-use}, hot functions +are automatically detected and this attribute is ignored. + +The @code{hot} attribute is not implemented in GCC versions earlier than 4.3. + @item regparm (@var{number}) @cindex @code{regparm} attribute @cindex functions that are passed arguments in registers on the 386 diff --git a/gcc/errors.h b/gcc/errors.h index 5fefa071644..a5c7fe508e9 100644 --- a/gcc/errors.h +++ b/gcc/errors.h @@ -34,10 +34,10 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA version of warning(). For those, you'd pass an OPT_W* value from options.h, but in generator programs it has no effect, so it's OK to just pass zero for calls from generator-only files. */ -extern void warning (int, const char *, ...) ATTRIBUTE_PRINTF_2; -extern void error (const char *, ...) ATTRIBUTE_PRINTF_1; -extern void fatal (const char *, ...) ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF_1; -extern void internal_error (const char *, ...) ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF_1; +extern void warning (int, const char *, ...) ATTRIBUTE_PRINTF_2 ATTRIBUTE_COLD; +extern void error (const char *, ...) ATTRIBUTE_PRINTF_1 ATTRIBUTE_COLD; +extern void fatal (const char *, ...) ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF_1 ATTRIBUTE_COLD; +extern void internal_error (const char *, ...) ATTRIBUTE_NORETURN ATTRIBUTE_PRINTF_1 ATTRIBUTE_COLD; extern const char *trim_filename (const char *); extern int have_error; diff --git a/gcc/function.h b/gcc/function.h index e02077f6c63..85431944e68 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -168,12 +168,12 @@ DEF_VEC_ALLOC_P(temp_slot_p,gc); enum function_frequency { /* This function most likely won't be executed at all. - (set only when profile feedback is available). */ + (set only when profile feedback is available or via function attribute). */ FUNCTION_FREQUENCY_UNLIKELY_EXECUTED, /* The default value. */ FUNCTION_FREQUENCY_NORMAL, /* Optimize this function hard - (set only when profile feedback is available). */ + (set only when profile feedback is available or via function attribute). */ FUNCTION_FREQUENCY_HOT }; diff --git a/gcc/predict.c b/gcc/predict.c index 349ab739140..f8a6a1175f2 100644 --- a/gcc/predict.c +++ b/gcc/predict.c @@ -117,6 +117,13 @@ maybe_hot_bb_p (basic_block bb) && (bb->count < profile_info->sum_max / PARAM_VALUE (HOT_BB_COUNT_FRACTION))) return false; + if (!profile_info || !flag_branch_probabilities) + { + if (cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED) + return false; + if (cfun->function_frequency == FUNCTION_FREQUENCY_HOT) + return true; + } if (bb->frequency < BB_FREQ_MAX / PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION)) return false; return true; @@ -131,6 +138,9 @@ probably_cold_bb_p (basic_block bb) && (bb->count < profile_info->sum_max / PARAM_VALUE (HOT_BB_COUNT_FRACTION))) return true; + if ((!profile_info || !flag_branch_probabilities) + && cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED) + return true; if (bb->frequency < BB_FREQ_MAX / PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION)) return true; return false; @@ -142,6 +152,9 @@ probably_never_executed_bb_p (basic_block bb) { if (profile_info && flag_branch_probabilities) return ((bb->count + profile_info->runs / 2) / profile_info->runs) == 0; + if ((!profile_info || !flag_branch_probabilities) + && cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED) + return true; return false; } @@ -1234,6 +1247,7 @@ tree_bb_level_predictions (void) for (bsi = bsi_start (bb); !bsi_end_p (bsi); bsi_next (&bsi)) { tree stmt = bsi_stmt (bsi); + tree decl; switch (TREE_CODE (stmt)) { case GIMPLE_MODIFY_STMT: @@ -1248,6 +1262,12 @@ call_expr:; if (call_expr_flags (stmt) & ECF_NORETURN) predict_paths_leading_to (bb, heads, PRED_NORETURN, NOT_TAKEN); + decl = get_callee_fndecl (stmt); + if (decl + && lookup_attribute ("cold", + DECL_ATTRIBUTES (decl))) + predict_paths_leading_to (bb, heads, PRED_COLD_FUNCTION, + NOT_TAKEN); break; default: break; @@ -1785,7 +1805,15 @@ compute_function_frequency (void) basic_block bb; if (!profile_info || !flag_branch_probabilities) - return; + { + if (lookup_attribute ("cold", DECL_ATTRIBUTES (current_function_decl)) + != NULL) + cfun->function_frequency = FUNCTION_FREQUENCY_UNLIKELY_EXECUTED; + else if (lookup_attribute ("hot", DECL_ATTRIBUTES (current_function_decl)) + != NULL) + cfun->function_frequency = FUNCTION_FREQUENCY_HOT; + return; + } cfun->function_frequency = FUNCTION_FREQUENCY_UNLIKELY_EXECUTED; FOR_EACH_BB (bb) { diff --git a/gcc/predict.def b/gcc/predict.def index ac6777cc16b..cf31442c175 100644 --- a/gcc/predict.def +++ b/gcc/predict.def @@ -73,6 +73,10 @@ DEF_PREDICTOR (PRED_CONTINUE, "continue", HITRATE (56), 0) DEF_PREDICTOR (PRED_NORETURN, "noreturn call", HITRATE (99), PRED_FLAG_FIRST_MATCH) +/* Branch to basic block containing call marked by cold function attribute. */ +DEF_PREDICTOR (PRED_COLD_FUNCTION, "cold function call", HITRATE (99), + PRED_FLAG_FIRST_MATCH) + /* Loopback edge is taken. */ DEF_PREDICTOR (PRED_LOOP_BRANCH, "loop branch", HITRATE (86), PRED_FLAG_FIRST_MATCH) |