Index: llvm/trunk/include/llvm/CodeGen/SelectionDAG.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/SelectionDAG.h +++ llvm/trunk/include/llvm/CodeGen/SelectionDAG.h @@ -1195,9 +1195,10 @@ unsigned O); /// Transfer debug values from one node to another, while optionally - /// generating fragment expressions for split-up values. + /// generating fragment expressions for split-up values. If \p InvalidateDbg + /// is set, debug values are invalidated after they are transferred. void transferDbgValues(SDValue From, SDValue To, unsigned OffsetInBits = 0, - unsigned SizeInBits = 0); + unsigned SizeInBits = 0, bool InvalidateDbg = true); /// Remove the specified node from the system. If any of its /// operands then becomes dead, remove them as well. Inform UpdateListener @@ -1279,10 +1280,6 @@ return DbgInfo->getSDDbgValues(SD); } -private: - /// Transfer SDDbgValues. Called via ReplaceAllUses{OfValue}?With - void TransferDbgValues(SDValue From, SDValue To); - public: /// Return true if there are any SDDbgValue nodes associated /// with this SelectionDAG. Index: llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp =================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp +++ llvm/trunk/lib/CodeGen/SelectionDAG/LegalizeTypes.cpp @@ -845,13 +845,14 @@ AnalyzeNewValue(Lo); AnalyzeNewValue(Hi); - // Transfer debug values. + // Transfer debug values. Don't invalidate the source debug value until it's + // been transferred to the high and low bits. if (DAG.getDataLayout().isBigEndian()) { - DAG.transferDbgValues(Op, Hi, 0, Hi.getValueSizeInBits()); + DAG.transferDbgValues(Op, Hi, 0, Hi.getValueSizeInBits(), false); DAG.transferDbgValues(Op, Lo, Hi.getValueSizeInBits(), Lo.getValueSizeInBits()); } else { - DAG.transferDbgValues(Op, Lo, 0, Lo.getValueSizeInBits()); + DAG.transferDbgValues(Op, Lo, 0, Lo.getValueSizeInBits(), false); DAG.transferDbgValues(Op, Hi, Lo.getValueSizeInBits(), Hi.getValueSizeInBits()); } Index: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -7027,16 +7027,29 @@ } void SelectionDAG::transferDbgValues(SDValue From, SDValue To, - unsigned OffsetInBits, - unsigned SizeInBits) { + unsigned OffsetInBits, unsigned SizeInBits, + bool InvalidateDbg) { SDNode *FromNode = From.getNode(); SDNode *ToNode = To.getNode(); - assert(FromNode != ToNode); + assert(FromNode && ToNode && "Can't modify dbg values"); + + // Remove these checks when ReplaceAllUsesWith gets stricter. + // TODO: assert(From != To && "Redundant dbg value transfer"); + // TODO: assert(FromNode != ToNode && "Intranode dbg value transfer"); + if (From == To || FromNode == ToNode) + return; + + if (!FromNode->getHasDebugValue()) + return; SmallVector ClonedDVs; for (SDDbgValue *Dbg : GetDbgValues(FromNode)) { - if (Dbg->getKind() != SDDbgValue::SDNODE) - break; + // Just transfer the dbg value attached to From. + if (Dbg->getResNo() != From.getResNo()) + continue; + + assert(!Dbg->isInvalidated() && "Invalid dbg value"); + assert(Dbg->getKind() == SDDbgValue::SDNODE && "Can't transfer dbg value"); DIVariable *Var = Dbg->getVariable(); auto *Expr = Dbg->getExpression(); @@ -7059,7 +7072,9 @@ getDbgValue(Var, Expr, ToNode, To.getResNo(), Dbg->isIndirect(), Dbg->getDebugLoc(), Dbg->getOrder()); ClonedDVs.push_back(Clone); - Dbg->setIsInvalidated(); + + if (InvalidateDbg) + Dbg->setIsInvalidated(); } for (SDDbgValue *Dbg : ClonedDVs) @@ -7137,7 +7152,7 @@ assert(From != To.getNode() && "Cannot replace uses of with self"); // Preserve Debug Values - TransferDbgValues(FromN, To); + transferDbgValues(FromN, To); // Iterate over all the existing uses of From. New uses will be added // to the beginning of the use list, which we avoid visiting. @@ -7196,7 +7211,7 @@ for (unsigned i = 0, e = From->getNumValues(); i != e; ++i) if (From->hasAnyUseOfValue(i)) { assert((i < To->getNumValues()) && "Invalid To location"); - TransferDbgValues(SDValue(From, i), SDValue(To, i)); + transferDbgValues(SDValue(From, i), SDValue(To, i)); } // Iterate over just the existing users of From. See the comments in @@ -7240,7 +7255,7 @@ // Preserve Debug Info. for (unsigned i = 0, e = From->getNumValues(); i != e; ++i) - TransferDbgValues(SDValue(From, i), *To); + transferDbgValues(SDValue(From, i), *To); // Iterate over just the existing users of From. See the comments in // the ReplaceAllUsesWith above. @@ -7287,7 +7302,7 @@ } // Preserve Debug Info. - TransferDbgValues(From, To); + transferDbgValues(From, To); // Iterate over just the existing users of From. See the comments in // the ReplaceAllUsesWith above. @@ -7365,7 +7380,7 @@ if (Num == 1) return ReplaceAllUsesOfValueWith(*From, *To); - TransferDbgValues(*From, *To); + transferDbgValues(*From, *To); // Read up all the uses and make records of them. This helps // processing new uses that are introduced during the @@ -7514,31 +7529,6 @@ DbgInfo->add(DB, SD, isParameter); } -/// Transfer SDDbgValues. Called in replace nodes. -void SelectionDAG::TransferDbgValues(SDValue From, SDValue To) { - if (From == To || !From.getNode()->getHasDebugValue()) - return; - SDNode *FromNode = From.getNode(); - SDNode *ToNode = To.getNode(); - SmallVector ClonedDVs; - for (auto *Dbg : GetDbgValues(FromNode)) { - // Only add Dbgvalues attached to same ResNo. - if (Dbg->getKind() == SDDbgValue::SDNODE && - Dbg->getSDNode() == From.getNode() && - Dbg->getResNo() == From.getResNo() && !Dbg->isInvalidated()) { - assert(FromNode != ToNode && - "Should not transfer Debug Values intranode"); - SDDbgValue *Clone = getDbgValue(Dbg->getVariable(), Dbg->getExpression(), - ToNode, To.getResNo(), Dbg->isIndirect(), - Dbg->getDebugLoc(), Dbg->getOrder()); - ClonedDVs.push_back(Clone); - Dbg->setIsInvalidated(); - } - } - for (SDDbgValue *I : ClonedDVs) - AddDbgValue(I, ToNode, false); -} - SDValue SelectionDAG::makeEquivalentMemoryOrdering(LoadSDNode *OldLoad, SDValue NewMemOp) { assert(isa(NewMemOp.getNode()) && "Expected a memop node");