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