|
37 | 37 | #include "llvm/IR/Verifier.h"
|
38 | 38 | #include "llvm/InitializePasses.h"
|
39 | 39 | #include "llvm/LTO/LTO.h"
|
| 40 | +#include "llvm/LTO/LTOBackend.h" |
40 | 41 | #include "llvm/LTO/legacy/LTOModule.h"
|
41 | 42 | #include "llvm/LTO/legacy/UpdateCompilerUsed.h"
|
42 | 43 | #include "llvm/Linker/Linker.h"
|
@@ -123,41 +124,29 @@ LTOCodeGenerator::LTOCodeGenerator(LLVMContext &Context)
|
123 | 124 | TheLinker(new Linker(*MergedModule)) {
|
124 | 125 | Context.setDiscardValueNames(LTODiscardValueNames);
|
125 | 126 | Context.enableDebugTypeODRUniquing();
|
126 |
| - initializeLTOPasses(); |
127 | 127 | }
|
128 | 128 |
|
129 | 129 | LTOCodeGenerator::~LTOCodeGenerator() {}
|
130 | 130 |
|
131 |
| -// Initialize LTO passes. Please keep this function in sync with |
132 |
| -// PassManagerBuilder::populateLTOPassManager(), and make sure all LTO |
133 |
| -// passes are initialized. |
134 |
| -void LTOCodeGenerator::initializeLTOPasses() { |
135 |
| - PassRegistry &R = *PassRegistry::getPassRegistry(); |
136 |
| - |
137 |
| - initializeInternalizeLegacyPassPass(R); |
138 |
| - initializeIPSCCPLegacyPassPass(R); |
139 |
| - initializeGlobalOptLegacyPassPass(R); |
140 |
| - initializeConstantMergeLegacyPassPass(R); |
141 |
| - initializeDAHPass(R); |
142 |
| - initializeInstructionCombiningPassPass(R); |
143 |
| - initializeSimpleInlinerPass(R); |
144 |
| - initializePruneEHPass(R); |
145 |
| - initializeGlobalDCELegacyPassPass(R); |
146 |
| - initializeOpenMPOptLegacyPassPass(R); |
147 |
| - initializeArgPromotionPass(R); |
148 |
| - initializeJumpThreadingPass(R); |
149 |
| - initializeSROALegacyPassPass(R); |
150 |
| - initializeAttributorLegacyPassPass(R); |
151 |
| - initializeAttributorCGSCCLegacyPassPass(R); |
152 |
| - initializePostOrderFunctionAttrsLegacyPassPass(R); |
153 |
| - initializeReversePostOrderFunctionAttrsLegacyPassPass(R); |
154 |
| - initializeGlobalsAAWrapperPassPass(R); |
155 |
| - initializeLegacyLICMPassPass(R); |
156 |
| - initializeMergedLoadStoreMotionLegacyPassPass(R); |
157 |
| - initializeGVNLegacyPassPass(R); |
158 |
| - initializeMemCpyOptLegacyPassPass(R); |
159 |
| - initializeDCELegacyPassPass(R); |
160 |
| - initializeCFGSimplifyPassPass(R); |
| 131 | +lto::Config LTOCodeGenerator::toConfig() const { |
| 132 | + lto::Config Conf; |
| 133 | + Conf.CGFileType = FileType; |
| 134 | + Conf.CPU = MCpu; |
| 135 | + Conf.MAttrs = MAttrs; |
| 136 | + Conf.RelocModel = RelocModel; |
| 137 | + Conf.Options = Options; |
| 138 | + Conf.CodeModel = None; |
| 139 | + Conf.StatsFile = LTOStatsFile; |
| 140 | + Conf.OptLevel = OptLevel; |
| 141 | + Conf.Freestanding = Freestanding; |
| 142 | + Conf.PTO.LoopVectorization = OptLevel > 1; |
| 143 | + Conf.PTO.SLPVectorization = OptLevel > 1; |
| 144 | + Conf.DisableVerify = DisableVerify; |
| 145 | + Conf.PreCodeGenPassesHook = [](legacy::PassManager &PM) { |
| 146 | + PM.add(createObjCARCContractPass()); |
| 147 | + }; |
| 148 | + |
| 149 | + return Conf; |
161 | 150 | }
|
162 | 151 |
|
163 | 152 | void LTOCodeGenerator::setAsmUndefinedRefs(LTOModule *Mod) {
|
@@ -268,38 +257,35 @@ bool LTOCodeGenerator::writeMergedModules(StringRef Path) {
|
268 | 257 | bool LTOCodeGenerator::compileOptimizedToFile(const char **Name) {
|
269 | 258 | // make unique temp output file to put generated code
|
270 | 259 | SmallString<128> Filename;
|
271 |
| - int FD; |
272 | 260 |
|
273 |
| - StringRef Extension |
274 |
| - (FileType == CGFT_AssemblyFile ? "s" : "o"); |
| 261 | + auto AddStream = |
| 262 | + [&](size_t Task) -> std::unique_ptr<lto::NativeObjectStream> { |
| 263 | + StringRef Extension(FileType == CGFT_AssemblyFile ? "s" : "o"); |
275 | 264 |
|
276 |
| - std::error_code EC = |
277 |
| - sys::fs::createTemporaryFile("lto-llvm", Extension, FD, Filename); |
278 |
| - if (EC) { |
279 |
| - emitError(EC.message()); |
280 |
| - return false; |
281 |
| - } |
| 265 | + int FD; |
| 266 | + std::error_code EC = |
| 267 | + sys::fs::createTemporaryFile("lto-llvm", Extension, FD, Filename); |
| 268 | + if (EC) |
| 269 | + emitError(EC.message()); |
282 | 270 |
|
283 |
| - // generate object file |
284 |
| - ToolOutputFile objFile(Filename, FD); |
| 271 | + return std::make_unique<lto::NativeObjectStream>( |
| 272 | + std::make_unique<llvm::raw_fd_ostream>(FD, true)); |
| 273 | + }; |
285 | 274 |
|
286 |
| - bool genResult = compileOptimized(&objFile.os()); |
287 |
| - objFile.os().close(); |
288 |
| - if (objFile.os().has_error()) { |
289 |
| - emitError((Twine("could not write object file: ") + Filename + ": " + |
290 |
| - objFile.os().error().message()) |
291 |
| - .str()); |
292 |
| - objFile.os().clear_error(); |
293 |
| - sys::fs::remove(Twine(Filename)); |
294 |
| - return false; |
295 |
| - } |
| 275 | + bool genResult = compileOptimized(AddStream, 1); |
296 | 276 |
|
297 |
| - objFile.keep(); |
298 | 277 | if (!genResult) {
|
299 | 278 | sys::fs::remove(Twine(Filename));
|
300 | 279 | return false;
|
301 | 280 | }
|
302 | 281 |
|
| 282 | + // If statistics were requested, save them to the specified file or |
| 283 | + // print them out after codegen. |
| 284 | + if (StatsFile) |
| 285 | + PrintStatisticsJSON(StatsFile->os()); |
| 286 | + else if (AreStatisticsEnabled()) |
| 287 | + PrintStatistics(); |
| 288 | + |
303 | 289 | NativeObjectPath = Filename.c_str();
|
304 | 290 | *Name = NativeObjectPath.c_str();
|
305 | 291 | return true;
|
@@ -568,57 +554,43 @@ bool LTOCodeGenerator::optimize() {
|
568 | 554 | // Write LTOPostLink flag for passes that require all the modules.
|
569 | 555 | MergedModule->addModuleFlag(Module::Error, "LTOPostLink", 1);
|
570 | 556 |
|
571 |
| - // Instantiate the pass manager to organize the passes. |
572 |
| - legacy::PassManager passes; |
573 |
| - |
574 | 557 | // Add an appropriate DataLayout instance for this module...
|
575 | 558 | MergedModule->setDataLayout(TargetMach->createDataLayout());
|
576 | 559 |
|
577 |
| - passes.add( |
578 |
| - createTargetTransformInfoWrapperPass(TargetMach->getTargetIRAnalysis())); |
579 |
| - |
580 |
| - Triple TargetTriple(TargetMach->getTargetTriple()); |
581 |
| - PassManagerBuilder PMB; |
582 |
| - PMB.LoopVectorize = true; |
583 |
| - PMB.SLPVectorize = true; |
584 |
| - PMB.Inliner = createFunctionInliningPass(); |
585 |
| - PMB.LibraryInfo = new TargetLibraryInfoImpl(TargetTriple); |
586 |
| - if (Freestanding) |
587 |
| - PMB.LibraryInfo->disableAllFunctions(); |
588 |
| - PMB.OptLevel = OptLevel; |
589 |
| - PMB.VerifyInput = !DisableVerify; |
590 |
| - PMB.VerifyOutput = !DisableVerify; |
591 |
| - |
592 |
| - PMB.populateLTOPassManager(passes); |
| 560 | + lto::Config Conf = toConfig(); |
593 | 561 |
|
594 |
| - // Run our queue of passes all at once now, efficiently. |
595 |
| - passes.run(*MergedModule); |
| 562 | + ModuleSummaryIndex CombinedIndex(false); |
| 563 | + TargetMach = createTargetMachine(); |
| 564 | + if (!opt(Conf, TargetMach.get(), 0, *MergedModule, /*IsThinLTO=*/false, |
| 565 | + /*ExportSummary=*/&CombinedIndex, /*ImportSummary=*/nullptr, |
| 566 | + /*CmdArgs*/ std::vector<uint8_t>())) { |
| 567 | + emitError("LTO middle-end optimizations failed"); |
| 568 | + return false; |
| 569 | + } |
596 | 570 |
|
597 | 571 | return true;
|
598 | 572 | }
|
599 | 573 |
|
600 |
| -bool LTOCodeGenerator::compileOptimized(ArrayRef<raw_pwrite_stream *> Out) { |
| 574 | +bool LTOCodeGenerator::compileOptimized(lto::AddStreamFn AddStream, |
| 575 | + unsigned ParallelismLevel) { |
601 | 576 | if (!this->determineTarget())
|
602 | 577 | return false;
|
603 | 578 |
|
604 | 579 | // We always run the verifier once on the merged module. If it has already
|
605 | 580 | // been called in optimize(), this call will return early.
|
606 | 581 | verifyMergedModuleOnce();
|
607 | 582 |
|
608 |
| - legacy::PassManager preCodeGenPasses; |
609 |
| - |
610 |
| - // If the bitcode files contain ARC code and were compiled with optimization, |
611 |
| - // the ObjCARCContractPass must be run, so do it unconditionally here. |
612 |
| - preCodeGenPasses.add(createObjCARCContractPass()); |
613 |
| - preCodeGenPasses.run(*MergedModule); |
614 |
| - |
615 | 583 | // Re-externalize globals that may have been internalized to increase scope
|
616 | 584 | // for splitting
|
617 | 585 | restoreLinkageForExternals();
|
618 | 586 |
|
619 |
| - splitCodeGen( |
620 |
| - *MergedModule, Out, {}, [&]() { return createTargetMachine(); }, FileType, |
621 |
| - ShouldRestoreGlobalsLinkage); |
| 587 | + lto::Config Conf = toConfig(); |
| 588 | + ModuleSummaryIndex CombinedIndex(false); |
| 589 | + |
| 590 | + Error Err = |
| 591 | + backend(Conf, AddStream, ParallelismLevel, *MergedModule, CombinedIndex); |
| 592 | + assert(!Err && "unexpected code-generation failure"); |
| 593 | + (void)Err; |
622 | 594 |
|
623 | 595 | // If statistics were requested, save them to the specified file or
|
624 | 596 | // print them out after codegen.
|
|
0 commit comments