# include "irop_t.h"
# include "irnode_t.h"
-# include "firmstat.h"
+# include "irhooks.h"
-# include "iropt.h" /* for firm_set_default_operations */
+# include "iropt_t.h" /* for firm_set_default_operations */
# include "xmalloc.h"
ir_op *op_EndExcept; ir_op *get_op_EndExcept (void) { return op_EndExcept; }
ir_op *op_NoMem; ir_op *get_op_NoMem (void) { return op_NoMem; }
+ir_op *op_Mux; ir_op *get_op_Mux (void) { return op_Mux; }
+/*
+ * 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);
- stat_new_ir_op(res);
+ firm_set_default_copy_attr(res);
+
+ hook_new_ir_op(res);
return res;
}
void free_ir_op(ir_op *code) {
- stat_free_ir_op(code);
+ hook_free_ir_op(code);
free(code);
}
op_Load = new_ir_op(iro_Load, "Load", op_pin_state_exc_pinned, L|F, oparity_any, -1, sizeof(load_attr));
op_Store = new_ir_op(iro_Store, "Store", op_pin_state_exc_pinned, L|F, oparity_any, -1, sizeof(store_attr));
op_Alloc = new_ir_op(iro_Alloc, "Alloc", op_pin_state_pinned, L|F, oparity_any, -1, sizeof(alloc_attr));
- op_Free = new_ir_op(iro_Free, "Free", op_pin_state_pinned, L, oparity_any, -1, sizeof(type *));
+ op_Free = new_ir_op(iro_Free, "Free", op_pin_state_pinned, L, oparity_any, -1, sizeof(free_attr));
op_Sync = new_ir_op(iro_Sync, "Sync", op_pin_state_pinned, 0, oparity_any, -1, 0);
op_Proj = new_ir_op(iro_Proj, "Proj", op_pin_state_floats, 0, oparity_any, -1, sizeof(long));
op_EndExcept = new_ir_op(iro_EndExcept, "EndExcept", op_pin_state_pinned, X|I, oparity_any, -1, sizeof(end_attr));
op_NoMem = new_ir_op(iro_NoMem, "NoMem", op_pin_state_pinned, 0, oparity_zero, -1, 0);
+ op_Mux = new_ir_op(iro_Mux, "Mux", op_pin_state_floats, 0, oparity_trinary, -1, 0);
#undef Y
#undef F
free_ir_op (op_EndExcept); op_EndExcept = NULL;
free_ir_op (op_NoMem ); op_NoMem = NULL;
+ free_ir_op (op_Mux ); op_Mux = NULL;
}
/* Returns the string for the opcode. */
return __get_op_code(op);
}
-ident *(get_op_ident)(ir_op *op){
+ident *(get_op_ident)(const ir_op *op){
return __get_op_ident(op);
}
const char *get_op_pin_state_name(op_pin_state s) {
switch(s) {
- case op_pin_state_floats: return "op_pin_state_floats";
- case op_pin_state_pinned: return "op_pin_state_pinned";
- case op_pin_state_exc_pinned: return "op_pin_state_exc_pinned";
- case op_pin_state_mem_pinned: return "op_pin_state_mem_pinned";
+#define XXX(s) case s: return #s
+ XXX(op_pin_state_floats);
+ XXX(op_pin_state_pinned);
+ XXX(op_pin_state_exc_pinned);
+ XXX(op_pin_state_mem_pinned);
+#undef XXX
}
+ return "<none>";
}
op_pin_state (get_op_pinned)(const ir_op *op){