#include "mini.h"
+#ifndef DISABLE_SSA
+
#define USE_ORIGINAL_VARS
#define CREATE_PRUNED_SSA
{
MonoInst *inst, *new_var;
int i, j, idx;
- GList *tmp;
+ GSList *tmp;
MonoInst **new_stack;
#ifdef DEBUG_SSA
printf ("RENAME VARS BB%d %s\n", bb->block_num, mono_method_full_name (cfg->method, TRUE));
#endif
- for (inst = bb->code; inst; inst = inst->next) {
+ MONO_BB_FOR_EACH_INS (bb, inst) {
if (inst->opcode != OP_PHI)
replace_usage (cfg, bb, inst, stack);
inst->inst_i0 = new_var;
#ifdef USE_ORIGINAL_VARS
- cfg->vars [new_var->inst_c0]->reg = idx;
+ MONO_VARINFO (cfg, new_var->inst_c0)->reg = idx;
#endif
stack [idx] = new_var;
if (n->in_bb [j] == bb)
break;
- for (inst = n->code; inst; inst = inst->next) {
+ MONO_BB_FOR_EACH_INS (n, inst) {
if (inst->ssa_op == MONO_SSA_STORE && inst->inst_i1->opcode == OP_PHI) {
idx = inst->inst_i1->inst_c0;
if (stack [idx])
mono_bitset_set (vinfo [i].def_in, 0);
}
for (i = 0; i < cfg->num_bblocks; ++i) {
- for (inst = cfg->bblocks [i]->code; inst; inst = inst->next) {
+ MONO_BB_FOR_EACH_INS (cfg->bblocks [i], inst) {
if (inst->ssa_op == MONO_SSA_STORE) {
idx = inst->inst_i0->inst_c0;
g_assert (idx < cfg->num_varinfo);
store->inst_i1 = inst;
store->klass = store->inst_i0->klass;
- store->next = bb->code;
- bb->code = store;
- if (!bb->last_ins)
- bb->last_ins = bb->code;
+ MONO_INST_LIST_ADD (&store->node, &bb->ins_list);
#ifdef DEBUG_SSA
printf ("ADD PHI BB%d %s\n", cfg->bblocks [idx]->block_num, mono_method_full_name (cfg->method, TRUE));
(inst->inst_i0->opcode == OP_LOCAL || inst->inst_i0->opcode == OP_ARG)) {
MonoInst *new_var;
int idx = inst->inst_i0->inst_c0;
- MonoMethodVar *mv = cfg->vars [idx];
+ MonoMethodVar *mv = MONO_VARINFO (cfg, idx);
if (mv->reg != -1 && mv->reg != mv->idx) {
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;
}
}
for (i = 0; i < cfg->num_bblocks; ++i) {
MonoBasicBlock *bb = cfg->bblocks [i];
- for (inst = bb->code; inst; inst = inst->next) {
+ MONO_BB_FOR_EACH_INS (bb, inst) {
if (inst->ssa_op == MONO_SSA_STORE && inst->inst_i1->opcode == OP_PHI) {
phi = inst->inst_i1;
for (j = 0; j < bb->in_count; j++) {
MonoBasicBlock *pred = bb->in_bb [j];
int idx = phi->inst_phi_args [j + 1];
- MonoMethodVar *mv = cfg->vars [idx];
+ MonoMethodVar *mv = MONO_VARINFO (cfg, idx);
if (mv->reg != -1 && mv->reg != mv->idx) {
//printf ("PHICOPY %d %d -> %d\n", idx, mv->reg, inst->inst_i0->inst_c0);
}
/* remove the phi functions */
- inst->opcode = CEE_NOP;
+ inst->opcode = OP_NOP;
inst->ssa_op = MONO_SSA_NOP;
}
}
for (i = 0; i < cfg->num_bblocks; ++i) {
MonoBasicBlock *bb = cfg->bblocks [i];
- for (inst = bb->code; inst; inst = inst->next)
+ MONO_BB_FOR_EACH_INS (bb, inst)
mono_ssa_replace_copies (cfg, bb, inst, is_live);
}
for (i = 0; i < cfg->num_varinfo; ++i) {
- cfg->vars [i]->reg = -1;
- if (!is_live [i]) {
+ MONO_VARINFO (cfg, i)->reg = -1;
+ if (!is_live [i] && !(cfg->varinfo [i]->flags & MONO_INST_VOLATILE)) {
cfg->varinfo [i]->flags |= MONO_INST_IS_DEAD;
}
}
}
-#define IS_CALL(op) (op == CEE_CALLI || op == CEE_CALL || op == CEE_CALLVIRT || (op >= OP_VOIDCALL && op <= OP_CALL_MEMBASE))
+#define IS_CALL(op) (op == CEE_CALLI || op == OP_CALL || op == OP_CALLVIRT || (op >= OP_VOIDCALL && op <= OP_CALL_MEMBASE))
typedef struct {
MonoBasicBlock *bb;
if ((inst->ssa_op == MONO_SSA_STORE) &&
(inst->inst_i0->opcode == OP_LOCAL /*|| inst->inst_i0->opcode == OP_ARG */)) {
idx = inst->inst_i0->inst_c0;
- info = cfg->vars [idx];
+ info = MONO_VARINFO (cfg, idx);
//printf ("%d defined in BB%d %p\n", idx, bb->block_num, root);
if (info->def) {
g_warning ("more than one definition of variable %d in %s", idx,
for (i = inst->inst_i1->inst_phi_args [0]; i > 0; i--) {
MonoVarUsageInfo *ui = mono_mempool_alloc (cfg->mempool, sizeof (MonoVarUsageInfo));
idx = inst->inst_i1->inst_phi_args [i];
- info = cfg->vars [idx];
+ info = MONO_VARINFO (cfg, idx);
//printf ("FOUND %d\n", idx);
ui->bb = bb;
ui->inst = root;
(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;
- info = cfg->vars [idx];
+ info = MONO_VARINFO (cfg, idx);
//printf ("FOUND %d\n", idx);
ui->bb = bb;
ui->inst = root;
g_assert ((cfg->comp_done & MONO_COMP_SSA_DEF_USE));
for (bb = cfg->bb_entry; bb; bb = bb->next_bb) {
- for (inst = bb->code; inst; inst = inst->next) {
+ MONO_BB_FOR_EACH_INS (bb, inst) {
if (inst->ssa_op == MONO_SSA_STORE && inst->inst_i0->opcode == OP_LOCAL &&
!IS_CALL (inst->inst_i1->opcode) && inst->inst_i1->opcode != OP_PHI && !inst->flags) {
- i1 = cfg->vars [inst->inst_i0->inst_c0];
+ i1 = MONO_VARINFO (cfg, inst->inst_i0->inst_c0);
/* fixme: compiling mcs does not work when I enable this */
#if 0
//mono_print_tree (u); printf ("\n");
- inst->opcode = CEE_NOP;
+ inst->opcode = OP_NOP;
inst->ssa_op = MONO_SSA_NOP;
}
}
#endif
- if ((next = inst->next) && next->ssa_op == MONO_SSA_STORE && next->inst_i0->opcode == OP_LOCAL &&
- next->inst_i1->ssa_op == MONO_SSA_LOAD && next->inst_i1->inst_i0->opcode == OP_LOCAL &&
- next->inst_i1->inst_i0->inst_c0 == inst->inst_i0->inst_c0 && g_list_length (i1->uses) == 1 &&
- inst->opcode == next->opcode && inst->inst_i0->type == next->inst_i0->type) {
- i2 = cfg->vars [next->inst_i0->inst_c0];
+ next = mono_inst_list_next (&inst->node, &bb->ins_list);
+ if (next && next->ssa_op == MONO_SSA_STORE &&
+ next->inst_i0->opcode == OP_LOCAL &&
+ next->inst_i1->ssa_op == MONO_SSA_LOAD &&
+ next->inst_i1->inst_i0->opcode == OP_LOCAL &&
+ next->inst_i1->inst_i0->inst_c0 == inst->inst_i0->inst_c0 &&
+ g_list_length (i1->uses) == 1 &&
+ inst->opcode == next->opcode &&
+ inst->inst_i0->type == next->inst_i0->type) {
+ i2 = MONO_VARINFO (cfg, next->inst_i0->inst_c0);
//printf ("ELIM. COPY in BB%d %s\n", bb->block_num, mono_method_full_name (cfg->method, TRUE));
inst->inst_i0 = next->inst_i0;
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) {
+ MONO_BB_FOR_EACH_INS (bb, 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)) {
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))) {
+ } else if (inst->opcode == OP_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;
}
}
{
g_assert (inst);
- if (inst->opcode == CEE_SWITCH) {
+ if (inst->opcode == OP_SWITCH) {
int r1, i, a;
int cases = GPOINTER_TO_INT (inst->klass);
}
}
}
+ } 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;
}
} else if (inst->ssa_op == MONO_SSA_STORE &&
(inst->inst_i0->opcode == OP_LOCAL || inst->inst_i0->opcode == OP_ARG)) {
- MonoMethodVar *info = cfg->vars [inst->inst_i0->inst_c0];
+ MonoMethodVar *info = MONO_VARINFO (cfg, inst->inst_i0->inst_c0);
MonoInst *i1 = inst->inst_i1;
int res;
int j;
for (j = 1; j <= i1->inst_phi_args [0]; j++) {
- MonoMethodVar *mv = cfg->vars [i1->inst_phi_args [j]];
+ MonoMethodVar *mv = MONO_VARINFO (cfg, i1->inst_phi_args [j]);
MonoInst *src = mv->def;
if (mv->def_bb && !(mv->def_bb->flags & BB_REACHABLE)) {
memset (carray, 0, sizeof (MonoInst *) * cfg->num_varinfo);
for (i = 0; i < cfg->num_varinfo; i++) {
- MonoMethodVar *info = cfg->vars [i];
+ MonoMethodVar *info = MONO_VARINFO (cfg, i);
if (!info->def)
info->cpstate = 2;
}
}
}
- for (inst = bb->code; inst; inst = inst->next) {
+ MONO_BB_FOR_EACH_INS (bb, inst)
visit_inst (cfg, bb, inst, &cvars, &bblock_list, carray);
- }
while (cvars) {
MonoMethodVar *info = (MonoMethodVar *)cvars->data;
for (bb = cfg->bb_entry->next_bb; bb; bb = bb->next_bb) {
MonoInst *inst;
- for (inst = bb->code; inst; inst = inst->next) {
+ MONO_BB_FOR_EACH_INS (bb, inst)
fold_tree (cfg, bb, inst, carray);
- }
}
g_free (carray);
/* fixme: we should update usage infos during cprop, instead of computing it again */
cfg->comp_done &= ~MONO_COMP_SSA_DEF_USE;
for (i = 0; i < cfg->num_varinfo; i++) {
- MonoMethodVar *info = cfg->vars [i];
+ MonoMethodVar *info = MONO_VARINFO (cfg, i);
info->def = NULL;
info->uses = NULL;
}
work_list = NULL;
for (i = 0; i < cfg->num_varinfo; i++) {
- MonoMethodVar *info = cfg->vars [i];
+ MonoMethodVar *info = MONO_VARINFO (cfg, 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");
if (i1->opcode == OP_PHI) {
int j;
for (j = i1->inst_phi_args [0]; j > 0; j--) {
- MonoMethodVar *u = cfg->vars [i1->inst_phi_args [j]];
+ MonoMethodVar *u = MONO_VARINFO (cfg, i1->inst_phi_args [j]);
add_to_dce_worklist (cfg, info, u, &work_list);
}
} else if (i1->ssa_op == MONO_SSA_LOAD &&
(i1->inst_i0->opcode == OP_LOCAL || i1->inst_i0->opcode == OP_ARG)) {
- MonoMethodVar *u = cfg->vars [i1->inst_i0->inst_c0];
+ MonoMethodVar *u = MONO_VARINFO (cfg, 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;
}
continue;
for (i = 0; i < cfg->num_varinfo; i++) {
- MonoMethodVar *info = cfg->vars [i];
+ MonoMethodVar *info = MONO_VARINFO (cfg, i);
if (info->def && info->def->ssa_op == MONO_SSA_STORE &&
info->def->inst_i0->opcode == OP_LOCAL && g_list_find (lp, info->def_bb)) {
}
}
#endif
+
+#endif /* DISABLE_SSA */
+