[llvm] 89950ad - [DebugInfo][InstrRef] Track a single variable at a time

Jeremy Morse via llvm-commits llvm-commits at lists.llvm.org
Wed Oct 20 07:04:09 PDT 2021


Author: Jeremy Morse
Date: 2021-10-20T15:03:52+01:00
New Revision: 89950ade216bcabf3cb9acf2cf7218763fd40a92

URL: https://github.com/llvm/llvm-project/commit/89950ade216bcabf3cb9acf2cf7218763fd40a92
DIFF: https://github.com/llvm/llvm-project/commit/89950ade216bcabf3cb9acf2cf7218763fd40a92.diff

LOG: [DebugInfo][InstrRef] Track a single variable at a time

Here's another performance patch for InstrRefBasedLDV: rather than
processing all variable values in a scope at a time, instead, process one
variable at a time. The benefits are twofold:
 * It's easier to reason about one variable at a time in your mind,
 * It improves performance, apparently from increased locality.

The downside is that the value-propagation code gets indented one level
further, plus there's some churn in the unit tests.

Differential Revision: https://reviews.llvm.org/D111799

Added: 
    

Modified: 
    llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
    llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h
    llvm/unittests/CodeGen/InstrRefLDVTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
index 9a36f46d8533..d286aa903547 100644
--- a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
+++ b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
@@ -2034,19 +2034,11 @@ Optional<ValueIDNum> InstrRefBasedLDV::pickVPHILoc(
 
   for (auto p : BlockOrders) {
     unsigned ThisBBNum = p->getNumber();
-    auto LiveOutMap = LiveOuts.find(p);
-    if (LiveOutMap == LiveOuts.end())
-      // This predecessor isn't in scope, it must have no live-in/live-out
-      // locations.
+    auto OutValIt = LiveOuts.find(p);
+    if (OutValIt == LiveOuts.end())
+      // If we have a predecessor not in scope, we'll never find a PHI position.
       return None;
-
-    auto It = LiveOutMap->second->find(Var);
-    if (It == LiveOutMap->second->end())
-      // There's no value recorded for this variable in this predecessor,
-      // leave an empty set of locations.
-      return None;
-
-    const DbgValue &OutVal = It->second;
+    const DbgValue &OutVal = *OutValIt->second;
 
     if (OutVal.Kind == DbgValue::Const || OutVal.Kind == DbgValue::NoVal)
       // Consts and no-values cannot have locations we can join on.
@@ -2124,10 +2116,9 @@ Optional<ValueIDNum> InstrRefBasedLDV::pickVPHILoc(
 
 bool InstrRefBasedLDV::vlocJoin(
     MachineBasicBlock &MBB, LiveIdxT &VLOCOutLocs,
-    const SmallSet<DebugVariable, 4> &AllVars,
     SmallPtrSet<const MachineBasicBlock *, 8> &InScopeBlocks,
     SmallPtrSet<const MachineBasicBlock *, 8> &BlocksToExplore,
-    DenseMap<DebugVariable, DbgValue> &LiveIns) {
+    DbgValue &LiveIn) {
   // To emulate VarLocBasedImpl, process this block if it's not in scope but
   // _does_ assign a variable value. No live-ins for this scope are transferred
   // in though, so we can return immediately.
@@ -2148,137 +2139,94 @@ bool InstrRefBasedLDV::vlocJoin(
 
   unsigned CurBlockRPONum = BBToOrder[&MBB];
 
-  // We re-construct the live-in map each time we join. For each variable, call
-  // one of these "confirm" utilities, according to which flavour of variable
-  // value it is.
-  auto ConfirmValue = [&LiveIns, &Changed](const DebugVariable &DV,
-                                           const DbgValue &VR) {
-    auto OldLiveIn = LiveIns.find(DV);
-    assert(OldLiveIn != LiveIns.end());
-    if (OldLiveIn->second != VR) {
-      Changed = true;
-      OldLiveIn->second = VR;
+  // Collect all the incoming DbgValues for this variable, from predecessor
+  // live-out values.
+  SmallVector<InValueT, 8> Values;
+  bool Bail = false;
+  int BackEdgesStart = 0;
+  for (auto p : BlockOrders) {
+    // If the predecessor isn't in scope / to be explored, we'll never be
+    // able to join any locations.
+    if (!BlocksToExplore.contains(p)) {
+      Bail = true;
+      break;
     }
-  };
-
-  auto ConfirmVPHI = [&ConfirmValue,
-                      &MBB](const DebugVariable &Var,
-                            const DbgValueProperties &Properties) {
-    DbgValue NoLocPHIVal(MBB.getNumber(), Properties, DbgValue::VPHI);
-    ConfirmValue(Var, NoLocPHIVal);
-  };
-
-  // Attempt to join the values for each variable.
-  for (auto &Var : AllVars) {
-    // Collect all the incoming DbgValues for this variable, from predecessor
-    // live-out values.
-    SmallVector<InValueT, 8> Values;
-    bool Bail = false;
-    int BackEdgesStart = 0;
-    for (auto p : BlockOrders) {
-      // If the predecessor isn't in scope / to be explored, we'll never be
-      // able to join any locations.
-      if (!BlocksToExplore.contains(p)) {
-        Bail = true;
-        break;
-      }
-
-      // If the predecessors OutLocs is absent, there's not much we can do.
-      auto OL = VLOCOutLocs.find(p);
-      if (OL == VLOCOutLocs.end()) {
-        Bail = true;
-        break;
-      }
 
-      // No live-out value for this predecessor also means we can't produce
-      // a joined value.
-      auto VIt = OL->second->find(Var);
-      if (VIt == OL->second->end()) {
-        Bail = true;
-        break;
-      }
-
-      // Keep track of where back-edges begin in the Values vector. Relies on
-      // BlockOrders being sorted by RPO.
-      unsigned ThisBBRPONum = BBToOrder[p];
-      if (ThisBBRPONum < CurBlockRPONum)
-        ++BackEdgesStart;
+    // All Live-outs will have been initialized.
+    DbgValue &OutLoc = *VLOCOutLocs.find(p)->second;
 
-      Values.push_back(std::make_pair(p, &VIt->second));
-    }
+    // Keep track of where back-edges begin in the Values vector. Relies on
+    // BlockOrders being sorted by RPO.
+    unsigned ThisBBRPONum = BBToOrder[p];
+    if (ThisBBRPONum < CurBlockRPONum)
+      ++BackEdgesStart;
 
-    // Pick out the live-in value from last time we vlocJoin'd this block.
-    auto LiveInIt = LiveIns.find(Var);
-    assert(LiveInIt != LiveIns.end() && "Uninitialized live-in vloc?");
-    const DbgValue &OldLiveInDbgValue = LiveInIt->second;
+    Values.push_back(std::make_pair(p, &OutLoc));
+  }
 
-    // If there were no values, or one of the predecessors couldn't have a
-    // value, then give up immediately. It's not safe to produce a live-in
-    // value. Leave as whatever it was before.
-    if (Bail || Values.size() == 0) {
-      ConfirmValue(Var, OldLiveInDbgValue);
-      continue;
-    }
+  // If there were no values, or one of the predecessors couldn't have a
+  // value, then give up immediately. It's not safe to produce a live-in
+  // value. Leave as whatever it was before.
+  if (Bail || Values.size() == 0)
+    return false;
 
-    // All (non-entry) blocks have at least one non-backedge predecessor.
-    // Pick the variable value from the first of these, to compare against
-    // all others.
-    const DbgValue &FirstVal = *Values[0].second;
-
-    // If the old live-in value is not a PHI then either a) no PHI is needed
-    // here, or b) we eliminated the PHI that was here. If so, we can just
-    // propagate in the first parents incoming value.
-    if (OldLiveInDbgValue.Kind != DbgValue::VPHI ||
-        OldLiveInDbgValue.BlockNo != MBB.getNumber()) {
-      ConfirmValue(Var, FirstVal);
-      continue;
-    }
+  // All (non-entry) blocks have at least one non-backedge predecessor.
+  // Pick the variable value from the first of these, to compare against
+  // all others.
+  const DbgValue &FirstVal = *Values[0].second;
+
+  // If the old live-in value is not a PHI then either a) no PHI is needed
+  // here, or b) we eliminated the PHI that was here. If so, we can just
+  // propagate in the first parent's incoming value.
+  if (LiveIn.Kind != DbgValue::VPHI || LiveIn.BlockNo != MBB.getNumber()) {
+    Changed = LiveIn != FirstVal;
+    if (Changed)
+      LiveIn = FirstVal;
+    return Changed;
+  }
+
+  // Scan for variable values that can never be resolved: if they have
+  // 
diff erent DIExpressions, 
diff erent indirectness, or are mixed constants /
+  // non-constants.
+  for (auto &V : Values) {
+    if (V.second->Properties != FirstVal.Properties)
+      return false;
+    if (V.second->Kind == DbgValue::NoVal)
+      return false;
+    if (V.second->Kind == DbgValue::Const && FirstVal.Kind != DbgValue::Const)
+      return false;
+  }
 
-    // Scan for variable values that can never be resolved: if they have
-    // 
diff erent DIExpressions, 
diff erent indirectness, or are mixed constants /
-    // non-constants.
-    bool AlwaysIncompatible = false;
-    for (auto &V : Values) {
-      if (V.second->Properties != FirstVal.Properties)
-        AlwaysIncompatible = true;
-      if (V.second->Kind == DbgValue::NoVal)
-        AlwaysIncompatible = true;
-      if (V.second->Kind == DbgValue::Const && FirstVal.Kind != DbgValue::Const)
-        AlwaysIncompatible = true;
-    }
+  // Try to eliminate this PHI. Do the incoming values all agree?
+  bool Disagree = false;
+  for (auto &V : Values) {
+    if (*V.second == FirstVal)
+      continue; // No disagreement.
 
-    if (AlwaysIncompatible) {
-      // Leave this as a VPHI.
-      ConfirmVPHI(Var, OldLiveInDbgValue.Properties);
+    // Eliminate if a backedge feeds a VPHI back into itself.
+    if (V.second->Kind == DbgValue::VPHI &&
+        V.second->BlockNo == MBB.getNumber() &&
+        // Is this a backedge?
+        std::distance(Values.begin(), &V) >= BackEdgesStart)
       continue;
-    }
-
-    // Try to eliminate this PHI. Do the incoming values all agree?
-    bool Disagree = false;
-    for (auto &V : Values) {
-      if (*V.second == FirstVal)
-        continue; // No disagreement.
-
-      // Eliminate if a backedge feeds a VPHI back into itself.
-      if (V.second->Kind == DbgValue::VPHI &&
-          V.second->BlockNo == MBB.getNumber() &&
-          // Is this a backedge?
-          std::distance(Values.begin(), &V) >= BackEdgesStart)
-        continue;
 
-      Disagree = true;
-    }
-
-    // No disagreement -> live-through value.
-    if (!Disagree) {
-      ConfirmValue(Var, FirstVal);
-    } else {
-      // Otherwise use a VPHI.
-      ConfirmVPHI(Var, FirstVal.Properties);
-    }
+    Disagree = true;
   }
 
-  return Changed;
+  // No disagreement -> live-through value.
+  if (!Disagree) {
+    Changed = LiveIn != FirstVal;
+    if (Changed)
+      LiveIn = FirstVal;
+    return Changed;
+  } else {
+    // Otherwise use a VPHI.
+    DbgValue VPHI(MBB.getNumber(), FirstVal.Properties, DbgValue::VPHI);
+    Changed = LiveIn != VPHI;
+    if (Changed)
+      LiveIn = VPHI;
+    return Changed;
+  }
 }
 
 void InstrRefBasedLDV::buildVLocValueMap(const DILocation *DILoc,
@@ -2383,6 +2331,13 @@ void InstrRefBasedLDV::buildVLocValueMap(const DILocation *DILoc,
   if (BlocksToExplore.size() == 1)
     return;
 
+  // Convert a const set to a non-const set. LexicalScopes
+  // getMachineBasicBlocks returns const MBB pointers, IDF wants mutable ones.
+  // (Neither of them mutate anything).
+  SmallPtrSet<MachineBasicBlock *, 8> MutBlocksToExplore;
+  for (const auto *MBB : BlocksToExplore)
+    MutBlocksToExplore.insert(const_cast<MachineBasicBlock *>(MBB));
+
   // Picks out relevants blocks RPO order and sort them.
   for (auto *MBB : BlocksToExplore)
     BlockOrders.push_back(const_cast<MachineBasicBlock *>(MBB));
@@ -2391,20 +2346,17 @@ void InstrRefBasedLDV::buildVLocValueMap(const DILocation *DILoc,
   unsigned NumBlocks = BlockOrders.size();
 
   // Allocate some vectors for storing the live ins and live outs. Large.
-  SmallVector<DenseMap<DebugVariable, DbgValue>, 32> LiveIns, LiveOuts;
-  LiveIns.resize(NumBlocks);
-  LiveOuts.resize(NumBlocks);
+  SmallVector<DbgValue, 32> LiveIns, LiveOuts;
+  LiveIns.reserve(NumBlocks);
+  LiveOuts.reserve(NumBlocks);
 
   // Initialize all values to start as NoVals. This signifies "it's live
   // through, but we don't know what it is".
   DbgValueProperties EmptyProperties(EmptyExpr, false);
-  unsigned int BlockIdx = 0;
-  for (auto &VarMap : LiveIns) {
-    for (const DebugVariable &Var : VarsWeCareAbout)
-      VarMap.insert(
-          {Var, DbgValue(BlockIdx, EmptyProperties, DbgValue::NoVal)});
-
-    ++BlockIdx;
+  for (unsigned int I = 0; I < NumBlocks; ++I) {
+    DbgValue EmptyDbgValue(I, EmptyProperties, DbgValue::NoVal);
+    LiveIns.push_back(EmptyDbgValue);
+    LiveOuts.push_back(EmptyDbgValue);
   }
 
   // Produce by-MBB indexes of live-in/live-outs, to ease lookup within
@@ -2417,26 +2369,20 @@ void InstrRefBasedLDV::buildVLocValueMap(const DILocation *DILoc,
     LiveInIdx[BlockOrders[I]] = &LiveIns[I];
   }
 
-  // Initialize all live-outs to "nothing", to avoid later conditionals.
-  for (auto &LiveOut : LiveOutIdx) {
-    const MachineBasicBlock *OutBB = LiveOut.first;
-    auto *LiveOutMap = LiveOut.second;
-    DbgValue EmptyDbgValue(OutBB->getNumber(), EmptyProperties,
-                           DbgValue::NoVal);
-    for (const DebugVariable &Var : VarsWeCareAbout)
-
-      LiveOutMap->insert(std::make_pair(Var, EmptyDbgValue));
-  }
-
-  // Convert a const set to a non-const set. LexicalScopes
-  // getMachineBasicBlocks returns const MBB pointers, IDF wants mutable ones.
-  // (Neither of them mutate anything).
-  SmallPtrSet<MachineBasicBlock *, 8> MutBlocksToExplore;
-  for (const auto *MBB : BlocksToExplore)
-    MutBlocksToExplore.insert(const_cast<MachineBasicBlock*>(MBB));
+  // Loop over each variable and place PHIs for it, then propagate values
+  // between blocks. This keeps the locality of working on one lexical scope at
+  // at time, but avoids re-processing variable values because some other
+  // variable has been assigned.
+  for (auto &Var : VarsWeCareAbout) {
+    // Re-initialize live-ins and live-outs, to clear the remains of previous
+    // variables live-ins / live-outs.
+    for (unsigned int I = 0; I < NumBlocks; ++I) {
+      DbgValue EmptyDbgValue(I, EmptyProperties, DbgValue::NoVal);
+      LiveIns[I] = EmptyDbgValue;
+      LiveOuts[I] = EmptyDbgValue;
+    }
 
-  // Place PHIs for variable values, using the LLVM IDF calculator.
-  for (const DebugVariable &Var : VarsWeCareAbout) {
+    // Place PHIs for variable values, using the LLVM IDF calculator.
     // Collect the set of blocks where variables are def'd.
     SmallPtrSet<MachineBasicBlock *, 32> DefBlocks;
     for (const MachineBasicBlock *ExpMBB : BlocksToExplore) {
@@ -2453,157 +2399,134 @@ void InstrRefBasedLDV::buildVLocValueMap(const DILocation *DILoc,
     // Insert PHIs into the per-block live-in tables for this variable.
     for (MachineBasicBlock *PHIMBB : PHIBlocks) {
       unsigned BlockNo = PHIMBB->getNumber();
-      auto *BlockLiveIns = LiveInIdx[PHIMBB];
-      auto It = BlockLiveIns->find(Var);
-      assert(It != BlockLiveIns->end() && "Uninitialized live-in?");
-      It->second = DbgValue(BlockNo, EmptyProperties, DbgValue::VPHI);
+      DbgValue *LiveIn = LiveInIdx[PHIMBB];
+      *LiveIn = DbgValue(BlockNo, EmptyProperties, DbgValue::VPHI);
     }
-  }
 
-  for (auto *MBB : BlockOrders) {
-    Worklist.push(BBToOrder[MBB]);
-    OnWorklist.insert(MBB);
-  }
-
-  // Iterate over all the blocks we selected, propagating variable values. This
-  // loop does two things:
-  //  * Eliminates un-necessary VPHIs in vlocJoin,
-  //  * Evaluates the blocks transfer function (i.e. variable assignments) and
-  //    stores the result to the blocks live-outs.
-  // Always evaluate the transfer function on the first iteration, and when the
-  // live-ins change thereafter.
-  bool FirstTrip = true;
-  while (!Worklist.empty() || !Pending.empty()) {
-    while (!Worklist.empty()) {
-      auto *MBB = OrderToBB[Worklist.top()];
-      CurBB = MBB->getNumber();
-      Worklist.pop();
-
-      auto BlockLiveInsIt = LiveInIdx.find(MBB);
-      assert(BlockLiveInsIt != LiveInIdx.end());
-      auto &BlockLiveIns = *BlockLiveInsIt->second;
-
-      // Join values from predecessors. Updates LiveInIdx, and writes output
-      // into JoinedInLocs.
-      bool InLocsChanged =
-          vlocJoin(*MBB, LiveOutIdx, VarsWeCareAbout, InScopeBlocks,
-                   BlocksToExplore, BlockLiveIns);
-
-      SmallVector<const MachineBasicBlock *, 8> Preds;
-      for (const auto *Pred : MBB->predecessors())
-        Preds.push_back(Pred);
-
-      // Opportunistically pick a machine-value for any VPHIs starting in this
-      // block. This makes their machine-value available and propagated through
-      // all blocks by the time value propagation finishes. We can't do this any
-      // earlier as it needs to read the block live-outs.
-      for (auto &Var : VarsWeCareAbout) {
-        DbgValue &Val = BlockLiveIns.find(Var)->second;
-        if (Val.Kind != DbgValue::VPHI || Val.BlockNo != (int)CurBB)
-          continue;
-
-        // There's a small possibility that on a preceeding path, a VPHI is
-        // eliminated and transitions from VPHI-with-location to
-        // live-through-value. As a result, the selected location of any VPHI
-        // might change, so we need to re-compute it on each iteration.
-        Optional<ValueIDNum> ValueNum = pickVPHILoc(
-                  *MBB, Var, LiveOutIdx, MOutLocs, Preds);
+    for (auto *MBB : BlockOrders) {
+      Worklist.push(BBToOrder[MBB]);
+      OnWorklist.insert(MBB);
+    }
 
-        if (ValueNum) {
-          InLocsChanged |= Val.ID != *ValueNum;
-          Val.ID = *ValueNum;
+    // Iterate over all the blocks we selected, propagating the variables value.
+    // This loop does two things:
+    //  * Eliminates un-necessary VPHIs in vlocJoin,
+    //  * Evaluates the blocks transfer function (i.e. variable assignments) and
+    //    stores the result to the blocks live-outs.
+    // Always evaluate the transfer function on the first iteration, and when
+    // the live-ins change thereafter.
+    bool FirstTrip = true;
+    while (!Worklist.empty() || !Pending.empty()) {
+      while (!Worklist.empty()) {
+        auto *MBB = OrderToBB[Worklist.top()];
+        CurBB = MBB->getNumber();
+        Worklist.pop();
+
+        auto LiveInsIt = LiveInIdx.find(MBB);
+        assert(LiveInsIt != LiveInIdx.end());
+        DbgValue *LiveIn = LiveInsIt->second;
+
+        // Join values from predecessors. Updates LiveInIdx, and writes output
+        // into JoinedInLocs.
+        bool InLocsChanged =
+            vlocJoin(*MBB, LiveOutIdx, InScopeBlocks, BlocksToExplore, *LiveIn);
+
+        SmallVector<const MachineBasicBlock *, 8> Preds;
+        for (const auto *Pred : MBB->predecessors())
+          Preds.push_back(Pred);
+
+        // If this block's live-in value is a VPHI, try to pick a machine-value
+        // for it. This makes the machine-value available and propagated
+        // through all blocks by the time value propagation finishes. We can't
+        // do this any earlier as it needs to read the block live-outs.
+        if (LiveIn->Kind == DbgValue::VPHI && LiveIn->BlockNo == (int)CurBB) {
+          // There's a small possibility that on a preceeding path, a VPHI is
+          // eliminated and transitions from VPHI-with-location to
+          // live-through-value. As a result, the selected location of any VPHI
+          // might change, so we need to re-compute it on each iteration.
+          Optional<ValueIDNum> ValueNum =
+              pickVPHILoc(*MBB, Var, LiveOutIdx, MOutLocs, Preds);
+
+          if (ValueNum) {
+            InLocsChanged |= LiveIn->ID != *ValueNum;
+            LiveIn->ID = *ValueNum;
+          }
         }
-      }
-
-      if (!InLocsChanged && !FirstTrip)
-        continue;
 
-      auto &LiveOuts = *LiveOutIdx[MBB];
-      bool OLChanged = false;
+        if (!InLocsChanged && !FirstTrip)
+          continue;
 
-      // Do transfer function.
-      auto &VTracker = AllTheVLocs[MBB->getNumber()];
-      SmallSet<DebugVariable, 8> VarsTransferred;
-      for (auto &Transfer : VTracker.Vars) {
-        // Is this var we're mangling in this scope?
-        if (VarsWeCareAbout.count(Transfer.first)) {
-          VarsTransferred.insert(Transfer.first);
-          auto OutIt = LiveOuts.find(Transfer.first);
-          assert(OutIt != LiveOuts.end());
+        DbgValue *LiveOut = LiveOutIdx[MBB];
+        bool OLChanged = false;
 
+        // Do transfer function.
+        auto &VTracker = AllTheVLocs[MBB->getNumber()];
+        auto TransferIt = VTracker.Vars.find(Var);
+        if (TransferIt != VTracker.Vars.end()) {
           // Erase on empty transfer (DBG_VALUE $noreg).
-          if (Transfer.second.Kind == DbgValue::Undef) {
+          if (TransferIt->second.Kind == DbgValue::Undef) {
             DbgValue NewVal(MBB->getNumber(), EmptyProperties, DbgValue::NoVal);
-            if (OutIt->second != NewVal) {
-              OutIt->second = NewVal;
+            if (*LiveOut != NewVal) {
+              *LiveOut = NewVal;
               OLChanged = true;
             }
           } else {
             // Insert new variable value; or overwrite.
-            if (OutIt->second != Transfer.second) {
-              OutIt->second = Transfer.second;
+            if (*LiveOut != TransferIt->second) {
+              *LiveOut = TransferIt->second;
               OLChanged = true;
             }
           }
+        } else {
+          // Just copy live-ins to live-outs, for anything not transferred.
+          if (*LiveOut != *LiveIn) {
+            *LiveOut = *LiveIn;
+            OLChanged = true;
+          }
         }
-      }
 
-      // For anything not assigned by the transfer function, copy live-in to
-      // live-outs.
-      for (const DebugVariable &Var : VarsWeCareAbout) {
-        if (VarsTransferred.count(Var))
+        // If no live-out value changed, there's no need to explore further.
+        if (!OLChanged)
           continue;
 
-        auto OutIt = LiveOuts.find(Var);
-        auto InIt = BlockLiveIns.find(Var);
-        if (InIt->second != OutIt->second) {
-          OutIt->second = InIt->second;
-          OLChanged = true;
-        }
-      }
-
-      // If no live-out value changed, there's no need to explore further.
-      if (!OLChanged)
-        continue;
-
-      // We should visit all successors. Ensure we'll visit any non-backedge
-      // successors during this dataflow iteration; book backedge successors
-      // to be visited next time around.
-      for (auto s : MBB->successors()) {
-        // Ignore out of scope / not-to-be-explored successors.
-        if (LiveInIdx.find(s) == LiveInIdx.end())
-          continue;
+        // We should visit all successors. Ensure we'll visit any non-backedge
+        // successors during this dataflow iteration; book backedge successors
+        // to be visited next time around.
+        for (auto s : MBB->successors()) {
+          // Ignore out of scope / not-to-be-explored successors.
+          if (LiveInIdx.find(s) == LiveInIdx.end())
+            continue;
 
-        if (BBToOrder[s] > BBToOrder[MBB]) {
-          if (OnWorklist.insert(s).second)
-            Worklist.push(BBToOrder[s]);
-        } else if (OnPending.insert(s).second && (FirstTrip || OLChanged)) {
-          Pending.push(BBToOrder[s]);
+          if (BBToOrder[s] > BBToOrder[MBB]) {
+            if (OnWorklist.insert(s).second)
+              Worklist.push(BBToOrder[s]);
+          } else if (OnPending.insert(s).second && (FirstTrip || OLChanged)) {
+            Pending.push(BBToOrder[s]);
+          }
         }
       }
+      Worklist.swap(Pending);
+      std::swap(OnWorklist, OnPending);
+      OnPending.clear();
+      assert(Pending.empty());
+      FirstTrip = false;
     }
-    Worklist.swap(Pending);
-    std::swap(OnWorklist, OnPending);
-    OnPending.clear();
-    assert(Pending.empty());
-    FirstTrip = false;
-  }
 
-  // Save live-ins to output vector. Ignore any that are still marked as being
-  // VPHIs with no location -- those are variables that we know the value of,
-  // but are not actually available in the register file.
-  for (auto *MBB : BlockOrders) {
-    auto &VarMap = *LiveInIdx[MBB];
-    for (auto &P : VarMap) {
-      if (P.second.Kind == DbgValue::NoVal)
+    // Save live-ins to output vector. Ignore any that are still marked as being
+    // VPHIs with no location -- those are variables that we know the value of,
+    // but are not actually available in the register file.
+    for (auto *MBB : BlockOrders) {
+      DbgValue *BlockLiveIn = LiveInIdx[MBB];
+      if (BlockLiveIn->Kind == DbgValue::NoVal)
         continue;
-      if (P.second.Kind == DbgValue::VPHI && P.second.ID == ValueIDNum::EmptyValue)
+      if (BlockLiveIn->Kind == DbgValue::VPHI &&
+          BlockLiveIn->ID == ValueIDNum::EmptyValue)
         continue;
-      if (P.second.Kind == DbgValue::VPHI)
-        P.second.Kind = DbgValue::Def;
-      Output[MBB->getNumber()].push_back(P);
+      if (BlockLiveIn->Kind == DbgValue::VPHI)
+        BlockLiveIn->Kind = DbgValue::Def;
+      Output[MBB->getNumber()].push_back(std::make_pair(Var, *BlockLiveIn));
     }
-  }
+  } // Per-variable loop.
 
   BlockOrders.clear();
   BlocksToExplore.clear();

diff  --git a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h
index 2ced4578c4c6..0de8ed5fc352 100644
--- a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h
+++ b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h
@@ -636,9 +636,8 @@ class InstrRefBasedLDV : public LDVImpl {
   using MLocTransferMap = std::map<LocIdx, ValueIDNum>;
 
   /// Live in/out structure for the variable values: a per-block map of
-  /// variables to their values. XXX, better name?
-  using LiveIdxT =
-      DenseMap<const MachineBasicBlock *, DenseMap<DebugVariable, DbgValue> *>;
+  /// variables to their values.
+  using LiveIdxT = DenseMap<const MachineBasicBlock *, DbgValue *>;
 
   using VarAndLoc = std::pair<DebugVariable, DbgValue>;
 
@@ -856,16 +855,14 @@ class InstrRefBasedLDV : public LDVImpl {
   /// Attempt to eliminate un-necessary PHIs on entry to a block. Examines the
   /// live-in values coming from predecessors live-outs, and replaces any PHIs
   /// already present in this blocks live-ins with a live-through value if the
-  /// PHI isn't needed. Live out variable values are stored in
-  /// \p VLOCOutLocs. The live-ins for \p MBB are stored in \p LiveIns, which
-  /// is also an output argument.
+  /// PHI isn't needed.
+  /// \p LiveIn Old live-in value, overwritten with new one if live-in changes.
   /// \returns true if any live-ins change value, either from value propagation
   ///          or PHI elimination.
   bool vlocJoin(MachineBasicBlock &MBB, LiveIdxT &VLOCOutLocs,
-                const SmallSet<DebugVariable, 4> &AllVars,
                 SmallPtrSet<const MachineBasicBlock *, 8> &InScopeBlocks,
                 SmallPtrSet<const MachineBasicBlock *, 8> &BlocksToExplore,
-                DenseMap<DebugVariable, DbgValue> &LiveIns);
+                DbgValue &LiveIn);
 
   /// For the given block and live-outs feeding into it, try to find a
   /// machine location where all the variable values join together.

diff  --git a/llvm/unittests/CodeGen/InstrRefLDVTest.cpp b/llvm/unittests/CodeGen/InstrRefLDVTest.cpp
index d460a0353c1c..c6420b5b5a02 100644
--- a/llvm/unittests/CodeGen/InstrRefLDVTest.cpp
+++ b/llvm/unittests/CodeGen/InstrRefLDVTest.cpp
@@ -179,12 +179,11 @@ class InstrRefLDVTest : public testing::Test {
   }
 
   bool vlocJoin(MachineBasicBlock &MBB, InstrRefBasedLDV::LiveIdxT &VLOCOutLocs,
-                const SmallSet<DebugVariable, 4> &AllVars,
                 SmallPtrSet<const MachineBasicBlock *, 8> &InScopeBlocks,
                 SmallPtrSet<const MachineBasicBlock *, 8> &BlocksToExplore,
-                DenseMap<DebugVariable, DbgValue> &InLocsT) {
-    return LDV->vlocJoin(MBB, VLOCOutLocs, AllVars, InScopeBlocks,
-                         BlocksToExplore, InLocsT);
+                DbgValue &InLoc) {
+    return LDV->vlocJoin(MBB, VLOCOutLocs, InScopeBlocks, BlocksToExplore,
+                         InLoc);
   }
 
   void buildVLocValueMap(const DILocation *DILoc,
@@ -1242,8 +1241,8 @@ TEST_F(InstrRefLDVTest, pickVPHILocDiamond) {
 
   DebugVariable Var(FuncVariable, None, nullptr);
   DbgValueProperties EmptyProps(EmptyExpr, false);
-  SmallVector<DenseMap<DebugVariable, DbgValue>, 32> VLiveOuts;
-  VLiveOuts.resize(4);
+  SmallVector<DbgValue, 32> VLiveOuts;
+  VLiveOuts.resize(4, DbgValue(EmptyProps, DbgValue::Undef));
   InstrRefBasedLDV::LiveIdxT VLiveOutIdx;
   VLiveOutIdx[MBB0] = &VLiveOuts[0];
   VLiveOutIdx[MBB1] = &VLiveOuts[1];
@@ -1261,8 +1260,8 @@ TEST_F(InstrRefLDVTest, pickVPHILocDiamond) {
   Optional<ValueIDNum> Result;
 
   // Simple case: join two distinct values on entry to the block.
-  VLiveOuts[1].insert({Var,  DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)});
-  VLiveOuts[2].insert({Var,  DbgValue(LiveInRax, EmptyProps, DbgValue::Def)});
+  VLiveOuts[1] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  VLiveOuts[2] = DbgValue(LiveInRax, EmptyProps, DbgValue::Def);
   Result = pickVPHILoc(*MBB3, Var, VLiveOutIdx, OutLocsPtr, Preds);
   // Should have picked a PHI in $rsp in block 3.
   EXPECT_TRUE(Result);
@@ -1280,22 +1279,20 @@ TEST_F(InstrRefLDVTest, pickVPHILocDiamond) {
   // Swap back,
   std::swap(VLiveOuts[1], VLiveOuts[2]);
   // Setting one of these to being a constant should prohibit merging.
-  VLiveOuts[1].find(Var)->second.Kind = DbgValue::Const;
-  VLiveOuts[1].find(Var)->second.MO = MachineOperand::CreateImm(0);
+  VLiveOuts[1].Kind = DbgValue::Const;
+  VLiveOuts[1].MO = MachineOperand::CreateImm(0);
   Result = pickVPHILoc(*MBB3, Var, VLiveOutIdx, OutLocsPtr, Preds);
   EXPECT_FALSE(Result);
 
   // Seeing both to being a constant -> still prohibit, it shouldn't become
   // a value in the register file anywhere.
-  VLiveOuts[2].find(Var)->second = VLiveOuts[1].find(Var)->second;
+  VLiveOuts[2] = VLiveOuts[1];
   Result = pickVPHILoc(*MBB3, Var, VLiveOutIdx, OutLocsPtr, Preds);
   EXPECT_FALSE(Result);
 
   // NoVals shouldn't join with anything else.
-  VLiveOuts[1].clear();
-  VLiveOuts[2].clear();
-  VLiveOuts[1].insert({Var,  DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)});
-  VLiveOuts[2].insert({Var,  DbgValue(2, EmptyProps, DbgValue::NoVal)});
+  VLiveOuts[1] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  VLiveOuts[2] = DbgValue(2, EmptyProps, DbgValue::NoVal);
   Result = pickVPHILoc(*MBB3, Var, VLiveOutIdx, OutLocsPtr, Preds);
   EXPECT_FALSE(Result);
 
@@ -1303,9 +1300,9 @@ TEST_F(InstrRefLDVTest, pickVPHILocDiamond) {
   // such a scenario: first, where one incoming edge has a VPHI with no known
   // value. This represents an edge where there was a PHI value that can't be
   // found in the register file -- we can't subsequently find a PHI here.
-  VLiveOuts[2].clear();
-  VLiveOuts[2].insert({Var,  DbgValue(2, EmptyProps, DbgValue::VPHI)});
-  EXPECT_EQ(VLiveOuts[2].find(Var)->second.ID, ValueIDNum::EmptyValue);
+  VLiveOuts[1] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  VLiveOuts[2] = DbgValue(2, EmptyProps, DbgValue::VPHI);
+  EXPECT_EQ(VLiveOuts[2].ID, ValueIDNum::EmptyValue);
   Result = pickVPHILoc(*MBB3, Var, VLiveOutIdx, OutLocsPtr, Preds);
   EXPECT_FALSE(Result);
 
@@ -1313,7 +1310,9 @@ TEST_F(InstrRefLDVTest, pickVPHILocDiamond) {
   // location. Use a PHI machine-value for doing this, as VPHIs should always
   // have PHI values, or they should have been eliminated.
   OutLocs[2][0] = RspPHIInBlk2;
-  VLiveOuts[2].find(Var)->second.ID = RspPHIInBlk2;
+  VLiveOuts[1] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  VLiveOuts[2] = DbgValue(2, EmptyProps, DbgValue::VPHI);
+  VLiveOuts[2].ID = RspPHIInBlk2; // Set location where PHI happens.
   Result = pickVPHILoc(*MBB3, Var, VLiveOutIdx, OutLocsPtr, Preds);
   EXPECT_TRUE(Result);
   if (Result) {
@@ -1327,16 +1326,17 @@ TEST_F(InstrRefLDVTest, pickVPHILocDiamond) {
 
   // Check that we don't pick values when the properties disagree, for example
   // 
diff erent indirectness or DIExpression.
-  DIExpression *NewExpr = DIExpression::prepend(EmptyExpr, DIExpression::ApplyOffset, 4);
+  DIExpression *NewExpr =
+      DIExpression::prepend(EmptyExpr, DIExpression::ApplyOffset, 4);
   DbgValueProperties PropsWithExpr(NewExpr, false);
-  VLiveOuts[2].clear();
-  VLiveOuts[2].insert({Var,  DbgValue(LiveInRsp, PropsWithExpr, DbgValue::Def)});
+  VLiveOuts[1] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  VLiveOuts[2] = DbgValue(LiveInRsp, PropsWithExpr, DbgValue::Def);
   Result = pickVPHILoc(*MBB3, Var, VLiveOutIdx, OutLocsPtr, Preds);
   EXPECT_FALSE(Result);
 
   DbgValueProperties PropsWithIndirect(EmptyExpr, true);
-  VLiveOuts[2].clear();
-  VLiveOuts[2].insert({Var,  DbgValue(LiveInRsp, PropsWithIndirect, DbgValue::Def)});
+  VLiveOuts[1] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  VLiveOuts[2] = DbgValue(LiveInRsp, PropsWithIndirect, DbgValue::Def);
   Result = pickVPHILoc(*MBB3, Var, VLiveOutIdx, OutLocsPtr, Preds);
   EXPECT_FALSE(Result);
 }
@@ -1370,8 +1370,8 @@ TEST_F(InstrRefLDVTest, pickVPHILocLoops) {
 
   DebugVariable Var(FuncVariable, None, nullptr);
   DbgValueProperties EmptyProps(EmptyExpr, false);
-  SmallVector<DenseMap<DebugVariable, DbgValue>, 32> VLiveOuts;
-  VLiveOuts.resize(3);
+  SmallVector<DbgValue, 32> VLiveOuts;
+  VLiveOuts.resize(3, DbgValue(EmptyProps, DbgValue::Undef));
   InstrRefBasedLDV::LiveIdxT VLiveOutIdx;
   VLiveOutIdx[MBB0] = &VLiveOuts[0];
   VLiveOutIdx[MBB1] = &VLiveOuts[1];
@@ -1388,8 +1388,8 @@ TEST_F(InstrRefLDVTest, pickVPHILocLoops) {
   Optional<ValueIDNum> Result;
 
   // See that we can merge as normal on a backedge.
-  VLiveOuts[0].insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)});
-  VLiveOuts[1].insert({Var, DbgValue(LiveInRax, EmptyProps, DbgValue::Def)});
+  VLiveOuts[0] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  VLiveOuts[1] = DbgValue(LiveInRax, EmptyProps, DbgValue::Def);
   Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, OutLocsPtr, Preds);
   // Should have picked a PHI in $rsp in block 1.
   EXPECT_TRUE(Result);
@@ -1410,11 +1410,9 @@ TEST_F(InstrRefLDVTest, pickVPHILocLoops) {
   OutLocs[0][1] = LiveInRsp;
   OutLocs[1][0] = RaxPHIInBlk1;
   OutLocs[1][1] = RaxPHIInBlk1;
-  VLiveOuts[0].clear();
-  VLiveOuts[1].clear();
-  VLiveOuts[0].insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)});
+  VLiveOuts[0] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
   // Crucially, a VPHI originating in this block:
-  VLiveOuts[1].insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)});
+  VLiveOuts[1] = DbgValue(1, EmptyProps, DbgValue::VPHI);
   Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, OutLocsPtr, Preds);
   EXPECT_TRUE(Result);
   if (Result) {
@@ -1430,8 +1428,8 @@ TEST_F(InstrRefLDVTest, pickVPHILocLoops) {
   // Additionally, if the VPHI coming back on the loop backedge isn't from
   // this block (block 1), we can't merge it.
   OutLocs[1][1] = RaxPHIInBlk1;
-  VLiveOuts[1].clear();
-  VLiveOuts[1].insert({Var, DbgValue(0, EmptyProps, DbgValue::VPHI)});
+  VLiveOuts[0] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  VLiveOuts[1] = DbgValue(0, EmptyProps, DbgValue::VPHI);
   Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, OutLocsPtr, Preds);
   EXPECT_FALSE(Result);
 }
@@ -1474,8 +1472,8 @@ TEST_F(InstrRefLDVTest, pickVPHILocBadlyNestedLoops) {
 
   DebugVariable Var(FuncVariable, None, nullptr);
   DbgValueProperties EmptyProps(EmptyExpr, false);
-  SmallVector<DenseMap<DebugVariable, DbgValue>, 32> VLiveOuts;
-  VLiveOuts.resize(5);
+  SmallVector<DbgValue, 32> VLiveOuts;
+  VLiveOuts.resize(5, DbgValue(EmptyProps, DbgValue::Undef));
   InstrRefBasedLDV::LiveIdxT VLiveOutIdx;
   VLiveOutIdx[MBB0] = &VLiveOuts[0];
   VLiveOutIdx[MBB1] = &VLiveOuts[1];
@@ -1497,9 +1495,9 @@ TEST_F(InstrRefLDVTest, pickVPHILocBadlyNestedLoops) {
   Optional<ValueIDNum> Result;
 
   // See that we can merge as normal on a backedge.
-  VLiveOuts[0].insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)});
-  VLiveOuts[1].insert({Var, DbgValue(LiveInRax, EmptyProps, DbgValue::Def)});
-  VLiveOuts[2].insert({Var, DbgValue(LiveInRbx, EmptyProps, DbgValue::Def)});
+  VLiveOuts[0] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  VLiveOuts[1] = DbgValue(LiveInRax, EmptyProps, DbgValue::Def);
+  VLiveOuts[2] = DbgValue(LiveInRbx, EmptyProps, DbgValue::Def);
   Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, OutLocsPtr, Preds);
   // Should have picked a PHI in $rsp in block 1.
   EXPECT_TRUE(Result);
@@ -1526,8 +1524,9 @@ TEST_F(InstrRefLDVTest, pickVPHILocBadlyNestedLoops) {
 
   // If the variables value on that edge is a VPHI feeding into itself, that's
   // fine.
-  VLiveOuts[1].clear();
-  VLiveOuts[1].insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)});
+  VLiveOuts[0] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  VLiveOuts[1] = DbgValue(1, EmptyProps, DbgValue::VPHI);
+  VLiveOuts[2] = DbgValue(LiveInRbx, EmptyProps, DbgValue::Def);
   Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, OutLocsPtr, Preds);
   EXPECT_TRUE(Result);
   if (Result) {
@@ -1536,8 +1535,9 @@ TEST_F(InstrRefLDVTest, pickVPHILocBadlyNestedLoops) {
 
   // Likewise: the other backedge being a VPHI from block 1 should be accepted.
   OutLocs[2][0] = RspPHIInBlk1;
-  VLiveOuts[2].clear();
-  VLiveOuts[2].insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)});
+  VLiveOuts[0] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  VLiveOuts[1] = DbgValue(1, EmptyProps, DbgValue::VPHI);
+  VLiveOuts[2] = DbgValue(1, EmptyProps, DbgValue::VPHI);
   Result = pickVPHILoc(*MBB1, Var, VLiveOutIdx, OutLocsPtr, Preds);
   EXPECT_TRUE(Result);
   if (Result) {
@@ -1601,18 +1601,13 @@ TEST_F(InstrRefLDVTest, vlocJoinDiamond) {
 
   DebugVariable Var(FuncVariable, None, nullptr);
   DbgValueProperties EmptyProps(EmptyExpr, false);
-  SmallVector<DenseMap<DebugVariable, DbgValue>, 32> VLiveOuts, VLiveIns;
-  VLiveOuts.resize(4);
-  VLiveIns.resize(4);
-  InstrRefBasedLDV::LiveIdxT VLiveOutIdx, VLiveInIdx;
+  SmallVector<DbgValue, 32> VLiveOuts;
+  VLiveOuts.resize(4, DbgValue(EmptyProps, DbgValue::Undef));
+  InstrRefBasedLDV::LiveIdxT VLiveOutIdx;
   VLiveOutIdx[MBB0] = &VLiveOuts[0];
   VLiveOutIdx[MBB1] = &VLiveOuts[1];
   VLiveOutIdx[MBB2] = &VLiveOuts[2];
   VLiveOutIdx[MBB3] = &VLiveOuts[3];
-  VLiveInIdx[MBB0] = &VLiveIns[0];
-  VLiveInIdx[MBB1] = &VLiveIns[1];
-  VLiveInIdx[MBB2] = &VLiveIns[2];
-  VLiveInIdx[MBB3] = &VLiveIns[3];
 
   SmallPtrSet<const MachineBasicBlock *, 8> AllBlocks;
   AllBlocks.insert(MBB0);
@@ -1627,43 +1622,33 @@ TEST_F(InstrRefLDVTest, vlocJoinDiamond) {
   SmallSet<DebugVariable, 4> AllVars;
   AllVars.insert(Var);
 
-  DenseMap<DebugVariable, DbgValue> JoinedLocs;
-
   // vlocJoin is here to propagate incoming values, and eliminate PHIs. Start
   // off by propagating a value into the merging block, number 3.
-  JoinedLocs.insert({Var, DbgValue(3, EmptyProps, DbgValue::NoVal)});
-  VLiveOuts[1].insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)});
-  VLiveOuts[2].insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)});
-  bool Result =
-      vlocJoin(*MBB3, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs);
+  DbgValue JoinedLoc = DbgValue(3, EmptyProps, DbgValue::NoVal);
+  VLiveOuts[1] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  VLiveOuts[2] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  bool Result = vlocJoin(*MBB3, VLiveOutIdx, AllBlocks, AllBlocks, JoinedLoc);
   EXPECT_TRUE(Result); // Output locs should have changed.
-  auto It = JoinedLocs.find(Var);
-  EXPECT_EQ(It->second.Kind, DbgValue::Def);
-  EXPECT_EQ(It->second.ID, LiveInRsp);
-  // JoinedLocs.clear(); <--- leave commented out for next test,
+  EXPECT_EQ(JoinedLoc.Kind, DbgValue::Def);
+  EXPECT_EQ(JoinedLoc.ID, LiveInRsp);
 
   // And if we did it a second time, leaving the live-ins as it was, then
   // we should report no change.
-  Result =
-      vlocJoin(*MBB3, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs);
+  Result = vlocJoin(*MBB3, VLiveOutIdx, AllBlocks, AllBlocks, JoinedLoc);
   EXPECT_FALSE(Result);
-  JoinedLocs.clear();
 
   // If the live-in variable values are 
diff erent, but there's no PHI placed
   // in this block, then just pick a location. It should be the first (in RPO)
   // predecessor to avoid being a backedge.
-  VLiveOuts[2].clear();
-  VLiveOuts[2].insert({Var, DbgValue(LiveInRax, EmptyProps, DbgValue::Def)});
-  JoinedLocs.insert({Var, DbgValue(3, EmptyProps, DbgValue::NoVal)});
-  Result =
-      vlocJoin(*MBB3, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs);
+  VLiveOuts[1] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  VLiveOuts[2] = DbgValue(LiveInRax, EmptyProps, DbgValue::Def);
+  JoinedLoc = DbgValue(3, EmptyProps, DbgValue::NoVal);
+  Result = vlocJoin(*MBB3, VLiveOutIdx, AllBlocks, AllBlocks, JoinedLoc);
   EXPECT_TRUE(Result);
-  It = JoinedLocs.find(Var);
-  EXPECT_EQ(It->second.Kind, DbgValue::Def);
+  EXPECT_EQ(JoinedLoc.Kind, DbgValue::Def);
   // RPO is blocks 0 2 1 3, so LiveInRax is picked as the first predecessor
   // of this join.
-  EXPECT_EQ(It->second.ID, LiveInRax);
-  JoinedLocs.clear();
+  EXPECT_EQ(JoinedLoc.ID, LiveInRax);
 
   // No tests for whether vlocJoin will pass-through a variable with 
diff ering
   // expressions / properties. Those can only come about due to assignments; and
@@ -1673,114 +1658,81 @@ TEST_F(InstrRefLDVTest, vlocJoinDiamond) {
 
   // Try placing a PHI. With 
diff ering input values (LiveInRsp, LiveInRax),
   // this PHI should not be eliminated.
-  JoinedLocs.insert({Var, DbgValue(3, EmptyProps, DbgValue::VPHI)});
-  Result =
-      vlocJoin(*MBB3, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs);
+  JoinedLoc = DbgValue(3, EmptyProps, DbgValue::VPHI);
+  Result = vlocJoin(*MBB3, VLiveOutIdx, AllBlocks, AllBlocks, JoinedLoc);
   // Expect no change.
   EXPECT_FALSE(Result);
-  It = JoinedLocs.find(Var);
-  EXPECT_EQ(It->second.Kind, DbgValue::VPHI);
+  EXPECT_EQ(JoinedLoc.Kind, DbgValue::VPHI);
   // This should not have been assigned a fixed value.
-  EXPECT_EQ(It->second.ID, ValueIDNum::EmptyValue);
-  EXPECT_EQ(It->second.BlockNo, 3);
-  JoinedLocs.clear();
+  EXPECT_EQ(JoinedLoc.ID, ValueIDNum::EmptyValue);
+  EXPECT_EQ(JoinedLoc.BlockNo, 3);
 
   // Try a simple PHI elimination. Put a PHI in block 3, but LiveInRsp on both
   // incoming edges. Re-load in and out-locs with unrelated values; they're
   // irrelevant.
-  VLiveOuts[1].clear();
-  VLiveOuts[2].clear();
-  VLiveOuts[1].insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)});
-  VLiveOuts[2].insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)});
-  JoinedLocs.insert({Var, DbgValue(3, EmptyProps, DbgValue::VPHI)});
-  Result =
-      vlocJoin(*MBB3, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs);
+  VLiveOuts[1] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  VLiveOuts[2] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  JoinedLoc = DbgValue(3, EmptyProps, DbgValue::VPHI);
+  Result = vlocJoin(*MBB3, VLiveOutIdx, AllBlocks, AllBlocks, JoinedLoc);
   EXPECT_TRUE(Result);
-  It = JoinedLocs.find(Var);
-  EXPECT_EQ(It->second.Kind, DbgValue::Def);
-  EXPECT_EQ(It->second.ID, LiveInRsp);
-  JoinedLocs.clear();
+  EXPECT_EQ(JoinedLoc.Kind, DbgValue::Def);
+  EXPECT_EQ(JoinedLoc.ID, LiveInRsp);
 
   // If the "current" live-in is a VPHI, but not a VPHI generated in the current
   // block, then it's the remains of an earlier value propagation. We should
   // value propagate through this merge. Even if the current incoming values
   // disagree, because we've previously determined any VPHI here is redundant.
-  VLiveOuts[1].clear();
-  VLiveOuts[2].clear();
-  VLiveOuts[1].insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)});
-  VLiveOuts[2].insert({Var, DbgValue(LiveInRax, EmptyProps, DbgValue::Def)});
-  JoinedLocs.insert({Var, DbgValue(2, EmptyProps, DbgValue::VPHI)});
-  Result =
-      vlocJoin(*MBB3, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs);
+  VLiveOuts[1] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  VLiveOuts[2] = DbgValue(LiveInRax, EmptyProps, DbgValue::Def);
+  JoinedLoc = DbgValue(2, EmptyProps, DbgValue::VPHI);
+  Result = vlocJoin(*MBB3, VLiveOutIdx, AllBlocks, AllBlocks, JoinedLoc);
   EXPECT_TRUE(Result);
-  It = JoinedLocs.find(Var);
-  EXPECT_EQ(It->second.Kind, DbgValue::Def);
-  EXPECT_EQ(It->second.ID, LiveInRax); // from block 2
-  JoinedLocs.clear();
+  EXPECT_EQ(JoinedLoc.Kind, DbgValue::Def);
+  EXPECT_EQ(JoinedLoc.ID, LiveInRax); // from block 2
 
   // The above test, but test that we will install one value-propagated VPHI
   // over another.
-  VLiveOuts[1].clear();
-  VLiveOuts[2].clear();
-  VLiveOuts[1].insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)});
-  VLiveOuts[2].insert({Var, DbgValue(0, EmptyProps, DbgValue::VPHI)});
-  JoinedLocs.insert({Var, DbgValue(2, EmptyProps, DbgValue::VPHI)});
-  Result =
-      vlocJoin(*MBB3, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs);
+  VLiveOuts[1] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  VLiveOuts[2] = DbgValue(0, EmptyProps, DbgValue::VPHI);
+  JoinedLoc = DbgValue(2, EmptyProps, DbgValue::VPHI);
+  Result = vlocJoin(*MBB3, VLiveOutIdx, AllBlocks, AllBlocks, JoinedLoc);
   EXPECT_TRUE(Result);
