| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196 |
- /*
- * Copyright (c)2023 YAMAMOTO Takashi. All rights reserved.
- * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- */
- #include <llvm-c/TargetMachine.h>
- #if LLVM_VERSION_MAJOR < 17
- #include <llvm/ADT/None.h>
- #include <llvm/ADT/Optional.h>
- #endif
- #include <llvm/IR/Instructions.h>
- #if LLVM_VERSION_MAJOR >= 14
- #include <llvm/MC/TargetRegistry.h>
- #else
- #include <llvm/Support/TargetRegistry.h>
- #endif
- #include <llvm/Target/TargetMachine.h>
- #include "bh_assert.h"
- #include "aot_llvm_extra2.h"
- #if LLVM_VERSION_MAJOR >= 17
- namespace llvm {
- template<typename T>
- using Optional = std::optional<T>;
- }
- #endif
- static llvm::Optional<llvm::Reloc::Model>
- convert(LLVMRelocMode reloc_mode)
- {
- switch (reloc_mode) {
- case LLVMRelocDefault:
- #if LLVM_VERSION_MAJOR >= 16
- return std::nullopt;
- #else
- return llvm::None;
- #endif
- case LLVMRelocStatic:
- return llvm::Reloc::Static;
- case LLVMRelocPIC:
- return llvm::Reloc::PIC_;
- case LLVMRelocDynamicNoPic:
- return llvm::Reloc::DynamicNoPIC;
- case LLVMRelocROPI:
- return llvm::Reloc::ROPI;
- case LLVMRelocRWPI:
- return llvm::Reloc::RWPI;
- case LLVMRelocROPI_RWPI:
- return llvm::Reloc::ROPI_RWPI;
- }
- bh_assert(0);
- #if LLVM_VERSION_MAJOR >= 16
- return std::nullopt;
- #else
- return llvm::None;
- #endif
- }
- #if LLVM_VERSION_MAJOR < 18
- static llvm::CodeGenOpt::Level
- convert(LLVMCodeGenOptLevel opt_level)
- {
- switch (opt_level) {
- case LLVMCodeGenLevelNone:
- return llvm::CodeGenOpt::None;
- case LLVMCodeGenLevelLess:
- return llvm::CodeGenOpt::Less;
- case LLVMCodeGenLevelDefault:
- return llvm::CodeGenOpt::Default;
- case LLVMCodeGenLevelAggressive:
- return llvm::CodeGenOpt::Aggressive;
- }
- bh_assert(0);
- return llvm::CodeGenOpt::None;
- }
- #else
- static llvm::CodeGenOptLevel
- convert(LLVMCodeGenOptLevel opt_level)
- {
- switch (opt_level) {
- case LLVMCodeGenLevelNone:
- return llvm::CodeGenOptLevel::None;
- case LLVMCodeGenLevelLess:
- return llvm::CodeGenOptLevel::Less;
- case LLVMCodeGenLevelDefault:
- return llvm::CodeGenOptLevel::Default;
- case LLVMCodeGenLevelAggressive:
- return llvm::CodeGenOptLevel::Aggressive;
- }
- bh_assert(0);
- return llvm::CodeGenOptLevel::None;
- }
- #endif
- static llvm::Optional<llvm::CodeModel::Model>
- convert(LLVMCodeModel code_model, bool *jit)
- {
- *jit = false;
- switch (code_model) {
- case LLVMCodeModelDefault:
- #if LLVM_VERSION_MAJOR >= 16
- return std::nullopt;
- #else
- return llvm::None;
- #endif
- case LLVMCodeModelJITDefault:
- *jit = true;
- #if LLVM_VERSION_MAJOR >= 16
- return std::nullopt;
- #else
- return llvm::None;
- #endif
- case LLVMCodeModelTiny:
- return llvm::CodeModel::Tiny;
- case LLVMCodeModelSmall:
- return llvm::CodeModel::Small;
- case LLVMCodeModelKernel:
- return llvm::CodeModel::Kernel;
- case LLVMCodeModelMedium:
- return llvm::CodeModel::Medium;
- case LLVMCodeModelLarge:
- return llvm::CodeModel::Large;
- }
- bh_assert(0);
- #if LLVM_VERSION_MAJOR >= 16
- return std::nullopt;
- #else
- return llvm::None;
- #endif
- }
- LLVMTargetMachineRef
- LLVMCreateTargetMachineWithOpts(LLVMTargetRef ctarget, const char *triple,
- const char *cpu, const char *features,
- LLVMCodeGenOptLevel opt_level,
- LLVMRelocMode reloc_mode,
- LLVMCodeModel code_model,
- bool EmitStackSizeSection,
- const char *StackUsageOutput)
- {
- llvm::TargetOptions opts;
- // -fstack-size-section equiv
- // emit it to ".stack_sizes" section in case of ELF
- // you can read it with "llvm-readobj --stack-sizes"
- opts.EmitStackSizeSection = EmitStackSizeSection;
- // -fstack-usage equiv
- if (StackUsageOutput != NULL) {
- opts.StackUsageOutput = StackUsageOutput;
- }
- auto target = reinterpret_cast<llvm::Target *>(ctarget);
- auto rm = convert(reloc_mode);
- auto ol = convert(opt_level);
- bool jit;
- auto cm = convert(code_model, &jit);
- #if LLVM_VERSION_MAJOR >= 21
- auto targetmachine = target->createTargetMachine(
- llvm::Triple(triple), cpu, features, opts, rm, cm, ol, jit);
- #else
- auto targetmachine = target->createTargetMachine(triple, cpu, features,
- opts, rm, cm, ol, jit);
- #endif
- #if LLVM_VERSION_MAJOR >= 18
- // always place data in normal data section.
- //
- // note that:
- // - our aot file emitter/loader doesn't support x86-64 large data
- // sections. (eg .lrodata)
- // - for our purposes, "data" is usually something the compiler
- // generated. (eg. jump tables) we probably never benefit from
- // large data sections.
- targetmachine->setLargeDataThreshold(UINT64_MAX);
- #endif
- return reinterpret_cast<LLVMTargetMachineRef>(targetmachine);
- }
- /* https://reviews.llvm.org/D153107 */
- #if LLVM_VERSION_MAJOR < 18
- using namespace llvm;
- LLVMTailCallKind
- LLVMGetTailCallKind(LLVMValueRef Call)
- {
- return (LLVMTailCallKind)unwrap<CallInst>(Call)->getTailCallKind();
- }
- void
- LLVMSetTailCallKind(LLVMValueRef Call, LLVMTailCallKind kind)
- {
- unwrap<CallInst>(Call)->setTailCallKind((CallInst::TailCallKind)kind);
- }
- #endif
|