@@ -5234,6 +5234,218 @@ bool PPCInstrInfo::isTOCSaveMI(const MachineInstr &MI) const {
52345234// We limit the max depth to track incoming values of PHIs or binary ops
52355235// (e.g. AND) to avoid excessive cost.
52365236const unsigned MAX_BINOP_DEPTH = 1 ;
5237+
5238+ void PPCInstrInfo::replaceInstrAfterElimExt32To64 (const Register &Reg,
5239+ MachineRegisterInfo *MRI,
5240+ unsigned BinOpDepth,
5241+ LiveVariables *LV) const {
5242+ MachineInstr *MI = MRI->getVRegDef (Reg);
5243+ if (!MI)
5244+ return ;
5245+
5246+ unsigned Opcode = MI->getOpcode ();
5247+ bool IsReplaceInstr = false ;
5248+ int NewOpcode = -1 ;
5249+
5250+ auto SetNewOpcode = [&](int NewOpc) {
5251+ if (!IsReplaceInstr) {
5252+ NewOpcode = NewOpc;
5253+ IsReplaceInstr = true ;
5254+ }
5255+ };
5256+
5257+ switch (Opcode) {
5258+ case PPC::OR:
5259+ SetNewOpcode (PPC::OR8);
5260+ [[fallthrough]];
5261+ case PPC::ISEL:
5262+ SetNewOpcode (PPC::ISEL8);
5263+ [[fallthrough]];
5264+ case PPC::OR8:
5265+ case PPC::PHI:
5266+ if (BinOpDepth < MAX_BINOP_DEPTH) {
5267+ unsigned OperandEnd = 3 , OperandStride = 1 ;
5268+ if (Opcode == PPC::PHI) {
5269+ OperandEnd = MI->getNumOperands ();
5270+ OperandStride = 2 ;
5271+ }
5272+
5273+ for (unsigned I = 1 ; I != OperandEnd; I += OperandStride) {
5274+ assert (MI->getOperand (I).isReg () && " Operand must be register" );
5275+ Register SrcReg = MI->getOperand (I).getReg ();
5276+ replaceInstrAfterElimExt32To64 (SrcReg, MRI, BinOpDepth + 1 , LV);
5277+ }
5278+
5279+ if (!IsReplaceInstr)
5280+ return ;
5281+ }
5282+ break ;
5283+ case PPC::COPY: {
5284+ Register SrcReg = MI->getOperand (1 ).getReg ();
5285+ const MachineFunction *MF = MI->getMF ();
5286+ if (!MF->getSubtarget <PPCSubtarget>().isSVR4ABI ()) {
5287+ replaceInstrAfterElimExt32To64 (SrcReg, MRI, BinOpDepth, LV);
5288+ return ;
5289+ }
5290+ // From here on everything is SVR4ABI
5291+ if (MI->getParent ()->getBasicBlock () == &MF->getFunction ().getEntryBlock ())
5292+ return ;
5293+
5294+ if (SrcReg != PPC::X3) {
5295+ replaceInstrAfterElimExt32To64 (SrcReg, MRI, BinOpDepth, LV);
5296+ return ;
5297+ }
5298+ }
5299+ return ;
5300+ case PPC::ORI:
5301+ SetNewOpcode (PPC::ORI8);
5302+ [[fallthrough]];
5303+ case PPC::XORI:
5304+ SetNewOpcode (PPC::XORI8);
5305+ [[fallthrough]];
5306+ case PPC::ORIS:
5307+ SetNewOpcode (PPC::ORIS8);
5308+ [[fallthrough]];
5309+ case PPC::XORIS:
5310+ SetNewOpcode (PPC::XORIS8);
5311+ [[fallthrough]];
5312+ case PPC::ORI8:
5313+ case PPC::XORI8:
5314+ case PPC::ORIS8:
5315+ case PPC::XORIS8: {
5316+ Register SrcReg = MI->getOperand (1 ).getReg ();
5317+ replaceInstrAfterElimExt32To64 (SrcReg, MRI, BinOpDepth, LV);
5318+
5319+ if (!IsReplaceInstr)
5320+ return ;
5321+ break ;
5322+ }
5323+ case PPC::AND:
5324+ SetNewOpcode (PPC::AND8);
5325+ [[fallthrough]];
5326+ case PPC::AND8: {
5327+ if (BinOpDepth < MAX_BINOP_DEPTH) {
5328+ Register SrcReg1 = MI->getOperand (1 ).getReg ();
5329+ replaceInstrAfterElimExt32To64 (SrcReg1, MRI, BinOpDepth, LV);
5330+ Register SrcReg2 = MI->getOperand (2 ).getReg ();
5331+ replaceInstrAfterElimExt32To64 (SrcReg2, MRI, BinOpDepth, LV);
5332+ if (!IsReplaceInstr)
5333+ return ;
5334+ }
5335+ break ;
5336+ }
5337+ case PPC::RLWINM:
5338+ SetNewOpcode (PPC::RLWINM8);
5339+ break ;
5340+ case PPC::RLWINM_rec:
5341+ SetNewOpcode (PPC::RLWINM8_rec);
5342+ break ;
5343+ case PPC::RLWNM:
5344+ SetNewOpcode (PPC ::RLWNM8);
5345+ break ;
5346+ case PPC::RLWNM_rec:
5347+ SetNewOpcode (PPC::RLWNM8_rec);
5348+ break ;
5349+ case PPC::ANDC_rec:
5350+ SetNewOpcode (PPC::ANDC8_rec);
5351+ break ;
5352+ case PPC::ANDIS_rec:
5353+ SetNewOpcode (PPC::ANDIS8_rec);
5354+ break ;
5355+ default :
5356+ break ;
5357+ }
5358+
5359+ const PPCInstrInfo *TII =
5360+ MI->getMF ()->getSubtarget <PPCSubtarget>().getInstrInfo ();
5361+ if ((definedBySignExtendingOp (Reg, MRI) && !TII->isZExt32To64 (Opcode) &&
5362+ !isOpZeroOfSubwordPreincLoad (Opcode)) ||
5363+ IsReplaceInstr) {
5364+
5365+ const TargetRegisterClass *RC = MRI->getRegClass (Reg);
5366+
5367+ if (RC == &PPC::G8RCRegClass || RC == &PPC::G8RC_and_G8RC_NOX0RegClass)
5368+ return ;
5369+
5370+ if (!IsReplaceInstr)
5371+ NewOpcode = PPC::get64BitInstrFromSignedExt32BitInstr (Opcode);
5372+
5373+ assert (NewOpcode != -1 &&
5374+ " Must have a 64-bit opcode to map the 32-bit opcode!" );
5375+
5376+ const TargetRegisterInfo *TRI = MRI->getTargetRegisterInfo ();
5377+ const MCInstrDesc &MCID = TII->get (NewOpcode);
5378+
5379+ Register SrcReg = MI->getOperand (0 ).getReg ();
5380+ const TargetRegisterClass *NewRC =
5381+ TRI->getRegClass (MCID.operands ()[0 ].RegClass );
5382+ const TargetRegisterClass *SrcRC = MRI->getRegClass (SrcReg);
5383+
5384+ if (NewRC == SrcRC)
5385+ return ;
5386+
5387+ DebugLoc DL = MI->getDebugLoc ();
5388+ auto MBB = MI->getParent ();
5389+
5390+ // Since the pseudo-opcode of the instruction is promoted from 32-bit to
5391+ // 64-bit, if the operand of the original instruction belongs to
5392+ // PPC::GRCRegClass or PPC::GPRC_and_GPRC_NOR0RegClass, we need to promote
5393+ // the operand to PPC::G8CRegClass or PPC::G8RC_and_G8RC_NOR0RegClass,
5394+ // respectively.
5395+ DenseMap<unsigned , Register> PromoteRegs;
5396+ DenseMap<unsigned , Register> ReCalRegs;
5397+ for (unsigned i = 1 ; i < MI->getNumOperands (); i++) {
5398+ MachineOperand &Operand = MI->getOperand (i);
5399+ if (Operand.isReg ()) {
5400+ Register OperandReg = Operand.getReg ();
5401+ if (!OperandReg.isVirtual ())
5402+ continue ;
5403+
5404+ const TargetRegisterClass *RC =
5405+ TRI->getRegClass (MCID.operands ()[i].RegClass );
5406+ const TargetRegisterClass *OrgRC = MRI->getRegClass (OperandReg);
5407+ if (RC != MRI->getRegClass (OperandReg) &&
5408+ (OrgRC == &PPC::GPRCRegClass ||
5409+ OrgRC == &PPC::GPRC_and_GPRC_NOR0RegClass)) {
5410+ Register TmpReg = MRI->createVirtualRegister (RC);
5411+ Register DstTmpReg = MRI->createVirtualRegister (RC);
5412+ BuildMI (*MBB, MI, DL, TII->get (PPC::IMPLICIT_DEF), TmpReg);
5413+ BuildMI (*MBB, MI, DL, TII->get (PPC::INSERT_SUBREG), DstTmpReg)
5414+ .addReg (TmpReg)
5415+ .addReg (OperandReg)
5416+ .addImm (PPC::sub_32);
5417+ PromoteRegs[i] = DstTmpReg;
5418+ ReCalRegs[i] = DstTmpReg;
5419+ } else {
5420+ ReCalRegs[i] = OperandReg;
5421+ }
5422+ }
5423+ }
5424+
5425+ Register NewReg = MRI->createVirtualRegister (NewRC);
5426+
5427+ BuildMI (*MBB, MI, DL, TII->get (NewOpcode), NewReg);
5428+ MachineBasicBlock::instr_iterator Iter (MI);
5429+ --Iter;
5430+ for (unsigned i = 1 ; i < MI->getNumOperands (); i++)
5431+ if (PromoteRegs.find (i) != PromoteRegs.end ())
5432+ MachineInstrBuilder (*Iter->getMF (), Iter)
5433+ .addReg (PromoteRegs[i], RegState::Kill);
5434+ else
5435+ Iter->addOperand (MI->getOperand (i));
5436+
5437+ for (auto Iter = ReCalRegs.begin (); Iter != ReCalRegs.end (); Iter++)
5438+ LV->recomputeForSingleDefVirtReg (Iter->second );
5439+ MI->eraseFromParent ();
5440+
5441+ BuildMI (*MBB, ++Iter, DL, TII->get (PPC::COPY), SrcReg)
5442+ .addReg (NewReg, RegState::Kill, PPC::sub_32);
5443+ LV->recomputeForSingleDefVirtReg (NewReg);
5444+ return ;
5445+ }
5446+ return ;
5447+ }
5448+
52375449// The isSignOrZeroExtended function is recursive. The parameter BinOpDepth
52385450// does not count all of the recursions. The parameter BinOpDepth is incremented
52395451// only when isSignOrZeroExtended calls itself more than once. This is done to
0 commit comments