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_AVR
207 #define SUBTARGET_AVR SUBTARGET(AVR)
209 #define SUBTARGET_AVR
212 #ifdef LLVM_COMPONENT_MIPS
213 #define SUBTARGET_MIPS SUBTARGET(Mips)
215 #define SUBTARGET_MIPS
218 #ifdef LLVM_COMPONENT_POWERPC
219 #define SUBTARGET_PPC SUBTARGET(PPC)
221 #define SUBTARGET_PPC
224 #ifdef LLVM_COMPONENT_SYSTEMZ
225 #define SUBTARGET_SYSTEMZ SUBTARGET(SystemZ)
227 #define SUBTARGET_SYSTEMZ
230 #ifdef LLVM_COMPONENT_MSP430
231 #define SUBTARGET_MSP430 SUBTARGET(MSP430)
233 #define SUBTARGET_MSP430
236 #ifdef LLVM_COMPONENT_RISCV
237 #define SUBTARGET_RISCV SUBTARGET(RISCV)
239 #define SUBTARGET_RISCV
242 #ifdef LLVM_COMPONENT_SPARC
243 #define SUBTARGET_SPARC SUBTARGET(Sparc)
245 #define SUBTARGET_SPARC
248 #ifdef LLVM_COMPONENT_HEXAGON
249 #define SUBTARGET_HEXAGON SUBTARGET(Hexagon)
251 #define SUBTARGET_HEXAGON
254 #define GEN_SUBTARGETS \
267 #define SUBTARGET(x) \
269 extern const SubtargetFeatureKV x##FeatureKV[]; \
270 extern const SubtargetFeatureKV x##SubTypeKV[]; \
276 extern "C" bool LLVMRustHasFeature(LLVMTargetMachineRef TM,
277 const char *Feature) {
278 TargetMachine *Target = unwrap(TM);
279 const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
280 return MCInfo->checkFeatures(std::string("+") + Feature);
283 enum class LLVMRustCodeModel {
292 static Optional<CodeModel::Model> fromRust(LLVMRustCodeModel Model) {
294 case LLVMRustCodeModel::Tiny:
295 return CodeModel::Tiny;
296 case LLVMRustCodeModel::Small:
297 return CodeModel::Small;
298 case LLVMRustCodeModel::Kernel:
299 return CodeModel::Kernel;
300 case LLVMRustCodeModel::Medium:
301 return CodeModel::Medium;
302 case LLVMRustCodeModel::Large:
303 return CodeModel::Large;
304 case LLVMRustCodeModel::None:
307 report_fatal_error("Bad CodeModel.");
311 enum class LLVMRustCodeGenOptLevel {
319 static CodeGenOpt::Level fromRust(LLVMRustCodeGenOptLevel Level) {
321 case LLVMRustCodeGenOptLevel::None:
322 return CodeGenOpt::None;
323 case LLVMRustCodeGenOptLevel::Less:
324 return CodeGenOpt::Less;
325 case LLVMRustCodeGenOptLevel::Default:
326 return CodeGenOpt::Default;
327 case LLVMRustCodeGenOptLevel::Aggressive:
328 return CodeGenOpt::Aggressive;
330 report_fatal_error("Bad CodeGenOptLevel.");
334 enum class LLVMRustPassBuilderOptLevel {
343 static PassBuilder::OptimizationLevel fromRust(LLVMRustPassBuilderOptLevel Level) {
345 case LLVMRustPassBuilderOptLevel::O0:
346 return PassBuilder::O0;
347 case LLVMRustPassBuilderOptLevel::O1:
348 return PassBuilder::O1;
349 case LLVMRustPassBuilderOptLevel::O2:
350 return PassBuilder::O2;
351 case LLVMRustPassBuilderOptLevel::O3:
352 return PassBuilder::O3;
353 case LLVMRustPassBuilderOptLevel::Os:
354 return PassBuilder::Os;
355 case LLVMRustPassBuilderOptLevel::Oz:
356 return PassBuilder::Oz;
358 report_fatal_error("Bad PassBuilderOptLevel.");
362 enum class LLVMRustRelocModel {
371 static Reloc::Model fromRust(LLVMRustRelocModel RustReloc) {
373 case LLVMRustRelocModel::Static:
374 return Reloc::Static;
375 case LLVMRustRelocModel::PIC:
377 case LLVMRustRelocModel::DynamicNoPic:
378 return Reloc::DynamicNoPIC;
379 case LLVMRustRelocModel::ROPI:
381 case LLVMRustRelocModel::RWPI:
383 case LLVMRustRelocModel::ROPIRWPI:
384 return Reloc::ROPI_RWPI;
386 report_fatal_error("Bad RelocModel.");
390 /// getLongestEntryLength - Return the length of the longest entry in the table.
391 template<typename KV>
392 static size_t getLongestEntryLength(ArrayRef<KV> Table) {
394 for (auto &I : Table)
395 MaxLen = std::max(MaxLen, std::strlen(I.Key));
399 extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM) {
400 const TargetMachine *Target = unwrap(TM);
401 const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
402 const Triple::ArchType HostArch = Triple(sys::getProcessTriple()).getArch();
403 const Triple::ArchType TargetArch = Target->getTargetTriple().getArch();
404 const ArrayRef<SubtargetSubTypeKV> CPUTable = MCInfo->getCPUTable();
405 unsigned MaxCPULen = getLongestEntryLength(CPUTable);
407 printf("Available CPUs for this target:\n");
408 if (HostArch == TargetArch) {
409 const StringRef HostCPU = sys::getHostCPUName();
410 printf(" %-*s - Select the CPU of the current host (currently %.*s).\n",
411 MaxCPULen, "native", (int)HostCPU.size(), HostCPU.data());
413 for (auto &CPU : CPUTable)
414 printf(" %-*s\n", MaxCPULen, CPU.Key);
418 extern "C" void LLVMRustPrintTargetFeatures(LLVMTargetMachineRef TM) {
419 const TargetMachine *Target = unwrap(TM);
420 const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
421 const ArrayRef<SubtargetFeatureKV> FeatTable = MCInfo->getFeatureTable();
422 unsigned MaxFeatLen = getLongestEntryLength(FeatTable);
424 printf("Available features for this target:\n");
425 for (auto &Feature : FeatTable)
426 printf(" %-*s - %s.\n", MaxFeatLen, Feature.Key, Feature.Desc);
427 printf("\nRust-specific features:\n");
428 printf(" %-*s - %s.\n",
431 "Enables libraries with C Run-time Libraries(CRT) to be statically linked"
435 printf("Use +feature to enable a feature, or -feature to disable it.\n"
436 "For example, rustc -C -target-cpu=mycpu -C "
437 "target-feature=+feature1,-feature2\n\n");
442 extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef) {
443 printf("Target CPU help is not supported by this LLVM version.\n\n");
446 extern "C" void LLVMRustPrintTargetFeatures(LLVMTargetMachineRef) {
447 printf("Target features help is not supported by this LLVM version.\n\n");
451 extern "C" const char* LLVMRustGetHostCPUName(size_t *len) {
452 StringRef Name = sys::getHostCPUName();
457 extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
458 const char *TripleStr, const char *CPU, const char *Feature,
459 const char *ABIStr, LLVMRustCodeModel RustCM, LLVMRustRelocModel RustReloc,
460 LLVMRustCodeGenOptLevel RustOptLevel, bool UseSoftFloat,
461 bool FunctionSections,
463 bool TrapUnreachable,
466 bool EmitStackSizeSection,
467 bool RelaxELFRelocations,
470 auto OptLevel = fromRust(RustOptLevel);
471 auto RM = fromRust(RustReloc);
472 auto CM = fromRust(RustCM);
475 Triple Trip(Triple::normalize(TripleStr));
476 const llvm::Target *TheTarget =
477 TargetRegistry::lookupTarget(Trip.getTriple(), Error);
478 if (TheTarget == nullptr) {
479 LLVMRustSetLastError(Error.c_str());
483 TargetOptions Options;
485 Options.FloatABIType = FloatABI::Default;
487 Options.FloatABIType = FloatABI::Soft;
489 Options.DataSections = DataSections;
490 Options.FunctionSections = FunctionSections;
491 Options.MCOptions.AsmVerbose = AsmComments;
492 Options.MCOptions.PreserveAsmComments = AsmComments;
493 Options.MCOptions.ABIName = ABIStr;
494 Options.RelaxELFRelocations = RelaxELFRelocations;
495 Options.UseInitArray = UseInitArray;
497 if (TrapUnreachable) {
498 // Tell LLVM to codegen `unreachable` into an explicit trap instruction.
499 // This limits the extent of possible undefined behavior in some cases, as
500 // it prevents control flow from "falling through" into whatever code
501 // happens to be laid out next in memory.
502 Options.TrapUnreachable = true;
506 Options.ThreadModel = ThreadModel::Single;
509 Options.EmitStackSizeSection = EmitStackSizeSection;
511 TargetMachine *TM = TheTarget->createTargetMachine(
512 Trip.getTriple(), CPU, Feature, Options, RM, CM, OptLevel);
516 extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) {
520 extern "C" void LLVMRustConfigurePassManagerBuilder(
521 LLVMPassManagerBuilderRef PMBR, LLVMRustCodeGenOptLevel OptLevel,
522 bool MergeFunctions, bool SLPVectorize, bool LoopVectorize, bool PrepareForThinLTO,
523 const char* PGOGenPath, const char* PGOUsePath) {
524 unwrap(PMBR)->MergeFunctions = MergeFunctions;
525 unwrap(PMBR)->SLPVectorize = SLPVectorize;
526 unwrap(PMBR)->OptLevel = fromRust(OptLevel);
527 unwrap(PMBR)->LoopVectorize = LoopVectorize;
528 unwrap(PMBR)->PrepareForThinLTO = PrepareForThinLTO;
532 unwrap(PMBR)->EnablePGOInstrGen = true;
533 unwrap(PMBR)->PGOInstrGen = PGOGenPath;
537 unwrap(PMBR)->PGOInstrUse = PGOUsePath;
541 // Unfortunately, the LLVM C API doesn't provide a way to set the `LibraryInfo`
542 // field of a PassManagerBuilder, we expose our own method of doing so.
543 extern "C" void LLVMRustAddBuilderLibraryInfo(LLVMPassManagerBuilderRef PMBR,
545 bool DisableSimplifyLibCalls) {
546 Triple TargetTriple(unwrap(M)->getTargetTriple());
547 TargetLibraryInfoImpl *TLI = new TargetLibraryInfoImpl(TargetTriple);
548 if (DisableSimplifyLibCalls)
549 TLI->disableAllFunctions();
550 unwrap(PMBR)->LibraryInfo = TLI;
553 // Unfortunately, the LLVM C API doesn't provide a way to create the
554 // TargetLibraryInfo pass, so we use this method to do so.
555 extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR, LLVMModuleRef M,
556 bool DisableSimplifyLibCalls) {
557 Triple TargetTriple(unwrap(M)->getTargetTriple());
558 TargetLibraryInfoImpl TLII(TargetTriple);
559 if (DisableSimplifyLibCalls)
560 TLII.disableAllFunctions();
561 unwrap(PMR)->add(new TargetLibraryInfoWrapperPass(TLII));
564 // Unfortunately, the LLVM C API doesn't provide an easy way of iterating over
565 // all the functions in a module, so we do that manually here. You'll find
566 // similar code in clang's BackendUtil.cpp file.
567 extern "C" void LLVMRustRunFunctionPassManager(LLVMPassManagerRef PMR,
569 llvm::legacy::FunctionPassManager *P =
570 unwrap<llvm::legacy::FunctionPassManager>(PMR);
571 P->doInitialization();
573 // Upgrade all calls to old intrinsics first.
574 for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E;)
575 UpgradeCallsToIntrinsic(&*I++); // must be post-increment, as we remove
577 for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E;
579 if (!I->isDeclaration())
585 extern "C" void LLVMRustSetLLVMOptions(int Argc, char **Argv) {
586 // Initializing the command-line options more than once is not allowed. So,
587 // check if they've already been initialized. (This could happen if we're
588 // being called from rustpkg, for example). If the arguments change, then
589 // that's just kinda unfortunate.
590 static bool Initialized = false;
594 cl::ParseCommandLineOptions(Argc, Argv);
597 enum class LLVMRustFileType {
603 #if LLVM_VERSION_GE(10, 0)
604 static CodeGenFileType fromRust(LLVMRustFileType Type) {
606 case LLVMRustFileType::AssemblyFile:
607 return CGFT_AssemblyFile;
608 case LLVMRustFileType::ObjectFile:
609 return CGFT_ObjectFile;
611 report_fatal_error("Bad FileType.");
615 static TargetMachine::CodeGenFileType fromRust(LLVMRustFileType Type) {
617 case LLVMRustFileType::AssemblyFile:
618 return TargetMachine::CGFT_AssemblyFile;
619 case LLVMRustFileType::ObjectFile:
620 return TargetMachine::CGFT_ObjectFile;
622 report_fatal_error("Bad FileType.");
627 extern "C" LLVMRustResult
628 LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR,
629 LLVMModuleRef M, const char *Path,
630 LLVMRustFileType RustFileType) {
631 llvm::legacy::PassManager *PM = unwrap<llvm::legacy::PassManager>(PMR);
632 auto FileType = fromRust(RustFileType);
634 std::string ErrorInfo;
636 raw_fd_ostream OS(Path, EC, sys::fs::F_None);
638 ErrorInfo = EC.message();
639 if (ErrorInfo != "") {
640 LLVMRustSetLastError(ErrorInfo.c_str());
641 return LLVMRustResult::Failure;
644 buffer_ostream BOS(OS);
645 unwrap(Target)->addPassesToEmitFile(*PM, BOS, nullptr, FileType, false);
648 // Apparently `addPassesToEmitFile` adds a pointer to our on-the-stack output
649 // stream (OS), so the only real safe place to delete this is here? Don't we
650 // wish this was written in Rust?
651 LLVMDisposePassManager(PMR);
652 return LLVMRustResult::Success;
655 extern "C" typedef void (*LLVMRustSelfProfileBeforePassCallback)(void*, // LlvmSelfProfiler
656 const char*, // pass name
657 const char*); // IR name
658 extern "C" typedef void (*LLVMRustSelfProfileAfterPassCallback)(void*); // LlvmSelfProfiler
660 #if LLVM_VERSION_GE(9, 0)
662 std::string LLVMRustwrappedIrGetName(const llvm::Any &WrappedIr) {
663 if (any_isa<const Module *>(WrappedIr))
664 return any_cast<const Module *>(WrappedIr)->getName().str();
665 if (any_isa<const Function *>(WrappedIr))
666 return any_cast<const Function *>(WrappedIr)->getName().str();
667 if (any_isa<const Loop *>(WrappedIr))
668 return any_cast<const Loop *>(WrappedIr)->getName().str();
669 if (any_isa<const LazyCallGraph::SCC *>(WrappedIr))
670 return any_cast<const LazyCallGraph::SCC *>(WrappedIr)->getName();
675 void LLVMSelfProfileInitializeCallbacks(
676 PassInstrumentationCallbacks& PIC, void* LlvmSelfProfiler,
677 LLVMRustSelfProfileBeforePassCallback BeforePassCallback,
678 LLVMRustSelfProfileAfterPassCallback AfterPassCallback) {
679 PIC.registerBeforePassCallback([LlvmSelfProfiler, BeforePassCallback](
680 StringRef Pass, llvm::Any Ir) {
681 std::string PassName = Pass.str();
682 std::string IrName = LLVMRustwrappedIrGetName(Ir);
683 BeforePassCallback(LlvmSelfProfiler, PassName.c_str(), IrName.c_str());
687 PIC.registerAfterPassCallback(
688 [LlvmSelfProfiler, AfterPassCallback](StringRef Pass, llvm::Any Ir) {
689 AfterPassCallback(LlvmSelfProfiler);
692 PIC.registerAfterPassInvalidatedCallback(
693 [LlvmSelfProfiler, AfterPassCallback](StringRef Pass) {
694 AfterPassCallback(LlvmSelfProfiler);
697 PIC.registerBeforeAnalysisCallback([LlvmSelfProfiler, BeforePassCallback](
698 StringRef Pass, llvm::Any Ir) {
699 std::string PassName = Pass.str();
700 std::string IrName = LLVMRustwrappedIrGetName(Ir);
701 BeforePassCallback(LlvmSelfProfiler, PassName.c_str(), IrName.c_str());
704 PIC.registerAfterAnalysisCallback(
705 [LlvmSelfProfiler, AfterPassCallback](StringRef Pass, llvm::Any Ir) {
706 AfterPassCallback(LlvmSelfProfiler);
711 enum class LLVMRustOptStage {
719 struct LLVMRustSanitizerOptions {
720 bool SanitizeAddress;
721 bool SanitizeAddressRecover;
723 bool SanitizeMemoryRecover;
724 int SanitizeMemoryTrackOrigins;
729 LLVMRustOptimizeWithNewPassManager(
730 LLVMModuleRef ModuleRef,
731 LLVMTargetMachineRef TMRef,
732 LLVMRustPassBuilderOptLevel OptLevelRust,
733 LLVMRustOptStage OptStage,
734 bool NoPrepopulatePasses, bool VerifyIR, bool UseThinLTOBuffers,
735 bool MergeFunctions, bool UnrollLoops, bool SLPVectorize, bool LoopVectorize,
736 bool DisableSimplifyLibCalls, bool EmitLifetimeMarkers,
737 LLVMRustSanitizerOptions *SanitizerOptions,
738 const char *PGOGenPath, const char *PGOUsePath,
739 void* LlvmSelfProfiler,
740 LLVMRustSelfProfileBeforePassCallback BeforePassCallback,
741 LLVMRustSelfProfileAfterPassCallback AfterPassCallback) {
742 #if LLVM_VERSION_GE(9, 0)
743 Module *TheModule = unwrap(ModuleRef);
744 TargetMachine *TM = unwrap(TMRef);
745 PassBuilder::OptimizationLevel OptLevel = fromRust(OptLevelRust);
747 // FIXME: MergeFunctions is not supported by NewPM yet.
748 (void) MergeFunctions;
750 PipelineTuningOptions PTO;
751 PTO.LoopUnrolling = UnrollLoops;
752 PTO.LoopInterleaving = UnrollLoops;
753 PTO.LoopVectorization = LoopVectorize;
754 PTO.SLPVectorization = SLPVectorize;
756 PassInstrumentationCallbacks PIC;
757 StandardInstrumentations SI;
758 SI.registerCallbacks(PIC);
760 if (LlvmSelfProfiler){
761 LLVMSelfProfileInitializeCallbacks(PIC,LlvmSelfProfiler,BeforePassCallback,AfterPassCallback);
764 Optional<PGOOptions> PGOOpt;
767 PGOOpt = PGOOptions(PGOGenPath, "", "", PGOOptions::IRInstr);
768 } else if (PGOUsePath) {
770 PGOOpt = PGOOptions(PGOUsePath, "", "", PGOOptions::IRUse);
773 PassBuilder PB(TM, PTO, PGOOpt, &PIC);
775 // FIXME: We may want to expose this as an option.
776 bool DebugPassManager = false;
777 LoopAnalysisManager LAM(DebugPassManager);
778 FunctionAnalysisManager FAM(DebugPassManager);
779 CGSCCAnalysisManager CGAM(DebugPassManager);
780 ModuleAnalysisManager MAM(DebugPassManager);
782 FAM.registerPass([&] { return PB.buildDefaultAAPipeline(); });
784 Triple TargetTriple(TheModule->getTargetTriple());
785 std::unique_ptr<TargetLibraryInfoImpl> TLII(new TargetLibraryInfoImpl(TargetTriple));
786 if (DisableSimplifyLibCalls)
787 TLII->disableAllFunctions();
788 FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
790 PB.registerModuleAnalyses(MAM);
791 PB.registerCGSCCAnalyses(CGAM);
792 PB.registerFunctionAnalyses(FAM);
793 PB.registerLoopAnalyses(LAM);
794 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
796 // We manually collect pipeline callbacks so we can apply them at O0, where the
797 // PassBuilder does not create a pipeline.
798 std::vector<std::function<void(ModulePassManager &)>> PipelineStartEPCallbacks;
799 std::vector<std::function<void(FunctionPassManager &, PassBuilder::OptimizationLevel)>>
800 OptimizerLastEPCallbacks;
803 PipelineStartEPCallbacks.push_back([VerifyIR](ModulePassManager &MPM) {
804 MPM.addPass(VerifierPass());
808 if (SanitizerOptions) {
809 if (SanitizerOptions->SanitizeMemory) {
810 MemorySanitizerOptions Options(
811 SanitizerOptions->SanitizeMemoryTrackOrigins,
812 SanitizerOptions->SanitizeMemoryRecover,
813 /*CompileKernel=*/false);
814 #if LLVM_VERSION_GE(10, 0)
815 PipelineStartEPCallbacks.push_back([Options](ModulePassManager &MPM) {
816 MPM.addPass(MemorySanitizerPass(Options));
819 OptimizerLastEPCallbacks.push_back(
820 [Options](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
821 FPM.addPass(MemorySanitizerPass(Options));
826 if (SanitizerOptions->SanitizeThread) {
827 #if LLVM_VERSION_GE(10, 0)
828 PipelineStartEPCallbacks.push_back([](ModulePassManager &MPM) {
829 MPM.addPass(ThreadSanitizerPass());
832 OptimizerLastEPCallbacks.push_back(
833 [](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
834 FPM.addPass(ThreadSanitizerPass());
839 if (SanitizerOptions->SanitizeAddress) {
840 PipelineStartEPCallbacks.push_back([&](ModulePassManager &MPM) {
841 MPM.addPass(RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
843 OptimizerLastEPCallbacks.push_back(
844 [SanitizerOptions](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
845 FPM.addPass(AddressSanitizerPass(
846 /*CompileKernel=*/false, SanitizerOptions->SanitizeAddressRecover,
847 /*UseAfterScope=*/true));
850 PipelineStartEPCallbacks.push_back(
851 [SanitizerOptions](ModulePassManager &MPM) {
852 MPM.addPass(ModuleAddressSanitizerPass(
853 /*CompileKernel=*/false, SanitizerOptions->SanitizeAddressRecover));
859 ModulePassManager MPM(DebugPassManager);
860 if (!NoPrepopulatePasses) {
861 if (OptLevel == PassBuilder::O0) {
862 for (const auto &C : PipelineStartEPCallbacks)
865 if (!OptimizerLastEPCallbacks.empty()) {
866 FunctionPassManager FPM(DebugPassManager);
867 for (const auto &C : OptimizerLastEPCallbacks)
869 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
872 MPM.addPass(AlwaysInlinerPass(EmitLifetimeMarkers));
874 #if LLVM_VERSION_GE(10, 0)
876 PB.addPGOInstrPassesForO0(
877 MPM, DebugPassManager, PGOOpt->Action == PGOOptions::IRInstr,
878 /*IsCS=*/false, PGOOpt->ProfileFile, PGOOpt->ProfileRemappingFile);
882 for (const auto &C : PipelineStartEPCallbacks)
883 PB.registerPipelineStartEPCallback(C);
884 if (OptStage != LLVMRustOptStage::PreLinkThinLTO) {
885 for (const auto &C : OptimizerLastEPCallbacks)
886 PB.registerOptimizerLastEPCallback(C);
890 case LLVMRustOptStage::PreLinkNoLTO:
891 MPM = PB.buildPerModuleDefaultPipeline(OptLevel, DebugPassManager);
893 case LLVMRustOptStage::PreLinkThinLTO:
894 MPM = PB.buildThinLTOPreLinkDefaultPipeline(OptLevel, DebugPassManager);
895 if (!OptimizerLastEPCallbacks.empty()) {
896 FunctionPassManager FPM(DebugPassManager);
897 for (const auto &C : OptimizerLastEPCallbacks)
899 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
902 case LLVMRustOptStage::PreLinkFatLTO:
903 MPM = PB.buildLTOPreLinkDefaultPipeline(OptLevel, DebugPassManager);
905 case LLVMRustOptStage::ThinLTO:
906 // FIXME: Does it make sense to pass the ModuleSummaryIndex?
907 // It only seems to be needed for C++ specific optimizations.
908 MPM = PB.buildThinLTODefaultPipeline(OptLevel, DebugPassManager, nullptr);
910 case LLVMRustOptStage::FatLTO:
911 MPM = PB.buildLTODefaultPipeline(OptLevel, DebugPassManager, nullptr);
917 if (UseThinLTOBuffers) {
918 MPM.addPass(CanonicalizeAliasesPass());
919 MPM.addPass(NameAnonGlobalPass());
922 // Upgrade all calls to old intrinsics first.
923 for (Module::iterator I = TheModule->begin(), E = TheModule->end(); I != E;)
924 UpgradeCallsToIntrinsic(&*I++); // must be post-increment, as we remove
926 MPM.run(*TheModule, MAM);
928 // The new pass manager has been available for a long time,
929 // but we don't bother supporting it on old LLVM versions.
930 report_fatal_error("New pass manager only supported since LLVM 9");
934 // Callback to demangle function name
936 // * name to be demangled
939 // * output buffer len
940 // Returns len of demangled string, or 0 if demangle failed.
941 typedef size_t (*DemangleFn)(const char*, size_t, char*, size_t);
946 class RustAssemblyAnnotationWriter : public AssemblyAnnotationWriter {
948 std::vector<char> Buf;
951 RustAssemblyAnnotationWriter(DemangleFn Demangle) : Demangle(Demangle) {}
953 // Return empty string if demangle failed
954 // or if name does not need to be demangled
955 StringRef CallDemangle(StringRef name) {
960 if (Buf.size() < name.size() * 2) {
961 // Semangled name usually shorter than mangled,
962 // but allocate twice as much memory just in case
963 Buf.resize(name.size() * 2);
966 auto R = Demangle(name.data(), name.size(), Buf.data(), Buf.size());
972 auto Demangled = StringRef(Buf.data(), R);
973 if (Demangled == name) {
974 // Do not print anything if demangled name is equal to mangled.
981 void emitFunctionAnnot(const Function *F,
982 formatted_raw_ostream &OS) override {
983 StringRef Demangled = CallDemangle(F->getName());
984 if (Demangled.empty()) {
988 OS << "; " << Demangled << "\n";
991 void emitInstructionAnnot(const Instruction *I,
992 formatted_raw_ostream &OS) override {
995 if (const CallInst *CI = dyn_cast<CallInst>(I)) {
997 Value = CI->getCalledValue();
998 } else if (const InvokeInst* II = dyn_cast<InvokeInst>(I)) {
1000 Value = II->getCalledValue();
1002 // Could demangle more operations, e. g.
1003 // `store %place, @function`.
1007 if (!Value->hasName()) {
1011 StringRef Demangled = CallDemangle(Value->getName());
1012 if (Demangled.empty()) {
1016 OS << "; " << Name << " " << Demangled << "\n";
1022 extern "C" LLVMRustResult
1023 LLVMRustPrintModule(LLVMModuleRef M, const char *Path, DemangleFn Demangle) {
1024 std::string ErrorInfo;
1026 raw_fd_ostream OS(Path, EC, sys::fs::F_None);
1028 ErrorInfo = EC.message();
1029 if (ErrorInfo != "") {
1030 LLVMRustSetLastError(ErrorInfo.c_str());
1031 return LLVMRustResult::Failure;
1034 RustAssemblyAnnotationWriter AAW(Demangle);
1035 formatted_raw_ostream FOS(OS);
1036 unwrap(M)->print(FOS, &AAW);
1038 return LLVMRustResult::Success;
1041 extern "C" void LLVMRustPrintPasses() {
1042 LLVMInitializePasses();
1043 struct MyListener : PassRegistrationListener {
1044 void passEnumerate(const PassInfo *Info) {
1045 StringRef PassArg = Info->getPassArgument();
1046 StringRef PassName = Info->getPassName();
1047 if (!PassArg.empty()) {
1048 // These unsigned->signed casts could theoretically overflow, but
1049 // realistically never will (and even if, the result is implementation
1050 // defined rather plain UB).
1051 printf("%15.*s - %.*s\n", (int)PassArg.size(), PassArg.data(),
1052 (int)PassName.size(), PassName.data());
1057 PassRegistry *PR = PassRegistry::getPassRegistry();
1058 PR->enumerateWith(&Listener);
1061 extern "C" void LLVMRustAddAlwaysInlinePass(LLVMPassManagerBuilderRef PMBR,
1062 bool AddLifetimes) {
1063 unwrap(PMBR)->Inliner = llvm::createAlwaysInlinerLegacyPass(AddLifetimes);
1066 extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **Symbols,
1068 llvm::legacy::PassManager passes;
1070 auto PreserveFunctions = [=](const GlobalValue &GV) {
1071 for (size_t I = 0; I < Len; I++) {
1072 if (GV.getName() == Symbols[I]) {
1079 passes.add(llvm::createInternalizePass(PreserveFunctions));
1081 passes.run(*unwrap(M));
1084 extern "C" void LLVMRustMarkAllFunctionsNounwind(LLVMModuleRef M) {
1085 for (Module::iterator GV = unwrap(M)->begin(), E = unwrap(M)->end(); GV != E;
1087 GV->setDoesNotThrow();
1088 Function *F = dyn_cast<Function>(GV);
1092 for (Function::iterator B = F->begin(), BE = F->end(); B != BE; ++B) {
1093 for (BasicBlock::iterator I = B->begin(), IE = B->end(); I != IE; ++I) {
1094 if (isa<InvokeInst>(I)) {
1095 InvokeInst *CI = cast<InvokeInst>(I);
1096 CI->setDoesNotThrow();
1104 LLVMRustSetDataLayoutFromTargetMachine(LLVMModuleRef Module,
1105 LLVMTargetMachineRef TMR) {
1106 TargetMachine *Target = unwrap(TMR);
1107 unwrap(Module)->setDataLayout(Target->createDataLayout());
1110 extern "C" void LLVMRustSetModulePICLevel(LLVMModuleRef M) {
1111 unwrap(M)->setPICLevel(PICLevel::Level::BigPIC);
1114 extern "C" void LLVMRustSetModulePIELevel(LLVMModuleRef M) {
1115 unwrap(M)->setPIELevel(PIELevel::Level::Large);
1118 // Here you'll find an implementation of ThinLTO as used by the Rust compiler
1119 // right now. This ThinLTO support is only enabled on "recent ish" versions of
1120 // LLVM, and otherwise it's just blanket rejected from other compilers.
1122 // Most of this implementation is straight copied from LLVM. At the time of
1123 // this writing it wasn't *quite* suitable to reuse more code from upstream
1124 // for our purposes, but we should strive to upstream this support once it's
1125 // ready to go! I figure we may want a bit of testing locally first before
1126 // sending this upstream to LLVM. I hear though they're quite eager to receive
1127 // feedback like this!
1129 // If you're reading this code and wondering "what in the world" or you're
1130 // working "good lord by LLVM upgrade is *still* failing due to these bindings"
1131 // then fear not! (ok maybe fear a little). All code here is mostly based
1132 // on `lib/LTO/ThinLTOCodeGenerator.cpp` in LLVM.
1134 // You'll find that the general layout here roughly corresponds to the `run`
1135 // method in that file as well as `ProcessThinLTOModule`. Functions are
1136 // specifically commented below as well, but if you're updating this code
1137 // or otherwise trying to understand it, the LLVM source will be useful in
1138 // interpreting the mysteries within.
1140 // Otherwise I'll apologize in advance, it probably requires a relatively
1141 // significant investment on your part to "truly understand" what's going on
1142 // here. Not saying I do myself, but it took me awhile staring at LLVM's source
1143 // and various online resources about ThinLTO to make heads or tails of all
1146 // This is a shared data structure which *must* be threadsafe to share
1147 // read-only amongst threads. This also corresponds basically to the arguments
1148 // of the `ProcessThinLTOModule` function in the LLVM source.
1149 struct LLVMRustThinLTOData {
1150 // The combined index that is the global analysis over all modules we're
1151 // performing ThinLTO for. This is mostly managed by LLVM.
1152 ModuleSummaryIndex Index;
1154 // All modules we may look at, stored as in-memory serialized versions. This
1155 // is later used when inlining to ensure we can extract any module to inline
1157 StringMap<MemoryBufferRef> ModuleMap;
1159 // A set that we manage of everything we *don't* want internalized. Note that
1160 // this includes all transitive references right now as well, but it may not
1162 DenseSet<GlobalValue::GUID> GUIDPreservedSymbols;
1164 // Not 100% sure what these are, but they impact what's internalized and
1165 // what's inlined across modules, I believe.
1166 StringMap<FunctionImporter::ImportMapTy> ImportLists;
1167 StringMap<FunctionImporter::ExportSetTy> ExportLists;
1168 StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries;
1170 LLVMRustThinLTOData() : Index(/* HaveGVs = */ false) {}
1173 // Just an argument to the `LLVMRustCreateThinLTOData` function below.
1174 struct LLVMRustThinLTOModule {
1175 const char *identifier;
1180 // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp`, not sure what it
1182 static const GlobalValueSummary *
1183 getFirstDefinitionForLinker(const GlobalValueSummaryList &GVSummaryList) {
1184 auto StrongDefForLinker = llvm::find_if(
1185 GVSummaryList, [](const std::unique_ptr<GlobalValueSummary> &Summary) {
1186 auto Linkage = Summary->linkage();
1187 return !GlobalValue::isAvailableExternallyLinkage(Linkage) &&
1188 !GlobalValue::isWeakForLinker(Linkage);
1190 if (StrongDefForLinker != GVSummaryList.end())
1191 return StrongDefForLinker->get();
1193 auto FirstDefForLinker = llvm::find_if(
1194 GVSummaryList, [](const std::unique_ptr<GlobalValueSummary> &Summary) {
1195 auto Linkage = Summary->linkage();
1196 return !GlobalValue::isAvailableExternallyLinkage(Linkage);
1198 if (FirstDefForLinker == GVSummaryList.end())
1200 return FirstDefForLinker->get();
1203 // The main entry point for creating the global ThinLTO analysis. The structure
1204 // here is basically the same as before threads are spawned in the `run`
1205 // function of `lib/LTO/ThinLTOCodeGenerator.cpp`.
1206 extern "C" LLVMRustThinLTOData*
1207 LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
1209 const char **preserved_symbols,
1211 #if LLVM_VERSION_GE(10, 0)
1212 auto Ret = std::make_unique<LLVMRustThinLTOData>();
1214 auto Ret = llvm::make_unique<LLVMRustThinLTOData>();
1217 // Load each module's summary and merge it into one combined index
1218 for (int i = 0; i < num_modules; i++) {
1219 auto module = &modules[i];
1220 StringRef buffer(module->data, module->len);
1221 MemoryBufferRef mem_buffer(buffer, module->identifier);
1223 Ret->ModuleMap[module->identifier] = mem_buffer;
1225 if (Error Err = readModuleSummaryIndex(mem_buffer, Ret->Index, i)) {
1226 LLVMRustSetLastError(toString(std::move(Err)).c_str());
1231 // Collect for each module the list of function it defines (GUID -> Summary)
1232 Ret->Index.collectDefinedGVSummariesPerModule(Ret->ModuleToDefinedGVSummaries);
1234 // Convert the preserved symbols set from string to GUID, this is then needed
1235 // for internalization.
1236 for (int i = 0; i < num_symbols; i++) {
1237 auto GUID = GlobalValue::getGUID(preserved_symbols[i]);
1238 Ret->GUIDPreservedSymbols.insert(GUID);
1241 // Collect the import/export lists for all modules from the call-graph in the
1244 // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp`
1245 auto deadIsPrevailing = [&](GlobalValue::GUID G) {
1246 return PrevailingType::Unknown;
1248 // We don't have a complete picture in our use of ThinLTO, just our immediate
1249 // crate, so we need `ImportEnabled = false` to limit internalization.
1250 // Otherwise, we sometimes lose `static` values -- see #60184.
1251 computeDeadSymbolsWithConstProp(Ret->Index, Ret->GUIDPreservedSymbols,
1252 deadIsPrevailing, /* ImportEnabled = */ false);
1253 ComputeCrossModuleImport(
1255 Ret->ModuleToDefinedGVSummaries,
1260 // Resolve LinkOnce/Weak symbols, this has to be computed early be cause it
1261 // impacts the caching.
1263 // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp` with some of this
1264 // being lifted from `lib/LTO/LTO.cpp` as well
1265 StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
1266 DenseMap<GlobalValue::GUID, const GlobalValueSummary *> PrevailingCopy;
1267 for (auto &I : Ret->Index) {
1268 if (I.second.SummaryList.size() > 1)
1269 PrevailingCopy[I.first] = getFirstDefinitionForLinker(I.second.SummaryList);
1271 auto isPrevailing = [&](GlobalValue::GUID GUID, const GlobalValueSummary *S) {
1272 const auto &Prevailing = PrevailingCopy.find(GUID);
1273 if (Prevailing == PrevailingCopy.end())
1275 return Prevailing->second == S;
1277 auto recordNewLinkage = [&](StringRef ModuleIdentifier,
1278 GlobalValue::GUID GUID,
1279 GlobalValue::LinkageTypes NewLinkage) {
1280 ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;
1282 #if LLVM_VERSION_GE(9, 0)
1283 thinLTOResolvePrevailingInIndex(Ret->Index, isPrevailing, recordNewLinkage,
1284 Ret->GUIDPreservedSymbols);
1286 thinLTOResolvePrevailingInIndex(Ret->Index, isPrevailing, recordNewLinkage);
1289 // Here we calculate an `ExportedGUIDs` set for use in the `isExported`
1290 // callback below. This callback below will dictate the linkage for all
1291 // summaries in the index, and we basically just only want to ensure that dead
1292 // symbols are internalized. Otherwise everything that's already external
1293 // linkage will stay as external, and internal will stay as internal.
1294 std::set<GlobalValue::GUID> ExportedGUIDs;
1295 for (auto &List : Ret->Index) {
1296 for (auto &GVS: List.second.SummaryList) {
1297 if (GlobalValue::isLocalLinkage(GVS->linkage()))
1299 auto GUID = GVS->getOriginalName();
1300 if (GVS->flags().Live)
1301 ExportedGUIDs.insert(GUID);
1304 #if LLVM_VERSION_GE(10, 0)
1305 auto isExported = [&](StringRef ModuleIdentifier, ValueInfo VI) {
1306 const auto &ExportList = Ret->ExportLists.find(ModuleIdentifier);
1307 return (ExportList != Ret->ExportLists.end() &&
1308 ExportList->second.count(VI)) ||
1309 ExportedGUIDs.count(VI.getGUID());
1311 thinLTOInternalizeAndPromoteInIndex(Ret->Index, isExported, isPrevailing);
1313 auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) {
1314 const auto &ExportList = Ret->ExportLists.find(ModuleIdentifier);
1315 return (ExportList != Ret->ExportLists.end() &&
1316 ExportList->second.count(GUID)) ||
1317 ExportedGUIDs.count(GUID);
1319 thinLTOInternalizeAndPromoteInIndex(Ret->Index, isExported);
1322 return Ret.release();
1326 LLVMRustFreeThinLTOData(LLVMRustThinLTOData *Data) {
1330 // Below are the various passes that happen *per module* when doing ThinLTO.
1332 // In other words, these are the functions that are all run concurrently
1333 // with one another, one per module. The passes here correspond to the analysis
1334 // passes in `lib/LTO/ThinLTOCodeGenerator.cpp`, currently found in the
1335 // `ProcessThinLTOModule` function. Here they're split up into separate steps
1336 // so rustc can save off the intermediate bytecode between each step.
1339 LLVMRustPrepareThinLTORename(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
1340 Module &Mod = *unwrap(M);
1341 if (renameModuleForThinLTO(Mod, Data->Index)) {
1342 LLVMRustSetLastError("renameModuleForThinLTO failed");
1349 LLVMRustPrepareThinLTOResolveWeak(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
1350 Module &Mod = *unwrap(M);
1351 const auto &DefinedGlobals = Data->ModuleToDefinedGVSummaries.lookup(Mod.getModuleIdentifier());
1352 thinLTOResolvePrevailingInModule(Mod, DefinedGlobals);
1357 LLVMRustPrepareThinLTOInternalize(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
1358 Module &Mod = *unwrap(M);
1359 const auto &DefinedGlobals = Data->ModuleToDefinedGVSummaries.lookup(Mod.getModuleIdentifier());
1360 thinLTOInternalizeModule(Mod, DefinedGlobals);
1365 LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
1366 Module &Mod = *unwrap(M);
1368 const auto &ImportList = Data->ImportLists.lookup(Mod.getModuleIdentifier());
1369 auto Loader = [&](StringRef Identifier) {
1370 const auto &Memory = Data->ModuleMap.lookup(Identifier);
1371 auto &Context = Mod.getContext();
1372 auto MOrErr = getLazyBitcodeModule(Memory, Context, true, true);
1377 // The rest of this closure is a workaround for
1378 // https://bugs.llvm.org/show_bug.cgi?id=38184 where during ThinLTO imports
1379 // we accidentally import wasm custom sections into different modules,
1380 // duplicating them by in the final output artifact.
1382 // The issue is worked around here by manually removing the
1383 // `wasm.custom_sections` named metadata node from any imported module. This
1384 // we know isn't used by any optimization pass so there's no need for it to
1387 // Note that the metadata is currently lazily loaded, so we materialize it
1388 // here before looking up if there's metadata inside. The `FunctionImporter`
1389 // will immediately materialize metadata anyway after an import, so this
1390 // shouldn't be a perf hit.
1391 if (Error Err = (*MOrErr)->materializeMetadata()) {
1392 Expected<std::unique_ptr<Module>> Ret(std::move(Err));
1396 auto *WasmCustomSections = (*MOrErr)->getNamedMetadata("wasm.custom_sections");
1397 if (WasmCustomSections)
1398 WasmCustomSections->eraseFromParent();
1402 FunctionImporter Importer(Data->Index, Loader);
1403 Expected<bool> Result = Importer.importFunctions(Mod, ImportList);
1405 LLVMRustSetLastError(toString(Result.takeError()).c_str());
1411 extern "C" typedef void (*LLVMRustModuleNameCallback)(void*, // payload
1412 const char*, // importing module name
1413 const char*); // imported module name
1415 // Calls `module_name_callback` for each module import done by ThinLTO.
1416 // The callback is provided with regular null-terminated C strings.
1418 LLVMRustGetThinLTOModuleImports(const LLVMRustThinLTOData *data,
1419 LLVMRustModuleNameCallback module_name_callback,
1420 void* callback_payload) {
1421 for (const auto& importing_module : data->ImportLists) {
1422 const std::string importing_module_id = importing_module.getKey().str();
1423 const auto& imports = importing_module.getValue();
1424 for (const auto& imported_module : imports) {
1425 const std::string imported_module_id = imported_module.getKey().str();
1426 module_name_callback(callback_payload,
1427 importing_module_id.c_str(),
1428 imported_module_id.c_str());
1433 // This struct and various functions are sort of a hack right now, but the
1434 // problem is that we've got in-memory LLVM modules after we generate and
1435 // optimize all codegen-units for one compilation in rustc. To be compatible
1436 // with the LTO support above we need to serialize the modules plus their
1437 // ThinLTO summary into memory.
1439 // This structure is basically an owned version of a serialize module, with
1440 // a ThinLTO summary attached.
1441 struct LLVMRustThinLTOBuffer {
1445 extern "C" LLVMRustThinLTOBuffer*
1446 LLVMRustThinLTOBufferCreate(LLVMModuleRef M) {
1447 #if LLVM_VERSION_GE(10, 0)
1448 auto Ret = std::make_unique<LLVMRustThinLTOBuffer>();
1450 auto Ret = llvm::make_unique<LLVMRustThinLTOBuffer>();
1453 raw_string_ostream OS(Ret->data);
1455 legacy::PassManager PM;
1456 PM.add(createWriteThinLTOBitcodePass(OS));
1460 return Ret.release();
1464 LLVMRustThinLTOBufferFree(LLVMRustThinLTOBuffer *Buffer) {
1468 extern "C" const void*
1469 LLVMRustThinLTOBufferPtr(const LLVMRustThinLTOBuffer *Buffer) {
1470 return Buffer->data.data();
1474 LLVMRustThinLTOBufferLen(const LLVMRustThinLTOBuffer *Buffer) {
1475 return Buffer->data.length();
1478 // This is what we used to parse upstream bitcode for actual ThinLTO
1479 // processing. We'll call this once per module optimized through ThinLTO, and
1480 // it'll be called concurrently on many threads.
1481 extern "C" LLVMModuleRef
1482 LLVMRustParseBitcodeForLTO(LLVMContextRef Context,
1485 const char *identifier) {
1486 StringRef Data(data, len);
1487 MemoryBufferRef Buffer(Data, identifier);
1488 unwrap(Context)->enableDebugTypeODRUniquing();
1489 Expected<std::unique_ptr<Module>> SrcOrError =
1490 parseBitcodeFile(Buffer, *unwrap(Context));
1492 LLVMRustSetLastError(toString(SrcOrError.takeError()).c_str());
1495 return wrap(std::move(*SrcOrError).release());
1498 // Find the bitcode section in the object file data and return it as a slice.
1499 // Fail if the bitcode section is present but empty.
1501 // On success, the return value is the pointer to the start of the slice and
1502 // `out_len` is filled with the (non-zero) length. On failure, the return value
1503 // is `nullptr` and `out_len` is set to zero.
1504 extern "C" const char*
1505 LLVMRustGetBitcodeSliceFromObjectData(const char *data,
1510 StringRef Data(data, len);
1511 MemoryBufferRef Buffer(Data, ""); // The id is unused.
1513 Expected<MemoryBufferRef> BitcodeOrError =
1514 object::IRObjectFile::findBitcodeInMemBuffer(Buffer);
1515 if (!BitcodeOrError) {
1516 LLVMRustSetLastError(toString(BitcodeOrError.takeError()).c_str());
1520 *out_len = BitcodeOrError->getBufferSize();
1521 return BitcodeOrError->getBufferStart();
1524 // Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
1525 // the comment in `back/lto.rs` for why this exists.
1527 LLVMRustThinLTOGetDICompileUnit(LLVMModuleRef Mod,
1529 DICompileUnit **B) {
1530 Module *M = unwrap(Mod);
1531 DICompileUnit **Cur = A;
1532 DICompileUnit **Next = B;
1533 for (DICompileUnit *CU : M->debug_compile_units()) {
1542 // Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
1543 // the comment in `back/lto.rs` for why this exists.
1545 LLVMRustThinLTOPatchDICompileUnit(LLVMModuleRef Mod, DICompileUnit *Unit) {
1546 Module *M = unwrap(Mod);
1548 // If the original source module didn't have a `DICompileUnit` then try to
1549 // merge all the existing compile units. If there aren't actually any though
1550 // then there's not much for us to do so return.
1551 if (Unit == nullptr) {
1552 for (DICompileUnit *CU : M->debug_compile_units()) {
1556 if (Unit == nullptr)
1560 // Use LLVM's built-in `DebugInfoFinder` to find a bunch of debuginfo and
1561 // process it recursively. Note that we specifically iterate over instructions
1562 // to ensure we feed everything into it.
1563 DebugInfoFinder Finder;
1564 Finder.processModule(*M);
1565 for (Function &F : M->functions()) {
1566 for (auto &FI : F) {
1567 for (Instruction &BI : FI) {
1568 if (auto Loc = BI.getDebugLoc())
1569 Finder.processLocation(*M, Loc);
1570 if (auto DVI = dyn_cast<DbgValueInst>(&BI))
1571 Finder.processValue(*M, DVI);
1572 if (auto DDI = dyn_cast<DbgDeclareInst>(&BI))
1573 Finder.processDeclare(*M, DDI);
1578 // After we've found all our debuginfo, rewrite all subprograms to point to
1579 // the same `DICompileUnit`.
1580 for (auto &F : Finder.subprograms()) {
1581 F->replaceUnit(Unit);
1584 // Erase any other references to other `DICompileUnit` instances, the verifier
1585 // will later ensure that we don't actually have any other stale references to
1587 auto *MD = M->getNamedMetadata("llvm.dbg.cu");
1588 MD->clearOperands();
1589 MD->addOperand(Unit);