@@ -233,6 +233,63 @@ void DebugLocDwarfExpression::commitTemporaryBuffer() {
233233 TmpBuf->Comments .clear ();
234234}
235235
236+ namespace {
237+ // / Utility class for finding the common divergent address space of all the
238+ // / DIExpressions that describe the location of a variable, if such an address
239+ // / space exists.
240+ class CommonDivergentAddrSpaceFinder {
241+ std::optional<unsigned > CommonAS;
242+ bool HasCommonAddrSpace = true ;
243+
244+ public:
245+ void addSubExpr (const DIExpression *Expr) {
246+ if (!Expr || !HasCommonAddrSpace)
247+ return ;
248+ std::optional<unsigned > ExprAS = Expr->getNewDivergentAddrSpace ();
249+ if (!ExprAS)
250+ HasCommonAddrSpace = false ;
251+ else if (!CommonAS)
252+ CommonAS = *ExprAS;
253+ else if (*CommonAS != *ExprAS)
254+ HasCommonAddrSpace = false ;
255+ }
256+
257+ std::optional<unsigned > get () const {
258+ return HasCommonAddrSpace ? CommonAS : std::nullopt ;
259+ }
260+ };
261+ } // namespace
262+
263+ std::optional<unsigned > DbgVariable::getCommonDivergentAddrSpace () const {
264+ const Loc::Variant *Loc = &asVariant ();
265+
266+ if (auto *LM = std::get_if<Loc::Multi>(Loc))
267+ return LM->getCommonDivergentAddrSpace ();
268+
269+ CommonDivergentAddrSpaceFinder Finder;
270+ if (auto *LS = std::get_if<Loc::Single>(Loc)) {
271+ Finder.addSubExpr (LS->getExpr ());
272+ } else if (auto *MMI = std::get_if<Loc::MMI>(Loc)) {
273+ for (auto &FIE : MMI->getFrameIndexExprs ())
274+ Finder.addSubExpr (FIE.Expr );
275+ } else if (auto *EV = std::get_if<Loc::EntryValue>(Loc)) {
276+ for (auto &Val : EV->EntryValues )
277+ Finder.addSubExpr (&Val.Expr );
278+ }
279+
280+ return Finder.get ();
281+ }
282+
283+ bool DbgVariable::isDivergentAddrSpaceCompatible () const {
284+ if (auto *DT = dyn_cast<DIDerivedType>(getType ()))
285+ return DT->getTag () == dwarf::DW_TAG_pointer_type ||
286+ DT->getTag () == dwarf::DW_TAG_reference_type ||
287+ DT->getTag () == dwarf::DW_TAG_rvalue_reference_type;
288+ // FIXME: We could support divergent address spaces on pointer/reference
289+ // fields of struct types.
290+ return false ;
291+ }
292+
236293const DIType *DbgVariable::getType () const {
237294 return getVariable ()->getType ();
238295}
@@ -1952,6 +2009,18 @@ void DwarfDebug::collectEntityInfo(DwarfCompileUnit &TheCU,
19522009 continue ;
19532010 }
19542011
2012+ // If all entries in the location list produce a consistent divergent
2013+ // address space we need to inform the expression emitter that it is
2014+ // permitted to produce divergent address spaces.
2015+ if (RegVar->isDivergentAddrSpaceCompatible ()) {
2016+ CommonDivergentAddrSpaceFinder Finder;
2017+ for (const DebugLocEntry &DLE : Entries)
2018+ for (const DbgValueLoc &DVL : DLE.getValues ())
2019+ Finder.addSubExpr (DVL.getExpression ());
2020+ if (std::optional<unsigned > AS = Finder.get ())
2021+ List.setCommonDivergentAddrSpace (*AS);
2022+ }
2023+
19552024 // If the variable has a DIBasicType, extract it. Basic types cannot have
19562025 // unique identifiers, so don't bother resolving the type with the
19572026 // identifier map.
@@ -3181,6 +3250,8 @@ void DebugLocEntry::finalize(const AsmPrinter &AP,
31813250 DebugLocStream::EntryBuilder Entry (List, Begin, End);
31823251 BufferByteStreamer Streamer = Entry.getStreamer ();
31833252 DebugLocDwarfExpression DwarfExpr (AP, Streamer, TheCU);
3253+ if (List.hasCommonDivergentAddrSpace ())
3254+ DwarfExpr.permitDivergentAddrSpace ();
31843255 const DbgValueLoc &Value = Values[0 ];
31853256 if (Value.isFragment ()) {
31863257 // Emit all fragments that belong to the same variable and range.
0 commit comments