diff options
Diffstat (limited to 'lib/Target/Hexagon/HexagonBlockRanges.cpp')
-rw-r--r-- | lib/Target/Hexagon/HexagonBlockRanges.cpp | 77 |
1 files changed, 64 insertions, 13 deletions
diff --git a/lib/Target/Hexagon/HexagonBlockRanges.cpp b/lib/Target/Hexagon/HexagonBlockRanges.cpp index adc213c3d438..1640b40c164f 100644 --- a/lib/Target/Hexagon/HexagonBlockRanges.cpp +++ b/lib/Target/Hexagon/HexagonBlockRanges.cpp @@ -219,8 +219,7 @@ HexagonBlockRanges::HexagonBlockRanges(MachineFunction &mf) TII(*HST.getInstrInfo()), TRI(*HST.getRegisterInfo()), Reserved(TRI.getReservedRegs(mf)) { // Consider all non-allocatable registers as reserved. - for (auto I = TRI.regclass_begin(), E = TRI.regclass_end(); I != E; ++I) { - auto *RC = *I; + for (const TargetRegisterClass *RC : TRI.regclasses()) { if (RC->isAllocatable()) continue; for (unsigned R : *RC) @@ -233,14 +232,16 @@ HexagonBlockRanges::RegisterSet HexagonBlockRanges::getLiveIns( const TargetRegisterInfo &TRI) { RegisterSet LiveIns; RegisterSet Tmp; + for (auto I : B.liveins()) { - if (I.LaneMask.all()) { - Tmp.insert({I.PhysReg,0}); + MCSubRegIndexIterator S(I.PhysReg, &TRI); + if (I.LaneMask.all() || (I.LaneMask.any() && !S.isValid())) { + Tmp.insert({I.PhysReg, 0}); continue; } - for (MCSubRegIndexIterator S(I.PhysReg, &TRI); S.isValid(); ++S) { - LaneBitmask M = TRI.getSubRegIndexLaneMask(S.getSubRegIndex()); - if ((M & I.LaneMask).any()) + for (; S.isValid(); ++S) { + unsigned SI = S.getSubRegIndex(); + if ((I.LaneMask & TRI.getSubRegIndexLaneMask(SI)).any()) Tmp.insert({S.getSubReg(), 0}); } } @@ -307,6 +308,8 @@ void HexagonBlockRanges::computeInitialLiveRanges(InstrIndexMap &IndexMap, LastUse[R] = LastDef[R] = IndexType::None; }; + RegisterSet Defs, Clobbers; + for (auto &In : B) { if (In.isDebugValue()) continue; @@ -325,19 +328,67 @@ void HexagonBlockRanges::computeInitialLiveRanges(InstrIndexMap &IndexMap, closeRange(S); } } - // Process defs. + // Process defs and clobbers. + Defs.clear(); + Clobbers.clear(); for (auto &Op : In.operands()) { if (!Op.isReg() || !Op.isDef() || Op.isUndef()) continue; RegisterRef R = { Op.getReg(), Op.getSubReg() }; - if (TargetRegisterInfo::isPhysicalRegister(R.Reg) && Reserved[R.Reg]) - continue; for (auto S : expandToSubRegs(R, MRI, TRI)) { - if (LastDef[S] != IndexType::None || LastUse[S] != IndexType::None) - closeRange(S); - LastDef[S] = Index; + if (TargetRegisterInfo::isPhysicalRegister(S.Reg) && Reserved[S.Reg]) + continue; + if (Op.isDead()) + Clobbers.insert(S); + else + Defs.insert(S); + } + } + + for (auto &Op : In.operands()) { + if (!Op.isRegMask()) + continue; + const uint32_t *BM = Op.getRegMask(); + for (unsigned PR = 1, N = TRI.getNumRegs(); PR != N; ++PR) { + // Skip registers that have subregisters. A register is preserved + // iff its bit is set in the regmask, so if R1:0 was preserved, both + // R1 and R0 would also be present. + if (MCSubRegIterator(PR, &TRI, false).isValid()) + continue; + if (Reserved[PR]) + continue; + if (BM[PR/32] & (1u << (PR%32))) + continue; + RegisterRef R = { PR, 0 }; + if (!Defs.count(R)) + Clobbers.insert(R); } } + // Defs and clobbers can overlap, e.g. + // %D0<def,dead> = COPY %vreg5, %R0<imp-def>, %R1<imp-def> + for (RegisterRef R : Defs) + Clobbers.erase(R); + + // Update maps for defs. + for (RegisterRef S : Defs) { + // Defs should already be expanded into subregs. + assert(!TargetRegisterInfo::isPhysicalRegister(S.Reg) || + !MCSubRegIterator(S.Reg, &TRI, false).isValid()); + if (LastDef[S] != IndexType::None || LastUse[S] != IndexType::None) + closeRange(S); + LastDef[S] = Index; + } + // Update maps for clobbers. + for (RegisterRef S : Clobbers) { + // Clobbers should already be expanded into subregs. + assert(!TargetRegisterInfo::isPhysicalRegister(S.Reg) || + !MCSubRegIterator(S.Reg, &TRI, false).isValid()); + if (LastDef[S] != IndexType::None || LastUse[S] != IndexType::None) + closeRange(S); + // Create a single-instruction range. + LastDef[S] = LastUse[S] = Index; + closeRange(S); + } } // Collect live-on-exit. |