sparc: support float perms
[libfirm] / ir / ir / iredges.c
index 1cf1f13..cd99e83 100644 (file)
@@ -51,7 +51,7 @@
 #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 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]))
 
@@ -69,7 +69,7 @@ size_t ir_edgeset_size(const ir_edgeset_t *self);
 #define hashset_iterator_next   ir_edgeset_iterator_next
 #define hashset_remove_iterator ir_edgeset_remove_iterator
 
-#include "hashset.c"
+#include "hashset.c.inl"
 
 /**
  * A function that allows for setting an edge.
@@ -156,17 +156,6 @@ static inline long edge_get_id(const ir_edge_t *e)
        return (long)e;
 }
 
-/**
- * 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.
- */
 size_t edges_register_private_data(size_t n)
 {
        size_t res = edges_private_size;
@@ -177,11 +166,6 @@ size_t edges_register_private_data(size_t n)
        return res;
 }
 
-/*
- * Reset the user's private data at offset 'offset'
- * The user has to remember his offset and the size of his data!
- * Caution: Using wrong values here can destroy other users private data!
- */
 void edges_reset_private_data(ir_graph *irg, int offset, unsigned size)
 {
        irg_edge_info_t       *info = get_irg_edge_info(irg, EDGE_KIND_NORMAL);
@@ -197,12 +181,8 @@ void edges_reset_private_data(ir_graph *irg, int offset, unsigned size)
 
 #define get_irn_out_list_head(irn) (&get_irn_out_info(irn)->outs)
 
-#define edge_hash(edge) (TIMES37((edge)->pos) + HASH_PTR((edge)->src))
+#define edge_hash(edge) (TIMES37((edge)->pos) + hash_ptr((edge)->src))
 
-/**
- * Initialize the out information for a graph.
- * @note Dead node elimination can call this on an already initialized graph.
- */
 void edges_init_graph_kind(ir_graph *irg, ir_edge_kind_t kind)
 {
        if (edges_activated_kind(irg, kind)) {
@@ -222,15 +202,6 @@ void edges_init_graph_kind(ir_graph *irg, ir_edge_kind_t kind)
        }
 }
 
-/**
- * Get the edge object of an outgoing edge at a node.
- * @param  irg  The graph, the node is in.
- * @param  src  The node at which the edge originates.
- * @param  pos  The position of the edge.
- * @param  kind The kind of the edge.
- * @return      The corresponding edge object or NULL,
- *              if no such edge exists.
- */
 const ir_edge_t *get_irn_edge_kind(const ir_node *src, int pos, ir_edge_kind_t kind)
 {
        ir_graph *irg = get_irn_irg(src);
@@ -310,7 +281,6 @@ void edges_dump_kind(ir_graph *irg, ir_edge_kind_t kind)
        }
 }
 
-/* The edge from (src, pos) -> old_tgt is redirected to tgt */
 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)
