void HexagonGenMux::buildMaps(MachineBasicBlock &B, InstrIndexMap &I2X, DefUseInfoMap &DUM) { unsigned Index = 0; unsigned NR = HRI->getNumRegs(); BitVector Defs(NR), Uses(NR); for (MachineBasicBlock::iterator I = B.begin(), E = B.end(); I != E; ++I) { MachineInstr *MI = &*I; I2X.insert(std::make_pair(MI, Index)); Defs.reset(); Uses.reset(); getDefsUses(MI, Defs, Uses); DUM.insert(std::make_pair(Index, DefUseInfo(Defs, Uses))); Index++; } }
HexagonBlockRanges::RegToRangeMap HexagonBlockRanges::computeDeadMap( InstrIndexMap &IndexMap, RegToRangeMap &LiveMap) { RegToRangeMap DeadMap; auto addDeadRanges = [&IndexMap,&LiveMap,&DeadMap] (RegisterRef R) -> void { auto F = LiveMap.find(R); if (F == LiveMap.end() || F->second.empty()) { DeadMap[R].add(IndexType::Entry, IndexType::Exit, false, false); return; } RangeList &RL = F->second; RangeList::iterator A = RL.begin(), Z = RL.end()-1; // Try to create the initial range. if (A->start() != IndexType::Entry) { IndexType DE = IndexMap.getPrevIndex(A->start()); if (DE != IndexType::Entry) DeadMap[R].add(IndexType::Entry, DE, false, false); } while (A != Z) { // Creating a dead range that follows A. Pay attention to empty // ranges (i.e. those ending with "None"). IndexType AE = (A->end() == IndexType::None) ? A->start() : A->end(); IndexType DS = IndexMap.getNextIndex(AE); ++A; IndexType DE = IndexMap.getPrevIndex(A->start()); if (DS < DE) DeadMap[R].add(DS, DE, false, false); } // Try to create the final range. if (Z->end() != IndexType::Exit) { IndexType ZE = (Z->end() == IndexType::None) ? Z->start() : Z->end(); IndexType DS = IndexMap.getNextIndex(ZE); if (DS < IndexType::Exit) DeadMap[R].add(DS, IndexType::Exit, false, false); } }; MachineFunction &MF = *IndexMap.getBlock().getParent(); auto &MRI = MF.getRegInfo(); unsigned NumRegs = TRI.getNumRegs(); BitVector Visited(NumRegs); for (unsigned R = 1; R < NumRegs; ++R) { for (auto S : expandToSubRegs({R,0}, MRI, TRI)) { if (Reserved[S.Reg] || Visited[S.Reg]) continue; addDeadRanges(S); Visited[S.Reg] = true; } } for (auto &P : LiveMap) if (TargetRegisterInfo::isVirtualRegister(P.first.Reg)) addDeadRanges(P.first); LLVM_DEBUG(dbgs() << __func__ << ": dead map\n" << PrintRangeMap(DeadMap, TRI) << '\n'); return DeadMap; }
void HexagonBlockRanges::computeInitialLiveRanges(InstrIndexMap &IndexMap, RegToRangeMap &LiveMap) { std::map<RegisterRef,IndexType> LastDef, LastUse; RegisterSet LiveOnEntry; MachineBasicBlock &B = IndexMap.getBlock(); MachineRegisterInfo &MRI = B.getParent()->getRegInfo(); for (auto R : getLiveIns(B, MRI, TRI)) LiveOnEntry.insert(R); for (auto R : LiveOnEntry) LastDef[R] = IndexType::Entry; auto closeRange = [&LastUse,&LastDef,&LiveMap] (RegisterRef R) -> void { auto LD = LastDef[R], LU = LastUse[R]; if (LD == IndexType::None) LD = IndexType::Entry; if (LU == IndexType::None) LU = IndexType::Exit; LiveMap[R].add(LD, LU, false, false); LastUse[R] = LastDef[R] = IndexType::None; }; RegisterSet Defs, Clobbers; for (auto &In : B) { if (In.isDebugInstr()) continue; IndexType Index = IndexMap.getIndex(&In); // Process uses first. for (auto &Op : In.operands()) { if (!Op.isReg() || !Op.isUse() || Op.isUndef()) continue; RegisterRef R = { Op.getReg(), Op.getSubReg() }; if (TargetRegisterInfo::isPhysicalRegister(R.Reg) && Reserved[R.Reg]) continue; bool IsKill = Op.isKill(); for (auto S : expandToSubRegs(R, MRI, TRI)) { LastUse[S] = Index; if (IsKill) closeRange(S); } } // 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() }; for (auto S : expandToSubRegs(R, MRI, TRI)) { 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. // dead %d0 = COPY %5, implicit-def %r0, implicit-def %r1 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. RegisterSet LiveOnExit; for (auto *SB : B.successors()) for (auto R : getLiveIns(*SB, MRI, TRI)) LiveOnExit.insert(R); for (auto R : LiveOnExit) LastUse[R] = IndexType::Exit; // Process remaining registers. RegisterSet Left; for (auto &I : LastUse) if (I.second != IndexType::None) Left.insert(I.first); for (auto &I : LastDef) if (I.second != IndexType::None) Left.insert(I.first); for (auto R : Left) closeRange(R); // Finalize the live ranges. for (auto &P : LiveMap) P.second.unionize(); }
void HexagonBlockRanges::computeInitialLiveRanges(InstrIndexMap &IndexMap, RegToRangeMap &LiveMap) { std::map<RegisterRef,IndexType> LastDef, LastUse; RegisterSet LiveOnEntry; MachineBasicBlock &B = IndexMap.getBlock(); MachineRegisterInfo &MRI = B.getParent()->getRegInfo(); for (auto R : getLiveIns(B)) for (auto S : expandToSubRegs(R, MRI, TRI)) LiveOnEntry.insert(S); for (auto R : LiveOnEntry) LastDef[R] = IndexType::Entry; auto closeRange = [&LastUse,&LastDef,&LiveMap] (RegisterRef R) -> void { auto LD = LastDef[R], LU = LastUse[R]; if (LD == IndexType::None) LD = IndexType::Entry; if (LU == IndexType::None) LU = IndexType::Exit; LiveMap[R].add(LD, LU, false, false); LastUse[R] = LastDef[R] = IndexType::None; }; for (auto &In : B) { if (In.isDebugValue()) continue; IndexType Index = IndexMap.getIndex(&In); // Process uses first. for (auto &Op : In.operands()) { if (!Op.isReg() || !Op.isUse() || Op.isUndef()) continue; RegisterRef R = { Op.getReg(), Op.getSubReg() }; if (TargetRegisterInfo::isPhysicalRegister(R.Reg) && Reserved[R.Reg]) continue; bool IsKill = Op.isKill(); for (auto S : expandToSubRegs(R, MRI, TRI)) { LastUse[S] = Index; if (IsKill) closeRange(S); } } // Process defs. 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; } } } // Collect live-on-exit. RegisterSet LiveOnExit; for (auto *SB : B.successors()) for (auto R : getLiveIns(*SB)) for (auto S : expandToSubRegs(R, MRI, TRI)) LiveOnExit.insert(S); for (auto R : LiveOnExit) LastUse[R] = IndexType::Exit; // Process remaining registers. RegisterSet Left; for (auto &I : LastUse) if (I.second != IndexType::None) Left.insert(I.first); for (auto &I : LastDef) if (I.second != IndexType::None) Left.insert(I.first); for (auto R : Left) closeRange(R); // Finalize the live ranges. for (auto &P : LiveMap) P.second.unionize(); }