I'm looking into a few cases where we're still getting the base/index
operand ordering wrong on PowerPC for an indexed load/store instruction,
even after the PTR_PLUS merge and fix for PR28690.  One of the cases I
observed was caused by reload picking r0 to use for the base reg opnd as a
result of spilling.  Since r0 is not a valid register for the base reg
position, we end up switching the order of the operands before emitting the
instruction which then causes the performance hit on Power6.  r0 is not a
valid BASE_REG_CLASS register, only INDEX_REG_CLASS, but the following
section of code from reload.c:find_reloads_address_1() dealing with
PLUS(REG REG) may try assigning the base reg opnd to the INDEX_REG class in
a couple situations.  This then allows r0 to be picked for the base reg
opnd.  Is this being done on purpose (going on assumption that operands are
commutative), such as to allow more opportunities for a successful
allocation with reduced spill?  If it's not wise for me to modify this
code, possibly due to effect on other architectures, what are some other
options (maybe introduce a new HONOR_BASE_INDEX_ORDER target macro)?

        else if (code0 == REG && code1 == REG)
          {
            if (REGNO_OK_FOR_INDEX_P (REGNO (op0))
                && regno_ok_for_base_p (REGNO (op1), mode, PLUS, REG))
              return 0;
            else if (REGNO_OK_FOR_INDEX_P (REGNO (op1))
                     && regno_ok_for_base_p (REGNO (op0), mode, PLUS, REG))
              return 0;
            else if (regno_ok_for_base_p (REGNO (op1), mode, PLUS, REG))
>>>>              find_reloads_address_1 (mode, orig_op0, 1, PLUS, SCRATCH,
                                      &XEXP (x, 0), opnum, type,
ind_levels,
                                      insn);
            else if (regno_ok_for_base_p (REGNO (op0), mode, PLUS, REG))
              find_reloads_address_1 (mode, orig_op1, 1, PLUS, SCRATCH,
                                      &XEXP (x, 1), opnum, type,
ind_levels,
                                      insn);
            else if (REGNO_OK_FOR_INDEX_P (REGNO (op1)))
              find_reloads_address_1 (mode, orig_op0, 0, PLUS, REG,
                                      &XEXP (x, 0), opnum, type,
ind_levels,
                                      insn);
            else if (REGNO_OK_FOR_INDEX_P (REGNO (op0)))
              find_reloads_address_1 (mode, orig_op1, 0, PLUS, REG,
                                      &XEXP (x, 1), opnum, type,
ind_levels,
                                      insn);
            else
              {
>>>>                find_reloads_address_1 (mode, orig_op0, 1, PLUS,
SCRATCH,
                                        &XEXP (x, 0), opnum, type,
ind_levels,
                                        insn);
                find_reloads_address_1 (mode, orig_op1, 0, PLUS, REG,
                                        &XEXP (x, 1), opnum, type,
ind_levels,
                                        insn);
              }
          }


I've also seen the same situation come up during register renaming
(regrename.c), but not too surprising since the code there says it's based
off find_reloads_address_1() and is coded similarly.


-Pat

Reply via email to