@@ -193,6 +193,64 @@ PassManagerBuilder::~PassManagerBuilder() {
193
193
delete Inliner;
194
194
}
195
195
196
+ // / Set of global extensions, automatically added as part of the standard set.
197
+ static ManagedStatic<
198
+ SmallVector<std::tuple<PassManagerBuilder::ExtensionPointTy,
199
+ PassManagerBuilder::ExtensionFn,
200
+ PassManagerBuilder::GlobalExtensionID>,
201
+ 8 >>
202
+ GlobalExtensions;
203
+ static PassManagerBuilder::GlobalExtensionID GlobalExtensionsCounter;
204
+
205
+ // / Check if GlobalExtensions is constructed and not empty.
206
+ // / Since GlobalExtensions is a managed static, calling 'empty()' will trigger
207
+ // / the construction of the object.
208
+ static bool GlobalExtensionsNotEmpty () {
209
+ return GlobalExtensions.isConstructed () && !GlobalExtensions->empty ();
210
+ }
211
+
212
+ PassManagerBuilder::GlobalExtensionID
213
+ PassManagerBuilder::addGlobalExtension (PassManagerBuilder::ExtensionPointTy Ty,
214
+ PassManagerBuilder::ExtensionFn Fn) {
215
+ auto ExtensionID = GlobalExtensionsCounter++;
216
+ GlobalExtensions->push_back (std::make_tuple (Ty, std::move (Fn), ExtensionID));
217
+ return ExtensionID;
218
+ }
219
+
220
+ void PassManagerBuilder::removeGlobalExtension (
221
+ PassManagerBuilder::GlobalExtensionID ExtensionID) {
222
+ // RegisterStandardPasses may try to call this function after GlobalExtensions
223
+ // has already been destroyed; doing so should not generate an error.
224
+ if (!GlobalExtensions.isConstructed ())
225
+ return ;
226
+
227
+ auto GlobalExtension =
228
+ llvm::find_if (*GlobalExtensions, [ExtensionID](const auto &elem) {
229
+ return std::get<2 >(elem) == ExtensionID;
230
+ });
231
+ assert (GlobalExtension != GlobalExtensions->end () &&
232
+ " The extension ID to be removed should always be valid." );
233
+
234
+ GlobalExtensions->erase (GlobalExtension);
235
+ }
236
+
237
+ void PassManagerBuilder::addExtension (ExtensionPointTy Ty, ExtensionFn Fn) {
238
+ Extensions.push_back (std::make_pair (Ty, std::move (Fn)));
239
+ }
240
+
241
+ void PassManagerBuilder::addExtensionsToPM (ExtensionPointTy ETy,
242
+ legacy::PassManagerBase &PM) const {
243
+ if (GlobalExtensionsNotEmpty ()) {
244
+ for (auto &Ext : *GlobalExtensions) {
245
+ if (std::get<0 >(Ext) == ETy)
246
+ std::get<1 >(Ext)(*this , PM);
247
+ }
248
+ }
249
+ for (const auto &[PT, Fn] : Extensions)
250
+ if (PT == ETy)
251
+ Fn (*this , PM);
252
+ }
253
+
196
254
void PassManagerBuilder::addInitialAliasAnalysisPasses (
197
255
legacy::PassManagerBase &PM) const {
198
256
switch (UseCFLAA) {
@@ -219,6 +277,8 @@ void PassManagerBuilder::addInitialAliasAnalysisPasses(
219
277
220
278
void PassManagerBuilder::populateFunctionPassManager (
221
279
legacy::FunctionPassManager &FPM) {
280
+ addExtensionsToPM (EP_EarlyAsPossible, FPM);
281
+
222
282
// Add LibraryInfo if we have some.
223
283
if (LibraryInfo)
224
284
FPM.add (new TargetLibraryInfoWrapperPass (*LibraryInfo));
@@ -281,6 +341,7 @@ void PassManagerBuilder::addFunctionSimplificationPasses(
281
341
MPM.add (createInstructionCombiningPass ());
282
342
if (SizeLevel == 0 && !DisableLibCallsShrinkWrap)
283
343
MPM.add (createLibCallsShrinkWrapPass ());
344
+ addExtensionsToPM (EP_Peephole, MPM);
284
345
285
346
// TODO: Investigate the cost/benefit of tail call elimination on debugging.
286
347
if (OptLevel > 1 )
@@ -330,6 +391,7 @@ void PassManagerBuilder::addFunctionSimplificationPasses(
330
391
}
331
392
MPM.add (createLoopIdiomPass ()); // Recognize idioms like memset.
332
393
MPM.add (createIndVarSimplifyPass ()); // Canonicalize indvars
394
+ addExtensionsToPM (EP_LateLoopOptimizations, MPM);
333
395
MPM.add (createLoopDeletionPass ()); // Delete dead loops
334
396
335
397
if (EnableLoopInterchange)
@@ -338,6 +400,7 @@ void PassManagerBuilder::addFunctionSimplificationPasses(
338
400
// Unroll small loops and perform peeling.
339
401
MPM.add (createSimpleLoopUnrollPass (OptLevel, DisableUnrollLoops,
340
402
ForgetAllSCEVInLoopUnroll));
403
+ addExtensionsToPM (EP_LoopOptimizerEnd, MPM);
341
404
// This ends the loop pass pipelines.
342
405
343
406
// Break up allocas that may now be splittable after loop unrolling.
@@ -361,6 +424,7 @@ void PassManagerBuilder::addFunctionSimplificationPasses(
361
424
// Run instcombine after redundancy elimination to exploit opportunities
362
425
// opened up by them.
363
426
MPM.add (createInstructionCombiningPass ());
427
+ addExtensionsToPM (EP_Peephole, MPM);
364
428
if (OptLevel > 1 ) {
365
429
if (EnableDFAJumpThreading && SizeLevel == 0 )
366
430
MPM.add (createDFAJumpThreadingPass ());
@@ -378,6 +442,8 @@ void PassManagerBuilder::addFunctionSimplificationPasses(
378
442
/* AllowSpeculation=*/ true ));
379
443
}
380
444
445
+ addExtensionsToPM (EP_ScalarOptimizerLate, MPM);
446
+
381
447
if (RerollLoops)
382
448
MPM.add (createLoopRerollPass ());
383
449
@@ -386,6 +452,7 @@ void PassManagerBuilder::addFunctionSimplificationPasses(
386
452
SimplifyCFGOptions ().hoistCommonInsts (true ).sinkCommonInsts (true )));
387
453
// Clean up after everything.
388
454
MPM.add (createInstructionCombiningPass ());
455
+ addExtensionsToPM (EP_Peephole, MPM);
389
456
}
390
457
391
458
// / FIXME: Should LTO cause any differences to this set of passes?
@@ -469,6 +536,7 @@ void PassManagerBuilder::addVectorPasses(legacy::PassManagerBase &PM,
469
536
PM.add (createVectorCombinePass ());
470
537
471
538
if (!IsFullLTO) {
539
+ addExtensionsToPM (EP_Peephole, PM);
472
540
PM.add (createInstructionCombiningPass ());
473
541
474
542
if (EnableUnrollAndJam && !DisableUnrollLoops) {
@@ -527,6 +595,10 @@ void PassManagerBuilder::populateModulePassManager(
527
595
// builds. The function merging pass is
528
596
if (MergeFunctions)
529
597
MPM.add (createMergeFunctionsPass ());
598
+ else if (GlobalExtensionsNotEmpty () || !Extensions.empty ())
599
+ MPM.add (createBarrierNoopPass ());
600
+
601
+ addExtensionsToPM (EP_EnabledOnOptLevel0, MPM);
530
602
531
603
MPM.add (createAnnotationRemarksLegacyPass ());
532
604
return ;
@@ -545,6 +617,8 @@ void PassManagerBuilder::populateModulePassManager(
545
617
if (AttributorRun & AttributorRunOption::MODULE)
546
618
MPM.add (createAttributorLegacyPass ());
547
619
620
+ addExtensionsToPM (EP_ModuleOptimizerEarly, MPM);
621
+
548
622
if (OptLevel > 2 )
549
623
MPM.add (createCallSiteSplittingPass ());
550
624
@@ -562,6 +636,7 @@ void PassManagerBuilder::populateModulePassManager(
562
636
MPM.add (createDeadArgEliminationPass ()); // Dead argument elimination
563
637
564
638
MPM.add (createInstructionCombiningPass ()); // Clean up after IPCP & DAE
639
+ addExtensionsToPM (EP_Peephole, MPM);
565
640
MPM.add (
566
641
createCFGSimplificationPass (SimplifyCFGOptions ().convertSwitchRangeToICmp (
567
642
true ))); // Clean up after IPCP & DAE
@@ -590,6 +665,7 @@ void PassManagerBuilder::populateModulePassManager(
590
665
591
666
MPM.add (createPostOrderFunctionAttrsLegacyPass ());
592
667
668
+ addExtensionsToPM (EP_CGSCCOptimizerLate, MPM);
593
669
addFunctionSimplificationPasses (MPM);
594
670
595
671
// FIXME: This is a HACK! The inliner pass above implicitly creates a CGSCC
@@ -664,6 +740,8 @@ void PassManagerBuilder::populateModulePassManager(
664
740
MPM.add (createEarlyCSEPass (false ));
665
741
}
666
742
743
+ addExtensionsToPM (EP_VectorizerStart, MPM);
744
+
667
745
// Re-rotate loops in all our loop nests. These may have fallout out of
668
746
// rotated form due to GVN or other transformations, and the vectorizer relies
669
747
// on the rotated form. Disable header duplication at -Oz.
@@ -716,6 +794,8 @@ void PassManagerBuilder::populateModulePassManager(
716
794
MPM.add (createCFGSimplificationPass (
717
795
SimplifyCFGOptions ().convertSwitchRangeToICmp (true )));
718
796
797
+ addExtensionsToPM (EP_OptimizerLast, MPM);
798
+
719
799
MPM.add (createAnnotationRemarksLegacyPass ());
720
800
}
721
801
0 commit comments