errors.h (warning, [...]): Mark as cold.

* 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.

From-SVN: r122632
This commit is contained in:
Jan Hubicka 2007-03-06 19:57:27 +01:00 committed by Jan Hubicka
parent 20f326d710
commit 52bf96d2f2
9 changed files with 169 additions and 11 deletions

View file

@ -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

View file

@ -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. */

View file

@ -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

View file

@ -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;

View file

@ -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
};

View file

@ -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)
{

View file

@ -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)

View file

@ -1,3 +1,7 @@
2007-03-06 Jan Hubicka <jh@suse.cz>
* ansidecl.h (ATTRIBUTE_COLD, ATTRIBUTE_HOT): New.
2007-02-09 Joseph S. Myers <joseph@codesourcery.com>
* libiberty.h (pex_write_input): Remove prototype.

View file

@ -367,6 +367,22 @@ So instead we use the macro below and test it against specific values. */
# define ATTRIBUTE_PACKED __attribute__ ((packed))
#endif
/* Attribute `hot' and `cold' was valid as of gcc 4.3. */
#ifndef ATTRIBUTE_COLD
# if (GCC_VERSION >= 4003)
# define ATTRIBUTE_COLD __attribute__ ((__cold__))
# else
# define ATTRIBUTE_COLD
# endif /* GNUC >= 4.3 */
#endif /* ATTRIBUTE_COLD */
#ifndef ATTRIBUTE_HOT
# if (GCC_VERSION >= 4003)
# define ATTRIBUTE_HOT __attribute__ ((__hot__))
# else
# define ATTRIBUTE_HOT
# endif /* GNUC >= 4.3 */
#endif /* ATTRIBUTE_HOT */
/* We use __extension__ in some places to suppress -pedantic warnings
about GCC extensions. This feature didn't work properly before
gcc 2.8. */