/*
- * Project: libFIRM
- * File name: ir/ir/iredges.c
- * Purpose: Always available outs.
- * Author: Sebastian Hack
- * Modified by: Michael Beck, Andreas Schoesser
- * Created: 14.1.2005
- * CVS-ID: $Id$
- * Copyright: (c) 1998-2006 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.
*/
/**
- * Always available outs.
- * @author Sebastian Hack
- * @date 14.1.2005
+ * @file
+ * @brief Always available outs.
+ * @author Sebastian Hack, Michael Beck, Andreas Schoesser
+ * @date 14.1.2005
+ * @version $Id$
+ * @summary
+ * This are out-edges (also called def-use edges) that are dynamically
+ * updated as the graph changes.
*/
-
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
-#ifdef HAVE_ALLOCA_H
-#include <alloca.h>
-#endif
-#ifdef HAVE_MALLOC_H
-#include <malloc.h>
-#endif
-
#include "irnode_t.h"
#include "iropt_t.h"
#include "iredgekinds.h"
#include "debug.h"
#include "set.h"
#include "bitset.h"
+#include "xmalloc.h"
/**
-* A function that allows for setting an edge.
-* This abstraction is necessary since different edge kind have
-* different methods of setting edges.
-*/
+ * A function that allows for setting an edge.
+ * This abstraction is necessary since different edge kind have
+ * different methods of setting edges.
+ */
typedef void (set_edge_func_t)(ir_node *src, int pos, ir_node *tgt);
typedef int (get_edge_src_arity_func_t)(const ir_node *src);
typedef ir_node *(get_edge_src_n_func_t)(const ir_node *src, int pos);
/**
-* Additional data for an edge kind.
-*/
+ * Additional data for an edge kind.
+ */
typedef struct {
const char *name;
set_edge_func_t *set_edge;
*/
static int edges_dbg = 0;
+#ifdef DEBUG_libfirm
/* a static variable holding the last number assigned to a new edge */
static long last_edge_num = -1;
+#endif
static INLINE long edge_get_id(const ir_edge_t *e) {
#ifdef DEBUG_libfirm
edge_change_cnt(tgt, kind, +1);
} /* else */
+#ifndef DEBUG_libfirm
/* verify list heads */
if (edges_dbg) {
if (tgt)
if (old_tgt)
vrfy_list_head(old_tgt, kind);
}
+#endif
DBG((dbg, LEVEL_5, "announce out edge: %+F %d-> %+F(%+F): %s\n", src, pos, tgt, old_tgt, msg));
}
int list_cnt;
int ref_cnt;
int edge_cnt;
+ unsigned long idx;
const struct list_head *head;
const struct list_head *pos;
bs = get_irn_link(irn);
list_cnt = 0;
- ref_cnt = bitset_popcnt(bs);
+ ref_cnt = 0;
edge_cnt = _get_irn_edge_info(irn, EDGE_KIND_NORMAL)->out_count;
head = _get_irn_outs_head(irn, EDGE_KIND_NORMAL);
list_cnt++;
}
+ /* check all nodes that reference us and count edges that point number
+ * of ins that actually point to us */
+ ref_cnt = 0;
+ bitset_foreach(bs, idx) {
+ int i, arity;
+ ir_node *src = get_idx_irn(w->irg, idx);
+
+ arity = get_irn_arity(src);
+ for(i = 0; i < arity; ++i) {
+ ir_node *in = get_irn_n(src, i);
+ if(in == irn)
+ ref_cnt++;
+ }
+ }
+
if (edge_cnt != list_cnt) {
w->problem_found = 1;
ir_fprintf(stderr, "Edge Verifier: edge count is %d, but %d edge(s) are recorded in list at %+F\n",
}
if (ref_cnt != list_cnt) {
- unsigned long idx;
-
w->problem_found = 1;
- ir_fprintf(stderr, "Edge Verifier: %+F reachable by %d node(s), but %d edge(s) recorded in list\n",
+ ir_fprintf(stderr, "Edge Verifier: %+F reachable by %d node(s), but the list contains %d edge(s)\n",
irn, ref_cnt, list_cnt);
+ /* Matze: buggy if a node has multiple ins pointing at irn */
+#if 0
list_for_each(pos, head) {
ir_edge_t *edge = list_entry(pos, ir_edge_t, list);
bitset_flip(bs, get_irn_idx(edge->src));
ir_fprintf(stderr, " %+F", src);
}
fprintf(stderr, "\n");
+#endif
}
bitset_free(bs);
struct build_walker w;
int problem_found = 0;
- if (! edges_dbg)
- return 0;
-
/* verify normal edges only */
problem_found = edges_verify_kind(irg, EDGE_KIND_NORMAL);