From: Krzysztof Parzyszek Date: Thu, 25 Mar 2021 18:43:55 +0000 (-0500) Subject: [Hexagon] Limit virtual register reuse range in FI elimination X-Git-Tag: llvmorg-14-init~11243 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a5b7d38c579c3e9651bd611e4f92ca6eb0140c8a;p=platform%2Fupstream%2Fllvm.git [Hexagon] Limit virtual register reuse range in FI elimination --- diff --git a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp index db3fb93..6e55bc6 100644 --- a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp +++ b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp @@ -17,6 +17,7 @@ #include "HexagonSubtarget.h" #include "HexagonTargetMachine.h" #include "llvm/ADT/BitVector.h" +#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/STLExtras.h" #include "llvm/CodeGen/LiveIntervals.h" #include "llvm/CodeGen/LiveRegUnits.h" @@ -43,9 +44,14 @@ using namespace llvm; -static cl::opt FrameIndexSearchLimit( - "hexagon-frame-index-search-limit", cl::init(32), cl::Hidden, - cl::desc("Limit on instruction search in frame index elimination")); +static cl::opt FrameIndexSearchRange( + "hexagon-frame-index-search-range", cl::init(32), cl::Hidden, + cl::desc("Limit on instruction search range in frame index elimination")); + +static cl::opt FrameIndexReuseLimit( + "hexagon-frame-index-reuse-limit", cl::init(~0), cl::Hidden, + cl::desc("Limit on the number of reused registers in frame index " + "elimination")); HexagonRegisterInfo::HexagonRegisterInfo(unsigned HwMode) : HexagonGenRegisterInfo(Hexagon::R31, 0/*DwarfFlavor*/, 0/*EHFlavor*/, @@ -197,6 +203,7 @@ BitVector HexagonRegisterInfo::getReservedRegs(const MachineFunction &MF) void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, int SPAdj, unsigned FIOp, RegScavenger *RS) const { + static unsigned ReuseCount = 0; // // Hexagon_TODO: Do we need to enforce this for Hexagon? assert(SPAdj == 0 && "Unexpected"); @@ -274,35 +281,50 @@ void HexagonRegisterInfo::eliminateFrameIndex(MachineBasicBlock::iterator II, // Search backwards in the block for "Reg = A2_addi BP, RealOffset". // This will give us a chance to avoid creating a new register. Register ReuseBP; - unsigned SearchCount = 0, SearchLimit = FrameIndexSearchLimit; - bool PassedCall = false; - LiveRegUnits Defs(*this), Uses(*this); - for (auto I = std::next(II.getReverse()), E = MB.rend(); I != E; ++I) { - if (SearchCount == SearchLimit) + if (ReuseCount < FrameIndexReuseLimit) { + unsigned SearchCount = 0, SearchRange = FrameIndexSearchRange; + SmallSet SeenVRegs; + bool PassedCall = false; + LiveRegUnits Defs(*this), Uses(*this); + + for (auto I = std::next(II.getReverse()), E = MB.rend(); I != E; ++I) { + if (SearchCount == SearchRange) + break; + ++SearchCount; + const MachineInstr &BI = *I; + LiveRegUnits::accumulateUsedDefed(BI, Defs, Uses, this); + PassedCall |= BI.isCall(); + for (const MachineOperand &Op : BI.operands()) { + if (SeenVRegs.size() > 1) + break; + if (Op.isReg() && Op.getReg().isVirtual()) + SeenVRegs.insert(Op.getReg()); + } + if (BI.getOpcode() != Hexagon::A2_addi) + continue; + if (BI.getOperand(1).getReg() != BP) + continue; + const auto &Op2 = BI.getOperand(2); + if (!Op2.isImm() || Op2.getImm() != RealOffset) + continue; + + Register R = BI.getOperand(0).getReg(); + if (R.isPhysical()) { + if (Defs.available(R)) + ReuseBP = R; + } else if (R.isVirtual()) { + // Extending a range of a virtual register can be dangerous, + // since the scavenger will need to find a physical register + // for it. Avoid extending the range past a function call, + // and avoid overlapping it with another virtual register. + if (!PassedCall && SeenVRegs.size() <= 1) + ReuseBP = R; + } break; - ++SearchCount; - const MachineInstr &BI = *I; - LiveRegUnits::accumulateUsedDefed(BI, Defs, Uses, this); - PassedCall |= BI.isCall(); - - if (BI.getOpcode() != Hexagon::A2_addi) - continue; - if (BI.getOperand(1).getReg() != BP) - continue; - const auto &Op2 = BI.getOperand(2); - if (!Op2.isImm() || Op2.getImm() != RealOffset) - continue; - - Register R = BI.getOperand(0).getReg(); - if (R.isPhysical()) { - if (Defs.available(R)) - ReuseBP = R; - } else if (R.isVirtual()) { - if (!PassedCall) - ReuseBP = R; } - break; + if (ReuseBP) + ++ReuseCount; } auto &MRI = MF.getRegInfo();