Author: leo
Date: Thu Aug 11 04:26:39 2005
New Revision: 8913

Modified:
   trunk/imcc/cfg.c
Log:
Re: [perl #36597] [PATCH]Dominance Frontiers

This patch adds a bb_remove_edge() function, and decouples unreachable blocks
from the CFG by removing their successor edges.
-----

I think this is the best way to handle unreachable blocks in the CFG,
other than removing them, which is an -O1 optimization.

[ changed fprintf to IMCC_debug --leo ]

Courtesy of Curtis Rawls <[EMAIL PROTECTED]>


Modified: trunk/imcc/cfg.c
==============================================================================
--- trunk/imcc/cfg.c    (original)
+++ trunk/imcc/cfg.c    Thu Aug 11 04:26:39 2005
@@ -27,6 +27,7 @@ static void init_basic_blocks(IMC_Unit *
 static void analyse_life_symbol(Parrot_Interp, IMC_Unit *, SymReg*);
 static void analyse_life_block(Parrot_Interp, Basic_block*, SymReg*);
 static void bb_add_edge(IMC_Unit *, Basic_block*, Basic_block*);
+static void bb_remove_edge(IMC_Unit *, Edge*);
 static Basic_block* make_basic_block(Interp *, IMC_Unit *, Instruction*);
 
 /* Code: */
@@ -238,13 +239,13 @@ bb_check_newsub(Parrot_Interp interprete
             }
     }
 }
+
 /* Once the basic blocks have been computed, build_cfg computes
    the dependencies between them. */
-
 void
 build_cfg(Parrot_Interp interpreter, IMC_Unit * unit)
 {
-    int i, j;
+    int i, j, changes;
     SymReg * addr;
     Basic_block *last = NULL, *bb;
     Edge *pred;
@@ -343,6 +344,25 @@ invok:
         last = bb;
     }
 
+    /* Decouple unreachable blocks (not the first block, with no predecessors)
+     * from the CFG
+     */
+    do {
+        changes = 0;
+        for (i = 1; i < unit->n_basic_blocks; i++) {
+            bb = unit->bb_list[i];
+            if (!bb->pred_list) {
+                /* Remove all successor edges of block bb */
+                while (bb->succ_list) {
+                    bb_remove_edge(unit, bb->succ_list);
+                    IMCC_debug(interpreter, DEBUG_CFG,
+                            "remove edge from bb: %d\n", bb->index);
+                    changes = 1;
+                }
+            }
+        }
+    } while (changes);
+
     if (IMCC_INFO(interpreter)->debug & DEBUG_CFG)
         dump_cfg(unit);
 }
@@ -423,6 +443,44 @@ bb_add_edge(IMC_Unit * unit, Basic_block
 }
 
 static void
+bb_remove_edge(IMC_Unit * unit, Edge * edge)
+{
+    Edge *prev;
+
+    if (edge->from->succ_list == edge) {
+        edge->from->succ_list = edge->succ_next;
+    } else {
+        for (prev = edge->from->succ_list; prev; prev = prev->succ_next) {
+            if (prev->succ_next == edge) {
+                prev->succ_next = edge->succ_next;
+            }
+        }
+    }
+
+    if (edge->to->pred_list == edge) {
+        edge->to->pred_list = edge->pred_next;
+    } else {
+        for (prev = edge->to->pred_list; prev; prev = prev->pred_next) {
+            if (prev->pred_next == edge) {
+                prev->pred_next = edge->pred_next;
+            }
+        }
+    }
+
+    if (unit->edge_list == edge) {
+        unit->edge_list = edge->next;
+       free(edge);
+    } else {
+        for (prev = unit->edge_list; prev; prev = prev->next) {
+            if (prev->next == edge) {
+                prev->next = edge->next;
+               free(edge);
+            }
+        }
+    }
+}
+
+static void
 free_edge(IMC_Unit * unit)
 {
     Edge *e, *next;
@@ -512,8 +570,8 @@ propagate_alias(Parrot_Interp interprete
                           !instruction_reads(ins, r1)) {
                        add_instruct_reads(interpreter, ins, r1);
                         any = 1;
-                   }
-                   else if (instruction_reads(ins, r1) &&
+                    }
+                    else if (instruction_reads(ins, r1) &&
                           !instruction_reads(ins, r0)) {
                        add_instruct_reads(interpreter, ins, r0);
                         any = 1;
@@ -796,7 +854,12 @@ compute_dominators (Parrot_Interp interp
     dominators[0] = set_make(n);
     set_add(dominators[0], 0);
     for (i = 1; i < n; i++) {
-        dominators[i] = set_make_full(n);
+        if (unit->bb_list[i]->pred_list) {
+            dominators[i] = set_make_full(n);
+        } else {
+            dominators[i] = set_make(n);
+            set_add(dominators[i], i);
+        }
     }
 
 #if USE_BFS
@@ -859,14 +922,14 @@ compute_dominators (Parrot_Interp interp
                         if (set_contains(dominators[runner], i)) {
                             wrong = 1;
                             break;
-                        } 
+                        }
                     }
                 }
-                if (!wrong) { 
+                if (!wrong) {
                     unit->idoms[b] = unit->bb_list[i]->index;
                     break;
                 }
-            }       
+            }
        }
    }
 

Reply via email to