Revision 866cb6cb

b/tcg/tcg.c
1193 1193
    }
1194 1194
}
1195 1195

  
1196
/* Liveness analysis : update the opc_dead_iargs array to tell if a
1196
/* Liveness analysis : update the opc_dead_args array to tell if a
1197 1197
   given input arguments is dead. Instructions updating dead
1198 1198
   temporaries are removed. */
1199 1199
static void tcg_liveness_analysis(TCGContext *s)
......
1203 1203
    TCGArg *args;
1204 1204
    const TCGOpDef *def;
1205 1205
    uint8_t *dead_temps;
1206
    unsigned int dead_iargs;
1206
    unsigned int dead_args;
1207 1207
    
1208 1208
    gen_opc_ptr++; /* skip end */
1209 1209

  
1210 1210
    nb_ops = gen_opc_ptr - gen_opc_buf;
1211 1211

  
1212
    s->op_dead_iargs = tcg_malloc(nb_ops * sizeof(uint16_t));
1212
    s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1213 1213
    
1214 1214
    dead_temps = tcg_malloc(s->nb_temps);
1215 1215
    memset(dead_temps, 1, s->nb_temps);
......
1256 1256
                    }
1257 1257

  
1258 1258
                    /* input args are live */
1259
                    dead_iargs = 0;
1260
                    for(i = 0; i < nb_iargs; i++) {
1261
                        arg = args[i + nb_oargs];
1259
                    dead_args = 0;
1260
                    for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
1261
                        arg = args[i];
1262 1262
                        if (arg != TCG_CALL_DUMMY_ARG) {
1263 1263
                            if (dead_temps[arg]) {
1264
                                dead_iargs |= (1 << i);
1264
                                dead_args |= (1 << i);
1265 1265
                            }
1266 1266
                            dead_temps[arg] = 0;
1267 1267
                        }
1268 1268
                    }
1269
                    s->op_dead_iargs[op_index] = dead_iargs;
1269
                    s->op_dead_args[op_index] = dead_args;
1270 1270
                }
1271 1271
                args--;
1272 1272
            }
......
1327 1327
                }
1328 1328

  
1329 1329
                /* input args are live */
1330
                dead_iargs = 0;
1331
                for(i = 0; i < nb_iargs; i++) {
1332
                    arg = args[i + nb_oargs];
1330
                dead_args = 0;
1331
                for(i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1332
                    arg = args[i];
1333 1333
                    if (dead_temps[arg]) {
1334
                        dead_iargs |= (1 << i);
1334
                        dead_args |= (1 << i);
1335 1335
                    }
1336 1336
                    dead_temps[arg] = 0;
1337 1337
                }
1338
                s->op_dead_iargs[op_index] = dead_iargs;
1338
                s->op_dead_args[op_index] = dead_args;
1339 1339
            }
1340 1340
            break;
1341 1341
        }
......
1352 1352
    int nb_ops;
1353 1353
    nb_ops = gen_opc_ptr - gen_opc_buf;
1354 1354

  
1355
    s->op_dead_iargs = tcg_malloc(nb_ops * sizeof(uint16_t));
1356
    memset(s->op_dead_iargs, 0, nb_ops * sizeof(uint16_t));
1355
    s->op_dead_args = tcg_malloc(nb_ops * sizeof(uint16_t));
1356
    memset(s->op_dead_args, 0, nb_ops * sizeof(uint16_t));
1357 1357
}
1358 1358
#endif
1359 1359

  
......
1557 1557
    save_globals(s, allocated_regs);
1558 1558
}
1559 1559

  
1560
#define IS_DEAD_IARG(n) ((dead_iargs >> (n)) & 1)
1560
#define IS_DEAD_ARG(n) ((dead_args >> (n)) & 1)
1561 1561

  
1562 1562
static void tcg_reg_alloc_movi(TCGContext *s, const TCGArg *args)
1563 1563
{
......
1582 1582

  
1583 1583
static void tcg_reg_alloc_mov(TCGContext *s, const TCGOpDef *def,
1584 1584
                              const TCGArg *args,
1585
                              unsigned int dead_iargs)
1585
                              unsigned int dead_args)
