walker for complete interprocedural graph
authorGötz Lindenmaier <goetz@ipd.info.uni-karlsruhe.de>
Wed, 11 Sep 2002 16:41:18 +0000 (16:41 +0000)
committerGötz Lindenmaier <goetz@ipd.info.uni-karlsruhe.de>
Wed, 11 Sep 2002 16:41:18 +0000 (16:41 +0000)
dump const nodes local
access routines of ip_cfop nodes

[r474]

ir/ir/irdump.c
ir/ir/irdump.h
ir/ir/irgopt.c
ir/ir/irgraph.c
ir/ir/irgraph.h
ir/ir/irgwalk.c
ir/ir/irgwalk.h
ir/ir/irmode.h
ir/ir/irnode.c
ir/ir/irnode.h
ir/ir/iropt.c

index 59d43cc..dc6b749 100644 (file)
@@ -92,6 +92,13 @@ int dump_keepalive = 0;
 int dump_out_edge_flag = 0;
 int dump_dominator_information_flag = 0;
 int dump_loop_information_flag = 0;
+int dump_const_local = 0;
+static INLINE bool dump_const_local_set() {
+  if (!dump_out_edge_flag && !dump_loop_information_flag)
+    return dump_const_local;
+  else
+    return false;
+}
 
 /* A global variable to record output of the Bad node. */
 int Bad_dumped;
@@ -227,15 +234,66 @@ dump_node_vcgattr (ir_node *n)
   }
 }
 
+bool pred_in_wrong_graph(ir_node *n, int pos, pmap *irgmap) {
+  ir_node *block = (is_Block(n)) ? n : get_nodes_Block(n);
+
+  if (irgmap &&
+      ((get_irn_op(n) == op_Filter) || (get_irn_op(n) == op_Block))) {
+    ir_node *pred = skip_Proj(get_Block_cfgpred(block, pos));
+    if (is_ip_cfop(pred)) {
+      ir_graph *irg = get_ip_cfop_irg(pred);
+      if (pmap_find(irgmap, irg) == NULL) return true;
+    }
+  }
+
+  return false;
+}
+
+
+void dump_const_node_local(ir_node *n, pmap *irgmap) {
+  int i;
+  if (!dump_const_local_set()) return;
+  /* Use visited flag to avoid outputting nodes twice.
+     initialize it first. */
+  for (i = 0; i < get_irn_arity(n); i++) {
+    ir_node *con = get_irn_n(n, i);
+    if (get_irn_op(con) == op_Const) {
+      if (pred_in_wrong_graph(n, i, irgmap)) continue; /* pred not dumped */
+      set_irn_visited(con, get_irg_visited(current_ir_graph)-1);
+    }
+  }
+  for (i = 0; i < get_irn_arity(n); i++) {
+    ir_node *con = get_irn_n(n, i);
+    if ((get_irn_op(con) == op_Const) && irn_not_visited(con)) {
+      if (pred_in_wrong_graph(n, i, irgmap)) continue; /* pred not dumped */
+      mark_irn_visited(con);
+      /* Generate a new name for the node by appending the names of
+        n and const. */
+      xfprintf (F, "node: {title: \""); PRINT_NODEID(n); PRINT_NODEID(con);
+      fprintf(F, "\" label: \"");
+      dump_node_opcode(con);
+      dump_node_mode (con);
+      xfprintf (F, " ");
+      dump_node_nodeattr(con);
+#ifdef DEBUG_libfirm
+      xfprintf (F, " %ld", get_irn_node_nr(con));
+#endif
+      xfprintf (F, "\" ");
+      dump_node_vcgattr(con);
+      xfprintf (F, "}\n");
+    }
+  }
+}
+
 void
