@@ -565,6 +565,8 @@ bool PPCRegisterInfo::getRegAllocationHints(Register VirtReg,
565
565
const VirtRegMap *VRM,
566
566
const LiveRegMatrix *Matrix) const {
567
567
const MachineRegisterInfo *MRI = &MF.getRegInfo ();
568
+ const PPCSubtarget &Subtarget = MF.getSubtarget <PPCSubtarget>();
569
+ const TargetRegisterInfo *TRI = Subtarget.getRegisterInfo ();
568
570
569
571
// Call the base implementation first to set any hints based on the usual
570
572
// heuristics and decide what the return value should be. We want to return
@@ -582,15 +584,20 @@ bool PPCRegisterInfo::getRegAllocationHints(Register VirtReg,
582
584
if (MF.getSubtarget <PPCSubtarget>().isISAFuture ())
583
585
return BaseImplRetVal;
584
586
585
- // We are interested in instructions that copy values to ACC/UACC.
586
- // The copy into UACC will be simply a COPY to a subreg so we
587
- // want to allocate the corresponding physical subreg for the source.
588
- // The copy into ACC will be a BUILD_UACC so we want to allocate
589
- // the same number UACC for the source.
587
+ MachineBasicBlock *LastUseMBB = nullptr ;
588
+ bool UseInOneMBB = true ;
590
589
const TargetRegisterClass *RegClass = MRI->getRegClass (VirtReg);
591
590
for (MachineInstr &Use : MRI->reg_nodbg_instructions (VirtReg)) {
591
+ if (LastUseMBB && Use.getParent () != LastUseMBB)
592
+ UseInOneMBB = false ;
593
+ LastUseMBB = Use.getParent ();
592
594
const MachineOperand *ResultOp = nullptr ;
593
595
Register ResultReg;
596
+ // We are interested in instructions that copy values to ACC/UACC.
597
+ // The copy into UACC will be simply a COPY to a subreg so we
598
+ // want to allocate the corresponding physical subreg for the source.
599
+ // The copy into ACC will be a BUILD_UACC so we want to allocate
600
+ // the same number UACC for the source.
594
601
switch (Use.getOpcode ()) {
595
602
case TargetOpcode::COPY: {
596
603
ResultOp = &Use.getOperand (0 );
@@ -628,6 +635,46 @@ bool PPCRegisterInfo::getRegAllocationHints(Register VirtReg,
628
635
}
629
636
}
630
637
}
638
+
639
+ // In single MBB, allocate different CRs for different definitions can improve
640
+ // performance.
641
+ if (UseInOneMBB && LastUseMBB &&
642
+ (RegClass->hasSuperClassEq (&PPC::CRRCRegClass) ||
643
+ RegClass->hasSuperClassEq (&PPC::CRBITRCRegClass))) {
644
+ std::set<MCPhysReg> ModifiedRegisters;
645
+ bool Skip = true ;
646
+ // Scan from the last instruction writes VirtReg to the beginning of the
647
+ // MBB.
648
+ for (MachineInstr &MI :
649
+ llvm::make_range (LastUseMBB->rbegin (), LastUseMBB->rend ())) {
650
+ if (MI.isDebugInstr ())
651
+ continue ;
652
+ if (MI.modifiesRegister (VirtReg, TRI))
653
+ Skip = false ;
654
+ if (Skip)
655
+ continue ;
656
+ for (MachineOperand &MO : MI.operands ()) {
657
+ if (!MO.isReg () || !MO.getReg () || !MO.getReg ().isVirtual () ||
658
+ !MO.isDef ())
659
+ continue ;
660
+ MCPhysReg PhysReg = VRM->getPhys (MO.getReg ());
661
+ if (PhysReg == VirtRegMap::NO_PHYS_REG)
662
+ continue ;
663
+ llvm::copy_if (
664
+ TRI->superregs_inclusive (PhysReg),
665
+ std::inserter (ModifiedRegisters, ModifiedRegisters.begin ()),
666
+ [&](MCPhysReg SR) { return PPC::CRRCRegClass.contains (SR); });
667
+ }
668
+ }
669
+ llvm::copy_if (llvm::make_range (Order.begin (), Order.end ()),
670
+ std::back_inserter (Hints), [&](MCPhysReg Reg) {
671
+ return llvm::all_of (TRI->superregs_inclusive (Reg),
672
+ [&](MCPhysReg SR) {
673
+ return !ModifiedRegisters.count (SR);
674
+ });
675
+ });
676
+ }
677
+
631
678
return BaseImplRetVal;
632
679
}
633
680
0 commit comments