]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
Rollup merge of #106997 - Sp00ph:introselect, r=scottmcm
[rust.git] / compiler / rustc_llvm / llvm-wrapper / PassWrapper.cpp
1 #include <stdio.h>
2
3 #include <vector>
4 #include <set>
5
6 #include "LLVMWrapper.h"
7
8 #include "llvm/Analysis/AliasAnalysis.h"
9 #include "llvm/Analysis/TargetLibraryInfo.h"
10 #include "llvm/Analysis/TargetTransformInfo.h"
11 #include "llvm/CodeGen/TargetSubtargetInfo.h"
12 #include "llvm/InitializePasses.h"
13 #include "llvm/IR/AutoUpgrade.h"
14 #include "llvm/IR/AssemblyAnnotationWriter.h"
15 #include "llvm/IR/IntrinsicInst.h"
16 #include "llvm/IR/Verifier.h"
17 #include "llvm/Object/ObjectFile.h"
18 #include "llvm/Object/IRObjectFile.h"
19 #include "llvm/Passes/PassBuilder.h"
20 #include "llvm/Passes/PassPlugin.h"
21 #include "llvm/Passes/StandardInstrumentations.h"
22 #include "llvm/Support/CBindingWrapping.h"
23 #include "llvm/Support/FileSystem.h"
24 #include "llvm/Support/Host.h"
25 #if LLVM_VERSION_LT(14, 0)
26 #include "llvm/Support/TargetRegistry.h"
27 #else
28 #include "llvm/MC/TargetRegistry.h"
29 #endif
30 #include "llvm/Target/TargetMachine.h"
31 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
32 #include "llvm/Transforms/IPO/AlwaysInliner.h"
33 #include "llvm/Transforms/IPO/FunctionImport.h"
34 #include "llvm/Transforms/IPO/Internalize.h"
35 #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
36 #include "llvm/Transforms/Utils/AddDiscriminators.h"
37 #include "llvm/Transforms/Utils/FunctionImportUtils.h"
38 #include "llvm/LTO/LTO.h"
39 #include "llvm/Bitcode/BitcodeWriter.h"
40 #include "llvm-c/Transforms/PassManagerBuilder.h"
41
42 #include "llvm/Transforms/Instrumentation.h"
43 #include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
44 #include "llvm/Support/TimeProfiler.h"
45 #include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
46 #include "llvm/Transforms/Instrumentation/InstrProfiling.h"
47 #include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
48 #include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
49 #include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
50 #include "llvm/Transforms/Utils/CanonicalizeAliases.h"
51 #include "llvm/Transforms/Utils/NameAnonGlobals.h"
52 #include "llvm/Transforms/Utils.h"
53
54 using namespace llvm;
55
56 typedef struct LLVMOpaquePass *LLVMPassRef;
57 typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef;
58
59 DEFINE_STDCXX_CONVERSION_FUNCTIONS(Pass, LLVMPassRef)
60 DEFINE_STDCXX_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
61
62 extern "C" void LLVMInitializePasses() {
63   PassRegistry &Registry = *PassRegistry::getPassRegistry();
64   initializeCore(Registry);
65   initializeCodeGen(Registry);
66   initializeScalarOpts(Registry);
67   initializeVectorization(Registry);
68   initializeIPO(Registry);
69   initializeAnalysis(Registry);
70   initializeTransformUtils(Registry);
71   initializeInstCombine(Registry);
72 #if LLVM_VERSION_LT(16, 0)
73   initializeInstrumentation(Registry);
74 #endif
75   initializeTarget(Registry);
76 }
77
78 extern "C" void LLVMTimeTraceProfilerInitialize() {
79   timeTraceProfilerInitialize(
80       /* TimeTraceGranularity */ 0,
81       /* ProcName */ "rustc");
82 }
83
84 extern "C" void LLVMTimeTraceProfilerFinishThread() {
85   timeTraceProfilerFinishThread();
86 }
87
88 extern "C" void LLVMTimeTraceProfilerFinish(const char* FileName) {
89   StringRef FN(FileName);
90   std::error_code EC;
91   raw_fd_ostream OS(FN, EC, sys::fs::CD_CreateAlways);
92
93   timeTraceProfilerWrite(OS);
94   timeTraceProfilerCleanup();
95 }
96
97 #ifdef LLVM_COMPONENT_X86
98 #define SUBTARGET_X86 SUBTARGET(X86)
99 #else
100 #define SUBTARGET_X86
101 #endif
102
103 #ifdef LLVM_COMPONENT_ARM
104 #define SUBTARGET_ARM SUBTARGET(ARM)
105 #else
106 #define SUBTARGET_ARM
107 #endif
108
109 #ifdef LLVM_COMPONENT_AARCH64
110 #define SUBTARGET_AARCH64 SUBTARGET(AArch64)
111 #else
112 #define SUBTARGET_AARCH64
113 #endif
114
115 #ifdef LLVM_COMPONENT_AVR
116 #define SUBTARGET_AVR SUBTARGET(AVR)
117 #else
118 #define SUBTARGET_AVR
119 #endif
120
121 #ifdef LLVM_COMPONENT_M68k
122 #define SUBTARGET_M68K SUBTARGET(M68k)
123 #else
124 #define SUBTARGET_M68K
125 #endif
126
127 #ifdef LLVM_COMPONENT_MIPS
128 #define SUBTARGET_MIPS SUBTARGET(Mips)
129 #else
130 #define SUBTARGET_MIPS
131 #endif
132
133 #ifdef LLVM_COMPONENT_POWERPC
134 #define SUBTARGET_PPC SUBTARGET(PPC)
135 #else
136 #define SUBTARGET_PPC
137 #endif
138
139 #ifdef LLVM_COMPONENT_SYSTEMZ
140 #define SUBTARGET_SYSTEMZ SUBTARGET(SystemZ)
141 #else
142 #define SUBTARGET_SYSTEMZ
143 #endif
144
145 #ifdef LLVM_COMPONENT_MSP430
146 #define SUBTARGET_MSP430 SUBTARGET(MSP430)
147 #else
148 #define SUBTARGET_MSP430
149 #endif
150
151 #ifdef LLVM_COMPONENT_RISCV
152 #define SUBTARGET_RISCV SUBTARGET(RISCV)
153 #else
154 #define SUBTARGET_RISCV
155 #endif
156
157 #ifdef LLVM_COMPONENT_SPARC
158 #define SUBTARGET_SPARC SUBTARGET(Sparc)
159 #else
160 #define SUBTARGET_SPARC
161 #endif
162
163 #ifdef LLVM_COMPONENT_HEXAGON
164 #define SUBTARGET_HEXAGON SUBTARGET(Hexagon)
165 #else
166 #define SUBTARGET_HEXAGON
167 #endif
168
169 #define GEN_SUBTARGETS                                                         \
170   SUBTARGET_X86                                                                \
171   SUBTARGET_ARM                                                                \
172   SUBTARGET_AARCH64                                                            \
173   SUBTARGET_AVR                                                                \
174   SUBTARGET_M68K                                                               \
175   SUBTARGET_MIPS                                                               \
176   SUBTARGET_PPC                                                                \
177   SUBTARGET_SYSTEMZ                                                            \
178   SUBTARGET_MSP430                                                             \
179   SUBTARGET_SPARC                                                              \
180   SUBTARGET_HEXAGON                                                            \
181   SUBTARGET_RISCV                                                              \
182
183 #define SUBTARGET(x)                                                           \
184   namespace llvm {                                                             \
185   extern const SubtargetFeatureKV x##FeatureKV[];                              \
186   extern const SubtargetFeatureKV x##SubTypeKV[];                              \
187   }
188
189 GEN_SUBTARGETS
190 #undef SUBTARGET
191
192 extern "C" bool LLVMRustHasFeature(LLVMTargetMachineRef TM,
193                                    const char *Feature) {
194   TargetMachine *Target = unwrap(TM);
195   const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
196   return MCInfo->checkFeatures(std::string("+") + Feature);
197 }
198
199 enum class LLVMRustCodeModel {
200   Tiny,
201   Small,
202   Kernel,
203   Medium,
204   Large,
205   None,
206 };
207
208 #if LLVM_VERSION_LT(16, 0)
209 static Optional<CodeModel::Model>
210 #else
211 static std::optional<CodeModel::Model>
212 #endif
213 fromRust(LLVMRustCodeModel Model) {
214   switch (Model) {
215   case LLVMRustCodeModel::Tiny:
216     return CodeModel::Tiny;
217   case LLVMRustCodeModel::Small:
218     return CodeModel::Small;
219   case LLVMRustCodeModel::Kernel:
220     return CodeModel::Kernel;
221   case LLVMRustCodeModel::Medium:
222     return CodeModel::Medium;
223   case LLVMRustCodeModel::Large:
224     return CodeModel::Large;
225   case LLVMRustCodeModel::None:
226 #if LLVM_VERSION_LT(16, 0)
227     return None;
228 #else
229     return std::nullopt;
230 #endif
231   default:
232     report_fatal_error("Bad CodeModel.");
233   }
234 }
235
236 enum class LLVMRustCodeGenOptLevel {
237   None,
238   Less,
239   Default,
240   Aggressive,
241 };
242
243 static CodeGenOpt::Level fromRust(LLVMRustCodeGenOptLevel Level) {
244   switch (Level) {
245   case LLVMRustCodeGenOptLevel::None:
246     return CodeGenOpt::None;
247   case LLVMRustCodeGenOptLevel::Less:
248     return CodeGenOpt::Less;
249   case LLVMRustCodeGenOptLevel::Default:
250     return CodeGenOpt::Default;
251   case LLVMRustCodeGenOptLevel::Aggressive:
252     return CodeGenOpt::Aggressive;
253   default:
254     report_fatal_error("Bad CodeGenOptLevel.");
255   }
256 }
257
258 enum class LLVMRustPassBuilderOptLevel {
259   O0,
260   O1,
261   O2,
262   O3,
263   Os,
264   Oz,
265 };
266
267 #if LLVM_VERSION_LT(14,0)
268 using OptimizationLevel = PassBuilder::OptimizationLevel;
269 #endif
270
271 static OptimizationLevel fromRust(LLVMRustPassBuilderOptLevel Level) {
272   switch (Level) {
273   case LLVMRustPassBuilderOptLevel::O0:
274     return OptimizationLevel::O0;
275   case LLVMRustPassBuilderOptLevel::O1:
276     return OptimizationLevel::O1;
277   case LLVMRustPassBuilderOptLevel::O2:
278     return OptimizationLevel::O2;
279   case LLVMRustPassBuilderOptLevel::O3:
280     return OptimizationLevel::O3;
281   case LLVMRustPassBuilderOptLevel::Os:
282     return OptimizationLevel::Os;
283   case LLVMRustPassBuilderOptLevel::Oz:
284     return OptimizationLevel::Oz;
285   default:
286     report_fatal_error("Bad PassBuilderOptLevel.");
287   }
288 }
289
290 enum class LLVMRustRelocModel {
291   Static,
292   PIC,
293   DynamicNoPic,
294   ROPI,
295   RWPI,
296   ROPIRWPI,
297 };
298
299 static Reloc::Model fromRust(LLVMRustRelocModel RustReloc) {
300   switch (RustReloc) {
301   case LLVMRustRelocModel::Static:
302     return Reloc::Static;
303   case LLVMRustRelocModel::PIC:
304     return Reloc::PIC_;
305   case LLVMRustRelocModel::DynamicNoPic:
306     return Reloc::DynamicNoPIC;
307   case LLVMRustRelocModel::ROPI:
308     return Reloc::ROPI;
309   case LLVMRustRelocModel::RWPI:
310     return Reloc::RWPI;
311   case LLVMRustRelocModel::ROPIRWPI:
312     return Reloc::ROPI_RWPI;
313   }
314   report_fatal_error("Bad RelocModel.");
315 }
316
317 #ifdef LLVM_RUSTLLVM
318 /// getLongestEntryLength - Return the length of the longest entry in the table.
319 template<typename KV>
320 static size_t getLongestEntryLength(ArrayRef<KV> Table) {
321   size_t MaxLen = 0;
322   for (auto &I : Table)
323     MaxLen = std::max(MaxLen, std::strlen(I.Key));
324   return MaxLen;
325 }
326
327 extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM) {
328   const TargetMachine *Target = unwrap(TM);
329   const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
330   const Triple::ArchType HostArch = Triple(sys::getProcessTriple()).getArch();
331   const Triple::ArchType TargetArch = Target->getTargetTriple().getArch();
332   const ArrayRef<SubtargetSubTypeKV> CPUTable = MCInfo->getCPUTable();
333   unsigned MaxCPULen = getLongestEntryLength(CPUTable);
334
335   printf("Available CPUs for this target:\n");
336   if (HostArch == TargetArch) {
337     const StringRef HostCPU = sys::getHostCPUName();
338     printf("    %-*s - Select the CPU of the current host (currently %.*s).\n",
339       MaxCPULen, "native", (int)HostCPU.size(), HostCPU.data());
340   }
341   for (auto &CPU : CPUTable)
342     printf("    %-*s\n", MaxCPULen, CPU.Key);
343   printf("\n");
344 }
345
346 extern "C" size_t LLVMRustGetTargetFeaturesCount(LLVMTargetMachineRef TM) {
347   const TargetMachine *Target = unwrap(TM);
348   const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
349   const ArrayRef<SubtargetFeatureKV> FeatTable = MCInfo->getFeatureTable();
350   return FeatTable.size();
351 }
352
353 extern "C" void LLVMRustGetTargetFeature(LLVMTargetMachineRef TM, size_t Index,
354                                          const char** Feature, const char** Desc) {
355   const TargetMachine *Target = unwrap(TM);
356   const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
357   const ArrayRef<SubtargetFeatureKV> FeatTable = MCInfo->getFeatureTable();
358   const SubtargetFeatureKV Feat = FeatTable[Index];
359   *Feature = Feat.Key;
360   *Desc = Feat.Desc;
361 }
362
363 #else
364
365 extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef) {
366   printf("Target CPU help is not supported by this LLVM version.\n\n");
367 }
368
369 extern "C" size_t LLVMRustGetTargetFeaturesCount(LLVMTargetMachineRef) {
370   return 0;
371 }
372
373 extern "C" void LLVMRustGetTargetFeature(LLVMTargetMachineRef, const char**, const char**) {}
374 #endif
375
376 extern "C" const char* LLVMRustGetHostCPUName(size_t *len) {
377   StringRef Name = sys::getHostCPUName();
378   *len = Name.size();
379   return Name.data();
380 }
381
382 extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
383     const char *TripleStr, const char *CPU, const char *Feature,
384     const char *ABIStr, LLVMRustCodeModel RustCM, LLVMRustRelocModel RustReloc,
385     LLVMRustCodeGenOptLevel RustOptLevel, bool UseSoftFloat,
386     bool FunctionSections,
387     bool DataSections,
388     bool UniqueSectionNames,
389     bool TrapUnreachable,
390     bool Singlethread,
391     bool AsmComments,
392     bool EmitStackSizeSection,
393     bool RelaxELFRelocations,
394     bool UseInitArray,
395     const char *SplitDwarfFile) {
396
397   auto OptLevel = fromRust(RustOptLevel);
398   auto RM = fromRust(RustReloc);
399   auto CM = fromRust(RustCM);
400
401   std::string Error;
402   Triple Trip(Triple::normalize(TripleStr));
403   const llvm::Target *TheTarget =
404       TargetRegistry::lookupTarget(Trip.getTriple(), Error);
405   if (TheTarget == nullptr) {
406     LLVMRustSetLastError(Error.c_str());
407     return nullptr;
408   }
409
410   TargetOptions Options;
411
412   Options.FloatABIType = FloatABI::Default;
413   if (UseSoftFloat) {
414     Options.FloatABIType = FloatABI::Soft;
415   }
416   Options.DataSections = DataSections;
417   Options.FunctionSections = FunctionSections;
418   Options.UniqueSectionNames = UniqueSectionNames;
419   Options.MCOptions.AsmVerbose = AsmComments;
420   Options.MCOptions.PreserveAsmComments = AsmComments;
421   Options.MCOptions.ABIName = ABIStr;
422   if (SplitDwarfFile) {
423       Options.MCOptions.SplitDwarfFile = SplitDwarfFile;
424   }
425   Options.RelaxELFRelocations = RelaxELFRelocations;
426   Options.UseInitArray = UseInitArray;
427
428   if (TrapUnreachable) {
429     // Tell LLVM to codegen `unreachable` into an explicit trap instruction.
430     // This limits the extent of possible undefined behavior in some cases, as
431     // it prevents control flow from "falling through" into whatever code
432     // happens to be laid out next in memory.
433     Options.TrapUnreachable = true;
434   }
435
436   if (Singlethread) {
437     Options.ThreadModel = ThreadModel::Single;
438   }
439
440   Options.EmitStackSizeSection = EmitStackSizeSection;
441
442   TargetMachine *TM = TheTarget->createTargetMachine(
443       Trip.getTriple(), CPU, Feature, Options, RM, CM, OptLevel);
444   return wrap(TM);
445 }
446
447 extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) {
448   delete unwrap(TM);
449 }
450
451 // Unfortunately, the LLVM C API doesn't provide a way to create the
452 // TargetLibraryInfo pass, so we use this method to do so.
453 extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR, LLVMModuleRef M,
454                                        bool DisableSimplifyLibCalls) {
455   Triple TargetTriple(unwrap(M)->getTargetTriple());
456   TargetLibraryInfoImpl TLII(TargetTriple);
457   if (DisableSimplifyLibCalls)
458     TLII.disableAllFunctions();
459   unwrap(PMR)->add(new TargetLibraryInfoWrapperPass(TLII));
460 }
461
462 extern "C" void LLVMRustSetLLVMOptions(int Argc, char **Argv) {
463   // Initializing the command-line options more than once is not allowed. So,
464   // check if they've already been initialized. (This could happen if we're
465   // being called from rustpkg, for example). If the arguments change, then
466   // that's just kinda unfortunate.
467   static bool Initialized = false;
468   if (Initialized)
469     return;
470   Initialized = true;
471   cl::ParseCommandLineOptions(Argc, Argv);
472 }
473
474 enum class LLVMRustFileType {
475   AssemblyFile,
476   ObjectFile,
477 };
478
479 static CodeGenFileType fromRust(LLVMRustFileType Type) {
480   switch (Type) {
481   case LLVMRustFileType::AssemblyFile:
482     return CGFT_AssemblyFile;
483   case LLVMRustFileType::ObjectFile:
484     return CGFT_ObjectFile;
485   default:
486     report_fatal_error("Bad FileType.");
487   }
488 }
489
490 extern "C" LLVMRustResult
491 LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR,
492                         LLVMModuleRef M, const char *Path, const char *DwoPath,
493                         LLVMRustFileType RustFileType) {
494   llvm::legacy::PassManager *PM = unwrap<llvm::legacy::PassManager>(PMR);
495   auto FileType = fromRust(RustFileType);
496
497   std::string ErrorInfo;
498   std::error_code EC;
499   raw_fd_ostream OS(Path, EC, sys::fs::OF_None);
500   if (EC)
501     ErrorInfo = EC.message();
502   if (ErrorInfo != "") {
503     LLVMRustSetLastError(ErrorInfo.c_str());
504     return LLVMRustResult::Failure;
505   }
506
507   buffer_ostream BOS(OS);
508   if (DwoPath) {
509     raw_fd_ostream DOS(DwoPath, EC, sys::fs::OF_None);
510     EC.clear();
511     if (EC)
512         ErrorInfo = EC.message();
513     if (ErrorInfo != "") {
514       LLVMRustSetLastError(ErrorInfo.c_str());
515       return LLVMRustResult::Failure;
516     }
517     buffer_ostream DBOS(DOS);
518     unwrap(Target)->addPassesToEmitFile(*PM, BOS, &DBOS, FileType, false);
519     PM->run(*unwrap(M));
520   } else {
521     unwrap(Target)->addPassesToEmitFile(*PM, BOS, nullptr, FileType, false);
522     PM->run(*unwrap(M));
523   }
524
525   // Apparently `addPassesToEmitFile` adds a pointer to our on-the-stack output
526   // stream (OS), so the only real safe place to delete this is here? Don't we
527   // wish this was written in Rust?
528   LLVMDisposePassManager(PMR);
529   return LLVMRustResult::Success;
530 }
531
532 extern "C" typedef void (*LLVMRustSelfProfileBeforePassCallback)(void*, // LlvmSelfProfiler
533                                                       const char*,      // pass name
534                                                       const char*);     // IR name
535 extern "C" typedef void (*LLVMRustSelfProfileAfterPassCallback)(void*); // LlvmSelfProfiler
536
537 std::string LLVMRustwrappedIrGetName(const llvm::Any &WrappedIr) {
538   if (any_isa<const Module *>(WrappedIr))
539     return any_cast<const Module *>(WrappedIr)->getName().str();
540   if (any_isa<const Function *>(WrappedIr))
541     return any_cast<const Function *>(WrappedIr)->getName().str();
542   if (any_isa<const Loop *>(WrappedIr))
543     return any_cast<const Loop *>(WrappedIr)->getName().str();
544   if (any_isa<const LazyCallGraph::SCC *>(WrappedIr))
545     return any_cast<const LazyCallGraph::SCC *>(WrappedIr)->getName();
546   return "<UNKNOWN>";
547 }
548
549
550 void LLVMSelfProfileInitializeCallbacks(
551     PassInstrumentationCallbacks& PIC, void* LlvmSelfProfiler,
552     LLVMRustSelfProfileBeforePassCallback BeforePassCallback,
553     LLVMRustSelfProfileAfterPassCallback AfterPassCallback) {
554   PIC.registerBeforeNonSkippedPassCallback([LlvmSelfProfiler, BeforePassCallback](
555                                            StringRef Pass, llvm::Any Ir) {
556     std::string PassName = Pass.str();
557     std::string IrName = LLVMRustwrappedIrGetName(Ir);
558     BeforePassCallback(LlvmSelfProfiler, PassName.c_str(), IrName.c_str());
559   });
560
561   PIC.registerAfterPassCallback(
562       [LlvmSelfProfiler, AfterPassCallback](StringRef Pass, llvm::Any IR,
563                                             const PreservedAnalyses &Preserved) {
564         AfterPassCallback(LlvmSelfProfiler);
565       });
566
567   PIC.registerAfterPassInvalidatedCallback(
568       [LlvmSelfProfiler, AfterPassCallback](StringRef Pass, const PreservedAnalyses &Preserved) {
569         AfterPassCallback(LlvmSelfProfiler);
570       });
571
572   PIC.registerBeforeAnalysisCallback([LlvmSelfProfiler, BeforePassCallback](
573                                          StringRef Pass, llvm::Any Ir) {
574     std::string PassName = Pass.str();
575     std::string IrName = LLVMRustwrappedIrGetName(Ir);
576     BeforePassCallback(LlvmSelfProfiler, PassName.c_str(), IrName.c_str());
577   });
578
579   PIC.registerAfterAnalysisCallback(
580       [LlvmSelfProfiler, AfterPassCallback](StringRef Pass, llvm::Any Ir) {
581         AfterPassCallback(LlvmSelfProfiler);
582       });
583 }
584
585 enum class LLVMRustOptStage {
586   PreLinkNoLTO,
587   PreLinkThinLTO,
588   PreLinkFatLTO,
589   ThinLTO,
590   FatLTO,
591 };
592
593 struct LLVMRustSanitizerOptions {
594   bool SanitizeAddress;
595   bool SanitizeAddressRecover;
596   bool SanitizeMemory;
597   bool SanitizeMemoryRecover;
598   int  SanitizeMemoryTrackOrigins;
599   bool SanitizeThread;
600   bool SanitizeHWAddress;
601   bool SanitizeHWAddressRecover;
602 };
603
604 extern "C" LLVMRustResult
605 LLVMRustOptimize(
606     LLVMModuleRef ModuleRef,
607     LLVMTargetMachineRef TMRef,
608     LLVMRustPassBuilderOptLevel OptLevelRust,
609     LLVMRustOptStage OptStage,
610     bool NoPrepopulatePasses, bool VerifyIR, bool UseThinLTOBuffers,
611     bool MergeFunctions, bool UnrollLoops, bool SLPVectorize, bool LoopVectorize,
612     bool DisableSimplifyLibCalls, bool EmitLifetimeMarkers,
613     LLVMRustSanitizerOptions *SanitizerOptions,
614     const char *PGOGenPath, const char *PGOUsePath,
615     bool InstrumentCoverage, const char *InstrProfileOutput,
616     bool InstrumentGCOV,
617     const char *PGOSampleUsePath, bool DebugInfoForProfiling,
618     void* LlvmSelfProfiler,
619     LLVMRustSelfProfileBeforePassCallback BeforePassCallback,
620     LLVMRustSelfProfileAfterPassCallback AfterPassCallback,
621     const char *ExtraPasses, size_t ExtraPassesLen,
622     const char *LLVMPlugins, size_t LLVMPluginsLen) {
623   Module *TheModule = unwrap(ModuleRef);
624   TargetMachine *TM = unwrap(TMRef);
625   OptimizationLevel OptLevel = fromRust(OptLevelRust);
626
627
628   PipelineTuningOptions PTO;
629   PTO.LoopUnrolling = UnrollLoops;
630   PTO.LoopInterleaving = UnrollLoops;
631   PTO.LoopVectorization = LoopVectorize;
632   PTO.SLPVectorization = SLPVectorize;
633   PTO.MergeFunctions = MergeFunctions;
634
635   // FIXME: We may want to expose this as an option.
636   bool DebugPassManager = false;
637
638   PassInstrumentationCallbacks PIC;
639 #if LLVM_VERSION_LT(16, 0)
640   StandardInstrumentations SI(DebugPassManager);
641 #else
642   StandardInstrumentations SI(TheModule->getContext(), DebugPassManager);
643 #endif
644   SI.registerCallbacks(PIC);
645
646   if (LlvmSelfProfiler){
647     LLVMSelfProfileInitializeCallbacks(PIC,LlvmSelfProfiler,BeforePassCallback,AfterPassCallback);
648   }
649
650 #if LLVM_VERSION_LT(16, 0)
651   Optional<PGOOptions> PGOOpt;
652 #else
653   std::optional<PGOOptions> PGOOpt;
654 #endif
655   if (PGOGenPath) {
656     assert(!PGOUsePath && !PGOSampleUsePath);
657     PGOOpt = PGOOptions(PGOGenPath, "", "", PGOOptions::IRInstr,
658                         PGOOptions::NoCSAction, DebugInfoForProfiling);
659   } else if (PGOUsePath) {
660     assert(!PGOSampleUsePath);
661     PGOOpt = PGOOptions(PGOUsePath, "", "", PGOOptions::IRUse,
662                         PGOOptions::NoCSAction, DebugInfoForProfiling);
663   } else if (PGOSampleUsePath) {
664     PGOOpt = PGOOptions(PGOSampleUsePath, "", "", PGOOptions::SampleUse,
665                         PGOOptions::NoCSAction, DebugInfoForProfiling);
666   } else if (DebugInfoForProfiling) {
667     PGOOpt = PGOOptions("", "", "", PGOOptions::NoAction,
668                         PGOOptions::NoCSAction, DebugInfoForProfiling);
669   }
670
671   PassBuilder PB(TM, PTO, PGOOpt, &PIC);
672   LoopAnalysisManager LAM;
673   FunctionAnalysisManager FAM;
674   CGSCCAnalysisManager CGAM;
675   ModuleAnalysisManager MAM;
676
677   FAM.registerPass([&] { return PB.buildDefaultAAPipeline(); });
678
679   Triple TargetTriple(TheModule->getTargetTriple());
680   std::unique_ptr<TargetLibraryInfoImpl> TLII(new TargetLibraryInfoImpl(TargetTriple));
681   if (DisableSimplifyLibCalls)
682     TLII->disableAllFunctions();
683   FAM.registerPass([&] { return TargetLibraryAnalysis(*TLII); });
684
685   PB.registerModuleAnalyses(MAM);
686   PB.registerCGSCCAnalyses(CGAM);
687   PB.registerFunctionAnalyses(FAM);
688   PB.registerLoopAnalyses(LAM);
689   PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
690
691   // We manually collect pipeline callbacks so we can apply them at O0, where the
692   // PassBuilder does not create a pipeline.
693   std::vector<std::function<void(ModulePassManager &, OptimizationLevel)>>
694       PipelineStartEPCallbacks;
695   std::vector<std::function<void(ModulePassManager &, OptimizationLevel)>>
696       OptimizerLastEPCallbacks;
697
698   if (VerifyIR) {
699     PipelineStartEPCallbacks.push_back(
700       [VerifyIR](ModulePassManager &MPM, OptimizationLevel Level) {
701         MPM.addPass(VerifierPass());
702       }
703     );
704   }
705
706   if (InstrumentGCOV) {
707     PipelineStartEPCallbacks.push_back(
708       [](ModulePassManager &MPM, OptimizationLevel Level) {
709         MPM.addPass(GCOVProfilerPass(GCOVOptions::getDefault()));
710       }
711     );
712   }
713
714   if (InstrumentCoverage) {
715     PipelineStartEPCallbacks.push_back(
716       [InstrProfileOutput](ModulePassManager &MPM, OptimizationLevel Level) {
717         InstrProfOptions Options;
718         if (InstrProfileOutput) {
719           Options.InstrProfileOutput = InstrProfileOutput;
720         }
721         MPM.addPass(InstrProfiling(Options, false));
722       }
723     );
724   }
725
726   if (SanitizerOptions) {
727     if (SanitizerOptions->SanitizeMemory) {
728 #if LLVM_VERSION_GE(14, 0)
729       MemorySanitizerOptions Options(
730           SanitizerOptions->SanitizeMemoryTrackOrigins,
731           SanitizerOptions->SanitizeMemoryRecover,
732           /*CompileKernel=*/false,
733           /*EagerChecks=*/true);
734 #else
735       MemorySanitizerOptions Options(
736           SanitizerOptions->SanitizeMemoryTrackOrigins,
737           SanitizerOptions->SanitizeMemoryRecover,
738           /*CompileKernel=*/false);
739 #endif
740       OptimizerLastEPCallbacks.push_back(
741         [Options](ModulePassManager &MPM, OptimizationLevel Level) {
742 #if LLVM_VERSION_GE(14, 0) && LLVM_VERSION_LT(16, 0)
743           MPM.addPass(ModuleMemorySanitizerPass(Options));
744 #else
745           MPM.addPass(MemorySanitizerPass(Options));
746 #endif
747 #if LLVM_VERSION_LT(16, 0)
748           MPM.addPass(createModuleToFunctionPassAdaptor(MemorySanitizerPass(Options)));
749 #endif
750         }
751       );
752     }
753
754     if (SanitizerOptions->SanitizeThread) {
755       OptimizerLastEPCallbacks.push_back(
756         [](ModulePassManager &MPM, OptimizationLevel Level) {
757 #if LLVM_VERSION_GE(14, 0)
758           MPM.addPass(ModuleThreadSanitizerPass());
759 #else
760           MPM.addPass(ThreadSanitizerPass());
761 #endif
762           MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));
763         }
764       );
765     }
766
767     if (SanitizerOptions->SanitizeAddress) {
768       OptimizerLastEPCallbacks.push_back(
769         [SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level) {
770 #if LLVM_VERSION_LT(15, 0)
771           MPM.addPass(RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
772 #endif
773 #if LLVM_VERSION_GE(14, 0)
774           AddressSanitizerOptions opts = AddressSanitizerOptions{
775             /*CompileKernel=*/false,
776             SanitizerOptions->SanitizeAddressRecover,
777             /*UseAfterScope=*/true,
778             AsanDetectStackUseAfterReturnMode::Runtime,
779           };
780 #if LLVM_VERSION_LT(16, 0)
781           MPM.addPass(ModuleAddressSanitizerPass(opts));
782 #else
783           MPM.addPass(AddressSanitizerPass(opts));
784 #endif
785 #else
786           MPM.addPass(ModuleAddressSanitizerPass(
787               /*CompileKernel=*/false, SanitizerOptions->SanitizeAddressRecover));
788           MPM.addPass(createModuleToFunctionPassAdaptor(AddressSanitizerPass(
789               /*CompileKernel=*/false, SanitizerOptions->SanitizeAddressRecover,
790               /*UseAfterScope=*/true)));
791 #endif
792         }
793       );
794     }
795     if (SanitizerOptions->SanitizeHWAddress) {
796       OptimizerLastEPCallbacks.push_back(
797         [SanitizerOptions](ModulePassManager &MPM, OptimizationLevel Level) {
798 #if LLVM_VERSION_GE(14, 0)
799           HWAddressSanitizerOptions opts(
800               /*CompileKernel=*/false, SanitizerOptions->SanitizeHWAddressRecover,
801               /*DisableOptimization=*/false);
802           MPM.addPass(HWAddressSanitizerPass(opts));
803 #else
804           MPM.addPass(HWAddressSanitizerPass(
805               /*CompileKernel=*/false, SanitizerOptions->SanitizeHWAddressRecover));
806 #endif
807         }
808       );
809     }
810   }
811
812   if (LLVMPluginsLen) {
813     auto PluginsStr = StringRef(LLVMPlugins, LLVMPluginsLen);
814     SmallVector<StringRef> Plugins;
815     PluginsStr.split(Plugins, ',', -1, false);
816     for (auto PluginPath: Plugins) {
817       auto Plugin = PassPlugin::Load(PluginPath.str());
818       if (!Plugin) {
819         LLVMRustSetLastError(("Failed to load pass plugin" + PluginPath.str()).c_str());
820         return LLVMRustResult::Failure;
821       }
822       Plugin->registerPassBuilderCallbacks(PB);
823     }
824   }
825
826   ModulePassManager MPM;
827   bool NeedThinLTOBufferPasses = UseThinLTOBuffers;
828   if (!NoPrepopulatePasses) {
829     // The pre-link pipelines don't support O0 and require using budilO0DefaultPipeline() instead.
830     // At the same time, the LTO pipelines do support O0 and using them is required.
831     bool IsLTO = OptStage == LLVMRustOptStage::ThinLTO || OptStage == LLVMRustOptStage::FatLTO;
832     if (OptLevel == OptimizationLevel::O0 && !IsLTO) {
833       for (const auto &C : PipelineStartEPCallbacks)
834         PB.registerPipelineStartEPCallback(C);
835       for (const auto &C : OptimizerLastEPCallbacks)
836         PB.registerOptimizerLastEPCallback(C);
837
838       // Pass false as we manually schedule ThinLTOBufferPasses below.
839       MPM = PB.buildO0DefaultPipeline(OptLevel, /* PreLinkLTO */ false);
840     } else {
841       for (const auto &C : PipelineStartEPCallbacks)
842         PB.registerPipelineStartEPCallback(C);
843       if (OptStage != LLVMRustOptStage::PreLinkThinLTO) {
844         for (const auto &C : OptimizerLastEPCallbacks)
845           PB.registerOptimizerLastEPCallback(C);
846       }
847
848       switch (OptStage) {
849       case LLVMRustOptStage::PreLinkNoLTO:
850         MPM = PB.buildPerModuleDefaultPipeline(OptLevel, DebugPassManager);
851         break;
852       case LLVMRustOptStage::PreLinkThinLTO:
853         MPM = PB.buildThinLTOPreLinkDefaultPipeline(OptLevel);
854         // The ThinLTOPreLink pipeline already includes ThinLTOBuffer passes. However, callback
855         // passes may still run afterwards. This means we need to run the buffer passes again.
856         // FIXME: In LLVM 13, the ThinLTOPreLink pipeline also runs OptimizerLastEPCallbacks
857         // before the RequiredLTOPreLinkPasses, in which case we can remove these hacks.
858         if (OptimizerLastEPCallbacks.empty())
859           NeedThinLTOBufferPasses = false;
860         for (const auto &C : OptimizerLastEPCallbacks)
861           C(MPM, OptLevel);
862         break;
863       case LLVMRustOptStage::PreLinkFatLTO:
864         MPM = PB.buildLTOPreLinkDefaultPipeline(OptLevel);
865         NeedThinLTOBufferPasses = false;
866         break;
867       case LLVMRustOptStage::ThinLTO:
868         // FIXME: Does it make sense to pass the ModuleSummaryIndex?
869         // It only seems to be needed for C++ specific optimizations.
870         MPM = PB.buildThinLTODefaultPipeline(OptLevel, nullptr);
871         break;
872       case LLVMRustOptStage::FatLTO:
873         MPM = PB.buildLTODefaultPipeline(OptLevel, nullptr);
874         break;
875       }
876     }
877   } else {
878     // We're not building any of the default pipelines but we still want to
879     // add the verifier, instrumentation, etc passes if they were requested
880     for (const auto &C : PipelineStartEPCallbacks)
881       C(MPM, OptLevel);
882     for (const auto &C : OptimizerLastEPCallbacks)
883       C(MPM, OptLevel);
884   }
885
886   if (ExtraPassesLen) {
887     if (auto Err = PB.parsePassPipeline(MPM, StringRef(ExtraPasses, ExtraPassesLen))) {
888       std::string ErrMsg = toString(std::move(Err));
889       LLVMRustSetLastError(ErrMsg.c_str());
890       return LLVMRustResult::Failure;
891     }
892   }
893
894   if (NeedThinLTOBufferPasses) {
895     MPM.addPass(CanonicalizeAliasesPass());
896     MPM.addPass(NameAnonGlobalPass());
897   }
898
899   // Upgrade all calls to old intrinsics first.
900   for (Module::iterator I = TheModule->begin(), E = TheModule->end(); I != E;)
901     UpgradeCallsToIntrinsic(&*I++); // must be post-increment, as we remove
902
903   MPM.run(*TheModule, MAM);
904   return LLVMRustResult::Success;
905 }
906
907 // Callback to demangle function name
908 // Parameters:
909 // * name to be demangled
910 // * name len
911 // * output buffer
912 // * output buffer len
913 // Returns len of demangled string, or 0 if demangle failed.
914 typedef size_t (*DemangleFn)(const char*, size_t, char*, size_t);
915
916
917 namespace {
918
919 class RustAssemblyAnnotationWriter : public AssemblyAnnotationWriter {
920   DemangleFn Demangle;
921   std::vector<char> Buf;
922
923 public:
924   RustAssemblyAnnotationWriter(DemangleFn Demangle) : Demangle(Demangle) {}
925
926   // Return empty string if demangle failed
927   // or if name does not need to be demangled
928   StringRef CallDemangle(StringRef name) {
929     if (!Demangle) {
930       return StringRef();
931     }
932
933     if (Buf.size() < name.size() * 2) {
934       // Semangled name usually shorter than mangled,
935       // but allocate twice as much memory just in case
936       Buf.resize(name.size() * 2);
937     }
938
939     auto R = Demangle(name.data(), name.size(), Buf.data(), Buf.size());
940     if (!R) {
941       // Demangle failed.
942       return StringRef();
943     }
944
945     auto Demangled = StringRef(Buf.data(), R);
946     if (Demangled == name) {
947       // Do not print anything if demangled name is equal to mangled.
948       return StringRef();
949     }
950
951     return Demangled;
952   }
953
954   void emitFunctionAnnot(const Function *F,
955                          formatted_raw_ostream &OS) override {
956     StringRef Demangled = CallDemangle(F->getName());
957     if (Demangled.empty()) {
958         return;
959     }
960
961     OS << "; " << Demangled << "\n";
962   }
963
964   void emitInstructionAnnot(const Instruction *I,
965                             formatted_raw_ostream &OS) override {
966     const char *Name;
967     const Value *Value;
968     if (const CallInst *CI = dyn_cast<CallInst>(I)) {
969       Name = "call";
970       Value = CI->getCalledOperand();
971     } else if (const InvokeInst* II = dyn_cast<InvokeInst>(I)) {
972       Name = "invoke";
973       Value = II->getCalledOperand();
974     } else {
975       // Could demangle more operations, e. g.
976       // `store %place, @function`.
977       return;
978     }
979
980     if (!Value->hasName()) {
981       return;
982     }
983
984     StringRef Demangled = CallDemangle(Value->getName());
985     if (Demangled.empty()) {
986       return;
987     }
988
989     OS << "; " << Name << " " << Demangled << "\n";
990   }
991 };
992
993 } // namespace
994
995 extern "C" LLVMRustResult
996 LLVMRustPrintModule(LLVMModuleRef M, const char *Path, DemangleFn Demangle) {
997   std::string ErrorInfo;
998   std::error_code EC;
999   raw_fd_ostream OS(Path, EC, sys::fs::OF_None);
1000   if (EC)
1001     ErrorInfo = EC.message();
1002   if (ErrorInfo != "") {
1003     LLVMRustSetLastError(ErrorInfo.c_str());
1004     return LLVMRustResult::Failure;
1005   }
1006
1007   RustAssemblyAnnotationWriter AAW(Demangle);
1008   formatted_raw_ostream FOS(OS);
1009   unwrap(M)->print(FOS, &AAW);
1010
1011   return LLVMRustResult::Success;
1012 }
1013
1014 extern "C" void LLVMRustPrintPasses() {
1015   LLVMInitializePasses();
1016   struct MyListener : PassRegistrationListener {
1017     void passEnumerate(const PassInfo *Info) {
1018       StringRef PassArg = Info->getPassArgument();
1019       StringRef PassName = Info->getPassName();
1020       if (!PassArg.empty()) {
1021         // These unsigned->signed casts could theoretically overflow, but
1022         // realistically never will (and even if, the result is implementation
1023         // defined rather plain UB).
1024         printf("%15.*s - %.*s\n", (int)PassArg.size(), PassArg.data(),
1025                (int)PassName.size(), PassName.data());
1026       }
1027     }
1028   } Listener;
1029
1030   PassRegistry *PR = PassRegistry::getPassRegistry();
1031   PR->enumerateWith(&Listener);
1032 }
1033
1034 extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **Symbols,
1035                                            size_t Len) {
1036   auto PreserveFunctions = [=](const GlobalValue &GV) {
1037     for (size_t I = 0; I < Len; I++) {
1038       if (GV.getName() == Symbols[I]) {
1039         return true;
1040       }
1041     }
1042     return false;
1043   };
1044
1045   internalizeModule(*unwrap(M), PreserveFunctions);
1046 }
1047
1048 extern "C" void
1049 LLVMRustSetDataLayoutFromTargetMachine(LLVMModuleRef Module,
1050                                        LLVMTargetMachineRef TMR) {
1051   TargetMachine *Target = unwrap(TMR);
1052   unwrap(Module)->setDataLayout(Target->createDataLayout());
1053 }
1054
1055 extern "C" void LLVMRustSetModulePICLevel(LLVMModuleRef M) {
1056   unwrap(M)->setPICLevel(PICLevel::Level::BigPIC);
1057 }
1058
1059 extern "C" void LLVMRustSetModulePIELevel(LLVMModuleRef M) {
1060   unwrap(M)->setPIELevel(PIELevel::Level::Large);
1061 }
1062
1063 extern "C" void LLVMRustSetModuleCodeModel(LLVMModuleRef M,
1064                                            LLVMRustCodeModel Model) {
1065   auto CM = fromRust(Model);
1066   if (!CM)
1067     return;
1068   unwrap(M)->setCodeModel(*CM);
1069 }
1070
1071 // Here you'll find an implementation of ThinLTO as used by the Rust compiler
1072 // right now. This ThinLTO support is only enabled on "recent ish" versions of
1073 // LLVM, and otherwise it's just blanket rejected from other compilers.
1074 //
1075 // Most of this implementation is straight copied from LLVM. At the time of
1076 // this writing it wasn't *quite* suitable to reuse more code from upstream
1077 // for our purposes, but we should strive to upstream this support once it's
1078 // ready to go! I figure we may want a bit of testing locally first before
1079 // sending this upstream to LLVM. I hear though they're quite eager to receive
1080 // feedback like this!
1081 //
1082 // If you're reading this code and wondering "what in the world" or you're
1083 // working "good lord by LLVM upgrade is *still* failing due to these bindings"
1084 // then fear not! (ok maybe fear a little). All code here is mostly based
1085 // on `lib/LTO/ThinLTOCodeGenerator.cpp` in LLVM.
1086 //
1087 // You'll find that the general layout here roughly corresponds to the `run`
1088 // method in that file as well as `ProcessThinLTOModule`. Functions are
1089 // specifically commented below as well, but if you're updating this code
1090 // or otherwise trying to understand it, the LLVM source will be useful in
1091 // interpreting the mysteries within.
1092 //
1093 // Otherwise I'll apologize in advance, it probably requires a relatively
1094 // significant investment on your part to "truly understand" what's going on
1095 // here. Not saying I do myself, but it took me awhile staring at LLVM's source
1096 // and various online resources about ThinLTO to make heads or tails of all
1097 // this.
1098
1099 // This is a shared data structure which *must* be threadsafe to share
1100 // read-only amongst threads. This also corresponds basically to the arguments
1101 // of the `ProcessThinLTOModule` function in the LLVM source.
1102 struct LLVMRustThinLTOData {
1103   // The combined index that is the global analysis over all modules we're
1104   // performing ThinLTO for. This is mostly managed by LLVM.
1105   ModuleSummaryIndex Index;
1106
1107   // All modules we may look at, stored as in-memory serialized versions. This
1108   // is later used when inlining to ensure we can extract any module to inline
1109   // from.
1110   StringMap<MemoryBufferRef> ModuleMap;
1111
1112   // A set that we manage of everything we *don't* want internalized. Note that
1113   // this includes all transitive references right now as well, but it may not
1114   // always!
1115   DenseSet<GlobalValue::GUID> GUIDPreservedSymbols;
1116
1117   // Not 100% sure what these are, but they impact what's internalized and
1118   // what's inlined across modules, I believe.
1119   StringMap<FunctionImporter::ImportMapTy> ImportLists;
1120   StringMap<FunctionImporter::ExportSetTy> ExportLists;
1121   StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries;
1122   StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
1123
1124   LLVMRustThinLTOData() : Index(/* HaveGVs = */ false) {}
1125 };
1126
1127 // Just an argument to the `LLVMRustCreateThinLTOData` function below.
1128 struct LLVMRustThinLTOModule {
1129   const char *identifier;
1130   const char *data;
1131   size_t len;
1132 };
1133
1134 // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp`, not sure what it
1135 // does.
1136 static const GlobalValueSummary *
1137 getFirstDefinitionForLinker(const GlobalValueSummaryList &GVSummaryList) {
1138   auto StrongDefForLinker = llvm::find_if(
1139       GVSummaryList, [](const std::unique_ptr<GlobalValueSummary> &Summary) {
1140         auto Linkage = Summary->linkage();
1141         return !GlobalValue::isAvailableExternallyLinkage(Linkage) &&
1142                !GlobalValue::isWeakForLinker(Linkage);
1143       });
1144   if (StrongDefForLinker != GVSummaryList.end())
1145     return StrongDefForLinker->get();
1146
1147   auto FirstDefForLinker = llvm::find_if(
1148       GVSummaryList, [](const std::unique_ptr<GlobalValueSummary> &Summary) {
1149         auto Linkage = Summary->linkage();
1150         return !GlobalValue::isAvailableExternallyLinkage(Linkage);
1151       });
1152   if (FirstDefForLinker == GVSummaryList.end())
1153     return nullptr;
1154   return FirstDefForLinker->get();
1155 }
1156
1157 // The main entry point for creating the global ThinLTO analysis. The structure
1158 // here is basically the same as before threads are spawned in the `run`
1159 // function of `lib/LTO/ThinLTOCodeGenerator.cpp`.
1160 extern "C" LLVMRustThinLTOData*
1161 LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
1162                           int num_modules,
1163                           const char **preserved_symbols,
1164                           int num_symbols) {
1165   auto Ret = std::make_unique<LLVMRustThinLTOData>();
1166
1167   // Load each module's summary and merge it into one combined index
1168   for (int i = 0; i < num_modules; i++) {
1169     auto module = &modules[i];
1170     StringRef buffer(module->data, module->len);
1171     MemoryBufferRef mem_buffer(buffer, module->identifier);
1172
1173     Ret->ModuleMap[module->identifier] = mem_buffer;
1174
1175     if (Error Err = readModuleSummaryIndex(mem_buffer, Ret->Index, i)) {
1176       LLVMRustSetLastError(toString(std::move(Err)).c_str());
1177       return nullptr;
1178     }
1179   }
1180
1181   // Collect for each module the list of function it defines (GUID -> Summary)
1182   Ret->Index.collectDefinedGVSummariesPerModule(Ret->ModuleToDefinedGVSummaries);
1183
1184   // Convert the preserved symbols set from string to GUID, this is then needed
1185   // for internalization.
1186   for (int i = 0; i < num_symbols; i++) {
1187     auto GUID = GlobalValue::getGUID(preserved_symbols[i]);
1188     Ret->GUIDPreservedSymbols.insert(GUID);
1189   }
1190
1191   // Collect the import/export lists for all modules from the call-graph in the
1192   // combined index
1193   //
1194   // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp`
1195   auto deadIsPrevailing = [&](GlobalValue::GUID G) {
1196     return PrevailingType::Unknown;
1197   };
1198   // We don't have a complete picture in our use of ThinLTO, just our immediate
1199   // crate, so we need `ImportEnabled = false` to limit internalization.
1200   // Otherwise, we sometimes lose `static` values -- see #60184.
1201   computeDeadSymbolsWithConstProp(Ret->Index, Ret->GUIDPreservedSymbols,
1202                                   deadIsPrevailing, /* ImportEnabled = */ false);
1203   ComputeCrossModuleImport(
1204     Ret->Index,
1205     Ret->ModuleToDefinedGVSummaries,
1206     Ret->ImportLists,
1207     Ret->ExportLists
1208   );
1209
1210   // Resolve LinkOnce/Weak symbols, this has to be computed early be cause it
1211   // impacts the caching.
1212   //
1213   // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp` with some of this
1214   // being lifted from `lib/LTO/LTO.cpp` as well
1215   DenseMap<GlobalValue::GUID, const GlobalValueSummary *> PrevailingCopy;
1216   for (auto &I : Ret->Index) {
1217     if (I.second.SummaryList.size() > 1)
1218       PrevailingCopy[I.first] = getFirstDefinitionForLinker(I.second.SummaryList);
1219   }
1220   auto isPrevailing = [&](GlobalValue::GUID GUID, const GlobalValueSummary *S) {
1221     const auto &Prevailing = PrevailingCopy.find(GUID);
1222     if (Prevailing == PrevailingCopy.end())
1223       return true;
1224     return Prevailing->second == S;
1225   };
1226   auto recordNewLinkage = [&](StringRef ModuleIdentifier,
1227                               GlobalValue::GUID GUID,
1228                               GlobalValue::LinkageTypes NewLinkage) {
1229     Ret->ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;
1230   };
1231
1232   // Uses FromPrevailing visibility scheme which works for many binary
1233   // formats. We probably could and should use ELF visibility scheme for many of
1234   // our targets, however.
1235   lto::Config conf;
1236   thinLTOResolvePrevailingInIndex(conf, Ret->Index, isPrevailing, recordNewLinkage,
1237                                   Ret->GUIDPreservedSymbols);
1238
1239   // Here we calculate an `ExportedGUIDs` set for use in the `isExported`
1240   // callback below. This callback below will dictate the linkage for all
1241   // summaries in the index, and we basically just only want to ensure that dead
1242   // symbols are internalized. Otherwise everything that's already external
1243   // linkage will stay as external, and internal will stay as internal.
1244   std::set<GlobalValue::GUID> ExportedGUIDs;
1245   for (auto &List : Ret->Index) {
1246     for (auto &GVS: List.second.SummaryList) {
1247       if (GlobalValue::isLocalLinkage(GVS->linkage()))
1248         continue;
1249       auto GUID = GVS->getOriginalName();
1250       if (GVS->flags().Live)
1251         ExportedGUIDs.insert(GUID);
1252     }
1253   }
1254   auto isExported = [&](StringRef ModuleIdentifier, ValueInfo VI) {
1255     const auto &ExportList = Ret->ExportLists.find(ModuleIdentifier);
1256     return (ExportList != Ret->ExportLists.end() &&
1257       ExportList->second.count(VI)) ||
1258       ExportedGUIDs.count(VI.getGUID());
1259   };
1260   thinLTOInternalizeAndPromoteInIndex(Ret->Index, isExported, isPrevailing);
1261
1262   return Ret.release();
1263 }
1264
1265 extern "C" void
1266 LLVMRustFreeThinLTOData(LLVMRustThinLTOData *Data) {
1267   delete Data;
1268 }
1269
1270 // Below are the various passes that happen *per module* when doing ThinLTO.
1271 //
1272 // In other words, these are the functions that are all run concurrently
1273 // with one another, one per module. The passes here correspond to the analysis
1274 // passes in `lib/LTO/ThinLTOCodeGenerator.cpp`, currently found in the
1275 // `ProcessThinLTOModule` function. Here they're split up into separate steps
1276 // so rustc can save off the intermediate bytecode between each step.
1277
1278 static bool
1279 clearDSOLocalOnDeclarations(Module &Mod, TargetMachine &TM) {
1280   // When linking an ELF shared object, dso_local should be dropped. We
1281   // conservatively do this for -fpic.
1282   bool ClearDSOLocalOnDeclarations =
1283       TM.getTargetTriple().isOSBinFormatELF() &&
1284       TM.getRelocationModel() != Reloc::Static &&
1285       Mod.getPIELevel() == PIELevel::Default;
1286   return ClearDSOLocalOnDeclarations;
1287 }
1288
1289 extern "C" bool
1290 LLVMRustPrepareThinLTORename(const LLVMRustThinLTOData *Data, LLVMModuleRef M,
1291                              LLVMTargetMachineRef TM) {
1292   Module &Mod = *unwrap(M);
1293   TargetMachine &Target = *unwrap(TM);
1294
1295   bool ClearDSOLocal = clearDSOLocalOnDeclarations(Mod, Target);
1296   bool error = renameModuleForThinLTO(Mod, Data->Index, ClearDSOLocal);
1297
1298   if (error) {
1299     LLVMRustSetLastError("renameModuleForThinLTO failed");
1300     return false;
1301   }
1302   return true;
1303 }
1304
1305 extern "C" bool
1306 LLVMRustPrepareThinLTOResolveWeak(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
1307   Module &Mod = *unwrap(M);
1308   const auto &DefinedGlobals = Data->ModuleToDefinedGVSummaries.lookup(Mod.getModuleIdentifier());
1309 #if LLVM_VERSION_GE(14, 0)
1310   thinLTOFinalizeInModule(Mod, DefinedGlobals, /*PropagateAttrs=*/true);
1311 #else
1312   thinLTOResolvePrevailingInModule(Mod, DefinedGlobals);
1313 #endif
1314   return true;
1315 }
1316
1317 extern "C" bool
1318 LLVMRustPrepareThinLTOInternalize(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
1319   Module &Mod = *unwrap(M);
1320   const auto &DefinedGlobals = Data->ModuleToDefinedGVSummaries.lookup(Mod.getModuleIdentifier());
1321   thinLTOInternalizeModule(Mod, DefinedGlobals);
1322   return true;
1323 }
1324
1325 extern "C" bool
1326 LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, LLVMModuleRef M,
1327                              LLVMTargetMachineRef TM) {
1328   Module &Mod = *unwrap(M);
1329   TargetMachine &Target = *unwrap(TM);
1330
1331   const auto &ImportList = Data->ImportLists.lookup(Mod.getModuleIdentifier());
1332   auto Loader = [&](StringRef Identifier) {
1333     const auto &Memory = Data->ModuleMap.lookup(Identifier);
1334     auto &Context = Mod.getContext();
1335     auto MOrErr = getLazyBitcodeModule(Memory, Context, true, true);
1336
1337     if (!MOrErr)
1338       return MOrErr;
1339
1340     // The rest of this closure is a workaround for
1341     // https://bugs.llvm.org/show_bug.cgi?id=38184 where during ThinLTO imports
1342     // we accidentally import wasm custom sections into different modules,
1343     // duplicating them by in the final output artifact.
1344     //
1345     // The issue is worked around here by manually removing the
1346     // `wasm.custom_sections` named metadata node from any imported module. This
1347     // we know isn't used by any optimization pass so there's no need for it to
1348     // be imported.
1349     //
1350     // Note that the metadata is currently lazily loaded, so we materialize it
1351     // here before looking up if there's metadata inside. The `FunctionImporter`
1352     // will immediately materialize metadata anyway after an import, so this
1353     // shouldn't be a perf hit.
1354     if (Error Err = (*MOrErr)->materializeMetadata()) {
1355       Expected<std::unique_ptr<Module>> Ret(std::move(Err));
1356       return Ret;
1357     }
1358
1359     auto *WasmCustomSections = (*MOrErr)->getNamedMetadata("wasm.custom_sections");
1360     if (WasmCustomSections)
1361       WasmCustomSections->eraseFromParent();
1362
1363     return MOrErr;
1364   };
1365   bool ClearDSOLocal = clearDSOLocalOnDeclarations(Mod, Target);
1366   FunctionImporter Importer(Data->Index, Loader, ClearDSOLocal);
1367   Expected<bool> Result = Importer.importFunctions(Mod, ImportList);
1368   if (!Result) {
1369     LLVMRustSetLastError(toString(Result.takeError()).c_str());
1370     return false;
1371   }
1372   return true;
1373 }
1374
1375 // This struct and various functions are sort of a hack right now, but the
1376 // problem is that we've got in-memory LLVM modules after we generate and
1377 // optimize all codegen-units for one compilation in rustc. To be compatible
1378 // with the LTO support above we need to serialize the modules plus their
1379 // ThinLTO summary into memory.
1380 //
1381 // This structure is basically an owned version of a serialize module, with
1382 // a ThinLTO summary attached.
1383 struct LLVMRustThinLTOBuffer {
1384   std::string data;
1385 };
1386
1387 extern "C" LLVMRustThinLTOBuffer*
1388 LLVMRustThinLTOBufferCreate(LLVMModuleRef M, bool is_thin) {
1389   auto Ret = std::make_unique<LLVMRustThinLTOBuffer>();
1390   {
1391     raw_string_ostream OS(Ret->data);
1392     {
1393       if (is_thin) {
1394         PassBuilder PB;
1395         LoopAnalysisManager LAM;
1396         FunctionAnalysisManager FAM;
1397         CGSCCAnalysisManager CGAM;
1398         ModuleAnalysisManager MAM;
1399         PB.registerModuleAnalyses(MAM);
1400         PB.registerCGSCCAnalyses(CGAM);
1401         PB.registerFunctionAnalyses(FAM);
1402         PB.registerLoopAnalyses(LAM);
1403         PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
1404         ModulePassManager MPM;
1405         MPM.addPass(ThinLTOBitcodeWriterPass(OS, nullptr));
1406         MPM.run(*unwrap(M), MAM);
1407       } else {
1408         WriteBitcodeToFile(*unwrap(M), OS);
1409       }
1410     }
1411   }
1412   return Ret.release();
1413 }
1414
1415 extern "C" void
1416 LLVMRustThinLTOBufferFree(LLVMRustThinLTOBuffer *Buffer) {
1417   delete Buffer;
1418 }
1419
1420 extern "C" const void*
1421 LLVMRustThinLTOBufferPtr(const LLVMRustThinLTOBuffer *Buffer) {
1422   return Buffer->data.data();
1423 }
1424
1425 extern "C" size_t
1426 LLVMRustThinLTOBufferLen(const LLVMRustThinLTOBuffer *Buffer) {
1427   return Buffer->data.length();
1428 }
1429
1430 // This is what we used to parse upstream bitcode for actual ThinLTO
1431 // processing. We'll call this once per module optimized through ThinLTO, and
1432 // it'll be called concurrently on many threads.
1433 extern "C" LLVMModuleRef
1434 LLVMRustParseBitcodeForLTO(LLVMContextRef Context,
1435                            const char *data,
1436                            size_t len,
1437                            const char *identifier) {
1438   StringRef Data(data, len);
1439   MemoryBufferRef Buffer(Data, identifier);
1440   unwrap(Context)->enableDebugTypeODRUniquing();
1441   Expected<std::unique_ptr<Module>> SrcOrError =
1442       parseBitcodeFile(Buffer, *unwrap(Context));
1443   if (!SrcOrError) {
1444     LLVMRustSetLastError(toString(SrcOrError.takeError()).c_str());
1445     return nullptr;
1446   }
1447   return wrap(std::move(*SrcOrError).release());
1448 }
1449
1450 // Find the bitcode section in the object file data and return it as a slice.
1451 // Fail if the bitcode section is present but empty.
1452 //
1453 // On success, the return value is the pointer to the start of the slice and
1454 // `out_len` is filled with the (non-zero) length. On failure, the return value
1455 // is `nullptr` and `out_len` is set to zero.
1456 extern "C" const char*
1457 LLVMRustGetBitcodeSliceFromObjectData(const char *data,
1458                                       size_t len,
1459                                       size_t *out_len) {
1460   *out_len = 0;
1461
1462   StringRef Data(data, len);
1463   MemoryBufferRef Buffer(Data, ""); // The id is unused.
1464
1465   Expected<MemoryBufferRef> BitcodeOrError =
1466     object::IRObjectFile::findBitcodeInMemBuffer(Buffer);
1467   if (!BitcodeOrError) {
1468     LLVMRustSetLastError(toString(BitcodeOrError.takeError()).c_str());
1469     return nullptr;
1470   }
1471
1472   *out_len = BitcodeOrError->getBufferSize();
1473   return BitcodeOrError->getBufferStart();
1474 }
1475
1476 // Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
1477 // the comment in `back/lto.rs` for why this exists.
1478 extern "C" void
1479 LLVMRustThinLTOGetDICompileUnit(LLVMModuleRef Mod,
1480                                 DICompileUnit **A,
1481                                 DICompileUnit **B) {
1482   Module *M = unwrap(Mod);
1483   DICompileUnit **Cur = A;
1484   DICompileUnit **Next = B;
1485   for (DICompileUnit *CU : M->debug_compile_units()) {
1486     *Cur = CU;
1487     Cur = Next;
1488     Next = nullptr;
1489     if (Cur == nullptr)
1490       break;
1491   }
1492 }
1493
1494 // Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
1495 // the comment in `back/lto.rs` for why this exists.
1496 extern "C" void
1497 LLVMRustThinLTOPatchDICompileUnit(LLVMModuleRef Mod, DICompileUnit *Unit) {
1498   Module *M = unwrap(Mod);
1499
1500   // If the original source module didn't have a `DICompileUnit` then try to
1501   // merge all the existing compile units. If there aren't actually any though
1502   // then there's not much for us to do so return.
1503   if (Unit == nullptr) {
1504     for (DICompileUnit *CU : M->debug_compile_units()) {
1505       Unit = CU;
1506       break;
1507     }
1508     if (Unit == nullptr)
1509       return;
1510   }
1511
1512   // Use LLVM's built-in `DebugInfoFinder` to find a bunch of debuginfo and
1513   // process it recursively. Note that we used to specifically iterate over
1514   // instructions to ensure we feed everything into it, but `processModule`
1515   // started doing this the same way in LLVM 7 (commit d769eb36ab2b8).
1516   DebugInfoFinder Finder;
1517   Finder.processModule(*M);
1518
1519   // After we've found all our debuginfo, rewrite all subprograms to point to
1520   // the same `DICompileUnit`.
1521   for (auto &F : Finder.subprograms()) {
1522     F->replaceUnit(Unit);
1523   }
1524
1525   // Erase any other references to other `DICompileUnit` instances, the verifier
1526   // will later ensure that we don't actually have any other stale references to
1527   // worry about.
1528   auto *MD = M->getNamedMetadata("llvm.dbg.cu");
1529   MD->clearOperands();
1530   MD->addOperand(Unit);
1531 }
1532
1533 // Computes the LTO cache key for the provided 'ModId' in the given 'Data',
1534 // storing the result in 'KeyOut'.
1535 // Currently, this cache key is a SHA-1 hash of anything that could affect
1536 // the result of optimizing this module (e.g. module imports, exports, liveness
1537 // of access globals, etc).
1538 // The precise details are determined by LLVM in `computeLTOCacheKey`, which is
1539 // used during the normal linker-plugin incremental thin-LTO process.
1540 extern "C" void
1541 LLVMRustComputeLTOCacheKey(RustStringRef KeyOut, const char *ModId, LLVMRustThinLTOData *Data) {
1542   SmallString<40> Key;
1543   llvm::lto::Config conf;
1544   const auto &ImportList = Data->ImportLists.lookup(ModId);
1545   const auto &ExportList = Data->ExportLists.lookup(ModId);
1546   const auto &ResolvedODR = Data->ResolvedODR.lookup(ModId);
1547   const auto &DefinedGlobals = Data->ModuleToDefinedGVSummaries.lookup(ModId);
1548   std::set<GlobalValue::GUID> CfiFunctionDefs;
1549   std::set<GlobalValue::GUID> CfiFunctionDecls;
1550
1551   // Based on the 'InProcessThinBackend' constructor in LLVM
1552   for (auto &Name : Data->Index.cfiFunctionDefs())
1553     CfiFunctionDefs.insert(
1554         GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Name)));
1555   for (auto &Name : Data->Index.cfiFunctionDecls())
1556     CfiFunctionDecls.insert(
1557         GlobalValue::getGUID(GlobalValue::dropLLVMManglingEscape(Name)));
1558
1559   llvm::computeLTOCacheKey(Key, conf, Data->Index, ModId,
1560       ImportList, ExportList, ResolvedODR, DefinedGlobals, CfiFunctionDefs, CfiFunctionDecls
1561   );
1562
1563   LLVMRustStringWriteImpl(KeyOut, Key.c_str(), Key.size());
1564 }