diff --git a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h --- a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h +++ b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h @@ -1340,14 +1340,21 @@ SmallPtrSet &BlocksToExplore, 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. - /// \returns Value ID of a machine PHI if an appropriate one is available. - Optional - pickVPHILoc(const MachineBasicBlock &MBB, const DebugVariable &Var, + /// For the given block and live-outs feeding into it, try to find + /// machine locations for every debug operand where all the values feeding + /// into that operand join together. + /// \returns true if a joined location was found for every value that needed + /// to be joined. + bool + pickVPHILoc(SmallVectorImpl &OutValues, const MachineBasicBlock &MBB, const LiveIdxT &LiveOuts, FuncValueTable &MOutLocs, const SmallVectorImpl &BlockOrders); + Optional pickValuePHILoc( + unsigned DbgOpIdx, const MachineBasicBlock &MBB, const LiveIdxT &LiveOuts, + FuncValueTable &MOutLocs, + const SmallVectorImpl &BlockOrders); + /// Take collections of DBG_VALUE instructions stored in TTracker, and /// install them into their output blocks. Preserves a stable order of /// DBG_VALUEs produced (which would otherwise cause nondeterminism) through diff --git a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp --- a/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp +++ b/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp @@ -2390,33 +2390,102 @@ IDF.calculate(PHIBlocks); } -Optional InstrRefBasedLDV::pickVPHILoc( - const MachineBasicBlock &MBB, const DebugVariable &Var, +bool InstrRefBasedLDV::pickVPHILoc( + SmallVectorImpl &OutValues, const MachineBasicBlock &MBB, const LiveIdxT &LiveOuts, FuncValueTable &MOutLocs, const SmallVectorImpl &BlockOrders) { - // Collect a set of locations from predecessor where its live-out value can - // be found. - SmallVector, 8> Locs; - SmallVector Properties; - unsigned NumLocs = MTracker->getNumLocs(); // No predecessors means no PHIs. if (BlockOrders.empty()) - return None; + return false; + + // All the location operands that do not already agree need to be joined, + // track the indices of each such location operand here. + SmallDenseSet LocOpsToJoin; + + auto FirstValueIt = LiveOuts.find(BlockOrders[0]); + if (FirstValueIt == LiveOuts.end()) + return false; + const DbgValue &FirstValue = *FirstValueIt->second; for (auto p : BlockOrders) { - unsigned ThisBBNum = p->getNumber(); 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; + return false; const DbgValue &OutVal = *OutValIt->second; - if (OutVal.getDbgOpID(0).isConst() || OutVal.Kind == DbgValue::NoVal) - // Consts and no-values cannot have locations we can join on. - return None; + // No-values cannot have locations we can join on. + if (OutVal.Kind == DbgValue::NoVal) + return false; + + // For unjoined VPHIs where we don't know the location, we definitely + // can't find a join loc unless the VPHI is a backedge. + if (OutVal.isUnjoinedPHI() && OutVal.BlockNo != MBB.getNumber()) + return false; + + if (FirstValue.Properties != OutVal.Properties) + return false; + + for (unsigned Idx = 0; Idx < FirstValue.getLocationOpCount(); ++Idx) { + // An unjoined PHI has no defined locations, and so a shared location must + // be found for every operand. + if (OutVal.isUnjoinedPHI()) { + LocOpsToJoin.insert(Idx); + continue; + } + DbgOpID FirstValOp = FirstValue.getDbgOpID(Idx); + DbgOpID OutValOp = OutVal.getDbgOpID(Idx); + if (FirstValOp != OutValOp) { + // We can never join constant ops - the ops must either both be equal + // constant ops or non-const ops. + if (FirstValOp.isConst() || OutValOp.isConst()) + return false; + else + LocOpsToJoin.insert(Idx); + } + } + } + + SmallVector NewDbgOps; + + for (unsigned Idx = 0; Idx < FirstValue.getLocationOpCount(); ++Idx) { + if (!LocOpsToJoin.contains(Idx)) { + NewDbgOps.push_back(FirstValue.getDbgOpID(Idx)); + continue; + } + + Optional JoinedOpLoc = + pickValuePHILoc(Idx, MBB, LiveOuts, MOutLocs, BlockOrders); + + if (!JoinedOpLoc) + return false; + + NewDbgOps.push_back(DbgOpStore.insert(*JoinedOpLoc)); + } - Properties.push_back(&OutVal.Properties); + OutValues.append(NewDbgOps); + return true; +} + +Optional InstrRefBasedLDV::pickValuePHILoc( + unsigned DbgOpIdx, const MachineBasicBlock &MBB, const LiveIdxT &LiveOuts, + FuncValueTable &MOutLocs, + const SmallVectorImpl &BlockOrders) { + + // Collect a set of locations from predecessor where its live-out value can + // be found. + SmallVector, 8> Locs; + unsigned NumLocs = MTracker->getNumLocs(); + + for (auto p : BlockOrders) { + unsigned ThisBBNum = p->getNumber(); + auto OutValIt = LiveOuts.find(p); + assert(OutValIt != LiveOuts.end()); + const DbgValue &OutVal = *OutValIt->second; + DbgOpID OutValOpID = OutVal.getDbgOpID(DbgOpIdx); + DbgOp OutValOp = DbgOpStore.find(OutValOpID); + assert(!OutValOp.IsConst); // Create new empty vector of locations. Locs.resize(Locs.size() + 1); @@ -2425,8 +2494,8 @@ // present. Do the same for VPHIs where we know the VPHI value. if (OutVal.Kind == DbgValue::Def || (OutVal.Kind == DbgValue::VPHI && OutVal.BlockNo != MBB.getNumber() && - !OutVal.getDbgOpID(0).isUndef())) { - ValueIDNum ValToLookFor = DbgOpStore.find(OutVal.getDbgOpID(0)).ID; + OutValOp.ID != ValueIDNum::EmptyValue)) { + ValueIDNum ValToLookFor = OutValOp.ID; // Search the live-outs of the predecessor for the specified value. for (unsigned int I = 0; I < NumLocs; ++I) { if (MOutLocs[ThisBBNum][I] == ValToLookFor) @@ -2434,11 +2503,6 @@ } } else { assert(OutVal.Kind == DbgValue::VPHI); - // For VPHIs where we don't know the location, we definitely can't find - // a join loc. - if (OutVal.BlockNo != MBB.getNumber()) - return None; - // Otherwise: this is a VPHI on a backedge feeding back into itself, i.e. // a value that's live-through the whole loop. (It has to be a backedge, // because a block can't dominate itself). We can accept as a PHI location @@ -2452,17 +2516,9 @@ } } } - // We should have found locations for all predecessors, or returned. assert(Locs.size() == BlockOrders.size()); - // Check that all properties are the same. We can't pick a location if they're - // not. - const DbgValueProperties *Properties0 = Properties[0]; - for (auto *Prop : Properties) - if (*Prop != *Properties0) - return None; - // Starting with the first set of locations, take the intersection with // subsequent sets. SmallVector CandidateLocs = Locs[0]; @@ -2476,6 +2532,8 @@ if (CandidateLocs.empty()) return None; + Locs.clear(); + // We now have a set of LocIdxes that contain the right output value in // each of the predecessors. Pick the lowest; if there's a register loc, // that'll be it. @@ -2815,13 +2873,13 @@ // 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 ValueNum = - pickVPHILoc(*MBB, Var, LiveOutIdx, MOutLocs, Preds); + SmallVector JoinedOps; - if (ValueNum) { - DbgOpID ValueID = DbgOpStore.insert(*ValueNum); - InLocsChanged |= LiveIn->getDbgOpID(0) != ValueID; - LiveIn->setDbgOpIDs(ValueID); + if (pickVPHILoc(JoinedOps, *MBB, LiveOutIdx, MOutLocs, Preds)) { + bool NewLocPicked = !equal(LiveIn->getDbgOpIDs(), JoinedOps); + InLocsChanged |= NewLocPicked; + if (NewLocPicked) + LiveIn->setDbgOpIDs(JoinedOps); } }