Skip to content

Commit

Permalink
[RegisterCoalescer] Moving the RegisterCoalescer subtarget hook onto …
Browse files Browse the repository at this point in the history
…the TargetRegisterInfo instead of the TargetSubtargetInfo.

llvm-svn: 213188
Chris Bieneman committed Jul 16, 2014
1 parent 2458bec commit df4b763
Showing 7 changed files with 80 additions and 75 deletions.
12 changes: 12 additions & 0 deletions llvm/include/llvm/Target/TargetRegisterInfo.h
Original file line number Diff line number Diff line change
@@ -807,6 +807,18 @@ class TargetRegisterInfo : public MCRegisterInfo {
int SPAdj, unsigned FIOperandNum,
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.

9 changes: 0 additions & 9 deletions llvm/include/llvm/Target/TargetSubtargetInfo.h
Original file line number Diff line number Diff line change
@@ -126,15 +126,6 @@ class TargetSubtargetInfo : public MCSubtargetInfo {
/// \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
3 changes: 1 addition & 2 deletions llvm/lib/CodeGen/RegisterCoalescer.cpp
Original file line number Diff line number Diff line change
@@ -1038,7 +1038,6 @@ bool RegisterCoalescer::joinCopy(MachineInstr *CopyMI, bool &Again) {
}

if (CP.getNewRC()) {
const TargetSubtargetInfo &ST = TM->getSubtarget<TargetSubtargetInfo>();
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;
59 changes: 59 additions & 0 deletions llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
Original file line number Diff line number Diff line change
@@ -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<ARMFunctionInfo>();
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;
}
8 changes: 8 additions & 0 deletions llvm/lib/Target/ARM/ARMBaseRegisterInfo.h
Original file line number Diff line number Diff line change
@@ -187,6 +187,14 @@ class ARMBaseRegisterInfo : public ARMGenRegisterInfo {
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
57 changes: 0 additions & 57 deletions llvm/lib/Target/ARM/ARMSubtarget.cpp
Original file line number Diff line number Diff line change
@@ -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<ARMFunctionInfo>();
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;
}
7 changes: 0 additions & 7 deletions llvm/lib/Target/ARM/ARMSubtarget.h
Original file line number Diff line number Diff line change
@@ -444,13 +444,6 @@ class ARMSubtarget : public ARMGenSubtargetInfo {
/// 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

0 comments on commit df4b763

Please sign in to comment.