We still have some lno bits in our tree. We tried to remove them and found:

gzip +0.5%
vpr -0.4%
gcc -3.2%
mcf -0.3%
crafty +0.2%
parser +0.2%
perlbmk -2.2%
gap +0.2%
vortex -0.1%
bzip2 +1.9%
twolf -0.7%

on x86 (probably a core2 duo) in our 4.2 tree (with the rest of our local patches). -3.2% means a 3.2% better codegen (roughly) with the lno bits. I didn't rerun the numbers for mainline to see if they are still applicable.

Of all the LNO bits, the last major bits seems to be the below bit. I don't even know if it is responsible for the benefit we see. I thought I'd mention it, as a 2-3% win on two of the spec tests seems worthwhile.

I'd be interested in finding someone that might be interested in tracking down where the benefit comes from in the patch and pushing into mainline what goodness there is to be had from the patch. Any takers? If I can find someone, I'd be happy to send out the version of the patch for mainline. [ hum just 567 lines] On second though, I'll just include at the end for reference. Note, there is one soft conflict resolution to resolve in going from the 4.2 context to mainline, which I've not yet resolved.

2004-07-13  Zdenek Dvorak  <[EMAIL PROTECTED]>

        * Makefile.in (tree-ssa-loop.o, tree-ssa-dce.o): Add function.h
        dependency.
* builtins.c (expand_builtin): Handle BUILT_IN_MAYBE_INFINITE_LOOP.
        * builtins.def (BUILT_IN_MAYBE_INFINITE_LOOP): New builtin.
* function.h (struct function): Add marked_maybe_inf_loops field.
        * timevar.def (TV_MARK_MILOOPS): New timevar.
        * tree-flow.h (mark_maybe_infinite_loops): Declare.
        * tree-optimize.c (init_tree_optimization_passes): Add
        pass_mark_maybe_inf_loops.
        * tree-pass.h (pass_mark_maybe_inf_loops): Declare.
        * tree-ssa-dce.c: Include function.h.
(find_obviously_necessary_stmts): Mark back edges only if they were
        not marked already.
        (perform_tree_ssa_dce): Do not call mark_dfs_back_edges here.
        * tree-ssa-loop-niter.c (unmark_surely_finite_loop,
        mark_maybe_infinite_loops): New functions.
        * tree-ssa-loop.c: Include function.h.
        (tree_mark_maybe_inf_loops, gate_tree_mark_maybe_inf_loops,
        pass_mark_maybe_inf_loops): New pass.
        * tree-ssa-operands.c (function_ignores_memory_p): Add
        BUILT_IN_MAYBE_INFINITE_LOOP.

