TargetMachineC.cpp revision fa74752298602e0b74fb60ce3f0e76d0c461d3d8
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/TargetMachine.h"
15#include "llvm-c/Core.h"
16#include "llvm-c/Target.h"
17#include "llvm/IR/DataLayout.h"
18#include "llvm/IR/Module.h"
19#include "llvm/PassManager.h"
20#include "llvm/Support/CodeGen.h"
21#include "llvm/Support/FormattedStream.h"
22#include "llvm/Support/TargetRegistry.h"
23#include "llvm/Support/raw_ostream.h"
24#include "llvm/Support/Host.h"
25#include "llvm/Target/TargetMachine.h"
26#include <cassert>
27#include <cstdlib>
28#include <cstring>
29
30using namespace llvm;
31
32inline DataLayout *unwrap(LLVMTargetDataRef P) {
33  return reinterpret_cast<DataLayout*>(P);
34}
35
36inline LLVMTargetDataRef wrap(const DataLayout *P) {
37  return reinterpret_cast<LLVMTargetDataRef>(const_cast<DataLayout*>(P));
38}
39
40inline TargetLibraryInfo *unwrap(LLVMTargetLibraryInfoRef P) {
41  return reinterpret_cast<TargetLibraryInfo*>(P);
42}
43
44inline LLVMTargetLibraryInfoRef wrap(const TargetLibraryInfo *P) {
45  TargetLibraryInfo *X = const_cast<TargetLibraryInfo*>(P);
46  return reinterpret_cast<LLVMTargetLibraryInfoRef>(X);
47}
48
49inline TargetMachine *unwrap(LLVMTargetMachineRef P) {
50  return reinterpret_cast<TargetMachine*>(P);
51}
52inline Target *unwrap(LLVMTargetRef P) {
53  return reinterpret_cast<Target*>(P);
54}
55inline LLVMTargetMachineRef wrap(const TargetMachine *P) {
56  return
57    reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine*>(P));
58}
59inline LLVMTargetRef wrap(const Target * P) {
60  return reinterpret_cast<LLVMTargetRef>(const_cast<Target*>(P));
61}
62
63LLVMTargetRef LLVMGetFirstTarget() {
64  if(TargetRegistry::begin() == TargetRegistry::end()) {
65    return NULL;
66  }
67
68  const Target* target = &*TargetRegistry::begin();
69  return wrap(target);
70}
71LLVMTargetRef LLVMGetNextTarget(LLVMTargetRef T) {
72  return wrap(unwrap(T)->getNext());
73}
74
75LLVMTargetRef LLVMGetTargetFromName(const char *Name) {
76  for (TargetRegistry::iterator IT = TargetRegistry::begin(),
77                                IE = TargetRegistry::end(); IT != IE; ++IT) {
78    if (IT->getName() == Name)
79      return wrap(&*IT);
80  }
81
82  return NULL;
83}
84
85LLVMBool LLVMGetTargetFromTriple(const char* TripleStr, LLVMTargetRef *T,
86                                 char **ErrorMessage) {
87  std::string Error;
88
89  *T = wrap(TargetRegistry::lookupTarget(TripleStr, Error));
90
91  if (!*T) {
92    if (ErrorMessage)
93      *ErrorMessage = strdup(Error.c_str());
94
95    return 1;
96  }
97
98  return 0;
99}
100
101const char * LLVMGetTargetName(LLVMTargetRef T) {
102  return unwrap(T)->getName();
103}
104
105const char * LLVMGetTargetDescription(LLVMTargetRef T) {
106  return unwrap(T)->getShortDescription();
107}
108
109LLVMBool LLVMTargetHasJIT(LLVMTargetRef T) {
110  return unwrap(T)->hasJIT();
111}
112
113LLVMBool LLVMTargetHasTargetMachine(LLVMTargetRef T) {
114  return unwrap(T)->hasTargetMachine();
115}
116
117LLVMBool LLVMTargetHasAsmBackend(LLVMTargetRef T) {
118  return unwrap(T)->hasMCAsmBackend();
119}
120
121LLVMTargetMachineRef LLVMCreateTargetMachine(LLVMTargetRef T,
122        const char* Triple, const char* CPU, const char* Features,
123        LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc,
124        LLVMCodeModel CodeModel) {
125  Reloc::Model RM;
126  switch (Reloc){
127    case LLVMRelocStatic:
128      RM = Reloc::Static;
129      break;
130    case LLVMRelocPIC:
131      RM = Reloc::PIC_;
132      break;
133    case LLVMRelocDynamicNoPic:
134      RM = Reloc::DynamicNoPIC;
135      break;
136    default:
137      RM = Reloc::Default;
138      break;
139  }
140
141  CodeModel::Model CM = unwrap(CodeModel);
142
143  CodeGenOpt::Level OL;
144  switch (Level) {
145    case LLVMCodeGenLevelNone:
146      OL = CodeGenOpt::None;
147      break;
148    case LLVMCodeGenLevelLess:
149      OL = CodeGenOpt::Less;
150      break;
151    case LLVMCodeGenLevelAggressive:
152      OL = CodeGenOpt::Aggressive;
153      break;
154    default:
155      OL = CodeGenOpt::Default;
156      break;
157  }
158
159  TargetOptions opt;
160  return wrap(unwrap(T)->createTargetMachine(Triple, CPU, Features, opt, RM,
161    CM, OL));
162}
163
164
165void LLVMDisposeTargetMachine(LLVMTargetMachineRef T) {
166  delete unwrap(T);
167}
168
169LLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T) {
170  const Target* target = &(unwrap(T)->getTarget());
171  return wrap(target);
172}
173
174char* LLVMGetTargetMachineTriple(LLVMTargetMachineRef T) {
175  std::string StringRep = unwrap(T)->getTargetTriple();
176  return strdup(StringRep.c_str());
177}
178
179char* LLVMGetTargetMachineCPU(LLVMTargetMachineRef T) {
180  std::string StringRep = unwrap(T)->getTargetCPU();
181  return strdup(StringRep.c_str());
182}
183
184char* LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T) {
185  std::string StringRep = unwrap(T)->getTargetFeatureString();
186  return strdup(StringRep.c_str());
187}
188
189LLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T) {
190  return wrap(unwrap(T)->getDataLayout());
191}
192
193void LLVMSetTargetMachineAsmVerbosity(LLVMTargetMachineRef T,
194                                      LLVMBool VerboseAsm) {
195  unwrap(T)->setAsmVerbosityDefault(VerboseAsm);
196}
197
198static LLVMBool LLVMTargetMachineEmit(LLVMTargetMachineRef T, LLVMModuleRef M,
199  formatted_raw_ostream &OS, LLVMCodeGenFileType codegen, char **ErrorMessage) {
200  TargetMachine* TM = unwrap(T);
201  Module* Mod = unwrap(M);
202
203  PassManager pass;
204
205  std::string error;
206
207  const DataLayout* td = TM->getDataLayout();
208
209  if (!td) {
210    error = "No DataLayout in TargetMachine";
211    *ErrorMessage = strdup(error.c_str());
212    return true;
213  }
214  pass.add(new DataLayout(*td));
215
216  TargetMachine::CodeGenFileType ft;
217  switch (codegen) {
218    case LLVMAssemblyFile:
219      ft = TargetMachine::CGFT_AssemblyFile;
220      break;
221    default:
222      ft = TargetMachine::CGFT_ObjectFile;
223      break;
224  }
225  if (TM->addPassesToEmitFile(pass, OS, ft)) {
226    error = "TargetMachine can't emit a file of this type";
227    *ErrorMessage = strdup(error.c_str());
228    return true;
229  }
230
231  pass.run(*Mod);
232
233  OS.flush();
234  return false;
235}
236
237LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,
238  char* Filename, LLVMCodeGenFileType codegen, char** ErrorMessage) {
239  std::string error;
240  raw_fd_ostream dest(Filename, error, sys::fs::F_Binary);
241  if (!error.empty()) {
242    *ErrorMessage = strdup(error.c_str());
243    return true;
244  }
245  formatted_raw_ostream destf(dest);
246  bool Result = LLVMTargetMachineEmit(T, M, destf, codegen, ErrorMessage);
247  dest.flush();
248  return Result;
249}
250
251LLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T,
252  LLVMModuleRef M, LLVMCodeGenFileType codegen, char** ErrorMessage,
253  LLVMMemoryBufferRef *OutMemBuf) {
254  std::string CodeString;
255  raw_string_ostream OStream(CodeString);
256  formatted_raw_ostream Out(OStream);
257  bool Result = LLVMTargetMachineEmit(T, M, Out, codegen, ErrorMessage);
258  OStream.flush();
259
260  std::string &Data = OStream.str();
261  *OutMemBuf = LLVMCreateMemoryBufferWithMemoryRangeCopy(Data.c_str(),
262                                                     Data.length(), "");
263  return Result;
264}
265
266char *LLVMGetDefaultTargetTriple(void) {
267  return strdup(sys::getDefaultTargetTriple().c_str());
268}
269