Path: blob/main/contrib/llvm-project/llvm/lib/Target/TargetMachineC.cpp
35233 views
//===-- TargetMachine.cpp -------------------------------------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// This file implements the LLVM-C part of TargetMachine.h9//10//===----------------------------------------------------------------------===//1112#include "llvm-c/Core.h"13#include "llvm-c/TargetMachine.h"14#include "llvm/Analysis/TargetTransformInfo.h"15#include "llvm/IR/DataLayout.h"16#include "llvm/IR/LegacyPassManager.h"17#include "llvm/IR/Module.h"18#include "llvm/MC/TargetRegistry.h"19#include "llvm/Support/CBindingWrapping.h"20#include "llvm/Support/FileSystem.h"21#include "llvm/Support/raw_ostream.h"22#include "llvm/Target/CodeGenCWrappers.h"23#include "llvm/Target/TargetMachine.h"24#include "llvm/TargetParser/Host.h"25#include "llvm/TargetParser/SubtargetFeature.h"26#include <cstring>27#include <optional>2829using namespace llvm;3031namespace llvm {3233/// Options for LLVMCreateTargetMachine().34struct LLVMTargetMachineOptions {35std::string CPU;36std::string Features;37std::string ABI;38CodeGenOptLevel OL = CodeGenOptLevel::Default;39std::optional<Reloc::Model> RM;40std::optional<CodeModel::Model> CM;41bool JIT;42};4344} // namespace llvm4546DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMTargetMachineOptions,47LLVMTargetMachineOptionsRef)4849static TargetMachine *unwrap(LLVMTargetMachineRef P) {50return reinterpret_cast<TargetMachine *>(P);51}52static Target *unwrap(LLVMTargetRef P) {53return reinterpret_cast<Target*>(P);54}55static LLVMTargetMachineRef wrap(const TargetMachine *P) {56return reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine *>(P));57}58static LLVMTargetRef wrap(const Target * P) {59return reinterpret_cast<LLVMTargetRef>(const_cast<Target*>(P));60}6162LLVMTargetRef LLVMGetFirstTarget() {63if (TargetRegistry::targets().begin() == TargetRegistry::targets().end()) {64return nullptr;65}6667const Target *target = &*TargetRegistry::targets().begin();68return wrap(target);69}70LLVMTargetRef LLVMGetNextTarget(LLVMTargetRef T) {71return wrap(unwrap(T)->getNext());72}7374LLVMTargetRef LLVMGetTargetFromName(const char *Name) {75StringRef NameRef = Name;76auto I = find_if(TargetRegistry::targets(),77[&](const Target &T) { return T.getName() == NameRef; });78return I != TargetRegistry::targets().end() ? wrap(&*I) : nullptr;79}8081LLVMBool LLVMGetTargetFromTriple(const char* TripleStr, LLVMTargetRef *T,82char **ErrorMessage) {83std::string Error;8485*T = wrap(TargetRegistry::lookupTarget(TripleStr, Error));8687if (!*T) {88if (ErrorMessage)89*ErrorMessage = strdup(Error.c_str());9091return 1;92}9394return 0;95}9697const char * LLVMGetTargetName(LLVMTargetRef T) {98return unwrap(T)->getName();99}100101const char * LLVMGetTargetDescription(LLVMTargetRef T) {102return unwrap(T)->getShortDescription();103}104105LLVMBool LLVMTargetHasJIT(LLVMTargetRef T) {106return unwrap(T)->hasJIT();107}108109LLVMBool LLVMTargetHasTargetMachine(LLVMTargetRef T) {110return unwrap(T)->hasTargetMachine();111}112113LLVMBool LLVMTargetHasAsmBackend(LLVMTargetRef T) {114return unwrap(T)->hasMCAsmBackend();115}116117LLVMTargetMachineOptionsRef LLVMCreateTargetMachineOptions(void) {118return wrap(new LLVMTargetMachineOptions());119}120121void LLVMDisposeTargetMachineOptions(LLVMTargetMachineOptionsRef Options) {122delete unwrap(Options);123}124125void LLVMTargetMachineOptionsSetCPU(LLVMTargetMachineOptionsRef Options,126const char *CPU) {127unwrap(Options)->CPU = CPU;128}129130void LLVMTargetMachineOptionsSetFeatures(LLVMTargetMachineOptionsRef Options,131const char *Features) {132unwrap(Options)->Features = Features;133}134135void LLVMTargetMachineOptionsSetABI(LLVMTargetMachineOptionsRef Options,136const char *ABI) {137unwrap(Options)->ABI = ABI;138}139140void LLVMTargetMachineOptionsSetCodeGenOptLevel(141LLVMTargetMachineOptionsRef Options, LLVMCodeGenOptLevel Level) {142CodeGenOptLevel OL;143144switch (Level) {145case LLVMCodeGenLevelNone:146OL = CodeGenOptLevel::None;147break;148case LLVMCodeGenLevelLess:149OL = CodeGenOptLevel::Less;150break;151case LLVMCodeGenLevelAggressive:152OL = CodeGenOptLevel::Aggressive;153break;154case LLVMCodeGenLevelDefault:155OL = CodeGenOptLevel::Default;156break;157}158159unwrap(Options)->OL = OL;160}161162void LLVMTargetMachineOptionsSetRelocMode(LLVMTargetMachineOptionsRef Options,163LLVMRelocMode Reloc) {164std::optional<Reloc::Model> RM;165166switch (Reloc) {167case LLVMRelocStatic:168RM = Reloc::Static;169break;170case LLVMRelocPIC:171RM = Reloc::PIC_;172break;173case LLVMRelocDynamicNoPic:174RM = Reloc::DynamicNoPIC;175break;176case LLVMRelocROPI:177RM = Reloc::ROPI;178break;179case LLVMRelocRWPI:180RM = Reloc::RWPI;181break;182case LLVMRelocROPI_RWPI:183RM = Reloc::ROPI_RWPI;184break;185case LLVMRelocDefault:186break;187}188189unwrap(Options)->RM = RM;190}191192void LLVMTargetMachineOptionsSetCodeModel(LLVMTargetMachineOptionsRef Options,193LLVMCodeModel CodeModel) {194auto CM = unwrap(CodeModel, unwrap(Options)->JIT);195unwrap(Options)->CM = CM;196}197198LLVMTargetMachineRef199LLVMCreateTargetMachineWithOptions(LLVMTargetRef T, const char *Triple,200LLVMTargetMachineOptionsRef Options) {201auto *Opt = unwrap(Options);202TargetOptions TO;203TO.MCOptions.ABIName = Opt->ABI;204return wrap(unwrap(T)->createTargetMachine(Triple, Opt->CPU, Opt->Features,205TO, Opt->RM, Opt->CM, Opt->OL,206Opt->JIT));207}208209LLVMTargetMachineRef210LLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple, const char *CPU,211const char *Features, LLVMCodeGenOptLevel Level,212LLVMRelocMode Reloc, LLVMCodeModel CodeModel) {213auto *Options = LLVMCreateTargetMachineOptions();214215LLVMTargetMachineOptionsSetCPU(Options, CPU);216LLVMTargetMachineOptionsSetFeatures(Options, Features);217LLVMTargetMachineOptionsSetCodeGenOptLevel(Options, Level);218LLVMTargetMachineOptionsSetRelocMode(Options, Reloc);219LLVMTargetMachineOptionsSetCodeModel(Options, CodeModel);220221auto *Machine = LLVMCreateTargetMachineWithOptions(T, Triple, Options);222223LLVMDisposeTargetMachineOptions(Options);224return Machine;225}226227void LLVMDisposeTargetMachine(LLVMTargetMachineRef T) { delete unwrap(T); }228229LLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T) {230const Target* target = &(unwrap(T)->getTarget());231return wrap(target);232}233234char* LLVMGetTargetMachineTriple(LLVMTargetMachineRef T) {235std::string StringRep = unwrap(T)->getTargetTriple().str();236return strdup(StringRep.c_str());237}238239char* LLVMGetTargetMachineCPU(LLVMTargetMachineRef T) {240std::string StringRep = std::string(unwrap(T)->getTargetCPU());241return strdup(StringRep.c_str());242}243244char* LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T) {245std::string StringRep = std::string(unwrap(T)->getTargetFeatureString());246return strdup(StringRep.c_str());247}248249void LLVMSetTargetMachineAsmVerbosity(LLVMTargetMachineRef T,250LLVMBool VerboseAsm) {251unwrap(T)->Options.MCOptions.AsmVerbose = VerboseAsm;252}253254void LLVMSetTargetMachineFastISel(LLVMTargetMachineRef T, LLVMBool Enable) {255unwrap(T)->setFastISel(Enable);256}257258void LLVMSetTargetMachineGlobalISel(LLVMTargetMachineRef T, LLVMBool Enable) {259unwrap(T)->setGlobalISel(Enable);260}261262void LLVMSetTargetMachineGlobalISelAbort(LLVMTargetMachineRef T,263LLVMGlobalISelAbortMode Mode) {264GlobalISelAbortMode AM = GlobalISelAbortMode::Enable;265switch (Mode) {266case LLVMGlobalISelAbortDisable:267AM = GlobalISelAbortMode::Disable;268break;269case LLVMGlobalISelAbortEnable:270AM = GlobalISelAbortMode::Enable;271break;272case LLVMGlobalISelAbortDisableWithDiag:273AM = GlobalISelAbortMode::DisableWithDiag;274break;275}276277unwrap(T)->setGlobalISelAbort(AM);278}279280void LLVMSetTargetMachineMachineOutliner(LLVMTargetMachineRef T,281LLVMBool Enable) {282unwrap(T)->setMachineOutliner(Enable);283}284285LLVMTargetDataRef LLVMCreateTargetDataLayout(LLVMTargetMachineRef T) {286return wrap(new DataLayout(unwrap(T)->createDataLayout()));287}288289static LLVMBool LLVMTargetMachineEmit(LLVMTargetMachineRef T, LLVMModuleRef M,290raw_pwrite_stream &OS,291LLVMCodeGenFileType codegen,292char **ErrorMessage) {293TargetMachine* TM = unwrap(T);294Module* Mod = unwrap(M);295296legacy::PassManager pass;297298std::string error;299300Mod->setDataLayout(TM->createDataLayout());301302CodeGenFileType ft;303switch (codegen) {304case LLVMAssemblyFile:305ft = CodeGenFileType::AssemblyFile;306break;307default:308ft = CodeGenFileType::ObjectFile;309break;310}311if (TM->addPassesToEmitFile(pass, OS, nullptr, ft)) {312error = "TargetMachine can't emit a file of this type";313*ErrorMessage = strdup(error.c_str());314return true;315}316317pass.run(*Mod);318319OS.flush();320return false;321}322323LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,324const char *Filename,325LLVMCodeGenFileType codegen,326char **ErrorMessage) {327std::error_code EC;328raw_fd_ostream dest(Filename, EC, sys::fs::OF_None);329if (EC) {330*ErrorMessage = strdup(EC.message().c_str());331return true;332}333bool Result = LLVMTargetMachineEmit(T, M, dest, codegen, ErrorMessage);334dest.flush();335return Result;336}337338LLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T,339LLVMModuleRef M, LLVMCodeGenFileType codegen, char** ErrorMessage,340LLVMMemoryBufferRef *OutMemBuf) {341SmallString<0> CodeString;342raw_svector_ostream OStream(CodeString);343bool Result = LLVMTargetMachineEmit(T, M, OStream, codegen, ErrorMessage);344345StringRef Data = OStream.str();346*OutMemBuf =347LLVMCreateMemoryBufferWithMemoryRangeCopy(Data.data(), Data.size(), "");348return Result;349}350351char *LLVMGetDefaultTargetTriple(void) {352return strdup(sys::getDefaultTargetTriple().c_str());353}354355char *LLVMNormalizeTargetTriple(const char* triple) {356return strdup(Triple::normalize(StringRef(triple)).c_str());357}358359char *LLVMGetHostCPUName(void) {360return strdup(sys::getHostCPUName().data());361}362363char *LLVMGetHostCPUFeatures(void) {364SubtargetFeatures Features;365for (const auto &[Feature, IsEnabled] : sys::getHostCPUFeatures())366Features.AddFeature(Feature, IsEnabled);367368return strdup(Features.getString().c_str());369}370371void LLVMAddAnalysisPasses(LLVMTargetMachineRef T, LLVMPassManagerRef PM) {372unwrap(PM)->add(373createTargetTransformInfoWrapperPass(unwrap(T)->getTargetIRAnalysis()));374}375376377