Add get_block and set_block operations.
authorMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Fri, 13 Jul 2007 13:34:36 +0000 (13:34 +0000)
committerMichael Beck <beck@ipd.info.uni-karlsruhe.de>
Fri, 13 Jul 2007 13:34:36 +0000 (13:34 +0000)
Proj's are now automatically in the block of it's predecessor
get_nodes_block() is free of special cases ...

[r15115]

include/libfirm/irop.h
ir/ir/irgopt.c
ir/ir/irnode.c
ir/ir/irnode_t.h
ir/ir/iropt.c

index 1f92e19..b4a3ee5 100644 (file)
@@ -223,6 +223,19 @@ op_func get_generic_function_ptr(const ir_op *op);
  */
 void set_generic_function_ptr(ir_op *op, op_func func);
 
+/**
+ * The get_nodes_block operation.
+ * This operation returns the block of a node.
+ * For block nodes, it returns its Macroblock header.
+ */
+typedef ir_node *(*get_block_func)(const ir_node *self);
+
+/**
+ * The set_nodes_block operation.
+ * This operation sets the block of a node.
+ */
+typedef void (*set_block_func)(ir_node *self, ir_node *block);
+
 /**
  * The compute value operation.
  * This operation evaluates an IR node into a tarval if possible,
@@ -331,19 +344,21 @@ typedef int (*dump_node_func)(ir_node *self, FILE *F, dump_reason_t reason);
  * io_op Operations.
  */
 typedef struct {
-       computed_value_func   computed_value;   /**< evaluates a node into a tarval if possible. */
-       equivalent_node_func  equivalent_node;  /**< optimizes the node by returning an equivalent one. */
-       transform_node_func   transform_node;   /**< optimizes the node by transforming it. */
-       node_cmp_attr_func    node_cmp_attr;    /**< compares two node attributes. */
-       reassociate_func      reassociate;      /**< reassociate a tree */
-       copy_attr_func        copy_attr;        /**< copy node attributes */
-       get_type_func         get_type;         /**< return the type of a node */
-       get_type_attr_func    get_type_attr;    /**< return the type attribute of a node */
-       get_entity_attr_func  get_entity_attr;  /**< return the entity attribute of a node */
-       verify_node_func      verify_node;      /**< verify the node */
-       verify_proj_node_func verify_proj_node; /**< verify the Proj node */
-       dump_node_func        dump_node;        /**< dump a node */
-       op_func               generic;          /**< a generic function */
+       get_block_func        get_block;        /**< Return the block of a node. */
+       set_block_func        set_block;        /**< Sets the block of a node. */
+       computed_value_func   computed_value;   /**< Evaluates a node into a tarval if possible. */
+       equivalent_node_func  equivalent_node;  /**< Optimizes the node by returning an equivalent one. */
+       transform_node_func   transform_node;   /**< Optimizes the node by transforming it. */
+       node_cmp_attr_func    node_cmp_attr;    /**< Compares two node attributes. */
+       reassociate_func      reassociate;      /**< Reassociate a tree. */
+       copy_attr_func        copy_attr;        /**< Copy node attributes. */
+       get_type_func         get_type;         /**< Return the type of a node. */
+       get_type_attr_func    get_type_attr;    /**< Return the type attribute of a node. */
+       get_entity_attr_func  get_entity_attr;  /**< Return the entity attribute of a node. */
+       verify_node_func      verify_node;      /**< Verify the node. */
+       verify_proj_node_func verify_proj_node; /**< Verify the Proj node. */
+       dump_node_func        dump_node;        /**< Dump a node. */
+       op_func               generic;          /**< A generic function. */
 } ir_op_ops;
 
 /**
index 971e0c1..73be488 100644 (file)
@@ -2059,6 +2059,7 @@ static ir_node *get_deepest_common_ancestor(ir_node *node, ir_node *dca)
        return dca;
 }
 
+#ifdef CAN_PLACE_PROJS
 static void set_projs_block(ir_node *node, ir_node *block)
 {
        int i;
@@ -2074,6 +2075,7 @@ static void set_projs_block(ir_node *node, ir_node *block)
                set_nodes_block(succ, block);
        }
 }
+#endif
 
 /**
  * Find the latest legal block for N and place N into the
@@ -2141,9 +2143,11 @@ static void place_floats_late(ir_node *n, pdeq *worklist) {
                                if (dca != NULL) {
                                        set_nodes_block(n, dca);
                                        move_out_of_loops(n, early_blk);
+#ifdef CAN_PLACE_PROJS
                                        if(get_irn_mode(n) == mode_T) {
                                                set_projs_block(n, get_nodes_block(n));
                                        }
+#endif
                                }
                        }
                }
index cc871e5..5348ef7 100644 (file)
@@ -282,7 +282,7 @@ ir_node *
 }
 
 void
-set_irn_n (ir_node *node, int n, ir_node *in) {
+set_irn_n(ir_node *node, int n, ir_node *in) {
        assert(node && node->kind == k_ir_node);
        assert(-1 <= n);
        assert(n < get_irn_arity(node));
@@ -316,8 +316,7 @@ set_irn_n (ir_node *node, int n, ir_node *in) {
        node->in[n + 1] = in;
 }
 
-int add_irn_n(ir_node *node, ir_node *in)
-{
+int add_irn_n(ir_node *node, ir_node *in) {
        int pos;
        ir_graph *irg = get_irn_irg(node);
 
@@ -333,25 +332,21 @@ int add_irn_n(ir_node *node, ir_node *in)
 }
 
 int
-(get_irn_deps)(const ir_node *node)
-{
+(get_irn_deps)(const ir_node *node) {
        return _get_irn_deps(node);
 }
 
 ir_node *
-(get_irn_dep)(const ir_node *node, int pos)
-{
+(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)
-{
+(set_irn_dep)(ir_node *node, int pos, ir_node *dep) {
        _set_irn_dep(node, pos, dep);
 }
 
-int add_irn_dep(ir_node *node, ir_node *dep)
-{
+int add_irn_dep(ir_node *node, ir_node *dep) {
        int res = 0;
 
        if (node->deps == NULL) {
@@ -651,18 +646,14 @@ int get_irn_pred_pos(ir_node *node, ir_node *arg) {
 
 /** manipulate fields of individual nodes **/
 
