@@ -49,21 +49,21 @@ FORCE_INLINE LLVMBasicBlockRef t2c_block_map_search(struct LLVM_block_map *map,
49
49
return NULL ;
50
50
}
51
51
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; \
67
67
}
68
68
69
69
#define T2C_LLVM_GEN_ADDR (reg , rv_member , ir_member ) \
@@ -190,17 +190,20 @@ typedef void (*t2c_codegen_block_func_t)(LLVMBuilderRef *builder UNUSED,
190
190
LLVMBuilderRef * untaken_builder UNUSED ,
191
191
riscv_t * rv UNUSED ,
192
192
uint64_t mem_base UNUSED ,
193
+ block_t * block UNUSED ,
193
194
rv_insn_t * ir UNUSED );
194
195
195
196
static void t2c_trace_ebb (LLVMBuilderRef * builder ,
196
197
LLVMTypeRef * param_types UNUSED ,
197
198
LLVMValueRef start ,
198
199
LLVMBasicBlockRef * entry ,
199
200
riscv_t * rv ,
200
- rv_insn_t * ir ,
201
+ block_t * block ,
201
202
set_t * set ,
202
203
struct LLVM_block_map * map )
203
204
{
205
+ rv_insn_t * ir = block -> ir_head ;
206
+
204
207
if (set_has (set , ir -> pc ))
205
208
return ;
206
209
set_add (set , ir -> pc );
@@ -210,7 +213,7 @@ static void t2c_trace_ebb(LLVMBuilderRef *builder,
210
213
while (1 ) {
211
214
((t2c_codegen_block_func_t ) dispatch_table [ir -> opcode ])(
212
215
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 );
214
217
if (!ir -> next )
215
218
break ;
216
219
ir = ir -> next ;
@@ -222,30 +225,43 @@ static void t2c_trace_ebb(LLVMBuilderRef *builder,
222
225
LLVMBuildBr (utk ,
223
226
t2c_block_map_search (map , ir -> branch_untaken -> pc ));
224
227
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
+ }
234
243
}
235
244
}
236
245
if (ir -> branch_taken ) {
237
246
if (set_has (set , ir -> branch_taken -> pc ))
238
247
LLVMBuildBr (tk ,
239
248
t2c_block_map_search (map , ir -> branch_taken -> pc ));
240
249
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
+ }
249
265
}
250
266
}
251
267
}
@@ -254,6 +270,9 @@ static void t2c_trace_ebb(LLVMBuilderRef *builder,
254
270
void t2c_compile (riscv_t * rv , block_t * block )
255
271
{
256
272
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
+ */
257
276
LLVMTypeRef io_members [] = {
258
277
LLVMPointerType (LLVMVoidType (), 0 ), LLVMPointerType (LLVMVoidType (), 0 ),
259
278
LLVMPointerType (LLVMVoidType (), 0 ), LLVMPointerType (LLVMVoidType (), 0 ),
@@ -291,8 +310,7 @@ void t2c_compile(riscv_t *rv, block_t *block)
291
310
struct LLVM_block_map map ;
292
311
map .count = 0 ;
293
312
/* 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 );
296
314
/* Offload LLVM IR to LLVM backend */
297
315
char * error = NULL , * triple = LLVMGetDefaultTargetTriple ();
298
316
LLVMExecutionEngineRef engine ;
@@ -319,7 +337,15 @@ void t2c_compile(riscv_t *rv, block_t *block)
319
337
320
338
/* Return the function pointer of T2C generated machine code */
321
339
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
+
323
349
block -> hot2 = true;
324
350
}
325
351
@@ -333,11 +359,11 @@ void jit_cache_exit(struct jit_cache *cache)
333
359
free (cache );
334
360
}
335
361
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 )
337
363
{
338
- uint32_t pos = pc & (N_JIT_CACHE_ENTRIES - 1 );
364
+ uint32_t pos = key & (N_JIT_CACHE_ENTRIES - 1 );
339
365
340
- cache [pos ].pc = pc ;
366
+ cache [pos ].key = key ;
341
367
cache [pos ].entry = entry ;
342
368
}
343
369
0 commit comments