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