6 #include "LLVMWrapper.h"
8 #include "llvm/Analysis/AliasAnalysis.h"
9 #include "llvm/Analysis/TargetLibraryInfo.h"
10 #include "llvm/Analysis/TargetTransformInfo.h"
11 #include "llvm/CodeGen/TargetSubtargetInfo.h"
12 #include "llvm/InitializePasses.h"
13 #include "llvm/IR/AutoUpgrade.h"
14 #include "llvm/IR/AssemblyAnnotationWriter.h"
15 #include "llvm/IR/IntrinsicInst.h"
16 #include "llvm/IR/Verifier.h"
17 #include "llvm/Object/ObjectFile.h"
18 #include "llvm/Object/IRObjectFile.h"
19 #include "llvm/Passes/PassBuilder.h"
20 #include "llvm/Passes/PassPlugin.h"
21 #include "llvm/Passes/StandardInstrumentations.h"
22 #include "llvm/Support/CBindingWrapping.h"
23 #include "llvm/Support/FileSystem.h"
24 #include "llvm/Support/Host.h"
25 #if LLVM_VERSION_LT(14, 0)
26 #include "llvm/Support/TargetRegistry.h"
28 #include "llvm/MC/TargetRegistry.h"
30 #include "llvm/Target/TargetMachine.h"
31 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
32 #include "llvm/Transforms/IPO/AlwaysInliner.h"
33 #include "llvm/Transforms/IPO/FunctionImport.h"
34 #if LLVM_VERSION_GE(15, 0)
35 #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
37 #include "llvm/Transforms/Utils/AddDiscriminators.h"
38 #include "llvm/Transforms/Utils/FunctionImportUtils.h"
39 #include "llvm/LTO/LTO.h"
40 #include "llvm/Bitcode/BitcodeWriterPass.h"
41 #include "llvm-c/Transforms/PassManagerBuilder.h"
43 #include "llvm/Transforms/Instrumentation.h"
44 #include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
45 #include "llvm/Support/TimeProfiler.h"
46 #include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
47 #include "llvm/Transforms/Instrumentation/InstrProfiling.h"
48 #include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
49 #include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
50 #include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
51 #include "llvm/Transforms/Utils/CanonicalizeAliases.h"
52 #include "llvm/Transforms/Utils/NameAnonGlobals.h"
53 #include "llvm/Transforms/Utils.h"
57 typedef struct LLVMOpaquePass *LLVMPassRef;
58 typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef;
60 DEFINE_STDCXX_CONVERSION_FUNCTIONS(Pass, LLVMPassRef)
61 DEFINE_STDCXX_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
63 extern "C" void LLVMInitializePasses() {
64 PassRegistry &Registry = *PassRegistry::getPassRegistry();
65 initializeCore(Registry);
66 initializeCodeGen(Registry);
67 initializeScalarOpts(Registry);
68 initializeVectorization(Registry);
69 initializeIPO(Registry);
70 initializeAnalysis(Registry);
71 initializeTransformUtils(Registry);
72 initializeInstCombine(Registry);
73 initializeInstrumentation(Registry);
74 initializeTarget(Registry);
77 extern "C" void LLVMTimeTraceProfilerInitialize() {
78 timeTraceProfilerInitialize(
79 /* TimeTraceGranularity */ 0,
80 /* ProcName */ "rustc");
83 extern "C" void LLVMTimeTraceProfilerFinishThread() {
84 timeTraceProfilerFinishThread();
87 extern "C" void LLVMTimeTraceProfilerFinish(const char* FileName) {
88 StringRef FN(FileName);
90 raw_fd_ostream OS(FN, EC, sys::fs::CD_CreateAlways);
92 timeTraceProfilerWrite(OS);
93 timeTraceProfilerCleanup();
96 #ifdef LLVM_COMPONENT_X86
97 #define SUBTARGET_X86 SUBTARGET(X86)
102 #ifdef LLVM_COMPONENT_ARM
103 #define SUBTARGET_ARM SUBTARGET(ARM)
105 #define SUBTARGET_ARM
108 #ifdef LLVM_COMPONENT_AARCH64
109 #define SUBTARGET_AARCH64 SUBTARGET(AArch64)
111 #define SUBTARGET_AARCH64
114 #ifdef LLVM_COMPONENT_AVR
115 #define SUBTARGET_AVR SUBTARGET(AVR)
117 #define SUBTARGET_AVR
120 #ifdef LLVM_COMPONENT_M68k
121 #define SUBTARGET_M68K SUBTARGET(M68k)
123 #define SUBTARGET_M68K
126 #ifdef LLVM_COMPONENT_MIPS
127 #define SUBTARGET_MIPS SUBTARGET(Mips)
129 #define SUBTARGET_MIPS
132 #ifdef LLVM_COMPONENT_POWERPC
133 #define SUBTARGET_PPC SUBTARGET(PPC)
135 #define SUBTARGET_PPC
138 #ifdef LLVM_COMPONENT_SYSTEMZ
139 #define SUBTARGET_SYSTEMZ SUBTARGET(SystemZ)
141 #define SUBTARGET_SYSTEMZ
144 #ifdef LLVM_COMPONENT_MSP430
145 #define SUBTARGET_MSP430 SUBTARGET(MSP430)
147 #define SUBTARGET_MSP430
150 #ifdef LLVM_COMPONENT_RISCV
151 #define SUBTARGET_RISCV SUBTARGET(RISCV)
153 #define SUBTARGET_RISCV
156 #ifdef LLVM_COMPONENT_SPARC
157 #define SUBTARGET_SPARC SUBTARGET(Sparc)
159 #define SUBTARGET_SPARC
162 #ifdef LLVM_COMPONENT_HEXAGON
163 #define SUBTARGET_HEXAGON SUBTARGET(Hexagon)
165 #define SUBTARGET_HEXAGON
168 #define GEN_SUBTARGETS \
182 #define SUBTARGET(x) \
184 extern const SubtargetFeatureKV x##FeatureKV[]; \
185 extern const SubtargetFeatureKV x##SubTypeKV[]; \
191 extern "C" bool LLVMRustHasFeature(LLVMTargetMachineRef TM,
192 const char *Feature) {
193 TargetMachine *Target = unwrap(TM);
194 const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
195 return MCInfo->checkFeatures(std::string("+") + Feature);
198 enum class LLVMRustCodeModel {
207 static Optional<CodeModel::Model> fromRust(LLVMRustCodeModel Model) {
209 case LLVMRustCodeModel::Tiny:
210 return CodeModel::Tiny;
211 case LLVMRustCodeModel::Small:
212 return CodeModel::Small;
213 case LLVMRustCodeModel::Kernel:
214 return CodeModel::Kernel;
215 case LLVMRustCodeModel::Medium:
216 return CodeModel::Medium;
217 case LLVMRustCodeModel::Large:
218 return CodeModel::Large;
219 case LLVMRustCodeModel::None:
222 report_fatal_error("Bad CodeModel.");
226 enum class LLVMRustCodeGenOptLevel {
233 static CodeGenOpt::Level fromRust(LLVMRustCodeGenOptLevel Level) {
235 case LLVMRustCodeGenOptLevel::None:
236 return CodeGenOpt::None;
237 case LLVMRustCodeGenOptLevel::Less:
238 return CodeGenOpt::Less;
239 case LLVMRustCodeGenOptLevel::Default:
240 return CodeGenOpt::Default;
241 case LLVMRustCodeGenOptLevel::Aggressive:
242 return CodeGenOpt::Aggressive;
244 report_fatal_error("Bad CodeGenOptLevel.");
248 enum class LLVMRustPassBuilderOptLevel {
257 #if LLVM_VERSION_LT(14,0)
258 using OptimizationLevel = PassBuilder::OptimizationLevel;
261 static OptimizationLevel fromRust(LLVMRustPassBuilderOptLevel Level) {
263 case LLVMRustPassBuilderOptLevel::O0:
264 return OptimizationLevel::O0;
265 case LLVMRustPassBuilderOptLevel::O1:
266 return OptimizationLevel::O1;
267 case LLVMRustPassBuilderOptLevel::O2:
268 return OptimizationLevel::O2;
269 case LLVMRustPassBuilderOptLevel::O3:
270 return OptimizationLevel::O3;
271 case LLVMRustPassBuilderOptLevel::Os:
272 return OptimizationLevel::Os;
273 case LLVMRustPassBuilderOptLevel::Oz:
274 return OptimizationLevel::Oz;
276 report_fatal_error("Bad PassBuilderOptLevel.");
280 enum class LLVMRustRelocModel {
289 static Reloc::Model fromRust(LLVMRustRelocModel RustReloc) {
291 case LLVMRustRelocModel::Static:
292 return Reloc::Static;
293 case LLVMRustRelocModel::PIC:
295 case LLVMRustRelocModel::DynamicNoPic:
296 return Reloc::DynamicNoPIC;
297 case LLVMRustRelocModel::ROPI:
299 case LLVMRustRelocModel::RWPI:
301 case LLVMRustRelocModel::ROPIRWPI:
302 return Reloc::ROPI_RWPI;
304 report_fatal_error("Bad RelocModel.");
308 /// getLongestEntryLength - Return the length of the longest entry in the table.
309 template<typename KV>
310 static size_t getLongestEntryLength(ArrayRef<KV> Table) {
312 for (auto &I : Table)
313 MaxLen = std::max(MaxLen, std::strlen(I.Key));
317 extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM) {
318 const TargetMachine *Target = unwrap(TM);
319 const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
320 const Triple::ArchType HostArch = Triple(sys::getProcessTriple()).getArch();
321 const Triple::ArchType TargetArch = Target->getTargetTriple().getArch();
322 const ArrayRef<SubtargetSubTypeKV> CPUTable = MCInfo->getCPUTable();
323 unsigned MaxCPULen = getLongestEntryLength(CPUTable);
325 printf("Available CPUs for this target:\n");
326 if (HostArch == TargetArch) {
327 const StringRef HostCPU = sys::getHostCPUName();
328 printf(" %-*s - Select the CPU of the current host (currently %.*s).\n",
329 MaxCPULen, "native", (int)HostCPU.size(), HostCPU.data());
331 for (auto &CPU : CPUTable)
332 printf(" %-*s\n", MaxCPULen, CPU.Key);
336 extern "C" size_t LLVMRustGetTargetFeaturesCount(LLVMTargetMachineRef TM) {
337 const TargetMachine *Target = unwrap(TM);
338 const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
339 const ArrayRef<SubtargetFeatureKV> FeatTable = MCInfo->getFeatureTable();
340 return FeatTable.size();
343 extern "C" void LLVMRustGetTargetFeature(LLVMTargetMachineRef TM, size_t Index,
344 const char** Feature, const char** Desc) {
345 const TargetMachine *Target = unwrap(TM);
346 const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
347 const ArrayRef<SubtargetFeatureKV> FeatTable = MCInfo->getFeatureTable();
348 const SubtargetFeatureKV Feat = FeatTable[Index];
355 extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef) {
356 printf("Target CPU help is not supported by this LLVM version.\n\n");
359 extern "C" size_t LLVMRustGetTargetFeaturesCount(LLVMTargetMachineRef) {
363 extern "C" void LLVMRustGetTargetFeature(LLVMTargetMachineRef, const char**, const char**) {}
366 extern "C" const char* LLVMRustGetHostCPUName(size_t *len) {
367 StringRef Name = sys::getHostCPUName();
372 extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
373 const char *TripleStr, const char *CPU, const char *Feature,
374 const char *ABIStr, LLVMRustCodeModel RustCM, LLVMRustRelocModel RustReloc,
375 LLVMRustCodeGenOptLevel RustOptLevel, bool UseSoftFloat,
376 bool FunctionSections,
378 bool UniqueSectionNames,
379 bool TrapUnreachable,
382 bool EmitStackSizeSection,
383 bool RelaxELFRelocations,
385 const char *SplitDwarfFile) {
387 auto OptLevel = fromRust(RustOptLevel);
388 auto RM = fromRust(RustReloc);
389 auto CM = fromRust(RustCM);
392 Triple Trip(Triple::normalize(TripleStr));
393 const llvm::Target *TheTarget =
394 TargetRegistry::lookupTarget(Trip.getTriple(), Error);
395 if (TheTarget == nullptr) {
396 LLVMRustSetLastError(Error.c_str());
400 TargetOptions Options;
402 Options.FloatABIType = FloatABI::Default;
404 Options.FloatABIType = FloatABI::Soft;
406 Options.DataSections = DataSections;
407 Options.FunctionSections = FunctionSections;
408 Options.UniqueSectionNames = UniqueSectionNames;
409 Options.MCOptions.AsmVerbose = AsmComments;
410 Options.MCOptions.PreserveAsmComments = AsmComments;
411 Options.MCOptions.ABIName = ABIStr;
412 if (SplitDwarfFile) {
413 Options.MCOptions.SplitDwarfFile = SplitDwarfFile;
415 Options.RelaxELFRelocations = RelaxELFRelocations;
416 Options.UseInitArray = UseInitArray;
418 if (TrapUnreachable) {
419 // Tell LLVM to codegen `unreachable` into an explicit trap instruction.
420 // This limits the extent of possible undefined behavior in some cases, as
421 // it prevents control flow from "falling through" into whatever code
422 // happens to be laid out next in memory.
423 Options.TrapUnreachable = true;
427 Options.ThreadModel = ThreadModel::Single;
430 Options.EmitStackSizeSection = EmitStackSizeSection;
432 TargetMachine *TM = TheTarget->createTargetMachine(
433 Trip.getTriple(), CPU, Feature, Options, RM, CM, OptLevel);
437 extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) {
441 // Unfortunately, the LLVM C API doesn't provide a way to create the
442 // TargetLibraryInfo pass, so we use this method to do so.
443 extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR, LLVMModuleRef M,
444 bool DisableSimplifyLibCalls) {
445 Triple TargetTriple(unwrap(M)->getTargetTriple());
446 TargetLibraryInfoImpl TLII(TargetTriple);
447 if (DisableSimplifyLibCalls)
448 TLII.disableAllFunctions();
449 unwrap(PMR)->add(new TargetLibraryInfoWrapperPass(TLII));
452 extern "C" void LLVMRustSetLLVMOptions(int Argc, char **Argv) {
453 // Initializing the command-line options more than once is not allowed. So,
454 // check if they've already been initialized. (This could happen if we're
455 // being called from rustpkg, for example). If the arguments change, then
456 // that's just kinda unfortunate.
457 static bool Initialized = false;
461 cl::ParseCommandLineOptions(Argc, Argv);
464 enum class LLVMRustFileType {
469 static CodeGenFileType fromRust(LLVMRustFileType Type) {
471 case LLVMRustFileType::AssemblyFile:
472 return CGFT_AssemblyFile;
473 case LLVMRustFileType::ObjectFile:
474 return CGFT_ObjectFile;
476 report_fatal_error("Bad FileType.");
480 extern "C" LLVMRustResult
481 LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR,
482 LLVMModuleRef M, const char *Path, const char *DwoPath,
483 LLVMRustFileType RustFileType) {
484 llvm::legacy::PassManager *PM = unwrap<llvm::legacy::PassManager>(PMR);
485 auto FileType = fromRust(RustFileType);
487 std::string ErrorInfo;
489 raw_fd_ostream OS(Path, EC, sys::fs::OF_None);
491 ErrorInfo = EC.message();
492 if (ErrorInfo != "") {
493 LLVMRustSetLastError(ErrorInfo.c_str());
494 return LLVMRustResult::Failure;
497 buffer_ostream BOS(OS);
499 raw_fd_ostream DOS(DwoPath, EC, sys::fs::OF_None);
502 ErrorInfo = EC.message();
503 if (ErrorInfo != "") {
504 LLVMRustSetLastError(ErrorInfo.c_str());
505 return LLVMRustResult::Failure;
507 buffer_ostream DBOS(DOS);
508 unwrap(Target)->addPassesToEmitFile(*PM, BOS, &DBOS, FileType, false);
511 unwrap(Target)->addPassesToEmitFile(*PM, BOS, nullptr, FileType, false);
515 // Apparently `addPassesToEmitFile` adds a pointer to our on-the-stack output
516 // stream (OS), so the only real safe place to delete this is here? Don't we
517 // wish this was written in Rust?
518 LLVMDisposePassManager(PMR);
519 return LLVMRustResult::Success;
522 extern "C" typedef void (*LLVMRustSelfProfileBeforePassCallback)(void*, // LlvmSelfProfiler
523 const char*, // pass name
524 const char*); // IR name
525 extern "C" typedef void (*LLVMRustSelfProfileAfterPassCallback)(void*); // LlvmSelfProfiler
527 std::string LLVMRustwrappedIrGetName(const llvm::Any &WrappedIr) {
528 if (any_isa<const Module *>(WrappedIr))
529 return any_cast<const Module *>(WrappedIr)->getName().str();
530 if (any_isa<const Function *>(WrappedIr))
531 return any_cast<const Function *>(WrappedIr)->getName().str();
532 if (any_isa<const Loop *>(WrappedIr))
533 return any_cast<const Loop *>(WrappedIr)->getName().str();
534 if (any_isa<const LazyCallGraph::SCC *>(WrappedIr))
535 return any_cast<const LazyCallGraph::SCC *>(WrappedIr)->getName();
540 void LLVMSelfProfileInitializeCallbacks(
541 PassInstrumentationCallbacks& PIC, void* LlvmSelfProfiler,
542 LLVMRustSelfProfileBeforePassCallback BeforePassCallback,
543 LLVMRustSelfProfileAfterPassCallback AfterPassCallback) {
544 PIC.registerBeforeNonSkippedPassCallback([LlvmSelfProfiler, BeforePassCallback](
545 StringRef Pass, llvm::Any Ir) {
546 std::string PassName = Pass.str();
547 std::string IrName = LLVMRustwrappedIrGetName(Ir);
548 BeforePassCallback(LlvmSelfProfiler, PassName.c_str(), IrName.c_str());
551 PIC.registerAfterPassCallback(
552 [LlvmSelfProfiler, AfterPassCallback](StringRef Pass, llvm::Any IR,
553 const PreservedAnalyses &Preserved) {
554 AfterPassCallback(LlvmSelfProfiler);
557 PIC.registerAfterPassInvalidatedCallback(
558 [LlvmSelfProfiler, AfterPassCallback](StringRef Pass, const PreservedAnalyses &Preserved) {
559 AfterPassCallback(LlvmSelfProfiler);
562 PIC.registerBeforeAnalysisCallback([LlvmSelfProfiler, BeforePassCallback](
563 StringRef Pass, llvm::Any Ir) {
564 std::string PassName = Pass.str();
565 std::string IrName = LLVMRustwrappedIrGetName(Ir);
566 BeforePassCallback(LlvmSelfProfiler, PassName.c_str(), IrName.c_str());
569 PIC.registerAfterAnalysisCallback(
570 [LlvmSelfProfiler, AfterPassCallback](StringRef Pass, llvm::Any Ir) {
571 AfterPassCallback(LlvmSelfProfiler);
575 enum class LLVMRustOptStage {
583 struct LLVMRustSanitizerOptions {
584 bool SanitizeAddress;
585 bool SanitizeAddressRecover;
587 bool SanitizeMemoryRecover;
588 int SanitizeMemoryTrackOrigins;
590 bool SanitizeHWAddress;
591 bool SanitizeHWAddressRecover;
594 extern "C" LLVMRustResult
596 LLVMModuleRef ModuleRef,
597 LLVMTargetMachineRef TMRef,
598 LLVMRustPassBuilderOptLevel OptLevelRust,
599 LLVMRustOptStage OptStage,
600 bool NoPrepopulatePasses, bool VerifyIR, bool UseThinLTOBuffers,
601 bool MergeFunctions, bool UnrollLoops, bool SLPVectorize, bool LoopVectorize,
602 bool DisableSimplifyLibCalls, bool EmitLifetimeMarkers,
603 LLVMRustSanitizerOptions *SanitizerOptions,
604 const char *PGOGenPath, const char *PGOUsePath,
605 bool InstrumentCoverage, const char *InstrProfileOutput,
607 const char *PGOSampleUsePath, bool DebugInfoForProfiling,
608 void* LlvmSelfProfiler,
609 LLVMRustSelfProfileBeforePassCallback BeforePassCallback,
610 LLVMRustSelfProfileAfterPassCallback AfterPassCallback,
611 const char *ExtraPasses, size_t ExtraPassesLen,
612 const char *LLVMPlugins, size_t LLVMPluginsLen) {
613 Module *TheModule = unwrap(ModuleRef);
614 TargetMachine *TM = unwrap(TMRef);
615 OptimizationLevel OptLevel = fromRust(OptLevelRust);
618 PipelineTuningOptions PTO;
619 PTO.LoopUnrolling = UnrollLoops;
620 PTO.LoopInterleaving = UnrollLoops;
621 PTO.LoopVectorization = LoopVectorize;
622 PTO.SLPVectorization = SLPVectorize;
623 PTO.MergeFunctions = MergeFunctions;
625 // FIXME: We may want to expose this as an option.
626 bool DebugPassManager = false;
628 PassInstrumentationCallbacks PIC;
629 StandardInstrumentations SI(DebugPassManager);
630 SI.registerCallbacks(PIC);
632 if (LlvmSelfProfiler){
633 LLVMSelfProfileInitializeCallbacks(PIC,LlvmSelfProfiler,BeforePassCallback,AfterPassCallback);
636 Optional<PGOOptions> PGOOpt;
638 assert(!PGOUsePath && !PGOSampleUsePath);
639 PGOOpt = PGOOptions(PGOGenPath, "", "", PGOOptions::IRInstr,
640 PGOOptions::NoCSAction, DebugInfoForProfiling);
641 } else if (PGOUsePath) {
642 assert(!PGOSampleUsePath);
643 PGOOpt = PGOOptions(PGOUsePath, "", "", PGOOptions::IRUse,
644 PGOOptions::NoCSAction, DebugInfoForProfiling);
645 } else if (PGOSampleUsePath) {
646 PGOOpt = PGOOptions(PGOSampleUsePath, "", "", PGOOptions::SampleUse,
647 PGOOptions::NoCSAction, DebugInfoForProfiling);
648 } else if (DebugInfoForProfiling) {
649 PGOOpt = PGOOptions("", "", "", PGOOptions::NoAction,
650 PGOOptions::NoCSAction, DebugInfoForProfiling);
653 PassBuilder PB(TM, PTO, PGOOpt, &PIC);
654 LoopAnalysisManager LAM;
655 FunctionAnalysisManager FAM;
656 CGSCCAnalysisManager CGAM;
657 ModuleAnalysisManager MAM;
659 FAM.registerPass([&] { return PB.buildDefaultAAPipeline(); });
661 Triple TargetTriple(TheModule->getTargetTriple());
662 std::unique_ptr<TargetLibraryInfoImpl> TLII(new TargetLibraryInfoImpl(TargetTriple));
663 if (DisableSimplifyLibCalls)
664 TLII->disableAllFunctions();
665 FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
667 PB.registerModuleAnalyses(MAM);
668 PB.registerCGSCCAnalyses(CGAM);
669 PB.registerFunctionAnalyses(FAM);
670 PB.registerLoopAnalyses(LAM);
671 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
673 // We manually collect pipeline callbacks so we can apply them at O0, where the
674 // PassBuilder does not create a pipeline.
675 std::vector<std::function<void(ModulePassManager &, OptimizationLevel)>>
676 PipelineStartEPCallbacks;
677 std::vector<std::function<void(ModulePassManager &, OptimizationLevel)>>
678 OptimizerLastEPCallbacks;
681 PipelineStartEPCallbacks.push_back(
682 [VerifyIR](ModulePassManager &MPM, OptimizationLevel Level) {
683 MPM.addPass(VerifierPass());
688 if (InstrumentGCOV) {
689 PipelineStartEPCallbacks.push_back(
690 [](ModulePassManager &MPM, OptimizationLevel Level) {
691 MPM.addPass(GCOVProfilerPass(GCOVOptions::getDefault()));
696 if (InstrumentCoverage) {
697 PipelineStartEPCallbacks.push_back(
698 [InstrProfileOutput](ModulePassManager &MPM, OptimizationLevel Level) {
699 InstrProfOptions Options;
700 if (InstrProfileOutput) {
701 Options.InstrProfileOutput = InstrProfileOutput;
703 MPM.addPass(InstrProfiling(Options, false));
708 if (SanitizerOptions) {
709 if (SanitizerOptions->SanitizeMemory) {
710 #if LLVM_VERSION_GE(14, 0)
711 MemorySanitizerOptions Options(
712 SanitizerOptions->SanitizeMemoryTrackOrigins,
713 SanitizerOptions->SanitizeMemoryRecover,
714 /*CompileKernel=*/false,
715 /*EagerChecks=*/true);
717 MemorySanitizerOptions Options(
718 SanitizerOptions->SanitizeMemoryTrackOrigins,
719 SanitizerOptions->SanitizeMemoryRecover,
720 /*CompileKernel=*/false);
722 OptimizerLastEPCallbacks.push_back(
723 [Options](ModulePassManager &MPM, OptimizationLevel Level) {
724 #if LLVM_VERSION_GE(14, 0) && LLVM_VERSION_LT(16, 0)
725 MPM.addPass(ModuleMemorySanitizerPass(Options));
727 MPM.addPass(MemorySanitizerPass(Options));
729 #if LLVM_VERSION_LT(16, 0)
730 MPM.addPass(createModuleToFunctionPassAdaptor(MemorySanitizerPass(Options)));
736 if (SanitizerOptions->SanitizeThread) {
737 OptimizerLastEPCallbacks.push_back(
738 [](ModulePassManager &MPM, OptimizationLevel Level) {
739 #if LLVM_VERSION_GE(14, 0)
740 MPM.addPass(ModuleThreadSanitizerPass());
742 MPM.addPass(ThreadSanitizerPass());
744 MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));
749 if (SanitizerOptions->SanitizeAddress) {
750 OptimizerLastEPCallbacks.push_back(
751 [SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level) {
752 #if LLVM_VERSION_LT(15, 0)
753 MPM.addPass(RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
755 #if LLVM_VERSION_GE(14, 0)
756 AddressSanitizerOptions opts = AddressSanitizerOptions{
757 /*CompileKernel=*/false,
758 SanitizerOptions->SanitizeAddressRecover,
759 /*UseAfterScope=*/true,
760 AsanDetectStackUseAfterReturnMode::Runtime,
762 #if LLVM_VERSION_LT(16, 0)
763 MPM.addPass(ModuleAddressSanitizerPass(opts));
765 MPM.addPass(AddressSanitizerPass(opts));
768 MPM.addPass(ModuleAddressSanitizerPass(
769 /*CompileKernel=*/false, SanitizerOptions->SanitizeAddressRecover));
770 MPM.addPass(createModuleToFunctionPassAdaptor(AddressSanitizerPass(
771 /*CompileKernel=*/false, SanitizerOptions->SanitizeAddressRecover,
772 /*UseAfterScope=*/true)));
777 if (SanitizerOptions->SanitizeHWAddress) {
778 OptimizerLastEPCallbacks.push_back(
779 [SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level) {
780 #if LLVM_VERSION_GE(14, 0)
781 HWAddressSanitizerOptions opts(
782 /*CompileKernel=*/false, SanitizerOptions->SanitizeHWAddressRecover,
783 /*DisableOptimization=*/false);
784 MPM.addPass(HWAddressSanitizerPass(opts));
786 MPM.addPass(HWAddressSanitizerPass(
787 /*CompileKernel=*/false, SanitizerOptions->SanitizeHWAddressRecover));
794 if (LLVMPluginsLen) {
795 auto PluginsStr = StringRef(LLVMPlugins, LLVMPluginsLen);
796 SmallVector<StringRef> Plugins;
797 PluginsStr.split(Plugins, ',', -1, false);
798 for (auto PluginPath: Plugins) {
799 auto Plugin = PassPlugin::Load(PluginPath.str());
801 LLVMRustSetLastError(("Failed to load pass plugin" + PluginPath.str()).c_str());
804 Plugin->registerPassBuilderCallbacks(PB);
808 ModulePassManager MPM;
809 bool NeedThinLTOBufferPasses = UseThinLTOBuffers;
810 if (!NoPrepopulatePasses) {
811 // The pre-link pipelines don't support O0 and require using budilO0DefaultPipeline() instead.
812 // At the same time, the LTO pipelines do support O0 and using them is required.
813 bool IsLTO = OptStage == LLVMRustOptStage::ThinLTO || OptStage == LLVMRustOptStage::FatLTO;
814 if (OptLevel == OptimizationLevel::O0 && !IsLTO) {
815 for (const auto &C : PipelineStartEPCallbacks)
816 PB.registerPipelineStartEPCallback(C);
817 for (const auto &C : OptimizerLastEPCallbacks)
818 PB.registerOptimizerLastEPCallback(C);
820 // Pass false as we manually schedule ThinLTOBufferPasses below.
821 MPM = PB.buildO0DefaultPipeline(OptLevel, /* PreLinkLTO */ false);
823 for (const auto &C : PipelineStartEPCallbacks)
824 PB.registerPipelineStartEPCallback(C);
825 if (OptStage != LLVMRustOptStage::PreLinkThinLTO) {
826 for (const auto &C : OptimizerLastEPCallbacks)
827 PB.registerOptimizerLastEPCallback(C);
831 case LLVMRustOptStage::PreLinkNoLTO:
832 MPM = PB.buildPerModuleDefaultPipeline(OptLevel, DebugPassManager);
834 case LLVMRustOptStage::PreLinkThinLTO:
835 MPM = PB.buildThinLTOPreLinkDefaultPipeline(OptLevel);
836 // The ThinLTOPreLink pipeline already includes ThinLTOBuffer passes. However, callback
837 // passes may still run afterwards. This means we need to run the buffer passes again.
838 // FIXME: In LLVM 13, the ThinLTOPreLink pipeline also runs OptimizerLastEPCallbacks
839 // before the RequiredLTOPreLinkPasses, in which case we can remove these hacks.
840 if (OptimizerLastEPCallbacks.empty())
841 NeedThinLTOBufferPasses = false;
842 for (const auto &C : OptimizerLastEPCallbacks)
845 case LLVMRustOptStage::PreLinkFatLTO:
846 MPM = PB.buildLTOPreLinkDefaultPipeline(OptLevel);
847 NeedThinLTOBufferPasses = false;
849 case LLVMRustOptStage::ThinLTO:
850 // FIXME: Does it make sense to pass the ModuleSummaryIndex?
851 // It only seems to be needed for C++ specific optimizations.
852 MPM = PB.buildThinLTODefaultPipeline(OptLevel, nullptr);
854 case LLVMRustOptStage::FatLTO:
855 MPM = PB.buildLTODefaultPipeline(OptLevel, nullptr);
860 // We're not building any of the default pipelines but we still want to
861 // add the verifier, instrumentation, etc passes if they were requested
862 for (const auto &C : PipelineStartEPCallbacks)
864 for (const auto &C : OptimizerLastEPCallbacks)
868 if (ExtraPassesLen) {
869 if (auto Err = PB.parsePassPipeline(MPM, StringRef(ExtraPasses, ExtraPassesLen))) {
870 std::string ErrMsg = toString(std::move(Err));
871 LLVMRustSetLastError(ErrMsg.c_str());
872 return LLVMRustResult::Failure;
876 if (NeedThinLTOBufferPasses) {
877 MPM.addPass(CanonicalizeAliasesPass());
878 MPM.addPass(NameAnonGlobalPass());
881 // Upgrade all calls to old intrinsics first.
882 for (Module::iterator I = TheModule->begin(), E = TheModule->end(); I != E;)
883 UpgradeCallsToIntrinsic(&*I++); // must be post-increment, as we remove
885 MPM.run(*TheModule, MAM);
886 return LLVMRustResult::Success;
889 // Callback to demangle function name
891 // * name to be demangled
894 // * output buffer len
895 // Returns len of demangled string, or 0 if demangle failed.
896 typedef size_t (*DemangleFn)(const char*, size_t, char*, size_t);
901 class RustAssemblyAnnotationWriter : public AssemblyAnnotationWriter {
903 std::vector<char> Buf;
906 RustAssemblyAnnotationWriter(DemangleFn Demangle) : Demangle(Demangle) {}
908 // Return empty string if demangle failed
909 // or if name does not need to be demangled
910 StringRef CallDemangle(StringRef name) {
915 if (Buf.size() < name.size() * 2) {
916 // Semangled name usually shorter than mangled,
917 // but allocate twice as much memory just in case
918 Buf.resize(name.size() * 2);
921 auto R = Demangle(name.data(), name.size(), Buf.data(), Buf.size());
927 auto Demangled = StringRef(Buf.data(), R);
928 if (Demangled == name) {
929 // Do not print anything if demangled name is equal to mangled.
936 void emitFunctionAnnot(const Function *F,
937 formatted_raw_ostream &OS) override {
938 StringRef Demangled = CallDemangle(F->getName());
939 if (Demangled.empty()) {
943 OS << "; " << Demangled << "\n";
946 void emitInstructionAnnot(const Instruction *I,
947 formatted_raw_ostream &OS) override {
950 if (const CallInst *CI = dyn_cast<CallInst>(I)) {
952 Value = CI->getCalledOperand();
953 } else if (const InvokeInst* II = dyn_cast<InvokeInst>(I)) {
955 Value = II->getCalledOperand();
957 // Could demangle more operations, e. g.
958 // `store %place, @function`.
962 if (!Value->hasName()) {
966 StringRef Demangled = CallDemangle(Value->getName());
967 if (Demangled.empty()) {
971 OS << "; " << Name << " " << Demangled << "\n";
977 extern "C" LLVMRustResult
978 LLVMRustPrintModule(LLVMModuleRef M, const char *Path, DemangleFn Demangle) {
979 std::string ErrorInfo;
981 raw_fd_ostream OS(Path, EC, sys::fs::OF_None);
983 ErrorInfo = EC.message();
984 if (ErrorInfo != "") {
985 LLVMRustSetLastError(ErrorInfo.c_str());
986 return LLVMRustResult::Failure;
989 RustAssemblyAnnotationWriter AAW(Demangle);
990 formatted_raw_ostream FOS(OS);
991 unwrap(M)->print(FOS, &AAW);
993 return LLVMRustResult::Success;
996 extern "C" void LLVMRustPrintPasses() {
997 LLVMInitializePasses();
998 struct MyListener : PassRegistrationListener {
999 void passEnumerate(const PassInfo *Info) {
1000 StringRef PassArg = Info->getPassArgument();
1001 StringRef PassName = Info->getPassName();
1002 if (!PassArg.empty()) {
1003 // These unsigned->signed casts could theoretically overflow, but
1004 // realistically never will (and even if, the result is implementation
1005 // defined rather plain UB).
1006 printf("%15.*s - %.*s\n", (int)PassArg.size(), PassArg.data(),
1007 (int)PassName.size(), PassName.data());
1012 PassRegistry *PR = PassRegistry::getPassRegistry();
1013 PR->enumerateWith(&Listener);
1016 extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **Symbols,
1018 llvm::legacy::PassManager passes;
1020 auto PreserveFunctions = [=](const GlobalValue &GV) {
1021 for (size_t I = 0; I < Len; I++) {
1022 if (GV.getName() == Symbols[I]) {
1029 passes.add(llvm::createInternalizePass(PreserveFunctions));
1031 passes.run(*unwrap(M));
1035 LLVMRustSetDataLayoutFromTargetMachine(LLVMModuleRef Module,
1036 LLVMTargetMachineRef TMR) {
1037 TargetMachine *Target = unwrap(TMR);
1038 unwrap(Module)->setDataLayout(Target->createDataLayout());
1041 extern "C" void LLVMRustSetModulePICLevel(LLVMModuleRef M) {
1042 unwrap(M)->setPICLevel(PICLevel::Level::BigPIC);
1045 extern "C" void LLVMRustSetModulePIELevel(LLVMModuleRef M) {
1046 unwrap(M)->setPIELevel(PIELevel::Level::Large);
1049 extern "C" void LLVMRustSetModuleCodeModel(LLVMModuleRef M,
1050 LLVMRustCodeModel Model) {
1051 auto CM = fromRust(Model);
1054 unwrap(M)->setCodeModel(*CM);
1057 // Here you'll find an implementation of ThinLTO as used by the Rust compiler
1058 // right now. This ThinLTO support is only enabled on "recent ish" versions of
1059 // LLVM, and otherwise it's just blanket rejected from other compilers.
1061 // Most of this implementation is straight copied from LLVM. At the time of
1062 // this writing it wasn't *quite* suitable to reuse more code from upstream
1063 // for our purposes, but we should strive to upstream this support once it's
1064 // ready to go! I figure we may want a bit of testing locally first before
1065 // sending this upstream to LLVM. I hear though they're quite eager to receive
1066 // feedback like this!
1068 // If you're reading this code and wondering "what in the world" or you're
1069 // working "good lord by LLVM upgrade is *still* failing due to these bindings"
1070 // then fear not! (ok maybe fear a little). All code here is mostly based
1071 // on `lib/LTO/ThinLTOCodeGenerator.cpp` in LLVM.
1073 // You'll find that the general layout here roughly corresponds to the `run`
1074 // method in that file as well as `ProcessThinLTOModule`. Functions are
1075 // specifically commented below as well, but if you're updating this code
1076 // or otherwise trying to understand it, the LLVM source will be useful in
1077 // interpreting the mysteries within.
1079 // Otherwise I'll apologize in advance, it probably requires a relatively
1080 // significant investment on your part to "truly understand" what's going on
1081 // here. Not saying I do myself, but it took me awhile staring at LLVM's source
1082 // and various online resources about ThinLTO to make heads or tails of all
1085 // This is a shared data structure which *must* be threadsafe to share
1086 // read-only amongst threads. This also corresponds basically to the arguments
1087 // of the `ProcessThinLTOModule` function in the LLVM source.
1088 struct LLVMRustThinLTOData {
1089 // The combined index that is the global analysis over all modules we're
1090 // performing ThinLTO for. This is mostly managed by LLVM.
1091 ModuleSummaryIndex Index;
1093 // All modules we may look at, stored as in-memory serialized versions. This
1094 // is later used when inlining to ensure we can extract any module to inline
1096 StringMap<MemoryBufferRef> ModuleMap;
1098 // A set that we manage of everything we *don't* want internalized. Note that
1099 // this includes all transitive references right now as well, but it may not
1101 DenseSet<GlobalValue::GUID> GUIDPreservedSymbols;
1103 // Not 100% sure what these are, but they impact what's internalized and
1104 // what's inlined across modules, I believe.
1105 StringMap<FunctionImporter::ImportMapTy> ImportLists;
1106 StringMap<FunctionImporter::ExportSetTy> ExportLists;
1107 StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries;
1108 StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
1110 LLVMRustThinLTOData() : Index(/* HaveGVs = */ false) {}
1113 // Just an argument to the `LLVMRustCreateThinLTOData` function below.
1114 struct LLVMRustThinLTOModule {
1115 const char *identifier;
1120 // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp`, not sure what it
1122 static const GlobalValueSummary *
1123 getFirstDefinitionForLinker(const GlobalValueSummaryList &GVSummaryList) {
1124 auto StrongDefForLinker = llvm::find_if(
1125 GVSummaryList, [](const std::unique_ptr<GlobalValueSummary> &Summary) {
1126 auto Linkage = Summary->linkage();
1127 return !GlobalValue::isAvailableExternallyLinkage(Linkage) &&
1128 !GlobalValue::isWeakForLinker(Linkage);
1130 if (StrongDefForLinker != GVSummaryList.end())
1131 return StrongDefForLinker->get();
1133 auto FirstDefForLinker = llvm::find_if(
1134 GVSummaryList, [](const std::unique_ptr<GlobalValueSummary> &Summary) {
1135 auto Linkage = Summary->linkage();
1136 return !GlobalValue::isAvailableExternallyLinkage(Linkage);
1138 if (FirstDefForLinker == GVSummaryList.end())
1140 return FirstDefForLinker->get();
1143 // The main entry point for creating the global ThinLTO analysis. The structure
1144 // here is basically the same as before threads are spawned in the `run`
1145 // function of `lib/LTO/ThinLTOCodeGenerator.cpp`.
1146 extern "C" LLVMRustThinLTOData*
1147 LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
1149 const char **preserved_symbols,
1151 auto Ret = std::make_unique<LLVMRustThinLTOData>();
1153 // Load each module's summary and merge it into one combined index
1154 for (int i = 0; i < num_modules; i++) {
1155 auto module = &modules[i];
1156 StringRef buffer(module->data, module->len);
1157 MemoryBufferRef mem_buffer(buffer, module->identifier);
1159 Ret->ModuleMap[module->identifier] = mem_buffer;
1161 if (Error Err = readModuleSummaryIndex(mem_buffer, Ret->Index, i)) {
1162 LLVMRustSetLastError(toString(std::move(Err)).c_str());
1167 // Collect for each module the list of function it defines (GUID -> Summary)
1168 Ret->Index.collectDefinedGVSummariesPerModule(Ret->ModuleToDefinedGVSummaries);
1170 // Convert the preserved symbols set from string to GUID, this is then needed
1171 // for internalization.
1172 for (int i = 0; i < num_symbols; i++) {
1173 auto GUID = GlobalValue::getGUID(preserved_symbols[i]);
1174 Ret->GUIDPreservedSymbols.insert(GUID);
1177 // Collect the import/export lists for all modules from the call-graph in the
1180 // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp`
1181 auto deadIsPrevailing = [&](GlobalValue::GUID G) {
1182 return PrevailingType::Unknown;
1184 // We don't have a complete picture in our use of ThinLTO, just our immediate
1185 // crate, so we need `ImportEnabled = false` to limit internalization.
1186 // Otherwise, we sometimes lose `static` values -- see #60184.
1187 computeDeadSymbolsWithConstProp(Ret->Index, Ret->GUIDPreservedSymbols,
1188 deadIsPrevailing, /* ImportEnabled = */ false);
1189 ComputeCrossModuleImport(
1191 Ret->ModuleToDefinedGVSummaries,
1196 // Resolve LinkOnce/Weak symbols, this has to be computed early be cause it
1197 // impacts the caching.
1199 // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp` with some of this
1200 // being lifted from `lib/LTO/LTO.cpp` as well
1201 DenseMap<GlobalValue::GUID, const GlobalValueSummary *> PrevailingCopy;
1202 for (auto &I : Ret->Index) {
1203 if (I.second.SummaryList.size() > 1)
1204 PrevailingCopy[I.first] = getFirstDefinitionForLinker(I.second.SummaryList);
1206 auto isPrevailing = [&](GlobalValue::GUID GUID, const GlobalValueSummary *S) {
1207 const auto &Prevailing = PrevailingCopy.find(GUID);
1208 if (Prevailing == PrevailingCopy.end())
1210 return Prevailing->second == S;
1212 auto recordNewLinkage = [&](StringRef ModuleIdentifier,
1213 GlobalValue::GUID GUID,
1214 GlobalValue::LinkageTypes NewLinkage) {
1215 Ret->ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;
1218 // Uses FromPrevailing visibility scheme which works for many binary
1219 // formats. We probably could and should use ELF visibility scheme for many of
1220 // our targets, however.
1222 thinLTOResolvePrevailingInIndex(conf, Ret->Index, isPrevailing, recordNewLinkage,
1223 Ret->GUIDPreservedSymbols);
1225 // Here we calculate an `ExportedGUIDs` set for use in the `isExported`
1226 // callback below. This callback below will dictate the linkage for all
1227 // summaries in the index, and we basically just only want to ensure that dead
1228 // symbols are internalized. Otherwise everything that's already external
1229 // linkage will stay as external, and internal will stay as internal.
1230 std::set<GlobalValue::GUID> ExportedGUIDs;
1231 for (auto &List : Ret->Index) {
1232 for (auto &GVS: List.second.SummaryList) {
1233 if (GlobalValue::isLocalLinkage(GVS->linkage()))
1235 auto GUID = GVS->getOriginalName();
1236 if (GVS->flags().Live)
1237 ExportedGUIDs.insert(GUID);
1240 auto isExported = [&](StringRef ModuleIdentifier, ValueInfo VI) {
1241 const auto &ExportList = Ret->ExportLists.find(ModuleIdentifier);
1242 return (ExportList != Ret->ExportLists.end() &&
1243 ExportList->second.count(VI)) ||
1244 ExportedGUIDs.count(VI.getGUID());
1246 thinLTOInternalizeAndPromoteInIndex(Ret->Index, isExported, isPrevailing);
1248 return Ret.release();
1252 LLVMRustFreeThinLTOData(LLVMRustThinLTOData *Data) {
1256 // Below are the various passes that happen *per module* when doing ThinLTO.
1258 // In other words, these are the functions that are all run concurrently
1259 // with one another, one per module. The passes here correspond to the analysis
1260 // passes in `lib/LTO/ThinLTOCodeGenerator.cpp`, currently found in the
1261 // `ProcessThinLTOModule` function. Here they're split up into separate steps
1262 // so rustc can save off the intermediate bytecode between each step.
1265 clearDSOLocalOnDeclarations(Module &Mod, TargetMachine &TM) {
1266 // When linking an ELF shared object, dso_local should be dropped. We
1267 // conservatively do this for -fpic.
1268 bool ClearDSOLocalOnDeclarations =
1269 TM.getTargetTriple().isOSBinFormatELF() &&
1270 TM.getRelocationModel() != Reloc::Static &&
1271 Mod.getPIELevel() == PIELevel::Default;
1272 return ClearDSOLocalOnDeclarations;
1276 LLVMRustPrepareThinLTORename(const LLVMRustThinLTOData *Data, LLVMModuleRef M,
1277 LLVMTargetMachineRef TM) {
1278 Module &Mod = *unwrap(M);
1279 TargetMachine &Target = *unwrap(TM);
1281 bool ClearDSOLocal = clearDSOLocalOnDeclarations(Mod, Target);
1282 bool error = renameModuleForThinLTO(Mod, Data->Index, ClearDSOLocal);
1285 LLVMRustSetLastError("renameModuleForThinLTO failed");
1292 LLVMRustPrepareThinLTOResolveWeak(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
1293 Module &Mod = *unwrap(M);
1294 const auto &DefinedGlobals = Data->ModuleToDefinedGVSummaries.lookup(Mod.getModuleIdentifier());
1295 #if LLVM_VERSION_GE(14, 0)
1296 thinLTOFinalizeInModule(Mod, DefinedGlobals, /*PropagateAttrs=*/true);
1298 thinLTOResolvePrevailingInModule(Mod, DefinedGlobals);
1304 LLVMRustPrepareThinLTOInternalize(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
1305 Module &Mod = *unwrap(M);
1306 const auto &DefinedGlobals = Data->ModuleToDefinedGVSummaries.lookup(Mod.getModuleIdentifier());
1307 thinLTOInternalizeModule(Mod, DefinedGlobals);
1312 LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, LLVMModuleRef M,
1313 LLVMTargetMachineRef TM) {
1314 Module &Mod = *unwrap(M);
1315 TargetMachine &Target = *unwrap(TM);
1317 const auto &ImportList = Data->ImportLists.lookup(Mod.getModuleIdentifier());
1318 auto Loader = [&](StringRef Identifier) {
1319 const auto &Memory = Data->ModuleMap.lookup(Identifier);
1320 auto &Context = Mod.getContext();
1321 auto MOrErr = getLazyBitcodeModule(Memory, Context, true, true);
1326 // The rest of this closure is a workaround for
1327 // https://bugs.llvm.org/show_bug.cgi?id=38184 where during ThinLTO imports
1328 // we accidentally import wasm custom sections into different modules,
1329 // duplicating them by in the final output artifact.
1331 // The issue is worked around here by manually removing the
1332 // `wasm.custom_sections` named metadata node from any imported module. This
1333 // we know isn't used by any optimization pass so there's no need for it to
1336 // Note that the metadata is currently lazily loaded, so we materialize it
1337 // here before looking up if there's metadata inside. The `FunctionImporter`
1338 // will immediately materialize metadata anyway after an import, so this
1339 // shouldn't be a perf hit.
1340 if (Error Err = (*MOrErr)->materializeMetadata()) {
1341 Expected<std::unique_ptr<Module>> Ret(std::move(Err));
1345 auto *WasmCustomSections = (*MOrErr)->getNamedMetadata("wasm.custom_sections");
1346 if (WasmCustomSections)
1347 WasmCustomSections->eraseFromParent();
1351 bool ClearDSOLocal = clearDSOLocalOnDeclarations(Mod, Target);
1352 FunctionImporter Importer(Data->Index, Loader, ClearDSOLocal);
1353 Expected<bool> Result = Importer.importFunctions(Mod, ImportList);
1355 LLVMRustSetLastError(toString(Result.takeError()).c_str());
1361 // This struct and various functions are sort of a hack right now, but the
1362 // problem is that we've got in-memory LLVM modules after we generate and
1363 // optimize all codegen-units for one compilation in rustc. To be compatible
1364 // with the LTO support above we need to serialize the modules plus their
1365 // ThinLTO summary into memory.
1367 // This structure is basically an owned version of a serialize module, with
1368 // a ThinLTO summary attached.
1369 struct LLVMRustThinLTOBuffer {
1373 extern "C" LLVMRustThinLTOBuffer*
1374 LLVMRustThinLTOBufferCreate(LLVMModuleRef M, bool is_thin) {
1375 auto Ret = std::make_unique<LLVMRustThinLTOBuffer>();
1377 raw_string_ostream OS(Ret->data);
1380 #if LLVM_VERSION_LT(15, 0)
1381 legacy::PassManager PM;
1382 PM.add(createWriteThinLTOBitcodePass(OS));
1386 LoopAnalysisManager LAM;
1387 FunctionAnalysisManager FAM;
1388 CGSCCAnalysisManager CGAM;
1389 ModuleAnalysisManager MAM;
1390 PB.registerModuleAnalyses(MAM);
1391 PB.registerCGSCCAnalyses(CGAM);
1392 PB.registerFunctionAnalyses(FAM);
1393 PB.registerLoopAnalyses(LAM);
1394 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
1395 ModulePassManager MPM;
1396 MPM.addPass(ThinLTOBitcodeWriterPass(OS, nullptr));
1397 MPM.run(*unwrap(M), MAM);
1400 legacy::PassManager PM;
1401 PM.add(createBitcodeWriterPass(OS));
1406 return Ret.release();
1410 LLVMRustThinLTOBufferFree(LLVMRustThinLTOBuffer *Buffer) {
1414 extern "C" const void*
1415 LLVMRustThinLTOBufferPtr(const LLVMRustThinLTOBuffer *Buffer) {
1416 return Buffer->data.data();
1420 LLVMRustThinLTOBufferLen(const LLVMRustThinLTOBuffer *Buffer) {
1421 return Buffer->data.length();
1424 // This is what we used to parse upstream bitcode for actual ThinLTO
1425 // processing. We'll call this once per module optimized through ThinLTO, and
1426 // it'll be called concurrently on many threads.
1427 extern "C" LLVMModuleRef
1428 LLVMRustParseBitcodeForLTO(LLVMContextRef Context,
1431 const char *identifier) {
1432 StringRef Data(data, len);
1433 MemoryBufferRef Buffer(Data, identifier);
1434 unwrap(Context)->enableDebugTypeODRUniquing();
1435 Expected<std::unique_ptr<Module>> SrcOrError =
1436 parseBitcodeFile(Buffer, *unwrap(Context));
1438 LLVMRustSetLastError(toString(SrcOrError.takeError()).c_str());
1441 return wrap(std::move(*SrcOrError).release());
1444 // Find the bitcode section in the object file data and return it as a slice.
1445 // Fail if the bitcode section is present but empty.
1447 // On success, the return value is the pointer to the start of the slice and
1448 // `out_len` is filled with the (non-zero) length. On failure, the return value
1449 // is `nullptr` and `out_len` is set to zero.
1450 extern "C" const char*
1451 LLVMRustGetBitcodeSliceFromObjectData(const char *data,
1456 StringRef Data(data, len);
1457 MemoryBufferRef Buffer(Data, ""); // The id is unused.
1459 Expected<MemoryBufferRef> BitcodeOrError =
1460 object::IRObjectFile::findBitcodeInMemBuffer(Buffer);
1461 if (!BitcodeOrError) {
1462 LLVMRustSetLastError(toString(BitcodeOrError.takeError()).c_str());
1466 *out_len = BitcodeOrError->getBufferSize();
1467 return BitcodeOrError->getBufferStart();
1470 // Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
1471 // the comment in `back/lto.rs` for why this exists.
1473 LLVMRustThinLTOGetDICompileUnit(LLVMModuleRef Mod,
1475 DICompileUnit **B) {
1476 Module *M = unwrap(Mod);
1477 DICompileUnit **Cur = A;
1478 DICompileUnit **Next = B;
1479 for (DICompileUnit *CU : M->debug_compile_units()) {
1488 // Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
1489 // the comment in `back/lto.rs` for why this exists.
1491 LLVMRustThinLTOPatchDICompileUnit(LLVMModuleRef Mod, DICompileUnit *Unit) {
1492 Module *M = unwrap(Mod);
1494 // If the original source module didn't have a `DICompileUnit` then try to
1495 // merge all the existing compile units. If there aren't actually any though
1496 // then there's not much for us to do so return.
1497 if (Unit == nullptr) {
1498 for (DICompileUnit *CU : M->debug_compile_units()) {
1502 if (Unit == nullptr)
1506 // Use LLVM's built-in `DebugInfoFinder` to find a bunch of debuginfo and
1507 // process it recursively. Note that we used to specifically iterate over
1508 // instructions to ensure we feed everything into it, but `processModule`
1509 // started doing this the same way in LLVM 7 (commit d769eb36ab2b8).
1510 DebugInfoFinder Finder;
1511 Finder.processModule(*M);
1513 // After we've found all our debuginfo, rewrite all subprograms to point to
1514 // the same `DICompileUnit`.
1515 for (auto &F : Finder.subprograms()) {
1516 F->replaceUnit(Unit);
1519 // Erase any other references to other `DICompileUnit` instances, the verifier
1520 // will later ensure that we don't actually have any other stale references to
1522 auto *MD = M->getNamedMetadata("llvm.dbg.cu");
1523 MD->clearOperands();
1524 MD->addOperand(Unit);
1527 // Computes the LTO cache key for the provided 'ModId' in the given 'Data',
1528 // storing the result in 'KeyOut'.
1529 // Currently, this cache key is a SHA-1 hash of anything that could affect
1530 // the result of optimizing this module (e.g. module imports, exports, liveness
1531 // of access globals, etc).
1532 // The precise details are determined by LLVM in `computeLTOCacheKey`, which is
1533 // used during the normal linker-plugin incremental thin-LTO process.
1535 LLVMRustComputeLTOCacheKey(RustStringRef KeyOut, const char *ModId, LLVMRustThinLTOData *Data) {
1536 SmallString<40> Key;
1537 llvm::lto::Config conf;
1538 const auto &ImportList = Data->ImportLists.lookup(ModId);
1539 const auto &ExportList = Data->ExportLists.lookup(ModId);
1540 const auto &ResolvedODR = Data->ResolvedODR.lookup(ModId);
1541 const auto &DefinedGlobals = Data->ModuleToDefinedGVSummaries.lookup(ModId);
1542 std::set<GlobalValue::GUID> CfiFunctionDefs;
1543 std::set<GlobalValue::GUID> CfiFunctionDecls;
1545 // Based on the 'InProcessThinBackend' constructor in LLVM
1546 for (auto &Name : Data->Index.cfiFunctionDefs())
1547 CfiFunctionDefs.insert(
1548 GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Name)));
1549 for (auto &Name : Data->Index.cfiFunctionDecls())
1550 CfiFunctionDecls.insert(
1551 GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Name)));
1553 llvm::computeLTOCacheKey(Key, conf, Data->Index, ModId,
1554 ImportList, ExportList, ResolvedODR, DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls
1557 LLVMRustStringWriteImpl(KeyOut, Key.c_str(), Key.size());