]> git.lizzy.rs Git - rust.git/blob - src/rustllvm/PassWrapper.cpp
Rollup merge of #68958 - GuillaumeGomez:clean-up-e0277-e0282, r=Dylan-DPC
[rust.git] / src / rustllvm / PassWrapper.cpp
1 #include <stdio.h>
2
3 #include <vector>
4 #include <set>
5
6 #include "rustllvm.h"
7
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/Support/CBindingWrapping.h"
16 #include "llvm/Support/FileSystem.h"
17 #include "llvm/Support/Host.h"
18 #include "llvm/Target/TargetMachine.h"
19 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
20 #include "llvm/Transforms/IPO/AlwaysInliner.h"
21 #include "llvm/Transforms/IPO/FunctionImport.h"
22 #include "llvm/Transforms/Utils/FunctionImportUtils.h"
23 #include "llvm/LTO/LTO.h"
24 #include "llvm-c/Transforms/PassManagerBuilder.h"
25
26 #include "llvm/Transforms/Instrumentation.h"
27 #if LLVM_VERSION_GE(9, 0)
28 #include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
29 #include "llvm/Support/TimeProfiler.h"
30 #endif
31 #if LLVM_VERSION_GE(8, 0)
32 #include "llvm/Transforms/Instrumentation/ThreadSanitizer.h"
33 #include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
34 #endif
35
36 using namespace llvm;
37 using namespace llvm::legacy;
38
39 typedef struct LLVMOpaquePass *LLVMPassRef;
40 typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef;
41
42 DEFINE_STDCXX_CONVERSION_FUNCTIONS(Pass, LLVMPassRef)
43 DEFINE_STDCXX_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
44 DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassManagerBuilder,
45                                    LLVMPassManagerBuilderRef)
46
47 extern "C" void LLVMInitializePasses() {
48   PassRegistry &Registry = *PassRegistry::getPassRegistry();
49   initializeCore(Registry);
50   initializeCodeGen(Registry);
51   initializeScalarOpts(Registry);
52   initializeVectorization(Registry);
53   initializeIPO(Registry);
54   initializeAnalysis(Registry);
55   initializeTransformUtils(Registry);
56   initializeInstCombine(Registry);
57   initializeInstrumentation(Registry);
58   initializeTarget(Registry);
59 }
60
61 extern "C" void LLVMTimeTraceProfilerInitialize() {
62 #if LLVM_VERSION_GE(9, 0)
63   timeTraceProfilerInitialize();
64 #endif
65 }
66
67 extern "C" void LLVMTimeTraceProfilerFinish(const char* FileName) {
68 #if LLVM_VERSION_GE(9, 0)
69   StringRef FN(FileName);
70   std::error_code EC;
71   raw_fd_ostream OS(FN, EC, sys::fs::CD_CreateAlways);
72
73   timeTraceProfilerWrite(OS);
74   timeTraceProfilerCleanup();
75 #endif
76 }
77
78 enum class LLVMRustPassKind {
79   Other,
80   Function,
81   Module,
82 };
83
84 static LLVMRustPassKind toRust(PassKind Kind) {
85   switch (Kind) {
86   case PT_Function:
87     return LLVMRustPassKind::Function;
88   case PT_Module:
89     return LLVMRustPassKind::Module;
90   default:
91     return LLVMRustPassKind::Other;
92   }
93 }
94
95 extern "C" LLVMPassRef LLVMRustFindAndCreatePass(const char *PassName) {
96   StringRef SR(PassName);
97   PassRegistry *PR = PassRegistry::getPassRegistry();
98
99   const PassInfo *PI = PR->getPassInfo(SR);
100   if (PI) {
101     return wrap(PI->createPass());
102   }
103   return nullptr;
104 }
105
106 extern "C" LLVMPassRef LLVMRustCreateAddressSanitizerFunctionPass(bool Recover) {
107   const bool CompileKernel = false;
108   const bool UseAfterScope = true;
109
110   return wrap(createAddressSanitizerFunctionPass(CompileKernel, Recover, UseAfterScope));
111 }
112
113 extern "C" LLVMPassRef LLVMRustCreateModuleAddressSanitizerPass(bool Recover) {
114   const bool CompileKernel = false;
115
116 #if LLVM_VERSION_GE(9, 0)
117   return wrap(createModuleAddressSanitizerLegacyPassPass(CompileKernel, Recover));
118 #else
119   return wrap(createAddressSanitizerModulePass(CompileKernel, Recover));
120 #endif
121 }
122
123 extern "C" LLVMPassRef LLVMRustCreateMemorySanitizerPass(int TrackOrigins, bool Recover) {
124 #if LLVM_VERSION_GE(9, 0)
125   const bool CompileKernel = false;
126
127   return wrap(createMemorySanitizerLegacyPassPass(
128       MemorySanitizerOptions{TrackOrigins, Recover, CompileKernel}));
129 #elif LLVM_VERSION_GE(8, 0)
130   return wrap(createMemorySanitizerLegacyPassPass(TrackOrigins, Recover));
131 #else
132   return wrap(createMemorySanitizerPass(TrackOrigins, Recover));
133 #endif
134 }
135
136 extern "C" LLVMPassRef LLVMRustCreateThreadSanitizerPass() {
137 #if LLVM_VERSION_GE(8, 0)
138   return wrap(createThreadSanitizerLegacyPassPass());
139 #else
140   return wrap(createThreadSanitizerPass());
141 #endif
142 }
143
144 extern "C" LLVMRustPassKind LLVMRustPassKind(LLVMPassRef RustPass) {
145   assert(RustPass);
146   Pass *Pass = unwrap(RustPass);
147   return toRust(Pass->getPassKind());
148 }
149
150 extern "C" void LLVMRustAddPass(LLVMPassManagerRef PMR, LLVMPassRef RustPass) {
151   assert(RustPass);
152   Pass *Pass = unwrap(RustPass);
153   PassManagerBase *PMB = unwrap(PMR);
154   PMB->add(Pass);
155 }
156
157 extern "C"
158 void LLVMRustPassManagerBuilderPopulateThinLTOPassManager(
159   LLVMPassManagerBuilderRef PMBR,
160   LLVMPassManagerRef PMR
161 ) {
162   unwrap(PMBR)->populateThinLTOPassManager(*unwrap(PMR));
163 }
164
165 extern "C"
166 void LLVMRustAddLastExtensionPasses(
167     LLVMPassManagerBuilderRef PMBR, LLVMPassRef *Passes, size_t NumPasses) {
168   auto AddExtensionPasses = [Passes, NumPasses](
169       const PassManagerBuilder &Builder, PassManagerBase &PM) {
170     for (size_t I = 0; I < NumPasses; I++) {
171       PM.add(unwrap(Passes[I]));
172     }
173   };
174   // Add the passes to both of the pre-finalization extension points,
175   // so they are run for optimized and non-optimized builds.
176   unwrap(PMBR)->addExtension(PassManagerBuilder::EP_OptimizerLast,
177                              AddExtensionPasses);
178   unwrap(PMBR)->addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
179                              AddExtensionPasses);
180 }
181
182 #ifdef LLVM_COMPONENT_X86
183 #define SUBTARGET_X86 SUBTARGET(X86)
184 #else
185 #define SUBTARGET_X86
186 #endif
187
188 #ifdef LLVM_COMPONENT_ARM
189 #define SUBTARGET_ARM SUBTARGET(ARM)
190 #else
191 #define SUBTARGET_ARM
192 #endif
193
194 #ifdef LLVM_COMPONENT_AARCH64
195 #define SUBTARGET_AARCH64 SUBTARGET(AArch64)
196 #else
197 #define SUBTARGET_AARCH64
198 #endif
199
200 #ifdef LLVM_COMPONENT_MIPS
201 #define SUBTARGET_MIPS SUBTARGET(Mips)
202 #else
203 #define SUBTARGET_MIPS
204 #endif
205
206 #ifdef LLVM_COMPONENT_POWERPC
207 #define SUBTARGET_PPC SUBTARGET(PPC)
208 #else
209 #define SUBTARGET_PPC
210 #endif
211
212 #ifdef LLVM_COMPONENT_SYSTEMZ
213 #define SUBTARGET_SYSTEMZ SUBTARGET(SystemZ)
214 #else
215 #define SUBTARGET_SYSTEMZ
216 #endif
217
218 #ifdef LLVM_COMPONENT_MSP430
219 #define SUBTARGET_MSP430 SUBTARGET(MSP430)
220 #else
221 #define SUBTARGET_MSP430
222 #endif
223
224 #ifdef LLVM_COMPONENT_RISCV
225 #define SUBTARGET_RISCV SUBTARGET(RISCV)
226 #else
227 #define SUBTARGET_RISCV
228 #endif
229
230 #ifdef LLVM_COMPONENT_SPARC
231 #define SUBTARGET_SPARC SUBTARGET(Sparc)
232 #else
233 #define SUBTARGET_SPARC
234 #endif
235
236 #ifdef LLVM_COMPONENT_HEXAGON
237 #define SUBTARGET_HEXAGON SUBTARGET(Hexagon)
238 #else
239 #define SUBTARGET_HEXAGON
240 #endif
241
242 #define GEN_SUBTARGETS                                                         \
243   SUBTARGET_X86                                                                \
244   SUBTARGET_ARM                                                                \
245   SUBTARGET_AARCH64                                                            \
246   SUBTARGET_MIPS                                                               \
247   SUBTARGET_PPC                                                                \
248   SUBTARGET_SYSTEMZ                                                            \
249   SUBTARGET_MSP430                                                             \
250   SUBTARGET_SPARC                                                              \
251   SUBTARGET_HEXAGON                                                            \
252   SUBTARGET_RISCV                                                              \
253
254 #define SUBTARGET(x)                                                           \
255   namespace llvm {                                                             \
256   extern const SubtargetFeatureKV x##FeatureKV[];                              \
257   extern const SubtargetFeatureKV x##SubTypeKV[];                              \
258   }
259
260 GEN_SUBTARGETS
261 #undef SUBTARGET
262
263 extern "C" bool LLVMRustHasFeature(LLVMTargetMachineRef TM,
264                                    const char *Feature) {
265   TargetMachine *Target = unwrap(TM);
266   const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
267   return MCInfo->checkFeatures(std::string("+") + Feature);
268 }
269
270 enum class LLVMRustCodeModel {
271   Other,
272   Small,
273   Kernel,
274   Medium,
275   Large,
276   None,
277 };
278
279 static CodeModel::Model fromRust(LLVMRustCodeModel Model) {
280   switch (Model) {
281   case LLVMRustCodeModel::Small:
282     return CodeModel::Small;
283   case LLVMRustCodeModel::Kernel:
284     return CodeModel::Kernel;
285   case LLVMRustCodeModel::Medium:
286     return CodeModel::Medium;
287   case LLVMRustCodeModel::Large:
288     return CodeModel::Large;
289   default:
290     report_fatal_error("Bad CodeModel.");
291   }
292 }
293
294 enum class LLVMRustCodeGenOptLevel {
295   Other,
296   None,
297   Less,
298   Default,
299   Aggressive,
300 };
301
302 static CodeGenOpt::Level fromRust(LLVMRustCodeGenOptLevel Level) {
303   switch (Level) {
304   case LLVMRustCodeGenOptLevel::None:
305     return CodeGenOpt::None;
306   case LLVMRustCodeGenOptLevel::Less:
307     return CodeGenOpt::Less;
308   case LLVMRustCodeGenOptLevel::Default:
309     return CodeGenOpt::Default;
310   case LLVMRustCodeGenOptLevel::Aggressive:
311     return CodeGenOpt::Aggressive;
312   default:
313     report_fatal_error("Bad CodeGenOptLevel.");
314   }
315 }
316
317 enum class LLVMRustRelocMode {
318   Default,
319   Static,
320   PIC,
321   DynamicNoPic,
322   ROPI,
323   RWPI,
324   ROPIRWPI,
325 };
326
327 static Optional<Reloc::Model> fromRust(LLVMRustRelocMode RustReloc) {
328   switch (RustReloc) {
329   case LLVMRustRelocMode::Default:
330     return None;
331   case LLVMRustRelocMode::Static:
332     return Reloc::Static;
333   case LLVMRustRelocMode::PIC:
334     return Reloc::PIC_;
335   case LLVMRustRelocMode::DynamicNoPic:
336     return Reloc::DynamicNoPIC;
337   case LLVMRustRelocMode::ROPI:
338     return Reloc::ROPI;
339   case LLVMRustRelocMode::RWPI:
340     return Reloc::RWPI;
341   case LLVMRustRelocMode::ROPIRWPI:
342     return Reloc::ROPI_RWPI;
343   }
344   report_fatal_error("Bad RelocModel.");
345 }
346
347 #ifdef LLVM_RUSTLLVM
348 /// getLongestEntryLength - Return the length of the longest entry in the table.
349 template<typename KV>
350 static size_t getLongestEntryLength(ArrayRef<KV> Table) {
351   size_t MaxLen = 0;
352   for (auto &I : Table)
353     MaxLen = std::max(MaxLen, std::strlen(I.Key));
354   return MaxLen;
355 }
356
357 extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM) {
358   const TargetMachine *Target = unwrap(TM);
359   const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
360   const Triple::ArchType HostArch = Triple(sys::getProcessTriple()).getArch();
361   const Triple::ArchType TargetArch = Target->getTargetTriple().getArch();
362   const ArrayRef<SubtargetSubTypeKV> CPUTable = MCInfo->getCPUTable();
363   unsigned MaxCPULen = getLongestEntryLength(CPUTable);
364
365   printf("Available CPUs for this target:\n");
366   if (HostArch == TargetArch) {
367     const StringRef HostCPU = sys::getHostCPUName();
368     printf("    %-*s - Select the CPU of the current host (currently %.*s).\n",
369       MaxCPULen, "native", (int)HostCPU.size(), HostCPU.data());
370   }
371   for (auto &CPU : CPUTable)
372     printf("    %-*s\n", MaxCPULen, CPU.Key);
373   printf("\n");
374 }
375
376 extern "C" void LLVMRustPrintTargetFeatures(LLVMTargetMachineRef TM) {
377   const TargetMachine *Target = unwrap(TM);
378   const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
379   const ArrayRef<SubtargetFeatureKV> FeatTable = MCInfo->getFeatureTable();
380   unsigned MaxFeatLen = getLongestEntryLength(FeatTable);
381
382   printf("Available features for this target:\n");
383   for (auto &Feature : FeatTable)
384     printf("    %-*s - %s.\n", MaxFeatLen, Feature.Key, Feature.Desc);
385   printf("\n");
386
387   printf("Use +feature to enable a feature, or -feature to disable it.\n"
388          "For example, rustc -C -target-cpu=mycpu -C "
389          "target-feature=+feature1,-feature2\n\n");
390 }
391
392 #else
393
394 extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef) {
395   printf("Target CPU help is not supported by this LLVM version.\n\n");
396 }
397
398 extern "C" void LLVMRustPrintTargetFeatures(LLVMTargetMachineRef) {
399   printf("Target features help is not supported by this LLVM version.\n\n");
400 }
401 #endif
402
403 extern "C" const char* LLVMRustGetHostCPUName(size_t *len) {
404   StringRef Name = sys::getHostCPUName();
405   *len = Name.size();
406   return Name.data();
407 }
408
409 extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
410     const char *TripleStr, const char *CPU, const char *Feature,
411     const char *ABIStr, LLVMRustCodeModel RustCM, LLVMRustRelocMode RustReloc,
412     LLVMRustCodeGenOptLevel RustOptLevel, bool UseSoftFloat,
413     bool PositionIndependentExecutable, bool FunctionSections,
414     bool DataSections,
415     bool TrapUnreachable,
416     bool Singlethread,
417     bool AsmComments,
418     bool EmitStackSizeSection,
419     bool RelaxELFRelocations) {
420
421   auto OptLevel = fromRust(RustOptLevel);
422   auto RM = fromRust(RustReloc);
423
424   std::string Error;
425   Triple Trip(Triple::normalize(TripleStr));
426   const llvm::Target *TheTarget =
427       TargetRegistry::lookupTarget(Trip.getTriple(), Error);
428   if (TheTarget == nullptr) {
429     LLVMRustSetLastError(Error.c_str());
430     return nullptr;
431   }
432
433   TargetOptions Options;
434
435   Options.FloatABIType = FloatABI::Default;
436   if (UseSoftFloat) {
437     Options.FloatABIType = FloatABI::Soft;
438   }
439   Options.DataSections = DataSections;
440   Options.FunctionSections = FunctionSections;
441   Options.MCOptions.AsmVerbose = AsmComments;
442   Options.MCOptions.PreserveAsmComments = AsmComments;
443   Options.MCOptions.ABIName = ABIStr;
444   Options.RelaxELFRelocations = RelaxELFRelocations;
445
446   if (TrapUnreachable) {
447     // Tell LLVM to codegen `unreachable` into an explicit trap instruction.
448     // This limits the extent of possible undefined behavior in some cases, as
449     // it prevents control flow from "falling through" into whatever code
450     // happens to be laid out next in memory.
451     Options.TrapUnreachable = true;
452   }
453
454   if (Singlethread) {
455     Options.ThreadModel = ThreadModel::Single;
456   }
457
458   Options.EmitStackSizeSection = EmitStackSizeSection;
459
460   Optional<CodeModel::Model> CM;
461   if (RustCM != LLVMRustCodeModel::None)
462     CM = fromRust(RustCM);
463   TargetMachine *TM = TheTarget->createTargetMachine(
464       Trip.getTriple(), CPU, Feature, Options, RM, CM, OptLevel);
465   return wrap(TM);
466 }
467
468 extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) {
469   delete unwrap(TM);
470 }
471
472 extern "C" void LLVMRustConfigurePassManagerBuilder(
473     LLVMPassManagerBuilderRef PMBR, LLVMRustCodeGenOptLevel OptLevel,
474     bool MergeFunctions, bool SLPVectorize, bool LoopVectorize, bool PrepareForThinLTO,
475     const char* PGOGenPath, const char* PGOUsePath) {
476   unwrap(PMBR)->MergeFunctions = MergeFunctions;
477   unwrap(PMBR)->SLPVectorize = SLPVectorize;
478   unwrap(PMBR)->OptLevel = fromRust(OptLevel);
479   unwrap(PMBR)->LoopVectorize = LoopVectorize;
480   unwrap(PMBR)->PrepareForThinLTO = PrepareForThinLTO;
481
482   if (PGOGenPath) {
483     assert(!PGOUsePath);
484     unwrap(PMBR)->EnablePGOInstrGen = true;
485     unwrap(PMBR)->PGOInstrGen = PGOGenPath;
486   }
487   if (PGOUsePath) {
488     assert(!PGOGenPath);
489     unwrap(PMBR)->PGOInstrUse = PGOUsePath;
490   }
491 }
492
493 // Unfortunately, the LLVM C API doesn't provide a way to set the `LibraryInfo`
494 // field of a PassManagerBuilder, we expose our own method of doing so.
495 extern "C" void LLVMRustAddBuilderLibraryInfo(LLVMPassManagerBuilderRef PMBR,
496                                               LLVMModuleRef M,
497                                               bool DisableSimplifyLibCalls) {
498   Triple TargetTriple(unwrap(M)->getTargetTriple());
499   TargetLibraryInfoImpl *TLI = new TargetLibraryInfoImpl(TargetTriple);
500   if (DisableSimplifyLibCalls)
501     TLI->disableAllFunctions();
502   unwrap(PMBR)->LibraryInfo = TLI;
503 }
504
505 // Unfortunately, the LLVM C API doesn't provide a way to create the
506 // TargetLibraryInfo pass, so we use this method to do so.
507 extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR, LLVMModuleRef M,
508                                        bool DisableSimplifyLibCalls) {
509   Triple TargetTriple(unwrap(M)->getTargetTriple());
510   TargetLibraryInfoImpl TLII(TargetTriple);
511   if (DisableSimplifyLibCalls)
512     TLII.disableAllFunctions();
513   unwrap(PMR)->add(new TargetLibraryInfoWrapperPass(TLII));
514 }
515
516 // Unfortunately, the LLVM C API doesn't provide an easy way of iterating over
517 // all the functions in a module, so we do that manually here. You'll find
518 // similar code in clang's BackendUtil.cpp file.
519 extern "C" void LLVMRustRunFunctionPassManager(LLVMPassManagerRef PMR,
520                                                LLVMModuleRef M) {
521   llvm::legacy::FunctionPassManager *P =
522       unwrap<llvm::legacy::FunctionPassManager>(PMR);
523   P->doInitialization();
524
525   // Upgrade all calls to old intrinsics first.
526   for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E;)
527     UpgradeCallsToIntrinsic(&*I++); // must be post-increment, as we remove
528
529   for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E;
530        ++I)
531     if (!I->isDeclaration())
532       P->run(*I);
533
534   P->doFinalization();
535 }
536
537 extern "C" void LLVMRustSetLLVMOptions(int Argc, char **Argv) {
538   // Initializing the command-line options more than once is not allowed. So,
539   // check if they've already been initialized.  (This could happen if we're
540   // being called from rustpkg, for example). If the arguments change, then
541   // that's just kinda unfortunate.
542   static bool Initialized = false;
543   if (Initialized)
544     return;
545   Initialized = true;
546   cl::ParseCommandLineOptions(Argc, Argv);
547 }
548
549 enum class LLVMRustFileType {
550   Other,
551   AssemblyFile,
552   ObjectFile,
553 };
554
555 #if LLVM_VERSION_GE(10, 0)
556 static CodeGenFileType fromRust(LLVMRustFileType Type) {
557   switch (Type) {
558   case LLVMRustFileType::AssemblyFile:
559     return CGFT_AssemblyFile;
560   case LLVMRustFileType::ObjectFile:
561     return CGFT_ObjectFile;
562   default:
563     report_fatal_error("Bad FileType.");
564   }
565 }
566 #else
567 static TargetMachine::CodeGenFileType fromRust(LLVMRustFileType Type) {
568   switch (Type) {
569   case LLVMRustFileType::AssemblyFile:
570     return TargetMachine::CGFT_AssemblyFile;
571   case LLVMRustFileType::ObjectFile:
572     return TargetMachine::CGFT_ObjectFile;
573   default:
574     report_fatal_error("Bad FileType.");
575   }
576 }
577 #endif
578
579 extern "C" LLVMRustResult
580 LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR,
581                         LLVMModuleRef M, const char *Path,
582                         LLVMRustFileType RustFileType) {
583   llvm::legacy::PassManager *PM = unwrap<llvm::legacy::PassManager>(PMR);
584   auto FileType = fromRust(RustFileType);
585
586   std::string ErrorInfo;
587   std::error_code EC;
588   raw_fd_ostream OS(Path, EC, sys::fs::F_None);
589   if (EC)
590     ErrorInfo = EC.message();
591   if (ErrorInfo != "") {
592     LLVMRustSetLastError(ErrorInfo.c_str());
593     return LLVMRustResult::Failure;
594   }
595
596   buffer_ostream BOS(OS);
597   unwrap(Target)->addPassesToEmitFile(*PM, BOS, nullptr, FileType, false);
598   PM->run(*unwrap(M));
599
600   // Apparently `addPassesToEmitFile` adds a pointer to our on-the-stack output
601   // stream (OS), so the only real safe place to delete this is here? Don't we
602   // wish this was written in Rust?
603   LLVMDisposePassManager(PMR);
604   return LLVMRustResult::Success;
605 }
606
607
608 // Callback to demangle function name
609 // Parameters:
610 // * name to be demangled
611 // * name len
612 // * output buffer
613 // * output buffer len
614 // Returns len of demangled string, or 0 if demangle failed.
615 typedef size_t (*DemangleFn)(const char*, size_t, char*, size_t);
616
617
618 namespace {
619
620 class RustAssemblyAnnotationWriter : public AssemblyAnnotationWriter {
621   DemangleFn Demangle;
622   std::vector<char> Buf;
623
624 public:
625   RustAssemblyAnnotationWriter(DemangleFn Demangle) : Demangle(Demangle) {}
626
627   // Return empty string if demangle failed
628   // or if name does not need to be demangled
629   StringRef CallDemangle(StringRef name) {
630     if (!Demangle) {
631       return StringRef();
632     }
633
634     if (Buf.size() < name.size() * 2) {
635       // Semangled name usually shorter than mangled,
636       // but allocate twice as much memory just in case
637       Buf.resize(name.size() * 2);
638     }
639
640     auto R = Demangle(name.data(), name.size(), Buf.data(), Buf.size());
641     if (!R) {
642       // Demangle failed.
643       return StringRef();
644     }
645
646     auto Demangled = StringRef(Buf.data(), R);
647     if (Demangled == name) {
648       // Do not print anything if demangled name is equal to mangled.
649       return StringRef();
650     }
651
652     return Demangled;
653   }
654
655   void emitFunctionAnnot(const Function *F,
656                          formatted_raw_ostream &OS) override {
657     StringRef Demangled = CallDemangle(F->getName());
658     if (Demangled.empty()) {
659         return;
660     }
661
662     OS << "; " << Demangled << "\n";
663   }
664
665   void emitInstructionAnnot(const Instruction *I,
666                             formatted_raw_ostream &OS) override {
667     const char *Name;
668     const Value *Value;
669     if (const CallInst *CI = dyn_cast<CallInst>(I)) {
670       Name = "call";
671       Value = CI->getCalledValue();
672     } else if (const InvokeInst* II = dyn_cast<InvokeInst>(I)) {
673       Name = "invoke";
674       Value = II->getCalledValue();
675     } else {
676       // Could demangle more operations, e. g.
677       // `store %place, @function`.
678       return;
679     }
680
681     if (!Value->hasName()) {
682       return;
683     }
684
685     StringRef Demangled = CallDemangle(Value->getName());
686     if (Demangled.empty()) {
687       return;
688     }
689
690     OS << "; " << Name << " " << Demangled << "\n";
691   }
692 };
693
694 } // namespace
695
696 extern "C" LLVMRustResult
697 LLVMRustPrintModule(LLVMModuleRef M, const char *Path, DemangleFn Demangle) {
698   std::string ErrorInfo;
699   std::error_code EC;
700   raw_fd_ostream OS(Path, EC, sys::fs::F_None);
701   if (EC)
702     ErrorInfo = EC.message();
703   if (ErrorInfo != "") {
704     LLVMRustSetLastError(ErrorInfo.c_str());
705     return LLVMRustResult::Failure;
706   }
707
708   RustAssemblyAnnotationWriter AAW(Demangle);
709   formatted_raw_ostream FOS(OS);
710   unwrap(M)->print(FOS, &AAW);
711
712   return LLVMRustResult::Success;
713 }
714
715 extern "C" void LLVMRustPrintPasses() {
716   LLVMInitializePasses();
717   struct MyListener : PassRegistrationListener {
718     void passEnumerate(const PassInfo *Info) {
719       StringRef PassArg = Info->getPassArgument();
720       StringRef PassName = Info->getPassName();
721       if (!PassArg.empty()) {
722         // These unsigned->signed casts could theoretically overflow, but
723         // realistically never will (and even if, the result is implementation
724         // defined rather plain UB).
725         printf("%15.*s - %.*s\n", (int)PassArg.size(), PassArg.data(),
726                (int)PassName.size(), PassName.data());
727       }
728     }
729   } Listener;
730
731   PassRegistry *PR = PassRegistry::getPassRegistry();
732   PR->enumerateWith(&Listener);
733 }
734
735 extern "C" void LLVMRustAddAlwaysInlinePass(LLVMPassManagerBuilderRef PMBR,
736                                             bool AddLifetimes) {
737   unwrap(PMBR)->Inliner = llvm::createAlwaysInlinerLegacyPass(AddLifetimes);
738 }
739
740 extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **Symbols,
741                                            size_t Len) {
742   llvm::legacy::PassManager passes;
743
744   auto PreserveFunctions = [=](const GlobalValue &GV) {
745     for (size_t I = 0; I < Len; I++) {
746       if (GV.getName() == Symbols[I]) {
747         return true;
748       }
749     }
750     return false;
751   };
752
753   passes.add(llvm::createInternalizePass(PreserveFunctions));
754
755   passes.run(*unwrap(M));
756 }
757
758 extern "C" void LLVMRustMarkAllFunctionsNounwind(LLVMModuleRef M) {
759   for (Module::iterator GV = unwrap(M)->begin(), E = unwrap(M)->end(); GV != E;
760        ++GV) {
761     GV->setDoesNotThrow();
762     Function *F = dyn_cast<Function>(GV);
763     if (F == nullptr)
764       continue;
765
766     for (Function::iterator B = F->begin(), BE = F->end(); B != BE; ++B) {
767       for (BasicBlock::iterator I = B->begin(), IE = B->end(); I != IE; ++I) {
768         if (isa<InvokeInst>(I)) {
769           InvokeInst *CI = cast<InvokeInst>(I);
770           CI->setDoesNotThrow();
771         }
772       }
773     }
774   }
775 }
776
777 extern "C" void
778 LLVMRustSetDataLayoutFromTargetMachine(LLVMModuleRef Module,
779                                        LLVMTargetMachineRef TMR) {
780   TargetMachine *Target = unwrap(TMR);
781   unwrap(Module)->setDataLayout(Target->createDataLayout());
782 }
783
784 extern "C" void LLVMRustSetModulePICLevel(LLVMModuleRef M) {
785   unwrap(M)->setPICLevel(PICLevel::Level::BigPIC);
786 }
787
788 extern "C" void LLVMRustSetModulePIELevel(LLVMModuleRef M) {
789   unwrap(M)->setPIELevel(PIELevel::Level::Large);
790 }
791
792 // Here you'll find an implementation of ThinLTO as used by the Rust compiler
793 // right now. This ThinLTO support is only enabled on "recent ish" versions of
794 // LLVM, and otherwise it's just blanket rejected from other compilers.
795 //
796 // Most of this implementation is straight copied from LLVM. At the time of
797 // this writing it wasn't *quite* suitable to reuse more code from upstream
798 // for our purposes, but we should strive to upstream this support once it's
799 // ready to go! I figure we may want a bit of testing locally first before
800 // sending this upstream to LLVM. I hear though they're quite eager to receive
801 // feedback like this!
802 //
803 // If you're reading this code and wondering "what in the world" or you're
804 // working "good lord by LLVM upgrade is *still* failing due to these bindings"
805 // then fear not! (ok maybe fear a little). All code here is mostly based
806 // on `lib/LTO/ThinLTOCodeGenerator.cpp` in LLVM.
807 //
808 // You'll find that the general layout here roughly corresponds to the `run`
809 // method in that file as well as `ProcessThinLTOModule`. Functions are
810 // specifically commented below as well, but if you're updating this code
811 // or otherwise trying to understand it, the LLVM source will be useful in
812 // interpreting the mysteries within.
813 //
814 // Otherwise I'll apologize in advance, it probably requires a relatively
815 // significant investment on your part to "truly understand" what's going on
816 // here. Not saying I do myself, but it took me awhile staring at LLVM's source
817 // and various online resources about ThinLTO to make heads or tails of all
818 // this.
819
820 // This is a shared data structure which *must* be threadsafe to share
821 // read-only amongst threads. This also corresponds basically to the arguments
822 // of the `ProcessThinLTOModule` function in the LLVM source.
823 struct LLVMRustThinLTOData {
824   // The combined index that is the global analysis over all modules we're
825   // performing ThinLTO for. This is mostly managed by LLVM.
826   ModuleSummaryIndex Index;
827
828   // All modules we may look at, stored as in-memory serialized versions. This
829   // is later used when inlining to ensure we can extract any module to inline
830   // from.
831   StringMap<MemoryBufferRef> ModuleMap;
832
833   // A set that we manage of everything we *don't* want internalized. Note that
834   // this includes all transitive references right now as well, but it may not
835   // always!
836   DenseSet<GlobalValue::GUID> GUIDPreservedSymbols;
837
838   // Not 100% sure what these are, but they impact what's internalized and
839   // what's inlined across modules, I believe.
840   StringMap<FunctionImporter::ImportMapTy> ImportLists;
841   StringMap<FunctionImporter::ExportSetTy> ExportLists;
842   StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries;
843
844   LLVMRustThinLTOData() : Index(/* HaveGVs = */ false) {}
845 };
846
847 // Just an argument to the `LLVMRustCreateThinLTOData` function below.
848 struct LLVMRustThinLTOModule {
849   const char *identifier;
850   const char *data;
851   size_t len;
852 };
853
854 // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp`, not sure what it
855 // does.
856 static const GlobalValueSummary *
857 getFirstDefinitionForLinker(const GlobalValueSummaryList &GVSummaryList) {
858   auto StrongDefForLinker = llvm::find_if(
859       GVSummaryList, [](const std::unique_ptr<GlobalValueSummary> &Summary) {
860         auto Linkage = Summary->linkage();
861         return !GlobalValue::isAvailableExternallyLinkage(Linkage) &&
862                !GlobalValue::isWeakForLinker(Linkage);
863       });
864   if (StrongDefForLinker != GVSummaryList.end())
865     return StrongDefForLinker->get();
866
867   auto FirstDefForLinker = llvm::find_if(
868       GVSummaryList, [](const std::unique_ptr<GlobalValueSummary> &Summary) {
869         auto Linkage = Summary->linkage();
870         return !GlobalValue::isAvailableExternallyLinkage(Linkage);
871       });
872   if (FirstDefForLinker == GVSummaryList.end())
873     return nullptr;
874   return FirstDefForLinker->get();
875 }
876
877 // The main entry point for creating the global ThinLTO analysis. The structure
878 // here is basically the same as before threads are spawned in the `run`
879 // function of `lib/LTO/ThinLTOCodeGenerator.cpp`.
880 extern "C" LLVMRustThinLTOData*
881 LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
882                           int num_modules,
883                           const char **preserved_symbols,
884                           int num_symbols) {
885 #if LLVM_VERSION_GE(10, 0)
886   auto Ret = std::make_unique<LLVMRustThinLTOData>();
887 #else
888   auto Ret = llvm::make_unique<LLVMRustThinLTOData>();
889 #endif
890
891   // Load each module's summary and merge it into one combined index
892   for (int i = 0; i < num_modules; i++) {
893     auto module = &modules[i];
894     StringRef buffer(module->data, module->len);
895     MemoryBufferRef mem_buffer(buffer, module->identifier);
896
897     Ret->ModuleMap[module->identifier] = mem_buffer;
898
899     if (Error Err = readModuleSummaryIndex(mem_buffer, Ret->Index, i)) {
900       LLVMRustSetLastError(toString(std::move(Err)).c_str());
901       return nullptr;
902     }
903   }
904
905   // Collect for each module the list of function it defines (GUID -> Summary)
906   Ret->Index.collectDefinedGVSummariesPerModule(Ret->ModuleToDefinedGVSummaries);
907
908   // Convert the preserved symbols set from string to GUID, this is then needed
909   // for internalization.
910   for (int i = 0; i < num_symbols; i++) {
911     auto GUID = GlobalValue::getGUID(preserved_symbols[i]);
912     Ret->GUIDPreservedSymbols.insert(GUID);
913   }
914
915   // Collect the import/export lists for all modules from the call-graph in the
916   // combined index
917   //
918   // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp`
919   auto deadIsPrevailing = [&](GlobalValue::GUID G) {
920     return PrevailingType::Unknown;
921   };
922 #if LLVM_VERSION_GE(8, 0)
923   // We don't have a complete picture in our use of ThinLTO, just our immediate
924   // crate, so we need `ImportEnabled = false` to limit internalization.
925   // Otherwise, we sometimes lose `static` values -- see #60184.
926   computeDeadSymbolsWithConstProp(Ret->Index, Ret->GUIDPreservedSymbols,
927                                   deadIsPrevailing, /* ImportEnabled = */ false);
928 #else
929   computeDeadSymbols(Ret->Index, Ret->GUIDPreservedSymbols, deadIsPrevailing);
930 #endif
931   ComputeCrossModuleImport(
932     Ret->Index,
933     Ret->ModuleToDefinedGVSummaries,
934     Ret->ImportLists,
935     Ret->ExportLists
936   );
937
938   // Resolve LinkOnce/Weak symbols, this has to be computed early be cause it
939   // impacts the caching.
940   //
941   // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp` with some of this
942   // being lifted from `lib/LTO/LTO.cpp` as well
943   StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
944   DenseMap<GlobalValue::GUID, const GlobalValueSummary *> PrevailingCopy;
945   for (auto &I : Ret->Index) {
946     if (I.second.SummaryList.size() > 1)
947       PrevailingCopy[I.first] = getFirstDefinitionForLinker(I.second.SummaryList);
948   }
949   auto isPrevailing = [&](GlobalValue::GUID GUID, const GlobalValueSummary *S) {
950     const auto &Prevailing = PrevailingCopy.find(GUID);
951     if (Prevailing == PrevailingCopy.end())
952       return true;
953     return Prevailing->second == S;
954   };
955   auto recordNewLinkage = [&](StringRef ModuleIdentifier,
956                               GlobalValue::GUID GUID,
957                               GlobalValue::LinkageTypes NewLinkage) {
958     ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;
959   };
960 #if LLVM_VERSION_GE(9, 0)
961   thinLTOResolvePrevailingInIndex(Ret->Index, isPrevailing, recordNewLinkage,
962                                   Ret->GUIDPreservedSymbols);
963 #elif LLVM_VERSION_GE(8, 0)
964   thinLTOResolvePrevailingInIndex(Ret->Index, isPrevailing, recordNewLinkage);
965 #else
966   thinLTOResolveWeakForLinkerInIndex(Ret->Index, isPrevailing, recordNewLinkage);
967 #endif
968
969   // Here we calculate an `ExportedGUIDs` set for use in the `isExported`
970   // callback below. This callback below will dictate the linkage for all
971   // summaries in the index, and we basically just only want to ensure that dead
972   // symbols are internalized. Otherwise everything that's already external
973   // linkage will stay as external, and internal will stay as internal.
974   std::set<GlobalValue::GUID> ExportedGUIDs;
975   for (auto &List : Ret->Index) {
976     for (auto &GVS: List.second.SummaryList) {
977       if (GlobalValue::isLocalLinkage(GVS->linkage()))
978         continue;
979       auto GUID = GVS->getOriginalName();
980       if (GVS->flags().Live)
981         ExportedGUIDs.insert(GUID);
982     }
983   }
984 #if LLVM_VERSION_GE(10, 0)
985   auto isExported = [&](StringRef ModuleIdentifier, ValueInfo VI) {
986     const auto &ExportList = Ret->ExportLists.find(ModuleIdentifier);
987     return (ExportList != Ret->ExportLists.end() &&
988       ExportList->second.count(VI)) ||
989       ExportedGUIDs.count(VI.getGUID());
990   };
991   thinLTOInternalizeAndPromoteInIndex(Ret->Index, isExported, isPrevailing);
992 #else
993   auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) {
994     const auto &ExportList = Ret->ExportLists.find(ModuleIdentifier);
995     return (ExportList != Ret->ExportLists.end() &&
996       ExportList->second.count(GUID)) ||
997       ExportedGUIDs.count(GUID);
998   };
999   thinLTOInternalizeAndPromoteInIndex(Ret->Index, isExported);
1000 #endif
1001
1002   return Ret.release();
1003 }
1004
1005 extern "C" void
1006 LLVMRustFreeThinLTOData(LLVMRustThinLTOData *Data) {
1007   delete Data;
1008 }
1009
1010 // Below are the various passes that happen *per module* when doing ThinLTO.
1011 //
1012 // In other words, these are the functions that are all run concurrently
1013 // with one another, one per module. The passes here correspond to the analysis
1014 // passes in `lib/LTO/ThinLTOCodeGenerator.cpp`, currently found in the
1015 // `ProcessThinLTOModule` function. Here they're split up into separate steps
1016 // so rustc can save off the intermediate bytecode between each step.
1017
1018 extern "C" bool
1019 LLVMRustPrepareThinLTORename(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
1020   Module &Mod = *unwrap(M);
1021   if (renameModuleForThinLTO(Mod, Data->Index)) {
1022     LLVMRustSetLastError("renameModuleForThinLTO failed");
1023     return false;
1024   }
1025   return true;
1026 }
1027
1028 extern "C" bool
1029 LLVMRustPrepareThinLTOResolveWeak(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
1030   Module &Mod = *unwrap(M);
1031   const auto &DefinedGlobals = Data->ModuleToDefinedGVSummaries.lookup(Mod.getModuleIdentifier());
1032 #if LLVM_VERSION_GE(8, 0)
1033   thinLTOResolvePrevailingInModule(Mod, DefinedGlobals);
1034 #else
1035   thinLTOResolveWeakForLinkerModule(Mod, DefinedGlobals);
1036 #endif
1037   return true;
1038 }
1039
1040 extern "C" bool
1041 LLVMRustPrepareThinLTOInternalize(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
1042   Module &Mod = *unwrap(M);
1043   const auto &DefinedGlobals = Data->ModuleToDefinedGVSummaries.lookup(Mod.getModuleIdentifier());
1044   thinLTOInternalizeModule(Mod, DefinedGlobals);
1045   return true;
1046 }
1047
1048 extern "C" bool
1049 LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
1050   Module &Mod = *unwrap(M);
1051
1052   const auto &ImportList = Data->ImportLists.lookup(Mod.getModuleIdentifier());
1053   auto Loader = [&](StringRef Identifier) {
1054     const auto &Memory = Data->ModuleMap.lookup(Identifier);
1055     auto &Context = Mod.getContext();
1056     auto MOrErr = getLazyBitcodeModule(Memory, Context, true, true);
1057
1058     if (!MOrErr)
1059       return MOrErr;
1060
1061     // The rest of this closure is a workaround for
1062     // https://bugs.llvm.org/show_bug.cgi?id=38184 where during ThinLTO imports
1063     // we accidentally import wasm custom sections into different modules,
1064     // duplicating them by in the final output artifact.
1065     //
1066     // The issue is worked around here by manually removing the
1067     // `wasm.custom_sections` named metadata node from any imported module. This
1068     // we know isn't used by any optimization pass so there's no need for it to
1069     // be imported.
1070     //
1071     // Note that the metadata is currently lazily loaded, so we materialize it
1072     // here before looking up if there's metadata inside. The `FunctionImporter`
1073     // will immediately materialize metadata anyway after an import, so this
1074     // shouldn't be a perf hit.
1075     if (Error Err = (*MOrErr)->materializeMetadata()) {
1076       Expected<std::unique_ptr<Module>> Ret(std::move(Err));
1077       return Ret;
1078     }
1079
1080     auto *WasmCustomSections = (*MOrErr)->getNamedMetadata("wasm.custom_sections");
1081     if (WasmCustomSections)
1082       WasmCustomSections->eraseFromParent();
1083
1084     return MOrErr;
1085   };
1086   FunctionImporter Importer(Data->Index, Loader);
1087   Expected<bool> Result = Importer.importFunctions(Mod, ImportList);
1088   if (!Result) {
1089     LLVMRustSetLastError(toString(Result.takeError()).c_str());
1090     return false;
1091   }
1092   return true;
1093 }
1094
1095 extern "C" typedef void (*LLVMRustModuleNameCallback)(void*, // payload
1096                                                       const char*, // importing module name
1097                                                       const char*); // imported module name
1098
1099 // Calls `module_name_callback` for each module import done by ThinLTO.
1100 // The callback is provided with regular null-terminated C strings.
1101 extern "C" void
1102 LLVMRustGetThinLTOModuleImports(const LLVMRustThinLTOData *data,
1103                                 LLVMRustModuleNameCallback module_name_callback,
1104                                 void* callback_payload) {
1105   for (const auto& importing_module : data->ImportLists) {
1106     const std::string importing_module_id = importing_module.getKey().str();
1107     const auto& imports = importing_module.getValue();
1108     for (const auto& imported_module : imports) {
1109       const std::string imported_module_id = imported_module.getKey().str();
1110       module_name_callback(callback_payload,
1111                            importing_module_id.c_str(),
1112                            imported_module_id.c_str());
1113     }
1114   }
1115 }
1116
1117 // This struct and various functions are sort of a hack right now, but the
1118 // problem is that we've got in-memory LLVM modules after we generate and
1119 // optimize all codegen-units for one compilation in rustc. To be compatible
1120 // with the LTO support above we need to serialize the modules plus their
1121 // ThinLTO summary into memory.
1122 //
1123 // This structure is basically an owned version of a serialize module, with
1124 // a ThinLTO summary attached.
1125 struct LLVMRustThinLTOBuffer {
1126   std::string data;
1127 };
1128
1129 extern "C" LLVMRustThinLTOBuffer*
1130 LLVMRustThinLTOBufferCreate(LLVMModuleRef M) {
1131 #if LLVM_VERSION_GE(10, 0)
1132   auto Ret = std::make_unique<LLVMRustThinLTOBuffer>();
1133 #else
1134   auto Ret = llvm::make_unique<LLVMRustThinLTOBuffer>();
1135 #endif
1136   {
1137     raw_string_ostream OS(Ret->data);
1138     {
1139       legacy::PassManager PM;
1140       PM.add(createWriteThinLTOBitcodePass(OS));
1141       PM.run(*unwrap(M));
1142     }
1143   }
1144   return Ret.release();
1145 }
1146
1147 extern "C" void
1148 LLVMRustThinLTOBufferFree(LLVMRustThinLTOBuffer *Buffer) {
1149   delete Buffer;
1150 }
1151
1152 extern "C" const void*
1153 LLVMRustThinLTOBufferPtr(const LLVMRustThinLTOBuffer *Buffer) {
1154   return Buffer->data.data();
1155 }
1156
1157 extern "C" size_t
1158 LLVMRustThinLTOBufferLen(const LLVMRustThinLTOBuffer *Buffer) {
1159   return Buffer->data.length();
1160 }
1161
1162 // This is what we used to parse upstream bitcode for actual ThinLTO
1163 // processing.  We'll call this once per module optimized through ThinLTO, and
1164 // it'll be called concurrently on many threads.
1165 extern "C" LLVMModuleRef
1166 LLVMRustParseBitcodeForLTO(LLVMContextRef Context,
1167                            const char *data,
1168                            size_t len,
1169                            const char *identifier) {
1170   StringRef Data(data, len);
1171   MemoryBufferRef Buffer(Data, identifier);
1172   unwrap(Context)->enableDebugTypeODRUniquing();
1173   Expected<std::unique_ptr<Module>> SrcOrError =
1174       parseBitcodeFile(Buffer, *unwrap(Context));
1175   if (!SrcOrError) {
1176     LLVMRustSetLastError(toString(SrcOrError.takeError()).c_str());
1177     return nullptr;
1178   }
1179   return wrap(std::move(*SrcOrError).release());
1180 }
1181
1182 // Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
1183 // the comment in `back/lto.rs` for why this exists.
1184 extern "C" void
1185 LLVMRustThinLTOGetDICompileUnit(LLVMModuleRef Mod,
1186                                 DICompileUnit **A,
1187                                 DICompileUnit **B) {
1188   Module *M = unwrap(Mod);
1189   DICompileUnit **Cur = A;
1190   DICompileUnit **Next = B;
1191   for (DICompileUnit *CU : M->debug_compile_units()) {
1192     *Cur = CU;
1193     Cur = Next;
1194     Next = nullptr;
1195     if (Cur == nullptr)
1196       break;
1197   }
1198 }
1199
1200 // Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
1201 // the comment in `back/lto.rs` for why this exists.
1202 extern "C" void
1203 LLVMRustThinLTOPatchDICompileUnit(LLVMModuleRef Mod, DICompileUnit *Unit) {
1204   Module *M = unwrap(Mod);
1205
1206   // If the original source module didn't have a `DICompileUnit` then try to
1207   // merge all the existing compile units. If there aren't actually any though
1208   // then there's not much for us to do so return.
1209   if (Unit == nullptr) {
1210     for (DICompileUnit *CU : M->debug_compile_units()) {
1211       Unit = CU;
1212       break;
1213     }
1214     if (Unit == nullptr)
1215       return;
1216   }
1217
1218   // Use LLVM's built-in `DebugInfoFinder` to find a bunch of debuginfo and
1219   // process it recursively. Note that we specifically iterate over instructions
1220   // to ensure we feed everything into it.
1221   DebugInfoFinder Finder;
1222   Finder.processModule(*M);
1223   for (Function &F : M->functions()) {
1224     for (auto &FI : F) {
1225       for (Instruction &BI : FI) {
1226         if (auto Loc = BI.getDebugLoc())
1227           Finder.processLocation(*M, Loc);
1228         if (auto DVI = dyn_cast<DbgValueInst>(&BI))
1229           Finder.processValue(*M, DVI);
1230         if (auto DDI = dyn_cast<DbgDeclareInst>(&BI))
1231           Finder.processDeclare(*M, DDI);
1232       }
1233     }
1234   }
1235
1236   // After we've found all our debuginfo, rewrite all subprograms to point to
1237   // the same `DICompileUnit`.
1238   for (auto &F : Finder.subprograms()) {
1239     F->replaceUnit(Unit);
1240   }
1241
1242   // Erase any other references to other `DICompileUnit` instances, the verifier
1243   // will later ensure that we don't actually have any other stale references to
1244   // worry about.
1245   auto *MD = M->getNamedMetadata("llvm.dbg.cu");
1246   MD->clearOperands();
1247   MD->addOperand(Unit);
1248 }