-dump_node (ir_node *n) {
+dump_node (ir_node *n, pmap * map) {
+  if (dump_const_local_set() && (get_irn_op(n) == op_Const)) return;
 
   /* dump this node */
   xfprintf (F, "node: {title: \""); PRINT_NODEID(n); fprintf(F, "\" label: \"");
 
   dump_node_opcode(n);
   dump_node_mode (n);
-  //if (dump_loop_information_flag) dump_node_loop_info(n);
   xfprintf (F, " ");
   dump_node_nodeattr(n);
 #ifdef DEBUG_libfirm
@@ -244,6 +302,7 @@ dump_node (ir_node *n) {
   xfprintf (F, "\" ");
   dump_node_vcgattr(n);
   xfprintf (F, "}\n");
+  dump_const_node_local(n, map);
 }
 
 void
@@ -443,6 +502,7 @@ dump_ir_node (ir_node *n)
 /* dump the edge to the block this node belongs to */
 void
 dump_ir_block_edge(ir_node *n)  {
+  if (dump_const_local_set() && (get_irn_op(n) == op_Const)) return;
   if (is_no_Block(n)) {
     xfprintf (F, "edge: { sourcename: \"");
     PRINT_NODEID(n);
@@ -549,7 +609,7 @@ dump_ir_data_edges(ir_node *n)  {
   for (i = 0; i < get_irn_arity(n); i++) {
     ir_node * pred = get_irn_n(n, i);
     assert(pred);
-    if (interprocedural_view && get_irn_visited(pred) < visited)
+    if ((interprocedural_view && get_irn_visited(pred) < visited))
       continue; /* pred not dumped */
     if (is_backedge(n, i))
       fprintf (F, "backedge: {sourcename: \"");
@@ -557,6 +617,8 @@ dump_ir_data_edges(ir_node *n)  {
       fprintf (F, "edge: {sourcename: \"");
     PRINT_NODEID(n);
     fprintf (F, "\" targetname: \"");
+    if ((dump_const_local_set()) && (get_irn_op(pred) == op_Const))
+      PRINT_NODEID(n);
     PRINT_NODEID(pred);
     fprintf (F, "\"");
     fprintf (F, " label: \"%d\" ", i);
@@ -1015,7 +1077,7 @@ int node_floats(ir_node *n) {
 
 void
 dump_whole_node (ir_node *n, void* env) {
-  dump_node(n);
+  dump_node(n, NULL);
   if (!node_floats(n)) dump_ir_block_edge(n);
   dump_ir_data_edges(n);
 }
@@ -1052,7 +1114,7 @@ dump_ir_blocks_nodes (ir_node *n, void *env) {
   ir_node *block = (ir_node *)env;
 
   if (is_no_Block(n) && get_nodes_Block(n) == block && !node_floats(n)) {
-    dump_node(n);
+    dump_node(n, NULL);
     dump_ir_data_edges(n);
   }
   if (get_irn_op(n) == op_Bad)
@@ -1094,14 +1156,14 @@ dump_ir_block (ir_node *block, void *env) {
 void
 dump_blockless_nodes (ir_node *n, void *env) {
   if (is_no_Block(n) && get_irn_op(get_nodes_Block(n)) == op_Bad) {
-    dump_node(n);
+    dump_node(n, NULL);
     dump_ir_data_edges(n);
     dump_ir_block_edge(n);
     if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
     return;
   }
   if (node_floats(n)) {
-    dump_node(n);
+    dump_node(n, NULL);
     dump_ir_data_edges(n);
     if (get_irn_op(n) == op_Bad) Bad_dumped = 1;
   }
@@ -1118,7 +1180,7 @@ void dump_ir_block_graph_2  (ir_graph *irg)
 
   /* dump the Bad node */
   if (!Bad_dumped)
-    dump_node(get_irg_bad(irg));
+    dump_node(get_irg_bad(irg), NULL);
 }
 
 void
@@ -1317,6 +1379,11 @@ void turn_off_edge_labels() {
   edge_label = 0;
 }
 
+
+void dump_consts_local(bool b) {
+  dump_const_local = b;
+}
+
 void turn_off_constant_entity_values() {
   const_entities = 0;
 }
@@ -1345,12 +1412,6 @@ static void clear_link(ir_node * node, void * env) {
   set_irn_link(node, NULL);
 }
 
-
-static INLINE bool is_Block(ir_node * node) {
-  return !is_no_Block(node);
-}
-
-
 static void collect_blocks_floats_cg(ir_node * node, pmap * map) {
   if (is_Block(node)
       || node_floats(node)
@@ -1372,29 +1433,31 @@ static void collect_blocks_floats_cg(ir_node * node, pmap * map) {
 }
 
 
-static void dump_cg_ir_block(ir_node * node, void * env) {
-  assert(is_Block(node));
+static void dump_cg_ir_block(ir_node * block, void * env) {
+  ir_node *node;
+  pmap *irgmap = (pmap *)env;
+  assert(is_Block(block));
   xfprintf(F, "graph: { title: \"");
-  PRINT_NODEID(node);
+  PRINT_NODEID(block);
   fprintf(F, "\"  label: \"");
 #ifdef DEBUG_libfirm
-  xfprintf (F, "%ld", get_irn_node_nr(node));
+  xfprintf (F, "%ld", get_irn_node_nr(block));
 #else
-  xfprintf (F, "%I", node->op->name);
+  xfprintf (F, "%I", block->op->name);
 #endif
-  if (exc_normal != get_Block_exc(node)) {
-    fprintf (F, " (%s)", exc_to_string (get_Block_exc(node)));
+  if (exc_normal != get_Block_exc(block)) {
+    fprintf (F, " (%s)", exc_to_string (get_Block_exc(block)));
   }
 
   xfprintf(F, "\" status:clustered color:%s \n",
-          get_Block_matured(node) ? "yellow" : "red");
+          get_Block_matured(block) ? "yellow" : "red");
 
   /* dump the blocks edges */
-  dump_ir_data_edges(node);
+  dump_ir_data_edges(block);
 
   /* dump the nodes that go into the block */
   for (node = get_irn_link(node); node; node = get_irn_link(node)) {
-    dump_node(node);
+    dump_node(node, irgmap);
     dump_ir_data_edges(node);
   }
 
@@ -1402,58 +1465,112 @@ static void dump_cg_ir_block(ir_node * node, void * env) {
   xfprintf(F, "}\n\n");
 }
 
+void d_cg_block_graph(ir_graph *irg, ir_node **arr, pmap *irgmap) {
+  int i;
+
+  xfprintf(F, "graph: { title: \"%p\" label: \"%I\" status:clustered color:white \n",
+          irg, get_entity_ident(get_irg_ent(irg)));
+
+  for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
+    ir_node * node = arr[i];
+    if (is_Block(node)) {
+      /* Dumps the block and all the nodes in the block , which are to
+        be found in Block->link. */
+      dump_cg_ir_block(node, irgmap);
+    } else {
+      /* Nodes that are not in a Block. */
+      dump_node(node, NULL);
+      dump_ir_data_edges(node);
+    }
+  }
+  /* Close the vcg information for the irg */
+  xfprintf(F, "}\n\n");
+}
 
 /* dump interprocedural graph with surrounding methods */
 void dump_cg_block_graph(ir_graph * irg) {
   pmap * map = pmap_create();
+  pmap * map2 = pmap_create();
   pmap_entry * entry;
+
   vcg_open(irg, "");
 
   irg_walk_graph(irg, clear_link, (irg_walk_func) collect_blocks_floats_cg, map);
+  for (entry = pmap_first(map); entry; entry = pmap_next(map))
+    pmap_insert(map2, entry->key, entry->value);
   for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
-    ir_node ** arr = entry->value;
-    int i;
-
-    xfprintf(F, "graph: { title: \"%I\" label: \"%I\" status:clustered color:white \n",
-            get_entity_ident(get_irg_ent(entry->key)),
-            get_entity_ident(get_irg_ent(entry->key)));
+    d_cg_block_graph(entry->key, entry->value, map2);
+    DEL_ARR_F(entry->value);
+  }
 
-    for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
-      ir_node * node = arr[i];
-      if (is_Block(node)) {
-       /* Dumps the block and all the nodes in the block , with are to be found in
-          Block->link. */
-       dump_cg_ir_block(node, NULL);
-      } else {
-       /* Node that are not in a Block. */
-       dump_node(node);
-       dump_ir_data_edges(node);
-      }
-    }
+  pmap_destroy(map);
+  pmap_destroy(map2);
 
-    DEL_ARR_F(arr);
+  if (dump_loop_information_flag) dump_loop_info(irg);
+  vcg_close();
+}
 
-    /* Close the vcg information for the irg */
-    xfprintf(F, "}\n\n");
+static void collect_node(ir_node * node, void *env) {
+  if (is_Block(node)
+      || node_floats(node)
+      || get_irn_op(node) == op_Bad
+      || get_irn_op(node) == op_Unknown) {
+    ir_node ** arr = (ir_node **) get_irg_link(current_ir_graph);
+    ARR_APP1(ir_node *, arr, node);
+    set_irg_link(current_ir_graph, arr);    /* arr is an l-value, APP_ARR might change it! */
+  } else {
+    ir_node * block = get_nodes_Block(node);
+    set_irn_link(node, get_irn_link(block));
+    set_irn_link(block, node);
   }
+}
 
-  pmap_destroy(map);
+/* Links all nodes that have the block field set in the link field of
+   the block.  Adds all blocks and nodes not associated with a block
+   in a array in irg->link. */
+static void collect_nodes() {
+  int i;
+  for (i = 0; i < get_irp_n_irgs(); i++)
+    set_irg_link(get_irp_irg(i), NEW_ARR_F(ir_node *, 0));
+  cg_walk(clear_link, collect_node, NULL);
+}
 
-  if (dump_loop_information_flag) {
-    dump_loop_info(irg);
+static void dump_graphs() {
+  int i;
+  for (i = 0; i < get_irp_n_irgs(); i++) {
+    current_ir_graph = get_irp_irg(i);
+    d_cg_block_graph(current_ir_graph, get_irg_link(current_ir_graph), NULL);
   }
+}
+
+/* Dump all irgs in interprocedural view to a single file. */
+void dump_all_cg_block_graph() {
+  int i;
+  int rem_view = interprocedural_view;
+  interprocedural_view = 1;
+  vcg_open_name ("All_graphs");
+
+  collect_nodes();
+  dump_graphs();
+
+  if (dump_loop_information_flag)
+    for (i = 0; i < get_irp_n_irgs(); i++)
+      dump_loop_info(get_irp_irg(i));
 
   vcg_close();
+  interprocedural_view = rem_view;
 }
 
-
 /* dump interprocedural block graph with surrounding methods */
 void dump_cg_graph(ir_graph * irg) {
   pmap * map = pmap_create();
+  pmap * map2 = pmap_create(); /* We can not iterate in the same map twice! */
   pmap_entry * entry;
   vcg_open(irg, "");
 
   irg_walk_graph(irg, clear_link, (irg_walk_func) collect_blocks_floats_cg, map);
+  for (entry = pmap_first(map); entry; entry = pmap_next(map))
+    pmap_insert(map2, entry->key, entry->value);
   for (entry = pmap_first(map); entry; entry = pmap_next(map)) {
     ir_node ** arr = entry->value;
     int i;
@@ -1464,11 +1581,11 @@ void dump_cg_graph(ir_graph * irg) {
 
     for (i = ARR_LEN(arr) - 1; i >= 0; --i) {
       ir_node * node = arr[i];
-      dump_node(node);
+      dump_node(node, map2);
       dump_ir_data_edges(node);
       if (is_Block(node)) {
        for (node = get_irn_link(node); node; node = get_irn_link(node)) {
-         dump_node(node);
+         dump_node(node, map2);
          dump_ir_block_edge(node);
          dump_ir_data_edges(node);
        }
@@ -1482,6 +1599,7 @@ void dump_cg_graph(ir_graph * irg) {
   }
 
   pmap_destroy(map);
+  pmap_destroy(map2);
 
   vcg_close();
 }
index b8a4501..7f91c13 100644 (file)
@@ -232,6 +232,9 @@ void dump_cg_graph(ir_graph * irg);
  */
 void dump_cg_block_graph(ir_graph * irg);
 
+
+void dump_all_cg_block_graph();
+
 /****m* irdump/dump_all_ir_graphs
  *
  * NAME
@@ -276,6 +279,27 @@ void dump_all_ir_graphs (void dump_graph(ir_graph*));
  */
 void turn_off_edge_labels();
 
+/****m* irdump/dump_consts_local
+ *
+ * NAME
+ *   dump_consts_local
+ * SYNOPSIS
+ *   void dump_consts_local(bool b);
+ * FUNCTION
+ *   If set to true constants will be replicated for every use. In non blocked
+ *   view edges from constant to block are scipped.  Vcg
+ *   then layouts the graphs more compact, this makes them better readable.
+ *   The flag is automatically and temporarily set to false if other
+ *   edges are dumped, as outs, loop, ...
+ *   Default setting: false.
+ * INPUTS
+ * RESULT
+ * SEE ALSO
+ *
+ ***
+ */
+void dump_consts_local(bool b);
+
 
 /****m* irdump/turn_off_constant_entity_values
  *
@@ -351,6 +375,25 @@ void dump_out_edges();
  */
 void dump_dominator_information();
 
+
+/****m* irdump/dump_loop_information
+ *
+ * NAME
+ *   dump_loop_information
+ * SYNOPSIS
+ *   void dump_loop_information()
+ * FUNCTION
+ *   If this flag is set the dumper dumps loop nodes and edges from
+ *   these nodes to the contained ir nodes.
+ *   Can be turned off with dont_dump_loop_information().
+ *   If the loops are interprocedural nodes can be missing.
+ * INPUTS
+ *   No inputs
+ * RESULT
+ * SEE ALSO
+ *
+ ***
+ */
 void dump_loop_information();
 void dont_dump_loop_information();
 
index 1e1893d..c7a3cc9 100644 (file)
@@ -743,7 +743,7 @@ void inline_small_irgs(ir_graph *irg, int size) {
 
   if (!(get_optimize() && get_opt_inline())) return;
 
-  /*DDME(get_irg_ent(current_ir_graph));*/
+  //DDME(get_irg_ent(current_ir_graph));
 
   current_ir_graph = irg;
   /* Handle graph state */
@@ -766,7 +766,6 @@ void inline_small_irgs(ir_graph *irg, int size) {
       tv = get_Const_tarval(get_Call_ptr(calls[i]));
       callee = get_entity_irg(tv->u.p.ent);
       if ((_obstack_memory_used(callee->obst) - obstack_room(callee->obst)) < size) {
-       /*printf(" inlineing "); DDME(tv->u.p.ent);*/
        inline_method(calls[i], callee);
       }
     }
@@ -904,7 +903,7 @@ consumer_dom_dca (ir_node *dca, ir_node *consumer, ir_node *producer)
   return dca;
 }
 
-int get_irn_loop_depth(ir_node *n) {
+INLINE int get_irn_loop_depth(ir_node *n) {
   return get_loop_depth(get_irn_loop(n));
 }
 
@@ -988,9 +987,8 @@ place_floats_late (ir_node *n)
        dca = consumer_dom_dca (dca, get_irn_out(n, i), n);
       }
       set_nodes_Block(n, dca);
-#if 1
+
       move_out_of_loops (n, early);
-#endif
     }
   }
 
@@ -1018,8 +1016,6 @@ INLINE void place_late() {
   }
 }
 
-#include "irdump.h"
-
 void place_code(ir_graph *irg) {
   ir_graph *rem = current_ir_graph;
   current_ir_graph = irg;
index f7bf56a..4b5c340 100644 (file)
@@ -456,17 +456,21 @@ unsigned long
 get_max_irg_visited(void)
 {
   int i;
-  for(i = 0; i < get_irp_n_irgs(); i++)
-    assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
+  //for(i = 0; i < get_irp_n_irgs(); i++)
+  //  assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
   return max_irg_visited;
 }
 
+void set_max_irg_visited(int val) {
+  max_irg_visited = val;
+}
+
 unsigned long
 inc_max_irg_visited(void)
 {
   int i;
-  for(i = 0; i < get_irp_n_irgs(); i++)
-    assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
+  //  for(i = 0; i < get_irp_n_irgs(); i++)
+  //assert(max_irg_visited >= get_irg_visited(get_irp_irg(i)));
   max_irg_visited++;
   return max_irg_visited;
 }
index 913055c..c77251d 100644 (file)
@@ -226,6 +226,7 @@ void     inc_irg_visited(ir_graph *irg);
 unsigned long get_irg_visited (ir_graph *irg);
 void     set_irg_visited(ir_graph *irg, unsigned long i);
 unsigned long get_max_irg_visited(void);
+void set_max_irg_visited(int val);
 unsigned long inc_max_irg_visited(void);
 
 /* increments block_visited by one */
index 8b84a24..7221ba3 100644 (file)
@@ -45,7 +45,8 @@ static void irg_walk_cg(ir_node * node, int visited, eset * irg_set,
 
   if (pre) pre(node, env);
 
-  if (is_no_Block(node)) irg_walk_cg(get_nodes_Block(node), visited, irg_set, pre, post, env);
+  if (is_no_Block(node))
+    irg_walk_cg(get_nodes_Block(node), visited, irg_set, pre, post, env);
 
   if (get_irn_op(node) == op_Block) { /* block */
     for (i = get_irn_arity(node) - 1; i >= 0; --i) {
@@ -103,37 +104,22 @@ static void collect_irgs(ir_node * node, eset * irg_set) {
   }
 }
 
-
 void irg_walk_2(ir_node *node, irg_walk_func pre, irg_walk_func post, void * env)
 {
   int i;
-
-
   assert(node);
-  /*      printf(" - "); DDMSG2(node);  */
 
   if (get_irn_visited(node) < get_irg_visited(current_ir_graph)) {
-
-/*      printf(" -> "); DDMSG2(node);  */
     set_irn_visited(node, get_irg_visited(current_ir_graph));
 
-    if (pre) {
-      pre(node, env);
-    }
+    if (pre) pre(node, env);
 
-    if (is_no_Block(node)) {
+    if (is_no_Block(node))
       irg_walk_2(get_nodes_Block(node), pre, post, env);
-    }
-    for (i = get_irn_arity(node) - 1; i >= 0; --i) {
-      /* printf("   "); DDMSG2(node);
-        printf("   "); DDMSG2(get_irn_n(node, i));  */
-
+    for (i = get_irn_arity(node) - 1; i >= 0; --i)
       irg_walk_2(get_irn_n(node, i), pre, post, env);
-    }
 
-/*      printf(" <- "); DDMSG2(node);  */
-    if (post)
-      post(node, env);
+    if (post) post(node, env);
   }
   return;
 }
@@ -171,9 +157,6 @@ void irg_walk_graph(ir_graph *irg, irg_walk_func pre, irg_walk_func post, void *
   current_ir_graph = rem;
 }
 
-
-/***************************************************************************/
-
 /* Executes irg_walk(end, pre, post, env) for all irgraphs in irprog.
    Sets current_ir_graph properly for each walk.  Conserves current
    current_ir_graph. */
@@ -191,6 +174,84 @@ void all_irg_walk(irg_walk_func pre, irg_walk_func post, void *env) {
   current_ir_graph = rem;
 }
 
+/***************************************************************************/
+
+/* Returns current_ir_graph and sets it to the irg of predecessor index
+   of node n. */
+static INLINE ir_graph *
+switch_irg (ir_node *n, int index) {
+  ir_graph *old_current = current_ir_graph;
+
+  if (interprocedural_view) {
+    /* Only Filter and Block nodes can have predecessors in other graphs. */
+    if (get_irn_op(n) == op_Filter)
+      n = get_nodes_Block(n);
+    if (get_irn_op(n) == op_Block) {
+      ir_node *cfop = skip_Proj(get_Block_cfgpred(n, index));
+      if (is_ip_cfop(cfop)) {
+       current_ir_graph = get_irn_irg(cfop);
+      }
+    }
+  }
+
+  return old_current;
+}
+
+void cg_walk_2(ir_node *node, irg_walk_func pre, irg_walk_func post, void * env)
+{
+  int i;
+  ir_graph *rem = NULL;
+  assert(node);
+
+  if (get_irn_visited(node) < get_irg_visited(current_ir_graph)) {
+    set_irn_visited(node, get_irg_visited(current_ir_graph));
+
+    if (pre) pre(node, env);
+
+    if (is_no_Block(node))
+      cg_walk_2(get_nodes_Block(node), pre, post, env);
+    for (i = get_irn_arity(node) - 1; i >= 0; --i) {
+      rem = switch_irg(node, i);
+      cg_walk_2(get_irn_n(node, i), pre, post, env);
+      current_ir_graph = rem;
+    }
+
+    if (post) post(node, env);
+  }
+  return;
+}
+
+
+/* Walks all irgs in interprocedural view.  Visits each node only once. */
+void cg_walk(irg_walk_func pre, irg_walk_func post, void *env) {
+  int i;
+  ir_graph *rem = current_ir_graph;
+  int rem_view = interprocedural_view;
+
+  interprocedural_view = true;
+
+  inc_max_irg_visited();
+  /* Fix all irg_visited flags */
+  for (i = 0; i < get_irp_n_irgs(); i++)
+    set_irg_visited(get_irp_irg(i), get_max_irg_visited());
+
+  /* Walk starting at unreachable procedures. */
+  for (i = 0; i < get_irp_n_irgs(); i++) {
+    ir_node *sb;
+    current_ir_graph = get_irp_irg(i);
+
+    sb = get_irg_start_block(current_ir_graph);
+    if ((get_Block_n_cfgpreds(sb) > 1) ||
+       (get_nodes_Block(get_Block_cfgpred(sb, 0)) != sb)) continue;
+
+    cg_walk_2(get_irg_end(current_ir_graph), pre, post, env);
+  }
+
+  interprocedural_view = rem_view;
+  current_ir_graph = rem;
+}
+
+
 /***************************************************************************/
 
 /* Walks back from n until it finds a real cf op. */
@@ -210,38 +271,27 @@ ir_node *get_cf_op(ir_node *n) {
 void irg_block_walk_2(ir_node *node, irg_walk_func pre, irg_walk_func post, void *env)
 {
   int i;
-
   assert(get_irn_opcode(node) == iro_Block);
 
   if(get_Block_block_visited(node) < get_irg_block_visited(current_ir_graph)) {
     set_Block_block_visited(node, get_irg_block_visited(current_ir_graph));
 
-    if(pre)
-      pre(node, env);
+    if(pre) pre(node, env);
 
     for(i = get_Block_n_cfgpreds(node) - 1; i >= 0; --i) {
-
       /* find the corresponding predecessor block. */
       ir_node *pred = get_cf_op(get_Block_cfgpred(node, i));
-      /* GL: I'm not sure whether this assert must go through.  There
-         could be Id chains?? Tuple/Proj .... */
-
-      assert(is_cfop(pred)
-                        || is_fragile_op(pred)
-                        || (get_irn_op(pred) == op_Bad));
-
       pred = get_nodes_Block(pred);
       if(get_irn_opcode(pred) == iro_Block) {
        /* recursion */
        irg_block_walk_2(pred, pre, post, env);
       }
       else {
-               assert(get_irn_opcode(pred) == iro_Bad);
+       assert(get_irn_opcode(pred) == iro_Bad);
       }
     }
 
-    if(post)
-      post(node, env);
+    if(post) post(node, env);
   }
   return;
 }
@@ -273,7 +323,8 @@ void irg_block_walk(ir_node *node, irg_walk_func pre, irg_walk_func post, void *
 }
 
 
-void irg_block_walk_graph(ir_graph *irg, irg_walk_func pre, irg_walk_func post, void *env) {
+void irg_block_walk_graph(ir_graph *irg, irg_walk_func pre,
+                         irg_walk_func post, void *env) {
   ir_graph * rem = current_ir_graph;
   current_ir_graph = irg;
   irg_block_walk(get_irg_end(irg), pre, post, env);
@@ -340,6 +391,58 @@ void walk_const_code(irg_walk_func pre, irg_walk_func post, void *env) {
   current_ir_graph = rem;
 }
 
+
+/********************************************************************/
+/** Walking support for interprocedural analysis                   **/
+/**                                                                **/
+/** @@@ Don't use, not operational yet, doesn't grok recursions!!  **/
+/** @@@ Header for irgwalk.h, here until it works. **/
+/**                                                                **/
+/** Interprocedural walking should not walk all predecessors of    **/
+/** all nodes.  When leaving a procedure the walker should only    **/
+/** follow the edge corresponding to the most recent entry of the  **/
+/** procedure.  The following functions use an internal stack to   **/
+/** remember the current call site of a procedure.                 **/
+/** They also set current_ir_graph correctly.                      **/
+/**                                                                **/
+/** Usage example:                                                 **/
+/**                                                                **/
+/** void init_ip_walk ();                                          **/
+/** work_on_graph(some_end_node);                                  **/
+/** void finish_ip_walk();                                         **/
+/**                                                                **/
+/** work_on_graph(ir_node *n) {                                    **/
+/**   for (i = 0; i < get_irn_arity(n); i++) {                     **/
+/**     if (...) continue;                                         **/
+/**     ir_node *m = get_irn_ip_pred(n, i);                        **/
+/**     if !m continue;                                            **/
+/**     work_on_graph(m);                                          **/
+/**     return_recur(n, i);                                        **/
+/**   }                                                            **/
+/** }                                                              **/
+/********************************************************************/
+
+/* Allocates some necessary datastructures. */
+void init_ip_walk ();
+/* Frees some necessary datastructures. */
+void finish_ip_walk();
+
+/* Call for i in {0|-1 ... get_irn_arity(n)}.
+   If n is a conventional node returns the same node as get_irn_n(n, i).
+   If the predecessors of n are in the callee of the procedure n belongs
+   to, returns get_irn_n(n, i) if this node is in the callee on the top
+   of the stack, else returns NULL.
+   If the predecessors of n are in a procedure called by the procedure n
+   belongs to pushes the caller on the caller stack in the callee.
+   Sets current_ir_graph to the graph the node returned is in. */
+ir_node *get_irn_ip_pred(ir_node *n, int pos);
+
+/* If get_irn_ip_pred() returned a node (not NULL) this must be
+   called to clear up the stacks.
+   Sets current_ir_graph to the graph n is in. */
+void return_recur(ir_node *n, int pos);
+
+
 /********************************************************************/
 /** Walking support for interprocedural analysis                   **/
 /********************************************************************/
index 3d217fa..71f6ee7 100644 (file)
@@ -37,9 +37,13 @@ void irg_walk_graph(ir_graph *irg, irg_walk_func pre, irg_walk_func post, void *
 
 /* Executes irg_walk(end, pre, post, env) for all irgraphs in irprog.
    Sets current_ir_graph properly for each walk.  Conserves current
-   current_ir_graph. */
+   current_ir_graph.  In interprocedural view nodes can be visited several
+   times. */
 void all_irg_walk(irg_walk_func pre, irg_walk_func post, void *env);
 
+/* Walks all irgs in interprocedural view.  Visits each node only once.
+   Sets current_ir_graph properly. */
+void cg_walk(irg_walk_func pre, irg_walk_func post, void *env);
 
 /* Walks only over Block nodes in the graph.  Has it's own visited
    flag, so that it can be interleaved with the other walker.
@@ -55,54 +59,5 @@ void irg_block_walk_graph(ir_graph *irg, irg_walk_func pre, irg_walk_func post,
    Uses visited flag in const_code_irg. */
 void walk_const_code(irg_walk_func pre, irg_walk_func post, void *env);
 
-/********************************************************************/
-/** Walking support for interprocedural analysis                   **/
-/**                                                                **/
-/** @@@ Don't use, not operational yet, doesn't grok recursions!!  **/
-/**                                                                **/
-/** Interprocedural walking should not walk all predecessors of    **/
-/** all nodes.  When leaving a procedure the walker should only    **/
-/** follow the edge corresponding to the most recent entry of the  **/
-/** procedure.  The following functions use an internal stack to   **/
-/** remember the current call site of a procedure.                 **/
-/** They also set current_ir_graph correctly.                      **/
-/**                                                                **/
-/** Usage example:                                                 **/
-/**                                                                **/
-/** void init_ip_walk ();                                          **/
-/** work_on_graph(some_end_node);                                  **/
-/** void finish_ip_walk();                                         **/
-/**                                                                **/
-/** work_on_graph(ir_node *n) {                                    **/
-/**   for (i = 0; i < get_irn_arity(n); i++) {                     **/
-/**     if (...) continue;                                         **/
-/**     ir_node *m = get_irn_ip_pred(n, i);                        **/
-/**     if !m continue;                                            **/
-/**     work_on_graph(m);                                          **/
-/**     return_recur(n, i);                                        **/
-/**   }                                                            **/
-/** }                                                              **/
-/********************************************************************/
-
-/* Allocates some necessary datastructures. */
-void init_ip_walk ();
-/* Frees some necessary datastructures. */
-void finish_ip_walk();
-
-/* Call for i in {0|-1 ... get_irn_arity(n)}.
-   If n is a conventional node returns the same node as get_irn_n(n, i).
-   If the predecessors of n are in the callee of the procedure n belongs
-   to, returns get_irn_n(n, i) if this node is in the callee on the top
-   of the stack, else returns NULL.
-   If the predecessors of n are in a procedure called by the procedure n
-   belongs to pushes the caller on the caller stack in the callee.
-   Sets current_ir_graph to the graph the node returned is in. */
-ir_node *get_irn_ip_pred(ir_node *n, int pos);
-
-/* If get_irn_ip_pred() returned a node (not NULL) this must be
-   called to clear up the stacks.
-   Sets current_ir_graph to the graph n is in. */
-void return_recur(ir_node *n, int pos);
-
 
 # endif /* _IRGWALK_H_ */
index 76bf8fa..ffdd0b8 100644 (file)
@@ -123,7 +123,6 @@ unsigned get_mode_ffloat   (ir_mode *mode);
 int mode_is_signed (ir_mode *mode);
 int mode_is_float (ir_mode *mode);
 int mode_is_int (ir_mode *mode);
-# define is_chilCHIL(m) ((m) <= irm_L && (m) >= irm_c) /* old */
 int mode_is_num (ir_mode *mode);
 int mode_is_data (ir_mode *mode);
 int mode_is_datab (ir_mode *mode);
index 78e7a9b..036ee9e 100644 (file)
@@ -258,11 +258,11 @@ set_irn_in (ir_node *node, int arity, ir_node **in) {
    If it is a block, the entry -1 is NULL. */
 INLINE ir_node *
 get_irn_n (ir_node *node, int n) {
-  /* debug @@@ */
+  /* debug @@@
   if (-1 > n || get_irn_arity(node) <= n) {
     printf("pos: %d, arity: %d ", n, get_irn_arity(node));
     DDMN(node);
-  }
+    } */
   assert(node); assert(-1 <= n && n < get_irn_arity(node));
   if (interprocedural_view) { /* handle Filter and Block specially */
     if (get_irn_opcode(node) == iro_Filter) {
@@ -511,13 +511,13 @@ get_Block_n_cfgpreds (ir_node *node) {
 
 INLINE ir_node *
 get_Block_cfgpred (ir_node *node, int pos) {
-  /* debug @@@ */
   assert (node->op == op_Block);
+  /* debug @@@
   if (-1 > pos || get_irn_arity(node) <= pos) {
     dump_ir_block_graph(current_ir_graph);
     printf("pos: %d, arity: %d ", pos, get_irn_arity(node));
     DDMN(node);
-  }
+    } */
   assert(node); assert(-1 <= pos && pos < get_irn_arity(node));
   return get_irn_n(node, pos);
 }
@@ -645,8 +645,8 @@ ir_node ** get_Block_cg_cfgpred_arr(ir_node * node) {
 }
 
 int get_Block_cg_n_cfgpreds(ir_node * node) {
-  assert(node->op == op_Block && node->attr.block.in_cg);
-  return ARR_LEN(node->attr.block.in_cg) - 1;
+  assert(node->op == op_Block);
+  return node->attr.block.in_cg == NULL ? 0 : ARR_LEN(node->attr.block.in_cg) - 1;
 }
 
 ir_node * get_Block_cg_cfgpred(ir_node * node, int pos) {
@@ -2212,6 +2212,12 @@ is_no_Block (ir_node *node) {
   return (get_irn_opcode(node) != iro_Block);
 }
 
+INLINE int
+is_Block (ir_node *node) {
+  assert(node);
+  return (get_irn_opcode(node) == iro_Block);
+}
+
 INLINE int
 is_Proj (ir_node *node) {
   assert(node);
@@ -2227,10 +2233,23 @@ is_cfop(ir_node *node) {
 
 /* Returns true if the operation manipulates interprocedural control flow:
    CallBegin, EndReg, EndExcept */
-int is_ip_cfop(ir_node *node) {
+INLINE int is_ip_cfop(ir_node *node) {
   return is_ip_cfopcode(get_irn_op(node));
 }
 
+ir_graph *get_ip_cfop_irg(ir_node *n) {
+  switch (get_irn_opcode(n)) {
+  case iro_EndReg:
+    return get_EndReg_irg(n);
+  case iro_EndExcept:
+    return get_EndExcept_irg(n);
+  case iro_CallBegin:
+    return get_CallBegin_irg(n);
+  default:
+    assert(is_ip_cfop(n));
+  }
+}
+
 /* Returns true if the operation can change the control flow because
    of an exception. */
 int
index cf4c98b..b1810cc 100644 (file)
@@ -160,13 +160,16 @@ INLINE int       Block_not_block_visited(ir_node *node);
 
 /* Set and remove interprocedural predecessors. If the interprocedural
  * predecessors are removed, the node has the same predecessors in
- * both views. */
+ * both views.
+ * @@@ Maybe better:  arity is zero if no cg preds. */
 void set_Block_cg_cfgpred_arr(ir_node * node, int arity, ir_node ** in);
 void set_Block_cg_cfgpred(ir_node * node, int pos, ir_node * pred);
 /* @@@ not supported */
 ir_node ** get_Block_cg_cfgpred_arr(ir_node * node);
+/* Returns the number of interproc predecessors.  0 if none. */
 int get_Block_cg_n_cfgpreds(ir_node * node);
 ir_node * get_Block_cg_cfgpred(ir_node * node, int pos);
+/* frees the memory. */
 void remove_Block_cg_cfgpred_arr(ir_node * node);
 
 /* exc handling @@@ ajacs specific -- not supported */
@@ -193,7 +196,6 @@ INLINE void set_End_keepalive(ir_node *end, int pos, ir_node *ka);
 INLINE void free_End (ir_node *end);
 
 ir_graph *get_EndReg_irg (ir_node *end);
-
 ir_graph *get_EndExcept_irg  (ir_node *end);
 
 /* We distinguish three kinds of Cond nodes.  These can be distinguished
@@ -452,7 +454,8 @@ INLINE ir_node  *get_Filter_pred(ir_node *node);
 INLINE void      set_Filter_pred(ir_node *node, ir_node *pred);
 INLINE long      get_Filter_proj(ir_node *node);
 INLINE void      set_Filter_proj(ir_node *node, long proj);
-/* set the interprocedural predecessors, ...d_arr uses current_ir_graph. */
+/* set the interprocedural predecessors, ...d_arr uses current_ir_graph.
+ * @@@ Maybe better:  arity is zero if no cg preds. */
 void             set_Filter_cg_pred_arr(ir_node * node, int arity, ir_node ** in);
 void             set_Filter_cg_pred(ir_node * node, int pos, ir_node * pred);
 int              get_Filter_n_cg_preds(ir_node *node);
@@ -533,6 +536,8 @@ INLINE ir_node *skip_Tuple (ir_node *node);
 INLINE int      is_Bad    (ir_node *node);
 /* returns true if the node is not a Block */
 INLINE int      is_no_Block (ir_node *node);
+/* returns true if the node is a Block */
+INLINE int      is_Block (ir_node *node);
 /* returns true if node is a Proj node or a Filter node in
  * intraprocedural view */
 INLINE int      is_Proj (ir_node *node);
@@ -546,6 +551,8 @@ int is_ip_cfop(ir_node *node);
 /* Returns true if the operation can change the control flow because
    of an exception: Call, Quot, DivMod, Div, Mod, Load, Store, Alloc,
    Bad. */
+ir_graph *get_ip_cfop_irg(ir_node *n);
+
 int is_fragile_op(ir_node *node);
 /* Returns the memory operand of fragile operations. */
 ir_node *get_fragile_op_mem(ir_node *node);
index 84e8bac..e2ed9e2 100644 (file)
@@ -180,8 +180,8 @@ computed_value (ir_node *n)
         only 1 is used.
          There are several case where we can evaluate a Cmp node:
          1. The nodes compared are both the same.  If we compare for
-            equal, this will return true, else it will return false.
-            This step relies on cse.
+            equal, greater equal, ... this will return true, else it
+           will return false.  This step relies on cse.
          2. The predecessors of Cmp are target values.  We can evaluate
             the Cmp.
          3. The predecessors are Allocs or void* constants.  Allocs never
@@ -322,7 +322,8 @@ equivalent_node (ir_node *n)
        if ((get_irn_op(a) == op_Proj) &&
            (get_irn_op(b) == op_Proj) &&
            (get_Proj_pred(a) == get_Proj_pred(b)) &&
-           (get_irn_op(get_Proj_pred(a)) == op_Cond)) {
+           (get_irn_op(get_Proj_pred(a)) == op_Cond) &&
+           (get_irn_mode(get_Cond_selector(get_Proj_pred(a))) == mode_b)) {
          /* Also a single entry Block following a single exit Block.  Phis have
             twice the same operand and will be optimized away. */
          n = get_nodes_Block(a);                                         DBG_OPT_IFSIM;
@@ -407,10 +408,11 @@ equivalent_node (ir_node *n)
       set_Tuple_pred(n, 2, a);
     }
     break;
-    /* GL: Why are they skipped?  DivMod allocates new nodes --> it's
-       treated in transform node.
-          case iro_Mod, Quot, DivMod
-    */
+  /*
+  case iro_Mod, Quot, DivMod
+    DivMod allocates new nodes --> it's treated in transform node.
+    What about Quot, DivMod?
+  */
   case iro_And:
     if (a == b) {
       n = a;    /* And has it's own neutral element */
@@ -574,7 +576,7 @@ equivalent_node (ir_node *n)
        }
       } else if (get_irn_mode(n) == mode_X &&
                 is_Bad(get_nodes_Block(n))) {
-        /* Remove dead control flow. */
+        /* Remove dead control flow -- early gigo. */
        n = new_Bad();
       }
     }