Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[mono] Don't use recursion in mono_ssa_rename_vars #61677

Merged
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
208 changes: 133 additions & 75 deletions src/mono/mono/mini/ssa.c
Original file line number Diff line number Diff line change
Expand Up @@ -159,24 +159,47 @@ typedef struct {
int idx;
} RenameInfo;

/**
* mono_ssa_rename_vars:
* Implement renaming of SSA variables. Also compute def-use information in parallel.
* \p stack_history points to an area of memory which can be used for storing changes
* made to the stack, so they can be reverted later.
*/
static void
mono_ssa_rename_vars (MonoCompile *cfg, int max_vars, MonoBasicBlock *bb, gboolean *originals_used, MonoInst **stack, guint32 *lvreg_stack, gboolean *lvreg_defined, RenameInfo *stack_history, int stack_history_size)
rename_phi_arguments_in_out_bbs(MonoCompile *cfg, MonoBasicBlock *bb, MonoInst **stack)
{
MonoInst *ins, *new_var;
int i, j, idx;
GSList *tmp;
int stack_history_len = 0;
int i, j;

if (cfg->verbose_level >= 4)
printf ("\nRENAME VARS BLOCK %d:\n", bb->block_num);
for (i = 0; i < bb->out_count; i++) {
MonoBasicBlock *n = bb->out_bb [i];

for (j = 0; j < n->in_count; j++)
if (n->in_bb [j] == bb)
break;

for (ins = n->code; ins; ins = ins->next) {
if (MONO_IS_PHI (ins)) {
int idx = ins->inst_c0;
if (stack [idx])
new_var = stack [idx];
else
new_var = cfg->varinfo [idx];
#ifdef DEBUG_SSA
printf ("FOUND PHI %d (%d, %d)\n", idx, j, new_var->inst_c0);
#endif
ins->inst_phi_args [j + 1] = new_var->dreg;
record_use (cfg, new_var, n, ins);
if (G_UNLIKELY (cfg->verbose_level >= 4))
printf ("\tAdd PHI R%d <- R%d to BB%d\n", ins->dreg, new_var->dreg, n->block_num);
}
else
/* The phi nodes are at the beginning of the bblock */
break;
}
}
}

