+#include "bitset.h"
+#include "xmalloc.h"
+
+#include "iredgeset.h"
+#include "hashptr.h"
+
+#define DO_REHASH
+#define SCALAR_RETURN
+#define HashSet ir_edgeset_t
+#define HashSetIterator ir_edgeset_iterator_t
+#define ValueType ir_edge_t*
+#define NullValue NULL
+#define DeletedValue ((ir_edge_t*)-1)
+#define Hash(this,key) (HASH_PTR(key->src) ^ (key->pos * 40013))
+#define KeysEqual(this,key1,key2) ((key1->src) == (key2->src) && (key1->pos == key2->pos))
+#define SetRangeEmpty(ptr,size) memset(ptr, 0, (size) * sizeof((ptr)[0]))
+
+#define hashset_init ir_edgeset_init
+#define hashset_init_size ir_edgeset_init_size
+#define hashset_destroy ir_edgeset_destroy
+#define hashset_insert ir_edgeset_insert
+#define hashset_remove ir_edgeset_remove
+#define hashset_find ir_edgeset_find
+#define hashset_size ir_edgeset_size
+#define hashset_iterator_init ir_edgeset_iterator_init
+#define hashset_iterator_next ir_edgeset_iterator_next
+#define hashset_remove_iterator ir_edgeset_remove_iterator
+
+#include "hashset.c"
+
+/**
+ * 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.
+ */
+typedef struct {
+ const char *name; /**< name of this edge kind */
+ set_edge_func_t *set_edge; /**< the set_edge function */
+ int first_idx; /**< index of the first possible edge */
+ get_edge_src_arity_func_t *get_arity; /**< the get_arity function */
+ get_edge_src_n_func_t *get_n; /**< the get_n function */
+} ir_edge_kind_info_t;
+
+/**
+ * Get the predecessor block.
+ */
+static ir_node *get_block_n(const ir_node *irn, int pos) {
+ if (is_Block(irn))
+ return get_Block_cfgpred_block(irn, pos);
+ /* might be a Bad */
+ return NULL;
+}
+
+static const ir_edge_kind_info_t edge_kind_info[EDGE_KIND_LAST] = {
+ { "normal" , set_irn_n, -1, get_irn_arity, get_irn_n },
+ { "block succs", NULL, 0, get_irn_arity, get_block_n },
+ { "dependency", set_irn_dep, 0, get_irn_deps, get_irn_dep }
+};
+
+#define foreach_tgt(irn, i, n, kind) for(i = edge_kind_info[kind].first_idx, n = edge_kind_info[kind].get_arity(irn); i < n; ++i)
+#define get_n(irn, pos, kind) (edge_kind_info[kind].get_n(irn, pos))
+#define get_kind_str(kind) (edge_kind_info[kind].name)
+
+DEBUG_ONLY(static firm_dbg_module_t *dbg;)
+
+/**
+ * This flag is set to 1, if the edges get initialized for an irg.
+ * Then register additional data is forbidden.
+ */
+static int edges_used = 0;
+
+/**
+ * Summed size of all users private data
+ */
+
+static int edges_private_size = 0;
+#define EDGE_SIZE (sizeof(ir_edge_t) + edges_private_size)
+
+/**
+ * If set to 1, the list heads are checked every time an edge is changed.
+ */
+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
+ return e->edge_nr;
+#else /* DEBUG_libfirm */
+ return (long)e;
+#endif /* DEBUG_libfirm */
+}
+
+/**
+ * Announce to reserve extra space for each edge to be allocated.
+ *
+ * @param n: Size of the space to reserve
+ *
+ * @return Offset at which the private data will begin
+ *
+ * Several users can reserve extra space for private usage.
+ * Each user has to remember his given offset and the size of his private data.
+ * To be called before FIRM is initialized.
+ */
+int edges_register_private_data(size_t n) {
+ int res = edges_private_size;
+
+ assert(!edges_used && "you cannot register private edge data, if edges have been initialized");