-/* this works for all except Block */
 ir_node *
-get_nodes_block(const ir_node *node) {
-       assert(node->op != op_Block);
-       assert(is_irn_pinned_in_irg(node) && "block info may be incorrect");
-       return get_irn_n(node, -1);
+(get_nodes_block)(const ir_node *node) {
+       return _get_nodes_block(node);
 }
 
 void
 set_nodes_block(ir_node *node, ir_node *block) {
-       assert(node->op != op_Block);
-       set_irn_n(node, -1, block);
+       node->op->ops.set_block(node, block);
 }
 
 /* Test whether arbitrary node is frame pointer, i.e. Proj(pn_Start_P_frame_base)
index 75fbced..61e7652 100644 (file)
@@ -112,6 +112,11 @@ _is_ir_node(const void *thing) {
        return (get_kind(thing) == k_ir_node);
 }
 
+static INLINE ir_node *_get_nodes_block(const ir_node *node) {
+       assert(_is_ir_node(node));
+       return node->op->ops.get_block(node);
+}
+
 /**
  * Gets the op of a node.
  * Intern version for libFirm.
@@ -825,6 +830,7 @@ static INLINE void _set_irn_dbg_info(ir_node *n, dbg_info *db) {
 
 /* this section MUST contain all inline functions */
 #define is_ir_node(thing)                     _is_ir_node(thing)
+#define get_nodes_block(node)                 _get_nodes_block(node)
 #define get_irn_intra_arity(node)             _get_irn_intra_arity(node)
 #define get_irn_inter_arity(node)             _get_irn_inter_arity(node)
 #define get_irn_arity(node)                   _get_irn_arity(node)
index d4424f3..3e2cace 100644 (file)
@@ -664,8 +664,7 @@ tarval *computed_value(ir_node *n) {
  * @return
  *    The operations.
  */
-static ir_op_ops *firm_set_default_computed_value(ir_opcode code, ir_op_ops *ops)
-{
+static ir_op_ops *firm_set_default_computed_value(ir_opcode code, ir_op_ops *ops) {
 #define CASE(a)                                    \
        case iro_##a:                                  \
                ops->computed_value  = computed_value_##a; \
@@ -4320,10 +4319,103 @@ ir_node *optimize_in_place(ir_node *n) {
        return optimize_in_place_2(n);
 }  /* optimize_in_place */
 
+/**
+ * Return the block for all default nodes.
+ */
+static ir_node *get_block_default(const ir_node *self) {
+       return get_irn_n(self, -1);
+}
+
+/**
+ * Sets the block for all default nodes.
+ */
+static void set_block_default(ir_node *self, ir_node *blk) {
+       set_irn_n(self, -1, blk);
+}
+
+/**
+ * It's not allowed to get the block of a block. Anyway, returns
+ * the macroblock header in release mode.
+ */
+static ir_node *get_block_Block(const ir_node *self) {
+       assert(!"get_nodes_block() called for a block");
+       return get_irn_n(self, -1);
+}
+
+/**
+ * It's not allowed to set the block of a block. In release mode sets
+ * the macroblock header.
+ */
+static void set_block_Block(ir_node *self, ir_node *blk) {
+       assert(!"set_nodes_block() called for a block");
+       set_irn_n(self, -1, blk);
+}
+
+/**
+ * The anchor is always placed in the endblock or a graph.
+ */
+static ir_node *get_block_Anchor(const ir_node *self) {
+       return get_irn_n(self, anchor_end_block);
+}
+
+/**
+ * It's forbidden to set the anchor block.
+ */
+static void set_block_Anchor(ir_node *self, ir_node *blk) {
+       (void) self;
+       (void) blk;
+       assert(!"set_nodes_block() called for the Anchor");
+}
+
+/**
+ * Proj nodes are always in the block of it's predecessor.
+ */
+static ir_node *get_block_Proj(const ir_node *self) {
+       ir_node *pred = get_Proj_pred(self);
+       return get_nodes_block(pred);
+}
+
+/**
+ * Proj nodes silently ignore the block set request.
+ */
+static void set_block_Proj(ir_node *self, ir_node *blk) {
+       (void) self;
+       (void) blk;
+}
+
+/**
+ * Set the default get_block operation.
+ */
+static  ir_op_ops *firm_set_default_get_block(ir_opcode code, ir_op_ops *ops) {
+#define CASE(a)                                    \
+       case iro_##a:                                  \
+               ops->get_block = get_block_##a; \
+               ops->set_block = set_block_##a; \
+               break
+
+       switch (code) {
+       CASE(Block);
+       CASE(Anchor);
+#ifndef CAN_PLACE_PROJS
+       CASE(Proj);
+#endif
+       default:
+               /* not allowed to be NULL */
+               if (! ops->get_block)
+                       ops->get_block = get_block_default;
+               if (! ops->set_block)
+                       ops->set_block = set_block_default;
+       }
+
+       return ops;
+#undef CASE
+}  /* firm_set_default_get_block */
+
 /*
  * Sets the default operation for an ir_ops.
  */
 ir_op_ops *firm_set_default_operations(ir_opcode code, ir_op_ops *ops) {
+       ops = firm_set_default_get_block(code, ops);
        ops = firm_set_default_computed_value(code, ops);
        ops = firm_set_default_equivalent_node(code, ops);
        ops = firm_set_default_transform_node(code, ops);