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.
15 #include "llvm/Analysis/TargetLibraryInfo.h"
16 #include "llvm/Analysis/TargetTransformInfo.h"
17 #include "llvm/IR/AutoUpgrade.h"
18 #include "llvm/Support/CBindingWrapping.h"
19 #include "llvm/Support/FileSystem.h"
20 #include "llvm/Support/Host.h"
21 #include "llvm/Target/TargetMachine.h"
22 #include "llvm/Target/TargetSubtargetInfo.h"
23 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
25 #if LLVM_VERSION_GE(4, 0)
26 #include "llvm/Transforms/IPO/AlwaysInliner.h"
29 #include "llvm-c/Transforms/PassManagerBuilder.h"
32 using namespace llvm::legacy
;
34 extern cl::opt
<bool> EnableARMEHABI
;
36 typedef struct LLVMOpaquePass
*LLVMPassRef
;
37 typedef struct LLVMOpaqueTargetMachine
*LLVMTargetMachineRef
;
39 DEFINE_STDCXX_CONVERSION_FUNCTIONS(Pass
, LLVMPassRef
)
40 DEFINE_STDCXX_CONVERSION_FUNCTIONS(TargetMachine
, LLVMTargetMachineRef
)
41 DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassManagerBuilder
,
42 LLVMPassManagerBuilderRef
)
44 extern "C" void LLVMInitializePasses() {
45 PassRegistry
&Registry
= *PassRegistry::getPassRegistry();
46 initializeCore(Registry
);
47 initializeCodeGen(Registry
);
48 initializeScalarOpts(Registry
);
49 initializeVectorization(Registry
);
50 initializeIPO(Registry
);
51 initializeAnalysis(Registry
);
52 #if LLVM_VERSION_EQ(3, 7)
53 initializeIPA(Registry
);
55 initializeTransformUtils(Registry
);
56 initializeInstCombine(Registry
);
57 initializeInstrumentation(Registry
);
58 initializeTarget(Registry
);
61 enum class LLVMRustPassKind
{
67 static LLVMRustPassKind
toRust(PassKind Kind
) {
70 return LLVMRustPassKind::Function
;
72 return LLVMRustPassKind::Module
;
74 return LLVMRustPassKind::Other
;
78 extern "C" LLVMPassRef
LLVMRustFindAndCreatePass(const char *PassName
) {
79 StringRef
SR(PassName
);
80 PassRegistry
*PR
= PassRegistry::getPassRegistry();
82 const PassInfo
*PI
= PR
->getPassInfo(SR
);
84 return wrap(PI
->createPass());
89 extern "C" LLVMRustPassKind
LLVMRustPassKind(LLVMPassRef RustPass
) {
91 Pass
*Pass
= unwrap(RustPass
);
92 return toRust(Pass
->getPassKind());
95 extern "C" void LLVMRustAddPass(LLVMPassManagerRef PMR
, LLVMPassRef RustPass
) {
97 Pass
*Pass
= unwrap(RustPass
);
98 PassManagerBase
*PMB
= unwrap(PMR
);
102 #ifdef LLVM_COMPONENT_X86
103 #define SUBTARGET_X86 SUBTARGET(X86)
105 #define SUBTARGET_X86
108 #ifdef LLVM_COMPONENT_ARM
109 #define SUBTARGET_ARM SUBTARGET(ARM)
111 #define SUBTARGET_ARM
114 #ifdef LLVM_COMPONENT_AARCH64
115 #define SUBTARGET_AARCH64 SUBTARGET(AArch64)
117 #define SUBTARGET_AARCH64
120 #ifdef LLVM_COMPONENT_MIPS
121 #define SUBTARGET_MIPS SUBTARGET(Mips)
123 #define SUBTARGET_MIPS
126 #ifdef LLVM_COMPONENT_POWERPC
127 #define SUBTARGET_PPC SUBTARGET(PPC)
129 #define SUBTARGET_PPC
132 #ifdef LLVM_COMPONENT_SYSTEMZ
133 #define SUBTARGET_SYSTEMZ SUBTARGET(SystemZ)
135 #define SUBTARGET_SYSTEMZ
138 #ifdef LLVM_COMPONENT_MSP430
139 #define SUBTARGET_MSP430 SUBTARGET(MSP430)
141 #define SUBTARGET_MSP430
144 #ifdef LLVM_COMPONENT_SPARC
145 #define SUBTARGET_SPARC SUBTARGET(Sparc)
147 #define SUBTARGET_SPARC
150 #ifdef LLVM_COMPONENT_HEXAGON
151 #define SUBTARGET_HEXAGON SUBTARGET(Hexagon)
153 #define SUBTARGET_HEXAGON
156 #define GEN_SUBTARGETS \
167 #define SUBTARGET(x) \
169 extern const SubtargetFeatureKV x##FeatureKV[]; \
170 extern const SubtargetFeatureKV x##SubTypeKV[]; \
176 extern "C" bool LLVMRustHasFeature(LLVMTargetMachineRef TM
,
177 const char *Feature
) {
178 TargetMachine
*Target
= unwrap(TM
);
179 const MCSubtargetInfo
*MCInfo
= Target
->getMCSubtargetInfo();
180 const FeatureBitset
&Bits
= MCInfo
->getFeatureBits();
181 const llvm::SubtargetFeatureKV
*FeatureEntry
;
183 #define SUBTARGET(x) \
184 if (MCInfo->isCPUStringValid(x##SubTypeKV[0].Key)) { \
185 FeatureEntry = x##FeatureKV; \
188 GEN_SUBTARGETS
{ return false; }
191 while (strcmp(Feature
, FeatureEntry
->Key
) != 0)
194 return (Bits
& FeatureEntry
->Value
) == FeatureEntry
->Value
;
197 enum class LLVMRustCodeModel
{
207 static CodeModel::Model
fromRust(LLVMRustCodeModel Model
) {
209 case LLVMRustCodeModel::Default
:
210 return CodeModel::Default
;
211 case LLVMRustCodeModel::JITDefault
:
212 return CodeModel::JITDefault
;
213 case LLVMRustCodeModel::Small
:
214 return CodeModel::Small
;
215 case LLVMRustCodeModel::Kernel
:
216 return CodeModel::Kernel
;
217 case LLVMRustCodeModel::Medium
:
218 return CodeModel::Medium
;
219 case LLVMRustCodeModel::Large
:
220 return CodeModel::Large
;
222 llvm_unreachable("Bad CodeModel.");
226 enum class LLVMRustCodeGenOptLevel
{
234 static CodeGenOpt::Level
fromRust(LLVMRustCodeGenOptLevel Level
) {
236 case LLVMRustCodeGenOptLevel::None
:
237 return CodeGenOpt::None
;
238 case LLVMRustCodeGenOptLevel::Less
:
239 return CodeGenOpt::Less
;
240 case LLVMRustCodeGenOptLevel::Default
:
241 return CodeGenOpt::Default
;
242 case LLVMRustCodeGenOptLevel::Aggressive
:
243 return CodeGenOpt::Aggressive
;
245 llvm_unreachable("Bad CodeGenOptLevel.");
249 enum class LLVMRustRelocMode
{
259 #if LLVM_VERSION_LE(3, 8)
260 static Reloc::Model
fromRust(LLVMRustRelocMode RustReloc
) {
262 static Optional
<Reloc::Model
> fromRust(LLVMRustRelocMode RustReloc
) {
265 case LLVMRustRelocMode::Default
:
266 #if LLVM_VERSION_LE(3, 8)
267 return Reloc::Default
;
271 case LLVMRustRelocMode::Static
:
272 return Reloc::Static
;
273 case LLVMRustRelocMode::PIC
:
275 case LLVMRustRelocMode::DynamicNoPic
:
276 return Reloc::DynamicNoPIC
;
277 #if LLVM_VERSION_GE(4, 0)
278 case LLVMRustRelocMode::ROPI
:
280 case LLVMRustRelocMode::RWPI
:
282 case LLVMRustRelocMode::ROPIRWPI
:
283 return Reloc::ROPI_RWPI
;
286 llvm_unreachable("Bad RelocModel.");
291 /// getLongestEntryLength - Return the length of the longest entry in the table.
293 static size_t getLongestEntryLength(ArrayRef
<SubtargetFeatureKV
> Table
) {
295 for (auto &I
: Table
)
296 MaxLen
= std::max(MaxLen
, std::strlen(I
.Key
));
300 extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM
) {
301 const TargetMachine
*Target
= unwrap(TM
);
302 const MCSubtargetInfo
*MCInfo
= Target
->getMCSubtargetInfo();
303 const ArrayRef
<SubtargetFeatureKV
> CPUTable
= MCInfo
->getCPUTable();
304 unsigned MaxCPULen
= getLongestEntryLength(CPUTable
);
306 printf("Available CPUs for this target:\n");
307 for (auto &CPU
: CPUTable
)
308 printf(" %-*s - %s.\n", MaxCPULen
, CPU
.Key
, CPU
.Desc
);
312 extern "C" void LLVMRustPrintTargetFeatures(LLVMTargetMachineRef TM
) {
313 const TargetMachine
*Target
= unwrap(TM
);
314 const MCSubtargetInfo
*MCInfo
= Target
->getMCSubtargetInfo();
315 const ArrayRef
<SubtargetFeatureKV
> FeatTable
= MCInfo
->getFeatureTable();
316 unsigned MaxFeatLen
= getLongestEntryLength(FeatTable
);
318 printf("Available features for this target:\n");
319 for (auto &Feature
: FeatTable
)
320 printf(" %-*s - %s.\n", MaxFeatLen
, Feature
.Key
, Feature
.Desc
);
323 printf("Use +feature to enable a feature, or -feature to disable it.\n"
324 "For example, rustc -C -target-cpu=mycpu -C "
325 "target-feature=+feature1,-feature2\n\n");
330 extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef
) {
331 printf("Target CPU help is not supported by this LLVM version.\n\n");
334 extern "C" void LLVMRustPrintTargetFeatures(LLVMTargetMachineRef
) {
335 printf("Target features help is not supported by this LLVM version.\n\n");
339 extern "C" LLVMTargetMachineRef
LLVMRustCreateTargetMachine(
340 const char *TripleStr
, const char *CPU
, const char *Feature
,
341 LLVMRustCodeModel RustCM
, LLVMRustRelocMode RustReloc
,
342 LLVMRustCodeGenOptLevel RustOptLevel
, bool UseSoftFloat
,
343 bool PositionIndependentExecutable
, bool FunctionSections
,
346 auto CM
= fromRust(RustCM
);
347 auto OptLevel
= fromRust(RustOptLevel
);
348 auto RM
= fromRust(RustReloc
);
351 Triple
Trip(Triple::normalize(TripleStr
));
352 const llvm::Target
*TheTarget
=
353 TargetRegistry::lookupTarget(Trip
.getTriple(), Error
);
354 if (TheTarget
== nullptr) {
355 LLVMRustSetLastError(Error
.c_str());
359 StringRef RealCPU
= CPU
;
360 if (RealCPU
== "native") {
361 RealCPU
= sys::getHostCPUName();
364 TargetOptions Options
;
365 #if LLVM_VERSION_LE(3, 8)
366 Options
.PositionIndependentExecutable
= PositionIndependentExecutable
;
369 Options
.FloatABIType
= FloatABI::Default
;
371 Options
.FloatABIType
= FloatABI::Soft
;
373 Options
.DataSections
= DataSections
;
374 Options
.FunctionSections
= FunctionSections
;
376 TargetMachine
*TM
= TheTarget
->createTargetMachine(
377 Trip
.getTriple(), RealCPU
, Feature
, Options
, RM
, CM
, OptLevel
);
381 extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM
) {
385 // Unfortunately, LLVM doesn't expose a C API to add the corresponding analysis
386 // passes for a target to a pass manager. We export that functionality through
388 extern "C" void LLVMRustAddAnalysisPasses(LLVMTargetMachineRef TM
,
389 LLVMPassManagerRef PMR
,
391 PassManagerBase
*PM
= unwrap(PMR
);
393 createTargetTransformInfoWrapperPass(unwrap(TM
)->getTargetIRAnalysis()));
396 extern "C" void LLVMRustConfigurePassManagerBuilder(
397 LLVMPassManagerBuilderRef PMBR
, LLVMRustCodeGenOptLevel OptLevel
,
398 bool MergeFunctions
, bool SLPVectorize
, bool LoopVectorize
) {
399 // Ignore mergefunc for now as enabling it causes crashes.
400 // unwrap(PMBR)->MergeFunctions = MergeFunctions;
401 unwrap(PMBR
)->SLPVectorize
= SLPVectorize
;
402 unwrap(PMBR
)->OptLevel
= fromRust(OptLevel
);
403 unwrap(PMBR
)->LoopVectorize
= LoopVectorize
;
406 // Unfortunately, the LLVM C API doesn't provide a way to set the `LibraryInfo`
407 // field of a PassManagerBuilder, we expose our own method of doing so.
408 extern "C" void LLVMRustAddBuilderLibraryInfo(LLVMPassManagerBuilderRef PMBR
,
410 bool DisableSimplifyLibCalls
) {
411 Triple
TargetTriple(unwrap(M
)->getTargetTriple());
412 TargetLibraryInfoImpl
*TLI
= new TargetLibraryInfoImpl(TargetTriple
);
413 if (DisableSimplifyLibCalls
)
414 TLI
->disableAllFunctions();
415 unwrap(PMBR
)->LibraryInfo
= TLI
;
418 // Unfortunately, the LLVM C API doesn't provide a way to create the
419 // TargetLibraryInfo pass, so we use this method to do so.
420 extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR
, LLVMModuleRef M
,
421 bool DisableSimplifyLibCalls
) {
422 Triple
TargetTriple(unwrap(M
)->getTargetTriple());
423 TargetLibraryInfoImpl
TLII(TargetTriple
);
424 if (DisableSimplifyLibCalls
)
425 TLII
.disableAllFunctions();
426 unwrap(PMR
)->add(new TargetLibraryInfoWrapperPass(TLII
));
429 // Unfortunately, the LLVM C API doesn't provide an easy way of iterating over
430 // all the functions in a module, so we do that manually here. You'll find
431 // similar code in clang's BackendUtil.cpp file.
432 extern "C" void LLVMRustRunFunctionPassManager(LLVMPassManagerRef PMR
,
434 llvm::legacy::FunctionPassManager
*P
=
435 unwrap
<llvm::legacy::FunctionPassManager
>(PMR
);
436 P
->doInitialization();
438 // Upgrade all calls to old intrinsics first.
439 for (Module::iterator I
= unwrap(M
)->begin(), E
= unwrap(M
)->end(); I
!= E
;)
440 UpgradeCallsToIntrinsic(&*I
++); // must be post-increment, as we remove
442 for (Module::iterator I
= unwrap(M
)->begin(), E
= unwrap(M
)->end(); I
!= E
;
444 if (!I
->isDeclaration())
450 extern "C" void LLVMRustSetLLVMOptions(int Argc
, char **Argv
) {
451 // Initializing the command-line options more than once is not allowed. So,
452 // check if they've already been initialized. (This could happen if we're
453 // being called from rustpkg, for example). If the arguments change, then
454 // that's just kinda unfortunate.
455 static bool Initialized
= false;
459 cl::ParseCommandLineOptions(Argc
, Argv
);
462 enum class LLVMRustFileType
{
468 static TargetMachine::CodeGenFileType
fromRust(LLVMRustFileType Type
) {
470 case LLVMRustFileType::AssemblyFile
:
471 return TargetMachine::CGFT_AssemblyFile
;
472 case LLVMRustFileType::ObjectFile
:
473 return TargetMachine::CGFT_ObjectFile
;
475 llvm_unreachable("Bad FileType.");
479 extern "C" LLVMRustResult
480 LLVMRustWriteOutputFile(LLVMTargetMachineRef Target
, LLVMPassManagerRef PMR
,
481 LLVMModuleRef M
, const char *Path
,
482 LLVMRustFileType RustFileType
) {
483 llvm::legacy::PassManager
*PM
= unwrap
<llvm::legacy::PassManager
>(PMR
);
484 auto FileType
= fromRust(RustFileType
);
486 std::string ErrorInfo
;
488 raw_fd_ostream
OS(Path
, EC
, sys::fs::F_None
);
490 ErrorInfo
= EC
.message();
491 if (ErrorInfo
!= "") {
492 LLVMRustSetLastError(ErrorInfo
.c_str());
493 return LLVMRustResult::Failure
;
496 unwrap(Target
)->addPassesToEmitFile(*PM
, OS
, FileType
, false);
499 // Apparently `addPassesToEmitFile` adds a pointer to our on-the-stack output
500 // stream (OS), so the only real safe place to delete this is here? Don't we
501 // wish this was written in Rust?
503 return LLVMRustResult::Success
;
506 extern "C" void LLVMRustPrintModule(LLVMPassManagerRef PMR
, LLVMModuleRef M
,
508 llvm::legacy::PassManager
*PM
= unwrap
<llvm::legacy::PassManager
>(PMR
);
509 std::string ErrorInfo
;
512 raw_fd_ostream
OS(Path
, EC
, sys::fs::F_None
);
514 ErrorInfo
= EC
.message();
516 formatted_raw_ostream
FOS(OS
);
518 PM
->add(createPrintModulePass(FOS
));
523 extern "C" void LLVMRustPrintPasses() {
524 LLVMInitializePasses();
525 struct MyListener
: PassRegistrationListener
{
526 void passEnumerate(const PassInfo
*Info
) {
527 #if LLVM_VERSION_GE(4, 0)
528 StringRef PassArg
= Info
->getPassArgument();
529 StringRef PassName
= Info
->getPassName();
530 if (!PassArg
.empty()) {
531 // These unsigned->signed casts could theoretically overflow, but
532 // realistically never will (and even if, the result is implementation
533 // defined rather plain UB).
534 printf("%15.*s - %.*s\n", (int)PassArg
.size(), PassArg
.data(),
535 (int)PassName
.size(), PassName
.data());
538 if (Info
->getPassArgument() && *Info
->getPassArgument()) {
539 printf("%15s - %s\n", Info
->getPassArgument(), Info
->getPassName());
545 PassRegistry
*PR
= PassRegistry::getPassRegistry();
546 PR
->enumerateWith(&Listener
);
549 extern "C" void LLVMRustAddAlwaysInlinePass(LLVMPassManagerBuilderRef PMBR
,
551 #if LLVM_VERSION_GE(4, 0)
552 unwrap(PMBR
)->Inliner
= llvm::createAlwaysInlinerLegacyPass(AddLifetimes
);
554 unwrap(PMBR
)->Inliner
= createAlwaysInlinerPass(AddLifetimes
);
558 extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M
, char **Symbols
,
560 llvm::legacy::PassManager passes
;
562 #if LLVM_VERSION_LE(3, 8)
563 ArrayRef
<const char *> Ref(Symbols
, Len
);
564 passes
.add(llvm::createInternalizePass(Ref
));
566 auto PreserveFunctions
= [=](const GlobalValue
&GV
) {
567 for (size_t I
= 0; I
< Len
; I
++) {
568 if (GV
.getName() == Symbols
[I
]) {
575 passes
.add(llvm::createInternalizePass(PreserveFunctions
));
578 passes
.run(*unwrap(M
));
581 extern "C" void LLVMRustMarkAllFunctionsNounwind(LLVMModuleRef M
) {
582 for (Module::iterator GV
= unwrap(M
)->begin(), E
= unwrap(M
)->end(); GV
!= E
;
584 GV
->setDoesNotThrow();
585 Function
*F
= dyn_cast
<Function
>(GV
);
589 for (Function::iterator B
= F
->begin(), BE
= F
->end(); B
!= BE
; ++B
) {
590 for (BasicBlock::iterator I
= B
->begin(), IE
= B
->end(); I
!= IE
; ++I
) {
591 if (isa
<InvokeInst
>(I
)) {
592 InvokeInst
*CI
= cast
<InvokeInst
>(I
);
593 CI
->setDoesNotThrow();
601 LLVMRustSetDataLayoutFromTargetMachine(LLVMModuleRef Module
,
602 LLVMTargetMachineRef TMR
) {
603 TargetMachine
*Target
= unwrap(TMR
);
604 unwrap(Module
)->setDataLayout(Target
->createDataLayout());
607 extern "C" LLVMTargetDataRef
LLVMRustGetModuleDataLayout(LLVMModuleRef M
) {
608 return wrap(&unwrap(M
)->getDataLayout());
611 extern "C" void LLVMRustSetModulePIELevel(LLVMModuleRef M
) {
612 #if LLVM_VERSION_GE(3, 9)
613 unwrap(M
)->setPIELevel(PIELevel::Level::Large
);