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.
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.
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"
28 #if LLVM_VERSION_GE(4, 0)
29 #include "llvm/Transforms/IPO/AlwaysInliner.h"
32 #include "llvm-c/Transforms/PassManagerBuilder.h"
35 using namespace llvm::legacy
;
37 extern cl::opt
<bool> EnableARMEHABI
;
39 typedef struct LLVMOpaquePass
*LLVMPassRef
;
40 typedef struct LLVMOpaqueTargetMachine
*LLVMTargetMachineRef
;
42 DEFINE_STDCXX_CONVERSION_FUNCTIONS(Pass
, LLVMPassRef
)
43 DEFINE_STDCXX_CONVERSION_FUNCTIONS(TargetMachine
, LLVMTargetMachineRef
)
44 DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassManagerBuilder
,
45 LLVMPassManagerBuilderRef
)
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
);
58 initializeTransformUtils(Registry
);
59 initializeInstCombine(Registry
);
60 initializeInstrumentation(Registry
);
61 initializeTarget(Registry
);
64 enum class LLVMRustPassKind
{
70 static LLVMRustPassKind
toRust(PassKind Kind
) {
73 return LLVMRustPassKind::Function
;
75 return LLVMRustPassKind::Module
;
77 return LLVMRustPassKind::Other
;
81 extern "C" LLVMPassRef
LLVMRustFindAndCreatePass(const char *PassName
) {
82 StringRef
SR(PassName
);
83 PassRegistry
*PR
= PassRegistry::getPassRegistry();
85 const PassInfo
*PI
= PR
->getPassInfo(SR
);
87 return wrap(PI
->createPass());
92 extern "C" LLVMRustPassKind
LLVMRustPassKind(LLVMPassRef RustPass
) {
94 Pass
*Pass
= unwrap(RustPass
);
95 return toRust(Pass
->getPassKind());
98 extern "C" void LLVMRustAddPass(LLVMPassManagerRef PMR
, LLVMPassRef RustPass
) {
100 Pass
*Pass
= unwrap(RustPass
);
101 PassManagerBase
*PMB
= unwrap(PMR
);
105 #ifdef LLVM_COMPONENT_X86
106 #define SUBTARGET_X86 SUBTARGET(X86)
108 #define SUBTARGET_X86
111 #ifdef LLVM_COMPONENT_ARM
112 #define SUBTARGET_ARM SUBTARGET(ARM)
114 #define SUBTARGET_ARM
117 #ifdef LLVM_COMPONENT_AARCH64
118 #define SUBTARGET_AARCH64 SUBTARGET(AArch64)
120 #define SUBTARGET_AARCH64
123 #ifdef LLVM_COMPONENT_MIPS
124 #define SUBTARGET_MIPS SUBTARGET(Mips)
126 #define SUBTARGET_MIPS
129 #ifdef LLVM_COMPONENT_POWERPC
130 #define SUBTARGET_PPC SUBTARGET(PPC)
132 #define SUBTARGET_PPC
135 #ifdef LLVM_COMPONENT_SYSTEMZ
136 #define SUBTARGET_SYSTEMZ SUBTARGET(SystemZ)
138 #define SUBTARGET_SYSTEMZ
141 #ifdef LLVM_COMPONENT_MSP430
142 #define SUBTARGET_MSP430 SUBTARGET(MSP430)
144 #define SUBTARGET_MSP430
147 #ifdef LLVM_COMPONENT_SPARC
148 #define SUBTARGET_SPARC SUBTARGET(Sparc)
150 #define SUBTARGET_SPARC
153 #ifdef LLVM_COMPONENT_HEXAGON
154 #define SUBTARGET_HEXAGON SUBTARGET(Hexagon)
156 #define SUBTARGET_HEXAGON
159 #define GEN_SUBTARGETS \
170 #define SUBTARGET(x) \
172 extern const SubtargetFeatureKV x##FeatureKV[]; \
173 extern const SubtargetFeatureKV x##SubTypeKV[]; \
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
;
186 #define SUBTARGET(x) \
187 if (MCInfo->isCPUStringValid(x##SubTypeKV[0].Key)) { \
188 FeatureEntry = x##FeatureKV; \
191 GEN_SUBTARGETS
{ return false; }
194 while (strcmp(Feature
, FeatureEntry
->Key
) != 0)
197 return (Bits
& FeatureEntry
->Value
) == FeatureEntry
->Value
;
200 enum class LLVMRustCodeModel
{
210 static CodeModel::Model
fromRust(LLVMRustCodeModel 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
;
225 llvm_unreachable("Bad CodeModel.");
229 enum class LLVMRustCodeGenOptLevel
{
237 static CodeGenOpt::Level
fromRust(LLVMRustCodeGenOptLevel 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
;
248 llvm_unreachable("Bad CodeGenOptLevel.");
252 enum class LLVMRustRelocMode
{
262 #if LLVM_VERSION_LE(3, 8)
263 static Reloc::Model
fromRust(LLVMRustRelocMode RustReloc
) {
265 static Optional
<Reloc::Model
> fromRust(LLVMRustRelocMode RustReloc
) {
268 case LLVMRustRelocMode::Default
:
269 #if LLVM_VERSION_LE(3, 8)
270 return Reloc::Default
;
274 case LLVMRustRelocMode::Static
:
275 return Reloc::Static
;
276 case LLVMRustRelocMode::PIC
:
278 case LLVMRustRelocMode::DynamicNoPic
:
279 return Reloc::DynamicNoPIC
;
280 #if LLVM_VERSION_GE(4, 0)
281 case LLVMRustRelocMode::ROPI
:
283 case LLVMRustRelocMode::RWPI
:
285 case LLVMRustRelocMode::ROPIRWPI
:
286 return Reloc::ROPI_RWPI
;
289 llvm_unreachable("Bad RelocModel.");
294 /// getLongestEntryLength - Return the length of the longest entry in the table.
296 static size_t getLongestEntryLength(ArrayRef
<SubtargetFeatureKV
> Table
) {
298 for (auto &I
: Table
)
299 MaxLen
= std::max(MaxLen
, std::strlen(I
.Key
));
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
);
309 printf("Available CPUs for this target:\n");
310 for (auto &CPU
: CPUTable
)
311 printf(" %-*s - %s.\n", MaxCPULen
, CPU
.Key
, CPU
.Desc
);
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
);
321 printf("Available features for this target:\n");
322 for (auto &Feature
: FeatTable
)
323 printf(" %-*s - %s.\n", MaxFeatLen
, Feature
.Key
, Feature
.Desc
);
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");
333 extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef
) {
334 printf("Target CPU help is not supported by this LLVM version.\n\n");
337 extern "C" void LLVMRustPrintTargetFeatures(LLVMTargetMachineRef
) {
338 printf("Target features help is not supported by this LLVM version.\n\n");
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
,
349 auto CM
= fromRust(RustCM
);
350 auto OptLevel
= fromRust(RustOptLevel
);
351 auto RM
= fromRust(RustReloc
);
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());
362 StringRef RealCPU
= CPU
;
363 if (RealCPU
== "native") {
364 RealCPU
= sys::getHostCPUName();
367 TargetOptions Options
;
368 #if LLVM_VERSION_LE(3, 8)
369 Options
.PositionIndependentExecutable
= PositionIndependentExecutable
;
372 Options
.FloatABIType
= FloatABI::Default
;
374 Options
.FloatABIType
= FloatABI::Soft
;
376 Options
.DataSections
= DataSections
;
377 Options
.FunctionSections
= FunctionSections
;
379 TargetMachine
*TM
= TheTarget
->createTargetMachine(
380 Trip
.getTriple(), RealCPU
, Feature
, Options
, RM
, CM
, OptLevel
);
384 extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM
) {
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
391 extern "C" void LLVMRustAddAnalysisPasses(LLVMTargetMachineRef TM
,
392 LLVMPassManagerRef PMR
,
394 PassManagerBase
*PM
= unwrap(PMR
);
396 createTargetTransformInfoWrapperPass(unwrap(TM
)->getTargetIRAnalysis()));
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
;
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
,
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
;
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
));
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
,
437 llvm::legacy::FunctionPassManager
*P
=
438 unwrap
<llvm::legacy::FunctionPassManager
>(PMR
);
439 P
->doInitialization();
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
445 for (Module::iterator I
= unwrap(M
)->begin(), E
= unwrap(M
)->end(); I
!= E
;
447 if (!I
->isDeclaration())
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;
462 cl::ParseCommandLineOptions(Argc
, Argv
);
465 enum class LLVMRustFileType
{
471 static TargetMachine::CodeGenFileType
fromRust(LLVMRustFileType Type
) {
473 case LLVMRustFileType::AssemblyFile
:
474 return TargetMachine::CGFT_AssemblyFile
;
475 case LLVMRustFileType::ObjectFile
:
476 return TargetMachine::CGFT_ObjectFile
;
478 llvm_unreachable("Bad FileType.");
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
);
489 std::string ErrorInfo
;
491 raw_fd_ostream
OS(Path
, EC
, sys::fs::F_None
);
493 ErrorInfo
= EC
.message();
494 if (ErrorInfo
!= "") {
495 LLVMRustSetLastError(ErrorInfo
.c_str());
496 return LLVMRustResult::Failure
;
499 unwrap(Target
)->addPassesToEmitFile(*PM
, OS
, FileType
, false);
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?
506 return LLVMRustResult::Success
;
510 // Callback to demangle function name
512 // * name to be demangled
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);
522 class RustAssemblyAnnotationWriter
: public AssemblyAnnotationWriter
{
524 std::vector
<char> Buf
;
527 RustAssemblyAnnotationWriter(DemangleFn Demangle
) : Demangle(Demangle
) {}
529 // Return empty string if demangle failed
530 // or if name does not need to be demangled
531 StringRef
CallDemangle(StringRef name
) {
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);
542 auto R
= Demangle(name
.data(), name
.size(), Buf
.data(), Buf
.size());
548 auto Demangled
= StringRef(Buf
.data(), R
);
549 if (Demangled
== name
) {
550 // Do not print anything if demangled name is equal to mangled.
557 void emitFunctionAnnot(const Function
*F
,
558 formatted_raw_ostream
&OS
) override
{
559 StringRef Demangled
= CallDemangle(F
->getName());
560 if (Demangled
.empty()) {
564 OS
<< "; " << Demangled
<< "\n";
567 void emitInstructionAnnot(const Instruction
*I
,
568 formatted_raw_ostream
&OS
) override
{
571 if (const CallInst
*CI
= dyn_cast
<CallInst
>(I
)) {
573 Value
= CI
->getCalledValue();
574 } else if (const InvokeInst
* II
= dyn_cast
<InvokeInst
>(I
)) {
576 Value
= II
->getCalledValue();
578 // Could demangle more operations, e. g.
579 // `store %place, @function`.
583 if (!Value
->hasName()) {
587 StringRef Demangled
= CallDemangle(Value
->getName());
588 if (Demangled
.empty()) {
592 OS
<< "; " << Name
<< " " << Demangled
<< "\n";
596 class RustPrintModulePass
: public ModulePass
{
601 RustPrintModulePass() : ModulePass(ID
), OS(nullptr), Demangle(nullptr) {}
602 RustPrintModulePass(raw_ostream
&OS
, DemangleFn Demangle
)
603 : ModulePass(ID
), OS(&OS
), Demangle(Demangle
) {}
605 bool runOnModule(Module
&M
) override
{
606 RustAssemblyAnnotationWriter
AW(Demangle
);
608 M
.print(*OS
, &AW
, false);
613 void getAnalysisUsage(AnalysisUsage
&AU
) const override
{
614 AU
.setPreservesAll();
617 static StringRef
name() { return "RustPrintModulePass"; }
623 void initializeRustPrintModulePassPass(PassRegistry
&);
626 char RustPrintModulePass::ID
= 0;
627 INITIALIZE_PASS(RustPrintModulePass
, "print-rust-module",
628 "Print rust module to stderr", false, false)
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
;
636 raw_fd_ostream
OS(Path
, EC
, sys::fs::F_None
);
638 ErrorInfo
= EC
.message();
640 formatted_raw_ostream
FOS(OS
);
642 PM
->add(new RustPrintModulePass(FOS
, Demangle
));
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());
662 if (Info
->getPassArgument() && *Info
->getPassArgument()) {
663 printf("%15s - %s\n", Info
->getPassArgument(), Info
->getPassName());
669 PassRegistry
*PR
= PassRegistry::getPassRegistry();
670 PR
->enumerateWith(&Listener
);
673 extern "C" void LLVMRustAddAlwaysInlinePass(LLVMPassManagerBuilderRef PMBR
,
675 #if LLVM_VERSION_GE(4, 0)
676 unwrap(PMBR
)->Inliner
= llvm::createAlwaysInlinerLegacyPass(AddLifetimes
);
678 unwrap(PMBR
)->Inliner
= createAlwaysInlinerPass(AddLifetimes
);
682 extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M
, char **Symbols
,
684 llvm::legacy::PassManager passes
;
686 #if LLVM_VERSION_LE(3, 8)
687 ArrayRef
<const char *> Ref(Symbols
, Len
);
688 passes
.add(llvm::createInternalizePass(Ref
));
690 auto PreserveFunctions
= [=](const GlobalValue
&GV
) {
691 for (size_t I
= 0; I
< Len
; I
++) {
692 if (GV
.getName() == Symbols
[I
]) {
699 passes
.add(llvm::createInternalizePass(PreserveFunctions
));
702 passes
.run(*unwrap(M
));
705 extern "C" void LLVMRustMarkAllFunctionsNounwind(LLVMModuleRef M
) {
706 for (Module::iterator GV
= unwrap(M
)->begin(), E
= unwrap(M
)->end(); GV
!= E
;
708 GV
->setDoesNotThrow();
709 Function
*F
= dyn_cast
<Function
>(GV
);
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();
725 LLVMRustSetDataLayoutFromTargetMachine(LLVMModuleRef Module
,
726 LLVMTargetMachineRef TMR
) {
727 TargetMachine
*Target
= unwrap(TMR
);
728 unwrap(Module
)->setDataLayout(Target
->createDataLayout());
731 extern "C" LLVMTargetDataRef
LLVMRustGetModuleDataLayout(LLVMModuleRef M
) {
732 return wrap(&unwrap(M
)->getDataLayout());
735 extern "C" void LLVMRustSetModulePIELevel(LLVMModuleRef M
) {
736 #if LLVM_VERSION_GE(3, 9)
737 unwrap(M
)->setPIELevel(PIELevel::Level::Large
);