1 #include "llvm/CodeGen/AssignmentTrackingAnalysis.h"
2 #include "LiveDebugValues/LiveDebugValues.h"
3 #include "llvm/ADT/BitVector.h"
4 #include "llvm/ADT/DenseMapInfo.h"
5 #include "llvm/ADT/IntervalMap.h"
6 #include "llvm/ADT/PostOrderIterator.h"
7 #include "llvm/ADT/STLExtras.h"
8 #include "llvm/ADT/SmallSet.h"
9 #include "llvm/ADT/Statistic.h"
10 #include "llvm/ADT/UniqueVector.h"
11 #include "llvm/Analysis/Interval.h"
12 #include "llvm/BinaryFormat/Dwarf.h"
13 #include "llvm/IR/BasicBlock.h"
14 #include "llvm/IR/DataLayout.h"
15 #include "llvm/IR/DebugInfo.h"
16 #include "llvm/IR/Function.h"
17 #include "llvm/IR/Instruction.h"
18 #include "llvm/IR/IntrinsicInst.h"
19 #include "llvm/IR/PassManager.h"
20 #include "llvm/IR/PrintPasses.h"
21 #include "llvm/InitializePasses.h"
22 #include "llvm/Support/CommandLine.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/Support/raw_ostream.h"
25 #include "llvm/Transforms/Utils/BasicBlockUtils.h"
26 #include <assert.h>
27 #include <cstdint>
28 #include <optional>
29 #include <sstream>
30 #include <unordered_map>
31 
32 using namespace llvm;
33 #define DEBUG_TYPE "debug-ata"
34 
35 STATISTIC(NumDefsScanned, "Number of dbg locs that get scanned for removal");
36 STATISTIC(NumDefsRemoved, "Number of dbg locs removed");
37 STATISTIC(NumWedgesScanned, "Number of dbg wedges scanned");
38 STATISTIC(NumWedgesChanged, "Number of dbg wedges changed");
39 
40 static cl::opt<unsigned>
41     MaxNumBlocks("debug-ata-max-blocks", cl::init(10000),
42                  cl::desc("Maximum num basic blocks before debug info dropped"),
43                  cl::Hidden);
44 /// Option for debugging the pass, determines if the memory location fragment
45 /// filling happens after generating the variable locations.
46 static cl::opt<bool> EnableMemLocFragFill("mem-loc-frag-fill", cl::init(true),
47                                           cl::Hidden);
48 /// Print the results of the analysis. Respects -filter-print-funcs.
49 static cl::opt<bool> PrintResults("print-debug-ata", cl::init(false),
50                                   cl::Hidden);
51 
52 /// Coalesce adjacent dbg locs describing memory locations that have contiguous
53 /// fragments. This reduces the cost of LiveDebugValues which does SSA
54 /// construction for each explicitly stated variable fragment.
55 static cl::opt<cl::boolOrDefault>
56     CoalesceAdjacentFragmentsOpt("debug-ata-coalesce-frags", cl::Hidden);
57 
58 // Implicit conversions are disabled for enum class types, so unfortunately we
59 // need to create a DenseMapInfo wrapper around the specified underlying type.
60 template <> struct llvm::DenseMapInfo<VariableID> {
61   using Wrapped = DenseMapInfo<unsigned>;
62   static inline VariableID getEmptyKey() {
63     return static_cast<VariableID>(Wrapped::getEmptyKey());
64   }
65   static inline VariableID getTombstoneKey() {
66     return static_cast<VariableID>(Wrapped::getTombstoneKey());
67   }
68   static unsigned getHashValue(const VariableID &Val) {
69     return Wrapped::getHashValue(static_cast<unsigned>(Val));
70   }
71   static bool isEqual(const VariableID &LHS, const VariableID &RHS) {
72     return LHS == RHS;
73   }
74 };
75 
76 /// Helper class to build FunctionVarLocs, since that class isn't easy to
77 /// modify. TODO: There's not a great deal of value in the split, it could be
78 /// worth merging the two classes.
79 class FunctionVarLocsBuilder {
80   friend FunctionVarLocs;
81   UniqueVector<DebugVariable> Variables;
82   // Use an unordered_map so we don't invalidate iterators after
83   // insert/modifications.
84   std::unordered_map<const Instruction *, SmallVector<VarLocInfo>>
85       VarLocsBeforeInst;
86 
87   SmallVector<VarLocInfo> SingleLocVars;
88 
89 public:
90   unsigned getNumVariables() const { return Variables.size(); }
91 
92   /// Find or insert \p V and return the ID.
93   VariableID insertVariable(DebugVariable V) {
94     return static_cast<VariableID>(Variables.insert(V));
95   }
96 
97   /// Get a variable from its \p ID.
98   const DebugVariable &getVariable(VariableID ID) const {
99     return Variables[static_cast<unsigned>(ID)];
100   }
101 
102   /// Return ptr to wedge of defs or nullptr if no defs come just before /p
103   /// Before.
104   const SmallVectorImpl<VarLocInfo> *getWedge(const Instruction *Before) const {
105     auto R = VarLocsBeforeInst.find(Before);
106     if (R == VarLocsBeforeInst.end())
107       return nullptr;
108     return &R->second;
109   }
110 
111   /// Replace the defs that come just before /p Before with /p Wedge.
112   void setWedge(const Instruction *Before, SmallVector<VarLocInfo> &&Wedge) {
113     VarLocsBeforeInst[Before] = std::move(Wedge);
114   }
115 
116   /// Add a def for a variable that is valid for its lifetime.
117   void addSingleLocVar(DebugVariable Var, DIExpression *Expr, DebugLoc DL,
118                        RawLocationWrapper R) {
119     VarLocInfo VarLoc;
120     VarLoc.VariableID = insertVariable(Var);
121     VarLoc.Expr = Expr;
122     VarLoc.DL = DL;
123     VarLoc.Values = R;
124     SingleLocVars.emplace_back(VarLoc);
125   }
126 
127   /// Add a def to the wedge of defs just before /p Before.
128   void addVarLoc(Instruction *Before, DebugVariable Var, DIExpression *Expr,
129                  DebugLoc DL, RawLocationWrapper R) {
130     VarLocInfo VarLoc;
131     VarLoc.VariableID = insertVariable(Var);
132     VarLoc.Expr = Expr;
133     VarLoc.DL = DL;
134     VarLoc.Values = R;
135     VarLocsBeforeInst[Before].emplace_back(VarLoc);
136   }
137 };
138 
139 void FunctionVarLocs::print(raw_ostream &OS, const Function &Fn) const {
140   // Print the variable table first. TODO: Sorting by variable could make the
141   // output more stable?
142   unsigned Counter = -1;
143   OS << "=== Variables ===\n";
144   for (const DebugVariable &V : Variables) {
145     ++Counter;
146     // Skip first entry because it is a dummy entry.
147     if (Counter == 0) {
148       continue;
149     }
150     OS << "[" << Counter << "] " << V.getVariable()->getName();
151     if (auto F = V.getFragment())
152       OS << " bits [" << F->OffsetInBits << ", "
153          << F->OffsetInBits + F->SizeInBits << ")";
154     if (const auto *IA = V.getInlinedAt())
155       OS << " inlined-at " << *IA;
156     OS << "\n";
157   }
158 
159   auto PrintLoc = [&OS](const VarLocInfo &Loc) {
160     OS << "DEF Var=[" << (unsigned)Loc.VariableID << "]"
161        << " Expr=" << *Loc.Expr << " Values=(";
162     for (auto *Op : Loc.Values.location_ops()) {
163       errs() << Op->getName() << " ";
164     }
165     errs() << ")\n";
166   };
167 
168   // Print the single location variables.
169   OS << "=== Single location vars ===\n";
170   for (auto It = single_locs_begin(), End = single_locs_end(); It != End;
171        ++It) {
172     PrintLoc(*It);
173   }
174 
175   // Print the non-single-location defs in line with IR.
176   OS << "=== In-line variable defs ===";
177   for (const BasicBlock &BB : Fn) {
178     OS << "\n" << BB.getName() << ":\n";
179     for (const Instruction &I : BB) {
180       for (auto It = locs_begin(&I), End = locs_end(&I); It != End; ++It) {
181         PrintLoc(*It);
182       }
183       OS << I << "\n";
184     }
185   }
186 }
187 
188 void FunctionVarLocs::init(FunctionVarLocsBuilder &Builder) {
189   // Add the single-location variables first.
190   for (const auto &VarLoc : Builder.SingleLocVars)
191     VarLocRecords.emplace_back(VarLoc);
192   // Mark the end of the section.
193   SingleVarLocEnd = VarLocRecords.size();
194 
195   // Insert a contiguous block of VarLocInfos for each instruction, mapping it
196   // to the start and end position in the vector with VarLocsBeforeInst.
197   for (auto &P : Builder.VarLocsBeforeInst) {
198     unsigned BlockStart = VarLocRecords.size();
199     for (const VarLocInfo &VarLoc : P.second)
200       VarLocRecords.emplace_back(VarLoc);
201     unsigned BlockEnd = VarLocRecords.size();
202     // Record the start and end indices.
203     if (BlockEnd != BlockStart)
204       VarLocsBeforeInst[P.first] = {BlockStart, BlockEnd};
205   }
206 
207   // Copy the Variables vector from the builder's UniqueVector.
208   assert(Variables.empty() && "Expect clear before init");
209   // UniqueVectors IDs are one-based (which means the VarLocInfo VarID values
210   // are one-based) so reserve an extra and insert a dummy.
211   Variables.reserve(Builder.Variables.size() + 1);
212   Variables.push_back(DebugVariable(nullptr, std::nullopt, nullptr));
213   Variables.append(Builder.Variables.begin(), Builder.Variables.end());
214 }
215 
216 void FunctionVarLocs::clear() {
217   Variables.clear();
218   VarLocRecords.clear();
219   VarLocsBeforeInst.clear();
220   SingleVarLocEnd = 0;
221 }
222 
223 /// Walk backwards along constant GEPs and bitcasts to the base storage from \p
224 /// Start as far as possible. Prepend \Expression with the offset and append it
225 /// with a DW_OP_deref that haes been implicit until now. Returns the walked-to
226 /// value and modified expression.
227 static std::pair<Value *, DIExpression *>
228 walkToAllocaAndPrependOffsetDeref(const DataLayout &DL, Value *Start,
229                                   DIExpression *Expression) {
230   APInt OffsetInBytes(DL.getTypeSizeInBits(Start->getType()), false);
231   Value *End =
232       Start->stripAndAccumulateInBoundsConstantOffsets(DL, OffsetInBytes);
233   SmallVector<uint64_t, 3> Ops;
234   if (OffsetInBytes.getBoolValue()) {
235     Ops = {dwarf::DW_OP_plus_uconst, OffsetInBytes.getZExtValue()};
236     Expression = DIExpression::prependOpcodes(
237         Expression, Ops, /*StackValue=*/false, /*EntryValue=*/false);
238   }
239   Expression = DIExpression::append(Expression, {dwarf::DW_OP_deref});
240   return {End, Expression};
241 }
242 
243 /// Extract the offset used in \p DIExpr. Returns std::nullopt if the expression
244 /// doesn't explicitly describe a memory location with DW_OP_deref or if the
245 /// expression is too complex to interpret.
246 static std::optional<int64_t>
247 getDerefOffsetInBytes(const DIExpression *DIExpr) {
248   int64_t Offset = 0;
249   const unsigned NumElements = DIExpr->getNumElements();
250   const auto Elements = DIExpr->getElements();
251   unsigned ExpectedDerefIdx = 0;
252   // Extract the offset.
253   if (NumElements > 2 && Elements[0] == dwarf::DW_OP_plus_uconst) {
254     Offset = Elements[1];
255     ExpectedDerefIdx = 2;
256   } else if (NumElements > 3 && Elements[0] == dwarf::DW_OP_constu) {
257     ExpectedDerefIdx = 3;
258     if (Elements[2] == dwarf::DW_OP_plus)
259       Offset = Elements[1];
260     else if (Elements[2] == dwarf::DW_OP_minus)
261       Offset = -Elements[1];
262     else
263       return std::nullopt;
264   }
265 
266   // If that's all there is it means there's no deref.
267   if (ExpectedDerefIdx >= NumElements)
268     return std::nullopt;
269 
270   // Check the next element is DW_OP_deref - otherwise this is too complex or
271   // isn't a deref expression.
272   if (Elements[ExpectedDerefIdx] != dwarf::DW_OP_deref)
273     return std::nullopt;
274 
275   // Check the final operation is either the DW_OP_deref or is a fragment.
276   if (NumElements == ExpectedDerefIdx + 1)
277     return Offset; // Ends with deref.
278   unsigned ExpectedFragFirstIdx = ExpectedDerefIdx + 1;
279   unsigned ExpectedFragFinalIdx = ExpectedFragFirstIdx + 2;
280   if (NumElements == ExpectedFragFinalIdx + 1 &&
281       Elements[ExpectedFragFirstIdx] == dwarf::DW_OP_LLVM_fragment)
282     return Offset; // Ends with deref + fragment.
283 
284   // Don't bother trying to interpret anything more complex.
285   return std::nullopt;
286 }
287 
288 /// A whole (unfragmented) source variable.
289 using DebugAggregate = std::pair<const DILocalVariable *, const DILocation *>;
290 static DebugAggregate getAggregate(const DbgVariableIntrinsic *DII) {
291   return DebugAggregate(DII->getVariable(), DII->getDebugLoc().getInlinedAt());
292 }
293 static DebugAggregate getAggregate(const DebugVariable &Var) {
294   return DebugAggregate(Var.getVariable(), Var.getInlinedAt());
295 }
296 
297 static bool shouldCoalesceFragments(Function &F) {
298   // Enabling fragment coalescing reduces compiler run time when instruction
299   // referencing is enabled. However, it may cause LiveDebugVariables to create
300   // incorrect locations. Since instruction-referencing mode effectively
301   // bypasses LiveDebugVariables we only enable coalescing if the cl::opt flag
302   // has not been explicitly set and instruction-referencing is turned on.
303   switch (CoalesceAdjacentFragmentsOpt) {
304   case cl::boolOrDefault::BOU_UNSET:
305     return debuginfoShouldUseDebugInstrRef(
306         Triple(F.getParent()->getTargetTriple()));
307   case cl::boolOrDefault::BOU_TRUE:
308     return true;
309   case cl::boolOrDefault::BOU_FALSE:
310     return false;
311   }
312   llvm_unreachable("Unknown boolOrDefault value");
313 }
314 
315 namespace {
316 /// In dwarf emission, the following sequence
317 ///    1. dbg.value ... Fragment(0, 64)
318 ///    2. dbg.value ... Fragment(0, 32)
319 /// effectively sets Fragment(32, 32) to undef (each def sets all bits not in
320 /// the intersection of the fragments to having "no location"). This makes
321 /// sense for implicit location values because splitting the computed values
322 /// could be troublesome, and is probably quite uncommon.  When we convert
323 /// dbg.assigns to dbg.value+deref this kind of thing is common, and describing
324 /// a location (memory) rather than a value means we don't need to worry about
325 /// splitting any values, so we try to recover the rest of the fragment
326 /// location here.
327 /// This class performs a(nother) dataflow analysis over the function, adding
328 /// variable locations so that any bits of a variable with a memory location
329 /// have that location explicitly reinstated at each subsequent variable
330 /// location definition that that doesn't overwrite those bits. i.e. after a
331 /// variable location def, insert new defs for the memory location with
332 /// fragments for the difference of "all bits currently in memory" and "the
333 /// fragment of the second def".
334 class MemLocFragmentFill {
335   Function &Fn;
336   FunctionVarLocsBuilder *FnVarLocs;
337   const DenseSet<DebugAggregate> *VarsWithStackSlot;
338   bool CoalesceAdjacentFragments;
339 
340   // 0 = no memory location.
341   using BaseAddress = unsigned;
342   using OffsetInBitsTy = unsigned;
343   using FragTraits = IntervalMapHalfOpenInfo<OffsetInBitsTy>;
344   using FragsInMemMap = IntervalMap<
345       OffsetInBitsTy, BaseAddress,
346       IntervalMapImpl::NodeSizer<OffsetInBitsTy, BaseAddress>::LeafSize,
347       FragTraits>;
348   FragsInMemMap::Allocator IntervalMapAlloc;
349   using VarFragMap = DenseMap<unsigned, FragsInMemMap>;
350 
351   /// IDs for memory location base addresses in maps. Use 0 to indicate that
352   /// there's no memory location.
353   UniqueVector<RawLocationWrapper> Bases;
354   UniqueVector<DebugAggregate> Aggregates;
355   DenseMap<const BasicBlock *, VarFragMap> LiveIn;
356   DenseMap<const BasicBlock *, VarFragMap> LiveOut;
357 
358   struct FragMemLoc {
359     unsigned Var;
360     unsigned Base;
361     unsigned OffsetInBits;
362     unsigned SizeInBits;
363     DebugLoc DL;
364   };
365   using InsertMap = MapVector<Instruction *, SmallVector<FragMemLoc>>;
366 
367   /// BBInsertBeforeMap holds a description for the set of location defs to be
368   /// inserted after the analysis is complete. It is updated during the dataflow
369   /// and the entry for a block is CLEARED each time it is (re-)visited. After
370   /// the dataflow is complete, each block entry will contain the set of defs
371   /// calculated during the final (fixed-point) iteration.
372   DenseMap<const BasicBlock *, InsertMap> BBInsertBeforeMap;
373 
374   static bool intervalMapsAreEqual(const FragsInMemMap &A,
375                                    const FragsInMemMap &B) {
376     auto AIt = A.begin(), AEnd = A.end();
377     auto BIt = B.begin(), BEnd = B.end();
378     for (; AIt != AEnd; ++AIt, ++BIt) {
379       if (BIt == BEnd)
380         return false; // B has fewer elements than A.
381       if (AIt.start() != BIt.start() || AIt.stop() != BIt.stop())
382         return false; // Interval is different.
383       if (*AIt != *BIt)
384         return false; // Value at interval is different.
385     }
386     // AIt == AEnd. Check BIt is also now at end.
387     return BIt == BEnd;
388   }
389 
390   static bool varFragMapsAreEqual(const VarFragMap &A, const VarFragMap &B) {
391     if (A.size() != B.size())
392       return false;
393     for (const auto &APair : A) {
394       auto BIt = B.find(APair.first);
395       if (BIt == B.end())
396         return false;
397       if (!intervalMapsAreEqual(APair.second, BIt->second))
398         return false;
399     }
400     return true;
401   }
402 
403   /// Return a string for the value that \p BaseID represents.
404   std::string toString(unsigned BaseID) {
405     if (BaseID)
406       return Bases[BaseID].getVariableLocationOp(0)->getName().str();
407     else
408       return "None";
409   }
410 
411   /// Format string describing an FragsInMemMap (IntervalMap) interval.
412   std::string toString(FragsInMemMap::const_iterator It, bool Newline = true) {
413     std::string String;
414     std::stringstream S(String);
415     if (It.valid()) {
416       S << "[" << It.start() << ", " << It.stop()
417         << "): " << toString(It.value());
418     } else {
419       S << "invalid iterator (end)";
420     }
421     if (Newline)
422       S << "\n";
423     return S.str();
424   };
425 
426   FragsInMemMap meetFragments(const FragsInMemMap &A, const FragsInMemMap &B) {
427     FragsInMemMap Result(IntervalMapAlloc);
428     for (auto AIt = A.begin(), AEnd = A.end(); AIt != AEnd; ++AIt) {
429       LLVM_DEBUG(dbgs() << "a " << toString(AIt));
430       // This is basically copied from process() and inverted (process is
431       // performing something like a union whereas this is more of an
432       // intersect).
433 
434       // There's no work to do if interval `a` overlaps no fragments in map `B`.
435       if (!B.overlaps(AIt.start(), AIt.stop()))
436         continue;
437 
438       // Does StartBit intersect an existing fragment?
439       auto FirstOverlap = B.find(AIt.start());
440       assert(FirstOverlap != B.end());
441       bool IntersectStart = FirstOverlap.start() < AIt.start();
442       LLVM_DEBUG(dbgs() << "- FirstOverlap " << toString(FirstOverlap, false)
443                         << ", IntersectStart: " << IntersectStart << "\n");
444 
445       // Does EndBit intersect an existing fragment?
446       auto LastOverlap = B.find(AIt.stop());
447       bool IntersectEnd =
448           LastOverlap != B.end() && LastOverlap.start() < AIt.stop();
449       LLVM_DEBUG(dbgs() << "- LastOverlap " << toString(LastOverlap, false)
450                         << ", IntersectEnd: " << IntersectEnd << "\n");
451 
452       // Check if both ends of `a` intersect the same interval `b`.
453       if (IntersectStart && IntersectEnd && FirstOverlap == LastOverlap) {
454         // Insert `a` (`a` is contained in `b`) if the values match.
455         // [ a ]
456         // [ - b - ]
457         // -
458         // [ r ]
459         LLVM_DEBUG(dbgs() << "- a is contained within "
460                           << toString(FirstOverlap));
461         if (*AIt && *AIt == *FirstOverlap)
462           Result.insert(AIt.start(), AIt.stop(), *AIt);
463       } else {
464         // There's an overlap but `a` is not fully contained within
465         // `b`. Shorten any end-point intersections.
466         //     [ - a - ]
467         // [ - b - ]
468         // -
469         //     [ r ]
470         auto Next = FirstOverlap;
471         if (IntersectStart) {
472           LLVM_DEBUG(dbgs() << "- insert intersection of a and "
473                             << toString(FirstOverlap));
474           if (*AIt && *AIt == *FirstOverlap)
475             Result.insert(AIt.start(), FirstOverlap.stop(), *AIt);
476           ++Next;
477         }
478         // [ - a - ]
479         //     [ - b - ]
480         // -
481         //     [ r ]
482         if (IntersectEnd) {
483           LLVM_DEBUG(dbgs() << "- insert intersection of a and "
484                             << toString(LastOverlap));
485           if (*AIt && *AIt == *LastOverlap)
486             Result.insert(LastOverlap.start(), AIt.stop(), *AIt);
487         }
488 
489         // Insert all intervals in map `B` that are contained within interval
490         // `a` where the values match.
491         // [ -  - a -  - ]
492         // [ b1 ]   [ b2 ]
493         // -
494         // [ r1 ]   [ r2 ]
495         while (Next != B.end() && Next.start() < AIt.stop() &&
496                Next.stop() <= AIt.stop()) {
497           LLVM_DEBUG(dbgs()
498                      << "- insert intersection of a and " << toString(Next));
499           if (*AIt && *AIt == *Next)
500             Result.insert(Next.start(), Next.stop(), *Next);
501           ++Next;
502         }
503       }
504     }
505     return Result;
506   }
507 
508   /// Meet \p A and \p B, storing the result in \p A.
509   void meetVars(VarFragMap &A, const VarFragMap &B) {
510     // Meet A and B.
511     //
512     // Result = meet(a, b) for a in A, b in B where Var(a) == Var(b)
513     for (auto It = A.begin(), End = A.end(); It != End; ++It) {
514       unsigned AVar = It->first;
515       FragsInMemMap &AFrags = It->second;
516       auto BIt = B.find(AVar);
517       if (BIt == B.end()) {
518         A.erase(It);
519         continue; // Var has no bits defined in B.
520       }
521       LLVM_DEBUG(dbgs() << "meet fragment maps for "
522                         << Aggregates[AVar].first->getName() << "\n");
523       AFrags = meetFragments(AFrags, BIt->second);
524     }
525   }
526 
527   bool meet(const BasicBlock &BB,
528             const SmallPtrSet<BasicBlock *, 16> &Visited) {
529     LLVM_DEBUG(dbgs() << "meet block info from preds of " << BB.getName()
530                       << "\n");
531 
532     VarFragMap BBLiveIn;
533     bool FirstMeet = true;
534     // LiveIn locs for BB is the meet of the already-processed preds' LiveOut
535     // locs.
536     for (auto I = pred_begin(&BB), E = pred_end(&BB); I != E; I++) {
537       // Ignore preds that haven't been processed yet. This is essentially the
538       // same as initialising all variables to implicit top value (⊤) which is
539       // the identity value for the meet operation.
540       const BasicBlock *Pred = *I;
541       if (!Visited.count(Pred))
542         continue;
543 
544       auto PredLiveOut = LiveOut.find(Pred);
545       assert(PredLiveOut != LiveOut.end());
546 
547       if (FirstMeet) {
548         LLVM_DEBUG(dbgs() << "BBLiveIn = " << Pred->getName() << "\n");
549         BBLiveIn = PredLiveOut->second;
550         FirstMeet = false;
551       } else {
552         LLVM_DEBUG(dbgs() << "BBLiveIn = meet BBLiveIn, " << Pred->getName()
553                           << "\n");
554         meetVars(BBLiveIn, PredLiveOut->second);
555       }
556 
557       // An empty set is ⊥ for the intersect-like meet operation. If we've
558       // already got ⊥ there's no need to run the code - we know the result is
559       // ⊥ since `meet(a, ⊥) = ⊥`.
560       if (BBLiveIn.size() == 0)
561         break;
562     }
563 
564     auto CurrentLiveInEntry = LiveIn.find(&BB);
565     // If there's no LiveIn entry for the block yet, add it.
566     if (CurrentLiveInEntry == LiveIn.end()) {
567       LLVM_DEBUG(dbgs() << "change=true (first) on meet on " << BB.getName()
568                         << "\n");
569       LiveIn[&BB] = std::move(BBLiveIn);
570       return /*Changed=*/true;
571     }
572 
573     // If the LiveIn set has changed (expensive check) update it and return
574     // true.
575     if (!varFragMapsAreEqual(BBLiveIn, CurrentLiveInEntry->second)) {
576       LLVM_DEBUG(dbgs() << "change=true on meet on " << BB.getName() << "\n");
577       CurrentLiveInEntry->second = std::move(BBLiveIn);
578       return /*Changed=*/true;
579     }
580 
581     LLVM_DEBUG(dbgs() << "change=false on meet on " << BB.getName() << "\n");
582     return /*Changed=*/false;
583   }
584 
585   void insertMemLoc(BasicBlock &BB, Instruction &Before, unsigned Var,
586                     unsigned StartBit, unsigned EndBit, unsigned Base,
587                     DebugLoc DL) {
588     assert(StartBit < EndBit && "Cannot create fragment of size <= 0");
589     if (!Base)
590       return;
591     FragMemLoc Loc;
592     Loc.Var = Var;
593     Loc.OffsetInBits = StartBit;
594     Loc.SizeInBits = EndBit - StartBit;
595     assert(Base && "Expected a non-zero ID for Base address");
596     Loc.Base = Base;
597     Loc.DL = DL;
598     BBInsertBeforeMap[&BB][&Before].push_back(Loc);
599     LLVM_DEBUG(dbgs() << "Add mem def for " << Aggregates[Var].first->getName()
600                       << " bits [" << StartBit << ", " << EndBit << ")\n");
601   }
602 
603   /// Inserts a new dbg def if the interval found when looking up \p StartBit
604   /// in \p FragMap starts before \p StartBit or ends after \p EndBit (which
605   /// indicates - assuming StartBit->EndBit has just been inserted - that the
606   /// slice has been coalesced in the map).
607   void coalesceFragments(BasicBlock &BB, Instruction &Before, unsigned Var,
608                          unsigned StartBit, unsigned EndBit, unsigned Base,
609                          DebugLoc DL, const FragsInMemMap &FragMap) {
610     if (!CoalesceAdjacentFragments)
611       return;
612     // We've inserted the location into the map. The map will have coalesced
613     // adjacent intervals (variable fragments) that describe the same memory
614     // location. Use this knowledge to insert a debug location that describes
615     // that coalesced fragment. This may eclipse other locs we've just
616     // inserted. This is okay as redundant locs will be cleaned up later.
617     auto CoalescedFrag = FragMap.find(StartBit);
618     // Bail if no coalescing has taken place.
619     if (CoalescedFrag.start() == StartBit && CoalescedFrag.stop() == EndBit)
620       return;
621 
622     LLVM_DEBUG(dbgs() << "- Insert loc for bits " << CoalescedFrag.start()
623                       << " to " << CoalescedFrag.stop() << "\n");
624     insertMemLoc(BB, Before, Var, CoalescedFrag.start(), CoalescedFrag.stop(),
625                  Base, DL);
626   }
627 
628   void addDef(const VarLocInfo &VarLoc, Instruction &Before, BasicBlock &BB,
629               VarFragMap &LiveSet) {
630     DebugVariable DbgVar = FnVarLocs->getVariable(VarLoc.VariableID);
631     if (skipVariable(DbgVar.getVariable()))
632       return;
633     // Don't bother doing anything for this variables if we know it's fully
634     // promoted. We're only interested in variables that (sometimes) live on
635     // the stack here.
636     if (!VarsWithStackSlot->count(getAggregate(DbgVar)))
637       return;
638     unsigned Var = Aggregates.insert(
639         DebugAggregate(DbgVar.getVariable(), VarLoc.DL.getInlinedAt()));
640 
641     // [StartBit: EndBit) are the bits affected by this def.
642     const DIExpression *DIExpr = VarLoc.Expr;
643     unsigned StartBit;
644     unsigned EndBit;
645     if (auto Frag = DIExpr->getFragmentInfo()) {
646       StartBit = Frag->OffsetInBits;
647       EndBit = StartBit + Frag->SizeInBits;
648     } else {
649       assert(static_cast<bool>(DbgVar.getVariable()->getSizeInBits()));
650       StartBit = 0;
651       EndBit = *DbgVar.getVariable()->getSizeInBits();
652     }
653 
654     // We will only fill fragments for simple memory-describing dbg.value
655     // intrinsics. If the fragment offset is the same as the offset from the
656     // base pointer, do The Thing, otherwise fall back to normal dbg.value
657     // behaviour. AssignmentTrackingLowering has generated DIExpressions
658     // written in terms of the base pointer.
659     // TODO: Remove this condition since the fragment offset doesn't always
660     // equal the offset from base pointer (e.g. for a SROA-split variable).
661     const auto DerefOffsetInBytes = getDerefOffsetInBytes(DIExpr);
662     const unsigned Base =
663         DerefOffsetInBytes && *DerefOffsetInBytes * 8 == StartBit
664             ? Bases.insert(VarLoc.Values)
665             : 0;
666     LLVM_DEBUG(dbgs() << "DEF " << DbgVar.getVariable()->getName() << " ["
667                       << StartBit << ", " << EndBit << "): " << toString(Base)
668                       << "\n");
669 
670     // First of all, any locs that use mem that are disrupted need reinstating.
671     // Unfortunately, IntervalMap doesn't let us insert intervals that overlap
672     // with existing intervals so this code involves a lot of fiddling around
673     // with intervals to do that manually.
674     auto FragIt = LiveSet.find(Var);
675 
676     // Check if the variable does not exist in the map.
677     if (FragIt == LiveSet.end()) {
678       // Add this variable to the BB map.
679       auto P = LiveSet.try_emplace(Var, FragsInMemMap(IntervalMapAlloc));
680       assert(P.second && "Var already in map?");
681       // Add the interval to the fragment map.
682       P.first->second.insert(StartBit, EndBit, Base);
683       return;
684     }
685     // The variable has an entry in the map.
686 
687     FragsInMemMap &FragMap = FragIt->second;
688     // First check the easy case: the new fragment `f` doesn't overlap with any
689     // intervals.
690     if (!FragMap.overlaps(StartBit, EndBit)) {
691       LLVM_DEBUG(dbgs() << "- No overlaps\n");
692       FragMap.insert(StartBit, EndBit, Base);
693       coalesceFragments(BB, Before, Var, StartBit, EndBit, Base, VarLoc.DL,
694                         FragMap);
695       return;
696     }
697     // There is at least one overlap.
698 
699     // Does StartBit intersect an existing fragment?
700     auto FirstOverlap = FragMap.find(StartBit);
701     assert(FirstOverlap != FragMap.end());
702     bool IntersectStart = FirstOverlap.start() < StartBit;
703 
704     // Does EndBit intersect an existing fragment?
705     auto LastOverlap = FragMap.find(EndBit);
706     bool IntersectEnd = LastOverlap.valid() && LastOverlap.start() < EndBit;
707 
708     // Check if both ends of `f` intersect the same interval `i`.
709     if (IntersectStart && IntersectEnd && FirstOverlap == LastOverlap) {
710       LLVM_DEBUG(dbgs() << "- Intersect single interval @ both ends\n");
711       // Shorten `i` so that there's space to insert `f`.
712       //      [ f ]
713       // [  -   i   -  ]
714       // +
715       // [ i ][ f ][ i ]
716 
717       // Save values for use after inserting a new interval.
718       auto EndBitOfOverlap = FirstOverlap.stop();
719       unsigned OverlapValue = FirstOverlap.value();
720 
721       // Shorten the overlapping interval.
722       FirstOverlap.setStop(StartBit);
723       insertMemLoc(BB, Before, Var, FirstOverlap.start(), StartBit,
724                    OverlapValue, VarLoc.DL);
725 
726       // Insert a new interval to represent the end part.
727       FragMap.insert(EndBit, EndBitOfOverlap, OverlapValue);
728       insertMemLoc(BB, Before, Var, EndBit, EndBitOfOverlap, OverlapValue,
729                    VarLoc.DL);
730 
731       // Insert the new (middle) fragment now there is space.
732       FragMap.insert(StartBit, EndBit, Base);
733     } else {
734       // There's an overlap but `f` may not be fully contained within
735       // `i`. Shorten any end-point intersections so that we can then
736       // insert `f`.
737       //      [ - f - ]
738       // [ - i - ]
739       // |   |
740       // [ i ]
741       // Shorten any end-point intersections.
742       if (IntersectStart) {
743         LLVM_DEBUG(dbgs() << "- Intersect interval at start\n");
744         // Split off at the intersection.
745         FirstOverlap.setStop(StartBit);
746         insertMemLoc(BB, Before, Var, FirstOverlap.start(), StartBit,
747                      *FirstOverlap, VarLoc.DL);
748       }
749       // [ - f - ]
750       //      [ - i - ]
751       //          |   |
752       //          [ i ]
753       if (IntersectEnd) {
754         LLVM_DEBUG(dbgs() << "- Intersect interval at end\n");
755         // Split off at the intersection.
756         LastOverlap.setStart(EndBit);
757         insertMemLoc(BB, Before, Var, EndBit, LastOverlap.stop(), *LastOverlap,
758                      VarLoc.DL);
759       }
760 
761       LLVM_DEBUG(dbgs() << "- Erase intervals contained within\n");
762       // FirstOverlap and LastOverlap have been shortened such that they're
763       // no longer overlapping with [StartBit, EndBit). Delete any overlaps
764       // that remain (these will be fully contained within `f`).
765       // [ - f - ]       }
766       //      [ - i - ]  } Intersection shortening that has happened above.
767       //          |   |  }
768       //          [ i ]  }
769       // -----------------
770       // [i2 ]           } Intervals fully contained within `f` get erased.
771       // -----------------
772       // [ - f - ][ i ]  } Completed insertion.
773       auto It = FirstOverlap;
774       if (IntersectStart)
775         ++It; // IntersectStart: first overlap has been shortened.
776       while (It.valid() && It.start() >= StartBit && It.stop() <= EndBit) {
777         LLVM_DEBUG(dbgs() << "- Erase " << toString(It));
778         It.erase(); // This increments It after removing the interval.
779       }
780       // We've dealt with all the overlaps now!
781       assert(!FragMap.overlaps(StartBit, EndBit));
782       LLVM_DEBUG(dbgs() << "- Insert DEF into now-empty space\n");
783       FragMap.insert(StartBit, EndBit, Base);
784     }
785 
786     coalesceFragments(BB, Before, Var, StartBit, EndBit, Base, VarLoc.DL,
787                       FragMap);
788   }
789 
790   bool skipVariable(const DILocalVariable *V) { return !V->getSizeInBits(); }
791 
792   void process(BasicBlock &BB, VarFragMap &LiveSet) {
793     BBInsertBeforeMap[&BB].clear();
794     for (auto &I : BB) {
795       if (const auto *Locs = FnVarLocs->getWedge(&I)) {
796         for (const VarLocInfo &Loc : *Locs) {
797           addDef(Loc, I, *I.getParent(), LiveSet);
798         }
799       }
800     }
801   }
802 
803 public:
804   MemLocFragmentFill(Function &Fn,
805                      const DenseSet<DebugAggregate> *VarsWithStackSlot,
806                      bool CoalesceAdjacentFragments)
807       : Fn(Fn), VarsWithStackSlot(VarsWithStackSlot),
808         CoalesceAdjacentFragments(CoalesceAdjacentFragments) {}
809 
810   /// Add variable locations to \p FnVarLocs so that any bits of a variable
811   /// with a memory location have that location explicitly reinstated at each
812   /// subsequent variable location definition that that doesn't overwrite those
813   /// bits. i.e. after a variable location def, insert new defs for the memory
814   /// location with fragments for the difference of "all bits currently in
815   /// memory" and "the fragment of the second def". e.g.
816   ///
817   ///     Before:
818   ///
819   ///     var x bits 0 to 63:  value in memory
820   ///     more instructions
821   ///     var x bits 0 to 31:  value is %0
822   ///
823   ///     After:
824   ///
825   ///     var x bits 0 to 63:  value in memory
826   ///     more instructions
827   ///     var x bits 0 to 31:  value is %0
828   ///     var x bits 32 to 61: value in memory ; <-- new loc def
829   ///
830   void run(FunctionVarLocsBuilder *FnVarLocs) {
831     if (!EnableMemLocFragFill)
832       return;
833 
834     this->FnVarLocs = FnVarLocs;
835 
836     // Prepare for traversal.
837     //
838     ReversePostOrderTraversal<Function *> RPOT(&Fn);
839     std::priority_queue<unsigned int, std::vector<unsigned int>,
840                         std::greater<unsigned int>>
841         Worklist;
842     std::priority_queue<unsigned int, std::vector<unsigned int>,
843                         std::greater<unsigned int>>
844         Pending;
845     DenseMap<unsigned int, BasicBlock *> OrderToBB;
846     DenseMap<BasicBlock *, unsigned int> BBToOrder;
847     { // Init OrderToBB and BBToOrder.
848       unsigned int RPONumber = 0;
849       for (auto RI = RPOT.begin(), RE = RPOT.end(); RI != RE; ++RI) {
850         OrderToBB[RPONumber] = *RI;
851         BBToOrder[*RI] = RPONumber;
852         Worklist.push(RPONumber);
853         ++RPONumber;
854       }
855       LiveIn.init(RPONumber);
856       LiveOut.init(RPONumber);
857     }
858 
859     // Perform the traversal.
860     //
861     // This is a standard "intersect of predecessor outs" dataflow problem. To
862     // solve it, we perform meet() and process() using the two worklist method
863     // until the LiveIn data for each block becomes unchanging.
864     //
865     // This dataflow is essentially working on maps of sets and at each meet we
866     // intersect the maps and the mapped sets. So, initialized live-in maps
867     // monotonically decrease in value throughout the dataflow.
868     SmallPtrSet<BasicBlock *, 16> Visited;
869     while (!Worklist.empty() || !Pending.empty()) {
870       // We track what is on the pending worklist to avoid inserting the same
871       // thing twice.  We could avoid this with a custom priority queue, but
872       // this is probably not worth it.
873       SmallPtrSet<BasicBlock *, 16> OnPending;
874       LLVM_DEBUG(dbgs() << "Processing Worklist\n");
875       while (!Worklist.empty()) {
876         BasicBlock *BB = OrderToBB[Worklist.top()];
877         LLVM_DEBUG(dbgs() << "\nPop BB " << BB->getName() << "\n");
878         Worklist.pop();
879         bool InChanged = meet(*BB, Visited);
880         // Always consider LiveIn changed on the first visit.
881         InChanged |= Visited.insert(BB).second;
882         if (InChanged) {
883           LLVM_DEBUG(dbgs()
884                      << BB->getName() << " has new InLocs, process it\n");
885           //  Mutate a copy of LiveIn while processing BB. Once we've processed
886           //  the terminator LiveSet is the LiveOut set for BB.
887           //  This is an expensive copy!
888           VarFragMap LiveSet = LiveIn[BB];
889 
890           // Process the instructions in the block.
891           process(*BB, LiveSet);
892 
893           // Relatively expensive check: has anything changed in LiveOut for BB?
894           if (!varFragMapsAreEqual(LiveOut[BB], LiveSet)) {
895             LLVM_DEBUG(dbgs() << BB->getName()
896                               << " has new OutLocs, add succs to worklist: [ ");
897             LiveOut[BB] = std::move(LiveSet);
898             for (auto I = succ_begin(BB), E = succ_end(BB); I != E; I++) {
899               if (OnPending.insert(*I).second) {
900                 LLVM_DEBUG(dbgs() << I->getName() << " ");
901                 Pending.push(BBToOrder[*I]);
902               }
903             }
904             LLVM_DEBUG(dbgs() << "]\n");
905           }
906         }
907       }
908       Worklist.swap(Pending);
909       // At this point, pending must be empty, since it was just the empty
910       // worklist
911       assert(Pending.empty() && "Pending should be empty");
912     }
913 
914     // Insert new location defs.
915     for (auto &Pair : BBInsertBeforeMap) {
916       InsertMap &Map = Pair.second;
917       for (auto &Pair : Map) {
918         Instruction *InsertBefore = Pair.first;
919         assert(InsertBefore && "should never be null");
920         auto FragMemLocs = Pair.second;
921         auto &Ctx = Fn.getContext();
922 
923         for (auto &FragMemLoc : FragMemLocs) {
924           DIExpression *Expr = DIExpression::get(Ctx, std::nullopt);
925           if (FragMemLoc.SizeInBits !=
926               *Aggregates[FragMemLoc.Var].first->getSizeInBits())
927             Expr = *DIExpression::createFragmentExpression(
928                 Expr, FragMemLoc.OffsetInBits, FragMemLoc.SizeInBits);
929           Expr = DIExpression::prepend(Expr, DIExpression::DerefAfter,
930                                        FragMemLoc.OffsetInBits / 8);
931           DebugVariable Var(Aggregates[FragMemLoc.Var].first, Expr,
932                             FragMemLoc.DL.getInlinedAt());
933           FnVarLocs->addVarLoc(InsertBefore, Var, Expr, FragMemLoc.DL,
934                                Bases[FragMemLoc.Base]);
935         }
936       }
937     }
938   }
939 };
940 
941 /// AssignmentTrackingLowering encapsulates a dataflow analysis over a function
942 /// that interprets assignment tracking debug info metadata and stores in IR to
943 /// create a map of variable locations.
944 class AssignmentTrackingLowering {
945 public:
946   /// The kind of location in use for a variable, where Mem is the stack home,
947   /// Val is an SSA value or const, and None means that there is not one single
948   /// kind (either because there are multiple or because there is none; it may
949   /// prove useful to split this into two values in the future).
950   ///
951   /// LocKind is a join-semilattice with the partial order:
952   /// None > Mem, Val
953   ///
954   /// i.e.
955   /// join(Mem, Mem)   = Mem
956   /// join(Val, Val)   = Val
957   /// join(Mem, Val)   = None
958   /// join(None, Mem)  = None
959   /// join(None, Val)  = None
960   /// join(None, None) = None
961   ///
962   /// Note: the order is not `None > Val > Mem` because we're using DIAssignID
963   /// to name assignments and are not tracking the actual stored values.
964   /// Therefore currently there's no way to ensure that Mem values and Val
965   /// values are the same. This could be a future extension, though it's not
966   /// clear that many additional locations would be recovered that way in
967   /// practice as the likelihood of this sitation arising naturally seems
968   /// incredibly low.
969   enum class LocKind { Mem, Val, None };
970 
971   /// An abstraction of the assignment of a value to a variable or memory
972   /// location.
973   ///
974   /// An Assignment is Known or NoneOrPhi. A Known Assignment means we have a
975   /// DIAssignID ptr that represents it. NoneOrPhi means that we don't (or
976   /// can't) know the ID of the last assignment that took place.
977   ///
978   /// The Status of the Assignment (Known or NoneOrPhi) is another
979   /// join-semilattice. The partial order is:
980   /// NoneOrPhi > Known {id_0, id_1, ...id_N}
981   ///
982   /// i.e. for all values x and y where x != y:
983   /// join(x, x) = x
984   /// join(x, y) = NoneOrPhi
985   struct Assignment {
986     enum S { Known, NoneOrPhi } Status;
987     /// ID of the assignment. nullptr if Status is not Known.
988     DIAssignID *ID;
989     /// The dbg.assign that marks this dbg-def. Mem-defs don't use this field.
990     /// May be nullptr.
991     DbgAssignIntrinsic *Source;
992 
993     bool isSameSourceAssignment(const Assignment &Other) const {
994       // Don't include Source in the equality check. Assignments are
995       // defined by their ID, not debug intrinsic(s).
996       return std::tie(Status, ID) == std::tie(Other.Status, Other.ID);
997     }
998     void dump(raw_ostream &OS) {
999       static const char *LUT[] = {"Known", "NoneOrPhi"};
1000       OS << LUT[Status] << "(id=";
1001       if (ID)
1002         OS << ID;
1003       else
1004         OS << "null";
1005       OS << ", s=";
1006       if (Source)
1007         OS << *Source;
1008       else
1009         OS << "null";
1010       OS << ")";
1011     }
1012 
1013     static Assignment make(DIAssignID *ID, DbgAssignIntrinsic *Source) {
1014       return Assignment(Known, ID, Source);
1015     }
1016     static Assignment makeFromMemDef(DIAssignID *ID) {
1017       return Assignment(Known, ID, nullptr);
1018     }
1019     static Assignment makeNoneOrPhi() {
1020       return Assignment(NoneOrPhi, nullptr, nullptr);
1021     }
1022     // Again, need a Top value?
1023     Assignment()
1024         : Status(NoneOrPhi), ID(nullptr), Source(nullptr) {
1025     } // Can we delete this?
1026     Assignment(S Status, DIAssignID *ID, DbgAssignIntrinsic *Source)
1027         : Status(Status), ID(ID), Source(Source) {
1028       // If the Status is Known then we expect there to be an assignment ID.
1029       assert(Status == NoneOrPhi || ID);
1030     }
1031   };
1032 
1033   using AssignmentMap = SmallVector<Assignment>;
1034   using LocMap = SmallVector<LocKind>;
1035   using OverlapMap = DenseMap<VariableID, SmallVector<VariableID>>;
1036   using UntaggedStoreAssignmentMap =
1037       DenseMap<const Instruction *,
1038                SmallVector<std::pair<VariableID, at::AssignmentInfo>>>;
1039 
1040 private:
1041   /// The highest numbered VariableID for partially promoted variables plus 1,
1042   /// the values for which start at 1.
1043   unsigned TrackedVariablesVectorSize = 0;
1044   /// Map a variable to the set of variables that it fully contains.
1045   OverlapMap VarContains;
1046   /// Map untagged stores to the variable fragments they assign to. Used by
1047   /// processUntaggedInstruction.
1048   UntaggedStoreAssignmentMap UntaggedStoreVars;
1049 
1050   // Machinery to defer inserting dbg.values.
1051   using InsertMap = MapVector<Instruction *, SmallVector<VarLocInfo>>;
1052   InsertMap InsertBeforeMap;
1053   /// Clear the location definitions currently cached for insertion after /p
1054   /// After.
1055   void resetInsertionPoint(Instruction &After);
1056   void emitDbgValue(LocKind Kind, const DbgVariableIntrinsic *Source,
1057                     Instruction *After);
1058 
1059   static bool mapsAreEqual(const BitVector &Mask, const AssignmentMap &A,
1060                            const AssignmentMap &B) {
1061     return llvm::all_of(Mask.set_bits(), [&](unsigned VarID) {
1062       return A[VarID].isSameSourceAssignment(B[VarID]);
1063     });
1064   }
1065 
1066   /// Represents the stack and debug assignments in a block. Used to describe
1067   /// the live-in and live-out values for blocks, as well as the "current"
1068   /// value as we process each instruction in a block.
1069   struct BlockInfo {
1070     /// The set of variables (VariableID) being tracked in this block.
1071     BitVector VariableIDsInBlock;
1072     /// Dominating assignment to memory for each variable, indexed by
1073     /// VariableID.
1074     AssignmentMap StackHomeValue;
1075     /// Dominating assignemnt to each variable, indexed by VariableID.
1076     AssignmentMap DebugValue;
1077     /// Location kind for each variable. LiveLoc indicates whether the
1078     /// dominating assignment in StackHomeValue (LocKind::Mem), DebugValue
1079     /// (LocKind::Val), or neither (LocKind::None) is valid, in that order of
1080     /// preference. This cannot be derived by inspecting DebugValue and
1081     /// StackHomeValue due to the fact that there's no distinction in
1082     /// Assignment (the class) between whether an assignment is unknown or a
1083     /// merge of multiple assignments (both are Status::NoneOrPhi). In other
1084     /// words, the memory location may well be valid while both DebugValue and
1085     /// StackHomeValue contain Assignments that have a Status of NoneOrPhi.
1086     /// Indexed by VariableID.
1087     LocMap LiveLoc;
1088 
1089   public:
1090     enum AssignmentKind { Stack, Debug };
1091     const AssignmentMap &getAssignmentMap(AssignmentKind Kind) const {
1092       switch (Kind) {
1093       case Stack:
1094         return StackHomeValue;
1095       case Debug:
1096         return DebugValue;
1097       }
1098       llvm_unreachable("Unknown AssignmentKind");
1099     }
1100     AssignmentMap &getAssignmentMap(AssignmentKind Kind) {
1101       return const_cast<AssignmentMap &>(
1102           const_cast<const BlockInfo *>(this)->getAssignmentMap(Kind));
1103     }
1104 
1105     bool isVariableTracked(VariableID Var) const {
1106       return VariableIDsInBlock[static_cast<unsigned>(Var)];
1107     }
1108 
1109     const Assignment &getAssignment(AssignmentKind Kind, VariableID Var) const {
1110       assert(isVariableTracked(Var) && "Var not tracked in block");
1111       return getAssignmentMap(Kind)[static_cast<unsigned>(Var)];
1112     }
1113 
1114     LocKind getLocKind(VariableID Var) const {
1115       assert(isVariableTracked(Var) && "Var not tracked in block");
1116       return LiveLoc[static_cast<unsigned>(Var)];
1117     }
1118 
1119     /// Set LocKind for \p Var only: does not set LocKind for VariableIDs of
1120     /// fragments contained win \p Var.
1121     void setLocKind(VariableID Var, LocKind K) {
1122       VariableIDsInBlock.set(static_cast<unsigned>(Var));
1123       LiveLoc[static_cast<unsigned>(Var)] = K;
1124     }
1125 
1126     /// Set the assignment in the \p Kind assignment map for \p Var only: does
1127     /// not set the assignment for VariableIDs of fragments contained win \p
1128     /// Var.
1129     void setAssignment(AssignmentKind Kind, VariableID Var,
1130                        const Assignment &AV) {
1131       VariableIDsInBlock.set(static_cast<unsigned>(Var));
1132       getAssignmentMap(Kind)[static_cast<unsigned>(Var)] = AV;
1133     }
1134 
1135     /// Return true if there is an assignment matching \p AV in the \p Kind
1136     /// assignment map. Does consider assignments for VariableIDs of fragments
1137     /// contained win \p Var.
1138     bool hasAssignment(AssignmentKind Kind, VariableID Var,
1139                        const Assignment &AV) const {
1140       if (!isVariableTracked(Var))
1141         return false;
1142       return AV.isSameSourceAssignment(getAssignment(Kind, Var));
1143     }
1144 
1145     /// Compare every element in each map to determine structural equality
1146     /// (slow).
1147     bool operator==(const BlockInfo &Other) const {
1148       return VariableIDsInBlock == Other.VariableIDsInBlock &&
1149              LiveLoc == Other.LiveLoc &&
1150              mapsAreEqual(VariableIDsInBlock, StackHomeValue,
1151                           Other.StackHomeValue) &&
1152              mapsAreEqual(VariableIDsInBlock, DebugValue, Other.DebugValue);
1153     }
1154     bool operator!=(const BlockInfo &Other) const { return !(*this == Other); }
1155     bool isValid() {
1156       return LiveLoc.size() == DebugValue.size() &&
1157              LiveLoc.size() == StackHomeValue.size();
1158     }
1159 
1160     /// Clear everything and initialise with ⊤-values for all variables.
1161     void init(int NumVars) {
1162       StackHomeValue.clear();
1163       DebugValue.clear();
1164       LiveLoc.clear();
1165       VariableIDsInBlock = BitVector(NumVars);
1166       StackHomeValue.insert(StackHomeValue.begin(), NumVars,
1167                             Assignment::makeNoneOrPhi());
1168       DebugValue.insert(DebugValue.begin(), NumVars,
1169                         Assignment::makeNoneOrPhi());
1170       LiveLoc.insert(LiveLoc.begin(), NumVars, LocKind::None);
1171     }
1172 
1173     /// Helper for join.
1174     template <typename ElmtType, typename FnInputType>
1175     static void joinElmt(int Index, SmallVector<ElmtType> &Target,
1176                          const SmallVector<ElmtType> &A,
1177                          const SmallVector<ElmtType> &B,
1178                          ElmtType (*Fn)(FnInputType, FnInputType)) {
1179       Target[Index] = Fn(A[Index], B[Index]);
1180     }
1181 
1182     /// See comment for AssignmentTrackingLowering::joinBlockInfo.
1183     static BlockInfo join(const BlockInfo &A, const BlockInfo &B, int NumVars) {
1184       // Join A and B.
1185       //
1186       // Intersect = join(a, b) for a in A, b in B where Var(a) == Var(b)
1187       // Difference = join(x, ⊤) for x where Var(x) is in A xor B
1188       // Join = Intersect ∪ Difference
1189       //
1190       // This is achieved by performing a join on elements from A and B with
1191       // variables common to both A and B (join elements indexed by var
1192       // intersect), then adding ⊤-value elements for vars in A xor B. The
1193       // latter part is equivalent to performing join on elements with variables
1194       // in A xor B with the ⊤-value for the map element since join(x, ⊤) = ⊤.
1195       // BlockInfo::init initializes all variable entries to the ⊤ value so we
1196       // don't need to explicitly perform that step as Join.VariableIDsInBlock
1197       // is set to the union of the variables in A and B at the end of this
1198       // function.
1199       BlockInfo Join;
1200       Join.init(NumVars);
1201 
1202       BitVector Intersect = A.VariableIDsInBlock;
1203       Intersect &= B.VariableIDsInBlock;
1204 
1205       for (auto VarID : Intersect.set_bits()) {
1206         joinElmt(VarID, Join.LiveLoc, A.LiveLoc, B.LiveLoc, joinKind);
1207         joinElmt(VarID, Join.DebugValue, A.DebugValue, B.DebugValue,
1208                  joinAssignment);
1209         joinElmt(VarID, Join.StackHomeValue, A.StackHomeValue, B.StackHomeValue,
1210                  joinAssignment);
1211       }
1212 
1213       Join.VariableIDsInBlock = A.VariableIDsInBlock;
1214       Join.VariableIDsInBlock |= B.VariableIDsInBlock;
1215       assert(Join.isValid());
1216       return Join;
1217     }
1218   };
1219 
1220   Function &Fn;
1221   const DataLayout &Layout;
1222   const DenseSet<DebugAggregate> *VarsWithStackSlot;
1223   FunctionVarLocsBuilder *FnVarLocs;
1224   DenseMap<const BasicBlock *, BlockInfo> LiveIn;
1225   DenseMap<const BasicBlock *, BlockInfo> LiveOut;
1226 
1227   /// Helper for process methods to track variables touched each frame.
1228   DenseSet<VariableID> VarsTouchedThisFrame;
1229 
1230   /// The set of variables that sometimes are not located in their stack home.
1231   DenseSet<DebugAggregate> NotAlwaysStackHomed;
1232 
1233   VariableID getVariableID(const DebugVariable &Var) {
1234     return static_cast<VariableID>(FnVarLocs->insertVariable(Var));
1235   }
1236 
1237   /// Join the LiveOut values of preds that are contained in \p Visited into
1238   /// LiveIn[BB]. Return True if LiveIn[BB] has changed as a result. LiveIn[BB]
1239   /// values monotonically increase. See the @link joinMethods join methods
1240   /// @endlink documentation for more info.
1241   bool join(const BasicBlock &BB, const SmallPtrSet<BasicBlock *, 16> &Visited);
1242   ///@name joinMethods
1243   /// Functions that implement `join` (the least upper bound) for the
1244   /// join-semilattice types used in the dataflow. There is an explicit bottom
1245   /// value (⊥) for some types and and explicit top value (⊤) for all types.
1246   /// By definition:
1247   ///
1248   ///     Join(A, B) >= A && Join(A, B) >= B
1249   ///     Join(A, ⊥) = A
1250   ///     Join(A, ⊤) = ⊤
1251   ///
1252   /// These invariants are important for monotonicity.
1253   ///
1254   /// For the map-type functions, all unmapped keys in an empty map are
1255   /// associated with a bottom value (⊥). This represents their values being
1256   /// unknown. Unmapped keys in non-empty maps (joining two maps with a key
1257   /// only present in one) represents either a variable going out of scope or
1258   /// dropped debug info. It is assumed the key is associated with a top value
1259   /// (⊤) in this case (unknown location / assignment).
1260   ///@{
1261   static LocKind joinKind(LocKind A, LocKind B);
1262   static Assignment joinAssignment(const Assignment &A, const Assignment &B);
1263   BlockInfo joinBlockInfo(const BlockInfo &A, const BlockInfo &B);
1264   ///@}
1265 
1266   /// Process the instructions in \p BB updating \p LiveSet along the way. \p
1267   /// LiveSet must be initialized with the current live-in locations before
1268   /// calling this.
1269   void process(BasicBlock &BB, BlockInfo *LiveSet);
1270   ///@name processMethods
1271   /// Methods to process instructions in order to update the LiveSet (current
1272   /// location information).
1273   ///@{
1274   void processNonDbgInstruction(Instruction &I, BlockInfo *LiveSet);
1275   void processDbgInstruction(DbgInfoIntrinsic &I, BlockInfo *LiveSet);
1276   /// Update \p LiveSet after encountering an instruction with a DIAssignID
1277   /// attachment, \p I.
1278   void processTaggedInstruction(Instruction &I, BlockInfo *LiveSet);
1279   /// Update \p LiveSet after encountering an instruciton without a DIAssignID
1280   /// attachment, \p I.
1281   void processUntaggedInstruction(Instruction &I, BlockInfo *LiveSet);
1282   void processDbgAssign(DbgAssignIntrinsic &DAI, BlockInfo *LiveSet);
1283   void processDbgValue(DbgValueInst &DVI, BlockInfo *LiveSet);
1284   /// Add an assignment to memory for the variable /p Var.
1285   void addMemDef(BlockInfo *LiveSet, VariableID Var, const Assignment &AV);
1286   /// Add an assignment to the variable /p Var.
1287   void addDbgDef(BlockInfo *LiveSet, VariableID Var, const Assignment &AV);
1288   ///@}
1289 
1290   /// Set the LocKind for \p Var.
1291   void setLocKind(BlockInfo *LiveSet, VariableID Var, LocKind K);
1292   /// Get the live LocKind for a \p Var. Requires addMemDef or addDbgDef to
1293   /// have been called for \p Var first.
1294   LocKind getLocKind(BlockInfo *LiveSet, VariableID Var);
1295   /// Return true if \p Var has an assignment in \p M matching \p AV.
1296   bool hasVarWithAssignment(BlockInfo *LiveSet, BlockInfo::AssignmentKind Kind,
1297                             VariableID Var, const Assignment &AV);
1298   /// Return the set of VariableIDs corresponding the fragments contained fully
1299   /// within the variable/fragment \p Var.
1300   ArrayRef<VariableID> getContainedFragments(VariableID Var) const;
1301 
1302   /// Mark \p Var as having been touched this frame. Note, this applies only
1303   /// to the exact fragment \p Var and not to any fragments contained within.
1304   void touchFragment(VariableID Var);
1305 
1306   /// Emit info for variables that are fully promoted.
1307   bool emitPromotedVarLocs(FunctionVarLocsBuilder *FnVarLocs);
1308 
1309 public:
1310   AssignmentTrackingLowering(Function &Fn, const DataLayout &Layout,
1311                              const DenseSet<DebugAggregate> *VarsWithStackSlot)
1312       : Fn(Fn), Layout(Layout), VarsWithStackSlot(VarsWithStackSlot) {}
1313   /// Run the analysis, adding variable location info to \p FnVarLocs. Returns
1314   /// true if any variable locations have been added to FnVarLocs.
1315   bool run(FunctionVarLocsBuilder *FnVarLocs);
1316 };
1317 } // namespace
1318 
1319 ArrayRef<VariableID>
1320 AssignmentTrackingLowering::getContainedFragments(VariableID Var) const {
1321   auto R = VarContains.find(Var);
1322   if (R == VarContains.end())
1323     return std::nullopt;
1324   return R->second;
1325 }
1326 
1327 void AssignmentTrackingLowering::touchFragment(VariableID Var) {
1328   VarsTouchedThisFrame.insert(Var);
1329 }
1330 
1331 void AssignmentTrackingLowering::setLocKind(BlockInfo *LiveSet, VariableID Var,
1332                                             LocKind K) {
1333   auto SetKind = [this](BlockInfo *LiveSet, VariableID Var, LocKind K) {
1334     LiveSet->setLocKind(Var, K);
1335     touchFragment(Var);
1336   };
1337   SetKind(LiveSet, Var, K);
1338 
1339   // Update the LocKind for all fragments contained within Var.
1340   for (VariableID Frag : getContainedFragments(Var))
1341     SetKind(LiveSet, Frag, K);
1342 }
1343 
1344 AssignmentTrackingLowering::LocKind
1345 AssignmentTrackingLowering::getLocKind(BlockInfo *LiveSet, VariableID Var) {
1346   return LiveSet->getLocKind(Var);
1347 }
1348 
1349 void AssignmentTrackingLowering::addMemDef(BlockInfo *LiveSet, VariableID Var,
1350                                            const Assignment &AV) {
1351   LiveSet->setAssignment(BlockInfo::Stack, Var, AV);
1352 
1353   // Use this assigment for all fragments contained within Var, but do not
1354   // provide a Source because we cannot convert Var's value to a value for the
1355   // fragment.
1356   Assignment FragAV = AV;
1357   FragAV.Source = nullptr;
1358   for (VariableID Frag : getContainedFragments(Var))
1359     LiveSet->setAssignment(BlockInfo::Stack, Frag, FragAV);
1360 }
1361 
1362 void AssignmentTrackingLowering::addDbgDef(BlockInfo *LiveSet, VariableID Var,
1363                                            const Assignment &AV) {
1364   LiveSet->setAssignment(BlockInfo::Debug, Var, AV);
1365 
1366   // Use this assigment for all fragments contained within Var, but do not
1367   // provide a Source because we cannot convert Var's value to a value for the
1368   // fragment.
1369   Assignment FragAV = AV;
1370   FragAV.Source = nullptr;
1371   for (VariableID Frag : getContainedFragments(Var))
1372     LiveSet->setAssignment(BlockInfo::Debug, Frag, FragAV);
1373 }
1374 
1375 static DIAssignID *getIDFromInst(const Instruction &I) {
1376   return cast<DIAssignID>(I.getMetadata(LLVMContext::MD_DIAssignID));
1377 }
1378 
1379 static DIAssignID *getIDFromMarker(const DbgAssignIntrinsic &DAI) {
1380   return cast<DIAssignID>(DAI.getAssignID());
1381 }
1382 
1383 /// Return true if \p Var has an assignment in \p M matching \p AV.
1384 bool AssignmentTrackingLowering::hasVarWithAssignment(
1385     BlockInfo *LiveSet, BlockInfo::AssignmentKind Kind, VariableID Var,
1386     const Assignment &AV) {
1387   if (!LiveSet->hasAssignment(Kind, Var, AV))
1388     return false;
1389 
1390   // Check all the frags contained within Var as these will have all been
1391   // mapped to AV at the last store to Var.
1392   for (VariableID Frag : getContainedFragments(Var))
1393     if (!LiveSet->hasAssignment(Kind, Frag, AV))
1394       return false;
1395   return true;
1396 }
1397 
1398 #ifndef NDEBUG
1399 const char *locStr(AssignmentTrackingLowering::LocKind Loc) {
1400   using LocKind = AssignmentTrackingLowering::LocKind;
1401   switch (Loc) {
1402   case LocKind::Val:
1403     return "Val";
1404   case LocKind::Mem:
1405     return "Mem";
1406   case LocKind::None:
1407     return "None";
1408   };
1409   llvm_unreachable("unknown LocKind");
1410 }
1411 #endif
1412 
1413 void AssignmentTrackingLowering::emitDbgValue(
1414     AssignmentTrackingLowering::LocKind Kind,
1415     const DbgVariableIntrinsic *Source, Instruction *After) {
1416 
1417   DILocation *DL = Source->getDebugLoc();
1418   auto Emit = [this, Source, After, DL](Metadata *Val, DIExpression *Expr) {
1419     assert(Expr);
1420     if (!Val)
1421       Val = ValueAsMetadata::get(
1422           PoisonValue::get(Type::getInt1Ty(Source->getContext())));
1423 
1424     // Find a suitable insert point.
1425     Instruction *InsertBefore = After->getNextNode();
1426     assert(InsertBefore && "Shouldn't be inserting after a terminator");
1427 
1428     VariableID Var = getVariableID(DebugVariable(Source));
1429     VarLocInfo VarLoc;
1430     VarLoc.VariableID = static_cast<VariableID>(Var);
1431     VarLoc.Expr = Expr;
1432     VarLoc.Values = RawLocationWrapper(Val);
1433     VarLoc.DL = DL;
1434     // Insert it into the map for later.
1435     InsertBeforeMap[InsertBefore].push_back(VarLoc);
1436   };
1437 
1438   // NOTE: This block can mutate Kind.
1439   if (Kind == LocKind::Mem) {
1440     const auto *DAI = cast<DbgAssignIntrinsic>(Source);
1441     // Check the address hasn't been dropped (e.g. the debug uses may not have
1442     // been replaced before deleting a Value).
1443     if (DAI->isKillAddress()) {
1444       // The address isn't valid so treat this as a non-memory def.
1445       Kind = LocKind::Val;
1446     } else {
1447       Value *Val = DAI->getAddress();
1448       DIExpression *Expr = DAI->getAddressExpression();
1449       assert(!Expr->getFragmentInfo() &&
1450              "fragment info should be stored in value-expression only");
1451       // Copy the fragment info over from the value-expression to the new
1452       // DIExpression.
1453       if (auto OptFragInfo = Source->getExpression()->getFragmentInfo()) {
1454         auto FragInfo = *OptFragInfo;
1455         Expr = *DIExpression::createFragmentExpression(
1456             Expr, FragInfo.OffsetInBits, FragInfo.SizeInBits);
1457       }
1458       // The address-expression has an implicit deref, add it now.
1459       std::tie(Val, Expr) =
1460           walkToAllocaAndPrependOffsetDeref(Layout, Val, Expr);
1461       Emit(ValueAsMetadata::get(Val), Expr);
1462       return;
1463     }
1464   }
1465 
1466   if (Kind == LocKind::Val) {
1467     Emit(Source->getRawLocation(), Source->getExpression());
1468     return;
1469   }
1470 
1471   if (Kind == LocKind::None) {
1472     Emit(nullptr, Source->getExpression());
1473     return;
1474   }
1475 }
1476 
1477 void AssignmentTrackingLowering::processNonDbgInstruction(
1478     Instruction &I, AssignmentTrackingLowering::BlockInfo *LiveSet) {
1479   if (I.hasMetadata(LLVMContext::MD_DIAssignID))
1480     processTaggedInstruction(I, LiveSet);
1481   else
1482     processUntaggedInstruction(I, LiveSet);
1483 }
1484 
1485 void AssignmentTrackingLowering::processUntaggedInstruction(
1486     Instruction &I, AssignmentTrackingLowering::BlockInfo *LiveSet) {
1487   // Interpret stack stores that are not tagged as an assignment in memory for
1488   // the variables associated with that address. These stores may not be tagged
1489   // because a) the store cannot be represented using dbg.assigns (non-const
1490   // length or offset) or b) the tag was accidentally dropped during
1491   // optimisations. For these stores we fall back to assuming that the stack
1492   // home is a valid location for the variables. The benefit is that this
1493   // prevents us missing an assignment and therefore incorrectly maintaining
1494   // earlier location definitions, and in many cases it should be a reasonable
1495   // assumption. However, this will occasionally lead to slight
1496   // inaccuracies. The value of a hoisted untagged store will be visible
1497   // "early", for example.
1498   assert(!I.hasMetadata(LLVMContext::MD_DIAssignID));
1499   auto It = UntaggedStoreVars.find(&I);
1500   if (It == UntaggedStoreVars.end())
1501     return; // No variables associated with the store destination.
1502 
1503   LLVM_DEBUG(dbgs() << "processUntaggedInstruction on UNTAGGED INST " << I
1504                     << "\n");
1505   // Iterate over the variables that this store affects, add a NoneOrPhi dbg
1506   // and mem def, set lockind to Mem, and emit a location def for each.
1507   for (auto [Var, Info] : It->second) {
1508     // This instruction is treated as both a debug and memory assignment,
1509     // meaning the memory location should be used. We don't have an assignment
1510     // ID though so use Assignment::makeNoneOrPhi() to create an imaginary one.
1511     addMemDef(LiveSet, Var, Assignment::makeNoneOrPhi());
1512     addDbgDef(LiveSet, Var, Assignment::makeNoneOrPhi());
1513     setLocKind(LiveSet, Var, LocKind::Mem);
1514     LLVM_DEBUG(dbgs() << "  setting Stack LocKind to: " << locStr(LocKind::Mem)
1515                       << "\n");
1516     // Build the dbg location def to insert.
1517     //
1518     // DIExpression: Add fragment and offset.
1519     DebugVariable V = FnVarLocs->getVariable(Var);
1520     DIExpression *DIE = DIExpression::get(I.getContext(), std::nullopt);
1521     if (auto Frag = V.getFragment()) {
1522       auto R = DIExpression::createFragmentExpression(DIE, Frag->OffsetInBits,
1523                                                       Frag->SizeInBits);
1524       assert(R && "unexpected createFragmentExpression failure");
1525       DIE = *R;
1526     }
1527     SmallVector<uint64_t, 3> Ops;
1528     if (Info.OffsetInBits)
1529       Ops = {dwarf::DW_OP_plus_uconst, Info.OffsetInBits / 8};
1530     Ops.push_back(dwarf::DW_OP_deref);
1531     DIE = DIExpression::prependOpcodes(DIE, Ops, /*StackValue=*/false,
1532                                        /*EntryValue=*/false);
1533     // Find a suitable insert point.
1534     Instruction *InsertBefore = I.getNextNode();
1535     assert(InsertBefore && "Shouldn't be inserting after a terminator");
1536 
1537     // Get DILocation for this unrecorded assignment.
1538     DILocation *InlinedAt = const_cast<DILocation *>(V.getInlinedAt());
1539     const DILocation *DILoc = DILocation::get(
1540         Fn.getContext(), 0, 0, V.getVariable()->getScope(), InlinedAt);
1541 
1542     VarLocInfo VarLoc;
1543     VarLoc.VariableID = static_cast<VariableID>(Var);
1544     VarLoc.Expr = DIE;
1545     VarLoc.Values = RawLocationWrapper(
1546         ValueAsMetadata::get(const_cast<AllocaInst *>(Info.Base)));
1547     VarLoc.DL = DILoc;
1548     // 3. Insert it into the map for later.
1549     InsertBeforeMap[InsertBefore].push_back(VarLoc);
1550   }
1551 }
1552 
1553 void AssignmentTrackingLowering::processTaggedInstruction(
1554     Instruction &I, AssignmentTrackingLowering::BlockInfo *LiveSet) {
1555   auto Linked = at::getAssignmentMarkers(&I);
1556   // No dbg.assign intrinsics linked.
1557   // FIXME: All vars that have a stack slot this store modifies that don't have
1558   // a dbg.assign linked to it should probably treat this like an untagged
1559   // store.
1560   if (Linked.empty())
1561     return;
1562 
1563   LLVM_DEBUG(dbgs() << "processTaggedInstruction on " << I << "\n");
1564   for (DbgAssignIntrinsic *DAI : Linked) {
1565     VariableID Var = getVariableID(DebugVariable(DAI));
1566     // Something has gone wrong if VarsWithStackSlot doesn't contain a variable
1567     // that is linked to a store.
1568     assert(VarsWithStackSlot->count(getAggregate(DAI)) &&
1569            "expected DAI's variable to have stack slot");
1570 
1571     Assignment AV = Assignment::makeFromMemDef(getIDFromInst(I));
1572     addMemDef(LiveSet, Var, AV);
1573 
1574     LLVM_DEBUG(dbgs() << "   linked to " << *DAI << "\n");
1575     LLVM_DEBUG(dbgs() << "   LiveLoc " << locStr(getLocKind(LiveSet, Var))
1576                       << " -> ");
1577 
1578     // The last assignment to the stack is now AV. Check if the last debug
1579     // assignment has a matching Assignment.
1580     if (hasVarWithAssignment(LiveSet, BlockInfo::Debug, Var, AV)) {
1581       // The StackHomeValue and DebugValue for this variable match so we can
1582       // emit a stack home location here.
1583       LLVM_DEBUG(dbgs() << "Mem, Stack matches Debug program\n";);
1584       LLVM_DEBUG(dbgs() << "   Stack val: "; AV.dump(dbgs()); dbgs() << "\n");
1585       LLVM_DEBUG(dbgs() << "   Debug val: ";
1586                  LiveSet->DebugValue[static_cast<unsigned>(Var)].dump(dbgs());
1587                  dbgs() << "\n");
1588       setLocKind(LiveSet, Var, LocKind::Mem);
1589       emitDbgValue(LocKind::Mem, DAI, &I);
1590       continue;
1591     }
1592 
1593     // The StackHomeValue and DebugValue for this variable do not match. I.e.
1594     // The value currently stored in the stack is not what we'd expect to
1595     // see, so we cannot use emit a stack home location here. Now we will
1596     // look at the live LocKind for the variable and determine an appropriate
1597     // dbg.value to emit.
1598     LocKind PrevLoc = getLocKind(LiveSet, Var);
1599     switch (PrevLoc) {
1600     case LocKind::Val: {
1601       // The value in memory in memory has changed but we're not currently
1602       // using the memory location. Do nothing.
1603       LLVM_DEBUG(dbgs() << "Val, (unchanged)\n";);
1604       setLocKind(LiveSet, Var, LocKind::Val);
1605     } break;
1606     case LocKind::Mem: {
1607       // There's been an assignment to memory that we were using as a
1608       // location for this variable, and the Assignment doesn't match what
1609       // we'd expect to see in memory.
1610       Assignment DbgAV = LiveSet->getAssignment(BlockInfo::Debug, Var);
1611       if (DbgAV.Status == Assignment::NoneOrPhi) {
1612         // We need to terminate any previously open location now.
1613         LLVM_DEBUG(dbgs() << "None, No Debug value available\n";);
1614         setLocKind(LiveSet, Var, LocKind::None);
1615         emitDbgValue(LocKind::None, DAI, &I);
1616       } else {
1617         // The previous DebugValue Value can be used here.
1618         LLVM_DEBUG(dbgs() << "Val, Debug value is Known\n";);
1619         setLocKind(LiveSet, Var, LocKind::Val);
1620         if (DbgAV.Source) {
1621           emitDbgValue(LocKind::Val, DbgAV.Source, &I);
1622         } else {
1623           // PrevAV.Source is nullptr so we must emit undef here.
1624           emitDbgValue(LocKind::None, DAI, &I);
1625         }
1626       }
1627     } break;
1628     case LocKind::None: {
1629       // There's been an assignment to memory and we currently are
1630       // not tracking a location for the variable. Do not emit anything.
1631       LLVM_DEBUG(dbgs() << "None, (unchanged)\n";);
1632       setLocKind(LiveSet, Var, LocKind::None);
1633     } break;
1634     }
1635   }
1636 }
1637 
1638 void AssignmentTrackingLowering::processDbgAssign(DbgAssignIntrinsic &DAI,
1639                                                   BlockInfo *LiveSet) {
1640   // Only bother tracking variables that are at some point stack homed. Other
1641   // variables can be dealt with trivially later.
1642   if (!VarsWithStackSlot->count(getAggregate(&DAI)))
1643     return;
1644 
1645   VariableID Var = getVariableID(DebugVariable(&DAI));
1646   Assignment AV = Assignment::make(getIDFromMarker(DAI), &DAI);
1647   addDbgDef(LiveSet, Var, AV);
1648 
1649   LLVM_DEBUG(dbgs() << "processDbgAssign on " << DAI << "\n";);
1650   LLVM_DEBUG(dbgs() << "   LiveLoc " << locStr(getLocKind(LiveSet, Var))
1651                     << " -> ");
1652 
1653   // Check if the DebugValue and StackHomeValue both hold the same
1654   // Assignment.
1655   if (hasVarWithAssignment(LiveSet, BlockInfo::Stack, Var, AV)) {
1656     // They match. We can use the stack home because the debug intrinsics state
1657     // that an assignment happened here, and we know that specific assignment
1658     // was the last one to take place in memory for this variable.
1659     LocKind Kind;
1660     if (DAI.isKillAddress()) {
1661       LLVM_DEBUG(
1662           dbgs()
1663               << "Val, Stack matches Debug program but address is killed\n";);
1664       Kind = LocKind::Val;
1665     } else {
1666       LLVM_DEBUG(dbgs() << "Mem, Stack matches Debug program\n";);
1667       Kind = LocKind::Mem;
1668     };
1669     setLocKind(LiveSet, Var, Kind);
1670     emitDbgValue(Kind, &DAI, &DAI);
1671   } else {
1672     // The last assignment to the memory location isn't the one that we want to
1673     // show to the user so emit a dbg.value(Value). Value may be undef.
1674     LLVM_DEBUG(dbgs() << "Val, Stack contents is unknown\n";);
1675     setLocKind(LiveSet, Var, LocKind::Val);
1676     emitDbgValue(LocKind::Val, &DAI, &DAI);
1677   }
1678 }
1679 
1680 void AssignmentTrackingLowering::processDbgValue(DbgValueInst &DVI,
1681                                                  BlockInfo *LiveSet) {
1682   // Only other tracking variables that are at some point stack homed.
1683   // Other variables can be dealt with trivally later.
1684   if (!VarsWithStackSlot->count(getAggregate(&DVI)))
1685     return;
1686 
1687   VariableID Var = getVariableID(DebugVariable(&DVI));
1688   // We have no ID to create an Assignment with so we mark this assignment as
1689   // NoneOrPhi. Note that the dbg.value still exists, we just cannot determine
1690   // the assignment responsible for setting this value.
1691   // This is fine; dbg.values are essentially interchangable with unlinked
1692   // dbg.assigns, and some passes such as mem2reg and instcombine add them to
1693   // PHIs for promoted variables.
1694   Assignment AV = Assignment::makeNoneOrPhi();
1695   addDbgDef(LiveSet, Var, AV);
1696 
1697   LLVM_DEBUG(dbgs() << "processDbgValue on " << DVI << "\n";);
1698   LLVM_DEBUG(dbgs() << "   LiveLoc " << locStr(getLocKind(LiveSet, Var))
1699                     << " -> Val, dbg.value override");
1700 
1701   setLocKind(LiveSet, Var, LocKind::Val);
1702   emitDbgValue(LocKind::Val, &DVI, &DVI);
1703 }
1704 
1705 static bool hasZeroSizedFragment(DbgVariableIntrinsic &DVI) {
1706   if (auto F = DVI.getExpression()->getFragmentInfo())
1707     return F->SizeInBits == 0;
1708   return false;
1709 }
1710 
1711 void AssignmentTrackingLowering::processDbgInstruction(
1712     DbgInfoIntrinsic &I, AssignmentTrackingLowering::BlockInfo *LiveSet) {
1713   auto *DVI = dyn_cast<DbgVariableIntrinsic>(&I);
1714   if (!DVI)
1715     return;
1716 
1717   // Ignore assignments to zero bits of the variable.
1718   if (hasZeroSizedFragment(*DVI))
1719     return;
1720 
1721   if (auto *DAI = dyn_cast<DbgAssignIntrinsic>(&I))
1722     processDbgAssign(*DAI, LiveSet);
1723   else if (auto *DVI = dyn_cast<DbgValueInst>(&I))
1724     processDbgValue(*DVI, LiveSet);
1725 }
1726 
1727 void AssignmentTrackingLowering::resetInsertionPoint(Instruction &After) {
1728   assert(!After.isTerminator() && "Can't insert after a terminator");
1729   auto R = InsertBeforeMap.find(After.getNextNode());
1730   if (R == InsertBeforeMap.end())
1731     return;
1732   R->second.clear();
1733 }
1734 
1735 void AssignmentTrackingLowering::process(BasicBlock &BB, BlockInfo *LiveSet) {
1736   for (auto II = BB.begin(), EI = BB.end(); II != EI;) {
1737     assert(VarsTouchedThisFrame.empty());
1738     // Process the instructions in "frames". A "frame" includes a single
1739     // non-debug instruction followed any debug instructions before the
1740     // next non-debug instruction.
1741     if (!isa<DbgInfoIntrinsic>(&*II)) {
1742       if (II->isTerminator())
1743         break;
1744       resetInsertionPoint(*II);
1745       processNonDbgInstruction(*II, LiveSet);
1746       assert(LiveSet->isValid());
1747       ++II;
1748     }
1749     while (II != EI) {
1750       auto *Dbg = dyn_cast<DbgInfoIntrinsic>(&*II);
1751       if (!Dbg)
1752         break;
1753       resetInsertionPoint(*II);
1754       processDbgInstruction(*Dbg, LiveSet);
1755       assert(LiveSet->isValid());
1756       ++II;
1757     }
1758 
1759     // We've processed everything in the "frame". Now determine which variables
1760     // cannot be represented by a dbg.declare.
1761     for (auto Var : VarsTouchedThisFrame) {
1762       LocKind Loc = getLocKind(LiveSet, Var);
1763       // If a variable's LocKind is anything other than LocKind::Mem then we
1764       // must note that it cannot be represented with a dbg.declare.
1765       // Note that this check is enough without having to check the result of
1766       // joins() because for join to produce anything other than Mem after
1767       // we've already seen a Mem we'd be joining None or Val with Mem. In that
1768       // case, we've already hit this codepath when we set the LocKind to Val
1769       // or None in that block.
1770       if (Loc != LocKind::Mem) {
1771         DebugVariable DbgVar = FnVarLocs->getVariable(Var);
1772         DebugAggregate Aggr{DbgVar.getVariable(), DbgVar.getInlinedAt()};
1773         NotAlwaysStackHomed.insert(Aggr);
1774       }
1775     }
1776     VarsTouchedThisFrame.clear();
1777   }
1778 }
1779 
1780 AssignmentTrackingLowering::LocKind
1781 AssignmentTrackingLowering::joinKind(LocKind A, LocKind B) {
1782   // Partial order:
1783   // None > Mem, Val
1784   return A == B ? A : LocKind::None;
1785 }
1786 
1787 AssignmentTrackingLowering::Assignment
1788 AssignmentTrackingLowering::joinAssignment(const Assignment &A,
1789                                            const Assignment &B) {
1790   // Partial order:
1791   // NoneOrPhi(null, null) > Known(v, ?s)
1792 
1793   // If either are NoneOrPhi the join is NoneOrPhi.
1794   // If either value is different then the result is
1795   // NoneOrPhi (joining two values is a Phi).
1796   if (!A.isSameSourceAssignment(B))
1797     return Assignment::makeNoneOrPhi();
1798   if (A.Status == Assignment::NoneOrPhi)
1799     return Assignment::makeNoneOrPhi();
1800 
1801   // Source is used to lookup the value + expression in the debug program if
1802   // the stack slot gets assigned a value earlier than expected. Because
1803   // we're only tracking the one dbg.assign, we can't capture debug PHIs.
1804   // It's unlikely that we're losing out on much coverage by avoiding that
1805   // extra work.
1806   // The Source may differ in this situation:
1807   // Pred.1:
1808   //   dbg.assign i32 0, ..., !1, ...
1809   // Pred.2:
1810   //   dbg.assign i32 1, ..., !1, ...
1811   // Here the same assignment (!1) was performed in both preds in the source,
1812   // but we can't use either one unless they are identical (e.g. .we don't
1813   // want to arbitrarily pick between constant values).
1814   auto JoinSource = [&]() -> DbgAssignIntrinsic * {
1815     if (A.Source == B.Source)
1816       return A.Source;
1817     if (A.Source == nullptr || B.Source == nullptr)
1818       return nullptr;
1819     if (A.Source->isIdenticalTo(B.Source))
1820       return A.Source;
1821     return nullptr;
1822   };
1823   DbgAssignIntrinsic *Source = JoinSource();
1824   assert(A.Status == B.Status && A.Status == Assignment::Known);
1825   assert(A.ID == B.ID);
1826   return Assignment::make(A.ID, Source);
1827 }
1828 
1829 AssignmentTrackingLowering::BlockInfo
1830 AssignmentTrackingLowering::joinBlockInfo(const BlockInfo &A,
1831                                           const BlockInfo &B) {
1832   return BlockInfo::join(A, B, TrackedVariablesVectorSize);
1833 }
1834 
1835 bool AssignmentTrackingLowering::join(
1836     const BasicBlock &BB, const SmallPtrSet<BasicBlock *, 16> &Visited) {
1837 
1838   SmallVector<const BasicBlock *> VisitedPreds;
1839   // Ignore backedges if we have not visited the predecessor yet. As the
1840   // predecessor hasn't yet had locations propagated into it, most locations
1841   // will not yet be valid, so treat them as all being uninitialized and
1842   // potentially valid. If a location guessed to be correct here is
1843   // invalidated later, we will remove it when we revisit this block. This
1844   // is essentially the same as initialising all LocKinds and Assignments to
1845   // an implicit ⊥ value which is the identity value for the join operation.
1846   for (auto I = pred_begin(&BB), E = pred_end(&BB); I != E; I++) {
1847     const BasicBlock *Pred = *I;
1848     if (Visited.count(Pred))
1849       VisitedPreds.push_back(Pred);
1850   }
1851 
1852   // No preds visited yet.
1853   if (VisitedPreds.empty()) {
1854     auto It = LiveIn.try_emplace(&BB, BlockInfo());
1855     bool DidInsert = It.second;
1856     if (DidInsert)
1857       It.first->second.init(TrackedVariablesVectorSize);
1858     return /*Changed*/ DidInsert;
1859   }
1860 
1861   // Exactly one visited pred. Copy the LiveOut from that pred into BB LiveIn.
1862   if (VisitedPreds.size() == 1) {
1863     const BlockInfo &PredLiveOut = LiveOut.find(VisitedPreds[0])->second;
1864     auto CurrentLiveInEntry = LiveIn.find(&BB);
1865 
1866     // Check if there isn't an entry, or there is but the LiveIn set has
1867     // changed (expensive check).
1868     if (CurrentLiveInEntry == LiveIn.end())
1869       LiveIn.insert(std::make_pair(&BB, PredLiveOut));
1870     else if (PredLiveOut != CurrentLiveInEntry->second)
1871       CurrentLiveInEntry->second = PredLiveOut;
1872     else
1873       return /*Changed*/ false;
1874     return /*Changed*/ true;
1875   }
1876 
1877   // More than one pred. Join LiveOuts of blocks 1 and 2.
1878   assert(VisitedPreds.size() > 1);
1879   const BlockInfo &PredLiveOut0 = LiveOut.find(VisitedPreds[0])->second;
1880   const BlockInfo &PredLiveOut1 = LiveOut.find(VisitedPreds[1])->second;
1881   BlockInfo BBLiveIn = joinBlockInfo(PredLiveOut0, PredLiveOut1);
1882 
1883   // Join the LiveOuts of subsequent blocks.
1884   ArrayRef Tail = ArrayRef(VisitedPreds).drop_front(2);
1885   for (const BasicBlock *Pred : Tail) {
1886     const auto &PredLiveOut = LiveOut.find(Pred);
1887     assert(PredLiveOut != LiveOut.end() &&
1888            "block should have been processed already");
1889     BBLiveIn = joinBlockInfo(std::move(BBLiveIn), PredLiveOut->second);
1890   }
1891 
1892   // Save the joined result for BB.
1893   auto CurrentLiveInEntry = LiveIn.find(&BB);
1894   // Check if there isn't an entry, or there is but the LiveIn set has changed
1895   // (expensive check).
1896   if (CurrentLiveInEntry == LiveIn.end())
1897     LiveIn.try_emplace(&BB, std::move(BBLiveIn));
1898   else if (BBLiveIn != CurrentLiveInEntry->second)
1899     CurrentLiveInEntry->second = std::move(BBLiveIn);
1900   else
1901     return /*Changed*/ false;
1902   return /*Changed*/ true;
1903 }
1904 
1905 /// Return true if A fully contains B.
1906 static bool fullyContains(DIExpression::FragmentInfo A,
1907                           DIExpression::FragmentInfo B) {
1908   auto ALeft = A.OffsetInBits;
1909   auto BLeft = B.OffsetInBits;
1910   if (BLeft < ALeft)
1911     return false;
1912 
1913   auto ARight = ALeft + A.SizeInBits;
1914   auto BRight = BLeft + B.SizeInBits;
1915   if (BRight > ARight)
1916     return false;
1917   return true;
1918 }
1919 
1920 static std::optional<at::AssignmentInfo>
1921 getUntaggedStoreAssignmentInfo(const Instruction &I, const DataLayout &Layout) {
1922   // Don't bother checking if this is an AllocaInst. We know this
1923   // instruction has no tag which means there are no variables associated
1924   // with it.
1925   if (const auto *SI = dyn_cast<StoreInst>(&I))
1926     return at::getAssignmentInfo(Layout, SI);
1927   if (const auto *MI = dyn_cast<MemIntrinsic>(&I))
1928     return at::getAssignmentInfo(Layout, MI);
1929   // Alloca or non-store-like inst.
1930   return std::nullopt;
1931 }
1932 
1933 /// Build a map of {Variable x: Variables y} where all variable fragments
1934 /// contained within the variable fragment x are in set y. This means that
1935 /// y does not contain all overlaps because partial overlaps are excluded.
1936 ///
1937 /// While we're iterating over the function, add single location defs for
1938 /// dbg.declares to \p FnVarLocs.
1939 ///
1940 /// Variables that are interesting to this pass in are added to
1941 /// FnVarLocs->Variables first. TrackedVariablesVectorSize is set to the ID of
1942 /// the last interesting variable plus 1, meaning variables with ID 1
1943 /// (inclusive) to TrackedVariablesVectorSize (exclusive) are interesting. The
1944 /// subsequent variables are either stack homed or fully promoted.
1945 ///
1946 /// Finally, populate UntaggedStoreVars with a mapping of untagged stores to
1947 /// the stored-to variable fragments.
1948 ///
1949 /// These tasks are bundled together to reduce the number of times we need
1950 /// to iterate over the function as they can be achieved together in one pass.
1951 static AssignmentTrackingLowering::OverlapMap buildOverlapMapAndRecordDeclares(
1952     Function &Fn, FunctionVarLocsBuilder *FnVarLocs,
1953     const DenseSet<DebugAggregate> &VarsWithStackSlot,
1954     AssignmentTrackingLowering::UntaggedStoreAssignmentMap &UntaggedStoreVars,
1955     unsigned &TrackedVariablesVectorSize) {
1956   DenseSet<DebugVariable> Seen;
1957   // Map of Variable: [Fragments].
1958   DenseMap<DebugAggregate, SmallVector<DebugVariable, 8>> FragmentMap;
1959   // Iterate over all instructions:
1960   // - dbg.declare    -> add single location variable record
1961   // - dbg.*          -> Add fragments to FragmentMap
1962   // - untagged store -> Add fragments to FragmentMap and update
1963   //                     UntaggedStoreVars.
1964   // We need to add fragments for untagged stores too so that we can correctly
1965   // clobber overlapped fragment locations later.
1966   SmallVector<DbgDeclareInst *> Declares;
1967   for (auto &BB : Fn) {
1968     for (auto &I : BB) {
1969       if (auto *DDI = dyn_cast<DbgDeclareInst>(&I)) {
1970         Declares.push_back(DDI);
1971       } else if (auto *DII = dyn_cast<DbgVariableIntrinsic>(&I)) {
1972         DebugVariable DV = DebugVariable(DII);
1973         DebugAggregate DA = {DV.getVariable(), DV.getInlinedAt()};
1974         if (!VarsWithStackSlot.contains(DA))
1975           continue;
1976         if (Seen.insert(DV).second)
1977           FragmentMap[DA].push_back(DV);
1978       } else if (auto Info = getUntaggedStoreAssignmentInfo(
1979                      I, Fn.getParent()->getDataLayout())) {
1980         // Find markers linked to this alloca.
1981         for (DbgAssignIntrinsic *DAI : at::getAssignmentMarkers(Info->Base)) {
1982           // Discard the fragment if it covers the entire variable.
1983           std::optional<DIExpression::FragmentInfo> FragInfo =
1984               [&Info, DAI]() -> std::optional<DIExpression::FragmentInfo> {
1985             DIExpression::FragmentInfo F;
1986             F.OffsetInBits = Info->OffsetInBits;
1987             F.SizeInBits = Info->SizeInBits;
1988             if (auto ExistingFrag = DAI->getExpression()->getFragmentInfo())
1989               F.OffsetInBits += ExistingFrag->OffsetInBits;
1990             if (auto Sz = DAI->getVariable()->getSizeInBits()) {
1991               if (F.OffsetInBits == 0 && F.SizeInBits == *Sz)
1992                 return std::nullopt;
1993             }
1994             return F;
1995           }();
1996 
1997           DebugVariable DV = DebugVariable(DAI->getVariable(), FragInfo,
1998                                            DAI->getDebugLoc().getInlinedAt());
1999           DebugAggregate DA = {DV.getVariable(), DV.getInlinedAt()};
2000           if (!VarsWithStackSlot.contains(DA))
2001             continue;
2002 
2003           // Cache this info for later.
2004           UntaggedStoreVars[&I].push_back(
2005               {FnVarLocs->insertVariable(DV), *Info});
2006 
2007           if (Seen.insert(DV).second)
2008             FragmentMap[DA].push_back(DV);
2009         }
2010       }
2011     }
2012   }
2013 
2014   // Sort the fragment map for each DebugAggregate in ascending
2015   // order of fragment size - there should be no duplicates.
2016   for (auto &Pair : FragmentMap) {
2017     SmallVector<DebugVariable, 8> &Frags = Pair.second;
2018     std::sort(Frags.begin(), Frags.end(),
2019               [](const DebugVariable &Next, const DebugVariable &Elmt) {
2020                 return Elmt.getFragmentOrDefault().SizeInBits >
2021                        Next.getFragmentOrDefault().SizeInBits;
2022               });
2023     // Check for duplicates.
2024     assert(std::adjacent_find(Frags.begin(), Frags.end()) == Frags.end());
2025   }
2026 
2027   // Build the map.
2028   AssignmentTrackingLowering::OverlapMap Map;
2029   for (auto &Pair : FragmentMap) {
2030     auto &Frags = Pair.second;
2031     for (auto It = Frags.begin(), IEnd = Frags.end(); It != IEnd; ++It) {
2032       DIExpression::FragmentInfo Frag = It->getFragmentOrDefault();
2033       // Find the frags that this is contained within.
2034       //
2035       // Because Frags is sorted by size and none have the same offset and
2036       // size, we know that this frag can only be contained by subsequent
2037       // elements.
2038       SmallVector<DebugVariable, 8>::iterator OtherIt = It;
2039       ++OtherIt;
2040       VariableID ThisVar = FnVarLocs->insertVariable(*It);
2041       for (; OtherIt != IEnd; ++OtherIt) {
2042         DIExpression::FragmentInfo OtherFrag = OtherIt->getFragmentOrDefault();
2043         VariableID OtherVar = FnVarLocs->insertVariable(*OtherIt);
2044         if (fullyContains(OtherFrag, Frag))
2045           Map[OtherVar].push_back(ThisVar);
2046       }
2047     }
2048   }
2049 
2050   // VariableIDs are 1-based so the variable-tracking bitvector needs
2051   // NumVariables plus 1 bits.
2052   TrackedVariablesVectorSize = FnVarLocs->getNumVariables() + 1;
2053 
2054   // Finally, insert the declares afterwards, so the first IDs are all
2055   // partially stack homed vars.
2056   for (auto *DDI : Declares)
2057     FnVarLocs->addSingleLocVar(DebugVariable(DDI), DDI->getExpression(),
2058                                DDI->getDebugLoc(), DDI->getWrappedLocation());
2059   return Map;
2060 }
2061 
2062 bool AssignmentTrackingLowering::run(FunctionVarLocsBuilder *FnVarLocsBuilder) {
2063   if (Fn.size() > MaxNumBlocks) {
2064     LLVM_DEBUG(dbgs() << "[AT] Dropping var locs in: " << Fn.getName()
2065                       << ": too many blocks (" << Fn.size() << ")\n");
2066     at::deleteAll(&Fn);
2067     return false;
2068   }
2069 
2070   FnVarLocs = FnVarLocsBuilder;
2071 
2072   // The general structure here is inspired by VarLocBasedImpl.cpp
2073   // (LiveDebugValues).
2074 
2075   // Build the variable fragment overlap map.
2076   // Note that this pass doesn't handle partial overlaps correctly (FWIW
2077   // neither does LiveDebugVariables) because that is difficult to do and
2078   // appears to be rare occurance.
2079   VarContains = buildOverlapMapAndRecordDeclares(
2080       Fn, FnVarLocs, *VarsWithStackSlot, UntaggedStoreVars,
2081       TrackedVariablesVectorSize);
2082 
2083   // Prepare for traversal.
2084   ReversePostOrderTraversal<Function *> RPOT(&Fn);
2085   std::priority_queue<unsigned int, std::vector<unsigned int>,
2086                       std::greater<unsigned int>>
2087       Worklist;
2088   std::priority_queue<unsigned int, std::vector<unsigned int>,
2089                       std::greater<unsigned int>>
2090       Pending;
2091   DenseMap<unsigned int, BasicBlock *> OrderToBB;
2092   DenseMap<BasicBlock *, unsigned int> BBToOrder;
2093   { // Init OrderToBB and BBToOrder.
2094     unsigned int RPONumber = 0;
2095     for (auto RI = RPOT.begin(), RE = RPOT.end(); RI != RE; ++RI) {
2096       OrderToBB[RPONumber] = *RI;
2097       BBToOrder[*RI] = RPONumber;
2098       Worklist.push(RPONumber);
2099       ++RPONumber;
2100     }
2101     LiveIn.init(RPONumber);
2102     LiveOut.init(RPONumber);
2103   }
2104 
2105   // Perform the traversal.
2106   //
2107   // This is a standard "union of predecessor outs" dataflow problem. To solve
2108   // it, we perform join() and process() using the two worklist method until
2109   // the LiveIn data for each block becomes unchanging. The "proof" that this
2110   // terminates can be put together by looking at the comments around LocKind,
2111   // Assignment, and the various join methods, which show that all the elements
2112   // involved are made up of join-semilattices; LiveIn(n) can only
2113   // monotonically increase in value throughout the dataflow.
2114   //
2115   SmallPtrSet<BasicBlock *, 16> Visited;
2116   while (!Worklist.empty()) {
2117     // We track what is on the pending worklist to avoid inserting the same
2118     // thing twice.
2119     SmallPtrSet<BasicBlock *, 16> OnPending;
2120     LLVM_DEBUG(dbgs() << "Processing Worklist\n");
2121     while (!Worklist.empty()) {
2122       BasicBlock *BB = OrderToBB[Worklist.top()];
2123       LLVM_DEBUG(dbgs() << "\nPop BB " << BB->getName() << "\n");
2124       Worklist.pop();
2125       bool InChanged = join(*BB, Visited);
2126       // Always consider LiveIn changed on the first visit.
2127       InChanged |= Visited.insert(BB).second;
2128       if (InChanged) {
2129         LLVM_DEBUG(dbgs() << BB->getName() << " has new InLocs, process it\n");
2130         // Mutate a copy of LiveIn while processing BB. After calling process
2131         // LiveSet is the LiveOut set for BB.
2132         BlockInfo LiveSet = LiveIn[BB];
2133 
2134         // Process the instructions in the block.
2135         process(*BB, &LiveSet);
2136 
2137         // Relatively expensive check: has anything changed in LiveOut for BB?
2138         if (LiveOut[BB] != LiveSet) {
2139           LLVM_DEBUG(dbgs() << BB->getName()
2140                             << " has new OutLocs, add succs to worklist: [ ");
2141           LiveOut[BB] = std::move(LiveSet);
2142           for (auto I = succ_begin(BB), E = succ_end(BB); I != E; I++) {
2143             if (OnPending.insert(*I).second) {
2144               LLVM_DEBUG(dbgs() << I->getName() << " ");
2145               Pending.push(BBToOrder[*I]);
2146             }
2147           }
2148           LLVM_DEBUG(dbgs() << "]\n");
2149         }
2150       }
2151     }
2152     Worklist.swap(Pending);
2153     // At this point, pending must be empty, since it was just the empty
2154     // worklist
2155     assert(Pending.empty() && "Pending should be empty");
2156   }
2157 
2158   // That's the hard part over. Now we just have some admin to do.
2159 
2160   // Record whether we inserted any intrinsics.
2161   bool InsertedAnyIntrinsics = false;
2162 
2163   // Identify and add defs for single location variables.
2164   //
2165   // Go through all of the defs that we plan to add. If the aggregate variable
2166   // it's a part of is not in the NotAlwaysStackHomed set we can emit a single
2167   // location def and omit the rest. Add an entry to AlwaysStackHomed so that
2168   // we can identify those uneeded defs later.
2169   DenseSet<DebugAggregate> AlwaysStackHomed;
2170   for (const auto &Pair : InsertBeforeMap) {
2171     const auto &Vec = Pair.second;
2172     for (VarLocInfo VarLoc : Vec) {
2173       DebugVariable Var = FnVarLocs->getVariable(VarLoc.VariableID);
2174       DebugAggregate Aggr{Var.getVariable(), Var.getInlinedAt()};
2175 
2176       // Skip this Var if it's not always stack homed.
2177       if (NotAlwaysStackHomed.contains(Aggr))
2178         continue;
2179 
2180       // Skip complex cases such as when different fragments of a variable have
2181       // been split into different allocas. Skipping in this case means falling
2182       // back to using a list of defs (which could reduce coverage, but is no
2183       // less correct).
2184       bool Simple =
2185           VarLoc.Expr->getNumElements() == 1 && VarLoc.Expr->startsWithDeref();
2186       if (!Simple) {
2187         NotAlwaysStackHomed.insert(Aggr);
2188         continue;
2189       }
2190 
2191       // All source assignments to this variable remain and all stores to any
2192       // part of the variable store to the same address (with varying
2193       // offsets). We can just emit a single location for the whole variable.
2194       //
2195       // Unless we've already done so, create the single location def now.
2196       if (AlwaysStackHomed.insert(Aggr).second) {
2197         assert(!VarLoc.Values.hasArgList());
2198         // TODO: When more complex cases are handled VarLoc.Expr should be
2199         // built appropriately rather than always using an empty DIExpression.
2200         // The assert below is a reminder.
2201         assert(Simple);
2202         VarLoc.Expr = DIExpression::get(Fn.getContext(), std::nullopt);
2203         DebugVariable Var = FnVarLocs->getVariable(VarLoc.VariableID);
2204         FnVarLocs->addSingleLocVar(Var, VarLoc.Expr, VarLoc.DL, VarLoc.Values);
2205         InsertedAnyIntrinsics = true;
2206       }
2207     }
2208   }
2209 
2210   // Insert the other DEFs.
2211   for (const auto &[InsertBefore, Vec] : InsertBeforeMap) {
2212     SmallVector<VarLocInfo> NewDefs;
2213     for (const VarLocInfo &VarLoc : Vec) {
2214       DebugVariable Var = FnVarLocs->getVariable(VarLoc.VariableID);
2215       DebugAggregate Aggr{Var.getVariable(), Var.getInlinedAt()};
2216       // If this variable is always stack homed then we have already inserted a
2217       // dbg.declare and deleted this dbg.value.
2218       if (AlwaysStackHomed.contains(Aggr))
2219         continue;
2220       NewDefs.push_back(VarLoc);
2221       InsertedAnyIntrinsics = true;
2222     }
2223 
2224     FnVarLocs->setWedge(InsertBefore, std::move(NewDefs));
2225   }
2226 
2227   InsertedAnyIntrinsics |= emitPromotedVarLocs(FnVarLocs);
2228 
2229   return InsertedAnyIntrinsics;
2230 }
2231 
2232 bool AssignmentTrackingLowering::emitPromotedVarLocs(
2233     FunctionVarLocsBuilder *FnVarLocs) {
2234   bool InsertedAnyIntrinsics = false;
2235   // Go through every block, translating debug intrinsics for fully promoted
2236   // variables into FnVarLocs location defs. No analysis required for these.
2237   for (auto &BB : Fn) {
2238     for (auto &I : BB) {
2239       // Skip instructions other than dbg.values and dbg.assigns.
2240       auto *DVI = dyn_cast<DbgValueInst>(&I);
2241       if (!DVI)
2242         continue;
2243       // Skip variables that haven't been promoted - we've dealt with those
2244       // already.
2245       if (VarsWithStackSlot->contains(getAggregate(DVI)))
2246         continue;
2247       Instruction *InsertBefore = I.getNextNode();
2248       assert(InsertBefore && "Unexpected: debug intrinsics after a terminator");
2249       FnVarLocs->addVarLoc(InsertBefore, DebugVariable(DVI),
2250                            DVI->getExpression(), DVI->getDebugLoc(),
2251                            DVI->getWrappedLocation());
2252       InsertedAnyIntrinsics = true;
2253     }
2254   }
2255   return InsertedAnyIntrinsics;
2256 }
2257 
2258 /// Remove redundant definitions within sequences of consecutive location defs.
2259 /// This is done using a backward scan to keep the last def describing a
2260 /// specific variable/fragment.
2261 ///
2262 /// This implements removeRedundantDbgInstrsUsingBackwardScan from
2263 /// lib/Transforms/Utils/BasicBlockUtils.cpp for locations described with
2264 /// FunctionVarLocsBuilder instead of with intrinsics.
2265 static bool
2266 removeRedundantDbgLocsUsingBackwardScan(const BasicBlock *BB,
2267                                         FunctionVarLocsBuilder &FnVarLocs) {
2268   bool Changed = false;
2269   SmallDenseMap<DebugAggregate, BitVector> VariableDefinedBits;
2270   // Scan over the entire block, not just over the instructions mapped by
2271   // FnVarLocs, because wedges in FnVarLocs may only be seperated by debug
2272   // instructions.
2273   for (const Instruction &I : reverse(*BB)) {
2274     if (!isa<DbgVariableIntrinsic>(I)) {
2275       // Sequence of consecutive defs ended. Clear map for the next one.
2276       VariableDefinedBits.clear();
2277     }
2278 
2279     // Get the location defs that start just before this instruction.
2280     const auto *Locs = FnVarLocs.getWedge(&I);
2281     if (!Locs)
2282       continue;
2283 
2284     NumWedgesScanned++;
2285     bool ChangedThisWedge = false;
2286     // The new pruned set of defs, reversed because we're scanning backwards.
2287     SmallVector<VarLocInfo> NewDefsReversed;
2288 
2289     // Iterate over the existing defs in reverse.
2290     for (auto RIt = Locs->rbegin(), REnd = Locs->rend(); RIt != REnd; ++RIt) {
2291       NumDefsScanned++;
2292       DebugAggregate Aggr =
2293           getAggregate(FnVarLocs.getVariable(RIt->VariableID));
2294       uint64_t SizeInBits = Aggr.first->getSizeInBits().value_or(0);
2295 
2296       if (SizeInBits == 0) {
2297         // If the size is unknown (0) then keep this location def to be safe.
2298         NewDefsReversed.push_back(*RIt);
2299         continue;
2300       }
2301 
2302       // Only keep this location definition if it is not fully eclipsed by
2303       // other definitions in this wedge that come after it
2304 
2305       // Inert the bits the location definition defines.
2306       auto InsertResult =
2307           VariableDefinedBits.try_emplace(Aggr, BitVector(SizeInBits));
2308       bool FirstDefinition = InsertResult.second;
2309       BitVector &DefinedBits = InsertResult.first->second;
2310 
2311       DIExpression::FragmentInfo Fragment =
2312           RIt->Expr->getFragmentInfo().value_or(
2313               DIExpression::FragmentInfo(SizeInBits, 0));
2314       bool InvalidFragment = Fragment.endInBits() > SizeInBits;
2315 
2316       // If this defines any previously undefined bits, keep it.
2317       if (FirstDefinition || InvalidFragment ||
2318           DefinedBits.find_first_unset_in(Fragment.startInBits(),
2319                                           Fragment.endInBits()) != -1) {
2320         if (!InvalidFragment)
2321           DefinedBits.set(Fragment.startInBits(), Fragment.endInBits());
2322         NewDefsReversed.push_back(*RIt);
2323         continue;
2324       }
2325 
2326       // Redundant def found: throw it away. Since the wedge of defs is being
2327       // rebuilt, doing nothing is the same as deleting an entry.
2328       ChangedThisWedge = true;
2329       NumDefsRemoved++;
2330     }
2331 
2332     // Un-reverse the defs and replace the wedge with the pruned version.
2333     if (ChangedThisWedge) {
2334       std::reverse(NewDefsReversed.begin(), NewDefsReversed.end());
2335       FnVarLocs.setWedge(&I, std::move(NewDefsReversed));
2336       NumWedgesChanged++;
2337       Changed = true;
2338     }
2339   }
2340 
2341   return Changed;
2342 }
2343 
2344 /// Remove redundant location defs using a forward scan. This can remove a
2345 /// location definition that is redundant due to indicating that a variable has
2346 /// the same value as is already being indicated by an earlier def.
2347 ///
2348 /// This implements removeRedundantDbgInstrsUsingForwardScan from
2349 /// lib/Transforms/Utils/BasicBlockUtils.cpp for locations described with
2350 /// FunctionVarLocsBuilder instead of with intrinsics
2351 static bool
2352 removeRedundantDbgLocsUsingForwardScan(const BasicBlock *BB,
2353                                        FunctionVarLocsBuilder &FnVarLocs) {
2354   bool Changed = false;
2355   DenseMap<DebugVariable, std::pair<RawLocationWrapper, DIExpression *>>
2356       VariableMap;
2357 
2358   // Scan over the entire block, not just over the instructions mapped by
2359   // FnVarLocs, because wedges in FnVarLocs may only be seperated by debug
2360   // instructions.
2361   for (const Instruction &I : *BB) {
2362     // Get the defs that come just before this instruction.
2363     const auto *Locs = FnVarLocs.getWedge(&I);
2364     if (!Locs)
2365       continue;
2366 
2367     NumWedgesScanned++;
2368     bool ChangedThisWedge = false;
2369     // The new pruned set of defs.
2370     SmallVector<VarLocInfo> NewDefs;
2371 
2372     // Iterate over the existing defs.
2373     for (const VarLocInfo &Loc : *Locs) {
2374       NumDefsScanned++;
2375       DebugVariable Key(FnVarLocs.getVariable(Loc.VariableID).getVariable(),
2376                         std::nullopt, Loc.DL.getInlinedAt());
2377       auto VMI = VariableMap.find(Key);
2378 
2379       // Update the map if we found a new value/expression describing the
2380       // variable, or if the variable wasn't mapped already.
2381       if (VMI == VariableMap.end() || VMI->second.first != Loc.Values ||
2382           VMI->second.second != Loc.Expr) {
2383         VariableMap[Key] = {Loc.Values, Loc.Expr};
2384         NewDefs.push_back(Loc);
2385         continue;
2386       }
2387 
2388       // Did not insert this Loc, which is the same as removing it.
2389       ChangedThisWedge = true;
2390       NumDefsRemoved++;
2391     }
2392 
2393     // Replace the existing wedge with the pruned version.
2394     if (ChangedThisWedge) {
2395       FnVarLocs.setWedge(&I, std::move(NewDefs));
2396       NumWedgesChanged++;
2397       Changed = true;
2398     }
2399   }
2400 
2401   return Changed;
2402 }
2403 
2404 static bool
2405 removeUndefDbgLocsFromEntryBlock(const BasicBlock *BB,
2406                                  FunctionVarLocsBuilder &FnVarLocs) {
2407   assert(BB->isEntryBlock());
2408   // Do extra work to ensure that we remove semantically unimportant undefs.
2409   //
2410   // This is to work around the fact that SelectionDAG will hoist dbg.values
2411   // using argument values to the top of the entry block. That can move arg
2412   // dbg.values before undef and constant dbg.values which they previously
2413   // followed. The easiest thing to do is to just try to feed SelectionDAG
2414   // input it's happy with.
2415   //
2416   // Map of {Variable x: Fragments y} where the fragments y of variable x have
2417   // have at least one non-undef location defined already. Don't use directly,
2418   // instead call DefineBits and HasDefinedBits.
2419   SmallDenseMap<DebugAggregate, SmallDenseSet<DIExpression::FragmentInfo>>
2420       VarsWithDef;
2421   // Specify that V (a fragment of A) has a non-undef location.
2422   auto DefineBits = [&VarsWithDef](DebugAggregate A, DebugVariable V) {
2423     VarsWithDef[A].insert(V.getFragmentOrDefault());
2424   };
2425   // Return true if a non-undef location has been defined for V (a fragment of
2426   // A). Doesn't imply that the location is currently non-undef, just that a
2427   // non-undef location has been seen previously.
2428   auto HasDefinedBits = [&VarsWithDef](DebugAggregate A, DebugVariable V) {
2429     auto FragsIt = VarsWithDef.find(A);
2430     if (FragsIt == VarsWithDef.end())
2431       return false;
2432     return llvm::any_of(FragsIt->second, [V](auto Frag) {
2433       return DIExpression::fragmentsOverlap(Frag, V.getFragmentOrDefault());
2434     });
2435   };
2436 
2437   bool Changed = false;
2438   DenseMap<DebugVariable, std::pair<Value *, DIExpression *>> VariableMap;
2439 
2440   // Scan over the entire block, not just over the instructions mapped by
2441   // FnVarLocs, because wedges in FnVarLocs may only be seperated by debug
2442   // instructions.
2443   for (const Instruction &I : *BB) {
2444     // Get the defs that come just before this instruction.
2445     const auto *Locs = FnVarLocs.getWedge(&I);
2446     if (!Locs)
2447       continue;
2448 
2449     NumWedgesScanned++;
2450     bool ChangedThisWedge = false;
2451     // The new pruned set of defs.
2452     SmallVector<VarLocInfo> NewDefs;
2453 
2454     // Iterate over the existing defs.
2455     for (const VarLocInfo &Loc : *Locs) {
2456       NumDefsScanned++;
2457       DebugAggregate Aggr{FnVarLocs.getVariable(Loc.VariableID).getVariable(),
2458                           Loc.DL.getInlinedAt()};
2459       DebugVariable Var = FnVarLocs.getVariable(Loc.VariableID);
2460 
2461       // Remove undef entries that are encountered before any non-undef
2462       // intrinsics from the entry block.
2463       if (Loc.Values.isKillLocation(Loc.Expr) && !HasDefinedBits(Aggr, Var)) {
2464         // Did not insert this Loc, which is the same as removing it.
2465         NumDefsRemoved++;
2466         ChangedThisWedge = true;
2467         continue;
2468       }
2469 
2470       DefineBits(Aggr, Var);
2471       NewDefs.push_back(Loc);
2472     }
2473 
2474     // Replace the existing wedge with the pruned version.
2475     if (ChangedThisWedge) {
2476       FnVarLocs.setWedge(&I, std::move(NewDefs));
2477       NumWedgesChanged++;
2478       Changed = true;
2479     }
2480   }
2481 
2482   return Changed;
2483 }
2484 
2485 static bool removeRedundantDbgLocs(const BasicBlock *BB,
2486                                    FunctionVarLocsBuilder &FnVarLocs) {
2487   bool MadeChanges = false;
2488   MadeChanges |= removeRedundantDbgLocsUsingBackwardScan(BB, FnVarLocs);
2489   if (BB->isEntryBlock())
2490     MadeChanges |= removeUndefDbgLocsFromEntryBlock(BB, FnVarLocs);
2491   MadeChanges |= removeRedundantDbgLocsUsingForwardScan(BB, FnVarLocs);
2492 
2493   if (MadeChanges)
2494     LLVM_DEBUG(dbgs() << "Removed redundant dbg locs from: " << BB->getName()
2495                       << "\n");
2496   return MadeChanges;
2497 }
2498 
2499 static DenseSet<DebugAggregate> findVarsWithStackSlot(Function &Fn) {
2500   DenseSet<DebugAggregate> Result;
2501   for (auto &BB : Fn) {
2502     for (auto &I : BB) {
2503       // Any variable linked to an instruction is considered
2504       // interesting. Ideally we only need to check Allocas, however, a
2505       // DIAssignID might get dropped from an alloca but not stores. In that
2506       // case, we need to consider the variable interesting for NFC behaviour
2507       // with this change. TODO: Consider only looking at allocas.
2508       for (DbgAssignIntrinsic *DAI : at::getAssignmentMarkers(&I)) {
2509         Result.insert({DAI->getVariable(), DAI->getDebugLoc().getInlinedAt()});
2510       }
2511     }
2512   }
2513   return Result;
2514 }
2515 
2516 static void analyzeFunction(Function &Fn, const DataLayout &Layout,
2517                             FunctionVarLocsBuilder *FnVarLocs) {
2518   // The analysis will generate location definitions for all variables, but we
2519   // only need to perform a dataflow on the set of variables which have a stack
2520   // slot. Find those now.
2521   DenseSet<DebugAggregate> VarsWithStackSlot = findVarsWithStackSlot(Fn);
2522 
2523   bool Changed = false;
2524 
2525   // Use a scope block to clean up AssignmentTrackingLowering before running
2526   // MemLocFragmentFill to reduce peak memory consumption.
2527   {
2528     AssignmentTrackingLowering Pass(Fn, Layout, &VarsWithStackSlot);
2529     Changed = Pass.run(FnVarLocs);
2530   }
2531 
2532   if (Changed) {
2533     MemLocFragmentFill Pass(Fn, &VarsWithStackSlot,
2534                             shouldCoalesceFragments(Fn));
2535     Pass.run(FnVarLocs);
2536 
2537     // Remove redundant entries. As well as reducing memory consumption and
2538     // avoiding waiting cycles later by burning some now, this has another
2539     // important job. That is to work around some SelectionDAG quirks. See
2540     // removeRedundantDbgLocsUsingForwardScan comments for more info on that.
2541     for (auto &BB : Fn)
2542       removeRedundantDbgLocs(&BB, *FnVarLocs);
2543   }
2544 }
2545 
2546 bool AssignmentTrackingAnalysis::runOnFunction(Function &F) {
2547   if (!isAssignmentTrackingEnabled(*F.getParent()))
2548     return false;
2549 
2550   LLVM_DEBUG(dbgs() << "AssignmentTrackingAnalysis run on " << F.getName()
2551                     << "\n");
2552   auto DL = std::make_unique<DataLayout>(F.getParent());
2553 
2554   // Clear previous results.
2555   Results->clear();
2556 
2557   FunctionVarLocsBuilder Builder;
2558   analyzeFunction(F, *DL.get(), &Builder);
2559 
2560   // Save these results.
2561   Results->init(Builder);
2562 
2563   if (PrintResults && isFunctionInPrintList(F.getName()))
2564     Results->print(errs(), F);
2565 
2566   // Return false because this pass does not modify the function.
2567   return false;
2568 }
2569 
2570 AssignmentTrackingAnalysis::AssignmentTrackingAnalysis()
2571     : FunctionPass(ID), Results(std::make_unique<FunctionVarLocs>()) {}
2572 
2573 char AssignmentTrackingAnalysis::ID = 0;
2574 
2575 INITIALIZE_PASS(AssignmentTrackingAnalysis, DEBUG_TYPE,
2576                 "Assignment Tracking Analysis", false, true)
2577