long proj; /**< For Proj nodes, its proj number */
ir_entity *ent; /**< For Sel Nodes, its entity */
int intVal; /**< For Conv/Div Nodes: strict/remainderless */
+ unsigned uintVal;/**< for Builtin: the kind */
+ ir_node *block; /**< for Block: itself */
+ void *ptr; /**< generic pointer for hash/cmp */
} u;
};
key.u.intVal = get_Conv_strict(irn);
break;
case iro_Div:
- key.u.intVal = is_Div_remainderless(irn);
+ key.u.intVal = get_Div_no_remainder(irn);
+ break;
+ case iro_Block:
+ key.u.block = irn;
+ break;
+ case iro_Load:
+ key.mode = get_Load_mode(irn);
+ break;
+ case iro_Builtin:
+ key.u.intVal = get_Builtin_kind(irn);
break;
default:
break;
}
first = 0;
} else {
- assert(key.code == get_irn_opcode(irn));
+ assert((unsigned)key.code == get_irn_opcode(irn));
assert(key.mode == get_irn_mode(irn));
assert(key.arity == get_irn_arity(irn));
assert(key.u.intVal == get_Conv_strict(irn));
break;
case iro_Div:
- assert(key.u.intVal == is_Div_remainderless(irn));
+ assert(key.u.intVal == get_Div_no_remainder(irn));
+ break;
+ case iro_Block:
+ assert(key.u.block == irn);
+ break;
+ case iro_Load:
+ assert(key.mode == get_Load_mode(irn));
+ break;
+ case iro_Builtin:
+ assert(key.u.intVal == (int) get_Builtin_kind(irn));
break;
default:
break;
* @return a hash value for the given opcode map entry
*/
static unsigned opcode_hash(const opcode_key_t *entry) {
- return (entry->mode - (ir_mode *)0) * 9 + entry->code + entry->u.proj * 3 + HASH_PTR(entry->u.ent) + entry->arity;
+ return (entry->mode - (ir_mode *)0) * 9 + entry->code + entry->u.proj * 3 + HASH_PTR(entry->u.ptr) + entry->arity;
} /* opcode_hash */
/**
(void) size;
return o1->code != o2->code || o1->mode != o2->mode ||
o1->arity != o2->arity ||
- o1->u.proj != o2->u.proj || o1->u.ent != o2->u.ent ||
- o1->u.intVal != o2->u.intVal;
+ o1->u.proj != o2->u.proj ||
+ o1->u.intVal != o2->u.intVal || /* this already checks uIntVal */
+ o1->u.ptr != o2->u.ptr;
} /* cmp_opcode */
/**
key.u.intVal = get_Conv_strict(irn);
break;
case iro_Div:
- key.u.intVal = is_Div_remainderless(irn);
+ key.u.intVal = get_Div_no_remainder(irn);
+ break;
+ case iro_Block:
+ /*
+ * Some ugliness here: Two Blocks having the same
+ * IJmp predecessor would be congruent, which of course is wrong.
+ * We fix it by never letting blocks be congruent
+ * which cannot be detected by combo either.
+ */
+ key.u.block = irn;
+ break;
+ case iro_Load:
+ key.mode = get_Load_mode(irn);
+ break;
+ case iro_Builtin:
+ key.u.intVal = get_Builtin_kind(irn);
break;
default:
break;
pred = i == -1 ? get_irn_n(skipped, i) : get_irn_n(node->node, i);
p = get_irn_node(pred);
-
return p->part;
} /* lambda_partition */
int i;
ir_node *block = node->node;
- if (block == get_irg_start_block(current_ir_graph)) {
- /* start block is always reachable */
+ if (block == get_irg_start_block(current_ir_graph) || has_Block_label(block)) {
+ /* start block and labelled blocks are always reachable */
node->type.tv = tarval_reachable;
return;
}
node->type.tv = tarval_reachable;
} else if (selector->type.tv == tarval_top) {
if (tarval_UNKNOWN == tarval_top &&
- pnc == get_Cond_defaultProj(cond)) {
+ pnc == get_Cond_default_proj(cond)) {
/* a switch based of Top is always "default" */
node->type.tv = tarval_reachable;
} else {
}
} else {
long value = get_tarval_long(selector->type.tv);
- if (pnc == get_Cond_defaultProj(cond)) {
+ if (pnc == get_Cond_default_proj(cond)) {
/* default switch, have to check ALL other cases */
int i;
* Return non-zero if the control flow predecessor node pred
* is the only reachable control flow exit of its block.
*
- * @param pred the control flow exit
+ * @param pred the control flow exit
+ * @param block the destination block
*/
-static int can_exchange(ir_node *pred) {
- if (is_Start(pred))
+static int can_exchange(ir_node *pred, ir_node *block) {
+ if (is_Start(pred) || has_Block_label(block))
return 0;
else if (is_Jmp(pred))
return 1;
/* only one predecessor combine */
ir_node *pred = skip_Proj(get_Block_cfgpred(block, 0));
- if (can_exchange(pred)) {
+ if (can_exchange(pred, block)) {
ir_node *new_block = get_nodes_block(pred);
DB((dbg, LEVEL_1, "Fuse %+F with %+F\n", block, new_block));
DBG_OPT_COMBO(block, new_block, FS_OPT_COMBO_CF);
/* this Block has only one live predecessor */
ir_node *pred = skip_Proj(in_X[0]);
- if (can_exchange(pred)) {
+ if (can_exchange(pred, block)) {
ir_node *new_block = get_nodes_block(pred);
DBG_OPT_COMBO(block, new_block, FS_OPT_COMBO_CF);
exchange(block, new_block);
set_irg_extblk_inconsistent(irg);
set_irg_doms_inconsistent(irg);
set_irg_loopinfo_inconsistent(irg);
+ set_irg_entity_usage_state(irg, ir_entity_usage_not_computed);
}
ir_free_resources(irg, IR_RESOURCE_IRN_LINK | IR_RESOURCE_PHI_LIST);