123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270 |
- //===-- TargetMachine.cpp -------------------------------------------------===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file implements the LLVM-C part of TargetMachine.h
- //
- //===----------------------------------------------------------------------===//
- #include "llvm-c/Core.h"
- #include "llvm-c/TargetMachine.h"
- #include "llvm/Analysis/TargetTransformInfo.h"
- #include "llvm/IR/DataLayout.h"
- #include "llvm/IR/LegacyPassManager.h"
- #include "llvm/IR/Module.h"
- #include "llvm/MC/SubtargetFeature.h"
- #include "llvm/MC/TargetRegistry.h"
- #include "llvm/Support/FileSystem.h"
- #include "llvm/Support/Host.h"
- #include "llvm/Support/raw_ostream.h"
- #include "llvm/Target/CodeGenCWrappers.h"
- #include "llvm/Target/TargetMachine.h"
- #include <cstring>
- #include <optional>
- using namespace llvm;
- static TargetMachine *unwrap(LLVMTargetMachineRef P) {
- return reinterpret_cast<TargetMachine *>(P);
- }
- static Target *unwrap(LLVMTargetRef P) {
- return reinterpret_cast<Target*>(P);
- }
- static LLVMTargetMachineRef wrap(const TargetMachine *P) {
- return reinterpret_cast<LLVMTargetMachineRef>(const_cast<TargetMachine *>(P));
- }
- static LLVMTargetRef wrap(const Target * P) {
- return reinterpret_cast<LLVMTargetRef>(const_cast<Target*>(P));
- }
- LLVMTargetRef LLVMGetFirstTarget() {
- if (TargetRegistry::targets().begin() == TargetRegistry::targets().end()) {
- return nullptr;
- }
- const Target *target = &*TargetRegistry::targets().begin();
- return wrap(target);
- }
- LLVMTargetRef LLVMGetNextTarget(LLVMTargetRef T) {
- return wrap(unwrap(T)->getNext());
- }
- LLVMTargetRef LLVMGetTargetFromName(const char *Name) {
- StringRef NameRef = Name;
- auto I = find_if(TargetRegistry::targets(),
- [&](const Target &T) { return T.getName() == NameRef; });
- return I != TargetRegistry::targets().end() ? wrap(&*I) : nullptr;
- }
- LLVMBool LLVMGetTargetFromTriple(const char* TripleStr, LLVMTargetRef *T,
- char **ErrorMessage) {
- std::string Error;
- *T = wrap(TargetRegistry::lookupTarget(TripleStr, Error));
- if (!*T) {
- if (ErrorMessage)
- *ErrorMessage = strdup(Error.c_str());
- return 1;
- }
- return 0;
- }
- const char * LLVMGetTargetName(LLVMTargetRef T) {
- return unwrap(T)->getName();
- }
- const char * LLVMGetTargetDescription(LLVMTargetRef T) {
- return unwrap(T)->getShortDescription();
- }
- LLVMBool LLVMTargetHasJIT(LLVMTargetRef T) {
- return unwrap(T)->hasJIT();
- }
- LLVMBool LLVMTargetHasTargetMachine(LLVMTargetRef T) {
- return unwrap(T)->hasTargetMachine();
- }
- LLVMBool LLVMTargetHasAsmBackend(LLVMTargetRef T) {
- return unwrap(T)->hasMCAsmBackend();
- }
- LLVMTargetMachineRef LLVMCreateTargetMachine(LLVMTargetRef T,
- const char *Triple, const char *CPU, const char *Features,
- LLVMCodeGenOptLevel Level, LLVMRelocMode Reloc,
- LLVMCodeModel CodeModel) {
- std::optional<Reloc::Model> RM;
- switch (Reloc){
- case LLVMRelocStatic:
- RM = Reloc::Static;
- break;
- case LLVMRelocPIC:
- RM = Reloc::PIC_;
- break;
- case LLVMRelocDynamicNoPic:
- RM = Reloc::DynamicNoPIC;
- break;
- case LLVMRelocROPI:
- RM = Reloc::ROPI;
- break;
- case LLVMRelocRWPI:
- RM = Reloc::RWPI;
- break;
- case LLVMRelocROPI_RWPI:
- RM = Reloc::ROPI_RWPI;
- break;
- default:
- break;
- }
- bool JIT;
- std::optional<CodeModel::Model> CM = unwrap(CodeModel, JIT);
- CodeGenOpt::Level OL;
- switch (Level) {
- case LLVMCodeGenLevelNone:
- OL = CodeGenOpt::None;
- break;
- case LLVMCodeGenLevelLess:
- OL = CodeGenOpt::Less;
- break;
- case LLVMCodeGenLevelAggressive:
- OL = CodeGenOpt::Aggressive;
- break;
- default:
- OL = CodeGenOpt::Default;
- break;
- }
- TargetOptions opt;
- return wrap(unwrap(T)->createTargetMachine(Triple, CPU, Features, opt, RM, CM,
- OL, JIT));
- }
- void LLVMDisposeTargetMachine(LLVMTargetMachineRef T) { delete unwrap(T); }
- LLVMTargetRef LLVMGetTargetMachineTarget(LLVMTargetMachineRef T) {
- const Target* target = &(unwrap(T)->getTarget());
- return wrap(target);
- }
- char* LLVMGetTargetMachineTriple(LLVMTargetMachineRef T) {
- std::string StringRep = unwrap(T)->getTargetTriple().str();
- return strdup(StringRep.c_str());
- }
- char* LLVMGetTargetMachineCPU(LLVMTargetMachineRef T) {
- std::string StringRep = std::string(unwrap(T)->getTargetCPU());
- return strdup(StringRep.c_str());
- }
- char* LLVMGetTargetMachineFeatureString(LLVMTargetMachineRef T) {
- std::string StringRep = std::string(unwrap(T)->getTargetFeatureString());
- return strdup(StringRep.c_str());
- }
- void LLVMSetTargetMachineAsmVerbosity(LLVMTargetMachineRef T,
- LLVMBool VerboseAsm) {
- unwrap(T)->Options.MCOptions.AsmVerbose = VerboseAsm;
- }
- LLVMTargetDataRef LLVMCreateTargetDataLayout(LLVMTargetMachineRef T) {
- return wrap(new DataLayout(unwrap(T)->createDataLayout()));
- }
- static LLVMBool LLVMTargetMachineEmit(LLVMTargetMachineRef T, LLVMModuleRef M,
- raw_pwrite_stream &OS,
- LLVMCodeGenFileType codegen,
- char **ErrorMessage) {
- TargetMachine* TM = unwrap(T);
- Module* Mod = unwrap(M);
- legacy::PassManager pass;
- std::string error;
- Mod->setDataLayout(TM->createDataLayout());
- CodeGenFileType ft;
- switch (codegen) {
- case LLVMAssemblyFile:
- ft = CGFT_AssemblyFile;
- break;
- default:
- ft = CGFT_ObjectFile;
- break;
- }
- if (TM->addPassesToEmitFile(pass, OS, nullptr, ft)) {
- error = "TargetMachine can't emit a file of this type";
- *ErrorMessage = strdup(error.c_str());
- return true;
- }
- pass.run(*Mod);
- OS.flush();
- return false;
- }
- LLVMBool LLVMTargetMachineEmitToFile(LLVMTargetMachineRef T, LLVMModuleRef M,
- const char *Filename,
- LLVMCodeGenFileType codegen,
- char **ErrorMessage) {
- std::error_code EC;
- raw_fd_ostream dest(Filename, EC, sys::fs::OF_None);
- if (EC) {
- *ErrorMessage = strdup(EC.message().c_str());
- return true;
- }
- bool Result = LLVMTargetMachineEmit(T, M, dest, codegen, ErrorMessage);
- dest.flush();
- return Result;
- }
- LLVMBool LLVMTargetMachineEmitToMemoryBuffer(LLVMTargetMachineRef T,
- LLVMModuleRef M, LLVMCodeGenFileType codegen, char** ErrorMessage,
- LLVMMemoryBufferRef *OutMemBuf) {
- SmallString<0> CodeString;
- raw_svector_ostream OStream(CodeString);
- bool Result = LLVMTargetMachineEmit(T, M, OStream, codegen, ErrorMessage);
- StringRef Data = OStream.str();
- *OutMemBuf =
- LLVMCreateMemoryBufferWithMemoryRangeCopy(Data.data(), Data.size(), "");
- return Result;
- }
- char *LLVMGetDefaultTargetTriple(void) {
- return strdup(sys::getDefaultTargetTriple().c_str());
- }
- char *LLVMNormalizeTargetTriple(const char* triple) {
- return strdup(Triple::normalize(StringRef(triple)).c_str());
- }
- char *LLVMGetHostCPUName(void) {
- return strdup(sys::getHostCPUName().data());
- }
- char *LLVMGetHostCPUFeatures(void) {
- SubtargetFeatures Features;
- StringMap<bool> HostFeatures;
- if (sys::getHostCPUFeatures(HostFeatures))
- for (const auto &[Feature, IsEnabled] : HostFeatures)
- Features.AddFeature(Feature, IsEnabled);
- return strdup(Features.getString().c_str());
- }
- void LLVMAddAnalysisPasses(LLVMTargetMachineRef T, LLVMPassManagerRef PM) {
- unwrap(PM)->add(
- createTargetTransformInfoWrapperPass(unwrap(T)->getTargetIRAnalysis()));
- }
|