-  It = JoinedLocs.find(Var);
-  EXPECT_EQ(It->second.Kind, DbgValue::VPHI);
-  EXPECT_EQ(It->second.BlockNo, 0);
-  JoinedLocs.clear();
+  EXPECT_EQ(JoinedLoc.Kind, DbgValue::VPHI);
+  EXPECT_EQ(JoinedLoc.BlockNo, 0);
 
   // We shouldn't eliminate PHIs when properties disagree.
   DbgValueProperties PropsWithIndirect(EmptyExpr, true);
-  VLiveOuts[1].clear();
-  VLiveOuts[2].clear();
-  VLiveOuts[1].insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)});
-  VLiveOuts[2].insert(
-      {Var, DbgValue(LiveInRsp, PropsWithIndirect, DbgValue::Def)});
-  JoinedLocs.insert({Var, DbgValue(3, EmptyProps, DbgValue::VPHI)});
-  Result =
-      vlocJoin(*MBB3, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs);
+  VLiveOuts[1] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  VLiveOuts[2] = DbgValue(LiveInRsp, PropsWithIndirect, DbgValue::Def);
+  JoinedLoc = DbgValue(3, EmptyProps, DbgValue::VPHI);
+  Result = vlocJoin(*MBB3, VLiveOutIdx, AllBlocks, AllBlocks, JoinedLoc);
   EXPECT_FALSE(Result);
