- dag_env_t *dag_env = env;
- int i, arity;
- ir_node *block;
- dag_link_t *link;
-
- if (is_Block(node))
- return;
-
- block = get_nodes_block(node);
-
- /* ignore start end end blocks */
- if (block == get_irg_start_block(current_ir_graph) ||
- block == get_irg_end_block(current_ir_graph))
- return;
-
- link = get_irn_link(node);
-
- if (! link) {
- /* not assigned node found, maybe a new root */
- dag_entry_t *entry = obstack_alloc(&dag_env->obst, sizeof(*entry));
-
- link = obstack_alloc(&dag_env->obst, sizeof(*link));
- link->entry = entry;
-
- entry->num_nodes = 1;
- entry->num_roots = 1;
- entry->num_inner_nodes = 0;
- entry->root = node;
- entry->is_dead = 0;
- entry->next = dag_env->list_of_dags;
-
- ++dag_env->num_of_dags;
- dag_env->list_of_dags = entry;
-
- set_irn_link(node, link);
- }
-
- /* put the predecessors into the same DAG as the current */
- for (i = 0, arity = get_irn_arity(node); i < arity; ++i) {
- ir_node *prev = get_irn_n(node, i);
- int special = 0;
-
- /*
- * copy constants if requested into the DAG's
- * beware, do NOT add a link, as this will result in
- * wrong intersections
- */
- if (dag_env->options & FIRMSTAT_COPY_CONSTANTS) {
- if (get_irn_op(prev) == op_Const || get_irn_op(prev) == op_SymConst) {
- ++link->entry->num_nodes;
- ++link->entry->num_inner_nodes;
- }
- }
-
- if (get_nodes_block(prev) == block) {
- dag_link_t *prev_link = get_irn_link(prev);
-
- if (! prev_link) {
- /* not assigned node, do it */
- set_irn_link(prev, link);
- ++link->entry->num_nodes;
- ++link->entry->num_inner_nodes;
- }
- else if (prev_link->entry != link->entry) {
- /* two DAGs intersect */
-
- assert(link->entry);
-
- link->entry->num_roots += prev_link->entry->num_roots;
- link->entry->num_nodes += prev_link->entry->num_nodes;
- link->entry->num_inner_nodes += prev_link->entry->num_inner_nodes;
-
- --dag_env->num_of_dags;
-
- prev_link->entry->is_dead = 1;
- prev_link->entry = link->entry;
- }
- }
- }
-}
+ dag_env_t *dag_env = env;
+ int i, arity;
+ ir_node *block;
+ dag_entry_t *entry;
+ ir_mode *mode;
+
+ if (is_Block(node))
+ return;
+
+ block = get_nodes_block(node);
+
+ /* ignore start end end blocks */
+ if (block == get_irg_start_block(current_ir_graph) ||
+ block == get_irg_end_block(current_ir_graph)) {
+ return;
+ } /* if */
+
+ /* ignore Phi nodes */
+ if (is_Phi(node))
+ return;
+
+ if (dag_env->options & FIRMSTAT_ARGS_ARE_ROOTS && is_arg(node))
+ return;
+
+ mode = get_irn_mode(node);
+ if (mode == mode_X || mode == mode_M) {
+ /* do NOT count mode_X and mode_M nodes */
+ return;
+ } /* if */
+
+ /* if this option is set, Loads are always leaves */
+ if (dag_env->options & FIRMSTAT_LOAD_IS_LEAVE && is_Load(node))
+ return;
+
+ if (dag_env->options & FIRMSTAT_CALL_IS_LEAVE && is_Call(node))
+ return;
+
+ entry = get_irn_dag_entry(node);
+
+ if (! entry) {
+ /* found an unassigned node, maybe a new root */
+ entry = new_dag_entry(dag_env, node);
+ } /* if */
+
+ /* put the predecessors into the same DAG as the current */
+ for (i = 0, arity = get_irn_arity(node); i < arity; ++i) {
+ ir_node *prev = get_irn_n(node, i);
+ ir_mode *mode = get_irn_mode(prev);
+
+ if (is_Phi(prev))
+ continue;
+
+ if (mode == mode_X || mode == mode_M)
+ continue;
+
+ /*
+ * copy constants if requested into the DAG's
+ * beware, do NOT add a link, as this will result in
+ * wrong intersections
+ */
+ if (dag_env->options & FIRMSTAT_COPY_CONSTANTS) {
+ if (is_irn_constlike(prev)) {
+ ++entry->num_nodes;
+ ++entry->num_inner_nodes;
+ } /* if */
+ } /* if */
+
+ /* only nodes from the same block goes into the DAG */
+ if (get_nodes_block(prev) == block) {
+ dag_entry_t *prev_entry = get_irn_dag_entry(prev);
+
+ if (! prev_entry) {
+ /* not assigned node, put it into the same DAG */
+ set_irn_dag_entry(prev, entry);
+ ++entry->num_nodes;
+ ++entry->num_inner_nodes;
+ } else {
+ if (prev_entry == entry) {
+ /* We found a node that is already assigned to this DAG.
+ This DAG is not a tree. */
+ entry->is_tree = 0;
+ } else {
+ /* two DAGs intersect: copy the data to one of them
+ and kill the other */
+ entry->num_roots += prev_entry->num_roots;
+ entry->num_nodes += prev_entry->num_nodes;
+ entry->num_inner_nodes += prev_entry->num_inner_nodes;
+ entry->is_tree &= prev_entry->is_tree;
+
+ --dag_env->num_of_dags;
+
+ prev_entry->is_dead = 1;
+ prev_entry->link = entry;
+ } /* if */
+ } /* if */
+ } /* if */
+ } /* for */
+} /* connect_dags */
+
+#define DEFAULT_RET 1
+#define COLOR_RET 1
+
+static unsigned mark_options;