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]

[patch] Improve estimate_num_insn


Hello,

estimate_num_insns is currently used for several things:

-- on several places (loop unrolling, unswitching, exception
   handling expansion), to estimate the size of the code
-- in prefetching, to estimate time necessary to execute the
   code
-- in inlining for magic heuristic (that pretends to do the
   former, but in fact turns out to be closer to the latter)

Not surprisingly, it cannot work well enough for all these usages
(in particular, the optimizations that rely on it being the size of
the code suffer by the unrealistical values returned for calls and
divisions).  This patch makes it possible to select which of these
three estimates should be returned (by passing the structure containing
costs of various constructs to it).

Bootstrapped & regtested on i686, x86_64 and ppc64.

Zdenek

	* tree-ssa-loop-unswitch.c: Include tree-inline.h.
	(tree_unswitch_single_loop): Pass eni_size_weights to
	tree_num_loop_insns.
	* tree-ssa-loop-manip.c: Include tree-inline.h.
	(can_unroll_loop_p): Pass eni_size_weights to
	tree_num_loop_insns.
	* tree-ssa-loop-ch.c (should_duplicate_loop_header_p):
	Pass eni_size_weights to estimate_num_insns.
	* tree.h (init_inline_once): Export.
	* toplev.c (backend_init): Call init_inline_once.
	* cgraphunit.c (cgraph_analyze_function): Pass
	eni_inlining_weights to estimate_num_insns.
	* ipa-inline.c (cgraph_decide_inlining,
	cgraph_early_inlining): Ditto.
	* tree-ssa-loop-ivcanon.c (tree_num_loop_insns): Pass weights
	to estimate_num_insns.
	(try_unroll_loop_completely): Pass eni_size_weights to
	tree_num_loop_insns.
	* tree-eh.c (decide_copy_try_finally): Pass eni_size_weights
	ot estimate_num_insns.
	* tree-ssa-loop-prefetch.c: Include tree-inline.h.
	(loop_prefetch_arrays): Pass eni_time_weights to tree_num_loop_insns.
	* tree-inline.c (eni_inlining_weights, eni_size_weights,
	eni_time_weights): New variables.
	(init_inline_once): Initialize them.
	(struct eni_data): Mew.
	(estimate_num_insns_1, estimate_num_insns): Use weights.
	* tree-inline.h (struct eni_weights_d): New.
	(eni_inlining_weights, eni_size_weights, eni_time_weights): Declare.
	(estimate_num_insns): Declaration changed.
	* cfgloop.h (tree_num_loop_insns): Declaration changed.
	* Makefile.in (tree-ssa-loop-unswitch.o, tree-ssa-loop-prefetch.o,
	tree-ssa-loop-manip.o): Add TREE_INLINE_H dependency.

	* gcc.dg/tree-ssa/loop-20.c: New test.

Index: tree-ssa-loop-unswitch.c
===================================================================
*** tree-ssa-loop-unswitch.c	(revision 118133)
--- tree-ssa-loop-unswitch.c	(working copy)
*************** Software Foundation, 51 Franklin Street,
*** 36,41 ****
--- 36,42 ----
  #include "domwalk.h"
  #include "params.h"
  #include "tree-pass.h"
+ #include "tree-inline.h"
  
  /* This file implements the loop unswitching, i.e. transformation of loops like
  
*************** tree_unswitch_single_loop (struct loops 
*** 202,208 ****
      }
  
    /* The loop should not be too large, to limit code growth.  */
!   if (tree_num_loop_insns (loop)
        > (unsigned) PARAM_VALUE (PARAM_MAX_UNSWITCH_INSNS))
      {
        if (dump_file && (dump_flags & TDF_DETAILS))
--- 203,209 ----
      }
  
    /* The loop should not be too large, to limit code growth.  */
