fix
[libfirm] / ir / ir / irgopt.c
index da817fd..8a7dde8 100644 (file)
@@ -1,13 +1,28 @@
 /*
- * Project:     libFIRM
- * File name:   ir/ir/irgopt.c
- * Purpose:     Optimizations for a whole ir graph, i.e., a procedure.
- * Author:      Christian Schaefer, Goetz Lindenmaier
- * Modified by: Sebastian Felis, Michael Beck
- * Created:
- * CVS-ID:      $Id$
- * Copyright:   (c) 1998-2007 Universität Karlsruhe
- * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
+ * Copyright (C) 1995-2007 University of Karlsruhe.  All right reserved.
+ *
+ * This file is part of libFirm.
+ *
+ * This file may be distributed and/or modified under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.GPL included in the
+ * packaging of this file.
+ *
+ * Licensees holding valid libFirm Professional Edition licenses may use
+ * this file in accordance with the libFirm Commercial License.
+ * Agreement provided with the Software.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ */
+
+/**
+ * @file
+ * @brief    Optimizations for a whole ir graph, i.e., a procedure.
+ * @author   Christian Schaefer, Goetz Lindenmaier, Sebastian Felis,
+ *           Michael Beck
+ * @version  $Id$
  */
 #ifdef HAVE_CONFIG_H
 # include "config.h"
@@ -163,6 +178,8 @@ void optimize_graph_df(ir_graph *irg) {
        pdeq     *waitq = new_pdeq();
        int      state = edges_activated(irg);
        ir_graph *rem = current_ir_graph;
+       ir_node  *end;
+       int      i;
 
        current_ir_graph = irg;
 
@@ -186,8 +203,23 @@ void optimize_graph_df(ir_graph *irg) {
 
        set_using_irn_link(irg);
 
-       /* walk over the graph */
-       irg_walk_graph(irg, NULL, opt_walker, waitq);
+       /* walk over the graph, but don't touch keep-alives */
+       irg_walk(get_irg_end_block(irg), NULL, opt_walker, waitq);
+
+       end = get_irg_end(irg);
+
+       /* optimize keep-alives by removing superfluous ones */
+       for (i = get_End_n_keepalives(end) - 1; i >= 0; --i) {
+               ir_node *ka = get_End_keepalive(end, i);
+
+               if (irn_visited(ka) && !is_irn_keep(ka)) {
+                       /* this node can be regularly visited, no need to keep it */
+                       set_End_keepalive(end, i, get_irg_bad(irg));
+               }
+       }
+       /* now walk again and visit all not yet visited nodes */
+       set_irg_visited(current_ir_graph, get_irg_visited(irg) - 1);
+       irg_walk(get_irg_end(irg), NULL, opt_walker, waitq);
 
        /* finish the wait queue */
        while (! pdeq_empty(waitq)) {