Doing diffs in .:
--- ./builtins.c.~1~    2007-04-13 10:06:18.000000000 -0700
+++ ./builtins.c        2007-04-21 15:54:01.000000000 -0700
@@ -6562,6 +6562,12 @@ expand_builtin (tree exp, rtx target, rt
        return target;
       break;
 
+    /* APPLE LOCAL begin lno */
+    case BUILT_IN_MAYBE_INFINITE_LOOP:
+      /* This is just a fake statement that expands to nothing.  */
+      return const0_rtx;
+    /* APPLE LOCAL end lno */
+
     case BUILT_IN_FETCH_AND_ADD_1:
     case BUILT_IN_FETCH_AND_ADD_2:
     case BUILT_IN_FETCH_AND_ADD_4:
--- ./builtins.def.~1~  2007-04-13 10:06:19.000000000 -0700
+++ ./builtins.def      2007-04-21 15:54:01.000000000 -0700
@@ -639,6 +639,8 @@ DEF_LIB_BUILTIN        (BUILT_IN_FREE, "
 DEF_GCC_BUILTIN        (BUILT_IN_FROB_RETURN_ADDR, "frob_return_addr", 
BT_FN_PTR_PTR, ATTR_NULL)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_GETTEXT, "gettext", 
BT_FN_STRING_CONST_STRING, ATTR_FORMAT_ARG_1)
 DEF_C99_BUILTIN        (BUILT_IN_IMAXABS, "imaxabs", BT_FN_INTMAX_INTMAX, 
ATTR_CONST_NOTHROW_LIST)
+/* APPLE LOCAL lno */
+DEF_GCC_BUILTIN        (BUILT_IN_MAYBE_INFINITE_LOOP, "maybe_infinite_loop", 
BT_FN_VOID, ATTR_NULL)
 DEF_GCC_BUILTIN        (BUILT_IN_INIT_DWARF_REG_SIZES, 
"init_dwarf_reg_size_table", BT_FN_VOID_PTR, ATTR_NULL)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_FINITE, "finite", BT_FN_INT_DOUBLE, 
ATTR_CONST_NOTHROW_LIST)
 DEF_EXT_LIB_BUILTIN    (BUILT_IN_FINITEF, "finitef", BT_FN_INT_FLOAT, 
ATTR_CONST_NOTHROW_LIST)
--- ./cfghooks.c.~1~    2007-02-12 20:10:38.000000000 -0800
+++ ./cfghooks.c        2007-04-21 15:59:31.000000000 -0700
@@ -405,6 +405,10 @@ edge
 split_block (basic_block bb, void *i)
 {
   basic_block new_bb;
+  /* APPLE LOCAL begin lno */
+  bool irr = (bb->flags & BB_IRREDUCIBLE_LOOP) != 0;
+  int flags = EDGE_FALLTHRU;
+  /* APPLE LOCAL end lno */
 
   if (!cfg_hooks->split_block)
     internal_error ("%s does not support split_block", cfg_hooks->name);
@@ -416,6 +420,13 @@ split_block (basic_block bb, void *i)
   new_bb->count = bb->count;
   new_bb->frequency = bb->frequency;
   new_bb->loop_depth = bb->loop_depth;
+  /* APPLE LOCAL begin lno */
+  if (irr)
+    {
+      new_bb->flags |= BB_IRREDUCIBLE_LOOP;
+      flags |= EDGE_IRREDUCIBLE_LOOP;
+    }
+  /* APPLE LOCAL end lno */
 
   if (dom_info_available_p (CDI_DOMINATORS))
     {
@@ -560,6 +571,15 @@ split_edge (edge e)
        }
     }
 
+  /* APPLE LOCAL begin lno */
+  if (irr)
+    {
+      ret->flags |= BB_IRREDUCIBLE_LOOP;
+      EDGE_PRED (ret, 0)->flags |= EDGE_IRREDUCIBLE_LOOP;
+      EDGE_SUCC (ret, 0)->flags |= EDGE_IRREDUCIBLE_LOOP;
+    }
+  /* APPLE LOCAL end lno */
+
   if (current_loops != NULL)
     {
       loop = find_common_loop (src->loop_father, dest->loop_father);
@@ -698,6 +718,8 @@ make_forwarder_block (basic_block bb, bo
   edge e, fallthru;
   edge_iterator ei;
   basic_block dummy, jump;
+  /* APPLE LOCAL lno */
+  bool fst_irr = false;
   struct loop *loop, *ploop, *cloop;
 
   if (!cfg_hooks->make_forwarder_block)
@@ -713,6 +735,8 @@ make_forwarder_block (basic_block bb, bo
     {
       if (redirect_edge_p (e))
        {
+      /* APPLE LOCAL lno */
+       fst_irr |= (e->flags & EDGE_IRREDUCIBLE_LOOP) != 0;
          ei_next (&ei);
          continue;
        }
@@ -733,6 +757,14 @@ make_forwarder_block (basic_block bb, bo
        new_bb_cbk (jump);
     }
 
+  /* APPLE LOCAL begin lno */
+  if (!fst_irr)
+    {
+      dummy->flags &= ~BB_IRREDUCIBLE_LOOP;
+      fallthru->flags &= ~EDGE_IRREDUCIBLE_LOOP;
+    }
+  /* APPLE LOCAL end lno */
+
   if (dom_info_available_p (CDI_DOMINATORS))
     {
       basic_block doms_to_fix[2];
--- ./cfgloop.c.~1~     2007-04-13 10:06:20.000000000 -0700
+++ ./cfgloop.c 2007-04-21 15:54:01.000000000 -0700
@@ -484,7 +484,13 @@ flow_loops_find (struct loops *loops)
 
       free (dfs_order);
       free (rc_order);
+      /* APPLE LOCAL begin lno */
     }
+  else
+    {
+      free_dominance_info (CDI_DOMINATORS);
+    }
+  /* APPLE LOCAL end lno */
 
   sbitmap_free (headers);
 
--- ./cfgrtl.c.~1~      2007-03-20 19:07:01.000000000 -0700
+++ ./cfgrtl.c  2007-04-21 15:54:01.000000000 -0700
@@ -2104,6 +2104,14 @@ purge_dead_edges (basic_block bb)
              && (! (e->flags & EDGE_ABNORMAL_CALL)
                  || CALL_P (BB_END (bb))))
            {
+             /* APPLE LOCAL begin lno */
+             /* If the call was removed/moved somewhere else, cleanup the
+                EDGE_ABNORMAL_CALL flag.  */
+             if ((e->flags & EDGE_ABNORMAL_CALL)
+                 && GET_CODE (BB_END (bb)) != CALL_INSN)
+               e->flags &= ~EDGE_ABNORMAL_CALL;
+             /* APPLE LOCAL end lno */
+
              ei_next (&ei);
              continue;
            }
--- ./doc/invoke.texi.~1~       2007-04-21 15:48:05.000000000 -0700
+++ ./doc/invoke.texi   2007-04-21 15:54:05.000000000 -0700
@@ -280,6 +280,11 @@ Objective-C and Objective-C++ Dialects}.
 [EMAIL PROTECTED]@[EMAIL PROTECTED] [EMAIL PROTECTED]@[EMAIL PROTECTED] @gol
 [EMAIL PROTECTED]@[EMAIL PROTECTED] [EMAIL PROTECTED]@[EMAIL PROTECTED] @gol
 [EMAIL PROTECTED]@r{]} [EMAIL PROTECTED]@[EMAIL PROTECTED] @gol
[EMAIL PROTECTED] APPLE LOCAL begin lno
+-fdump-tree-scev @[EMAIL PROTECTED]@r{]} @gol
+-fdump-tree-ddall @[EMAIL PROTECTED]@[EMAIL PROTECTED]
+-fdump-tree-elck @[EMAIL PROTECTED]@r{]} @gol
[EMAIL PROTECTED] APPLE LOCAL end lno
 [EMAIL PROTECTED]@[EMAIL PROTECTED] @gol
 [EMAIL PROTECTED]@[EMAIL PROTECTED] @gol
 [EMAIL PROTECTED]@[EMAIL PROTECTED] @gol
