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