+ /* Make a not spillable copy of the different node */
+ /* this is needed because the different irn could be */
+ /* in block far far away */
+ /* The copy is optimized later if not needed */
+
+ /* check if already exists such a copy in the schedule immediatly before */
+ cpy = find_copy(env, belower_skip_proj(irn), other_different);
+ if (! cpy) {
+ cpy = be_new_Copy(cls, birg->irg, block, other_different);
+ be_node_set_flags(cpy, BE_OUT_POS(0), arch_irn_flags_dont_spill);
+ DBG((mod, LEVEL_1, "created non-spillable %+F for value %+F\n", cpy, other_different));
+ }
+ else {
+ DBG((mod, LEVEL_1, "using already existing %+F for value %+F\n", cpy, other_different));
+ }
+
+ in[0] = irn;
+ in[1] = cpy;
+
+ /* Add the Keep resp. CopyKeep and reroute the users */
+ /* of the other_different irn in case of CopyKeep. */
+ if (get_n_out_edges(other_different) == 0) {
+ keep = be_new_Keep(cls, birg->irg, block, 2, in);
+ }
+ else {
+ keep = be_new_CopyKeep_single(cls, birg->irg, block, cpy, irn, get_irn_mode(other_different));
+ be_node_set_reg_class(keep, 1, cls);
+ }
+
+ DBG((mod, LEVEL_1, "created %+F(%+F, %+F)\n\n", keep, irn, cpy));
+
+ /* insert copy and keep into schedule */
+ assert(sched_is_scheduled(irn) && "need schedule to assure constraints");
+ if (! sched_is_scheduled(cpy))
+ sched_add_before(belower_skip_proj(irn), cpy);
+ sched_add_after(irn, keep);
+
+ /* insert the other different and it's copies into the set */
+ key.op = other_different;
+ key.copies = NULL;
+ entry = pset_find(op_set, &key, nodeset_hash(other_different));
+
+ if (! entry) {
+ entry = obstack_alloc(&env->obst, sizeof(*entry));
+ entry->copies = pset_new_ptr_default();
+ entry->op = other_different;
+ entry->cls = cls;
+ }
+
+ /* insert copy */
+ pset_insert_ptr(entry->copies, cpy);
+
+ /* insert keep in case of CopyKeep */
+ if (be_is_CopyKeep(keep))
+ pset_insert_ptr(entry->copies, keep);
+
+ pset_insert(op_set, entry, nodeset_hash(other_different));
+}
+
+/**
+ * Checks if node has a should_be_different constraint in output
+ * and adds a Keep then to assure the constraint.
+ */
+static void assure_different_constraints(ir_node *irn, constraint_env_t *env) {
+ const arch_register_req_t *req;
+ arch_register_req_t req_temp;
+
+ req = arch_get_register_req(env->birg->main_env->arch_env, &req_temp, irn, -1);
+
+ if (req) {
+ if (arch_register_req_is(req, should_be_different)) {
+ gen_assure_different_pattern(irn, req->other_different, env);
+ }
+ else if (arch_register_req_is(req, should_be_different_from_all)) {
+ int i, n = get_irn_arity(belower_skip_proj(irn));
+ for (i = 0; i < n; i++) {
+ gen_assure_different_pattern(irn, get_irn_n(belower_skip_proj(irn), i), env);
+ }