Revision 641d5fbe tcg/tcg.c

b/tcg/tcg.c
269 269
    int i;
270 270
    tcg_pool_reset(s);
271 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 273
        s->first_free_temp[i] = -1;
274 274
    s->labels = tcg_malloc(sizeof(TCGLabel) * TCG_MAX_LABELS);
275 275
    s->nb_labels = 0;
......
407 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 412
    TCGContext *s = &tcg_ctx;
413 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 420
    if (idx != -1) {
418 421
        /* There is already an available temp with the
419 422
           right type */
420 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 425
        ts->temp_allocated = 1;
426
        assert(ts->temp_local == temp_local);
423 427
    } else {
424 428
        idx = s->nb_temps;
425 429
#if TCG_TARGET_REG_BITS == 32
......
429 433
            ts->base_type = type;
430 434
            ts->type = TCG_TYPE_I32;
431 435
            ts->temp_allocated = 1;
436
            ts->temp_local = temp_local;
432 437
            ts->name = NULL;
433 438
            ts++;
434 439
            ts->base_type = TCG_TYPE_I32;
435 440
            ts->type = TCG_TYPE_I32;
436 441
            ts->temp_allocated = 1;
442
            ts->temp_local = temp_local;
437 443
            ts->name = NULL;
438 444
            s->nb_temps += 2;
439 445
        } else
......
444 450
            ts->base_type = type;
445 451
            ts->type = type;
446 452
            ts->temp_allocated = 1;
453
            ts->temp_local = temp_local;
447 454
            ts->name = NULL;
448 455
            s->nb_temps++;
449 456
        }
......
456 463
    TCGContext *s = &tcg_ctx;
457 464
    TCGTemp *ts;
458 465
    int idx = GET_TCGV(arg);
459
    TCGType type;
466
    int k;
460 467

  
461 468
    assert(idx >= s->nb_globals && idx < s->nb_temps);
462 469
    ts = &s->temps[idx];
463 470
    assert(ts->temp_allocated != 0);
464 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 692
    if (idx < s->nb_globals) {
684 693
        pstrcpy(buf, buf_size, ts->name);
685 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 700
    return buf;
689 701
}
......
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 1008
    memset(dead_temps, 0, s->nb_globals);
994 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 1030
/* Liveness analysis : update the opc_dead_iargs array to tell if a
998 1031
   given input arguments is dead. Instructions updating dead
999 1032
   temporaries are removed. */
......
1366 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 1435
/* save globals to their cannonical location and assume they can be
1370 1436
   modified be the following code. 'allocated_regs' is used in case a
1371 1437
   temporary registers needs to be allocated to store a constant. */
1372 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 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 1453

  
1410 1454
    for(i = s->nb_globals; i < s->nb_temps; i++) {
1411 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 1466
    save_globals(s, allocated_regs);

Also available in: Unified diff