[llvm] promote Pseduo Opcode from 32bit to 64bits after eliminating the `extsw` instruction in PPCMIPeepholes optimization (PR #85451)
Kamau Bridgeman via llvm-commits
llvm-commits at lists.llvm.org
Wed May 8 12:10:50 PDT 2024
================
@@ -5234,6 +5234,244 @@ 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;
+
+// The `PromoteInstr32To64ForEmliEXTSW` function is recursive. The parameter
+// BinOpDepth does not count all of the recursions. The parameter BinOpDepth is
+// incremented only when `PromoteInstr32To64ForEmliEXTSW` calls itself more
+// than once. This is done to prevent exponential recursion. The function will
+// promote the instruction which defines the register `Reg` in the parameter
+// from a 32-bit to a 64-bit instruction if needed. Additionally, all the used
+// and defined registers in the instruction may also need to be promoted from
+// 32-bit to 64-bit based on the promoted instruction description. If a used
+// register is promoted to 64-bit, the instruction which defines the promoted
+// register also needs to be promoted. After an instruction is promoted to 64
+// bits, the defined register of the promoted instruction is also 64-bit. A
+// defined register may be used by other instructions; in such cases,
+// we need to extract the 32-bit register used by other
+// non-promoted 32-bit instructions from the promoted 64-bit register.
+void PPCInstrInfo::PromoteInstr32To64ForEmliEXTSW(const Register &Reg,
+ MachineRegisterInfo *MRI,
+ unsigned BinOpDepth,
+ LiveVariables *LV) const {
+ MachineInstr *MI = MRI->getVRegDef(Reg);
+ if (!MI)
+ return;
+
+ unsigned Opcode = MI->getOpcode();
+ bool IsNonSignedExtInstrPromoted = false;
+ int NewOpcode = -1;
+
+ auto CheckAndSetNewOpcode = [&](int NewOpc) {
+ if (!IsNonSignedExtInstrPromoted) {
+ NewOpcode = NewOpc;
+ IsNonSignedExtInstrPromoted = true;
+ }
+ };
+
+ auto SetNewOpcode = [&](int NewOpc) {
+ NewOpcode = NewOpc;
+ IsNonSignedExtInstrPromoted = true;
+ };
+
+ switch (Opcode) {
+ case PPC::OR:
+ CheckAndSetNewOpcode(PPC::OR8);
+ [[fallthrough]];
+ case PPC::ISEL:
+ CheckAndSetNewOpcode(PPC::ISEL8);
+ [[fallthrough]];
+ 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();
+ PromoteInstr32To64ForEmliEXTSW(SrcReg, MRI, BinOpDepth + 1, LV);
+ }
+
+ if (!IsNonSignedExtInstrPromoted)
+ return;
+ }
+ break;
+ case PPC::COPY: {
+ Register SrcReg = MI->getOperand(1).getReg();
+ const MachineFunction *MF = MI->getMF();
+ if (!MF->getSubtarget<PPCSubtarget>().isSVR4ABI()) {
----------------
kamaub wrote:
We should copy the explanation comments for these conditions from `issignorzeroextended()` as well
https://github.com/llvm/llvm-project/pull/85451
More information about the llvm-commits
mailing list