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