TargetMachineC.cpp revision 263508
1101100Ssos//===-- TargetMachine.cpp -------------------------------------------------===//
2101100Ssos//
3101100Ssos//                     The LLVM Compiler Infrastructure
4101100Ssos//
5101100Ssos// This file is distributed under the University of Illinois Open Source
6101100Ssos// License. See LICENSE.TXT for details.
7101100Ssos//
8101100Ssos//===----------------------------------------------------------------------===//
9101100Ssos//
10101100Ssos// This file implements the LLVM-C part of TargetMachine.h
11101100Ssos//
12101100Ssos//===----------------------------------------------------------------------===//
13101100Ssos
14101100Ssos#include "llvm-c/TargetMachine.h"
15101100Ssos#include "llvm-c/Core.h"
16101100Ssos#include "llvm-c/Target.h"
17101100Ssos#include "llvm/IR/DataLayout.h"
18101100Ssos#include "llvm/IR/Module.h"
19101100Ssos#include "llvm/PassManager.h"
20101100Ssos#include "llvm/Support/CodeGen.h"
21101100Ssos#include "llvm/Support/FormattedStream.h"
22101100Ssos#include "llvm/Support/TargetRegistry.h"
23101100Ssos#include "llvm/Support/raw_ostream.h"
24101100Ssos#include "llvm/Support/Host.h"
25101100Ssos#include "llvm/Target/TargetMachine.h"
26101100Ssos#include <cassert>
27101100Ssos#include <cstdlib>
28101100Ssos#include <cstring>
29101100Ssos
30101100Ssosusing namespace llvm;
31101100Ssos
32101100Ssosinline DataLayout *unwrap(LLVMTargetDataRef P) {
33101100Ssos  return reinterpret_cast<DataLayout*>(P);
34101100Ssos}
35101100Ssos
36101100Ssosinline LLVMTargetDataRef wrap(const DataLayout *P) {
37101100Ssos  return reinterpret_cast<LLVMTargetDataRef>(const_cast<DataLayout*>(P));
38101100Ssos}
39101100Ssos
40101100Ssosinline TargetLibraryInfo *unwrap(LLVMTargetLibraryInfoRef P) {
41101100Ssos  return reinterpret_cast<TargetLibraryInfo*>(P);
42101100Ssos}
43101100Ssos
44101100Ssosinline LLVMTargetLibraryInfoRef wrap(const TargetLibraryInfo *P) {
45101100Ssos  TargetLibraryInfo *X = const_cast<TargetLibraryInfo*>(P);
46101100Ssos  return reinterpret_cast<LLVMTargetLibraryInfoRef>(X);
47101100Ssos}
48101100Ssos
49101100Ssosinline TargetMachine *unwrap(LLVMTargetMachineRef P) {
50101100Ssos  return reinterpret_cast<TargetMachine*>(P);
51101100Ssos}
52101100Ssosinline Target *unwrap(LLVMTargetRef P) {
53101100Ssos  return reinterpret_cast<Target*>(P);
54101100Ssos}
55102058Ssosinline LLVMTargetMachineRef wrap(const TargetMachine *P) {
56102058Ssos  return
57102058Ssos    reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine*>(P));
58102058Ssos}
59102058Ssosinline LLVMTargetRef wrap(const Target * P) {
60102058Ssos  return reinterpret_cast<LLVMTargetRef>(const_cast<Target*>(P));
61102058Ssos}
62101100Ssos
63101100SsosLLVMTargetRef LLVMGetFirstTarget() {
64101100Ssos  if(TargetRegistry::begin() == TargetRegistry::end()) {
65101100Ssos    return NULL;
66101100Ssos  }
67101100Ssos
68101100Ssos  const Target* target = &*TargetRegistry::begin();
69101100Ssos  return wrap(target);
70101100Ssos}
71101100SsosLLVMTargetRef LLVMGetNextTarget(LLVMTargetRef T) {
72111472Sphk  return wrap(unwrap(T)->getNext());
73101100Ssos}
74101100Ssos
75101100SsosLLVMTargetRef LLVMGetTargetFromName(const char *Name) {
76101100Ssos  StringRef NameRef = Name;
77101100Ssos  for (TargetRegistry::iterator IT = TargetRegistry::begin(),
78101100Ssos                                IE = TargetRegistry::end(); IT != IE; ++IT) {
79101100Ssos    if (IT->getName() == NameRef)
80101100Ssos      return wrap(&*IT);
81101100Ssos  }
82101100Ssos
83101100Ssos  return NULL;
84101100Ssos}
85101100Ssos
86101100SsosLLVMBool LLVMGetTargetFromTriple(const char* TripleStr, LLVMTargetRef *T,
87101100Ssos                                 char **ErrorMessage) {
88101100Ssos  std::string Error;
89101100Ssos
90101100Ssos  *T = wrap(TargetRegistry::lookupTarget(TripleStr, Error));
91101100Ssos
92101100Ssos  if (!*T) {
93111472Sphk    if (ErrorMessage)
94111472Sphk      *ErrorMessage = strdup(Error.c_str());
95111472Sphk
96111472Sphk    return 1;
97111472Sphk  }
98101100Ssos
99101100Ssos  return 0;
100101100Ssos}
101101100Ssos
102101100Ssosconst char * LLVMGetTargetName(LLVMTargetRef T) {
103101100Ssos  return unwrap(T)->getName();
104101100Ssos}
105101100Ssos
106101100Ssosconst char * LLVMGetTargetDescription(LLVMTargetRef T) {
107101100Ssos  return unwrap(T)->getShortDescription();
108101100Ssos}
109101100Ssos
110101100SsosLLVMBool LLVMTargetHasJIT(LLVMTargetRef T) {
111101100Ssos  return unwrap(T)->hasJIT();
112101100Ssos}
113101100Ssos
114101100SsosLLVMBool LLVMTargetHasTargetMachine(LLVMTargetRef T) {
115101100Ssos  return unwrap(T)->hasTargetMachine();
116101100Ssos}
117101100Ssos
118101100SsosLLVMBool LLVMTargetHasAsmBackend(LLVMTargetRef T) {
119101100Ssos  return unwrap(T)->hasMCAsmBackend();
120101100Ssos}
121101100Ssos
122101100SsosLLVMTargetMachineRef LLVMCreateTargetMachine(LLVMTargetRef T,
123101100Ssos        const char* Triple, const char* CPU, const char* Features,
124101100Ssos        LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc,
125101100Ssos        LLVMCodeModel CodeModel) {
126101100Ssos  Reloc::Model RM;
127101100Ssos  switch (Reloc){
128101100Ssos    case LLVMRelocStatic:
129101100Ssos      RM = Reloc::Static;
130101100Ssos      break;
131101100Ssos    case LLVMRelocPIC:
132101100Ssos      RM = Reloc::PIC_;
133101100Ssos      break;
134101100Ssos    case LLVMRelocDynamicNoPic:
135101100Ssos      RM = Reloc::DynamicNoPIC;
136101100Ssos      break;
137101100Ssos    default:
138101100Ssos      RM = Reloc::Default;
139101100Ssos      break;
140101100Ssos  }
141101100Ssos
142101100Ssos  CodeModel::Model CM = unwrap(CodeModel);
143101100Ssos
144101100Ssos  CodeGenOpt::Level OL;
145101100Ssos  switch (Level) {
146101100Ssos    case LLVMCodeGenLevelNone:
147101100Ssos      OL = CodeGenOpt::None;
148101100Ssos      break;
149101100Ssos    case LLVMCodeGenLevelLess:
150101100Ssos      OL = CodeGenOpt::Less;
151101100Ssos      break;
152101100Ssos    case LLVMCodeGenLevelAggressive:
153101100Ssos      OL = CodeGenOpt::Aggressive;
154111472Sphk      break;
155111472Sphk    default:
156111472Sphk      OL = CodeGenOpt::Default;
157111472Sphk      break;
158111472Sphk  }
159101100Ssos
160103714Sphk  TargetOptions opt;
161103714Sphk  return wrap(unwrap(T)->createTargetMachine(Triple, CPU, Features, opt, RM,
162104066Ssos    CM, OL));
163104066Ssos}
164101100Ssos
165104066Ssos
166104066Ssosvoid LLVMDisposeTargetMachine(LLVMTargetMachineRef T) {
167104066Ssos  delete unwrap(T);
168101100Ssos}
169101100Ssos
170101100SsosLLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T) {
171101100Ssos  const Target* target = &(unwrap(T)->getTarget());
172101100Ssos  return wrap(target);
173101100Ssos}
174101100Ssos
175101100Ssoschar* LLVMGetTargetMachineTriple(LLVMTargetMachineRef T) {
176101100Ssos  std::string StringRep = unwrap(T)->getTargetTriple();
177101100Ssos  return strdup(StringRep.c_str());
178101100Ssos}
179101100Ssos
180101100Ssoschar* LLVMGetTargetMachineCPU(LLVMTargetMachineRef T) {
181101100Ssos  std::string StringRep = unwrap(T)->getTargetCPU();
182101100Ssos  return strdup(StringRep.c_str());
183101100Ssos}
184101100Ssos
185101100Ssoschar* LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T) {
186101100Ssos  std::string StringRep = unwrap(T)->getTargetFeatureString();
187101100Ssos  return strdup(StringRep.c_str());
188101100Ssos}
189101100Ssos
190101100SsosLLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T) {
191101100Ssos  return wrap(unwrap(T)->getDataLayout());
192101100Ssos}
193101100Ssos
194101100Ssosvoid LLVMSetTargetMachineAsmVerbosity(LLVMTargetMachineRef T,
195101100Ssos                                      LLVMBool VerboseAsm) {
196101100Ssos  unwrap(T)->setAsmVerbosityDefault(VerboseAsm);
197101100Ssos}
198101100Ssos
199101100Ssosstatic LLVMBool LLVMTargetMachineEmit(LLVMTargetMachineRef T, LLVMModuleRef M,
200111472Sphk  formatted_raw_ostream &OS, LLVMCodeGenFileType codegen, char **ErrorMessage) {
201101100Ssos  TargetMachine* TM = unwrap(T);
202101100Ssos  Module* Mod = unwrap(M);
203101100Ssos
204101100Ssos  PassManager pass;
205101100Ssos
206101100Ssos  std::string error;
207101100Ssos
208101100Ssos  const DataLayout* td = TM->getDataLayout();
209101100Ssos
210101100Ssos  if (!td) {
211101100Ssos    error = "No DataLayout in TargetMachine";
212101100Ssos    *ErrorMessage = strdup(error.c_str());
213101100Ssos    return true;
214101100Ssos  }
215101100Ssos  pass.add(new DataLayout(*td));
216101100Ssos
217101100Ssos  TargetMachine::CodeGenFileType ft;
218101100Ssos  switch (codegen) {
219101100Ssos    case LLVMAssemblyFile:
220101100Ssos      ft = TargetMachine::CGFT_AssemblyFile;
221101100Ssos      break;
222101100Ssos    default:
223101100Ssos      ft = TargetMachine::CGFT_ObjectFile;
224101100Ssos      break;
225101100Ssos  }
226101100Ssos  if (TM->addPassesToEmitFile(pass, OS, ft)) {
227101100Ssos    error = "TargetMachine can't emit a file of this type";
228101100Ssos    *ErrorMessage = strdup(error.c_str());
229101100Ssos    return true;
230101100Ssos  }
231101100Ssos
232102058Ssos  pass.run(*Mod);
233101100Ssos
234101100Ssos  OS.flush();
235111979Sphk  return false;
236101100Ssos}
237101100Ssos
238101100SsosLLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,
239101100Ssos  char* Filename, LLVMCodeGenFileType codegen, char** ErrorMessage) {
240101100Ssos  std::string error;
241101100Ssos  raw_fd_ostream dest(Filename, error, sys::fs::F_Binary);
242101100Ssos  if (!error.empty()) {
243101100Ssos    *ErrorMessage = strdup(error.c_str());
244101100Ssos    return true;
245101100Ssos  }
246101100Ssos  formatted_raw_ostream destf(dest);
247101100Ssos  bool Result = LLVMTargetMachineEmit(T, M, destf, codegen, ErrorMessage);
248101100Ssos  dest.flush();
249101100Ssos  return Result;
250101100Ssos}
251101100Ssos
252101100SsosLLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T,
253111979Sphk  LLVMModuleRef M, LLVMCodeGenFileType codegen, char** ErrorMessage,
254101100Ssos  LLVMMemoryBufferRef *OutMemBuf) {
255101100Ssos  std::string CodeString;
256101100Ssos  raw_string_ostream OStream(CodeString);
257101100Ssos  formatted_raw_ostream Out(OStream);
258101100Ssos  bool Result = LLVMTargetMachineEmit(T, M, Out, codegen, ErrorMessage);
259101100Ssos  OStream.flush();
260101100Ssos
261101100Ssos  std::string &Data = OStream.str();
262101100Ssos  *OutMemBuf = LLVMCreateMemoryBufferWithMemoryRangeCopy(Data.c_str(),
263101100Ssos                                                     Data.length(), "");
264101100Ssos  return Result;
265101100Ssos}
266101100Ssos
267101100Ssoschar *LLVMGetDefaultTargetTriple(void) {
268101100Ssos  return strdup(sys::getDefaultTargetTriple().c_str());
269101100Ssos}
270101100Ssos