Message ID | 90583097-cd60-0152-66a5-e32d6830b776@microchip.com |
---|---|
State | New |
Headers | show |
On Thu, 24 Nov 2016, Pitchumani Sivanupandi wrote: > GCC inlines small functions if the code size after expansion is not excedded. > For test case (inline.c, avr-gcc -Os -S inline.c) code size become higher if > 'func2' is inlined. It happens because the CONVERT_EXPR/ NOP_EXPR are > considered > as zero cost expression. > > Few conversions will cost additional instructions. For targets like AVR > it will cost considerably as it's register size is just one byte. > > Attached the tentative patch that changes the CONVERT_EXPR/ NOP_EXPR cost > to 1 if the LHS is bigger than RHS and target's word_mode. > > Is this Ok? > > Would it be reasonable if cost evaluated as below instead of constant 1? > if (LHS PRECISION > RHS PRECISION) > cost = LHS_PRECISION / word_mode - 1 > else > cost = 0 > > Built GCC for native with bootstrap enabled. No issues. I believe a better check would be tree_nop_conversion_p (). Thus CASE_CONVERT: return tree_nop_conversion_p (type, TREE_TYPE (op0)) ? 0 : 1; note that + rhs_code = gimple_assign_rhs_code (stmt); + if ((rhs_code == NOP_EXPR) || (rhs_code == CONVERT_EXPR)) + { + cost += estimate_operator_cost (rhs_code, weights, + gimple_assign_lhs (stmt), + gimple_assign_rhs1 (stmt)); + } is super-ugly - please simply add the type of the expression as an additional argument (see gimple_expr_type (), but the type of the LHS would do as well). Note that doing this change might require some re-tuning of inliner params, but otherwise it's totally sensible. Thanks, Richard.
On 11/24/2016 03:58 AM, Pitchumani Sivanupandi wrote: > GCC inlines small functions if the code size after expansion is not > excedded. > For test case (inline.c, avr-gcc -Os -S inline.c) code size become > higher if > 'func2' is inlined. It happens because the CONVERT_EXPR/ NOP_EXPR are > considered > as zero cost expression. > > Few conversions will cost additional instructions. For targets like AVR > it will cost considerably as it's register size is just one byte. > > Attached the tentative patch that changes the CONVERT_EXPR/ NOP_EXPR cost > to 1 if the LHS is bigger than RHS and target's word_mode. > > Is this Ok? > > Would it be reasonable if cost evaluated as below instead of constant 1? > if (LHS PRECISION > RHS PRECISION) > cost = LHS_PRECISION / word_mode - 1 > else > cost = 0 > > Built GCC for native with bootstrap enabled. No issues. My high level worry here is that this introduces a target dependency into the early part of the tree optimization pipeline (the test against word_mode). I'd be more open to giving a cost to any widening conversion. That kind of change might have a wide reaching impact though. jeff
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index 6899d2a..dbb305d 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -3867,19 +3867,28 @@ estimate_move_cost (tree type, bool ARG_UNUSED (speed_p)) static int estimate_operator_cost (enum tree_code code, eni_weights *weights, - tree op1 ATTRIBUTE_UNUSED, tree op2) + tree op1, tree op2) { + unsigned int lhs_prec, rhs_prec; switch (code) { /* These are "free" conversions, or their presumed cost is folded into other operations. */ case RANGE_EXPR: - CASE_CONVERT: case COMPLEX_EXPR: case PAREN_EXPR: case VIEW_CONVERT_EXPR: return 0; - + CASE_CONVERT: + { + if (op1 && op2) { + lhs_prec = element_precision (TREE_TYPE (op1)); + rhs_prec = element_precision (TREE_TYPE (op2)); + if ((lhs_prec > rhs_prec) && (lhs_prec > word_mode)) + return 1; + } + return 0; + } /* Assign cost of 1 to usual operations. ??? We may consider mapping RTL costs to this. */ case COND_EXPR: @@ -4026,6 +4035,7 @@ estimate_num_insns (gimple *stmt, eni_weights *weights) { unsigned cost, i; enum gimple_code code = gimple_code (stmt); + enum tree_code rhs_code; tree lhs; tree rhs; @@ -4064,9 +4074,17 @@ estimate_num_insns (gimple *stmt, eni_weights *weights) if (gimple_assign_load_p (stmt)) cost += estimate_move_cost (TREE_TYPE (rhs), weights->time_based); - cost += estimate_operator_cost (gimple_assign_rhs_code (stmt), weights, + rhs_code = gimple_assign_rhs_code (stmt); + if ((rhs_code == NOP_EXPR) || (rhs_code == CONVERT_EXPR)) + { + cost += estimate_operator_cost (rhs_code, weights, + gimple_assign_lhs (stmt), + gimple_assign_rhs1 (stmt)); + } + else + cost += estimate_operator_cost (rhs_code, weights, gimple_assign_rhs1 (stmt), - get_gimple_rhs_class (gimple_assign_rhs_code (stmt)) + get_gimple_rhs_class (rhs_code) == GIMPLE_BINARY_RHS ? gimple_assign_rhs2 (stmt) : NULL); break;