@@ -276,15 +276,22 @@ llvm::cl::opt<std::string> StatsOnlyFunctionsNamePattern(
276
276
struct FunctionStat {
277
277
int BlockCount = 0 ;
278
278
int InstCount = 0 ;
279
+ // / True when the FunctionStat is created for a SIL Function after a SIL
280
+ // / Optimization pass has been run on it. When it is a post optimization SIL
281
+ // / Function, we do not want to store anything in the InlinedAts Map in
282
+ // / InstCountVisitor.
283
+ bool NewFunc = false ;
279
284
// / Instruction counts per SILInstruction kind.
280
285
InstructionCounts InstCounts;
281
286
282
287
using VarID = std::tuple<const SILDebugScope *, llvm::StringRef,
283
288
unsigned , unsigned >;
284
289
llvm::StringSet<> VarNames;
285
290
llvm::DenseSet<FunctionStat::VarID> DebugVariables;
291
+ llvm::DenseSet<const SILDebugScope *> VisitedScope;
292
+ llvm::DenseMap<VarID, const SILDebugScope *> InlinedAts;
286
293
287
- FunctionStat (SILFunction *F);
294
+ FunctionStat (SILFunction *F, bool NewFunc = false );
288
295
FunctionStat () {}
289
296
290
297
// The DebugVariables set contains pointers to VarNames. Disallow copy.
@@ -384,15 +391,24 @@ struct ModuleStat {
384
391
struct InstCountVisitor : SILInstructionVisitor<InstCountVisitor> {
385
392
int BlockCount = 0 ;
386
393
int InstCount = 0 ;
394
+ // / True when the InstCountVisitor is created for a SIL Function after a SIL
395
+ // / Optimization pass has been run on it. When it is a post optimization SIL
396
+ // / Function, we do not want to store anything in the InlinedAts Map in
397
+ // / InstCountVisitor.
398
+ const bool &NewFunc;
387
399
InstructionCounts &InstCounts;
388
400
389
401
llvm::StringSet<> &VarNames;
390
402
llvm::DenseSet<FunctionStat::VarID> &DebugVariables;
403
+ llvm::DenseMap<FunctionStat::VarID, const SILDebugScope *> &InlinedAts;
391
404
392
- InstCountVisitor (InstructionCounts &InstCounts,
393
- llvm::StringSet<> &VarNames,
394
- llvm::DenseSet<FunctionStat::VarID> &DebugVariables)
395
- : InstCounts(InstCounts), VarNames(VarNames), DebugVariables(DebugVariables) {}
405
+ InstCountVisitor (
406
+ InstructionCounts &InstCounts, llvm::StringSet<> &VarNames,
407
+ llvm::DenseSet<FunctionStat::VarID> &DebugVariables,
408
+ llvm::DenseMap<FunctionStat::VarID, const SILDebugScope *> &InlinedAts,
409
+ bool &NewFunc)
410
+ : NewFunc(NewFunc), InstCounts(InstCounts), VarNames(VarNames),
411
+ DebugVariables (DebugVariables), InlinedAts(InlinedAts) {}
396
412
397
413
int getBlockCount () const {
398
414
return BlockCount;
@@ -431,6 +447,8 @@ struct InstCountVisitor : SILInstructionVisitor<InstCountVisitor> {
431
447
varInfo->Scope ? varInfo->Scope : inst->getDebugScope (),
432
448
UniqueName, line, col);
433
449
DebugVariables.insert (key);
450
+ if (!NewFunc)
451
+ InlinedAts.try_emplace (key, varInfo->Scope ->InlinedCallSite );
434
452
}
435
453
};
436
454
@@ -710,16 +728,85 @@ bool isFirstTimeData(int Old, int New) {
710
728
return Old == 0 && New != Old;
711
729
}
712
730
713
- int computeLostVariables (llvm::DenseSet<FunctionStat::VarID> &Old,
714
- llvm::DenseSet<FunctionStat::VarID> &New) {
715
- unsigned count = 0 ;
716
- for (auto &var : Old) {
717
- if (New.contains (var))
731
+ // / Return true if \p Scope is the same as \p DbgValScope or a child scope of
732
+ // / \p DbgValScope, return false otherwise.
733
+ bool isScopeChildOfOrEqualTo (const SILDebugScope *Scope,
734
+ const SILDebugScope *DbgValScope) {
735
+ llvm::DenseSet<const SILDebugScope *> VisitedScope;
736
+ while (Scope != nullptr ) {
737
+ if (VisitedScope.find (Scope) == VisitedScope.end ()) {
738
+ VisitedScope.insert (Scope);
739
+ if (Scope == DbgValScope) {
740
+ return true ;
741
+ }
742
+ if (auto *S = dyn_cast<const SILDebugScope *>(Scope->Parent ))
743
+ Scope = S;
744
+ } else
745
+ return false ;
746
+ }
747
+ return false ;
748
+ }
749
+
750
+ // / Return true if \p InlinedAt is the same as \p DbgValInlinedAt or part of
751
+ // / the InlinedAt chain, return false otherwise.
752
+ bool isInlinedAtChildOfOrEqualTo (const SILDebugScope *InlinedAt,
753
+ const SILDebugScope *DbgValInlinedAt) {
754
+ if (DbgValInlinedAt == InlinedAt)
755
+ return true ;
756
+ if (!DbgValInlinedAt)
757
+ return false ;
758
+ if (!InlinedAt)
759
+ return false ;
760
+ auto *IA = InlinedAt;
761
+ while (IA) {
762
+ if (IA == DbgValInlinedAt)
763
+ return true ;
764
+ IA = IA->InlinedCallSite ;
765
+ }
766
+ return false ;
767
+ }
768
+
769
+ int computeLostVariables (SILFunction *F, FunctionStat &Old, FunctionStat &New) {
770
+ unsigned LostCount = 0 ;
771
+ unsigned PrevLostCount = 0 ;
772
+ auto &OldSet = Old.DebugVariables ;
773
+ auto &NewSet = New.DebugVariables ;
774
+ // Find an Instruction that shares the same scope as the dropped debug_value
775
+ // or has a scope that is the child of the scope of the debug_value, and has
776
+ // an inlinedAt equal to the inlinedAt of the debug_value or it's inlinedAt
777
+ // chain contains the inlinedAt of the debug_value, if such an Instruction is
778
+ // found, debug information is dropped.
779
+ for (auto &Var : OldSet) {
780
+ if (NewSet.contains (Var))
718
781
continue ;
719
- // llvm::dbgs() << "Lost variable: " << std::get<1>(var) << "\n";
720
- count++;
782
+ auto &DbgValScope = std::get<0 >(Var);
783
+ for (auto &BB : *F) {
784
+ for (auto &I : BB) {
785
+ if (I.isDebugInstruction ()) {
786
+ auto DbgLoc = I.getDebugLocation ();
787
+ auto Scope = DbgLoc.getScope ();
788
+ // If the Scope is a child of, or equal to the DbgValScope and is
789
+ // inlined at the Var's InlinedAt location, return true to signify
790
+ // that the Var has been dropped.
791
+ if (isScopeChildOfOrEqualTo (Scope, DbgValScope)) {
792
+ if (isInlinedAtChildOfOrEqualTo (Scope->InlinedCallSite ,
793
+ Old.InlinedAts [Var])) {
794
+ // Found another instruction in the variable's scope, so there
795
+ // exists a break point at which the variable could be observed.
796
+ // Count it as dropped.
797
+ LostCount++;
798
+ break ;
799
+ }
800
+ }
801
+ }
802
+ }
803
+ if (PrevLostCount != LostCount) {
804
+ PrevLostCount = LostCount;
805
+ break ;
806
+ }
807
+ }
721
808
}
722
- return count ;
809
+ return LostCount ;
723
810
}
724
811
725
812
// / Dump statistics for a SILFunction. It is only used if a user asked to
@@ -782,8 +869,7 @@ void processFuncStatsChanges(SILFunction *F, FunctionStat &OldStat,
782
869
// Compute deltas.
783
870
double DeltaBlockCount = computeDelta (OldStat.BlockCount , NewStat.BlockCount );
784
871
double DeltaInstCount = computeDelta (OldStat.InstCount , NewStat.InstCount );
785
- int LostVariables = computeLostVariables (OldStat.DebugVariables ,
786
- NewStat.DebugVariables );
872
+ int LostVariables = computeLostVariables (F, OldStat, NewStat);
787
873
788
874
NewLineInserter nl;
789
875
@@ -959,7 +1045,7 @@ void OptimizerStatsAnalysis::updateModuleStats(TransformationContext &Ctx) {
959
1045
InvalidatedFuncs.pop_back ();
960
1046
auto &FuncStat = getFunctionStat (F);
961
1047
auto &OldFuncStat = FuncStat;
962
- FunctionStat NewFuncStat (F);
1048
+ FunctionStat NewFuncStat (F, true );
963
1049
processFuncStatsChanges (F, OldFuncStat, NewFuncStat, Ctx);
964
1050
NewModStat.subFunctionStat (OldFuncStat);
965
1051
NewModStat.addFunctionStat (NewFuncStat);
@@ -984,7 +1070,7 @@ void OptimizerStatsAnalysis::updateModuleStats(TransformationContext &Ctx) {
984
1070
AddedFuncs.pop_back ();
985
1071
auto &FuncStat = getFunctionStat (F);
986
1072
FunctionStat OldFuncStat;
987
- FunctionStat NewFuncStat (F);
1073
+ FunctionStat NewFuncStat (F, true );
988
1074
processFuncStatsChanges (F, OldFuncStat, NewFuncStat, Ctx);
989
1075
NewModStat.addFunctionStat (NewFuncStat);
990
1076
FuncStat = std::move (NewFuncStat);
@@ -1003,8 +1089,8 @@ void OptimizerStatsAnalysis::updateModuleStats(TransformationContext &Ctx) {
1003
1089
ModStat = NewModStat;
1004
1090
}
1005
1091
1006
- FunctionStat::FunctionStat (SILFunction *F) {
1007
- InstCountVisitor V (InstCounts, VarNames, DebugVariables);
1092
+ FunctionStat::FunctionStat (SILFunction *F, bool NewFunc) : NewFunc(NewFunc ) {
1093
+ InstCountVisitor V (InstCounts, VarNames, DebugVariables, InlinedAts, NewFunc );
1008
1094
V.visitSILFunction (F);
1009
1095
BlockCount = V.getBlockCount ();
1010
1096
InstCount = V.getInstCount ();
0 commit comments