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