Message ID | 20200915011946.3395-6-amodra@gmail.com |
---|---|
State | New |
Headers | show |
Series | [RS6000] rs6000_rtx_costs multi-insn constants | expand |
On Tue, Sep 15, 2020 at 10:49:43AM +0930, Alan Modra wrote: > This small patch to rs6000_rtx_const considerably improves code (_costs) > generated for large constants in 64-bit code, teaching gcc that it is > better to load a constant from memory than to generate a sequence of > up to five dependent instructions. Note that the rs6000 backend does > generate large constants as loads from memory at expand time but > optimisation passes replace them with SETs of the value due to not > having correct costs. > > PR 94393 > * config/rs6000/rs6000.c (rs6000_rtx_costs): Cost multi-insn > constants. Okay for trunk. Note that some p10 insns take a floating point immediate, but those need to be handled specially anyway. Thanks! Segher
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 5b3c0ee0e8c..8c300b82b11 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -21181,7 +21181,9 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code, switch (code) { - /* On the RS/6000, if it is valid in the insn, it is free. */ + /* (reg) is costed at zero by rtlanal.c:rtx_cost. That sets a + baseline for rtx costs: If a constant is valid in an insn, + it is free. */ case CONST_INT: if (((outer_code == SET || outer_code == PLUS @@ -21242,6 +21244,17 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code, case CONST_DOUBLE: case CONST_WIDE_INT: + /* Subtract one insn here for consistency with the above code + that returns one less than the actual number of insns for + SETs. Don't subtract one for other than SETs, because other + operations will require the constant to be loaded to a + register before performing the operation. All special cases + for codes other than SET must be handled before we get + here. */ + *total = COSTS_N_INSNS (num_insns_constant (x, mode) + - (outer_code == SET ? 1 : 0)); + return true; + case CONST: case HIGH: case SYMBOL_REF: