Commit 641d5fbe6bef1cbc34732665efa8d5f0b71acbc4

Authored by bellard
1 parent 98fc5614

added local temporaries

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4576 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 2 changed files with 103 additions and 45 deletions
tcg/tcg.c
@@ -269,7 +269,7 @@ void tcg_func_start(TCGContext *s) @@ -269,7 +269,7 @@ void tcg_func_start(TCGContext *s)
269 int i; 269 int i;
270 tcg_pool_reset(s); 270 tcg_pool_reset(s);
271 s->nb_temps = s->nb_globals; 271 s->nb_temps = s->nb_globals;
272 - for(i = 0; i < TCG_TYPE_COUNT; i++) 272 + for(i = 0; i < (TCG_TYPE_COUNT * 2); i++)
273 s->first_free_temp[i] = -1; 273 s->first_free_temp[i] = -1;
274 s->labels = tcg_malloc(sizeof(TCGLabel) * TCG_MAX_LABELS); 274 s->labels = tcg_malloc(sizeof(TCGLabel) * TCG_MAX_LABELS);
275 s->nb_labels = 0; 275 s->nb_labels = 0;
@@ -407,19 +407,23 @@ TCGv tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset, @@ -407,19 +407,23 @@ TCGv tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset,
407 return MAKE_TCGV(idx); 407 return MAKE_TCGV(idx);
408 } 408 }
409 409
410 -TCGv tcg_temp_new(TCGType type) 410 +TCGv tcg_temp_new_internal(TCGType type, int temp_local)
411 { 411 {
412 TCGContext *s = &tcg_ctx; 412 TCGContext *s = &tcg_ctx;
413 TCGTemp *ts; 413 TCGTemp *ts;
414 - int idx; 414 + int idx, k;
415 415
416 - idx = s->first_free_temp[type]; 416 + k = type;
  417 + if (temp_local)
  418 + k += TCG_TYPE_COUNT;
  419 + idx = s->first_free_temp[k];
417 if (idx != -1) { 420 if (idx != -1) {
418 /* There is already an available temp with the 421 /* There is already an available temp with the
419 right type */ 422 right type */
420 ts = &s->temps[idx]; 423 ts = &s->temps[idx];
421 - s->first_free_temp[type] = ts->next_free_temp; 424 + s->first_free_temp[k] = ts->next_free_temp;
422 ts->temp_allocated = 1; 425 ts->temp_allocated = 1;
  426 + assert(ts->temp_local == temp_local);
423 } else { 427 } else {
424 idx = s->nb_temps; 428 idx = s->nb_temps;
425 #if TCG_TARGET_REG_BITS == 32 429 #if TCG_TARGET_REG_BITS == 32
@@ -429,11 +433,13 @@ TCGv tcg_temp_new(TCGType type) @@ -429,11 +433,13 @@ TCGv tcg_temp_new(TCGType type)
429 ts->base_type = type; 433 ts->base_type = type;
430 ts->type = TCG_TYPE_I32; 434 ts->type = TCG_TYPE_I32;
431 ts->temp_allocated = 1; 435 ts->temp_allocated = 1;
  436 + ts->temp_local = temp_local;
432 ts->name = NULL; 437 ts->name = NULL;
433 ts++; 438 ts++;
434 ts->base_type = TCG_TYPE_I32; 439 ts->base_type = TCG_TYPE_I32;
435 ts->type = TCG_TYPE_I32; 440 ts->type = TCG_TYPE_I32;
436 ts->temp_allocated = 1; 441 ts->temp_allocated = 1;
  442 + ts->temp_local = temp_local;
437 ts->name = NULL; 443 ts->name = NULL;
438 s->nb_temps += 2; 444 s->nb_temps += 2;
439 } else 445 } else
@@ -444,6 +450,7 @@ TCGv tcg_temp_new(TCGType type) @@ -444,6 +450,7 @@ TCGv tcg_temp_new(TCGType type)
444 ts->base_type = type; 450 ts->base_type = type;
445 ts->type = type; 451 ts->type = type;
446 ts->temp_allocated = 1; 452 ts->temp_allocated = 1;
  453 + ts->temp_local = temp_local;
447 ts->name = NULL; 454 ts->name = NULL;
448 s->nb_temps++; 455 s->nb_temps++;
449 } 456 }
@@ -456,15 +463,17 @@ void tcg_temp_free(TCGv arg) @@ -456,15 +463,17 @@ void tcg_temp_free(TCGv arg)
456 TCGContext *s = &tcg_ctx; 463 TCGContext *s = &tcg_ctx;
457 TCGTemp *ts; 464 TCGTemp *ts;
458 int idx = GET_TCGV(arg); 465 int idx = GET_TCGV(arg);
459 - TCGType type; 466 + int k;
460 467
461 assert(idx >= s->nb_globals && idx < s->nb_temps); 468 assert(idx >= s->nb_globals && idx < s->nb_temps);
462 ts = &s->temps[idx]; 469 ts = &s->temps[idx];
463 assert(ts->temp_allocated != 0); 470 assert(ts->temp_allocated != 0);
464 ts->temp_allocated = 0; 471 ts->temp_allocated = 0;
465 - type = ts->base_type;  
466 - ts->next_free_temp = s->first_free_temp[type];  
467 - s->first_free_temp[type] = idx; 472 + k = ts->base_type;
  473 + if (ts->temp_local)
  474 + k += TCG_TYPE_COUNT;
  475 + ts->next_free_temp = s->first_free_temp[k];
  476 + s->first_free_temp[k] = idx;
468 } 477 }
469 478
470 479
@@ -683,7 +692,10 @@ static char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size, @@ -683,7 +692,10 @@ static char *tcg_get_arg_str_idx(TCGContext *s, char *buf, int buf_size,
683 if (idx < s->nb_globals) { 692 if (idx < s->nb_globals) {
684 pstrcpy(buf, buf_size, ts->name); 693 pstrcpy(buf, buf_size, ts->name);
685 } else { 694 } else {
686 - snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals); 695 + if (ts->temp_local)
  696 + snprintf(buf, buf_size, "loc%d", idx - s->nb_globals);
  697 + else
  698 + snprintf(buf, buf_size, "tmp%d", idx - s->nb_globals);
687 } 699 }
688 return buf; 700 return buf;
689 } 701 }
@@ -987,13 +999,34 @@ static inline void tcg_set_nop(TCGContext *s, uint16_t *opc_ptr, @@ -987,13 +999,34 @@ static inline void tcg_set_nop(TCGContext *s, uint16_t *opc_ptr,
987 } 999 }
988 } 1000 }
989 1001
990 -/* liveness analysis: end of basic block: globals are live, temps are dead */  
991 -static inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps) 1002 +/* liveness analysis: end of function: globals are live, temps are
  1003 + dead. */
  1004 +/* XXX: at this stage, not used as there would be little gains because
  1005 + most TBs end with a conditional jump. */
  1006 +static inline void tcg_la_func_end(TCGContext *s, uint8_t *dead_temps)
992 { 1007 {
993 memset(dead_temps, 0, s->nb_globals); 1008 memset(dead_temps, 0, s->nb_globals);
994 memset(dead_temps + s->nb_globals, 1, s->nb_temps - s->nb_globals); 1009 memset(dead_temps + s->nb_globals, 1, s->nb_temps - s->nb_globals);
995 } 1010 }
996 1011
  1012 +/* liveness analysis: end of basic block: globals are live, temps are
  1013 + dead, local temps are live. */
  1014 +static inline void tcg_la_bb_end(TCGContext *s, uint8_t *dead_temps)
  1015 +{
  1016 + int i;
  1017 + TCGTemp *ts;
  1018 +
  1019 + memset(dead_temps, 0, s->nb_globals);
  1020 + ts = &s->temps[s->nb_globals];
  1021 + for(i = s->nb_globals; i < s->nb_temps; i++) {
  1022 + if (ts->temp_local)
  1023 + dead_temps[i] = 0;
  1024 + else
  1025 + dead_temps[i] = 1;
  1026 + ts++;
  1027 + }
  1028 +}
  1029 +
