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