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