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