Index: lib/CodeGen/LiveDebugValues.cpp =================================================================== --- lib/CodeGen/LiveDebugValues.cpp +++ lib/CodeGen/LiveDebugValues.cpp @@ -351,6 +351,43 @@ } }; + /// Map of VarLocs to a unique ID. Allows describing sets of variable + /// locations as a bitvector. + VarLocMap VarLocIDs; + + /// Tracks the set of currently-valid variable locations through the course + /// of processing one BB. + OpenRangesSet OpenRanges; + + /// For each BB, contains the set of valid variable locations at the end of + /// the BB. + VarLocInMBB OutLocs; + + /// For each BB, contains the set of valid variable locations at the first + /// instruction of the BB. + VarLocInMBB InLocs; + + /// DBG_VALUEs created in the course of moving variable locations within + /// blocks. Can be cause by register moves, spills and restores. + TransferMap Transfers; + + /// Ranges that are incoming after joining, but that we have deferred + /// creating DBG_VALUE insts for immediately. + VarLocInMBB PendingInLocs; + + /// A map from each Var/Fragment pair to a vector of fragments known to + /// overlap it. Pre-computed to allow location-propagation to quickly lookup + /// what other fragments are invalidated by a DBG_VALUE. + OverlapMap OverlapFragments; + + /// Map from DILocalVariable to all fragments of that Variable which are + /// known to exist. + VarToFragments SeenFragments; + + /// Working set of currently collected debug variables mapped to DBG_VALUEs + /// representing candidates for production of debug entry values. + DebugParamMap DebugEntryVals; + bool isSpillInstruction(const MachineInstr &MI, MachineFunction *MF, unsigned &Reg); /// If a given instruction is identified as a spill, return the spill location @@ -361,45 +398,28 @@ /// Given a spill instruction, extract the register and offset used to /// address the spill location in a target independent way. VarLoc::SpillLoc extractSpillBaseRegAndOffset(const MachineInstr &MI); - void insertTransferDebugPair(MachineInstr &MI, OpenRangesSet &OpenRanges, - TransferMap &Transfers, VarLocMap &VarLocIDs, - unsigned OldVarID, TransferKind Kind, - unsigned NewReg = 0); - - void transferDebugValue(const MachineInstr &MI, OpenRangesSet &OpenRanges, - VarLocMap &VarLocIDs); - void transferSpillOrRestoreInst(MachineInstr &MI, OpenRangesSet &OpenRanges, - VarLocMap &VarLocIDs, TransferMap &Transfers); - void emitEntryValues(MachineInstr &MI, OpenRangesSet &OpenRanges, - VarLocMap &VarLocIDs, TransferMap &Transfers, - DebugParamMap &DebugEntryVals, - SparseBitVector<> &KillSet); - void transferRegisterCopy(MachineInstr &MI, OpenRangesSet &OpenRanges, - VarLocMap &VarLocIDs, TransferMap &Transfers); - void transferRegisterDef(MachineInstr &MI, OpenRangesSet &OpenRanges, - VarLocMap &VarLocIDs, TransferMap &Transfers, - DebugParamMap &DebugEntryVals); - bool transferTerminator(MachineBasicBlock *MBB, OpenRangesSet &OpenRanges, - VarLocInMBB &OutLocs, const VarLocMap &VarLocIDs); - - void process(MachineInstr &MI, OpenRangesSet &OpenRanges, - VarLocInMBB &OutLocs, VarLocMap &VarLocIDs, - TransferMap &Transfers, DebugParamMap &DebugEntryVals, - bool transferChanges, OverlapMap &OverlapFragments, - VarToFragments &SeenFragments); - - void accumulateFragmentMap(MachineInstr &MI, VarToFragments &SeenFragments, - OverlapMap &OLapMap); + void insertTransferDebugPair(MachineInstr &MI, unsigned OldVarID, + TransferKind Kind, unsigned NewReg = 0); + + void transferDebugValue(const MachineInstr &MI); + void transferSpillOrRestoreInst(MachineInstr &MI); + void emitEntryValues(MachineInstr &MI, SparseBitVector<> &KillSet); + void transferRegisterCopy(MachineInstr &MI); + void transferRegisterDef(MachineInstr &MI); + bool transferTerminator(MachineBasicBlock *MBB, VarLocInMBB &OutLocs); + + void process(MachineInstr &MI, VarLocInMBB &OutLocs, bool transferChanges); + + void accumulateFragmentMap(MachineInstr &MI); bool join(MachineBasicBlock &MBB, VarLocInMBB &OutLocs, VarLocInMBB &InLocs, - const VarLocMap &VarLocIDs, SmallPtrSet &Visited, SmallPtrSetImpl &ArtificialBlocks, VarLocInMBB &PendingInLocs); /// Create DBG_VALUE insts for inlocs that have been propagated but /// had their instruction creation deferred. - void flushPendingLocs(VarLocInMBB &PendingInLocs, VarLocMap &VarLocIDs); + void flushPendingLocs(VarLocInMBB &PendingInLocs); bool ExtendRanges(MachineFunction &MF); @@ -420,8 +440,7 @@ /// Print to ostream with a message. void printVarLocInMBB(const MachineFunction &MF, const VarLocInMBB &V, - const VarLocMap &VarLocIDs, const char *msg, - raw_ostream &Out) const; + const char *msg, raw_ostream &Out) const; /// Calculate the liveness information for the given machine function. bool runOnMachineFunction(MachineFunction &MF) override; @@ -477,7 +496,8 @@ false, false) /// Default construct and initialize the pass. -LiveDebugValues::LiveDebugValues() : MachineFunctionPass(ID) { +LiveDebugValues::LiveDebugValues() + : MachineFunctionPass(ID), OpenRanges(OverlapFragments) { initializeLiveDebugValuesPass(*PassRegistry::getPassRegistry()); } @@ -527,9 +547,7 @@ #ifndef NDEBUG void LiveDebugValues::printVarLocInMBB(const MachineFunction &MF, - const VarLocInMBB &V, - const VarLocMap &VarLocIDs, - const char *msg, + const VarLocInMBB &V, const char *msg, raw_ostream &Out) const { Out << '\n' << msg << '\n'; for (const MachineBasicBlock &BB : MF) { @@ -565,9 +583,7 @@ /// End all previous ranges related to @MI and start a new range from @MI /// if it is a DBG_VALUE instr. -void LiveDebugValues::transferDebugValue(const MachineInstr &MI, - OpenRangesSet &OpenRanges, - VarLocMap &VarLocIDs) { +void LiveDebugValues::transferDebugValue(const MachineInstr &MI) { if (!MI.isDebugValue()) return; const DILocalVariable *Var = MI.getDebugVariable(); @@ -599,10 +615,6 @@ } void LiveDebugValues::emitEntryValues(MachineInstr &MI, - OpenRangesSet &OpenRanges, - VarLocMap &VarLocIDs, - TransferMap &Transfers, - DebugParamMap &DebugEntryVals, SparseBitVector<> &KillSet) { MachineFunction *MF = MI.getParent()->getParent(); for (unsigned ID : KillSet) { @@ -641,16 +653,16 @@ /// new VarLoc. If \p NewReg is different than default zero value then the /// new location will be register location created by the copy like instruction, /// otherwise it is variable's location on the stack. -void LiveDebugValues::insertTransferDebugPair( - MachineInstr &MI, OpenRangesSet &OpenRanges, TransferMap &Transfers, - VarLocMap &VarLocIDs, unsigned OldVarID, TransferKind Kind, - unsigned NewReg) { +void LiveDebugValues::insertTransferDebugPair(MachineInstr &MI, + unsigned OldVarID, + TransferKind Kind, + unsigned NewReg) { const MachineInstr *DebugInstr = &VarLocIDs[OldVarID].MI; MachineFunction *MF = MI.getParent()->getParent(); MachineInstr *NewDebugInstr; - auto ProcessVarLoc = [&MI, &OpenRanges, &Transfers, &DebugInstr, - &VarLocIDs](VarLoc &VL, MachineInstr *NewDebugInstr) { + auto ProcessVarLoc = [this, &MI, &DebugInstr](VarLoc &VL, + MachineInstr *NewDebugInstr) { unsigned LocId = VarLocIDs.insert(VL); // Close this variable's previous location range. @@ -728,9 +740,7 @@ } /// A definition of a register may mark the end of a range. -void LiveDebugValues::transferRegisterDef( - MachineInstr &MI, OpenRangesSet &OpenRanges, VarLocMap &VarLocIDs, - TransferMap &Transfers, DebugParamMap &DebugEntryVals) { +void LiveDebugValues::transferRegisterDef(MachineInstr &MI) { MachineFunction *MF = MI.getMF(); const TargetLowering *TLI = MF->getSubtarget().getTargetLowering(); unsigned SP = TLI->getStackPointerRegisterToSaveRestore(); @@ -764,8 +774,7 @@ if (auto *TPC = getAnalysisIfAvailable()) { auto &TM = TPC->getTM(); if (TM.Options.EnableDebugEntryValues) - emitEntryValues(MI, OpenRanges, VarLocIDs, Transfers, DebugEntryVals, - KillSet); + emitEntryValues(MI, KillSet); } } @@ -844,10 +853,7 @@ /// the DBG_VALUE without inserting it and keep track of it in \p Transfers. /// It will be inserted into the BB when we're done iterating over the /// instructions. -void LiveDebugValues::transferSpillOrRestoreInst(MachineInstr &MI, - OpenRangesSet &OpenRanges, - VarLocMap &VarLocIDs, - TransferMap &Transfers) { +void LiveDebugValues::transferSpillOrRestoreInst(MachineInstr &MI) { MachineFunction *MF = MI.getMF(); TransferKind TKind; unsigned Reg; @@ -880,8 +886,7 @@ << VarLocIDs[ID].Var.getVar()->getName() << ")\n"); } else continue; - insertTransferDebugPair(MI, OpenRanges, Transfers, VarLocIDs, ID, TKind, - Reg); + insertTransferDebugPair(MI, ID, TKind, Reg); return; } } @@ -889,10 +894,7 @@ /// If \p MI is a register copy instruction, that copies a previously tracked /// value from one register to another register that is callee saved, we /// create new DBG_VALUE instruction described with copy destination register. -void LiveDebugValues::transferRegisterCopy(MachineInstr &MI, - OpenRangesSet &OpenRanges, - VarLocMap &VarLocIDs, - TransferMap &Transfers) { +void LiveDebugValues::transferRegisterCopy(MachineInstr &MI) { const MachineOperand *SrcRegOp, *DestRegOp; if (!TII->isCopyInstr(MI, SrcRegOp, DestRegOp) || !SrcRegOp->isKill() || @@ -919,8 +921,7 @@ for (unsigned ID : OpenRanges.getVarLocs()) { if (VarLocIDs[ID].isDescribedByReg() == SrcReg) { - insertTransferDebugPair(MI, OpenRanges, Transfers, VarLocIDs, ID, - TransferKind::TransferCopy, DestReg); + insertTransferDebugPair(MI, ID, TransferKind::TransferCopy, DestReg); return; } } @@ -928,9 +929,7 @@ /// Terminate all open ranges at the end of the current basic block. bool LiveDebugValues::transferTerminator(MachineBasicBlock *CurMBB, - OpenRangesSet &OpenRanges, - VarLocInMBB &OutLocs, - const VarLocMap &VarLocIDs) { + VarLocInMBB &OutLocs) { bool Changed = false; if (OpenRanges.empty()) @@ -958,13 +957,7 @@ /// known-to-overlap fragments are present". /// \param MI A previously unprocessed DEBUG_VALUE instruction to analyze for /// fragment usage. -/// \param SeenFragments Map from DILocalVariable to all fragments of that -/// Variable which are known to exist. -/// \param OverlappingFragments The overlap map being constructed, from one -/// Var/Fragment pair to a vector of fragments known to overlap. -void LiveDebugValues::accumulateFragmentMap(MachineInstr &MI, - VarToFragments &SeenFragments, - OverlapMap &OverlappingFragments) { +void LiveDebugValues::accumulateFragmentMap(MachineInstr &MI) { DebugVariable MIVar(MI); FragmentInfo ThisFragment = MIVar.getFragmentDefault(); @@ -977,14 +970,14 @@ OneFragment.insert(ThisFragment); SeenFragments.insert({MIVar.getVar(), OneFragment}); - OverlappingFragments.insert({{MIVar.getVar(), ThisFragment}, {}}); + OverlapFragments.insert({{MIVar.getVar(), ThisFragment}, {}}); return; } // If this particular Variable/Fragment pair already exists in the overlap // map, it has already been accounted for. auto IsInOLapMap = - OverlappingFragments.insert({{MIVar.getVar(), ThisFragment}, {}}); + OverlapFragments.insert({{MIVar.getVar(), ThisFragment}, {}}); if (!IsInOLapMap.second) return; @@ -1002,8 +995,8 @@ // Mark the previously seen fragment as being overlapped by the current // one. auto ASeenFragmentsOverlaps = - OverlappingFragments.find({MIVar.getVar(), ASeenFragment}); - assert(ASeenFragmentsOverlaps != OverlappingFragments.end() && + OverlapFragments.find({MIVar.getVar(), ASeenFragment}); + assert(ASeenFragmentsOverlaps != OverlapFragments.end() && "Previously seen var fragment has no vector of overlaps"); ASeenFragmentsOverlaps->second.push_back(ThisFragment); } @@ -1013,22 +1006,17 @@ } /// This routine creates OpenRanges and OutLocs. -void LiveDebugValues::process(MachineInstr &MI, OpenRangesSet &OpenRanges, - VarLocInMBB &OutLocs, VarLocMap &VarLocIDs, - TransferMap &Transfers, DebugParamMap &DebugEntryVals, - bool transferChanges, - OverlapMap &OverlapFragments, - VarToFragments &SeenFragments) { - transferDebugValue(MI, OpenRanges, VarLocIDs); - transferRegisterDef(MI, OpenRanges, VarLocIDs, Transfers, - DebugEntryVals); +void LiveDebugValues::process(MachineInstr &MI, VarLocInMBB &OutLocs, + bool transferChanges) { + transferDebugValue(MI); + transferRegisterDef(MI); if (transferChanges) { - transferRegisterCopy(MI, OpenRanges, VarLocIDs, Transfers); - transferSpillOrRestoreInst(MI, OpenRanges, VarLocIDs, Transfers); + transferRegisterCopy(MI); + transferSpillOrRestoreInst(MI); } else { // Build up a map of overlapping fragments on the first run through. if (MI.isDebugValue()) - accumulateFragmentMap(MI, SeenFragments, OverlapFragments); + accumulateFragmentMap(MI); } } @@ -1037,7 +1025,6 @@ /// source variable in all the predecessors of @MBB reside in the same location. bool LiveDebugValues::join( MachineBasicBlock &MBB, VarLocInMBB &OutLocs, VarLocInMBB &InLocs, - const VarLocMap &VarLocIDs, SmallPtrSet &Visited, SmallPtrSetImpl &ArtificialBlocks, VarLocInMBB &PendingInLocs) { @@ -1133,8 +1120,7 @@ return Changed; } -void LiveDebugValues::flushPendingLocs(VarLocInMBB &PendingInLocs, - VarLocMap &VarLocIDs) { +void LiveDebugValues::flushPendingLocs(VarLocInMBB &PendingInLocs) { // PendingInLocs records all locations propagated into blocks, which have // not had DBG_VALUE insts created. Go through and create those insts now. for (auto &Iter : PendingInLocs) { @@ -1189,19 +1175,6 @@ bool OLChanged = false; bool MBBJoined = false; - VarLocMap VarLocIDs; // Map VarLoc<>unique ID for use in bitvectors. - OverlapMap OverlapFragments; // Map of overlapping variable fragments - OpenRangesSet OpenRanges(OverlapFragments); - // Ranges that are open until end of bb. - VarLocInMBB OutLocs; // Ranges that exist beyond bb. - VarLocInMBB InLocs; // Ranges that are incoming after joining. - TransferMap Transfers; // DBG_VALUEs associated with spills. - VarLocInMBB PendingInLocs; // Ranges that are incoming after joining, but - // that we have deferred creating DBG_VALUE insts - // for immediately. - - VarToFragments SeenFragments; - // Blocks which are artificial, i.e. blocks which exclusively contain // instructions without locations, or with line 0 locations. SmallPtrSet ArtificialBlocks; @@ -1233,10 +1206,6 @@ return Op.isReg() && Op.getReg() != SP && Op.getReg() != FP; }; - // Working set of currently collected debug variables mapped to DBG_VALUEs - // representing candidates for production of debug entry values. - DebugParamMap DebugEntryVals; - MachineBasicBlock &First_MBB = *(MF.begin()); // Only in the case of entry MBB collect DBG_VALUEs representing // function parameters in order to generate debug entry values for them. @@ -1261,10 +1230,9 @@ // within the BB in which the spill occurs. for (auto &MBB : MF) { for (auto &MI : MBB) { - process(MI, OpenRanges, OutLocs, VarLocIDs, Transfers, DebugEntryVals, - dontTransferChanges, OverlapFragments, SeenFragments); + process(MI, OutLocs, dontTransferChanges); } - transferTerminator(&MBB, OpenRanges, OutLocs, VarLocIDs); + transferTerminator(&MBB, OutLocs); // Add any entry DBG_VALUE instructions necessitated by parameter // clobbering. for (auto &TR : Transfers) { @@ -1286,8 +1254,8 @@ if (none_of(MBB.instrs(), hasNonArtificialLocation)) ArtificialBlocks.insert(&MBB); - LLVM_DEBUG(printVarLocInMBB(MF, OutLocs, VarLocIDs, - "OutLocs after initialization", dbgs())); + LLVM_DEBUG( + printVarLocInMBB(MF, OutLocs, "OutLocs after initialization", dbgs())); ReversePostOrderTraversal RPOT(&MF); unsigned int RPONumber = 0; @@ -1311,8 +1279,8 @@ while (!Worklist.empty()) { MachineBasicBlock *MBB = OrderToBB[Worklist.top()]; Worklist.pop(); - MBBJoined = join(*MBB, OutLocs, InLocs, VarLocIDs, Visited, - ArtificialBlocks, PendingInLocs); + MBBJoined = + join(*MBB, OutLocs, InLocs, Visited, ArtificialBlocks, PendingInLocs); Visited.insert(MBB); if (MBBJoined) { MBBJoined = false; @@ -1323,10 +1291,8 @@ // First load any pending inlocs. OpenRanges.insertFromLocSet(PendingInLocs[MBB], VarLocIDs); for (auto &MI : *MBB) - process(MI, OpenRanges, OutLocs, VarLocIDs, Transfers, - DebugEntryVals, transferChanges, OverlapFragments, - SeenFragments); - OLChanged |= transferTerminator(MBB, OpenRanges, OutLocs, VarLocIDs); + process(MI, OutLocs, transferChanges); + OLChanged |= transferTerminator(MBB, OutLocs); // Add any DBG_VALUE instructions necessitated by spills. for (auto &TR : Transfers) @@ -1334,10 +1300,10 @@ TR.DebugInst); Transfers.clear(); - LLVM_DEBUG(printVarLocInMBB(MF, OutLocs, VarLocIDs, - "OutLocs after propagating", dbgs())); - LLVM_DEBUG(printVarLocInMBB(MF, InLocs, VarLocIDs, - "InLocs after propagating", dbgs())); + LLVM_DEBUG( + printVarLocInMBB(MF, OutLocs, "OutLocs after propagating", dbgs())); + LLVM_DEBUG( + printVarLocInMBB(MF, InLocs, "InLocs after propagating", dbgs())); if (OLChanged) { OLChanged = false; @@ -1356,10 +1322,10 @@ // Deferred inlocs will not have had any DBG_VALUE insts created; do // that now. - flushPendingLocs(PendingInLocs, VarLocIDs); + flushPendingLocs(PendingInLocs); - LLVM_DEBUG(printVarLocInMBB(MF, OutLocs, VarLocIDs, "Final OutLocs", dbgs())); - LLVM_DEBUG(printVarLocInMBB(MF, InLocs, VarLocIDs, "Final InLocs", dbgs())); + LLVM_DEBUG(printVarLocInMBB(MF, OutLocs, "Final OutLocs", dbgs())); + LLVM_DEBUG(printVarLocInMBB(MF, InLocs, "Final InLocs", dbgs())); return Changed; } @@ -1381,5 +1347,17 @@ LS.initialize(MF); bool Changed = ExtendRanges(MF); + + // Clear up pass state. + VarLocIDs = VarLocMap(); + OpenRanges.clear(); + OutLocs.clear(); + InLocs.clear(); + Transfers.clear(); + PendingInLocs.clear(); + OverlapFragments.clear(); + SeenFragments.clear(); + DebugEntryVals.clear(); + return Changed; }