@@ -6498,8 +6498,55 @@ ModulePass *llvm::createSROA_Parameter_HLSL() {
64986498// ===----------------------------------------------------------------------===//
64996499
65006500namespace {
6501+
6502+ struct GVDebugInfoPatchCache {
6503+ DenseMap<Function *, SetVector<DISubprogram *>> SubprogramsForFunction;
6504+ DenseSet<DILocation *> Seen;
6505+ DITypeIdentifierMap EmptyMap;
6506+
6507+ void CollectSubprograms (DILocation *Loc, SetVector<DISubprogram *> &Set) {
6508+ while (Loc) {
6509+ // This is potentially very expensive. Avoid repeatedly looking for
6510+ // DISubprogram's
6511+ if (Seen.count (Loc))
6512+ return ;
6513+ Seen.insert (Loc);
6514+ auto *Scope = dyn_cast<DIScope>(Loc->getScope ());
6515+ while (Scope) {
6516+ if (auto SubP = dyn_cast<DISubprogram>(Scope)) {
6517+ Set.insert (SubP);
6518+ break ;
6519+ }
6520+ Scope = Scope->getScope ().resolve (EmptyMap);
6521+ }
6522+ Loc = Loc->getInlinedAt ();
6523+ }
6524+ }
6525+
6526+ SetVector<DISubprogram *> &
6527+ GetSubprogramsForFunction (Function *F, DebugInfoFinder &DbgFinder) {
6528+ auto It = SubprogramsForFunction.find (F);
6529+ if (It != SubprogramsForFunction.end ())
6530+ return It->second ;
6531+
6532+ SetVector<DISubprogram *> &Ret = SubprogramsForFunction[F];
6533+ for (DISubprogram *SP : DbgFinder.subprograms ()) {
6534+ if (SP->getFunction () == F) {
6535+ Ret.insert (SP);
6536+ break ;
6537+ }
6538+ }
6539+
6540+ for (BasicBlock &BB : *F)
6541+ for (Instruction &I : BB)
6542+ CollectSubprograms (I.getDebugLoc (), Ret);
6543+ return Ret;
6544+ }
6545+ };
6546+
65016547class LowerStaticGlobalIntoAlloca : public ModulePass {
65026548 DebugInfoFinder m_DbgFinder;
6549+ GVDebugInfoPatchCache m_GVDebugInfoCache;
65036550
65046551public:
65056552 static char ID; // Pass identification, replacement for typeid
@@ -6687,28 +6734,15 @@ FindGlobalVariableFragment(const DebugInfoFinder &DbgFinder,
66876734// Create a fake local variable for the GlobalVariable GV that has just been
66886735// lowered to local Alloca.
66896736//
6690- static void PatchDebugInfo (DebugInfoFinder &DbgFinder, Function *F,
6737+ static void PatchDebugInfo (GVDebugInfoPatchCache &Cache,
6738+ DebugInfoFinder &DbgFinder, Function *F,
66916739 GlobalVariable *GV, AllocaInst *AI) {
6692- if (!DbgFinder.compile_unit_count ())
6693- return ;
6694-
6695- // Find the subprogram for function
6696- DISubprogram *Subprogram = nullptr ;
6697- for (DISubprogram *SP : DbgFinder.subprograms ()) {
6698- if (SP->getFunction () == F) {
6699- Subprogram = SP;
6700- break ;
6701- }
6702- }
6703-
67046740 DIGlobalVariable *DGV = dxilutil::FindGlobalVariableDebugInfo (GV, DbgFinder);
67056741 if (!DGV)
67066742 return ;
67076743
6708- DITypeIdentifierMap EmptyMap;
6709- DIBuilder DIB (*GV->getParent ());
6710- DIScope *Scope = Subprogram;
6711- DebugLoc Loc = DebugLoc::get (DGV->getLine (), 0 , Scope);
6744+ if (!DbgFinder.compile_unit_count ())
6745+ return ;
67126746
67136747 // If the variable is a member of another variable, find the offset and size
67146748 bool IsFragment = false ;
@@ -6725,20 +6759,30 @@ static void PatchDebugInfo(DebugInfoFinder &DbgFinder, Function *F,
67256759 // Subprogram as its scope, so we don't have to make one up for it.
67266760 llvm::dwarf::Tag Tag = llvm::dwarf::Tag::DW_TAG_arg_variable;
67276761
6762+ DITypeIdentifierMap EmptyMap;
67286763 DIType *Ty = DGV->getType ().resolve (EmptyMap);
67296764 DXASSERT (Ty->getTag () != dwarf::DW_TAG_member,
67306765 " Member type is not allowed for variables." );
6731- DILocalVariable *ConvertedLocalVar = DIB.createLocalVariable (
6732- Tag, Scope, Name, DGV->getFile (), DGV->getLine (), Ty);
67336766
6734- DIExpression *Expr = nullptr ;
6735- if (IsFragment) {
6736- Expr = DIB.createBitPieceExpression (OffsetInBits, SizeInBits);
6737- } else {
6738- Expr = DIB.createExpression (ArrayRef<int64_t >());
6739- }
6767+ DIBuilder DIB (*GV->getParent ());
6768+
6769+ SetVector<DISubprogram *> &Subprograms =
6770+ Cache.GetSubprogramsForFunction (F, DbgFinder);
6771+ for (DISubprogram *Subprogram : Subprograms) {
6772+ DIScope *Scope = Subprogram;
6773+ DebugLoc Loc = DebugLoc::get (DGV->getLine (), 0 , Scope);
67406774
6741- DIB.insertDeclare (AI, ConvertedLocalVar, Expr, Loc, AI->getNextNode ());
6775+ DILocalVariable *ConvertedLocalVar = DIB.createLocalVariable (
6776+ Tag, Scope, Name, DGV->getFile (), DGV->getLine (), Ty);
6777+
6778+ DIExpression *Expr = nullptr ;
6779+ if (IsFragment)
6780+ Expr = DIB.createBitPieceExpression (OffsetInBits, SizeInBits);
6781+ else
6782+ Expr = DIB.createExpression (ArrayRef<int64_t >());
6783+
6784+ DIB.insertDeclare (AI, ConvertedLocalVar, Expr, Loc, AI->getNextNode ());
6785+ }
67426786}
67436787
67446788// Collect instructions using GV and the value used by the instruction.
@@ -6816,7 +6860,7 @@ bool LowerStaticGlobalIntoAlloca::lowerStaticGlobalIntoAlloca(
68166860 if (AI->user_empty ())
68176861 AI->eraseFromParent ();
68186862 else
6819- PatchDebugInfo (m_DbgFinder, F, GV, AI);
6863+ PatchDebugInfo (m_GVDebugInfoCache, m_DbgFinder, F, GV, AI);
68206864 }
68216865
68226866 GV->removeDeadConstantUsers ();
0 commit comments