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/Target/TargetLibraryInfo.h"
19 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
21 #include "llvm-c/Transforms/PassManagerBuilder.h"
25 extern cl::opt<bool> EnableARMEHABI;
27 typedef struct LLVMOpaquePass *LLVMPassRef;
28 typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef;
30 DEFINE_STDCXX_CONVERSION_FUNCTIONS(Pass, LLVMPassRef)
31 DEFINE_STDCXX_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
32 DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassManagerBuilder, LLVMPassManagerBuilderRef)
35 LLVMInitializePasses() {
36 PassRegistry &Registry = *PassRegistry::getPassRegistry();
37 initializeCore(Registry);
38 initializeCodeGen(Registry);
39 initializeScalarOpts(Registry);
40 initializeVectorization(Registry);
41 initializeIPO(Registry);
42 initializeAnalysis(Registry);
43 initializeIPA(Registry);
44 initializeTransformUtils(Registry);
45 initializeInstCombine(Registry);
46 initializeInstrumentation(Registry);
47 initializeTarget(Registry);
51 LLVMRustAddPass(LLVMPassManagerRef PM, const char *PassName) {
52 PassManagerBase *pm = unwrap(PM);
54 StringRef SR(PassName);
55 PassRegistry *PR = PassRegistry::getPassRegistry();
57 const PassInfo *PI = PR->getPassInfo(SR);
59 pm->add(PI->createPass());
65 extern "C" LLVMTargetMachineRef
66 LLVMRustCreateTargetMachine(const char *triple,
71 CodeGenOpt::Level OptLevel,
72 bool EnableSegmentedStacks,
74 bool NoFramePointerElim,
75 bool PositionIndependentExecutable,
76 bool FunctionSections,
79 Triple Trip(Triple::normalize(triple));
80 const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Trip.getTriple(),
82 if (TheTarget == NULL) {
83 LLVMRustSetLastError(Error.c_str());
87 StringRef real_cpu = cpu;
88 if (real_cpu == "native") {
89 real_cpu = sys::getHostCPUName();
92 TargetOptions Options;
93 Options.PositionIndependentExecutable = PositionIndependentExecutable;
94 Options.NoFramePointerElim = NoFramePointerElim;
95 Options.FloatABIType = FloatABI::Default;
96 Options.UseSoftFloat = UseSoftFloat;
98 Options.FloatABIType = FloatABI::Soft;
101 TargetMachine *TM = TheTarget->createTargetMachine(Trip.getTriple(),
108 TM->setDataSections(DataSections);
109 TM->setFunctionSections(FunctionSections);
114 LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) {
118 // Unfortunately, LLVM doesn't expose a C API to add the corresponding analysis
119 // passes for a target to a pass manager. We export that functionality through
122 LLVMRustAddAnalysisPasses(LLVMTargetMachineRef TM,
123 LLVMPassManagerRef PMR,
125 PassManagerBase *PM = unwrap(PMR);
126 #if LLVM_VERSION_MINOR >= 6
127 PM->add(new DataLayoutPass());
129 PM->add(new DataLayoutPass(unwrap(M)));
131 unwrap(TM)->addAnalysisPasses(*PM);
134 // Unfortunately, the LLVM C API doesn't provide a way to set the `LibraryInfo`
135 // field of a PassManagerBuilder, we expose our own method of doing so.
137 LLVMRustAddBuilderLibraryInfo(LLVMPassManagerBuilderRef PMB,
139 bool DisableSimplifyLibCalls) {
140 Triple TargetTriple(unwrap(M)->getTargetTriple());
141 TargetLibraryInfo *TLI = new TargetLibraryInfo(TargetTriple);
142 if (DisableSimplifyLibCalls)
143 TLI->disableAllFunctions();
144 unwrap(PMB)->LibraryInfo = TLI;
147 // Unfortunately, the LLVM C API doesn't provide a way to create the
148 // TargetLibraryInfo pass, so we use this method to do so.
150 LLVMRustAddLibraryInfo(LLVMPassManagerRef PMB,
152 bool DisableSimplifyLibCalls) {
153 Triple TargetTriple(unwrap(M)->getTargetTriple());
154 TargetLibraryInfo *TLI = new TargetLibraryInfo(TargetTriple);
155 if (DisableSimplifyLibCalls)
156 TLI->disableAllFunctions();
157 unwrap(PMB)->add(TLI);
160 // Unfortunately, the LLVM C API doesn't provide an easy way of iterating over
161 // all the functions in a module, so we do that manually here. You'll find
162 // similar code in clang's BackendUtil.cpp file.
164 LLVMRustRunFunctionPassManager(LLVMPassManagerRef PM, LLVMModuleRef M) {
165 FunctionPassManager *P = unwrap<FunctionPassManager>(PM);
166 P->doInitialization();
167 for (Module::iterator I = unwrap(M)->begin(),
168 E = unwrap(M)->end(); I != E; ++I)
169 if (!I->isDeclaration())
175 LLVMRustSetLLVMOptions(int Argc, char **Argv) {
176 // Initializing the command-line options more than once is not allowed. So,
177 // check if they've already been initialized. (This could happen if we're
178 // being called from rustpkg, for example). If the arguments change, then
179 // that's just kinda unfortunate.
180 static bool initialized = false;
181 if (initialized) return;
183 cl::ParseCommandLineOptions(Argc, Argv);
187 LLVMRustWriteOutputFile(LLVMTargetMachineRef Target,
188 LLVMPassManagerRef PMR,
191 TargetMachine::CodeGenFileType FileType) {
192 PassManager *PM = unwrap<PassManager>(PMR);
194 std::string ErrorInfo;
195 #if LLVM_VERSION_MINOR >= 6
197 raw_fd_ostream OS(path, EC, sys::fs::F_None);
199 ErrorInfo = EC.message();
201 raw_fd_ostream OS(path, ErrorInfo, sys::fs::F_None);
203 if (ErrorInfo != "") {
204 LLVMRustSetLastError(ErrorInfo.c_str());
207 formatted_raw_ostream FOS(OS);
209 unwrap(Target)->addPassesToEmitFile(*PM, FOS, FileType, false);
215 LLVMRustPrintModule(LLVMPassManagerRef PMR,
218 PassManager *PM = unwrap<PassManager>(PMR);
219 std::string ErrorInfo;
221 #if LLVM_VERSION_MINOR >= 6
223 raw_fd_ostream OS(path, EC, sys::fs::F_None);
225 ErrorInfo = EC.message();
227 raw_fd_ostream OS(path, ErrorInfo, sys::fs::F_None);
230 formatted_raw_ostream FOS(OS);
232 PM->add(createPrintModulePass(FOS));
238 LLVMRustPrintPasses() {
239 LLVMInitializePasses();
240 struct MyListener : PassRegistrationListener {
241 void passEnumerate(const PassInfo *info) {
242 if (info->getPassArgument() && *info->getPassArgument()) {
243 printf("%15s - %s\n", info->getPassArgument(),
244 info->getPassName());
249 PassRegistry *PR = PassRegistry::getPassRegistry();
250 PR->enumerateWith(&listener);
254 LLVMRustAddAlwaysInlinePass(LLVMPassManagerBuilderRef PMB, bool AddLifetimes) {
255 unwrap(PMB)->Inliner = createAlwaysInlinerPass(AddLifetimes);
259 LLVMRustRunRestrictionPass(LLVMModuleRef M, char **symbols, size_t len) {
261 ArrayRef<const char*> ref(symbols, len);
262 passes.add(llvm::createInternalizePass(ref));
263 passes.run(*unwrap(M));
267 LLVMRustMarkAllFunctionsNounwind(LLVMModuleRef M) {
268 for (Module::iterator GV = unwrap(M)->begin(),
269 E = unwrap(M)->end(); GV != E; ++GV) {
270 GV->setDoesNotThrow();
271 Function *F = dyn_cast<Function>(GV);
275 for (Function::iterator B = F->begin(), BE = F->end(); B != BE; ++B) {
276 for (BasicBlock::iterator I = B->begin(), IE = B->end();
278 if (isa<InvokeInst>(I)) {
279 InvokeInst *CI = cast<InvokeInst>(I);
280 CI->setDoesNotThrow();