@@ -48,6 +48,9 @@ typedef struct OptContext {
TCGContext *tcg;
TCGOp *prev_mb;
TCGTempSet temps_used;
+
+ /* In flight values from optimization. */
+ uint64_t z_mask;
} OptContext;
static inline TempOptInfo *ts_info(TCGTemp *ts)
@@ -629,6 +632,34 @@ static void copy_propagate(OptContext *ctx, TCGOp *op,
}
}
+static void finish_folding(OptContext *ctx, TCGOp *op)
+{
+ const TCGOpDef *def = &tcg_op_defs[op->opc];
+ int i, nb_oargs;
+
+ /*
+ * For an opcode that ends a BB, reset all temp data.
+ * We do no cross-BB optimization.
+ */
+ if (def->flags & TCG_OPF_BB_END) {
+ memset(&ctx->temps_used, 0, sizeof(ctx->temps_used));
+ ctx->prev_mb = NULL;
+ return;
+ }
+
+ nb_oargs = def->nb_oargs;
+ for (i = 0; i < nb_oargs; i++) {
+ reset_temp(op->args[i]);
+ /*
+ * Save the corresponding known-zero bits mask for the
+ * first output argument (only one supported so far).
+ */
+ if (i == 0) {
+ arg_info(op->args[i])->z_mask = ctx->z_mask;
+ }
+ }
+}
+
static bool fold_call(OptContext *ctx, TCGOp *op)
{
TCGContext *s = ctx->tcg;
@@ -1122,6 +1153,7 @@ void tcg_optimize(TCGContext *s)
partmask &= 0xffffffffu;
affected &= 0xffffffffu;
}
+ ctx.z_mask = z_mask;
if (partmask == 0) {
tcg_opt_gen_movi(&ctx, op, op->args[0], 0);
@@ -1570,22 +1602,7 @@ void tcg_optimize(TCGContext *s)
break;
}
- /* Some of the folding above can change opc. */
- opc = op->opc;
- def = &tcg_op_defs[opc];
- if (def->flags & TCG_OPF_BB_END) {
- memset(&ctx.temps_used, 0, sizeof(ctx.temps_used));
- } else {
- int nb_oargs = def->nb_oargs;
- for (i = 0; i < nb_oargs; i++) {
- reset_temp(op->args[i]);
- /* Save the corresponding known-zero bits mask for the
- first output argument (only one supported so far). */
- if (i == 0) {
- arg_info(op->args[i])->z_mask = z_mask;
- }
- }
- }
+ finish_folding(&ctx, op);
/* Eliminate duplicate and redundant fence instructions. */
if (ctx.prev_mb) {