@@ -5250,6 +5250,215 @@ bool PPCInstrInfo::isTOCSaveMI(const MachineInstr &MI) const {
5250
5250
// We limit the max depth to track incoming values of PHIs or binary ops
5251
5251
// (e.g. AND) to avoid excessive cost.
5252
5252
const 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
+
5253
5462
// The isSignOrZeroExtended function is recursive. The parameter BinOpDepth
5254
5463
// does not count all of the recursions. The parameter BinOpDepth is incremented
5255
5464
// only when isSignOrZeroExtended calls itself more than once. This is done to
0 commit comments