Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow JIT compilation for system emulation #521

Merged
merged 5 commits into from
Feb 14, 2025
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
8 changes: 8 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,14 @@ jobs:
.ci/boot-linux.sh
make ENABLE_SYSTEM=1 clean
if: ${{ always() }}
- name: boot Linux kernel test (JIT)
env:
CC: ${{ steps.install_cc.outputs.cc }}
run: |
make distclean && make INITRD_SIZE=32 ENABLE_SYSTEM=1 ENABLE_JIT=1 ENABLE_T2C=0 ENABLE_MOP_FUSION=0 -j$(nproc) && make ENABLE_SYSTEM=1 artifact -j$(nproc)
.ci/boot-linux.sh
make ENABLE_SYSTEM=1 ENABLE_JIT=1 ENABLE_T2C=0 ENABLE_MOP_FUSION=0 clean
if: ${{ always() }}
- name: Architecture test
env:
CC: ${{ steps.install_cc.outputs.cc }}
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,4 @@ tests/arch-test-target/config.ini
tests/arch-test-target/sail_cSim/riscv_sim_RV32
tests/scimark2/
__pycache__/
src/rv32_jit.c
vacantron marked this conversation as resolved.
Show resolved Hide resolved
src/minimal_dtb.h
16 changes: 9 additions & 7 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ CFLAGS = -std=gnu99 $(OPT_LEVEL) -Wall -Wextra -Werror
CFLAGS += -Wno-unused-label
CFLAGS += -include src/common.h -Isrc/

OBJS_EXT :=

# In the system test suite, the executable is an ELF file (e.g., MMU).
# However, the Linux kernel emulation includes the Image, DT, and
# root filesystem (rootfs). Therefore, the test suite needs this
Expand All @@ -36,6 +38,10 @@ $(call set-feature, LOG_COLOR)
ENABLE_SYSTEM ?= 0
$(call set-feature, SYSTEM)

ifeq ($(call has, SYSTEM), 1)
OBJS_EXT += system.o
endif

# Definition that bridges:
# Device Tree(initrd, memory range)
# src/io.c(memory init)
Expand Down Expand Up @@ -96,8 +102,6 @@ endif
# Disable Intel's Control-flow Enforcement Technology (CET)
CFLAGS += $(CFLAGS_NO_CET)

OBJS_EXT :=

# Integer Multiplication and Division instructions
ENABLE_EXT_M ?= 1
$(call set-feature, EXT_M)
Expand Down Expand Up @@ -248,7 +252,7 @@ ifeq ($(call has, JIT), 1)
ifeq ("$(CHECK_LLVM_LIBS)", "0")
OBJS_EXT += t2c.o
CFLAGS += -g $(shell $(LLVM_CONFIG) --cflags)
LDFLAGS += $(shell $(LLVM_CONFIG) --libs)
LDFLAGS += $(shell $(LLVM_CONFIG) --libfiles)
vacantron marked this conversation as resolved.
Show resolved Hide resolved
else
$(error No llvm-config-18 installed. Check llvm-config-18 installation in advance, or use "ENABLE_T2C=0" to disable tier-2 LLVM compiler)
endif
Expand All @@ -257,9 +261,6 @@ ifeq ($(call has, JIT), 1)
$(error JIT mode only supports for x64 and arm64 target currently.)
endif

src/rv32_jit.c:
$(Q)tools/gen-jit-template.py $(CFLAGS) > $@

$(OUT)/jit.o: src/jit.c src/rv32_jit.c
$(VECHO) " CC\t$@\n"
$(Q)$(CC) -o $@ $(CFLAGS) -c -MMD -MF [email protected] $<
Expand Down Expand Up @@ -409,9 +410,10 @@ endif

clean:
$(VECHO) "Cleaning... "
$(Q)$(RM) $(BIN) $(OBJS) $(DEV_OBJS) $(BUILD_DTB) $(BUILD_DTB2C) $(HIST_BIN) $(HIST_OBJS) $(deps) $(WEB_FILES) $(CACHE_OUT) src/rv32_jit.c
$(Q)$(RM) $(BIN) $(OBJS) $(DEV_OBJS) $(BUILD_DTB) $(BUILD_DTB2C) $(HIST_BIN) $(HIST_OBJS) $(deps) $(WEB_FILES) $(CACHE_OUT)
$(Q)-$(RM) $(SOFTFLOAT_LIB)
$(Q)$(call notice, [OK])

