This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[pretty-ipa] Make function frequencies part of cgraph node


Hi,
this patch makes function frequencies to be part of cgraph nodes.  This is a must for
WHOPR to be able to use them and also makes ipa-profile cleaner.
I plan to bring this change in with the merge of ipa-profile to avoid conflicts.

The patch adds lookups of cgraph node into some of predict.c predicates. I did
not benchmark any performance regression due to this, but it would make more
sense to have current node pointer same way as we have cfun and current
function decl.  Something to handle later too.

Bootstrapped/regtested x86_64-linux, will commit it to pretty-ipa later today.

	* cgraph.c (cgraph_create_node): Set node frequency to normal.
	(cgraph_clone_node): Copy function frequency.
	* cgraph.h (node_frequency): New enum
	(struct cgraph_node): Add.
	* final.c (rest_of_clean_state): Update.
	* lto-cgraph.c (lto_output_node): Output node frequency.
	(input_overwrite_node): Input node frequency.
	* tre-ssa-loop-ivopts (computation_cost): Update.
	* lto-streamer-out.c (output_function): Do not output function frequency.
	* predict.c (maybe_hot_frequency_p, cgraph_maybe_hot_edge_p,
	probably_never_executed_bb_p, optimize_function_for_size_p,
	compute_function_frequency, choose_function_section): Update.
	* lto-streamer-in.c (input_function): Do not input function frequency.
	* function.c (allocate_struct_function): Do not initialize function frequency.
	* function.h (function_frequency): Remove.
	(struct function): Remove function frequency.
	* ipa-profile.c (CGRAPH_NODE_FREQUENCY): Remove.
	(try_update): Update.
	* tree-inline.c (initialize_cfun): Do not update function frequency.
	* passes.c (pass_init_dump_file): Update.
	* i386.c (ix86_compute_frame_layout): Update.
	(ix86_pad_returns): Update.
Index: cgraph.c
===================================================================
*** cgraph.c	(revision 158408)
--- cgraph.c	(working copy)
*************** cgraph_create_node (void)
*** 453,458 ****
--- 453,459 ----
      cgraph_nodes->previous = node;
    node->previous = NULL;
    node->global.estimated_growth = INT_MIN;
+   node->frequency = NODE_FREQUENCY_NORMAL;
    cgraph_nodes = node;
    cgraph_n_nodes++;
    return node;
*************** cgraph_clone_node (struct cgraph_node *n
*** 1890,1895 ****
--- 1891,1897 ----
    new_node->global = n->global;
    new_node->rtl = n->rtl;
    new_node->count = count;
+   new_node->frequency = n->frequency;
    new_node->clone = n->clone;
    new_node->clone.tree_map = 0;
    if (n->count)
Index: cgraph.h
===================================================================
*** cgraph.h	(revision 158408)
--- cgraph.h	(working copy)
*************** struct GTY(()) cgraph_clone_info
*** 175,180 ****
--- 175,195 ----
    bitmap combined_args_to_skip;
  };
  
+ enum node_frequency {
+   /* This function most likely won't be executed at all.
+      (set only when profile feedback is available or via function attribute). */
+   NODE_FREQUENCY_UNLIKELY_EXECUTED,
+   /* For functions that are known to be executed once (i.e. constructors, destructors
+      and main function.  */
+   NODE_FREQUENCY_EXECUTED_ONCE,
+   /* The default value.  */
+   NODE_FREQUENCY_NORMAL,
+   /* Optimize this function hard
+      (set only when profile feedback is available or via function attribute). */
+   NODE_FREQUENCY_HOT
+ };
+ 
+ 
  /* The cgraph data structure.
     Each function decl has assigned cgraph_node listing callees and callers.  */
  
