diff options
author | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2018-07-13 23:42:29 +0000 |
---|---|---|
committer | Krzysztof Parzyszek <kparzysz@codeaurora.org> | 2018-07-13 23:42:29 +0000 |
commit | 7ced04c0fdf3cf524c877c37562eded5da4084d6 (patch) | |
tree | 7e227cc174b3382b31fde95824601354bea1e3b0 /llvm/lib/Target | |
parent | 9e25d5d2ce0e123b7a5c2e192420656b8336628c (diff) | |
download | bcm5719-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')
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp | 50 | ||||
-rw-r--r-- | llvm/lib/Target/Hexagon/HexagonRegisterInfo.h | 4 |
2 files changed, 54 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; } diff --git a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.h b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.h index ff60520d9ed..497dc45236b 100644 --- a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.h +++ b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.h @@ -63,6 +63,10 @@ public: return true; } + bool shouldCoalesce(MachineInstr *MI, const TargetRegisterClass *SrcRC, + unsigned SubReg, const TargetRegisterClass *DstRC, unsigned DstSubReg, + const TargetRegisterClass *NewRC, LiveIntervals &LIS) const override; + // Debug information queries. unsigned getRARegister() const; unsigned getFrameRegister(const MachineFunction &MF) const override; |