997 /* Liveness analysis : update the opc_dead_iargs array to tell if a 1030 /* Liveness analysis : update the opc_dead_iargs array to tell if a
998 given input arguments is dead. Instructions updating dead 1031 given input arguments is dead. Instructions updating dead
999 temporaries are removed. */ 1032 temporaries are removed. */
@@ -1366,37 +1399,48 @@ static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2) @@ -1366,37 +1399,48 @@ static int tcg_reg_alloc(TCGContext *s, TCGRegSet reg1, TCGRegSet reg2)
1366 tcg_abort(); 1399 tcg_abort();
1367 } 1400 }
1368 1401
  1402 +/* save a temporary to memory. 'allocated_regs' is used in case a
  1403 + temporary registers needs to be allocated to store a constant. */
  1404 +static void temp_save(TCGContext *s, int temp, TCGRegSet allocated_regs)
  1405 +{
  1406 + TCGTemp *ts;
  1407 + int reg;
  1408 +
  1409 + ts = &s->temps[temp];
  1410 + if (!ts->fixed_reg) {
  1411 + switch(ts->val_type) {
  1412 + case TEMP_VAL_REG:
  1413 + tcg_reg_free(s, ts->reg);
  1414 + break;
  1415 + case TEMP_VAL_DEAD:
  1416 + ts->val_type = TEMP_VAL_MEM;
  1417 + break;
  1418 + case TEMP_VAL_CONST:
  1419 + reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],
  1420 + allocated_regs);
  1421 + if (!ts->mem_allocated)
  1422 + temp_allocate_frame(s, temp);
  1423 + tcg_out_movi(s, ts->type, reg, ts->val);
  1424 + tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);
  1425 + ts->val_type = TEMP_VAL_MEM;
  1426 + break;
  1427 + case TEMP_VAL_MEM:
  1428 + break;
  1429 + default:
  1430 + tcg_abort();
  1431 + }
  1432 + }
  1433 +}
  1434 +
