xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/TargetMachineC.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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"
205f757f3fSDimitry 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"
2506c3fb27SDimitry Andric #include "llvm/TargetParser/Host.h"
2606c3fb27SDimitry Andric #include "llvm/TargetParser/SubtargetFeature.h"
270b57cec5SDimitry Andric #include <cstring>
28bdd1243dSDimitry Andric #include <optional>
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric using namespace llvm;
310b57cec5SDimitry Andric 
325f757f3fSDimitry Andric namespace llvm {
335f757f3fSDimitry Andric 
345f757f3fSDimitry Andric /// Options for LLVMCreateTargetMachine().
355f757f3fSDimitry Andric struct LLVMTargetMachineOptions {
365f757f3fSDimitry Andric   std::string CPU;
375f757f3fSDimitry Andric   std::string Features;
385f757f3fSDimitry Andric   std::string ABI;
395f757f3fSDimitry Andric   CodeGenOptLevel OL = CodeGenOptLevel::Default;
405f757f3fSDimitry Andric   std::optional<Reloc::Model> RM;
415f757f3fSDimitry Andric   std::optional<CodeModel::Model> CM;
425f757f3fSDimitry Andric   bool JIT;
435f757f3fSDimitry Andric };
445f757f3fSDimitry Andric 
455f757f3fSDimitry Andric } // namespace llvm
465f757f3fSDimitry Andric 
475f757f3fSDimitry Andric DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMTargetMachineOptions,
485f757f3fSDimitry Andric                                    LLVMTargetMachineOptionsRef)
495f757f3fSDimitry Andric 
500b57cec5SDimitry Andric static TargetMachine *unwrap(LLVMTargetMachineRef P) {
510b57cec5SDimitry Andric   return reinterpret_cast<TargetMachine *>(P);
520b57cec5SDimitry Andric }
530b57cec5SDimitry Andric static Target *unwrap(LLVMTargetRef P) {
540b57cec5SDimitry Andric   return reinterpret_cast<Target*>(P);
550b57cec5SDimitry Andric }
560b57cec5SDimitry Andric static LLVMTargetMachineRef wrap(const TargetMachine *P) {
570b57cec5SDimitry Andric   return reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine *>(P));
580b57cec5SDimitry Andric }
590b57cec5SDimitry Andric static LLVMTargetRef wrap(const Target * P) {
600b57cec5SDimitry Andric   return reinterpret_cast<LLVMTargetRef>(const_cast<Target*>(P));
610b57cec5SDimitry Andric }
620b57cec5SDimitry Andric 
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 }
710b57cec5SDimitry Andric LLVMTargetRef LLVMGetNextTarget(LLVMTargetRef T) {
720b57cec5SDimitry Andric   return wrap(unwrap(T)->getNext());
730b57cec5SDimitry Andric }
740b57cec5SDimitry Andric 
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 
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 
980b57cec5SDimitry Andric const char * LLVMGetTargetName(LLVMTargetRef T) {
990b57cec5SDimitry Andric   return unwrap(T)->getName();
1000b57cec5SDimitry Andric }
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric const char * LLVMGetTargetDescription(LLVMTargetRef T) {
1030b57cec5SDimitry Andric   return unwrap(T)->getShortDescription();
1040b57cec5SDimitry Andric }
1050b57cec5SDimitry Andric 
1060b57cec5SDimitry Andric LLVMBool LLVMTargetHasJIT(LLVMTargetRef T) {
1070b57cec5SDimitry Andric   return unwrap(T)->hasJIT();
1080b57cec5SDimitry Andric }
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric LLVMBool LLVMTargetHasTargetMachine(LLVMTargetRef T) {
1110b57cec5SDimitry Andric   return unwrap(T)->hasTargetMachine();
1120b57cec5SDimitry Andric }
1130b57cec5SDimitry Andric 
1140b57cec5SDimitry Andric LLVMBool LLVMTargetHasAsmBackend(LLVMTargetRef T) {
1150b57cec5SDimitry Andric   return unwrap(T)->hasMCAsmBackend();
1160b57cec5SDimitry Andric }
1170b57cec5SDimitry Andric 
1185f757f3fSDimitry Andric LLVMTargetMachineOptionsRef LLVMCreateTargetMachineOptions(void) {
1195f757f3fSDimitry Andric   return wrap(new LLVMTargetMachineOptions());
1205f757f3fSDimitry Andric }
1215f757f3fSDimitry Andric 
1225f757f3fSDimitry Andric void LLVMDisposeTargetMachineOptions(LLVMTargetMachineOptionsRef Options) {
1235f757f3fSDimitry Andric   delete unwrap(Options);
1245f757f3fSDimitry Andric }
1255f757f3fSDimitry Andric 
1265f757f3fSDimitry Andric void LLVMTargetMachineOptionsSetCPU(LLVMTargetMachineOptionsRef Options,
1275f757f3fSDimitry Andric                                     const char *CPU) {
1285f757f3fSDimitry Andric   unwrap(Options)->CPU = CPU;
1295f757f3fSDimitry Andric }
1305f757f3fSDimitry Andric 
1315f757f3fSDimitry Andric void LLVMTargetMachineOptionsSetFeatures(LLVMTargetMachineOptionsRef Options,
1325f757f3fSDimitry Andric                                          const char *Features) {
1335f757f3fSDimitry Andric   unwrap(Options)->Features = Features;
1345f757f3fSDimitry Andric }
1355f757f3fSDimitry Andric 
1365f757f3fSDimitry Andric void LLVMTargetMachineOptionsSetABI(LLVMTargetMachineOptionsRef Options,
1375f757f3fSDimitry Andric                                     const char *ABI) {
1385f757f3fSDimitry Andric   unwrap(Options)->ABI = ABI;
1395f757f3fSDimitry Andric }
1405f757f3fSDimitry Andric 
1415f757f3fSDimitry Andric void LLVMTargetMachineOptionsSetCodeGenOptLevel(
1425f757f3fSDimitry Andric     LLVMTargetMachineOptionsRef Options, LLVMCodeGenOptLevel Level) {
1435f757f3fSDimitry Andric   CodeGenOptLevel OL;
1445f757f3fSDimitry Andric 
1455f757f3fSDimitry Andric   switch (Level) {
1465f757f3fSDimitry Andric   case LLVMCodeGenLevelNone:
1475f757f3fSDimitry Andric     OL = CodeGenOptLevel::None;
1485f757f3fSDimitry Andric     break;
1495f757f3fSDimitry Andric   case LLVMCodeGenLevelLess:
1505f757f3fSDimitry Andric     OL = CodeGenOptLevel::Less;
1515f757f3fSDimitry Andric     break;
1525f757f3fSDimitry Andric   case LLVMCodeGenLevelAggressive:
1535f757f3fSDimitry Andric     OL = CodeGenOptLevel::Aggressive;
1545f757f3fSDimitry Andric     break;
1555f757f3fSDimitry Andric   case LLVMCodeGenLevelDefault:
1565f757f3fSDimitry Andric     OL = CodeGenOptLevel::Default;
1575f757f3fSDimitry Andric     break;
1585f757f3fSDimitry Andric   }
1595f757f3fSDimitry Andric 
1605f757f3fSDimitry Andric   unwrap(Options)->OL = OL;
1615f757f3fSDimitry Andric }
1625f757f3fSDimitry Andric 
1635f757f3fSDimitry Andric void LLVMTargetMachineOptionsSetRelocMode(LLVMTargetMachineOptionsRef Options,
1645f757f3fSDimitry Andric                                           LLVMRelocMode Reloc) {
165bdd1243dSDimitry Andric   std::optional<Reloc::Model> RM;
1665f757f3fSDimitry 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;
1865f757f3fSDimitry Andric   case LLVMRelocDefault:
1870b57cec5SDimitry Andric     break;
1880b57cec5SDimitry Andric   }
1890b57cec5SDimitry Andric 
1905f757f3fSDimitry Andric   unwrap(Options)->RM = RM;
1910b57cec5SDimitry Andric }
1920b57cec5SDimitry Andric 
1935f757f3fSDimitry Andric void LLVMTargetMachineOptionsSetCodeModel(LLVMTargetMachineOptionsRef Options,
1945f757f3fSDimitry Andric                                           LLVMCodeModel CodeModel) {
1955f757f3fSDimitry Andric   auto CM = unwrap(CodeModel, unwrap(Options)->JIT);
1965f757f3fSDimitry Andric   unwrap(Options)->CM = CM;
1975f757f3fSDimitry Andric }
1985f757f3fSDimitry Andric 
1995f757f3fSDimitry Andric LLVMTargetMachineRef
2005f757f3fSDimitry Andric LLVMCreateTargetMachineWithOptions(LLVMTargetRef T, const char *Triple,
2015f757f3fSDimitry Andric                                    LLVMTargetMachineOptionsRef Options) {
2025f757f3fSDimitry Andric   auto *Opt = unwrap(Options);
2035f757f3fSDimitry Andric   TargetOptions TO;
2045f757f3fSDimitry Andric   TO.MCOptions.ABIName = Opt->ABI;
2055f757f3fSDimitry Andric   return wrap(unwrap(T)->createTargetMachine(Triple, Opt->CPU, Opt->Features,
2065f757f3fSDimitry Andric                                              TO, Opt->RM, Opt->CM, Opt->OL,
2075f757f3fSDimitry Andric                                              Opt->JIT));
2085f757f3fSDimitry Andric }
2095f757f3fSDimitry Andric 
2105f757f3fSDimitry Andric LLVMTargetMachineRef
2115f757f3fSDimitry Andric LLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple, const char *CPU,
2125f757f3fSDimitry Andric                         const char *Features, LLVMCodeGenOptLevel Level,
2135f757f3fSDimitry Andric                         LLVMRelocMode Reloc, LLVMCodeModel CodeModel) {
2145f757f3fSDimitry Andric   auto *Options = LLVMCreateTargetMachineOptions();
2155f757f3fSDimitry Andric 
2165f757f3fSDimitry Andric   LLVMTargetMachineOptionsSetCPU(Options, CPU);
2175f757f3fSDimitry Andric   LLVMTargetMachineOptionsSetFeatures(Options, Features);
2185f757f3fSDimitry Andric   LLVMTargetMachineOptionsSetCodeGenOptLevel(Options, Level);
2195f757f3fSDimitry Andric   LLVMTargetMachineOptionsSetRelocMode(Options, Reloc);
2205f757f3fSDimitry Andric   LLVMTargetMachineOptionsSetCodeModel(Options, CodeModel);
2215f757f3fSDimitry Andric 
2225f757f3fSDimitry Andric   auto *Machine = LLVMCreateTargetMachineWithOptions(T, Triple, Options);
2235f757f3fSDimitry Andric 
2245f757f3fSDimitry Andric   LLVMDisposeTargetMachineOptions(Options);
2255f757f3fSDimitry Andric   return Machine;
2260b57cec5SDimitry Andric }
2270b57cec5SDimitry Andric 
2280b57cec5SDimitry Andric void LLVMDisposeTargetMachine(LLVMTargetMachineRef T) { delete unwrap(T); }
2290b57cec5SDimitry Andric 
2300b57cec5SDimitry Andric LLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T) {
2310b57cec5SDimitry Andric   const Target* target = &(unwrap(T)->getTarget());
2320b57cec5SDimitry Andric   return wrap(target);
2330b57cec5SDimitry Andric }
2340b57cec5SDimitry Andric 
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 
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 
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 
2500b57cec5SDimitry Andric void LLVMSetTargetMachineAsmVerbosity(LLVMTargetMachineRef T,
2510b57cec5SDimitry Andric                                       LLVMBool VerboseAsm) {
2520b57cec5SDimitry Andric   unwrap(T)->Options.MCOptions.AsmVerbose = VerboseAsm;
2530b57cec5SDimitry Andric }
2540b57cec5SDimitry Andric 
2555f757f3fSDimitry Andric void LLVMSetTargetMachineFastISel(LLVMTargetMachineRef T, LLVMBool Enable) {
2565f757f3fSDimitry Andric   unwrap(T)->setFastISel(Enable);
2575f757f3fSDimitry Andric }
2585f757f3fSDimitry Andric 
2595f757f3fSDimitry Andric void LLVMSetTargetMachineGlobalISel(LLVMTargetMachineRef T, LLVMBool Enable) {
2605f757f3fSDimitry Andric   unwrap(T)->setGlobalISel(Enable);
2615f757f3fSDimitry Andric }
2625f757f3fSDimitry Andric 
2635f757f3fSDimitry Andric void LLVMSetTargetMachineGlobalISelAbort(LLVMTargetMachineRef T,
2645f757f3fSDimitry Andric                                          LLVMGlobalISelAbortMode Mode) {
2655f757f3fSDimitry Andric   GlobalISelAbortMode AM = GlobalISelAbortMode::Enable;
2665f757f3fSDimitry Andric   switch (Mode) {
2675f757f3fSDimitry Andric   case LLVMGlobalISelAbortDisable:
2685f757f3fSDimitry Andric     AM = GlobalISelAbortMode::Disable;
2695f757f3fSDimitry Andric     break;
2705f757f3fSDimitry Andric   case LLVMGlobalISelAbortEnable:
2715f757f3fSDimitry Andric     AM = GlobalISelAbortMode::Enable;
2725f757f3fSDimitry Andric     break;
2735f757f3fSDimitry Andric   case LLVMGlobalISelAbortDisableWithDiag:
2745f757f3fSDimitry Andric     AM = GlobalISelAbortMode::DisableWithDiag;
2755f757f3fSDimitry Andric     break;
2765f757f3fSDimitry Andric   }
2775f757f3fSDimitry Andric 
2785f757f3fSDimitry Andric   unwrap(T)->setGlobalISelAbort(AM);
2795f757f3fSDimitry Andric }
2805f757f3fSDimitry Andric 
2815f757f3fSDimitry Andric void LLVMSetTargetMachineMachineOutliner(LLVMTargetMachineRef T,
2825f757f3fSDimitry Andric                                          LLVMBool Enable) {
2835f757f3fSDimitry Andric   unwrap(T)->setMachineOutliner(Enable);
2845f757f3fSDimitry Andric }
2855f757f3fSDimitry Andric 
2860b57cec5SDimitry Andric LLVMTargetDataRef LLVMCreateTargetDataLayout(LLVMTargetMachineRef T) {
2870b57cec5SDimitry Andric   return wrap(new DataLayout(unwrap(T)->createDataLayout()));
2880b57cec5SDimitry Andric }
2890b57cec5SDimitry Andric 
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:
3065f757f3fSDimitry Andric       ft = CodeGenFileType::AssemblyFile;
3070b57cec5SDimitry Andric       break;
3080b57cec5SDimitry Andric     default:
3095f757f3fSDimitry 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 
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 
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 
3520b57cec5SDimitry Andric char *LLVMGetDefaultTargetTriple(void) {
3530b57cec5SDimitry Andric   return strdup(sys::getDefaultTargetTriple().c_str());
3540b57cec5SDimitry Andric }
3550b57cec5SDimitry Andric 
3560b57cec5SDimitry Andric char *LLVMNormalizeTargetTriple(const char* triple) {
3570b57cec5SDimitry Andric   return strdup(Triple::normalize(StringRef(triple)).c_str());
3580b57cec5SDimitry Andric }
3590b57cec5SDimitry Andric 
3600b57cec5SDimitry Andric char *LLVMGetHostCPUName(void) {
3610b57cec5SDimitry Andric   return strdup(sys::getHostCPUName().data());
3620b57cec5SDimitry Andric }
3630b57cec5SDimitry Andric 
3640b57cec5SDimitry Andric char *LLVMGetHostCPUFeatures(void) {
3650b57cec5SDimitry Andric   SubtargetFeatures Features;
366*0fca6ea1SDimitry Andric   for (const auto &[Feature, IsEnabled] : sys::getHostCPUFeatures())
367bdd1243dSDimitry Andric     Features.AddFeature(Feature, IsEnabled);
3680b57cec5SDimitry Andric 
3690b57cec5SDimitry Andric   return strdup(Features.getString().c_str());
3700b57cec5SDimitry Andric }
3710b57cec5SDimitry Andric 
3720b57cec5SDimitry Andric void LLVMAddAnalysisPasses(LLVMTargetMachineRef T, LLVMPassManagerRef PM) {
3730b57cec5SDimitry Andric   unwrap(PM)->add(
3740b57cec5SDimitry Andric       createTargetTransformInfoWrapperPass(unwrap(T)->getTargetIRAnalysis()));
3750b57cec5SDimitry Andric }
376