!   if (tree_num_loop_insns (loop, &eni_size_weights)
        > (unsigned) PARAM_VALUE (PARAM_MAX_UNSWITCH_INSNS))
      {
        if (dump_file && (dump_flags & TDF_DETAILS))
Index: tree-ssa-loop-manip.c
===================================================================
*** tree-ssa-loop-manip.c	(revision 118133)
--- tree-ssa-loop-manip.c	(working copy)
*************** Software Foundation, 51 Franklin Street,
*** 37,42 ****
--- 37,43 ----
  #include "cfglayout.h"
  #include "tree-scalar-evolution.h"
  #include "params.h"
+ #include "tree-inline.h"
  
  /* Creates an induction variable with value BASE + STEP * iteration in LOOP.
     It is expected that neither BASE nor STEP are shared with other expressions
*************** can_unroll_loop_p (struct loop *loop, un
*** 659,665 ****
      return false;
  
    /* The final loop should be small enough.  */
!   if (tree_num_loop_insns (loop) * factor
        > (unsigned) PARAM_VALUE (PARAM_MAX_UNROLLED_INSNS))
      return false;
  
--- 660,666 ----
      return false;
  
    /* The final loop should be small enough.  */
!   if (tree_num_loop_insns (loop, &eni_size_weights) * factor
        > (unsigned) PARAM_VALUE (PARAM_MAX_UNROLLED_INSNS))
      return false;
  
Index: tree-ssa-loop-ch.c
===================================================================
*** tree-ssa-loop-ch.c	(revision 118133)
--- tree-ssa-loop-ch.c	(working copy)
*************** should_duplicate_loop_header_p (basic_bl
*** 87,93 ****
        if (get_call_expr_in (last))
  	return false;
  
!       *limit -= estimate_num_insns (last);
        if (*limit < 0)
  	return false;
      }
--- 87,93 ----
        if (get_call_expr_in (last))
  	return false;
  
!       *limit -= estimate_num_insns (last, &eni_size_weights);
        if (*limit < 0)
  	return false;
      }
Index: tree.h
===================================================================
*** tree.h	(revision 118133)
--- tree.h	(working copy)
*************** extern unsigned HOST_WIDE_INT compute_bu
*** 4613,4616 ****
--- 4613,4620 ----
  /* In expr.c.  */
  extern unsigned HOST_WIDE_INT highest_pow2_factor (tree);
  
+ /* In tree-inline.c.  */
+ 
+ void init_inline_once (void);
+ 
  #endif  /* GCC_TREE_H  */
Index: toplev.c
===================================================================
*** toplev.c	(revision 118133)
--- toplev.c	(working copy)
*************** backend_init (void)
*** 1870,1875 ****
--- 1870,1876 ----
    init_regs ();
    init_fake_stack_mems ();
    init_alias_once ();
+   init_inline_once ();
    init_reload ();
    init_varasm_once ();
  
