|
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" |
41 | 40 | #include "llvm/LTO/legacy/LTOModule.h"
|
42 | 41 | #include "llvm/LTO/legacy/UpdateCompilerUsed.h"
|
43 | 42 | #include "llvm/Linker/Linker.h"
|
@@ -124,29 +123,41 @@ LTOCodeGenerator::LTOCodeGenerator(LLVMContext &Context)
|
124 | 123 | TheLinker(new Linker(*MergedModule)) {
|
125 | 124 | Context.setDiscardValueNames(LTODiscardValueNames);
|
126 | 125 | Context.enableDebugTypeODRUniquing();
|
| 126 | + initializeLTOPasses(); |
127 | 127 | }
|
128 | 128 |
|
129 | 129 | LTOCodeGenerator::~LTOCodeGenerator() {}
|
130 | 130 |
|
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; |
| 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); |
150 | 161 | }
|
151 | 162 |
|
152 | 163 | void LTOCodeGenerator::setAsmUndefinedRefs(LTOModule *Mod) {
|
@@ -257,35 +268,38 @@ bool LTOCodeGenerator::writeMergedModules(StringRef Path) {
|
257 | 268 | bool LTOCodeGenerator::compileOptimizedToFile(const char **Name) {
|
258 | 269 | // make unique temp output file to put generated code
|
259 | 270 | SmallString<128> Filename;
|
| 271 | + int FD; |
260 | 272 |
|
261 |
| - auto AddStream = |
262 |
| - [&](size_t Task) -> std::unique_ptr<lto::NativeObjectStream> { |
263 |
| - StringRef Extension(FileType == CGFT_AssemblyFile ? "s" : "o"); |
| 273 | + StringRef Extension |
| 274 | + (FileType == CGFT_AssemblyFile ? "s" : "o"); |
264 | 275 |
|
265 |
| - int FD; |
266 |
| - std::error_code EC = |
267 |
| - sys::fs::createTemporaryFile("lto-llvm", Extension, FD, Filename); |
268 |
| - if (EC) |
269 |
| - emitError(EC.message()); |
| 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 | + } |
270 | 282 |
|
271 |
| - return std::make_unique<lto::NativeObjectStream>( |
272 |
| - std::make_unique<llvm::raw_fd_ostream>(FD, true)); |
273 |
| - }; |
| 283 | + // generate object file |
| 284 | + ToolOutputFile objFile(Filename, FD); |
274 | 285 |
|
275 |
| - bool genResult = compileOptimized(AddStream, 1); |
| 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 | + } |
276 | 296 |
|
| 297 | + objFile.keep(); |
277 | 298 | if (!genResult) {
|
278 | 299 | sys::fs::remove(Twine(Filename));
|
279 | 300 | return false;
|
280 | 301 | }
|
281 | 302 |
|
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 |
| - |
289 | 303 | NativeObjectPath = Filename.c_str();
|
290 | 304 | *Name = NativeObjectPath.c_str();
|
291 | 305 | return true;
|
@@ -554,43 +568,57 @@ bool LTOCodeGenerator::optimize() {
|
554 | 568 | // Write LTOPostLink flag for passes that require all the modules.
|
555 | 569 | MergedModule->addModuleFlag(Module::Error, "LTOPostLink", 1);
|
556 | 570 |
|
| 571 | + // Instantiate the pass manager to organize the passes. |
| 572 | + legacy::PassManager passes; |
| 573 | + |
557 | 574 | // Add an appropriate DataLayout instance for this module...
|
558 | 575 | MergedModule->setDataLayout(TargetMach->createDataLayout());
|
559 | 576 |
|
560 |
| - lto::Config Conf = toConfig(); |
| 577 | + passes.add( |
| 578 | + createTargetTransformInfoWrapperPass(TargetMach->getTargetIRAnalysis())); |
561 | 579 |
|
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 |
| - } |
| 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); |
| 593 | + |
| 594 | + // Run our queue of passes all at once now, efficiently. |
| 595 | + passes.run(*MergedModule); |
570 | 596 |
|
571 | 597 | return true;
|
572 | 598 | }
|
573 | 599 |
|
574 |
| -bool LTOCodeGenerator::compileOptimized(lto::AddStreamFn AddStream, |
575 |
| - unsigned ParallelismLevel) { |
| 600 | +bool LTOCodeGenerator::compileOptimized(ArrayRef<raw_pwrite_stream *> Out) { |
576 | 601 | if (!this->determineTarget())
|
577 | 602 | return false;
|
578 | 603 |
|
579 | 604 | // We always run the verifier once on the merged module. If it has already
|
580 | 605 | // been called in optimize(), this call will return early.
|
581 | 606 | verifyMergedModuleOnce();
|
582 | 607 |
|
| 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 | + |
583 | 615 | // Re-externalize globals that may have been internalized to increase scope
|
584 | 616 | // for splitting
|
585 | 617 | restoreLinkageForExternals();
|
586 | 618 |
|
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; |
| 619 | + splitCodeGen( |
| 620 | + *MergedModule, Out, {}, [&]() { return createTargetMachine(); }, FileType, |
| 621 | + ShouldRestoreGlobalsLinkage); |
594 | 622 |
|
595 | 623 | // If statistics were requested, save them to the specified file or
|
596 | 624 | // print them out after codegen.
|
|
0 commit comments