#include "mini.h"
-extern guint8 mono_burg_arity [];
-
#define USE_ORIGINAL_VARS
#define CREATE_PRUNED_SSA
arity = mono_burg_arity [inst->opcode];
- if ((inst->ssa_op == MONO_SSA_LOAD || inst->ssa_op == MONO_SSA_MAYBE_LOAD) &&
+ if ((inst->ssa_op == MONO_SSA_LOAD || inst->ssa_op == MONO_SSA_ADDRESS_TAKEN) &&
(inst->inst_i0->opcode == OP_LOCAL || inst->inst_i0->opcode == OP_ARG)) {
MonoInst *new_var;
int idx = inst->inst_i0->inst_c0;
{
MonoInst *inst, *new_var;
int i, j, idx;
- GList *tmp;
+ GSList *tmp;
MonoInst **new_stack;
#ifdef DEBUG_SSA
arity = mono_burg_arity [inst->opcode];
- if ((inst->ssa_op == MONO_SSA_LOAD || inst->ssa_op == MONO_SSA_MAYBE_LOAD || inst->ssa_op == MONO_SSA_STORE) &&
+ if ((inst->ssa_op == MONO_SSA_LOAD || inst->ssa_op == MONO_SSA_ADDRESS_TAKEN || inst->ssa_op == MONO_SSA_STORE) &&
(inst->inst_i0->opcode == OP_LOCAL || inst->inst_i0->opcode == OP_ARG)) {
MonoInst *new_var;
int idx = inst->inst_i0->inst_c0;
if (inst->ssa_op == MONO_SSA_STORE && inst->inst_i1->ssa_op == MONO_SSA_LOAD &&
inst->inst_i0->inst_c0 == inst->inst_i1->inst_i0->inst_c0) {
inst->ssa_op = MONO_SSA_NOP;
- inst->opcode = CEE_NOP;
+ inst->opcode = OP_NOP;
}
}
}
/* remove the phi functions */
- inst->opcode = CEE_NOP;
+ inst->opcode = OP_NOP;
inst->ssa_op = MONO_SSA_NOP;
}
}
MonoInst *inst;
} MonoVarUsageInfo;
-static void
+
+
+
+/*
+ * Returns TRUE if the tree can have side effects.
+ */
+static gboolean
analyze_dev_use (MonoCompile *cfg, MonoBasicBlock *bb, MonoInst *root, MonoInst *inst)
{
MonoMethodVar *info;
int i, idx, arity;
+ gboolean has_side_effects;
if (!inst)
- return;
+ return FALSE;
arity = mono_burg_arity [inst->opcode];
+ switch (inst->opcode) {
+#define ANALYZE_DEV_USE_SPECIFIC_OPS 1
+#define OPDEF(a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) case a1:
+#include "simple-cee-ops.h"
+#undef OPDEF
+#define MINI_OP(a1,a2) case a1:
+#include "simple-mini-ops.h"
+#undef MINI_OP
+#undef ANALYZE_DEV_USE_SPECIFIC_OPS
+ has_side_effects = FALSE;
+ break;
+ default:
+ has_side_effects = TRUE;
+ }
if ((inst->ssa_op == MONO_SSA_STORE) &&
(inst->inst_i0->opcode == OP_LOCAL /*|| inst->inst_i0->opcode == OP_ARG */)) {
}
}
- if ((inst->ssa_op == MONO_SSA_LOAD || inst->ssa_op == MONO_SSA_MAYBE_LOAD) &&
+ if ((inst->ssa_op == MONO_SSA_LOAD || inst->ssa_op == MONO_SSA_ADDRESS_TAKEN) &&
(inst->inst_i0->opcode == OP_LOCAL || inst->inst_i0->opcode == OP_ARG)) {
MonoVarUsageInfo *ui = mono_mempool_alloc (cfg->mempool, sizeof (MonoVarUsageInfo));
idx = inst->inst_i0->inst_c0;
} else {
if (arity) {
//if (inst->ssa_op != MONO_SSA_STORE)
- analyze_dev_use (cfg, bb, root, inst->inst_left);
+ if (analyze_dev_use (cfg, bb, root, inst->inst_left))
+ has_side_effects = TRUE;
if (arity > 1)
- analyze_dev_use (cfg, bb, root, inst->inst_right);
+ if (analyze_dev_use (cfg, bb, root, inst->inst_right))
+ has_side_effects = TRUE;
}
}
+
+ return has_side_effects;
}
//mono_print_tree (u); printf ("\n");
- inst->opcode = CEE_NOP;
+ inst->opcode = OP_NOP;
inst->ssa_op = MONO_SSA_NOP;
}
}
i2->def = inst;
i1->def = NULL;
i1->uses = NULL;
- next->opcode = CEE_NOP;
+ next->opcode = OP_NOP;
next->ssa_op = MONO_SSA_NOP;
}
}
for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
MonoInst *inst;
for (inst = bb->code; inst; inst = inst->next) {
- analyze_dev_use (cfg, bb, inst, inst);
+ gboolean has_side_effects = analyze_dev_use (cfg, bb, inst, inst);
+ if (has_side_effects && (inst->ssa_op == MONO_SSA_STORE) &&
+ (inst->inst_i0->opcode == OP_LOCAL || inst->inst_i0->opcode == OP_ARG)) {
+ inst->inst_i0->flags |= MONO_INST_DEFINITION_HAS_SIDE_EFFECTS;
+ }
}
}
if (target) {
bb->out_bb [0] = target;
bb->out_count = 1;
- inst->opcode = CEE_BR;
+ inst->opcode = OP_BR;
inst->inst_target_bb = target;
}
} else if (inst->opcode == CEE_SWITCH && (evaluate_const_tree (cfg, inst->inst_left, &a, carray) == 1) && (a >= 0) && (a < GPOINTER_TO_INT (inst->klass))) {
bb->out_bb [0] = inst->inst_many_bb [a];
bb->out_count = 1;
inst->inst_target_bb = bb->out_bb [0];
- inst->opcode = CEE_BR;
+ inst->opcode = OP_BR;
}
}
}
}
}
+ } else if (inst->opcode == OP_BR) {
+ MonoBasicBlock *target = inst->inst_target_bb;
+
+ if (!(target->flags & BB_REACHABLE)) {
+ target->flags |= BB_REACHABLE;
+ *bblist = g_list_prepend (*bblist, target);
+ }
} else if ((inst->opcode >= CEE_BEQ && inst->opcode <= CEE_BLT_UN) &&
((inst->inst_i0->opcode == OP_COMPARE) || (inst->inst_i0->opcode == OP_LCOMPARE))) {
int a, b, r1, r2;
for (i = 0; i < cfg->num_varinfo; i++) {
MonoMethodVar *info = cfg->vars [i];
work_list = g_list_prepend (work_list, info);
+
+ //if ((info->def != NULL) && (info->def->inst_i1->opcode != OP_PHI)) printf ("SSA DEADCE TOTAL LOCAL\n");
}
while (work_list) {
MonoMethodVar *info = (MonoMethodVar *)work_list->data;
work_list = g_list_delete_link (work_list, work_list);
- if (!info->uses && info->def && (!(cfg->varinfo [info->idx]->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT)))) {
+ if (!info->uses && info->def && (!(cfg->varinfo [info->idx]->flags & (MONO_INST_DEFINITION_HAS_SIDE_EFFECTS|MONO_INST_VOLATILE|MONO_INST_INDIRECT)))) {
MonoInst *i1;
//printf ("ELIMINATE %s: ", mono_method_full_name (cfg->method, TRUE)); mono_print_tree (info->def); printf ("\n");
MonoMethodVar *u = cfg->vars [i1->inst_i0->inst_c0];
add_to_dce_worklist (cfg, info, u, &work_list);
}
+ //if (i1->opcode != OP_PHI) printf ("SSA DEADCE DEAD LOCAL\n");
- info->def->opcode = CEE_NOP;
+ info->def->opcode = OP_NOP;
info->def->ssa_op = MONO_SSA_NOP;
}