/* Copy the attributes. These might point to additional data. If this
was allocated on the old obstack the pointers now are dangling. This
frees e.g. the memory of the graph_arr allocated in new_immBlock. */
- copy_attrs(n, nn);
+ copy_node_attr(n, nn);
new_backedge_info(nn);
set_new_node(n, nn);
-1,
NULL);
/* Copy the attributes. Well, there might be some in the future... */
- copy_attrs(oe, ne);
+ copy_node_attr(oe, ne);
set_new_node(oe, ne);
/* copy the Bad node */
* The amount of additional space for custom data to be allocated upon
* creating a new node.
*/
-static size_t additional_node_data_size = 0;
+unsigned firm_add_node_size = 0;
-size_t register_additional_node_data(size_t size)
-{
- assert(!forbid_new_data && "Too late to register additional node data");
+/* register new space for every node */
+unsigned register_additional_node_data(unsigned size) {
+ assert(!forbid_new_data && "Too late to register additional node data");
- if(forbid_new_data)
- return 0;
+ if (forbid_new_data)
+ return 0;
- return additional_node_data_size += size;
+ return firm_add_node_size += size;
}
void
-init_irnode (void)
-{
+init_irnode(void) {
/* Forbid the addition of new data to an ir node. */
forbid_new_data = 1;
}
int arity, ir_node **in)
{
ir_node *res;
- size_t node_size = offsetof(ir_node, attr) + op->attr_size + additional_node_data_size;
+ size_t node_size = offsetof(ir_node, attr) + op->attr_size + firm_add_node_size;
char *p;
assert(irg && op && mode);
p = obstack_alloc (irg->obst, node_size);
memset(p, 0, node_size);
- res = (ir_node *) (p + additional_node_data_size);
+ res = (ir_node *) (p + firm_add_node_size);
res->kind = k_ir_node;
res->op = op;
return res;
}
-/* Copies all attributes stored in the old node to the new node.
- Assumes both have the same opcode and sufficient size. */
-void
-copy_attrs (const ir_node *old_node, ir_node *new_node) {
- assert(get_irn_op(old_node) == get_irn_op(new_node));
- memcpy(&new_node->attr, &old_node->attr, get_op_attr_size(get_irn_op(old_node)));
- if (get_irn_op(new_node) == op_Call) remove_Call_callee_arr(new_node);
-}
-
/*-- getting some parameters from ir_nodes --*/
int
* must be passed to the access macro get_irn_data(), 0 if the
* registration failed.
*/
-size_t register_additional_node_data(size_t size);
+unsigned register_additional_node_data(unsigned size);
/*-----------------------------------------------------------------*/
* Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
*/
-
/**
* @file irnode_t.h
*
* @author Martin Trapp, Christian Schaefer
*/
-
# ifndef _IRNODE_T_H_
# define _IRNODE_T_H_
};
-/** Copies all attributes stored in the old node to the new node.
- Assumes both have the same opcode and sufficient size. */
-void
-copy_attrs(const ir_node *old_node, ir_node *new_node);
-
-
/** Returns the array with the ins. The content of the array may not be
changed. */
ir_node **get_irn_in (const ir_node *node);
except_attr get_irn_except_attr (ir_node *node);
/** @} */
+/*
+ * The amount of additional space for custom data to be allocated upon creating a new node.
+ */
+extern unsigned firm_add_node_size;
+
/*-------------------------------------------------------------------*/
/* These function are most used in libfirm. Give them as static */
/* functions so they can be inlined. */
return node->op;
}
+/** Copies all attributes stored in the old node to the new node.
+ Assumes both have the same opcode and sufficient size. */
+static INLINE void
+copy_node_attr(const ir_node *old_node, ir_node *new_node) {
+ ir_op *op = __get_irn_op(old_node);
+
+ /* must always exist */
+ op->copy_attr(old_node, new_node);
+}
+
/**
* Gets the opcode of a node.
* Intern version for libFirm.
# include "irnode_t.h"
# include "firmstat.h"
-# include "iropt.h" /* for firm_set_default_operations */
+# include "iropt_t.h" /* for firm_set_default_operations */
# include "xmalloc.h"
ir_op *op_NoMem; ir_op *get_op_NoMem (void) { return op_NoMem; }
+/*
+ * Copies all attributes stored in the old node to the new node.
+ * Assumes both have the same opcode and sufficient size.
+ */
+void default_copy_attr(const ir_node *old_node, ir_node *new_node) {
+ unsigned size = firm_add_node_size;
+
+ assert(get_irn_op(old_node) == get_irn_op(new_node));
+ memcpy(&new_node->attr, &old_node->attr, get_op_attr_size(get_irn_op(old_node)));
+
+ if (size > 0) {
+ /* copy additional node data */
+ memcpy(get_irn_data(new_node, void, size), get_irn_data(old_node, void, size), size);
+ }
+}
+
+/**
+ * Copies all attributes stored in the old node to the new node.
+ * Assumes both have the same opcode and sufficient size.
+ */
+static void
+call_copy_attr(const ir_node *old_node, ir_node *new_node) {
+ default_copy_attr(old_node, new_node);
+
+ remove_Call_callee_arr(new_node);
+}
+
+/**
+ * Sets the copy_attr operation for an ir_op
+ */
+static ir_op *firm_set_default_copy_attr(ir_op *op) {
+ if (op->code == iro_Call)
+ op->copy_attr = call_copy_attr;
+ else
+ op->copy_attr = default_copy_attr;
+
+ return op;
+}
+
ir_op *
new_ir_op(opcode code, const char *name, op_pin_state p, unsigned flags, op_arity opar, int op_index, size_t attr_size)
{
res->op_index = op_index;
firm_set_default_operations(res);
+ firm_set_default_copy_attr(res);
+
stat_new_ir_op(res);
return res;
}
*/
typedef int (*reassociate_func)(ir_node *n);
+/**
+ * The copy attribute operation.
+ * Copy the node attributes from a 'old' node to a 'new' one.
+ */
+typedef void (*copy_attr_func)(const ir_node *old_node, ir_node *new_node);
+
/** The type of an ir_op. */
struct ir_op {
opcode code; /**< the unique opcode of the op */
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 */
};
/**
/** Free memory used by irop module. */
void finish_op(void);
+/**
+ * Copies simply all attributes stored in the old node to the new node.
+ * Assumes both have the same opcode and sufficient size.
+ */
+void default_copy_attr(const ir_node *old_node, ir_node *new_node);
+
/** Returns the attribute size of nodes of this opcode.
@note Use not encouraged, internal feature. */
static INLINE int get_op_attr_size (const ir_op *op) {
*/
ir_node *optimize_in_place (ir_node *n);
-/**
- * set the default ir op operations
- */
-ir_op *firm_set_default_operations(ir_op *op);
-
# endif /* _IROPT_H_ */
return tarval_bad;
}
+/**
+ * set the default ir op operations
+ */
+ir_op *firm_set_default_operations(ir_op *op);
# endif /* _IROPT_T_H_ */