Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 2 additions & 31 deletions scripts/generate_llvm_version_info.cr
Original file line number Diff line number Diff line change
Expand Up @@ -5,36 +5,7 @@
# LLVM installation different from the one bundled with Crystal.

require "c/libloaderapi"

# The list of supported targets are hardcoded in:
# https://github.com/llvm/llvm-project/blob/main/llvm/CMakeLists.txt
LLVM_ALL_TARGETS = %w(
AArch64
AMDGPU
ARM
AVR
BPF
Hexagon
Lanai
LoongArch
Mips
MSP430
NVPTX
PowerPC
RISCV
Sparc
SPIRV
SystemZ
VE
WebAssembly
X86
XCore
ARC
CSKY
DirectX
M68k
Xtensa
)
require "llvm/lib_llvm/config"

def find_dll_in_env_path
ENV["PATH"]?.try &.split(Process::PATH_DELIMITER, remove_empty: true) do |path|
Expand Down Expand Up @@ -62,7 +33,7 @@ begin
patch = uninitialized LibC::UInt
llvm_get_version.call(pointerof(major), pointerof(minor), pointerof(patch))

targets_built = LLVM_ALL_TARGETS.select do |target|
targets_built = LibLLVM::ALL_TARGETS.select do |target|
LibC.GetProcAddress(dll, "LLVMInitialize#{target}Target") && LibC.GetProcAddress(dll, "LLVMInitialize#{target}TargetInfo")
end

Expand Down
105 changes: 22 additions & 83 deletions src/llvm.cr
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@ require "./llvm/**"
require "c/string"

module LLVM
@@initialized = false

# Returns the runtime version of LLVM.
#
# Starting with LLVM 16, this method returns the version as reported by
Expand All @@ -20,85 +18,25 @@ module LLVM
{% end %}
end

def self.init_x86 : Nil
return if @@initialized_x86
@@initialized_x86 = true

{% if LibLLVM::BUILT_TARGETS.includes?(:x86) %}
LibLLVM.initialize_x86_target_info
LibLLVM.initialize_x86_target
LibLLVM.initialize_x86_target_mc
LibLLVM.initialize_x86_asm_printer
LibLLVM.initialize_x86_asm_parser
LibLLVM.link_in_mc_jit
{% else %}
raise "ERROR: LLVM was built without X86 target"
{% end %}
end

def self.init_aarch64 : Nil
return if @@initialized_aarch64
@@initialized_aarch64 = true

{% if LibLLVM::BUILT_TARGETS.includes?(:aarch64) %}
LibLLVM.initialize_aarch64_target_info
LibLLVM.initialize_aarch64_target
LibLLVM.initialize_aarch64_target_mc
LibLLVM.initialize_aarch64_asm_printer
LibLLVM.initialize_aarch64_asm_parser
LibLLVM.link_in_mc_jit
{% else %}
raise "ERROR: LLVM was built without AArch64 target"
{% end %}
end

def self.init_arm : Nil
return if @@initialized_arm
@@initialized_arm = true

{% if LibLLVM::BUILT_TARGETS.includes?(:arm) %}
LibLLVM.initialize_arm_target_info
LibLLVM.initialize_arm_target
LibLLVM.initialize_arm_target_mc
LibLLVM.initialize_arm_asm_printer
LibLLVM.initialize_arm_asm_parser
LibLLVM.link_in_mc_jit
{% else %}
raise "ERROR: LLVM was built without ARM target"
{% end %}
end
{% for target in LibLLVM::ALL_TARGETS %}
{% name = target.downcase.id %}
@@initialized_{{name}} = Atomic(Bool).new(false)

def self.init_avr : Nil
return if @@initialized_avr
@@initialized_avr = true

{% if LibLLVM::BUILT_TARGETS.includes?(:avr) %}
LibLLVM.initialize_avr_target_info
LibLLVM.initialize_avr_target
LibLLVM.initialize_avr_target_mc
LibLLVM.initialize_avr_asm_printer
LibLLVM.initialize_avr_asm_parser
LibLLVM.link_in_mc_jit
{% else %}
raise "ERROR: LLVM was built without AVR target"
{% end %}
end
def self.init_{{name}} : Nil
return if @@initialized_{{name}}.swap(true)

def self.init_webassembly : Nil
return if @@initialized_webassembly
@@initialized_webassembly = true

{% if LibLLVM::BUILT_TARGETS.includes?(:webassembly) %}
LibLLVM.initialize_webassembly_target_info
LibLLVM.initialize_webassembly_target
LibLLVM.initialize_webassembly_target_mc
LibLLVM.initialize_webassembly_asm_printer
LibLLVM.initialize_webassembly_asm_parser
LibLLVM.link_in_mc_jit
{% else %}
raise "ERROR: LLVM was built without WebAssembly target"
{% end %}
end
\{% if LibLLVM::BUILT_TARGETS.includes?({{name.symbolize}}) %}
LibLLVM.initialize_{{name}}_target_info
LibLLVM.initialize_{{name}}_target
LibLLVM.initialize_{{name}}_target_mc
LibLLVM.initialize_{{name}}_asm_printer
LibLLVM.initialize_{{name}}_asm_parser
LibLLVM.link_in_mc_jit
\{% else %}
raise "ERROR: LLVM was built without {{target.id}} target"
\{% end %}
end
{% end %}