Index: cgraphunit.c
===================================================================
*** cgraphunit.c	(revision 118133)
--- cgraphunit.c	(working copy)
*************** cgraph_analyze_function (struct cgraph_n
*** 952,958 ****
  
    node->local.inlinable = tree_inlinable_function_p (decl);
    if (!flag_unit_at_a_time)
!     node->local.self_insns = estimate_num_insns (decl);
    if (node->local.inlinable)
      node->local.disregard_inline_limits
        = lang_hooks.tree_inlining.disregard_inline_limits (decl);
--- 952,958 ----
  
    node->local.inlinable = tree_inlinable_function_p (decl);
    if (!flag_unit_at_a_time)
!     node->local.self_insns = estimate_num_insns (decl, &eni_inlining_weights);
    if (node->local.inlinable)
      node->local.disregard_inline_limits
        = lang_hooks.tree_inlining.disregard_inline_limits (decl);
Index: testsuite/gcc.dg/tree-ssa/loop-20.c
===================================================================
*** testsuite/gcc.dg/tree-ssa/loop-20.c	(revision 0)
--- testsuite/gcc.dg/tree-ssa/loop-20.c	(revision 0)
***************
*** 0 ****
--- 1,26 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O2 -funroll-loops -fdump-tree-cunroll-details" } */
+ 
+ void bla(int);
+ 
+ void foo(void)
+ {
+   int i;
+ 
+   /* This loop used to appear to be too large for unrolling.  */
+   for (i = 0; i < 4; i++)
+     {
+       bla (i);
+       bla (2*i);
+       bla (3*i);
+       bla (4*i);
+       bla (5*i);
+       bla (6*i);
+       bla (7*i);
+       bla (8*i);
+     }
+ }
+ 
+ /* { dg-final { scan-tree-dump-times "Unrolled loop 1 completely" 1 "cunroll" } } */
+ 
+ /* { dg-final { cleanup-tree-dump "cunroll" } } */
Index: ipa-inline.c
===================================================================
*** ipa-inline.c	(revision 118133)
--- ipa-inline.c	(working copy)
*************** cgraph_decide_inlining (void)
*** 915,921 ****
  	   already did so.  */
  	if (!flag_early_inlining)
  	  node->local.self_insns = node->global.insns
! 	     = estimate_num_insns (node->decl);
  
  	initial_insns += node->local.self_insns;
  	gcc_assert (node->local.self_insns == node->global.insns);
--- 915,921 ----
  	   already did so.  */
  	if (!flag_early_inlining)
  	  node->local.self_insns = node->global.insns
! 	     = estimate_num_insns (node->decl, &eni_inlining_weights);
  
  	initial_insns += node->local.self_insns;
  	gcc_assert (node->local.self_insns == node->global.insns);
*************** cgraph_early_inlining (void)
*** 1200,1206 ****
        node = order[i];
        if (node->analyzed && (node->needed || node->reachable))
          node->local.self_insns = node->global.insns
! 	  = estimate_num_insns (node->decl);
      }
    for (i = nnodes - 1; i >= 0; i--)
      {
--- 1200,1206 ----
        node = order[i];
        if (node->analyzed && (node->needed || node->reachable))
          node->local.self_insns = node->global.insns
! 	  = estimate_num_insns (node->decl, &eni_inlining_weights);
      }
    for (i = nnodes - 1; i >= 0; i--)
      {
Index: tree-ssa-loop-ivcanon.c
===================================================================
*** tree-ssa-loop-ivcanon.c	(revision 118133)
--- tree-ssa-loop-ivcanon.c	(working copy)
*************** create_canonical_iv (struct loop *loop, 
*** 111,120 ****
    update_stmt (cond);
  }
  
! /* Computes an estimated number of insns in LOOP.  */
  
  unsigned
! tree_num_loop_insns (struct loop *loop)
  {
    basic_block *body = get_loop_body (loop);
    block_stmt_iterator bsi;
--- 111,120 ----
    update_stmt (cond);
  }
  
! /* Computes an estimated number of insns in LOOP, weighted by WEIGHTS.  */
  
  unsigned
! tree_num_loop_insns (struct loop *loop, eni_weights *weights)
  {
    basic_block *body = get_loop_body (loop);
    block_stmt_iterator bsi;
*************** tree_num_loop_insns (struct loop *loop)
*** 122,128 ****
  
    for (i = 0; i < loop->num_nodes; i++)
      for (bsi = bsi_start (body[i]); !bsi_end_p (bsi); bsi_next (&bsi))
!       size += estimate_num_insns (bsi_stmt (bsi));
    free (body);
  
    return size;
--- 122,128 ----
  
    for (i = 0; i < loop->num_nodes; i++)
      for (bsi = bsi_start (body[i]); !bsi_end_p (bsi); bsi_next (&bsi))
!       size += estimate_num_insns (bsi_stmt (bsi), weights);
    free (body);
  
    return size;
*************** try_unroll_loop_completely (struct loops
*** 183,189 ****
        if (ul == UL_SINGLE_ITER)
  	return false;
  
!       ninsns = tree_num_loop_insns (loop);
  
        if (n_unroll * ninsns
  	  > (unsigned) PARAM_VALUE (PARAM_MAX_COMPLETELY_PEELED_INSNS))
--- 183,189 ----
        if (ul == UL_SINGLE_ITER)
  	return false;
  
!       ninsns = tree_num_loop_insns (loop, &eni_size_weights);
  
        if (n_unroll * ninsns
  	  > (unsigned) PARAM_VALUE (PARAM_MAX_COMPLETELY_PEELED_INSNS))
Index: tree-eh.c
===================================================================
*** tree-eh.c	(revision 118133)
--- tree-eh.c	(working copy)
*************** decide_copy_try_finally (int ndests, tre
*** 1320,1326 ****
      return false;
  
    /* Finally estimate N times, plus N gotos.  */
!   f_estimate = estimate_num_insns (finally);
    f_estimate = (f_estimate + 1) * ndests;
  
    /* Switch statement (cost 10), N variable assignments, N gotos.  */
--- 1320,1326 ----
      return false;
  
    /* Finally estimate N times, plus N gotos.  */
!   f_estimate = estimate_num_insns (finally, &eni_size_weights);
    f_estimate = (f_estimate + 1) * ndests;
  
    /* Switch statement (cost 10), N variable assignments, N gotos.  */
Index: tree-ssa-loop-prefetch.c
===================================================================
*** tree-ssa-loop-prefetch.c	(revision 118133)
--- tree-ssa-loop-prefetch.c	(working copy)
*************** Software Foundation, 59 Temple Place - S
*** 45,50 ****
--- 45,51 ----
  #include "toplev.h"
  #include "params.h"
  #include "langhooks.h"
+ #include "tree-inline.h"
  
  /* This pass inserts prefetch instructions to optimize cache usage during
     accesses to arrays in loops.  It processes loops sequentially and:
*************** loop_prefetch_arrays (struct loops *loop
*** 973,979 ****
  
    /* FIXME: We should use not size of the loop, but the average number of
       instructions executed per iteration of the loop.  */
!   ninsns = tree_num_loop_insns (loop);
    ahead = (PREFETCH_LATENCY + ninsns - 1) / ninsns;
    unroll_factor = determine_unroll_factor (loop, refs, ahead, ninsns,
  					   &desc);
--- 974,980 ----
  
    /* FIXME: We should use not size of the loop, but the average number of
       instructions executed per iteration of the loop.  */
!   ninsns = tree_num_loop_insns (loop, &eni_time_weights);
    ahead = (PREFETCH_LATENCY + ninsns - 1) / ninsns;
    unroll_factor = determine_unroll_factor (loop, refs, ahead, ninsns,
  					   &desc);
Index: tree-inline.c
===================================================================
*** tree-inline.c	(revision 118133)
--- tree-inline.c	(working copy)
*************** int flag_inline_trees = 0;
*** 105,110 ****
--- 105,125 ----
     o Provide heuristics to clamp inlining of recursive template
       calls?  */
  
+ 
+ /* Weights that estimate_num_insns uses for heuristics in inlining.  */
+ 
+ eni_weights eni_inlining_weights;
+ 
+ /* Weights that estimate_num_insns uses to estimate the size of the
+    produced code.  */
+ 
+ eni_weights eni_size_weights;
+ 
+ /* Weights that estimate_num_insns uses to estimate the time necessary
+    to execute the produced code.  */
+ 
+ eni_weights eni_time_weights;
+ 
  /* Prototypes.  */
  
  static tree declare_return_variable (copy_body_data *, tree, tree, tree *);
*************** estimate_move_cost (tree type)
*** 1567,1580 ****
      return ((size + MOVE_MAX_PIECES - 1) / MOVE_MAX_PIECES);
  }
  
  /* Used by estimate_num_insns.  Estimate number of instructions seen
     by given statement.  */
  
  static tree
  estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data)
  {
!   int *count = (int *) data;
    tree x = *tp;
  
    if (IS_TYPE_OR_DECL_P (x))
      {
--- 1582,1607 ----
      return ((size + MOVE_MAX_PIECES - 1) / MOVE_MAX_PIECES);
  }
  
+ /* Arguments for estimate_num_insns_1.  */
+ 
+ struct eni_data
+ {
+   /* Used to return the number of insns.  */
+   int count;
+ 
+   /* Weights of various constructs.  */
+   eni_weights *weights;
+ };
+ 
  /* Used by estimate_num_insns.  Estimate number of instructions seen
     by given statement.  */
  
  static tree
  estimate_num_insns_1 (tree *tp, int *walk_subtrees, void *data)
  {
!   struct eni_data *d = data;
    tree x = *tp;
+   unsigned cost;
  
    if (IS_TYPE_OR_DECL_P (x))
      {
*************** estimate_num_insns_1 (tree *tp, int *wal
*** 1687,1693 ****
        /* Otherwise it's a store, so fall through to compute the move cost.  */
  
      case CONSTRUCTOR:
!       *count += estimate_move_cost (TREE_TYPE (x));
        break;
  
      /* Assign cost of 1 to usual operations.
--- 1714,1720 ----
        /* Otherwise it's a store, so fall through to compute the move cost.  */
  
      case CONSTRUCTOR:
!       d->count += estimate_move_cost (TREE_TYPE (x));
        break;
  
      /* Assign cost of 1 to usual operations.
*************** estimate_num_insns_1 (tree *tp, int *wal
*** 1754,1761 ****
      case POSTDECREMENT_EXPR:
      case POSTINCREMENT_EXPR:
  
-     case SWITCH_EXPR:
- 
      case ASM_EXPR:
  
      case REALIGN_LOAD_EXPR:
--- 1781,1786 ----
*************** estimate_num_insns_1 (tree *tp, int *wal
*** 1769,1775 ****
      case WIDEN_MULT_EXPR:
  
      case RESX_EXPR:
!       *count += 1;
        break;
  
      /* Few special cases of expensive operations.  This is useful
--- 1794,1806 ----
      case WIDEN_MULT_EXPR:
  
      case RESX_EXPR:
!       d->count += 1;
!       break;
! 
!     case SWITCH_EXPR:
!       /* TODO: Cost of a switch should be derived from the number of
! 	 branches.  */
!       d->count += d->weights->switch_cost;
        break;
  
      /* Few special cases of expensive operations.  This is useful
*************** estimate_num_insns_1 (tree *tp, int *wal
*** 1784,1796 ****
      case FLOOR_MOD_EXPR:
      case ROUND_MOD_EXPR:
      case RDIV_EXPR:
!       *count += 10;
        break;
      case CALL_EXPR:
        {
  	tree decl = get_callee_fndecl (x);
  	tree arg;
  
  	if (decl && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
  	  switch (DECL_FUNCTION_CODE (decl))
  	    {
--- 1815,1828 ----
      case FLOOR_MOD_EXPR:
      case ROUND_MOD_EXPR:
      case RDIV_EXPR:
!       d->count += d->weights->div_mod_cost;
        break;
      case CALL_EXPR:
        {
  	tree decl = get_callee_fndecl (x);
  	tree arg;
  
+ 	cost = d->weights->call_cost;
  	if (decl && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
  	  switch (DECL_FUNCTION_CODE (decl))
  	    {
*************** estimate_num_insns_1 (tree *tp, int *wal
*** 1799,1804 ****
--- 1831,1840 ----
  	      return NULL_TREE;
  	    case BUILT_IN_EXPECT:
  	      return NULL_TREE;
+ 	    /* Prefetch instruction is not expensive.  */
+ 	    case BUILT_IN_PREFETCH:
+ 	      cost = 1;
+ 	      break;
  	    default:
  	      break;
  	    }
*************** estimate_num_insns_1 (tree *tp, int *wal
*** 1808,1822 ****
  	if (!decl)
  	  {
  	    for (arg = TREE_OPERAND (x, 1); arg; arg = TREE_CHAIN (arg))
! 	      *count += estimate_move_cost (TREE_TYPE (TREE_VALUE (arg)));
  	  }
  	else
  	  {
  	    for (arg = DECL_ARGUMENTS (decl); arg; arg = TREE_CHAIN (arg))
! 	      *count += estimate_move_cost (TREE_TYPE (arg));
  	  }
  
! 	*count += PARAM_VALUE (PARAM_INLINE_CALL_COST);
  	break;
        }
  
--- 1844,1858 ----
  	if (!decl)
  	  {
  	    for (arg = TREE_OPERAND (x, 1); arg; arg = TREE_CHAIN (arg))
! 	      d->count += estimate_move_cost (TREE_TYPE (TREE_VALUE (arg)));
  	  }
  	else
  	  {
  	    for (arg = DECL_ARGUMENTS (decl); arg; arg = TREE_CHAIN (arg))
! 	      d->count += estimate_move_cost (TREE_TYPE (arg));
  	  }
  
! 	d->count += cost;
  	break;
        }
  
*************** estimate_num_insns_1 (tree *tp, int *wal
*** 1830,1836 ****
      case OMP_CRITICAL:
      case OMP_ATOMIC:
        /* OpenMP directives are generally very expensive.  */
!       *count += 40;
        break;
  
      default:
--- 1866,1872 ----
      case OMP_CRITICAL:
      case OMP_ATOMIC:
        /* OpenMP directives are generally very expensive.  */
!       d->count += d->weights->omp_cost;
        break;
  
      default:
*************** estimate_num_insns_1 (tree *tp, int *wal
*** 1839,1854 ****
    return NULL;
  }
  
! /* Estimate number of instructions that will be created by expanding EXPR.  */
  
  int
! estimate_num_insns (tree expr)
  {
-   int num = 0;
    struct pointer_set_t *visited_nodes;
    basic_block bb;
    block_stmt_iterator bsi;
    struct function *my_function;
  
    /* If we're given an entire function, walk the CFG.  */
    if (TREE_CODE (expr) == FUNCTION_DECL)
--- 1875,1894 ----
    return NULL;
  }
  
! /* Estimate number of instructions that will be created by expanding EXPR.
!    WEIGHTS contains weigths attributed to various constructs.  */
  
  int
! estimate_num_insns (tree expr, eni_weights *weights)
  {
    struct pointer_set_t *visited_nodes;
    basic_block bb;
    block_stmt_iterator bsi;
    struct function *my_function;
+   struct eni_data data;
+ 
+   data.count = 0;
+   data.weights = weights;
  
    /* If we're given an entire function, walk the CFG.  */
    if (TREE_CODE (expr) == FUNCTION_DECL)
*************** estimate_num_insns (tree expr)
*** 1863,1877 ****
  	       bsi_next (&bsi))
  	    {
  	      walk_tree (bsi_stmt_ptr (bsi), estimate_num_insns_1,
! 			 &num, visited_nodes);
  	    }
  	}
        pointer_set_destroy (visited_nodes);
      }
    else
!     walk_tree_without_duplicates (&expr, estimate_num_insns_1, &num);
  
!   return num;
  }
  
  typedef struct function *function_p;
--- 1903,1942 ----
  	       bsi_next (&bsi))
  	    {
  	      walk_tree (bsi_stmt_ptr (bsi), estimate_num_insns_1,
! 			 &data, visited_nodes);
  	    }
  	}
        pointer_set_destroy (visited_nodes);
      }
    else
