Some of the cost functions in the PowerPC compiler uses the length of the instruction to factor in the costs. This patches adjusts this calculation so that prefixed instructions are treated as the same cost as non-prefixed instructions.
I forgot to mention in the previous patchs, all 10 of the patches have been bootstrapped on a little endian power8 system in progression, and there were no regressions. Once the previous patches have been checked in, can I check this patch into the trunk? 2019-08-14 Michael Meissner <meiss...@linux.ibm.com> * config/rs6000/rs6000.c (rs6000_num_insns): New function. (rs6000_insn_cost): Use rs6000_num_insns to treat prefixed load/store instructions with the same case as non-prefixed instructions. Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 274177) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -21369,7 +21369,43 @@ rs6000_debug_rtx_costs (rtx x, machine_mode mode, return ret; } +/* How many real instructions are generated for this insn? This is slightly + different from the length attribute, in that the length attribute counts the + number of bytes. With prefixed instructions, we don't want to count a + prefixed instruction (length 12 bytes including possible NOP) as taking 3 + instructions, but just one. */ + static int +rs6000_num_insns (rtx_insn *insn) +{ + /* Try to figure it out based on the length and whether there are prefixed + instructions. While prefixed instructions are only 8 bytes, we have to + use 12 as the size of the first prefixed instruction in case the + instruction needs to be aligned. Back to back prefixed instructions would + only take 20 bytes, since it is guaranteed that one of the prefixed + instructions does not need the alignment. */ + int length = get_attr_length (insn); + + if (length >= 12 && TARGET_PREFIXED_ADDR + && get_attr_prefixed (insn) == PREFIXED_YES) + { + /* Single prefixed instruction. */ + if (length == 12) + return 1; + + /* A normal instruction and a prefixed instruction (16) or two back + to back prefixed instructions (20). */ + if (length == 16 || length == 20) + return 2; + + /* Guess for larger instruction sizes. */ + return 2 + (length - 20) / 4; + } + + return length / 4; +} + +static int rs6000_insn_cost (rtx_insn *insn, bool speed) { if (recog_memoized (insn) < 0) @@ -21382,7 +21418,7 @@ rs6000_insn_cost (rtx_insn *insn, bool speed) if (cost > 0) return cost; - int n = get_attr_length (insn) / 4; + int n = rs6000_num_insns (insn); enum attr_type type = get_attr_type (insn); switch (type) -- Michael Meissner, IBM IBM, M/S 2506R, 550 King Street, Littleton, MA 01460-6245, USA email: meiss...@linux.ibm.com, phone: +1 (978) 899-4797