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 #if LLVM_VERSION_MINOR >= 7
19 #include "llvm/Analysis/TargetLibraryInfo.h"
20 #include "llvm/Analysis/TargetTransformInfo.h"
22 #include "llvm/Target/TargetLibraryInfo.h"
24 #include "llvm/Target/TargetMachine.h"
25 #include "llvm/Target/TargetSubtargetInfo.h"
26 #include "llvm/Transforms/IPO/PassManagerBuilder.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
, LLVMPassManagerBuilderRef
)
44 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 initializeIPA(Registry
);
53 initializeTransformUtils(Registry
);
54 initializeInstCombine(Registry
);
55 initializeInstrumentation(Registry
);
56 initializeTarget(Registry
);
60 LLVMRustAddPass(LLVMPassManagerRef PM
, const char *PassName
) {
61 PassManagerBase
*pm
= unwrap(PM
);
63 StringRef
SR(PassName
);
64 PassRegistry
*PR
= PassRegistry::getPassRegistry();
66 const PassInfo
*PI
= PR
->getPassInfo(SR
);
68 pm
->add(PI
->createPass());
74 extern "C" LLVMTargetMachineRef
75 LLVMRustCreateTargetMachine(const char *triple
,
80 CodeGenOpt::Level OptLevel
,
81 bool EnableSegmentedStacks
,
83 bool PositionIndependentExecutable
,
84 bool FunctionSections
,
87 Triple
Trip(Triple::normalize(triple
));
88 const llvm::Target
*TheTarget
= TargetRegistry::lookupTarget(Trip
.getTriple(),
90 if (TheTarget
== NULL
) {
91 LLVMRustSetLastError(Error
.c_str());
95 StringRef real_cpu
= cpu
;
96 if (real_cpu
== "native") {
97 real_cpu
= sys::getHostCPUName();
100 TargetOptions Options
;
101 Options
.PositionIndependentExecutable
= PositionIndependentExecutable
;
102 Options
.FloatABIType
= FloatABI::Default
;
104 Options
.FloatABIType
= FloatABI::Soft
;
106 Options
.DataSections
= DataSections
;
107 Options
.FunctionSections
= FunctionSections
;
109 TargetMachine
*TM
= TheTarget
->createTargetMachine(Trip
.getTriple(),
120 LLVMRustDisposeTargetMachine(LLVMTargetMachineRef TM
) {
124 // Unfortunately, LLVM doesn't expose a C API to add the corresponding analysis
125 // passes for a target to a pass manager. We export that functionality through
128 LLVMRustAddAnalysisPasses(LLVMTargetMachineRef TM
,
129 LLVMPassManagerRef PMR
,
131 PassManagerBase
*PM
= unwrap(PMR
);
132 #if LLVM_VERSION_MINOR >= 7
133 PM
->add(createTargetTransformInfoWrapperPass(
134 unwrap(TM
)->getTargetIRAnalysis()));
136 #if LLVM_VERSION_MINOR == 6
137 PM
->add(new DataLayoutPass());
139 PM
->add(new DataLayoutPass(unwrap(M
)));
141 unwrap(TM
)->addAnalysisPasses(*PM
);
146 LLVMRustConfigurePassManagerBuilder(LLVMPassManagerBuilderRef PMB
,
147 CodeGenOpt::Level OptLevel
,
150 bool LoopVectorize
) {
151 #if LLVM_VERSION_MINOR >= 6
152 // Ignore mergefunc for now as enabling it causes crashes.
153 //unwrap(PMB)->MergeFunctions = MergeFunctions;
155 unwrap(PMB
)->SLPVectorize
= SLPVectorize
;
156 unwrap(PMB
)->OptLevel
= OptLevel
;
157 unwrap(PMB
)->LoopVectorize
= LoopVectorize
;
160 // Unfortunately, the LLVM C API doesn't provide a way to set the `LibraryInfo`
161 // field of a PassManagerBuilder, we expose our own method of doing so.
163 LLVMRustAddBuilderLibraryInfo(LLVMPassManagerBuilderRef PMB
,
165 bool DisableSimplifyLibCalls
) {
166 Triple
TargetTriple(unwrap(M
)->getTargetTriple());
167 #if LLVM_VERSION_MINOR >= 7
168 TargetLibraryInfoImpl
*TLI
= new TargetLibraryInfoImpl(TargetTriple
);
170 TargetLibraryInfo
*TLI
= new TargetLibraryInfo(TargetTriple
);
172 if (DisableSimplifyLibCalls
)
173 TLI
->disableAllFunctions();
174 unwrap(PMB
)->LibraryInfo
= TLI
;
177 // Unfortunately, the LLVM C API doesn't provide a way to create the
178 // TargetLibraryInfo pass, so we use this method to do so.
180 LLVMRustAddLibraryInfo(LLVMPassManagerRef PMB
,
182 bool DisableSimplifyLibCalls
) {
183 Triple
TargetTriple(unwrap(M
)->getTargetTriple());
184 #if LLVM_VERSION_MINOR >= 7
185 TargetLibraryInfoImpl
TLII(TargetTriple
);
186 if (DisableSimplifyLibCalls
)
187 TLII
.disableAllFunctions();
188 unwrap(PMB
)->add(new TargetLibraryInfoWrapperPass(TLII
));
190 TargetLibraryInfo
*TLI
= new TargetLibraryInfo(TargetTriple
);
191 if (DisableSimplifyLibCalls
)
192 TLI
->disableAllFunctions();
193 unwrap(PMB
)->add(TLI
);
197 // Unfortunately, the LLVM C API doesn't provide an easy way of iterating over
198 // all the functions in a module, so we do that manually here. You'll find
199 // similar code in clang's BackendUtil.cpp file.
201 LLVMRustRunFunctionPassManager(LLVMPassManagerRef PM
, LLVMModuleRef M
) {
202 FunctionPassManager
*P
= unwrap
<FunctionPassManager
>(PM
);
203 P
->doInitialization();
204 for (Module::iterator I
= unwrap(M
)->begin(),
205 E
= unwrap(M
)->end(); I
!= E
; ++I
)
206 if (!I
->isDeclaration())
212 LLVMRustSetLLVMOptions(int Argc
, char **Argv
) {
213 // Initializing the command-line options more than once is not allowed. So,
214 // check if they've already been initialized. (This could happen if we're
215 // being called from rustpkg, for example). If the arguments change, then
216 // that's just kinda unfortunate.
217 static bool initialized
= false;
218 if (initialized
) return;
220 cl::ParseCommandLineOptions(Argc
, Argv
);
224 LLVMRustWriteOutputFile(LLVMTargetMachineRef Target
,
225 LLVMPassManagerRef PMR
,
228 TargetMachine::CodeGenFileType FileType
) {
229 PassManager
*PM
= unwrap
<PassManager
>(PMR
);
231 std::string ErrorInfo
;
232 #if LLVM_VERSION_MINOR >= 6
234 raw_fd_ostream
OS(path
, EC
, sys::fs::F_None
);
236 ErrorInfo
= EC
.message();
238 raw_fd_ostream
OS(path
, ErrorInfo
, sys::fs::F_None
);
240 if (ErrorInfo
!= "") {
241 LLVMRustSetLastError(ErrorInfo
.c_str());
245 #if LLVM_VERSION_MINOR >= 7
246 unwrap(Target
)->addPassesToEmitFile(*PM
, OS
, FileType
, false);
248 formatted_raw_ostream
FOS(OS
);
249 unwrap(Target
)->addPassesToEmitFile(*PM
, FOS
, FileType
, false);
253 // Apparently `addPassesToEmitFile` adds an pointer to our on-the-stack output
254 // stream (OS), so the only real safe place to delete this is here? Don't we
255 // wish this was written in Rust?
261 LLVMRustPrintModule(LLVMPassManagerRef PMR
,
264 PassManager
*PM
= unwrap
<PassManager
>(PMR
);
265 std::string ErrorInfo
;
267 #if LLVM_VERSION_MINOR >= 6
269 raw_fd_ostream
OS(path
, EC
, sys::fs::F_None
);
271 ErrorInfo
= EC
.message();
273 raw_fd_ostream
OS(path
, ErrorInfo
, sys::fs::F_None
);
276 formatted_raw_ostream
FOS(OS
);
278 PM
->add(createPrintModulePass(FOS
));
284 LLVMRustPrintPasses() {
285 LLVMInitializePasses();
286 struct MyListener
: PassRegistrationListener
{
287 void passEnumerate(const PassInfo
*info
) {
288 if (info
->getPassArgument() && *info
->getPassArgument()) {
289 printf("%15s - %s\n", info
->getPassArgument(),
290 info
->getPassName());
295 PassRegistry
*PR
= PassRegistry::getPassRegistry();
296 PR
->enumerateWith(&listener
);
300 LLVMRustAddAlwaysInlinePass(LLVMPassManagerBuilderRef PMB
, bool AddLifetimes
) {
301 unwrap(PMB
)->Inliner
= createAlwaysInlinerPass(AddLifetimes
);
305 LLVMRustRunRestrictionPass(LLVMModuleRef M
, char **symbols
, size_t len
) {
307 ArrayRef
<const char*> ref(symbols
, len
);
308 passes
.add(llvm::createInternalizePass(ref
));
309 passes
.run(*unwrap(M
));
313 LLVMRustMarkAllFunctionsNounwind(LLVMModuleRef M
) {
314 for (Module::iterator GV
= unwrap(M
)->begin(),
315 E
= unwrap(M
)->end(); GV
!= E
; ++GV
) {
316 GV
->setDoesNotThrow();
317 Function
*F
= dyn_cast
<Function
>(GV
);
321 for (Function::iterator B
= F
->begin(), BE
= F
->end(); B
!= BE
; ++B
) {
322 for (BasicBlock::iterator I
= B
->begin(), IE
= B
->end();
324 if (isa
<InvokeInst
>(I
)) {
325 InvokeInst
*CI
= cast
<InvokeInst
>(I
);
326 CI
->setDoesNotThrow();
334 LLVMRustSetDataLayoutFromTargetMachine(LLVMModuleRef Module
,
335 LLVMTargetMachineRef TMR
) {
336 TargetMachine
*Target
= unwrap(TMR
);
337 #if LLVM_VERSION_MINOR >= 7
338 if (const DataLayout
*DL
= Target
->getDataLayout())
339 unwrap(Module
)->setDataLayout(*DL
);
340 #elif LLVM_VERSION_MINOR >= 6
341 if (const DataLayout
*DL
= Target
->getSubtargetImpl()->getDataLayout())
342 unwrap(Module
)->setDataLayout(DL
);
344 if (const DataLayout
*DL
= Target
->getDataLayout())
345 unwrap(Module
)->setDataLayout(DL
);
349 extern "C" LLVMTargetDataRef
350 LLVMRustGetModuleDataLayout(LLVMModuleRef M
) {
351 #if LLVM_VERSION_MINOR >= 7
352 return wrap(&unwrap(M
)->getDataLayout());
354 return wrap(unwrap(M
)->getDataLayout());