!     walk_tree_without_duplicates (&expr, estimate_num_insns_1, &data);
  
!   return data.count;
! }
! 
! /* Initializes weights used by estimate_num_insns.  */
! 
! void
! init_inline_once (void)
! {
!   eni_inlining_weights.call_cost = PARAM_VALUE (PARAM_INLINE_CALL_COST);
!   eni_inlining_weights.div_mod_cost = 10;
!   eni_inlining_weights.switch_cost = 1;
!   eni_inlining_weights.omp_cost = 40;
! 
!   eni_size_weights.call_cost = 1;
!   eni_size_weights.div_mod_cost = 1;
!   eni_size_weights.switch_cost = 10;
!   eni_size_weights.omp_cost = 40;
! 
!   /* Estimating time for call is difficult, since we have no idea what the
!      called function does.  In the current uses of eni_time_weights,
!      underestimating the cost does less harm than overestimating it, so
!      we choose a rather small walue here.  */
!   eni_time_weights.call_cost = 10;
!   eni_time_weights.div_mod_cost = 10;
!   eni_size_weights.switch_cost = 4;
!   eni_time_weights.omp_cost = 40;
  }
  
  typedef struct function *function_p;
Index: tree-inline.h
===================================================================
*** tree-inline.h	(revision 118133)
--- tree-inline.h	(working copy)
*************** typedef struct copy_body_data
*** 90,95 ****
--- 90,126 ----
    bool transform_lang_insert_block;
  } copy_body_data;
  
