-/* Copyright (C) 1998 - 2000 by Universitaet Karlsruhe
- * All rights reserved.
- *
- * Authors: Christian Schaefer
- *
- *
+/*
+ * Project: libFIRM
+ * File name: ir/ir/irvrfy.c
+ * Purpose: Check irnodes for correctness.
+ * Author: Christian Schaefer
+ * Modified by: Goetz Lindenmaier. Till Riedel
+ * Created:
+ * CVS-ID: $Id$
+ * Copyright: (c) 1998-2003 Universität Karlsruhe
+ * Licence: This file protected by GPL - GNU GENERAL PUBLIC LICENSE.
*/
-/* $Id$ */
-
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
# include "irgwalk.h"
#ifdef NDEBUG
-#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, 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(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. */
switch (get_irn_opcode(pred)) {
case iro_Start:
ASSERT_AND_RET(
- ((proj == 0 && mode == mode_X) ||
- (proj == 1 && mode == mode_M) ||
- (proj == 2 && mode == mode_P) ||
- (proj == 3 && mode == mode_P) ||
- (proj == 4 && mode == mode_T)),
+ (
+ (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_Alloc:
ASSERT_AND_RET(
- ((proj == 0 && mode == mode_M) ||
+ (
+ (proj == 0 && mode == mode_M) ||
(proj == 1 /* && mode == mode_X*/) ||
- (proj == 2 && mode == mode_P)),
+ (proj == 2 && mode_is_reference(mode))
+ ),
"wrong Proj from Alloc", 0);
break;
ASSERT_AND_RET(
(proj < get_method_n_params(mt)),
"More Projs for args than args in type", 0);
- if ((mode == mode_P) && is_compound_type(get_method_param_type(mt, proj)))
+ if ((mode_is_reference(mode)) && is_compound_type(get_method_param_type(mt, proj)))
/* value argument */ break;
ASSERT_AND_RET(
ASSERT_AND_RET(
(proj < get_method_n_ress(mt)),
"More Projs for results than results in type.", 0);
- if ((mode == mode_P) && is_compound_type(get_method_res_type(mt, proj)))
+ if ((mode_is_reference(mode)) && is_compound_type(get_method_res_type(mt, proj)))
/* value result */ break;
ASSERT_AND_RET(
int opcode, opcode1;
ir_mode *mymode, *op1mode = NULL, *op2mode, *op3mode;
int op_is_symmetric = 1; /* 0: asymmetric
-1: operands have identical modes
-2: modes of operands == mode of this node */
+ 1: operands have identical modes
+ 2: modes of operands == mode of this node */
type *mt; /* A method type */
ir_node **in;
switch (opcode)
{
+
+ case iro_Block:
+ for (i = 0; i < get_Block_n_cfgpreds(n); ++i) {
+ ir_node *pred = get_Block_cfgpred(n, i);
+ ASSERT_AND_RET((is_Bad(pred) || (get_irn_mode(pred) == mode_X)), "Block node", 0);
+ }
+ // End block may only have Return, Raise or fragile ops as preds.
+ if (n == get_irg_end_block(irg))
+ for (i = 0; i < get_Block_n_cfgpreds(n); ++i) {
+ ir_node *pred = skip_Proj(get_Block_cfgpred(n, i));
+ if (is_Proj(pred) || get_irn_op(pred) == op_Tuple)
+ break; // We can not test properly. How many tuples are there?
+ ASSERT_AND_RET(((get_irn_op(pred) == op_Return) ||
+ is_Bad(pred) ||
+ (get_irn_op(pred) == op_Raise) ||
+ is_fragile_op(pred) ),
+ "End Block node", 0);
+ }
+ break;
+
case iro_Start:
ASSERT_AND_RET(
- /* Start: BB --> X x M x P x data1 x ... x datan */
+ /* Start: BB --> X x M x ref x data1 x ... x datan x ref */
mymode == mode_T, "Start node", 0
);
break;
op1mode = get_irn_mode(in[1]);
op2mode = get_irn_mode(in[2]);
ASSERT_AND_RET(
- /* Sel: BB x M x P --> X x M */
- op1mode == mode_M && op2mode == mode_P &&
+ /* Sel: BB x M x ref --> X x M */
+ op1mode == mode_M && mode_is_reference(op2mode) &&
mymode == mode_T, "Raise node", 0
);
break;
ASSERT_AND_RET(
/* SymConst: BB --> int*/
(mode_is_int(mymode) ||
- /* SymConst: BB --> P*/
- mymode == mode_P)
+ /* SymConst: BB --> ref */
+ mode_is_reference(mymode))
,"SymConst node", 0);
break;
op1mode = get_irn_mode(in[1]);
op2mode = get_irn_mode(in[2]);
ASSERT_AND_RET(
- /* Sel: BB x M x P x int^n --> P */
- op1mode == mode_M && op2mode == mode_P &&
- mymode == mode_P, "Sel node", 0
+ /* Sel: BB x M x ref x int^n --> ref */
+ (op1mode == mode_M && op2mode == mymode && mode_is_reference(mymode)),
+ "Sel node", 0
);
for (i=3; i < get_irn_arity(n); i++)
{
case iro_Call:
op1mode = get_irn_mode(in[1]);
op2mode = get_irn_mode(in[2]);
- /* Call: BB x M x P x data1 x ... x datan
+ /* Call: BB x M x ref x data1 x ... x datan
--> M x datan+1 x ... x data n+m */
- ASSERT_AND_RET( op1mode == mode_M && op2mode == mode_P, "Call node", 0 ); /* operand M x P */
+ ASSERT_AND_RET( op1mode == mode_M && mode_is_reference(op2mode), "Call node", 0 ); /* operand M x ref */
for (i=3; i < get_irn_arity(n); i++) {
ASSERT_AND_RET( mode_is_data(get_irn_mode(in[i])), "Call node", 0 ); /* operand datai */
};
/* Compare arguments of node with those of type */
mt = get_Call_type(n);
- if (get_method_variadicity(mt) == variadic) {
+ if (get_method_variadicity(mt) == variadicity_variadic) {
ASSERT_AND_RET(
get_Call_n_params(n) >= get_method_n_params(mt),
"Number of args for Call doesn't match number of args in variadic type.",
}
for (i = 0; i < get_method_n_params(mt); i++) {
- ASSERT_AND_RET(
+ ASSERT_AND_RET_DBG(
get_irn_mode(get_Call_param(n, i)) == get_type_mode(get_method_param_type(mt, i)),
- "Mode of arg for Call doesn't match mode of arg type.", 0);
+ "Mode of arg for Call doesn't match mode of arg type.", 0,
+ {
+ int i;
+
+ fprintf(stderr, "Assertion for Call type-check failed: %s(", get_type_name(mt));
+ for (i = 0; i < get_method_n_params(mt); ++i) {
+ fprintf(stderr, "%s ", get_mode_name(get_type_mode(get_method_param_type(mt, i))));
+ }
+ fprintf(stderr, ") != CALL(");
+
+ for (i = 0; i < get_Call_n_params(n); ++i) {
+ fprintf(stderr, "%s ", get_mode_name(get_irn_mode(get_Call_param(n, i))));
+ }
+ fprintf(stderr, ")\n");
+
+ }
+ );
}
break;
op1mode = get_irn_mode(in[1]);
op2mode = get_irn_mode(in[2]);
ASSERT_AND_RET(
- /* common Add: BB x num x num --> num */
- (( op1mode == mymode && op2mode == op1mode && mode_is_num(mymode)) ||
- /* Pointer Add: BB x P x int --> P */
- (op1mode == mode_P && mode_is_int(op2mode) && mymode == mode_P) ||
- /* Pointer Add: BB x int x P --> P */
- (mode_is_int(op1mode) && op2mode == mode_P && mymode == mode_P)),
+ (
+ /* common Add: BB x numP x numP --> numP */
+ (op1mode == mymode && op2mode == op1mode && mode_is_numP(mymode)) ||
+ /* Pointer Add: BB x ref x int --> ref */
+ (mode_is_reference(op1mode) && mode_is_int(op2mode) && op1mode == mymode) ||
+ /* Pointer Add: BB x int x ref --> ref */
+ (mode_is_int(op1mode) && op2mode == mymode && mode_is_reference(mymode))
+ ),
"Add node", 0
);
- if (op1mode == mode_P || op2mode == mode_P) {
- /* BB x P x int --> P or BB x int x P --> P */
- op_is_symmetric = 0; /* ArmRoq */
+ if (mode_is_reference(op1mode) != mode_is_reference(op2mode)) {
+ /* BB x ref x int --> ref or BB x int x ref --> ref */
+ op_is_symmetric = 0;
} else {
- /* BB x num x num --> num */
+ /* BB x num x num --> num or BB x ref x ref */
op_is_symmetric = 2;
}
break;
op1mode = get_irn_mode(in[1]);
op2mode = get_irn_mode(in[2]);
ASSERT_AND_RET(
- /* common Sub: BB x num x num --> num */
- ((mymode ==op1mode && mymode == op2mode && mode_is_num(op1mode)) ||
- /* Pointer Sub: BB x P x int --> P */
- (op1mode == mode_P && mode_is_int(op2mode) && mymode == mode_P) ||
- /* Pointer Sub: BB x int x P --> P */
- (mode_is_int(op1mode) && op2mode == mode_P && mymode == mode_P) ||
- /* Pointer Sub: BB x P x P --> int */
- (op1mode == mode_P && op2mode == mode_P && mode_is_int(mymode))),
+ /* common Sub: BB x numP x numP --> numP */
+ ((mymode ==op1mode && mymode == op2mode && mode_is_numP(op1mode)) ||
+ /* Pointer Sub: BB x ref x int --> ref */
+ (op1mode == mymode && mode_is_int(op2mode) && mode_is_reference(mymode)) ||
+ /* Pointer Sub: BB x int x ref --> ref */
+ (mode_is_int(op1mode) && op2mode == mymode && mode_is_reference(mymode)) ||
+ /* Pointer Sub: BB x ref x ref --> int */
+ (op1mode == op2mode && mode_is_reference(op2mode) && mode_is_int(mymode))),
"Sub node", 0
);
- if (op1mode == mode_P && op2mode == mode_P) {
- op_is_symmetric = 1; /* ArmRoq */
- } else if (op1mode == mode_P || op2mode == mode_P) {
- op_is_symmetric = 0; /* ArmRoq */
+ if (mode_is_reference(op1mode) != mode_is_reference(op2mode)) {
+ op_is_symmetric = 0;
} else {
op_is_symmetric = 2;
}
);
break;
+ case iro_Cast:
+ op1mode = get_irn_mode(in[1]);
+ ASSERT_AND_RET(
+ /* Conv: BB x datab1 --> datab2 */
+ mode_is_data(op1mode) && op1mode == mymode,
+ "Cast node", 0
+ );
+ break;
+
case iro_Phi:
/* Phi: BB x dataM^n --> dataM */
/* for some reason "<=" aborts. int there a problem with get_store? */
op1mode = get_irn_mode(in[1]);
op2mode = get_irn_mode(in[2]);
ASSERT_AND_RET(
- /* Load: BB x M x P --> M x X x data */
- op1mode == mode_M && op2mode == mode_P,
+ /* Load: BB x M x ref --> M x X x data */
+ op1mode == mode_M && mode_is_reference(op2mode),
"Load node", 0
);
ASSERT_AND_RET( mymode == mode_T, "Load node", 0 );
op2mode = get_irn_mode(in[2]);
op3mode = get_irn_mode(in[3]);
ASSERT_AND_RET(
- /* Load: BB x M x P x data --> M x X */
- op1mode == mode_M && op2mode == mode_P && mode_is_data(op3mode),
+ /* Load: BB x M x ref data --> M x X */
+ op1mode == mode_M && mode_is_reference(op2mode) && mode_is_data(op3mode),
"Store node", 0
);
ASSERT_AND_RET(mymode == mode_T, "Store node", 0);
op1mode = get_irn_mode(in[1]);
op2mode = get_irn_mode(in[2]);
ASSERT_AND_RET(
- /* Alloc: BB x M x int_u --> M x X x P */
+ /* Alloc: BB x M x int_u --> M x X x ref */
op1mode == mode_M &&
mode_is_int(op2mode) &&
!mode_is_signed(op2mode) &&
op1mode = get_irn_mode(in[1]);
op2mode = get_irn_mode(in[2]);
ASSERT_AND_RET(
- /* Free: BB x M x P --> M */
- op1mode == mode_M && op2mode == mode_P &&
+ /* Free: BB x M x ref --> M */
+ op1mode == mode_M && mode_is_reference(op2mode) &&
mymode == mode_M,
"Free node",0
);