diff --git a/llvm/include/llvm/IR/IntrinsicInst.h b/llvm/include/llvm/IR/IntrinsicInst.h --- a/llvm/include/llvm/IR/IntrinsicInst.h +++ b/llvm/include/llvm/IR/IntrinsicInst.h @@ -270,6 +270,13 @@ return cast(getArgOperand(2))->getMetadata(); } + /// Use of this should generally be avoided; instead, + /// replaceVariableLocationOp and addVariableLocationOps should be used where + /// possible to avoid creating invalid state. + void setRawLocation(Metadata *Location) { + return setArgOperand(0, MetadataAsValue::get(getContext(), Location)); + } + /// Get the size (in bits) of the variable, or fragment of the variable that /// is described. Optional getFragmentSizeInBits() const; diff --git a/llvm/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h b/llvm/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h --- a/llvm/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h +++ b/llvm/lib/CodeGen/SelectionDAG/SDNodeDbgValue.h @@ -138,7 +138,7 @@ private: LocOpVector LocationOps; - SDNodeVector SDNodes; + SDNodeVector AdditionalDependencies; DIVariable *Var; DIExpression *Expr; DebugLoc DL; @@ -153,8 +153,9 @@ ArrayRef Dependencies, bool IsIndirect, DebugLoc DL, unsigned O, bool IsVariadic) : LocationOps(L.begin(), L.end()), - SDNodes(Dependencies.begin(), Dependencies.end()), Var(Var), Expr(Expr), - DL(DL), Order(O), IsIndirect(IsIndirect), IsVariadic(IsVariadic) { + AdditionalDependencies(Dependencies.begin(), Dependencies.end()), + Var(Var), Expr(Expr), DL(DL), Order(O), IsIndirect(IsIndirect), + IsVariadic(IsVariadic) { assert(IsVariadic || L.size() == 1); assert(!(IsVariadic && IsIndirect)); } @@ -170,9 +171,18 @@ LocOpVector copyLocationOps() const { return LocationOps; } // Returns the SDNodes which this SDDbgValue depends on. - ArrayRef getSDNodes() const { return SDNodes; } + SDNodeVector getSDNodes() const { + SDNodeVector Dependencies; + for (SDDbgOperand DbgOp : LocationOps) + if (DbgOp.getKind() == SDDbgOperand::SDNODE) + Dependencies.push_back(DbgOp.getSDNode()); + Dependencies.append(AdditionalDependencies); + return Dependencies; + } - SDNodeVector copySDNodes() const { return SDNodes; } + ArrayRef getAdditionalDependencies() const { + return AdditionalDependencies; + } /// Returns whether this is an indirect value. bool isIndirect() const { return IsIndirect; } diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -8476,7 +8476,7 @@ assert(cast(Var)->isValidLocationForIntrinsic(DL) && "Expected inlined-at fields to agree"); return new (DbgInfo->getAlloc()) - SDDbgValue(Var, Expr, SDDbgOperand::fromNode(N, R), N, IsIndirect, DL, O, + SDDbgValue(Var, Expr, SDDbgOperand::fromNode(N, R), {}, IsIndirect, DL, O, /*IsVariadic=*/false); } @@ -8600,12 +8600,10 @@ Expr = *Fragment; } - auto NewDependencies = Dbg->copySDNodes(); - std::replace(NewDependencies.begin(), NewDependencies.end(), FromNode, - ToNode); + auto AdditionalDependencies = Dbg->getAdditionalDependencies(); // Clone the SDDbgValue and move it to To. SDDbgValue *Clone = getDbgValueList( - Var, Expr, NewLocOps, NewDependencies, Dbg->isIndirect(), + Var, Expr, NewLocOps, AdditionalDependencies, Dbg->isIndirect(), Dbg->getDebugLoc(), std::max(ToNode->getIROrder(), Dbg->getOrder()), Dbg->isVariadic()); ClonedDVs.push_back(Clone); @@ -8665,11 +8663,9 @@ (void)Changed; assert(Changed && "Salvage target doesn't use N"); - auto NewDependencies = DV->copySDNodes(); - std::replace(NewDependencies.begin(), NewDependencies.end(), &N, - N0.getNode()); + auto AdditionalDependencies = DV->getAdditionalDependencies(); SDDbgValue *Clone = getDbgValueList(DV->getVariable(), DIExpr, - NewLocOps, NewDependencies, + NewLocOps, AdditionalDependencies, DV->isIndirect(), DV->getDebugLoc(), DV->getOrder(), DV->isVariadic()); ClonedDVs.push_back(Clone); diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp --- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -1340,7 +1340,6 @@ // Only emit func arg dbg value for non-variadic dbg.values for now. if (!IsVariadic && EmitFuncArgumentDbgValue(V, Var, Expr, dl, false, N)) return true; - Dependencies.push_back(N.getNode()); if (auto *FISDN = dyn_cast(N.getNode())) { // Construct a FrameIndexDbgValue for FrameIndexSDNodes so we can // describe stack slot locations. @@ -1352,6 +1351,7 @@ // dbg.value(i32* %px, !"int x", !DIExpression(DW_OP_deref)) // // Both describe the direct values of their associated variables. + Dependencies.push_back(N.getNode()); LocationOps.emplace_back(SDDbgOperand::fromFrameIdx(FISDN->getIndex())); continue; } diff --git a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp --- a/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp +++ b/llvm/lib/Transforms/Scalar/LoopStrengthReduce.cpp @@ -5831,12 +5831,13 @@ using EqualValues = SmallVector, 4>; using EqualValuesMap = - DenseMap, EqualValues>; -using ExpressionMap = DenseMap; + DenseMap>>; +using LocationMap = + DenseMap>; static void DbgGatherEqualValues(Loop *L, ScalarEvolution &SE, EqualValuesMap &DbgValueToEqualSet, - ExpressionMap &DbgValueToExpression) { + LocationMap &DbgValueToLocation) { for (auto &B : L->getBlocks()) { for (auto &I : *B) { auto DVI = dyn_cast(&I); @@ -5862,39 +5863,45 @@ EqSet.emplace_back( std::make_tuple(&Phi, Offset.getValue().getSExtValue())); } - DbgValueToEqualSet[{DVI, Idx}] = std::move(EqSet); - DbgValueToExpression[DVI] = DVI->getExpression(); + DbgValueToEqualSet[DVI].push_back({Idx, std::move(EqSet)}); + DbgValueToLocation[DVI] = { + DVI->getExpression(), + DVI->hasArgList() ? DVI->getRawLocation() + : ValueAsMetadata::get(UndefValue::get( + DVI->getVariableLocationOp(0)->getType()))}; } } } } static void DbgApplyEqualValues(EqualValuesMap &DbgValueToEqualSet, - ExpressionMap &DbgValueToExpression) { + LocationMap &DbgValueToLocation) { for (auto A : DbgValueToEqualSet) { - auto DVI = A.first.first; - auto Idx = A.first.second; + auto DVI = A.first; // Only update those that are now undef. - if (!isa_and_nonnull(DVI->getVariableLocationOp(Idx))) + if (!DVI->isUndef()) continue; - for (auto EV : A.second) { - auto EVHandle = std::get(EV); - if (!EVHandle) - continue; - // The dbg.value may have had its value changed by LSR; refresh it from - // the map, but continue to update the mapped expression as it may be - // updated multiple times in this function. - auto DbgDIExpr = DbgValueToExpression[DVI]; - auto Offset = std::get(EV); - DVI->replaceVariableLocationOp(Idx, EVHandle); - if (Offset) { - SmallVector Ops; - DIExpression::appendOffset(Ops, Offset); - DbgDIExpr = DIExpression::appendOpsToArg(DbgDIExpr, Ops, Idx, true); + // The dbg.value may have had its value or expression changed by LSR; + // refresh them from the map. + auto DbgDIExpr = DbgValueToLocation[DVI].first; + DVI->setRawLocation(DbgValueToLocation[DVI].second); + DVI->setExpression(DbgDIExpr); + for (auto IdxEV : A.second) { + auto Idx = IdxEV.first; + for (auto EV : IdxEV.second) { + auto EVHandle = std::get(EV); + if (!EVHandle) + continue; + auto Offset = std::get(EV); + DVI->replaceVariableLocationOp(Idx, EVHandle); + if (Offset) { + SmallVector Ops; + DIExpression::appendOffset(Ops, Offset); + DbgDIExpr = DIExpression::appendOpsToArg(DbgDIExpr, Ops, Idx, true); + } + DVI->setExpression(DbgDIExpr); + break; } - DVI->setExpression(DbgDIExpr); - DbgValueToExpression[DVI] = DbgDIExpr; - break; } } } @@ -5917,8 +5924,8 @@ // Debug preservation - before we start removing anything create equivalence // sets for the llvm.dbg.value intrinsics. EqualValuesMap DbgValueToEqualSet; - ExpressionMap DbgValueToExpression; - DbgGatherEqualValues(L, SE, DbgValueToEqualSet, DbgValueToExpression); + LocationMap DbgValueToLocation; + DbgGatherEqualValues(L, SE, DbgValueToEqualSet, DbgValueToLocation); // Remove any extra phis created by processing inner loops. Changed |= DeleteDeadPHIs(L->getHeader(), &TLI, MSSAU.get()); @@ -5938,7 +5945,7 @@ } } - DbgApplyEqualValues(DbgValueToEqualSet, DbgValueToExpression); + DbgApplyEqualValues(DbgValueToEqualSet, DbgValueToLocation); return Changed; }