+ /* Weights of constructions for estimate_num_insns.  */
+ 
+ typedef struct eni_weights_d
+ {
+   /* Cost per call.  */
+   unsigned call_cost;
+ 
+   /* Cost of "expensive" div and mod operations.  */
+   unsigned div_mod_cost;
+ 
+   /* Cost of switch statement.  */
+   unsigned switch_cost;
+ 
+   /* Cost for omp construct.  */
+   unsigned omp_cost;
+ } eni_weights;
+ 
+ /* Weights that estimate_num_insns uses for heuristics in inlining.  */
+ 
+ extern eni_weights eni_inlining_weights;
+ 
+ /* Weights that estimate_num_insns uses to estimate the size of the
+    produced code.  */
+ 
+ extern eni_weights eni_size_weights;
+ 
+ /* Weights that estimate_num_insns uses to estimate the time necessary
+    to execute the produced code.  */
+ 
+ extern eni_weights eni_time_weights;
+ 
  /* Function prototypes.  */
  
  extern tree copy_body_r (tree *, int *, void *);
*************** void save_body (tree, tree *, tree *);
*** 103,109 ****
  int estimate_move_cost (tree type);
  void push_cfun (struct function *new_cfun);
  void pop_cfun (void);
! int estimate_num_insns (tree expr);
  bool tree_versionable_function_p (tree);
  void tree_function_versioning (tree, tree, varray_type, bool);
  