def self.init_native_target : Nil
{% if flag?(:i386) || flag?(:x86_64) %}
Expand All @@ -117,10 +55,11 @@ module LLVM
end

def self.init_all_targets : Nil
{% for target in %i(x86 aarch64 arm avr webassembly) %}
{% if LibLLVM::BUILT_TARGETS.includes?(target) %}
init_{{ target.id }}
{% end %}
{% for target in LibLLVM::ALL_TARGETS %}
{% name = target.downcase.id %}
\{% if LibLLVM::BUILT_TARGETS.includes?({{name.symbolize}}) %}
init_{{name}}
\{% end %}
{% end %}
end

Expand Down
1 change: 1 addition & 0 deletions src/llvm/lib_llvm.cr
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,5 @@ lib LibLLVM
alias SizeT = LibC::SizeT
end

require "./lib_llvm/config"
require "./lib_llvm/**"
35 changes: 35 additions & 0 deletions src/llvm/lib_llvm/config.cr
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# The list of supported targets are hardcoded in:
# https://github.com/llvm/llvm-project/blob/main/llvm/CMakeLists.txt

lib LibLLVM
ALL_TARGETS = [
# default targets (as of LLVM 21)
"AArch64",
"AMDGPU",
"ARM",
"AVR",
"BPF",
"Hexagon",
"Lanai",
"LoongArch",
"MSP430",
"Mips",
"NVPTX",
"PowerPC",
"RISCV",
"SPIRV",
"Sparc",
"SystemZ",
"VE",
"WebAssembly",
"X86",
"XCore",

# experimental targets (as of LLVM 21)
"ARC",
"CSKY",
"DirectX",
"M68k",
"Xtensa",
]
end
33 changes: 8 additions & 25 deletions src/llvm/lib_llvm/target.cr
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,14 @@ require "./types"
lib LibLLVM
type TargetDataRef = Void*

fun initialize_aarch64_target_info = LLVMInitializeAArch64TargetInfo
fun initialize_aarch64_target = LLVMInitializeAArch64Target
fun initialize_aarch64_target_mc = LLVMInitializeAArch64TargetMC
fun initialize_aarch64_asm_printer = LLVMInitializeAArch64AsmPrinter
fun initialize_aarch64_asm_parser = LLVMInitializeAArch64AsmParser
fun initialize_arm_target_info = LLVMInitializeARMTargetInfo
fun initialize_arm_target = LLVMInitializeARMTarget
fun initialize_arm_target_mc = LLVMInitializeARMTargetMC
fun initialize_arm_asm_printer = LLVMInitializeARMAsmPrinter
fun initialize_arm_asm_parser = LLVMInitializeARMAsmParser
fun initialize_avr_target_info = LLVMInitializeAVRTargetInfo
fun initialize_avr_target = LLVMInitializeAVRTarget
fun initialize_avr_target_mc = LLVMInitializeAVRTargetMC
fun initialize_avr_asm_printer = LLVMInitializeAVRAsmPrinter
fun initialize_avr_asm_parser = LLVMInitializeAVRAsmParser
fun initialize_webassembly_target_info = LLVMInitializeWebAssemblyTargetInfo
fun initialize_webassembly_target = LLVMInitializeWebAssemblyTarget
fun initialize_webassembly_target_mc = LLVMInitializeWebAssemblyTargetMC
fun initialize_webassembly_asm_printer = LLVMInitializeWebAssemblyAsmPrinter
fun initialize_webassembly_asm_parser = LLVMInitializeWebAssemblyAsmParser
fun initialize_x86_target_info = LLVMInitializeX86TargetInfo
fun initialize_x86_target = LLVMInitializeX86Target
fun initialize_x86_target_mc = LLVMInitializeX86TargetMC
fun initialize_x86_asm_printer = LLVMInitializeX86AsmPrinter
fun initialize_x86_asm_parser = LLVMInitializeX86AsmParser
{% for target in ALL_TARGETS %}
{% name = target.downcase.id %}
fun initialize_{{name}}_target_info = LLVMInitialize{{target.id}}TargetInfo
fun initialize_{{name}}_target = LLVMInitialize{{target.id}}Target
fun initialize_{{name}}_target_mc = LLVMInitialize{{target.id}}TargetMC
fun initialize_{{name}}_asm_printer = LLVMInitialize{{target.id}}AsmPrinter
fun initialize_{{name}}_asm_parser = LLVMInitialize{{target.id}}AsmParser
{% end %}

fun set_module_data_layout = LLVMSetModuleDataLayout(m : ModuleRef, dl : TargetDataRef)

Expand Down
Loading