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/Support/CBindingWrapping.h"
16 #include "llvm/Support/FileSystem.h"
17 #include "llvm/Support/Host.h"
18 #include "llvm/Analysis/TargetLibraryInfo.h"
19 #include "llvm/Analysis/TargetTransformInfo.h"
20 #include "llvm/IR/AutoUpgrade.h"
21 #include "llvm/Target/TargetMachine.h"
22 #include "llvm/Target/TargetSubtargetInfo.h"
23 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
26 #include "llvm-c/Transforms/PassManagerBuilder.h"
29 using namespace llvm::legacy;
31 extern cl::opt<bool> EnableARMEHABI;
33 typedef struct LLVMOpaquePass *LLVMPassRef;
34 typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef;
36 DEFINE_STDCXX_CONVERSION_FUNCTIONS(Pass, LLVMPassRef)
37 DEFINE_STDCXX_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
38 DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassManagerBuilder, LLVMPassManagerBuilderRef)
41 LLVMInitializePasses() {
42 PassRegistry &Registry = *PassRegistry::getPassRegistry();
43 initializeCore(Registry);
44 initializeCodeGen(Registry);
45 initializeScalarOpts(Registry);
46 initializeVectorization(Registry);
47 initializeIPO(Registry);
48 initializeAnalysis(Registry);
49 #if LLVM_VERSION_MINOR == 7
50 initializeIPA(Registry);
52 initializeTransformUtils(Registry);
53 initializeInstCombine(Registry);
54 initializeInstrumentation(Registry);
55 initializeTarget(Registry);
58 enum class LLVMRustPassKind {
64 static LLVMRustPassKind
65 to_rust(PassKind kind)
69 return LLVMRustPassKind::Function;
71 return LLVMRustPassKind::Module;
73 return LLVMRustPassKind::Other;
77 extern "C" LLVMPassRef
78 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
90 LLVMRustPassKind(LLVMPassRef rust_pass) {
92 Pass *pass = unwrap(rust_pass);
93 return to_rust(pass->getPassKind());
97 LLVMRustAddPass(LLVMPassManagerRef PM, LLVMPassRef rust_pass) {
99 Pass *pass = unwrap(rust_pass);
100 PassManagerBase *pm = unwrap(PM);
104 #ifdef LLVM_COMPONENT_X86
105 #define SUBTARGET_X86 SUBTARGET(X86)
107 #define SUBTARGET_X86
110 #ifdef LLVM_COMPONENT_ARM
111 #define SUBTARGET_ARM SUBTARGET(ARM)
113 #define SUBTARGET_ARM
116 #ifdef LLVM_COMPONENT_AARCH64
117 #define SUBTARGET_AARCH64 SUBTARGET(AArch64)
119 #define SUBTARGET_AARCH64
122 #ifdef LLVM_COMPONENT_MIPS
123 #define SUBTARGET_MIPS SUBTARGET(Mips)
125 #define SUBTARGET_MIPS
128 #ifdef LLVM_COMPONENT_POWERPC
129 #define SUBTARGET_PPC SUBTARGET(PPC)
131 #define SUBTARGET_PPC
134 #define GEN_SUBTARGETS \
141 #define SUBTARGET(x) namespace llvm { \
142 extern const SubtargetFeatureKV x##FeatureKV[]; \
143 extern const SubtargetFeatureKV x##SubTypeKV[]; \
150 LLVMRustHasFeature(LLVMTargetMachineRef TM,
151 const char *feature) {
152 TargetMachine *Target = unwrap(TM);
153 const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
154 const FeatureBitset &Bits = MCInfo->getFeatureBits();
155 const llvm::SubtargetFeatureKV *FeatureEntry;
157 #define SUBTARGET(x) \
158 if (MCInfo->isCPUStringValid(x##SubTypeKV[0].Key)) { \
159 FeatureEntry = x##FeatureKV; \
167 while (strcmp(feature, FeatureEntry->Key) != 0)
170 return (Bits & FeatureEntry->Value) == FeatureEntry->Value;
173 enum class LLVMRustCodeModel {
183 static CodeModel::Model
184 from_rust(LLVMRustCodeModel model)
187 case LLVMRustCodeModel::Default:
188 return CodeModel::Default;
189 case LLVMRustCodeModel::JITDefault:
190 return CodeModel::JITDefault;
191 case LLVMRustCodeModel::Small:
192 return CodeModel::Small;
193 case LLVMRustCodeModel::Kernel:
194 return CodeModel::Kernel;
195 case LLVMRustCodeModel::Medium:
196 return CodeModel::Medium;
197 case LLVMRustCodeModel::Large:
198 return CodeModel::Large;
200 llvm_unreachable("Bad CodeModel.");
204 enum class LLVMRustCodeGenOptLevel {
212 static CodeGenOpt::Level
213 from_rust(LLVMRustCodeGenOptLevel level)
216 case LLVMRustCodeGenOptLevel::None:
217 return CodeGenOpt::None;
218 case LLVMRustCodeGenOptLevel::Less:
219 return CodeGenOpt::Less;
220 case LLVMRustCodeGenOptLevel::Default:
221 return CodeGenOpt::Default;
222 case LLVMRustCodeGenOptLevel::Aggressive:
223 return CodeGenOpt::Aggressive;
225 llvm_unreachable("Bad CodeGenOptLevel.");
229 extern "C" LLVMTargetMachineRef
230 LLVMRustCreateTargetMachine(const char *triple,
233 LLVMRustCodeModel rust_CM,
235 LLVMRustCodeGenOptLevel rust_OptLevel,
237 bool PositionIndependentExecutable,
238 bool FunctionSections,
241 #if LLVM_VERSION_MINOR <= 8
244 Optional<Reloc::Model> RM;
246 auto CM = from_rust(rust_CM);
247 auto OptLevel = from_rust(rust_OptLevel);
250 case LLVMRelocStatic:
256 case LLVMRelocDynamicNoPic:
257 RM = Reloc::DynamicNoPIC;
260 #if LLVM_VERSION_MINOR <= 8
267 Triple Trip(Triple::normalize(triple));
268 const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Trip.getTriple(),
270 if (TheTarget == NULL) {
271 LLVMRustSetLastError(Error.c_str());
275 StringRef real_cpu = cpu;
276 if (real_cpu == "native") {
277 real_cpu = sys::getHostCPUName();
280 TargetOptions Options;
281 #if LLVM_VERSION_MINOR <= 8
282 Options.PositionIndependentExecutable = PositionIndependentExecutable;
285 Options.FloatABIType = FloatABI::Default;
287 Options.FloatABIType = FloatABI::Soft;
289 Options.DataSections = DataSections;
290 Options.FunctionSections = FunctionSections;
292 TargetMachine *TM = TheTarget->createTargetMachine(Trip.getTriple(),
303 LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) {
307 // Unfortunately, LLVM doesn't expose a C API to add the corresponding analysis
308 // passes for a target to a pass manager. We export that functionality through
311 LLVMRustAddAnalysisPasses(LLVMTargetMachineRef TM,
312 LLVMPassManagerRef PMR,
314 PassManagerBase *PM = unwrap(PMR);
315 PM->add(createTargetTransformInfoWrapperPass(
316 unwrap(TM)->getTargetIRAnalysis()));
320 LLVMRustConfigurePassManagerBuilder(LLVMPassManagerBuilderRef PMB,
321 LLVMRustCodeGenOptLevel OptLevel,
324 bool LoopVectorize) {
325 // Ignore mergefunc for now as enabling it causes crashes.
326 //unwrap(PMB)->MergeFunctions = MergeFunctions;
327 unwrap(PMB)->SLPVectorize = SLPVectorize;
328 unwrap(PMB)->OptLevel = from_rust(OptLevel);
329 unwrap(PMB)->LoopVectorize = LoopVectorize;
332 // Unfortunately, the LLVM C API doesn't provide a way to set the `LibraryInfo`
333 // field of a PassManagerBuilder, we expose our own method of doing so.
335 LLVMRustAddBuilderLibraryInfo(LLVMPassManagerBuilderRef PMB,
337 bool DisableSimplifyLibCalls) {
338 Triple TargetTriple(unwrap(M)->getTargetTriple());
339 TargetLibraryInfoImpl *TLI = new TargetLibraryInfoImpl(TargetTriple);
340 if (DisableSimplifyLibCalls)
341 TLI->disableAllFunctions();
342 unwrap(PMB)->LibraryInfo = TLI;
345 // Unfortunately, the LLVM C API doesn't provide a way to create the
346 // TargetLibraryInfo pass, so we use this method to do so.
348 LLVMRustAddLibraryInfo(LLVMPassManagerRef PMB,
350 bool DisableSimplifyLibCalls) {
351 Triple TargetTriple(unwrap(M)->getTargetTriple());
352 TargetLibraryInfoImpl TLII(TargetTriple);
353 if (DisableSimplifyLibCalls)
354 TLII.disableAllFunctions();
355 unwrap(PMB)->add(new TargetLibraryInfoWrapperPass(TLII));
358 // Unfortunately, the LLVM C API doesn't provide an easy way of iterating over
359 // all the functions in a module, so we do that manually here. You'll find
360 // similar code in clang's BackendUtil.cpp file.
362 LLVMRustRunFunctionPassManager(LLVMPassManagerRef PM, LLVMModuleRef M) {
363 llvm::legacy::FunctionPassManager *P = unwrap<llvm::legacy::FunctionPassManager>(PM);
364 P->doInitialization();
366 // Upgrade all calls to old intrinsics first.
367 for (Module::iterator I = unwrap(M)->begin(),
368 E = unwrap(M)->end(); I != E;)
369 UpgradeCallsToIntrinsic(&*I++); // must be post-increment, as we remove
371 for (Module::iterator I = unwrap(M)->begin(),
372 E = unwrap(M)->end(); I != E; ++I)
373 if (!I->isDeclaration())
380 LLVMRustSetLLVMOptions(int Argc, char **Argv) {
381 // Initializing the command-line options more than once is not allowed. So,
382 // check if they've already been initialized. (This could happen if we're
383 // being called from rustpkg, for example). If the arguments change, then
384 // that's just kinda unfortunate.
385 static bool initialized = false;
386 if (initialized) return;
388 cl::ParseCommandLineOptions(Argc, Argv);
391 enum class LLVMRustFileType {
397 static TargetMachine::CodeGenFileType
398 from_rust(LLVMRustFileType type)
401 case LLVMRustFileType::AssemblyFile:
402 return TargetMachine::CGFT_AssemblyFile;
403 case LLVMRustFileType::ObjectFile:
404 return TargetMachine::CGFT_ObjectFile;
406 llvm_unreachable("Bad FileType.");
410 extern "C" LLVMRustResult
411 LLVMRustWriteOutputFile(LLVMTargetMachineRef Target,
412 LLVMPassManagerRef PMR,
415 LLVMRustFileType rust_FileType) {
416 llvm::legacy::PassManager *PM = unwrap<llvm::legacy::PassManager>(PMR);
417 auto FileType = from_rust(rust_FileType);
419 std::string ErrorInfo;
421 raw_fd_ostream OS(path, EC, sys::fs::F_None);
423 ErrorInfo = EC.message();
424 if (ErrorInfo != "") {
425 LLVMRustSetLastError(ErrorInfo.c_str());
426 return LLVMRustResult::Failure;
429 unwrap(Target)->addPassesToEmitFile(*PM, OS, FileType, false);
432 // Apparently `addPassesToEmitFile` adds a pointer to our on-the-stack output
433 // stream (OS), so the only real safe place to delete this is here? Don't we
434 // wish this was written in Rust?
436 return LLVMRustResult::Success;
440 LLVMRustPrintModule(LLVMPassManagerRef PMR,
443 llvm::legacy::PassManager *PM = unwrap<llvm::legacy::PassManager>(PMR);
444 std::string ErrorInfo;
447 raw_fd_ostream OS(path, EC, sys::fs::F_None);
449 ErrorInfo = EC.message();
451 formatted_raw_ostream FOS(OS);
453 PM->add(createPrintModulePass(FOS));
459 LLVMRustPrintPasses() {
460 LLVMInitializePasses();
461 struct MyListener : PassRegistrationListener {
462 void passEnumerate(const PassInfo *info) {
463 if (info->getPassArgument() && *info->getPassArgument()) {
464 printf("%15s - %s\n", info->getPassArgument(),
465 info->getPassName());
470 PassRegistry *PR = PassRegistry::getPassRegistry();
471 PR->enumerateWith(&listener);
475 LLVMRustAddAlwaysInlinePass(LLVMPassManagerBuilderRef PMB, bool AddLifetimes) {
476 unwrap(PMB)->Inliner = createAlwaysInlinerPass(AddLifetimes);
480 LLVMRustRunRestrictionPass(LLVMModuleRef M, char **symbols, size_t len) {
481 llvm::legacy::PassManager passes;
483 #if LLVM_VERSION_MINOR <= 8
484 ArrayRef<const char*> ref(symbols, len);
485 passes.add(llvm::createInternalizePass(ref));
487 auto PreserveFunctions = [=](const GlobalValue &GV) {
488 for (size_t i=0; i<len; i++) {
489 if (GV.getName() == symbols[i]) {
496 passes.add(llvm::createInternalizePass(PreserveFunctions));
499 passes.run(*unwrap(M));
503 LLVMRustMarkAllFunctionsNounwind(LLVMModuleRef M) {
504 for (Module::iterator GV = unwrap(M)->begin(),
505 E = unwrap(M)->end(); GV != E; ++GV) {
506 GV->setDoesNotThrow();
507 Function *F = dyn_cast<Function>(GV);
511 for (Function::iterator B = F->begin(), BE = F->end(); B != BE; ++B) {
512 for (BasicBlock::iterator I = B->begin(), IE = B->end();
514 if (isa<InvokeInst>(I)) {
515 InvokeInst *CI = cast<InvokeInst>(I);
516 CI->setDoesNotThrow();
524 LLVMRustSetDataLayoutFromTargetMachine(LLVMModuleRef Module,
525 LLVMTargetMachineRef TMR) {
526 TargetMachine *Target = unwrap(TMR);
527 unwrap(Module)->setDataLayout(Target->createDataLayout());
530 extern "C" LLVMTargetDataRef
531 LLVMRustGetModuleDataLayout(LLVMModuleRef M) {
532 return wrap(&unwrap(M)->getDataLayout());
536 LLVMRustSetModulePIELevel(LLVMModuleRef M) {
537 #if LLVM_VERSION_MINOR >= 9
538 unwrap(M)->setPIELevel(PIELevel::Level::Large);