/**
* must be called from peephole optimisations before a node will be killed
* and its users will be redirected to new_node.
- * so bepeephole can update it's internal state.
+ * so bepeephole can update its internal state.
*
- * Note: killing a node and rewiring os only allowed if new_node produces
+ * Note: killing a node and rewiring is only allowed if new_node produces
* the same registers as old_node.
*/
static void be_peephole_before_exchange(const ir_node *old_node,
/**
* Check whether the node has only one user. Explicitly ignore the anchor.
*/
-static int has_only_one_user(ir_node *node)
+bool be_has_only_one_user(ir_node *node)
{
int n = get_irn_n_edges(node);
+ int n_users;
const ir_edge_t *edge;
if (n <= 1)
return 1;
- if (n > 2)
- return 0;
-
+ n_users = 0;
foreach_out_edge(node, edge) {
ir_node *src = get_edge_src_irn(edge);
- if (is_Anchor(src))
- return 1;
+ /* ignore anchor and keep-alive edges */
+ if (is_Anchor(src) || is_End(src))
+ continue;
+ n_users++;
}
- return 0;
+ return n_users == 1;
}
/*
if (!be_is_IncSP(pred))
return node;
- if (!has_only_one_user(pred))
+ if (!be_has_only_one_user(pred))
return node;
pred_offs = be_get_IncSP_offset(pred);
curr_offs = be_get_IncSP_offset(node);
-
- if (pred_offs == BE_STACK_FRAME_SIZE_EXPAND) {
- if (curr_offs != BE_STACK_FRAME_SIZE_SHRINK) {
- return node;
- }
- offs = 0;
- } else if (pred_offs == BE_STACK_FRAME_SIZE_SHRINK) {
- if (curr_offs != BE_STACK_FRAME_SIZE_EXPAND) {
- return node;
- }
- offs = 0;
- } else if (curr_offs == BE_STACK_FRAME_SIZE_EXPAND ||
- curr_offs == BE_STACK_FRAME_SIZE_SHRINK) {
- return node;
- } else {
- offs = curr_offs + pred_offs;
- }
+ offs = curr_offs + pred_offs;
/* add node offset to pred and remove our IncSP */
be_set_IncSP_offset(pred, offs);
xfree(register_values);
}
-BE_REGISTER_MODULE_CONSTRUCTOR(be_init_peephole);
+BE_REGISTER_MODULE_CONSTRUCTOR(be_init_peephole)
void be_init_peephole(void)
{
FIRM_DBG_REGISTER(dbg, "firm.be.peephole");