1369 /* save globals to their cannonical location and assume they can be 1435 /* save globals to their cannonical location and assume they can be
1370 modified be the following code. 'allocated_regs' is used in case a 1436 modified be the following code. 'allocated_regs' is used in case a
1371 temporary registers needs to be allocated to store a constant. */ 1437 temporary registers needs to be allocated to store a constant. */
1372 static void save_globals(TCGContext *s, TCGRegSet allocated_regs) 1438 static void save_globals(TCGContext *s, TCGRegSet allocated_regs)
1373 { 1439 {
1374 - TCGTemp *ts;  
1375 - int i, reg; 1440 + int i;
1376 1441
1377 for(i = 0; i < s->nb_globals; i++) { 1442 for(i = 0; i < s->nb_globals; i++) {
1378 - ts = &s->temps[i];  
1379 - if (!ts->fixed_reg) {  
1380 - switch(ts->val_type) {  
1381 - case TEMP_VAL_REG:  
1382 - tcg_reg_free(s, ts->reg);  
1383 - break;  
1384 - case TEMP_VAL_DEAD:  
1385 - ts->val_type = TEMP_VAL_MEM;  
1386 - break;  
1387 - case TEMP_VAL_CONST:  
1388 - reg = tcg_reg_alloc(s, tcg_target_available_regs[ts->type],  
1389 - allocated_regs);  
1390 - tcg_out_movi(s, ts->type, reg, ts->val);  
1391 - tcg_out_st(s, ts->type, reg, ts->mem_reg, ts->mem_offset);  
1392 - ts->val_type = TEMP_VAL_MEM;  
1393 - break;  
1394 - case TEMP_VAL_MEM:  
1395 - break;  
1396 - default:  
1397 - tcg_abort();  
1398 - }  
1399 - } 1443 + temp_save(s, i, allocated_regs);
1400 } 1444 }
1401 } 1445 }
1402 1446
@@ -1409,10 +1453,14 @@ static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs) @@ -1409,10 +1453,14 @@ static void tcg_reg_alloc_bb_end(TCGContext *s, TCGRegSet allocated_regs)
1409 1453
1410 for(i = s->nb_globals; i < s->nb_temps; i++) { 1454 for(i = s->nb_globals; i < s->nb_temps; i++) {
1411 ts = &s->temps[i]; 1455 ts = &s->temps[i];
1412 - if (ts->val_type == TEMP_VAL_REG) {  
1413 - s->reg_to_temp[ts->reg] = -1; 1456 + if (ts->temp_local) {
  1457 + temp_save(s, i, allocated_regs);
  1458 + } else {
  1459 + if (ts->val_type == TEMP_VAL_REG) {
  1460 + s->reg_to_temp[ts->reg] = -1;
  1461 + }
  1462 + ts->val_type = TEMP_VAL_DEAD;
1414 } 1463 }
1415 - ts->val_type = TEMP_VAL_DEAD;  
1416 } 1464 }
1417 1465
1418 save_globals(s, allocated_regs); 1466 save_globals(s, allocated_regs);
tcg/tcg.h
@@ -189,6 +189,9 @@ typedef struct TCGTemp { @@ -189,6 +189,9 @@ typedef struct TCGTemp {
189 unsigned int fixed_reg:1; 189 unsigned int fixed_reg:1;
190 unsigned int mem_coherent:1; 190 unsigned int mem_coherent:1;
191 unsigned int mem_allocated:1; 191 unsigned int mem_allocated:1;
  192 + unsigned int temp_local:1; /* If true, the temp is saved accross
  193 + basic blocks. Otherwise, it is not
  194 + preserved accross basic blocks. */
192 unsigned int temp_allocated:1; /* never used for code gen */ 195 unsigned int temp_allocated:1; /* never used for code gen */
193 /* index of next free temp of same base type, -1 if end */ 196 /* index of next free temp of same base type, -1 if end */
194 int next_free_temp; 197 int next_free_temp;
@@ -212,11 +215,8 @@ struct TCGContext { @@ -212,11 +215,8 @@ struct TCGContext {
212 TCGTemp *temps; /* globals first, temps after */ 215 TCGTemp *temps; /* globals first, temps after */
213 int nb_globals; 216 int nb_globals;
214 int nb_temps; 217 int nb_temps;
215 - int first_free_temp[TCG_TYPE_COUNT]; /* index of free temps, -1 if none */  
216 -  
217 - /* constant indexes (end of temp array) */  
218 - int const_start;  
219 - int const_end; 218 + /* index of free temps, -1 if none */
  219 + int first_free_temp[TCG_TYPE_COUNT * 2];
220 220
221 /* goto_tb support */ 221 /* goto_tb support */
222 uint8_t *code_buf; 222 uint8_t *code_buf;
@@ -224,8 +224,10 @@ struct TCGContext { @@ -224,8 +224,10 @@ struct TCGContext {
224 uint16_t *tb_next_offset; 224 uint16_t *tb_next_offset;
225 uint16_t *tb_jmp_offset; /* != NULL if USE_DIRECT_JUMP */ 225 uint16_t *tb_jmp_offset; /* != NULL if USE_DIRECT_JUMP */
226 226
  227 + /* liveness analysis */
227 uint16_t *op_dead_iargs; /* for each operation, each bit tells if the 228 uint16_t *op_dead_iargs; /* for each operation, each bit tells if the
228 corresponding input argument is dead */ 229 corresponding input argument is dead */
  230 +
229 /* tells in which temporary a given register is. It does not take 231 /* tells in which temporary a given register is. It does not take
230 into account fixed registers */ 232 into account fixed registers */
231 int reg_to_temp[TCG_TARGET_NB_REGS]; 233 int reg_to_temp[TCG_TARGET_NB_REGS];
@@ -305,7 +307,15 @@ TCGv tcg_global_reg2_new_hack(TCGType type, int reg1, int reg2, @@ -305,7 +307,15 @@ TCGv tcg_global_reg2_new_hack(TCGType type, int reg1, int reg2,
305 const char *name); 307 const char *name);
306 TCGv tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset, 308 TCGv tcg_global_mem_new(TCGType type, int reg, tcg_target_long offset,
307 const char *name); 309 const char *name);
308 -TCGv tcg_temp_new(TCGType type); 310 +TCGv tcg_temp_new_internal(TCGType type, int temp_local);
  311 +static inline TCGv tcg_temp_new(TCGType type)
  312 +{
  313 + return tcg_temp_new_internal(type, 0);
  314 +}
  315 +static inline TCGv tcg_temp_local_new(TCGType type)
  316 +{
  317 + return tcg_temp_new_internal(type, 1);
  318 +}
309 void tcg_temp_free(TCGv arg); 319 void tcg_temp_free(TCGv arg);
310 char *tcg_get_arg_str(TCGContext *s, char *buf, int buf_size, TCGv arg); 320 char *tcg_get_arg_str(TCGContext *s, char *buf, int buf_size, TCGv arg);
311 void tcg_dump_info(FILE *f, 321 void tcg_dump_info(FILE *f,