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