Skip to content

Commit 8c0721b

Browse files
authored
Merge pull request #705 from sysprog21/llvm-revisions
Support LLVM 18-21 for T2C
2 parents 14ad9d0 + b26939d commit 8c0721b

File tree

3 files changed

+121
-19
lines changed

3 files changed

+121
-19
lines changed

Makefile

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -138,40 +138,44 @@ ifeq ($(CONFIG_JIT),y)
138138
OBJS_EXT += jit.o
139139
T2C_ENABLED := 0
140140
ifeq ($(CONFIG_T2C),y)
141-
# LLVM 18 detection (only when T2C enabled)
142-
LLVM_CONFIG := $(strip $(or \
143-
$(shell which llvm-config-18 2>/dev/null),\
144-
$(shell brew --prefix llvm@18 2>/dev/null | xargs -I{} sh -c 'test -x {}/bin/llvm-config && echo {}/bin/llvm-config' 2>/dev/null),\
145-
$(shell which llvm-config 2>/dev/null | xargs -I{} sh -c '{} --version 2>/dev/null | grep -q "^18\." && echo {}' 2>/dev/null)))
146-
HOMEBREW_LLVM_PREFIX := $(shell which brew >/dev/null 2>&1 && brew --prefix llvm@18 2>/dev/null)
141+
# LLVM detection using helpers from mk/toolchain.mk
142+
# User can override with: make LLVM_CONFIG=/path/to/llvm-config
143+
ifndef LLVM_CONFIG
144+
LLVM_CONFIG := $(call detect-llvm-config)
145+
endif
147146
ifneq ($(LLVM_CONFIG),)
148-
CHECK_LLVM := $(shell $(LLVM_CONFIG) --libs 2>/dev/null 1>&2; echo $$?)
149-
ifeq ($(CHECK_LLVM),0)
147+
LLVM_VERSION := $(call llvm-version,$(LLVM_CONFIG))
148+
ifeq ($(call llvm-check-libs,$(LLVM_CONFIG)),0)
150149
T2C_ENABLED := 1
151150
OBJS_EXT += t2c.o
152-
CFLAGS += -g $(shell $(LLVM_CONFIG) --cflags)
153-
LDFLAGS += $(shell $(LLVM_CONFIG) --libfiles)
151+
CFLAGS += -g $(call llvm-cflags,$(LLVM_CONFIG))
152+
LDFLAGS += $(call llvm-libfiles,$(LLVM_CONFIG))
153+
# Add Homebrew library path if needed
154+
HOMEBREW_LLVM_PREFIX := $(call detect-homebrew-llvm-prefix)
154155
ifneq ($(HOMEBREW_LLVM_PREFIX),)
155156
ifneq ($(findstring $(HOMEBREW_LLVM_PREFIX),$(LLVM_CONFIG)),)
156157
LDFLAGS += -L$(HOMEBREW_LLVM_PREFIX)/lib
157158
endif
158159
endif
159160
else
160-
$(warning LLVM 18 libraries not found. T2C disabled.)
161+
$(warning LLVM $(LLVM_VERSION) libraries not found. T2C disabled.)
161162
endif
162163
else
163-
$(warning llvm-config-18 not found. T2C disabled.)
164+
$(warning llvm-config ($(LLVM_MIN_VERSION)-$(LLVM_MAX_VERSION)) not found. T2C disabled.)
164165
endif
165166
endif
166167
CFLAGS += -DRV32_FEATURE_T2C=$(T2C_ENABLED)
167-
ifneq ($(UNAME_M),$(filter $(UNAME_M),x86_64 aarch64 arm64))
168-
$(error JIT only supports x86_64 and ARM64 platforms.)
168+
# JIT requires x86_64 or ARM64; skip check for WASM builds (emcc cross-compiles)
169+
ifneq ($(CC_IS_EMCC),1)
170+
ifneq ($(UNAME_M),$(filter $(UNAME_M),x86_64 aarch64 arm64))
171+
$(error JIT only supports x86_64 and ARM64 platforms.)
172+
endif
169173
endif
170174
$(OUT)/jit.o: src/jit.c src/rv32_jit.c $(CONFIG_HEADER)
171175
$(VECHO) " CC\t$@\n"
172176
$(Q)$(CC) -o $@ $(CFLAGS) -c -MMD -MF $@.d $<
173-
# Pass T2C optimization level from Kconfig (0-3, default 3)
174-
T2C_OPT_LEVEL ?= $(if $(CONFIG_T2C_OPT_LEVEL),$(CONFIG_T2C_OPT_LEVEL),3)
177+
# T2C optimization level from Kconfig (0-3, default 3)
178+
T2C_OPT_LEVEL ?= $(or $(CONFIG_T2C_OPT_LEVEL),3)
175179
$(OUT)/t2c.o: src/t2c.c src/t2c_template.c $(CONFIG_HEADER)
176180
$(VECHO) " CC\t$@\n"
177181
$(Q)$(CC) -o $@ $(CFLAGS) -DCONFIG_T2C_OPT_LEVEL=$(T2C_OPT_LEVEL) -c -MMD -MF $@.d $<