1586 1586
{
1587 1587
    TCGTemp *ts, *ots;
1588 1588
    int reg;
......
1592 1592
    ts = &s->temps[args[1]];
1593 1593
    arg_ct = &def->args_ct[0];
1594 1594

  
1595
    /* XXX: always mark arg dead if IS_DEAD_IARG(0) */
1595
    /* XXX: always mark arg dead if IS_DEAD_ARG(1) */
1596 1596
    if (ts->val_type == TEMP_VAL_REG) {
1597
        if (IS_DEAD_IARG(0) && !ts->fixed_reg && !ots->fixed_reg) {
1597
        if (IS_DEAD_ARG(1) && !ts->fixed_reg && !ots->fixed_reg) {
1598 1598
            /* the mov can be suppressed */
1599 1599
            if (ots->val_type == TEMP_VAL_REG)
1600 1600
                s->reg_to_temp[ots->reg] = -1;
......
1642 1642
static void tcg_reg_alloc_op(TCGContext *s, 
1643 1643
                             const TCGOpDef *def, TCGOpcode opc,
1644 1644
                             const TCGArg *args,
1645
                             unsigned int dead_iargs)
1645
                             unsigned int dead_args)
1646 1646
{
1647 1647
    TCGRegSet allocated_regs;
1648 1648
    int i, k, nb_iargs, nb_oargs, reg;
......
1701 1701
                /* if the input is aliased to an output and if it is
1702 1702
                   not dead after the instruction, we must allocate
1703 1703
                   a new register and move it */
1704
                if (!IS_DEAD_IARG(i - nb_oargs)) 
1704
                if (!IS_DEAD_ARG(i)) {
1705 1705
                    goto allocate_in_reg;
1706
                }
1706 1707
            }
1707 1708
        }
1708 1709
        reg = ts->reg;
......
1725 1726
        tcg_reg_alloc_bb_end(s, allocated_regs);
1726 1727
    } else {
1727 1728
        /* mark dead temporaries and free the associated registers */
1728
        for(i = 0; i < nb_iargs; i++) {
1729
            arg = args[nb_oargs + i];
1730
            if (IS_DEAD_IARG(i)) {
1729
        for(i = nb_oargs; i < nb_oargs + nb_iargs; i++) {
1730
            arg = args[i];
1731
            if (IS_DEAD_ARG(i)) {
1731 1732
                ts = &s->temps[arg];
1732 1733
                if (!ts->fixed_reg) {
1733 1734
                    if (ts->val_type == TEMP_VAL_REG)
......
1808 1809

  
1809 1810
static int tcg_reg_alloc_call(TCGContext *s, const TCGOpDef *def,
1810 1811
                              TCGOpcode opc, const TCGArg *args,
1811
                              unsigned int dead_iargs)
1812
                              unsigned int dead_args)
1812 1813
{
1813 1814
    int nb_iargs, nb_oargs, flags, nb_regs, i, reg, nb_params;
1814 1815
    TCGArg arg, func_arg;
......
1930 1931
        
1931 1932
    
1932 1933
    /* mark dead temporaries and free the associated registers */
1933
    for(i = 0; i < nb_iargs; i++) {
1934
        arg = args[nb_oargs + i];
1935
        if (IS_DEAD_IARG(i)) {
1934
    for(i = nb_oargs; i < nb_iargs + nb_oargs; i++) {
1935
        arg = args[i];
1936
        if (IS_DEAD_ARG(i)) {
1936 1937
            ts = &s->temps[arg];
1937 1938
            if (!ts->fixed_reg) {
1938 1939
                if (ts->val_type == TEMP_VAL_REG)
......
2007 2008
    TCGOpcode opc;
2008 2009
    int op_index;
2009 2010
    const TCGOpDef *def;
2010
    unsigned int dead_iargs;
2011
    unsigned int dead_args;
2011 2012
    const TCGArg *args;
2012 2013

  
2013 2014
#ifdef DEBUG_DISAS
......
2058 2059
#if TCG_TARGET_REG_BITS == 64
2059 2060
        case INDEX_op_mov_i64:
2060 2061
#endif
2061
            dead_iargs = s->op_dead_iargs[op_index];
2062
            tcg_reg_alloc_mov(s, def, args, dead_iargs);
2062
            dead_args = s->op_dead_args[op_index];
2063
            tcg_reg_alloc_mov(s, def, args, dead_args);
2063 2064
            break;
2064 2065
        case INDEX_op_movi_i32:
2065 2066
#if TCG_TARGET_REG_BITS == 64
......
2095 2096
            tcg_out_label(s, args[0], (long)s->code_ptr);
2096 2097
            break;
2097 2098
        case INDEX_op_call:
2098
            dead_iargs = s->op_dead_iargs[op_index];
2099
            args += tcg_reg_alloc_call(s, def, opc, args, dead_iargs);
2099
            dead_args = s->op_dead_args[op_index];
2100
            args += tcg_reg_alloc_call(s, def, opc, args, dead_args);
2100 2101
            goto next;
2101 2102
        case INDEX_op_end:
2102 2103
            goto the_end;
......
2104 2105
            /* Note: in order to speed up the code, it would be much
2105 2106
               faster to have specialized register allocator functions for
2106 2107
               some common argument patterns */
2107
            dead_iargs = s->op_dead_iargs[op_index];
2108
            tcg_reg_alloc_op(s, def, opc, args, dead_iargs);
2108
            dead_args = s->op_dead_args[op_index];
2109
            tcg_reg_alloc_op(s, def, opc, args, dead_args);
2109 2110
            break;
2110 2111
        }
2111 2112
        args += def->nb_args;
b/tcg/tcg.h
286 286
    uint16_t *tb_jmp_offset; /* != NULL if USE_DIRECT_JUMP */
287 287

  
288 288
    /* liveness analysis */
289
    uint16_t *op_dead_iargs; /* for each operation, each bit tells if the
290
                                corresponding input argument is dead */
289
    uint16_t *op_dead_args; /* for each operation, each bit tells if the
290
                               corresponding argument is dead */
291 291
    
292 292
    /* tells in which temporary a given register is. It does not take
293 293
       into account fixed registers */

Also available in: Unified diff