@@ -49,21 +49,21 @@ FORCE_INLINE LLVMBasicBlockRef t2c_block_map_search(struct LLVM_block_map *map,
4949 return NULL ;
5050}
5151
52- #define T2C_OP (inst , code ) \
53- static void t2c_##inst( \
54- LLVMBuilderRef *builder UNUSED, LLVMTypeRef *param_types UNUSED, \
55- LLVMValueRef start UNUSED, LLVMBasicBlockRef *entry UNUSED, \
56- LLVMBuilderRef *taken_builder UNUSED, \
57- LLVMBuilderRef *untaken_builder UNUSED, riscv_t *rv UNUSED, \
58- uint64_t mem_base UNUSED, rv_insn_t *ir UNUSED) \
59- { \
60- LLVMValueRef timer_ptr = t2c_gen_timer_addr(start, builder, ir); \
61- LLVMValueRef timer = \
62- LLVMBuildLoad2(*builder, LLVMInt64Type(), timer_ptr, ""); \
63- timer = LLVMBuildAdd(*builder, timer, \
64- LLVMConstInt(LLVMInt64Type(), 1, false), ""); \
65- LLVMBuildStore(*builder, timer, timer_ptr); \
66- code; \
52+ #define T2C_OP (inst , code ) \
53+ static void t2c_##inst( \
54+ LLVMBuilderRef *builder UNUSED, LLVMTypeRef *param_types UNUSED, \
55+ LLVMValueRef start UNUSED, LLVMBasicBlockRef *entry UNUSED, \
56+ LLVMBuilderRef *taken_builder UNUSED, \
57+ LLVMBuilderRef *untaken_builder UNUSED, riscv_t *rv UNUSED, \
58+ uint64_t mem_base UNUSED, block_t *block UNUSED, rv_insn_t *ir UNUSED) \
59+ { \
60+ LLVMValueRef timer_ptr = t2c_gen_timer_addr(start, builder, ir); \
61+ LLVMValueRef timer = \
62+ LLVMBuildLoad2(*builder, LLVMInt64Type(), timer_ptr, ""); \
63+ timer = LLVMBuildAdd(*builder, timer, \
64+ LLVMConstInt(LLVMInt64Type(), 1, false), ""); \
65+ LLVMBuildStore(*builder, timer, timer_ptr); \
66+ code; \
6767 }
6868
6969#define T2C_LLVM_GEN_ADDR (reg , rv_member , ir_member ) \
@@ -190,17 +190,20 @@ typedef void (*t2c_codegen_block_func_t)(LLVMBuilderRef *builder UNUSED,
190190 LLVMBuilderRef * untaken_builder UNUSED ,
191191 riscv_t * rv UNUSED ,
192192 uint64_t mem_base UNUSED ,
193+ block_t * block UNUSED ,
193194 rv_insn_t * ir UNUSED );
194195
195196static void t2c_trace_ebb (LLVMBuilderRef * builder ,
196197 LLVMTypeRef * param_types UNUSED ,
197198 LLVMValueRef start ,
198199 LLVMBasicBlockRef * entry ,
199200 riscv_t * rv ,
200- rv_insn_t * ir ,
201+ block_t * block ,
201202 set_t * set ,
202203 struct LLVM_block_map * map )
203204{
205+ rv_insn_t * ir = block -> ir_head ;
206+
204207 if (set_has (set , ir -> pc ))
205208 return ;
206209 set_add (set , ir -> pc );
@@ -210,7 +213,7 @@ static void t2c_trace_ebb(LLVMBuilderRef *builder,
210213 while (1 ) {
211214 ((t2c_codegen_block_func_t ) dispatch_table [ir -> opcode ])(
212215 builder , param_types , start , entry , & tk , & utk , rv ,
213- (uint64_t ) ((memory_t * ) PRIV (rv )-> mem )-> mem_base , ir );
216+ (uint64_t ) ((memory_t * ) PRIV (rv )-> mem )-> mem_base , block , ir );
214217 if (!ir -> next )
215218 break ;
216219 ir = ir -> next ;
@@ -222,30 +225,43 @@ static void t2c_trace_ebb(LLVMBuilderRef *builder,
222225 LLVMBuildBr (utk ,
223226 t2c_block_map_search (map , ir -> branch_untaken -> pc ));
224227 else {
225- LLVMBasicBlockRef untaken_entry =
226- LLVMAppendBasicBlock (start ,
227- "untaken_"
228- "entry" );
229- LLVMBuilderRef untaken_builder = LLVMCreateBuilder ();
230- LLVMPositionBuilderAtEnd (untaken_builder , untaken_entry );
231- LLVMBuildBr (utk , untaken_entry );
232- t2c_trace_ebb (& untaken_builder , param_types , start ,
233- & untaken_entry , rv , ir -> branch_untaken , set , map );
228+ block_t * blk =
229+ cache_get (rv -> block_cache , ir -> branch_untaken -> pc , false);
230+ if (blk && blk -> translatable
231+ #if RV32_HAS (SYSTEM )
232+ && blk -> satp == block -> satp
233+ #endif
234+ ) {
235+ LLVMBasicBlockRef untaken_entry =
236+ LLVMAppendBasicBlock (start , "untaken_entry" );
237+ LLVMBuilderRef untaken_builder = LLVMCreateBuilder ();
238+ LLVMPositionBuilderAtEnd (untaken_builder , untaken_entry );
239+ LLVMBuildBr (utk , untaken_entry );
240+ t2c_trace_ebb (& untaken_builder , param_types , start ,
241+ & untaken_entry , rv , blk , set , map );
242+ }
234243 }
235244 }
236245 if (ir -> branch_taken ) {
237246 if (set_has (set , ir -> branch_taken -> pc ))
238247 LLVMBuildBr (tk ,
239248 t2c_block_map_search (map , ir -> branch_taken -> pc ));
240249 else {
241- LLVMBasicBlockRef taken_entry = LLVMAppendBasicBlock (start ,
242- "taken_"
243- "entry" );
244- LLVMBuilderRef taken_builder = LLVMCreateBuilder ();
245- LLVMPositionBuilderAtEnd (taken_builder , taken_entry );
246- LLVMBuildBr (tk , taken_entry );
247- t2c_trace_ebb (& taken_builder , param_types , start , & taken_entry ,
248- rv , ir -> branch_taken , set , map );
250+ block_t * blk =
251+ cache_get (rv -> block_cache , ir -> branch_taken -> pc , false);
252+ if (blk && blk -> translatable
253+ #if RV32_HAS (SYSTEM )
254+ && blk -> satp == block -> satp
255+ #endif
256+ ) {
257+ LLVMBasicBlockRef taken_entry =
258+ LLVMAppendBasicBlock (start , "taken_entry" );
259+ LLVMBuilderRef taken_builder = LLVMCreateBuilder ();
260+ LLVMPositionBuilderAtEnd (taken_builder , taken_entry );
261+ LLVMBuildBr (tk , taken_entry );
262+ t2c_trace_ebb (& taken_builder , param_types , start ,
263+ & taken_entry , rv , blk , set , map );
264+ }
249265 }
250266 }
251267 }
@@ -254,6 +270,9 @@ static void t2c_trace_ebb(LLVMBuilderRef *builder,
254270void t2c_compile (riscv_t * rv , block_t * block )
255271{
256272 LLVMModuleRef module = LLVMModuleCreateWithName ("my_module" );
273+ /* FIXME: riscv_t structure would change according to different
274+ * configuration. The linked block might jump to the wrong function pointer.
275+ */
257276 LLVMTypeRef io_members [] = {
258277 LLVMPointerType (LLVMVoidType (), 0 ), LLVMPointerType (LLVMVoidType (), 0 ),
259278 LLVMPointerType (LLVMVoidType (), 0 ), LLVMPointerType (LLVMVoidType (), 0 ),
@@ -291,8 +310,7 @@ void t2c_compile(riscv_t *rv, block_t *block)
291310 struct LLVM_block_map map ;
292311 map .count = 0 ;
293312 /* Translate custon IR into LLVM IR */
294- t2c_trace_ebb (& builder , param_types , start , & entry , rv , block -> ir_head ,
295- & set , & map );
313+ t2c_trace_ebb (& builder , param_types , start , & entry , rv , block , & set , & map );
296314 /* Offload LLVM IR to LLVM backend */
297315 char * error = NULL , * triple = LLVMGetDefaultTargetTriple ();
298316 LLVMExecutionEngineRef engine ;
@@ -319,7 +337,15 @@ void t2c_compile(riscv_t *rv, block_t *block)
319337
320338 /* Return the function pointer of T2C generated machine code */
321339 block -> func = (exec_t2c_func_t ) LLVMGetPointerToGlobal (engine , start );
322- jit_cache_update (rv -> jit_cache , block -> pc_start , block -> func );
340+
341+ #if RV32_HAS (SYSTEM )
342+ uint64_t key = (uint64_t ) block -> pc_start | ((uint64_t ) block -> satp << 32 );
343+ #else
344+ uint64_t key = (uint64_t ) block -> pc_start ;
345+ #endif
346+
347+ jit_cache_update (rv -> jit_cache , key , block -> func );
348+
323349 block -> hot2 = true;
324350}
325351
@@ -333,11 +359,11 @@ void jit_cache_exit(struct jit_cache *cache)
333359 free (cache );
334360}
335361
336- void jit_cache_update (struct jit_cache * cache , uint32_t pc , void * entry )
362+ void jit_cache_update (struct jit_cache * cache , uint64_t key , void * entry )
337363{
338- uint32_t pos = pc & (N_JIT_CACHE_ENTRIES - 1 );
364+ uint32_t pos = key & (N_JIT_CACHE_ENTRIES - 1 );
339365
340- cache [pos ].pc = pc ;
366+ cache [pos ].key = key ;
341367 cache [pos ].entry = entry ;
342368}
343369
0 commit comments