]> git.lizzy.rs Git - rust.git/blob - src/rustllvm/PassWrapper.cpp
Remove CodeGenOptLevel::Other
[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   None,
315   Less,
316   Default,
317   Aggressive,
318 };
319
320 static CodeGenOpt::Level fromRust(LLVMRustCodeGenOptLevel Level) {
321   switch (Level) {
322   case LLVMRustCodeGenOptLevel::None:
323     return CodeGenOpt::None;
324   case LLVMRustCodeGenOptLevel::Less:
325     return CodeGenOpt::Less;
326   case LLVMRustCodeGenOptLevel::Default:
327     return CodeGenOpt::Default;
328   case LLVMRustCodeGenOptLevel::Aggressive:
329     return CodeGenOpt::Aggressive;
330   default:
331     report_fatal_error("Bad CodeGenOptLevel.");
332   }
333 }
334
335 enum class LLVMRustPassBuilderOptLevel {
336   O0,
337   O1,
338   O2,
339   O3,
340   Os,
341   Oz,
342 };
343
344 static PassBuilder::OptimizationLevel fromRust(LLVMRustPassBuilderOptLevel Level) {
345   switch (Level) {
346   case LLVMRustPassBuilderOptLevel::O0:
347     return PassBuilder::OptimizationLevel::O0;
348   case LLVMRustPassBuilderOptLevel::O1:
349     return PassBuilder::OptimizationLevel::O1;
350   case LLVMRustPassBuilderOptLevel::O2:
351     return PassBuilder::OptimizationLevel::O2;
352   case LLVMRustPassBuilderOptLevel::O3:
353     return PassBuilder::OptimizationLevel::O3;
354   case LLVMRustPassBuilderOptLevel::Os:
355     return PassBuilder::OptimizationLevel::Os;
356   case LLVMRustPassBuilderOptLevel::Oz:
357     return PassBuilder::OptimizationLevel::Oz;
358   default:
359     report_fatal_error("Bad PassBuilderOptLevel.");
360   }
361 }
362
363 enum class LLVMRustRelocModel {
364   Static,
365   PIC,
366   DynamicNoPic,
367   ROPI,
368   RWPI,
369   ROPIRWPI,
370 };
371
372 static Reloc::Model fromRust(LLVMRustRelocModel RustReloc) {
373   switch (RustReloc) {
374   case LLVMRustRelocModel::Static:
375     return Reloc::Static;
376   case LLVMRustRelocModel::PIC:
377     return Reloc::PIC_;
378   case LLVMRustRelocModel::DynamicNoPic:
379     return Reloc::DynamicNoPIC;
380   case LLVMRustRelocModel::ROPI:
381     return Reloc::ROPI;
382   case LLVMRustRelocModel::RWPI:
383     return Reloc::RWPI;
384   case LLVMRustRelocModel::ROPIRWPI:
385     return Reloc::ROPI_RWPI;
386   }
387   report_fatal_error("Bad RelocModel.");
388 }
389
390 #ifdef LLVM_RUSTLLVM
391 /// getLongestEntryLength - Return the length of the longest entry in the table.
392 template<typename KV>
393 static size_t getLongestEntryLength(ArrayRef<KV> Table) {
394   size_t MaxLen = 0;
395   for (auto &I : Table)
396     MaxLen = std::max(MaxLen, std::strlen(I.Key));
397   return MaxLen;
398 }
399
400 extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM) {
401   const TargetMachine *Target = unwrap(TM);
402   const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
403   const Triple::ArchType HostArch = Triple(sys::getProcessTriple()).getArch();
404   const Triple::ArchType TargetArch = Target->getTargetTriple().getArch();
405   const ArrayRef<SubtargetSubTypeKV> CPUTable = MCInfo->getCPUTable();
406   unsigned MaxCPULen = getLongestEntryLength(CPUTable);
407
408   printf("Available CPUs for this target:\n");
409   if (HostArch == TargetArch) {
410     const StringRef HostCPU = sys::getHostCPUName();
411     printf("    %-*s - Select the CPU of the current host (currently %.*s).\n",
412       MaxCPULen, "native", (int)HostCPU.size(), HostCPU.data());
413   }
414   for (auto &CPU : CPUTable)
415     printf("    %-*s\n", MaxCPULen, CPU.Key);
416   printf("\n");
417 }
418
419 extern "C" void LLVMRustPrintTargetFeatures(LLVMTargetMachineRef TM) {
420   const TargetMachine *Target = unwrap(TM);
421   const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
422   const ArrayRef<SubtargetFeatureKV> FeatTable = MCInfo->getFeatureTable();
423   unsigned MaxFeatLen = getLongestEntryLength(FeatTable);
424
425   printf("Available features for this target:\n");
426   for (auto &Feature : FeatTable)
427     printf("    %-*s - %s.\n", MaxFeatLen, Feature.Key, Feature.Desc);
428   printf("\nRust-specific features:\n");
429   printf("    %-*s - %s.\n",
430     MaxFeatLen,
431     "crt-static",
432     "Enables libraries with C Run-time Libraries(CRT) to be statically linked"
433   );
434   printf("\n");
435
436   printf("Use +feature to enable a feature, or -feature to disable it.\n"
437          "For example, rustc -C -target-cpu=mycpu -C "
438          "target-feature=+feature1,-feature2\n\n");
439 }
440
441 #else
442
443 extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef) {
444   printf("Target CPU help is not supported by this LLVM version.\n\n");
445 }
446
447 extern "C" void LLVMRustPrintTargetFeatures(LLVMTargetMachineRef) {
448   printf("Target features help is not supported by this LLVM version.\n\n");
449 }
450 #endif
451
452 extern "C" const char* LLVMRustGetHostCPUName(size_t *len) {
453   StringRef Name = sys::getHostCPUName();
454   *len = Name.size();
455   return Name.data();
456 }
457
458 extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
459     const char *TripleStr, const char *CPU, const char *Feature,
460     const char *ABIStr, LLVMRustCodeModel RustCM, LLVMRustRelocModel RustReloc,
461     LLVMRustCodeGenOptLevel RustOptLevel, bool UseSoftFloat,
462     bool FunctionSections,
463     bool DataSections,
464     bool TrapUnreachable,
465     bool Singlethread,
466     bool AsmComments,
467     bool EmitStackSizeSection,
468     bool RelaxELFRelocations,
469     bool UseInitArray) {
470
471   auto OptLevel = fromRust(RustOptLevel);
472   auto RM = fromRust(RustReloc);
473   auto CM = fromRust(RustCM);
474
475   std::string Error;
476   Triple Trip(Triple::normalize(TripleStr));
477   const llvm::Target *TheTarget =
478       TargetRegistry::lookupTarget(Trip.getTriple(), Error);
479   if (TheTarget == nullptr) {
480     LLVMRustSetLastError(Error.c_str());
481     return nullptr;
482   }
483
484   TargetOptions Options;
485
486   Options.FloatABIType = FloatABI::Default;
487   if (UseSoftFloat) {
488     Options.FloatABIType = FloatABI::Soft;
489   }
490   Options.DataSections = DataSections;
491   Options.FunctionSections = FunctionSections;
492   Options.MCOptions.AsmVerbose = AsmComments;
493   Options.MCOptions.PreserveAsmComments = AsmComments;
494   Options.MCOptions.ABIName = ABIStr;
495   Options.RelaxELFRelocations = RelaxELFRelocations;
496   Options.UseInitArray = UseInitArray;
497
498   if (TrapUnreachable) {
499     // Tell LLVM to codegen `unreachable` into an explicit trap instruction.
500     // This limits the extent of possible undefined behavior in some cases, as
501     // it prevents control flow from "falling through" into whatever code
502     // happens to be laid out next in memory.
503     Options.TrapUnreachable = true;
504   }
505
506   if (Singlethread) {
507     Options.ThreadModel = ThreadModel::Single;
508   }
509
510   Options.EmitStackSizeSection = EmitStackSizeSection;
511
512   TargetMachine *TM = TheTarget->createTargetMachine(
513       Trip.getTriple(), CPU, Feature, Options, RM, CM, OptLevel);
514   return wrap(TM);
515 }
516
517 extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) {
518   delete unwrap(TM);
519 }
520
521 extern "C" void LLVMRustConfigurePassManagerBuilder(
522     LLVMPassManagerBuilderRef PMBR, LLVMRustCodeGenOptLevel OptLevel,
523     bool MergeFunctions, bool SLPVectorize, bool LoopVectorize, bool PrepareForThinLTO,
524     const char* PGOGenPath, const char* PGOUsePath) {
525   unwrap(PMBR)->MergeFunctions = MergeFunctions;
526   unwrap(PMBR)->SLPVectorize = SLPVectorize;
527   unwrap(PMBR)->OptLevel = fromRust(OptLevel);
528   unwrap(PMBR)->LoopVectorize = LoopVectorize;
529   unwrap(PMBR)->PrepareForThinLTO = PrepareForThinLTO;
530
531   if (PGOGenPath) {
532     assert(!PGOUsePath);
533     unwrap(PMBR)->EnablePGOInstrGen = true;
534     unwrap(PMBR)->PGOInstrGen = PGOGenPath;
535   }
536   if (PGOUsePath) {
537     assert(!PGOGenPath);
538     unwrap(PMBR)->PGOInstrUse = PGOUsePath;
539   }
540 }
541
542 // Unfortunately, the LLVM C API doesn't provide a way to set the `LibraryInfo`
543 // field of a PassManagerBuilder, we expose our own method of doing so.
544 extern "C" void LLVMRustAddBuilderLibraryInfo(LLVMPassManagerBuilderRef PMBR,
545                                               LLVMModuleRef M,
546                                               bool DisableSimplifyLibCalls) {
547   Triple TargetTriple(unwrap(M)->getTargetTriple());
548   TargetLibraryInfoImpl *TLI = new TargetLibraryInfoImpl(TargetTriple);
549   if (DisableSimplifyLibCalls)
550     TLI->disableAllFunctions();
551   unwrap(PMBR)->LibraryInfo = TLI;
552 }
553
554 // Unfortunately, the LLVM C API doesn't provide a way to create the
555 // TargetLibraryInfo pass, so we use this method to do so.
556 extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR, LLVMModuleRef M,
557                                        bool DisableSimplifyLibCalls) {
558   Triple TargetTriple(unwrap(M)->getTargetTriple());
559   TargetLibraryInfoImpl TLII(TargetTriple);
560   if (DisableSimplifyLibCalls)
561     TLII.disableAllFunctions();
562   unwrap(PMR)->add(new TargetLibraryInfoWrapperPass(TLII));
563 }
564
565 // Unfortunately, the LLVM C API doesn't provide an easy way of iterating over
566 // all the functions in a module, so we do that manually here. You'll find
567 // similar code in clang's BackendUtil.cpp file.
568 extern "C" void LLVMRustRunFunctionPassManager(LLVMPassManagerRef PMR,
569                                                LLVMModuleRef M) {
570   llvm::legacy::FunctionPassManager *P =
571       unwrap<llvm::legacy::FunctionPassManager>(PMR);
572   P->doInitialization();
573
574   // Upgrade all calls to old intrinsics first.
575   for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E;)
576     UpgradeCallsToIntrinsic(&*I++); // must be post-increment, as we remove
577
578   for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E;
579        ++I)
580     if (!I->isDeclaration())
581       P->run(*I);
582
583   P->doFinalization();
584 }
585
586 extern "C" void LLVMRustSetLLVMOptions(int Argc, char **Argv) {
587   // Initializing the command-line options more than once is not allowed. So,
588   // check if they've already been initialized.  (This could happen if we're
589   // being called from rustpkg, for example). If the arguments change, then
590   // that's just kinda unfortunate.
591   static bool Initialized = false;
592   if (Initialized)
593     return;
594   Initialized = true;
595   cl::ParseCommandLineOptions(Argc, Argv);
596 }
597
598 enum class LLVMRustFileType {
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 #if LLVM_VERSION_GE(11, 0)
800   std::vector<std::function<void(ModulePassManager &, PassBuilder::OptimizationLevel)>>
801       OptimizerLastEPCallbacks;
802 #else
803   std::vector<std::function<void(FunctionPassManager &, PassBuilder::OptimizationLevel)>>
804       OptimizerLastEPCallbacks;
805 #endif
806
807   if (VerifyIR) {
808     PipelineStartEPCallbacks.push_back([VerifyIR](ModulePassManager &MPM) {
809         MPM.addPass(VerifierPass());
810     });
811   }
812
813   if (SanitizerOptions) {
814     if (SanitizerOptions->SanitizeMemory) {
815       MemorySanitizerOptions Options(
816           SanitizerOptions->SanitizeMemoryTrackOrigins,
817           SanitizerOptions->SanitizeMemoryRecover,
818           /*CompileKernel=*/false);
819 #if LLVM_VERSION_GE(11, 0)
820       OptimizerLastEPCallbacks.push_back(
821         [Options](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) {
822           MPM.addPass(MemorySanitizerPass(Options));
823           MPM.addPass(createModuleToFunctionPassAdaptor(MemorySanitizerPass(Options)));
824         }
825       );
826 #else
827 #if LLVM_VERSION_GE(10, 0)
828       PipelineStartEPCallbacks.push_back([Options](ModulePassManager &MPM) {
829         MPM.addPass(MemorySanitizerPass(Options));
830       });
831 #endif
832       OptimizerLastEPCallbacks.push_back(
833         [Options](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
834           FPM.addPass(MemorySanitizerPass(Options));
835         }
836       );
837 #endif
838     }
839
840     if (SanitizerOptions->SanitizeThread) {
841 #if LLVM_VERSION_GE(11, 0)
842       OptimizerLastEPCallbacks.push_back(
843         [](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) {
844           MPM.addPass(ThreadSanitizerPass());
845           MPM.addPass(createModuleToFunctionPassAdaptor(ThreadSanitizerPass()));
846         }
847       );
848 #else
849 #if LLVM_VERSION_GE(10, 0)
850       PipelineStartEPCallbacks.push_back([](ModulePassManager &MPM) {
851         MPM.addPass(ThreadSanitizerPass());
852       });
853 #endif
854       OptimizerLastEPCallbacks.push_back(
855         [](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
856           FPM.addPass(ThreadSanitizerPass());
857         }
858       );
859 #endif
860     }
861
862     if (SanitizerOptions->SanitizeAddress) {
863 #if LLVM_VERSION_GE(11, 0)
864       OptimizerLastEPCallbacks.push_back(
865         [SanitizerOptions](ModulePassManager &MPM, PassBuilder::OptimizationLevel Level) {
866           MPM.addPass(RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
867           MPM.addPass(ModuleAddressSanitizerPass(
868               /*CompileKernel=*/false, SanitizerOptions->SanitizeAddressRecover));
869           MPM.addPass(createModuleToFunctionPassAdaptor(AddressSanitizerPass(
870               /*CompileKernel=*/false, SanitizerOptions->SanitizeAddressRecover,
871               /*UseAfterScope=*/true)));
872         }
873       );
874 #else
875       PipelineStartEPCallbacks.push_back([&](ModulePassManager &MPM) {
876         MPM.addPass(RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
877       });
878       OptimizerLastEPCallbacks.push_back(
879         [SanitizerOptions](FunctionPassManager &FPM, PassBuilder::OptimizationLevel Level) {
880           FPM.addPass(AddressSanitizerPass(
881               /*CompileKernel=*/false, SanitizerOptions->SanitizeAddressRecover,
882               /*UseAfterScope=*/true));
883         }
884       );
885       PipelineStartEPCallbacks.push_back(
886         [SanitizerOptions](ModulePassManager &MPM) {
887           MPM.addPass(ModuleAddressSanitizerPass(
888               /*CompileKernel=*/false, SanitizerOptions->SanitizeAddressRecover));
889         }
890       );
891 #endif
892     }
893   }
894
895   ModulePassManager MPM(DebugPassManager);
896   if (!NoPrepopulatePasses) {
897     if (OptLevel == PassBuilder::OptimizationLevel::O0) {
898       for (const auto &C : PipelineStartEPCallbacks)
899         C(MPM);
900
901 #if LLVM_VERSION_GE(11, 0)
902       for (const auto &C : OptimizerLastEPCallbacks)
903         C(MPM, OptLevel);
904 #else
905       if (!OptimizerLastEPCallbacks.empty()) {
906         FunctionPassManager FPM(DebugPassManager);
907         for (const auto &C : OptimizerLastEPCallbacks)
908           C(FPM, OptLevel);
909         MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
910       }
911 #endif
912
913       MPM.addPass(AlwaysInlinerPass(EmitLifetimeMarkers));
914
915 #if LLVM_VERSION_GE(10, 0)
916       if (PGOOpt) {
917         PB.addPGOInstrPassesForO0(
918             MPM, DebugPassManager, PGOOpt->Action == PGOOptions::IRInstr,
919             /*IsCS=*/false, PGOOpt->ProfileFile, PGOOpt->ProfileRemappingFile);
920       }
921 #endif
922     } else {
923       for (const auto &C : PipelineStartEPCallbacks)
924         PB.registerPipelineStartEPCallback(C);
925       if (OptStage != LLVMRustOptStage::PreLinkThinLTO) {
926         for (const auto &C : OptimizerLastEPCallbacks)
927           PB.registerOptimizerLastEPCallback(C);
928       }
929
930       switch (OptStage) {
931       case LLVMRustOptStage::PreLinkNoLTO:
932         MPM = PB.buildPerModuleDefaultPipeline(OptLevel, DebugPassManager);
933         break;
934       case LLVMRustOptStage::PreLinkThinLTO:
935         MPM = PB.buildThinLTOPreLinkDefaultPipeline(OptLevel, DebugPassManager);
936 #if LLVM_VERSION_GE(11, 0)
937         for (const auto &C : OptimizerLastEPCallbacks)
938           C(MPM, OptLevel);
939 #else
940         if (!OptimizerLastEPCallbacks.empty()) {
941           FunctionPassManager FPM(DebugPassManager);
942           for (const auto &C : OptimizerLastEPCallbacks)
943             C(FPM, OptLevel);
944           MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
945         }
946 #endif
947         break;
948       case LLVMRustOptStage::PreLinkFatLTO:
949         MPM = PB.buildLTOPreLinkDefaultPipeline(OptLevel, DebugPassManager);
950         break;
951       case LLVMRustOptStage::ThinLTO:
952         // FIXME: Does it make sense to pass the ModuleSummaryIndex?
953         // It only seems to be needed for C++ specific optimizations.
954         MPM = PB.buildThinLTODefaultPipeline(OptLevel, DebugPassManager, nullptr);
955         break;
956       case LLVMRustOptStage::FatLTO:
957         MPM = PB.buildLTODefaultPipeline(OptLevel, DebugPassManager, nullptr);
958         break;
959       }
960     }
961   }
962
963   if (UseThinLTOBuffers) {
964     MPM.addPass(CanonicalizeAliasesPass());
965     MPM.addPass(NameAnonGlobalPass());
966   }
967
968   // Upgrade all calls to old intrinsics first.
969   for (Module::iterator I = TheModule->begin(), E = TheModule->end(); I != E;)
970     UpgradeCallsToIntrinsic(&*I++); // must be post-increment, as we remove
971
972   MPM.run(*TheModule, MAM);
973 #else
974   // The new pass manager has been available for a long time,
975   // but we don't bother supporting it on old LLVM versions.
976   report_fatal_error("New pass manager only supported since LLVM 9");
977 #endif
978 }
979
980 // Callback to demangle function name
981 // Parameters:
982 // * name to be demangled
983 // * name len
984 // * output buffer
985 // * output buffer len
986 // Returns len of demangled string, or 0 if demangle failed.
987 typedef size_t (*DemangleFn)(const char*, size_t, char*, size_t);
988
989
990 namespace {
991
992 class RustAssemblyAnnotationWriter : public AssemblyAnnotationWriter {
993   DemangleFn Demangle;
994   std::vector<char> Buf;
995
996 public:
997   RustAssemblyAnnotationWriter(DemangleFn Demangle) : Demangle(Demangle) {}
998
999   // Return empty string if demangle failed
1000   // or if name does not need to be demangled
1001   StringRef CallDemangle(StringRef name) {
1002     if (!Demangle) {
1003       return StringRef();
1004     }
1005
1006     if (Buf.size() < name.size() * 2) {
1007       // Semangled name usually shorter than mangled,
1008       // but allocate twice as much memory just in case
1009       Buf.resize(name.size() * 2);
1010     }
1011
1012     auto R = Demangle(name.data(), name.size(), Buf.data(), Buf.size());
1013     if (!R) {
1014       // Demangle failed.
1015       return StringRef();
1016     }
1017
1018     auto Demangled = StringRef(Buf.data(), R);
1019     if (Demangled == name) {
1020       // Do not print anything if demangled name is equal to mangled.
1021       return StringRef();
1022     }
1023
1024     return Demangled;
1025   }
1026
1027   void emitFunctionAnnot(const Function *F,
1028                          formatted_raw_ostream &OS) override {
1029     StringRef Demangled = CallDemangle(F->getName());
1030     if (Demangled.empty()) {
1031         return;
1032     }
1033
1034     OS << "; " << Demangled << "\n";
1035   }
1036
1037   void emitInstructionAnnot(const Instruction *I,
1038                             formatted_raw_ostream &OS) override {
1039     const char *Name;
1040     const Value *Value;
1041     if (const CallInst *CI = dyn_cast<CallInst>(I)) {
1042       Name = "call";
1043       Value = CI->getCalledOperand();
1044     } else if (const InvokeInst* II = dyn_cast<InvokeInst>(I)) {
1045       Name = "invoke";
1046       Value = II->getCalledOperand();
1047     } else {
1048       // Could demangle more operations, e. g.
1049       // `store %place, @function`.
1050       return;
1051     }
1052
1053     if (!Value->hasName()) {
1054       return;
1055     }
1056
1057     StringRef Demangled = CallDemangle(Value->getName());
1058     if (Demangled.empty()) {
1059       return;
1060     }
1061
1062     OS << "; " << Name << " " << Demangled << "\n";
1063   }
1064 };
1065
1066 } // namespace
1067
1068 extern "C" LLVMRustResult
1069 LLVMRustPrintModule(LLVMModuleRef M, const char *Path, DemangleFn Demangle) {
1070   std::string ErrorInfo;
1071   std::error_code EC;
1072   raw_fd_ostream OS(Path, EC, sys::fs::F_None);
1073   if (EC)
1074     ErrorInfo = EC.message();
1075   if (ErrorInfo != "") {
1076     LLVMRustSetLastError(ErrorInfo.c_str());
1077     return LLVMRustResult::Failure;
1078   }
1079
1080   RustAssemblyAnnotationWriter AAW(Demangle);
1081   formatted_raw_ostream FOS(OS);
1082   unwrap(M)->print(FOS, &AAW);
1083
1084   return LLVMRustResult::Success;
1085 }
1086
1087 extern "C" void LLVMRustPrintPasses() {
1088   LLVMInitializePasses();
1089   struct MyListener : PassRegistrationListener {
1090     void passEnumerate(const PassInfo *Info) {
1091       StringRef PassArg = Info->getPassArgument();
1092       StringRef PassName = Info->getPassName();
1093       if (!PassArg.empty()) {
1094         // These unsigned->signed casts could theoretically overflow, but
1095         // realistically never will (and even if, the result is implementation
1096         // defined rather plain UB).
1097         printf("%15.*s - %.*s\n", (int)PassArg.size(), PassArg.data(),
1098                (int)PassName.size(), PassName.data());
1099       }
1100     }
1101   } Listener;
1102
1103   PassRegistry *PR = PassRegistry::getPassRegistry();
1104   PR->enumerateWith(&Listener);
1105 }
1106
1107 extern "C" void LLVMRustAddAlwaysInlinePass(LLVMPassManagerBuilderRef PMBR,
1108                                             bool AddLifetimes) {
1109   unwrap(PMBR)->Inliner = llvm::createAlwaysInlinerLegacyPass(AddLifetimes);
1110 }
1111
1112 extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **Symbols,
1113                                            size_t Len) {
1114   llvm::legacy::PassManager passes;
1115
1116   auto PreserveFunctions = [=](const GlobalValue &GV) {
1117     for (size_t I = 0; I < Len; I++) {
1118       if (GV.getName() == Symbols[I]) {
1119         return true;
1120       }
1121     }
1122     return false;
1123   };
1124
1125   passes.add(llvm::createInternalizePass(PreserveFunctions));
1126
1127   passes.run(*unwrap(M));
1128 }
1129
1130 extern "C" void LLVMRustMarkAllFunctionsNounwind(LLVMModuleRef M) {
1131   for (Module::iterator GV = unwrap(M)->begin(), E = unwrap(M)->end(); GV != E;
1132        ++GV) {
1133     GV->setDoesNotThrow();
1134     Function *F = dyn_cast<Function>(GV);
1135     if (F == nullptr)
1136       continue;
1137
1138     for (Function::iterator B = F->begin(), BE = F->end(); B != BE; ++B) {
1139       for (BasicBlock::iterator I = B->begin(), IE = B->end(); I != IE; ++I) {
1140         if (isa<InvokeInst>(I)) {
1141           InvokeInst *CI = cast<InvokeInst>(I);
1142           CI->setDoesNotThrow();
1143         }
1144       }
1145     }
1146   }
1147 }
1148
1149 extern "C" void
1150 LLVMRustSetDataLayoutFromTargetMachine(LLVMModuleRef Module,
1151                                        LLVMTargetMachineRef TMR) {
1152   TargetMachine *Target = unwrap(TMR);
1153   unwrap(Module)->setDataLayout(Target->createDataLayout());
1154 }
1155
1156 extern "C" void LLVMRustSetModulePICLevel(LLVMModuleRef M) {
1157   unwrap(M)->setPICLevel(PICLevel::Level::BigPIC);
1158 }
1159
1160 extern "C" void LLVMRustSetModulePIELevel(LLVMModuleRef M) {
1161   unwrap(M)->setPIELevel(PIELevel::Level::Large);
1162 }
1163
1164 // Here you'll find an implementation of ThinLTO as used by the Rust compiler
1165 // right now. This ThinLTO support is only enabled on "recent ish" versions of
1166 // LLVM, and otherwise it's just blanket rejected from other compilers.
1167 //
1168 // Most of this implementation is straight copied from LLVM. At the time of
1169 // this writing it wasn't *quite* suitable to reuse more code from upstream
1170 // for our purposes, but we should strive to upstream this support once it's
1171 // ready to go! I figure we may want a bit of testing locally first before
1172 // sending this upstream to LLVM. I hear though they're quite eager to receive
1173 // feedback like this!
1174 //
1175 // If you're reading this code and wondering "what in the world" or you're
1176 // working "good lord by LLVM upgrade is *still* failing due to these bindings"
1177 // then fear not! (ok maybe fear a little). All code here is mostly based
1178 // on `lib/LTO/ThinLTOCodeGenerator.cpp` in LLVM.
1179 //
1180 // You'll find that the general layout here roughly corresponds to the `run`
1181 // method in that file as well as `ProcessThinLTOModule`. Functions are
1182 // specifically commented below as well, but if you're updating this code
1183 // or otherwise trying to understand it, the LLVM source will be useful in
1184 // interpreting the mysteries within.
1185 //
1186 // Otherwise I'll apologize in advance, it probably requires a relatively
1187 // significant investment on your part to "truly understand" what's going on
1188 // here. Not saying I do myself, but it took me awhile staring at LLVM's source
1189 // and various online resources about ThinLTO to make heads or tails of all
1190 // this.
1191
1192 // This is a shared data structure which *must* be threadsafe to share
1193 // read-only amongst threads. This also corresponds basically to the arguments
1194 // of the `ProcessThinLTOModule` function in the LLVM source.
1195 struct LLVMRustThinLTOData {
1196   // The combined index that is the global analysis over all modules we're
1197   // performing ThinLTO for. This is mostly managed by LLVM.
1198   ModuleSummaryIndex Index;
1199
1200   // All modules we may look at, stored as in-memory serialized versions. This
1201   // is later used when inlining to ensure we can extract any module to inline
1202   // from.
1203   StringMap<MemoryBufferRef> ModuleMap;
1204
1205   // A set that we manage of everything we *don't* want internalized. Note that
1206   // this includes all transitive references right now as well, but it may not
1207   // always!
1208   DenseSet<GlobalValue::GUID> GUIDPreservedSymbols;
1209
1210   // Not 100% sure what these are, but they impact what's internalized and
1211   // what's inlined across modules, I believe.
1212   StringMap<FunctionImporter::ImportMapTy> ImportLists;
1213   StringMap<FunctionImporter::ExportSetTy> ExportLists;
1214   StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries;
1215
1216   LLVMRustThinLTOData() : Index(/* HaveGVs = */ false) {}
1217 };
1218
1219 // Just an argument to the `LLVMRustCreateThinLTOData` function below.
1220 struct LLVMRustThinLTOModule {
1221   const char *identifier;
1222   const char *data;
1223   size_t len;
1224 };
1225
1226 // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp`, not sure what it
1227 // does.
1228 static const GlobalValueSummary *
1229 getFirstDefinitionForLinker(const GlobalValueSummaryList &GVSummaryList) {
1230   auto StrongDefForLinker = llvm::find_if(
1231       GVSummaryList, [](const std::unique_ptr<GlobalValueSummary> &Summary) {
1232         auto Linkage = Summary->linkage();
1233         return !GlobalValue::isAvailableExternallyLinkage(Linkage) &&
1234                !GlobalValue::isWeakForLinker(Linkage);
1235       });
1236   if (StrongDefForLinker != GVSummaryList.end())
1237     return StrongDefForLinker->get();
1238
1239   auto FirstDefForLinker = llvm::find_if(
1240       GVSummaryList, [](const std::unique_ptr<GlobalValueSummary> &Summary) {
1241         auto Linkage = Summary->linkage();
1242         return !GlobalValue::isAvailableExternallyLinkage(Linkage);
1243       });
1244   if (FirstDefForLinker == GVSummaryList.end())
1245     return nullptr;
1246   return FirstDefForLinker->get();
1247 }
1248
1249 // The main entry point for creating the global ThinLTO analysis. The structure
1250 // here is basically the same as before threads are spawned in the `run`
1251 // function of `lib/LTO/ThinLTOCodeGenerator.cpp`.
1252 extern "C" LLVMRustThinLTOData*
1253 LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
1254                           int num_modules,
1255                           const char **preserved_symbols,
1256                           int num_symbols) {
1257 #if LLVM_VERSION_GE(10, 0)
1258   auto Ret = std::make_unique<LLVMRustThinLTOData>();
1259 #else
1260   auto Ret = llvm::make_unique<LLVMRustThinLTOData>();
1261 #endif
1262
1263   // Load each module's summary and merge it into one combined index
1264   for (int i = 0; i < num_modules; i++) {
1265     auto module = &modules[i];
1266     StringRef buffer(module->data, module->len);
1267     MemoryBufferRef mem_buffer(buffer, module->identifier);
1268
1269     Ret->ModuleMap[module->identifier] = mem_buffer;
1270
1271     if (Error Err = readModuleSummaryIndex(mem_buffer, Ret->Index, i)) {
1272       LLVMRustSetLastError(toString(std::move(Err)).c_str());
1273       return nullptr;
1274     }
1275   }
1276
1277   // Collect for each module the list of function it defines (GUID -> Summary)
1278   Ret->Index.collectDefinedGVSummariesPerModule(Ret->ModuleToDefinedGVSummaries);
1279
1280   // Convert the preserved symbols set from string to GUID, this is then needed
1281   // for internalization.
1282   for (int i = 0; i < num_symbols; i++) {
1283     auto GUID = GlobalValue::getGUID(preserved_symbols[i]);
1284     Ret->GUIDPreservedSymbols.insert(GUID);
1285   }
1286
1287   // Collect the import/export lists for all modules from the call-graph in the
1288   // combined index
1289   //
1290   // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp`
1291   auto deadIsPrevailing = [&](GlobalValue::GUID G) {
1292     return PrevailingType::Unknown;
1293   };
1294   // We don't have a complete picture in our use of ThinLTO, just our immediate
1295   // crate, so we need `ImportEnabled = false` to limit internalization.
1296   // Otherwise, we sometimes lose `static` values -- see #60184.
1297   computeDeadSymbolsWithConstProp(Ret->Index, Ret->GUIDPreservedSymbols,
1298                                   deadIsPrevailing, /* ImportEnabled = */ false);
1299   ComputeCrossModuleImport(
1300     Ret->Index,
1301     Ret->ModuleToDefinedGVSummaries,
1302     Ret->ImportLists,
1303     Ret->ExportLists
1304   );
1305
1306   // Resolve LinkOnce/Weak symbols, this has to be computed early be cause it
1307   // impacts the caching.
1308   //
1309   // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp` with some of this
1310   // being lifted from `lib/LTO/LTO.cpp` as well
1311   StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
1312   DenseMap<GlobalValue::GUID, const GlobalValueSummary *> PrevailingCopy;
1313   for (auto &I : Ret->Index) {
1314     if (I.second.SummaryList.size() > 1)
1315       PrevailingCopy[I.first] = getFirstDefinitionForLinker(I.second.SummaryList);
1316   }
1317   auto isPrevailing = [&](GlobalValue::GUID GUID, const GlobalValueSummary *S) {
1318     const auto &Prevailing = PrevailingCopy.find(GUID);
1319     if (Prevailing == PrevailingCopy.end())
1320       return true;
1321     return Prevailing->second == S;
1322   };
1323   auto recordNewLinkage = [&](StringRef ModuleIdentifier,
1324                               GlobalValue::GUID GUID,
1325                               GlobalValue::LinkageTypes NewLinkage) {
1326     ResolvedODR[ModuleIdentifier][GUID] = NewLinkage;
1327   };
1328 #if LLVM_VERSION_GE(9, 0)
1329   thinLTOResolvePrevailingInIndex(Ret->Index, isPrevailing, recordNewLinkage,
1330                                   Ret->GUIDPreservedSymbols);
1331 #else
1332   thinLTOResolvePrevailingInIndex(Ret->Index, isPrevailing, recordNewLinkage);
1333 #endif
1334
1335   // Here we calculate an `ExportedGUIDs` set for use in the `isExported`
1336   // callback below. This callback below will dictate the linkage for all
1337   // summaries in the index, and we basically just only want to ensure that dead
1338   // symbols are internalized. Otherwise everything that's already external
1339   // linkage will stay as external, and internal will stay as internal.
1340   std::set<GlobalValue::GUID> ExportedGUIDs;
1341   for (auto &List : Ret->Index) {
1342     for (auto &GVS: List.second.SummaryList) {
1343       if (GlobalValue::isLocalLinkage(GVS->linkage()))
1344         continue;
1345       auto GUID = GVS->getOriginalName();
1346       if (GVS->flags().Live)
1347         ExportedGUIDs.insert(GUID);
1348     }
1349   }
1350 #if LLVM_VERSION_GE(10, 0)
1351   auto isExported = [&](StringRef ModuleIdentifier, ValueInfo VI) {
1352     const auto &ExportList = Ret->ExportLists.find(ModuleIdentifier);
1353     return (ExportList != Ret->ExportLists.end() &&
1354       ExportList->second.count(VI)) ||
1355       ExportedGUIDs.count(VI.getGUID());
1356   };
1357   thinLTOInternalizeAndPromoteInIndex(Ret->Index, isExported, isPrevailing);
1358 #else
1359   auto isExported = [&](StringRef ModuleIdentifier, GlobalValue::GUID GUID) {
1360     const auto &ExportList = Ret->ExportLists.find(ModuleIdentifier);
1361     return (ExportList != Ret->ExportLists.end() &&
1362       ExportList->second.count(GUID)) ||
1363       ExportedGUIDs.count(GUID);
1364   };
1365   thinLTOInternalizeAndPromoteInIndex(Ret->Index, isExported);
1366 #endif
1367
1368   return Ret.release();
1369 }
1370
1371 extern "C" void
1372 LLVMRustFreeThinLTOData(LLVMRustThinLTOData *Data) {
1373   delete Data;
1374 }
1375
1376 // Below are the various passes that happen *per module* when doing ThinLTO.
1377 //
1378 // In other words, these are the functions that are all run concurrently
1379 // with one another, one per module. The passes here correspond to the analysis
1380 // passes in `lib/LTO/ThinLTOCodeGenerator.cpp`, currently found in the
1381 // `ProcessThinLTOModule` function. Here they're split up into separate steps
1382 // so rustc can save off the intermediate bytecode between each step.
1383
1384 #if LLVM_VERSION_GE(11, 0)
1385 static bool
1386 clearDSOLocalOnDeclarations(Module &Mod, TargetMachine &TM) {
1387   // When linking an ELF shared object, dso_local should be dropped. We
1388   // conservatively do this for -fpic.
1389   bool ClearDSOLocalOnDeclarations =
1390       TM.getTargetTriple().isOSBinFormatELF() &&
1391       TM.getRelocationModel() != Reloc::Static &&
1392       Mod.getPIELevel() == PIELevel::Default;
1393   return ClearDSOLocalOnDeclarations;
1394 }
1395 #endif
1396
1397 extern "C" bool
1398 LLVMRustPrepareThinLTORename(const LLVMRustThinLTOData *Data, LLVMModuleRef M,
1399                              LLVMTargetMachineRef TM) {
1400   Module &Mod = *unwrap(M);
1401   TargetMachine &Target = *unwrap(TM);
1402
1403 #if LLVM_VERSION_GE(11, 0)
1404   bool ClearDSOLocal = clearDSOLocalOnDeclarations(Mod, Target);
1405   bool error = renameModuleForThinLTO(Mod, Data->Index, ClearDSOLocal);
1406 #else
1407   bool error = renameModuleForThinLTO(Mod, Data->Index);
1408 #endif
1409
1410   if (error) {
1411     LLVMRustSetLastError("renameModuleForThinLTO failed");
1412     return false;
1413   }
1414   return true;
1415 }
1416
1417 extern "C" bool
1418 LLVMRustPrepareThinLTOResolveWeak(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
1419   Module &Mod = *unwrap(M);
1420   const auto &DefinedGlobals = Data->ModuleToDefinedGVSummaries.lookup(Mod.getModuleIdentifier());
1421   thinLTOResolvePrevailingInModule(Mod, DefinedGlobals);
1422   return true;
1423 }
1424
1425 extern "C" bool
1426 LLVMRustPrepareThinLTOInternalize(const LLVMRustThinLTOData *Data, LLVMModuleRef M) {
1427   Module &Mod = *unwrap(M);
1428   const auto &DefinedGlobals = Data->ModuleToDefinedGVSummaries.lookup(Mod.getModuleIdentifier());
1429   thinLTOInternalizeModule(Mod, DefinedGlobals);
1430   return true;
1431 }
1432
1433 extern "C" bool
1434 LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data, LLVMModuleRef M,
1435                              LLVMTargetMachineRef TM) {
1436   Module &Mod = *unwrap(M);
1437   TargetMachine &Target = *unwrap(TM);
1438
1439   const auto &ImportList = Data->ImportLists.lookup(Mod.getModuleIdentifier());
1440   auto Loader = [&](StringRef Identifier) {
1441     const auto &Memory = Data->ModuleMap.lookup(Identifier);
1442     auto &Context = Mod.getContext();
1443     auto MOrErr = getLazyBitcodeModule(Memory, Context, true, true);
1444
1445     if (!MOrErr)
1446       return MOrErr;
1447
1448     // The rest of this closure is a workaround for
1449     // https://bugs.llvm.org/show_bug.cgi?id=38184 where during ThinLTO imports
1450     // we accidentally import wasm custom sections into different modules,
1451     // duplicating them by in the final output artifact.
1452     //
1453     // The issue is worked around here by manually removing the
1454     // `wasm.custom_sections` named metadata node from any imported module. This
1455     // we know isn't used by any optimization pass so there's no need for it to
1456     // be imported.
1457     //
1458     // Note that the metadata is currently lazily loaded, so we materialize it
1459     // here before looking up if there's metadata inside. The `FunctionImporter`
1460     // will immediately materialize metadata anyway after an import, so this
1461     // shouldn't be a perf hit.
1462     if (Error Err = (*MOrErr)->materializeMetadata()) {
1463       Expected<std::unique_ptr<Module>> Ret(std::move(Err));
1464       return Ret;
1465     }
1466
1467     auto *WasmCustomSections = (*MOrErr)->getNamedMetadata("wasm.custom_sections");
1468     if (WasmCustomSections)
1469       WasmCustomSections->eraseFromParent();
1470
1471     return MOrErr;
1472   };
1473 #if LLVM_VERSION_GE(11, 0)
1474   bool ClearDSOLocal = clearDSOLocalOnDeclarations(Mod, Target);
1475   FunctionImporter Importer(Data->Index, Loader, ClearDSOLocal);
1476 #else
1477   FunctionImporter Importer(Data->Index, Loader);
1478 #endif
1479   Expected<bool> Result = Importer.importFunctions(Mod, ImportList);
1480   if (!Result) {
1481     LLVMRustSetLastError(toString(Result.takeError()).c_str());
1482     return false;
1483   }
1484   return true;
1485 }
1486
1487 extern "C" typedef void (*LLVMRustModuleNameCallback)(void*, // payload
1488                                                       const char*, // importing module name
1489                                                       const char*); // imported module name
1490
1491 // Calls `module_name_callback` for each module import done by ThinLTO.
1492 // The callback is provided with regular null-terminated C strings.
1493 extern "C" void
1494 LLVMRustGetThinLTOModuleImports(const LLVMRustThinLTOData *data,
1495                                 LLVMRustModuleNameCallback module_name_callback,
1496                                 void* callback_payload) {
1497   for (const auto& importing_module : data->ImportLists) {
1498     const std::string importing_module_id = importing_module.getKey().str();
1499     const auto& imports = importing_module.getValue();
1500     for (const auto& imported_module : imports) {
1501       const std::string imported_module_id = imported_module.getKey().str();
1502       module_name_callback(callback_payload,
1503                            importing_module_id.c_str(),
1504                            imported_module_id.c_str());
1505     }
1506   }
1507 }
1508
1509 // This struct and various functions are sort of a hack right now, but the
1510 // problem is that we've got in-memory LLVM modules after we generate and
1511 // optimize all codegen-units for one compilation in rustc. To be compatible
1512 // with the LTO support above we need to serialize the modules plus their
1513 // ThinLTO summary into memory.
1514 //
1515 // This structure is basically an owned version of a serialize module, with
1516 // a ThinLTO summary attached.
1517 struct LLVMRustThinLTOBuffer {
1518   std::string data;
1519 };
1520
1521 extern "C" LLVMRustThinLTOBuffer*
1522 LLVMRustThinLTOBufferCreate(LLVMModuleRef M) {
1523 #if LLVM_VERSION_GE(10, 0)
1524   auto Ret = std::make_unique<LLVMRustThinLTOBuffer>();
1525 #else
1526   auto Ret = llvm::make_unique<LLVMRustThinLTOBuffer>();
1527 #endif
1528   {
1529     raw_string_ostream OS(Ret->data);
1530     {
1531       legacy::PassManager PM;
1532       PM.add(createWriteThinLTOBitcodePass(OS));
1533       PM.run(*unwrap(M));
1534     }
1535   }
1536   return Ret.release();
1537 }
1538
1539 extern "C" void
1540 LLVMRustThinLTOBufferFree(LLVMRustThinLTOBuffer *Buffer) {
1541   delete Buffer;
1542 }
1543
1544 extern "C" const void*
1545 LLVMRustThinLTOBufferPtr(const LLVMRustThinLTOBuffer *Buffer) {
1546   return Buffer->data.data();
1547 }
1548
1549 extern "C" size_t
1550 LLVMRustThinLTOBufferLen(const LLVMRustThinLTOBuffer *Buffer) {
1551   return Buffer->data.length();
1552 }
1553
1554 // This is what we used to parse upstream bitcode for actual ThinLTO
1555 // processing.  We'll call this once per module optimized through ThinLTO, and
1556 // it'll be called concurrently on many threads.
1557 extern "C" LLVMModuleRef
1558 LLVMRustParseBitcodeForLTO(LLVMContextRef Context,
1559                            const char *data,
1560                            size_t len,
1561                            const char *identifier) {
1562   StringRef Data(data, len);
1563   MemoryBufferRef Buffer(Data, identifier);
1564   unwrap(Context)->enableDebugTypeODRUniquing();
1565   Expected<std::unique_ptr<Module>> SrcOrError =
1566       parseBitcodeFile(Buffer, *unwrap(Context));
1567   if (!SrcOrError) {
1568     LLVMRustSetLastError(toString(SrcOrError.takeError()).c_str());
1569     return nullptr;
1570   }
1571   return wrap(std::move(*SrcOrError).release());
1572 }
1573
1574 // Find the bitcode section in the object file data and return it as a slice.
1575 // Fail if the bitcode section is present but empty.
1576 //
1577 // On success, the return value is the pointer to the start of the slice and
1578 // `out_len` is filled with the (non-zero) length. On failure, the return value
1579 // is `nullptr` and `out_len` is set to zero.
1580 extern "C" const char*
1581 LLVMRustGetBitcodeSliceFromObjectData(const char *data,
1582                                       size_t len,
1583                                       size_t *out_len) {
1584   *out_len = 0;
1585
1586   StringRef Data(data, len);
1587   MemoryBufferRef Buffer(Data, ""); // The id is unused.
1588
1589   Expected<MemoryBufferRef> BitcodeOrError =
1590     object::IRObjectFile::findBitcodeInMemBuffer(Buffer);
1591   if (!BitcodeOrError) {
1592     LLVMRustSetLastError(toString(BitcodeOrError.takeError()).c_str());
1593     return nullptr;
1594   }
1595
1596   *out_len = BitcodeOrError->getBufferSize();
1597   return BitcodeOrError->getBufferStart();
1598 }
1599
1600 // Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
1601 // the comment in `back/lto.rs` for why this exists.
1602 extern "C" void
1603 LLVMRustThinLTOGetDICompileUnit(LLVMModuleRef Mod,
1604                                 DICompileUnit **A,
1605                                 DICompileUnit **B) {
1606   Module *M = unwrap(Mod);
1607   DICompileUnit **Cur = A;
1608   DICompileUnit **Next = B;
1609   for (DICompileUnit *CU : M->debug_compile_units()) {
1610     *Cur = CU;
1611     Cur = Next;
1612     Next = nullptr;
1613     if (Cur == nullptr)
1614       break;
1615   }
1616 }
1617
1618 // Rewrite all `DICompileUnit` pointers to the `DICompileUnit` specified. See
1619 // the comment in `back/lto.rs` for why this exists.
1620 extern "C" void
1621 LLVMRustThinLTOPatchDICompileUnit(LLVMModuleRef Mod, DICompileUnit *Unit) {
1622   Module *M = unwrap(Mod);
1623
1624   // If the original source module didn't have a `DICompileUnit` then try to
1625   // merge all the existing compile units. If there aren't actually any though
1626   // then there's not much for us to do so return.
1627   if (Unit == nullptr) {
1628     for (DICompileUnit *CU : M->debug_compile_units()) {
1629       Unit = CU;
1630       break;
1631     }
1632     if (Unit == nullptr)
1633       return;
1634   }
1635
1636   // Use LLVM's built-in `DebugInfoFinder` to find a bunch of debuginfo and
1637   // process it recursively. Note that we used to specifically iterate over
1638   // instructions to ensure we feed everything into it, but `processModule`
1639   // started doing this the same way in LLVM 7 (commit d769eb36ab2b8).
1640   DebugInfoFinder Finder;
1641   Finder.processModule(*M);
1642
1643   // After we've found all our debuginfo, rewrite all subprograms to point to
1644   // the same `DICompileUnit`.
1645   for (auto &F : Finder.subprograms()) {
1646     F->replaceUnit(Unit);
1647   }
1648
1649   // Erase any other references to other `DICompileUnit` instances, the verifier
1650   // will later ensure that we don't actually have any other stale references to
1651   // worry about.
1652   auto *MD = M->getNamedMetadata("llvm.dbg.cu");
1653   MD->clearOperands();
1654   MD->addOperand(Unit);
1655 }