*************** struct GTY((chain_next ("%h.next"), chai
*** 263,268 ****
--- 278,286 ----
    /* Set for alias and thunk nodes, same_body points to the node they are alias
       of and they are linked through the next/previous pointers.  */
    unsigned same_body_alias : 1;
+   /* How commonly executed the node is.  Initialized during branch
+      probabilities pass.  */
+   ENUM_BITFIELD (node_frequency) frequency : 2;
  };
  
  typedef struct cgraph_node *cgraph_node_ptr;
Index: final.c
===================================================================
*** final.c	(revision 158408)
--- final.c	(working copy)
*************** rest_of_clean_state (void)
*** 4374,4387 ****
        else
  	{
  	  const char *aname;
  
  	  aname = (IDENTIFIER_POINTER
  		   (DECL_ASSEMBLER_NAME (current_function_decl)));
  	  fprintf (final_output, "\n;; Function (%s) %s\n\n", aname,
! 	     cfun->function_frequency == FUNCTION_FREQUENCY_HOT
  	     ? " (hot)"
! 	     : cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED
  	     ? " (unlikely executed)"
  	     : "");
  
  	  flag_dump_noaddr = flag_dump_unnumbered = 1;
--- 4374,4390 ----
        else
  	{
  	  const char *aname;
+ 	  struct cgraph_node *node = cgraph_node (current_function_decl);
  
  	  aname = (IDENTIFIER_POINTER
  		   (DECL_ASSEMBLER_NAME (current_function_decl)));
  	  fprintf (final_output, "\n;; Function (%s) %s\n\n", aname,
! 	     node->frequency == NODE_FREQUENCY_HOT
  	     ? " (hot)"
! 	     : node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED
  	     ? " (unlikely executed)"
+ 	     : node->frequency == NODE_FREQUENCY_EXECUTED_ONCE
+ 	     ? " (executed once)"
  	     : "");
  
  	  flag_dump_noaddr = flag_dump_unnumbered = 1;
Index: lto-cgraph.c
===================================================================
*** lto-cgraph.c	(revision 158408)
--- lto-cgraph.c	(working copy)
*************** lto_output_node (struct lto_simple_outpu
*** 268,273 ****
--- 268,274 ----
    bp_pack_value (bp, node->process, 1);
    bp_pack_value (bp, node->alias, 1);
    bp_pack_value (bp, node->finalized_by_frontend, 1);
+   bp_pack_value (bp, node->frequency, 2);
    lto_output_bitpack (ob->main_stream, bp);
    bitpack_delete (bp);
  
*************** input_overwrite_node (struct lto_file_de
*** 535,540 ****
--- 536,542 ----
    node->process = bp_unpack_value (bp, 1);
    node->alias = bp_unpack_value (bp, 1);
    node->finalized_by_frontend = bp_unpack_value (bp, 1);
+   node->frequency = (enum node_frequency)bp_unpack_value (bp, 2);
  }
  
  
Index: tree-ssa-loop-ivopts.c
===================================================================
*** tree-ssa-loop-ivopts.c	(revision 158408)
--- tree-ssa-loop-ivopts.c	(working copy)
*************** computation_cost (tree expr, bool speed)
*** 2738,2746 ****
    unsigned cost;
    /* Avoid using hard regs in ways which may be unsupported.  */
    int regno = LAST_VIRTUAL_REGISTER + 1;
!   enum function_frequency real_frequency = cfun->function_frequency;
  
!   cfun->function_frequency = FUNCTION_FREQUENCY_NORMAL;
    crtl->maybe_hot_insn_p = speed;
    walk_tree (&expr, prepare_decl_rtl, &regno, NULL);
    start_sequence ();
--- 2738,2747 ----
    unsigned cost;
    /* Avoid using hard regs in ways which may be unsupported.  */
    int regno = LAST_VIRTUAL_REGISTER + 1;
!   struct cgraph_node *node = cgraph_node (current_function_decl);
!   enum node_frequency real_frequency = node->frequency;
  
!   node->frequency = NODE_FREQUENCY_NORMAL;
    crtl->maybe_hot_insn_p = speed;
    walk_tree (&expr, prepare_decl_rtl, &regno, NULL);
    start_sequence ();
*************** computation_cost (tree expr, bool speed)
*** 2748,2754 ****
    seq = get_insns ();
    end_sequence ();
    default_rtl_profile ();
!   cfun->function_frequency = real_frequency;
  
    cost = seq_cost (seq, speed);
    if (MEM_P (rslt))
--- 2749,2755 ----
    seq = get_insns ();
    end_sequence ();
    default_rtl_profile ();
!   node->frequency = real_frequency;
  
    cost = seq_cost (seq, speed);
    if (MEM_P (rslt))
Index: lto-streamer-out.c
===================================================================
*** lto-streamer-out.c	(revision 158408)
--- lto-streamer-out.c	(working copy)
*************** output_function (struct cgraph_node *nod
*** 1866,1872 ****
    bp_pack_value (bp, fn->has_nonlocal_label, 1);
    bp_pack_value (bp, fn->calls_alloca, 1);
    bp_pack_value (bp, fn->calls_setjmp, 1);
-   bp_pack_value (bp, fn->function_frequency, 2);
    bp_pack_value (bp, fn->va_list_fpr_size, 8);
    bp_pack_value (bp, fn->va_list_gpr_size, 8);
    lto_output_bitpack (ob->main_stream, bp);
--- 1866,1871 ----
Index: predict.c
===================================================================
*** predict.c	(revision 158408)
--- predict.c	(working copy)
*************** static const struct predictor_info predi
*** 113,128 ****
  static inline bool
  maybe_hot_frequency_p (int freq)
  {
    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 (profile_status == PROFILE_ABSENT)
      return true;
!   if (cfun->function_frequency == FUNCTION_FREQUENCY_EXECUTED_ONCE
        && freq <= (ENTRY_BLOCK_PTR->frequency * 2 / 3))
      return false;
    if (freq < BB_FREQ_MAX / PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION))
--- 113,129 ----
  static inline bool
  maybe_hot_frequency_p (int freq)
  {
+   struct cgraph_node *node = cgraph_node (current_function_decl);
    if (!profile_info || !flag_branch_probabilities)
      {
!       if (node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED)
          return false;
!       if (node->frequency == NODE_FREQUENCY_HOT)
          return true;
      }
    if (profile_status == PROFILE_ABSENT)
      return true;
!   if (node->frequency == NODE_FREQUENCY_EXECUTED_ONCE
        && freq <= (ENTRY_BLOCK_PTR->frequency * 2 / 3))
      return false;
    if (freq < BB_FREQ_MAX / PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION))
*************** cgraph_maybe_hot_edge_p (struct cgraph_e
*** 164,187 ****
        && (edge->count
  	  <= profile_info->sum_max / PARAM_VALUE (HOT_BB_COUNT_FRACTION)))
      return false;
!   if (lookup_attribute ("cold", DECL_ATTRIBUTES (edge->callee->decl))
!       || lookup_attribute ("cold", DECL_ATTRIBUTES (edge->caller->decl)))
      return false;
    if (optimize_size)
      return false;
!   if (lookup_attribute ("hot", DECL_ATTRIBUTES (edge->caller->decl)))
      return true;
!   if (DECL_STRUCT_FUNCTION (edge->caller->decl))
!     {
!       struct function *fun = DECL_STRUCT_FUNCTION (edge->caller->decl);
!       if (fun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED)
!         return false;
!       if (fun->function_frequency == FUNCTION_FREQUENCY_HOT)
!         return true;
!       if (fun->function_frequency == FUNCTION_FREQUENCY_EXECUTED_ONCE
!           && edge->frequency < CGRAPH_FREQ_BASE * 3 / 2)
! 	return false;
!     }
    if (flag_guess_branch_prob
        && edge->frequency <= (CGRAPH_FREQ_BASE
        			     / PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION)))
--- 165,180 ----
        && (edge->count
  	  <= profile_info->sum_max / PARAM_VALUE (HOT_BB_COUNT_FRACTION)))
      return false;
!   if (edge->caller->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED
!       || edge->callee->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED)
      return false;
    if (optimize_size)
      return false;
!   if (edge->caller->frequency == NODE_FREQUENCY_HOT)
      return true;
!   if (edge->caller->frequency == NODE_FREQUENCY_EXECUTED_ONCE
!       && edge->frequency < CGRAPH_FREQ_BASE * 3 / 2)
!     return false;
    if (flag_guess_branch_prob
        && edge->frequency <= (CGRAPH_FREQ_BASE
        			     / PARAM_VALUE (HOT_BB_FREQUENCY_FRACTION)))
*************** probably_never_executed_bb_p (const_basi
*** 207,213 ****
    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;
  }
--- 200,206 ----
    if (profile_info && flag_branch_probabilities)
      return ((bb->count + profile_info->runs / 2) / profile_info->runs) == 0;
    if ((!profile_info || !flag_branch_probabilities)
!       && cgraph_node (current_function_decl)->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED)
      return true;
    return false;
  }
*************** bool
*** 218,225 ****
  optimize_function_for_size_p (struct function *fun)
  {
    return (optimize_size
! 	  || (fun && (fun->function_frequency
! 		      == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED)));
  }
  
  /* Return true when current function should always be optimized for speed.  */
--- 211,219 ----
  optimize_function_for_size_p (struct function *fun)
  {
    return (optimize_size
! 	  || (fun && fun->decl
! 	      && (cgraph_node (fun->decl)->frequency
! 		  == NODE_FREQUENCY_UNLIKELY_EXECUTED)));
  }
  
  /* Return true when current function should always be optimized for speed.  */
*************** void
*** 2164,2198 ****
  compute_function_frequency (void)
  {
    basic_block bb;
! 
!   if (cfun->function_frequency == FUNCTION_FREQUENCY_EXECUTED_ONCE)
!     return;
  
    if (!profile_info || !flag_branch_probabilities)
      {
        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;
        else if (MAIN_NAME_P (DECL_NAME (current_function_decl)))
!         cfun->function_frequency = FUNCTION_FREQUENCY_EXECUTED_ONCE;
        else if (DECL_STATIC_CONSTRUCTOR (current_function_decl)
  	       || DECL_STATIC_DESTRUCTOR (current_function_decl))
!         cfun->function_frequency = FUNCTION_FREQUENCY_EXECUTED_ONCE;
        return;
      }
!   cfun->function_frequency = FUNCTION_FREQUENCY_UNLIKELY_EXECUTED;
    FOR_EACH_BB (bb)
      {
        if (maybe_hot_bb_p (bb))
  	{
! 	  cfun->function_frequency = FUNCTION_FREQUENCY_HOT;
  	  return;
  	}
        if (!probably_never_executed_bb_p (bb))
! 	cfun->function_frequency = FUNCTION_FREQUENCY_NORMAL;
      }
  }
  
--- 2158,2190 ----
  compute_function_frequency (void)
  {
    basic_block bb;
!   struct cgraph_node *node = cgraph_node (current_function_decl);
  
    if (!profile_info || !flag_branch_probabilities)
      {
        if (lookup_attribute ("cold", DECL_ATTRIBUTES (current_function_decl))
  	  != NULL)
!         node->frequency = NODE_FREQUENCY_UNLIKELY_EXECUTED;
        else if (lookup_attribute ("hot", DECL_ATTRIBUTES (current_function_decl))
  	       != NULL)
!         node->frequency = NODE_FREQUENCY_HOT;
        else if (MAIN_NAME_P (DECL_NAME (current_function_decl)))
!         node->frequency = NODE_FREQUENCY_EXECUTED_ONCE;
        else if (DECL_STATIC_CONSTRUCTOR (current_function_decl)
  	       || DECL_STATIC_DESTRUCTOR (current_function_decl))
!         node->frequency = NODE_FREQUENCY_EXECUTED_ONCE;
        return;
      }
!   node->frequency = NODE_FREQUENCY_UNLIKELY_EXECUTED;
    FOR_EACH_BB (bb)
      {
        if (maybe_hot_bb_p (bb))
  	{
! 	  node->frequency = NODE_FREQUENCY_HOT;
  	  return;
  	}
        if (!probably_never_executed_bb_p (bb))
! 	node->frequency = NODE_FREQUENCY_NORMAL;
      }
  }
  
*************** compute_function_frequency (void)
*** 2200,2205 ****
--- 2192,2198 ----
  static void
  choose_function_section (void)
  {
+   struct cgraph_node *node = cgraph_node (current_function_decl);
    if (DECL_SECTION_NAME (current_function_decl)
        || !targetm.have_named_sections
        /* Theoretically we can split the gnu.linkonce text section too,
*************** choose_function_section (void)
*** 2215,2224 ****
    if (flag_reorder_blocks_and_partition)
      return;
  
!   if (cfun->function_frequency == FUNCTION_FREQUENCY_HOT)
      DECL_SECTION_NAME (current_function_decl) =
        build_string (strlen (HOT_TEXT_SECTION_NAME), HOT_TEXT_SECTION_NAME);
!   if (cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED)
      DECL_SECTION_NAME (current_function_decl) =
        build_string (strlen (UNLIKELY_EXECUTED_TEXT_SECTION_NAME),
  		    UNLIKELY_EXECUTED_TEXT_SECTION_NAME);
--- 2208,2217 ----
    if (flag_reorder_blocks_and_partition)
      return;
  
!   if (node->frequency == NODE_FREQUENCY_HOT)
      DECL_SECTION_NAME (current_function_decl) =
        build_string (strlen (HOT_TEXT_SECTION_NAME), HOT_TEXT_SECTION_NAME);
!   if (node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED)
      DECL_SECTION_NAME (current_function_decl) =
        build_string (strlen (UNLIKELY_EXECUTED_TEXT_SECTION_NAME),
  		    UNLIKELY_EXECUTED_TEXT_SECTION_NAME);
Index: lto-streamer-in.c
===================================================================
*** lto-streamer-in.c	(revision 158408)
--- lto-streamer-in.c	(working copy)
*************** input_function (tree fn_decl, struct dat
*** 1314,1320 ****
    fn->has_nonlocal_label = bp_unpack_value (bp, 1);
    fn->calls_alloca = bp_unpack_value (bp, 1);
    fn->calls_setjmp = bp_unpack_value (bp, 1);
-   fn->function_frequency = (enum function_frequency) bp_unpack_value (bp, 2);
    fn->va_list_fpr_size = bp_unpack_value (bp, 8);
    fn->va_list_gpr_size = bp_unpack_value (bp, 8);
    bitpack_delete (bp);
--- 1314,1319 ----
Index: function.c
===================================================================
*** function.c	(revision 158408)
--- function.c	(working copy)
*************** allocate_struct_function (tree fndecl, b
*** 4115,4122 ****
  
    cfun = GGC_CNEW (struct function);
  
-   cfun->function_frequency = FUNCTION_FREQUENCY_NORMAL;
- 
    init_eh_for_function ();
  
    if (init_machine_status)
--- 4115,4120 ----
Index: function.h
===================================================================
*** function.h	(revision 158408)
--- function.h	(working copy)
*************** typedef struct ipa_opt_pass_d *ipa_opt_p
*** 176,195 ****
  DEF_VEC_P(ipa_opt_pass);
  DEF_VEC_ALLOC_P(ipa_opt_pass,heap);
  
- enum function_frequency {
-   /* This function most likely won't be executed at all.
-      (set only when profile feedback is available or via function attribute). */
-   FUNCTION_FREQUENCY_UNLIKELY_EXECUTED,
-   /* For functions that are known to be executed once (i.e. constructors, destructors
-      and main function.  */
-   FUNCTION_FREQUENCY_EXECUTED_ONCE,
-   /* The default value.  */
-   FUNCTION_FREQUENCY_NORMAL,
-   /* Optimize this function hard
-      (set only when profile feedback is available or via function attribute). */
-   FUNCTION_FREQUENCY_HOT
- };
- 
  struct GTY(()) varasm_status {
    /* If we're using a per-function constant pool, this is it.  */
    struct rtx_constant_pool *pool;
--- 176,181 ----
*************** struct GTY(()) function {
*** 541,550 ****
       function.  */
    unsigned int va_list_fpr_size : 8;
  
-   /* How commonly executed the function is.  Initialized during branch
-      probabilities pass.  */
-   ENUM_BITFIELD (function_frequency) function_frequency : 2;
- 
    /* Nonzero if function being compiled can call setjmp.  */
    unsigned int calls_setjmp : 1;
  
--- 527,532 ----
Index: ipa-profile.c
===================================================================
*** ipa-profile.c	(revision 158497)
--- ipa-profile.c	(working copy)
*************** along with GCC; see the file COPYING3.  
*** 26,33 ****
  #include "cgraph.h"
  #include "tree.h"
  
- #define CGRAPH_NODE_FREQUENCY(node)  (DECL_STRUCT_FUNCTION((node)->decl)->function_frequency)
- 
  static bool
  try_update (struct cgraph_node *node)
  {
--- 26,31 ----
*************** try_update (struct cgraph_node *node)
*** 41,49 ****
      return false;
    if (!node->analyzed)
      return false;
!   if (CGRAPH_NODE_FREQUENCY (node) == FUNCTION_FREQUENCY_HOT)
      return false;
!   if (CGRAPH_NODE_FREQUENCY (node) == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED)
      return false;
    if (dump_file && (dump_flags & TDF_DETAILS))
      fprintf (dump_file, "Processing %s\n", cgraph_node_name (node));
--- 39,47 ----
      return false;
    if (!node->analyzed)
      return false;
!   if (node->frequency == NODE_FREQUENCY_HOT)
      return false;
!   if (node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED)
      return false;
    if (dump_file && (dump_flags & TDF_DETAILS))
      fprintf (dump_file, "Processing %s\n", cgraph_node_name (node));
*************** try_update (struct cgraph_node *node)
*** 51,61 ****
         edge && (maybe_unlikely_executed || maybe_executed_once);
         edge = edge->next_caller)
      {
!       switch (CGRAPH_NODE_FREQUENCY (edge->caller))
          {
! 	case FUNCTION_FREQUENCY_UNLIKELY_EXECUTED:
  	  break;
! 	case FUNCTION_FREQUENCY_EXECUTED_ONCE:
  	  if (edge->frequency == 0)
  	    break;
  	  if (dump_file && (dump_flags & TDF_DETAILS))
--- 49,59 ----
         edge && (maybe_unlikely_executed || maybe_executed_once);
         edge = edge->next_caller)
      {
!       switch (edge->caller->frequency)
          {
! 	case NODE_FREQUENCY_UNLIKELY_EXECUTED:
  	  break;
! 	case NODE_FREQUENCY_EXECUTED_ONCE:
  	  if (edge->frequency == 0)
  	    break;
  	  if (dump_file && (dump_flags & TDF_DETAILS))
*************** try_update (struct cgraph_node *node)
*** 68,75 ****
  	        fprintf (dump_file, "  Called in loop\n");
  	    }
  	  break;
! 	case FUNCTION_FREQUENCY_HOT:
! 	case FUNCTION_FREQUENCY_NORMAL:
  	  if (!edge->frequency)
  	    continue;
  	  if (dump_file && (dump_flags & TDF_DETAILS))
--- 66,73 ----
  	        fprintf (dump_file, "  Called in loop\n");
  	    }
  	  break;
! 	case NODE_FREQUENCY_HOT:
! 	case NODE_FREQUENCY_NORMAL:
  	  if (!edge->frequency)
  	    continue;
  	  if (dump_file && (dump_flags & TDF_DETAILS))
*************** try_update (struct cgraph_node *node)
*** 81,94 ****
      }
     if (maybe_unlikely_executed)
       {
!        CGRAPH_NODE_FREQUENCY (node) = FUNCTION_FREQUENCY_UNLIKELY_EXECUTED;
         if (dump_file)
           fprintf (dump_file, "Node %s promoted to unlikely executed.\n", cgraph_node_name (node));
         return true;
       }
!    if (maybe_executed_once && CGRAPH_NODE_FREQUENCY (node) != FUNCTION_FREQUENCY_EXECUTED_ONCE)
       {
!        CGRAPH_NODE_FREQUENCY (node) = FUNCTION_FREQUENCY_EXECUTED_ONCE;
         if (dump_file)
           fprintf (dump_file, "Node %s promoted to executed once.\n", cgraph_node_name (node));
         return true;
--- 79,92 ----
      }
     if (maybe_unlikely_executed)
       {
!        node->frequency = NODE_FREQUENCY_UNLIKELY_EXECUTED;
         if (dump_file)
           fprintf (dump_file, "Node %s promoted to unlikely executed.\n", cgraph_node_name (node));
         return true;
       }
!    if (maybe_executed_once && node->frequency != NODE_FREQUENCY_EXECUTED_ONCE)
       {
!        node->frequency = NODE_FREQUENCY_EXECUTED_ONCE;
         if (dump_file)
           fprintf (dump_file, "Node %s promoted to executed once.\n", cgraph_node_name (node));
         return true;
Index: tree-inline.c
===================================================================
*** tree-inline.c	(revision 158471)
--- tree-inline.c	(working copy)
*************** initialize_cfun (tree new_fndecl, tree c
*** 2015,2021 ****
    cfun->last_verified = src_cfun->last_verified;
    cfun->va_list_gpr_size = src_cfun->va_list_gpr_size;
    cfun->va_list_fpr_size = src_cfun->va_list_fpr_size;
-   cfun->function_frequency = src_cfun->function_frequency;
    cfun->has_nonlocal_label = src_cfun->has_nonlocal_label;
    cfun->stdarg = src_cfun->stdarg;
    cfun->dont_save_pending_sizes_p = src_cfun->dont_save_pending_sizes_p;
--- 2015,2020 ----
Index: passes.c
===================================================================
*** passes.c	(revision 158487)
--- passes.c	(working copy)
*************** pass_init_dump_file (struct opt_pass *pa
*** 1362,1375 ****
        if (dump_file && current_function_decl)
  	{
  	  const char *dname, *aname;
  	  dname = lang_hooks.decl_printable_name (current_function_decl, 2);
  	  aname = (IDENTIFIER_POINTER
  		   (DECL_ASSEMBLER_NAME (current_function_decl)));
  	  fprintf (dump_file, "\n;; Function %s (%s)%s\n\n", dname, aname,
! 	     cfun->function_frequency == FUNCTION_FREQUENCY_HOT
  	     ? " (hot)"
! 	     : cfun->function_frequency == FUNCTION_FREQUENCY_UNLIKELY_EXECUTED
  	     ? " (unlikely executed)"
  	     : "");
  	}
        return initializing_dump;
--- 1362,1378 ----
        if (dump_file && current_function_decl)
  	{
  	  const char *dname, *aname;
+ 	  struct cgraph_node *node = cgraph_node (current_function_decl);
  	  dname = lang_hooks.decl_printable_name (current_function_decl, 2);
  	  aname = (IDENTIFIER_POINTER
  		   (DECL_ASSEMBLER_NAME (current_function_decl)));
  	  fprintf (dump_file, "\n;; Function %s (%s)%s\n\n", dname, aname,
! 	     node->frequency == NODE_FREQUENCY_HOT
  	     ? " (hot)"
! 	     : node->frequency == NODE_FREQUENCY_UNLIKELY_EXECUTED
  	     ? " (unlikely executed)"
+ 	     : node->frequency == NODE_FREQUENCY_EXECUTED_ONCE
+ 	     ? " (executed once)"
  	     : "");
  	}
        return initializing_dump;
Index: config/i386/i386.c
===================================================================
*** config/i386/i386.c	(revision 158408)
--- config/i386/i386.c	(working copy)
*************** ix86_compute_frame_layout (struct ix86_f
*** 8034,8039 ****
--- 8034,8040 ----
        && cfun->machine->use_fast_prologue_epilogue_nregs != frame->nregs)
      {
        int count = frame->nregs;
+       struct cgraph_node *node = cgraph_node (current_function_decl);
  
        cfun->machine->use_fast_prologue_epilogue_nregs = count;
        /* The fast prologue uses move instead of push to save registers.  This
*************** ix86_compute_frame_layout (struct ix86_f
*** 8048,8056 ****
  	 slow to use many of them.  */
        if (count)
  	count = (count - 1) * FAST_PROLOGUE_INSN_COUNT;
!       if (cfun->function_frequency < FUNCTION_FREQUENCY_NORMAL
  	  || (flag_branch_probabilities
! 	      && cfun->function_frequency < FUNCTION_FREQUENCY_HOT))
          cfun->machine->use_fast_prologue_epilogue = false;
        else
          cfun->machine->use_fast_prologue_epilogue
--- 8049,8057 ----
  	 slow to use many of them.  */
        if (count)
  	count = (count - 1) * FAST_PROLOGUE_INSN_COUNT;
!       if (node->frequency < NODE_FREQUENCY_NORMAL
  	  || (flag_branch_probabilities
! 	      && node->frequency < NODE_FREQUENCY_HOT))
          cfun->machine->use_fast_prologue_epilogue = false;
        else
          cfun->machine->use_fast_prologue_epilogue
*************** ix86_pad_returns (void)
*** 26702,26708 ****
  	    replace = true;
  	  /* Empty functions get branch mispredict even when the jump destination
  	     is not visible to us.  */
! 	  if (!prev && cfun->function_frequency > FUNCTION_FREQUENCY_UNLIKELY_EXECUTED)
  	    replace = true;
  	}
        if (replace)
--- 26703,26709 ----
  	    replace = true;
  	  /* Empty functions get branch mispredict even when the jump destination
  	     is not visible to us.  */
! 	  if (!prev && !optimize_function_for_size_p (cfun))
  	    replace = true;
  	}
        if (replace)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]