@@ -442,9 +412,7 @@ void edges_notify_edge(ir_node *src, int pos, ir_node *tgt, ir_node *old_tgt,
                        edges_notify_edge_kind(src, pos, bl_tgt, bl_old, EDGE_KIND_BLOCK, irg);
                } else if (get_irn_mode(src) == mode_X && old_tgt != NULL && is_Block(old_tgt)) {
                        /* moving a jump node from one block to another */
-                       const ir_edge_t *edge;
-                       const ir_edge_t *next;
-                       foreach_out_edge_kind_safe(old_tgt, edge, next, EDGE_KIND_BLOCK) {
+                       foreach_out_edge_kind_safe(old_tgt, edge, EDGE_KIND_BLOCK) {
                                ir_node *succ       = get_edge_src_irn(edge);
                                int      succ_pos   = get_edge_src_pos(edge);
                                ir_node *block_pred = get_Block_cfgpred(succ, succ_pos);
@@ -602,30 +570,30 @@ static void visitor(ir_node *irn, void *data)
        }
 }
 
-/*
- * Build the initial edge set.
- * Beware, this is not a simple task because it suffers from two
- * difficulties:
- * - the anchor set allows access to Nodes that may not be reachable from
- *   the End node
- * - the identities add nodes to the "root set" that are not yet reachable
- *   from End. However, after some transformations, the CSE may revival these
- *   nodes
- *
- * These problems can be fixed using different strategies:
- * - Add an age flag to every node. Whenever the edge of a node is older
- *   then the current edge, invalidate the edges of this node.
- *   While this would help for revivaled nodes, it increases memory and runtime.
- * - Delete the identities set.
- *   Solves the revival problem, but may increase the memory consumption, as
- *   nodes cannot be revivaled at all.
- * - Manually iterate over the identities root set. This did not consume more memory
- *   but increase the computation time because the |identities| >= |V|
- *
- * Currently, we use the last option.
- */
 void edges_activate_kind(ir_graph *irg, ir_edge_kind_t kind)
 {
+       /*
+        * Build the initial edge set.
+        * Beware, this is not a simple task because it suffers from two
+        * difficulties:
+        * - the anchor set allows access to Nodes that may not be reachable from
+        *   the End node
+        * - the identities add nodes to the "root set" that are not yet reachable
+        *   from End. However, after some transformations, the CSE may revival these
+        *   nodes
+        *
+        * These problems can be fixed using different strategies:
+        * - Add an age flag to every node. Whenever the edge of a node is older
+        *   then the current edge, invalidate the edges of this node.
+        *   While this would help for revivaled nodes, it increases memory and runtime.
+        * - Delete the identities set.
+        *   Solves the revival problem, but may increase the memory consumption, as
+        *   nodes cannot be revivaled at all.
+        * - Manually iterate over the identities root set. This did not consume more memory
+        *   but increase the computation time because the |identities| >= |V|
+        *
+        * Currently, we use the last option.
+        */
        struct build_walker w;
        irg_edge_info_t     *info = get_irg_edge_info(irg, kind);
        visitor_info_t      visit;
@@ -661,6 +629,7 @@ void edges_deactivate_kind(ir_graph *irg, ir_edge_kind_t kind)
                ir_edgeset_destroy(&info->edges);
                info->allocated = 0;
        }
+       clear_irg_properties(irg, IR_GRAPH_PROPERTY_CONSISTENT_OUT_EDGES);
 }
 
 int (edges_activated_kind)(const ir_graph *irg, ir_edge_kind_t kind)
@@ -668,14 +637,6 @@ int (edges_activated_kind)(const ir_graph *irg, ir_edge_kind_t kind)
        return edges_activated_kind_(irg, kind);
 }
 
-
-/**
- * Reroute all use-edges from a node to another.
- * @param from The node whose use-edges shall be withdrawn.
- * @param to   The node to which all the use-edges of @p from shall be
- *             sent to.
- * @param irg  The graph.
- */
 void edges_reroute_kind(ir_node *from, ir_node *to, ir_edge_kind_t kind)
 {
        ir_graph *irg = get_irn_irg(from);
@@ -694,6 +655,16 @@ void edges_reroute_kind(ir_node *from, ir_node *to, ir_edge_kind_t kind)
        }
 }
 
