8 #include "llvm/Analysis/TargetLibraryInfo.h"
9 #include "llvm/Analysis/TargetTransformInfo.h"
10 #include "llvm/CodeGen/TargetSubtargetInfo.h"
11 #include "llvm/InitializePasses.h"
12 #include "llvm/IR/AutoUpgrade.h"
13 #include "llvm/IR/AssemblyAnnotationWriter.h"
14 #include "llvm/IR/IntrinsicInst.h"
15 #include "llvm/IR/Verifier.h"
16 #include "llvm/Object/ObjectFile.h"
17 #include "llvm/Object/IRObjectFile.h"
18 #include "llvm/Passes/PassBuilder.h"
19 #if LLVM_VERSION_GE(9, 0)
20 #include "llvm/Passes/StandardInstrumentations.h"
22 #include "llvm/Support/CBindingWrapping.h"
23 #include "llvm/Support/FileSystem.h"
24 #include "llvm/Support/Host.h"
25 #include "llvm/Target/TargetMachine.h"
26 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
27 #include "llvm/Transforms/IPO/AlwaysInliner.h"
28 #include "llvm/Transforms/IPO/FunctionImport.h"
29 #include "llvm/Transforms/Utils/FunctionImportUtils.h"
30 #include "llvm/LTO/LTO.h"
31 #include "llvm-c/Transforms/PassManagerBuilder.h"
33 #include "llvm/Transforms/Instrumentation.h"
34 #if LLVM_VERSION_GE(9, 0)
35 #include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
36 #include "llvm/Support/TimeProfiler.h"
38 #include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
39 #include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
40 #if LLVM_VERSION_GE(9, 0)
41 #include "llvm/Transforms/Utils/CanonicalizeAliases.h"
43 #include "llvm/Transforms/Utils/NameAnonGlobals.h"
47 typedef struct LLVMOpaquePass *LLVMPassRef;
48 typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef;
50 DEFINE_STDCXX_CONVERSION_FUNCTIONS(Pass, LLVMPassRef)
51 DEFINE_STDCXX_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
52 DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassManagerBuilder,
53 LLVMPassManagerBuilderRef)
55 extern "C" void LLVMInitializePasses() {
56 PassRegistry &Registry = *PassRegistry::getPassRegistry();
57 initializeCore(Registry);
58 initializeCodeGen(Registry);
59 initializeScalarOpts(Registry);
60 initializeVectorization(Registry);
61 initializeIPO(Registry);
62 initializeAnalysis(Registry);
63 initializeTransformUtils(Registry);
64 initializeInstCombine(Registry);
65 initializeInstrumentation(Registry);
66 initializeTarget(Registry);
69 extern "C" void LLVMTimeTraceProfilerInitialize() {
70 #if LLVM_VERSION_GE(10, 0)
71 timeTraceProfilerInitialize(
72 /* TimeTraceGranularity */ 0,
73 /* ProcName */ "rustc");
74 #elif LLVM_VERSION_GE(9, 0)
75 timeTraceProfilerInitialize();
79 extern "C" void LLVMTimeTraceProfilerFinish(const char* FileName) {
80 #if LLVM_VERSION_GE(9, 0)
81 StringRef FN(FileName);
83 raw_fd_ostream OS(FN, EC, sys::fs::CD_CreateAlways);
85 timeTraceProfilerWrite(OS);
86 timeTraceProfilerCleanup();
90 enum class LLVMRustPassKind {
96 static LLVMRustPassKind toRust(PassKind Kind) {
99 return LLVMRustPassKind::Function;
101 return LLVMRustPassKind::Module;
103 return LLVMRustPassKind::Other;
107 extern "C" LLVMPassRef LLVMRustFindAndCreatePass(const char *PassName) {
108 StringRef SR(PassName);
109 PassRegistry *PR = PassRegistry::getPassRegistry();
111 const PassInfo *PI = PR->getPassInfo(SR);
113 return wrap(PI->createPass());
118 extern "C" LLVMPassRef LLVMRustCreateAddressSanitizerFunctionPass(bool Recover) {
119 const bool CompileKernel = false;
120 const bool UseAfterScope = true;
122 return wrap(createAddressSanitizerFunctionPass(CompileKernel, Recover, UseAfterScope));
125 extern "C" LLVMPassRef LLVMRustCreateModuleAddressSanitizerPass(bool Recover) {
126 const bool CompileKernel = false;
128 #if LLVM_VERSION_GE(9, 0)
129 return wrap(createModuleAddressSanitizerLegacyPassPass(CompileKernel, Recover));
131 return wrap(createAddressSanitizerModulePass(CompileKernel, Recover));
135 extern "C" LLVMPassRef LLVMRustCreateMemorySanitizerPass(int TrackOrigins, bool Recover) {
136 #if LLVM_VERSION_GE(9, 0)
137 const bool CompileKernel = false;
139 return wrap(createMemorySanitizerLegacyPassPass(
140 MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel}));
142 return wrap(createMemorySanitizerLegacyPassPass(TrackOrigins, Recover));
146 extern "C" LLVMPassRef LLVMRustCreateThreadSanitizerPass() {
147 return wrap(createThreadSanitizerLegacyPassPass());
150 extern "C" LLVMRustPassKind LLVMRustPassKind(LLVMPassRef RustPass) {
152 Pass *Pass = unwrap(RustPass);
153 return toRust(Pass->getPassKind());
156 extern "C" void LLVMRustAddPass(LLVMPassManagerRef PMR, LLVMPassRef RustPass) {
158 Pass *Pass = unwrap(RustPass);
159 PassManagerBase *PMB = unwrap(PMR);
164 void LLVMRustPassManagerBuilderPopulateThinLTOPassManager(
165 LLVMPassManagerBuilderRef PMBR,
166 LLVMPassManagerRef PMR
168 unwrap(PMBR)->populateThinLTOPassManager(*unwrap(PMR));
172 void LLVMRustAddLastExtensionPasses(
173 LLVMPassManagerBuilderRef PMBR, LLVMPassRef *Passes, size_t NumPasses) {
174 auto AddExtensionPasses = [Passes, NumPasses](
175 const PassManagerBuilder &Builder, PassManagerBase &PM) {
176 for (size_t I = 0; I < NumPasses; I++) {
177 PM.add(unwrap(Passes[I]));
180 // Add the passes to both of the pre-finalization extension points,
181 // so they are run for optimized and non-optimized builds.
182 unwrap(PMBR)->addExtension(PassManagerBuilder::EP_OptimizerLast,
184 unwrap(PMBR)->addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
188 #ifdef LLVM_COMPONENT_X86
189 #define SUBTARGET_X86 SUBTARGET(X86)
191 #define SUBTARGET_X86
194 #ifdef LLVM_COMPONENT_ARM
195 #define SUBTARGET_ARM SUBTARGET(ARM)
197 #define SUBTARGET_ARM
200 #ifdef LLVM_COMPONENT_AARCH64
201 #define SUBTARGET_AARCH64 SUBTARGET(AArch64)
203 #define SUBTARGET_AARCH64
206 #ifdef LLVM_COMPONENT_MIPS
207 #define SUBTARGET_MIPS SUBTARGET(Mips)
209 #define SUBTARGET_MIPS
212 #ifdef LLVM_COMPONENT_POWERPC
213 #define SUBTARGET_PPC SUBTARGET(PPC)
215 #define SUBTARGET_PPC
218 #ifdef LLVM_COMPONENT_SYSTEMZ
219 #define SUBTARGET_SYSTEMZ SUBTARGET(SystemZ)
221 #define SUBTARGET_SYSTEMZ
224 #ifdef LLVM_COMPONENT_MSP430
225 #define SUBTARGET_MSP430 SUBTARGET(MSP430)
227 #define SUBTARGET_MSP430
230 #ifdef LLVM_COMPONENT_RISCV
231 #define SUBTARGET_RISCV SUBTARGET(RISCV)
233 #define SUBTARGET_RISCV
236 #ifdef LLVM_COMPONENT_SPARC
237 #define SUBTARGET_SPARC SUBTARGET(Sparc)
239 #define SUBTARGET_SPARC
242 #ifdef LLVM_COMPONENT_HEXAGON
243 #define SUBTARGET_HEXAGON SUBTARGET(Hexagon)
245 #define SUBTARGET_HEXAGON
248 #define GEN_SUBTARGETS \
260 #define SUBTARGET(x) \
262 extern const SubtargetFeatureKV x##FeatureKV[]; \
263 extern const SubtargetFeatureKV x##SubTypeKV[]; \
269 extern "C" bool LLVMRustHasFeature(LLVMTargetMachineRef TM,
270 const char *Feature) {
271 TargetMachine *Target = unwrap(TM);
272 const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
273 return MCInfo->checkFeatures(std::string("+") + Feature);
276 enum class LLVMRustCodeModel {
285 static Optional<CodeModel::Model> fromRust(LLVMRustCodeModel Model) {
287 case LLVMRustCodeModel::Tiny:
288 return CodeModel::Tiny;
289 case LLVMRustCodeModel::Small:
290 return CodeModel::Small;
291 case LLVMRustCodeModel::Kernel:
292 return CodeModel::Kernel;
293 case LLVMRustCodeModel::Medium:
294 return CodeModel::Medium;
295 case LLVMRustCodeModel::Large:
296 return CodeModel::Large;
297 case LLVMRustCodeModel::None:
300 report_fatal_error("Bad CodeModel.");
304 enum class LLVMRustCodeGenOptLevel {
312 static CodeGenOpt::Level fromRust(LLVMRustCodeGenOptLevel Level) {
314 case LLVMRustCodeGenOptLevel::None:
315 return CodeGenOpt::None;
316 case LLVMRustCodeGenOptLevel::Less:
317 return CodeGenOpt::Less;
318 case LLVMRustCodeGenOptLevel::Default:
319 return CodeGenOpt::Default;
320 case LLVMRustCodeGenOptLevel::Aggressive:
321 return CodeGenOpt::Aggressive;
323 report_fatal_error("Bad CodeGenOptLevel.");
327 enum class LLVMRustPassBuilderOptLevel {
336 static PassBuilder::OptimizationLevel fromRust(LLVMRustPassBuilderOptLevel Level) {
338 case LLVMRustPassBuilderOptLevel::O0:
339 return PassBuilder::O0;
340 case LLVMRustPassBuilderOptLevel::O1:
341 return PassBuilder::O1;
342 case LLVMRustPassBuilderOptLevel::O2:
343 return PassBuilder::O2;
344 case LLVMRustPassBuilderOptLevel::O3:
345 return PassBuilder::O3;
346 case LLVMRustPassBuilderOptLevel::Os:
347 return PassBuilder::Os;
348 case LLVMRustPassBuilderOptLevel::Oz:
349 return PassBuilder::Oz;
351 report_fatal_error("Bad PassBuilderOptLevel.");
355 enum class LLVMRustRelocModel {
364 static Reloc::Model fromRust(LLVMRustRelocModel RustReloc) {
366 case LLVMRustRelocModel::Static:
367 return Reloc::Static;
368 case LLVMRustRelocModel::PIC:
370 case LLVMRustRelocModel::DynamicNoPic:
371 return Reloc::DynamicNoPIC;
372 case LLVMRustRelocModel::ROPI:
374 case LLVMRustRelocModel::RWPI:
376 case LLVMRustRelocModel::ROPIRWPI:
377 return Reloc::ROPI_RWPI;
379 report_fatal_error("Bad RelocModel.");
383 /// getLongestEntryLength - Return the length of the longest entry in the table.
384 template<typename KV>
385 static size_t getLongestEntryLength(ArrayRef<KV> Table) {
387 for (auto &I : Table)
388 MaxLen = std::max(MaxLen, std::strlen(I.Key));
392 extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM) {
393 const TargetMachine *Target = unwrap(TM);
394 const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
395 const Triple::ArchType HostArch = Triple(sys::getProcessTriple()).getArch();
396 const Triple::ArchType TargetArch = Target->getTargetTriple().getArch();
397 const ArrayRef<SubtargetSubTypeKV> CPUTable = MCInfo->getCPUTable();
398 unsigned MaxCPULen = getLongestEntryLength(CPUTable);
400 printf("Available CPUs for this target:\n");
401 if (HostArch == TargetArch) {
402 const StringRef HostCPU = sys::getHostCPUName();
403 printf(" %-*s - Select the CPU of the current host (currently %.*s).\n",
404 MaxCPULen, "native", (int)HostCPU.size(), HostCPU.data());
406 for (auto &CPU : CPUTable)
407 printf(" %-*s\n", MaxCPULen, CPU.Key);
411 extern "C" void LLVMRustPrintTargetFeatures(LLVMTargetMachineRef TM) {
412 const TargetMachine *Target = unwrap(TM);
413 const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
414 const ArrayRef<SubtargetFeatureKV> FeatTable = MCInfo->getFeatureTable();
415 unsigned MaxFeatLen = getLongestEntryLength(FeatTable);
417 printf("Available features for this target:\n");
418 for (auto &Feature : FeatTable)
419 printf(" %-*s - %s.\n", MaxFeatLen, Feature.Key, Feature.Desc);
422 printf("Use +feature to enable a feature, or -feature to disable it.\n"
423 "For example, rustc -C -target-cpu=mycpu -C "
424 "target-feature=+feature1,-feature2\n\n");
429 extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef) {
430 printf("Target CPU help is not supported by this LLVM version.\n\n");
433 extern "C" void LLVMRustPrintTargetFeatures(LLVMTargetMachineRef) {
434 printf("Target features help is not supported by this LLVM version.\n\n");
438 extern "C" const char* LLVMRustGetHostCPUName(size_t *len) {
439 StringRef Name = sys::getHostCPUName();
444 extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
445 const char *TripleStr, const char *CPU, const char *Feature,
446 const char *ABIStr, LLVMRustCodeModel RustCM, LLVMRustRelocModel RustReloc,
447 LLVMRustCodeGenOptLevel RustOptLevel, bool UseSoftFloat,
448 bool FunctionSections,
450 bool TrapUnreachable,
453 bool EmitStackSizeSection,
454 bool RelaxELFRelocations,
457 auto OptLevel = fromRust(RustOptLevel);
458 auto RM = fromRust(RustReloc);
459 auto CM = fromRust(RustCM);
462 Triple Trip(Triple::normalize(TripleStr));
463 const llvm::Target *TheTarget =
464 TargetRegistry::lookupTarget(Trip.getTriple(), Error);
465 if (TheTarget == nullptr) {
466 LLVMRustSetLastError(Error.c_str());
470 TargetOptions Options;
472 Options.FloatABIType = FloatABI::Default;
474 Options.FloatABIType = FloatABI::Soft;
476 Options.DataSections = DataSections;
477 Options.FunctionSections = FunctionSections;
478 Options.MCOptions.AsmVerbose = AsmComments;
479 Options.MCOptions.PreserveAsmComments = AsmComments;
480 Options.MCOptions.ABIName = ABIStr;
481 Options.RelaxELFRelocations = RelaxELFRelocations;
482 Options.UseInitArray = UseInitArray;
484 if (TrapUnreachable) {
485 // Tell LLVM to codegen `unreachable` into an explicit trap instruction.
486 // This limits the extent of possible undefined behavior in some cases, as
487 // it prevents control flow from "falling through" into whatever code
488 // happens to be laid out next in memory.
489 Options.TrapUnreachable = true;
493 Options.ThreadModel = ThreadModel::Single;
496 Options.EmitStackSizeSection = EmitStackSizeSection;
498 TargetMachine *TM = TheTarget->createTargetMachine(
499 Trip.getTriple(), CPU, Feature, Options, RM, CM, OptLevel);
503 extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) {
507 extern "C" void LLVMRustConfigurePassManagerBuilder(
508 LLVMPassManagerBuilderRef PMBR, LLVMRustCodeGenOptLevel OptLevel,
509 bool MergeFunctions, bool SLPVectorize, bool LoopVectorize, bool PrepareForThinLTO,
510 const char* PGOGenPath, const char* PGOUsePath) {
511 unwrap(PMBR)->MergeFunctions = MergeFunctions;
512 unwrap(PMBR)->SLPVectorize = SLPVectorize;
513 unwrap(PMBR)->OptLevel = fromRust(OptLevel);
514 unwrap(PMBR)->LoopVectorize = LoopVectorize;
515 unwrap(PMBR)->PrepareForThinLTO = PrepareForThinLTO;
519 unwrap(PMBR)->EnablePGOInstrGen = true;
520 unwrap(PMBR)->PGOInstrGen = PGOGenPath;
524 unwrap(PMBR)->PGOInstrUse = PGOUsePath;
528 // Unfortunately, the LLVM C API doesn't provide a way to set the `LibraryInfo`
529 // field of a PassManagerBuilder, we expose our own method of doing so.
530 extern "C" void LLVMRustAddBuilderLibraryInfo(LLVMPassManagerBuilderRef PMBR,
532 bool DisableSimplifyLibCalls) {
533 Triple TargetTriple(unwrap(M)->getTargetTriple());
534 TargetLibraryInfoImpl *TLI = new TargetLibraryInfoImpl(TargetTriple);
535 if (DisableSimplifyLibCalls)
536 TLI->disableAllFunctions();
537 unwrap(PMBR)->LibraryInfo = TLI;
540 // Unfortunately, the LLVM C API doesn't provide a way to create the
541 // TargetLibraryInfo pass, so we use this method to do so.
542 extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR, LLVMModuleRef M,
543 bool DisableSimplifyLibCalls) {
544 Triple TargetTriple(unwrap(M)->getTargetTriple());
545 TargetLibraryInfoImpl TLII(TargetTriple);
546 if (DisableSimplifyLibCalls)
547 TLII.disableAllFunctions();
548 unwrap(PMR)->add(new TargetLibraryInfoWrapperPass(TLII));
551 // Unfortunately, the LLVM C API doesn't provide an easy way of iterating over
552 // all the functions in a module, so we do that manually here. You'll find
553 // similar code in clang's BackendUtil.cpp file.
554 extern "C" void LLVMRustRunFunctionPassManager(LLVMPassManagerRef PMR,
556 llvm::legacy::FunctionPassManager *P =
557 unwrap<llvm::legacy::FunctionPassManager>(PMR);
558 P->doInitialization();
560 // Upgrade all calls to old intrinsics first.
561 for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E;)
562 UpgradeCallsToIntrinsic(&*I++); // must be post-increment, as we remove
564 for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E;
566 if (!I->isDeclaration())
572 extern "C" void LLVMRustSetLLVMOptions(int Argc, char **Argv) {
573 // Initializing the command-line options more than once is not allowed. So,
574 // check if they've already been initialized. (This could happen if we're
575 // being called from rustpkg, for example). If the arguments change, then
576 // that's just kinda unfortunate.
577 static bool Initialized = false;
581 cl::ParseCommandLineOptions(Argc, Argv);
584 enum class LLVMRustFileType {
590 #if LLVM_VERSION_GE(10, 0)
591 static CodeGenFileType fromRust(LLVMRustFileType Type) {
593 case LLVMRustFileType::AssemblyFile:
594 return CGFT_AssemblyFile;
595 case LLVMRustFileType::ObjectFile:
596 return CGFT_ObjectFile;
598 report_fatal_error("Bad FileType.");
602 static TargetMachine::CodeGenFileType fromRust(LLVMRustFileType Type) {
604 case LLVMRustFileType::AssemblyFile:
605 return TargetMachine::CGFT_AssemblyFile;
606 case LLVMRustFileType::ObjectFile:
607 return TargetMachine::CGFT_ObjectFile;
609 report_fatal_error("Bad FileType.");
614 extern "C" LLVMRustResult
615 LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR,
616 LLVMModuleRef M, const char *Path,
617 LLVMRustFileType RustFileType) {
618 llvm::legacy::PassManager *PM = unwrap<llvm::legacy::PassManager>(PMR);
619 auto FileType = fromRust(RustFileType);
621 std::string ErrorInfo;
623 raw_fd_ostream OS(Path, EC, sys::fs::F_None);
625 ErrorInfo = EC.message();
626 if (ErrorInfo != "") {
627 LLVMRustSetLastError(ErrorInfo.c_str());
628 return LLVMRustResult::Failure;
631 buffer_ostream BOS(OS);
632 unwrap(Target)->addPassesToEmitFile(*PM, BOS, nullptr, FileType, false);
635 // Apparently `addPassesToEmitFile` adds a pointer to our on-the-stack output
636 // stream (OS), so the only real safe place to delete this is here? Don't we
637 // wish this was written in Rust?
638 LLVMDisposePassManager(PMR);
639 return LLVMRustResult::Success;
642 extern "C" typedef void (*LLVMRustSelfProfileBeforePassCallback)(void*, // LlvmSelfProfiler
643 const char*, // pass name
644 const char*); // IR name
645 extern "C" typedef void (*LLVMRustSelfProfileAfterPassCallback)(void*); // LlvmSelfProfiler
647 #if LLVM_VERSION_GE(9, 0)
649 std::string LLVMRustwrappedIrGetName(const llvm::Any &WrappedIr) {
650 if (any_isa<const Module *>(WrappedIr))
651 return any_cast<const Module *>(WrappedIr)->getName().str();
652 if (any_isa<const Function *>(WrappedIr))
653 return any_cast<const Function *>(WrappedIr)->getName().str();
654 if (any_isa<const Loop *>(WrappedIr))
655 return any_cast<const Loop *>(WrappedIr)->getName().str();
656 if (any_isa<const LazyCallGraph::SCC *>(WrappedIr))
657 return any_cast<const LazyCallGraph::SCC *>(WrappedIr)->getName();
662 void LLVMSelfProfileInitializeCallbacks(
663 PassInstrumentationCallbacks& PIC, void* LlvmSelfProfiler,
664 LLVMRustSelfProfileBeforePassCallback BeforePassCallback,
665 LLVMRustSelfProfileAfterPassCallback AfterPassCallback) {
666 PIC.registerBeforePassCallback([LlvmSelfProfiler, BeforePassCallback](
667 StringRef Pass, llvm::Any Ir) {
668 std::string PassName = Pass.str();
669 std::string IrName = LLVMRustwrappedIrGetName(Ir);
670 BeforePassCallback(LlvmSelfProfiler, PassName.c_str(), IrName.c_str());
674 PIC.registerAfterPassCallback(
675 [LlvmSelfProfiler, AfterPassCallback](StringRef Pass, llvm::Any Ir) {
676 AfterPassCallback(LlvmSelfProfiler);
679 PIC.registerAfterPassInvalidatedCallback(
680 [LlvmSelfProfiler, AfterPassCallback](StringRef Pass) {
681 AfterPassCallback(LlvmSelfProfiler);
684 PIC.registerBeforeAnalysisCallback([LlvmSelfProfiler, BeforePassCallback](
685 StringRef Pass, llvm::Any Ir) {
686 std::string PassName = Pass.str();
687 std::string IrName = LLVMRustwrappedIrGetName(Ir);
688 BeforePassCallback(LlvmSelfProfiler, PassName.c_str(), IrName.c_str());
691 PIC.registerAfterAnalysisCallback(
692 [LlvmSelfProfiler, AfterPassCallback](StringRef Pass, llvm::Any Ir) {
693 AfterPassCallback(LlvmSelfProfiler);
698 enum class LLVMRustOptStage {
706 struct LLVMRustSanitizerOptions {
709 bool SanitizeAddress;
710 bool SanitizeRecover;
711 int SanitizeMemoryTrackOrigins;
715 LLVMRustOptimizeWithNewPassManager(
716 LLVMModuleRef ModuleRef,
717 LLVMTargetMachineRef TMRef,
718 LLVMRustPassBuilderOptLevel OptLevelRust,
719 LLVMRustOptStage OptStage,
720 bool NoPrepopulatePasses, bool VerifyIR, bool UseThinLTOBuffers,
721 bool MergeFunctions, bool UnrollLoops, bool SLPVectorize, bool LoopVectorize,
722 bool DisableSimplifyLibCalls, bool EmitLifetimeMarkers,
723 LLVMRustSanitizerOptions *SanitizerOptions,
724 const char *PGOGenPath, const char *PGOUsePath,
725 void* LlvmSelfProfiler,
726 LLVMRustSelfProfileBeforePassCallback BeforePassCallback,
727 LLVMRustSelfProfileAfterPassCallback AfterPassCallback) {
728 #if LLVM_VERSION_GE(9, 0)
729 Module *TheModule = unwrap(ModuleRef);
730 TargetMachine *TM = unwrap(TMRef);
731 PassBuilder::OptimizationLevel OptLevel = fromRust(OptLevelRust);
733 // FIXME: MergeFunctions is not supported by NewPM yet.
734 (void) MergeFunctions;
736 PipelineTuningOptions PTO;
737 PTO.LoopUnrolling = UnrollLoops;
738 PTO.LoopInterleaving = UnrollLoops;
739 PTO.LoopVectorization = LoopVectorize;
740 PTO.SLPVectorization = SLPVectorize;
742 PassInstrumentationCallbacks PIC;
743 StandardInstrumentations SI;
744 SI.registerCallbacks(PIC);
746 if (LlvmSelfProfiler){
747 LLVMSelfProfileInitializeCallbacks(PIC,LlvmSelfProfiler,BeforePassCallback,AfterPassCallback);
750 Optional<PGOOptions> PGOOpt;
753 PGOOpt = PGOOptions(PGOGenPath, "", "", PGOOptions::IRInstr);
754 } else if (PGOUsePath) {
756 PGOOpt = PGOOptions(PGOUsePath, "", "", PGOOptions::IRUse);
759 PassBuilder PB(TM, PTO, PGOOpt, &PIC);
761 // FIXME: We may want to expose this as an option.
762 bool DebugPassManager = false;
763 LoopAnalysisManager LAM(DebugPassManager);
764 FunctionAnalysisManager FAM(DebugPassManager);
765 CGSCCAnalysisManager CGAM(DebugPassManager);
766 ModuleAnalysisManager MAM(DebugPassManager);
768 FAM.registerPass([&] { return PB.buildDefaultAAPipeline(); });
770 Triple TargetTriple(TheModule->getTargetTriple());
771 std::unique_ptr<TargetLibraryInfoImpl> TLII(new TargetLibraryInfoImpl(TargetTriple));
772 if (DisableSimplifyLibCalls)
773 TLII->disableAllFunctions();
774 FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
776 PB.registerModuleAnalyses(MAM);
777 PB.registerCGSCCAnalyses(CGAM);
778 PB.registerFunctionAnalyses(FAM);
779 PB.registerLoopAnalyses(LAM);
780 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
782 // We manually collect pipeline callbacks so we can apply them at O0, where the
783 // PassBuilder does not create a pipeline.
784 std::vector<std::function<void(ModulePassManager &)>> PipelineStartEPCallbacks;
785 std::vector<std::function<void(FunctionPassManager &, PassBuilder::OptimizationLevel)>>
786 OptimizerLastEPCallbacks;
789 PipelineStartEPCallbacks.push_back([VerifyIR](ModulePassManager &MPM) {
790 MPM.addPass(VerifierPass());
794 if (SanitizerOptions) {
795 if (SanitizerOptions->SanitizeMemory) {
796 MemorySanitizerOptions Options(
797 SanitizerOptions->SanitizeMemoryTrackOrigins,
798 SanitizerOptions->SanitizeRecover,
799 /*CompileKernel=*/false);
800 #if LLVM_VERSION_GE(10, 0)
801 PipelineStartEPCallbacks.push_back([Options](ModulePassManager &MPM) {
802 MPM.addPass(MemorySanitizerPass(Options));
805 OptimizerLastEPCallbacks.push_back(
806 [Options](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
807 FPM.addPass(MemorySanitizerPass(Options));
812 if (SanitizerOptions->SanitizeThread) {
813 #if LLVM_VERSION_GE(10, 0)
814 PipelineStartEPCallbacks.push_back([](ModulePassManager &MPM) {
815 MPM.addPass(ThreadSanitizerPass());
818 OptimizerLastEPCallbacks.push_back(
819 [](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
820 FPM.addPass(ThreadSanitizerPass());
825 if (SanitizerOptions->SanitizeAddress) {
826 PipelineStartEPCallbacks.push_back([&](ModulePassManager &MPM) {
827 MPM.addPass(RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
829 OptimizerLastEPCallbacks.push_back(
830 [SanitizerOptions](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
831 FPM.addPass(AddressSanitizerPass(
832 /*CompileKernel=*/false, SanitizerOptions->SanitizeRecover,
833 /*UseAfterScope=*/true));
836 PipelineStartEPCallbacks.push_back(
837 [SanitizerOptions](ModulePassManager &MPM) {
838 MPM.addPass(ModuleAddressSanitizerPass(
839 /*CompileKernel=*/false, SanitizerOptions->SanitizeRecover));
845 ModulePassManager MPM(DebugPassManager);
846 if (!NoPrepopulatePasses) {
847 if (OptLevel == PassBuilder::O0) {
848 for (const auto &C : PipelineStartEPCallbacks)
851 if (!OptimizerLastEPCallbacks.empty()) {
852 FunctionPassManager FPM(DebugPassManager);
853 for (const auto &C : OptimizerLastEPCallbacks)
855 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
858 MPM.addPass(AlwaysInlinerPass(EmitLifetimeMarkers));
860 #if LLVM_VERSION_GE(10, 0)
862 PB.addPGOInstrPassesForO0(
863 MPM, DebugPassManager, PGOOpt->Action == PGOOptions::IRInstr,
864 /*IsCS=*/false, PGOOpt->ProfileFile, PGOOpt->ProfileRemappingFile);
868 for (const auto &C : PipelineStartEPCallbacks)
869 PB.registerPipelineStartEPCallback(C);
870 if (OptStage != LLVMRustOptStage::PreLinkThinLTO) {
871 for (const auto &C : OptimizerLastEPCallbacks)
872 PB.registerOptimizerLastEPCallback(C);
876 case LLVMRustOptStage::PreLinkNoLTO:
877 MPM = PB.buildPerModuleDefaultPipeline(OptLevel, DebugPassManager);
879 case LLVMRustOptStage::PreLinkThinLTO:
880 MPM = PB.buildThinLTOPreLinkDefaultPipeline(OptLevel, DebugPassManager);
881 if (!OptimizerLastEPCallbacks.empty()) {
882 FunctionPassManager FPM(DebugPassManager);
883 for (const auto &C : OptimizerLastEPCallbacks)
885 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
888 case LLVMRustOptStage::PreLinkFatLTO:
889 MPM = PB.buildLTOPreLinkDefaultPipeline(OptLevel, DebugPassManager);
891 case LLVMRustOptStage::ThinLTO:
892 // FIXME: Does it make sense to pass the ModuleSummaryIndex?
893 // It only seems to be needed for C++ specific optimizations.
894 MPM = PB.buildThinLTODefaultPipeline(OptLevel, DebugPassManager, nullptr);
896 case LLVMRustOptStage::FatLTO:
897 MPM = PB.buildLTODefaultPipeline(OptLevel, DebugPassManager, nullptr);
903 if (UseThinLTOBuffers) {
904 MPM.addPass(CanonicalizeAliasesPass());
905 MPM.addPass(NameAnonGlobalPass());
908 // Upgrade all calls to old intrinsics first.
909 for (Module::iterator I = TheModule->begin(), E = TheModule->end(); I != E;)
910 UpgradeCallsToIntrinsic(&*I++); // must be post-increment, as we remove
912 MPM.run(*TheModule, MAM);
914 // The new pass manager has been available for a long time,
915 // but we don't bother supporting it on old LLVM versions.
916 report_fatal_error("New pass manager only supported since LLVM 9");
920 // Callback to demangle function name
922 // * name to be demangled
925 // * output buffer len
926 // Returns len of demangled string, or 0 if demangle failed.
927 typedef size_t (*DemangleFn)(const char*, size_t, char*, size_t);
932 class RustAssemblyAnnotationWriter : public AssemblyAnnotationWriter {
934 std::vector<char> Buf;
937 RustAssemblyAnnotationWriter(DemangleFn Demangle) : Demangle(Demangle) {}
939 // Return empty string if demangle failed
940 // or if name does not need to be demangled
941 StringRef CallDemangle(StringRef name) {
946 if (Buf.size() < name.size() * 2) {
947 // Semangled name usually shorter than mangled,
948 // but allocate twice as much memory just in case
949 Buf.resize(name.size() * 2);
952 auto R = Demangle(name.data(), name.size(), Buf.data(), Buf.size());
958 auto Demangled = StringRef(Buf.data(), R);
959 if (Demangled == name) {
960 // Do not print anything if demangled name is equal to mangled.
967 void emitFunctionAnnot(const Function *F,
968 formatted_raw_ostream &OS) override {
969 StringRef Demangled = CallDemangle(F->getName());
970 if (Demangled.empty()) {
974 OS << "; " << Demangled << "\n";
977 void emitInstructionAnnot(const Instruction *I,
978 formatted_raw_ostream &OS) override {
981 if (const CallInst *CI = dyn_cast<CallInst>(I)) {
983 Value = CI->getCalledValue();
984 } else if (const InvokeInst* II = dyn_cast<InvokeInst>(I)) {
986 Value = II->getCalledValue();
988 // Could demangle more operations, e. g.
989 // `store %place, @function`.
993 if (!Value->hasName()) {
997 StringRef Demangled = CallDemangle(Value->getName());
998 if (Demangled.empty()) {
1002 OS << "; " << Name << " " << Demangled << "\n";
1008 extern "C" LLVMRustResult
1009 LLVMRustPrintModule(LLVMModuleRef M, const char *Path, DemangleFn Demangle) {
1010 std::string ErrorInfo;
1012 raw_fd_ostream OS(Path, EC, sys::fs::F_None);
1014 ErrorInfo = EC.message();
1015 if (ErrorInfo != "") {
1016 LLVMRustSetLastError(ErrorInfo.c_str());
1017 return LLVMRustResult::Failure;
1020 RustAssemblyAnnotationWriter AAW(Demangle);
1021 formatted_raw_ostream FOS(OS);
1022 unwrap(M)->print(FOS, &AAW);
1024 return LLVMRustResult::Success;
1027 extern "C" void LLVMRustPrintPasses() {
1028 LLVMInitializePasses();
1029 struct MyListener : PassRegistrationListener {
1030 void passEnumerate(const PassInfo *Info) {
1031 StringRef PassArg = Info->getPassArgument();
1032 StringRef PassName = Info->getPassName();
1033 if (!PassArg.empty()) {
1034 // These unsigned->signed casts could theoretically overflow, but
1035 // realistically never will (and even if, the result is implementation
1036 // defined rather plain UB).
1037 printf("%15.*s - %.*s\n", (int)PassArg.size(), PassArg.data(),
1038 (int)PassName.size(), PassName.data());
1043 PassRegistry *PR = PassRegistry::getPassRegistry();
1044 PR->enumerateWith(&Listener);
1047 extern "C" void LLVMRustAddAlwaysInlinePass(LLVMPassManagerBuilderRef PMBR,
1048 bool AddLifetimes) {
1049 unwrap(PMBR)->Inliner = llvm::createAlwaysInlinerLegacyPass(AddLifetimes);
1052 extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **Symbols,
1054 llvm::legacy::PassManager passes;
1056 auto PreserveFunctions = [=](const GlobalValue &GV) {
1057 for (size_t I = 0; I < Len; I++) {
1058 if (GV.getName() == Symbols[I]) {
1065 passes.add(llvm::createInternalizePass(PreserveFunctions));
1067 passes.run(*unwrap(M));
1070 extern "C" void LLVMRustMarkAllFunctionsNounwind(LLVMModuleRef M) {
1071 for (Module::iterator GV = unwrap(M)->begin(), E = unwrap(M)->end(); GV != E;
1073 GV->setDoesNotThrow();
1074 Function *F = dyn_cast<Function>(GV);
1078 for (Function::iterator B = F->begin(), BE = F->end(); B != BE; ++B) {
1079 for (BasicBlock::iterator I = B->begin(), IE = B->end(); I != IE; ++I) {
1080 if (isa<InvokeInst>(I)) {
1081 InvokeInst *CI = cast<InvokeInst>(I);
1082 CI->setDoesNotThrow();
1090 LLVMRustSetDataLayoutFromTargetMachine(LLVMModuleRef Module,
1091 LLVMTargetMachineRef TMR) {
1092 TargetMachine *Target = unwrap(TMR);
1093 unwrap(Module)->setDataLayout(Target->createDataLayout());
1096 extern "C" void LLVMRustSetModulePICLevel(LLVMModuleRef M) {
1097 unwrap(M)->setPICLevel(PICLevel::Level::BigPIC);
1100 extern "C" void LLVMRustSetModulePIELevel(LLVMModuleRef M) {
1101 unwrap(M)->setPIELevel(PIELevel::Level::Large);
1104 // Here you'll find an implementation of ThinLTO as used by the Rust compiler
1105 // right now. This ThinLTO support is only enabled on "recent ish" versions of
1106 // LLVM, and otherwise it's just blanket rejected from other compilers.
1108 // Most of this implementation is straight copied from LLVM. At the time of
1109 // this writing it wasn't *quite* suitable to reuse more code from upstream
1110 // for our purposes, but we should strive to upstream this support once it's
1111 // ready to go! I figure we may want a bit of testing locally first before
1112 // sending this upstream to LLVM. I hear though they're quite eager to receive
1113 // feedback like this!
1115 // If you're reading this code and wondering "what in the world" or you're
1116 // working "good lord by LLVM upgrade is *still* failing due to these bindings"
1117 // then fear not! (ok maybe fear a little). All code here is mostly based
1118 // on `lib/LTO/ThinLTOCodeGenerator.cpp` in LLVM.
1120 // You'll find that the general layout here roughly corresponds to the `run`
1121 // method in that file as well as `ProcessThinLTOModule`. Functions are
1122 // specifically commented below as well, but if you're updating this code
1123 // or otherwise trying to understand it, the LLVM source will be useful in
1124 // interpreting the mysteries within.
1126 // Otherwise I'll apologize in advance, it probably requires a relatively
1127 // significant investment on your part to "truly understand" what's going on
1128 // here. Not saying I do myself, but it took me awhile staring at LLVM's source
1129 // and various online resources about ThinLTO to make heads or tails of all
1132 // This is a shared data structure which *must* be threadsafe to share
1133 // read-only amongst threads. This also corresponds basically to the arguments
1134 // of the `ProcessThinLTOModule` function in the LLVM source.
1135 struct LLVMRustThinLTOData {
1136 // The combined index that is the global analysis over all modules we're
1137 // performing ThinLTO for. This is mostly managed by LLVM.
1138 ModuleSummaryIndex Index;
1140 // All modules we may look at, stored as in-memory serialized versions. This
1141 // is later used when inlining to ensure we can extract any module to inline
1143 StringMap<MemoryBufferRef> ModuleMap;
1145 // A set that we manage of everything we *don't* want internalized. Note that
1146 // this includes all transitive references right now as well, but it may not
1148 DenseSet<GlobalValue::GUID> GUIDPreservedSymbols;
1150 // Not 100% sure what these are, but they impact what's internalized and
1151 // what's inlined across modules, I believe.
1152 StringMap<FunctionImporter::ImportMapTy> ImportLists;
1153 StringMap<FunctionImporter::ExportSetTy> ExportLists;
1154 StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries;
1156 LLVMRustThinLTOData() : Index(/* HaveGVs = */ false) {}
1159 // Just an argument to the `LLVMRustCreateThinLTOData` function below.
1160 struct LLVMRustThinLTOModule {
1161 const char *identifier;
1166 // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp`, not sure what it
1168 static const GlobalValueSummary *
1169 getFirstDefinitionForLinker(const GlobalValueSummaryList &GVSummaryList) {
1170 auto StrongDefForLinker = llvm::find_if(
1171 GVSummaryList, [](const std::unique_ptr<GlobalValueSummary> &Summary) {
1172 auto Linkage = Summary->linkage();
1173 return !GlobalValue::isAvailableExternallyLinkage(Linkage) &&
1174 !GlobalValue::isWeakForLinker(Linkage);
1176 if (StrongDefForLinker != GVSummaryList.end())
1177 return StrongDefForLinker->get();
1179 auto FirstDefForLinker = llvm::find_if(
1180 GVSummaryList, [](const std::unique_ptr<GlobalValueSummary> &Summary) {
1181 auto Linkage = Summary->linkage();
1182 return !GlobalValue::isAvailableExternallyLinkage(Linkage);
1184 if (FirstDefForLinker == GVSummaryList.end())
1186 return FirstDefForLinker->get();
1189 // The main entry point for creating the global ThinLTO analysis. The structure
1190 // here is basically the same as before threads are spawned in the `run`
1191 // function of `lib/LTO/ThinLTOCodeGenerator.cpp`.
1192 extern "C" LLVMRustThinLTOData*
1193 LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
1195 const char **preserved_symbols,
1197 #if LLVM_VERSION_GE(10, 0)
1198 auto Ret = std::make_unique<LLVMRustThinLTOData>();
1200 auto Ret = llvm::make_unique<LLVMRustThinLTOData>();
1203 // Load each module's summary and merge it into one combined index
1204 for (int i = 0; i < num_modules; i++) {
1205 auto module = &modules[i];
1206 StringRef buffer(module->data, module->len);
1207 MemoryBufferRef mem_buffer(buffer, module->identifier);
1209 Ret->ModuleMap[module->identifier] = mem_buffer;
1211 if (Error Err = readModuleSummaryIndex(mem_buffer, Ret->Index, i)) {
1212 LLVMRustSetLastError(toString(std::move(Err)).c_str());
1217 // Collect for each module the list of function it defines (GUID -> Summary)
1218 Ret->Index.collectDefinedGVSummariesPerModule(Ret->ModuleToDefinedGVSummaries);
1220 // Convert the preserved symbols set from string to GUID, this is then needed
1221 // for internalization.
1222 for (int i = 0; i < num_symbols; i++) {
1223 auto GUID = GlobalValue::getGUID(preserved_symbols[i]);
1224 Ret->GUIDPreservedSymbols.insert(GUID);
1227 // Collect the import/export lists for all modules from the call-graph in the
1230 // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp`
1231 auto deadIsPrevailing = [&](GlobalValue::GUID G) {
1232 return PrevailingType::Unknown;
1234 // We don't have a complete picture in our use of ThinLTO, just our immediate
1235 // crate, so we need `ImportEnabled = false` to limit internalization.
1236 // Otherwise, we sometimes lose `static` values -- see #60184.
1237 computeDeadSymbolsWithConstProp(Ret->Index, Ret->GUIDPreservedSymbols,
1238 deadIsPrevailing, /* ImportEnabled = */ false);
1239 ComputeCrossModuleImport(
1241 Ret->ModuleToDefinedGVSummaries,
1246 // Resolve LinkOnce/Weak symbols, this has to be computed early be cause it
1247 // impacts the caching.
1249 // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp` with some of this
1250 // being lifted from `lib/LTO/LTO.cpp` as well
1251 StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
1252 DenseMap<GlobalValue::GUID, const GlobalValueSummary *> PrevailingCopy;
1253 for (auto &I : Ret->Index) {
1254 if (I.second.SummaryList.size() > 1)
1255 PrevailingCopy[I.first] = getFirstDefinitionForLinker(I.second.SummaryList);
1257 auto isPrevailing = [&](GlobalValue::GUID GUID, const GlobalValueSummary *S) {
1258 const auto &Prevailing = PrevailingCopy.find(GUID);
1259 if (Prevailing == PrevailingCopy.end())
1261 return Prevailing->second == S;
1263 auto recordNewLinkage = [&](StringRef ModuleIdentifier,
1264 GlobalValue::GUID GUID,
1265 GlobalValue::LinkageTypes NewLinkage) {
1266 ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;
1268 #if LLVM_VERSION_GE(9, 0)
1269 thinLTOResolvePrevailingInIndex(Ret->Index, isPrevailing, recordNewLinkage,
1270 Ret->GUIDPreservedSymbols);
1272 thinLTOResolvePrevailingInIndex(Ret->Index, isPrevailing, recordNewLinkage);
1275 // Here we calculate an `ExportedGUIDs` set for use in the `isExported`
1276 // callback below. This callback below will dictate the linkage for all
1277 // summaries in the index, and we basically just only want to ensure that dead
1278 // symbols are internalized. Otherwise everything that's already external
1279 // linkage will stay as external, and internal will stay as internal.
1280 std::set<GlobalValue::GUID> ExportedGUIDs;
1281 for (auto &List : Ret->Index) {
1282 for (auto &GVS: List.second.SummaryList) {
1283 if (GlobalValue::isLocalLinkage(GVS->linkage()))
1285 auto GUID = GVS->getOriginalName();
1286 if (GVS->flags().Live)
1287 ExportedGUIDs.insert(GUID);
1290 #if LLVM_VERSION_GE(10, 0)
1291 auto isExported = [&](StringRef ModuleIdentifier, ValueInfo VI) {
1292 const auto &ExportList = Ret->ExportLists.find(ModuleIdentifier);
1293 return (ExportList != Ret->ExportLists.end() &&
1294 ExportList->second.count(VI)) ||
1295 ExportedGUIDs.count(VI.getGUID());
1297 thinLTOInternalizeAndPromoteInIndex(Ret->Index, isExported, isPrevailing);
1299 auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) {
1300 const auto &ExportList = Ret->ExportLists.find(ModuleIdentifier);
1301 return (ExportList != Ret->ExportLists.end() &&
1302 ExportList->second.count(GUID)) ||
1303 ExportedGUIDs.count(GUID);
1305 thinLTOInternalizeAndPromoteInIndex(Ret->Index, isExported);
1308 return Ret.release();
1312 LLVMRustFreeThinLTOData(LLVMRustThinLTOData *Data) {
1316 // Below are the various passes that happen *per module* when doing ThinLTO.
1318 // In other words, these are the functions that are all run concurrently
1319 // with one another, one per module. The passes here correspond to the analysis
1320 // passes in `lib/LTO/ThinLTOCodeGenerator.cpp`, currently found in the
1321 // `ProcessThinLTOModule` function. Here they're split up into separate steps
1322 // so rustc can save off the intermediate bytecode between each step.
1325 LLVMRustPrepareThinLTORename(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
1326 Module &Mod = *unwrap(M);
1327 if (renameModuleForThinLTO(Mod, Data->Index)) {
1328 LLVMRustSetLastError("renameModuleForThinLTO failed");
1335 LLVMRustPrepareThinLTOResolveWeak(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
1336 Module &Mod = *unwrap(M);
1337 const auto &DefinedGlobals = Data->ModuleToDefinedGVSummaries.lookup(Mod.getModuleIdentifier());
1338 thinLTOResolvePrevailingInModule(Mod, DefinedGlobals);
1343 LLVMRustPrepareThinLTOInternalize(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
1344 Module &Mod = *unwrap(M);
1345 const auto &DefinedGlobals = Data->ModuleToDefinedGVSummaries.lookup(Mod.getModuleIdentifier());
1346 thinLTOInternalizeModule(Mod, DefinedGlobals);
1351 LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
1352 Module &Mod = *unwrap(M);
1354 const auto &ImportList = Data->ImportLists.lookup(Mod.getModuleIdentifier());
1355 auto Loader = [&](StringRef Identifier) {
1356 const auto &Memory = Data->ModuleMap.lookup(Identifier);
1357 auto &Context = Mod.getContext();
1358 auto MOrErr = getLazyBitcodeModule(Memory, Context, true, true);
1363 // The rest of this closure is a workaround for
1364 // https://bugs.llvm.org/show_bug.cgi?id=38184 where during ThinLTO imports
1365 // we accidentally import wasm custom sections into different modules,
1366 // duplicating them by in the final output artifact.
1368 // The issue is worked around here by manually removing the
1369 // `wasm.custom_sections` named metadata node from any imported module. This
1370 // we know isn't used by any optimization pass so there's no need for it to
1373 // Note that the metadata is currently lazily loaded, so we materialize it
1374 // here before looking up if there's metadata inside. The `FunctionImporter`
1375 // will immediately materialize metadata anyway after an import, so this
1376 // shouldn't be a perf hit.
1377 if (Error Err = (*MOrErr)->materializeMetadata()) {
1378 Expected<std::unique_ptr<Module>> Ret(std::move(Err));
1382 auto *WasmCustomSections = (*MOrErr)->getNamedMetadata("wasm.custom_sections");
1383 if (WasmCustomSections)
1384 WasmCustomSections->eraseFromParent();
1388 FunctionImporter Importer(Data->Index, Loader);
1389 Expected<bool> Result = Importer.importFunctions(Mod, ImportList);
1391 LLVMRustSetLastError(toString(Result.takeError()).c_str());
1397 extern "C" typedef void (*LLVMRustModuleNameCallback)(void*, // payload
1398 const char*, // importing module name
1399 const char*); // imported module name
1401 // Calls `module_name_callback` for each module import done by ThinLTO.
1402 // The callback is provided with regular null-terminated C strings.
1404 LLVMRustGetThinLTOModuleImports(const LLVMRustThinLTOData *data,
1405 LLVMRustModuleNameCallback module_name_callback,
1406 void* callback_payload) {
1407 for (const auto& importing_module : data->ImportLists) {
1408 const std::string importing_module_id = importing_module.getKey().str();
1409 const auto& imports = importing_module.getValue();
1410 for (const auto& imported_module : imports) {
1411 const std::string imported_module_id = imported_module.getKey().str();
1412 module_name_callback(callback_payload,
1413 importing_module_id.c_str(),
1414 imported_module_id.c_str());
1419 // This struct and various functions are sort of a hack right now, but the
1420 // problem is that we've got in-memory LLVM modules after we generate and
1421 // optimize all codegen-units for one compilation in rustc. To be compatible
1422 // with the LTO support above we need to serialize the modules plus their
1423 // ThinLTO summary into memory.
1425 // This structure is basically an owned version of a serialize module, with
1426 // a ThinLTO summary attached.
1427 struct LLVMRustThinLTOBuffer {
1431 extern "C" LLVMRustThinLTOBuffer*
1432 LLVMRustThinLTOBufferCreate(LLVMModuleRef M) {
1433 #if LLVM_VERSION_GE(10, 0)
1434 auto Ret = std::make_unique<LLVMRustThinLTOBuffer>();
1436 auto Ret = llvm::make_unique<LLVMRustThinLTOBuffer>();
1439 raw_string_ostream OS(Ret->data);
1441 legacy::PassManager PM;
1442 PM.add(createWriteThinLTOBitcodePass(OS));
1446 return Ret.release();
1450 LLVMRustThinLTOBufferFree(LLVMRustThinLTOBuffer *Buffer) {
1454 extern "C" const void*
1455 LLVMRustThinLTOBufferPtr(const LLVMRustThinLTOBuffer *Buffer) {
1456 return Buffer->data.data();
1460 LLVMRustThinLTOBufferLen(const LLVMRustThinLTOBuffer *Buffer) {
1461 return Buffer->data.length();
1464 // This is what we used to parse upstream bitcode for actual ThinLTO
1465 // processing. We'll call this once per module optimized through ThinLTO, and
1466 // it'll be called concurrently on many threads.
1467 extern "C" LLVMModuleRef
1468 LLVMRustParseBitcodeForLTO(LLVMContextRef Context,
1471 const char *identifier) {
1472 StringRef Data(data, len);
1473 MemoryBufferRef Buffer(Data, identifier);
1474 unwrap(Context)->enableDebugTypeODRUniquing();
1475 Expected<std::unique_ptr<Module>> SrcOrError =
1476 parseBitcodeFile(Buffer, *unwrap(Context));
1478 LLVMRustSetLastError(toString(SrcOrError.takeError()).c_str());
1481 return wrap(std::move(*SrcOrError).release());
1484 // Find the bitcode section in the object file data and return it as a slice.
1485 // Fail if the bitcode section is present but empty.
1487 // On success, the return value is the pointer to the start of the slice and
1488 // `out_len` is filled with the (non-zero) length. On failure, the return value
1489 // is `nullptr` and `out_len` is set to zero.
1490 extern "C" const char*
1491 LLVMRustGetBitcodeSliceFromObjectData(const char *data,
1496 StringRef Data(data, len);
1497 MemoryBufferRef Buffer(Data, ""); // The id is unused.
1499 Expected<MemoryBufferRef> BitcodeOrError =
1500 object::IRObjectFile::findBitcodeInMemBuffer(Buffer);
1501 if (!BitcodeOrError) {
1502 LLVMRustSetLastError(toString(BitcodeOrError.takeError()).c_str());
1506 *out_len = BitcodeOrError->getBufferSize();
1507 return BitcodeOrError->getBufferStart();
1510 // Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
1511 // the comment in `back/lto.rs` for why this exists.
1513 LLVMRustThinLTOGetDICompileUnit(LLVMModuleRef Mod,
1515 DICompileUnit **B) {
1516 Module *M = unwrap(Mod);
1517 DICompileUnit **Cur = A;
1518 DICompileUnit **Next = B;
1519 for (DICompileUnit *CU : M->debug_compile_units()) {
1528 // Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
1529 // the comment in `back/lto.rs` for why this exists.
1531 LLVMRustThinLTOPatchDICompileUnit(LLVMModuleRef Mod, DICompileUnit *Unit) {
1532 Module *M = unwrap(Mod);
1534 // If the original source module didn't have a `DICompileUnit` then try to
1535 // merge all the existing compile units. If there aren't actually any though
1536 // then there's not much for us to do so return.
1537 if (Unit == nullptr) {
1538 for (DICompileUnit *CU : M->debug_compile_units()) {
1542 if (Unit == nullptr)
1546 // Use LLVM's built-in `DebugInfoFinder` to find a bunch of debuginfo and
1547 // process it recursively. Note that we specifically iterate over instructions
1548 // to ensure we feed everything into it.
1549 DebugInfoFinder Finder;
1550 Finder.processModule(*M);
1551 for (Function &F : M->functions()) {
1552 for (auto &FI : F) {
1553 for (Instruction &BI : FI) {
1554 if (auto Loc = BI.getDebugLoc())
1555 Finder.processLocation(*M, Loc);
1556 if (auto DVI = dyn_cast<DbgValueInst>(&BI))
1557 Finder.processValue(*M, DVI);
1558 if (auto DDI = dyn_cast<DbgDeclareInst>(&BI))
1559 Finder.processDeclare(*M, DDI);
1564 // After we've found all our debuginfo, rewrite all subprograms to point to
1565 // the same `DICompileUnit`.
1566 for (auto &F : Finder.subprograms()) {
1567 F->replaceUnit(Unit);
1570 // Erase any other references to other `DICompileUnit` instances, the verifier
1571 // will later ensure that we don't actually have any other stale references to
1573 auto *MD = M->getNamedMetadata("llvm.dbg.cu");
1574 MD->clearOperands();
1575 MD->addOperand(Unit);