static int
create_new_vars (MonoCompile *cfg, int max_vars, MonoBasicBlock *bb, gboolean *originals_used, MonoInst **stack, guint32 *lvreg_stack, gboolean *lvreg_defined, RenameInfo **stack_history, int *stack_history_size)
{
MonoInst *ins, *new_var;
int i, stack_history_len = 0;

/* First pass: Create new vars */
for (ins = bb->code; ins; ins = ins->next) {
const char *spec = INS_INFO (ins->opcode);
int num_sregs;
Expand Down Expand Up @@ -233,21 +256,21 @@ mono_ssa_rename_vars (MonoCompile *cfg, int max_vars, MonoBasicBlock *bb, gboole
MonoMethodVar *info;

if (var && !(var->flags & (MONO_INST_VOLATILE|MONO_INST_INDIRECT))) {
idx = var->inst_c0;
int idx = var->inst_c0;
g_assert (idx < max_vars);

if (var->opcode == OP_ARG)
originals_used [idx] = TRUE;

if (stack_history_len + 128 > stack_history_size) {
stack_history_size += 1024;
RenameInfo *new_history = mono_mempool_alloc (cfg->mempool, sizeof (RenameInfo) * stack_history_size);
memcpy (new_history, stack_history, stack_history_len * sizeof (RenameInfo));
stack_history = new_history;
if (stack_history_len + 128 > *stack_history_size) {
*stack_history_size += 1024;
RenameInfo *new_history = mono_mempool_alloc (cfg->mempool, sizeof (RenameInfo) * *stack_history_size);
memcpy (new_history, *stack_history, stack_history_len * sizeof (RenameInfo));
*stack_history = new_history;
}

stack_history [stack_history_len].var = stack [idx];
stack_history [stack_history_len].idx = idx;
(*stack_history) [stack_history_len].var = stack [idx];
(*stack_history) [stack_history_len].idx = idx;
stack_history_len ++;

if (originals_used [idx]) {
Expand Down Expand Up @@ -284,49 +307,102 @@ mono_ssa_rename_vars (MonoCompile *cfg, int max_vars, MonoBasicBlock *bb, gboole
#ifdef DEBUG_SSA
printf ("\tAfter processing "); mono_print_ins (ins);
#endif
}

return stack_history_len;
}

static void
restore_stack (MonoInst **stack, RenameInfo *stack_history, int stack_history_len)
{
int i = stack_history_len;
while (i-- > 0) {
stack [stack_history [i].idx] = stack_history [i].var;
}
}

/* Rename PHI arguments in succeeding bblocks */
for (i = 0; i < bb->out_count; i++) {
MonoBasicBlock *n = bb->out_bb [i];
typedef struct {
GSList *blocks;
RenameInfo *history;
int size;
int len;
} RenameStackInfo;

for (j = 0; j < n->in_count; j++)
if (n->in_bb [j] == bb)
break;

for (ins = n->code; ins; ins = ins->next) {
if (MONO_IS_PHI (ins)) {
idx = ins->inst_c0;
if (stack [idx])
new_var = stack [idx];
else
new_var = cfg->varinfo [idx];
#ifdef DEBUG_SSA
printf ("FOUND PHI %d (%d, %d)\n", idx, j, new_var->inst_c0);
#endif
ins->inst_phi_args [j + 1] = new_var->dreg;
record_use (cfg, new_var, n, ins);
if (G_UNLIKELY (cfg->verbose_level >= 4))
printf ("\tAdd PHI R%d <- R%d to BB%d\n", ins->dreg, new_var->dreg, n->block_num);
/**
* mono_ssa_rename_vars:
* Implement renaming of SSA variables. Also compute def-use information in parallel.
* \p stack_history points to an area of memory which can be used for storing changes
* made to the stack, so they can be reverted later.
*/
static void
mono_ssa_rename_vars (MonoCompile *cfg, int max_vars, MonoBasicBlock *bb)
{
GSList *blocks = NULL;
RenameStackInfo* rename_stack;
int rename_stack_size, rename_stack_idx = 0;
RenameInfo *stack_history;
int stack_history_size;
gboolean *originals;
guint32 *lvreg_stack;
gboolean *lvreg_defined;
MonoInst **stack;

stack = g_newa (MonoInst*, cfg->num_varinfo);
memset (stack, 0, sizeof (MonoInst *) * cfg->num_varinfo);
lvreg_stack = g_new0 (guint32, cfg->next_vreg);
lvreg_defined = g_new0 (gboolean, cfg->next_vreg);
stack_history_size = 10240;
stack_history = g_new (RenameInfo, stack_history_size);
originals = g_new0 (gboolean, cfg->num_varinfo);
rename_stack_size = 16;
rename_stack = g_new (RenameStackInfo, rename_stack_size);

do {
if (G_UNLIKELY (cfg->verbose_level >= 4))
printf ("\nRENAME VARS BLOCK %d:\n", bb->block_num);

int stack_history_len = create_new_vars (cfg, max_vars, bb, originals, stack, lvreg_stack, lvreg_defined, &stack_history, &stack_history_size);
rename_phi_arguments_in_out_bbs (cfg, bb, stack);

if (bb->dominated) {
if (rename_stack_idx >= rename_stack_size - 1) {
rename_stack_size += MIN(rename_stack_size, 1024);
rename_stack = g_realloc(rename_stack, sizeof(RenameStackInfo)*rename_stack_size);
}
else
/* The phi nodes are at the beginning of the bblock */
break;
}
}

if (bb->dominated) {
for (tmp = bb->dominated; tmp; tmp = tmp->next) {
mono_ssa_rename_vars (cfg, max_vars, (MonoBasicBlock *)tmp->data, originals_used, stack, lvreg_stack, lvreg_defined, stack_history + stack_history_len, stack_history_size - stack_history_len);
RenameStackInfo* info = rename_stack + rename_stack_idx;
rename_stack_idx++;
info->blocks = blocks;
info->history = stack_history;
info->size = stack_history_size;
info->len = stack_history_len;
stack_history += stack_history_len;
stack_history_size -= stack_history_len;
blocks = bb->dominated;
} else {
restore_stack (stack, stack_history, stack_history_len);
blocks = blocks->next;

while (!blocks && rename_stack_idx > 0) {
rename_stack_idx--;
RenameStackInfo* info = rename_stack + rename_stack_idx;
blocks = info->blocks ? info->blocks->next : NULL;
stack_history = info->history;
stack_history_size = info->size;
stack_history_len = info->len;
restore_stack (stack, stack_history, stack_history_len);
}
}
}

/* Restore stack */
for (i = stack_history_len - 1; i >= 0; i--) {
stack [stack_history [i].idx] = stack_history [i].var;
}
if (blocks)
bb = (MonoBasicBlock*) blocks->data;
} while (blocks);

g_free (stack_history);
g_free (originals);
g_free (lvreg_stack);
g_free (lvreg_defined);
g_free (rename_stack);
cfg->comp_done |= MONO_COMP_SSA_DEF_USE;
}

Expand All @@ -336,13 +412,8 @@ mono_ssa_compute (MonoCompile *cfg)
int i, j, idx, bitsize;
MonoBitSet *set;
MonoMethodVar *vinfo = g_new0 (MonoMethodVar, cfg->num_varinfo);
MonoInst *ins, **stack;
MonoInst *ins;
guint8 *buf, *buf_start;
RenameInfo *stack_history;
int stack_history_size;
gboolean *originals;
guint32 *lvreg_stack;
gboolean *lvreg_defined;

g_assert (!(cfg->comp_done & MONO_COMP_SSA));

Expand Down Expand Up @@ -464,20 +535,7 @@ mono_ssa_compute (MonoCompile *cfg)
g_free (buf_start);

/* Renaming phase */

stack = g_newa (MonoInst*, cfg->num_varinfo);
memset (stack, 0, sizeof (MonoInst *) * cfg->num_varinfo);

lvreg_stack = g_new0 (guint32, cfg->next_vreg);
lvreg_defined = g_new0 (gboolean, cfg->next_vreg);
stack_history_size = 10240;
stack_history = g_new (RenameInfo, stack_history_size);
originals = g_new0 (gboolean, cfg->num_varinfo);
mono_ssa_rename_vars (cfg, cfg->num_varinfo, cfg->bb_entry, originals, stack, lvreg_stack, lvreg_defined, stack_history, stack_history_size);
g_free (stack_history);
g_free (originals);
g_free (lvreg_stack);
g_free (lvreg_defined);
mono_ssa_rename_vars (cfg, cfg->num_varinfo, cfg->bb_entry);

if (cfg->verbose_level >= 4)
printf ("\nEND COMPUTE SSA.\n\n");
Expand Down