distclean: clean
$(VECHO) "Deleting all generated files... "
$(Q)$(RM) -r $(OUT)/id1
Expand Down
3 changes: 3 additions & 0 deletions src/decode.h
Original file line number Diff line number Diff line change
Expand Up @@ -332,6 +332,9 @@ typedef struct {
struct rv_insn *target[HISTORY_SIZE];
#else
uint32_t times[HISTORY_SIZE];
#if RV32_HAS(SYSTEM)
uint32_t satp[HISTORY_SIZE];
#endif
#endif
} branch_history_table_t;

Expand Down
45 changes: 37 additions & 8 deletions src/emulate.c
Original file line number Diff line number Diff line change
Expand Up @@ -863,12 +863,12 @@ static block_t *block_find_or_translate(riscv_t *rv)
block_t *next_blk = block_find(map, rv->PC);
#else
/* lookup the next block in the block cache */
/*
* The function "cache_get()" gets the cached block by the given "key (PC)".
* In system simulation, the returned block might be dropped because it is
* not the one from the current process (by checking SATP CSR register).
*/
block_t *next_blk = (block_t *) cache_get(rv->block_cache, rv->PC, true);
#if RV32_HAS(SYSTEM)
/* discard cache if satp is not matched */
if (next_blk && next_blk->satp != rv->csr_satp)
next_blk = NULL;
#endif
#endif

if (next_blk)
Expand All @@ -886,6 +886,14 @@ static block_t *block_find_or_translate(riscv_t *rv)

block_translate(rv, next_blk);

#if RV32_HAS(JIT) && RV32_HAS(SYSTEM)
/*
* May be an ifetch fault which changes satp, Do not do this
* in "block_alloc()"
*/
next_blk->satp = rv->csr_satp;
#endif

optimize_constant(rv, next_blk);
#if RV32_HAS(MOP_FUSION)
/* macro operation fusion */
Expand All @@ -912,8 +920,6 @@ static block_t *block_find_or_translate(riscv_t *rv)
return next_blk;
}

list_del_init(&replaced_blk->list);

if (prev == replaced_blk)
prev = NULL;

Expand All @@ -932,6 +938,16 @@ static block_t *block_find_or_translate(riscv_t *rv)
if (untaken == replaced_blk_entry) {
entry->ir_tail->branch_untaken = NULL;
}

/* upadte JALR LUT */
if (!entry->ir_tail->branch_table) {
continue;
}

/**
* TODO: upadate all JALR instructions which references to this
* basic block as the destination.
*/
}

/* free IRs in replaced block */
Expand All @@ -945,6 +961,7 @@ static block_t *block_find_or_translate(riscv_t *rv)
mpool_free(rv->block_ir_mp, ir);
}

list_del_init(&replaced_blk->list);
mpool_free(rv->block_mp, replaced_blk);
#if RV32_HAS(T2C)
pthread_mutex_unlock(&rv->cache_lock);
Expand All @@ -961,6 +978,10 @@ static block_t *block_find_or_translate(riscv_t *rv)
#if RV32_HAS(JIT) && !RV32_HAS(ARCH_TEST)
static bool runtime_profiler(riscv_t *rv, block_t *block)
{
#if RV32_HAS(SYSTEM)
if (block->satp != rv->csr_satp)
return false;
#endif
/* Based on our observations, a significant number of true hotspots are
* characterized by high usage frequency and including loop. Consequently,
* we posit that our profiler could effectively identify hotspots using
Expand Down Expand Up @@ -1053,14 +1074,22 @@ void rv_step(void *arg)
/* by now, a block should be available */
assert(block);

#if RV32_HAS(JIT) && RV32_HAS(SYSTEM)
assert(block->satp == rv->csr_satp);
#endif

/* After emulating the previous block, it is determined whether the
* branch is taken or not. The IR array of the current block is then
* assigned to either the branch_taken or branch_untaken pointer of
* the previous block.
*/

#if RV32_HAS(BLOCK_CHAINING)
if (prev) {
if (prev
#if RV32_HAS(JIT) && RV32_HAS(SYSTEM)
&& prev->satp == rv->csr_satp
#endif
) {
rv_insn_t *last_ir = prev->ir_tail;
/* chain block */
if (!insn_is_unconditional_branch(last_ir->opcode)) {
Expand Down
Loading
Loading