-  It = JoinedLocs.find(Var);
-  EXPECT_EQ(It->second.Kind, DbgValue::VPHI);
-  EXPECT_EQ(It->second.BlockNo, 3);
-  JoinedLocs.clear();
+  EXPECT_EQ(JoinedLoc.Kind, DbgValue::VPHI);
+  EXPECT_EQ(JoinedLoc.BlockNo, 3);
 
   // Even if properties disagree, we should still value-propagate if there's no
   // PHI to be eliminated. The disagreeing values should work themselves out,
   // seeing how we've determined no PHI is necessary.
-  VLiveOuts[1].clear();
-  VLiveOuts[2].clear();
-  VLiveOuts[1].insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)});
-  VLiveOuts[2].insert(
-      {Var, DbgValue(LiveInRsp, PropsWithIndirect, DbgValue::Def)});
-  JoinedLocs.insert({Var, DbgValue(2, EmptyProps, DbgValue::VPHI)});
-  Result =
-      vlocJoin(*MBB3, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs);
+  VLiveOuts[1] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  VLiveOuts[2] = DbgValue(LiveInRsp, PropsWithIndirect, DbgValue::Def);
+  JoinedLoc = DbgValue(2, EmptyProps, DbgValue::VPHI);
+  Result = vlocJoin(*MBB3, VLiveOutIdx, AllBlocks, AllBlocks, JoinedLoc);
   EXPECT_TRUE(Result);
