Commit dbace876 authored by Matthias Braun's avatar Matthias Braun
Browse files

irop: refactor node_ops registration code

Get away from the strange set_default_XXX_op style and instead let the
code modules register their node ops directly.
parent ba831c86
......@@ -82,6 +82,7 @@ typedef enum {
* of an unknown_jump */
irop_flag_unknown_jump = 1U << 11,
} irop_flags;
ENUM_BITSET(irop_flags)
/** Returns the ident for the opcode name */
FIRM_API ident *get_op_ident(const ir_op *op);
......@@ -245,7 +246,7 @@ typedef struct {
equivalent_node_func equivalent_node; /**< Optimizes the node by returning an equivalent one. */
equivalent_node_func equivalent_node_Proj; /**< Optimizes the Proj node by returning an equivalent one. */
transform_node_func transform_node; /**< Optimizes the node by transforming it. */
equivalent_node_func transform_node_Proj; /**< Optimizes the Proj node by transforming it. */
transform_node_func transform_node_Proj; /**< Optimizes the Proj 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. */
......@@ -268,7 +269,6 @@ typedef struct {
* @param opar the parity of this IR operation
* @param op_index if the parity is oparity_unary, oparity_binary or oparity_trinary the index
* of the left operand
* @param ops operations for this opcode, iff NULL default operations are used
* @param attr_size attribute size for this IR operation
*
* @return The generated IR operation.
......@@ -277,8 +277,8 @@ typedef struct {
* The behavior of new opcode depends on the operations \c ops and the \c flags.
*/
FIRM_API ir_op *new_ir_op(unsigned code, const char *name, op_pin_state p,
unsigned flags, op_arity opar, int op_index,
size_t attr_size, const ir_op_ops *ops);
irop_flags flags, op_arity opar, int op_index,
size_t attr_size);
/** Returns one more than the highest opcode code in use. */
FIRM_API unsigned ir_get_n_opcodes(void);
......
......@@ -1271,31 +1271,21 @@ static void copy_attr(ir_graph *irg, const ir_node *old_node, ir_node *new_node)
}
}
static const ir_op_ops be_node_op_ops = {
firm_default_hash,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
copy_attr,
NULL,
NULL,
NULL,
NULL,
dump_node,
NULL,
&be_node_irn_ops
};
int is_be_node(const ir_node *irn)
{
return get_op_ops(get_irn_op(irn))->be_ops == &be_node_irn_ops;
}
static ir_op *new_be_op(unsigned code, const char *name, op_pin_state p,
irop_flags flags, op_arity opar, size_t attr_size)
{
ir_op *res = new_ir_op(code, name, p, flags, opar, 0, attr_size);
res->ops.dump_node = dump_node;
res->ops.copy_attr = copy_attr;
res->ops.be_ops = &be_node_irn_ops;
return res;
}
void be_init_op(void)
{
unsigned opc;
......@@ -1303,22 +1293,22 @@ void be_init_op(void)
assert(op_be_Spill == NULL);
/* Acquire all needed opcodes. */
op_be_Spill = new_ir_op(beo_Spill, "be_Spill", op_pin_state_exc_pinned, irop_flag_none, oparity_unary, 0, sizeof(be_frame_attr_t), &be_node_op_ops);
op_be_Reload = new_ir_op(beo_Reload, "be_Reload", op_pin_state_exc_pinned, irop_flag_none, oparity_zero, 0, sizeof(be_frame_attr_t), &be_node_op_ops);
op_be_Perm = new_ir_op(beo_Perm, "be_Perm", op_pin_state_exc_pinned, irop_flag_none, oparity_variable, 0, sizeof(be_node_attr_t), &be_node_op_ops);
op_be_MemPerm = new_ir_op(beo_MemPerm, "be_MemPerm", op_pin_state_exc_pinned, irop_flag_none, oparity_variable, 0, sizeof(be_memperm_attr_t), &be_node_op_ops);
op_be_Copy = new_ir_op(beo_Copy, "be_Copy", op_pin_state_exc_pinned, irop_flag_none, oparity_unary, 0, sizeof(be_node_attr_t), &be_node_op_ops);
op_be_Keep = new_ir_op(beo_Keep, "be_Keep", op_pin_state_exc_pinned, irop_flag_keep, oparity_dynamic, 0, sizeof(be_node_attr_t), &be_node_op_ops);
op_be_CopyKeep = new_ir_op(beo_CopyKeep, "be_CopyKeep", op_pin_state_exc_pinned, irop_flag_keep, oparity_variable, 0, sizeof(be_node_attr_t), &be_node_op_ops);
op_be_Call = new_ir_op(beo_Call, "be_Call", op_pin_state_exc_pinned, irop_flag_fragile|irop_flag_uses_memory, oparity_variable, 0, sizeof(be_call_attr_t), &be_node_op_ops);
op_be_Spill = new_be_op(beo_Spill, "be_Spill", op_pin_state_exc_pinned, irop_flag_none, oparity_unary, sizeof(be_frame_attr_t));
op_be_Reload = new_be_op(beo_Reload, "be_Reload", op_pin_state_exc_pinned, irop_flag_none, oparity_zero, sizeof(be_frame_attr_t));
op_be_Perm = new_be_op(beo_Perm, "be_Perm", op_pin_state_exc_pinned, irop_flag_none, oparity_variable, sizeof(be_node_attr_t));
op_be_MemPerm = new_be_op(beo_MemPerm, "be_MemPerm", op_pin_state_exc_pinned, irop_flag_none, oparity_variable, sizeof(be_memperm_attr_t));
op_be_Copy = new_be_op(beo_Copy, "be_Copy", op_pin_state_exc_pinned, irop_flag_none, oparity_unary, sizeof(be_node_attr_t));
op_be_Keep = new_be_op(beo_Keep, "be_Keep", op_pin_state_exc_pinned, irop_flag_keep, oparity_dynamic, sizeof(be_node_attr_t));
op_be_CopyKeep = new_be_op(beo_CopyKeep, "be_CopyKeep", op_pin_state_exc_pinned, irop_flag_keep, oparity_variable, sizeof(be_node_attr_t));
op_be_Call = new_be_op(beo_Call, "be_Call", op_pin_state_exc_pinned, irop_flag_fragile|irop_flag_uses_memory, oparity_variable, sizeof(be_call_attr_t));
ir_op_set_memory_index(op_be_Call, n_be_Call_mem);
ir_op_set_fragile_indices(op_be_Call, pn_be_Call_X_regular, pn_be_Call_X_except);
op_be_Return = new_ir_op(beo_Return, "be_Return", op_pin_state_exc_pinned, irop_flag_cfopcode, oparity_variable, 0, sizeof(be_return_attr_t), &be_node_op_ops);
op_be_AddSP = new_ir_op(beo_AddSP, "be_AddSP", op_pin_state_exc_pinned, irop_flag_none, oparity_unary, 0, sizeof(be_node_attr_t), &be_node_op_ops);
op_be_SubSP = new_ir_op(beo_SubSP, "be_SubSP", op_pin_state_exc_pinned, irop_flag_none, oparity_unary, 0, sizeof(be_node_attr_t), &be_node_op_ops);
op_be_IncSP = new_ir_op(beo_IncSP, "be_IncSP", op_pin_state_exc_pinned, irop_flag_none, oparity_unary, 0, sizeof(be_incsp_attr_t), &be_node_op_ops);
op_be_Start = new_ir_op(beo_Start, "be_Start", op_pin_state_exc_pinned, irop_flag_none, oparity_zero, 0, sizeof(be_node_attr_t), &be_node_op_ops);
op_be_FrameAddr = new_ir_op(beo_FrameAddr, "be_FrameAddr", op_pin_state_exc_pinned, irop_flag_none, oparity_unary, 0, sizeof(be_frame_attr_t), &be_node_op_ops);
op_be_Return = new_be_op(beo_Return, "be_Return", op_pin_state_exc_pinned, irop_flag_cfopcode, oparity_variable, sizeof(be_return_attr_t));
op_be_AddSP = new_be_op(beo_AddSP, "be_AddSP", op_pin_state_exc_pinned, irop_flag_none, oparity_unary, sizeof(be_node_attr_t));
op_be_SubSP = new_be_op(beo_SubSP, "be_SubSP", op_pin_state_exc_pinned, irop_flag_none, oparity_unary, sizeof(be_node_attr_t));
op_be_IncSP = new_be_op(beo_IncSP, "be_IncSP", op_pin_state_exc_pinned, irop_flag_none, oparity_unary, sizeof(be_incsp_attr_t));
op_be_Start = new_be_op(beo_Start, "be_Start", op_pin_state_exc_pinned, irop_flag_none, oparity_zero, sizeof(be_node_attr_t));
op_be_FrameAddr = new_be_op(beo_FrameAddr, "be_FrameAddr", op_pin_state_exc_pinned, irop_flag_none, oparity_unary, sizeof(be_frame_attr_t));
op_be_Spill->ops.node_cmp_attr = FrameAddr_cmp_attr;
op_be_Reload->ops.node_cmp_attr = FrameAddr_cmp_attr;
......
......@@ -652,28 +652,6 @@ EOF
$n{"dump_func"} = "${arch}_dump_node" if (!exists($n{"dump_func"}));
my $dump_func = $n{"dump_func"};
push(@obst_new_irop, "\n\tmemset(&ops, 0, sizeof(ops));\n");
push(@obst_new_irop, "\tops.be_ops = be_ops;\n");
push(@obst_new_irop, "\tops.dump_node = ${dump_func};\n");
if (defined($cmp_attr_func)) {
push(@obst_new_irop, "\tops.node_cmp_attr = ${cmp_attr_func};\n");
}
my $copy_attr_func = $copy_attr{$attr_type};
if (!defined($copy_attr_func)) {
if ($attr_type eq "") {
$copy_attr_func = "NULL";
} else {
$copy_attr_func = $default_copy_attr;
}
}
if (defined($copy_attr_func)) {
push(@obst_new_irop, "\tops.copy_attr = ${copy_attr_func};\n");
}
if (defined($hash_func)) {
push(@obst_new_irop, "\tops.hash = ${hash_func};\n");
}
my %known_flags = map { $_ => 1 } (
"none", "commutative", "cfopcode", "unknown_jump", "fragile",
"forking", "highlevel", "constlike", "keep", "start_block",
......@@ -698,8 +676,28 @@ EOF
$n_opcodes++;
$temp = "\top = new_ir_op(cur_opcode + iro_$op, \"$op\", op_pin_state_".$n{"state"}.", $op_flags";
$temp .= ", ".translate_arity($arity).", 0, ${attr_size}, &ops);\n";
$temp .= ", ".translate_arity($arity).", 0, ${attr_size});\n";
push(@obst_new_irop, $temp);
push(@obst_new_irop, "\top->ops.be_ops = be_ops;\n");
push(@obst_new_irop, "\top->ops.dump_node = ${dump_func};\n");
if (defined($cmp_attr_func)) {
push(@obst_new_irop, "\top->ops.node_cmp_attr = ${cmp_attr_func};\n");
}
my $copy_attr_func = $copy_attr{$attr_type};
if (!defined($copy_attr_func)) {
if ($attr_type eq "") {
$copy_attr_func = "NULL";
} else {
$copy_attr_func = $default_copy_attr;
}
}
if (defined($copy_attr_func)) {
push(@obst_new_irop, "\top->ops.copy_attr = ${copy_attr_func};\n");
}
if (defined($hash_func)) {
push(@obst_new_irop, "\top->ops.hash = ${hash_func};\n");
}
if ($is_fragile) {
push(@obst_new_irop, "\tir_op_set_memory_index(op, n_${op}_mem);\n");
push(@obst_new_irop, "\tir_op_set_fragile_indices(op, pn_${op}_X_regular, pn_${op}_X_except);\n");
......@@ -819,9 +817,8 @@ $obst_constructor
*/
void $arch\_create_opcodes(const arch_irn_ops_t *be_ops)
{
ir_op_ops ops;
ir_op *op;
int cur_opcode = get_next_ir_opcodes(iro_$arch\_last);
ir_op *op;
int cur_opcode = get_next_ir_opcodes(iro_$arch\_last);
$arch\_opcode_start = cur_opcode;
ENDOFMAIN
......
......@@ -1482,51 +1482,30 @@ static ir_entity *get_SymConst_attr_entity(const ir_node *self)
return NULL;
}
/** the get_type_attr operation must be always implemented */
static ir_type *get_Null_type(const ir_node *n)
{
(void) n;
return get_unknown_type();
}
void firm_set_default_get_type_attr(unsigned code, ir_op_ops *ops)
{
switch (code) {
case iro_Alloc: ops->get_type_attr = get_Alloc_type; break;
case iro_Builtin: ops->get_type_attr = get_Builtin_type; break;
case iro_Call: ops->get_type_attr = get_Call_type; break;
case iro_Cast: ops->get_type_attr = get_Cast_type; break;
case iro_CopyB: ops->get_type_attr = get_CopyB_type; break;
case iro_Free: ops->get_type_attr = get_Free_type; break;
case iro_InstOf: ops->get_type_attr = get_InstOf_type; break;
case iro_SymConst: ops->get_type_attr = get_SymConst_attr_type; break;
default:
/* not allowed to be NULL */
if (! ops->get_type_attr)
ops->get_type_attr = get_Null_type;
break;
}
static void register_get_type_func(ir_op *op, get_type_attr_func func)
{
op->ops.get_type_attr = func;
}
/** the get_entity_attr operation must be always implemented */
static ir_entity *get_Null_ent(const ir_node *n)
static void register_get_entity_func(ir_op *op, get_entity_attr_func func)
{
(void) n;
return NULL;
op->ops.get_entity_attr = func;
}
void firm_set_default_get_entity_attr(unsigned code, ir_op_ops *ops)
void ir_register_getter_ops(void)
{
switch (code) {
case iro_SymConst: ops->get_entity_attr = get_SymConst_attr_entity; break;
case iro_Sel: ops->get_entity_attr = get_Sel_entity; break;
case iro_Block: ops->get_entity_attr = get_Block_entity; break;
default:
/* not allowed to be NULL */
if (! ops->get_entity_attr)
ops->get_entity_attr = get_Null_ent;
break;
}
register_get_type_func(op_Alloc, get_Alloc_type);
register_get_type_func(op_Builtin, get_Builtin_type);
register_get_type_func(op_Call, get_Call_type);
register_get_type_func(op_Cast, get_Cast_type);
register_get_type_func(op_CopyB, get_CopyB_type);
register_get_type_func(op_Free, get_Free_type);
register_get_type_func(op_InstOf, get_InstOf_type);
register_get_type_func(op_SymConst, get_SymConst_attr_type);
register_get_entity_func(op_SymConst, get_SymConst_attr_entity);
register_get_entity_func(op_Sel, get_Sel_entity);
register_get_entity_func(op_Block, get_Block_entity);
}
void (set_irn_dbg_info)(ir_node *n, dbg_info *db)
......
......@@ -46,28 +46,6 @@ ir_node **get_irn_in(const ir_node *node);
*/
extern unsigned firm_add_node_size;
/**
* Sets the get_type_attr operation for an ir_op_ops.
*
* @param code the opcode for the default operation
* @param ops the operations initialized
*
* @return
* The operations.
*/
void firm_set_default_get_type_attr(unsigned code, ir_op_ops *ops);
/**
* Sets the get_entity_attr operation for an ir_op_ops.
*
* @param code the opcode for the default operation
* @param ops the operations initialized
*
* @return
* The operations.
*/
void firm_set_default_get_entity_attr(unsigned code, ir_op_ops *ops);
/**
* Returns an array with the predecessors of the Block. Depending on
* the implementation of the graph data structure this can be a copy of
......@@ -597,6 +575,8 @@ static inline const ir_switch_table_entry *ir_switch_table_get_entry_const(
return &table->entries[entry];
}
void ir_register_getter_ops(void);
/** initialize ir_node module */
void init_irnode(void);
......
......@@ -42,126 +42,15 @@ static ir_op **opcodes;
/** the available next opcode */
static unsigned next_iro = iro_MaxOpcode;
void default_copy_attr(ir_graph *irg, const ir_node *old_node,
ir_node *new_node)
{
unsigned size = firm_add_node_size;
(void) irg;
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 Call attributes stored in the old node to the new node.
*/
static void call_copy_attr(ir_graph *irg, const ir_node *old_node,
ir_node *new_node)
{
default_copy_attr(irg, old_node, new_node);
remove_Call_callee_arr(new_node);
}
/**
* Copies all Block attributes stored in the old node to the new node.
*/
static void block_copy_attr(ir_graph *irg, const ir_node *old_node,
ir_node *new_node)
{
default_copy_attr(irg, old_node, new_node);
new_node->attr.block.irg.irg = irg;
new_node->attr.block.phis = NULL;
new_node->attr.block.backedge = new_backedge_arr(irg->obst, get_irn_arity(new_node));
new_node->attr.block.block_visited = 0;
memset(&new_node->attr.block.dom, 0, sizeof(new_node->attr.block.dom));
memset(&new_node->attr.block.pdom, 0, sizeof(new_node->attr.block.pdom));
/* It should be safe to copy the entity here, as it has no back-link to the old block.
* It serves just as a label number, so copying a labeled block results in an exact copy.
* This is at least what we need for DCE to work. */
new_node->attr.block.entity = old_node->attr.block.entity;
new_node->attr.block.phis = NULL;
INIT_LIST_HEAD(&new_node->attr.block.succ_head);
}
/**
* Copies all phi attributes stored in old node to the new node
*/
static void phi_copy_attr(ir_graph *irg, const ir_node *old_node,
ir_node *new_node)
{
default_copy_attr(irg, old_node, new_node);
new_node->attr.phi.next = NULL;
new_node->attr.phi.u.backedge = new_backedge_arr(irg->obst, get_irn_arity(new_node));
}
/**
* Copies all ASM attributes stored in old node to the new node
*/
static void ASM_copy_attr(ir_graph *irg, const ir_node *old_node,
ir_node *new_node)
{
default_copy_attr(irg, old_node, new_node);
new_node->attr.assem.input_constraints = DUP_ARR_D(ir_asm_constraint, irg->obst, old_node->attr.assem.input_constraints);
new_node->attr.assem.output_constraints = DUP_ARR_D(ir_asm_constraint, irg->obst, old_node->attr.assem.output_constraints);
new_node->attr.assem.clobbers = DUP_ARR_D(ident*, irg->obst, old_node->attr.assem.clobbers);
}
static void switch_copy_attr(ir_graph *irg, const ir_node *old_node,
ir_node *new_node)
{
const ir_switch_table *table = get_Switch_table(old_node);
new_node->attr.switcha.table = ir_switch_table_duplicate(irg, table);
new_node->attr.switcha.n_outs = old_node->attr.switcha.n_outs;
}
/**
* Sets the default copy_attr operation for an ir_ops
*
* @param code the opcode for the default operation
* @param ops the operations initialized
*
* @return
* The operations.
*/
static void firm_set_default_copy_attr(unsigned code, ir_op_ops *ops)
{
switch (code) {
case iro_Call: ops->copy_attr = call_copy_attr; break;
case iro_Block: ops->copy_attr = block_copy_attr; break;
case iro_Phi: ops->copy_attr = phi_copy_attr; break;
case iro_ASM: ops->copy_attr = ASM_copy_attr; break;
case iro_Switch: ops->copy_attr = switch_copy_attr; break;
default:
if (ops->copy_attr == NULL)
ops->copy_attr = default_copy_attr;
}
}
/*
* Sets the default operation for an ir_ops.
*/
static void set_default_operations(unsigned code, ir_op_ops *ops)
{
firm_set_default_hash(code, ops);
firm_set_default_computed_value(code, ops);
firm_set_default_equivalent_node(code, ops);
firm_set_default_transform_node(code, ops);
firm_set_default_node_cmp_attr(code, ops);
firm_set_default_get_type_attr(code, ops);
firm_set_default_get_entity_attr(code, ops);
firm_set_default_copy_attr(code, ops);
firm_set_default_verifier(code, ops);
firm_set_default_reassoc(code, ops);
}
static ir_type *default_get_type_attr(const ir_node *node);
static ir_entity *default_get_entity_attr(const ir_node *node);
static unsigned default_hash_node(const ir_node *node);
static void default_copy_attr(ir_graph *irg, const ir_node *old_node,
ir_node *new_node);
ir_op *new_ir_op(unsigned code, const char *name, op_pin_state p,
unsigned flags, op_arity opar, int op_index, size_t attr_size,
const ir_op_ops *ops)
irop_flags flags, op_arity opar, int op_index,
size_t attr_size)
{
ir_op *res = XMALLOCZ(ir_op);
......@@ -174,12 +63,11 @@ ir_op *new_ir_op(unsigned code, const char *name, op_pin_state p,
res->op_index = op_index;
res->tag = 0;
if (ops)
res->ops = *ops;
else /* no given ops, set all operations to NULL */
memset(&res->ops, 0, sizeof(res->ops));
set_default_operations(code, &res->ops);
memset(&res->ops, 0, sizeof(res->ops));
res->ops.hash = default_hash_node;
res->ops.copy_attr = default_copy_attr;
res->ops.get_type_attr = default_get_type_attr;
res->ops.get_entity_attr = default_get_entity_attr;
{
size_t len = ARR_LEN(opcodes);
......@@ -313,6 +201,403 @@ irop_flags get_op_flags(const ir_op *op)
return (irop_flags)op->flags;
}
static ir_type *default_get_type_attr(const ir_node *node)
{
(void)node;
return get_unknown_type();
}
static ir_entity *default_get_entity_attr(const ir_node *node)
{
(void)node;
return NULL;
}
static unsigned default_hash_node(const ir_node *node)
{
unsigned h;
int i, irn_arity;
/* hash table value = 9*(9*(9*(9*(9*arity+in[0])+in[1])+ ...)+mode)+code */
h = irn_arity = get_irn_arity(node);
/* consider all in nodes... except the block if not a control flow. */
for (i = is_cfop(node) ? -1 : 0; i < irn_arity; ++i) {
ir_node *pred = get_irn_n(node, i);
if (is_irn_cse_neutral(pred))
h *= 9;
else
h = 9*h + hash_ptr(pred);
}
/* ...mode,... */
h = 9*h + hash_ptr(get_irn_mode(node));
/* ...and code */
h = 9*h + hash_ptr(get_irn_op(node));
return h;
}
/**
* Calculate a hash value of a Const node.
*/
static unsigned hash_Const(const ir_node *node)
{
unsigned h;
/* special value for const, as they only differ in their tarval. */
h = hash_ptr(node->attr.con.tarval);
return h;
}
/**
* Calculate a hash value of a SymConst node.
*/
static unsigned hash_SymConst(const ir_node *node)
{
unsigned h;
/* all others are pointers */
h = hash_ptr(node->attr.symc.sym.type_p);
return h;
}
/** Compares two exception attributes */
static int node_cmp_exception(const ir_node *a, const ir_node *b)
{
const except_attr *ea = &a->attr.except;
const except_attr *eb = &b->attr.except;
return ea->pin_state != eb->pin_state;
}
/** Compares the attributes of two Const nodes. */
static int node_cmp_attr_Const(const ir_node *a, const ir_node *b)
{
return get_Const_tarval(a) != get_Const_tarval(b);
}
/** Compares the attributes of two Proj nodes. */
static int node_cmp_attr_Proj(const ir_node *a, const ir_node *b)
{
return a->attr.proj.proj != b->attr.proj.proj;
}
/** Compares the attributes of two Alloc nodes. */
static int node_cmp_attr_Alloc(const ir_node *a, const ir_node *b)
{
const alloc_attr *pa = &a->attr.alloc;
const alloc_attr *pb = &b->attr.alloc;
if (pa->where != pb->where || pa->type != pb->type)
return 1;
return node_cmp_exception(a, b);
}
/** Compares the attributes of two Free nodes. */
static int node_cmp_attr_Free(const ir_node *a, const ir_node *b)
{
const free_attr *pa = &a->attr.free;
const free_attr *pb = &b->attr.free;
return (pa->where != pb->where) || (pa->type != pb->type);
}
/** Compares the attributes of two SymConst nodes. */
static int node_cmp_attr_SymConst(const ir_node *a, const ir_node *b)
{
const symconst_attr *pa = &a->attr.symc;
const symconst_attr *pb = &b->attr.symc;
return (pa->kind != pb->kind)
|| (pa->sym.type_p != pb->sym.type_p);
}
/** Compares the attributes of two Call nodes. */
static int node_cmp_attr_Call(const ir_node *a, const ir_node *b)
{
const call_attr *pa = &a->attr.call;
const call_attr *pb = &b->attr.call;
if (pa->type != pb->type)
return 1;
return node_cmp_exception(a, b);
}
/** Compares the attributes of two Sel nodes. */
static int node_cmp_attr_Sel(const ir_node *a, const ir_node *b)
{
const ir_entity *a_ent = get_Sel_entity(a);
const ir_entity *b_ent = get_Sel_entity(b);
return a_ent != b_ent;
}
/** Compares the attributes of two Phi nodes. */
static int node_cmp_attr_Phi(const ir_node *a, const ir_node *b)
{
(void) b;
/* do not CSE Phi-nodes without any inputs when building new graphs */
if (get_irn_arity(a) == 0 &&
get_irg_phase_state(get_irn_irg(a)) == phase_building) {
return 1;
}
return 0;
}
/** Compares the attributes of two Conv nodes. */
static int node_cmp_attr_Conv(const ir_node *a, const ir_node *b)
{
return get_Conv_strict(a) != get_Conv_strict(b);
}
/** Compares the attributes of two Cast nodes. */
static int node_cmp_attr_Cast(const ir_node *a, const ir_node *b)
{
return get_Cast_type(a) != get_Cast_type(b);
}