37
37
#include " llvm/Support/Debug.h"
38
38
#include " llvm/Support/GraphWriter.h"
39
39
#include " llvm/Support/ManagedStatic.h"
40
- #include " llvm/Support/Chrono.h"
41
40
42
41
using namespace swift ;
43
42
@@ -61,6 +60,10 @@ llvm::cl::opt<std::string> SILNumOptPassesToRun(
61
60
" sil-opt-pass-count" , llvm::cl::init(" " ),
62
61
llvm::cl::desc(" Stop optimizing after <N> passes or <N>.<M> passes/sub-passes" ));
63
62
63
+ llvm::cl::opt<unsigned > SILOptProfileRepeat (
64
+ " sil-opt-profile-repeat" , llvm::cl::init(1 ),
65
+ llvm::cl::desc(" repeat passes N times and report the run time" ));
66
+
64
67
llvm::cl::opt<std::string> SILBreakOnFun (
65
68
" sil-break-on-function" , llvm::cl::init(" " ),
66
69
llvm::cl::desc(
@@ -518,7 +521,6 @@ void SILPassManager::runPassOnFunction(unsigned TransIdx, SILFunction *F) {
518
521
F->dump (getOptions ().EmitVerboseSIL );
519
522
}
520
523
521
- llvm::sys::TimePoint<> StartTime = std::chrono::system_clock::now ();
522
524
if (breakBeforeRunning (F->getName (), SFT))
523
525
LLVM_BUILTIN_DEBUGTRAP;
524
526
if (SILForceVerifyAll ||
@@ -531,31 +533,64 @@ void SILPassManager::runPassOnFunction(unsigned TransIdx, SILFunction *F) {
531
533
assert (changeNotifications == SILAnalysis::InvalidationKind::Nothing
532
534
&& " change notifications not cleared" );
533
535
534
- swiftPassInvocation.startFunctionPassRun (SFT);
536
+ llvm::sys::TimePoint<> startTime = std::chrono::system_clock::now ();
537
+ std::chrono::nanoseconds duration (0 );
538
+
539
+ enum {
540
+ // In future we might want to make snapshots with positive number (e.g.
541
+ // corresponding to pass indices). Therefore use -1 here to avoid collisions.
542
+ SnapshotID = -1
543
+ };
544
+
545
+ unsigned numRepeats = SILOptProfileRepeat;
546
+ if (numRepeats > 1 ) {
547
+ // Need to create a snapshot to restore the original state for consecutive runs.
548
+ F->createSnapshot (SnapshotID);
549
+ }
550
+ for (unsigned runIdx = 0 ; runIdx < numRepeats; runIdx++) {
551
+ swiftPassInvocation.startFunctionPassRun (SFT);
552
+
553
+ // Run it!
554
+ SFT->run ();
555
+
556
+ if (changeNotifications != SILAnalysis::InvalidationKind::Nothing) {
557
+ // Pause time measurement while invalidating analysis and restoring the snapshot.
558
+ duration += (std::chrono::system_clock::now () - startTime);
535
559
536
- // Run it!
537
- SFT->run ();
560
+ if (runIdx < numRepeats - 1 ) {
561
+ invalidateAnalysis (F, SILAnalysis::InvalidationKind::Everything);
562
+ F->restoreFromSnapshot (SnapshotID);
563
+ } else {
564
+ invalidateAnalysis (F, changeNotifications);
565
+ }
566
+ changeNotifications = SILAnalysis::InvalidationKind::Nothing;
567
+
568
+ // Continue time measurement (including flushing deleted instructions).
569
+ startTime = std::chrono::system_clock::now ();
570
+ }
571
+ Mod->flushDeletedInsts ();
572
+ swiftPassInvocation.finishedFunctionPassRun ();
573
+ }
538
574
539
- if (changeNotifications != SILAnalysis::InvalidationKind::Nothing) {
540
- invalidateAnalysis (F, changeNotifications);
541
- changeNotifications = SILAnalysis::InvalidationKind::Nothing;
575
+ duration += (std::chrono::system_clock::now () - startTime);
576
+ totalPassRuntime += duration;
577
+ if (SILPrintPassTime) {
578
+ double milliSecs = (double )duration.count () / 1000000 .;
579
+ llvm::dbgs () << llvm::format (" %9.3f" , milliSecs) << " ms: " << SFT->getTag ()
580
+ << " @" << F->getName () << " \n " ;
542
581
}
543
- swiftPassInvocation.finishedFunctionPassRun ();
582
+
583
+ if (numRepeats > 1 )
584
+ F->deleteSnapshot (SnapshotID);
585
+
586
+ assert (analysesUnlocked () && " Expected all analyses to be unlocked!" );
544
587
545
588
if (SILForceVerifyAll ||
546
589
SILForceVerifyAroundPass.end () !=
547
590
std::find_if (SILForceVerifyAroundPass.begin (),
548
591
SILForceVerifyAroundPass.end (), MatchFun)) {
549
592
verifyAnalyses (F);
550
593
}
551
- assert (analysesUnlocked () && " Expected all analyses to be unlocked!" );
552
- Mod->flushDeletedInsts ();
553
-
554
- auto Delta = (std::chrono::system_clock::now () - StartTime).count ();
555
- if (SILPrintPassTime) {
556
- llvm::dbgs () << Delta << " (" << SFT->getID () << " ," << F->getName ()
557
- << " )\n " ;
558
- }
559
594
560
595
// If this pass invalidated anything, print and verify.
561
596
if (doPrintAfter (SFT, F, CurrentPassHasInvalidated)) {
@@ -564,7 +599,7 @@ void SILPassManager::runPassOnFunction(unsigned TransIdx, SILFunction *F) {
564
599
}
565
600
566
601
updateSILModuleStatsAfterTransform (F->getModule (), SFT, *this , NumPassesRun,
567
- Delta );
602
+ duration. count () );
568
603
569
604
// Remember if this pass didn't change anything.
570
605
if (!CurrentPassHasInvalidated)
@@ -697,9 +732,12 @@ void SILPassManager::runModulePass(unsigned TransIdx) {
697
732
assert (analysesUnlocked () && " Expected all analyses to be unlocked!" );
698
733
Mod->flushDeletedInsts ();
699
734
700
- auto Delta = (std::chrono::system_clock::now () - StartTime).count ();
735
+ std::chrono::nanoseconds duration = std::chrono::system_clock::now () - StartTime;
736
+ totalPassRuntime += duration;
737
+
701
738
if (SILPrintPassTime) {
702
- llvm::dbgs () << Delta << " (" << SMT->getID () << " ,Module)\n " ;
739
+ double milliSecs = (double )duration.count () / 1000000 .;
740
+ llvm::dbgs () << llvm::format (" %9.3f" , milliSecs) << " ms: " << SMT->getTag () << " \n " ;
703
741
}
704
742
705
743
// If this pass invalidated anything, print and verify.
@@ -708,7 +746,7 @@ void SILPassManager::runModulePass(unsigned TransIdx) {
708
746
printModule (Mod, Options.EmitVerboseSIL );
709
747
}
710
748
711
- updateSILModuleStatsAfterTransform (*Mod, SMT, *this , NumPassesRun, Delta );
749
+ updateSILModuleStatsAfterTransform (*Mod, SMT, *this , NumPassesRun, duration. count () );
712
750
713
751
if (Options.VerifyAll &&
714
752
(CurrentPassHasInvalidated || !SILVerifyWithoutInvalidation)) {
@@ -799,6 +837,12 @@ void SILPassManager::execute() {
799
837
800
838
// / D'tor.
801
839
SILPassManager::~SILPassManager () {
840
+
841
+ if (SILOptProfileRepeat > 1 ) {
842
+ double milliSecs = (double )totalPassRuntime.count () / 1000000 .;
843
+ llvm::dbgs () << llvm::format (" %9.3f" , milliSecs) << " ms: total runtime of all passes\n " ;
844
+ }
845
+
802
846
// Before we do anything further, verify the module and our analyses. These
803
847
// are natural points with which to verify.
804
848
//
0 commit comments