From df4b763be5897a315751cd071953e11c7d28a175 Mon Sep 17 00:00:00 2001 From: Chris Bieneman Date: Wed, 16 Jul 2014 20:13:31 +0000 Subject: [PATCH] [RegisterCoalescer] Moving the RegisterCoalescer subtarget hook onto the TargetRegisterInfo instead of the TargetSubtargetInfo. llvm-svn: 213188 --- llvm/include/llvm/Target/TargetRegisterInfo.h | 12 ++++++ llvm/include/llvm/Target/TargetSubtargetInfo.h | 9 ---- llvm/lib/CodeGen/RegisterCoalescer.cpp | 3 +- llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp | 59 ++++++++++++++++++++++++++ llvm/lib/Target/ARM/ARMBaseRegisterInfo.h | 8 ++++ llvm/lib/Target/ARM/ARMSubtarget.cpp | 57 ------------------------- llvm/lib/Target/ARM/ARMSubtarget.h | 7 --- 7 files changed, 80 insertions(+), 75 deletions(-) diff --git a/llvm/include/llvm/Target/TargetRegisterInfo.h b/llvm/include/llvm/Target/TargetRegisterInfo.h index c6f3fbf..5dda8bd 100644 --- a/llvm/include/llvm/Target/TargetRegisterInfo.h +++ b/llvm/include/llvm/Target/TargetRegisterInfo.h @@ -808,6 +808,18 @@ public: RegScavenger *RS = nullptr) const = 0; //===--------------------------------------------------------------------===// + /// Subtarget Hooks + + /// \brief SrcRC and DstRC will be morphed into NewRC if this returns true. + virtual bool shouldCoalesce(MachineInstr *MI, + const TargetRegisterClass *SrcRC, + unsigned SubReg, + const TargetRegisterClass *DstRC, + unsigned DstSubReg, + const TargetRegisterClass *NewRC) const + { return true; } + + //===--------------------------------------------------------------------===// /// Debug information queries. /// getFrameRegister - This method should return the register used as a base diff --git a/llvm/include/llvm/Target/TargetSubtargetInfo.h b/llvm/include/llvm/Target/TargetSubtargetInfo.h index 7808f4d..86e303e 100644 --- a/llvm/include/llvm/Target/TargetSubtargetInfo.h +++ b/llvm/include/llvm/Target/TargetSubtargetInfo.h @@ -126,15 +126,6 @@ public: /// \brief Reset the features for the subtarget. virtual void resetSubtargetFeatures(const MachineFunction *MF) { } - /// \brief SrcRC and DstRC will be morphed into NewRC if this returns true. - virtual bool shouldCoalesce(MachineInstr *MI, - const TargetRegisterClass *SrcRC, - unsigned SubReg, - const TargetRegisterClass *DstRC, - unsigned DstSubReg, - const TargetRegisterClass *NewRC) const - { return true; } - }; } // End llvm namespace diff --git a/llvm/lib/CodeGen/RegisterCoalescer.cpp b/llvm/lib/CodeGen/RegisterCoalescer.cpp index 0bda4c7..e04a3cf 100644 --- a/llvm/lib/CodeGen/RegisterCoalescer.cpp +++ b/llvm/lib/CodeGen/RegisterCoalescer.cpp @@ -1038,7 +1038,6 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) { } if (CP.getNewRC()) { - const TargetSubtargetInfo &ST = TM->getSubtarget(); auto SrcRC = MRI->getRegClass(CP.getSrcReg()); auto DstRC = MRI->getRegClass(CP.getDstReg()); unsigned SrcIdx = CP.getSrcIdx(); @@ -1047,7 +1046,7 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) { std::swap(SrcIdx, DstIdx); std::swap(SrcRC, DstRC); } - if (!ST.shouldCoalesce(CopyMI, SrcRC, SrcIdx, DstRC, DstIdx, + if (!TRI->shouldCoalesce(CopyMI, SrcRC, SrcIdx, DstRC, DstIdx, CP.getNewRC())) { DEBUG(dbgs() << "\tSubtarget bailed on coalescing.\n"); return false; diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp index cdd91c7..32b5f4a 100644 --- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp +++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp @@ -38,6 +38,8 @@ #include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetOptions.h" +#define DEBUG_TYPE "arm-register-info" + #define GET_REGINFO_TARGET_DESC #include "ARMGenRegisterInfo.inc" @@ -775,3 +777,60 @@ ARMBaseRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, MI.getOperand(FIOperandNum).ChangeToRegister(ScratchReg, false, false,true); } } + +bool ARMBaseRegisterInfo::shouldCoalesce(MachineInstr *MI, + const TargetRegisterClass *SrcRC, + unsigned SubReg, + const TargetRegisterClass *DstRC, + unsigned DstSubReg, + const TargetRegisterClass *NewRC) const { + auto MBB = MI->getParent(); + auto MF = MBB->getParent(); + const MachineRegisterInfo &MRI = MF->getRegInfo(); + // If not copying into a sub-register this should be ok because we shouldn't + // need to split the reg. + if (!DstSubReg) + return true; + // Small registers don't frequently cause a problem, so we can coalesce them. + if (NewRC->getSize() < 32 && DstRC->getSize() < 32 && SrcRC->getSize() < 32) + return true; + + auto NewRCWeight = + MRI.getTargetRegisterInfo()->getRegClassWeight(NewRC); + auto SrcRCWeight = + MRI.getTargetRegisterInfo()->getRegClassWeight(SrcRC); + auto DstRCWeight = + MRI.getTargetRegisterInfo()->getRegClassWeight(DstRC); + // If the source register class is more expensive than the destination, the + // coalescing is probably profitable. + if (SrcRCWeight.RegWeight > NewRCWeight.RegWeight) + return true; + if (DstRCWeight.RegWeight > NewRCWeight.RegWeight) + return true; + + // If the register allocator isn't constrained, we can always allow coalescing + // unfortunately we don't know yet if we will be constrained. + // The goal of this heuristic is to restrict how many expensive registers + // we allow to coalesce in a given basic block. + auto AFI = MF->getInfo(); + auto It = AFI->getCoalescedWeight(MBB); + + DEBUG(dbgs() << "\tARM::shouldCoalesce - Coalesced Weight: " + << It->second << "\n"); + DEBUG(dbgs() << "\tARM::shouldCoalesce - Reg Weight: " + << NewRCWeight.RegWeight << "\n"); + + // This number is the largest round number that which meets the criteria: + // (1) addresses PR18825 + // (2) generates better code in some test cases (like vldm-shed-a9.ll) + // (3) Doesn't regress any test cases (in-tree, test-suite, and SPEC) + // In practice the SizeMultiplier will only factor in for straight line code + // that uses a lot of NEON vectors, which isn't terribly common. + unsigned SizeMultiplier = MBB->size()/100; + SizeMultiplier = SizeMultiplier ? SizeMultiplier : 1; + if (It->second < NewRCWeight.WeightLimit * SizeMultiplier) { + It->second += NewRCWeight.RegWeight; + return true; + } + return false; +} diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h index 91df565..833d3f2 100644 --- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h +++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h @@ -187,6 +187,14 @@ public: void eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, unsigned FIOperandNum, RegScavenger *RS = nullptr) const override; + + /// \brief SrcRC and DstRC will be morphed into NewRC if this returns true + bool shouldCoalesce(MachineInstr *MI, + const TargetRegisterClass *SrcRC, + unsigned SubReg, + const TargetRegisterClass *DstRC, + unsigned DstSubReg, + const TargetRegisterClass *NewRC) const override; }; } // end namespace llvm diff --git a/llvm/lib/Target/ARM/ARMSubtarget.cpp b/llvm/lib/Target/ARM/ARMSubtarget.cpp index e605b86..c1b4562 100644 --- a/llvm/lib/Target/ARM/ARMSubtarget.cpp +++ b/llvm/lib/Target/ARM/ARMSubtarget.cpp @@ -438,60 +438,3 @@ bool ARMSubtarget::useMovt(const MachineFunction &MF) const { !MF.getFunction()->getAttributes().hasAttribute( AttributeSet::FunctionIndex, Attribute::MinSize)); } - -bool ARMSubtarget::shouldCoalesce(MachineInstr *MI, - const TargetRegisterClass *SrcRC, - unsigned SubReg, - const TargetRegisterClass *DstRC, - unsigned DstSubReg, - const TargetRegisterClass *NewRC) const { - auto MBB = MI->getParent(); - auto MF = MBB->getParent(); - const MachineRegisterInfo &MRI = MF->getRegInfo(); - // If not copying into a sub-register this should be ok because we shouldn't - // need to split the reg. - if (!DstSubReg) - return true; - // Small registers don't frequently cause a problem, so we can coalesce them. - if (NewRC->getSize() < 32 && DstRC->getSize() < 32 && SrcRC->getSize() < 32) - return true; - - auto NewRCWeight = - MRI.getTargetRegisterInfo()->getRegClassWeight(NewRC); - auto SrcRCWeight = - MRI.getTargetRegisterInfo()->getRegClassWeight(SrcRC); - auto DstRCWeight = - MRI.getTargetRegisterInfo()->getRegClassWeight(DstRC); - // If the source register class is more expensive than the destination, the - // coalescing is probably profitable. - if (SrcRCWeight.RegWeight > NewRCWeight.RegWeight) - return true; - if (DstRCWeight.RegWeight > NewRCWeight.RegWeight) - return true; - - // If the register allocator isn't constrained, we can always allow coalescing - // unfortunately we don't know yet if we will be constrained. - // The goal of this heuristic is to restrict how many expensive registers - // we allow to coalesce in a given basic block. - auto AFI = MF->getInfo(); - auto It = AFI->getCoalescedWeight(MBB); - - DEBUG(dbgs() << "\tARM::shouldCoalesce - Coalesced Weight: " - << It->second << "\n"); - DEBUG(dbgs() << "\tARM::shouldCoalesce - Reg Weight: " - << NewRCWeight.RegWeight << "\n"); - - // This number is the largest round number that which meets the criteria: - // (1) addresses PR18825 - // (2) generates better code in some test cases (like vldm-shed-a9.ll) - // (3) Doesn't regress any test cases (in-tree, test-suite, and SPEC) - // In practice the SizeMultiplier will only factor in for straight line code - // that uses a lot of NEON vectors, which isn't terribly common. - unsigned SizeMultiplier = MBB->size()/100; - SizeMultiplier = SizeMultiplier ? SizeMultiplier : 1; - if (It->second < NewRCWeight.WeightLimit * SizeMultiplier) { - It->second += NewRCWeight.RegWeight; - return true; - } - return false; -} diff --git a/llvm/lib/Target/ARM/ARMSubtarget.h b/llvm/lib/Target/ARM/ARMSubtarget.h index ffaff89..f8283b0 100644 --- a/llvm/lib/Target/ARM/ARMSubtarget.h +++ b/llvm/lib/Target/ARM/ARMSubtarget.h @@ -444,13 +444,6 @@ public: /// symbol. bool GVIsIndirectSymbol(const GlobalValue *GV, Reloc::Model RelocM) const; - /// \brief SrcRC and DstRC will be morphed into NewRC if this returns true - bool shouldCoalesce(MachineInstr *MI, - const TargetRegisterClass *SrcRC, - unsigned SubReg, - const TargetRegisterClass *DstRC, - unsigned DstSubReg, - const TargetRegisterClass *NewRC) const override; }; } // End llvm namespace -- 2.7.4