First set of licensing changes
[mono.git] / mono / mini / dominators.c
index d5f334dc226cce0b4a580ad6b244ea95aef3343b..b4c8dc39056147e947786a6c25efdbeb80096296 100644 (file)
@@ -6,13 +6,17 @@
  *   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>
+#include <mono/metadata/mempool.h>
+#include <mono/metadata/mempool-internals.h>
 
 #include "mini.h"
 
-//#define DEBUG_DOMINATORS
+#ifndef DISABLE_JIT
 
 /*
  * bb->dfn == 0 means either the bblock is ignored by the dfn calculation, or
@@ -30,7 +34,6 @@ static void
 compute_dominators (MonoCompile *cfg)
 {
        int bindex, i, bitsize;
-       char* mem;
        MonoBasicBlock *entry;
        MonoBasicBlock **doms;
        gboolean changed;
@@ -39,23 +42,22 @@ compute_dominators (MonoCompile *cfg)
 
        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) {
@@ -114,6 +116,9 @@ compute_dominators (MonoCompile *cfg)
                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;
@@ -126,7 +131,7 @@ compute_dominators (MonoCompile *cfg)
 
                        bb->idom = doms [bb->dfn];
                        if (bb->idom)
-                               bb->idom->dominated = g_list_prepend (bb->idom->dominated, bb);
+                               bb->idom->dominated = g_slist_prepend_mempool (cfg->mempool, bb->idom->dominated, bb);
                }
 
                /* The entry bb */
@@ -137,17 +142,19 @@ compute_dominators (MonoCompile *cfg)
 
        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
+
 static void
 check_dominance_frontier (MonoBasicBlock *x, MonoBasicBlock *t)
 {
@@ -176,6 +183,8 @@ check_dominance_frontier (MonoBasicBlock *x, MonoBasicBlock *t)
        }
 } 
 
+#endif
+
 /**
  * Compute dominance frontiers using the algorithm from the same paper.
  */
@@ -191,7 +200,7 @@ compute_dominance_frontier (MonoCompile *cfg)
                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];
@@ -254,7 +263,7 @@ df_set (MonoCompile *m, MonoBitSet* dest, MonoBitSet *set)
        int i;
 
        mono_bitset_foreach_bit (set, i, m->num_bblocks) {
-               mono_bitset_union (dest, m->bblocks [i]->dfrontier);
+               mono_bitset_union_fast (dest, m->bblocks [i]->dfrontier);
        }
 }
 
@@ -287,8 +296,6 @@ mono_compile_dominator_info (MonoCompile *cfg, int dom_flags)
                compute_dominance_frontier (cfg);
 }
 
-//#define DEBUG_NATURAL_LOOPS
-
 /*
  * code to detect loops and loop nesting level
  */
@@ -307,8 +314,13 @@ mono_compute_natural_loops (MonoCompile *cfg)
 
                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? */
@@ -321,7 +333,7 @@ mono_compute_natural_loops (MonoCompile *cfg)
                                        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);
                                        }
@@ -335,7 +347,7 @@ mono_compute_natural_loops (MonoCompile *cfg)
                                        if ((cb->dfn && mono_bitset_test_fast (in_loop_blocks, cb->dfn)) || (!cb->dfn && g_list_find (h->loop_blocks, cb)))
                                                continue;
 
-                                       h->loop_blocks = g_list_prepend (h->loop_blocks, cb);
+                                       h->loop_blocks = g_list_prepend_mempool (cfg->mempool, h->loop_blocks, cb);
                                        cb->nesting++;
                                        if (cb->dfn)
                                                mono_bitset_set_fast (in_loop_blocks, cb->dfn);
@@ -351,7 +363,7 @@ mono_compute_natural_loops (MonoCompile *cfg)
 
                                /* add the header if not already there */
                                if (!((h->dfn && mono_bitset_test_fast (in_loop_blocks, h->dfn)) || (!h->dfn && g_list_find (h->loop_blocks, h)))) {
-                                       h->loop_blocks = g_list_prepend (h->loop_blocks, h);
+                                       h->loop_blocks = g_list_prepend_mempool (cfg->mempool, h->loop_blocks, h);
                                        h->nesting++;
                                }
                        }
@@ -391,20 +403,19 @@ mono_compute_natural_loops (MonoCompile *cfg)
        }
        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
@@ -414,7 +425,6 @@ clear_idominators (MonoCompile *cfg)
     
        for (i = 0; i < cfg->num_bblocks; ++i) {
                if (cfg->bblocks[i]->dominated) {
-                       g_list_free (cfg->bblocks[i]->dominated);        
                        cfg->bblocks[i]->dominated = NULL;
                }
        }
@@ -429,10 +439,7 @@ clear_loops (MonoCompile *cfg)
     
        for (i = 0; i < cfg->num_bblocks; ++i) {
                cfg->bblocks[i]->nesting = 0;
-               if (cfg->bblocks[i]->loop_blocks) {
-                       g_list_free (cfg->bblocks[i]->loop_blocks);        
-                       cfg->bblocks[i]->loop_blocks = NULL;
-               }
+               cfg->bblocks[i]->loop_blocks = NULL;
        }
 
        cfg->comp_done &= ~MONO_COMP_LOOPS;   
@@ -446,3 +453,12 @@ mono_free_loop_info (MonoCompile *cfg)
     if (cfg->comp_done & MONO_COMP_LOOPS)
         clear_loops (cfg);
 }
+
+#else /* DISABLE_JIT */
+
+void
+mono_free_loop_info (MonoCompile *cfg)
+{
+}
+
+#endif /* DISABLE_JIT */