mk/toolchain.mk

Lines changed: 81 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,9 +179,87 @@ ifneq ($(SYSROOT),)
179179
KCONFIG_LDFLAGS += --sysroot=$(SYSROOT)
180180
endif
181181

182-
# Note: LLVM 18 detection for T2C is done inline in Makefile,
183-
# guarded by ifeq ($(CONFIG_T2C),y) to avoid expensive shell calls
184-
# when T2C is disabled (most builds).
182+
# LLVM Detection for T2C (Tier-2 Compiler)
183+
#
184+
# Supports LLVM 18-21. Detection is deferred until CONFIG_T2C is enabled
185+
# to avoid expensive shell calls in most builds.
186+
#
187+
# User can override: make LLVM_CONFIG=/path/to/llvm-config
188+
189+
# Supported LLVM version range
190+
LLVM_MIN_VERSION := 18
191+
LLVM_MAX_VERSION := 21
192+
193+
# Check if a versioned llvm-config exists in PATH
194+
# Usage: $(call llvm-config-path,VERSION)
195+
define llvm-config-path
196+
$(shell which llvm-config-$(1) 2>/dev/null)
197+
endef
198+
199+
# Check if Homebrew LLVM version exists
200+
# Usage: $(call llvm-homebrew-config,VERSION)
201+
define llvm-homebrew-config
202+
$(shell brew --prefix llvm@$(1) 2>/dev/null | xargs -I{} sh -c 'test -x {}/bin/llvm-config && echo {}/bin/llvm-config' 2>/dev/null)
203+
endef
204+
205+
# Check generic llvm-config with version validation
206+
# Usage: $(call llvm-config-generic,MIN,MAX)
207+
define llvm-config-generic
208+
$(shell which llvm-config 2>/dev/null | xargs -I{} sh -c 'ver=$$({} --version 2>/dev/null | cut -d. -f1); [ "$$ver" -ge $(1) ] && [ "$$ver" -le $(2) ] && echo {}' 2>/dev/null)
209+
endef
210+
211+
# Auto-detect LLVM configuration
212+
# Priority: versioned binaries (18-21), Homebrew versioned, Homebrew generic, generic with version check
213+
# Note: Prefers oldest supported version (18) for stability; override with LLVM_CONFIG= for newer
214+
define detect-llvm-config
215+
$(strip $(or \
216+
$(call llvm-config-path,18),\
217+
$(call llvm-config-path,19),\
218+
$(call llvm-config-path,20),\
219+
$(call llvm-config-path,21),\
220+
$(call llvm-homebrew-config,18),\
221+
$(call llvm-homebrew-config,19),\
222+
$(call llvm-homebrew-config,20),\
223+
$(call llvm-homebrew-config,21),\
224+
$(shell brew --prefix llvm 2>/dev/null | xargs -I{} sh -c 'test -x {}/bin/llvm-config && echo {}/bin/llvm-config' 2>/dev/null),\
225+
$(call llvm-config-generic,$(LLVM_MIN_VERSION),$(LLVM_MAX_VERSION))))
226+
endef
227+
228+
# Detect Homebrew LLVM prefix for library path
229+
define detect-homebrew-llvm-prefix
230+
$(strip $(or \
231+
$(shell which brew >/dev/null 2>&1 && brew --prefix llvm@18 2>/dev/null),\
232+
$(shell which brew >/dev/null 2>&1 && brew --prefix llvm@19 2>/dev/null),\
233+
$(shell which brew >/dev/null 2>&1 && brew --prefix llvm@20 2>/dev/null),\
234+
$(shell which brew >/dev/null 2>&1 && brew --prefix llvm@21 2>/dev/null),\
235+
$(shell which brew >/dev/null 2>&1 && brew --prefix llvm 2>/dev/null)))
236+
endef
237+
238+
# Get LLVM version major number
239+
# Usage: $(call llvm-version,LLVM_CONFIG_PATH)
240+
define llvm-version
241+
$(shell $(1) --version 2>/dev/null | cut -d. -f1)
242+
endef
243+
244+
# Check if LLVM libraries are available
245+
# Usage: $(call llvm-check-libs,LLVM_CONFIG_PATH)
246+
# Returns: "0" (string) on success, non-zero string on failure
247+
# Example: ifeq ($(call llvm-check-libs,$(LLVM_CONFIG)),0)
248+
define llvm-check-libs
249+
$(shell $(1) --libs 2>/dev/null 1>&2; echo $$?)
250+
endef
251+
252+
# Get LLVM compiler flags
253+
# Usage: $(call llvm-cflags,LLVM_CONFIG_PATH)
254+
define llvm-cflags
255+
$(shell $(1) --cflags 2>/dev/null)
256+
endef
257+
258+
# Get LLVM library files for linking
259+
# Usage: $(call llvm-libfiles,LLVM_CONFIG_PATH)
260+
define llvm-libfiles
261+
$(shell $(1) --libfiles 2>/dev/null)
262+
endef
185263

