@@ -49,15 +49,15 @@ 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, uint64_t mem_base UNUSED, \
58
- rv_insn_t *ir UNUSED) \
59
- { \
60
- 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, rv_insn_t *ir UNUSED) \
59
+ { \
60
+ code; \
61
61
}
62
62
63
63
#define T2C_LLVM_GEN_ADDR (reg , rv_member , ir_member ) \
@@ -135,6 +135,9 @@ FORCE_INLINE void t2c_gen_call_io_func(LLVMValueRef start,
135
135
& io_param , 1 , "" );
136
136
}
137
137
138
+ static LLVMTypeRef t2c_jit_cache_func_type ;
139
+ static LLVMTypeRef t2c_jit_cache_struct_type ;
140
+
138
141
#include "t2c_template.c"
139
142
#undef T2C_OP
140
143
@@ -174,14 +177,15 @@ typedef void (*t2c_codegen_block_func_t)(LLVMBuilderRef *builder UNUSED,
174
177
LLVMBasicBlockRef * entry UNUSED ,
175
178
LLVMBuilderRef * taken_builder UNUSED ,
176
179
LLVMBuilderRef * untaken_builder UNUSED ,
180
+ riscv_t * rv UNUSED ,
177
181
uint64_t mem_base UNUSED ,
178
182
rv_insn_t * ir UNUSED );
179
183
180
184
static void t2c_trace_ebb (LLVMBuilderRef * builder ,
181
185
LLVMTypeRef * param_types UNUSED ,
182
186
LLVMValueRef start ,
183
187
LLVMBasicBlockRef * entry ,
184
- uint64_t mem_base ,
188
+ riscv_t * rv ,
185
189
rv_insn_t * ir ,
186
190
set_t * set ,
187
191
struct LLVM_block_map * map )
@@ -194,7 +198,8 @@ static void t2c_trace_ebb(LLVMBuilderRef *builder,
194
198
195
199
while (1 ) {
196
200
((t2c_codegen_block_func_t ) dispatch_table [ir -> opcode ])(
197
- builder , param_types , start , entry , & tk , & utk , mem_base , ir );
201
+ builder , param_types , start , entry , & tk , & utk , rv ,
202
+ (uint64_t ) ((memory_t * ) PRIV (rv )-> mem )-> mem_base , ir );
198
203
if (!ir -> next )
199
204
break ;
200
205
ir = ir -> next ;
@@ -214,8 +219,7 @@ static void t2c_trace_ebb(LLVMBuilderRef *builder,
214
219
LLVMPositionBuilderAtEnd (untaken_builder , untaken_entry );
215
220
LLVMBuildBr (utk , untaken_entry );
216
221
t2c_trace_ebb (& untaken_builder , param_types , start ,
217
- & untaken_entry , mem_base , ir -> branch_untaken , set ,
218
- map );
222
+ & untaken_entry , rv , ir -> branch_untaken , set , map );
219
223
}
220
224
}
221
225
if (ir -> branch_taken ) {
@@ -230,13 +234,13 @@ static void t2c_trace_ebb(LLVMBuilderRef *builder,
230
234
LLVMPositionBuilderAtEnd (taken_builder , taken_entry );
231
235
LLVMBuildBr (tk , taken_entry );
232
236
t2c_trace_ebb (& taken_builder , param_types , start , & taken_entry ,
233
- mem_base , ir -> branch_taken , set , map );
237
+ rv , ir -> branch_taken , set , map );
234
238
}
235
239
}
236
240
}
237
241
}
238
242
239
- void t2c_compile (block_t * block , uint64_t mem_base )
243
+ void t2c_compile (riscv_t * rv , block_t * block )
240
244
{
241
245
LLVMModuleRef module = LLVMModuleCreateWithName ("my_module" );
242
246
LLVMTypeRef io_members [] = {
@@ -254,6 +258,16 @@ void t2c_compile(block_t *block, uint64_t mem_base)
254
258
LLVMTypeRef param_types [] = {LLVMPointerType (struct_rv , 0 )};
255
259
LLVMValueRef start = LLVMAddFunction (
256
260
module , "start" , LLVMFunctionType (LLVMVoidType (), param_types , 1 , 0 ));
261
+
262
+ LLVMTypeRef t2c_args [1 ] = {LLVMInt64Type ()};
263
+ t2c_jit_cache_func_type =
264
+ LLVMFunctionType (LLVMVoidType (), t2c_args , 1 , false);
265
+
266
+ /* Notice to the alignment */
267
+ LLVMTypeRef jit_cache_memb [2 ] = {LLVMInt64Type (),
268
+ LLVMPointerType (LLVMVoidType (), 0 )};
269
+ t2c_jit_cache_struct_type = LLVMStructType (jit_cache_memb , 2 , false);
270
+
257
271
LLVMBasicBlockRef first_block = LLVMAppendBasicBlock (start , "first_block" );
258
272
LLVMBuilderRef first_builder = LLVMCreateBuilder ();
259
273
LLVMPositionBuilderAtEnd (first_builder , first_block );
@@ -266,8 +280,8 @@ void t2c_compile(block_t *block, uint64_t mem_base)
266
280
struct LLVM_block_map map ;
267
281
map .count = 0 ;
268
282
/* Translate custon IR into LLVM IR */
269
- t2c_trace_ebb (& builder , param_types , start , & entry , mem_base ,
270
- block -> ir_head , & set , & map );
283
+ t2c_trace_ebb (& builder , param_types , start , & entry , rv , block -> ir_head ,
284
+ & set , & map );
271
285
/* Offload LLVM IR to LLVM backend */
272
286
char * error = NULL , * triple = LLVMGetDefaultTargetTriple ();
273
287
LLVMExecutionEngineRef engine ;
@@ -298,5 +312,29 @@ void t2c_compile(block_t *block, uint64_t mem_base)
298
312
299
313
/* Return the function pointer of T2C generated machine code */
300
314
block -> func = (exec_t2c_func_t ) LLVMGetPointerToGlobal (engine , start );
315
+ jit_cache_update (rv -> jit_cache , block -> pc_start , block -> func );
301
316
block -> hot2 = true;
302
317
}
318
+
319
+ struct jit_cache * jit_cache_init ()
320
+ {
321
+ return calloc (N_JIT_CACHE_ENTRIES , sizeof (struct jit_cache ));
322
+ }
323
+
324
+ void jit_cache_exit (struct jit_cache * cache )
325
+ {
326
+ free (cache );
327
+ }
328
+
329
+ void jit_cache_update (struct jit_cache * cache , uint32_t pc , void * entry )
330
+ {
331
+ uint32_t pos = pc & (N_JIT_CACHE_ENTRIES - 1 );
332
+
333
+ cache [pos ].pc = pc ;
334
+ cache [pos ].entry = entry ;
335
+ }
336
+
337
+ void jit_cache_clear (struct jit_cache * cache )
338
+ {
339
+ memset (cache , 0 , N_JIT_CACHE_ENTRIES * sizeof (struct jit_cache ));
340
+ }
0 commit comments