+void edges_reroute_except(ir_node *from, ir_node *to, ir_node *exception)
+{
+       foreach_out_edge_safe(from, edge) {
+               ir_node *src = get_edge_src_irn(edge);
+               if (src == exception)
+                       continue;
+               set_irn_n(src, edge->pos, to);
+       }
+}
+
 static void verify_set_presence(ir_node *irn, void *data)
 {
        build_walker *w     = (build_walker*)data;
@@ -718,8 +689,7 @@ static void verify_set_presence(ir_node *irn, void *data)
 
 static void verify_list_presence(ir_node *irn, void *data)
 {
-       build_walker    *w = (build_walker*)data;
-       const ir_edge_t *e;
+       build_walker *w = (build_walker*)data;
 
        bitset_set(w->reachable, get_irn_idx(irn));
 
@@ -825,7 +795,6 @@ static void verify_edge_counter(ir_node *irn, void *env)
        int                    list_cnt;
        int                    ref_cnt;
        int                    edge_cnt;
-       size_t                 idx;
        const struct list_head *head;
        const struct list_head *pos;
        ir_graph               *irg;
@@ -875,9 +844,6 @@ static void verify_edge_counter(ir_node *irn, void *env)
        bitset_free(bs);
 }
 
-/**
- * Verifies the out edges of an irg.
- */
 int edges_verify(ir_graph *irg)
 {
        struct build_walker w;
@@ -913,7 +879,6 @@ static int edges_verify_wrapper(ir_graph *irg, void *context)
        return 0;
 }
 
-/* Creates an ir_graph pass for edges_verify(). */
 ir_graph_pass_t *irg_verify_edges_pass(const char *name, unsigned assert_on_problem)
 {
        pass_t *pass = XMALLOCZ(pass_t);
@@ -943,50 +908,35 @@ void edges_activate(ir_graph *irg)
 {
        edges_activate_kind(irg, EDGE_KIND_NORMAL);
        edges_activate_kind(irg, EDGE_KIND_BLOCK);
-       if (get_irg_phase_state(irg) == phase_backend)
-               edges_activate_kind(irg, EDGE_KIND_DEP);
+       edges_activate_kind(irg, EDGE_KIND_DEP);
 }
 
 void edges_deactivate(ir_graph *irg)
 {
-       if (get_irg_phase_state(irg) == phase_backend)
-               edges_deactivate_kind(irg, EDGE_KIND_DEP);
+       edges_deactivate_kind(irg, EDGE_KIND_DEP);
        edges_deactivate_kind(irg, EDGE_KIND_BLOCK);
        edges_deactivate_kind(irg, EDGE_KIND_NORMAL);
 }
 
-int edges_assure(ir_graph *irg)
+void assure_edges(ir_graph *irg)
 {
-       int activated = 0;
-
-       if (edges_activated_kind(irg, EDGE_KIND_BLOCK)) {
-               activated = 1;
-       } else {
-               edges_activate_kind(irg, EDGE_KIND_BLOCK);
-       }
-       if (edges_activated_kind(irg, EDGE_KIND_NORMAL)) {
-               activated = 1;
-       } else {
-               edges_activate_kind(irg, EDGE_KIND_NORMAL);
-       }
-
-       return activated;
+       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);
 }
 
-int edges_assure_kind(ir_graph *irg, ir_edge_kind_t kind)
+void assure_edges_kind(ir_graph *irg, ir_edge_kind_t kind)
 {
-       int activated = edges_activated_kind(irg, kind);
-
-       if (!activated)
+       if (!edges_activated_kind(irg, kind))
                edges_activate_kind(irg, kind);
-
-       return activated;
 }
 
 void edges_node_deleted(ir_node *irn)
 {
        edges_node_deleted_kind(irn, EDGE_KIND_NORMAL);
        edges_node_deleted_kind(irn, EDGE_KIND_BLOCK);
+       edges_node_deleted_kind(irn, EDGE_KIND_DEP);
 }
 
 void edges_node_revival(ir_node *irn)
@@ -1023,15 +973,13 @@ int (get_irn_n_edges_kind)(const ir_node *irn, ir_edge_kind_t kind)
 static void irg_walk_edges2(ir_node *node, irg_walk_func *pre,
                             irg_walk_func *post, void *env)
 {
-       const ir_edge_t *edge, *next;
-
        if (irn_visited_else_mark(node))
                return;
 
        if (pre != NULL)
                pre(node, env);
 
-       foreach_out_edge_kind_safe(node, edge, next, EDGE_KIND_NORMAL) {
+       foreach_out_edge_kind_safe(node, edge, EDGE_KIND_NORMAL) {
                /* find the corresponding successor block. */
                ir_node *pred = get_edge_src_irn(edge);
                irg_walk_edges2(pred, pre, post, env);
@@ -1060,15 +1008,13 @@ void irg_walk_edges(ir_node *node, irg_walk_func *pre, irg_walk_func *post,
 static void irg_block_edges_walk2(ir_node *bl, irg_walk_func *pre,
                                   irg_walk_func *post, void *env)
 {
-       const ir_edge_t *edge, *next;
-
        if (!Block_block_visited(bl)) {
                mark_Block_block_visited(bl);
 
                if (pre)
                        pre(bl, env);
 
-               foreach_out_edge_kind_safe(bl, edge, next, EDGE_KIND_BLOCK) {
+               foreach_out_edge_kind_safe(bl, edge, EDGE_KIND_BLOCK) {
                        /* find the corresponding successor block. */
                        ir_node *pred = get_edge_src_irn(edge);
                        irg_block_edges_walk2(pred, pre, post, env);