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.");
250 /// getLongestEntryLength - Return the length of the longest entry in the table.
252 static size_t getLongestEntryLength(ArrayRef<SubtargetFeatureKV> Table) {
254 for (auto &I : Table)
255 MaxLen = std::max(MaxLen, std::strlen(I.Key));
259 extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM) {
260 const TargetMachine *Target = unwrap(TM);
261 const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
262 const ArrayRef<SubtargetFeatureKV> CPUTable = MCInfo->getCPUTable();
263 unsigned MaxCPULen = getLongestEntryLength(CPUTable);
265 printf("Available CPUs for this target:\n");
266 for (auto &CPU : CPUTable)
267 printf(" %-*s - %s.\n", MaxCPULen, CPU.Key, CPU.Desc);
271 extern "C" void LLVMRustPrintTargetFeatures(LLVMTargetMachineRef TM) {
272 const TargetMachine *Target = unwrap(TM);
273 const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
274 const ArrayRef<SubtargetFeatureKV> FeatTable = MCInfo->getFeatureTable();
275 unsigned MaxFeatLen = getLongestEntryLength(FeatTable);
277 printf("Available features for this target:\n");
278 for (auto &Feature : FeatTable)
279 printf(" %-*s - %s.\n", MaxFeatLen, Feature.Key, Feature.Desc);
282 printf("Use +feature to enable a feature, or -feature to disable it.\n"
283 "For example, rustc -C -target-cpu=mycpu -C "
284 "target-feature=+feature1,-feature2\n\n");
289 extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef) {
290 printf("Target CPU help is not supported by this LLVM version.\n\n");
293 extern "C" void LLVMRustPrintTargetFeatures(LLVMTargetMachineRef) {
294 printf("Target features help is not supported by this LLVM version.\n\n");
298 extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
299 const char *TripleStr, const char *CPU, const char *Feature,
300 LLVMRustCodeModel RustCM, LLVMRelocMode Reloc,
301 LLVMRustCodeGenOptLevel RustOptLevel, bool UseSoftFloat,
302 bool PositionIndependentExecutable, bool FunctionSections,
305 #if LLVM_VERSION_LE(3, 8)
308 Optional<Reloc::Model> RM;
310 auto CM = fromRust(RustCM);
311 auto OptLevel = fromRust(RustOptLevel);
314 case LLVMRelocStatic:
320 case LLVMRelocDynamicNoPic:
321 RM = Reloc::DynamicNoPIC;
324 #if LLVM_VERSION_LE(3, 8)
331 Triple Trip(Triple::normalize(TripleStr));
332 const llvm::Target *TheTarget =
333 TargetRegistry::lookupTarget(Trip.getTriple(), Error);
334 if (TheTarget == nullptr) {
335 LLVMRustSetLastError(Error.c_str());
339 StringRef RealCPU = CPU;
340 if (RealCPU == "native") {
341 RealCPU = sys::getHostCPUName();
344 TargetOptions Options;
345 #if LLVM_VERSION_LE(3, 8)
346 Options.PositionIndependentExecutable = PositionIndependentExecutable;
349 Options.FloatABIType = FloatABI::Default;
351 Options.FloatABIType = FloatABI::Soft;
353 Options.DataSections = DataSections;
354 Options.FunctionSections = FunctionSections;
356 TargetMachine *TM = TheTarget->createTargetMachine(
357 Trip.getTriple(), RealCPU, Feature, Options, RM, CM, OptLevel);
361 extern "C" void LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) {
365 // Unfortunately, LLVM doesn't expose a C API to add the corresponding analysis
366 // passes for a target to a pass manager. We export that functionality through
368 extern "C" void LLVMRustAddAnalysisPasses(LLVMTargetMachineRef TM,
369 LLVMPassManagerRef PMR,
371 PassManagerBase *PM = unwrap(PMR);
373 createTargetTransformInfoWrapperPass(unwrap(TM)->getTargetIRAnalysis()));
376 extern "C" void LLVMRustConfigurePassManagerBuilder(
377 LLVMPassManagerBuilderRef PMBR, LLVMRustCodeGenOptLevel OptLevel,
378 bool MergeFunctions, bool SLPVectorize, bool LoopVectorize) {
379 // Ignore mergefunc for now as enabling it causes crashes.
380 // unwrap(PMBR)->MergeFunctions = MergeFunctions;
381 unwrap(PMBR)->SLPVectorize = SLPVectorize;
382 unwrap(PMBR)->OptLevel = fromRust(OptLevel);
383 unwrap(PMBR)->LoopVectorize = LoopVectorize;
386 // Unfortunately, the LLVM C API doesn't provide a way to set the `LibraryInfo`
387 // field of a PassManagerBuilder, we expose our own method of doing so.
388 extern "C" void LLVMRustAddBuilderLibraryInfo(LLVMPassManagerBuilderRef PMBR,
390 bool DisableSimplifyLibCalls) {
391 Triple TargetTriple(unwrap(M)->getTargetTriple());
392 TargetLibraryInfoImpl *TLI = new TargetLibraryInfoImpl(TargetTriple);
393 if (DisableSimplifyLibCalls)
394 TLI->disableAllFunctions();
395 unwrap(PMBR)->LibraryInfo = TLI;
398 // Unfortunately, the LLVM C API doesn't provide a way to create the
399 // TargetLibraryInfo pass, so we use this method to do so.
400 extern "C" void LLVMRustAddLibraryInfo(LLVMPassManagerRef PMR, LLVMModuleRef M,
401 bool DisableSimplifyLibCalls) {
402 Triple TargetTriple(unwrap(M)->getTargetTriple());
403 TargetLibraryInfoImpl TLII(TargetTriple);
404 if (DisableSimplifyLibCalls)
405 TLII.disableAllFunctions();
406 unwrap(PMR)->add(new TargetLibraryInfoWrapperPass(TLII));
409 // Unfortunately, the LLVM C API doesn't provide an easy way of iterating over
410 // all the functions in a module, so we do that manually here. You'll find
411 // similar code in clang's BackendUtil.cpp file.
412 extern "C" void LLVMRustRunFunctionPassManager(LLVMPassManagerRef PMR,
414 llvm::legacy::FunctionPassManager *P =
415 unwrap<llvm::legacy::FunctionPassManager>(PMR);
416 P->doInitialization();
418 // Upgrade all calls to old intrinsics first.
419 for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E;)
420 UpgradeCallsToIntrinsic(&*I++); // must be post-increment, as we remove
422 for (Module::iterator I = unwrap(M)->begin(), E = unwrap(M)->end(); I != E;
424 if (!I->isDeclaration())
430 extern "C" void LLVMRustSetLLVMOptions(int Argc, char **Argv) {
431 // Initializing the command-line options more than once is not allowed. So,
432 // check if they've already been initialized. (This could happen if we're
433 // being called from rustpkg, for example). If the arguments change, then
434 // that's just kinda unfortunate.
435 static bool Initialized = false;
439 cl::ParseCommandLineOptions(Argc, Argv);
442 enum class LLVMRustFileType {
448 static TargetMachine::CodeGenFileType fromRust(LLVMRustFileType Type) {
450 case LLVMRustFileType::AssemblyFile:
451 return TargetMachine::CGFT_AssemblyFile;
452 case LLVMRustFileType::ObjectFile:
453 return TargetMachine::CGFT_ObjectFile;
455 llvm_unreachable("Bad FileType.");
459 extern "C" LLVMRustResult
460 LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, LLVMPassManagerRef PMR,
461 LLVMModuleRef M, const char *Path,
462 LLVMRustFileType RustFileType) {
463 llvm::legacy::PassManager *PM = unwrap<llvm::legacy::PassManager>(PMR);
464 auto FileType = fromRust(RustFileType);
466 std::string ErrorInfo;
468 raw_fd_ostream OS(Path, EC, sys::fs::F_None);
470 ErrorInfo = EC.message();
471 if (ErrorInfo != "") {
472 LLVMRustSetLastError(ErrorInfo.c_str());
473 return LLVMRustResult::Failure;
476 unwrap(Target)->addPassesToEmitFile(*PM, OS, FileType, false);
479 // Apparently `addPassesToEmitFile` adds a pointer to our on-the-stack output
480 // stream (OS), so the only real safe place to delete this is here? Don't we
481 // wish this was written in Rust?
483 return LLVMRustResult::Success;
486 extern "C" void LLVMRustPrintModule(LLVMPassManagerRef PMR, LLVMModuleRef M,
488 llvm::legacy::PassManager *PM = unwrap<llvm::legacy::PassManager>(PMR);
489 std::string ErrorInfo;
492 raw_fd_ostream OS(Path, EC, sys::fs::F_None);
494 ErrorInfo = EC.message();
496 formatted_raw_ostream FOS(OS);
498 PM->add(createPrintModulePass(FOS));
503 extern "C" void LLVMRustPrintPasses() {
504 LLVMInitializePasses();
505 struct MyListener : PassRegistrationListener {
506 void passEnumerate(const PassInfo *Info) {
507 #if LLVM_VERSION_GE(4, 0)
508 StringRef PassArg = Info->getPassArgument();
509 StringRef PassName = Info->getPassName();
510 if (!PassArg.empty()) {
511 // These unsigned->signed casts could theoretically overflow, but
512 // realistically never will (and even if, the result is implementation
513 // defined rather plain UB).
514 printf("%15.*s - %.*s\n", (int)PassArg.size(), PassArg.data(),
515 (int)PassName.size(), PassName.data());
518 if (Info->getPassArgument() && *Info->getPassArgument()) {
519 printf("%15s - %s\n", Info->getPassArgument(), Info->getPassName());
525 PassRegistry *PR = PassRegistry::getPassRegistry();
526 PR->enumerateWith(&Listener);
529 extern "C" void LLVMRustAddAlwaysInlinePass(LLVMPassManagerBuilderRef PMBR,
531 #if LLVM_VERSION_GE(4, 0)
532 unwrap(PMBR)->Inliner = llvm::createAlwaysInlinerLegacyPass(AddLifetimes);
534 unwrap(PMBR)->Inliner = createAlwaysInlinerPass(AddLifetimes);
538 extern "C" void LLVMRustRunRestrictionPass(LLVMModuleRef M, char **Symbols,
540 llvm::legacy::PassManager passes;
542 #if LLVM_VERSION_LE(3, 8)
543 ArrayRef<const char *> Ref(Symbols, Len);
544 passes.add(llvm::createInternalizePass(Ref));
546 auto PreserveFunctions = [=](const GlobalValue &GV) {
547 for (size_t I = 0; I < Len; I++) {
548 if (GV.getName() == Symbols[I]) {
555 passes.add(llvm::createInternalizePass(PreserveFunctions));
558 passes.run(*unwrap(M));
561 extern "C" void LLVMRustMarkAllFunctionsNounwind(LLVMModuleRef M) {
562 for (Module::iterator GV = unwrap(M)->begin(), E = unwrap(M)->end(); GV != E;
564 GV->setDoesNotThrow();
565 Function *F = dyn_cast<Function>(GV);
569 for (Function::iterator B = F->begin(), BE = F->end(); B != BE; ++B) {
570 for (BasicBlock::iterator I = B->begin(), IE = B->end(); I != IE; ++I) {
571 if (isa<InvokeInst>(I)) {
572 InvokeInst *CI = cast<InvokeInst>(I);
573 CI->setDoesNotThrow();
581 LLVMRustSetDataLayoutFromTargetMachine(LLVMModuleRef Module,
582 LLVMTargetMachineRef TMR) {
583 TargetMachine *Target = unwrap(TMR);
584 unwrap(Module)->setDataLayout(Target->createDataLayout());
587 extern "C" LLVMTargetDataRef LLVMRustGetModuleDataLayout(LLVMModuleRef M) {
588 return wrap(&unwrap(M)->getDataLayout());
591 extern "C" void LLVMRustSetModulePIELevel(LLVMModuleRef M) {
592 #if LLVM_VERSION_GE(3, 9)
593 unwrap(M)->setPIELevel(PIELevel::Level::Large);