OSDN Git Service

* errors.h (warning, error, fatal, internal_error): Mark as cold.
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 6 Mar 2007 18:57:27 +0000 (18:57 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 6 Mar 2007 18:57:27 +0000 (18:57 +0000)
* 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

gcc/ChangeLog
gcc/c-common.c
gcc/doc/extend.texi
gcc/errors.h
gcc/function.h
gcc/predict.c
gcc/predict.def
include/ChangeLog
include/ansidecl.h

index 0e6de0b..125b6ff 100644 (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
index 1a35af7..db64da5 100644 (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.  */
 
index dfa4f5d..788cbfc 100644 (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
index 5fefa07..a5c7fe5 100644 (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;
index e02077f..8543194 100644 (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
 };
 
index 349ab73..f8a6a11 100644 (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)
     {
index ac6777c..cf31442 100644 (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)
index dc04f66..e055666 100644 (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.
index 16adc47..c19955a 100644 (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.  */