summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp
diff options
context:
space:
mode:
authorKrzysztof Parzyszek <kparzysz@codeaurora.org>2018-07-13 23:42:29 +0000
committerKrzysztof Parzyszek <kparzysz@codeaurora.org>2018-07-13 23:42:29 +0000
commit7ced04c0fdf3cf524c877c37562eded5da4084d6 (patch)
tree7e227cc174b3382b31fde95824601354bea1e3b0 /llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp
parent9e25d5d2ce0e123b7a5c2e192420656b8336628c (diff)
downloadbcm5719-llvm-7ced04c0fdf3cf524c877c37562eded5da4084d6.tar.gz
bcm5719-llvm-7ced04c0fdf3cf524c877c37562eded5da4084d6.zip
[Hexagon] Avoid introducing calls into coalesced range of HVX vector pairs
If an HVX vector register is to be coalesced into a vector pair, make sure that the vector pair will not have a function call in its live range, unless it already had one. All HVX vector registers are volatile, so any vector register live across a function call will have to be spilled. If a vector needs to be spilled, and it's coalesced into a vector pair then the whole pair will need to be spilled (even if only a part of it is live), taking extra stack space. llvm-svn: 337073
Diffstat (limited to 'llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp')
-rw-r--r--llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp50
1 files changed, 50 insertions, 0 deletions
diff --git a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp
index ca0c2d707e9..2e11f875c0f 100644
--- a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp
@@ -19,6 +19,7 @@
#include "HexagonTargetMachine.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
+#include "llvm/CodeGen/LiveIntervals.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
@@ -243,6 +244,55 @@ void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II,
}
+bool HexagonRegisterInfo::shouldCoalesce(MachineInstr *MI,
+ const TargetRegisterClass *SrcRC, unsigned SubReg,
+ const TargetRegisterClass *DstRC, unsigned DstSubReg,
+ const TargetRegisterClass *NewRC, LiveIntervals &LIS) const {
+ // Coalescing will extend the live interval of the destination register.
+ // If the destination register is a vector pair, avoid introducing function
+ // calls into the interval, since it could result in a spilling of a pair
+ // instead of a single vector.
+ MachineFunction &MF = *MI->getParent()->getParent();
+ const HexagonSubtarget &HST = MF.getSubtarget<HexagonSubtarget>();
+ if (!HST.useHVXOps() || NewRC->getID() != Hexagon::HvxWRRegClass.getID())
+ return true;
+ bool SmallSrc = SrcRC->getID() == Hexagon::HvxVRRegClass.getID();
+ bool SmallDst = DstRC->getID() == Hexagon::HvxVRRegClass.getID();
+ if (!SmallSrc && !SmallDst)
+ return true;
+
+ unsigned DstReg = MI->getOperand(0).getReg();
+ unsigned SrcReg = MI->getOperand(1).getReg();
+ const SlotIndexes &Indexes = *LIS.getSlotIndexes();
+ auto HasCall = [&Indexes] (const LiveInterval::Segment &S) {
+ for (SlotIndex I = S.start.getBaseIndex(), E = S.end.getBaseIndex();
+ I != E; I = I.getNextIndex()) {
+ if (const MachineInstr *MI = Indexes.getInstructionFromIndex(I))
+ if (MI->isCall())
+ return true;
+ }
+ return false;
+ };
+
+ if (SmallSrc == SmallDst) {
+ // Both must be true, because the case for both being false was
+ // checked earlier. Both registers will be coalesced into a register
+ // of a wider class (HvxWR), and we don't want its live range to
+ // span over calls.
+ return !any_of(LIS.getInterval(DstReg), HasCall) &&
+ !any_of(LIS.getInterval(SrcReg), HasCall);
+ }
+
+ // If one register is large (HvxWR) and the other is small (HvxVR), then
+ // coalescing is ok if the large is already live across a function call,
+ // or if the small one is not.
+ unsigned SmallReg = SmallSrc ? SrcReg : DstReg;
+ unsigned LargeReg = SmallSrc ? DstReg : SrcReg;
+ return any_of(LIS.getInterval(LargeReg), HasCall) ||
+ !any_of(LIS.getInterval(SmallReg), HasCall);
+}
+
+
unsigned HexagonRegisterInfo::getRARegister() const {
return Hexagon::R31;
}
OpenPOWER on IntegriCloud