This simplifies the loop invariant motion cost function, removing
the use of the magic constant 20 (the default of lim-expensive),
and making SSA name copies and PAREN_EXPR wrappings have no cost
(movement decisions should not depend on the length of a SSA name
copy chain nor on whether an expression is wrapped inside a
PAREN_EXPR).

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.

Richard.

2011-12-05  Richard Guenther  <rguent...@suse.de>

        * tree-ssa-loop-im.c (stmt_cost): Simplify, use LIM_EXPENSIVE
        rather than magic constants.  Assign zero cost to PAREN_EXPR
        and SSA_NAME copies.  Assign cost proportional to the vector
        size for vector constructors.

Index: gcc/tree-ssa-loop-im.c
===================================================================
*** gcc/tree-ssa-loop-im.c      (revision 182001)
--- gcc/tree-ssa-loop-im.c      (working copy)
*************** add_dependency (tree def, struct lim_aux
*** 509,536 ****
    return true;
  }
  
! /* Returns an estimate for a cost of statement STMT.  TODO -- the values here
!    are just ad-hoc constants.  The estimates should be based on 
target-specific
!    values.  */
  
  static unsigned
  stmt_cost (gimple stmt)
  {
-   tree fndecl;
-   unsigned cost = 1;
- 
    /* Always try to create possibilities for unswitching.  */
    if (gimple_code (stmt) == GIMPLE_COND
        || gimple_code (stmt) == GIMPLE_PHI)
      return LIM_EXPENSIVE;
  
!   /* Hoisting memory references out should almost surely be a win.  */
!   if (gimple_references_memory_p (stmt))
!     cost += 20;
! 
    if (is_gimple_call (stmt))
      {
!       /* We should be hoisting calls if possible.  */
  
        /* Unless the call is a builtin_constant_p; this always folds to a
         constant, so moving it is useless.  */
--- 507,527 ----
    return true;
  }
  
! /* Returns an estimate for a cost of statement STMT.  The values here
!    are just ad-hoc constants, similar to costs for inlining.  */
  
  static unsigned
  stmt_cost (gimple stmt)
  {
    /* Always try to create possibilities for unswitching.  */
    if (gimple_code (stmt) == GIMPLE_COND
        || gimple_code (stmt) == GIMPLE_PHI)
      return LIM_EXPENSIVE;
  
!   /* We should be hoisting calls if possible.  */
    if (is_gimple_call (stmt))
      {
!       tree fndecl;
  
        /* Unless the call is a builtin_constant_p; this always folds to a
         constant, so moving it is useless.  */
*************** stmt_cost (gimple stmt)
*** 540,550 ****
          && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CONSTANT_P)
        return 0;
  
!       return cost + 20;
      }
  
    if (gimple_code (stmt) != GIMPLE_ASSIGN)
!     return cost;
  
    switch (gimple_assign_rhs_code (stmt))
      {
--- 531,545 ----
          && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_CONSTANT_P)
        return 0;
  
!       return LIM_EXPENSIVE;
      }
  
+   /* Hoisting memory references out should almost surely be a win.  */
+   if (gimple_references_memory_p (stmt))
+     return LIM_EXPENSIVE;
+ 
    if (gimple_code (stmt) != GIMPLE_ASSIGN)
!     return 1;
  
    switch (gimple_assign_rhs_code (stmt))
      {
*************** stmt_cost (gimple stmt)
*** 565,586 ****
      case TRUNC_MOD_EXPR:
      case RDIV_EXPR:
        /* Division and multiplication are usually expensive.  */
!       cost += 20;
!       break;
  
      case LSHIFT_EXPR:
      case RSHIFT_EXPR:
      case WIDEN_LSHIFT_EXPR:
      case LROTATE_EXPR:
      case RROTATE_EXPR:
!       cost += 20;
!       break;
  
      default:
!       break;
      }
- 
-   return cost;
  }
  
  /* Finds the outermost loop between OUTER and LOOP in that the memory 
reference
--- 560,590 ----
      case TRUNC_MOD_EXPR:
      case RDIV_EXPR:
        /* Division and multiplication are usually expensive.  */
!       return LIM_EXPENSIVE;
  
      case LSHIFT_EXPR:
      case RSHIFT_EXPR:
      case WIDEN_LSHIFT_EXPR:
      case LROTATE_EXPR:
      case RROTATE_EXPR:
!       /* Shifts and rotates are usually expensive.  */
!       return LIM_EXPENSIVE;
! 
!     case CONSTRUCTOR:
!       /* Make vector construction cost proportional to the number
!          of elements.  */
!       return CONSTRUCTOR_NELTS (gimple_assign_rhs1 (stmt));
! 
!     case SSA_NAME:
!     case PAREN_EXPR:
!       /* Whether or not something is wrapped inside a PAREN_EXPR
!          should not change move cost.  Nor should an intermediate
!        unpropagated SSA name copy.  */
!       return 0;
  
      default:
!       return 1;
      }
  }
  
  /* Finds the outermost loop between OUTER and LOOP in that the memory 
reference

Reply via email to