+ if (! eset_contains(ctx->pure_fkt, ent))
+ return;
+ ctx->n_calls_removed_SymConst++;
+ }
+ else if (get_irn_op(ptr) == op_Sel &&
+ get_irg_callee_info_state(current_ir_graph) == irg_callee_info_consistent) {
+ /* If all possible callees are real functions, we can remove the memory edge. */
+ int i, n_callees = get_Call_n_callees(call);
+ if (n_callees == 0)
+ /* This is kind of strange: dying code or a Call that will raise an exception
+ when executed as there is no implementation to call. So better not
+ optimize. */
+ return;
+ for (i = 0; i < n_callees; ++i) {
+ if (! eset_contains(ctx->pure_fkt, get_Call_callee(call, i)))
+ return;
+ }
+ ctx->n_calls_removed_Sel++;
+ }
+ else return;
+
+ /* ok, if we get here we found a call to a pure function,
+ * route the NoMem node to the call */
+ mem = get_Call_mem(call);
+
+ set_irn_link(call, mem);
+ set_Call_mem(call, new_r_NoMem(current_ir_graph));
+
+ /* finally, this call can float */
+ set_irn_pinned(call, op_pin_state_floats);
+
+ hook_func_call(current_ir_graph, call);
+
+ ctx->changed = 1;
+ } else if (get_irn_op(node) == op_Proj) {
+ call = get_Proj_pred(node);
+ if ((get_irn_op(call) != op_Call) ||
+ (get_irn_op(get_Call_mem(call)) != op_NoMem))
+ return;
+
+ switch(get_Proj_proj(node)) {
+ case pn_Call_M_regular: {
+ ir_node *old_mem = get_irn_link(call);
+ if (old_mem) exchange(node, old_mem);
+ } break;
+ case pn_Call_X_except:
+ case pn_Call_M_except:
+ exchange(node, new_Bad());
+ break;
+ default: ;
+ }
+ }