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 #if LLVM_VERSION_LT(11, 0)
53 DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassManagerBuilder,
54 LLVMPassManagerBuilderRef)
57 extern "C" void LLVMInitializePasses() {
58 PassRegistry &Registry = *PassRegistry::getPassRegistry();
59 initializeCore(Registry);
60 initializeCodeGen(Registry);
61 initializeScalarOpts(Registry);
62 initializeVectorization(Registry);
63 initializeIPO(Registry);
64 initializeAnalysis(Registry);
65 initializeTransformUtils(Registry);
66 initializeInstCombine(Registry);
67 initializeInstrumentation(Registry);
68 initializeTarget(Registry);
71 extern "C" void LLVMTimeTraceProfilerInitialize() {
72 #if LLVM_VERSION_GE(10, 0)
73 timeTraceProfilerInitialize(
74 /* TimeTraceGranularity */ 0,
75 /* ProcName */ "rustc");
76 #elif LLVM_VERSION_GE(9, 0)
77 timeTraceProfilerInitialize();
81 extern "C" void LLVMTimeTraceProfilerFinish(const char* FileName) {
82 #if LLVM_VERSION_GE(9, 0)
83 StringRef FN(FileName);
85 raw_fd_ostream OS(FN, EC, sys::fs::CD_CreateAlways);
87 timeTraceProfilerWrite(OS);
88 timeTraceProfilerCleanup();
92 enum class LLVMRustPassKind {
98 static LLVMRustPassKind toRust(PassKind Kind) {
101 return LLVMRustPassKind::Function;
103 return LLVMRustPassKind::Module;
105 return LLVMRustPassKind::Other;
109 extern "C" LLVMPassRef LLVMRustFindAndCreatePass(const char *PassName) {
110 StringRef SR(PassName);
111 PassRegistry *PR = PassRegistry::getPassRegistry();
113 const PassInfo *PI = PR->getPassInfo(SR);
115 return wrap(PI->createPass());
120 extern "C" LLVMPassRef LLVMRustCreateAddressSanitizerFunctionPass(bool Recover) {
121 const bool CompileKernel = false;
122 const bool UseAfterScope = true;
124 return wrap(createAddressSanitizerFunctionPass(CompileKernel, Recover, UseAfterScope));
127 extern "C" LLVMPassRef LLVMRustCreateModuleAddressSanitizerPass(bool Recover) {
128 const bool CompileKernel = false;
130 #if LLVM_VERSION_GE(9, 0)
131 return wrap(createModuleAddressSanitizerLegacyPassPass(CompileKernel, Recover));
133 return wrap(createAddressSanitizerModulePass(CompileKernel, Recover));
137 extern "C" LLVMPassRef LLVMRustCreateMemorySanitizerPass(int TrackOrigins, bool Recover) {
138 #if LLVM_VERSION_GE(9, 0)
139 const bool CompileKernel = false;
141 return wrap(createMemorySanitizerLegacyPassPass(
142 MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel}));
144 return wrap(createMemorySanitizerLegacyPassPass(TrackOrigins, Recover));
148 extern "C" LLVMPassRef LLVMRustCreateThreadSanitizerPass() {
149 return wrap(createThreadSanitizerLegacyPassPass());
152 extern "C" LLVMRustPassKind LLVMRustPassKind(LLVMPassRef RustPass) {
154 Pass *Pass = unwrap(RustPass);
155 return toRust(Pass->getPassKind());
158 extern "C" void LLVMRustAddPass(LLVMPassManagerRef PMR, LLVMPassRef RustPass) {
160 Pass *Pass = unwrap(RustPass);
161 PassManagerBase *PMB = unwrap(PMR);
166 void LLVMRustPassManagerBuilderPopulateThinLTOPassManager(
167 LLVMPassManagerBuilderRef PMBR,
168 LLVMPassManagerRef PMR
170 unwrap(PMBR)->populateThinLTOPassManager(*unwrap(PMR));
174 void LLVMRustAddLastExtensionPasses(
175 LLVMPassManagerBuilderRef PMBR, LLVMPassRef *Passes, size_t NumPasses) {
176 auto AddExtensionPasses = [Passes, NumPasses](
177 const PassManagerBuilder &Builder, PassManagerBase &PM) {
178 for (size_t I = 0; I < NumPasses; I++) {
179 PM.add(unwrap(Passes[I]));
182 // Add the passes to both of the pre-finalization extension points,
183 // so they are run for optimized and non-optimized builds.
184 unwrap(PMBR)->addExtension(PassManagerBuilder::EP_OptimizerLast,
186 unwrap(PMBR)->addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
190 #ifdef LLVM_COMPONENT_X86
191 #define SUBTARGET_X86 SUBTARGET(X86)
193 #define SUBTARGET_X86
196 #ifdef LLVM_COMPONENT_ARM
197 #define SUBTARGET_ARM SUBTARGET(ARM)
199 #define SUBTARGET_ARM
202 #ifdef LLVM_COMPONENT_AARCH64
203 #define SUBTARGET_AARCH64 SUBTARGET(AArch64)
205 #define SUBTARGET_AARCH64
208 #ifdef LLVM_COMPONENT_AVR
209 #define SUBTARGET_AVR SUBTARGET(AVR)
211 #define SUBTARGET_AVR
214 #ifdef LLVM_COMPONENT_MIPS
215 #define SUBTARGET_MIPS SUBTARGET(Mips)
217 #define SUBTARGET_MIPS
220 #ifdef LLVM_COMPONENT_POWERPC
221 #define SUBTARGET_PPC SUBTARGET(PPC)
223 #define SUBTARGET_PPC
226 #ifdef LLVM_COMPONENT_SYSTEMZ
227 #define SUBTARGET_SYSTEMZ SUBTARGET(SystemZ)
229 #define SUBTARGET_SYSTEMZ
232 #ifdef LLVM_COMPONENT_MSP430
233 #define SUBTARGET_MSP430 SUBTARGET(MSP430)
235 #define SUBTARGET_MSP430
238 #ifdef LLVM_COMPONENT_RISCV
239 #define SUBTARGET_RISCV SUBTARGET(RISCV)
241 #define SUBTARGET_RISCV
244 #ifdef LLVM_COMPONENT_SPARC
245 #define SUBTARGET_SPARC SUBTARGET(Sparc)
247 #define SUBTARGET_SPARC
250 #ifdef LLVM_COMPONENT_HEXAGON
251 #define SUBTARGET_HEXAGON SUBTARGET(Hexagon)
253 #define SUBTARGET_HEXAGON
256 #define GEN_SUBTARGETS \
269 #define SUBTARGET(x) \
271 extern const SubtargetFeatureKV x##FeatureKV[]; \
272 extern const SubtargetFeatureKV x##SubTypeKV[]; \
278 extern "C" bool LLVMRustHasFeature(LLVMTargetMachineRef TM,
279 const char *Feature) {
280 TargetMachine *Target = unwrap(TM);
281 const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
282 return MCInfo->checkFeatures(std::string("+") + Feature);
285 enum class LLVMRustCodeModel {
294 static Optional<CodeModel::Model> fromRust(LLVMRustCodeModel Model) {
296 case LLVMRustCodeModel::Tiny:
297 return CodeModel::Tiny;
298 case LLVMRustCodeModel::Small:
299 return CodeModel::Small;
300 case LLVMRustCodeModel::Kernel:
301 return CodeModel::Kernel;
302 case LLVMRustCodeModel::Medium:
303 return CodeModel::Medium;
304 case LLVMRustCodeModel::Large:
305 return CodeModel::Large;
306 case LLVMRustCodeModel::None:
309 report_fatal_error("Bad CodeModel.");
313 enum class LLVMRustCodeGenOptLevel {
320 static CodeGenOpt::Level fromRust(LLVMRustCodeGenOptLevel Level) {
322 case LLVMRustCodeGenOptLevel::None:
323 return CodeGenOpt::None;
324 case LLVMRustCodeGenOptLevel::Less:
325 return CodeGenOpt::Less;
326 case LLVMRustCodeGenOptLevel::Default:
327 return CodeGenOpt::Default;
328 case LLVMRustCodeGenOptLevel::Aggressive:
329 return CodeGenOpt::Aggressive;
331 report_fatal_error("Bad CodeGenOptLevel.");
335 enum class LLVMRustPassBuilderOptLevel {
344 static PassBuilder::OptimizationLevel fromRust(LLVMRustPassBuilderOptLevel Level) {
346 case LLVMRustPassBuilderOptLevel::O0:
347 return PassBuilder::OptimizationLevel::O0;
348 case LLVMRustPassBuilderOptLevel::O1:
349 return PassBuilder::OptimizationLevel::O1;
350 case LLVMRustPassBuilderOptLevel::O2:
351 return PassBuilder::OptimizationLevel::O2;
352 case LLVMRustPassBuilderOptLevel::O3:
353 return PassBuilder::OptimizationLevel::O3;
354 case LLVMRustPassBuilderOptLevel::Os:
355 return PassBuilder::OptimizationLevel::Os;
356 case LLVMRustPassBuilderOptLevel::Oz:
357 return PassBuilder::OptimizationLevel::Oz;
359 report_fatal_error("Bad PassBuilderOptLevel.");
363 enum class LLVMRustRelocModel {
372 static Reloc::Model fromRust(LLVMRustRelocModel RustReloc) {
374 case LLVMRustRelocModel::Static:
375 return Reloc::Static;
376 case LLVMRustRelocModel::PIC:
378 case LLVMRustRelocModel::DynamicNoPic:
379 return Reloc::DynamicNoPIC;
380 case LLVMRustRelocModel::ROPI:
382 case LLVMRustRelocModel::RWPI:
384 case LLVMRustRelocModel::ROPIRWPI:
385 return Reloc::ROPI_RWPI;
387 report_fatal_error("Bad RelocModel.");
391 /// getLongestEntryLength - Return the length of the longest entry in the table.
392 template<typename KV>
393 static size_t getLongestEntryLength(ArrayRef<KV> Table) {
395 for (auto &I : Table)
396 MaxLen = std::max(MaxLen, std::strlen(I.Key));
400 extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM) {
401 const TargetMachine *Target = unwrap(TM);
402 const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
403 const Triple::ArchType HostArch = Triple(sys::getProcessTriple()).getArch();
404 const Triple::ArchType TargetArch = Target->getTargetTriple().getArch();
405 const ArrayRef<SubtargetSubTypeKV> CPUTable = MCInfo->getCPUTable();
406 unsigned MaxCPULen = getLongestEntryLength(CPUTable);
408 printf("Available CPUs for this target:\n");
409 if (HostArch == TargetArch) {
410 const StringRef HostCPU = sys::getHostCPUName();
411 printf(" %-*s - Select the CPU of the current host (currently %.*s).\n",
412 MaxCPULen, "native", (int)HostCPU.size(), HostCPU.data());
414 for (auto &CPU : CPUTable)
415 printf(" %-*s\n", MaxCPULen, CPU.Key);
419 extern "C" void LLVMRustPrintTargetFeatures(LLVMTargetMachineRef TM) {
420 const TargetMachine *Target = unwrap(TM);
421 const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
422 const ArrayRef<SubtargetFeatureKV> FeatTable = MCInfo->getFeatureTable();
423 unsigned MaxFeatLen = getLongestEntryLength(FeatTable);
425 printf("Available features for this target:\n");
426 for (auto &Feature : FeatTable)
427 printf(" %-*s - %s.\n", MaxFeatLen, Feature.Key, Feature.Desc);
428 printf("\nRust-specific features:\n");
429 printf(" %-*s - %s.\n",
432 "Enables libraries with C Run-time Libraries(CRT) to be statically linked"
436 printf("Use +feature to enable a feature, or -feature to disable it.\n"
437 "For example, rustc -C -target-cpu=mycpu -C "
438 "target-feature=+feature1,-feature2\n\n");
443 extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef) {
444 printf("Target CPU help is not supported by this LLVM version.\n\n");
447 extern "C" void LLVMRustPrintTargetFeatures(LLVMTargetMachineRef) {
448 printf("Target features help is not supported by this LLVM version.\n\n");
452 extern "C" const char* LLVMRustGetHostCPUName(size_t *len) {
453 StringRef Name = sys::getHostCPUName();
458 extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
459 const char *TripleStr, const char *CPU, const char *Feature,
460 const char *ABIStr, LLVMRustCodeModel RustCM, LLVMRustRelocModel RustReloc,
461 LLVMRustCodeGenOptLevel RustOptLevel, bool UseSoftFloat,
462 bool FunctionSections,
464 bool TrapUnreachable,
467 bool EmitStackSizeSection,
468 bool RelaxELFRelocations,
471 auto OptLevel = fromRust(RustOptLevel);
472 auto RM = fromRust(RustReloc);
473 auto CM = fromRust(RustCM);
476 Triple Trip(Triple::normalize(TripleStr));
477 const llvm::Target *TheTarget =
478 TargetRegistry::lookupTarget(Trip.getTriple(), Error);
479 if (TheTarget == nullptr) {
480 LLVMRustSetLastError(Error.c_str());
484 TargetOptions Options;
486 Options.FloatABIType = FloatABI::Default;
488 Options.FloatABIType = FloatABI::Soft;
490 Options.DataSections = DataSections;
491 Options.FunctionSections = FunctionSections;
492 Options.MCOptions.AsmVerbose = AsmComments;
493 Options.MCOptions.PreserveAsmComments = AsmComments;
494 Options.MCOptions.ABIName = ABIStr;
495 Options.RelaxELFRelocations = RelaxELFRelocations;
496 Options.UseInitArray = UseInitArray;
498 if (TrapUnreachable) {
499 // Tell LLVM to codegen `unreachable` into an explicit trap instruction.
500 // This limits the extent of possible undefined behavior in some cases, as
501 // it prevents control flow from "falling through" into whatever code
502 // happens to be laid out next in memory.
503 Options.TrapUnreachable = true;
507 Options.ThreadModel = ThreadModel::Single;
510 Options.EmitStackSizeSection = EmitStackSizeSection;
512 TargetMachine *TM = TheTarget->createTargetMachine(
513 Trip.getTriple(), CPU, Feature, Options, RM, CM, OptLevel);
517 extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) {
521 extern "C" void LLVMRustConfigurePassManagerBuilder(
522 LLVMPassManagerBuilderRef PMBR, LLVMRustCodeGenOptLevel OptLevel,
523 bool MergeFunctions, bool SLPVectorize, bool LoopVectorize, bool PrepareForThinLTO,
524 const char* PGOGenPath, const char* PGOUsePath) {
525 unwrap(PMBR)->MergeFunctions = MergeFunctions;
526 unwrap(PMBR)->SLPVectorize = SLPVectorize;
527 unwrap(PMBR)->OptLevel = fromRust(OptLevel);
528 unwrap(PMBR)->LoopVectorize = LoopVectorize;
529 unwrap(PMBR)->PrepareForThinLTO = PrepareForThinLTO;
533 unwrap(PMBR)->EnablePGOInstrGen = true;
534 unwrap(PMBR)->PGOInstrGen = PGOGenPath;
538 unwrap(PMBR)->PGOInstrUse = PGOUsePath;
542 // Unfortunately, the LLVM C API doesn't provide a way to set the `LibraryInfo`
543 // field of a PassManagerBuilder, we expose our own method of doing so.
544 extern "C" void LLVMRustAddBuilderLibraryInfo(LLVMPassManagerBuilderRef PMBR,
546 bool DisableSimplifyLibCalls) {
547 Triple TargetTriple(unwrap(M)->getTargetTriple());
548 TargetLibraryInfoImpl *TLI = new TargetLibraryInfoImpl(TargetTriple);
549 if (DisableSimplifyLibCalls)
550 TLI->disableAllFunctions();
551 unwrap(PMBR)->LibraryInfo = TLI;
554 // Unfortunately, the LLVM C API doesn't provide a way to create the
555 // TargetLibraryInfo pass, so we use this method to do so.
556 extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR, LLVMModuleRef M,
557 bool DisableSimplifyLibCalls) {
558 Triple TargetTriple(unwrap(M)->getTargetTriple());
559 TargetLibraryInfoImpl TLII(TargetTriple);
560 if (DisableSimplifyLibCalls)
561 TLII.disableAllFunctions();
562 unwrap(PMR)->add(new TargetLibraryInfoWrapperPass(TLII));
565 // Unfortunately, the LLVM C API doesn't provide an easy way of iterating over
566 // all the functions in a module, so we do that manually here. You'll find
567 // similar code in clang's BackendUtil.cpp file.
568 extern "C" void LLVMRustRunFunctionPassManager(LLVMPassManagerRef PMR,
570 llvm::legacy::FunctionPassManager *P =
571 unwrap<llvm::legacy::FunctionPassManager>(PMR);
572 P->doInitialization();
574 // Upgrade all calls to old intrinsics first.
575 for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E;)
576 UpgradeCallsToIntrinsic(&*I++); // must be post-increment, as we remove
578 for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E;
580 if (!I->isDeclaration())
586 extern "C" void LLVMRustSetLLVMOptions(int Argc, char **Argv) {
587 // Initializing the command-line options more than once is not allowed. So,
588 // check if they've already been initialized. (This could happen if we're
589 // being called from rustpkg, for example). If the arguments change, then
590 // that's just kinda unfortunate.
591 static bool Initialized = false;
595 cl::ParseCommandLineOptions(Argc, Argv);
598 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 #if LLVM_VERSION_GE(11, 0)
800 std::vector<std::function<void(ModulePassManager &, PassBuilder::OptimizationLevel)>>
801 OptimizerLastEPCallbacks;
803 std::vector<std::function<void(FunctionPassManager &, PassBuilder::OptimizationLevel)>>
804 OptimizerLastEPCallbacks;
808 PipelineStartEPCallbacks.push_back([VerifyIR](ModulePassManager &MPM) {
809 MPM.addPass(VerifierPass());
813 if (SanitizerOptions) {
814 if (SanitizerOptions->SanitizeMemory) {
815 MemorySanitizerOptions Options(
816 SanitizerOptions->SanitizeMemoryTrackOrigins,
817 SanitizerOptions->SanitizeMemoryRecover,
818 /*CompileKernel=*/false);
819 #if LLVM_VERSION_GE(11, 0)
820 OptimizerLastEPCallbacks.push_back(
821 [Options](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) {
822 MPM.addPass(MemorySanitizerPass(Options));
823 MPM.addPass(createModuleToFunctionPassAdaptor(MemorySanitizerPass(Options)));
827 #if LLVM_VERSION_GE(10, 0)
828 PipelineStartEPCallbacks.push_back([Options](ModulePassManager &MPM) {
829 MPM.addPass(MemorySanitizerPass(Options));
832 OptimizerLastEPCallbacks.push_back(
833 [Options](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
834 FPM.addPass(MemorySanitizerPass(Options));
840 if (SanitizerOptions->SanitizeThread) {
841 #if LLVM_VERSION_GE(11, 0)
842 OptimizerLastEPCallbacks.push_back(
843 [](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) {
844 MPM.addPass(ThreadSanitizerPass());
845 MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));
849 #if LLVM_VERSION_GE(10, 0)
850 PipelineStartEPCallbacks.push_back([](ModulePassManager &MPM) {
851 MPM.addPass(ThreadSanitizerPass());
854 OptimizerLastEPCallbacks.push_back(
855 [](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
856 FPM.addPass(ThreadSanitizerPass());
862 if (SanitizerOptions->SanitizeAddress) {
863 #if LLVM_VERSION_GE(11, 0)
864 OptimizerLastEPCallbacks.push_back(
865 [SanitizerOptions](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) {
866 MPM.addPass(RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
867 MPM.addPass(ModuleAddressSanitizerPass(
868 /*CompileKernel=*/false, SanitizerOptions->SanitizeAddressRecover));
869 MPM.addPass(createModuleToFunctionPassAdaptor(AddressSanitizerPass(
870 /*CompileKernel=*/false, SanitizerOptions->SanitizeAddressRecover,
871 /*UseAfterScope=*/true)));
875 PipelineStartEPCallbacks.push_back([&](ModulePassManager &MPM) {
876 MPM.addPass(RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
878 OptimizerLastEPCallbacks.push_back(
879 [SanitizerOptions](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
880 FPM.addPass(AddressSanitizerPass(
881 /*CompileKernel=*/false, SanitizerOptions->SanitizeAddressRecover,
882 /*UseAfterScope=*/true));
885 PipelineStartEPCallbacks.push_back(
886 [SanitizerOptions](ModulePassManager &MPM) {
887 MPM.addPass(ModuleAddressSanitizerPass(
888 /*CompileKernel=*/false, SanitizerOptions->SanitizeAddressRecover));
895 ModulePassManager MPM(DebugPassManager);
896 if (!NoPrepopulatePasses) {
897 if (OptLevel == PassBuilder::OptimizationLevel::O0) {
898 for (const auto &C : PipelineStartEPCallbacks)
901 #if LLVM_VERSION_GE(11, 0)
902 for (const auto &C : OptimizerLastEPCallbacks)
905 if (!OptimizerLastEPCallbacks.empty()) {
906 FunctionPassManager FPM(DebugPassManager);
907 for (const auto &C : OptimizerLastEPCallbacks)
909 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
913 MPM.addPass(AlwaysInlinerPass(EmitLifetimeMarkers));
915 #if LLVM_VERSION_GE(10, 0)
917 PB.addPGOInstrPassesForO0(
918 MPM, DebugPassManager, PGOOpt->Action == PGOOptions::IRInstr,
919 /*IsCS=*/false, PGOOpt->ProfileFile, PGOOpt->ProfileRemappingFile);
923 for (const auto &C : PipelineStartEPCallbacks)
924 PB.registerPipelineStartEPCallback(C);
925 if (OptStage != LLVMRustOptStage::PreLinkThinLTO) {
926 for (const auto &C : OptimizerLastEPCallbacks)
927 PB.registerOptimizerLastEPCallback(C);
931 case LLVMRustOptStage::PreLinkNoLTO:
932 MPM = PB.buildPerModuleDefaultPipeline(OptLevel, DebugPassManager);
934 case LLVMRustOptStage::PreLinkThinLTO:
935 MPM = PB.buildThinLTOPreLinkDefaultPipeline(OptLevel, DebugPassManager);
936 #if LLVM_VERSION_GE(11, 0)
937 for (const auto &C : OptimizerLastEPCallbacks)
940 if (!OptimizerLastEPCallbacks.empty()) {
941 FunctionPassManager FPM(DebugPassManager);
942 for (const auto &C : OptimizerLastEPCallbacks)
944 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
948 case LLVMRustOptStage::PreLinkFatLTO:
949 MPM = PB.buildLTOPreLinkDefaultPipeline(OptLevel, DebugPassManager);
951 case LLVMRustOptStage::ThinLTO:
952 // FIXME: Does it make sense to pass the ModuleSummaryIndex?
953 // It only seems to be needed for C++ specific optimizations.
954 MPM = PB.buildThinLTODefaultPipeline(OptLevel, DebugPassManager, nullptr);
956 case LLVMRustOptStage::FatLTO:
957 MPM = PB.buildLTODefaultPipeline(OptLevel, DebugPassManager, nullptr);
963 if (UseThinLTOBuffers) {
964 MPM.addPass(CanonicalizeAliasesPass());
965 MPM.addPass(NameAnonGlobalPass());
968 // Upgrade all calls to old intrinsics first.
969 for (Module::iterator I = TheModule->begin(), E = TheModule->end(); I != E;)
970 UpgradeCallsToIntrinsic(&*I++); // must be post-increment, as we remove
972 MPM.run(*TheModule, MAM);
974 // The new pass manager has been available for a long time,
975 // but we don't bother supporting it on old LLVM versions.
976 report_fatal_error("New pass manager only supported since LLVM 9");
980 // Callback to demangle function name
982 // * name to be demangled
985 // * output buffer len
986 // Returns len of demangled string, or 0 if demangle failed.
987 typedef size_t (*DemangleFn)(const char*, size_t, char*, size_t);
992 class RustAssemblyAnnotationWriter : public AssemblyAnnotationWriter {
994 std::vector<char> Buf;
997 RustAssemblyAnnotationWriter(DemangleFn Demangle) : Demangle(Demangle) {}
999 // Return empty string if demangle failed
1000 // or if name does not need to be demangled
1001 StringRef CallDemangle(StringRef name) {
1006 if (Buf.size() < name.size() * 2) {
1007 // Semangled name usually shorter than mangled,
1008 // but allocate twice as much memory just in case
1009 Buf.resize(name.size() * 2);
1012 auto R = Demangle(name.data(), name.size(), Buf.data(), Buf.size());
1018 auto Demangled = StringRef(Buf.data(), R);
1019 if (Demangled == name) {
1020 // Do not print anything if demangled name is equal to mangled.
1027 void emitFunctionAnnot(const Function *F,
1028 formatted_raw_ostream &OS) override {
1029 StringRef Demangled = CallDemangle(F->getName());
1030 if (Demangled.empty()) {
1034 OS << "; " << Demangled << "\n";
1037 void emitInstructionAnnot(const Instruction *I,
1038 formatted_raw_ostream &OS) override {
1041 if (const CallInst *CI = dyn_cast<CallInst>(I)) {
1043 Value = CI->getCalledOperand();
1044 } else if (const InvokeInst* II = dyn_cast<InvokeInst>(I)) {
1046 Value = II->getCalledOperand();
1048 // Could demangle more operations, e. g.
1049 // `store %place, @function`.
1053 if (!Value->hasName()) {
1057 StringRef Demangled = CallDemangle(Value->getName());
1058 if (Demangled.empty()) {
1062 OS << "; " << Name << " " << Demangled << "\n";
1068 extern "C" LLVMRustResult
1069 LLVMRustPrintModule(LLVMModuleRef M, const char *Path, DemangleFn Demangle) {
1070 std::string ErrorInfo;
1072 raw_fd_ostream OS(Path, EC, sys::fs::F_None);
1074 ErrorInfo = EC.message();
1075 if (ErrorInfo != "") {
1076 LLVMRustSetLastError(ErrorInfo.c_str());
1077 return LLVMRustResult::Failure;
1080 RustAssemblyAnnotationWriter AAW(Demangle);
1081 formatted_raw_ostream FOS(OS);
1082 unwrap(M)->print(FOS, &AAW);
1084 return LLVMRustResult::Success;
1087 extern "C" void LLVMRustPrintPasses() {
1088 LLVMInitializePasses();
1089 struct MyListener : PassRegistrationListener {
1090 void passEnumerate(const PassInfo *Info) {
1091 StringRef PassArg = Info->getPassArgument();
1092 StringRef PassName = Info->getPassName();
1093 if (!PassArg.empty()) {
1094 // These unsigned->signed casts could theoretically overflow, but
1095 // realistically never will (and even if, the result is implementation
1096 // defined rather plain UB).
1097 printf("%15.*s - %.*s\n", (int)PassArg.size(), PassArg.data(),
1098 (int)PassName.size(), PassName.data());
1103 PassRegistry *PR = PassRegistry::getPassRegistry();
1104 PR->enumerateWith(&Listener);
1107 extern "C" void LLVMRustAddAlwaysInlinePass(LLVMPassManagerBuilderRef PMBR,
1108 bool AddLifetimes) {
1109 unwrap(PMBR)->Inliner = llvm::createAlwaysInlinerLegacyPass(AddLifetimes);
1112 extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **Symbols,
1114 llvm::legacy::PassManager passes;
1116 auto PreserveFunctions = [=](const GlobalValue &GV) {
1117 for (size_t I = 0; I < Len; I++) {
1118 if (GV.getName() == Symbols[I]) {
1125 passes.add(llvm::createInternalizePass(PreserveFunctions));
1127 passes.run(*unwrap(M));
1130 extern "C" void LLVMRustMarkAllFunctionsNounwind(LLVMModuleRef M) {
1131 for (Module::iterator GV = unwrap(M)->begin(), E = unwrap(M)->end(); GV != E;
1133 GV->setDoesNotThrow();
1134 Function *F = dyn_cast<Function>(GV);
1138 for (Function::iterator B = F->begin(), BE = F->end(); B != BE; ++B) {
1139 for (BasicBlock::iterator I = B->begin(), IE = B->end(); I != IE; ++I) {
1140 if (isa<InvokeInst>(I)) {
1141 InvokeInst *CI = cast<InvokeInst>(I);
1142 CI->setDoesNotThrow();
1150 LLVMRustSetDataLayoutFromTargetMachine(LLVMModuleRef Module,
1151 LLVMTargetMachineRef TMR) {
1152 TargetMachine *Target = unwrap(TMR);
1153 unwrap(Module)->setDataLayout(Target->createDataLayout());
1156 extern "C" void LLVMRustSetModulePICLevel(LLVMModuleRef M) {
1157 unwrap(M)->setPICLevel(PICLevel::Level::BigPIC);
1160 extern "C" void LLVMRustSetModulePIELevel(LLVMModuleRef M) {
1161 unwrap(M)->setPIELevel(PIELevel::Level::Large);
1164 // Here you'll find an implementation of ThinLTO as used by the Rust compiler
1165 // right now. This ThinLTO support is only enabled on "recent ish" versions of
1166 // LLVM, and otherwise it's just blanket rejected from other compilers.
1168 // Most of this implementation is straight copied from LLVM. At the time of
1169 // this writing it wasn't *quite* suitable to reuse more code from upstream
1170 // for our purposes, but we should strive to upstream this support once it's
1171 // ready to go! I figure we may want a bit of testing locally first before
1172 // sending this upstream to LLVM. I hear though they're quite eager to receive
1173 // feedback like this!
1175 // If you're reading this code and wondering "what in the world" or you're
1176 // working "good lord by LLVM upgrade is *still* failing due to these bindings"
1177 // then fear not! (ok maybe fear a little). All code here is mostly based
1178 // on `lib/LTO/ThinLTOCodeGenerator.cpp` in LLVM.
1180 // You'll find that the general layout here roughly corresponds to the `run`
1181 // method in that file as well as `ProcessThinLTOModule`. Functions are
1182 // specifically commented below as well, but if you're updating this code
1183 // or otherwise trying to understand it, the LLVM source will be useful in
1184 // interpreting the mysteries within.
1186 // Otherwise I'll apologize in advance, it probably requires a relatively
1187 // significant investment on your part to "truly understand" what's going on
1188 // here. Not saying I do myself, but it took me awhile staring at LLVM's source
1189 // and various online resources about ThinLTO to make heads or tails of all
1192 // This is a shared data structure which *must* be threadsafe to share
1193 // read-only amongst threads. This also corresponds basically to the arguments
1194 // of the `ProcessThinLTOModule` function in the LLVM source.
1195 struct LLVMRustThinLTOData {
1196 // The combined index that is the global analysis over all modules we're
1197 // performing ThinLTO for. This is mostly managed by LLVM.
1198 ModuleSummaryIndex Index;
1200 // All modules we may look at, stored as in-memory serialized versions. This
1201 // is later used when inlining to ensure we can extract any module to inline
1203 StringMap<MemoryBufferRef> ModuleMap;
1205 // A set that we manage of everything we *don't* want internalized. Note that
1206 // this includes all transitive references right now as well, but it may not
1208 DenseSet<GlobalValue::GUID> GUIDPreservedSymbols;
1210 // Not 100% sure what these are, but they impact what's internalized and
1211 // what's inlined across modules, I believe.
1212 StringMap<FunctionImporter::ImportMapTy> ImportLists;
1213 StringMap<FunctionImporter::ExportSetTy> ExportLists;
1214 StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries;
1216 LLVMRustThinLTOData() : Index(/* HaveGVs = */ false) {}
1219 // Just an argument to the `LLVMRustCreateThinLTOData` function below.
1220 struct LLVMRustThinLTOModule {
1221 const char *identifier;
1226 // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp`, not sure what it
1228 static const GlobalValueSummary *
1229 getFirstDefinitionForLinker(const GlobalValueSummaryList &GVSummaryList) {
1230 auto StrongDefForLinker = llvm::find_if(
1231 GVSummaryList, [](const std::unique_ptr<GlobalValueSummary> &Summary) {
1232 auto Linkage = Summary->linkage();
1233 return !GlobalValue::isAvailableExternallyLinkage(Linkage) &&
1234 !GlobalValue::isWeakForLinker(Linkage);
1236 if (StrongDefForLinker != GVSummaryList.end())
1237 return StrongDefForLinker->get();
1239 auto FirstDefForLinker = llvm::find_if(
1240 GVSummaryList, [](const std::unique_ptr<GlobalValueSummary> &Summary) {
1241 auto Linkage = Summary->linkage();
1242 return !GlobalValue::isAvailableExternallyLinkage(Linkage);
1244 if (FirstDefForLinker == GVSummaryList.end())
1246 return FirstDefForLinker->get();
1249 // The main entry point for creating the global ThinLTO analysis. The structure
1250 // here is basically the same as before threads are spawned in the `run`
1251 // function of `lib/LTO/ThinLTOCodeGenerator.cpp`.
1252 extern "C" LLVMRustThinLTOData*
1253 LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
1255 const char **preserved_symbols,
1257 #if LLVM_VERSION_GE(10, 0)
1258 auto Ret = std::make_unique<LLVMRustThinLTOData>();
1260 auto Ret = llvm::make_unique<LLVMRustThinLTOData>();
1263 // Load each module's summary and merge it into one combined index
1264 for (int i = 0; i < num_modules; i++) {
1265 auto module = &modules[i];
1266 StringRef buffer(module->data, module->len);
1267 MemoryBufferRef mem_buffer(buffer, module->identifier);
1269 Ret->ModuleMap[module->identifier] = mem_buffer;
1271 if (Error Err = readModuleSummaryIndex(mem_buffer, Ret->Index, i)) {
1272 LLVMRustSetLastError(toString(std::move(Err)).c_str());
1277 // Collect for each module the list of function it defines (GUID -> Summary)
1278 Ret->Index.collectDefinedGVSummariesPerModule(Ret->ModuleToDefinedGVSummaries);
1280 // Convert the preserved symbols set from string to GUID, this is then needed
1281 // for internalization.
1282 for (int i = 0; i < num_symbols; i++) {
1283 auto GUID = GlobalValue::getGUID(preserved_symbols[i]);
1284 Ret->GUIDPreservedSymbols.insert(GUID);
1287 // Collect the import/export lists for all modules from the call-graph in the
1290 // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp`
1291 auto deadIsPrevailing = [&](GlobalValue::GUID G) {
1292 return PrevailingType::Unknown;
1294 // We don't have a complete picture in our use of ThinLTO, just our immediate
1295 // crate, so we need `ImportEnabled = false` to limit internalization.
1296 // Otherwise, we sometimes lose `static` values -- see #60184.
1297 computeDeadSymbolsWithConstProp(Ret->Index, Ret->GUIDPreservedSymbols,
1298 deadIsPrevailing, /* ImportEnabled = */ false);
1299 ComputeCrossModuleImport(
1301 Ret->ModuleToDefinedGVSummaries,
1306 // Resolve LinkOnce/Weak symbols, this has to be computed early be cause it
1307 // impacts the caching.
1309 // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp` with some of this
1310 // being lifted from `lib/LTO/LTO.cpp` as well
1311 StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
1312 DenseMap<GlobalValue::GUID, const GlobalValueSummary *> PrevailingCopy;
1313 for (auto &I : Ret->Index) {
1314 if (I.second.SummaryList.size() > 1)
1315 PrevailingCopy[I.first] = getFirstDefinitionForLinker(I.second.SummaryList);
1317 auto isPrevailing = [&](GlobalValue::GUID GUID, const GlobalValueSummary *S) {
1318 const auto &Prevailing = PrevailingCopy.find(GUID);
1319 if (Prevailing == PrevailingCopy.end())
1321 return Prevailing->second == S;
1323 auto recordNewLinkage = [&](StringRef ModuleIdentifier,
1324 GlobalValue::GUID GUID,
1325 GlobalValue::LinkageTypes NewLinkage) {
1326 ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;
1328 #if LLVM_VERSION_GE(9, 0)
1329 thinLTOResolvePrevailingInIndex(Ret->Index, isPrevailing, recordNewLinkage,
1330 Ret->GUIDPreservedSymbols);
1332 thinLTOResolvePrevailingInIndex(Ret->Index, isPrevailing, recordNewLinkage);
1335 // Here we calculate an `ExportedGUIDs` set for use in the `isExported`
1336 // callback below. This callback below will dictate the linkage for all
1337 // summaries in the index, and we basically just only want to ensure that dead
1338 // symbols are internalized. Otherwise everything that's already external
1339 // linkage will stay as external, and internal will stay as internal.
1340 std::set<GlobalValue::GUID> ExportedGUIDs;
1341 for (auto &List : Ret->Index) {
1342 for (auto &GVS: List.second.SummaryList) {
1343 if (GlobalValue::isLocalLinkage(GVS->linkage()))
1345 auto GUID = GVS->getOriginalName();
1346 if (GVS->flags().Live)
1347 ExportedGUIDs.insert(GUID);
1350 #if LLVM_VERSION_GE(10, 0)
1351 auto isExported = [&](StringRef ModuleIdentifier, ValueInfo VI) {
1352 const auto &ExportList = Ret->ExportLists.find(ModuleIdentifier);
1353 return (ExportList != Ret->ExportLists.end() &&
1354 ExportList->second.count(VI)) ||
1355 ExportedGUIDs.count(VI.getGUID());
1357 thinLTOInternalizeAndPromoteInIndex(Ret->Index, isExported, isPrevailing);
1359 auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) {
1360 const auto &ExportList = Ret->ExportLists.find(ModuleIdentifier);
1361 return (ExportList != Ret->ExportLists.end() &&
1362 ExportList->second.count(GUID)) ||
1363 ExportedGUIDs.count(GUID);
1365 thinLTOInternalizeAndPromoteInIndex(Ret->Index, isExported);
1368 return Ret.release();
1372 LLVMRustFreeThinLTOData(LLVMRustThinLTOData *Data) {
1376 // Below are the various passes that happen *per module* when doing ThinLTO.
1378 // In other words, these are the functions that are all run concurrently
1379 // with one another, one per module. The passes here correspond to the analysis
1380 // passes in `lib/LTO/ThinLTOCodeGenerator.cpp`, currently found in the
1381 // `ProcessThinLTOModule` function. Here they're split up into separate steps
1382 // so rustc can save off the intermediate bytecode between each step.
1384 #if LLVM_VERSION_GE(11, 0)
1386 clearDSOLocalOnDeclarations(Module &Mod, TargetMachine &TM) {
1387 // When linking an ELF shared object, dso_local should be dropped. We
1388 // conservatively do this for -fpic.
1389 bool ClearDSOLocalOnDeclarations =
1390 TM.getTargetTriple().isOSBinFormatELF() &&
1391 TM.getRelocationModel() != Reloc::Static &&
1392 Mod.getPIELevel() == PIELevel::Default;
1393 return ClearDSOLocalOnDeclarations;
1398 LLVMRustPrepareThinLTORename(const LLVMRustThinLTOData *Data, LLVMModuleRef M,
1399 LLVMTargetMachineRef TM) {
1400 Module &Mod = *unwrap(M);
1401 TargetMachine &Target = *unwrap(TM);
1403 #if LLVM_VERSION_GE(11, 0)
1404 bool ClearDSOLocal = clearDSOLocalOnDeclarations(Mod, Target);
1405 bool error = renameModuleForThinLTO(Mod, Data->Index, ClearDSOLocal);
1407 bool error = renameModuleForThinLTO(Mod, Data->Index);
1411 LLVMRustSetLastError("renameModuleForThinLTO failed");
1418 LLVMRustPrepareThinLTOResolveWeak(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
1419 Module &Mod = *unwrap(M);
1420 const auto &DefinedGlobals = Data->ModuleToDefinedGVSummaries.lookup(Mod.getModuleIdentifier());
1421 thinLTOResolvePrevailingInModule(Mod, DefinedGlobals);
1426 LLVMRustPrepareThinLTOInternalize(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
1427 Module &Mod = *unwrap(M);
1428 const auto &DefinedGlobals = Data->ModuleToDefinedGVSummaries.lookup(Mod.getModuleIdentifier());
1429 thinLTOInternalizeModule(Mod, DefinedGlobals);
1434 LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, LLVMModuleRef M,
1435 LLVMTargetMachineRef TM) {
1436 Module &Mod = *unwrap(M);
1437 TargetMachine &Target = *unwrap(TM);
1439 const auto &ImportList = Data->ImportLists.lookup(Mod.getModuleIdentifier());
1440 auto Loader = [&](StringRef Identifier) {
1441 const auto &Memory = Data->ModuleMap.lookup(Identifier);
1442 auto &Context = Mod.getContext();
1443 auto MOrErr = getLazyBitcodeModule(Memory, Context, true, true);
1448 // The rest of this closure is a workaround for
1449 // https://bugs.llvm.org/show_bug.cgi?id=38184 where during ThinLTO imports
1450 // we accidentally import wasm custom sections into different modules,
1451 // duplicating them by in the final output artifact.
1453 // The issue is worked around here by manually removing the
1454 // `wasm.custom_sections` named metadata node from any imported module. This
1455 // we know isn't used by any optimization pass so there's no need for it to
1458 // Note that the metadata is currently lazily loaded, so we materialize it
1459 // here before looking up if there's metadata inside. The `FunctionImporter`
1460 // will immediately materialize metadata anyway after an import, so this
1461 // shouldn't be a perf hit.
1462 if (Error Err = (*MOrErr)->materializeMetadata()) {
1463 Expected<std::unique_ptr<Module>> Ret(std::move(Err));
1467 auto *WasmCustomSections = (*MOrErr)->getNamedMetadata("wasm.custom_sections");
1468 if (WasmCustomSections)
1469 WasmCustomSections->eraseFromParent();
1473 #if LLVM_VERSION_GE(11, 0)
1474 bool ClearDSOLocal = clearDSOLocalOnDeclarations(Mod, Target);
1475 FunctionImporter Importer(Data->Index, Loader, ClearDSOLocal);
1477 FunctionImporter Importer(Data->Index, Loader);
1479 Expected<bool> Result = Importer.importFunctions(Mod, ImportList);
1481 LLVMRustSetLastError(toString(Result.takeError()).c_str());
1487 extern "C" typedef void (*LLVMRustModuleNameCallback)(void*, // payload
1488 const char*, // importing module name
1489 const char*); // imported module name
1491 // Calls `module_name_callback` for each module import done by ThinLTO.
1492 // The callback is provided with regular null-terminated C strings.
1494 LLVMRustGetThinLTOModuleImports(const LLVMRustThinLTOData *data,
1495 LLVMRustModuleNameCallback module_name_callback,
1496 void* callback_payload) {
1497 for (const auto& importing_module : data->ImportLists) {
1498 const std::string importing_module_id = importing_module.getKey().str();
1499 const auto& imports = importing_module.getValue();
1500 for (const auto& imported_module : imports) {
1501 const std::string imported_module_id = imported_module.getKey().str();
1502 module_name_callback(callback_payload,
1503 importing_module_id.c_str(),
1504 imported_module_id.c_str());
1509 // This struct and various functions are sort of a hack right now, but the
1510 // problem is that we've got in-memory LLVM modules after we generate and
1511 // optimize all codegen-units for one compilation in rustc. To be compatible
1512 // with the LTO support above we need to serialize the modules plus their
1513 // ThinLTO summary into memory.
1515 // This structure is basically an owned version of a serialize module, with
1516 // a ThinLTO summary attached.
1517 struct LLVMRustThinLTOBuffer {
1521 extern "C" LLVMRustThinLTOBuffer*
1522 LLVMRustThinLTOBufferCreate(LLVMModuleRef M) {
1523 #if LLVM_VERSION_GE(10, 0)
1524 auto Ret = std::make_unique<LLVMRustThinLTOBuffer>();
1526 auto Ret = llvm::make_unique<LLVMRustThinLTOBuffer>();
1529 raw_string_ostream OS(Ret->data);
1531 legacy::PassManager PM;
1532 PM.add(createWriteThinLTOBitcodePass(OS));
1536 return Ret.release();
1540 LLVMRustThinLTOBufferFree(LLVMRustThinLTOBuffer *Buffer) {
1544 extern "C" const void*
1545 LLVMRustThinLTOBufferPtr(const LLVMRustThinLTOBuffer *Buffer) {
1546 return Buffer->data.data();
1550 LLVMRustThinLTOBufferLen(const LLVMRustThinLTOBuffer *Buffer) {
1551 return Buffer->data.length();
1554 // This is what we used to parse upstream bitcode for actual ThinLTO
1555 // processing. We'll call this once per module optimized through ThinLTO, and
1556 // it'll be called concurrently on many threads.
1557 extern "C" LLVMModuleRef
1558 LLVMRustParseBitcodeForLTO(LLVMContextRef Context,
1561 const char *identifier) {
1562 StringRef Data(data, len);
1563 MemoryBufferRef Buffer(Data, identifier);
1564 unwrap(Context)->enableDebugTypeODRUniquing();
1565 Expected<std::unique_ptr<Module>> SrcOrError =
1566 parseBitcodeFile(Buffer, *unwrap(Context));
1568 LLVMRustSetLastError(toString(SrcOrError.takeError()).c_str());
1571 return wrap(std::move(*SrcOrError).release());
1574 // Find the bitcode section in the object file data and return it as a slice.
1575 // Fail if the bitcode section is present but empty.
1577 // On success, the return value is the pointer to the start of the slice and
1578 // `out_len` is filled with the (non-zero) length. On failure, the return value
1579 // is `nullptr` and `out_len` is set to zero.
1580 extern "C" const char*
1581 LLVMRustGetBitcodeSliceFromObjectData(const char *data,
1586 StringRef Data(data, len);
1587 MemoryBufferRef Buffer(Data, ""); // The id is unused.
1589 Expected<MemoryBufferRef> BitcodeOrError =
1590 object::IRObjectFile::findBitcodeInMemBuffer(Buffer);
1591 if (!BitcodeOrError) {
1592 LLVMRustSetLastError(toString(BitcodeOrError.takeError()).c_str());
1596 *out_len = BitcodeOrError->getBufferSize();
1597 return BitcodeOrError->getBufferStart();
1600 // Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
1601 // the comment in `back/lto.rs` for why this exists.
1603 LLVMRustThinLTOGetDICompileUnit(LLVMModuleRef Mod,
1605 DICompileUnit **B) {
1606 Module *M = unwrap(Mod);
1607 DICompileUnit **Cur = A;
1608 DICompileUnit **Next = B;
1609 for (DICompileUnit *CU : M->debug_compile_units()) {
1618 // Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
1619 // the comment in `back/lto.rs` for why this exists.
1621 LLVMRustThinLTOPatchDICompileUnit(LLVMModuleRef Mod, DICompileUnit *Unit) {
1622 Module *M = unwrap(Mod);
1624 // If the original source module didn't have a `DICompileUnit` then try to
1625 // merge all the existing compile units. If there aren't actually any though
1626 // then there's not much for us to do so return.
1627 if (Unit == nullptr) {
1628 for (DICompileUnit *CU : M->debug_compile_units()) {
1632 if (Unit == nullptr)
1636 // Use LLVM's built-in `DebugInfoFinder` to find a bunch of debuginfo and
1637 // process it recursively. Note that we used to specifically iterate over
1638 // instructions to ensure we feed everything into it, but `processModule`
1639 // started doing this the same way in LLVM 7 (commit d769eb36ab2b8).
1640 DebugInfoFinder Finder;
1641 Finder.processModule(*M);
1643 // After we've found all our debuginfo, rewrite all subprograms to point to
1644 // the same `DICompileUnit`.
1645 for (auto &F : Finder.subprograms()) {
1646 F->replaceUnit(Unit);
1649 // Erase any other references to other `DICompileUnit` instances, the verifier
1650 // will later ensure that we don't actually have any other stale references to
1652 auto *MD = M->getNamedMetadata("llvm.dbg.cu");
1653 MD->clearOperands();
1654 MD->addOperand(Unit);