@@ -290,6 +295,10 @@ Objective-C and Objective-C++ Dialects}.
 [EMAIL PROTECTED]@[EMAIL PROTECTED] @gol
 -fdump-tree-salias @gol
 [EMAIL PROTECTED]@[EMAIL PROTECTED] @gol
[EMAIL PROTECTED] APPLE LOCAL begin lno
[EMAIL PROTECTED]@[EMAIL PROTECTED] @gol
[EMAIL PROTECTED]@[EMAIL PROTECTED] @gol
[EMAIL PROTECTED] APPLE LOCAL end lno
 [EMAIL PROTECTED]@[EMAIL PROTECTED] @gol
 [EMAIL PROTECTED] @gol
 [EMAIL PROTECTED]@[EMAIL PROTECTED] @gol
@@ -358,6 +367,8 @@ Objective-C and Objective-C++ Dialects}.
 -ftree-ch -ftree-sra -ftree-ter -ftree-fre -ftree-vectorize @gol
 -ftree-vect-loop-version -ftree-salias -fipa-pta -fweb @gol
 -ftree-copy-prop -ftree-store-ccp -ftree-store-copy-prop -fwhole-program @gol
[EMAIL PROTECTED] APPLE LOCAL lno
+-fscalar-evolutions -fall-data-deps @gol
 --param @[EMAIL PROTECTED]
 -O  -O0  -O1  -O2  -O3  -Os}
 
@@ -4609,6 +4620,24 @@ appending @file{.dce} to the source file
 Dump each function after adding mudflap instrumentation.  The file name is
 made by appending @file{.mudflap} to the source file name.
 
[EMAIL PROTECTED] APPLE LOCAL begin lno
[EMAIL PROTECTED] scev
[EMAIL PROTECTED] fdump-tree-scev
+Dump the information gathered by the scalar evolution analyzer.
+The file name is made by appending @file{.scev} to the source file name.
+
[EMAIL PROTECTED] ddall
[EMAIL PROTECTED] fdump-tree-ddall
+Dump all the data dependence relations.
+The file name is made by appending @file{.ddall} to the source file name.
+
[EMAIL PROTECTED] elck
[EMAIL PROTECTED] fdump-tree-elck
+Dump each function after performing checks elimination based on scalar
+evolution informations.  The file name is made by appending
[EMAIL PROTECTED] to the source file name.
[EMAIL PROTECTED] APPLE LOCAL end lno
+
 @item sra
 @opindex fdump-tree-sra
 Dump each function after performing scalar replacement of aggregates.  The
