summaryrefslogtreecommitdiffstats
path: root/tcg/optimize.c
diff options
context:
space:
mode:
authorBlue Swirl <blauwirbel@gmail.com>2011-08-06 13:58:47 +0000
committerBlue Swirl <blauwirbel@gmail.com>2011-08-07 09:33:20 +0000
commite31b0a7c050711884ad570fe73df806520953618 (patch)
treed2268fd649f1f2a5e154276918c2e9c243ca9534 /tcg/optimize.c
parent97b348e7d221c94ddde609346407bd2cd6f85044 (diff)
downloadhqemu-e31b0a7c050711884ad570fe73df806520953618.zip
hqemu-e31b0a7c050711884ad570fe73df806520953618.tar.gz
TCG: fix copy propagation
Copy propagation introduced in 22613af4a6d9602001e6d0e7b6d98aa40aa018dc considered only global registers. However, register temps and stack allocated locals must be handled differently because register temps don't survive across brcond. Fix by propagating only within same class of temps. Tested-by: Stefan Weil <weil@mail.berlios.de> Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Diffstat (limited to 'tcg/optimize.c')
-rw-r--r--tcg/optimize.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/tcg/optimize.c b/tcg/optimize.c
index a3bfa5e..7eb5eb1 100644
--- a/tcg/optimize.c
+++ b/tcg/optimize.c
@@ -185,12 +185,15 @@ static int op_to_movi(int op)
}
}
-static void tcg_opt_gen_mov(TCGArg *gen_args, TCGArg dst, TCGArg src,
- int nb_temps, int nb_globals)
+static void tcg_opt_gen_mov(TCGContext *s, TCGArg *gen_args, TCGArg dst,
+ TCGArg src, int nb_temps, int nb_globals)
{
reset_temp(dst, nb_temps, nb_globals);
assert(temps[src].state != TCG_TEMP_COPY);
- if (src >= nb_globals) {
+ /* Don't try to copy if one of temps is a global or either one
+ is local and another is register */
+ if (src >= nb_globals && dst >= nb_globals &&
+ tcg_arg_is_local(s, src) == tcg_arg_is_local(s, dst)) {
assert(temps[src].state != TCG_TEMP_CONST);
if (temps[src].state != TCG_TEMP_HAS_COPY) {
temps[src].state = TCG_TEMP_HAS_COPY;
@@ -474,7 +477,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
gen_opc_buf[op_index] = INDEX_op_nop;
} else {
gen_opc_buf[op_index] = op_to_mov(op);
- tcg_opt_gen_mov(gen_args, args[0], args[1],
+ tcg_opt_gen_mov(s, gen_args, args[0], args[1],
nb_temps, nb_globals);
gen_args += 2;
args += 3;
@@ -500,7 +503,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
gen_opc_buf[op_index] = INDEX_op_nop;
} else {
gen_opc_buf[op_index] = op_to_mov(op);
- tcg_opt_gen_mov(gen_args, args[0], args[1], nb_temps,
+ tcg_opt_gen_mov(s, gen_args, args[0], args[1], nb_temps,
nb_globals);
gen_args += 2;
args += 3;
@@ -523,7 +526,7 @@ static TCGArg *tcg_constant_folding(TCGContext *s, uint16_t *tcg_opc_ptr,
break;
}
if (temps[args[1]].state != TCG_TEMP_CONST) {
- tcg_opt_gen_mov(gen_args, args[0], args[1],
+ tcg_opt_gen_mov(s, gen_args, args[0], args[1],
nb_temps, nb_globals);
gen_args += 2;
args += 2;
OpenPOWER on IntegriCloud