Skip to content

Commit 4200aa9

Browse files
Unify and split the pass pipeline (#49798)
Unify and split the pass pipeline
1 parent 2e76fc4 commit 4200aa9

File tree

1 file changed

+114
-160
lines changed

1 file changed

+114
-160
lines changed

src/pipeline.cpp

Lines changed: 114 additions & 160 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,9 @@ namespace {
208208
// .sinkCommonInsts(true)
209209
;
210210
}
211+
#if JL_LLVM_VERSION < 150000
212+
#define LICMOptions()
213+
#endif
211214

212215
// At any given time exactly one of each pair of overloads is strictly unused
213216
#ifdef _COMPILER_GCC_
@@ -323,8 +326,7 @@ namespace {
323326

324327
#define JULIA_PASS(ADD_PASS) if (!options.llvm_only) { ADD_PASS; } else do { } while (0)
325328

326-
//Use for O1 and below
327-
static void buildBasicPipeline(ModulePassManager &MPM, PassBuilder *PB, OptimizationLevel O, OptimizationOptions options) JL_NOTSAFEPOINT {
329+
static void buildEarlySimplificationPipeline(ModulePassManager &MPM, PassBuilder *PB, OptimizationLevel O, const OptimizationOptions &options) JL_NOTSAFEPOINT {
328330
#ifdef JL_DEBUG_BUILD
329331
addVerificationPasses(MPM, options.llvm_only);
330332
#endif
@@ -333,118 +335,32 @@ static void buildBasicPipeline(ModulePassManager &MPM, PassBuilder *PB, Optimiza
333335
invokePipelineStartCallbacks(MPM, PB, O);
334336
MPM.addPass(Annotation2MetadataPass());
335337
MPM.addPass(ConstantMergePass());
336-
if (!options.dump_native) {
337-
JULIA_PASS(MPM.addPass(CPUFeaturesPass()));
338-
if (O.getSpeedupLevel() > 0) {
339-
MPM.addPass(createModuleToFunctionPassAdaptor(InstSimplifyPass()));
340-
}
341-
}
342338
{
343339
FunctionPassManager FPM;
344340
FPM.addPass(LowerExpectIntrinsicPass());
341+
if (O.getSpeedupLevel() >= 2) {
342+
JULIA_PASS(FPM.addPass(PropagateJuliaAddrspacesPass()));
343+
}
345344
FPM.addPass(SimplifyCFGPass(basicSimplifyCFGOptions()));
346-
if (O.getSpeedupLevel() > 0) {
345+
if (O.getSpeedupLevel() >= 1) {
346+
FPM.addPass(DCEPass());
347347
FPM.addPass(SROAPass());
348-
FPM.addPass(InstCombinePass());
349-
FPM.addPass(EarlyCSEPass());
350348
}
351-
FPM.addPass(MemCpyOptPass());
352349
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
353350
}
354351
invokeEarlySimplificationCallbacks(MPM, PB, O);
355-
MPM.addPass(AlwaysInlinerPass());
356-
{
357-
CGSCCPassManager CGPM;
358-
invokeCGSCCCallbacks(CGPM, PB, O);
359-
MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
360-
}
361-
invokeOptimizerEarlyCallbacks(MPM, PB, O);
362-
JULIA_PASS(MPM.addPass(LowerSIMDLoopPass()));
363-
{
364-
FunctionPassManager FPM;
365-
{
366-
LoopPassManager LPM;
367-
invokeLateLoopOptimizationCallbacks(LPM, PB, O);
368-
invokeLoopOptimizerEndCallbacks(LPM, PB, O);
369-
FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM)));
370-
}
371-
invokeScalarOptimizerCallbacks(FPM, PB, O);
372-
invokeVectorizerCallbacks(FPM, PB, O);
373-
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
374-
}
375-
if (options.lower_intrinsics) {
376-
//TODO no barrier pass?
377-
{
378-
FunctionPassManager FPM;
379-
JULIA_PASS(FPM.addPass(LowerExcHandlersPass()));
380-
JULIA_PASS(FPM.addPass(GCInvariantVerifierPass(false)));
381-
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
382-
}
383-
JULIA_PASS(MPM.addPass(RemoveNIPass()));
384-
JULIA_PASS(MPM.addPass(createModuleToFunctionPassAdaptor(LateLowerGCPass())));
385-
JULIA_PASS(MPM.addPass(FinalLowerGCPass()));
386-
JULIA_PASS(MPM.addPass(LowerPTLSPass(options.dump_native)));
387-
} else {
388-
JULIA_PASS(MPM.addPass(RemoveNIPass()));
389-
}
390-
JULIA_PASS(MPM.addPass(LowerSIMDLoopPass())); // TODO why do we do this twice
391-
if (options.dump_native) {
392-
JULIA_PASS(MPM.addPass(MultiVersioningPass(options.external_use)));
393-
JULIA_PASS(MPM.addPass(CPUFeaturesPass()));
394-
if (O.getSpeedupLevel() > 0) {
395-
FunctionPassManager FPM;
396-
FPM.addPass(InstSimplifyPass());
397-
FPM.addPass(SimplifyCFGPass(basicSimplifyCFGOptions()));
398-
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
399-
}
400-
}
401-
invokeOptimizerLastCallbacks(MPM, PB, O);
402-
{
403-
FunctionPassManager FPM;
404-
FPM.addPass(WarnMissedTransformationsPass());
405-
FPM.addPass(AnnotationRemarksPass());
406-
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
407-
}
408-
addSanitizerPasses(MPM, O);
409-
JULIA_PASS(MPM.addPass(createModuleToFunctionPassAdaptor(DemoteFloat16Pass())));
410352
}
411353

412-
//Use for O2 and above
413-
static void buildFullPipeline(ModulePassManager &MPM, PassBuilder *PB, OptimizationLevel O, OptimizationOptions options) JL_NOTSAFEPOINT {
414-
#ifdef JL_DEBUG_BUILD
415-
addVerificationPasses(MPM, options.llvm_only);
416-
#endif
417-
// Place after verification in case we want to force it anyways
418-
MPM.addPass(ForceFunctionAttrsPass());
419-
invokePipelineStartCallbacks(MPM, PB, O);
420-
MPM.addPass(Annotation2MetadataPass());
421-
MPM.addPass(ConstantMergePass());
422-
{
423-
FunctionPassManager FPM;
424-
FPM.addPass(LowerExpectIntrinsicPass());
425-
JULIA_PASS(FPM.addPass(PropagateJuliaAddrspacesPass()));
426-
//TODO consider not using even basic simplification
427-
//options here, and adding a run of CVP to take advantage
428-
//of the unsimplified codegen information (e.g. known
429-
//zeros or ones)
430-
FPM.addPass(SimplifyCFGPass(basicSimplifyCFGOptions()));
431-
FPM.addPass(DCEPass());
432-
FPM.addPass(SROAPass());
433-
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
434-
}
435-
invokeEarlySimplificationCallbacks(MPM, PB, O);
436-
MPM.addPass(AlwaysInlinerPass());
354+
static void buildEarlyOptimizerPipeline(ModulePassManager &MPM, PassBuilder *PB, OptimizationLevel O, const OptimizationOptions &options) JL_NOTSAFEPOINT {
437355
invokeOptimizerEarlyCallbacks(MPM, PB, O);
438356
{
439357
CGSCCPassManager CGPM;
440358
invokeCGSCCCallbacks(CGPM, PB, O);
441-
{
359+
if (O.getSpeedupLevel() >= 2) {
442360
FunctionPassManager FPM;
443361
JULIA_PASS(FPM.addPass(AllocOptPass()));
444362
FPM.addPass(Float2IntPass());
445363
FPM.addPass(LowerConstantIntrinsicsPass());
446-
FPM.addPass(InstCombinePass());
447-
FPM.addPass(SimplifyCFGPass(basicSimplifyCFGOptions()));
448364
CGPM.addPass(createCGSCCToFunctionPassAdaptor(std::move(FPM)));
449365
}
450366
MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(std::move(CGPM)));
@@ -453,53 +369,68 @@ static void buildFullPipeline(ModulePassManager &MPM, PassBuilder *PB, Optimizat
453369
JULIA_PASS(MPM.addPass(MultiVersioningPass(options.external_use)));
454370
}
455371
JULIA_PASS(MPM.addPass(CPUFeaturesPass()));
456-
{
372+
if (O.getSpeedupLevel() >= 1) {
457373
FunctionPassManager FPM;
458-
FPM.addPass(SROAPass());
459-
// SROA can duplicate PHI nodes which can block LowerSIMD
460-
FPM.addPass(InstCombinePass());
461-
FPM.addPass(JumpThreadingPass());
462-
FPM.addPass(CorrelatedValuePropagationPass());
463-
FPM.addPass(ReassociatePass());
464-
FPM.addPass(EarlyCSEPass());
465-
JULIA_PASS(FPM.addPass(AllocOptPass()));
374+
if (O.getSpeedupLevel() >= 2) {
375+
FPM.addPass(SROAPass());
376+
// SROA can duplicate PHI nodes which can block LowerSIMD
377+
FPM.addPass(InstCombinePass());
378+
FPM.addPass(JumpThreadingPass());
379+
FPM.addPass(CorrelatedValuePropagationPass());
380+
FPM.addPass(ReassociatePass());
381+
FPM.addPass(EarlyCSEPass());
382+
JULIA_PASS(FPM.addPass(AllocOptPass()));
383+
} else { // if (O.getSpeedupLevel() >= 1) (exactly)
384+
FPM.addPass(InstCombinePass());
385+
FPM.addPass(EarlyCSEPass());
386+
}
466387
invokePeepholeEPCallbacks(FPM, PB, O);
467388
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
468389
}
469-
JULIA_PASS(MPM.addPass(LowerSIMDLoopPass()));
390+
}
391+
392+
static void buildLoopOptimizerPipeline(FunctionPassManager &FPM, PassBuilder *PB, OptimizationLevel O, const OptimizationOptions &options) JL_NOTSAFEPOINT {
470393
{
471-
FunctionPassManager FPM;
472-
{
473-
LoopPassManager LPM1, LPM2;
474-
LPM1.addPass(LoopRotatePass());
475-
invokeLateLoopOptimizationCallbacks(LPM1, PB, O);
476-
//We don't know if the loop callbacks support MSSA
477-
FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM1), /*UseMemorySSA = */false));
478-
#if JL_LLVM_VERSION < 150000
479-
#define LICMOptions()
480-
#endif
481-
LPM2.addPass(LICMPass(LICMOptions()));
482-
JULIA_PASS(LPM2.addPass(JuliaLICMPass()));
483-
LPM2.addPass(SimpleLoopUnswitchPass(/*NonTrivial*/true, true));
484-
LPM2.addPass(LICMPass(LICMOptions()));
485-
JULIA_PASS(LPM2.addPass(JuliaLICMPass()));
486-
//LICM needs MemorySSA now, so we must use it
487-
FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM2), /*UseMemorySSA = */true));
394+
LoopPassManager LPM;
395+
if (O.getSpeedupLevel() >= 2) {
396+
LPM.addPass(LoopRotatePass());
488397
}
398+
invokeLateLoopOptimizationCallbacks(LPM, PB, O);
399+
//We don't know if the loop callbacks support MSSA
400+
FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM), /*UseMemorySSA = */false));
401+
}
402+
if (O.getSpeedupLevel() >= 2) {
403+
LoopPassManager LPM;
404+
LPM.addPass(LICMPass(LICMOptions()));
405+
LPM.addPass(JuliaLICMPass());
406+
LPM.addPass(SimpleLoopUnswitchPass(/*NonTrivial*/true, true));
407+
LPM.addPass(LICMPass(LICMOptions()));
408+
LPM.addPass(JuliaLICMPass());
409+
//LICM needs MemorySSA now, so we must use it
410+
FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM), /*UseMemorySSA = */true));
411+
}
412+
if (O.getSpeedupLevel() >= 2) {
489413
FPM.addPass(IRCEPass());
490-
{
491-
LoopPassManager LPM;
414+
}
415+
{
416+
LoopPassManager LPM;
417+
if (O.getSpeedupLevel() >= 2) {
492418
LPM.addPass(LoopInstSimplifyPass());
493419
LPM.addPass(LoopIdiomRecognizePass());
494420
LPM.addPass(IndVarSimplifyPass());
495421
LPM.addPass(LoopDeletionPass());
496422
// This unroll will only unroll loops when the trip count is known and small,
497423
// so that no loop remains
498424
LPM.addPass(LoopFullUnrollPass());
499-
invokeLoopOptimizerEndCallbacks(LPM, PB, O);
500-
//We don't know if the loop end callbacks support MSSA
501-
FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM), /*UseMemorySSA = */false));
502425
}
426+
invokeLoopOptimizerEndCallbacks(LPM, PB, O);
427+
//We don't know if the loop end callbacks support MSSA
428+
FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM), /*UseMemorySSA = */false));
429+
}
430+
}
431+
432+
static void buildScalarOptimizerPipeline(FunctionPassManager &FPM, PassBuilder *PB, OptimizationLevel O, const OptimizationOptions &options) JL_NOTSAFEPOINT {
433+
if (O.getSpeedupLevel() >= 2) {
503434
JULIA_PASS(FPM.addPass(AllocOptPass()));
504435
FPM.addPass(SROAPass());
505436
FPM.addPass(InstSimplifyPass());
@@ -511,9 +442,11 @@ static void buildFullPipeline(ModulePassManager &MPM, PassBuilder *PB, Optimizat
511442
FPM.addPass(IRCEPass());
512443
FPM.addPass(InstCombinePass());
513444
FPM.addPass(JumpThreadingPass());
514-
if (O.getSpeedupLevel() >= 3) {
515-
FPM.addPass(GVNPass());
516-
}
445+
}
446+
if (O.getSpeedupLevel() >= 3) {
447+
FPM.addPass(GVNPass());
448+
}
449+
if (O.getSpeedupLevel() >= 2) {
517450
FPM.addPass(DSEPass());
518451
invokePeepholeEPCallbacks(FPM, PB, O);
519452
FPM.addPass(SimplifyCFGPass(aggressiveSimplifyCFGOptions()));
@@ -525,24 +458,28 @@ static void buildFullPipeline(ModulePassManager &MPM, PassBuilder *PB, Optimizat
525458
FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM)));
526459
}
527460
FPM.addPass(LoopDistributePass());
528-
FPM.addPass(InjectTLIMappings());
529-
invokeScalarOptimizerCallbacks(FPM, PB, O);
530-
//TODO look into loop vectorize options
531-
FPM.addPass(LoopVectorizePass());
532-
FPM.addPass(LoopLoadEliminationPass());
533-
FPM.addPass(InstCombinePass());
534-
FPM.addPass(SimplifyCFGPass(aggressiveSimplifyCFGOptions()));
535-
FPM.addPass(SLPVectorizerPass());
536-
invokeVectorizerCallbacks(FPM, PB, O);
537-
FPM.addPass(VectorCombinePass());
538-
FPM.addPass(ADCEPass());
539-
//TODO add BDCEPass here?
540-
// This unroll will unroll vectorized loops
541-
// as well as loops that we tried but failed to vectorize
542-
FPM.addPass(LoopUnrollPass(LoopUnrollOptions(O.getSpeedupLevel(), /*OnlyWhenForced = */ false, /*ForgetSCEV = */false)));
543-
FPM.addPass(WarnMissedTransformationsPass());
544-
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
545461
}
462+
invokeScalarOptimizerCallbacks(FPM, PB, O);
463+
}
464+
465+
static void buildVectorPipeline(FunctionPassManager &FPM, PassBuilder *PB, OptimizationLevel O, const OptimizationOptions &options) JL_NOTSAFEPOINT {
466+
//TODO look into loop vectorize options
467+
FPM.addPass(InjectTLIMappings());
468+
FPM.addPass(LoopVectorizePass());
469+
FPM.addPass(LoopLoadEliminationPass());
470+
FPM.addPass(InstCombinePass());
471+
FPM.addPass(SimplifyCFGPass(aggressiveSimplifyCFGOptions()));
472+
FPM.addPass(SLPVectorizerPass());
473+
invokeVectorizerCallbacks(FPM, PB, O);
474+
FPM.addPass(VectorCombinePass());
475+
FPM.addPass(ADCEPass());
476+
//TODO add BDCEPass here?
477+
// This unroll will unroll vectorized loops
478+
// as well as loops that we tried but failed to vectorize
479+
FPM.addPass(LoopUnrollPass(LoopUnrollOptions(O.getSpeedupLevel(), /*OnlyWhenForced = */ false, /*ForgetSCEV = */false)));
480+
}
481+
482+
static void buildIntrinsicLoweringPipeline(ModulePassManager &MPM, PassBuilder *PB, OptimizationLevel O, const OptimizationOptions &options) JL_NOTSAFEPOINT {
546483
if (options.lower_intrinsics) {
547484
//TODO barrier pass?
548485
{
@@ -556,15 +493,15 @@ static void buildFullPipeline(ModulePassManager &MPM, PassBuilder *PB, Optimizat
556493
JULIA_PASS(MPM.addPass(RemoveNIPass()));
557494
JULIA_PASS(MPM.addPass(createModuleToFunctionPassAdaptor(LateLowerGCPass())));
558495
JULIA_PASS(MPM.addPass(FinalLowerGCPass()));
559-
{
496+
if (O.getSpeedupLevel() >= 2) {
560497
FunctionPassManager FPM;
561498
FPM.addPass(GVNPass());
562499
FPM.addPass(SCCPPass());
563500
FPM.addPass(DCEPass());
564501
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
565502
}
566503
JULIA_PASS(MPM.addPass(LowerPTLSPass(options.dump_native)));
567-
{
504+
if (O.getSpeedupLevel() >= 1) {
568505
FunctionPassManager FPM;
569506
FPM.addPass(InstCombinePass());
570507
FPM.addPass(SimplifyCFGPass(aggressiveSimplifyCFGOptions()));
@@ -573,7 +510,10 @@ static void buildFullPipeline(ModulePassManager &MPM, PassBuilder *PB, Optimizat
573510
} else {
574511
JULIA_PASS(MPM.addPass(RemoveNIPass()));
575512
}
576-
{
513+
}
514+
515+
static void buildCleanupPipeline(ModulePassManager &MPM, PassBuilder *PB, OptimizationLevel O, const OptimizationOptions &options) JL_NOTSAFEPOINT {
516+
if (O.getSpeedupLevel() >= 2) {
577517
FunctionPassManager FPM;
578518
JULIA_PASS(FPM.addPass(CombineMulAddPass()));
579519
FPM.addPass(DivRemPairsPass());
@@ -585,9 +525,30 @@ static void buildFullPipeline(ModulePassManager &MPM, PassBuilder *PB, Optimizat
585525
{
586526
FunctionPassManager FPM;
587527
JULIA_PASS(FPM.addPass(DemoteFloat16Pass()));
588-
FPM.addPass(GVNPass());
528+
if (O.getSpeedupLevel() >= 2) {
529+
FPM.addPass(GVNPass());
530+
}
531+
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
532+
}
533+
}
534+
535+
static void buildPipeline(ModulePassManager &MPM, PassBuilder *PB, OptimizationLevel O, const OptimizationOptions &options) JL_NOTSAFEPOINT {
536+
buildEarlySimplificationPipeline(MPM, PB, O, options);
537+
MPM.addPass(AlwaysInlinerPass());
538+
buildEarlyOptimizerPipeline(MPM, PB, O, options);
539+
MPM.addPass(LowerSIMDLoopPass());
540+
{
541+
FunctionPassManager FPM;
542+
buildLoopOptimizerPipeline(FPM, PB, O, options);
543+
buildScalarOptimizerPipeline(FPM, PB, O, options);
544+
if (O.getSpeedupLevel() >= 2) {
545+
buildVectorPipeline(FPM, PB, O, options);
546+
}
547+
FPM.addPass(WarnMissedTransformationsPass());
589548
MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
590549
}
550+
buildIntrinsicLoweringPipeline(MPM, PB, O, options);
551+
buildCleanupPipeline(MPM, PB, O, options);
591552
}
592553

593554
#undef JULIA_PASS
@@ -665,10 +626,7 @@ PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
665626

666627
ModulePassManager createMPM(PassBuilder &PB, OptimizationLevel O, OptimizationOptions options) JL_NOTSAFEPOINT {
667628
ModulePassManager MPM;
668-
if (O.getSpeedupLevel() < 2)
669-
buildBasicPipeline(MPM, &PB, O, options);
670-
else
671-
buildFullPipeline(MPM, &PB, O, options);
629+
buildPipeline(MPM, &PB, O, options);
672630
return MPM;
673631
}
674632
}
@@ -805,11 +763,7 @@ void registerCallbacks(PassBuilder &PB) JL_NOTSAFEPOINT {
805763
auto julia_options = parseJuliaPipelineOptions(Name);
806764
if (julia_options) {
807765
ModulePassManager pipeline;
808-
if (julia_options->first.getSpeedupLevel() < 2) {
809-
buildBasicPipeline(pipeline, nullptr, julia_options->first, julia_options->second);
810-
} else {
811-
buildFullPipeline(pipeline, nullptr, julia_options->first, julia_options->second);
812-
}
766+
buildPipeline(pipeline, nullptr, julia_options->first, julia_options->second);
813767
PM.addPass(std::move(pipeline));
814768
return true;
815769
}

0 commit comments

Comments
 (0)