-  It = JoinedLocs.find(Var);
-  EXPECT_EQ(It->second.Kind, DbgValue::Def);
-  EXPECT_EQ(It->second.ID, LiveInRsp);
+  EXPECT_EQ(JoinedLoc.Kind, DbgValue::Def);
+  EXPECT_EQ(JoinedLoc.ID, LiveInRsp);
   // Also check properties come from block 2, the first RPO predecessor to block
   // three.
-  EXPECT_EQ(It->second.Properties, PropsWithIndirect);
-  JoinedLocs.clear();
-  VLiveIns[3].clear();
+  EXPECT_EQ(JoinedLoc.Properties, PropsWithIndirect);
 
   // Again, disagreeing properties, this time the expr, should cause a PHI to
   // not be eliminated.
-  DIExpression *NewExpr = DIExpression::prepend(EmptyExpr, DIExpression::ApplyOffset, 4);
+  DIExpression *NewExpr =
+      DIExpression::prepend(EmptyExpr, DIExpression::ApplyOffset, 4);
   DbgValueProperties PropsWithExpr(NewExpr, false);
-  VLiveOuts[1].clear();
-  VLiveOuts[2].clear();
-  VLiveOuts[1].insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)});
-  VLiveOuts[2].insert({Var, DbgValue(LiveInRsp, PropsWithExpr, DbgValue::Def)});
-  JoinedLocs.insert({Var, DbgValue(3, EmptyProps, DbgValue::VPHI)});
-  Result =
-      vlocJoin(*MBB3, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs);
+  VLiveOuts[1] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  VLiveOuts[2] = DbgValue(LiveInRsp, PropsWithExpr, DbgValue::Def);
+  JoinedLoc = DbgValue(3, EmptyProps, DbgValue::VPHI);
+  Result = vlocJoin(*MBB3, VLiveOutIdx, AllBlocks, AllBlocks, JoinedLoc);
   EXPECT_FALSE(Result);
 }
 
