+/** lambda n.(n[i].partition) for commutative nodes */
+static void *lambda_commutative_partition(const node_t *node, environment_t *env) {
+ ir_node *irn = node->node;
+ ir_node *skipped = skip_Proj(irn);
+ ir_node *pred, *left, *right;
+ node_t *p;
+ partition_t *pl, *pr;
+ int i = env->lambda_input;
+
+ if (i >= get_irn_arity(node->node)) {
+ /*
+ * We are outside the allowed range: This can happen even
+ * if we have split by opcode first: doing so might move Followers
+ * to Leaders and those will have a different opcode!
+ * Note that in this case the partition is on the cprop list and will be
+ * split again.
+ */
+ return NULL;
+ }
+
+ /* ignore the "control input" for non-pinned nodes
+ if we are running in GCSE mode */
+ if (i < env->end_idx && get_irn_pinned(skipped) != op_pin_state_pinned)
+ return NULL;
+
+ if (i == -1) {
+ pred = get_irn_n(skipped, i);
+ p = get_irn_node(pred);
+ return p->part;
+ }
+
+ if (is_op_commutative(get_irn_op(irn))) {
+ /* normalize partition order by returning the "smaller" on input 0,
+ the "bigger" on input 1. */
+ left = get_binop_left(irn);
+ pl = get_irn_node(left)->part;
+ right = get_binop_right(irn);
+ pr = get_irn_node(right)->part;
+
+ if (i == 0)
+ return pl < pr ? pl : pr;
+ else
+ return pl > pr ? pl : pr;
+ } else {
+ /* a not split out Follower */
+ pred = get_irn_n(irn, i);
+ p = get_irn_node(pred);
+
+ return p->part;
+ }
+} /* lambda_commutative_partition */
+