> In addition, it appears at first glance that GCC is either no longer > inlining at -Os, even when it would be a size advantage to do so, or is > making some very poor inlining choices. > > e.g. +72 nsTArray<ObserverRef>::nsTArray(nsTArray<ObserverRef> const&) > > We can turn some of these observations into bug reports if that would be > helpful, but if it would make more sense we could perhaps just tune the > inlining parameters directly to get the "real -Os" that we usually want.
We ran into similar inlining regressions in Ada, the heuristics have indeed changed significantly. The attached patchlet alone saves 3% in code size at -Os on a 50 MB executable and yields a 5% speedup at -O2 on another code. * ipa-inline.c (likely_eliminated_by_inlining_p): Really consider that loads from parameters passed by reference are free after inlining. -- Eric Botcazou
*** gcc/ipa-inline.c.0 2010-06-12 17:01:09.000000000 +0200 --- gcc/ipa-inline.c 2010-06-12 18:26:32.000000000 +0200 *************** likely_eliminated_by_inlining_p (gimple *** 1736,1754 **** bool rhs_free = false; bool lhs_free = false; ! while (handled_component_p (inner_lhs) || TREE_CODE (inner_lhs) == INDIRECT_REF) inner_lhs = TREE_OPERAND (inner_lhs, 0); ! while (handled_component_p (inner_rhs) ! || TREE_CODE (inner_rhs) == ADDR_EXPR || TREE_CODE (inner_rhs) == INDIRECT_REF) inner_rhs = TREE_OPERAND (inner_rhs, 0); - if (TREE_CODE (inner_rhs) == PARM_DECL || (TREE_CODE (inner_rhs) == SSA_NAME && SSA_NAME_IS_DEFAULT_DEF (inner_rhs) && TREE_CODE (SSA_NAME_VAR (inner_rhs)) == PARM_DECL)) rhs_free = true; ! if (rhs_free && is_gimple_reg (lhs)) lhs_free = true; if (((TREE_CODE (inner_lhs) == PARM_DECL || (TREE_CODE (inner_lhs) == SSA_NAME --- 1736,1757 ---- bool rhs_free = false; bool lhs_free = false; ! while (handled_component_p (inner_lhs) ! || TREE_CODE (inner_lhs) == INDIRECT_REF) inner_lhs = TREE_OPERAND (inner_lhs, 0); ! while (handled_component_p (inner_rhs) ! || TREE_CODE (inner_rhs) == ADDR_EXPR ! || TREE_CODE (inner_rhs) == INDIRECT_REF) inner_rhs = TREE_OPERAND (inner_rhs, 0); if (TREE_CODE (inner_rhs) == PARM_DECL || (TREE_CODE (inner_rhs) == SSA_NAME && SSA_NAME_IS_DEFAULT_DEF (inner_rhs) && TREE_CODE (SSA_NAME_VAR (inner_rhs)) == PARM_DECL)) rhs_free = true; ! if (rhs_free ! && (is_gimple_reg (lhs) ! || !is_gimple_reg_type (TREE_TYPE (lhs)))) lhs_free = true; if (((TREE_CODE (inner_lhs) == PARM_DECL || (TREE_CODE (inner_lhs) == SSA_NAME *************** likely_eliminated_by_inlining_p (gimple *** 1759,1765 **** || (TREE_CODE (inner_lhs) == SSA_NAME && TREE_CODE (SSA_NAME_VAR (inner_lhs)) == RESULT_DECL)) lhs_free = true; ! if (lhs_free && (is_gimple_reg (rhs) || is_gimple_min_invariant (rhs))) rhs_free = true; if (lhs_free && rhs_free) return true; --- 1762,1771 ---- || (TREE_CODE (inner_lhs) == SSA_NAME && TREE_CODE (SSA_NAME_VAR (inner_lhs)) == RESULT_DECL)) lhs_free = true; ! if (lhs_free ! && (is_gimple_reg (rhs) ! || !is_gimple_reg_type (TREE_TYPE (rhs)) ! || is_gimple_min_invariant (rhs))) rhs_free = true; if (lhs_free && rhs_free) return true;