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/Target.h"
15 #include "llvm-c/TargetMachine.h"
16 #include "llvm/Analysis/TargetTransformInfo.h"
17 #include "llvm/IR/DataLayout.h"
18 #include "llvm/IR/LegacyPassManager.h"
19 #include "llvm/IR/Module.h"
20 #include "llvm/MC/SubtargetFeature.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/CodeGenCWrappers.h"
27 #include "llvm/Target/TargetMachine.h"
34 static TargetMachine
*unwrap(LLVMTargetMachineRef P
) {
35 return reinterpret_cast<TargetMachine
*>(P
);
37 static Target
*unwrap(LLVMTargetRef P
) {
38 return reinterpret_cast<Target
*>(P
);
40 static LLVMTargetMachineRef
wrap(const TargetMachine
*P
) {
41 return reinterpret_cast<LLVMTargetMachineRef
>(const_cast<TargetMachine
*>(P
));
43 static LLVMTargetRef
wrap(const Target
* P
) {
44 return reinterpret_cast<LLVMTargetRef
>(const_cast<Target
*>(P
));
47 LLVMTargetRef
LLVMGetFirstTarget() {
48 if (TargetRegistry::targets().begin() == TargetRegistry::targets().end()) {
52 const Target
*target
= &*TargetRegistry::targets().begin();
55 LLVMTargetRef
LLVMGetNextTarget(LLVMTargetRef T
) {
56 return wrap(unwrap(T
)->getNext());
59 LLVMTargetRef
LLVMGetTargetFromName(const char *Name
) {
60 StringRef NameRef
= Name
;
61 auto I
= find_if(TargetRegistry::targets(),
62 [&](const Target
&T
) { return T
.getName() == NameRef
; });
63 return I
!= TargetRegistry::targets().end() ? wrap(&*I
) : nullptr;
66 LLVMBool
LLVMGetTargetFromTriple(const char* TripleStr
, LLVMTargetRef
*T
,
67 char **ErrorMessage
) {
70 *T
= wrap(TargetRegistry::lookupTarget(TripleStr
, Error
));
74 *ErrorMessage
= strdup(Error
.c_str());
82 const char * LLVMGetTargetName(LLVMTargetRef T
) {
83 return unwrap(T
)->getName();
86 const char * LLVMGetTargetDescription(LLVMTargetRef T
) {
87 return unwrap(T
)->getShortDescription();
90 LLVMBool
LLVMTargetHasJIT(LLVMTargetRef T
) {
91 return unwrap(T
)->hasJIT();
94 LLVMBool
LLVMTargetHasTargetMachine(LLVMTargetRef T
) {
95 return unwrap(T
)->hasTargetMachine();
98 LLVMBool
LLVMTargetHasAsmBackend(LLVMTargetRef T
) {
99 return unwrap(T
)->hasMCAsmBackend();
102 LLVMTargetMachineRef
LLVMCreateTargetMachine(LLVMTargetRef T
,
103 const char *Triple
, const char *CPU
, const char *Features
,
104 LLVMCodeGenOptLevel Level
, LLVMRelocMode Reloc
,
105 LLVMCodeModel CodeModel
) {
106 Optional
<Reloc::Model
> RM
;
108 case LLVMRelocStatic
:
114 case LLVMRelocDynamicNoPic
:
115 RM
= Reloc::DynamicNoPIC
;
123 case LLVMRelocROPI_RWPI
:
124 RM
= Reloc::ROPI_RWPI
;
131 Optional
<CodeModel::Model
> CM
= unwrap(CodeModel
, JIT
);
133 CodeGenOpt::Level OL
;
135 case LLVMCodeGenLevelNone
:
136 OL
= CodeGenOpt::None
;
138 case LLVMCodeGenLevelLess
:
139 OL
= CodeGenOpt::Less
;
141 case LLVMCodeGenLevelAggressive
:
142 OL
= CodeGenOpt::Aggressive
;
145 OL
= CodeGenOpt::Default
;
150 return wrap(unwrap(T
)->createTargetMachine(Triple
, CPU
, Features
, opt
, RM
, CM
,
154 void LLVMDisposeTargetMachine(LLVMTargetMachineRef T
) { delete unwrap(T
); }
156 LLVMTargetRef
LLVMGetTargetMachineTarget(LLVMTargetMachineRef T
) {
157 const Target
* target
= &(unwrap(T
)->getTarget());
161 char* LLVMGetTargetMachineTriple(LLVMTargetMachineRef T
) {
162 std::string StringRep
= unwrap(T
)->getTargetTriple().str();
163 return strdup(StringRep
.c_str());
166 char* LLVMGetTargetMachineCPU(LLVMTargetMachineRef T
) {
167 std::string StringRep
= unwrap(T
)->getTargetCPU();
168 return strdup(StringRep
.c_str());
171 char* LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T
) {
172 std::string StringRep
= unwrap(T
)->getTargetFeatureString();
173 return strdup(StringRep
.c_str());
176 void LLVMSetTargetMachineAsmVerbosity(LLVMTargetMachineRef T
,
177 LLVMBool VerboseAsm
) {
178 unwrap(T
)->Options
.MCOptions
.AsmVerbose
= VerboseAsm
;
181 LLVMTargetDataRef
LLVMCreateTargetDataLayout(LLVMTargetMachineRef T
) {
182 return wrap(new DataLayout(unwrap(T
)->createDataLayout()));
185 static LLVMBool
LLVMTargetMachineEmit(LLVMTargetMachineRef T
, LLVMModuleRef M
,
186 raw_pwrite_stream
&OS
,
187 LLVMCodeGenFileType codegen
,
188 char **ErrorMessage
) {
189 TargetMachine
* TM
= unwrap(T
);
190 Module
* Mod
= unwrap(M
);
192 legacy::PassManager pass
;
196 Mod
->setDataLayout(TM
->createDataLayout());
198 TargetMachine::CodeGenFileType ft
;
200 case LLVMAssemblyFile
:
201 ft
= TargetMachine::CGFT_AssemblyFile
;
204 ft
= TargetMachine::CGFT_ObjectFile
;
207 if (TM
->addPassesToEmitFile(pass
, OS
, nullptr, ft
)) {
208 error
= "TargetMachine can't emit a file of this type";
209 *ErrorMessage
= strdup(error
.c_str());
219 LLVMBool
LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T
, LLVMModuleRef M
,
220 char* Filename
, LLVMCodeGenFileType codegen
, char** ErrorMessage
) {
222 raw_fd_ostream
dest(Filename
, EC
, sys::fs::F_None
);
224 *ErrorMessage
= strdup(EC
.message().c_str());
227 bool Result
= LLVMTargetMachineEmit(T
, M
, dest
, codegen
, ErrorMessage
);
232 LLVMBool
LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T
,
233 LLVMModuleRef M
, LLVMCodeGenFileType codegen
, char** ErrorMessage
,
234 LLVMMemoryBufferRef
*OutMemBuf
) {
235 SmallString
<0> CodeString
;
236 raw_svector_ostream
OStream(CodeString
);
237 bool Result
= LLVMTargetMachineEmit(T
, M
, OStream
, codegen
, ErrorMessage
);
239 StringRef Data
= OStream
.str();
241 LLVMCreateMemoryBufferWithMemoryRangeCopy(Data
.data(), Data
.size(), "");
245 char *LLVMGetDefaultTargetTriple(void) {
246 return strdup(sys::getDefaultTargetTriple().c_str());
249 char *LLVMNormalizeTargetTriple(const char* triple
) {
250 return strdup(Triple::normalize(StringRef(triple
)).c_str());
253 char *LLVMGetHostCPUName(void) {
254 return strdup(sys::getHostCPUName().data());
257 char *LLVMGetHostCPUFeatures(void) {
258 SubtargetFeatures Features
;
259 StringMap
<bool> HostFeatures
;
261 if (sys::getHostCPUFeatures(HostFeatures
))
262 for (auto &F
: HostFeatures
)
263 Features
.AddFeature(F
.first(), F
.second
);
265 return strdup(Features
.getString().c_str());
268 void LLVMAddAnalysisPasses(LLVMTargetMachineRef T
, LLVMPassManagerRef PM
) {
270 createTargetTransformInfoWrapperPass(unwrap(T
)->getTargetIRAnalysis()));