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