--- 134,140 ----
  int estimate_move_cost (tree type);
  void push_cfun (struct function *new_cfun);
  void pop_cfun (void);
! int estimate_num_insns (tree expr, eni_weights *);
  bool tree_versionable_function_p (tree);
  void tree_function_versioning (tree, tree, varray_type, bool);
  
Index: cfgloop.h
===================================================================
*** cfgloop.h	(revision 118133)
--- cfgloop.h	(working copy)
*************** extern bool flow_loop_nested_p	(const st
*** 198,204 ****
  extern bool flow_bb_inside_loop_p (const struct loop *, const basic_block);
  extern struct loop * find_common_loop (struct loop *, struct loop *);
  struct loop *superloop_at_depth (struct loop *, unsigned);
! extern unsigned tree_num_loop_insns (struct loop *);
  extern int num_loop_insns (struct loop *);
  extern int average_num_loop_insns (struct loop *);
  extern unsigned get_loop_level (const struct loop *);
--- 198,205 ----
  extern bool flow_bb_inside_loop_p (const struct loop *, const basic_block);
  extern struct loop * find_common_loop (struct loop *, struct loop *);
  struct loop *superloop_at_depth (struct loop *, unsigned);
! struct eni_weights_d;
! extern unsigned tree_num_loop_insns (struct loop *, struct eni_weights_d *);
  extern int num_loop_insns (struct loop *);
  extern int average_num_loop_insns (struct loop *);
  extern unsigned get_loop_level (const struct loop *);
Index: Makefile.in
===================================================================
*** Makefile.in	(revision 118133)
--- Makefile.in	(working copy)
*************** tree-ssa-loop.o : tree-ssa-loop.c $(TREE
*** 1985,1991 ****
  tree-ssa-loop-unswitch.o : tree-ssa-loop-unswitch.c $(TREE_FLOW_H) \
     $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) \
     domwalk.h $(PARAMS_H) output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) \
