This patch is a simplification of the previous patch to adjust the rtx insn cost for prefixed instructions. Rather than making it a separate function with only one caller, I folded the code into rs6000_insn_cost.
You had asked for this to be a separate patch, so it is in this patch. The basic problem is if there is no explicit cost predicate, rs6000_insn_cost uses the instruction size to figure out how many instructions are present, and make the cost a fact on that. Since prefixed instructions are 12 bytes within GCC (to deal with the implicit NOP), if we did not do this change, the optimizers would try to save registers from prefixed loads because they thought the load was more expensive. Along with the other patches, I have done bootstraps on a little endian power8 system, and there were no regressions in the test suite. Can I check this into the trunk? 2019-10-08 Michael Meissner <meiss...@linux.ibm.com> * config/rs6000/rs6000.c (rs6000_insn_cost): Do not make prefixed instructions cost more because they are larger in size. Index: gcc/config/rs6000/rs6000.c =================================================================== --- gcc/config/rs6000/rs6000.c (revision 276715) +++ gcc/config/rs6000/rs6000.c (working copy) @@ -20972,14 +20972,38 @@ rs6000_insn_cost (rtx_insn *insn, bool s if (recog_memoized (insn) < 0) return 0; - if (!speed) - return get_attr_length (insn); + if (speed) + { + int cost = get_attr_cost (insn); + if (cost > 0) + return cost; + } - int cost = get_attr_cost (insn); - if (cost > 0) - return cost; + int cost; + int length = get_attr_length (insn); + int n = length / 4; + + /* 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. */ + if (length >= 12 && get_attr_prefixed (insn) == PREFIXED_YES) + { + /* Single prefixed instruction. */ + if (length == 12) + n = 1; + + /* A normal instruction and a prefixed instruction (16) or two back + to back prefixed instructions (20). */ + else if (length == 16 || length == 20) + n = 2; + + /* Guess for larger instruction sizes. */ + else + n = 2 + (length - 20) / 4; + } - int n = get_attr_length (insn) / 4; 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