Index: imcc/optimizer.c
===================================================================
--- imcc/optimizer.c	(revision 8937)
+++ imcc/optimizer.c	(working copy)
@@ -64,7 +64,7 @@
 /* buggy - turned off */
 #define  DO_LOOP_OPTIMIZATION 0
 
-static void if_branch(Interp *, IMC_Unit *);
+static int if_branch(Interp *, IMC_Unit *);
 
 static int branch_branch(Interp *interpreter, IMC_Unit *);
 static int unused_label(Interp *interpreter, IMC_Unit *);
@@ -82,16 +82,19 @@
 /*
  * Handles optimizations occuring before the construction of the CFG.
  */
-void
+int
 pre_optimize(Interp *interpreter, IMC_Unit * unit)
 {
+    int changes = 0;
+    
     if (IMCC_INFO(interpreter)->optimizer_level & OPT_PRE) {
         IMCC_info(interpreter, 2, "pre_optimize\n");
         /* TODO integrate all in one pass */
-        strength_reduce(interpreter, unit);
+        changes += strength_reduce(interpreter, unit);
         if (!IMCC_INFO(interpreter)->dont_optimize)
-            if_branch(interpreter, unit);
+            changes += if_branch(interpreter, unit);
     }
+    return changes;
 }
 
 /*
@@ -175,15 +178,15 @@
  *   unless cond L2
  *
  */
-static void
+static int
 if_branch(Interp *interpreter, IMC_Unit * unit)
 {
     Instruction *ins, *last;
-    int reg;
+    int reg, changed = 0;
 
     last = unit->instructions;
     if (!last->next)
-        return;
+        return changed;
     IMCC_info(interpreter, 2, "\tif_branch\n");
     for (ins = last->next; ins; ) {
         if ((last->type & ITBRANCH) &&          /* if ...L1 */
@@ -215,12 +218,14 @@
                     ostat.deleted_ins++;
                     ins = delete_ins(unit, ins, 1);
                     ostat.if_branch++;
+                    changed = 1;
                 }
             } /* label found */
         } /* branch detected */
         last = ins;
         ins = ins->next;
     }
+    return changed;
 }
 
 /*
Index: imcc/optimizer.h
===================================================================
--- imcc/optimizer.h	(revision 8937)
+++ imcc/optimizer.h	(working copy)
@@ -1,6 +1,6 @@
 #if !defined(PARROT_IMCC_OPTIMIZER_H_GUARD)
 #define PARROT_IMCC_OPTIMIZER_H_GUARD
-void pre_optimize(Interp *, IMC_Unit *);
+int pre_optimize(Interp *, IMC_Unit *);
 int cfg_optimize(Interp *, IMC_Unit *);
 int optimize(Interp *, IMC_Unit *);
 void post_optimize(Interp *, IMC_Unit *);
Index: imcc/reg_alloc.c
===================================================================
--- imcc/reg_alloc.c	(revision 8937)
+++ imcc/reg_alloc.c	(working copy)
@@ -105,8 +105,7 @@
 void
 imc_reg_alloc(Interp *interpreter, IMC_Unit * unit)
 {
-    int todo, first;
-    int loop_counter;
+    int first;
     char *function;
 
     if (!unit)
@@ -136,48 +135,31 @@
             (IMCC_INFO(interpreter)->debug & DEBUG_IMC))
         imc_stat_init(unit);
 
-    /* consecutive labels, if_branch, unused_labels ... */
-    pre_optimize(interpreter, unit);
-    if (IMCC_INFO(interpreter)->optimizer_level == OPT_PRE && unit->pasm_file)
+    if (IMCC_INFO(interpreter)->optimizer_level == OPT_PRE && unit->pasm_file) {
+        while (pre_optimize(interpreter, unit));
         return;
+    }
 
     nodeStack = imcstack_new();
     unit->n_spilled = 0;
 
-    todo = first = 1;
-    loop_counter = 0;
-    while (todo) {
-        loop_counter++;
-        find_basic_blocks(interpreter, unit, first);
-        build_cfg(interpreter, unit);
+    /* build CFG and life info, and optimize iteratively */
+    do {
+        first = 1;
+        do {
+            while (pre_optimize(interpreter, unit));
 
-        first = 0;
-        todo = cfg_optimize(interpreter, unit);
-    }
-    todo = first = 1;
-    loop_counter = 0;
-    while (todo) {
-        loop_counter++;
-        if (!first) {
-            find_basic_blocks(interpreter, unit, 0);
+            find_basic_blocks(interpreter, unit, first);
             build_cfg(interpreter, unit);
-        }
-        first = 0;
+            first = 0;
+        } while (cfg_optimize(interpreter, unit));
 
         compute_dominators(interpreter, unit);
         find_loops(interpreter, unit);
 
         build_reglist(interpreter, unit, 1);
         life_analysis(interpreter, unit);
-        /* optimize, as long as there is something to do */
-        if (IMCC_INFO(interpreter)->dont_optimize)
-            todo = 0;
-        else {
-            todo = optimize(interpreter, unit);
-            if (todo)
-                pre_optimize(interpreter, unit);
-        }
-    }
+    } while (!IMCC_INFO(interpreter)->dont_optimize && optimize(interpreter, unit));
 
     graph_coloring_reg_alloc(interpreter, unit);
 
