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