@@ -4650,6 +4679,13 @@ Dump each function after applying the na
 generic trees.  The file name is made by appending @file{.nrv} to the source
 file name.
 
[EMAIL PROTECTED] APPLE LOCAL begin lno
[EMAIL PROTECTED] loop
[EMAIL PROTECTED] fdump-tree-loop
+Dump each function after applying tree-level loop optimizations.  The file
+name is made by appending @file{.loop} to the source file name.
[EMAIL PROTECTED] APPLE LOCAL end lno
+
 @item vect
 @opindex fdump-tree-vect
 Dump each function after applying vectorization of loops.  The file name is
@@ -5550,6 +5586,12 @@ effectiveness of code motion optimizatio
 is enabled by default at @option{-O} and higher.  It is not enabled
 for @option{-Os}, since it usually increases code size.
 
[EMAIL PROTECTED] APPLE LOCAL begin lno
[EMAIL PROTECTED] -ftree-elim-checks 
+Perform elimination of checks based on scalar evolution informations.
+This flag is disabled by default.  
[EMAIL PROTECTED] APPLE LOCAL end lno
+
 @item -ftree-loop-optimize
 Perform loop optimizations on trees.  This flag is enabled by default
 at @option{-O} and higher.
--- ./fortran/f95-lang.c.~1~    2007-04-21 15:48:07.000000000 -0700
+++ ./fortran/f95-lang.c        2007-04-21 15:54:05.000000000 -0700
@@ -989,6 +989,12 @@ gfc_init_builtin_functions (void)
   ftype = build_function_type (long_integer_type_node, tmp);
   gfc_define_builtin ("__builtin_expect", ftype, BUILT_IN_EXPECT,
                      "__builtin_expect", true);
+  /* APPLE LOCAL begin lno */
+  ftype = build_function_type (void_type_node, void_list_node);
+  gfc_define_builtin ("__builtin_maybe_infinite_loop", ftype,
+                     BUILT_IN_MAYBE_INFINITE_LOOP, "maybe_infinite_loop",
+                     false);
+  /* APPLE LOCAL end lno */
 
 #define DEF_PRIMITIVE_TYPE(ENUM, VALUE) \
   builtin_types[(int) ENUM] = VALUE;
