*/
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,
* 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;
/**
return dca;
}
+#ifdef CAN_PLACE_PROJS
static void set_projs_block(ir_node *node, ir_node *block)
{
int i;
set_nodes_block(succ, block);
}
}
+#endif
/**
* Find the latest legal block for N and place N into the
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
}
}
}
}
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));
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);
}
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) {
/** 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)
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.
/* 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)
* @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; \
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);