@@ -1806,8 +1758,8 @@ TEST_F(InstrRefLDVTest, vlocJoinLoops) {
 
   DebugVariable Var(FuncVariable, None, nullptr);
   DbgValueProperties EmptyProps(EmptyExpr, false);
-  SmallVector<DenseMap<DebugVariable, DbgValue>, 32> VLiveOuts;
-  VLiveOuts.resize(3);
+  SmallVector<DbgValue, 32> VLiveOuts;
+  VLiveOuts.resize(3, DbgValue(EmptyProps, DbgValue::Undef));
   InstrRefBasedLDV::LiveIdxT VLiveOutIdx;
   VLiveOutIdx[MBB0] = &VLiveOuts[0];
   VLiveOutIdx[MBB1] = &VLiveOuts[1];
@@ -1825,77 +1777,59 @@ TEST_F(InstrRefLDVTest, vlocJoinLoops) {
   SmallSet<DebugVariable, 4> AllVars;
   AllVars.insert(Var);
 
-  DenseMap<DebugVariable, DbgValue> JoinedLocs;
-
   // Test some back-edge-specific behaviours of vloc join. Mostly: the fact that
   // VPHIs that arrive on backedges can be eliminated, despite having 
diff erent
   // values to the predecessor.
 
   // First: when there's no VPHI placed already, propagate the live-in value of
   // the first RPO predecessor.
-  VLiveOuts[0].insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)});
-  VLiveOuts[1].insert({Var, DbgValue(LiveInRax, EmptyProps, DbgValue::Def)});
-  JoinedLocs.insert({Var, DbgValue(LiveInRax, EmptyProps, DbgValue::Def)});
-  bool Result =
-      vlocJoin(*MBB1, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs);
+  VLiveOuts[0] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  VLiveOuts[1] = DbgValue(LiveInRax, EmptyProps, DbgValue::Def);
+  DbgValue JoinedLoc = DbgValue(LiveInRax, EmptyProps, DbgValue::Def);
+  bool Result = vlocJoin(*MBB1, VLiveOutIdx, AllBlocks, AllBlocks, JoinedLoc);
   EXPECT_TRUE(Result);
