1 //===-- TargetMachine.cpp -------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file implements the LLVM-C part of TargetMachine.h
11 //===----------------------------------------------------------------------===//
13 #include "llvm-c/Core.h"
14 #include "llvm-c/TargetMachine.h"
15 #include "llvm/Analysis/TargetTransformInfo.h"
16 #include "llvm/IR/DataLayout.h"
17 #include "llvm/IR/LegacyPassManager.h"
18 #include "llvm/IR/Module.h"
19 #include "llvm/MC/TargetRegistry.h"
20 #include "llvm/Support/CBindingWrapping.h"
21 #include "llvm/Support/FileSystem.h"
22 #include "llvm/Support/raw_ostream.h"
23 #include "llvm/Target/CodeGenCWrappers.h"
24 #include "llvm/Target/TargetMachine.h"
25 #include "llvm/TargetParser/Host.h"
26 #include "llvm/TargetParser/SubtargetFeature.h"
34 /// Options for LLVMCreateTargetMachine().
35 struct LLVMTargetMachineOptions
{
39 CodeGenOptLevel OL
= CodeGenOptLevel::Default
;
40 std::optional
<Reloc::Model
> RM
;
41 std::optional
<CodeModel::Model
> CM
;
47 DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMTargetMachineOptions
,
48 LLVMTargetMachineOptionsRef
)
50 static TargetMachine
*unwrap(LLVMTargetMachineRef P
) {
51 return reinterpret_cast<TargetMachine
*>(P
);
53 static Target
*unwrap(LLVMTargetRef P
) {
54 return reinterpret_cast<Target
*>(P
);
56 static LLVMTargetMachineRef
wrap(const TargetMachine
*P
) {
57 return reinterpret_cast<LLVMTargetMachineRef
>(const_cast<TargetMachine
*>(P
));
59 static LLVMTargetRef
wrap(const Target
* P
) {
60 return reinterpret_cast<LLVMTargetRef
>(const_cast<Target
*>(P
));
63 LLVMTargetRef
LLVMGetFirstTarget() {
64 if (TargetRegistry::targets().begin() == TargetRegistry::targets().end()) {
68 const Target
*target
= &*TargetRegistry::targets().begin();
71 LLVMTargetRef
LLVMGetNextTarget(LLVMTargetRef T
) {
72 return wrap(unwrap(T
)->getNext());
75 LLVMTargetRef
LLVMGetTargetFromName(const char *Name
) {
76 StringRef NameRef
= Name
;
77 auto I
= find_if(TargetRegistry::targets(),
78 [&](const Target
&T
) { return T
.getName() == NameRef
; });
79 return I
!= TargetRegistry::targets().end() ? wrap(&*I
) : nullptr;
82 LLVMBool
LLVMGetTargetFromTriple(const char* TripleStr
, LLVMTargetRef
*T
,
83 char **ErrorMessage
) {
86 *T
= wrap(TargetRegistry::lookupTarget(TripleStr
, Error
));
90 *ErrorMessage
= strdup(Error
.c_str());
98 const char * LLVMGetTargetName(LLVMTargetRef T
) {
99 return unwrap(T
)->getName();
102 const char * LLVMGetTargetDescription(LLVMTargetRef T
) {
103 return unwrap(T
)->getShortDescription();
106 LLVMBool
LLVMTargetHasJIT(LLVMTargetRef T
) {
107 return unwrap(T
)->hasJIT();
110 LLVMBool
LLVMTargetHasTargetMachine(LLVMTargetRef T
) {
111 return unwrap(T
)->hasTargetMachine();
114 LLVMBool
LLVMTargetHasAsmBackend(LLVMTargetRef T
) {
115 return unwrap(T
)->hasMCAsmBackend();
118 LLVMTargetMachineOptionsRef
LLVMCreateTargetMachineOptions(void) {
119 return wrap(new LLVMTargetMachineOptions());
122 void LLVMDisposeTargetMachineOptions(LLVMTargetMachineOptionsRef Options
) {
123 delete unwrap(Options
);
126 void LLVMTargetMachineOptionsSetCPU(LLVMTargetMachineOptionsRef Options
,
128 unwrap(Options
)->CPU
= CPU
;
131 void LLVMTargetMachineOptionsSetFeatures(LLVMTargetMachineOptionsRef Options
,
132 const char *Features
) {
133 unwrap(Options
)->Features
= Features
;
136 void LLVMTargetMachineOptionsSetABI(LLVMTargetMachineOptionsRef Options
,
138 unwrap(Options
)->ABI
= ABI
;
141 void LLVMTargetMachineOptionsSetCodeGenOptLevel(
142 LLVMTargetMachineOptionsRef Options
, LLVMCodeGenOptLevel Level
) {
146 case LLVMCodeGenLevelNone
:
147 OL
= CodeGenOptLevel::None
;
149 case LLVMCodeGenLevelLess
:
150 OL
= CodeGenOptLevel::Less
;
152 case LLVMCodeGenLevelAggressive
:
153 OL
= CodeGenOptLevel::Aggressive
;
155 case LLVMCodeGenLevelDefault
:
156 OL
= CodeGenOptLevel::Default
;
160 unwrap(Options
)->OL
= OL
;
163 void LLVMTargetMachineOptionsSetRelocMode(LLVMTargetMachineOptionsRef Options
,
164 LLVMRelocMode Reloc
) {
165 std::optional
<Reloc::Model
> RM
;
168 case LLVMRelocStatic
:
174 case LLVMRelocDynamicNoPic
:
175 RM
= Reloc::DynamicNoPIC
;
183 case LLVMRelocROPI_RWPI
:
184 RM
= Reloc::ROPI_RWPI
;
186 case LLVMRelocDefault
:
190 unwrap(Options
)->RM
= RM
;
193 void LLVMTargetMachineOptionsSetCodeModel(LLVMTargetMachineOptionsRef Options
,
194 LLVMCodeModel CodeModel
) {
195 auto CM
= unwrap(CodeModel
, unwrap(Options
)->JIT
);
196 unwrap(Options
)->CM
= CM
;
200 LLVMCreateTargetMachineWithOptions(LLVMTargetRef T
, const char *Triple
,
201 LLVMTargetMachineOptionsRef Options
) {
202 auto *Opt
= unwrap(Options
);
204 TO
.MCOptions
.ABIName
= Opt
->ABI
;
205 return wrap(unwrap(T
)->createTargetMachine(Triple
, Opt
->CPU
, Opt
->Features
,
206 TO
, Opt
->RM
, Opt
->CM
, Opt
->OL
,
211 LLVMCreateTargetMachine(LLVMTargetRef T
, const char *Triple
, const char *CPU
,
212 const char *Features
, LLVMCodeGenOptLevel Level
,
213 LLVMRelocMode Reloc
, LLVMCodeModel CodeModel
) {
214 auto *Options
= LLVMCreateTargetMachineOptions();
216 LLVMTargetMachineOptionsSetCPU(Options
, CPU
);
217 LLVMTargetMachineOptionsSetFeatures(Options
, Features
);
218 LLVMTargetMachineOptionsSetCodeGenOptLevel(Options
, Level
);
219 LLVMTargetMachineOptionsSetRelocMode(Options
, Reloc
);
220 LLVMTargetMachineOptionsSetCodeModel(Options
, CodeModel
);
222 auto *Machine
= LLVMCreateTargetMachineWithOptions(T
, Triple
, Options
);
224 LLVMDisposeTargetMachineOptions(Options
);
228 void LLVMDisposeTargetMachine(LLVMTargetMachineRef T
) { delete unwrap(T
); }
230 LLVMTargetRef
LLVMGetTargetMachineTarget(LLVMTargetMachineRef T
) {
231 const Target
* target
= &(unwrap(T
)->getTarget());
235 char* LLVMGetTargetMachineTriple(LLVMTargetMachineRef T
) {
236 std::string StringRep
= unwrap(T
)->getTargetTriple().str();
237 return strdup(StringRep
.c_str());
240 char* LLVMGetTargetMachineCPU(LLVMTargetMachineRef T
) {
241 std::string StringRep
= std::string(unwrap(T
)->getTargetCPU());
242 return strdup(StringRep
.c_str());
245 char* LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T
) {
246 std::string StringRep
= std::string(unwrap(T
)->getTargetFeatureString());
247 return strdup(StringRep
.c_str());
250 void LLVMSetTargetMachineAsmVerbosity(LLVMTargetMachineRef T
,
251 LLVMBool VerboseAsm
) {
252 unwrap(T
)->Options
.MCOptions
.AsmVerbose
= VerboseAsm
;
255 void LLVMSetTargetMachineFastISel(LLVMTargetMachineRef T
, LLVMBool Enable
) {
256 unwrap(T
)->setFastISel(Enable
);
259 void LLVMSetTargetMachineGlobalISel(LLVMTargetMachineRef T
, LLVMBool Enable
) {
260 unwrap(T
)->setGlobalISel(Enable
);
263 void LLVMSetTargetMachineGlobalISelAbort(LLVMTargetMachineRef T
,
264 LLVMGlobalISelAbortMode Mode
) {
265 GlobalISelAbortMode AM
= GlobalISelAbortMode::Enable
;
267 case LLVMGlobalISelAbortDisable
:
268 AM
= GlobalISelAbortMode::Disable
;
270 case LLVMGlobalISelAbortEnable
:
271 AM
= GlobalISelAbortMode::Enable
;
273 case LLVMGlobalISelAbortDisableWithDiag
:
274 AM
= GlobalISelAbortMode::DisableWithDiag
;
278 unwrap(T
)->setGlobalISelAbort(AM
);
281 void LLVMSetTargetMachineMachineOutliner(LLVMTargetMachineRef T
,
283 unwrap(T
)->setMachineOutliner(Enable
);
286 LLVMTargetDataRef
LLVMCreateTargetDataLayout(LLVMTargetMachineRef T
) {
287 return wrap(new DataLayout(unwrap(T
)->createDataLayout()));
290 static LLVMBool
LLVMTargetMachineEmit(LLVMTargetMachineRef T
, LLVMModuleRef M
,
291 raw_pwrite_stream
&OS
,
292 LLVMCodeGenFileType codegen
,
293 char **ErrorMessage
) {
294 TargetMachine
* TM
= unwrap(T
);
295 Module
* Mod
= unwrap(M
);
297 legacy::PassManager pass
;
301 Mod
->setDataLayout(TM
->createDataLayout());
305 case LLVMAssemblyFile
:
306 ft
= CodeGenFileType::AssemblyFile
;
309 ft
= CodeGenFileType::ObjectFile
;
312 if (TM
->addPassesToEmitFile(pass
, OS
, nullptr, ft
)) {
313 error
= "TargetMachine can't emit a file of this type";
314 *ErrorMessage
= strdup(error
.c_str());
324 LLVMBool
LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T
, LLVMModuleRef M
,
325 const char *Filename
,
326 LLVMCodeGenFileType codegen
,
327 char **ErrorMessage
) {
329 raw_fd_ostream
dest(Filename
, EC
, sys::fs::OF_None
);
331 *ErrorMessage
= strdup(EC
.message().c_str());
334 bool Result
= LLVMTargetMachineEmit(T
, M
, dest
, codegen
, ErrorMessage
);
339 LLVMBool
LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T
,
340 LLVMModuleRef M
, LLVMCodeGenFileType codegen
, char** ErrorMessage
,
341 LLVMMemoryBufferRef
*OutMemBuf
) {
342 SmallString
<0> CodeString
;
343 raw_svector_ostream
OStream(CodeString
);
344 bool Result
= LLVMTargetMachineEmit(T
, M
, OStream
, codegen
, ErrorMessage
);
346 StringRef Data
= OStream
.str();
348 LLVMCreateMemoryBufferWithMemoryRangeCopy(Data
.data(), Data
.size(), "");
352 char *LLVMGetDefaultTargetTriple(void) {
353 return strdup(sys::getDefaultTargetTriple().c_str());
356 char *LLVMNormalizeTargetTriple(const char* triple
) {
357 return strdup(Triple::normalize(StringRef(triple
)).c_str());
360 char *LLVMGetHostCPUName(void) {
361 return strdup(sys::getHostCPUName().data());
364 char *LLVMGetHostCPUFeatures(void) {
365 SubtargetFeatures Features
;
366 for (const auto &[Feature
, IsEnabled
] : sys::getHostCPUFeatures())
367 Features
.AddFeature(Feature
, IsEnabled
);
369 return strdup(Features
.getString().c_str());
372 void LLVMAddAnalysisPasses(LLVMTargetMachineRef T
, LLVMPassManagerRef PM
) {
374 createTargetTransformInfoWrapperPass(unwrap(T
)->getTargetIRAnalysis()));