blob: 20923c97ec8815c79a55b71d4becb84ec4def8c7 [file] [log] [blame]
Duncan Sands264d2e72012-04-11 10:25:24 +00001//===-- 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
Chandler Carruthed0881b2012-12-03 16:50:05 +000014#include "llvm-c/TargetMachine.h"
Duncan Sands264d2e72012-04-11 10:25:24 +000015#include "llvm-c/Core.h"
16#include "llvm-c/Target.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000017#include "llvm/IR/DataLayout.h"
18#include "llvm/IR/Module.h"
Duncan Sands264d2e72012-04-11 10:25:24 +000019#include "llvm/PassManager.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000020#include "llvm/Support/CodeGen.h"
Benjamin Kramerd59664f2014-04-29 23:26:49 +000021#include "llvm/Support/FileSystem.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000022#include "llvm/Support/FormattedStream.h"
Chandler Carruth8a8cd2b2014-01-07 11:48:04 +000023#include "llvm/Support/Host.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000024#include "llvm/Support/TargetRegistry.h"
25#include "llvm/Support/raw_ostream.h"
26#include "llvm/Target/TargetMachine.h"
Duncan Sands264d2e72012-04-11 10:25:24 +000027#include <cassert>
28#include <cstdlib>
29#include <cstring>
30
31using namespace llvm;
32
Eric Christopher04d4e932013-04-22 22:47:22 +000033inline 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}
Duncan Sands264d2e72012-04-11 10:25:24 +000046
47LLVMTargetRef LLVMGetFirstTarget() {
Anders Waldenborga89c1e32013-10-17 10:25:24 +000048 if(TargetRegistry::begin() == TargetRegistry::end()) {
Craig Topper062a2ba2014-04-25 05:30:21 +000049 return nullptr;
Anders Waldenborga89c1e32013-10-17 10:25:24 +000050 }
51
52 const Target* target = &*TargetRegistry::begin();
53 return wrap(target);
Duncan Sands264d2e72012-04-11 10:25:24 +000054}
55LLVMTargetRef LLVMGetNextTarget(LLVMTargetRef T) {
56 return wrap(unwrap(T)->getNext());
57}
58
Peter Zotovb2c8b8a2013-11-15 02:51:01 +000059LLVMTargetRef LLVMGetTargetFromName(const char *Name) {
Peter Zotov5a6cfda2013-11-15 02:51:18 +000060 StringRef NameRef = Name;
Peter Zotov7b61b752013-11-06 10:25:18 +000061 for (TargetRegistry::iterator IT = TargetRegistry::begin(),
62 IE = TargetRegistry::end(); IT != IE; ++IT) {
Peter Zotov5a6cfda2013-11-15 02:51:18 +000063 if (IT->getName() == NameRef)
Peter Zotovb2c8b8a2013-11-15 02:51:01 +000064 return wrap(&*IT);
Peter Zotov7b61b752013-11-06 10:25:18 +000065 }
66
Craig Topper062a2ba2014-04-25 05:30:21 +000067 return nullptr;
Peter Zotov7b61b752013-11-06 10:25:18 +000068}
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
Duncan Sands264d2e72012-04-11 10:25:24 +000086const 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
Peter Zotov0e38fc82013-11-15 02:51:12 +0000106LLVMTargetMachineRef LLVMCreateTargetMachine(LLVMTargetRef T,
107 const char* Triple, const char* CPU, const char* Features,
108 LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc,
109 LLVMCodeModel CodeModel) {
Duncan Sands264d2e72012-04-11 10:25:24 +0000110 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
Filip Pizlo85e0d272013-05-01 22:58:00 +0000126 CodeModel::Model CM = unwrap(CodeModel);
Duncan Sands264d2e72012-04-11 10:25:24 +0000127
Filip Pizlo85e0d272013-05-01 22:58:00 +0000128 CodeGenOpt::Level OL;
Duncan Sands264d2e72012-04-11 10:25:24 +0000129 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) {
Micah Villmowcdfe20b2012-10-08 16:38:25 +0000175 return wrap(unwrap(T)->getDataLayout());
Duncan Sands264d2e72012-04-11 10:25:24 +0000176}
177
Peter Zotov7b61b752013-11-06 10:25:18 +0000178void LLVMSetTargetMachineAsmVerbosity(LLVMTargetMachineRef T,
179 LLVMBool VerboseAsm) {
180 unwrap(T)->setAsmVerbosityDefault(VerboseAsm);
181}
182
Tom Stellardec924c52013-04-16 23:12:56 +0000183static LLVMBool LLVMTargetMachineEmit(LLVMTargetMachineRef T, LLVMModuleRef M,
184 formatted_raw_ostream &OS, LLVMCodeGenFileType codegen, char **ErrorMessage) {
Duncan Sands264d2e72012-04-11 10:25:24 +0000185 TargetMachine* TM = unwrap(T);
186 Module* Mod = unwrap(M);
187
188 PassManager pass;
189
190 std::string error;
191
Micah Villmowcdfe20b2012-10-08 16:38:25 +0000192 const DataLayout* td = TM->getDataLayout();
Duncan Sands264d2e72012-04-11 10:25:24 +0000193
194 if (!td) {
Micah Villmowcdfe20b2012-10-08 16:38:25 +0000195 error = "No DataLayout in TargetMachine";
Duncan Sands264d2e72012-04-11 10:25:24 +0000196 *ErrorMessage = strdup(error.c_str());
197 return true;
198 }
Rafael Espindola339430f2014-02-25 23:25:17 +0000199 Mod->setDataLayout(td);
200 pass.add(new DataLayoutPass(Mod));
Duncan Sands264d2e72012-04-11 10:25:24 +0000201
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 }
Tom Stellardec924c52013-04-16 23:12:56 +0000211 if (TM->addPassesToEmitFile(pass, OS, ft)) {
Nick Lewycky7b287ee2013-03-10 22:01:44 +0000212 error = "TargetMachine can't emit a file of this type";
Duncan Sands264d2e72012-04-11 10:25:24 +0000213 *ErrorMessage = strdup(error.c_str());
214 return true;
215 }
216
217 pass.run(*Mod);
218
Tom Stellardec924c52013-04-16 23:12:56 +0000219 OS.flush();
Duncan Sands264d2e72012-04-11 10:25:24 +0000220 return false;
221}
Tom Stellardec924c52013-04-16 23:12:56 +0000222
223LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,
224 char* Filename, LLVMCodeGenFileType codegen, char** ErrorMessage) {
225 std::string error;
Rafael Espindola90c7f1c2014-02-24 18:20:12 +0000226 raw_fd_ostream dest(Filename, error, sys::fs::F_None);
Tom Stellardec924c52013-04-16 23:12:56 +0000227 if (!error.empty()) {
228 *ErrorMessage = strdup(error.c_str());
229 return true;
230 }
Anders Waldenborg39f5d7d2013-10-17 10:39:35 +0000231 formatted_raw_ostream destf(dest);
Tom Stellardec924c52013-04-16 23:12:56 +0000232 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}
Peter Zotov7b61b752013-11-06 10:25:18 +0000251
252char *LLVMGetDefaultTargetTriple(void) {
253 return strdup(sys::getDefaultTargetTriple().c_str());
254}
Juergen Ributzka5fe955c2014-01-23 19:23:28 +0000255
256void LLVMAddAnalysisPasses(LLVMTargetMachineRef T, LLVMPassManagerRef PM) {
257 unwrap(T)->addAnalysisPasses(*unwrap(PM));
258}