!    coretypes.h $(TREE_DUMP_H) tree-pass.h $(BASIC_BLOCK_H) hard-reg-set.h
  tree-ssa-address.o : tree-ssa-address.c $(TREE_FLOW_H) $(CONFIG_H) \
     $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) \
     output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
--- 1985,1992 ----
  tree-ssa-loop-unswitch.o : tree-ssa-loop-unswitch.c $(TREE_FLOW_H) \
     $(CONFIG_H) $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) \
     domwalk.h $(PARAMS_H) output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) \
!    coretypes.h $(TREE_DUMP_H) tree-pass.h $(BASIC_BLOCK_H) hard-reg-set.h \
!     $(TREE_INLINE_H)
  tree-ssa-address.o : tree-ssa-address.c $(TREE_FLOW_H) $(CONFIG_H) \
     $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) \
     output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
*************** tree-ssa-loop-prefetch.o: tree-ssa-loop-
*** 2010,2016 ****
     output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
     tree-pass.h $(GGC_H) $(RECOG_H) insn-config.h $(HASHTAB_H) $(SCEV_H) \
     $(CFGLOOP_H) $(PARAMS_H) langhooks.h $(BASIC_BLOCK_H) hard-reg-set.h \
!    tree-chrec.h toplev.h langhooks.h
  tree-ssa-loop-ivopts.o : tree-ssa-loop-ivopts.c $(TREE_FLOW_H) $(CONFIG_H) \
     $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) $(EXPR_H) \
     output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
