[llvm] Promote pseudo opcodes from 32-bit to 64-bit for instructions that infer extsw elimination in PPCMIPeepholes pass (PR #85451)
Lei Huang via llvm-commits
llvm-commits at lists.llvm.org
Tue Oct 15 12:02:52 PDT 2024
================
@@ -5234,6 +5234,218 @@ bool PPCInstrInfo::isTOCSaveMI(const MachineInstr &MI) const {
// We limit the max depth to track incoming values of PHIs or binary ops
// (e.g. AND) to avoid excessive cost.
const unsigned MAX_BINOP_DEPTH = 1;
+
+// This function will promote the instruction which defines the register `Reg`
+// in the parameter from a 32-bit to a 64-bit instruction if needed. The logic
+// used to check whether an instruction needs to be promoted or not is similar
+// to the logic used to check whether or not a defined register is sign or zero
+// extended within the function PPCInstrInfo::isSignOrZeroExtended.
+// Additionally, the `promoteInstr32To64ForElimEXTSW` function is recursive.
+// BinOpDepth does not count all of the recursions. The parameter BinOpDepth is
+// incremented only when `promoteInstr32To64ForElimEXTSW` calls itself more
+// than once. This is done to prevent exponential recursion.
+void PPCInstrInfo::promoteInstr32To64ForElimEXTSW(const Register &Reg,
+ MachineRegisterInfo *MRI,
+ unsigned BinOpDepth,
+ LiveVariables *LV) const {
+ if (!Reg.isVirtual())
+ return;
+
+ MachineInstr *MI = MRI->getVRegDef(Reg);
+ if (!MI)
+ return;
+
+ unsigned Opcode = MI->getOpcode();
+ bool IsNonSignedExtInstrNeedPromoted = false;
+ int NewOpcode = -1;
+
+#define MapOpCode(A) \
+ case A: \
+ NewOpcode = A##8; \
+ IsNonSignedExtInstrNeedPromoted = true; \
+ break
+
+ switch (Opcode) {
+ MapOpCode(PPC::OR);
+ MapOpCode(PPC::ISEL);
+ MapOpCode(PPC::ORI);
+ MapOpCode(PPC::XORI);
+ MapOpCode(PPC::ORIS);
+ MapOpCode(PPC::XORIS);
+ MapOpCode(PPC::AND);
+ }
+#undef MapOpCode
+
+ switch (Opcode) {
+ case PPC::OR:
+ case PPC::ISEL:
+ case PPC::OR8:
+ case PPC::PHI:
+ if (BinOpDepth < MAX_BINOP_DEPTH) {
+ unsigned OperandEnd = 3, OperandStride = 1;
+ if (Opcode == PPC::PHI) {
+ OperandEnd = MI->getNumOperands();
+ OperandStride = 2;
+ }
+
+ for (unsigned I = 1; I < OperandEnd; I += OperandStride) {
+ assert(MI->getOperand(I).isReg() && "Operand must be register");
+ Register SrcReg = MI->getOperand(I).getReg();
+ promoteInstr32To64ForElimEXTSW(SrcReg, MRI, BinOpDepth + 1, LV);
+ }
+ }
+ break;
+ case PPC::COPY: {
+ // Refers to the logic of the `case PPC::COPY` statement in the function
+ // PPCInstrInfo::isSignOrZeroExtended().
+
+ Register SrcReg = MI->getOperand(1).getReg();
+ // In both ELFv1 and v2 ABI, method parameters and the return value
+ // are sign- or zero-extended.
+ const MachineFunction *MF = MI->getMF();
+ if (!MF->getSubtarget<PPCSubtarget>().isSVR4ABI()) {
+ // If this is a copy from another register, we recursively promote the
+ // source.
+ promoteInstr32To64ForElimEXTSW(SrcReg, MRI, BinOpDepth, LV);
+ return;
+ }
+
+ // From here on everything is SVR4ABI. COPY will be eliminated in the other
+ // pass, we do not need promote the COPY pseudo opcode.
+
+ if (SrcReg != PPC::X3)
+ // If this is a copy from another register, we recursively promote the
+ // source.
+ promoteInstr32To64ForElimEXTSW(SrcReg, MRI, BinOpDepth, LV);
+ return;
+ }
+ case PPC::ORI:
+ case PPC::XORI:
+ case PPC::ORIS:
+ case PPC::XORIS:
+ case PPC::ORI8:
+ case PPC::XORI8:
+ case PPC::ORIS8:
+ case PPC::XORIS8: {
+ Register SrcReg = MI->getOperand(1).getReg();
+ promoteInstr32To64ForElimEXTSW(SrcReg, MRI, BinOpDepth, LV);
+ break;
+ }
+ case PPC::AND:
+ case PPC::AND8: {
+ if (BinOpDepth < MAX_BINOP_DEPTH) {
+ Register SrcReg1 = MI->getOperand(1).getReg();
+ promoteInstr32To64ForElimEXTSW(SrcReg1, MRI, BinOpDepth + 1, LV);
+ Register SrcReg2 = MI->getOperand(2).getReg();
+ promoteInstr32To64ForElimEXTSW(SrcReg2, MRI, BinOpDepth + 1, LV);
----------------
lei137 wrote:
tmp var `SrcReg[12]` is not needed. Prefer to inline it into the call.
https://github.com/llvm/llvm-project/pull/85451
More information about the llvm-commits
mailing list