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