summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2007-03-06 18:57:27 +0000
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>2007-03-06 18:57:27 +0000
commit5de92639376d02c091b93418f3d4a0b25b92c26f (patch)
tree6db0f16a08d3e0f5d8feea8a59bd2d27420fa52d /gcc
parent4ea69e9efb4ab33b0ce910662afedbc496d319fa (diff)
downloadgcc-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/ChangeLog17
-rw-r--r--gcc/c-common.c59
-rw-r--r--gcc/doc/extend.texi38
-rw-r--r--gcc/errors.h8
-rw-r--r--gcc/function.h4
-rw-r--r--gcc/predict.c30
-rw-r--r--gcc/predict.def4
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)