| Hsiangkai Wang | 2532ac8 | 2018-08-17 15:22:04 +0000 | [diff] [blame] | 1 | //===- llvm/CodeGen/AsmPrinter/DbgEntityHistoryCalculator.cpp -------------===// | 
| Alexey Samsonov | 414b6fb | 2014-04-30 21:34:11 +0000 | [diff] [blame] | 2 | // | 
| Chandler Carruth | 2946cd7 | 2019-01-19 08:50:56 +0000 | [diff] [blame] | 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
|  | 4 | // See https://llvm.org/LICENSE.txt for license information. | 
|  | 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
| Alexey Samsonov | 414b6fb | 2014-04-30 21:34:11 +0000 | [diff] [blame] | 6 | // | 
|  | 7 | //===----------------------------------------------------------------------===// | 
|  | 8 |  | 
| Yonghong Song | 61b189e | 2018-12-18 23:10:17 +0000 | [diff] [blame] | 9 | #include "llvm/CodeGen/DbgEntityHistoryCalculator.h" | 
| Benjamin Kramer | 6bf8af5 | 2014-10-06 15:31:04 +0000 | [diff] [blame] | 10 | #include "llvm/ADT/BitVector.h" | 
| Eugene Zelenko | 6e07bfd | 2017-08-17 21:26:39 +0000 | [diff] [blame] | 11 | #include "llvm/ADT/STLExtras.h" | 
| David Stenberg | 5ffec6d | 2019-04-10 11:28:20 +0000 | [diff] [blame] | 12 | #include "llvm/ADT/SmallSet.h" | 
| Alexey Samsonov | dfcaf9c | 2014-05-20 18:34:54 +0000 | [diff] [blame] | 13 | #include "llvm/ADT/SmallVector.h" | 
| Alexey Samsonov | 414b6fb | 2014-04-30 21:34:11 +0000 | [diff] [blame] | 14 | #include "llvm/CodeGen/MachineBasicBlock.h" | 
|  | 15 | #include "llvm/CodeGen/MachineFunction.h" | 
| Eugene Zelenko | 6e07bfd | 2017-08-17 21:26:39 +0000 | [diff] [blame] | 16 | #include "llvm/CodeGen/MachineInstr.h" | 
|  | 17 | #include "llvm/CodeGen/MachineOperand.h" | 
| David Blaikie | b3bde2e | 2017-11-17 01:07:10 +0000 | [diff] [blame] | 18 | #include "llvm/CodeGen/TargetLowering.h" | 
|  | 19 | #include "llvm/CodeGen/TargetRegisterInfo.h" | 
|  | 20 | #include "llvm/CodeGen/TargetSubtargetInfo.h" | 
| Eugene Zelenko | 6e07bfd | 2017-08-17 21:26:39 +0000 | [diff] [blame] | 21 | #include "llvm/IR/DebugInfoMetadata.h" | 
|  | 22 | #include "llvm/IR/DebugLoc.h" | 
|  | 23 | #include "llvm/MC/MCRegisterInfo.h" | 
| Alexey Samsonov | 414b6fb | 2014-04-30 21:34:11 +0000 | [diff] [blame] | 24 | #include "llvm/Support/Debug.h" | 
| Benjamin Kramer | 16132e6 | 2015-03-23 18:07:13 +0000 | [diff] [blame] | 25 | #include "llvm/Support/raw_ostream.h" | 
| Eugene Zelenko | 6e07bfd | 2017-08-17 21:26:39 +0000 | [diff] [blame] | 26 | #include <cassert> | 
| Alexey Samsonov | dfcaf9c | 2014-05-20 18:34:54 +0000 | [diff] [blame] | 27 | #include <map> | 
| Eugene Zelenko | 6e07bfd | 2017-08-17 21:26:39 +0000 | [diff] [blame] | 28 | #include <utility> | 
|  | 29 |  | 
| Benjamin Kramer | 6bf8af5 | 2014-10-06 15:31:04 +0000 | [diff] [blame] | 30 | using namespace llvm; | 
| Alexey Samsonov | 414b6fb | 2014-04-30 21:34:11 +0000 | [diff] [blame] | 31 |  | 
|  | 32 | #define DEBUG_TYPE "dwarfdebug" | 
|  | 33 |  | 
| David Stenberg | 5ffec6d | 2019-04-10 11:28:20 +0000 | [diff] [blame] | 34 | namespace { | 
|  | 35 | using EntryIndex = DbgValueHistoryMap::EntryIndex; | 
|  | 36 | } | 
|  | 37 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 38 | // If @MI is a DBG_VALUE with debug value described by a | 
| Alexey Samsonov | dfcaf9c | 2014-05-20 18:34:54 +0000 | [diff] [blame] | 39 | // defined register, returns the number of this register. | 
|  | 40 | // In the other case, returns 0. | 
| Matt Arsenault | e3a676e | 2019-06-24 15:50:29 +0000 | [diff] [blame] | 41 | static Register isDescribedByReg(const MachineInstr &MI) { | 
| Alexey Samsonov | dfcaf9c | 2014-05-20 18:34:54 +0000 | [diff] [blame] | 42 | assert(MI.isDebugValue()); | 
| Adrian Prantl | 87b7eb9 | 2014-10-01 18:55:02 +0000 | [diff] [blame] | 43 | assert(MI.getNumOperands() == 4); | 
| David Stenberg | 1ae2d9a | 2019-10-15 11:31:21 +0000 | [diff] [blame] | 44 | // If the location of variable is an entry value (DW_OP_LLVM_entry_value) | 
| Djordje Todorovic | a0d4505 | 2019-06-27 13:52:34 +0000 | [diff] [blame] | 45 | // do not consider it as a register location. | 
|  | 46 | if (MI.getDebugExpression()->isEntryValue()) | 
|  | 47 | return 0; | 
| Alexey Samsonov | dfcaf9c | 2014-05-20 18:34:54 +0000 | [diff] [blame] | 48 | // If location of variable is described using a register (directly or | 
| Dominic Chen | 6ba1965 | 2016-08-11 17:52:40 +0000 | [diff] [blame] | 49 | // indirectly), this register is always a first operand. | 
| Matt Arsenault | e3a676e | 2019-06-24 15:50:29 +0000 | [diff] [blame] | 50 | return MI.getOperand(0).isReg() ? MI.getOperand(0).getReg() : Register(); | 
| Alexey Samsonov | dfcaf9c | 2014-05-20 18:34:54 +0000 | [diff] [blame] | 51 | } | 
|  | 52 |  | 
| David Stenberg | 5ffec6d | 2019-04-10 11:28:20 +0000 | [diff] [blame] | 53 | bool DbgValueHistoryMap::startDbgValue(InlinedEntity Var, | 
|  | 54 | const MachineInstr &MI, | 
|  | 55 | EntryIndex &NewIndex) { | 
| Alexey Samsonov | bb2990d | 2014-05-27 23:09:50 +0000 | [diff] [blame] | 56 | // Instruction range should start with a DBG_VALUE instruction for the | 
|  | 57 | // variable. | 
| Adrian Prantl | 87b7eb9 | 2014-10-01 18:55:02 +0000 | [diff] [blame] | 58 | assert(MI.isDebugValue() && "not a DBG_VALUE"); | 
| David Stenberg | 6feef56 | 2019-04-10 09:07:43 +0000 | [diff] [blame] | 59 | auto &Entries = VarEntries[Var]; | 
| David Stenberg | 5ffec6d | 2019-04-10 11:28:20 +0000 | [diff] [blame] | 60 | if (!Entries.empty() && Entries.back().isDbgValue() && | 
|  | 61 | !Entries.back().isClosed() && | 
|  | 62 | Entries.back().getInstr()->isIdenticalTo(MI)) { | 
| Nicola Zaghen | d34e60c | 2018-05-14 12:53:11 +0000 | [diff] [blame] | 63 | LLVM_DEBUG(dbgs() << "Coalescing identical DBG_VALUE entries:\n" | 
| David Stenberg | 5ffec6d | 2019-04-10 11:28:20 +0000 | [diff] [blame] | 64 | << "\t" << Entries.back().getInstr() << "\t" << MI | 
| David Stenberg | 3739979 | 2019-04-10 09:07:32 +0000 | [diff] [blame] | 65 | << "\n"); | 
| David Stenberg | 5ffec6d | 2019-04-10 11:28:20 +0000 | [diff] [blame] | 66 | return false; | 
| Alexey Samsonov | bb2990d | 2014-05-27 23:09:50 +0000 | [diff] [blame] | 67 | } | 
| David Stenberg | 5ffec6d | 2019-04-10 11:28:20 +0000 | [diff] [blame] | 68 | Entries.emplace_back(&MI, Entry::DbgValue); | 
|  | 69 | NewIndex = Entries.size() - 1; | 
|  | 70 | return true; | 
| Alexey Samsonov | bb2990d | 2014-05-27 23:09:50 +0000 | [diff] [blame] | 71 | } | 
|  | 72 |  | 
| David Stenberg | 5ffec6d | 2019-04-10 11:28:20 +0000 | [diff] [blame] | 73 | EntryIndex DbgValueHistoryMap::startClobber(InlinedEntity Var, | 
|  | 74 | const MachineInstr &MI) { | 
| David Stenberg | 6feef56 | 2019-04-10 09:07:43 +0000 | [diff] [blame] | 75 | auto &Entries = VarEntries[Var]; | 
| David Stenberg | b96943b | 2019-04-10 11:28:28 +0000 | [diff] [blame] | 76 | // If an instruction clobbers multiple registers that the variable is | 
|  | 77 | // described by, then we may have already created a clobbering instruction. | 
|  | 78 | if (Entries.back().isClobber() && Entries.back().getInstr() == &MI) | 
|  | 79 | return Entries.size() - 1; | 
| David Stenberg | 5ffec6d | 2019-04-10 11:28:20 +0000 | [diff] [blame] | 80 | Entries.emplace_back(&MI, Entry::Clobber); | 
|  | 81 | return Entries.size() - 1; | 
| David Stenberg | 3739979 | 2019-04-10 09:07:32 +0000 | [diff] [blame] | 82 | } | 
|  | 83 |  | 
| David Stenberg | 5ffec6d | 2019-04-10 11:28:20 +0000 | [diff] [blame] | 84 | void DbgValueHistoryMap::Entry::endEntry(EntryIndex Index) { | 
| Alexey Samsonov | bb2990d | 2014-05-27 23:09:50 +0000 | [diff] [blame] | 85 | // For now, instruction ranges are not allowed to cross basic block | 
|  | 86 | // boundaries. | 
| David Stenberg | 5ffec6d | 2019-04-10 11:28:20 +0000 | [diff] [blame] | 87 | assert(isDbgValue() && "Setting end index for non-debug value"); | 
|  | 88 | assert(!isClosed() && "End index has already been set"); | 
|  | 89 | EndIndex = Index; | 
| Alexey Samsonov | bb2990d | 2014-05-27 23:09:50 +0000 | [diff] [blame] | 90 | } | 
|  | 91 |  | 
| Hsiangkai Wang | 760c1ab | 2018-09-06 02:22:06 +0000 | [diff] [blame] | 92 | void DbgLabelInstrMap::addInstr(InlinedEntity Label, const MachineInstr &MI) { | 
| Hsiangkai Wang | 2532ac8 | 2018-08-17 15:22:04 +0000 | [diff] [blame] | 93 | assert(MI.isDebugLabel() && "not a DBG_LABEL"); | 
|  | 94 | LabelInstr[Label] = &MI; | 
|  | 95 | } | 
|  | 96 |  | 
| Alexey Samsonov | bb2990d | 2014-05-27 23:09:50 +0000 | [diff] [blame] | 97 | namespace { | 
| Eugene Zelenko | 6e07bfd | 2017-08-17 21:26:39 +0000 | [diff] [blame] | 98 |  | 
| Alexey Samsonov | bb2990d | 2014-05-27 23:09:50 +0000 | [diff] [blame] | 99 | // Maps physreg numbers to the variables they describe. | 
| Hsiangkai Wang | 760c1ab | 2018-09-06 02:22:06 +0000 | [diff] [blame] | 100 | using InlinedEntity = DbgValueHistoryMap::InlinedEntity; | 
|  | 101 | using RegDescribedVarsMap = std::map<unsigned, SmallVector<InlinedEntity, 1>>; | 
| Eugene Zelenko | 6e07bfd | 2017-08-17 21:26:39 +0000 | [diff] [blame] | 102 |  | 
| David Stenberg | 5ffec6d | 2019-04-10 11:28:20 +0000 | [diff] [blame] | 103 | // Keeps track of the debug value entries that are currently live for each | 
|  | 104 | // inlined entity. As the history map entries are stored in a SmallVector, they | 
|  | 105 | // may be moved at insertion of new entries, so store indices rather than | 
|  | 106 | // pointers. | 
|  | 107 | using DbgValueEntriesMap = std::map<InlinedEntity, SmallSet<EntryIndex, 1>>; | 
|  | 108 |  | 
| Eugene Zelenko | 6e07bfd | 2017-08-17 21:26:39 +0000 | [diff] [blame] | 109 | } // end anonymous namespace | 
| Alexey Samsonov | bb2990d | 2014-05-27 23:09:50 +0000 | [diff] [blame] | 110 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 111 | // Claim that @Var is not described by @RegNo anymore. | 
| Duncan P. N. Exon Smith | 62e0f45 | 2015-04-15 22:29:27 +0000 | [diff] [blame] | 112 | static void dropRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo, | 
| Hsiangkai Wang | 760c1ab | 2018-09-06 02:22:06 +0000 | [diff] [blame] | 113 | InlinedEntity Var) { | 
| Alexey Samsonov | dfcaf9c | 2014-05-20 18:34:54 +0000 | [diff] [blame] | 114 | const auto &I = RegVars.find(RegNo); | 
|  | 115 | assert(RegNo != 0U && I != RegVars.end()); | 
|  | 116 | auto &VarSet = I->second; | 
| Eugene Zelenko | 6e07bfd | 2017-08-17 21:26:39 +0000 | [diff] [blame] | 117 | const auto &VarPos = llvm::find(VarSet, Var); | 
| Alexey Samsonov | dfcaf9c | 2014-05-20 18:34:54 +0000 | [diff] [blame] | 118 | assert(VarPos != VarSet.end()); | 
|  | 119 | VarSet.erase(VarPos); | 
|  | 120 | // Don't keep empty sets in a map to keep it as small as possible. | 
|  | 121 | if (VarSet.empty()) | 
|  | 122 | RegVars.erase(I); | 
|  | 123 | } | 
|  | 124 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 125 | // Claim that @Var is now described by @RegNo. | 
| Duncan P. N. Exon Smith | 62e0f45 | 2015-04-15 22:29:27 +0000 | [diff] [blame] | 126 | static void addRegDescribedVar(RegDescribedVarsMap &RegVars, unsigned RegNo, | 
| Hsiangkai Wang | 760c1ab | 2018-09-06 02:22:06 +0000 | [diff] [blame] | 127 | InlinedEntity Var) { | 
| Alexey Samsonov | dfcaf9c | 2014-05-20 18:34:54 +0000 | [diff] [blame] | 128 | assert(RegNo != 0U); | 
| Alexey Samsonov | bb2990d | 2014-05-27 23:09:50 +0000 | [diff] [blame] | 129 | auto &VarSet = RegVars[RegNo]; | 
| David Majnemer | 0d955d0 | 2016-08-11 22:21:41 +0000 | [diff] [blame] | 130 | assert(!is_contained(VarSet, Var)); | 
| Alexey Samsonov | bb2990d | 2014-05-27 23:09:50 +0000 | [diff] [blame] | 131 | VarSet.push_back(Var); | 
| Alexey Samsonov | dfcaf9c | 2014-05-20 18:34:54 +0000 | [diff] [blame] | 132 | } | 
|  | 133 |  | 
| David Stenberg | b96943b | 2019-04-10 11:28:28 +0000 | [diff] [blame] | 134 | /// Create a clobbering entry and end all open debug value entries | 
|  | 135 | /// for \p Var that are described by \p RegNo using that entry. | 
| David Stenberg | 5ffec6d | 2019-04-10 11:28:20 +0000 | [diff] [blame] | 136 | static void clobberRegEntries(InlinedEntity Var, unsigned RegNo, | 
|  | 137 | const MachineInstr &ClobberingInstr, | 
|  | 138 | DbgValueEntriesMap &LiveEntries, | 
|  | 139 | DbgValueHistoryMap &HistMap) { | 
|  | 140 | EntryIndex ClobberIndex = HistMap.startClobber(Var, ClobberingInstr); | 
|  | 141 |  | 
| David Stenberg | b96943b | 2019-04-10 11:28:28 +0000 | [diff] [blame] | 142 | // Close all entries whose values are described by the register. | 
|  | 143 | SmallVector<EntryIndex, 4> IndicesToErase; | 
|  | 144 | for (auto Index : LiveEntries[Var]) { | 
|  | 145 | auto &Entry = HistMap.getEntry(Var, Index); | 
|  | 146 | assert(Entry.isDbgValue() && "Not a DBG_VALUE in LiveEntries"); | 
|  | 147 | if (isDescribedByReg(*Entry.getInstr()) == RegNo) { | 
|  | 148 | IndicesToErase.push_back(Index); | 
|  | 149 | Entry.endEntry(ClobberIndex); | 
|  | 150 | } | 
|  | 151 | } | 
|  | 152 |  | 
|  | 153 | // Drop all entries that have ended. | 
|  | 154 | for (auto Index : IndicesToErase) | 
|  | 155 | LiveEntries[Var].erase(Index); | 
| David Stenberg | 5ffec6d | 2019-04-10 11:28:20 +0000 | [diff] [blame] | 156 | } | 
|  | 157 |  | 
|  | 158 | /// Add a new debug value for \p Var. Closes all overlapping debug values. | 
|  | 159 | static void handleNewDebugValue(InlinedEntity Var, const MachineInstr &DV, | 
|  | 160 | RegDescribedVarsMap &RegVars, | 
|  | 161 | DbgValueEntriesMap &LiveEntries, | 
|  | 162 | DbgValueHistoryMap &HistMap) { | 
| David Stenberg | 5ffec6d | 2019-04-10 11:28:20 +0000 | [diff] [blame] | 163 | EntryIndex NewIndex; | 
|  | 164 | if (HistMap.startDbgValue(Var, DV, NewIndex)) { | 
| David Stenberg | b96943b | 2019-04-10 11:28:28 +0000 | [diff] [blame] | 165 | SmallDenseMap<unsigned, bool, 4> TrackedRegs; | 
|  | 166 |  | 
| David Stenberg | 5ffec6d | 2019-04-10 11:28:20 +0000 | [diff] [blame] | 167 | // If we have created a new debug value entry, close all preceding | 
|  | 168 | // live entries that overlap. | 
|  | 169 | SmallVector<EntryIndex, 4> IndicesToErase; | 
|  | 170 | const DIExpression *DIExpr = DV.getDebugExpression(); | 
|  | 171 | for (auto Index : LiveEntries[Var]) { | 
|  | 172 | auto &Entry = HistMap.getEntry(Var, Index); | 
|  | 173 | assert(Entry.isDbgValue() && "Not a DBG_VALUE in LiveEntries"); | 
|  | 174 | const MachineInstr &DV = *Entry.getInstr(); | 
| David Stenberg | b96943b | 2019-04-10 11:28:28 +0000 | [diff] [blame] | 175 | bool Overlaps = DIExpr->fragmentsOverlap(DV.getDebugExpression()); | 
|  | 176 | if (Overlaps) { | 
| David Stenberg | 5ffec6d | 2019-04-10 11:28:20 +0000 | [diff] [blame] | 177 | IndicesToErase.push_back(Index); | 
|  | 178 | Entry.endEntry(NewIndex); | 
|  | 179 | } | 
| Daniel Sanders | 0c47611 | 2019-08-15 19:22:08 +0000 | [diff] [blame] | 180 | if (Register Reg = isDescribedByReg(DV)) | 
| David Stenberg | b96943b | 2019-04-10 11:28:28 +0000 | [diff] [blame] | 181 | TrackedRegs[Reg] |= !Overlaps; | 
| David Stenberg | 5ffec6d | 2019-04-10 11:28:20 +0000 | [diff] [blame] | 182 | } | 
| David Stenberg | b96943b | 2019-04-10 11:28:28 +0000 | [diff] [blame] | 183 |  | 
|  | 184 | // If the new debug value is described by a register, add tracking of | 
|  | 185 | // that register if it is not already tracked. | 
| Daniel Sanders | 0c47611 | 2019-08-15 19:22:08 +0000 | [diff] [blame] | 186 | if (Register NewReg = isDescribedByReg(DV)) { | 
| David Stenberg | b96943b | 2019-04-10 11:28:28 +0000 | [diff] [blame] | 187 | if (!TrackedRegs.count(NewReg)) | 
|  | 188 | addRegDescribedVar(RegVars, NewReg, Var); | 
|  | 189 | LiveEntries[Var].insert(NewIndex); | 
|  | 190 | TrackedRegs[NewReg] = true; | 
|  | 191 | } | 
|  | 192 |  | 
|  | 193 | // Drop tracking of registers that are no longer used. | 
|  | 194 | for (auto I : TrackedRegs) | 
|  | 195 | if (!I.second) | 
|  | 196 | dropRegDescribedVar(RegVars, I.first, Var); | 
|  | 197 |  | 
| David Stenberg | 5ffec6d | 2019-04-10 11:28:20 +0000 | [diff] [blame] | 198 | // Drop all entries that have ended, and mark the new entry as live. | 
|  | 199 | for (auto Index : IndicesToErase) | 
|  | 200 | LiveEntries[Var].erase(Index); | 
|  | 201 | LiveEntries[Var].insert(NewIndex); | 
|  | 202 | } | 
| David Stenberg | 5ffec6d | 2019-04-10 11:28:20 +0000 | [diff] [blame] | 203 | } | 
|  | 204 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 205 | // Terminate the location range for variables described by register at | 
| Benjamin Kramer | 6bf8af5 | 2014-10-06 15:31:04 +0000 | [diff] [blame] | 206 | // @I by inserting @ClobberingInstr to their history. | 
|  | 207 | static void clobberRegisterUses(RegDescribedVarsMap &RegVars, | 
|  | 208 | RegDescribedVarsMap::iterator I, | 
|  | 209 | DbgValueHistoryMap &HistMap, | 
| David Stenberg | 5ffec6d | 2019-04-10 11:28:20 +0000 | [diff] [blame] | 210 | DbgValueEntriesMap &LiveEntries, | 
| Benjamin Kramer | 6bf8af5 | 2014-10-06 15:31:04 +0000 | [diff] [blame] | 211 | const MachineInstr &ClobberingInstr) { | 
|  | 212 | // Iterate over all variables described by this register and add this | 
|  | 213 | // instruction to their history, clobbering it. | 
|  | 214 | for (const auto &Var : I->second) | 
| David Stenberg | 5ffec6d | 2019-04-10 11:28:20 +0000 | [diff] [blame] | 215 | clobberRegEntries(Var, I->first, ClobberingInstr, LiveEntries, HistMap); | 
| Benjamin Kramer | 6bf8af5 | 2014-10-06 15:31:04 +0000 | [diff] [blame] | 216 | RegVars.erase(I); | 
|  | 217 | } | 
|  | 218 |  | 
| Adrian Prantl | 5f8f34e4 | 2018-05-01 15:54:18 +0000 | [diff] [blame] | 219 | // Terminate the location range for variables described by register | 
| Alexey Samsonov | dfcaf9c | 2014-05-20 18:34:54 +0000 | [diff] [blame] | 220 | // @RegNo by inserting @ClobberingInstr to their history. | 
|  | 221 | static void clobberRegisterUses(RegDescribedVarsMap &RegVars, unsigned RegNo, | 
|  | 222 | DbgValueHistoryMap &HistMap, | 
| David Stenberg | 5ffec6d | 2019-04-10 11:28:20 +0000 | [diff] [blame] | 223 | DbgValueEntriesMap &LiveEntries, | 
| Alexey Samsonov | dfcaf9c | 2014-05-20 18:34:54 +0000 | [diff] [blame] | 224 | const MachineInstr &ClobberingInstr) { | 
|  | 225 | const auto &I = RegVars.find(RegNo); | 
|  | 226 | if (I == RegVars.end()) | 
|  | 227 | return; | 
| David Stenberg | 5ffec6d | 2019-04-10 11:28:20 +0000 | [diff] [blame] | 228 | clobberRegisterUses(RegVars, I, HistMap, LiveEntries, ClobberingInstr); | 
| Alexey Samsonov | dfcaf9c | 2014-05-20 18:34:54 +0000 | [diff] [blame] | 229 | } | 
|  | 230 |  | 
| Hsiangkai Wang | 2532ac8 | 2018-08-17 15:22:04 +0000 | [diff] [blame] | 231 | void llvm::calculateDbgEntityHistory(const MachineFunction *MF, | 
|  | 232 | const TargetRegisterInfo *TRI, | 
|  | 233 | DbgValueHistoryMap &DbgValues, | 
|  | 234 | DbgLabelInstrMap &DbgLabels) { | 
| Reid Kleckner | f6f04f8 | 2016-03-25 17:54:46 +0000 | [diff] [blame] | 235 | const TargetLowering *TLI = MF->getSubtarget().getTargetLowering(); | 
|  | 236 | unsigned SP = TLI->getStackPointerRegisterToSaveRestore(); | 
| Daniel Sanders | 0c47611 | 2019-08-15 19:22:08 +0000 | [diff] [blame] | 237 | Register FrameReg = TRI->getFrameRegister(*MF); | 
| Alexey Samsonov | 8000e27 | 2014-06-09 21:53:47 +0000 | [diff] [blame] | 238 | RegDescribedVarsMap RegVars; | 
| David Stenberg | 5ffec6d | 2019-04-10 11:28:20 +0000 | [diff] [blame] | 239 | DbgValueEntriesMap LiveEntries; | 
| Alexey Samsonov | dfcaf9c | 2014-05-20 18:34:54 +0000 | [diff] [blame] | 240 | for (const auto &MBB : *MF) { | 
|  | 241 | for (const auto &MI : MBB) { | 
| Hsiangkai Wang | 2532ac8 | 2018-08-17 15:22:04 +0000 | [diff] [blame] | 242 | if (MI.isDebugValue()) { | 
|  | 243 | assert(MI.getNumOperands() > 1 && "Invalid DBG_VALUE instruction!"); | 
|  | 244 | // Use the base variable (without any DW_OP_piece expressions) | 
|  | 245 | // as index into History. The full variables including the | 
|  | 246 | // piece expressions are attached to the MI. | 
|  | 247 | const DILocalVariable *RawVar = MI.getDebugVariable(); | 
|  | 248 | assert(RawVar->isValidLocationForIntrinsic(MI.getDebugLoc()) && | 
|  | 249 | "Expected inlined-at fields to agree"); | 
| Hsiangkai Wang | 760c1ab | 2018-09-06 02:22:06 +0000 | [diff] [blame] | 250 | InlinedEntity Var(RawVar, MI.getDebugLoc()->getInlinedAt()); | 
| Shiva Chen | 801bf7e | 2018-05-09 02:42:00 +0000 | [diff] [blame] | 251 |  | 
| David Stenberg | 5ffec6d | 2019-04-10 11:28:20 +0000 | [diff] [blame] | 252 | handleNewDebugValue(Var, MI, RegVars, LiveEntries, DbgValues); | 
| Hsiangkai Wang | 2532ac8 | 2018-08-17 15:22:04 +0000 | [diff] [blame] | 253 | } else if (MI.isDebugLabel()) { | 
|  | 254 | assert(MI.getNumOperands() == 1 && "Invalid DBG_LABEL instruction!"); | 
|  | 255 | const DILabel *RawLabel = MI.getDebugLabel(); | 
|  | 256 | assert(RawLabel->isValidLocationForIntrinsic(MI.getDebugLoc()) && | 
|  | 257 | "Expected inlined-at fields to agree"); | 
|  | 258 | // When collecting debug information for labels, there is no MCSymbol | 
|  | 259 | // generated for it. So, we keep MachineInstr in DbgLabels in order | 
|  | 260 | // to query MCSymbol afterward. | 
| Hsiangkai Wang | 760c1ab | 2018-09-06 02:22:06 +0000 | [diff] [blame] | 261 | InlinedEntity L(RawLabel, MI.getDebugLoc()->getInlinedAt()); | 
| Hsiangkai Wang | 2532ac8 | 2018-08-17 15:22:04 +0000 | [diff] [blame] | 262 | DbgLabels.addInstr(L, MI); | 
|  | 263 | } | 
| Alexey Samsonov | dfcaf9c | 2014-05-20 18:34:54 +0000 | [diff] [blame] | 264 |  | 
| Tom Weaver | 453dc4d | 2019-12-20 14:03:34 +0000 | [diff] [blame^] | 265 | // Meta Instructions have no output and do not change any values and so | 
|  | 266 | // can be safely ignored. | 
|  | 267 | if (MI.isMetaInstruction()) | 
| Jeremy Morse | bcff417 | 2019-06-10 15:23:46 +0000 | [diff] [blame] | 268 | continue; | 
|  | 269 |  | 
|  | 270 | // Not a DBG_VALUE instruction. It may clobber registers which describe | 
|  | 271 | // some variables. | 
|  | 272 | for (const MachineOperand &MO : MI.operands()) { | 
|  | 273 | if (MO.isReg() && MO.isDef() && MO.getReg()) { | 
|  | 274 | // Ignore call instructions that claim to clobber SP. The AArch64 | 
|  | 275 | // backend does this for aggregate function arguments. | 
|  | 276 | if (MI.isCall() && MO.getReg() == SP) | 
|  | 277 | continue; | 
|  | 278 | // If this is a virtual register, only clobber it since it doesn't | 
|  | 279 | // have aliases. | 
| Daniel Sanders | 2bea69b | 2019-08-01 23:27:28 +0000 | [diff] [blame] | 280 | if (Register::isVirtualRegister(MO.getReg())) | 
| Jeremy Morse | bcff417 | 2019-06-10 15:23:46 +0000 | [diff] [blame] | 281 | clobberRegisterUses(RegVars, MO.getReg(), DbgValues, LiveEntries, | 
|  | 282 | MI); | 
|  | 283 | // If this is a register def operand, it may end a debug value | 
| Jeremy Morse | 181bf0c | 2019-06-13 10:03:17 +0000 | [diff] [blame] | 284 | // range. Ignore frame-register defs in the epilogue and prologue, | 
|  | 285 | // we expect debuggers to understand that stack-locations are | 
|  | 286 | // invalid outside of the function body. | 
| Jeremy Morse | bcff417 | 2019-06-10 15:23:46 +0000 | [diff] [blame] | 287 | else if (MO.getReg() != FrameReg || | 
| Jeremy Morse | 181bf0c | 2019-06-13 10:03:17 +0000 | [diff] [blame] | 288 | (!MI.getFlag(MachineInstr::FrameDestroy) && | 
|  | 289 | !MI.getFlag(MachineInstr::FrameSetup))) { | 
| Jeremy Morse | bcff417 | 2019-06-10 15:23:46 +0000 | [diff] [blame] | 290 | for (MCRegAliasIterator AI(MO.getReg(), TRI, true); AI.isValid(); | 
|  | 291 | ++AI) | 
|  | 292 | clobberRegisterUses(RegVars, *AI, DbgValues, LiveEntries, MI); | 
|  | 293 | } | 
|  | 294 | } else if (MO.isRegMask()) { | 
|  | 295 | // If this is a register mask operand, clobber all debug values in | 
|  | 296 | // non-CSRs. | 
|  | 297 | SmallVector<unsigned, 32> RegsToClobber; | 
|  | 298 | // Don't consider SP to be clobbered by register masks. | 
|  | 299 | for (auto It : RegVars) { | 
|  | 300 | unsigned int Reg = It.first; | 
| Daniel Sanders | 2bea69b | 2019-08-01 23:27:28 +0000 | [diff] [blame] | 301 | if (Reg != SP && Register::isPhysicalRegister(Reg) && | 
| Jeremy Morse | bcff417 | 2019-06-10 15:23:46 +0000 | [diff] [blame] | 302 | MO.clobbersPhysReg(Reg)) | 
|  | 303 | RegsToClobber.push_back(Reg); | 
|  | 304 | } | 
|  | 305 |  | 
|  | 306 | for (unsigned Reg : RegsToClobber) { | 
|  | 307 | clobberRegisterUses(RegVars, Reg, DbgValues, LiveEntries, MI); | 
|  | 308 | } | 
|  | 309 | } | 
|  | 310 | } // End MO loop. | 
|  | 311 | }   // End instr loop. | 
|  | 312 |  | 
|  | 313 | // Make sure locations for all variables are valid only until the end of | 
|  | 314 | // the basic block (unless it's the last basic block, in which case let | 
|  | 315 | // their liveness run off to the end of the function). | 
| Benjamin Kramer | 6bf8af5 | 2014-10-06 15:31:04 +0000 | [diff] [blame] | 316 | if (!MBB.empty() && &MBB != &MF->back()) { | 
| Jeremy Morse | bcff417 | 2019-06-10 15:23:46 +0000 | [diff] [blame] | 317 | // Iterate over all variables that have open debug values. | 
|  | 318 | for (auto &Pair : LiveEntries) { | 
|  | 319 | if (Pair.second.empty()) | 
|  | 320 | continue; | 
|  | 321 |  | 
|  | 322 | // Create a clobbering entry. | 
|  | 323 | EntryIndex ClobIdx = DbgValues.startClobber(Pair.first, MBB.back()); | 
|  | 324 |  | 
|  | 325 | // End all entries. | 
|  | 326 | for (EntryIndex Idx : Pair.second) { | 
|  | 327 | DbgValueHistoryMap::Entry &Ent = DbgValues.getEntry(Pair.first, Idx); | 
|  | 328 | assert(Ent.isDbgValue() && !Ent.isClosed()); | 
|  | 329 | Ent.endEntry(ClobIdx); | 
|  | 330 | } | 
| Benjamin Kramer | 6bf8af5 | 2014-10-06 15:31:04 +0000 | [diff] [blame] | 331 | } | 
| Jeremy Morse | bcff417 | 2019-06-10 15:23:46 +0000 | [diff] [blame] | 332 |  | 
|  | 333 | LiveEntries.clear(); | 
|  | 334 | RegVars.clear(); | 
| Alexey Samsonov | 8000e27 | 2014-06-09 21:53:47 +0000 | [diff] [blame] | 335 | } | 
| Alexey Samsonov | 414b6fb | 2014-04-30 21:34:11 +0000 | [diff] [blame] | 336 | } | 
|  | 337 | } | 
| Vedant Kumar | 7224c08 | 2018-06-01 22:33:15 +0000 | [diff] [blame] | 338 |  | 
|  | 339 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) | 
|  | 340 | LLVM_DUMP_METHOD void DbgValueHistoryMap::dump() const { | 
|  | 341 | dbgs() << "DbgValueHistoryMap:\n"; | 
|  | 342 | for (const auto &VarRangePair : *this) { | 
| Hsiangkai Wang | 760c1ab | 2018-09-06 02:22:06 +0000 | [diff] [blame] | 343 | const InlinedEntity &Var = VarRangePair.first; | 
| David Stenberg | 6feef56 | 2019-04-10 09:07:43 +0000 | [diff] [blame] | 344 | const Entries &Entries = VarRangePair.second; | 
| Vedant Kumar | 7224c08 | 2018-06-01 22:33:15 +0000 | [diff] [blame] | 345 |  | 
| Hsiangkai Wang | 760c1ab | 2018-09-06 02:22:06 +0000 | [diff] [blame] | 346 | const DILocalVariable *LocalVar = cast<DILocalVariable>(Var.first); | 
| Vedant Kumar | 7224c08 | 2018-06-01 22:33:15 +0000 | [diff] [blame] | 347 | const DILocation *Location = Var.second; | 
|  | 348 |  | 
|  | 349 | dbgs() << " - " << LocalVar->getName() << " at "; | 
|  | 350 |  | 
|  | 351 | if (Location) | 
|  | 352 | dbgs() << Location->getFilename() << ":" << Location->getLine() << ":" | 
|  | 353 | << Location->getColumn(); | 
|  | 354 | else | 
|  | 355 | dbgs() << "<unknown location>"; | 
|  | 356 |  | 
|  | 357 | dbgs() << " --\n"; | 
|  | 358 |  | 
| David Stenberg | 5ffec6d | 2019-04-10 11:28:20 +0000 | [diff] [blame] | 359 | for (const auto &E : enumerate(Entries)) { | 
|  | 360 | const auto &Entry = E.value(); | 
|  | 361 | dbgs() << "  Entry[" << E.index() << "]: "; | 
|  | 362 | if (Entry.isDbgValue()) | 
|  | 363 | dbgs() << "Debug value\n"; | 
|  | 364 | else | 
|  | 365 | dbgs() << "Clobber\n"; | 
|  | 366 | dbgs() << "   Instr: " << *Entry.getInstr(); | 
|  | 367 | if (Entry.isDbgValue()) { | 
|  | 368 | if (Entry.getEndIndex() == NoEntry) | 
|  | 369 | dbgs() << "   - Valid until end of function\n"; | 
|  | 370 | else | 
|  | 371 | dbgs() << "   - Closed by Entry[" << Entry.getEndIndex() << "]\n"; | 
|  | 372 | } | 
| Vedant Kumar | 7224c08 | 2018-06-01 22:33:15 +0000 | [diff] [blame] | 373 | dbgs() << "\n"; | 
|  | 374 | } | 
|  | 375 | } | 
|  | 376 | } | 
|  | 377 | #endif |