-  auto It = JoinedLocs.find(Var);
-  EXPECT_EQ(It->second.Kind, DbgValue::Def);
-  EXPECT_EQ(It->second.ID, LiveInRsp);
-  JoinedLocs.clear();
+  EXPECT_EQ(JoinedLoc.Kind, DbgValue::Def);
+  EXPECT_EQ(JoinedLoc.ID, LiveInRsp);
 
   // If there is a VPHI: don't elimiante it if there are disagreeing values.
-  VLiveOuts[0].insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)});
-  VLiveOuts[1].insert({Var, DbgValue(LiveInRax, EmptyProps, DbgValue::Def)});
-  JoinedLocs.insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)});
-  Result =
-      vlocJoin(*MBB1, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs);
+  VLiveOuts[0] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  VLiveOuts[1] = DbgValue(LiveInRax, EmptyProps, DbgValue::Def);
+  JoinedLoc = DbgValue(1, EmptyProps, DbgValue::VPHI);
+  Result = vlocJoin(*MBB1, VLiveOutIdx, AllBlocks, AllBlocks, JoinedLoc);
   EXPECT_FALSE(Result);
-  It = JoinedLocs.find(Var);
-  EXPECT_EQ(It->second.Kind, DbgValue::VPHI);
-  EXPECT_EQ(It->second.BlockNo, 1);
-  JoinedLocs.clear();
+  EXPECT_EQ(JoinedLoc.Kind, DbgValue::VPHI);
+  EXPECT_EQ(JoinedLoc.BlockNo, 1);
 
   // If we feed this VPHI back into itself though, we can eliminate it.