--- ./java/builtins.c.~1~       2007-02-15 18:23:31.000000000 -0800
+++ ./java/builtins.c   2007-04-21 15:54:05.000000000 -0700
@@ -467,6 +467,8 @@ initialize_builtins (void)
 {
   tree double_ftype_double, double_ftype_double_double;
   tree float_ftype_float, float_ftype_float_float;
+  /* APPLE LOCAL lno */
+  tree void_ftype;
   tree boolean_ftype_boolean_boolean;
   tree t;
   int i;
@@ -492,6 +494,10 @@ initialize_builtins (void)
   t = tree_cons (NULL_TREE, double_type_node, t);
   double_ftype_double_double = build_function_type (double_type_node, t);
 
+  /* APPLE LOCAL begin lno */
+  void_ftype = build_function_type (void_type_node, NULL_TREE);
+  /* APPLE LOCAL end lno */
+
   define_builtin (BUILT_IN_FMOD, "__builtin_fmod",
                  double_ftype_double_double, "fmod", BUILTIN_CONST);
   define_builtin (BUILT_IN_FMODF, "__builtin_fmodf",
@@ -536,6 +542,10 @@ initialize_builtins (void)
   define_builtin (BUILT_IN_TAN, "__builtin_tan",
                  double_ftype_double, "_ZN4java4lang4Math3tanEJdd",
                  BUILTIN_CONST);
+  /* APPLE LOCAL begin lno */
+  define_builtin (BUILT_IN_MAYBE_INFINITE_LOOP, 
"__builtin_maybe_infinite_loop",
+                 void_ftype, "__builtin_maybe_infinite_loop", 0);
+  /* APPLE LOCAL end lno */
   
   t = tree_cons (NULL_TREE, boolean_type_node, end_params_node);
   t = tree_cons (NULL_TREE, boolean_type_node, t);
--- ./java/decl.c.~1~   2007-02-02 11:13:32.000000000 -0800
+++ ./java/decl.c       2007-04-21 15:54:05.000000000 -0700
@@ -573,6 +573,8 @@ java_init_decl_processing (void)
 
   /* Define these next since types below may used them.  */
   integer_type_node = java_type_for_size (INT_TYPE_SIZE, 0);
+  /* APPLE LOCAL lno */
+  long_integer_type_node = java_type_for_size (LONG_TYPE_SIZE, 0);
   integer_zero_node = build_int_cst (NULL_TREE, 0);
   integer_one_node = build_int_cst (NULL_TREE, 1);
   integer_two_node = build_int_cst (NULL_TREE, 2);
--- ./loop-doloop.c.~1~ 2006-12-14 15:12:40.000000000 -0800
+++ ./loop-doloop.c     2007-04-21 15:54:05.000000000 -0700
@@ -174,6 +174,13 @@ doloop_valid_p (struct loop *loop, struc
         If the absolute increment is not 1, the loop can be infinite
         even with LTU/GTU, e.g. for (i = 3; i > 0; i -= 2)
 
+        APPLE LOCAL begin lno
+        Note that with LE and GE, the loop behavior is undefined
+        (C++ standard section 5 clause 5) if an overflow occurs, say
+        between INT_MAX and INT_MAX + 1.  We thus don't have to worry
+        about these two cases.
+        APPLE LOCAL end lno
+
         ??? We could compute these conditions at run-time and have a
         additional jump around the loop to ensure an infinite loop.
         However, it is very unlikely that this is the intended
--- ./opts.c.~1~        2007-04-21 15:48:09.000000000 -0700
+++ ./opts.c    2007-04-21 15:54:05.000000000 -0700
@@ -708,6 +708,13 @@ decode_options (unsigned int argc, const
       flag_tree_dce = 1;
       flag_tree_dom = 1;
       flag_tree_dse = 1;
+      /* APPLE LOCAL begin lno */
+      flag_tree_loop_im = 1;
+      flag_ivopts = 1;
+      flag_tree_vectorize = 0;
+      flag_tree_loop_linear = 0;
+      flag_tree_pre = 1;
+      /* APPLE LOCAL end lno */
       flag_tree_ter = 1;
       flag_tree_sra = 1;
       flag_tree_copyrename = 1;
--- ./passes.c.~1~      2007-04-21 15:48:10.000000000 -0700
+++ ./passes.c  2007-04-21 15:57:55.000000000 -0700
@@ -594,6 +594,9 @@ init_optimization_passes (void)
          NEXT_PASS (pass_check_data_deps);
          NEXT_PASS (pass_linear_transform);
          NEXT_PASS (pass_iv_canon);
+         /* APPLE LOCAL begin lno */
+         NEXT_PASS (pass_mark_maybe_inf_loops);
+         /* APPLE LOCAL end lno */
          NEXT_PASS (pass_if_conversion);
          NEXT_PASS (pass_vectorize);
            {
--- ./testsuite/lib/scantree.exp.~1~    2006-11-16 23:21:25.000000000 -0800
+++ ./testsuite/lib/scantree.exp        2007-04-21 15:54:05.000000000 -0700
@@ -17,6 +17,54 @@
 # Various utilities for scanning tree dump output, used by gcc-dg.exp and
 # g++-dg.exp.
 
+# APPLE LOCAL begin lno
+# Utility for diffing compiler result against an expected output file.
+# Invoked via dg-final.  Call pass if there are no differences between
+# the output of the compiler and the expected output file, otherwise
+# fail.  The expected output file has the same name as the output
+# file, and is stored in the same directory as the testcase.  
+#
+# Argument 0 is the suffix for the tree dump file
+# Argument 1 handles expected failures and the like
+proc diff-tree-dumps { args } {
+    if { [llength $args] < 1 } {
+       error "diff-tree-dumps: too few arguments"
+        return
+    }
+    if { [llength $args] > 2 } {
+       error "diff-tree-dumps:: too many arguments"
+       return
+    }
+    if { [llength $args] >= 2 } {
+       switch [dg-process-target [lindex $args 1]] {
+           "S" { }
+           "N" { return }
+           "F" { setup_xfail "*-*-*" }
+           "P" { }
+       }
+    }
+
+    # This assumes that we are two frames down from dg-test, and that
+    # it still stores the filename of the testcase in a local variable "name".
+    # A cleaner solution would require a new dejagnu release.
+    upvar 2 prog testcase
+    
+    # This must match the rule in gcc-dg.exp.
+    # APPLE LOCAL Selective inlining of functions that use Altivec 3837835
+    set new_file "[glob [file tail $testcase].\[ti\]??.[lindex $args 0]]"
+    set reference_file "[glob $testcase.[lindex $args 0]]"
+    
+    set test_result [diff $reference_file $new_file]
+    
+    if { $test_result == 1 } {
+       pass "$testcase diff-tree-dumps [lindex $args 0]"
+    } else {
+       fail "$testcase diff-tree-dumps [lindex $args 0]"
+       local_exec (diff $reference_file $new_file 0);
+    }
+}
+# APPLE LOCAL end lno
+
 load_lib scandump.exp
 
 # Utility for scanning compiler result, invoked via dg-final.
--- ./timevar.def.~1~   2007-03-12 19:03:09.000000000 -0700
+++ ./timevar.def       2007-04-21 15:54:05.000000000 -0700
@@ -102,6 +102,8 @@ DEFTIMEVAR (TV_TREE_DSE                  , "tree DS
 DEFTIMEVAR (TV_TREE_MERGE_PHI       , "PHI merge")
 DEFTIMEVAR (TV_TREE_LOOP            , "tree loop optimization")
 DEFTIMEVAR (TV_TREE_LOOP_BOUNDS             , "tree loop bounds")
+/* APPLE LOCAL lno */
+DEFTIMEVAR (TV_MARK_MILOOPS         , "mark maybe infinite loops")
 DEFTIMEVAR (TV_LIM                   , "loop invariant motion")
 DEFTIMEVAR (TV_TREE_LOOP_IVCANON     , "tree canonical iv")
 DEFTIMEVAR (TV_SCEV_CONST            , "scev constant prop")
--- ./tree-cfg.c.~1~    2007-04-13 10:06:21.000000000 -0700
+++ ./tree-cfg.c        2007-04-21 15:54:05.000000000 -0700
@@ -4081,7 +4081,8 @@ tree_redirect_edge_and_branch (edge e, b
     return ret;
 
   if (e->dest == dest)
-    return NULL;
+  /* APPLE LOCAL lno */
+    return e;
 
   label = tree_block_label (dest);
 
--- ./tree-flow.h.~1~   2007-04-13 10:06:20.000000000 -0700
+++ ./tree-flow.h       2007-04-21 15:54:05.000000000 -0700
@@ -1032,6 +1032,11 @@ enum move_pos
   };
 extern enum move_pos movement_possibility (tree);
 
+/* APPLE LOCAL begin lno */
+/* In tree-ssa-loop*.c  */
+void mark_maybe_infinite_loops (struct loops *);
+/* APPLE LOCAL end lno */
+
 /* The reasons a variable may escape a function.  */
 enum escape_type 
 {
--- ./tree-pass.h.~1~   2007-04-21 15:48:08.000000000 -0700
+++ ./tree-pass.h       2007-04-21 15:54:05.000000000 -0700
@@ -244,6 +244,9 @@ extern struct tree_opt_pass pass_tree_lo
 extern struct tree_opt_pass pass_tree_loop_init;
 extern struct tree_opt_pass pass_lim;
 extern struct tree_opt_pass pass_tree_unswitch;
+/* APPLE LOCAL begin lno */
+extern struct tree_opt_pass pass_mark_maybe_inf_loops;
+/* APPLE LOCAL end lno */
 extern struct tree_opt_pass pass_iv_canon;
 extern struct tree_opt_pass pass_scev_cprop;
 extern struct tree_opt_pass pass_empty_loop;
--- ./tree-ssa-loop-niter.c.~1~ 2007-04-21 15:48:08.000000000 -0700
+++ ./tree-ssa-loop-niter.c     2007-04-21 15:54:05.000000000 -0700
@@ -3137,3 +3137,87 @@ substitute_in_loop_info (struct loop *lo
 {
   loop->nb_iterations = simplify_replace_tree (loop->nb_iterations, name, val);
 }
+
+/* APPLE LOCAL begin lno */
+/*
+   
+   Removal of loops in DCE.
+
+*/
+
+/* If we are able to prove that the LOOP always exits, turn off the
+   EDGE_DFS_BACK flag from its latch edge.  */
+
+static void
+unmark_surely_finite_loop (struct loop *loop)
+{
+  edge *exits;
+  unsigned i, n_exits;
+  struct tree_niter_desc niter_desc;
+
+  exits = get_loop_exit_edges (loop, &n_exits);
+  for (i = 0; i < n_exits; i++)
+    if (number_of_iterations_exit (loop, exits[i], &niter_desc, false))
+      {
+       loop_latch_edge (loop)->flags &= ~EDGE_DFS_BACK;
+       return;
+      }
+}
+
+/* Emit special statements preventing removal of possibly infinite loops in
+   CD_DCE to the latches of LOOPS for that we are not able to prove that they
+   iterate just finite number of times.  */
+
+void
+mark_maybe_infinite_loops (struct loops *loops)
+{
+  unsigned i;
+  struct loop *loop;
+  basic_block bb;
+  edge e;
+  tree stmt;
+  bool inserted = false;
+  block_stmt_iterator bsi;
+
+  mark_dfs_back_edges ();
+
+  for (i = 1; i < loops->num; i++)
+    {
+      loop = loops->parray[i];
+      if (loop)
+       unmark_surely_finite_loop (loop);
+    }
+
+  FOR_EACH_BB (bb)
+    {
+      edge_iterator ei;
+      FOR_EACH_EDGE (e, ei, bb->succs)
+       if (e->flags & EDGE_DFS_BACK)
+         {
+           stmt = build_function_call_expr 
(built_in_decls[BUILT_IN_MAYBE_INFINITE_LOOP],
+                                            NULL);
+
+           mark_new_vars_to_rename (stmt);
+
+           if (!(e->flags & EDGE_ABNORMAL))
+             {
+               bsi_insert_on_edge (e, stmt);
+               inserted = true;
+               continue;
+             }
+
+           /* We cannot insert on abnormal edge, so insert to the basic block
+              at its start.  */
+           bsi = bsi_last (e->src);
+           if (!bsi_end_p (bsi)
+               && stmt_ends_bb_p (bsi_stmt (bsi)))
+             bsi_insert_before (&bsi, stmt, BSI_NEW_STMT);
+           else
+             bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
+         }
+    }
+
+  if (inserted)
+    loop_commit_inserts ();
+}
+/* APPLE LOCAL end lno */
--- ./tree-ssa-loop.c.~1~       2007-03-12 19:03:09.000000000 -0700
+++ ./tree-ssa-loop.c   2007-04-21 15:55:56.000000000 -0700
@@ -532,3 +532,42 @@ struct tree_opt_pass pass_tree_loop_done
   TODO_cleanup_cfg | TODO_dump_func,   /* todo_flags_finish */
   0                                    /* letter */
 };
+
+/* APPLE LOCAL begin lno */
+/* Marks loops that cannot be removed in DCE, since they are possibly
+   infinite.  */
+
+static unsigned int
+tree_mark_maybe_inf_loops (void)
+{
+  if (!current_loops)
+    return 0;
+
+  mark_maybe_infinite_loops (current_loops);
+  return 0;
+}
+
+static bool
+gate_tree_mark_maybe_inf_loops (void)
+{
+  return (flag_tree_dce != 0 && optimize >= 2);
+}
+
+struct tree_opt_pass pass_mark_maybe_inf_loops = 
+{
+  "miloops",                           /* name */
+  gate_tree_mark_maybe_inf_loops,      /* gate */
+  tree_mark_maybe_inf_loops,           /* execute */
+  NULL,                                        /* sub */
+  NULL,                                        /* next */
+  0,                                   /* static_pass_number */
+  TV_MARK_MILOOPS,                     /* tv_id */
+  PROP_cfg | PROP_ssa,                 /* properties_required */
+  0,                                   /* properties_provided */
+  0,                                   /* properties_destroyed */
+  0,                                   /* todo_flags_start */
+  TODO_update_ssa | TODO_dump_func,     /* todo_flags_finish */
+  0
+};
+
+/* APPLE LOCAL end lno */
--------------

Reply via email to