@@ -5250,6 +5250,215 @@ bool PPCInstrInfo::isTOCSaveMI(const MachineInstr &MI) const {
52505250// We limit the max depth to track incoming values of PHIs or binary ops
52515251// (e.g. AND) to avoid excessive cost.
52525252const unsigned MAX_BINOP_DEPTH = 1 ;
5253+
5254+ // This function will promote the instruction which defines the register `Reg`
5255+ // in the parameter from a 32-bit to a 64-bit instruction if needed. The logic
5256+ // used to check whether an instruction needs to be promoted or not is similar
5257+ // to the logic used to check whether or not a defined register is sign or zero
5258+ // extended within the function PPCInstrInfo::isSignOrZeroExtended.
5259+ // Additionally, the `promoteInstr32To64ForElimEXTSW` function is recursive.
5260+ // BinOpDepth does not count all of the recursions. The parameter BinOpDepth is
5261+ // incremented only when `promoteInstr32To64ForElimEXTSW` calls itself more
5262+ // than once. This is done to prevent exponential recursion.
5263+ void PPCInstrInfo::promoteInstr32To64ForElimEXTSW (const Register &Reg,
5264+ MachineRegisterInfo *MRI,
5265+ unsigned BinOpDepth,
5266+ LiveVariables *LV) const {
5267+ if (!Reg.isVirtual ())
5268+ return ;
5269+
5270+ MachineInstr *MI = MRI->getVRegDef (Reg);
5271+ if (!MI)
5272+ return ;
5273+
5274+ unsigned Opcode = MI->getOpcode ();
5275+
5276+ switch (Opcode) {
5277+ case PPC::OR:
5278+ case PPC::ISEL:
5279+ case PPC::OR8:
5280+ case PPC::PHI: {
5281+ if (BinOpDepth >= MAX_BINOP_DEPTH)
5282+ break ;
5283+ unsigned OperandEnd = 3 , OperandStride = 1 ;
5284+ if (Opcode == PPC::PHI) {
5285+ OperandEnd = MI->getNumOperands ();
5286+ OperandStride = 2 ;
5287+ }
5288+
5289+ for (unsigned I = 1 ; I < OperandEnd; I += OperandStride) {
5290+ assert (MI->getOperand (I).isReg () && " Operand must be register" );
5291+ promoteInstr32To64ForElimEXTSW (MI->getOperand (I).getReg (), MRI,
5292+ BinOpDepth + 1 , LV);
5293+ }
5294+
5295+ break ;
5296+ }
5297+ case PPC::COPY: {
5298+ // Refers to the logic of the `case PPC::COPY` statement in the function
5299+ // PPCInstrInfo::isSignOrZeroExtended().
5300+
5301+ Register SrcReg = MI->getOperand (1 ).getReg ();
5302+ // In both ELFv1 and v2 ABI, method parameters and the return value
5303+ // are sign- or zero-extended.
5304+ const MachineFunction *MF = MI->getMF ();
5305+ if (!MF->getSubtarget <PPCSubtarget>().isSVR4ABI ()) {
5306+ // If this is a copy from another register, we recursively promote the
5307+ // source.
5308+ promoteInstr32To64ForElimEXTSW (SrcReg, MRI, BinOpDepth, LV);
5309+ return ;
5310+ }
5311+
5312+ // From here on everything is SVR4ABI. COPY will be eliminated in the other
5313+ // pass, we do not need promote the COPY pseudo opcode.
5314+
5315+ if (SrcReg != PPC::X3)
5316+ // If this is a copy from another register, we recursively promote the
5317+ // source.
5318+ promoteInstr32To64ForElimEXTSW (SrcReg, MRI, BinOpDepth, LV);
5319+ return ;
5320+ }
5321+ case PPC::ORI:
5322+ case PPC::XORI:
5323+ case PPC::ORIS:
5324+ case PPC::XORIS:
5325+ case PPC::ORI8:
5326+ case PPC::XORI8:
5327+ case PPC::ORIS8:
5328+ case PPC::XORIS8:
5329+ promoteInstr32To64ForElimEXTSW (MI->getOperand (1 ).getReg (), MRI, BinOpDepth,
5330+ LV);
5331+ break ;
5332+ case PPC::AND:
5333+ case PPC::AND8:
5334+ if (BinOpDepth >= MAX_BINOP_DEPTH)
5335+ break ;
5336+
5337+ promoteInstr32To64ForElimEXTSW (MI->getOperand (1 ).getReg (), MRI,
5338+ BinOpDepth + 1 , LV);
5339+ promoteInstr32To64ForElimEXTSW (MI->getOperand (2 ).getReg (), MRI,
5340+ BinOpDepth + 1 , LV);
5341+ break ;
5342+ }
5343+
5344+ const TargetRegisterClass *RC = MRI->getRegClass (Reg);
5345+ if (RC == &PPC::G8RCRegClass || RC == &PPC::G8RC_and_G8RC_NOX0RegClass)
5346+ return ;
5347+
5348+ const PPCInstrInfo *TII =
5349+ MI->getMF ()->getSubtarget <PPCSubtarget>().getInstrInfo ();
5350+
5351+ // Map the 32bit to 64bit opcodes for instructions that are not signed or zero
5352+ // extended themselves, but may have operands who's destination registers of
5353+ // signed or zero extended instructions.
5354+ std::unordered_map<unsigned , unsigned > OpcodeMap = {
5355+ {PPC::OR, PPC::OR8}, {PPC::ISEL, PPC::ISEL8},
5356+ {PPC::ORI, PPC::ORI8}, {PPC::XORI, PPC::XORI8},
5357+ {PPC::ORIS, PPC::ORIS8}, {PPC::XORIS, PPC::XORIS8},
5358+ {PPC::AND, PPC::AND8}};
5359+
5360+ int NewOpcode = -1 ;
5361+ auto It = OpcodeMap.find (Opcode);
5362+ if (It != OpcodeMap.end ()) {
5363+ // Set the new opcode to the mapped 64-bit version.
5364+ NewOpcode = It->second ;
5365+ } else {
5366+ if (!TII->isSExt32To64 (Opcode))
5367+ return ;
5368+
5369+ // The TableGen function `get64BitInstrFromSignedExt32BitInstr` is used to
5370+ // map the 32-bit instruction with the `SExt32To64` flag to the 64-bit
5371+ // instruction with the same opcode.
5372+ NewOpcode = PPC::get64BitInstrFromSignedExt32BitInstr (Opcode);
5373+ }
5374+
5375+ assert (NewOpcode != -1 &&
5376+ " Must have a 64-bit opcode to map the 32-bit opcode!" );
5377+
5378+ const TargetRegisterInfo *TRI = MRI->getTargetRegisterInfo ();
5379+ const MCInstrDesc &MCID = TII->get (NewOpcode);
5380+ const TargetRegisterClass *NewRC =
5381+ TRI->getRegClass (MCID.operands ()[0 ].RegClass );
5382+
5383+ Register SrcReg = MI->getOperand (0 ).getReg ();
5384+ const TargetRegisterClass *SrcRC = MRI->getRegClass (SrcReg);
5385+
5386+ // If the register class of the defined register in the 32-bit instruction
5387+ // is the same as the register class of the defined register in the promoted
5388+ // 64-bit instruction, we do not need to promote the instruction.
5389+ if (NewRC == SrcRC)
5390+ return ;
5391+
5392+ DebugLoc DL = MI->getDebugLoc ();
5393+ auto MBB = MI->getParent ();
5394+
5395+ // Since the pseudo-opcode of the instruction is promoted from 32-bit to
5396+ // 64-bit, if the source reg class of the original instruction belongs to
5397+ // PPC::GRCRegClass or PPC::GPRC_and_GPRC_NOR0RegClass, we need to promote
5398+ // the operand to PPC::G8CRegClass or PPC::G8RC_and_G8RC_NOR0RegClass,
5399+ // respectively.
5400+ DenseMap<unsigned , Register> PromoteRegs;
5401+ for (unsigned i = 1 ; i < MI->getNumOperands (); i++) {
5402+ MachineOperand &Operand = MI->getOperand (i);
5403+ if (!Operand.isReg ())
5404+ continue ;
5405+
5406+ Register OperandReg = Operand.getReg ();
5407+ if (!OperandReg.isVirtual ())
5408+ continue ;
5409+
5410+ const TargetRegisterClass *NewUsedRegRC =
5411+ TRI->getRegClass (MCID.operands ()[i].RegClass );
5412+ const TargetRegisterClass *OrgRC = MRI->getRegClass (OperandReg);
5413+ if (NewUsedRegRC != OrgRC && (OrgRC == &PPC::GPRCRegClass ||
5414+ OrgRC == &PPC::GPRC_and_GPRC_NOR0RegClass)) {
5415+ // Promote the used 32-bit register to 64-bit register.
5416+ Register TmpReg = MRI->createVirtualRegister (NewUsedRegRC);
5417+ Register DstTmpReg = MRI->createVirtualRegister (NewUsedRegRC);
5418+ BuildMI (*MBB, MI, DL, TII->get (PPC::IMPLICIT_DEF), TmpReg);
5419+ BuildMI (*MBB, MI, DL, TII->get (PPC::INSERT_SUBREG), DstTmpReg)
5420+ .addReg (TmpReg)
5421+ .addReg (OperandReg)
5422+ .addImm (PPC::sub_32);
5423+ PromoteRegs[i] = DstTmpReg;
5424+ }
5425+ }
5426+
5427+ Register NewDefinedReg = MRI->createVirtualRegister (NewRC);
5428+
5429+ BuildMI (*MBB, MI, DL, TII->get (NewOpcode), NewDefinedReg);
5430+ MachineBasicBlock::instr_iterator Iter (MI);
5431+ --Iter;
5432+ MachineInstrBuilder MIBuilder (*Iter->getMF (), Iter);
5433+ for (unsigned i = 1 ; i < MI->getNumOperands (); i++) {
5434+ if (PromoteRegs.find (i) != PromoteRegs.end ())
5435+ MIBuilder.addReg (PromoteRegs[i], RegState::Kill);
5436+ else
5437+ Iter->addOperand (MI->getOperand (i));
5438+ }
5439+
5440+ for (unsigned i = 1 ; i < Iter->getNumOperands (); i++) {
5441+ MachineOperand &Operand = Iter->getOperand (i);
5442+ if (!Operand.isReg ())
5443+ continue ;
5444+ Register OperandReg = Operand.getReg ();
5445+ if (!OperandReg.isVirtual ())
5446+ continue ;
5447+ LV->recomputeForSingleDefVirtReg (OperandReg);
5448+ }
5449+
5450+ MI->eraseFromParent ();
5451+
5452+ // A defined register may be used by other instructions that are 32-bit.
5453+ // After the defined register is promoted to 64-bit for the promoted
5454+ // instruction, we need to demote the 64-bit defined register back to a
5455+ // 32-bit register
5456+ BuildMI (*MBB, ++Iter, DL, TII->get (PPC::COPY), SrcReg)
5457+ .addReg (NewDefinedReg, RegState::Kill, PPC::sub_32);
5458+ LV->recomputeForSingleDefVirtReg (NewDefinedReg);
5459+ return ;
5460+ }
5461+
52535462// The isSignOrZeroExtended function is recursive. The parameter BinOpDepth
52545463// does not count all of the recursions. The parameter BinOpDepth is incremented
52555464// only when isSignOrZeroExtended calls itself more than once. This is done to
0 commit comments