aot_llvm_extra2.cpp 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196
  1. /*
  2. * Copyright (c)2023 YAMAMOTO Takashi. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include <llvm-c/TargetMachine.h>
  6. #if LLVM_VERSION_MAJOR < 17
  7. #include <llvm/ADT/None.h>
  8. #include <llvm/ADT/Optional.h>
  9. #endif
  10. #include <llvm/IR/Instructions.h>
  11. #if LLVM_VERSION_MAJOR >= 14
  12. #include <llvm/MC/TargetRegistry.h>
  13. #else
  14. #include <llvm/Support/TargetRegistry.h>
  15. #endif
  16. #include <llvm/Target/TargetMachine.h>
  17. #include "bh_assert.h"
  18. #include "aot_llvm_extra2.h"
  19. #if LLVM_VERSION_MAJOR >= 17
  20. namespace llvm {
  21. template<typename T>
  22. using Optional = std::optional<T>;
  23. }
  24. #endif
  25. static llvm::Optional<llvm::Reloc::Model>
  26. convert(LLVMRelocMode reloc_mode)
  27. {
  28. switch (reloc_mode) {
  29. case LLVMRelocDefault:
  30. #if LLVM_VERSION_MAJOR >= 16
  31. return std::nullopt;
  32. #else
  33. return llvm::None;
  34. #endif
  35. case LLVMRelocStatic:
  36. return llvm::Reloc::Static;
  37. case LLVMRelocPIC:
  38. return llvm::Reloc::PIC_;
  39. case LLVMRelocDynamicNoPic:
  40. return llvm::Reloc::DynamicNoPIC;
  41. case LLVMRelocROPI:
  42. return llvm::Reloc::ROPI;
  43. case LLVMRelocRWPI:
  44. return llvm::Reloc::RWPI;
  45. case LLVMRelocROPI_RWPI:
  46. return llvm::Reloc::ROPI_RWPI;
  47. }
  48. bh_assert(0);
  49. #if LLVM_VERSION_MAJOR >= 16
  50. return std::nullopt;
  51. #else
  52. return llvm::None;
  53. #endif
  54. }
  55. #if LLVM_VERSION_MAJOR < 18
  56. static llvm::CodeGenOpt::Level
  57. convert(LLVMCodeGenOptLevel opt_level)
  58. {
  59. switch (opt_level) {
  60. case LLVMCodeGenLevelNone:
  61. return llvm::CodeGenOpt::None;
  62. case LLVMCodeGenLevelLess:
  63. return llvm::CodeGenOpt::Less;
  64. case LLVMCodeGenLevelDefault:
  65. return llvm::CodeGenOpt::Default;
  66. case LLVMCodeGenLevelAggressive:
  67. return llvm::CodeGenOpt::Aggressive;
  68. }
  69. bh_assert(0);
  70. return llvm::CodeGenOpt::None;
  71. }
  72. #else
  73. static llvm::CodeGenOptLevel
  74. convert(LLVMCodeGenOptLevel opt_level)
  75. {
  76. switch (opt_level) {
  77. case LLVMCodeGenLevelNone:
  78. return llvm::CodeGenOptLevel::None;
  79. case LLVMCodeGenLevelLess:
  80. return llvm::CodeGenOptLevel::Less;
  81. case LLVMCodeGenLevelDefault:
  82. return llvm::CodeGenOptLevel::Default;
  83. case LLVMCodeGenLevelAggressive:
  84. return llvm::CodeGenOptLevel::Aggressive;
  85. }
  86. bh_assert(0);
  87. return llvm::CodeGenOptLevel::None;
  88. }
  89. #endif
  90. static llvm::Optional<llvm::CodeModel::Model>
  91. convert(LLVMCodeModel code_model, bool *jit)
  92. {
  93. *jit = false;
  94. switch (code_model) {
  95. case LLVMCodeModelDefault:
  96. #if LLVM_VERSION_MAJOR >= 16
  97. return std::nullopt;
  98. #else
  99. return llvm::None;
  100. #endif
  101. case LLVMCodeModelJITDefault:
  102. *jit = true;
  103. #if LLVM_VERSION_MAJOR >= 16
  104. return std::nullopt;
  105. #else
  106. return llvm::None;
  107. #endif
  108. case LLVMCodeModelTiny:
  109. return llvm::CodeModel::Tiny;
  110. case LLVMCodeModelSmall:
  111. return llvm::CodeModel::Small;
  112. case LLVMCodeModelKernel:
  113. return llvm::CodeModel::Kernel;
  114. case LLVMCodeModelMedium:
  115. return llvm::CodeModel::Medium;
  116. case LLVMCodeModelLarge:
  117. return llvm::CodeModel::Large;
  118. }
  119. bh_assert(0);
  120. #if LLVM_VERSION_MAJOR >= 16
  121. return std::nullopt;
  122. #else
  123. return llvm::None;
  124. #endif
  125. }
  126. LLVMTargetMachineRef
  127. LLVMCreateTargetMachineWithOpts(LLVMTargetRef ctarget, const char *triple,
  128. const char *cpu, const char *features,
  129. LLVMCodeGenOptLevel opt_level,
  130. LLVMRelocMode reloc_mode,
  131. LLVMCodeModel code_model,
  132. bool EmitStackSizeSection,
  133. const char *StackUsageOutput)
  134. {
  135. llvm::TargetOptions opts;
  136. // -fstack-size-section equiv
  137. // emit it to ".stack_sizes" section in case of ELF
  138. // you can read it with "llvm-readobj --stack-sizes"
  139. opts.EmitStackSizeSection = EmitStackSizeSection;
  140. // -fstack-usage equiv
  141. if (StackUsageOutput != NULL) {
  142. opts.StackUsageOutput = StackUsageOutput;
  143. }
  144. auto target = reinterpret_cast<llvm::Target *>(ctarget);
  145. auto rm = convert(reloc_mode);
  146. auto ol = convert(opt_level);
  147. bool jit;
  148. auto cm = convert(code_model, &jit);
  149. #if LLVM_VERSION_MAJOR >= 21
  150. auto targetmachine = target->createTargetMachine(
  151. llvm::Triple(triple), cpu, features, opts, rm, cm, ol, jit);
  152. #else
  153. auto targetmachine = target->createTargetMachine(triple, cpu, features,
  154. opts, rm, cm, ol, jit);
  155. #endif
  156. #if LLVM_VERSION_MAJOR >= 18
  157. // always place data in normal data section.
  158. //
  159. // note that:
  160. // - our aot file emitter/loader doesn't support x86-64 large data
  161. // sections. (eg .lrodata)
  162. // - for our purposes, "data" is usually something the compiler
  163. // generated. (eg. jump tables) we probably never benefit from
  164. // large data sections.
  165. targetmachine->setLargeDataThreshold(UINT64_MAX);
  166. #endif
  167. return reinterpret_cast<LLVMTargetMachineRef>(targetmachine);
  168. }
  169. /* https://reviews.llvm.org/D153107 */
  170. #if LLVM_VERSION_MAJOR < 18
  171. using namespace llvm;
  172. LLVMTailCallKind
  173. LLVMGetTailCallKind(LLVMValueRef Call)
  174. {
  175. return (LLVMTailCallKind)unwrap<CallInst>(Call)->getTailCallKind();
  176. }
  177. void
  178. LLVMSetTailCallKind(LLVMValueRef Call, LLVMTailCallKind kind)
  179. {
  180. unwrap<CallInst>(Call)->setTailCallKind((CallInst::TailCallKind)kind);
  181. }
  182. #endif