+#ifdef NDEBUG
+/*
+ * in RELEASE mode, returns ret if the expression expr evaluates to zero
+ * in ASSERT mode, asserts the expression expr (and the string string).
+ */
+#define ASSERT_AND_RET(expr, string, ret) if (!(expr)) return (ret)
+
+/*
+ * in RELEASE mode, returns ret if the expression expr evaluates to zero
+ * in ASSERT mode, executes blk if the expression expr evaluates to zero and asserts
+ */
+#define ASSERT_AND_RET_DBG(expr, string, ret, blk) if (!(expr)) return (ret)
+#else
+#define ASSERT_AND_RET(expr, string, ret) do { assert((expr) && string); if (!(expr)) return (ret); } while(0)
+#define ASSERT_AND_RET_DBG(expr, string, ret, blk) do { if (!(expr)) { { blk } assert(0 && string); return (ret); } } while(0)
+#endif
+
+/* @@@ replace use of array "in" by access functions. */
+ir_node **get_irn_in(ir_node *node);
+
+INLINE static int
+vrfy_Proj_proj(ir_node *p, ir_graph *irg) {
+ ir_node *pred;
+ ir_mode *mode;
+ int proj;
+
+ pred = skip_nop(get_Proj_pred(p));
+ assert(get_irn_mode(pred) == mode_T);
+ mode = get_irn_mode(p);
+ proj = get_Proj_proj(p);
+
+ switch (get_irn_opcode(pred)) {
+ case iro_Start:
+ ASSERT_AND_RET(
+ (
+ (proj == pns_initial_exec && mode == mode_X) ||
+ (proj == pns_global_store && mode == mode_M) ||
+ (proj == pns_frame_base && mode_is_reference(mode)) ||
+ (proj == pns_globals && mode_is_reference(mode)) ||
+ (proj == pns_args && mode == mode_T) ||
+ (proj == pns_value_arg_base && mode_is_reference(mode))
+ ),
+ "wrong Proj from Start", 0);
+ break;
+
+ case iro_Cond:
+ ASSERT_AND_RET( (proj >= 0 && mode == mode_X), "wrong Proj from Cond", 0);
+ break;
+
+ case iro_Raise:
+ ASSERT_AND_RET(
+ ((proj == 0 && mode == mode_X) ||
+ (proj == 1 && mode == mode_M)),
+ "wrong Proj from Raise", 0);
+ break;
+
+ case iro_InstOf:
+ ASSERT_AND_RET( (proj >= 0 && mode == mode_X), "wrong Proj from InstOf", 0);
+ break;
+
+ case iro_Call:
+ ASSERT_AND_RET(
+ ((proj == 0 && mode == mode_M) ||
+ (proj == 1 && mode == mode_X) ||
+ (proj == 2 && mode == mode_T) ||
+ (proj == 3 && mode == mode_M)),
+ "wrong Proj from Call", 0);
+ break;
+
+ case iro_Quot:
+ ASSERT_AND_RET(
+ ((proj == 0 && mode == mode_M) ||
+ (proj == 1 && mode == mode_X) ||
+ (proj == 2 && mode_is_float(mode))),
+ "wrong Proj from Quot", 0);
+ break;
+
+ case iro_DivMod:
+ ASSERT_AND_RET(
+ ((proj == 0 && mode == mode_M) ||
+ (proj == 1 && mode == mode_X) ||
+ (proj == 2 && mode == mode_Is) ||
+ (proj == 3 && mode_is_int(mode))),
+ "wrong Proj from DivMod", 0);
+ break;
+
+ case iro_Div:
+ case iro_Mod:
+ ASSERT_AND_RET(
+ ((proj == 0 && mode == mode_M) ||
+ (proj == 1 && mode == mode_X) ||
+ (proj == 2 && mode_is_int(mode))),
+ "wrong Proj from Div or Mod", 0);
+ break;
+
+ case iro_Cmp:
+ ASSERT_AND_RET(
+ (proj >= 0 && proj <= 15 && mode == mode_b),
+ "wrong Proj from Cmp", 0);
+ break;
+
+ case iro_Load:
+ ASSERT_AND_RET(
+ ((proj == 0 && mode == mode_M) ||
+ (proj == 1 && mode == mode_X) ||
+ (proj == 2 && mode_is_data(mode))),
+ "wrong Proj from Load", 0);
+ break;
+
+ case iro_Store:
+ ASSERT_AND_RET(
+ ((proj == 0 && mode == mode_M) ||
+ (proj == 1 && mode == mode_X)),
+ "wrong Proj from Store", 0);
+ break;
+
+ case iro_Alloc:
+ ASSERT_AND_RET(
+ (
+ (proj == 0 && mode == mode_M) ||
+ (proj == 1 /* && mode == mode_X*/) ||
+ (proj == 2 && mode_is_reference(mode))
+ ),
+ "wrong Proj from Alloc", 0);
+ break;
+
+ case iro_Proj:
+ {
+ type *mt; /* A method type */
+ pred = skip_nop(get_Proj_pred(pred));
+ ASSERT_AND_RET((get_irn_mode(pred) == mode_T), "Proj from something not a tuple", 0);
+ switch (get_irn_opcode(pred))
+ {
+ case iro_Start:
+ {
+ ASSERT_AND_RET(
+ (proj >= 0 && mode_is_data(mode)),
+ "wrong Proj from Proj from Start", 0);
+ mt = get_entity_type(get_irg_ent(irg));
+ ASSERT_AND_RET(
+ (proj < get_method_n_params(mt)),
+ "More Projs for args than args in type", 0);
+ if ((mode_is_reference(mode)) && is_compound_type(get_method_param_type(mt, proj)))
+ /* value argument */ break;