186264
# Version Comparison Utilities
187265

src/t2c.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,28 @@
99
#include <llvm-c/ExecutionEngine.h>
1010
#include <llvm-c/Target.h>
1111
#include <llvm-c/Transforms/PassBuilder.h>
12+
#include <llvm/Config/llvm-config.h>
1213
#include <stdlib.h>
1314

15+
/* LLVM version compatibility check.
16+
* T2C requires LLVM 18-21 for the following APIs:
17+
* - LLVMRunPasses (new pass manager, added in LLVM 13)
18+
* - LLVMGetInlineAsm with 9 arguments (CanThrow param added in LLVM 13)
19+
* - LLVMBuildAtomicRMW (stable across 18-21)
20+
* - LLVMCreateTargetMachine (stable across 18-21)
21+
*
22+
* Note: LLVM 22+ may deprecate MCJIT in favor of ORC JIT.
23+
* When upgrading beyond LLVM 21, review:
24+
* - MCJIT deprecation status
25+
* - Any LLVMGetInlineAsm signature changes
26+
* - Code model defaults for JIT on aarch64
27+
*/
28+
#if LLVM_VERSION_MAJOR < 18
29+
#error "T2C requires LLVM 18 or later. Found LLVM " LLVM_VERSION_STRING
30+
#elif LLVM_VERSION_MAJOR > 21
31+
#warning "LLVM version > 21 detected. T2C is tested with LLVM 18-21."
32+
#endif
33+
1434
#include "jit.h"
1535
#include "mpool.h"
1636
#include "riscv_private.h"

0 commit comments

Comments
 (0)