@@ -52,9 +52,13 @@ llvm::cl::opt<bool> SILPrintPassTime(
5252 " sil-print-pass-time" , llvm::cl::init(false ),
5353 llvm::cl::desc(" Print the execution time of each SIL pass" ));
5454
55- llvm::cl::opt<unsigned > SILNumOptPassesToRun (
56- " sil-opt-pass-count" , llvm::cl::init(UINT_MAX),
57- llvm::cl::desc(" Stop optimizing after <N> optimization passes" ));
55+ llvm::cl::opt<bool > SILPrintLast (
56+ " sil-print-last" , llvm::cl::init(false ),
57+ llvm::cl::desc(" Print the last optimized function before and after the last pass" ));
58+
59+ llvm::cl::opt<std::string> SILNumOptPassesToRun (
60+ " sil-opt-pass-count" , llvm::cl::init(" " ),
61+ llvm::cl::desc(" Stop optimizing after <N> passes or <N>.<M> passes/sub-passes" ));
5862
5963llvm::cl::opt<std::string> SILBreakOnFun (
6064 " sil-break-on-function" , llvm::cl::init(" " ),
@@ -178,7 +182,11 @@ static bool functionSelectionEmpty() {
178182 return SILPrintFunction.empty () && SILPrintFunctions.empty ();
179183}
180184
181- static bool doPrintBefore (SILTransform *T, SILFunction *F) {
185+ bool SILPassManager::doPrintBefore (SILTransform *T, SILFunction *F) {
186+ if (NumPassesRun == maxNumPassesToRun - 1 && SILPrintLast &&
187+ maxNumSubpassesToRun == UINT_MAX && !isMandatory)
188+ return true ;
189+
182190 if (F && !isFunctionSelectedForPrinting (F))
183191 return false ;
184192
@@ -201,7 +209,10 @@ static bool doPrintBefore(SILTransform *T, SILFunction *F) {
201209 return false ;
202210}
203211
204- static bool doPrintAfter (SILTransform *T, SILFunction *F, bool PassChangedSIL) {
212+ bool SILPassManager::doPrintAfter (SILTransform *T, SILFunction *F, bool PassChangedSIL) {
213+ if (NumPassesRun == maxNumPassesToRun - 1 && SILPrintLast && !isMandatory)
214+ return true ;
215+
205216 if (F && !isFunctionSelectedForPrinting (F))
206217 return false ;
207218
@@ -316,6 +327,22 @@ SILPassManager::SILPassManager(SILModule *M, bool isMandatory,
316327 Analyses.push_back (create##NAME##Analysis (Mod));
317328#include " swift/SILOptimizer/Analysis/Analysis.def"
318329
330+ if (!SILNumOptPassesToRun.empty ()) {
331+ StringRef countsStr = SILNumOptPassesToRun;
332+ bool validFormat = true ;
333+ if (countsStr.consumeInteger (10 , maxNumPassesToRun))
334+ validFormat = false ;
335+ if (countsStr.startswith (" ." )) {
336+ countsStr = countsStr.drop_front (1 );
337+ if (countsStr.consumeInteger (10 , maxNumSubpassesToRun))
338+ validFormat = false ;
339+ }
340+ if (!validFormat || !countsStr.empty ()) {
341+ llvm::errs () << " error: wrong format of -sil-opt-pass-count option\n " ;
342+ exit (1 );
343+ }
344+ }
345+
319346 for (SILAnalysis *A : Analyses) {
320347 A->initialize (this );
321348 }
@@ -329,7 +356,27 @@ SILPassManager::SILPassManager(SILModule *M, bool isMandatory,
329356bool SILPassManager::continueTransforming () {
330357 if (isMandatory)
331358 return true ;
332- return NumPassesRun < SILNumOptPassesToRun;
359+ return NumPassesRun < maxNumPassesToRun;
360+ }
361+
362+ bool SILPassManager::continueWithNextSubpassRun (SILInstruction *forInst,
363+ SILFunction *function,
364+ SILTransform *trans) {
365+ if (isMandatory)
366+ return true ;
367+ if (NumPassesRun != maxNumPassesToRun - 1 )
368+ return true ;
369+
370+ unsigned subPass = numSubpassesRun++;
371+
372+ if (subPass == maxNumSubpassesToRun - 1 && SILPrintLast) {
373+ dumpPassInfo (" *** SIL function before " , trans, function);
374+ if (forInst) {
375+ llvm::dbgs () << " *** sub-pass " << subPass << " for " << *forInst;
376+ }
377+ function->dump (getOptions ().EmitVerboseSIL );
378+ }
379+ return subPass < maxNumSubpassesToRun;
333380}
334381
335382bool SILPassManager::analysesUnlocked () {
@@ -359,24 +406,20 @@ static bool breakBeforeRunning(StringRef fnName, SILFunctionTransform *SFT) {
359406}
360407
361408void SILPassManager::dumpPassInfo (const char *Title, SILTransform *Tr,
362- SILFunction *F) {
363- llvm::dbgs () << " " << Title << " #" << NumPassesRun << " , stage "
364- << StageName << " , pass : " << Tr->getID ()
365- << " (" << Tr->getTag () << " )" ;
409+ SILFunction *F, int passIdx) {
410+ llvm::dbgs () << " " << Title << " #" << NumPassesRun
411+ << " , stage " << StageName << " , pass" ;
412+ if (passIdx >= 0 )
413+ llvm::dbgs () << ' ' << passIdx;
414+ llvm::dbgs () << " : " << Tr->getID () << " (" << Tr->getTag () << " )" ;
366415 if (F)
367416 llvm::dbgs () << " , Function: " << F->getName ();
368417 llvm::dbgs () << ' \n ' ;
369418}
370419
371420void SILPassManager::dumpPassInfo (const char *Title, unsigned TransIdx,
372421 SILFunction *F) {
373- SILTransform *Tr = Transformations[TransIdx];
374- llvm::dbgs () << " " << Title << " #" << NumPassesRun << " , stage "
375- << StageName << " , pass " << TransIdx << " : " << Tr->getID ()
376- << " (" << Tr->getTag () << " )" ;
377- if (F)
378- llvm::dbgs () << " , Function: " << F->getName ();
379- llvm::dbgs () << ' \n ' ;
422+ dumpPassInfo (Title, Transformations[TransIdx], F, (int )TransIdx);
380423}
381424
382425bool SILPassManager::isMandatoryFunctionPass (SILFunctionTransform *sft) {
@@ -451,6 +494,7 @@ void SILPassManager::runPassOnFunction(unsigned TransIdx, SILFunction *F) {
451494 updateSILModuleStatsBeforeTransform (F->getModule (), SFT, *this , NumPassesRun);
452495
453496 CurrentPassHasInvalidated = false ;
497+ numSubpassesRun = 0 ;
454498
455499 auto MatchFun = [&](const std::string &Str) -> bool {
456500 return SFT->getTag ().contains (Str) || SFT->getID ().contains (Str);
@@ -623,6 +667,7 @@ void SILPassManager::runModulePass(unsigned TransIdx) {
623667 updateSILModuleStatsBeforeTransform (*Mod, SMT, *this , NumPassesRun);
624668
625669 CurrentPassHasInvalidated = false ;
670+ numSubpassesRun = 0 ;
626671
627672 if (SILPrintPassName)
628673 dumpPassInfo (" Run module pass" , TransIdx);
0 commit comments