summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/include/llvm/Target/TargetRegisterInfo.h12
-rw-r--r--llvm/include/llvm/Target/TargetSubtargetInfo.h9
-rw-r--r--llvm/lib/CodeGen/RegisterCoalescer.cpp3
-rw-r--r--llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp59
-rw-r--r--llvm/lib/Target/ARM/ARMBaseRegisterInfo.h8
-rw-r--r--llvm/lib/Target/ARM/ARMSubtarget.cpp57
-rw-r--r--llvm/lib/Target/ARM/ARMSubtarget.h7
7 files changed, 80 insertions, 75 deletions
diff --git a/llvm/include/llvm/Target/TargetRegisterInfo.h b/llvm/include/llvm/Target/TargetRegisterInfo.h
index c6f3fbf1c84..5dda8bd4b93 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 7808f4de57a..86e303e1834 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 0bda4c79987..e04a3cf077f 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<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;
diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index cdd91c7a703..32b5f4aa294 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<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;
+}
diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h
index 91df565a27d..833d3f21848 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 e605b86d7c9..c1b4562f411 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<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;
-}
diff --git a/llvm/lib/Target/ARM/ARMSubtarget.h b/llvm/lib/Target/ARM/ARMSubtarget.h
index ffaff89f04e..f8283b08d48 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
OpenPOWER on IntegriCloud