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