]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/lib/Target/TargetMachineC.cpp
MFV r337220: 8375 Kernel memory leak in nvpair code
[FreeBSD/FreeBSD.git] / contrib / llvm / lib / Target / TargetMachineC.cpp
1 //===-- TargetMachine.cpp -------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the LLVM-C part of TargetMachine.h
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm-c/Core.h"
15 #include "llvm-c/Target.h"
16 #include "llvm-c/TargetMachine.h"
17 #include "llvm/Analysis/TargetTransformInfo.h"
18 #include "llvm/IR/DataLayout.h"
19 #include "llvm/IR/LegacyPassManager.h"
20 #include "llvm/IR/Module.h"
21 #include "llvm/Support/CodeGenCWrappers.h"
22 #include "llvm/Support/FileSystem.h"
23 #include "llvm/Support/FormattedStream.h"
24 #include "llvm/Support/Host.h"
25 #include "llvm/Support/TargetRegistry.h"
26 #include "llvm/Support/raw_ostream.h"
27 #include "llvm/Target/TargetMachine.h"
28 #include <cassert>
29 #include <cstdlib>
30 #include <cstring>
31
32 using namespace llvm;
33
34 static TargetMachine *unwrap(LLVMTargetMachineRef P) {
35   return reinterpret_cast<TargetMachine *>(P);
36 }
37 static Target *unwrap(LLVMTargetRef P) {
38   return reinterpret_cast<Target*>(P);
39 }
40 static LLVMTargetMachineRef wrap(const TargetMachine *P) {
41   return reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine *>(P));
42 }
43 static LLVMTargetRef wrap(const Target * P) {
44   return reinterpret_cast<LLVMTargetRef>(const_cast<Target*>(P));
45 }
46
47 LLVMTargetRef LLVMGetFirstTarget() {
48   if (TargetRegistry::targets().begin() == TargetRegistry::targets().end()) {
49     return nullptr;
50   }
51
52   const Target *target = &*TargetRegistry::targets().begin();
53   return wrap(target);
54 }
55 LLVMTargetRef LLVMGetNextTarget(LLVMTargetRef T) {
56   return wrap(unwrap(T)->getNext());
57 }
58
59 LLVMTargetRef LLVMGetTargetFromName(const char *Name) {
60   StringRef NameRef = Name;
61   auto I = find_if(TargetRegistry::targets(),
62                    [&](const Target &T) { return T.getName() == NameRef; });
63   return I != TargetRegistry::targets().end() ? wrap(&*I) : nullptr;
64 }
65
66 LLVMBool LLVMGetTargetFromTriple(const char* TripleStr, LLVMTargetRef *T,
67                                  char **ErrorMessage) {
68   std::string Error;
69
70   *T = wrap(TargetRegistry::lookupTarget(TripleStr, Error));
71
72   if (!*T) {
73     if (ErrorMessage)
74       *ErrorMessage = strdup(Error.c_str());
75
76     return 1;
77   }
78
79   return 0;
80 }
81
82 const char * LLVMGetTargetName(LLVMTargetRef T) {
83   return unwrap(T)->getName();
84 }
85
86 const char * LLVMGetTargetDescription(LLVMTargetRef T) {
87   return unwrap(T)->getShortDescription();
88 }
89
90 LLVMBool LLVMTargetHasJIT(LLVMTargetRef T) {
91   return unwrap(T)->hasJIT();
92 }
93
94 LLVMBool LLVMTargetHasTargetMachine(LLVMTargetRef T) {
95   return unwrap(T)->hasTargetMachine();
96 }
97
98 LLVMBool LLVMTargetHasAsmBackend(LLVMTargetRef T) {
99   return unwrap(T)->hasMCAsmBackend();
100 }
101
102 LLVMTargetMachineRef LLVMCreateTargetMachine(LLVMTargetRef T,
103         const char *Triple, const char *CPU, const char *Features,
104         LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc,
105         LLVMCodeModel CodeModel) {
106   Optional<Reloc::Model> RM;
107   switch (Reloc){
108     case LLVMRelocStatic:
109       RM = Reloc::Static;
110       break;
111     case LLVMRelocPIC:
112       RM = Reloc::PIC_;
113       break;
114     case LLVMRelocDynamicNoPic:
115       RM = Reloc::DynamicNoPIC;
116       break;
117     default:
118       break;
119   }
120
121   bool JIT;
122   Optional<CodeModel::Model> CM = unwrap(CodeModel, JIT);
123
124   CodeGenOpt::Level OL;
125   switch (Level) {
126     case LLVMCodeGenLevelNone:
127       OL = CodeGenOpt::None;
128       break;
129     case LLVMCodeGenLevelLess:
130       OL = CodeGenOpt::Less;
131       break;
132     case LLVMCodeGenLevelAggressive:
133       OL = CodeGenOpt::Aggressive;
134       break;
135     default:
136       OL = CodeGenOpt::Default;
137       break;
138   }
139
140   TargetOptions opt;
141   return wrap(unwrap(T)->createTargetMachine(Triple, CPU, Features, opt, RM, CM,
142                                              OL, JIT));
143 }
144
145 void LLVMDisposeTargetMachine(LLVMTargetMachineRef T) { delete unwrap(T); }
146
147 LLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T) {
148   const Target* target = &(unwrap(T)->getTarget());
149   return wrap(target);
150 }
151
152 char* LLVMGetTargetMachineTriple(LLVMTargetMachineRef T) {
153   std::string StringRep = unwrap(T)->getTargetTriple().str();
154   return strdup(StringRep.c_str());
155 }
156
157 char* LLVMGetTargetMachineCPU(LLVMTargetMachineRef T) {
158   std::string StringRep = unwrap(T)->getTargetCPU();
159   return strdup(StringRep.c_str());
160 }
161
162 char* LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T) {
163   std::string StringRep = unwrap(T)->getTargetFeatureString();
164   return strdup(StringRep.c_str());
165 }
166
167 void LLVMSetTargetMachineAsmVerbosity(LLVMTargetMachineRef T,
168                                       LLVMBool VerboseAsm) {
169   unwrap(T)->Options.MCOptions.AsmVerbose = VerboseAsm;
170 }
171
172 LLVMTargetDataRef LLVMCreateTargetDataLayout(LLVMTargetMachineRef T) {
173   return wrap(new DataLayout(unwrap(T)->createDataLayout()));
174 }
175
176 static LLVMBool LLVMTargetMachineEmit(LLVMTargetMachineRef T, LLVMModuleRef M,
177                                       raw_pwrite_stream &OS,
178                                       LLVMCodeGenFileType codegen,
179                                       char **ErrorMessage) {
180   TargetMachine* TM = unwrap(T);
181   Module* Mod = unwrap(M);
182
183   legacy::PassManager pass;
184
185   std::string error;
186
187   Mod->setDataLayout(TM->createDataLayout());
188
189   TargetMachine::CodeGenFileType ft;
190   switch (codegen) {
191     case LLVMAssemblyFile:
192       ft = TargetMachine::CGFT_AssemblyFile;
193       break;
194     default:
195       ft = TargetMachine::CGFT_ObjectFile;
196       break;
197   }
198   if (TM->addPassesToEmitFile(pass, OS, ft)) {
199     error = "TargetMachine can't emit a file of this type";
200     *ErrorMessage = strdup(error.c_str());
201     return true;
202   }
203
204   pass.run(*Mod);
205
206   OS.flush();
207   return false;
208 }
209
210 LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,
211   char* Filename, LLVMCodeGenFileType codegen, char** ErrorMessage) {
212   std::error_code EC;
213   raw_fd_ostream dest(Filename, EC, sys::fs::F_None);
214   if (EC) {
215     *ErrorMessage = strdup(EC.message().c_str());
216     return true;
217   }
218   bool Result = LLVMTargetMachineEmit(T, M, dest, codegen, ErrorMessage);
219   dest.flush();
220   return Result;
221 }
222
223 LLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T,
224   LLVMModuleRef M, LLVMCodeGenFileType codegen, char** ErrorMessage,
225   LLVMMemoryBufferRef *OutMemBuf) {
226   SmallString<0> CodeString;
227   raw_svector_ostream OStream(CodeString);
228   bool Result = LLVMTargetMachineEmit(T, M, OStream, codegen, ErrorMessage);
229
230   StringRef Data = OStream.str();
231   *OutMemBuf =
232       LLVMCreateMemoryBufferWithMemoryRangeCopy(Data.data(), Data.size(), "");
233   return Result;
234 }
235
236 char *LLVMGetDefaultTargetTriple(void) {
237   return strdup(sys::getDefaultTargetTriple().c_str());
238 }
239
240 void LLVMAddAnalysisPasses(LLVMTargetMachineRef T, LLVMPassManagerRef PM) {
241   unwrap(PM)->add(
242       createTargetTransformInfoWrapperPass(unwrap(T)->getTargetIRAnalysis()));
243 }