- /* visit every Return */
- for (j = get_Block_n_cfgpreds(endbl) - 1; j >= 0; --j) {
- ir_node *node = get_Block_cfgpred(endbl, j);
- ir_op *op = get_irn_op(node);
- ir_node *mem;
-
- /* Bad nodes usually do NOT produce anything, so it's ok */
- if (op == op_Bad)
- continue;
-
- if (op == op_Return) {
- mem = get_Return_mem(node);
-
- /* Bad nodes usually do NOT produce anything, so it's ok */
- if (is_Bad(mem))
- continue;
-
- change = mem != get_irg_initial_mem(irg);
- if (change)
- break;
- }
- else {
- /* exception found */
- change = 1;
- break;
- }
+ /* exception found */
+ change = 1;
+ break;
+ }
+ }
+
+ if (! change) {
+ /* check, if a keep-alive exists */
+ for (j = get_End_n_keepalives(end) - 1; j >= 0; --j) {
+ ir_node *mem = get_End_keepalive(end, j);
+
+ if (mode_M != get_irn_mode(mem))
+ continue;
+
+ change = mem != get_irg_initial_mem(irg);
+ if (change)
+ break;
+ }
+ }
+
+ if (! change) {
+ /* no memory changes found, it's a const function */
+ set_irg_additional_property(irg, mtp_property_const);
+ return 1;
+ }
+ return 0;
+} /* is_const_function */
+#endif
+
+/* a marker */
+static char _mark;
+#define MARK &_mark
+
+#define UNMARK_IRG(irg) set_irg_link((irg), NULL)
+#define MARK_IRG(irg) set_irg_link((irg), MARK)
+#define IS_IRG_MARKED(irg) (get_irg_link(irg) == MARK)
+
+/* forward */
+static int is_pure_function(ir_graph *irg);
+
+#define UMAX(a,b) (a) > (b) ? (a) : (b)
+
+/**
+ * Follow the memory chain starting at node and determine
+ * the mtp_property.
+ *
+ * @return mtp_property_const if only calls of const functions are detected
+ * mtp_property_pure if only Loads and const/pure
+ * calls detected
+ * bad_property else
+ */
+static unsigned _follow_mem(ir_node *node) {
+ unsigned m, mode = mtp_property_const;
+ ir_node *ptr;
+ int i;
+
+ for (;;) {
+ if (irn_visited(node))
+ return mode;
+
+ mark_irn_visited(node);
+
+ switch (get_irn_opcode(node)) {
+ case iro_Proj:
+ node = get_Proj_pred(node);
+ break;
+
+ case iro_NoMem:
+ /* finish here */
+ return mode;
+
+ case iro_Phi:
+ case iro_Sync:
+ for (i = get_irn_arity(node) - 1; i >= 0; --i) {
+ mode &= _follow_mem(get_irn_n(node, i));