Index: include/llvm/Target/TargetMachine.h =================================================================== --- include/llvm/Target/TargetMachine.h +++ include/llvm/Target/TargetMachine.h @@ -217,6 +217,11 @@ /// uses this to answer queries about the IR. virtual TargetIRAnalysis getTargetIRAnalysis(); + /// Add target-specific function passes that should be run as early as + /// possible in the optimization pipeline. Most TargetMachines have no such + /// passes. + virtual void addEarlyAsPossiblePasses(PassManagerBase &) {} + /// These enums are meant to be passed into addPassesToEmitFile to indicate /// what type of file to emit, and returned by it to indicate what type of /// file could actually be made. Index: tools/opt/opt.cpp =================================================================== --- tools/opt/opt.cpp +++ tools/opt/opt.cpp @@ -230,7 +230,8 @@ /// OptLevel - Optimization Level static void AddOptimizationPasses(legacy::PassManagerBase &MPM, legacy::FunctionPassManager &FPM, - unsigned OptLevel, unsigned SizeLevel) { + TargetMachine *TM, unsigned OptLevel, + unsigned SizeLevel) { if (!NoVerify || VerifyEach) FPM.add(createVerifierPass()); // Verify that input is correct @@ -260,6 +261,14 @@ Builder.SLPVectorize = DisableSLPVectorization ? false : OptLevel > 1 && SizeLevel < 2; + // Add target-specific passes that need to run as early as possible. + if (TM) + Builder.addExtension( + PassManagerBuilder::EP_EarlyAsPossible, + [&](const PassManagerBuilder &, legacy::PassManagerBase &PM) { + TM->addEarlyAsPossiblePasses(PM); + }); + Builder.populateFunctionPassManager(FPM); Builder.populateModulePassManager(MPM); } @@ -518,27 +527,27 @@ } if (OptLevelO1 && OptLevelO1.getPosition() < PassList.getPosition(i)) { - AddOptimizationPasses(Passes, *FPasses, 1, 0); + AddOptimizationPasses(Passes, *FPasses, TM.get(), 1, 0); OptLevelO1 = false; } if (OptLevelO2 && OptLevelO2.getPosition() < PassList.getPosition(i)) { - AddOptimizationPasses(Passes, *FPasses, 2, 0); + AddOptimizationPasses(Passes, *FPasses, TM.get(), 2, 0); OptLevelO2 = false; } if (OptLevelOs && OptLevelOs.getPosition() < PassList.getPosition(i)) { - AddOptimizationPasses(Passes, *FPasses, 2, 1); + AddOptimizationPasses(Passes, *FPasses, TM.get(), 2, 1); OptLevelOs = false; } if (OptLevelOz && OptLevelOz.getPosition() < PassList.getPosition(i)) { - AddOptimizationPasses(Passes, *FPasses, 2, 2); + AddOptimizationPasses(Passes, *FPasses, TM.get(), 2, 2); OptLevelOz = false; } if (OptLevelO3 && OptLevelO3.getPosition() < PassList.getPosition(i)) { - AddOptimizationPasses(Passes, *FPasses, 3, 0); + AddOptimizationPasses(Passes, *FPasses, TM.get(), 3, 0); OptLevelO3 = false; } @@ -590,19 +599,19 @@ } if (OptLevelO1) - AddOptimizationPasses(Passes, *FPasses, 1, 0); + AddOptimizationPasses(Passes, *FPasses, TM.get(), 1, 0); if (OptLevelO2) - AddOptimizationPasses(Passes, *FPasses, 2, 0); + AddOptimizationPasses(Passes, *FPasses, TM.get(), 2, 0); if (OptLevelOs) - AddOptimizationPasses(Passes, *FPasses, 2, 1); + AddOptimizationPasses(Passes, *FPasses, TM.get(), 2, 1); if (OptLevelOz) - AddOptimizationPasses(Passes, *FPasses, 2, 2); + AddOptimizationPasses(Passes, *FPasses, TM.get(), 2, 2); if (OptLevelO3) - AddOptimizationPasses(Passes, *FPasses, 3, 0); + AddOptimizationPasses(Passes, *FPasses, TM.get(), 3, 0); if (OptLevelO1 || OptLevelO2 || OptLevelOs || OptLevelOz || OptLevelO3) { FPasses->doInitialization();