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