@@ -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