10b57cec5SDimitry Andric //===-- TargetMachine.cpp -------------------------------------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the LLVM-C part of TargetMachine.h
100b57cec5SDimitry Andric //
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric
130b57cec5SDimitry Andric #include "llvm-c/Core.h"
140b57cec5SDimitry Andric #include "llvm-c/TargetMachine.h"
150b57cec5SDimitry Andric #include "llvm/Analysis/TargetTransformInfo.h"
160b57cec5SDimitry Andric #include "llvm/IR/DataLayout.h"
170b57cec5SDimitry Andric #include "llvm/IR/LegacyPassManager.h"
180b57cec5SDimitry Andric #include "llvm/IR/Module.h"
19349cc55cSDimitry Andric #include "llvm/MC/TargetRegistry.h"
20*c9157d92SDimitry Andric #include "llvm/Support/CBindingWrapping.h"
210b57cec5SDimitry Andric #include "llvm/Support/FileSystem.h"
220b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
230b57cec5SDimitry Andric #include "llvm/Target/CodeGenCWrappers.h"
240b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h"
25fe013be4SDimitry Andric #include "llvm/TargetParser/Host.h"
26fe013be4SDimitry Andric #include "llvm/TargetParser/SubtargetFeature.h"
270b57cec5SDimitry Andric #include <cstring>
28bdd1243dSDimitry Andric #include <optional>
290b57cec5SDimitry Andric
300b57cec5SDimitry Andric using namespace llvm;
310b57cec5SDimitry Andric
32*c9157d92SDimitry Andric namespace llvm {
33*c9157d92SDimitry Andric
34*c9157d92SDimitry Andric /// Options for LLVMCreateTargetMachine().
35*c9157d92SDimitry Andric struct LLVMTargetMachineOptions {
36*c9157d92SDimitry Andric std::string CPU;
37*c9157d92SDimitry Andric std::string Features;
38*c9157d92SDimitry Andric std::string ABI;
39*c9157d92SDimitry Andric CodeGenOptLevel OL = CodeGenOptLevel::Default;
40*c9157d92SDimitry Andric std::optional<Reloc::Model> RM;
41*c9157d92SDimitry Andric std::optional<CodeModel::Model> CM;
42*c9157d92SDimitry Andric bool JIT;
43*c9157d92SDimitry Andric };
44*c9157d92SDimitry Andric
45*c9157d92SDimitry Andric } // namespace llvm
46*c9157d92SDimitry Andric
DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMTargetMachineOptions,LLVMTargetMachineOptionsRef)47*c9157d92SDimitry Andric DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMTargetMachineOptions,
48*c9157d92SDimitry Andric LLVMTargetMachineOptionsRef)
49*c9157d92SDimitry Andric
500b57cec5SDimitry Andric static TargetMachine *unwrap(LLVMTargetMachineRef P) {
510b57cec5SDimitry Andric return reinterpret_cast<TargetMachine *>(P);
520b57cec5SDimitry Andric }
unwrap(LLVMTargetRef P)530b57cec5SDimitry Andric static Target *unwrap(LLVMTargetRef P) {
540b57cec5SDimitry Andric return reinterpret_cast<Target*>(P);
550b57cec5SDimitry Andric }
wrap(const TargetMachine * P)560b57cec5SDimitry Andric static LLVMTargetMachineRef wrap(const TargetMachine *P) {
570b57cec5SDimitry Andric return reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine *>(P));
580b57cec5SDimitry Andric }
wrap(const Target * P)590b57cec5SDimitry Andric static LLVMTargetRef wrap(const Target * P) {
600b57cec5SDimitry Andric return reinterpret_cast<LLVMTargetRef>(const_cast<Target*>(P));
610b57cec5SDimitry Andric }
620b57cec5SDimitry Andric
LLVMGetFirstTarget()630b57cec5SDimitry Andric LLVMTargetRef LLVMGetFirstTarget() {
640b57cec5SDimitry Andric if (TargetRegistry::targets().begin() == TargetRegistry::targets().end()) {
650b57cec5SDimitry Andric return nullptr;
660b57cec5SDimitry Andric }
670b57cec5SDimitry Andric
680b57cec5SDimitry Andric const Target *target = &*TargetRegistry::targets().begin();
690b57cec5SDimitry Andric return wrap(target);
700b57cec5SDimitry Andric }
LLVMGetNextTarget(LLVMTargetRef T)710b57cec5SDimitry Andric LLVMTargetRef LLVMGetNextTarget(LLVMTargetRef T) {
720b57cec5SDimitry Andric return wrap(unwrap(T)->getNext());
730b57cec5SDimitry Andric }
740b57cec5SDimitry Andric
LLVMGetTargetFromName(const char * Name)750b57cec5SDimitry Andric LLVMTargetRef LLVMGetTargetFromName(const char *Name) {
760b57cec5SDimitry Andric StringRef NameRef = Name;
770b57cec5SDimitry Andric auto I = find_if(TargetRegistry::targets(),
780b57cec5SDimitry Andric [&](const Target &T) { return T.getName() == NameRef; });
790b57cec5SDimitry Andric return I != TargetRegistry::targets().end() ? wrap(&*I) : nullptr;
800b57cec5SDimitry Andric }
810b57cec5SDimitry Andric
LLVMGetTargetFromTriple(const char * TripleStr,LLVMTargetRef * T,char ** ErrorMessage)820b57cec5SDimitry Andric LLVMBool LLVMGetTargetFromTriple(const char* TripleStr, LLVMTargetRef *T,
830b57cec5SDimitry Andric char **ErrorMessage) {
840b57cec5SDimitry Andric std::string Error;
850b57cec5SDimitry Andric
860b57cec5SDimitry Andric *T = wrap(TargetRegistry::lookupTarget(TripleStr, Error));
870b57cec5SDimitry Andric
880b57cec5SDimitry Andric if (!*T) {
890b57cec5SDimitry Andric if (ErrorMessage)
900b57cec5SDimitry Andric *ErrorMessage = strdup(Error.c_str());
910b57cec5SDimitry Andric
920b57cec5SDimitry Andric return 1;
930b57cec5SDimitry Andric }
940b57cec5SDimitry Andric
950b57cec5SDimitry Andric return 0;
960b57cec5SDimitry Andric }
970b57cec5SDimitry Andric
LLVMGetTargetName(LLVMTargetRef T)980b57cec5SDimitry Andric const char * LLVMGetTargetName(LLVMTargetRef T) {
990b57cec5SDimitry Andric return unwrap(T)->getName();
1000b57cec5SDimitry Andric }
1010b57cec5SDimitry Andric
LLVMGetTargetDescription(LLVMTargetRef T)1020b57cec5SDimitry Andric const char * LLVMGetTargetDescription(LLVMTargetRef T) {
1030b57cec5SDimitry Andric return unwrap(T)->getShortDescription();
1040b57cec5SDimitry Andric }
1050b57cec5SDimitry Andric
LLVMTargetHasJIT(LLVMTargetRef T)1060b57cec5SDimitry Andric LLVMBool LLVMTargetHasJIT(LLVMTargetRef T) {
1070b57cec5SDimitry Andric return unwrap(T)->hasJIT();
1080b57cec5SDimitry Andric }
1090b57cec5SDimitry Andric
LLVMTargetHasTargetMachine(LLVMTargetRef T)1100b57cec5SDimitry Andric LLVMBool LLVMTargetHasTargetMachine(LLVMTargetRef T) {
1110b57cec5SDimitry Andric return unwrap(T)->hasTargetMachine();
1120b57cec5SDimitry Andric }
1130b57cec5SDimitry Andric
LLVMTargetHasAsmBackend(LLVMTargetRef T)1140b57cec5SDimitry Andric LLVMBool LLVMTargetHasAsmBackend(LLVMTargetRef T) {
1150b57cec5SDimitry Andric return unwrap(T)->hasMCAsmBackend();
1160b57cec5SDimitry Andric }
1170b57cec5SDimitry Andric
LLVMCreateTargetMachineOptions(void)118*c9157d92SDimitry Andric LLVMTargetMachineOptionsRef LLVMCreateTargetMachineOptions(void) {
119*c9157d92SDimitry Andric return wrap(new LLVMTargetMachineOptions());
120*c9157d92SDimitry Andric }
121*c9157d92SDimitry Andric
LLVMDisposeTargetMachineOptions(LLVMTargetMachineOptionsRef Options)122*c9157d92SDimitry Andric void LLVMDisposeTargetMachineOptions(LLVMTargetMachineOptionsRef Options) {
123*c9157d92SDimitry Andric delete unwrap(Options);
124*c9157d92SDimitry Andric }
125*c9157d92SDimitry Andric
LLVMTargetMachineOptionsSetCPU(LLVMTargetMachineOptionsRef Options,const char * CPU)126*c9157d92SDimitry Andric void LLVMTargetMachineOptionsSetCPU(LLVMTargetMachineOptionsRef Options,
127*c9157d92SDimitry Andric const char *CPU) {
128*c9157d92SDimitry Andric unwrap(Options)->CPU = CPU;
129*c9157d92SDimitry Andric }
130*c9157d92SDimitry Andric
LLVMTargetMachineOptionsSetFeatures(LLVMTargetMachineOptionsRef Options,const char * Features)131*c9157d92SDimitry Andric void LLVMTargetMachineOptionsSetFeatures(LLVMTargetMachineOptionsRef Options,
132*c9157d92SDimitry Andric const char *Features) {
133*c9157d92SDimitry Andric unwrap(Options)->Features = Features;
134*c9157d92SDimitry Andric }
135*c9157d92SDimitry Andric
LLVMTargetMachineOptionsSetABI(LLVMTargetMachineOptionsRef Options,const char * ABI)136*c9157d92SDimitry Andric void LLVMTargetMachineOptionsSetABI(LLVMTargetMachineOptionsRef Options,
137*c9157d92SDimitry Andric const char *ABI) {
138*c9157d92SDimitry Andric unwrap(Options)->ABI = ABI;
139*c9157d92SDimitry Andric }
140*c9157d92SDimitry Andric
LLVMTargetMachineOptionsSetCodeGenOptLevel(LLVMTargetMachineOptionsRef Options,LLVMCodeGenOptLevel Level)141*c9157d92SDimitry Andric void LLVMTargetMachineOptionsSetCodeGenOptLevel(
142*c9157d92SDimitry Andric LLVMTargetMachineOptionsRef Options, LLVMCodeGenOptLevel Level) {
143*c9157d92SDimitry Andric CodeGenOptLevel OL;
144*c9157d92SDimitry Andric
145*c9157d92SDimitry Andric switch (Level) {
146*c9157d92SDimitry Andric case LLVMCodeGenLevelNone:
147*c9157d92SDimitry Andric OL = CodeGenOptLevel::None;
148*c9157d92SDimitry Andric break;
149*c9157d92SDimitry Andric case LLVMCodeGenLevelLess:
150*c9157d92SDimitry Andric OL = CodeGenOptLevel::Less;
151*c9157d92SDimitry Andric break;
152*c9157d92SDimitry Andric case LLVMCodeGenLevelAggressive:
153*c9157d92SDimitry Andric OL = CodeGenOptLevel::Aggressive;
154*c9157d92SDimitry Andric break;
155*c9157d92SDimitry Andric case LLVMCodeGenLevelDefault:
156*c9157d92SDimitry Andric OL = CodeGenOptLevel::Default;
157*c9157d92SDimitry Andric break;
158*c9157d92SDimitry Andric }
159*c9157d92SDimitry Andric
160*c9157d92SDimitry Andric unwrap(Options)->OL = OL;
161*c9157d92SDimitry Andric }
162*c9157d92SDimitry Andric
LLVMTargetMachineOptionsSetRelocMode(LLVMTargetMachineOptionsRef Options,LLVMRelocMode Reloc)163*c9157d92SDimitry Andric void LLVMTargetMachineOptionsSetRelocMode(LLVMTargetMachineOptionsRef Options,
164*c9157d92SDimitry Andric LLVMRelocMode Reloc) {
165bdd1243dSDimitry Andric std::optional<Reloc::Model> RM;
166*c9157d92SDimitry Andric
1670b57cec5SDimitry Andric switch (Reloc) {
1680b57cec5SDimitry Andric case LLVMRelocStatic:
1690b57cec5SDimitry Andric RM = Reloc::Static;
1700b57cec5SDimitry Andric break;
1710b57cec5SDimitry Andric case LLVMRelocPIC:
1720b57cec5SDimitry Andric RM = Reloc::PIC_;
1730b57cec5SDimitry Andric break;
1740b57cec5SDimitry Andric case LLVMRelocDynamicNoPic:
1750b57cec5SDimitry Andric RM = Reloc::DynamicNoPIC;
1760b57cec5SDimitry Andric break;
1770b57cec5SDimitry Andric case LLVMRelocROPI:
1780b57cec5SDimitry Andric RM = Reloc::ROPI;
1790b57cec5SDimitry Andric break;
1800b57cec5SDimitry Andric case LLVMRelocRWPI:
1810b57cec5SDimitry Andric RM = Reloc::RWPI;
1820b57cec5SDimitry Andric break;
1830b57cec5SDimitry Andric case LLVMRelocROPI_RWPI:
1840b57cec5SDimitry Andric RM = Reloc::ROPI_RWPI;
1850b57cec5SDimitry Andric break;
186*c9157d92SDimitry Andric case LLVMRelocDefault:
1870b57cec5SDimitry Andric break;
1880b57cec5SDimitry Andric }
1890b57cec5SDimitry Andric
190*c9157d92SDimitry Andric unwrap(Options)->RM = RM;
1910b57cec5SDimitry Andric }
1920b57cec5SDimitry Andric
LLVMTargetMachineOptionsSetCodeModel(LLVMTargetMachineOptionsRef Options,LLVMCodeModel CodeModel)193*c9157d92SDimitry Andric void LLVMTargetMachineOptionsSetCodeModel(LLVMTargetMachineOptionsRef Options,
194*c9157d92SDimitry Andric LLVMCodeModel CodeModel) {
195*c9157d92SDimitry Andric auto CM = unwrap(CodeModel, unwrap(Options)->JIT);
196*c9157d92SDimitry Andric unwrap(Options)->CM = CM;
197*c9157d92SDimitry Andric }
198*c9157d92SDimitry Andric
199*c9157d92SDimitry Andric LLVMTargetMachineRef
LLVMCreateTargetMachineWithOptions(LLVMTargetRef T,const char * Triple,LLVMTargetMachineOptionsRef Options)200*c9157d92SDimitry Andric LLVMCreateTargetMachineWithOptions(LLVMTargetRef T, const char *Triple,
201*c9157d92SDimitry Andric LLVMTargetMachineOptionsRef Options) {
202*c9157d92SDimitry Andric auto *Opt = unwrap(Options);
203*c9157d92SDimitry Andric TargetOptions TO;
204*c9157d92SDimitry Andric TO.MCOptions.ABIName = Opt->ABI;
205*c9157d92SDimitry Andric return wrap(unwrap(T)->createTargetMachine(Triple, Opt->CPU, Opt->Features,
206*c9157d92SDimitry Andric TO, Opt->RM, Opt->CM, Opt->OL,
207*c9157d92SDimitry Andric Opt->JIT));
208*c9157d92SDimitry Andric }
209*c9157d92SDimitry Andric
210*c9157d92SDimitry Andric LLVMTargetMachineRef
LLVMCreateTargetMachine(LLVMTargetRef T,const char * Triple,const char * CPU,const char * Features,LLVMCodeGenOptLevel Level,LLVMRelocMode Reloc,LLVMCodeModel CodeModel)211*c9157d92SDimitry Andric LLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple, const char *CPU,
212*c9157d92SDimitry Andric const char *Features, LLVMCodeGenOptLevel Level,
213*c9157d92SDimitry Andric LLVMRelocMode Reloc, LLVMCodeModel CodeModel) {
214*c9157d92SDimitry Andric auto *Options = LLVMCreateTargetMachineOptions();
215*c9157d92SDimitry Andric
216*c9157d92SDimitry Andric LLVMTargetMachineOptionsSetCPU(Options, CPU);
217*c9157d92SDimitry Andric LLVMTargetMachineOptionsSetFeatures(Options, Features);
218*c9157d92SDimitry Andric LLVMTargetMachineOptionsSetCodeGenOptLevel(Options, Level);
219*c9157d92SDimitry Andric LLVMTargetMachineOptionsSetRelocMode(Options, Reloc);
220*c9157d92SDimitry Andric LLVMTargetMachineOptionsSetCodeModel(Options, CodeModel);
221*c9157d92SDimitry Andric
222*c9157d92SDimitry Andric auto *Machine = LLVMCreateTargetMachineWithOptions(T, Triple, Options);
223*c9157d92SDimitry Andric
224*c9157d92SDimitry Andric LLVMDisposeTargetMachineOptions(Options);
225*c9157d92SDimitry Andric return Machine;
2260b57cec5SDimitry Andric }
2270b57cec5SDimitry Andric
LLVMDisposeTargetMachine(LLVMTargetMachineRef T)2280b57cec5SDimitry Andric void LLVMDisposeTargetMachine(LLVMTargetMachineRef T) { delete unwrap(T); }
2290b57cec5SDimitry Andric
LLVMGetTargetMachineTarget(LLVMTargetMachineRef T)2300b57cec5SDimitry Andric LLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T) {
2310b57cec5SDimitry Andric const Target* target = &(unwrap(T)->getTarget());
2320b57cec5SDimitry Andric return wrap(target);
2330b57cec5SDimitry Andric }
2340b57cec5SDimitry Andric
LLVMGetTargetMachineTriple(LLVMTargetMachineRef T)2350b57cec5SDimitry Andric char* LLVMGetTargetMachineTriple(LLVMTargetMachineRef T) {
2360b57cec5SDimitry Andric std::string StringRep = unwrap(T)->getTargetTriple().str();
2370b57cec5SDimitry Andric return strdup(StringRep.c_str());
2380b57cec5SDimitry Andric }
2390b57cec5SDimitry Andric
LLVMGetTargetMachineCPU(LLVMTargetMachineRef T)2400b57cec5SDimitry Andric char* LLVMGetTargetMachineCPU(LLVMTargetMachineRef T) {
2415ffd83dbSDimitry Andric std::string StringRep = std::string(unwrap(T)->getTargetCPU());
2420b57cec5SDimitry Andric return strdup(StringRep.c_str());
2430b57cec5SDimitry Andric }
2440b57cec5SDimitry Andric
LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T)2450b57cec5SDimitry Andric char* LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T) {
2465ffd83dbSDimitry Andric std::string StringRep = std::string(unwrap(T)->getTargetFeatureString());
2470b57cec5SDimitry Andric return strdup(StringRep.c_str());
2480b57cec5SDimitry Andric }
2490b57cec5SDimitry Andric
LLVMSetTargetMachineAsmVerbosity(LLVMTargetMachineRef T,LLVMBool VerboseAsm)2500b57cec5SDimitry Andric void LLVMSetTargetMachineAsmVerbosity(LLVMTargetMachineRef T,
2510b57cec5SDimitry Andric LLVMBool VerboseAsm) {
2520b57cec5SDimitry Andric unwrap(T)->Options.MCOptions.AsmVerbose = VerboseAsm;
2530b57cec5SDimitry Andric }
2540b57cec5SDimitry Andric
LLVMSetTargetMachineFastISel(LLVMTargetMachineRef T,LLVMBool Enable)255*c9157d92SDimitry Andric void LLVMSetTargetMachineFastISel(LLVMTargetMachineRef T, LLVMBool Enable) {
256*c9157d92SDimitry Andric unwrap(T)->setFastISel(Enable);
257*c9157d92SDimitry Andric }
258*c9157d92SDimitry Andric
LLVMSetTargetMachineGlobalISel(LLVMTargetMachineRef T,LLVMBool Enable)259*c9157d92SDimitry Andric void LLVMSetTargetMachineGlobalISel(LLVMTargetMachineRef T, LLVMBool Enable) {
260*c9157d92SDimitry Andric unwrap(T)->setGlobalISel(Enable);
261*c9157d92SDimitry Andric }
262*c9157d92SDimitry Andric
LLVMSetTargetMachineGlobalISelAbort(LLVMTargetMachineRef T,LLVMGlobalISelAbortMode Mode)263*c9157d92SDimitry Andric void LLVMSetTargetMachineGlobalISelAbort(LLVMTargetMachineRef T,
264*c9157d92SDimitry Andric LLVMGlobalISelAbortMode Mode) {
265*c9157d92SDimitry Andric GlobalISelAbortMode AM = GlobalISelAbortMode::Enable;
266*c9157d92SDimitry Andric switch (Mode) {
267*c9157d92SDimitry Andric case LLVMGlobalISelAbortDisable:
268*c9157d92SDimitry Andric AM = GlobalISelAbortMode::Disable;
269*c9157d92SDimitry Andric break;
270*c9157d92SDimitry Andric case LLVMGlobalISelAbortEnable:
271*c9157d92SDimitry Andric AM = GlobalISelAbortMode::Enable;
272*c9157d92SDimitry Andric break;
273*c9157d92SDimitry Andric case LLVMGlobalISelAbortDisableWithDiag:
274*c9157d92SDimitry Andric AM = GlobalISelAbortMode::DisableWithDiag;
275*c9157d92SDimitry Andric break;
276*c9157d92SDimitry Andric }
277*c9157d92SDimitry Andric
278*c9157d92SDimitry Andric unwrap(T)->setGlobalISelAbort(AM);
279*c9157d92SDimitry Andric }
280*c9157d92SDimitry Andric
LLVMSetTargetMachineMachineOutliner(LLVMTargetMachineRef T,LLVMBool Enable)281*c9157d92SDimitry Andric void LLVMSetTargetMachineMachineOutliner(LLVMTargetMachineRef T,
282*c9157d92SDimitry Andric LLVMBool Enable) {
283*c9157d92SDimitry Andric unwrap(T)->setMachineOutliner(Enable);
284*c9157d92SDimitry Andric }
285*c9157d92SDimitry Andric
LLVMCreateTargetDataLayout(LLVMTargetMachineRef T)2860b57cec5SDimitry Andric LLVMTargetDataRef LLVMCreateTargetDataLayout(LLVMTargetMachineRef T) {
2870b57cec5SDimitry Andric return wrap(new DataLayout(unwrap(T)->createDataLayout()));
2880b57cec5SDimitry Andric }
2890b57cec5SDimitry Andric
LLVMTargetMachineEmit(LLVMTargetMachineRef T,LLVMModuleRef M,raw_pwrite_stream & OS,LLVMCodeGenFileType codegen,char ** ErrorMessage)2900b57cec5SDimitry Andric static LLVMBool LLVMTargetMachineEmit(LLVMTargetMachineRef T, LLVMModuleRef M,
2910b57cec5SDimitry Andric raw_pwrite_stream &OS,
2920b57cec5SDimitry Andric LLVMCodeGenFileType codegen,
2930b57cec5SDimitry Andric char **ErrorMessage) {
2940b57cec5SDimitry Andric TargetMachine* TM = unwrap(T);
2950b57cec5SDimitry Andric Module* Mod = unwrap(M);
2960b57cec5SDimitry Andric
2970b57cec5SDimitry Andric legacy::PassManager pass;
2980b57cec5SDimitry Andric
2990b57cec5SDimitry Andric std::string error;
3000b57cec5SDimitry Andric
3010b57cec5SDimitry Andric Mod->setDataLayout(TM->createDataLayout());
3020b57cec5SDimitry Andric
303480093f4SDimitry Andric CodeGenFileType ft;
3040b57cec5SDimitry Andric switch (codegen) {
3050b57cec5SDimitry Andric case LLVMAssemblyFile:
306*c9157d92SDimitry Andric ft = CodeGenFileType::AssemblyFile;
3070b57cec5SDimitry Andric break;
3080b57cec5SDimitry Andric default:
309*c9157d92SDimitry Andric ft = CodeGenFileType::ObjectFile;
3100b57cec5SDimitry Andric break;
3110b57cec5SDimitry Andric }
3120b57cec5SDimitry Andric if (TM->addPassesToEmitFile(pass, OS, nullptr, ft)) {
3130b57cec5SDimitry Andric error = "TargetMachine can't emit a file of this type";
3140b57cec5SDimitry Andric *ErrorMessage = strdup(error.c_str());
3150b57cec5SDimitry Andric return true;
3160b57cec5SDimitry Andric }
3170b57cec5SDimitry Andric
3180b57cec5SDimitry Andric pass.run(*Mod);
3190b57cec5SDimitry Andric
3200b57cec5SDimitry Andric OS.flush();
3210b57cec5SDimitry Andric return false;
3220b57cec5SDimitry Andric }
3230b57cec5SDimitry Andric
LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T,LLVMModuleRef M,const char * Filename,LLVMCodeGenFileType codegen,char ** ErrorMessage)3240b57cec5SDimitry Andric LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,
32581ad6265SDimitry Andric const char *Filename,
32681ad6265SDimitry Andric LLVMCodeGenFileType codegen,
32781ad6265SDimitry Andric char **ErrorMessage) {
3280b57cec5SDimitry Andric std::error_code EC;
3298bcb0991SDimitry Andric raw_fd_ostream dest(Filename, EC, sys::fs::OF_None);
3300b57cec5SDimitry Andric if (EC) {
3310b57cec5SDimitry Andric *ErrorMessage = strdup(EC.message().c_str());
3320b57cec5SDimitry Andric return true;
3330b57cec5SDimitry Andric }
3340b57cec5SDimitry Andric bool Result = LLVMTargetMachineEmit(T, M, dest, codegen, ErrorMessage);
3350b57cec5SDimitry Andric dest.flush();
3360b57cec5SDimitry Andric return Result;
3370b57cec5SDimitry Andric }
3380b57cec5SDimitry Andric
LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T,LLVMModuleRef M,LLVMCodeGenFileType codegen,char ** ErrorMessage,LLVMMemoryBufferRef * OutMemBuf)3390b57cec5SDimitry Andric LLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T,
3400b57cec5SDimitry Andric LLVMModuleRef M, LLVMCodeGenFileType codegen, char** ErrorMessage,
3410b57cec5SDimitry Andric LLVMMemoryBufferRef *OutMemBuf) {
3420b57cec5SDimitry Andric SmallString<0> CodeString;
3430b57cec5SDimitry Andric raw_svector_ostream OStream(CodeString);
3440b57cec5SDimitry Andric bool Result = LLVMTargetMachineEmit(T, M, OStream, codegen, ErrorMessage);
3450b57cec5SDimitry Andric
3460b57cec5SDimitry Andric StringRef Data = OStream.str();
3470b57cec5SDimitry Andric *OutMemBuf =
3480b57cec5SDimitry Andric LLVMCreateMemoryBufferWithMemoryRangeCopy(Data.data(), Data.size(), "");
3490b57cec5SDimitry Andric return Result;
3500b57cec5SDimitry Andric }
3510b57cec5SDimitry Andric
LLVMGetDefaultTargetTriple(void)3520b57cec5SDimitry Andric char *LLVMGetDefaultTargetTriple(void) {
3530b57cec5SDimitry Andric return strdup(sys::getDefaultTargetTriple().c_str());
3540b57cec5SDimitry Andric }
3550b57cec5SDimitry Andric
LLVMNormalizeTargetTriple(const char * triple)3560b57cec5SDimitry Andric char *LLVMNormalizeTargetTriple(const char* triple) {
3570b57cec5SDimitry Andric return strdup(Triple::normalize(StringRef(triple)).c_str());
3580b57cec5SDimitry Andric }
3590b57cec5SDimitry Andric
LLVMGetHostCPUName(void)3600b57cec5SDimitry Andric char *LLVMGetHostCPUName(void) {
3610b57cec5SDimitry Andric return strdup(sys::getHostCPUName().data());
3620b57cec5SDimitry Andric }
3630b57cec5SDimitry Andric
LLVMGetHostCPUFeatures(void)3640b57cec5SDimitry Andric char *LLVMGetHostCPUFeatures(void) {
3650b57cec5SDimitry Andric SubtargetFeatures Features;
3660b57cec5SDimitry Andric StringMap<bool> HostFeatures;
3670b57cec5SDimitry Andric
3680b57cec5SDimitry Andric if (sys::getHostCPUFeatures(HostFeatures))
369bdd1243dSDimitry Andric for (const auto &[Feature, IsEnabled] : HostFeatures)
370bdd1243dSDimitry Andric Features.AddFeature(Feature, IsEnabled);
3710b57cec5SDimitry Andric
3720b57cec5SDimitry Andric return strdup(Features.getString().c_str());
3730b57cec5SDimitry Andric }
3740b57cec5SDimitry Andric
LLVMAddAnalysisPasses(LLVMTargetMachineRef T,LLVMPassManagerRef PM)3750b57cec5SDimitry Andric void LLVMAddAnalysisPasses(LLVMTargetMachineRef T, LLVMPassManagerRef PM) {
3760b57cec5SDimitry Andric unwrap(PM)->add(
3770b57cec5SDimitry Andric createTargetTransformInfoWrapperPass(unwrap(T)->getTargetIRAnalysis()));
3780b57cec5SDimitry Andric }
379