@@ -1021,7 +1021,194 @@
#endif
tdefs++;
}
+}
+static void tcg_const_analysis(TCGContext *s)
+{
+ int nb_cargs, nb_iargs, nb_oargs, dest, src, src2, del_args, i;
+ TCGArg *args;
+ uint16_t op;
+ uint16_t *opc_ptr;
+ const TCGOpDef *def;
+ uint8_t *const_temps;
+ tcg_target_ulong *temp_values;
+ tcg_target_ulong val, mask;
+ tcg_target_ulong dest_val, src_val, src2_val;
+
+ const_temps = tcg_malloc(s->nb_temps);
+ memset(const_temps, 0, s->nb_temps);
+ temp_values = tcg_malloc(s->nb_temps * sizeof(uint32_t));
+
+ opc_ptr = gen_opc_buf;
+ args = gen_opparam_buf;
+ while (opc_ptr < gen_opc_ptr) {
+ op = *opc_ptr;
+ def = &tcg_op_defs[op];
+ nb_oargs = def->nb_oargs;
+ nb_iargs = def->nb_iargs;
+ nb_cargs = def->nb_cargs;
+ del_args = 0;
+ mask = ~((tcg_target_ulong)0);
+
+ switch(op) {
+ case INDEX_op_movi_i32:
+#if TCG_TARGET_REG_BITS == 64
+ case INDEX_op_movi_i64:
+#endif
+ dest = args[0];
+ val = args[1];
+ const_temps[dest] = 1;
+ temp_values[dest] = val;
+ break;
+ case INDEX_op_mov_i32:
+#if TCG_TARGET_REG_BITS == 64
+ case INDEX_op_mov_i64:
+#endif
+ dest = args[0];
+ src = args[1];
+ const_temps[dest] = const_temps[src];
+ temp_values[dest] = temp_values[src];
+ break;
+ case INDEX_op_not_i32:
+#if TCG_TARGET_REG_BITS == 64
+ mask = 0xffffffff;
+ case INDEX_op_not_i64:
+#endif
+ dest = args[0];
+ src = args[1];
+ if (const_temps[src]) {
+ const_temps[dest] = 1;
+ dest_val = ~temp_values[src];
+ *opc_ptr = INDEX_op_movi_i32;
+ args[1] = temp_values[dest] = dest_val & mask;
+ } else {
+ const_temps[dest] = 0;
+ }
+ break;
+ case INDEX_op_add_i32:
+ case INDEX_op_sub_i32:
+ case INDEX_op_mul_i32:
+ case INDEX_op_and_i32:
+ case INDEX_op_or_i32:
+ case INDEX_op_xor_i32:
+ case INDEX_op_shl_i32:
+ case INDEX_op_shr_i32:
+#if TCG_TARGET_REG_BITS == 64
+ mask = 0xffffffff;
+ case INDEX_op_add_i64:
+ case INDEX_op_sub_i64:
+ case INDEX_op_mul_i64:
+ case INDEX_op_and_i64:
+ case INDEX_op_or_i64:
+ case INDEX_op_xor_i64:
+ case INDEX_op_shl_i64:
+ case INDEX_op_shr_i64:
+#endif
+
+ dest = args[0];
+ src = args[1];
+ src2 = args[2];
+ if (const_temps[src] && const_temps[src2]) {
+ src_val = temp_values[src];
+ src2_val = temp_values[src2];
+ const_temps[dest] = 1;
+ switch (op) {
+ case INDEX_op_add_i32:
+ dest_val = src_val + src2_val;
+ break;
+ case INDEX_op_add_i64:
+ dest_val = (src_val + src2_val) & mask;
+ break;
+ case INDEX_op_sub_i32:
+ dest_val = src_val - src2_val;
+ break;
+ case INDEX_op_sub_i64:
+ dest_val = (src_val - src2_val) & mask;
+ break;
+ case INDEX_op_mul_i32:
+ dest_val = src_val * src2_val;
+ break;
+ case INDEX_op_mul_i64:
+ dest_val = (src_val * src2_val) & mask;
+ break;
+ case INDEX_op_and_i32:
+ dest_val = src_val & src2_val;
+ break;
+ case INDEX_op_and_i64:
+ dest_val = src_val & src2_val & mask;
+ break;
+ case INDEX_op_or_i32:
+ dest_val = src_val | src2_val;
+ break;
+ case INDEX_op_or_i64:
+ dest_val = (src_val | src2_val) & mask;
+ break;
+ case INDEX_op_xor_i32:
+ dest_val = src_val ^ src2_val;
+ break;
+ case INDEX_op_xor_i64:
+ dest_val = (src_val ^ src2_val) & mask;
+ break;
+ case INDEX_op_shl_i32:
+ dest_val = src_val << src2_val;
+ break;
+ case INDEX_op_shl_i64:
+ dest_val = (src_val << src2_val) & mask;
+ break;
+ case INDEX_op_shr_i32:
+ dest_val = src_val >> src2_val;
+ break;
+ case INDEX_op_shr_i64:
+ dest_val = (src_val >> src2_val) & mask;
+ break;
+ default:
+ fprintf(stderr,"index op %i\n",op);
+ tcg_abort();
+ return;
+ }
+ *opc_ptr = INDEX_op_movi_i32;
+ args[1] = temp_values[dest] = dest_val & mask;
+ del_args = 1;
+ } else {
+ const_temps[dest] = 0;
+ }
+ break;
+ case INDEX_op_call:
+ nb_oargs = args[0] >> 16;
+ nb_iargs = args[0] & 0xffff;
+ nb_cargs = def->nb_cargs;
+ args++;
+ for (i = 0; i < nb_oargs; i++) {
+ const_temps[args[i]] = 0;
+ }
+ break;
+ case INDEX_op_nopn:
+ /* variable number of arguments */
+ nb_cargs = args[0];
+ break;
+ case INDEX_op_set_label:
+ memset(const_temps, 0, s->nb_temps);
+ break;
+ default:
+ if (def->flags & TCG_OPF_BB_END) {
+ memset(const_temps, 0, s->nb_temps);
+ } else {
+ for (i = 0; i < nb_oargs; i++) {
+ const_temps[args[i]] = 0;
+ }
+ }
+ break;
+ }
+ opc_ptr++;
+ args += nb_iargs + nb_oargs + nb_cargs - del_args;
+ if (del_args > 0) {
+ gen_opparam_ptr -= del_args;
+ memmove(args, args + del_args, (gen_opparam_ptr - args) * sizeof(*args));
+ }
+ }
+
+ if (args != gen_opparam_ptr)
+ tcg_abort();
}
#ifdef USE_LIVENESS_ANALYSIS
@@ -1891,6 +2078,8 @@
}
#endif
+ tcg_const_analysis(s);
+
#ifdef CONFIG_PROFILER
s->la_time -= profile_getclock();
#endif