Commit 34c76679 authored by Christoph Mallon's avatar Christoph Mallon
Browse files

ir: Remove dependency edges.

parent 1ae6d18b
......@@ -21,8 +21,7 @@ typedef enum ir_edge_kind_t {
EDGE_KIND_NORMAL, /**< Normal data flow edges. */
EDGE_KIND_FIRST = EDGE_KIND_NORMAL,
EDGE_KIND_BLOCK, /**< Block to Block control flow edges. */
EDGE_KIND_DEP, /**< Dependency edges. */
EDGE_KIND_LAST = EDGE_KIND_DEP,
EDGE_KIND_LAST = EDGE_KIND_BLOCK,
} ir_edge_kind_t;
ENUM_COUNTABLE(ir_edge_kind_t)
......
......@@ -173,27 +173,6 @@ FIRM_API void walk_const_code(irg_walk_func *pre, irg_walk_func *post,
FIRM_API void irg_walk_blkwise_graph(ir_graph *irg, irg_walk_func *pre,
irg_walk_func *post, void *env);
/**
* Walks over reachable nodes in block-wise topological order, i.e. visit
* all nodes in a block before going to another block, starting at the end operation.
* Executes pre before visiting the predecessor of a node, post after.
* irg_walk_blkwise_graph() uses the visited flag in irg and the nodes to
* determine visited nodes.
* It executes inc_irg_visited() to generate a new flag. It marks the node as
* visited before executing pre.
* The void *env can be used to pass status information between the
* pre and post functions. Does not use the link fields.
* This walker also follows dependency edges.
*
* @param irg the irg graph
* @param pre walker function, executed before the predecessor of a node are visited
* @param post walker function, executed after the predecessor of a node are visited
* @param env environment, passed to pre and post
*/
FIRM_API void irg_walk_in_or_dep_blkwise_graph(ir_graph *irg,
irg_walk_func *pre,
irg_walk_func *post, void *env);
/**
* Walks over reachable nodes in block-wise topological order, i.e. visit
* all nodes in a block before going to another block, starting at the end operation.
......
......@@ -62,56 +62,6 @@ FIRM_API ir_node *get_irn_n(const ir_node *node, int n);
* the nodes opcode. */
FIRM_API void set_irn_in(ir_node *node, int arity, ir_node *const in[]);
/**
* Add an artificial dependency to the node.
*
* @param node The node.
* @param dep The dependency target.
*/
FIRM_API void add_irn_dep(ir_node *node, ir_node *dep);
/**
* Copy all dependencies from a node to another.
* This is only allowed in phase_backend!
*
* @param tgt The node which should be enriched.
* @param src The node whose dependencies shall be copied.
*/
FIRM_API void add_irn_deps(ir_node *tgt, ir_node const *src);
/**
* Returns the number of dependency predecessors/edges of node @p node.
* @param node The node.
* @return The length of the dependency array or 0 if it has not yet been
* allocated.
*/
FIRM_API int get_irn_n_deps(const ir_node *node);
/**
* Returns an entry of the dependency array.
* @param node The node.
* @param pos The position.
* @return The node at that position.
*/
FIRM_API ir_node *get_irn_dep(const ir_node *node, int pos);
/**
* Sets an entry of the dependency array.
* @param node The node.
* @param pos The position.
* @param dep The dependency target.
*/
FIRM_API void set_irn_dep(ir_node *node, int pos, ir_node *dep);
/**
* Deletes the entry of the dependency array, that points to dep. Does nothing
* if no dependency exists.
*
* @param node the node to delete the dependency at
* @param dep the target of the dependency to delete
*/
FIRM_API void delete_irn_dep(ir_node *node, ir_node *dep);
/** Replaces the n-th predecessor of a node with a new one. */
FIRM_API void set_irn_n(ir_node *node, int n, ir_node *in);
/**
......
......@@ -92,8 +92,7 @@ static bool search(ir_heights_t *h, const ir_node *curr, const ir_node *tgt)
h_curr->visited = h->visited;
/* Start a search from this node. */
for (int i = 0, n = get_irn_ins_or_deps(curr); i < n; ++i) {
ir_node *op = get_irn_in_or_dep(curr, i);
foreach_irn_in(curr, i, op) {
if (search(h, op, tgt))
return true;
}
......@@ -145,16 +144,6 @@ static unsigned compute_height(ir_heights_t *h, ir_node *irn, const ir_node *bl)
}
}
foreach_out_edge_kind(irn, edge, EDGE_KIND_DEP) {
ir_node *dep = get_edge_src_irn(edge);
assert(!is_Phi(dep));
if (!is_Block(dep) && get_nodes_block(dep) == bl) {
unsigned dep_height = compute_height(h, dep, bl);
ih->height = MAX(ih->height, dep_height+1);
}
}
return ih->height;
}
......@@ -170,13 +159,6 @@ static unsigned compute_heights_in_block(ir_node *bl, ir_heights_t *h)
max_height = MAX(curh, max_height);
}
foreach_out_edge_kind(bl, edge, EDGE_KIND_DEP) {
ir_node *dep = get_edge_src_irn(edge);
int curh = compute_height(h, dep, bl);
max_height = MAX(curh, max_height);
}
return max_height;
}
......
......@@ -76,9 +76,6 @@ static bool can_move(ir_node *node, ir_node *after)
ir_node *node_block = get_nodes_block(node);
assert(node_block == get_nodes_block(after));
/* TODO respect dep edges */
assert(get_irn_n_edges_kind(node, EDGE_KIND_DEP) == 0);
/** all users have to be after the after node */
foreach_out_edge(node, edge) {
ir_node *out = get_edge_src_irn(edge);
......
......@@ -100,12 +100,6 @@ static void try_make_ready(ir_node *node)
&& !is_available(op))
return;
}
for (int i = 0, n_deps = get_irn_n_deps(node); i < n_deps; ++i) {
ir_node *op = get_irn_dep(node, i);
if (!is_Block(op) && get_nodes_block(op) == current_block
&& !is_available(op))
return;
}
}
node_ready(node);
}
......@@ -123,12 +117,6 @@ static void make_available(ir_node *node)
&& !is_Phi(user))
try_make_ready(user);
}
foreach_out_edge_kind(node, edge, EDGE_KIND_DEP) {
ir_node *user = get_edge_src_irn(edge);
if (!is_Block(user) && get_nodes_block(user) == current_block
&& !is_Phi(user))
try_make_ready(user);
}
}
static void maybe_add_cfop(void)
......
......@@ -52,20 +52,6 @@ bool be_is_transformed(const ir_node *node)
return irn_visited(node);
}
/**
* Duplicate all dependency edges of a node.
*/
static void be_duplicate_deps(ir_node *old_node, ir_node *new_node)
{
int deps = get_irn_n_deps(old_node);
for (int i = 0; i < deps; ++i) {
ir_node *dep = get_irn_dep(old_node, i);
ir_node *new_dep = be_transform_node(dep);
add_irn_dep(new_node, new_dep);
}
}
ir_node *be_transform_phi(ir_node *node, const arch_register_req_t *req)
{
ir_node *block = be_transform_node(get_nodes_block(node));
......@@ -79,7 +65,6 @@ ir_node *be_transform_phi(ir_node *node, const arch_register_req_t *req)
ir_mode *mode = req->cls != NULL ? req->cls->mode : get_irn_mode(node);
ir_node *phi = new_ir_node(dbgi, irg, block, op_Phi, mode, arity, ins);
copy_node_attr(irg, node, phi);
be_duplicate_deps(node, phi);
backend_info_t *info = be_get_info(phi);
struct obstack *obst = be_get_be_obst(irg);
......@@ -137,7 +122,6 @@ static ir_node *transform_end(ir_node *node)
ir_node *block = be_transform_node(get_nodes_block(node));
ir_node *new_end = new_ir_node(dbgi, irg, block, op_End, mode_X, -1, NULL);
copy_node_attr(irg, node, new_end);
be_duplicate_deps(node, new_end);
set_irg_end(irg, new_end);
......@@ -184,8 +168,6 @@ ir_node *be_duplicate_node(ir_node *const node)
ir_node *const block = be_transform_node(get_nodes_block(node));
ir_node *const new_node = new_similar_node(node, block, ins);
be_duplicate_deps(node, new_node);
new_node->node_nr = node->node_nr;
return new_node;
}
......@@ -260,19 +242,6 @@ static void fix_loops(ir_node *node)
changed = true;
}
for (int i = 0, arity = get_irn_n_deps(node); i < arity; ++i) {
ir_node *in = get_irn_dep(node, i);
ir_node *nw = (ir_node*)get_irn_link(in);
if (nw != NULL && nw != in) {
set_irn_dep(node, i, nw);
in = nw;
changed = true;
}
fix_loops(in);
}
if (changed) {
identify_remember(node);
}
......
......@@ -61,9 +61,6 @@ ir_node *irn_copy_into_irg(const ir_node *node, ir_graph *irg)
/* copy the attributes */
copy_node_attr(irg, node, res);
/* duplicate dependency edges */
add_irn_deps(res, node);
return res;
}
......@@ -91,12 +88,6 @@ void irn_rewire_inputs(ir_node *node)
set_irn_n(new_node, i, new_in);
}
for (int i = 0, n_deps = get_irn_n_deps(new_node); i < n_deps; ++i) {
ir_node *dep = get_irn_dep(node, i);
ir_node *new_dep = get_new_node(dep);
set_irn_dep(new_node, i, new_dep);
}
/* Now the new node is complete. We can add it to the hash table for CSE. */
add_identities(new_node);
}
......@@ -1153,25 +1153,6 @@ void dump_ir_data_edges(FILE *F, const ir_node *n)
return;
}
/* dump the dependency edges. */
for (int i = 0, n_deps = get_irn_n_deps(n); i < n_deps; ++i) {
ir_node *dep = get_irn_dep(n, i);
if (dep) {
print_node_edge_kind(F, n);
fprintf(F, "{sourcename: ");
print_nodeid(F, n);
fprintf(F, " targetname: ");
if ((get_opt_dump_const_local()) && is_irn_constlike(dep)) {
print_constid(F, n, dep);
} else {
print_nodeid(F, dep);
}
fprintf(F, " label: \"%d\" ", i);
fprintf(F, " color: darkgreen}\n");
}
}
foreach_irn_in(n, i, pred) {
if ((flags & ir_dump_flag_back_edges) && is_backedge(n, i)) {
fprintf(F, "backedge: {sourcename: ");
......
......@@ -114,7 +114,6 @@ static ir_node *get_irn_safe_n(const ir_node *node, int n)
static const ir_edge_kind_info_t edge_kind_info[EDGE_KIND_LAST+1] = {
{ "normal" , set_irn_n, -1, get_irn_arity, get_irn_safe_n },
{ "block succs", NULL, 0, get_irn_arity, get_block_n },
{ "dependency", set_irn_dep, 0, get_irn_n_deps, get_irn_dep }
};
#define foreach_tgt(irn, i, n, kind) for (int i = edge_kind_info[kind].first_idx, n = edge_kind_info[kind].get_arity(irn); i < n; ++i)
......@@ -275,9 +274,7 @@ static void delete_edge(ir_node *src, int pos, ir_node *old_tgt,
edge_change_cnt(old_tgt_info, -1);
}
void edges_notify_edge_kind(ir_node *src, int pos, ir_node *tgt,
ir_node *old_tgt, ir_edge_kind_t kind,
ir_graph *irg)
static void edges_notify_edge_kind(ir_node *src, int pos, ir_node *tgt, ir_node *old_tgt, ir_edge_kind_t kind, ir_graph *irg)
{
assert(edges_activated_kind(irg, kind));
if (old_tgt == NULL) {
......@@ -454,38 +451,6 @@ static void init_lh_walker(ir_node *irn, void *data)
get_irn_edge_info(irn, kind)->out_count = 0;
}
/**
* Pre-Walker: initializes the list-heads and set the out-count
* of all nodes to 0.
*
* Additionally touches DEP nodes, as they might be DEAD.
* THIS IS UGLY, but I don't find a better way until we
*
* a) ensure that dead nodes are not used as input
* b) it might be sufficient to add those stupid NO_REG nodes
* to the anchor
*/
static void init_lh_walker_dep(ir_node *irn, void *data)
{
build_walker *w = (build_walker*)data;
ir_edge_kind_t kind = w->kind;
list_head *head = &get_irn_edge_info(irn, kind)->outs_head;
INIT_LIST_HEAD(head);
get_irn_edge_info(irn, kind)->edges_built = 0;
get_irn_edge_info(irn, kind)->out_count = 0;
for (int i = get_irn_n_deps(irn) - 1; i >= 0; --i) {
ir_node *dep = get_irn_dep(irn, i);
head = &get_irn_edge_info(dep, kind)->outs_head;
INIT_LIST_HEAD(head);
get_irn_edge_info(dep, kind)->edges_built = 0;
get_irn_edge_info(dep, kind)->out_count = 0;
}
}
void edges_activate_kind(ir_graph *irg, ir_edge_kind_t kind)
{
/*
......@@ -517,12 +482,7 @@ void edges_activate_kind(ir_graph *irg, ir_edge_kind_t kind)
info->activated = 1;
edges_init_graph_kind(irg, kind);
if (kind == EDGE_KIND_DEP) {
irg_walk_anchors(irg, init_lh_walker_dep, NULL, &w);
/* Argh: Dep nodes might be dead, so we MUST visit identities first */
visit_all_identities(irg, init_lh_walker_dep, &w);
irg_walk_anchors(irg, NULL, build_edges_walker, &w);
} else if (kind == EDGE_KIND_BLOCK) {
if (kind == EDGE_KIND_BLOCK) {
visit_all_identities(irg, init_lh_walker, &w);
irg_block_walk_graph(irg, init_lh_walker, build_edges_walker, &w);
} else {
......@@ -785,12 +745,10 @@ void edges_activate(ir_graph *irg)
{
edges_activate_kind(irg, EDGE_KIND_NORMAL);
edges_activate_kind(irg, EDGE_KIND_BLOCK);
edges_activate_kind(irg, EDGE_KIND_DEP);
}
void edges_deactivate(ir_graph *irg)
{
edges_deactivate_kind(irg, EDGE_KIND_DEP);
edges_deactivate_kind(irg, EDGE_KIND_BLOCK);
edges_deactivate_kind(irg, EDGE_KIND_NORMAL);
}
......@@ -799,7 +757,6 @@ void assure_edges(ir_graph *irg)
{
assure_edges_kind(irg, EDGE_KIND_BLOCK);
assure_edges_kind(irg, EDGE_KIND_NORMAL);
assure_edges_kind(irg, EDGE_KIND_DEP);
add_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES);
}
......@@ -812,7 +769,6 @@ void assure_edges_kind(ir_graph *irg, ir_edge_kind_t kind)
void edges_node_deleted(ir_node *irn)
{
edges_node_deleted_kind(irn, EDGE_KIND_NORMAL);
edges_node_deleted_kind(irn, EDGE_KIND_DEP);
if (is_Block(irn)) {
edges_node_deleted_kind(irn, EDGE_KIND_BLOCK);
}
......
......@@ -55,11 +55,7 @@ void exchange(ir_node *old, ir_node *nw)
/* If new outs are on, we can skip the id node creation and reroute
* the edges from the old node to the new directly. */
if (edges_activated(irg)) {
/* copy all dependencies from old to new */
add_irn_deps(nw, old);
edges_reroute(old, nw);
edges_reroute_kind(old, nw, EDGE_KIND_DEP);
edges_node_deleted(old);
/* noone is allowed to reference this node anymore */
set_irn_op(old, op_Deleted);
......
......@@ -158,8 +158,7 @@ static void irg_walk_in_or_dep_2_pre(ir_node *node, irg_walk_func *pre,
if (pred->visited < visited)
irg_walk_in_or_dep_2_pre(pred, pre, env);
}
for (int i = get_irn_ins_or_deps(node); i-- > 0; ) {
ir_node *pred = get_irn_in_or_dep(node, i);
foreach_irn_in_r(node, i, pred) {
if (pred->visited < visited)
irg_walk_in_or_dep_2_pre(pred, pre, env);
}
......@@ -181,8 +180,7 @@ static void irg_walk_in_or_dep_2_post(ir_node *node, irg_walk_func *post,
if (pred->visited < visited)
irg_walk_in_or_dep_2_post(pred, post, env);
}
for (int i = get_irn_ins_or_deps(node); i-- > 0; ) {
ir_node *pred = get_irn_in_or_dep(node, i);
foreach_irn_in_r(node, i, pred) {
if (pred->visited < visited)
irg_walk_in_or_dep_2_post(pred, post, env);
}
......@@ -208,8 +206,7 @@ static void irg_walk_in_or_dep_2_both(ir_node *node, irg_walk_func *pre,
if (pred->visited < visited)
irg_walk_in_or_dep_2_both(pred, pre, post, env);
}
for (int i = get_irn_ins_or_deps(node); i-- > 0; ) {
ir_node *pred = get_irn_in_or_dep(node, i);
foreach_irn_in_r(node, i, pred) {
if (pred->visited < visited)
irg_walk_in_or_dep_2_both(pred, pre, post, env);
}
......
......@@ -17,19 +17,13 @@
#include "hashptr.h"
#include "ircons.h"
#define _get_walk_arity(env, node) \
((env)->follow_deps ? get_irn_ins_or_deps((node)) : get_irn_arity((node)))
#define _get_walk_irn_n(env, node, pos) \
((env)->follow_deps ? get_irn_in_or_dep((node), (pos)) : get_irn_n((node), (pos)))
/**
* Metadata for block walker.
*/
typedef struct blk_collect_data_t {
struct obstack obst; /**< obstack to allocate objects on */
pset *blk_map; /**< Hash map: Block -> List */
ir_node **blk_list; /**< the Block list */
bool follow_deps; /**< follow dependency edges */
struct obstack obst; /**< obstack to allocate objects on */
pset *blk_map; /**< Hash map: Block -> List */
ir_node **blk_list; /**< the Block list */
} blk_collect_data_t;
/**
......@@ -262,8 +256,7 @@ static void collect_walk(ir_node *node, blk_collect_data_t *env)
if (is_Block(node)) {
/* predecessors of a block are control flow nodes */
for (int i = _get_walk_arity(env, node) - 1; i >= 0; --i) {
ir_node *pred = _get_walk_irn_n(env, node, i);
foreach_irn_in_r(node, i, pred) {
if (irn_visited(pred))
continue;
......@@ -286,8 +279,7 @@ static void collect_walk(ir_node *node, blk_collect_data_t *env)
collect_walk(block, env);
bool is_phi = is_Phi(node);
for (int i = _get_walk_arity(env, node) - 1; i >= 0; --i) {
ir_node *pred = _get_walk_irn_n(env, node, i);
foreach_irn_in_r(node, i, pred) {
if (irn_visited(pred))
continue;
......@@ -322,8 +314,7 @@ static void collect_blks_lists(ir_node *node, ir_node *block,
* outside the current block because Phi edges are always
* "outside". */
if (!is_Phi(node)) {
for (int i = _get_walk_arity(env, node) - 1; i >= 0; --i) {
ir_node *pred = _get_walk_irn_n(env, node, i);
foreach_irn_in_r(node, i, pred) {
/* BEWARE: predecessors of End nodes might be blocks */
if (is_Block(pred))
continue;
......@@ -371,7 +362,7 @@ static void collect_lists(ir_graph *const irg, blk_collect_data_t *const env)
* Intra procedural graph walker over blocks.
*/
static void do_irg_walk_blk(ir_graph *irg, irg_walk_func *pre,
irg_walk_func *post, void *env, bool follow_deps,
irg_walk_func *post, void *env,
void (*traverse)(ir_graph *irg,
blk_collect_data_t* blks,
irg_walk_func *pre,
......@@ -379,9 +370,8 @@ static void do_irg_walk_blk(ir_graph *irg, irg_walk_func *pre,
{
blk_collect_data_t blks;
obstack_init(&blks.obst);
blks.blk_map = new_pset(addr_cmp, 1);
blks.blk_list = NEW_ARR_F(ir_node *, 0);
blks.follow_deps = follow_deps;
blks.blk_map = new_pset(addr_cmp, 1);
blks.blk_list = NEW_ARR_F(ir_node*, 0);
/* first step: traverse the graph and fill the lists */
ir_reserve_resources(irg, IR_RESOURCE_IRN_VISITED);
......@@ -413,19 +403,12 @@ void irg_walk_blkwise_graph(ir_graph *irg, irg_walk_func *pre,
irg_walk_func *post, void *env)
{
hook_irg_walk_blkwise(irg, (generic_func*)pre, (generic_func*)post);
do_irg_walk_blk(irg, pre, post, env, false, traverse_blocks);
}
void irg_walk_in_or_dep_blkwise_graph(ir_graph *irg, irg_walk_func *pre,
irg_walk_func *post, void *env)
{
hook_irg_walk_blkwise(irg, (generic_func*)pre, (generic_func*)post);
do_irg_walk_blk(irg, pre, post, env, true, traverse_blocks);
do_irg_walk_blk(irg, pre, post, env, traverse_blocks);
}
void irg_walk_blkwise_dom_top_down(ir_graph *irg, irg_walk_func *pre,
irg_walk_func *post, void *env)
{
hook_irg_walk_blkwise(irg, (generic_func*)pre, (generic_func*)post);
do_irg_walk_blk(irg, pre, post, env, false, traverse_dom_blocks_top_down);
do_irg_walk_blk(irg, pre, post, env, traverse_dom_blocks_top_down);
}
......@@ -89,7 +89,6 @@ ir_node *new_ir_node(dbg_info *db, ir_graph *irg, ir_node *block, ir_op *op,
res->visited = 0;
res->node_idx = irg_register_node_idx(irg, res);
res->link = NULL;
res->deps = NULL;
if (arity < 0) {
res->in = NEW_ARR_F(ir_node *, 1); /* 1: space for block */
......@@ -248,60 +247,6 @@ void remove_Sync_n(ir_node *n, int i)
remove_irn_n(n, i);
}
int (get_irn_n_deps)(const ir_node *node)
{
return get_irn_n_deps_(node);
}
ir_node *(get_irn_dep)(const ir_node *node, int pos)
{
return get_irn_dep_(node, pos);
}
void set_irn_dep(ir_node *node, int pos, ir_node *dep)
{
assert(node->deps != NULL);
assert(pos >= 0 && pos < (int)ARR_LEN(node->deps));
assert(dep != NULL);
ir_node *old = node->deps[pos];
node->deps[pos] = dep;
ir_graph *irg = get_irn_irg(node);
if (edges_activated_kind(irg, EDGE_KIND_DEP))
edges_notify_edge_kind(node, pos, dep, old, EDGE_KIND_DEP, irg);
}
void add_irn_dep(ir_node *node, ir_node *dep)
{
assert(dep != NULL);
if (node->deps == NULL)
node->deps = NEW_ARR_F(ir_node *, 0);
ARR_APP1(ir_node*, node->deps, dep);
ir_graph *irg = get_irn_irg(node);
if (edges_activated_kind(irg, EDGE_KIND_DEP))
edges_notify_edge_kind(node, ARR_LEN(node->deps)-1, dep, NULL, EDGE_KIND_DEP, irg);
}
void delete_irn_dep(ir_node *node, ir_node *dep)
{
if (node->deps == NULL)
return;
for (size_t i = 0, n_deps = ARR_LEN(node->deps); i < n_deps; ++i) {
if (node->deps[i] == dep) {
set_irn_dep(node, i, node->deps[n_deps-1]);
edges_notify_edge(node, i, NULL, dep, get_irn_irg(node));
ARR_SHRINKLEN(node->deps, n_deps-1);
break;
}
}
}
void add_irn_deps(ir_node *const tgt, ir_node const *const src)
{
for (int i = 0, n = get_irn_n_deps(src); i < n; ++i)
add_irn_dep(tgt, get_irn_dep(src, i));
}
ir_mode *(get_irn_mode)(const ir_node *node)
{
......
......@@ -59,12 +59,6 @@
#define get_irn_generic_attr_const(node) get_irn_generic_attr_const_(node)
#define get_irn_idx(node) get_irn_idx_(node)
#define get_irn_n_deps(node) get_irn_n_deps_(node)
#define get_irn_dep(node, pos) get_irn_dep_(node, pos)
#define get_irn_ins_or_deps(node) get_irn_ins_or_deps_(node)
#define get_irn_in_or_dep(node, pos) get_irn_in_or_dep_(node, pos)
#define get_irn_dbg_info(node) get_irn_dbg_info_(node)
#define set_irn_dbg_info(node, db) set_irn_dbg_info_(node, db)
......@@ -177,31 +171,6 @@ static inline unsigned hash_irn(const ir_node *node)
return (unsigned) get_irn_idx(node);
}
static inline int get_irn_n_deps_(const ir_node *node)
{
return node->deps ? (int)ARR_LEN(node->deps) : 0;
}
static inline ir_node *get_irn_dep_(const ir_node *node, int pos)
{
assert(pos >= 0 && pos < (int)ARR_LEN(node->deps) && "dependency index out of range");
return node->deps[pos];
}