--- 2011,2017 ----
     output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
     tree-pass.h $(GGC_H) $(RECOG_H) insn-config.h $(HASHTAB_H) $(SCEV_H) \
     $(CFGLOOP_H) $(PARAMS_H) langhooks.h $(BASIC_BLOCK_H) hard-reg-set.h \
!    tree-chrec.h toplev.h langhooks.h $(TREE_INLINE_H)
  tree-ssa-loop-ivopts.o : tree-ssa-loop-ivopts.c $(TREE_FLOW_H) $(CONFIG_H) \
     $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) $(EXPR_H) \
     output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
*************** tree-ssa-loop-manip.o : tree-ssa-loop-ma
*** 2021,2027 ****
     $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) \
     output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
     tree-pass.h $(CFGLAYOUT_H) $(SCEV_H) $(BASIC_BLOCK_H) hard-reg-set.h \
!    $(PARAMS_H)
  tree-ssa-loop-im.o : tree-ssa-loop-im.c $(TREE_FLOW_H) $(CONFIG_H) \
     $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) domwalk.h \
     $(PARAMS_H) output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h \
--- 2022,2028 ----
     $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) \
     output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h $(TREE_DUMP_H) \
     tree-pass.h $(CFGLAYOUT_H) $(SCEV_H) $(BASIC_BLOCK_H) hard-reg-set.h \
!    $(PARAMS_H) $(TREE_INLINE_H)
  tree-ssa-loop-im.o : tree-ssa-loop-im.c $(TREE_FLOW_H) $(CONFIG_H) \
     $(SYSTEM_H) $(RTL_H) $(TREE_H) $(TM_P_H) $(CFGLOOP_H) domwalk.h \
     $(PARAMS_H) output.h $(DIAGNOSTIC_H) $(TIMEVAR_H) $(TM_H) coretypes.h \


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