-  VLiveOuts[0].clear();
-  VLiveOuts[1].clear();
-  VLiveOuts[0].insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)});
-  VLiveOuts[1].insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)});
-  JoinedLocs.insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)});
-  Result =
-      vlocJoin(*MBB1, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs);
+  VLiveOuts[0] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  VLiveOuts[1] = DbgValue(1, EmptyProps, DbgValue::VPHI);
+  JoinedLoc = DbgValue(1, EmptyProps, DbgValue::VPHI);
+  Result = vlocJoin(*MBB1, VLiveOutIdx, AllBlocks, AllBlocks, JoinedLoc);
   EXPECT_TRUE(Result);
-  It = JoinedLocs.find(Var);
-  EXPECT_EQ(It->second.Kind, DbgValue::Def);
-  EXPECT_EQ(It->second.ID, LiveInRsp);
-  JoinedLocs.clear();
+  EXPECT_EQ(JoinedLoc.Kind, DbgValue::Def);
+  EXPECT_EQ(JoinedLoc.ID, LiveInRsp);
 
   // Don't eliminate backedge VPHIs if the predecessors have 
diff erent
   // properties.
-  DIExpression *NewExpr = DIExpression::prepend(EmptyExpr, DIExpression::ApplyOffset, 4);
+  DIExpression *NewExpr =
+      DIExpression::prepend(EmptyExpr, DIExpression::ApplyOffset, 4);
   DbgValueProperties PropsWithExpr(NewExpr, false);
