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/Target/TargetLibraryInfo.h"
18 #include "llvm/Transforms/IPO/PassManagerBuilder.h"
20 #include "llvm-c/Transforms/PassManagerBuilder.h"
24 extern cl::opt<bool> EnableARMEHABI;
26 typedef struct LLVMOpaquePass *LLVMPassRef;
27 typedef struct LLVMOpaqueTargetMachine *LLVMTargetMachineRef;
29 DEFINE_STDCXX_CONVERSION_FUNCTIONS(Pass, LLVMPassRef)
30 DEFINE_STDCXX_CONVERSION_FUNCTIONS(TargetMachine, LLVMTargetMachineRef)
31 DEFINE_STDCXX_CONVERSION_FUNCTIONS(PassManagerBuilder, LLVMPassManagerBuilderRef)
34 LLVMInitializePasses() {
35 PassRegistry &Registry = *PassRegistry::getPassRegistry();
36 initializeCore(Registry);
37 initializeCodeGen(Registry);
38 initializeScalarOpts(Registry);
39 initializeVectorization(Registry);
40 initializeIPO(Registry);
41 initializeAnalysis(Registry);
42 initializeIPA(Registry);
43 initializeTransformUtils(Registry);
44 initializeInstCombine(Registry);
45 initializeInstrumentation(Registry);
46 initializeTarget(Registry);
50 LLVMRustAddPass(LLVMPassManagerRef PM, const char *PassName) {
51 PassManagerBase *pm = unwrap(PM);
53 StringRef SR(PassName);
54 PassRegistry *PR = PassRegistry::getPassRegistry();
56 const PassInfo *PI = PR->getPassInfo(SR);
58 pm->add(PI->createPass());
64 extern "C" LLVMTargetMachineRef
65 LLVMRustCreateTargetMachine(const char *triple,
70 CodeGenOpt::Level OptLevel,
71 bool EnableSegmentedStacks,
73 bool NoFramePointerElim,
74 bool FunctionSections,
77 Triple Trip(Triple::normalize(triple));
78 const llvm::Target *TheTarget = TargetRegistry::lookupTarget(Trip.getTriple(),
80 if (TheTarget == NULL) {
81 LLVMRustSetLastError(Error.c_str());
85 TargetOptions Options;
86 Options.NoFramePointerElim = NoFramePointerElim;
87 #if LLVM_VERSION_MINOR < 5
88 Options.EnableSegmentedStacks = EnableSegmentedStacks;
90 Options.FloatABIType = FloatABI::Default;
91 Options.UseSoftFloat = UseSoftFloat;
93 Options.FloatABIType = FloatABI::Soft;
96 TargetMachine *TM = TheTarget->createTargetMachine(Trip.getTriple(),
103 TM->setDataSections(DataSections);
104 TM->setFunctionSections(FunctionSections);
109 LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM) {
113 // Unfortunately, LLVM doesn't expose a C API to add the corresponding analysis
114 // passes for a target to a pass manager. We export that functionality through
117 LLVMRustAddAnalysisPasses(LLVMTargetMachineRef TM,
118 LLVMPassManagerRef PMR,
120 PassManagerBase *PM = unwrap(PMR);
121 #if LLVM_VERSION_MINOR >= 5
122 PM->add(new DataLayoutPass(unwrap(M)));
124 PM->add(new DataLayout(unwrap(M)));
126 unwrap(TM)->addAnalysisPasses(*PM);
129 // Unfortunately, the LLVM C API doesn't provide a way to set the `LibraryInfo`
130 // field of a PassManagerBuilder, we expose our own method of doing so.
132 LLVMRustAddBuilderLibraryInfo(LLVMPassManagerBuilderRef PMB,
134 bool DisableSimplifyLibCalls) {
135 Triple TargetTriple(unwrap(M)->getTargetTriple());
136 TargetLibraryInfo *TLI = new TargetLibraryInfo(TargetTriple);
137 if (DisableSimplifyLibCalls)
138 TLI->disableAllFunctions();
139 unwrap(PMB)->LibraryInfo = TLI;
142 // Unfortunately, the LLVM C API doesn't provide a way to create the
143 // TargetLibraryInfo pass, so we use this method to do so.
145 LLVMRustAddLibraryInfo(LLVMPassManagerRef PMB,
147 bool DisableSimplifyLibCalls) {
148 Triple TargetTriple(unwrap(M)->getTargetTriple());
149 TargetLibraryInfo *TLI = new TargetLibraryInfo(TargetTriple);
150 if (DisableSimplifyLibCalls)
151 TLI->disableAllFunctions();
152 unwrap(PMB)->add(TLI);
155 // Unfortunately, the LLVM C API doesn't provide an easy way of iterating over
156 // all the functions in a module, so we do that manually here. You'll find
157 // similar code in clang's BackendUtil.cpp file.
159 LLVMRustRunFunctionPassManager(LLVMPassManagerRef PM, LLVMModuleRef M) {
160 FunctionPassManager *P = unwrap<FunctionPassManager>(PM);
161 P->doInitialization();
162 for (Module::iterator I = unwrap(M)->begin(),
163 E = unwrap(M)->end(); I != E; ++I)
164 if (!I->isDeclaration())
170 LLVMRustSetLLVMOptions(int Argc, char **Argv) {
171 // Initializing the command-line options more than once is not allowed. So,
172 // check if they've already been initialized. (This could happen if we're
173 // being called from rustpkg, for example). If the arguments change, then
174 // that's just kinda unfortunate.
175 static bool initialized = false;
176 if (initialized) return;
178 cl::ParseCommandLineOptions(Argc, Argv);
182 LLVMRustWriteOutputFile(LLVMTargetMachineRef Target,
183 LLVMPassManagerRef PMR,
186 TargetMachine::CodeGenFileType FileType) {
187 PassManager *PM = unwrap<PassManager>(PMR);
189 std::string ErrorInfo;
190 #if LLVM_VERSION_MINOR >= 4
191 raw_fd_ostream OS(path, ErrorInfo, sys::fs::F_None);
193 raw_fd_ostream OS(path, ErrorInfo, raw_fd_ostream::F_Binary);
195 if (ErrorInfo != "") {
196 LLVMRustSetLastError(ErrorInfo.c_str());
199 formatted_raw_ostream FOS(OS);
201 unwrap(Target)->addPassesToEmitFile(*PM, FOS, FileType, false);
207 LLVMRustPrintModule(LLVMPassManagerRef PMR,
210 PassManager *PM = unwrap<PassManager>(PMR);
211 std::string ErrorInfo;
213 #if LLVM_VERSION_MINOR >= 4
214 raw_fd_ostream OS(path, ErrorInfo, sys::fs::F_None);
216 raw_fd_ostream OS(path, ErrorInfo, raw_fd_ostream::F_Binary);
219 formatted_raw_ostream FOS(OS);
221 #if LLVM_VERSION_MINOR >= 5
222 PM->add(createPrintModulePass(FOS));
224 PM->add(createPrintModulePass(&FOS));
231 LLVMRustPrintPasses() {
232 LLVMInitializePasses();
233 struct MyListener : PassRegistrationListener {
234 void passEnumerate(const PassInfo *info) {
235 if (info->getPassArgument() && *info->getPassArgument()) {
236 printf("%15s - %s\n", info->getPassArgument(),
237 info->getPassName());
242 PassRegistry *PR = PassRegistry::getPassRegistry();
243 PR->enumerateWith(&listener);
247 LLVMRustAddAlwaysInlinePass(LLVMPassManagerBuilderRef PMB, bool AddLifetimes) {
248 unwrap(PMB)->Inliner = createAlwaysInlinerPass(AddLifetimes);
252 LLVMRustRunRestrictionPass(LLVMModuleRef M, char **symbols, size_t len) {
254 ArrayRef<const char*> ref(symbols, len);
255 passes.add(llvm::createInternalizePass(ref));
256 passes.run(*unwrap(M));
260 LLVMRustMarkAllFunctionsNounwind(LLVMModuleRef M) {
261 for (Module::iterator GV = unwrap(M)->begin(),
262 E = unwrap(M)->end(); GV != E; ++GV) {
263 GV->setDoesNotThrow();
264 Function *F = dyn_cast<Function>(GV);
268 for (Function::iterator B = F->begin(), BE = F->end(); B != BE; ++B) {
269 for (BasicBlock::iterator I = B->begin(), IE = B->end();
271 if (isa<InvokeInst>(I)) {
272 InvokeInst *CI = cast<InvokeInst>(I);
273 CI->setDoesNotThrow();