blob: 0a80b4addb356489a062265134037977e0c0d76e [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"
Eric Christopherd9134482014-08-04 21:25:23 +000027#include "llvm/Target/TargetSubtargetInfo.h"
Duncan Sands264d2e72012-04-11 10:25:24 +000028#include <cassert>
29#include <cstdlib>
30#include <cstring>
31
32using namespace llvm;
33
Eric Christopher04d4e932013-04-22 22:47:22 +000034inline TargetMachine *unwrap(LLVMTargetMachineRef P) {
35 return reinterpret_cast<TargetMachine*>(P);
36}
37inline Target *unwrap(LLVMTargetRef P) {
38 return reinterpret_cast<Target*>(P);
39}
40inline LLVMTargetMachineRef wrap(const TargetMachine *P) {
41 return
42 reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine*>(P));
43}
44inline LLVMTargetRef wrap(const Target * P) {
45 return reinterpret_cast<LLVMTargetRef>(const_cast<Target*>(P));
46}
Duncan Sands264d2e72012-04-11 10:25:24 +000047
48LLVMTargetRef LLVMGetFirstTarget() {
Anders Waldenborga89c1e32013-10-17 10:25:24 +000049 if(TargetRegistry::begin() == TargetRegistry::end()) {
Craig Topper062a2ba2014-04-25 05:30:21 +000050 return nullptr;
Anders Waldenborga89c1e32013-10-17 10:25:24 +000051 }
52
53 const Target* target = &*TargetRegistry::begin();
54 return wrap(target);
Duncan Sands264d2e72012-04-11 10:25:24 +000055}
56LLVMTargetRef LLVMGetNextTarget(LLVMTargetRef T) {
57 return wrap(unwrap(T)->getNext());
58}
59
Peter Zotovb2c8b8a2013-11-15 02:51:01 +000060LLVMTargetRef LLVMGetTargetFromName(const char *Name) {
Peter Zotov5a6cfda2013-11-15 02:51:18 +000061 StringRef NameRef = Name;
Peter Zotov7b61b752013-11-06 10:25:18 +000062 for (TargetRegistry::iterator IT = TargetRegistry::begin(),
63 IE = TargetRegistry::end(); IT != IE; ++IT) {
Peter Zotov5a6cfda2013-11-15 02:51:18 +000064 if (IT->getName() == NameRef)
Peter Zotovb2c8b8a2013-11-15 02:51:01 +000065 return wrap(&*IT);
Peter Zotov7b61b752013-11-06 10:25:18 +000066 }
67
Craig Topper062a2ba2014-04-25 05:30:21 +000068 return nullptr;
Peter Zotov7b61b752013-11-06 10:25:18 +000069}
70
71LLVMBool LLVMGetTargetFromTriple(const char* TripleStr, LLVMTargetRef *T,
72 char **ErrorMessage) {
73 std::string Error;
74
75 *T = wrap(TargetRegistry::lookupTarget(TripleStr, Error));
76
77 if (!*T) {
78 if (ErrorMessage)
79 *ErrorMessage = strdup(Error.c_str());
80
81 return 1;
82 }
83
84 return 0;
85}
86
Duncan Sands264d2e72012-04-11 10:25:24 +000087const char * LLVMGetTargetName(LLVMTargetRef T) {
88 return unwrap(T)->getName();
89}
90
91const char * LLVMGetTargetDescription(LLVMTargetRef T) {
92 return unwrap(T)->getShortDescription();
93}
94
95LLVMBool LLVMTargetHasJIT(LLVMTargetRef T) {
96 return unwrap(T)->hasJIT();
97}
98
99LLVMBool LLVMTargetHasTargetMachine(LLVMTargetRef T) {
100 return unwrap(T)->hasTargetMachine();
101}
102
103LLVMBool LLVMTargetHasAsmBackend(LLVMTargetRef T) {
104 return unwrap(T)->hasMCAsmBackend();
105}
106
Peter Zotov0e38fc82013-11-15 02:51:12 +0000107LLVMTargetMachineRef LLVMCreateTargetMachine(LLVMTargetRef T,
108 const char* Triple, const char* CPU, const char* Features,
109 LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc,
110 LLVMCodeModel CodeModel) {
Duncan Sands264d2e72012-04-11 10:25:24 +0000111 Reloc::Model RM;
112 switch (Reloc){
113 case LLVMRelocStatic:
114 RM = Reloc::Static;
115 break;
116 case LLVMRelocPIC:
117 RM = Reloc::PIC_;
118 break;
119 case LLVMRelocDynamicNoPic:
120 RM = Reloc::DynamicNoPIC;
121 break;
122 default:
123 RM = Reloc::Default;
124 break;
125 }
126
Filip Pizlo85e0d272013-05-01 22:58:00 +0000127 CodeModel::Model CM = unwrap(CodeModel);
Duncan Sands264d2e72012-04-11 10:25:24 +0000128
Filip Pizlo85e0d272013-05-01 22:58:00 +0000129 CodeGenOpt::Level OL;
Duncan Sands264d2e72012-04-11 10:25:24 +0000130 switch (Level) {
131 case LLVMCodeGenLevelNone:
132 OL = CodeGenOpt::None;
133 break;
134 case LLVMCodeGenLevelLess:
135 OL = CodeGenOpt::Less;
136 break;
137 case LLVMCodeGenLevelAggressive:
138 OL = CodeGenOpt::Aggressive;
139 break;
140 default:
141 OL = CodeGenOpt::Default;
142 break;
143 }
144
145 TargetOptions opt;
146 return wrap(unwrap(T)->createTargetMachine(Triple, CPU, Features, opt, RM,
147 CM, OL));
148}
149
150
151void LLVMDisposeTargetMachine(LLVMTargetMachineRef T) {
152 delete unwrap(T);
153}
154
155LLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T) {
156 const Target* target = &(unwrap(T)->getTarget());
157 return wrap(target);
158}
159
160char* LLVMGetTargetMachineTriple(LLVMTargetMachineRef T) {
161 std::string StringRep = unwrap(T)->getTargetTriple();
162 return strdup(StringRep.c_str());
163}
164
165char* LLVMGetTargetMachineCPU(LLVMTargetMachineRef T) {
166 std::string StringRep = unwrap(T)->getTargetCPU();
167 return strdup(StringRep.c_str());
168}
169
170char* LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T) {
171 std::string StringRep = unwrap(T)->getTargetFeatureString();
172 return strdup(StringRep.c_str());
173}
174
175LLVMTargetDataRef LLVMGetTargetMachineData(LLVMTargetMachineRef T) {
Eric Christopher8b770652015-01-26 19:03:15 +0000176 return wrap(unwrap(T)->getDataLayout());
Duncan Sands264d2e72012-04-11 10:25:24 +0000177}
178
Peter Zotov7b61b752013-11-06 10:25:18 +0000179void LLVMSetTargetMachineAsmVerbosity(LLVMTargetMachineRef T,
180 LLVMBool VerboseAsm) {
181 unwrap(T)->setAsmVerbosityDefault(VerboseAsm);
182}
183
Tom Stellardec924c52013-04-16 23:12:56 +0000184static LLVMBool LLVMTargetMachineEmit(LLVMTargetMachineRef T, LLVMModuleRef M,
185 formatted_raw_ostream &OS, LLVMCodeGenFileType codegen, char **ErrorMessage) {
Duncan Sands264d2e72012-04-11 10:25:24 +0000186 TargetMachine* TM = unwrap(T);
187 Module* Mod = unwrap(M);
188
189 PassManager pass;
190
191 std::string error;
192
Eric Christopher8b770652015-01-26 19:03:15 +0000193 const DataLayout *td = TM->getDataLayout();
Duncan Sands264d2e72012-04-11 10:25:24 +0000194
195 if (!td) {
Micah Villmowcdfe20b2012-10-08 16:38:25 +0000196 error = "No DataLayout in TargetMachine";
Duncan Sands264d2e72012-04-11 10:25:24 +0000197 *ErrorMessage = strdup(error.c_str());
198 return true;
199 }
Rafael Espindola339430f2014-02-25 23:25:17 +0000200 Mod->setDataLayout(td);
Rafael Espindolac435adc2014-09-10 21:27:43 +0000201 pass.add(new DataLayoutPass());
Duncan Sands264d2e72012-04-11 10:25:24 +0000202
203 TargetMachine::CodeGenFileType ft;
204 switch (codegen) {
205 case LLVMAssemblyFile:
206 ft = TargetMachine::CGFT_AssemblyFile;
207 break;
208 default:
209 ft = TargetMachine::CGFT_ObjectFile;
210 break;
211 }
Tom Stellardec924c52013-04-16 23:12:56 +0000212 if (TM->addPassesToEmitFile(pass, OS, ft)) {
Nick Lewycky7b287ee2013-03-10 22:01:44 +0000213 error = "TargetMachine can't emit a file of this type";
Duncan Sands264d2e72012-04-11 10:25:24 +0000214 *ErrorMessage = strdup(error.c_str());
215 return true;
216 }
217
218 pass.run(*Mod);
219
Tom Stellardec924c52013-04-16 23:12:56 +0000220 OS.flush();
Duncan Sands264d2e72012-04-11 10:25:24 +0000221 return false;
222}
Tom Stellardec924c52013-04-16 23:12:56 +0000223
224LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,
225 char* Filename, LLVMCodeGenFileType codegen, char** ErrorMessage) {
Rafael Espindola3fd1e992014-08-25 18:16:47 +0000226 std::error_code EC;
227 raw_fd_ostream dest(Filename, EC, sys::fs::F_None);
228 if (EC) {
229 *ErrorMessage = strdup(EC.message().c_str());
Tom Stellardec924c52013-04-16 23:12:56 +0000230 return true;
231 }
Anders Waldenborg39f5d7d2013-10-17 10:39:35 +0000232 formatted_raw_ostream destf(dest);
Tom Stellardec924c52013-04-16 23:12:56 +0000233 bool Result = LLVMTargetMachineEmit(T, M, destf, codegen, ErrorMessage);
234 dest.flush();
235 return Result;
236}
237
238LLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T,
239 LLVMModuleRef M, LLVMCodeGenFileType codegen, char** ErrorMessage,
240 LLVMMemoryBufferRef *OutMemBuf) {
Alp Tokere69170a2014-06-26 22:52:05 +0000241 std::string CodeString;
242 raw_string_ostream OStream(CodeString);
243 formatted_raw_ostream Out(OStream);
Tom Stellardec924c52013-04-16 23:12:56 +0000244 bool Result = LLVMTargetMachineEmit(T, M, Out, codegen, ErrorMessage);
Alp Tokere69170a2014-06-26 22:52:05 +0000245 OStream.flush();
Tom Stellardec924c52013-04-16 23:12:56 +0000246
Alp Tokere69170a2014-06-26 22:52:05 +0000247 std::string &Data = OStream.str();
248 *OutMemBuf = LLVMCreateMemoryBufferWithMemoryRangeCopy(Data.c_str(),
249 Data.length(), "");
Tom Stellardec924c52013-04-16 23:12:56 +0000250 return Result;
251}
Peter Zotov7b61b752013-11-06 10:25:18 +0000252
253char *LLVMGetDefaultTargetTriple(void) {
254 return strdup(sys::getDefaultTargetTriple().c_str());
255}
Juergen Ributzka5fe955c2014-01-23 19:23:28 +0000256
257void LLVMAddAnalysisPasses(LLVMTargetMachineRef T, LLVMPassManagerRef PM) {
258 unwrap(T)->addAnalysisPasses(*unwrap(PM));
259}