]> git.proxmox.com Git - rustc.git/blob - src/rustllvm/PassWrapper.cpp
New upstream version 1.20.0+dfsg1
[rustc.git] / src / rustllvm / PassWrapper.cpp
1 // Copyright 2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 #include <stdio.h>
12
13 #include <vector>
14
15 #include "rustllvm.h"
16
17 #include "llvm/Analysis/TargetLibraryInfo.h"
18 #include "llvm/Analysis/TargetTransformInfo.h"
19 #include "llvm/IR/AutoUpgrade.h"
20 #include "llvm/IR/AssemblyAnnotationWriter.h"
21 #include "llvm/Support/CBindingWrapping.h"
22 #include "llvm/Support/FileSystem.h"
23 #include "llvm/Support/Host.h"
24 #include "llvm/Target/TargetMachine.h"
25 #include "llvm/Target/TargetSubtargetInfo.h"
26 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
27
28 #if LLVM_VERSION_GE(4, 0)
29 #include "llvm/Transforms/IPO/AlwaysInliner.h"
30 #endif
31
32 #include "llvm-c/Transforms/PassManagerBuilder.h"
33
34 using namespace llvm;
35 using namespace llvm::legacy;
36
37 extern cl::opt<bool> EnableARMEHABI;
38
39 typedef struct LLVMOpaquePass *LLVMPassRef;
40 typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef;
41
42 DEFINE_STDCXX_CONVERSION_FUNCTIONS(Pass, LLVMPassRef)
43 DEFINE_STDCXX_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
44 DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassManagerBuilder,
45 LLVMPassManagerBuilderRef)
46
47 extern "C" void LLVMInitializePasses() {
48 PassRegistry &Registry = *PassRegistry::getPassRegistry();
49 initializeCore(Registry);
50 initializeCodeGen(Registry);
51 initializeScalarOpts(Registry);
52 initializeVectorization(Registry);
53 initializeIPO(Registry);
54 initializeAnalysis(Registry);
55 #if LLVM_VERSION_EQ(3, 7)
56 initializeIPA(Registry);
57 #endif
58 initializeTransformUtils(Registry);
59 initializeInstCombine(Registry);
60 initializeInstrumentation(Registry);
61 initializeTarget(Registry);
62 }
63
64 enum class LLVMRustPassKind {
65 Other,
66 Function,
67 Module,
68 };
69
70 static LLVMRustPassKind toRust(PassKind Kind) {
71 switch (Kind) {
72 case PT_Function:
73 return LLVMRustPassKind::Function;
74 case PT_Module:
75 return LLVMRustPassKind::Module;
76 default:
77 return LLVMRustPassKind::Other;
78 }
79 }
80
81 extern "C" LLVMPassRef LLVMRustFindAndCreatePass(const char *PassName) {
82 StringRef SR(PassName);
83 PassRegistry *PR = PassRegistry::getPassRegistry();
84
85 const PassInfo *PI = PR->getPassInfo(SR);
86 if (PI) {
87 return wrap(PI->createPass());
88 }
89 return nullptr;
90 }
91
92 extern "C" LLVMRustPassKind LLVMRustPassKind(LLVMPassRef RustPass) {
93 assert(RustPass);
94 Pass *Pass = unwrap(RustPass);
95 return toRust(Pass->getPassKind());
96 }
97
98 extern "C" void LLVMRustAddPass(LLVMPassManagerRef PMR, LLVMPassRef RustPass) {
99 assert(RustPass);
100 Pass *Pass = unwrap(RustPass);
101 PassManagerBase *PMB = unwrap(PMR);
102 PMB->add(Pass);
103 }
104
105 #ifdef LLVM_COMPONENT_X86
106 #define SUBTARGET_X86 SUBTARGET(X86)
107 #else
108 #define SUBTARGET_X86
109 #endif
110
111 #ifdef LLVM_COMPONENT_ARM
112 #define SUBTARGET_ARM SUBTARGET(ARM)
113 #else
114 #define SUBTARGET_ARM
115 #endif
116
117 #ifdef LLVM_COMPONENT_AARCH64
118 #define SUBTARGET_AARCH64 SUBTARGET(AArch64)
119 #else
120 #define SUBTARGET_AARCH64
121 #endif
122
123 #ifdef LLVM_COMPONENT_MIPS
124 #define SUBTARGET_MIPS SUBTARGET(Mips)
125 #else
126 #define SUBTARGET_MIPS
127 #endif
128
129 #ifdef LLVM_COMPONENT_POWERPC
130 #define SUBTARGET_PPC SUBTARGET(PPC)
131 #else
132 #define SUBTARGET_PPC
133 #endif
134
135 #ifdef LLVM_COMPONENT_SYSTEMZ
136 #define SUBTARGET_SYSTEMZ SUBTARGET(SystemZ)
137 #else
138 #define SUBTARGET_SYSTEMZ
139 #endif
140
141 #ifdef LLVM_COMPONENT_MSP430
142 #define SUBTARGET_MSP430 SUBTARGET(MSP430)
143 #else
144 #define SUBTARGET_MSP430
145 #endif
146
147 #ifdef LLVM_COMPONENT_SPARC
148 #define SUBTARGET_SPARC SUBTARGET(Sparc)
149 #else
150 #define SUBTARGET_SPARC
151 #endif
152
153 #ifdef LLVM_COMPONENT_HEXAGON
154 #define SUBTARGET_HEXAGON SUBTARGET(Hexagon)
155 #else
156 #define SUBTARGET_HEXAGON
157 #endif
158
159 #define GEN_SUBTARGETS \
160 SUBTARGET_X86 \
161 SUBTARGET_ARM \
162 SUBTARGET_AARCH64 \
163 SUBTARGET_MIPS \
164 SUBTARGET_PPC \
165 SUBTARGET_SYSTEMZ \
166 SUBTARGET_MSP430 \
167 SUBTARGET_SPARC \
168 SUBTARGET_HEXAGON
169
170 #define SUBTARGET(x) \
171 namespace llvm { \
172 extern const SubtargetFeatureKV x##FeatureKV[]; \
173 extern const SubtargetFeatureKV x##SubTypeKV[]; \
174 }
175
176 GEN_SUBTARGETS
177 #undef SUBTARGET
178
179 extern "C" bool LLVMRustHasFeature(LLVMTargetMachineRef TM,
180 const char *Feature) {
181 TargetMachine *Target = unwrap(TM);
182 const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
183 const FeatureBitset &Bits = MCInfo->getFeatureBits();
184 const llvm::SubtargetFeatureKV *FeatureEntry;
185
186 #define SUBTARGET(x) \
187 if (MCInfo->isCPUStringValid(x##SubTypeKV[0].Key)) { \
188 FeatureEntry = x##FeatureKV; \
189 } else
190
191 GEN_SUBTARGETS { return false; }
192 #undef SUBTARGET
193
194 while (strcmp(Feature, FeatureEntry->Key) != 0)
195 FeatureEntry++;
196
197 return (Bits & FeatureEntry->Value) == FeatureEntry->Value;
198 }
199
200 enum class LLVMRustCodeModel {
201 Other,
202 Default,
203 JITDefault,
204 Small,
205 Kernel,
206 Medium,
207 Large,
208 };
209
210 static CodeModel::Model fromRust(LLVMRustCodeModel Model) {
211 switch (Model) {
212 case LLVMRustCodeModel::Default:
213 return CodeModel::Default;
214 case LLVMRustCodeModel::JITDefault:
215 return CodeModel::JITDefault;
216 case LLVMRustCodeModel::Small:
217 return CodeModel::Small;
218 case LLVMRustCodeModel::Kernel:
219 return CodeModel::Kernel;
220 case LLVMRustCodeModel::Medium:
221 return CodeModel::Medium;
222 case LLVMRustCodeModel::Large:
223 return CodeModel::Large;
224 default:
225 llvm_unreachable("Bad CodeModel.");
226 }
227 }
228
229 enum class LLVMRustCodeGenOptLevel {
230 Other,
231 None,
232 Less,
233 Default,
234 Aggressive,
235 };
236
237 static CodeGenOpt::Level fromRust(LLVMRustCodeGenOptLevel Level) {
238 switch (Level) {
239 case LLVMRustCodeGenOptLevel::None:
240 return CodeGenOpt::None;
241 case LLVMRustCodeGenOptLevel::Less:
242 return CodeGenOpt::Less;
243 case LLVMRustCodeGenOptLevel::Default:
244 return CodeGenOpt::Default;
245 case LLVMRustCodeGenOptLevel::Aggressive:
246 return CodeGenOpt::Aggressive;
247 default:
248 llvm_unreachable("Bad CodeGenOptLevel.");
249 }
250 }
251
252 enum class LLVMRustRelocMode {
253 Default,
254 Static,
255 PIC,
256 DynamicNoPic,
257 ROPI,
258 RWPI,
259 ROPIRWPI,
260 };
261
262 #if LLVM_VERSION_LE(3, 8)
263 static Reloc::Model fromRust(LLVMRustRelocMode RustReloc) {
264 #else
265 static Optional<Reloc::Model> fromRust(LLVMRustRelocMode RustReloc) {
266 #endif
267 switch (RustReloc) {
268 case LLVMRustRelocMode::Default:
269 #if LLVM_VERSION_LE(3, 8)
270 return Reloc::Default;
271 #else
272 return None;
273 #endif
274 case LLVMRustRelocMode::Static:
275 return Reloc::Static;
276 case LLVMRustRelocMode::PIC:
277 return Reloc::PIC_;
278 case LLVMRustRelocMode::DynamicNoPic:
279 return Reloc::DynamicNoPIC;
280 #if LLVM_VERSION_GE(4, 0)
281 case LLVMRustRelocMode::ROPI:
282 return Reloc::ROPI;
283 case LLVMRustRelocMode::RWPI:
284 return Reloc::RWPI;
285 case LLVMRustRelocMode::ROPIRWPI:
286 return Reloc::ROPI_RWPI;
287 #endif
288 default:
289 llvm_unreachable("Bad RelocModel.");
290 }
291 }
292
293 #if LLVM_RUSTLLVM
294 /// getLongestEntryLength - Return the length of the longest entry in the table.
295 ///
296 static size_t getLongestEntryLength(ArrayRef<SubtargetFeatureKV> Table) {
297 size_t MaxLen = 0;
298 for (auto &I : Table)
299 MaxLen = std::max(MaxLen, std::strlen(I.Key));
300 return MaxLen;
301 }
302
303 extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM) {
304 const TargetMachine *Target = unwrap(TM);
305 const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
306 const ArrayRef<SubtargetFeatureKV> CPUTable = MCInfo->getCPUTable();
307 unsigned MaxCPULen = getLongestEntryLength(CPUTable);
308
309 printf("Available CPUs for this target:\n");
310 for (auto &CPU : CPUTable)
311 printf(" %-*s - %s.\n", MaxCPULen, CPU.Key, CPU.Desc);
312 printf("\n");
313 }
314
315 extern "C" void LLVMRustPrintTargetFeatures(LLVMTargetMachineRef TM) {
316 const TargetMachine *Target = unwrap(TM);
317 const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
318 const ArrayRef<SubtargetFeatureKV> FeatTable = MCInfo->getFeatureTable();
319 unsigned MaxFeatLen = getLongestEntryLength(FeatTable);
320
321 printf("Available features for this target:\n");
322 for (auto &Feature : FeatTable)
323 printf(" %-*s - %s.\n", MaxFeatLen, Feature.Key, Feature.Desc);
324 printf("\n");
325
326 printf("Use +feature to enable a feature, or -feature to disable it.\n"
327 "For example, rustc -C -target-cpu=mycpu -C "
328 "target-feature=+feature1,-feature2\n\n");
329 }
330
331 #else
332
333 extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef) {
334 printf("Target CPU help is not supported by this LLVM version.\n\n");
335 }
336
337 extern "C" void LLVMRustPrintTargetFeatures(LLVMTargetMachineRef) {
338 printf("Target features help is not supported by this LLVM version.\n\n");
339 }
340 #endif
341
342 extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
343 const char *TripleStr, const char *CPU, const char *Feature,
344 LLVMRustCodeModel RustCM, LLVMRustRelocMode RustReloc,
345 LLVMRustCodeGenOptLevel RustOptLevel, bool UseSoftFloat,
346 bool PositionIndependentExecutable, bool FunctionSections,
347 bool DataSections) {
348
349 auto CM = fromRust(RustCM);
350 auto OptLevel = fromRust(RustOptLevel);
351 auto RM = fromRust(RustReloc);
352
353 std::string Error;
354 Triple Trip(Triple::normalize(TripleStr));
355 const llvm::Target *TheTarget =
356 TargetRegistry::lookupTarget(Trip.getTriple(), Error);
357 if (TheTarget == nullptr) {
358 LLVMRustSetLastError(Error.c_str());
359 return nullptr;
360 }
361
362 StringRef RealCPU = CPU;
363 if (RealCPU == "native") {
364 RealCPU = sys::getHostCPUName();
365 }
366
367 TargetOptions Options;
368 #if LLVM_VERSION_LE(3, 8)
369 Options.PositionIndependentExecutable = PositionIndependentExecutable;
370 #endif
371
372 Options.FloatABIType = FloatABI::Default;
373 if (UseSoftFloat) {
374 Options.FloatABIType = FloatABI::Soft;
375 }
376 Options.DataSections = DataSections;
377 Options.FunctionSections = FunctionSections;
378
379 TargetMachine *TM = TheTarget->createTargetMachine(
380 Trip.getTriple(), RealCPU, Feature, Options, RM, CM, OptLevel);
381 return wrap(TM);
382 }
383
384 extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) {
385 delete unwrap(TM);
386 }
387
388 // Unfortunately, LLVM doesn't expose a C API to add the corresponding analysis
389 // passes for a target to a pass manager. We export that functionality through
390 // this function.
391 extern "C" void LLVMRustAddAnalysisPasses(LLVMTargetMachineRef TM,
392 LLVMPassManagerRef PMR,
393 LLVMModuleRef M) {
394 PassManagerBase *PM = unwrap(PMR);
395 PM->add(
396 createTargetTransformInfoWrapperPass(unwrap(TM)->getTargetIRAnalysis()));
397 }
398
399 extern "C" void LLVMRustConfigurePassManagerBuilder(
400 LLVMPassManagerBuilderRef PMBR, LLVMRustCodeGenOptLevel OptLevel,
401 bool MergeFunctions, bool SLPVectorize, bool LoopVectorize) {
402 // Ignore mergefunc for now as enabling it causes crashes.
403 // unwrap(PMBR)->MergeFunctions = MergeFunctions;
404 unwrap(PMBR)->SLPVectorize = SLPVectorize;
405 unwrap(PMBR)->OptLevel = fromRust(OptLevel);
406 unwrap(PMBR)->LoopVectorize = LoopVectorize;
407 }
408
409 // Unfortunately, the LLVM C API doesn't provide a way to set the `LibraryInfo`
410 // field of a PassManagerBuilder, we expose our own method of doing so.
411 extern "C" void LLVMRustAddBuilderLibraryInfo(LLVMPassManagerBuilderRef PMBR,
412 LLVMModuleRef M,
413 bool DisableSimplifyLibCalls) {
414 Triple TargetTriple(unwrap(M)->getTargetTriple());
415 TargetLibraryInfoImpl *TLI = new TargetLibraryInfoImpl(TargetTriple);
416 if (DisableSimplifyLibCalls)
417 TLI->disableAllFunctions();
418 unwrap(PMBR)->LibraryInfo = TLI;
419 }
420
421 // Unfortunately, the LLVM C API doesn't provide a way to create the
422 // TargetLibraryInfo pass, so we use this method to do so.
423 extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR, LLVMModuleRef M,
424 bool DisableSimplifyLibCalls) {
425 Triple TargetTriple(unwrap(M)->getTargetTriple());
426 TargetLibraryInfoImpl TLII(TargetTriple);
427 if (DisableSimplifyLibCalls)
428 TLII.disableAllFunctions();
429 unwrap(PMR)->add(new TargetLibraryInfoWrapperPass(TLII));
430 }
431
432 // Unfortunately, the LLVM C API doesn't provide an easy way of iterating over
433 // all the functions in a module, so we do that manually here. You'll find
434 // similar code in clang's BackendUtil.cpp file.
435 extern "C" void LLVMRustRunFunctionPassManager(LLVMPassManagerRef PMR,
436 LLVMModuleRef M) {
437 llvm::legacy::FunctionPassManager *P =
438 unwrap<llvm::legacy::FunctionPassManager>(PMR);
439 P->doInitialization();
440
441 // Upgrade all calls to old intrinsics first.
442 for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E;)
443 UpgradeCallsToIntrinsic(&*I++); // must be post-increment, as we remove
444
445 for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E;
446 ++I)
447 if (!I->isDeclaration())
448 P->run(*I);
449
450 P->doFinalization();
451 }
452
453 extern "C" void LLVMRustSetLLVMOptions(int Argc, char **Argv) {
454 // Initializing the command-line options more than once is not allowed. So,
455 // check if they've already been initialized. (This could happen if we're
456 // being called from rustpkg, for example). If the arguments change, then
457 // that's just kinda unfortunate.
458 static bool Initialized = false;
459 if (Initialized)
460 return;
461 Initialized = true;
462 cl::ParseCommandLineOptions(Argc, Argv);
463 }
464
465 enum class LLVMRustFileType {
466 Other,
467 AssemblyFile,
468 ObjectFile,
469 };
470
471 static TargetMachine::CodeGenFileType fromRust(LLVMRustFileType Type) {
472 switch (Type) {
473 case LLVMRustFileType::AssemblyFile:
474 return TargetMachine::CGFT_AssemblyFile;
475 case LLVMRustFileType::ObjectFile:
476 return TargetMachine::CGFT_ObjectFile;
477 default:
478 llvm_unreachable("Bad FileType.");
479 }
480 }
481
482 extern "C" LLVMRustResult
483 LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR,
484 LLVMModuleRef M, const char *Path,
485 LLVMRustFileType RustFileType) {
486 llvm::legacy::PassManager *PM = unwrap<llvm::legacy::PassManager>(PMR);
487 auto FileType = fromRust(RustFileType);
488
489 std::string ErrorInfo;
490 std::error_code EC;
491 raw_fd_ostream OS(Path, EC, sys::fs::F_None);
492 if (EC)
493 ErrorInfo = EC.message();
494 if (ErrorInfo != "") {
495 LLVMRustSetLastError(ErrorInfo.c_str());
496 return LLVMRustResult::Failure;
497 }
498
499 unwrap(Target)->addPassesToEmitFile(*PM, OS, FileType, false);
500 PM->run(*unwrap(M));
501
502 // Apparently `addPassesToEmitFile` adds a pointer to our on-the-stack output
503 // stream (OS), so the only real safe place to delete this is here? Don't we
504 // wish this was written in Rust?
505 delete PM;
506 return LLVMRustResult::Success;
507 }
508
509
510 // Callback to demangle function name
511 // Parameters:
512 // * name to be demangled
513 // * name len
514 // * output buffer
515 // * output buffer len
516 // Returns len of demangled string, or 0 if demangle failed.
517 typedef size_t (*DemangleFn)(const char*, size_t, char*, size_t);
518
519
520 namespace {
521
522 class RustAssemblyAnnotationWriter : public AssemblyAnnotationWriter {
523 DemangleFn Demangle;
524 std::vector<char> Buf;
525
526 public:
527 RustAssemblyAnnotationWriter(DemangleFn Demangle) : Demangle(Demangle) {}
528
529 // Return empty string if demangle failed
530 // or if name does not need to be demangled
531 StringRef CallDemangle(StringRef name) {
532 if (!Demangle) {
533 return StringRef();
534 }
535
536 if (Buf.size() < name.size() * 2) {
537 // Semangled name usually shorter than mangled,
538 // but allocate twice as much memory just in case
539 Buf.resize(name.size() * 2);
540 }
541
542 auto R = Demangle(name.data(), name.size(), Buf.data(), Buf.size());
543 if (!R) {
544 // Demangle failed.
545 return StringRef();
546 }
547
548 auto Demangled = StringRef(Buf.data(), R);
549 if (Demangled == name) {
550 // Do not print anything if demangled name is equal to mangled.
551 return StringRef();
552 }
553
554 return Demangled;
555 }
556
557 void emitFunctionAnnot(const Function *F,
558 formatted_raw_ostream &OS) override {
559 StringRef Demangled = CallDemangle(F->getName());
560 if (Demangled.empty()) {
561 return;
562 }
563
564 OS << "; " << Demangled << "\n";
565 }
566
567 void emitInstructionAnnot(const Instruction *I,
568 formatted_raw_ostream &OS) override {
569 const char *Name;
570 const Value *Value;
571 if (const CallInst *CI = dyn_cast<CallInst>(I)) {
572 Name = "call";
573 Value = CI->getCalledValue();
574 } else if (const InvokeInst* II = dyn_cast<InvokeInst>(I)) {
575 Name = "invoke";
576 Value = II->getCalledValue();
577 } else {
578 // Could demangle more operations, e. g.
579 // `store %place, @function`.
580 return;
581 }
582
583 if (!Value->hasName()) {
584 return;
585 }
586
587 StringRef Demangled = CallDemangle(Value->getName());
588 if (Demangled.empty()) {
589 return;
590 }
591
592 OS << "; " << Name << " " << Demangled << "\n";
593 }
594 };
595
596 class RustPrintModulePass : public ModulePass {
597 raw_ostream* OS;
598 DemangleFn Demangle;
599 public:
600 static char ID;
601 RustPrintModulePass() : ModulePass(ID), OS(nullptr), Demangle(nullptr) {}
602 RustPrintModulePass(raw_ostream &OS, DemangleFn Demangle)
603 : ModulePass(ID), OS(&OS), Demangle(Demangle) {}
604
605 bool runOnModule(Module &M) override {
606 RustAssemblyAnnotationWriter AW(Demangle);
607
608 M.print(*OS, &AW, false);
609
610 return false;
611 }
612
613 void getAnalysisUsage(AnalysisUsage &AU) const override {
614 AU.setPreservesAll();
615 }
616
617 static StringRef name() { return "RustPrintModulePass"; }
618 };
619
620 } // namespace
621
622 namespace llvm {
623 void initializeRustPrintModulePassPass(PassRegistry&);
624 }
625
626 char RustPrintModulePass::ID = 0;
627 INITIALIZE_PASS(RustPrintModulePass, "print-rust-module",
628 "Print rust module to stderr", false, false)
629
630 extern "C" void LLVMRustPrintModule(LLVMPassManagerRef PMR, LLVMModuleRef M,
631 const char *Path, DemangleFn Demangle) {
632 llvm::legacy::PassManager *PM = unwrap<llvm::legacy::PassManager>(PMR);
633 std::string ErrorInfo;
634
635 std::error_code EC;
636 raw_fd_ostream OS(Path, EC, sys::fs::F_None);
637 if (EC)
638 ErrorInfo = EC.message();
639
640 formatted_raw_ostream FOS(OS);
641
642 PM->add(new RustPrintModulePass(FOS, Demangle));
643
644 PM->run(*unwrap(M));
645 }
646
647 extern "C" void LLVMRustPrintPasses() {
648 LLVMInitializePasses();
649 struct MyListener : PassRegistrationListener {
650 void passEnumerate(const PassInfo *Info) {
651 #if LLVM_VERSION_GE(4, 0)
652 StringRef PassArg = Info->getPassArgument();
653 StringRef PassName = Info->getPassName();
654 if (!PassArg.empty()) {
655 // These unsigned->signed casts could theoretically overflow, but
656 // realistically never will (and even if, the result is implementation
657 // defined rather plain UB).
658 printf("%15.*s - %.*s\n", (int)PassArg.size(), PassArg.data(),
659 (int)PassName.size(), PassName.data());
660 }
661 #else
662 if (Info->getPassArgument() && *Info->getPassArgument()) {
663 printf("%15s - %s\n", Info->getPassArgument(), Info->getPassName());
664 }
665 #endif
666 }
667 } Listener;
668
669 PassRegistry *PR = PassRegistry::getPassRegistry();
670 PR->enumerateWith(&Listener);
671 }
672
673 extern "C" void LLVMRustAddAlwaysInlinePass(LLVMPassManagerBuilderRef PMBR,
674 bool AddLifetimes) {
675 #if LLVM_VERSION_GE(4, 0)
676 unwrap(PMBR)->Inliner = llvm::createAlwaysInlinerLegacyPass(AddLifetimes);
677 #else
678 unwrap(PMBR)->Inliner = createAlwaysInlinerPass(AddLifetimes);
679 #endif
680 }
681
682 extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **Symbols,
683 size_t Len) {
684 llvm::legacy::PassManager passes;
685
686 #if LLVM_VERSION_LE(3, 8)
687 ArrayRef<const char *> Ref(Symbols, Len);
688 passes.add(llvm::createInternalizePass(Ref));
689 #else
690 auto PreserveFunctions = [=](const GlobalValue &GV) {
691 for (size_t I = 0; I < Len; I++) {
692 if (GV.getName() == Symbols[I]) {
693 return true;
694 }
695 }
696 return false;
697 };
698
699 passes.add(llvm::createInternalizePass(PreserveFunctions));
700 #endif
701
702 passes.run(*unwrap(M));
703 }
704
705 extern "C" void LLVMRustMarkAllFunctionsNounwind(LLVMModuleRef M) {
706 for (Module::iterator GV = unwrap(M)->begin(), E = unwrap(M)->end(); GV != E;
707 ++GV) {
708 GV->setDoesNotThrow();
709 Function *F = dyn_cast<Function>(GV);
710 if (F == nullptr)
711 continue;
712
713 for (Function::iterator B = F->begin(), BE = F->end(); B != BE; ++B) {
714 for (BasicBlock::iterator I = B->begin(), IE = B->end(); I != IE; ++I) {
715 if (isa<InvokeInst>(I)) {
716 InvokeInst *CI = cast<InvokeInst>(I);
717 CI->setDoesNotThrow();
718 }
719 }
720 }
721 }
722 }
723
724 extern "C" void
725 LLVMRustSetDataLayoutFromTargetMachine(LLVMModuleRef Module,
726 LLVMTargetMachineRef TMR) {
727 TargetMachine *Target = unwrap(TMR);
728 unwrap(Module)->setDataLayout(Target->createDataLayout());
729 }
730
731 extern "C" LLVMTargetDataRef LLVMRustGetModuleDataLayout(LLVMModuleRef M) {
732 return wrap(&unwrap(M)->getDataLayout());
733 }
734
735 extern "C" void LLVMRustSetModulePIELevel(LLVMModuleRef M) {
736 #if LLVM_VERSION_GE(3, 9)
737 unwrap(M)->setPIELevel(PIELevel::Level::Large);
738 #endif
739 }