-  VLiveOuts[1].clear();
-  VLiveOuts[1].insert({Var, DbgValue(1, PropsWithExpr, DbgValue::VPHI)});
-  JoinedLocs.insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)});
-  Result =
-      vlocJoin(*MBB1, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs);
+  VLiveOuts[0] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  VLiveOuts[1] = DbgValue(1, PropsWithExpr, DbgValue::VPHI);
+  JoinedLoc = DbgValue(1, EmptyProps, DbgValue::VPHI);
+  Result = vlocJoin(*MBB1, VLiveOutIdx, AllBlocks, AllBlocks, JoinedLoc);
   EXPECT_FALSE(Result);
-  It = JoinedLocs.find(Var);
-  EXPECT_EQ(It->second.Kind, DbgValue::VPHI);
-  EXPECT_EQ(It->second.BlockNo, 1);
-  JoinedLocs.clear();
+  EXPECT_EQ(JoinedLoc.Kind, DbgValue::VPHI);
+  EXPECT_EQ(JoinedLoc.BlockNo, 1);
 
   // Backedges with VPHIs, but from the wrong block, shouldn't be eliminated.
-  VLiveOuts[1].clear();
-  VLiveOuts[1].insert({Var, DbgValue(0, EmptyProps, DbgValue::VPHI)});
-  JoinedLocs.insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)});
-  Result =
-      vlocJoin(*MBB1, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs);
+  VLiveOuts[0] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  VLiveOuts[1] = DbgValue(0, EmptyProps, DbgValue::VPHI);
+  JoinedLoc = DbgValue(1, EmptyProps, DbgValue::VPHI);
+  Result = vlocJoin(*MBB1, VLiveOutIdx, AllBlocks, AllBlocks, JoinedLoc);
   EXPECT_FALSE(Result);
-  It = JoinedLocs.find(Var);
-  EXPECT_EQ(It->second.Kind, DbgValue::VPHI);
-  EXPECT_EQ(It->second.BlockNo, 1);
-  JoinedLocs.clear();
+  EXPECT_EQ(JoinedLoc.Kind, DbgValue::VPHI);
+  EXPECT_EQ(JoinedLoc.BlockNo, 1);
 }
 
 TEST_F(InstrRefLDVTest, vlocJoinBadlyNestedLoops) {
@@ -1927,8 +1861,8 @@ TEST_F(InstrRefLDVTest, vlocJoinBadlyNestedLoops) {
 
   DebugVariable Var(FuncVariable, None, nullptr);
   DbgValueProperties EmptyProps(EmptyExpr, false);
-  SmallVector<DenseMap<DebugVariable, DbgValue>, 32> VLiveOuts;
-  VLiveOuts.resize(5);
+  SmallVector<DbgValue, 32> VLiveOuts;
+  VLiveOuts.resize(5, DbgValue(EmptyProps, DbgValue::Undef));
   InstrRefBasedLDV::LiveIdxT VLiveOutIdx;
   VLiveOutIdx[MBB0] = &VLiveOuts[0];
   VLiveOutIdx[MBB1] = &VLiveOuts[1];
@@ -1951,69 +1885,46 @@ TEST_F(InstrRefLDVTest, vlocJoinBadlyNestedLoops) {
   SmallSet<DebugVariable, 4> AllVars;
   AllVars.insert(Var);
 
-  DenseMap<DebugVariable, DbgValue> JoinedLocs;
-
   // Test a normal VPHI isn't eliminated.
-  VLiveOuts[0].insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)});
-  VLiveOuts[1].insert({Var, DbgValue(LiveInRax, EmptyProps, DbgValue::Def)});
-  VLiveOuts[2].insert({Var, DbgValue(LiveInRbx, EmptyProps, DbgValue::Def)});
-  JoinedLocs.insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)});
-  bool Result =
-      vlocJoin(*MBB1, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs);
+  VLiveOuts[0] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  VLiveOuts[1] = DbgValue(LiveInRax, EmptyProps, DbgValue::Def);
+  VLiveOuts[2] = DbgValue(LiveInRbx, EmptyProps, DbgValue::Def);
+  DbgValue JoinedLoc = DbgValue(1, EmptyProps, DbgValue::VPHI);
+  bool Result = vlocJoin(*MBB1, VLiveOutIdx, AllBlocks, AllBlocks, JoinedLoc);
   EXPECT_FALSE(Result);
-  auto It = JoinedLocs.find(Var);
-  EXPECT_EQ(It->second.Kind, DbgValue::VPHI);
-  EXPECT_EQ(It->second.BlockNo, 1);
-  JoinedLocs.clear();
+  EXPECT_EQ(JoinedLoc.Kind, DbgValue::VPHI);
+  EXPECT_EQ(JoinedLoc.BlockNo, 1);
 
   // Common VPHIs on backedges should merge.
-  VLiveOuts[0].clear();
-  VLiveOuts[1].clear();
-  VLiveOuts[2].clear();
-  VLiveOuts[0].insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)});
-  VLiveOuts[1].insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)});
-  VLiveOuts[2].insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)});
-  JoinedLocs.insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)});
-  Result =
-      vlocJoin(*MBB1, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs);
+  VLiveOuts[0] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  VLiveOuts[1] = DbgValue(1, EmptyProps, DbgValue::VPHI);
+  VLiveOuts[2] = DbgValue(1, EmptyProps, DbgValue::VPHI);
+  JoinedLoc = DbgValue(1, EmptyProps, DbgValue::VPHI);
+  Result = vlocJoin(*MBB1, VLiveOutIdx, AllBlocks, AllBlocks, JoinedLoc);
   EXPECT_TRUE(Result);
-  It = JoinedLocs.find(Var);
-  EXPECT_EQ(It->second.Kind, DbgValue::Def);
-  EXPECT_EQ(It->second.ID, LiveInRsp);
-  JoinedLocs.clear();
+  EXPECT_EQ(JoinedLoc.Kind, DbgValue::Def);
+  EXPECT_EQ(JoinedLoc.ID, LiveInRsp);
 
   // They shouldn't merge if one of their properties is 
diff erent.
   DbgValueProperties PropsWithIndirect(EmptyExpr, true);
-  VLiveOuts[0].clear();
-  VLiveOuts[1].clear();
-  VLiveOuts[2].clear();
-  VLiveOuts[0].insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)});
-  VLiveOuts[1].insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)});
-  VLiveOuts[2].insert({Var, DbgValue(1, PropsWithIndirect, DbgValue::VPHI)});
-  JoinedLocs.insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)});
-  Result =
-      vlocJoin(*MBB1, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs);
+  VLiveOuts[0] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  VLiveOuts[1] = DbgValue(1, EmptyProps, DbgValue::VPHI);
+  VLiveOuts[2] = DbgValue(1, PropsWithIndirect, DbgValue::VPHI);
+  JoinedLoc = DbgValue(1, EmptyProps, DbgValue::VPHI);
+  Result = vlocJoin(*MBB1, VLiveOutIdx, AllBlocks, AllBlocks, JoinedLoc);
   EXPECT_FALSE(Result);
-  It = JoinedLocs.find(Var);
-  EXPECT_EQ(It->second.Kind, DbgValue::VPHI);
-  EXPECT_EQ(It->second.BlockNo, 1);
-  JoinedLocs.clear();
+  EXPECT_EQ(JoinedLoc.Kind, DbgValue::VPHI);
+  EXPECT_EQ(JoinedLoc.BlockNo, 1);
 
   // VPHIs from 
diff erent blocks should not merge.
-  VLiveOuts[0].clear();
-  VLiveOuts[1].clear();
-  VLiveOuts[2].clear();
-  VLiveOuts[0].insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)});
-  VLiveOuts[1].insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)});
-  VLiveOuts[2].insert({Var, DbgValue(2, EmptyProps, DbgValue::VPHI)});
-  JoinedLocs.insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)});
-  Result =
-      vlocJoin(*MBB1, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs);
+  VLiveOuts[0] = DbgValue(LiveInRsp, EmptyProps, DbgValue::Def);
+  VLiveOuts[1] = DbgValue(1, EmptyProps, DbgValue::VPHI);
+  VLiveOuts[2] = DbgValue(2, EmptyProps, DbgValue::VPHI);
+  JoinedLoc = DbgValue(1, EmptyProps, DbgValue::VPHI);
+  Result = vlocJoin(*MBB1, VLiveOutIdx, AllBlocks, AllBlocks, JoinedLoc);
   EXPECT_FALSE(Result);
-  It = JoinedLocs.find(Var);
-  EXPECT_EQ(It->second.Kind, DbgValue::VPHI);
-  EXPECT_EQ(It->second.BlockNo, 1);
-  JoinedLocs.clear();
+  EXPECT_EQ(JoinedLoc.Kind, DbgValue::VPHI);
+  EXPECT_EQ(JoinedLoc.BlockNo, 1);
 }
 
 // Above are tests for picking VPHI locations, and eliminating VPHIs. No


        


More information about the llvm-commits mailing list