* Paolo Molaro (lupus@ximian.com)
*
* (C) 2003 Ximian, Inc.
+ * Copyright 2011 Xamarin, Inc (http://www.xamarin.com)
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
*/
#include <string.h>
#include <mono/metadata/debug-helpers.h>
#ifndef DISABLE_JIT
-//#define DEBUG_DOMINATORS
-
/*
* bb->dfn == 0 means either the bblock is ignored by the dfn calculation, or
* it is the entry bblock.
compute_dominators (MonoCompile *cfg)
{
int bindex, i, bitsize;
- char* mem;
MonoBasicBlock *entry;
MonoBasicBlock **doms;
gboolean changed;
bitsize = mono_bitset_alloc_size (cfg->num_bblocks, 0);
- mem = mono_mempool_alloc0 (cfg->mempool, bitsize * cfg->num_bblocks);
-
entry = cfg->bblocks [0];
doms = g_new0 (MonoBasicBlock*, cfg->num_bblocks);
doms [entry->dfn] = entry;
-#ifdef DEBUG_DOMINATORS
- for (i = 0; i < cfg->num_bblocks; ++i) {
- MonoBasicBlock *bb = cfg->bblocks [i];
+ if (cfg->verbose_level > 1) {
+ for (i = 0; i < cfg->num_bblocks; ++i) {
+ int j;
+ MonoBasicBlock *bb = cfg->bblocks [i];
- printf ("BB%d IN: ", bb->block_num);
- for (j = 0; j < bb->in_count; ++j)
- printf ("%d ", bb->in_bb [j]->block_num);
- printf ("\n");
+ printf ("BB%d IN: ", bb->block_num);
+ for (j = 0; j < bb->in_count; ++j)
+ printf ("%d ", bb->in_bb [j]->block_num);
+ printf ("\n");
+ }
}
-#endif
changed = TRUE;
while (changed) {
MonoBasicBlock *bb = cfg->bblocks [i];
MonoBasicBlock *cbb;
MonoBitSet *dominators;
+ char *mem;
+
+ mem = (char *)mono_mempool_alloc0 (cfg->mempool, bitsize);
bb->dominators = dominators = mono_bitset_mem_new (mem, cfg->num_bblocks, 0);
mem += bitsize;
cfg->comp_done |= MONO_COMP_DOM | MONO_COMP_IDOM;
-#ifdef DEBUG_DOMINATORS
- printf ("DTREE %s %d\n", mono_method_full_name (cfg->method, TRUE),
- mono_method_get_header (cfg->method)->num_clauses);
- for (i = 0; i < cfg->num_bblocks; ++i) {
- MonoBasicBlock *bb = cfg->bblocks [i];
- printf ("BB%d(dfn=%d) (IDOM=BB%d): ", bb->block_num, bb->dfn, bb->idom ? bb->idom->block_num : -1);
- mono_blockset_print (cfg, bb->dominators, NULL, -1);
+ if (cfg->verbose_level > 1) {
+ printf ("DTREE %s %d\n", mono_method_full_name (cfg->method, TRUE),
+ cfg->header->num_clauses);
+ for (i = 0; i < cfg->num_bblocks; ++i) {
+ MonoBasicBlock *bb = cfg->bblocks [i];
+ printf ("BB%d(dfn=%d) (IDOM=BB%d): ", bb->block_num, bb->dfn, bb->idom ? bb->idom->block_num : -1);
+ mono_blockset_print (cfg, bb->dominators, NULL, -1);
+ }
}
-#endif
}
#if 0
cfg->bblocks [i]->flags &= ~BB_VISITED;
bitsize = mono_bitset_alloc_size (cfg->num_bblocks, 0);
- mem = mono_mempool_alloc0 (cfg->mempool, bitsize * cfg->num_bblocks);
+ mem = (char *)mono_mempool_alloc0 (cfg->mempool, bitsize * cfg->num_bblocks);
for (i = 0; i < cfg->num_bblocks; ++i) {
MonoBasicBlock *bb = cfg->bblocks [i];
compute_dominance_frontier (cfg);
}
-//#define DEBUG_NATURAL_LOOPS
-
/*
* code to detect loops and loop nesting level
*/
for (j = 0; j < n->out_count; j++) {
MonoBasicBlock *h = n->out_bb [j];
+ /* check for single block loops */
+ if (n == h) {
+ h->loop_blocks = g_list_prepend_mempool (cfg->mempool, h->loop_blocks, h);
+ h->nesting++;
+ }
/* check for back-edge from n to h */
- if (n != h && mono_bitset_test_fast (n->dominators, h->dfn)) {
+ else if (n != h && mono_bitset_test_fast (n->dominators, h->dfn)) {
GSList *todo;
/* already in loop_blocks? */
GList *l;
for (l = h->loop_blocks; l; l = l->next) {
- MonoBasicBlock *b = l->data;
+ MonoBasicBlock *b = (MonoBasicBlock *)l->data;
if (b->dfn)
mono_bitset_set_fast (in_loop_blocks, b->dfn);
}
}
g_free (bb_indexes);
-#ifdef DEBUG_NATURAL_LOOPS
- for (i = 0; i < cfg->num_bblocks; ++i) {
- if (cfg->bblocks [i]->loop_blocks) {
- MonoBasicBlock *h = (MonoBasicBlock *)cfg->bblocks [i]->loop_blocks->data;
- GList *l;
- printf ("LOOP START %d\n", h->block_num);
- for (l = h->loop_blocks; l; l = l->next) {
- MonoBasicBlock *cb = (MonoBasicBlock *)l->data;
- printf (" BB%d %d %p\n", cb->block_num, cb->nesting, cb->loop_blocks);
+ if (cfg->verbose_level > 1) {
+ for (i = 0; i < cfg->num_bblocks; ++i) {
+ if (cfg->bblocks [i]->loop_blocks) {
+ MonoBasicBlock *h = (MonoBasicBlock *)cfg->bblocks [i]->loop_blocks->data;
+ GList *l;
+ printf ("LOOP START %d\n", h->block_num);
+ for (l = h->loop_blocks; l; l = l->next) {
+ MonoBasicBlock *cb = (MonoBasicBlock *)l->data;
+ printf ("\tBB%d %d %p\n", cb->block_num, cb->nesting, cb->loop_blocks);
+ }
}
}
}
-#endif
-
}
static void