brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.0 KiB · aba6ea4 Raw
377 lines · cpp
1//===-- TargetMachine.cpp -------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file implements the LLVM-C part of TargetMachine.h10//11//===----------------------------------------------------------------------===//12 13#include "llvm-c/Core.h"14#include "llvm-c/TargetMachine.h"15#include "llvm/Analysis/TargetTransformInfo.h"16#include "llvm/IR/DataLayout.h"17#include "llvm/IR/LegacyPassManager.h"18#include "llvm/IR/Module.h"19#include "llvm/MC/TargetRegistry.h"20#include "llvm/Support/CBindingWrapping.h"21#include "llvm/Support/FileSystem.h"22#include "llvm/Support/raw_ostream.h"23#include "llvm/Target/CodeGenCWrappers.h"24#include "llvm/Target/TargetMachine.h"25#include "llvm/TargetParser/Host.h"26#include "llvm/TargetParser/SubtargetFeature.h"27#include <cstring>28#include <optional>29 30using namespace llvm;31 32namespace llvm {33 34/// Options for LLVMCreateTargetMachine().35struct LLVMTargetMachineOptions {36  std::string CPU;37  std::string Features;38  std::string ABI;39  CodeGenOptLevel OL = CodeGenOptLevel::Default;40  std::optional<Reloc::Model> RM;41  std::optional<CodeModel::Model> CM;42  bool JIT;43};44 45} // namespace llvm46 47DEFINE_SIMPLE_CONVERSION_FUNCTIONS(LLVMTargetMachineOptions,48                                   LLVMTargetMachineOptionsRef)49 50static TargetMachine *unwrap(LLVMTargetMachineRef P) {51  return reinterpret_cast<TargetMachine *>(P);52}53static Target *unwrap(LLVMTargetRef P) {54  return reinterpret_cast<Target*>(P);55}56static LLVMTargetMachineRef wrap(const TargetMachine *P) {57  return reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine *>(P));58}59static LLVMTargetRef wrap(const Target * P) {60  return reinterpret_cast<LLVMTargetRef>(const_cast<Target*>(P));61}62 63LLVMTargetRef LLVMGetFirstTarget() {64  if (TargetRegistry::targets().begin() == TargetRegistry::targets().end()) {65    return nullptr;66  }67 68  const Target *target = &*TargetRegistry::targets().begin();69  return wrap(target);70}71LLVMTargetRef LLVMGetNextTarget(LLVMTargetRef T) {72  return wrap(unwrap(T)->getNext());73}74 75LLVMTargetRef LLVMGetTargetFromName(const char *Name) {76  StringRef NameRef = Name;77  auto I = find_if(TargetRegistry::targets(),78                   [&](const Target &T) { return T.getName() == NameRef; });79  return I != TargetRegistry::targets().end() ? wrap(&*I) : nullptr;80}81 82LLVMBool LLVMGetTargetFromTriple(const char* TripleStr, LLVMTargetRef *T,83                                 char **ErrorMessage) {84  std::string Error;85 86  Triple TT(TripleStr);87  *T = wrap(TargetRegistry::lookupTarget(TT, Error));88 89  if (!*T) {90    if (ErrorMessage)91      *ErrorMessage = strdup(Error.c_str());92 93    return 1;94  }95 96  return 0;97}98 99const char * LLVMGetTargetName(LLVMTargetRef T) {100  return unwrap(T)->getName();101}102 103const char * LLVMGetTargetDescription(LLVMTargetRef T) {104  return unwrap(T)->getShortDescription();105}106 107LLVMBool LLVMTargetHasJIT(LLVMTargetRef T) {108  return unwrap(T)->hasJIT();109}110 111LLVMBool LLVMTargetHasTargetMachine(LLVMTargetRef T) {112  return unwrap(T)->hasTargetMachine();113}114 115LLVMBool LLVMTargetHasAsmBackend(LLVMTargetRef T) {116  return unwrap(T)->hasMCAsmBackend();117}118 119LLVMTargetMachineOptionsRef LLVMCreateTargetMachineOptions(void) {120  return wrap(new LLVMTargetMachineOptions());121}122 123void LLVMDisposeTargetMachineOptions(LLVMTargetMachineOptionsRef Options) {124  delete unwrap(Options);125}126 127void LLVMTargetMachineOptionsSetCPU(LLVMTargetMachineOptionsRef Options,128                                    const char *CPU) {129  unwrap(Options)->CPU = CPU;130}131 132void LLVMTargetMachineOptionsSetFeatures(LLVMTargetMachineOptionsRef Options,133                                         const char *Features) {134  unwrap(Options)->Features = Features;135}136 137void LLVMTargetMachineOptionsSetABI(LLVMTargetMachineOptionsRef Options,138                                    const char *ABI) {139  unwrap(Options)->ABI = ABI;140}141 142void LLVMTargetMachineOptionsSetCodeGenOptLevel(143    LLVMTargetMachineOptionsRef Options, LLVMCodeGenOptLevel Level) {144  CodeGenOptLevel OL;145 146  switch (Level) {147  case LLVMCodeGenLevelNone:148    OL = CodeGenOptLevel::None;149    break;150  case LLVMCodeGenLevelLess:151    OL = CodeGenOptLevel::Less;152    break;153  case LLVMCodeGenLevelAggressive:154    OL = CodeGenOptLevel::Aggressive;155    break;156  case LLVMCodeGenLevelDefault:157    OL = CodeGenOptLevel::Default;158    break;159  }160 161  unwrap(Options)->OL = OL;162}163 164void LLVMTargetMachineOptionsSetRelocMode(LLVMTargetMachineOptionsRef Options,165                                          LLVMRelocMode Reloc) {166  std::optional<Reloc::Model> RM;167 168  switch (Reloc) {169  case LLVMRelocStatic:170    RM = Reloc::Static;171    break;172  case LLVMRelocPIC:173    RM = Reloc::PIC_;174    break;175  case LLVMRelocDynamicNoPic:176    RM = Reloc::DynamicNoPIC;177    break;178  case LLVMRelocROPI:179    RM = Reloc::ROPI;180    break;181  case LLVMRelocRWPI:182    RM = Reloc::RWPI;183    break;184  case LLVMRelocROPI_RWPI:185    RM = Reloc::ROPI_RWPI;186    break;187  case LLVMRelocDefault:188    break;189  }190 191  unwrap(Options)->RM = RM;192}193 194void LLVMTargetMachineOptionsSetCodeModel(LLVMTargetMachineOptionsRef Options,195                                          LLVMCodeModel CodeModel) {196  auto CM = unwrap(CodeModel, unwrap(Options)->JIT);197  unwrap(Options)->CM = CM;198}199 200LLVMTargetMachineRef201LLVMCreateTargetMachineWithOptions(LLVMTargetRef T, const char *TripleStr,202                                   LLVMTargetMachineOptionsRef Options) {203  auto *Opt = unwrap(Options);204  TargetOptions TO;205  TO.MCOptions.ABIName = Opt->ABI;206  return wrap(unwrap(T)->createTargetMachine(Triple(TripleStr), Opt->CPU,207                                             Opt->Features, TO, Opt->RM,208                                             Opt->CM, Opt->OL, Opt->JIT));209}210 211LLVMTargetMachineRef212LLVMCreateTargetMachine(LLVMTargetRef T, const char *Triple, const char *CPU,213                        const char *Features, LLVMCodeGenOptLevel Level,214                        LLVMRelocMode Reloc, LLVMCodeModel CodeModel) {215  auto *Options = LLVMCreateTargetMachineOptions();216 217  LLVMTargetMachineOptionsSetCPU(Options, CPU);218  LLVMTargetMachineOptionsSetFeatures(Options, Features);219  LLVMTargetMachineOptionsSetCodeGenOptLevel(Options, Level);220  LLVMTargetMachineOptionsSetRelocMode(Options, Reloc);221  LLVMTargetMachineOptionsSetCodeModel(Options, CodeModel);222 223  auto *Machine = LLVMCreateTargetMachineWithOptions(T, Triple, Options);224 225  LLVMDisposeTargetMachineOptions(Options);226  return Machine;227}228 229void LLVMDisposeTargetMachine(LLVMTargetMachineRef T) { delete unwrap(T); }230 231LLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T) {232  const Target* target = &(unwrap(T)->getTarget());233  return wrap(target);234}235 236char* LLVMGetTargetMachineTriple(LLVMTargetMachineRef T) {237  std::string StringRep = unwrap(T)->getTargetTriple().str();238  return strdup(StringRep.c_str());239}240 241char* LLVMGetTargetMachineCPU(LLVMTargetMachineRef T) {242  std::string StringRep = std::string(unwrap(T)->getTargetCPU());243  return strdup(StringRep.c_str());244}245 246char* LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T) {247  std::string StringRep = std::string(unwrap(T)->getTargetFeatureString());248  return strdup(StringRep.c_str());249}250 251void LLVMSetTargetMachineAsmVerbosity(LLVMTargetMachineRef T,252                                      LLVMBool VerboseAsm) {253  unwrap(T)->Options.MCOptions.AsmVerbose = VerboseAsm;254}255 256void LLVMSetTargetMachineFastISel(LLVMTargetMachineRef T, LLVMBool Enable) {257  unwrap(T)->setFastISel(Enable);258}259 260void LLVMSetTargetMachineGlobalISel(LLVMTargetMachineRef T, LLVMBool Enable) {261  unwrap(T)->setGlobalISel(Enable);262}263 264void LLVMSetTargetMachineGlobalISelAbort(LLVMTargetMachineRef T,265                                         LLVMGlobalISelAbortMode Mode) {266  GlobalISelAbortMode AM = GlobalISelAbortMode::Enable;267  switch (Mode) {268  case LLVMGlobalISelAbortDisable:269    AM = GlobalISelAbortMode::Disable;270    break;271  case LLVMGlobalISelAbortEnable:272    AM = GlobalISelAbortMode::Enable;273    break;274  case LLVMGlobalISelAbortDisableWithDiag:275    AM = GlobalISelAbortMode::DisableWithDiag;276    break;277  }278 279  unwrap(T)->setGlobalISelAbort(AM);280}281 282void LLVMSetTargetMachineMachineOutliner(LLVMTargetMachineRef T,283                                         LLVMBool Enable) {284  unwrap(T)->setMachineOutliner(Enable);285}286 287LLVMTargetDataRef LLVMCreateTargetDataLayout(LLVMTargetMachineRef T) {288  return wrap(new DataLayout(unwrap(T)->createDataLayout()));289}290 291static LLVMBool LLVMTargetMachineEmit(LLVMTargetMachineRef T, LLVMModuleRef M,292                                      raw_pwrite_stream &OS,293                                      LLVMCodeGenFileType codegen,294                                      char **ErrorMessage) {295  TargetMachine* TM = unwrap(T);296  Module* Mod = unwrap(M);297 298  legacy::PassManager pass;299 300  std::string error;301 302  Mod->setDataLayout(TM->createDataLayout());303 304  CodeGenFileType ft;305  switch (codegen) {306    case LLVMAssemblyFile:307      ft = CodeGenFileType::AssemblyFile;308      break;309    default:310      ft = CodeGenFileType::ObjectFile;311      break;312  }313  if (TM->addPassesToEmitFile(pass, OS, nullptr, ft)) {314    error = "TargetMachine can't emit a file of this type";315    *ErrorMessage = strdup(error.c_str());316    return true;317  }318 319  pass.run(*Mod);320 321  OS.flush();322  return false;323}324 325LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,326                                     const char *Filename,327                                     LLVMCodeGenFileType codegen,328                                     char **ErrorMessage) {329  std::error_code EC;330  raw_fd_ostream dest(Filename, EC, sys::fs::OF_None);331  if (EC) {332    *ErrorMessage = strdup(EC.message().c_str());333    return true;334  }335  bool Result = LLVMTargetMachineEmit(T, M, dest, codegen, ErrorMessage);336  dest.flush();337  return Result;338}339 340LLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T,341  LLVMModuleRef M, LLVMCodeGenFileType codegen, char** ErrorMessage,342  LLVMMemoryBufferRef *OutMemBuf) {343  SmallString<0> CodeString;344  raw_svector_ostream OStream(CodeString);345  bool Result = LLVMTargetMachineEmit(T, M, OStream, codegen, ErrorMessage);346 347  StringRef Data = OStream.str();348  *OutMemBuf =349      LLVMCreateMemoryBufferWithMemoryRangeCopy(Data.data(), Data.size(), "");350  return Result;351}352 353char *LLVMGetDefaultTargetTriple(void) {354  return strdup(sys::getDefaultTargetTriple().c_str());355}356 357char *LLVMNormalizeTargetTriple(const char* triple) {358  return strdup(Triple::normalize(StringRef(triple)).c_str());359}360 361char *LLVMGetHostCPUName(void) {362  return strdup(sys::getHostCPUName().data());363}364 365char *LLVMGetHostCPUFeatures(void) {366  SubtargetFeatures Features;367  for (const auto &[Feature, IsEnabled] : sys::getHostCPUFeatures())368    Features.AddFeature(Feature, IsEnabled);369 370  return strdup(Features.getString().c_str());371}372 373void LLVMAddAnalysisPasses(LLVMTargetMachineRef T, LLVMPassManagerRef PM) {374  unwrap(PM)->add(375      createTargetTransformInfoWrapperPass(unwrap(T)->getTargetIRAnalysis()));376}377