Index: llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h =================================================================== --- llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h +++ llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h @@ -867,19 +867,16 @@ /// 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 and live in variable values are stored in - /// \p VLOCOutLocs and \p VLOCInLocs. The live-ins for \p MBB are computed and - /// stored into \p VLOCInLocs. - /// \p InLocsT Output argument, where calculated live-in values are also - /// stored. + /// 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. /// \returns true if any live-ins change value, either from value propagation /// or PHI elimination. bool vlocJoin(MachineBasicBlock &MBB, LiveIdxT &VLOCOutLocs, - LiveIdxT &VLOCInLocs, const SmallSet &AllVars, SmallPtrSet &InScopeBlocks, SmallPtrSet &BlocksToExplore, - DenseMap &InLocsT); + DenseMap &LiveIns); /// For the given block and live-outs feeding into it, try to find a /// machine location where all the variable values join together. Index: llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp =================================================================== --- llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp +++ llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp @@ -2126,11 +2126,11 @@ } bool InstrRefBasedLDV::vlocJoin( - MachineBasicBlock &MBB, LiveIdxT &VLOCOutLocs, LiveIdxT &VLOCInLocs, + MachineBasicBlock &MBB, LiveIdxT &VLOCOutLocs, const SmallSet &AllVars, SmallPtrSet &InScopeBlocks, SmallPtrSet &BlocksToExplore, - DenseMap &InLocsT) { + DenseMap &LiveIns) { // 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. @@ -2140,11 +2140,6 @@ LLVM_DEBUG(dbgs() << "join MBB: " << MBB.getNumber() << "\n"); bool Changed = false; - // Pick out the live-ins from prior iterations. - auto ILSIt = VLOCInLocs.find(&MBB); - assert(ILSIt != VLOCInLocs.end()); - auto &ILS = *ILSIt->second; - // Order predecessors by RPOT order, for exploring them in that order. SmallVector BlockOrders(MBB.predecessors()); @@ -2159,10 +2154,14 @@ // 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 = [&InLocsT](const DebugVariable &DV, DbgValue VR) { - auto Result = InLocsT.insert(std::make_pair(DV, VR)); - (void)Result; - assert(Result.second); + 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; + } }; auto ConfirmVPHI = [&ConfirmValue, @@ -2212,8 +2211,8 @@ } // Pick out the live-in value from last time we vlocJoin'd this block. - auto LiveInIt = ILS.find(Var); - assert(LiveInIt != ILS.end() && "Uninitialized live-in vloc?"); + auto LiveInIt = LiveIns.find(Var); + assert(LiveInIt != LiveIns.end() && "Uninitialized live-in vloc?"); const DbgValue &OldLiveInDbgValue = LiveInIt->second; // If there were no values, or one of the predecessors couldn't have a @@ -2282,11 +2281,6 @@ } } - // Store newly calculated in-locs into VLOCInLocs, if they've changed. - Changed = ILS != InLocsT; - if (Changed) - ILS = InLocsT; - return Changed; } @@ -2426,6 +2420,17 @@ 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). @@ -2477,14 +2482,15 @@ CurBB = MBB->getNumber(); Worklist.pop(); - DenseMap JoinedInLocs; + 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; - InLocsChanged = vlocJoin(*MBB, LiveOutIdx, LiveInIdx, - VarsWeCareAbout, InScopeBlocks, BlocksToExplore, - JoinedInLocs); + bool InLocsChanged = + vlocJoin(*MBB, LiveOutIdx, VarsWeCareAbout, InScopeBlocks, + BlocksToExplore, BlockLiveIns); SmallVector Preds; for (const auto *Pred : MBB->predecessors()) @@ -2495,7 +2501,7 @@ // 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 = JoinedInLocs.find(Var)->second; + DbgValue &Val = BlockLiveIns.find(Var)->second; if (Val.Kind != DbgValue::VPHI || Val.BlockNo != (unsigned)CurBB) continue; @@ -2509,46 +2515,60 @@ if (ValueNum) { InLocsChanged |= Val.ID != *ValueNum; Val.ID = *ValueNum; - // FIXME: it's stupid to have two different live-in maps at this - // stage, one for evaluating the transfer func in, one for storage. - // Fix this in the future. - LiveInIdx[MBB]->find(Var)->second.ID = *ValueNum; } } if (!InLocsChanged && !FirstTrip) continue; + auto &LiveOuts = *LiveOutIdx[MBB]; + bool OLChanged = false; + // Do transfer function. auto &VTracker = AllTheVLocs[MBB->getNumber()]; + SmallSet 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()); + // Erase on empty transfer (DBG_VALUE $noreg). if (Transfer.second.Kind == DbgValue::Undef) { - auto InLocIt = JoinedInLocs.find(Transfer.first); - assert(InLocIt != JoinedInLocs.end()); - InLocIt->second.Kind = DbgValue::NoVal; + DbgValue NewVal(MBB->getNumber(), EmptyProperties, DbgValue::NoVal); + if (OutIt->second != NewVal) { + OutIt->second = NewVal; + OLChanged = true; + } } else { // Insert new variable value; or overwrite. - auto NewValuePair = std::make_pair(Transfer.first, Transfer.second); - auto Result = JoinedInLocs.insert(NewValuePair); - if (!Result.second) - Result.first->second = Transfer.second; + if (OutIt->second != Transfer.second) { + OutIt->second = Transfer.second; + OLChanged = true; + } } } } - // Did the live-out locations change? - bool OLChanged = JoinedInLocs != *LiveOutIdx[MBB]; + // For anything not assigned by the transfer function, copy live-in to + // live-outs. + for (const DebugVariable &Var : VarsWeCareAbout) { + if (VarsTransferred.count(Var)) + continue; + + auto OutIt = LiveOuts.find(Var); + auto InIt = ILS.find(Var); + if (InIt->second != OutIt->second) { + OutIt->second = InIt->second; + OLChanged = true; + } + } - // If they haven't changed, there's no need to explore further. + // If no live-out value changed, there's no need to explore further. if (!OLChanged) continue; - // Commit to the live-out record. - *LiveOutIdx[MBB] = JoinedInLocs; - // 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. Index: llvm/unittests/CodeGen/InstrRefLDVTest.cpp =================================================================== --- llvm/unittests/CodeGen/InstrRefLDVTest.cpp +++ llvm/unittests/CodeGen/InstrRefLDVTest.cpp @@ -180,13 +180,12 @@ } bool vlocJoin(MachineBasicBlock &MBB, InstrRefBasedLDV::LiveIdxT &VLOCOutLocs, - InstrRefBasedLDV::LiveIdxT &VLOCInLocs, const SmallSet &AllVars, SmallPtrSet &InScopeBlocks, SmallPtrSet &BlocksToExplore, DenseMap &InLocsT) { - return LDV->vlocJoin(MBB, VLOCOutLocs, VLOCInLocs, AllVars, - InScopeBlocks, BlocksToExplore, InLocsT); + return LDV->vlocJoin(MBB, VLOCOutLocs, AllVars, InScopeBlocks, + BlocksToExplore, InLocsT); } void buildVLocValueMap(const DILocation *DILoc, @@ -1625,41 +1624,39 @@ // vlocJoin is here to propagate incoming values, and eliminate PHIs. Start // off by propagating a value into the merging block, number 3. - VLiveIns[3].insert({Var, DbgValue(3, EmptyProps, DbgValue::NoVal)}); + 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, VLiveInIdx, AllVars, - AllBlocks, AllBlocks, JoinedLocs); + bool Result = + vlocJoin(*MBB3, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs); EXPECT_TRUE(Result); // Output locs should have changed. - auto It = VLiveIns[3].find(Var); + auto It = JoinedLocs.find(Var); EXPECT_EQ(It->second.Kind, DbgValue::Def); EXPECT_EQ(It->second.ID, LiveInRsp); - JoinedLocs.clear(); + // JoinedLocs.clear(); <--- leave commented out for next test, // 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, VLiveInIdx, AllVars, - AllBlocks, AllBlocks, JoinedLocs); + Result = + vlocJoin(*MBB3, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs); EXPECT_FALSE(Result); JoinedLocs.clear(); - VLiveIns[3].clear(); // If the live-in variable values are different, 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)}); - VLiveIns[3].insert({Var, DbgValue(3, EmptyProps, DbgValue::NoVal)}); - Result = vlocJoin(*MBB3, VLiveOutIdx, VLiveInIdx, AllVars, - AllBlocks, AllBlocks, JoinedLocs); + JoinedLocs.insert({Var, DbgValue(3, EmptyProps, DbgValue::NoVal)}); + Result = + vlocJoin(*MBB3, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs); EXPECT_TRUE(Result); - It = VLiveIns[3].find(Var); + It = JoinedLocs.find(Var); EXPECT_EQ(It->second.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(); - VLiveIns[3].clear(); // No tests for whether vlocJoin will pass-through a variable with differing // expressions / properties. Those can only come about due to assignments; and @@ -1669,18 +1666,17 @@ // Try placing a PHI. With differing input values (LiveInRsp, LiveInRax), // this PHI should not be eliminated. - VLiveIns[3].insert({Var, DbgValue(3, EmptyProps, DbgValue::VPHI)}); - Result = vlocJoin(*MBB3, VLiveOutIdx, VLiveInIdx, AllVars, - AllBlocks, AllBlocks, JoinedLocs); + JoinedLocs.insert({Var, DbgValue(3, EmptyProps, DbgValue::VPHI)}); + Result = + vlocJoin(*MBB3, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs); // Expect no change. EXPECT_FALSE(Result); - It = VLiveIns[3].find(Var); + It = JoinedLocs.find(Var); EXPECT_EQ(It->second.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(); - VLiveIns[3].clear(); // 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 @@ -1689,15 +1685,14 @@ VLiveOuts[2].clear(); VLiveOuts[1].insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); VLiveOuts[2].insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); - VLiveIns[3].insert({Var, DbgValue(3, EmptyProps, DbgValue::VPHI)}); - Result = vlocJoin(*MBB3, VLiveOutIdx, VLiveInIdx, AllVars, - AllBlocks, AllBlocks, JoinedLocs); + JoinedLocs.insert({Var, DbgValue(3, EmptyProps, DbgValue::VPHI)}); + Result = + vlocJoin(*MBB3, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs); EXPECT_TRUE(Result); - It = VLiveIns[3].find(Var); + It = JoinedLocs.find(Var); EXPECT_EQ(It->second.Kind, DbgValue::Def); EXPECT_EQ(It->second.ID, LiveInRsp); JoinedLocs.clear(); - VLiveIns[3].clear(); // 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 @@ -1707,15 +1702,14 @@ VLiveOuts[2].clear(); VLiveOuts[1].insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); VLiveOuts[2].insert({Var, DbgValue(LiveInRax, EmptyProps, DbgValue::Def)}); - VLiveIns[3].insert({Var, DbgValue(2, EmptyProps, DbgValue::VPHI)}); - Result = vlocJoin(*MBB3, VLiveOutIdx, VLiveInIdx, AllVars, - AllBlocks, AllBlocks, JoinedLocs); + JoinedLocs.insert({Var, DbgValue(2, EmptyProps, DbgValue::VPHI)}); + Result = + vlocJoin(*MBB3, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs); EXPECT_TRUE(Result); - It = VLiveIns[3].find(Var); + It = JoinedLocs.find(Var); EXPECT_EQ(It->second.Kind, DbgValue::Def); EXPECT_EQ(It->second.ID, LiveInRax); // from block 2 JoinedLocs.clear(); - VLiveIns[3].clear(); // The above test, but test that we will install one value-propagated VPHI // over another. @@ -1723,31 +1717,30 @@ VLiveOuts[2].clear(); VLiveOuts[1].insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); VLiveOuts[2].insert({Var, DbgValue(0, EmptyProps, DbgValue::VPHI)}); - VLiveIns[3].insert({Var, DbgValue(2, EmptyProps, DbgValue::VPHI)}); - Result = vlocJoin(*MBB3, VLiveOutIdx, VLiveInIdx, AllVars, - AllBlocks, AllBlocks, JoinedLocs); + JoinedLocs.insert({Var, DbgValue(2, EmptyProps, DbgValue::VPHI)}); + Result = + vlocJoin(*MBB3, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs); EXPECT_TRUE(Result); - It = VLiveIns[3].find(Var); + It = JoinedLocs.find(Var); EXPECT_EQ(It->second.Kind, DbgValue::VPHI); EXPECT_EQ(It->second.BlockNo, 0); JoinedLocs.clear(); - VLiveIns[3].clear(); // 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)}); - VLiveIns[3].insert({Var, DbgValue(3, EmptyProps, DbgValue::VPHI)}); - Result = vlocJoin(*MBB3, VLiveOutIdx, VLiveInIdx, AllVars, - AllBlocks, AllBlocks, JoinedLocs); + 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); EXPECT_FALSE(Result); - It = VLiveIns[3].find(Var); + It = JoinedLocs.find(Var); EXPECT_EQ(It->second.Kind, DbgValue::VPHI); EXPECT_EQ(It->second.BlockNo, 3); JoinedLocs.clear(); - VLiveIns[3].clear(); // Even if properties disagree, we should still value-propagate if there's no // PHI to be eliminated. The disagreeing values should work themselves out, @@ -1755,12 +1748,13 @@ VLiveOuts[1].clear(); VLiveOuts[2].clear(); VLiveOuts[1].insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); - VLiveOuts[2].insert({Var, DbgValue(LiveInRsp, PropsWithIndirect, DbgValue::Def)}); - VLiveIns[3].insert({Var, DbgValue(2, EmptyProps, DbgValue::VPHI)}); - Result = vlocJoin(*MBB3, VLiveOutIdx, VLiveInIdx, AllVars, - AllBlocks, AllBlocks, JoinedLocs); + 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); EXPECT_TRUE(Result); - It = VLiveIns[3].find(Var); + It = JoinedLocs.find(Var); EXPECT_EQ(It->second.Kind, DbgValue::Def); EXPECT_EQ(It->second.ID, LiveInRsp); // Also check properties come from block 2, the first RPO predecessor to block @@ -1777,16 +1771,10 @@ VLiveOuts[2].clear(); VLiveOuts[1].insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); VLiveOuts[2].insert({Var, DbgValue(LiveInRsp, PropsWithExpr, DbgValue::Def)}); - VLiveIns[3].insert({Var, DbgValue(3, EmptyProps, DbgValue::VPHI)}); - Result = vlocJoin(*MBB3, VLiveOutIdx, VLiveInIdx, AllVars, - AllBlocks, AllBlocks, JoinedLocs); + JoinedLocs.insert({Var, DbgValue(3, EmptyProps, DbgValue::VPHI)}); + Result = + vlocJoin(*MBB3, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs); EXPECT_FALSE(Result); - It = VLiveIns[3].find(Var); - EXPECT_EQ(It->second.Kind, DbgValue::VPHI); - EXPECT_EQ(It->second.BlockNo, 3); - EXPECT_EQ(It->second.Properties, EmptyProps); - JoinedLocs.clear(); - VLiveIns[3].clear(); } TEST_F(InstrRefLDVTest, vlocJoinLoops) { @@ -1811,16 +1799,12 @@ DebugVariable Var(FuncVariable, None, nullptr); DbgValueProperties EmptyProps(EmptyExpr, false); - SmallVector, 32> VLiveOuts, VLiveIns; + SmallVector, 32> VLiveOuts; VLiveOuts.resize(3); - VLiveIns.resize(3); - InstrRefBasedLDV::LiveIdxT VLiveOutIdx, VLiveInIdx; + InstrRefBasedLDV::LiveIdxT VLiveOutIdx; VLiveOutIdx[MBB0] = &VLiveOuts[0]; VLiveOutIdx[MBB1] = &VLiveOuts[1]; VLiveOutIdx[MBB2] = &VLiveOuts[2]; - VLiveInIdx[MBB0] = &VLiveIns[0]; - VLiveInIdx[MBB1] = &VLiveIns[1]; - VLiveInIdx[MBB2] = &VLiveIns[2]; SmallPtrSet AllBlocks; AllBlocks.insert(MBB0); @@ -1844,43 +1828,40 @@ // the first RPO predecessor. VLiveOuts[0].insert({Var, DbgValue(LiveInRsp, EmptyProps, DbgValue::Def)}); VLiveOuts[1].insert({Var, DbgValue(LiveInRax, EmptyProps, DbgValue::Def)}); - VLiveIns[1].insert({Var, DbgValue(LiveInRax, EmptyProps, DbgValue::Def)}); - bool Result = vlocJoin(*MBB1, VLiveOutIdx, VLiveInIdx, AllVars, - AllBlocks, AllBlocks, JoinedLocs); + JoinedLocs.insert({Var, DbgValue(LiveInRax, EmptyProps, DbgValue::Def)}); + bool Result = + vlocJoin(*MBB1, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs); EXPECT_TRUE(Result); - auto It = VLiveIns[1].find(Var); + auto It = JoinedLocs.find(Var); EXPECT_EQ(It->second.Kind, DbgValue::Def); EXPECT_EQ(It->second.ID, LiveInRsp); JoinedLocs.clear(); - VLiveIns[1].clear(); // 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)}); - VLiveIns[1].insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)}); - Result = vlocJoin(*MBB1, VLiveOutIdx, VLiveInIdx, AllVars, - AllBlocks, AllBlocks, JoinedLocs); + JoinedLocs.insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)}); + Result = + vlocJoin(*MBB1, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs); EXPECT_FALSE(Result); - It = VLiveIns[1].find(Var); + It = JoinedLocs.find(Var); EXPECT_EQ(It->second.Kind, DbgValue::VPHI); EXPECT_EQ(It->second.BlockNo, 1); JoinedLocs.clear(); - VLiveIns[1].clear(); // 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)}); - VLiveIns[1].insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)}); - Result = vlocJoin(*MBB1, VLiveOutIdx, VLiveInIdx, AllVars, - AllBlocks, AllBlocks, JoinedLocs); + JoinedLocs.insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)}); + Result = + vlocJoin(*MBB1, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs); EXPECT_TRUE(Result); - It = VLiveIns[1].find(Var); + It = JoinedLocs.find(Var); EXPECT_EQ(It->second.Kind, DbgValue::Def); EXPECT_EQ(It->second.ID, LiveInRsp); JoinedLocs.clear(); - VLiveIns[1].clear(); // Don't eliminate backedge VPHIs if the predecessors have different // properties. @@ -1888,28 +1869,26 @@ DbgValueProperties PropsWithExpr(NewExpr, false); VLiveOuts[1].clear(); VLiveOuts[1].insert({Var, DbgValue(1, PropsWithExpr, DbgValue::VPHI)}); - VLiveIns[1].insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)}); - Result = vlocJoin(*MBB1, VLiveOutIdx, VLiveInIdx, AllVars, - AllBlocks, AllBlocks, JoinedLocs); + JoinedLocs.insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)}); + Result = + vlocJoin(*MBB1, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs); EXPECT_FALSE(Result); - It = VLiveIns[1].find(Var); + It = JoinedLocs.find(Var); EXPECT_EQ(It->second.Kind, DbgValue::VPHI); EXPECT_EQ(It->second.BlockNo, 1); JoinedLocs.clear(); - VLiveIns[1].clear(); // Backedges with VPHIs, but from the wrong block, shouldn't be eliminated. VLiveOuts[1].clear(); VLiveOuts[1].insert({Var, DbgValue(0, EmptyProps, DbgValue::VPHI)}); - VLiveIns[1].insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)}); - Result = vlocJoin(*MBB1, VLiveOutIdx, VLiveInIdx, AllVars, - AllBlocks, AllBlocks, JoinedLocs); + JoinedLocs.insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)}); + Result = + vlocJoin(*MBB1, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs); EXPECT_FALSE(Result); - It = VLiveIns[1].find(Var); + It = JoinedLocs.find(Var); EXPECT_EQ(It->second.Kind, DbgValue::VPHI); EXPECT_EQ(It->second.BlockNo, 1); JoinedLocs.clear(); - VLiveIns[1].clear(); } TEST_F(InstrRefLDVTest, vlocJoinBadlyNestedLoops) { @@ -1941,20 +1920,14 @@ DebugVariable Var(FuncVariable, None, nullptr); DbgValueProperties EmptyProps(EmptyExpr, false); - SmallVector, 32> VLiveOuts, VLiveIns; + SmallVector, 32> VLiveOuts; VLiveOuts.resize(5); - VLiveIns.resize(5); - InstrRefBasedLDV::LiveIdxT VLiveOutIdx, VLiveInIdx; + InstrRefBasedLDV::LiveIdxT VLiveOutIdx; VLiveOutIdx[MBB0] = &VLiveOuts[0]; VLiveOutIdx[MBB1] = &VLiveOuts[1]; VLiveOutIdx[MBB2] = &VLiveOuts[2]; VLiveOutIdx[MBB3] = &VLiveOuts[3]; VLiveOutIdx[MBB4] = &VLiveOuts[4]; - VLiveInIdx[MBB0] = &VLiveIns[0]; - VLiveInIdx[MBB1] = &VLiveIns[1]; - VLiveInIdx[MBB2] = &VLiveIns[2]; - VLiveInIdx[MBB3] = &VLiveIns[3]; - VLiveInIdx[MBB4] = &VLiveIns[4]; SmallPtrSet AllBlocks; AllBlocks.insert(MBB0); @@ -1977,15 +1950,14 @@ 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)}); - VLiveIns[1].insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)}); - bool Result = vlocJoin(*MBB1, VLiveOutIdx, VLiveInIdx, AllVars, - AllBlocks, AllBlocks, JoinedLocs); + JoinedLocs.insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)}); + bool Result = + vlocJoin(*MBB1, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs); EXPECT_FALSE(Result); - auto It = VLiveIns[1].find(Var); + auto It = JoinedLocs.find(Var); EXPECT_EQ(It->second.Kind, DbgValue::VPHI); EXPECT_EQ(It->second.BlockNo, 1); JoinedLocs.clear(); - VLiveIns[1].clear(); // Common VPHIs on backedges should merge. VLiveOuts[0].clear(); @@ -1994,15 +1966,14 @@ 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)}); - VLiveIns[1].insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)}); - Result = vlocJoin(*MBB1, VLiveOutIdx, VLiveInIdx, AllVars, - AllBlocks, AllBlocks, JoinedLocs); + JoinedLocs.insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)}); + Result = + vlocJoin(*MBB1, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs); EXPECT_TRUE(Result); - It = VLiveIns[1].find(Var); + It = JoinedLocs.find(Var); EXPECT_EQ(It->second.Kind, DbgValue::Def); EXPECT_EQ(It->second.ID, LiveInRsp); JoinedLocs.clear(); - VLiveIns[1].clear(); // They shouldn't merge if one of their properties is different. DbgValueProperties PropsWithIndirect(EmptyExpr, true); @@ -2012,15 +1983,14 @@ 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)}); - VLiveIns[1].insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)}); - Result = vlocJoin(*MBB1, VLiveOutIdx, VLiveInIdx, AllVars, - AllBlocks, AllBlocks, JoinedLocs); + JoinedLocs.insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)}); + Result = + vlocJoin(*MBB1, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs); EXPECT_FALSE(Result); - It = VLiveIns[1].find(Var); + It = JoinedLocs.find(Var); EXPECT_EQ(It->second.Kind, DbgValue::VPHI); EXPECT_EQ(It->second.BlockNo, 1); JoinedLocs.clear(); - VLiveIns[1].clear(); // VPHIs from different blocks should not merge. VLiveOuts[0].clear(); @@ -2029,15 +1999,14 @@ 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)}); - VLiveIns[1].insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)}); - Result = vlocJoin(*MBB1, VLiveOutIdx, VLiveInIdx, AllVars, - AllBlocks, AllBlocks, JoinedLocs); + JoinedLocs.insert({Var, DbgValue(1, EmptyProps, DbgValue::VPHI)}); + Result = + vlocJoin(*MBB1, VLiveOutIdx, AllVars, AllBlocks, AllBlocks, JoinedLocs); EXPECT_FALSE(Result); - It = VLiveIns[1].find(Var); + It = JoinedLocs.find(Var); EXPECT_EQ(It->second.Kind, DbgValue::VPHI); EXPECT_EQ(It->second.BlockNo, 1); JoinedLocs.clear(); - VLiveIns[1].clear(); } // Above are tests for picking VPHI locations, and eliminating VPHIs. No