This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[tree-ssa] PATCH to clean up GIMPLE predicates


This patch completes the transition to using predicates only to check for
valid forms, and not for simplicity.  Many of the old predicates have been
discarded, as they are no longer useful for that purpose.

I've also renamed some of the predicates for clarity.  is_gimple_varname
has become is_gimple_addr_expr_arg, while is_gimple_modify_expr_lhs has
become is_gimple_lvalue.  This is to clarify that if you want a general
lvalue, you want to use the latter predicate.

There are a couple of new predicates, as well:

is_gimple_variable tests for a variable; this is distinct from
is_gimple_id, which also allows functions, strings and such (and is static
until someone argues that it should be exposed).

is_gimple_reg is more restrictive--it only allows variables suitable for
renaming, i.e. nothing volatile, and nothing that needs to live in memory.

REALPART_EXPR and IMAGPART_EXPR are now handled as compound lvalues like
COMPONENT_REF and ARRAY_REF, rather than as transparent wrappers.

We now expand MIN_EXPR and MAX_EXPR into a COND_EXPR.

This seems to speed up bootstrap very slightly (~15 seconds out of 72
minutes of "user" time).

Tested athlon-pc-linux-gnu, applied to tree-ssa.

2003-08-21  Jason Merrill  <jason@redhat.com>

	* tree-simple.c: Total overhaul to only check forms and remove
	unnecessary predicates.
	(is_gimple_const): Accept function addresses here.
	Don't accept LABEL_DECL or RESULT_DECL.
	(is_gimple_val): Accept EXC_PTR_EXPR here.
	(is_gimple_lvalue): Rename from is_gimple_modify_expr_lhs.
	Accept BIT_FIELD_REF, REALPART_EXPR and IMAGPART_EXPR here.
	(is_gimple_addr_expr_arg): Replace with former is_gimple_varname.
	(is_gimple_constructor_elt): Just check for CONSTRUCTOR.
	(is_gimple_initializer): Just hand off to is_gimple_rhs.
	(is_gimple_rhs): Recognize most expressions here.
	(is_gimple_variable): New fn.
	(is_gimple_id): Use it.  Now static.
	(is_gimple_reg): New fn.
	(is_gimple_cast): Replace with former is_gimple_cast_op.
	(is_gimple_constructor, is_gimple_expr): Remove.
	(is_gimple_modify_expr, is_gimple_relop): Remove.
	(is_gimple_binary_expr, is_gimple_unary_expr): Remove.
	(is_gimple_call_expr, is_gimple_arglist): Remove.
	(is_gimple_compound_lval, is_gimple_arrayref): Remove.
	(is_gimple_compref, is_gimple_exprseq): Remove.
	(is_gimplifiable_builtin): Remove.
	* tree-simple.h: Adjust.
	* gimplify.c (gimplify_conversion): Break out from gimplify_expr.
	(gimplify_expr): Use is_gimple_reg predicate to force a temp.
	<COMPONENT_REF>: Use gimplify_compound_lval.
	<REALPART_EXPR, IMAGPART_EXPR>: Likewise.
	<INDIRECT_REF>: Use is_gimple_reg predicate.
	<MIN_EXPR, MAX_EXPR>: Use new gimplify_minimax_expr.
	<TREE_LIST>: Reject.
	(gimplify_tree_list, gimplify_component_ref): Remove.
	(gimplify_compound_lval): Include REALPART_EXPR and IMAGPART_EXPR.
	(gimplify_component_ref): Remove.
	(gimplify_call_expr): Handle non-gimplifiable builtins and walking
	the argument list here.
	(gimplify_tree_list): Remove.
	(gimplify_addr_expr): Use fb_either.
	* tree-alias-common.c (find_func_aliases): Update use of predicates.
	* cp/cp-simplify.c (cp_gimplify_init_expr): Update use of predicates.
	* fortran/trans-array.c (gfc_conv_expr_descriptor): Update use of 
	predicates.

*** ./gimplify.c.~1~	2003-08-21 14:40:25.000000000 -0400
--- ./gimplify.c	2003-08-21 15:06:27.000000000 -0400
*************** static void gimplify_constructor (tree, 
*** 46,54 ****
  static void gimplify_array_ref (tree *, tree *, tree *, int);
  static void gimplify_array_ref_to_plus (tree *, tree *, tree *);
  static void gimplify_compound_lval (tree *, tree *, tree *, int);
- static void gimplify_component_ref (tree *, tree *, tree *, int);
  static void gimplify_call_expr (tree *, tree *, tree *, int (*) (tree));
- static void gimplify_tree_list (tree *, tree *, tree *);
  static void gimplify_modify_expr (tree *, tree *, tree *, int);
  static void gimplify_compound_expr (tree *, tree *);
  static void gimplify_save_expr (tree *, tree *, tree *);
--- 46,52 ----
*************** static tree internal_get_tmp_var (tree, 
*** 88,93 ****
--- 86,94 ----
  static tree build_and_jump (tree *);
  static tree shortcut_cond_expr (tree);
  static tree gimple_boolify (tree);
+ static void gimplify_conversion (tree *);
+ static int gimplify_init_constructor (tree *, tree *, int);
+ static void gimplify_minimax_expr (tree *, tree *, tree *);
  
  static struct gimplify_ctx
  {
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 410,416 ****
  	  break;
  
  	case COMPONENT_REF:
! 	  gimplify_component_ref (expr_p, pre_p, post_p, fallback & fb_lvalue);
  	  break;
  
  	case COND_EXPR:
--- 411,417 ----
  	  break;
  
  	case COMPONENT_REF:
! 	  gimplify_compound_lval (expr_p, pre_p, post_p, fallback & fb_lvalue);
  	  break;
  
  	case COND_EXPR:
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 422,429 ****
  	  break;
  
  	case TREE_LIST:
! 	  gimplify_tree_list (expr_p, pre_p, post_p);
! 	  break;
  
  	case COMPOUND_EXPR:
  	  if (is_statement)
--- 423,429 ----
  	  break;
  
  	case TREE_LIST:
! 	  abort ();
  
  	case COMPOUND_EXPR:
  	  if (is_statement)
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 434,441 ****
  
  	case REALPART_EXPR:
  	case IMAGPART_EXPR:
! 	  gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
! 			 gimple_test_f, fallback);
  	  break;
  
  	case MODIFY_EXPR:
--- 434,440 ----
  
  	case REALPART_EXPR:
  	case IMAGPART_EXPR:
! 	  gimplify_compound_lval (expr_p, pre_p, post_p, fallback & fb_lvalue);
  	  break;
  
  	case MODIFY_EXPR:
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 475,520 ****
  	      break;
  	    }
  
! 	  /* If a NOP conversion is changing the type of a COMPONENT_REF
! 	     expression, then it is safe to force the type of the
! 	     COMPONENT_REF to be the same as the type of the field the
! 	     COMPONENT_REF is accessing.
! 
! 	     This is a profitable thing to do as canonicalization of
! 	     types on COMPONENT_REFs exposes more redundant COMPONENT_REFs.  */
! 	  if (TREE_CODE (TREE_OPERAND (*expr_p, 0)) == COMPONENT_REF)
! 	    {
! 	      TREE_TYPE (TREE_OPERAND (*expr_p, 0))
! 		= TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*expr_p, 0), 1));
! 	    }
! 
! 	  /* Strip away as many useless type conversions as possible
! 	     at the toplevel.  */
! 	  while (tree_ssa_useless_type_conversion (*expr_p))
! 	    *expr_p = TREE_OPERAND (*expr_p, 0);
! 
! 	  /* If we still have a conversion at the toplevel, then strip
! 	     away all but the outermost conversion.  */
! 	  if (TREE_CODE (*expr_p) == NOP_EXPR
! 	      || TREE_CODE (*expr_p) == CONVERT_EXPR)
! 	    {
! 	      STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
! 
! 	      /* And remove the outermost conversion if it's useless.  */
! 	      if (TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p))
! 		  == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
! 		{
! 		  *expr_p = TREE_OPERAND (*expr_p, 0);
! 		  break;
! 		}
! 	    }
! 	  else
  	    break;
  
  	case FIX_TRUNC_EXPR:
  	case FIX_CEIL_EXPR:
  	case FIX_FLOOR_EXPR:
  	case FIX_ROUND_EXPR:
  	  gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
  			 is_gimple_val, fb_rvalue);
  	  recalculate_side_effects (*expr_p);
--- 474,488 ----
  	      break;
  	    }
  
! 	  gimplify_conversion (expr_p);
! 	  if (*expr_p != save_expr)
  	    break;
  
  	case FIX_TRUNC_EXPR:
  	case FIX_CEIL_EXPR:
  	case FIX_FLOOR_EXPR:
  	case FIX_ROUND_EXPR:
+ 	  /* unary_expr: ... | '(' cast ')' val | ...  */
  	  gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
  			 is_gimple_val, fb_rvalue);
  	  recalculate_side_effects (*expr_p);
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 522,540 ****
  
  	case INDIRECT_REF:
  	  gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
! 			 is_gimple_id, fb_rvalue);
! 
! 	  /* If we are indirecting a variable in memory, load the
! 	     variable into a temporary and indirect the temporary.  */
! 	  tmp = TREE_OPERAND (*expr_p, 0);
! 	  if (DECL_P (tmp)
! 	      && (decl_function_context (tmp) == NULL
! 		  || TREE_STATIC (tmp)
! 		  || TREE_ADDRESSABLE (tmp)))
! 	    {
! 	      tmp = get_formal_tmp_var (tmp, pre_p);
! 	      TREE_OPERAND (*expr_p, 0) = tmp;
! 	    }
  
  	  recalculate_side_effects (*expr_p);
  	  break;
--- 490,496 ----
  
  	case INDIRECT_REF:
  	  gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
! 			 is_gimple_reg, fb_rvalue);
  
  	  recalculate_side_effects (*expr_p);
  	  break;
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 679,689 ****
  			 is_gimple_min_lval, fb_lvalue);
  	  break;
  
- 	  /* FIXME
  	case MIN_EXPR:
  	case MAX_EXPR:
! 	  gimplify_minimax_expr (expr_p, pre_p);
! 	  break; */
  
  	case LABEL_DECL:
  	  /* We get here when taking the address of a label.  We mark
--- 635,643 ----
  			 is_gimple_min_lval, fb_lvalue);
  	  break;
  
  	case MIN_EXPR:
  	case MAX_EXPR:
! 	  gimplify_minimax_expr (expr_p, pre_p, post_p);
  
  	case LABEL_DECL:
  	  /* We get here when taking the address of a label.  We mark
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 708,713 ****
--- 662,668 ----
  		     || TREE_CODE (*expr_p) == TRUTH_OR_EXPR
  		     || TREE_CODE (*expr_p) == TRUTH_XOR_EXPR)
  	      {
+ 		/* binary_expr : val binop val  */
  		gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
  			       is_gimple_val, fb_rvalue);
  
*************** gimplify_expr (tree *expr_p, tree *pre_p
*** 793,805 ****
       object the lvalue refers to would (probably) be modified by the
       postqueue; we need to copy the value out first, which means an
       rvalue.  */
!   if ((fallback & fb_lvalue) && !internal_post && is_gimple_varname (*expr_p))
      {
        /* An lvalue will do.  Take the address of the expression, store it
  	 in a temporary, and replace the expression with an INDIRECT_REF of
  	 that temporary.  */
        tmp = build_addr_expr (*expr_p);
!       gimplify_expr (&tmp, pre_p, post_p, is_gimple_id, fb_rvalue);
        *expr_p = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (tmp)), tmp);
      }
    else if ((fallback & fb_rvalue) && is_gimple_rhs (*expr_p))
--- 748,761 ----
       object the lvalue refers to would (probably) be modified by the
       postqueue; we need to copy the value out first, which means an
       rvalue.  */
!   if ((fallback & fb_lvalue) && !internal_post
!       && is_gimple_addr_expr_arg (*expr_p))
      {
        /* An lvalue will do.  Take the address of the expression, store it
  	 in a temporary, and replace the expression with an INDIRECT_REF of
  	 that temporary.  */
        tmp = build_addr_expr (*expr_p);
!       gimplify_expr (&tmp, pre_p, post_p, is_gimple_reg, fb_rvalue);
        *expr_p = build1 (INDIRECT_REF, TREE_TYPE (TREE_TYPE (tmp)), tmp);
      }
    else if ((fallback & fb_rvalue) && is_gimple_rhs (*expr_p))
*************** gimplify_exit_expr (tree *expr_p)
*** 1163,1169 ****
    *expr_p = expr;
  }
  
! /* Gimplifies a CONSTRUCTOR node at *EXPR_P.  */
  
  static void
  gimplify_constructor (tree t, tree *pre_p, tree *post_p)
--- 1119,1129 ----
    *expr_p = expr;
  }
  
! /* Gimplifies a CONSTRUCTOR node at *EXPR_P.
! 
!      aggr_init: '{' vals '}'
!      vals: aggr_init_elt | vals ',' aggr_init_elt
!      aggr_init_elt: val | aggr_init  */
  
  static void
  gimplify_constructor (tree t, tree *pre_p, tree *post_p)
*************** gimplify_init_constructor (tree *expr_p,
*** 1264,1269 ****
--- 1224,1289 ----
    return 0;
  }
  
+ /* *EXPR_P is a NOP_EXPR or CONVERT_EXPR.  Remove it and/or other conversions
+    underneath as appropriate.  */
+ 
+ static void
+ gimplify_conversion (tree *expr_p)
+ {  
+   /* If a NOP conversion is changing the type of a COMPONENT_REF
+      expression, then it is safe to force the type of the
+      COMPONENT_REF to be the same as the type of the field the
+      COMPONENT_REF is accessing.
+ 
+      This is a profitable thing to do as canonicalization of
+      types on COMPONENT_REFs exposes more redundant COMPONENT_REFs.  */
+   if (TREE_CODE (TREE_OPERAND (*expr_p, 0)) == COMPONENT_REF)
+     {
+       TREE_TYPE (TREE_OPERAND (*expr_p, 0))
+ 	= TREE_TYPE (TREE_OPERAND (TREE_OPERAND (*expr_p, 0), 1));
+     }
+ 
+   /* Strip away as many useless type conversions as possible
+      at the toplevel.  */
+   while (tree_ssa_useless_type_conversion (*expr_p))
+     *expr_p = TREE_OPERAND (*expr_p, 0);
+ 
+   /* If we still have a conversion at the toplevel, then strip
+      away all but the outermost conversion.  */
+   if (TREE_CODE (*expr_p) == NOP_EXPR
+       || TREE_CODE (*expr_p) == CONVERT_EXPR)
+     {
+       STRIP_SIGN_NOPS (TREE_OPERAND (*expr_p, 0));
+ 
+       /* And remove the outermost conversion if it's useless.  */
+       if (TYPE_MAIN_VARIANT (TREE_TYPE (*expr_p))
+ 	  == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (*expr_p, 0))))
+ 	*expr_p = TREE_OPERAND (*expr_p, 0);
+     }
+ }
+ 
+ /* Reduce MIN/MAX_EXPR to a COND_EXPR for further gimplification.  */
+ 
+ static void
+ gimplify_minimax_expr (tree *expr_p, tree *pre_p, tree *post_p)
+ {
+   tree op1 = TREE_OPERAND (*expr_p, 0);
+   tree op2 = TREE_OPERAND (*expr_p, 1);
+   enum tree_code code;
+ 
+   if (TREE_CODE (*expr_p) == MIN_EXPR)
+     code = LE_EXPR;
+   else
+     code = GE_EXPR;
+ 
+   gimplify_expr (&op1, pre_p, post_p, is_gimple_val, fb_rvalue);
+   gimplify_expr (&op2, pre_p, post_p, is_gimple_val, fb_rvalue);
+ 
+   *expr_p = build (COND_EXPR, TREE_TYPE (*expr_p),
+ 		   build (code, boolean_type_node, op1, op2),
+ 		   op1, op2);
+ }
+ 
  /*  Build an expression for the address of T.  Folds away INDIRECT_REF to
      avoid confusing the gimplify process.  */
  
*************** static void
*** 1305,1311 ****
  gimplify_array_ref (tree *expr_p, tree *pre_p,
  		    tree *post_p, int want_lvalue)
  {
- #if 1
    tree elttype = TREE_TYPE (TREE_TYPE (TREE_OPERAND (*expr_p, 0)));
    if (!TREE_CONSTANT (TYPE_SIZE_UNIT (elttype)))
      /* If the size of the array elements is not constant,
--- 1325,1330 ----
*************** gimplify_array_ref (tree *expr_p, tree *
*** 1315,1351 ****
      /* Handle array and member refs together for now.  When alias analysis
         improves, we may want to go back to handling them separately.  */
      gimplify_compound_lval (expr_p, pre_p, post_p, want_lvalue);
- #else
-   tree *p;
-   varray_type dim_stack;
- 
- #if defined ENABLE_CHECKING
-   if (TREE_CODE (*expr_p) != ARRAY_REF)
-     abort ();
- #endif
- 
-   VARRAY_GENERIC_PTR_INIT (dim_stack, 10, "dim_stack");
- 
-   /* Create a stack with all the dimensions of the array so that they can
-      be gimplified from left to right.  */
-   for (p = expr_p; TREE_CODE (*p) == ARRAY_REF; p = &TREE_OPERAND (*p, 0))
-     VARRAY_PUSH_GENERIC_PTR (dim_stack, (PTR) &TREE_OPERAND (*p, 1));
- 
-   /* After the loop above, 'p' points to the first non-ARRAY_REF,
-      and 'dim_stack' is a stack of pointers to all the dimensions in left
-      to right order (the leftmost dimension is at the top of the stack).
- 
-      Gimplify the base, and then each of the dimensions from left to
-      right.  */
- 
-   gimplify_expr (p, pre_p, post_p, is_gimple_min_lval, fb_lvalue);
- 
-   for (; VARRAY_ACTIVE_SIZE (dim_stack) > 0; VARRAY_POP (dim_stack))
-     {
-       tree *dim_p = (tree *)VARRAY_TOP_GENERIC_PTR (dim_stack);
-       gimplify_expr (dim_p, pre_p, post_p, is_gimple_val, fb_rvalue);
-     }
- #endif
  }
  
  /* Subroutine of gimplify_compound_lval.  Converts an ARRAY_REF to the
--- 1334,1339 ----
*************** gimplify_array_ref_to_plus (tree *expr_p
*** 1369,1375 ****
    *expr_p = build1 (INDIRECT_REF, elttype, result);
  }
  
! /* Gimplify the COMPONENT_REF or ARRAY_REF node pointed by EXPR_P.
  
     PRE_P points to the list where side effects that must happen before
       *EXPR_P should be stored.
--- 1357,1377 ----
    *expr_p = build1 (INDIRECT_REF, elttype, result);
  }
  
! /* Gimplify the COMPONENT_REF, ARRAY_REF, REALPART_EXPR or IMAGPART_EXPR
!    node pointed by EXPR_P.
! 
!       compound_lval
! 	      : min_lval '[' val ']'
! 	      | min_lval '.' ID
! 	      | compound_lval '[' val ']'
! 	      | compound_lval '.' ID
! 
!    This is not part of the original SIMPLE definition, which separates
!    array and member references, but it seems reasonable to handle them
!    together.  Also, this way we don't run into problems with union
!    aliasing; gcc requires that for accesses through a union to alias, the
!    union reference must be explicit, which was not always the case when we
!    were splitting up array and member refs.
  
     PRE_P points to the list where side effects that must happen before
       *EXPR_P should be stored.
*************** gimplify_compound_lval (tree *expr_p, tr
*** 1386,1392 ****
    varray_type stack;
  
  #if defined ENABLE_CHECKING
!   if (TREE_CODE (*expr_p) != ARRAY_REF && TREE_CODE (*expr_p) != COMPONENT_REF)
      abort ();
  #endif
  
--- 1388,1396 ----
    varray_type stack;
  
  #if defined ENABLE_CHECKING
!   if (TREE_CODE (*expr_p) != ARRAY_REF && TREE_CODE (*expr_p) != COMPONENT_REF
!       && TREE_CODE (*expr_p) != REALPART_EXPR
!       && TREE_CODE (*expr_p) != IMAGPART_EXPR)
      abort ();
  #endif
  
*************** gimplify_compound_lval (tree *expr_p, tr
*** 1397,1403 ****
    VARRAY_TREE_INIT (stack, 10, "stack");
  
    for (p = expr_p;
!        TREE_CODE (*p) == ARRAY_REF || TREE_CODE (*p) == COMPONENT_REF;
         p = &TREE_OPERAND (*p, 0))
      {
        code = TREE_CODE (*p);
--- 1401,1408 ----
    VARRAY_TREE_INIT (stack, 10, "stack");
  
    for (p = expr_p;
!        TREE_CODE (*p) == ARRAY_REF || TREE_CODE (*p) == COMPONENT_REF
! 	 || TREE_CODE (*p) == REALPART_EXPR || TREE_CODE (*p) == IMAGPART_EXPR;
         p = &TREE_OPERAND (*p, 0))
      {
        code = TREE_CODE (*p);
*************** gimplify_compound_lval (tree *expr_p, tr
*** 1412,1421 ****
        VARRAY_PUSH_TREE (stack, *p);
      }
  
!   /* Now 'p' points to the first bit that isn't an ARRAY_REF or
!      COMPONENT_REF, 'code' is the TREE_CODE of the last bit that was, and
!      'stack' is a stack of pointers to all the ARRAY_REFs and
!      COMPONENT_REFs we've walked through.
  
       Gimplify the base, and then process each of the outer nodes from left
       to right.  */
--- 1417,1425 ----
        VARRAY_PUSH_TREE (stack, *p);
      }
  
!   /* Now 'p' points to the first bit that isn't a ref, 'code' is the
!      TREE_CODE of the last bit that was, and 'stack' is a stack of pointers
!      to all the refs we've walked through.
  
       Gimplify the base, and then process each of the outer nodes from left
       to right.  */
*************** gimplify_self_mod_expr (tree *expr_p, tr
*** 1499,1506 ****
  
    /* Gimplify the LHS into a GIMPLE lvalue.  */
    lvalue = TREE_OPERAND (*expr_p, 0);
!   gimplify_expr (&lvalue, pre_p, post_p, is_gimple_modify_expr_lhs,
! 		 fb_lvalue);
  
    /* Extract the operands to the arithmetic operation.  */
    lhs = lvalue;
--- 1503,1509 ----
  
    /* Gimplify the LHS into a GIMPLE lvalue.  */
    lvalue = TREE_OPERAND (*expr_p, 0);
!   gimplify_expr (&lvalue, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
  
    /* Extract the operands to the arithmetic operation.  */
    lhs = lvalue;
*************** gimplify_self_mod_expr (tree *expr_p, tr
*** 1526,1567 ****
      *expr_p = t1;
  }
  
! /*  Gimplify the COMPONENT_REF node pointed by EXPR_P.
! 
!     PRE_P points to the list where side effects that must happen before
! 	*EXPR_P should be stored.
! 
!     POST_P points to the list where side effects that must happen after
!         *EXPR_P should be stored.  */
! 
! static void
! gimplify_component_ref (tree *expr_p, tree *pre_p,
! 			tree *post_p, int want_lvalue)
! {
! #if 1
!   /* Handle array and member refs together for now.  When alias analysis
!      improves, we may want to go back to handling them separately.  */
!   gimplify_compound_lval (expr_p, pre_p, post_p, want_lvalue);
! #else
!   tree *p;
! 
! #if defined ENABLE_CHECKING
!   if (TREE_CODE (*expr_p) != COMPONENT_REF)
!     abort ();
! #endif
! 
!   for (p = expr_p; TREE_CODE (*p) == COMPONENT_REF; p = &TREE_OPERAND (*p, 0))
!     if (! is_gimple_id (TREE_OPERAND (*p, 1)))
!       /* The RHS of a COMPONENT_REF should always be a FIELD_DECL.  */
!       abort ();
! 
!   /* Now we're down to the first bit that isn't a COMPONENT_REF.  */
!   gimplify_expr (p, pre_p, post_p, is_gimple_min_lval, fb_either);
! #endif
! }
  
  
! /*  Gimplify the CALL_EXPR node pointed by EXPR_P.
  
      PRE_P points to the list where side effects that must happen before
  	*EXPR_P should be stored.
--- 1529,1542 ----
      *expr_p = t1;
  }
  
! /*  Gimplify the CALL_EXPR node pointed by EXPR_P.
  
+       call_expr
+ 	      : ID '(' arglist ')'
  
!       arglist
! 	      : arglist ',' val
! 	      | val
  
      PRE_P points to the list where side effects that must happen before
  	*EXPR_P should be stored.
*************** gimplify_call_expr (tree *expr_p, tree *
*** 1574,1579 ****
--- 1549,1556 ----
  		    int (*gimple_test_f) (tree))
  {
    tree decl;
+   tree arglist;
+ 
  #if defined ENABLE_CHECKING
    if (TREE_CODE (*expr_p) != CALL_EXPR)
      abort ();
*************** gimplify_call_expr (tree *expr_p, tree *
*** 1594,1600 ****
    decl = get_callee_fndecl (*expr_p);
    if (decl && DECL_BUILT_IN (decl))
      {
!       tree new = simplify_builtin (*expr_p, gimple_test_f == is_gimple_stmt);
  
        if (new && new != *expr_p)
  	{
--- 1571,1592 ----
    decl = get_callee_fndecl (*expr_p);
    if (decl && DECL_BUILT_IN (decl))
      {
!       tree new;
! 
!       /* Some builtins cannot be gimplified because the require specific
! 	 arguments (e.g., MD builtins).  */
!       if (DECL_BUILT_IN_CLASS (decl) == BUILT_IN_MD
! 	  /* But we don't care if the call has no arguments.  */
! 	  && TREE_OPERAND (*expr_p, 1) != NULL_TREE)
! 	{
! 	  /* Mark the CALL_EXPR not gimplifiable so that optimizers don't
! 	     assume anything about it.  FIXME: Maybe we should add a target
! 	     hook for allowing this in the future?  */
! 	  mark_not_gimple (expr_p);
! 	  return;
! 	}
! 
!       new = simplify_builtin (*expr_p, gimple_test_f == is_gimple_stmt);
  
        if (new && new != *expr_p)
  	{
*************** gimplify_call_expr (tree *expr_p, tree *
*** 1611,1618 ****
  
    if (PUSH_ARGS_REVERSED)
      TREE_OPERAND (*expr_p, 1) = nreverse (TREE_OPERAND (*expr_p, 1));
!   gimplify_expr (&TREE_OPERAND (*expr_p, 1), pre_p, post_p,
! 		 is_gimple_arglist, fb_rvalue);
    if (PUSH_ARGS_REVERSED)
      TREE_OPERAND (*expr_p, 1) = nreverse (TREE_OPERAND (*expr_p, 1));
  
--- 1603,1612 ----
  
    if (PUSH_ARGS_REVERSED)
      TREE_OPERAND (*expr_p, 1) = nreverse (TREE_OPERAND (*expr_p, 1));
!   for (arglist = TREE_OPERAND (*expr_p, 1); arglist;
!        arglist = TREE_CHAIN (arglist))
!     gimplify_expr (&TREE_VALUE (arglist), pre_p, post_p, is_gimple_val,
! 		   fb_rvalue);
    if (PUSH_ARGS_REVERSED)
      TREE_OPERAND (*expr_p, 1) = nreverse (TREE_OPERAND (*expr_p, 1));
  
*************** gimplify_call_expr (tree *expr_p, tree *
*** 1639,1667 ****
      TREE_SIDE_EFFECTS (*expr_p) = 0;
  }
  
- /*  Gimplify the TREE_LIST node pointed by EXPR_P.
- 
-     PRE_P points to the list where side effects that must happen before
- 	*EXPR_P should be stored.
- 
-     POST_P points to the list where side effects that must happen after
-         *EXPR_P should be stored.  */
- 
- static void
- gimplify_tree_list (tree *expr_p, tree *pre_p, tree *post_p)
- {
-   tree op;
- 
- #if defined ENABLE_CHECKING
-   if (TREE_CODE (*expr_p) != TREE_LIST)
-     abort ();
- #endif
- 
-   for (op = *expr_p; op; op = TREE_CHAIN (op))
-     gimplify_expr (&TREE_VALUE (op), pre_p, post_p, is_gimple_val,
- 		   fb_rvalue);
- }
- 
  /* Handle shortcut semantics in the predicate operand of a COND_EXPR by
     rewriting it into multiple COND_EXPRs, and possibly GOTO_EXPRs.
  
--- 1633,1638 ----
*************** gimplify_cond_expr (tree *expr_p, tree *
*** 1974,1979 ****
--- 1945,1954 ----
  
  /*  Gimplify the MODIFY_EXPR node pointed by EXPR_P.
  
+       modify_expr
+ 	      : varname '=' rhs
+ 	      | '*' ID '=' rhs
+ 
      PRE_P points to the list where side effects that must happen before
  	*EXPR_P should be stored.
  
*************** gimplify_modify_expr (tree *expr_p, tree
*** 1995,2001 ****
      abort ();
  #endif
  
!   gimplify_expr (to_p, pre_p, post_p, is_gimple_modify_expr_lhs, fb_lvalue);
  
    /* If we are initializing something from a TARGET_EXPR, strip the
       TARGET_EXPR and initialize it directly.  */
--- 1970,1976 ----
      abort ();
  #endif
  
!   gimplify_expr (to_p, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
  
    /* If we are initializing something from a TARGET_EXPR, strip the
       TARGET_EXPR and initialize it directly.  */
*************** gimplify_save_expr (tree *expr_p, tree *
*** 2180,2185 ****
--- 2155,2165 ----
  
  /*  Re-write the ADDR_EXPR node pointed by EXPR_P
  
+       unary_expr
+ 	      : ...
+ 	      | '&' varname
+ 	      ...
+ 
      PRE_P points to the list where side effects that must happen before
  	*EXPR_P should be stored.
  
*************** gimplify_addr_expr (tree *expr_p, tree *
*** 2195,2202 ****
       builtins like __builtin_va_end).  */
    if (TREE_CODE (TREE_OPERAND (*expr_p, 0)) != INDIRECT_REF)
      {
        gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
! 		     is_gimple_addr_expr_arg, fb_lvalue);
        TREE_SIDE_EFFECTS (*expr_p)
  	= TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 0));
  
--- 2175,2184 ----
       builtins like __builtin_va_end).  */
    if (TREE_CODE (TREE_OPERAND (*expr_p, 0)) != INDIRECT_REF)
      {
+       /* We use fb_either here because the C frontend sometimes takes
+ 	 the address of a call that returns a struct.  */
        gimplify_expr (&TREE_OPERAND (*expr_p, 0), pre_p, post_p,
! 		     is_gimple_addr_expr_arg, fb_either);
        TREE_SIDE_EFFECTS (*expr_p)
  	= TREE_SIDE_EFFECTS (TREE_OPERAND (*expr_p, 0));
  
*************** gimplify_asm_expr (tree expr, tree *pre_
*** 2222,2235 ****
  
    for (link = ASM_OUTPUTS (expr); link; link = TREE_CHAIN (link))
      gimplify_expr (&TREE_VALUE (link), pre_p, NULL,
! 		   is_gimple_modify_expr_lhs, fb_lvalue);
  
    for (link = ASM_INPUTS (expr); link; link = TREE_CHAIN (link))
      {
        /* If the operand is a memory input, it should be an lvalue.  */
        if (asm_op_is_mem_input (link, expr))
  	gimplify_expr (&TREE_VALUE (link), pre_p, NULL,
! 		       is_gimple_modify_expr_lhs, fb_lvalue);
        else
  	gimplify_expr (&TREE_VALUE (link), pre_p, NULL,
  		       is_gimple_val, fb_rvalue);
--- 2204,2217 ----
  
    for (link = ASM_OUTPUTS (expr); link; link = TREE_CHAIN (link))
      gimplify_expr (&TREE_VALUE (link), pre_p, NULL,
! 		   is_gimple_lvalue, fb_lvalue);
  
    for (link = ASM_INPUTS (expr); link; link = TREE_CHAIN (link))
      {
        /* If the operand is a memory input, it should be an lvalue.  */
        if (asm_op_is_mem_input (link, expr))
  	gimplify_expr (&TREE_VALUE (link), pre_p, NULL,
! 		       is_gimple_lvalue, fb_lvalue);
        else
  	gimplify_expr (&TREE_VALUE (link), pre_p, NULL,
  		       is_gimple_val, fb_rvalue);
*** ./cp/cp-simplify.c.~1~	2003-08-21 14:40:25.000000000 -0400
--- ./cp/cp-simplify.c	2003-08-21 12:15:26.000000000 -0400
*************** cp_gimplify_init_expr (tree *expr_p, tre
*** 190,196 ****
       case we want to replace the INIT_EXPR.  */
    if (TREE_CODE (from) == AGGR_INIT_EXPR)
      {
!       gimplify_expr (&to, pre_p, post_p, is_gimple_modify_expr_lhs, fb_lvalue);
        TREE_OPERAND (from, 2) = to;
        *expr_p = from;
      }
--- 190,196 ----
       case we want to replace the INIT_EXPR.  */
    if (TREE_CODE (from) == AGGR_INIT_EXPR)
      {
!       gimplify_expr (&to, pre_p, post_p, is_gimple_lvalue, fb_lvalue);
        TREE_OPERAND (from, 2) = to;
        *expr_p = from;
      }
*** ./cp/call.c.~1~	2003-08-20 17:17:20.000000000 -0400
--- ./cp/call.c	2003-08-21 16:54:02.000000000 -0400
*************** build_conditional_expr (tree arg1, tree 
*** 3170,3176 ****
  	{
  	  arg2 = convert_like (conv2, arg2);
  	  arg2 = convert_from_reference (arg2);
! 	  if (!same_type_p (TREE_TYPE (arg2), arg3_type))
  	    abort ();
  	  arg2_type = TREE_TYPE (arg2);
  	}
--- 3170,3180 ----
  	{
  	  arg2 = convert_like (conv2, arg2);
  	  arg2 = convert_from_reference (arg2);
! 	  if (!same_type_p (TREE_TYPE (arg2), arg3_type)
! 	      && CLASS_TYPE_P (arg3_type))
! 	    /* The types need to match if we're converting to a class type.
! 	       If not, we don't care about cv-qual mismatches, since
! 	       non-class rvalues are not cv-qualified.  */
  	    abort ();
  	  arg2_type = TREE_TYPE (arg2);
  	}
*************** build_conditional_expr (tree arg1, tree 
*** 3178,3184 ****
  	{
  	  arg3 = convert_like (conv3, arg3);
  	  arg3 = convert_from_reference (arg3);
! 	  if (!same_type_p (TREE_TYPE (arg3), arg2_type))
  	    abort ();
  	  arg3_type = TREE_TYPE (arg3);
  	}
--- 3182,3189 ----
  	{
  	  arg3 = convert_like (conv3, arg3);
  	  arg3 = convert_from_reference (arg3);
! 	  if (!same_type_p (TREE_TYPE (arg3), arg2_type)
! 	      && CLASS_TYPE_P (arg2_type))
  	    abort ();
  	  arg3_type = TREE_TYPE (arg3);
  	}
*** ./cp/search.c.~1~	2003-08-20 17:17:24.000000000 -0400
--- ./cp/search.c	2003-08-22 11:05:00.000000000 -0400
*************** dfs_accessible_queue_p (tree derived, in
*** 758,764 ****
    return binfo;
  }
  
! /* Called from dfs_accessible_p via dfs_walk.  */
  
  static tree
  dfs_accessible_p (tree binfo, void *data)
--- 758,764 ----
    return binfo;
  }
  
! /* Called from accessible_p via dfs_walk.  */
  
  static tree
  dfs_accessible_p (tree binfo, void *data)
*** ./tree-simple.c.~1~	2003-08-21 14:40:25.000000000 -0400
--- ./tree-simple.c	2003-08-22 13:03:58.000000000 -0400
***************
*** 1,6 ****
--- 1,7 ----
  /* Functions to analyze and validate GIMPLE trees.
     Copyright (C) 2002, 2003 Free Software Foundation, Inc.
     Contributed by Diego Novillo <dnovillo@redhat.com>
+    Rewritten by Jason Merrill <jason@redhat.com>
  
  This file is part of GCC.
  
*************** Boston, MA 02111-1307, USA.  */
*** 74,82 ****
       SWITCH_EXPR
         op0 -> val
         op1 -> stmt
-        Do we also want to support op1 -> TREE_LIST, for more structured
-         selection a la McCAT SIMPLE?
         op2 -> array of case labels (as LABEL_DECLs?)
     jump-stmt:
         GOTO_EXPR
           op0 -> LABEL_DECL | '*' ID
--- 75,82 ----
       SWITCH_EXPR
         op0 -> val
         op1 -> stmt
         op2 -> array of case labels (as LABEL_DECLs?)
+          FIXME: add case value info
     jump-stmt:
         GOTO_EXPR
           op0 -> LABEL_DECL | '*' ID
*************** Boston, MA 02111-1307, USA.  */
*** 116,137 ****
       op0 -> ID | '&' ID
       op1 -> arglist
  
!    varname : compref | ID (rvalue)
!    lhs: varname | '*' ID  (lvalue)
!    pseudo-lval: ID | '*' ID  (either)
     compref :
       COMPONENT_REF
!        op0 -> compref | pseudo-lval
       | ARRAY_REF
!        op0 -> compref | pseudo-lval
         op1 -> val
  
     condition : val | val relop val
     val : ID | CONST
  
     rhs        : varname | CONST
  	      | '*' ID
! 	      | '&' varname_or_temp
  	      | call_expr
  	      | unop val
  	      | val binop val
--- 116,139 ----
       op0 -> ID | '&' ID
       op1 -> arglist
  
!    addr-expr-arg : compref | ID
!    lhs: addr-expr-arg | '*' ID
!    min-lval: ID | '*' ID
     compref :
       COMPONENT_REF
!        op0 -> compref | min-lval
       | ARRAY_REF
!        op0 -> compref | min-lval
         op1 -> val
+      | REALPART_EXPR
+      | IMAGPART_EXPR
  
     condition : val | val relop val
     val : ID | CONST
  
     rhs        : varname | CONST
  	      | '*' ID
! 	      | '&' addr-expr-arg
  	      | call_expr
  	      | unop val
  	      | val binop val
*************** Boston, MA 02111-1307, USA.  */
*** 167,349 ****
  
  */
  
! /* FIXME all of the is_gimple_* predicates should be changed to only test
!    for appropriate top-level structures; we can safely assume that after
!    gimplification, a PLUS_EXPR is a gimple PLUS_EXPR, so the predicate only
!    needs to decide whether or not a PLUS_EXPR is suitable here.  */
! 
! /* Returns nonzero if T is a gimple CONSTRUCTOR:
! 
!      aggr_init: '{' vals '}'
!      vals: aggr_init_elt | vals ',' aggr_init_elt
!      aggr_init_elt: val | aggr_init
! 
!    This is an extension to SIMPLE.  Perhaps CONSTRUCTORs should be
!    eliminated entirely?  */
! 
! int
! is_gimple_constructor (tree t)
! {
!   tree elt_list;
! 
!   if (TREE_CODE (t) != CONSTRUCTOR)
!     return 0;
! 
!   /* We used to return nonzero if TREE_STATIC (t) was set.  This
!      is wrong as we want to look inside constructors for static
!      variables for things like label addresses.  */
! 
!   for (elt_list = CONSTRUCTOR_ELTS (t); elt_list;
!        elt_list = TREE_CHAIN (elt_list))
!     if (!is_gimple_constructor_elt (TREE_VALUE (elt_list)))
!       return 0;
! 
!   return 1;
! }
! 
! /* Returns nonzero if T is a GIMPLE aggr_init_elt, as above.  */
! 
! int
! is_gimple_constructor_elt (tree t)
! {
!   return (is_gimple_val (t)
! 	  || is_gimple_constructor (t));
! }
! 
! /* Returns nonzero if T is a GIMPLE initializer for a decl, for use in the
!    INIT_EXPR we will generate.  This is the same as the right side of a
!    MODIFY_EXPR, but here we also allow a CONSTRUCTOR.  */
! 
! int
! is_gimple_initializer (tree t)
! {
!   return (is_gimple_rhs (t)
! 	  || is_gimple_constructor (t));
! }
! 
! /*  Return nonzero if T is a GIMPLE compound statement.
! 
!       compsmt
! 	      : '{' all_stmts '}'
! 	      | '{' '}'
! 	      | '{' decls all_stmts '}'
! 	      | '{' decls '}'  */
! 
! 
! 
  
  /* Validation of GIMPLE expressions.  */
  
- /*  Return nonzero if T is an expression that complies with the GIMPLE
-     grammar.
- 
-       expr
- 	      : rhs
- 	      | modify_expr  */
- 
- int
- is_gimple_expr (tree t)
- {
-   if (t == NULL_TREE)
-     return 1;
- 
-   return (is_gimple_rhs (t) || is_gimple_modify_expr (t));
- }
- 
- 
  /*  Return nonzero if T is a GIMPLE RHS:
  
!       rhs
! 	      : binary_expr
! 	      | unary_expr  */
  
  int
  is_gimple_rhs (tree t)
  {
!   if (t == NULL_TREE)
!     return 1;
! 
!   if (TREE_CODE (t) == CONSTRUCTOR)
!     /* Accept any sort of CONSTRUCTOR for now; we'll reduce it further in
!        gimplify_init_constructor.  */
!     return 1;
  
!   return (is_gimple_binary_expr (t)
!           || is_gimple_unary_expr (t));
! }
  
  
! /*  Return nonzero if T is a GIMPLE assignment expression:
  
!       modify_expr
! 	      : varname '=' rhs
! 	      | '*' ID '=' rhs  */
  
! int
! is_gimple_modify_expr (tree t)
! {
!   if (t == NULL_TREE)
      return 1;
  
!   return ((TREE_CODE (t) == MODIFY_EXPR
! 	   || TREE_CODE (t) == INIT_EXPR)
! 	  && is_gimple_modify_expr_lhs (TREE_OPERAND (t, 0))
! 	  && is_gimple_rhs (TREE_OPERAND (t, 1)));
  }
  
! 
! /*  Return nonzero if T is a valid LHS for a GIMPLE assignment expression.  */
  
  int
! is_gimple_modify_expr_lhs (tree t)
  {
!   if (t == NULL_TREE)
!     return 1;
! 
!   return (is_gimple_varname (t)
! 	  || (TREE_CODE (t) == INDIRECT_REF
! 	      && is_gimple_id (TREE_OPERAND (t, 0))));
  }
  
  
! /*  Return true if CODE is designates a GIMPLE relop:
! 
!       relop
! 	      : '<'
! 	      | '<='
! 	      ...  */
! 
! bool
! is_gimple_relop (enum tree_code code)
  {
!   return (TREE_CODE_CLASS (code) == '<');
  }
  
  
! /*  Return nonzero if T is a GIMPLE binary expression:
! 
!       binary_expr
! 	      : val binop val  */
  
  int
! is_gimple_binary_expr (tree t)
  {
!   enum tree_code code = TREE_CODE (t);
! 
!   if (t == NULL_TREE)
!     return 1;
! 
!   return ((TREE_CODE_CLASS (code) == '2'
! 	   || is_gimple_relop (code)
! 	   || code == TRUTH_AND_EXPR
! 	   || code == TRUTH_OR_EXPR
! 	   || code == TRUTH_XOR_EXPR)
! 	  && is_gimple_val (TREE_OPERAND (t, 0))
! 	  && is_gimple_val (TREE_OPERAND (t, 1)));
  }
  
  
! /*  Return nonzero if T is a GIMPLE conditional expression:
  
        condexpr
  	      : val
--- 169,263 ----
  
  */
  
! static int is_gimple_id (tree);
  
  /* Validation of GIMPLE expressions.  */
  
  /*  Return nonzero if T is a GIMPLE RHS:
  
!       rhs     : varname | CONST
! 	      | '*' ID
! 	      | '&' varname_or_temp
! 	      | call_expr
! 	      | unop val
! 	      | val binop val
! 	      | '(' cast ')' val  */
  
  int
  is_gimple_rhs (tree t)
  {
!   enum tree_code code = TREE_CODE (t);
  
!   switch (TREE_CODE_CLASS (code))
!     {
!     case '1':
!     case '2':
!     case '<':
!       return 1;
  
+     default:
+       break;
+     }
  
!   switch (code)
!     {
!     case TRUTH_AND_EXPR:
!     case TRUTH_OR_EXPR:
!     case TRUTH_XOR_EXPR:
!     case ADDR_EXPR:
!     case CALL_EXPR:
!     case CONSTRUCTOR:
!       /* FIXME lower VA_ARG_EXPR.  */
!     case VA_ARG_EXPR:
!       return 1;
  
!     default:
!       break;
!     }
  
!   if (is_gimple_lvalue (t) || is_gimple_val (t))
      return 1;
  
!   return 0;
  }
  
! /* Returns nonzero if T is a valid CONSTRUCTOR component in GIMPLE, either
!    a val or another CONSTRUCTOR.  */
  
  int
! is_gimple_constructor_elt (tree t)
  {
!   return (is_gimple_val (t)
! 	  || TREE_CODE (t) == CONSTRUCTOR);
  }
  
+ /* Returns nonzero if T is a GIMPLE initializer for a decl.  This is the
+    same as the right side of a MODIFY_EXPR, but uses a different function
+    so that we will actually simplify a CONSTRUCTOR.  */
  
! int
! is_gimple_initializer (tree t)
  {
!   return (is_gimple_rhs (t));
  }
  
  
! /*  Return nonzero if T is a valid LHS for a GIMPLE assignment expression.  */
  
  int
! is_gimple_lvalue (tree t)
  {
!   return (is_gimple_addr_expr_arg (t)
! 	  || TREE_CODE (t) == INDIRECT_REF
! 	  /* These are complex lvalues, but don't have addresses, so they
! 	     go here.  */
! 	  || TREE_CODE (t) == BIT_FIELD_REF
! 	  || TREE_CODE (t) == REALPART_EXPR
! 	  || TREE_CODE (t) == IMAGPART_EXPR);
  }
  
  
! /*  Return nonzero if T is a GIMPLE condition:
  
        condexpr
  	      : val
*************** is_gimple_binary_expr (tree t)
*** 352,489 ****
  int
  is_gimple_condexpr (tree t)
  {
-   if (t == NULL_TREE)
-     return 1;
- 
    return (is_gimple_val (t)
! 	  || (is_gimple_relop (TREE_CODE (t))
! 	      && is_gimple_val (TREE_OPERAND (t, 0))
! 	      && is_gimple_val (TREE_OPERAND (t, 1))));
  }
  
  
! /*  Return nonzero if T is a unary expression as defined by the GIMPLE
!     grammar:
! 
!       unary_expr
! 	      : simp_expr
! 	      | '*' ID
! 	      | '&' varname
! 	      | call_expr
! 	      | unop val
! 	      | '(' cast ')' val
! 
! 	      (cast here stands for all valid C typecasts)  */
! 
! int
! is_gimple_unary_expr (tree t)
! {
!   if (t == NULL_TREE)
!     return 1;
! 
!   /* Additions to the original grammar.  Allow VTABLE_REF
!      wrappers.  */
!   if (TREE_CODE (t) == VTABLE_REF)
!     return is_gimple_unary_expr (TREE_OPERAND (t, 0));
! 
!   if (is_gimple_varname (t) || is_gimple_const (t))
!     return 1;
! 
!   if (TREE_CODE (t) == INDIRECT_REF
!       && is_gimple_id (TREE_OPERAND (t, 0)))
!     return 1;
! 
!   if (TREE_CODE (t) == ADDR_EXPR
!       && is_gimple_addr_expr_arg (TREE_OPERAND (t, 0)))
!     return 1;
! 
!   if (is_gimple_call_expr (t))
!     return 1;
! 
!   if (TREE_CODE_CLASS (TREE_CODE (t)) == '1'
!       && is_gimple_val (TREE_OPERAND (t, 0)))
!     return 1;
! 
!   if (is_gimple_cast (t))
!     return 1;
! 
!   /* Addition to the original grammar.  Allow BIT_FIELD_REF nodes where
!      operand 0 is a GIMPLE identifier and operands 1 and 2 are GIMPLE
!      values.  */
!   if (TREE_CODE (t) == BIT_FIELD_REF)
!     return (is_gimple_min_lval (TREE_OPERAND (t, 0))
! 	    && is_gimple_val (TREE_OPERAND (t, 1))
! 	    && is_gimple_val (TREE_OPERAND (t, 2)));
! 
!   /* Addition to the original grammar.  Allow VA_ARG_EXPR nodes.  */
!   if (TREE_CODE (t) == VA_ARG_EXPR)
!     return 1;
! 
!   /* Addition to the original grammar.  Allow GIMPLE constructor
!      expressions.  */
!   if (TREE_CODE (t) == CONSTRUCTOR)
!     return is_gimple_constructor (t);
! 
!   return 0;
! }
! 
! 
! /*  Return nonzero if T is a GIMPLE call expression:
! 
!       call_expr
! 	      : ID '(' arglist ')'
! 
!       arglist
! 	      : arglist ',' val
! 	      | val  */
! 
! int
! is_gimple_call_expr (tree t)
! {
!   if (t == NULL_TREE)
!     return 1;
! 
!   if (TREE_CODE (t) != CALL_EXPR)
!     return 0;
! 
!   /* Some builtins cannot be gimplified because the require specific
!      arguments (e.g., MD builtins).  */
!   if (!is_gimplifiable_builtin (t))
!     {
!       /* Mark the CALL_EXPR not gimplifiable so that optimizers don't
!          assume anything about it.  Return nonzero to prevent any more
! 	 gimplification on this expression.  FIXME: is_gimple_* predicates
! 	 should not have side effects.  */
!       mark_not_gimple (&t);
!       return 1;
!     }
! 
!   return (is_gimple_id (TREE_OPERAND (t, 0))
!           && is_gimple_arglist (TREE_OPERAND (t, 1)));
! }
! 
! 
! /*  Return nonzero if T is a GIMPLE argument list:
! 
!       arglist
! 	      : arglist ',' val
! 	      | val  */
! 
! int
! is_gimple_arglist (tree t)
! {
!   tree op;
! 
!   /* Check that each argument is also in GIMPLE form.  */
!   for (op = t; op; op = TREE_CHAIN (op))
!     if (! is_gimple_val (TREE_VALUE (op)))
!       return 0;
! 
!   return 1;
! }
! 
! 
! /*  Return nonzero if T is GIMPLE variable name:
  
        varname
  	      : arrayref
--- 266,277 ----
  int
  is_gimple_condexpr (tree t)
  {
    return (is_gimple_val (t)
! 	  || TREE_CODE_CLASS (TREE_CODE (t)) == '<');
  }
  
  
! /*  Return nonzero if T is a valid operand for '&':
  
        varname
  	      : arrayref
*************** is_gimple_arglist (tree t)
*** 491,588 ****
  	      | ID     */
  
  int
- is_gimple_varname (tree t)
- {
-   if (t == NULL_TREE)
-     return 1;
- 
-   return (is_gimple_id (t)
- #if 0
- 	  || is_gimple_arrayref (t) || is_gimple_compref (t)
- #else
- 	  || is_gimple_compound_lval (t)
- #endif
- 	  );
- }
- 
- /* Returns nonzero if T is an array or member reference of the form:
- 
-       compound_lval
- 	      : min_lval '[' val ']'
- 	      | min_lval '.' ID
- 	      | compound_lval '[' val ']'
- 	      | compound_lval '.' ID
- 
-    This is not part of the original SIMPLE definition, which separates
-    array and member references, but it seems reasonable to handle them
-    together.  Also, this way we don't run into problems with union
-    aliasing; gcc requires that for accesses through a union to alias, the
-    union reference must be explicit, which was not always the case when we
-    were splitting up array and member refs.  */
- 
- int
- is_gimple_compound_lval (tree t)
- {
-   /* Allow arrays of complex types.  */
-   if (TREE_CODE (t) == REALPART_EXPR
-       || TREE_CODE (t) == IMAGPART_EXPR)
-     t = TREE_OPERAND (t, 0);
- 
-   if (TREE_CODE (t) != ARRAY_REF && TREE_CODE (t) != COMPONENT_REF)
-     return 0;
- 
-   for (; TREE_CODE (t) == COMPONENT_REF || TREE_CODE (t) == ARRAY_REF;
-        t = TREE_OPERAND (t, 0))
-     {
-       if (TREE_CODE (t) == ARRAY_REF
- 	  && !is_gimple_val (TREE_OPERAND (t, 1)))
- 	return 0;
-     }
- 
-   return is_gimple_min_lval (t);
- }
- 
- /*  Return nonzero if T can be used as the argument for an ADDR_EXPR node.
-     This is not part of the original SIMPLE grammar, but in C99 it is
-     possible to generate an address expression for a function call:
- 
-       struct A_s {
- 	char a[1];
-       } A;
- 
-       extern struct A_s foo ();
- 
-       main()
-       {
- 	char *t = foo().a;
-       }
- 
-     When the above is compiled with -std=iso9899:1999, the front end will
-     generate 't = (char *)(char[1] *)&foo ();'.  */
- 
- int
  is_gimple_addr_expr_arg (tree t)
  {
!   /* If we're taking the address of a label for the first time, then
!      this expression is not in gimple form.  */
!   if (TREE_CODE (t) == LABEL_DECL && ! FORCED_LABEL (t))
!     return 0;
! 
!   return (is_gimple_varname (t) || is_gimple_call_expr (t));
  }
  
! /*  Return nonzero if T is a constant.  */
  
  int
  is_gimple_const (tree t)
  {
!   if (t == NULL_TREE)
!     return 1;
  
!   STRIP_NOPS (t);
  
    if (TREE_CODE (t) == ADDR_EXPR
!       && TREE_CODE (TREE_OPERAND (t, 0)) == STRING_CST)
      return 1;
  
    if (TREE_CODE (t) == PLUS_EXPR
--- 279,315 ----
  	      | ID     */
  
  int
  is_gimple_addr_expr_arg (tree t)
  {
!   return (is_gimple_id (t)
! 	  || TREE_CODE (t) == ARRAY_REF
! 	  || TREE_CODE (t) == COMPONENT_REF);
  }
  
! /*  Return nonzero if T is a constant.  This is one of the few predicates
!     that looks deeper than the TREE_CODE; this is necessary because, e.g.,
!     some GIMPLE PLUS_EXPRs are considered constants and some are not.  */
  
  int
  is_gimple_const (tree t)
  {
!   tree tmp = t;
  
!   /* FIXME lose the STRIP_NOPS once we are more clever about builtins.  */
!   STRIP_NOPS (tmp);
!   if (TREE_CODE (tmp) == ADDR_EXPR
!       && TREE_CODE (TREE_OPERAND (tmp, 0)) == STRING_CST)
!     return 1;
  
    if (TREE_CODE (t) == ADDR_EXPR
! #if 0
!       && DECL_P (TREE_OPERAND (t, 0))
! #else
!       && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
! #endif
!       && (TREE_STATIC (TREE_OPERAND (t, 0))
! 	  || DECL_EXTERNAL (TREE_OPERAND (t, 0)))
!       && !DECL_WEAK (TREE_OPERAND (t, 0)))
      return 1;
  
    if (TREE_CODE (t) == PLUS_EXPR
*************** is_gimple_const (tree t)
*** 594,607 ****
    return (TREE_CODE (t) == INTEGER_CST
  	  || TREE_CODE (t) == REAL_CST
  	  || TREE_CODE (t) == STRING_CST
- 	  || TREE_CODE (t) == LABEL_DECL
- 	  || TREE_CODE (t) == RESULT_DECL
  	  || TREE_CODE (t) == COMPLEX_CST
  	  || TREE_CODE (t) == VECTOR_CST);
  }
  
! /* Return nonzero if T looks like a valid GIMPLE statement.  Note that it
!    doesn't recurse to verify that everything is fully simplified.  */
  
  int
  is_gimple_stmt (tree t)
--- 321,331 ----
    return (TREE_CODE (t) == INTEGER_CST
  	  || TREE_CODE (t) == REAL_CST
  	  || TREE_CODE (t) == STRING_CST
  	  || TREE_CODE (t) == COMPLEX_CST
  	  || TREE_CODE (t) == VECTOR_CST);
  }
  
! /* Return nonzero if T looks like a valid GIMPLE statement.  */
  
  int
  is_gimple_stmt (tree t)
*************** is_gimple_stmt (tree t)
*** 676,725 ****
      }
  }
  
! /*  Return nonzero if T is a GIMPLE identifier.  */
  
  int
! is_gimple_id (tree t)
  {
-   if (t == NULL_TREE)
-     return 1;
- 
-   /* Allow real and imaginary parts of a complex variable.  */
-   if (TREE_CODE (t) == REALPART_EXPR
-       || TREE_CODE (t) == IMAGPART_EXPR)
-     return is_gimple_id (TREE_OPERAND (t, 0));
- 
    return (TREE_CODE (t) == VAR_DECL
- 	  || TREE_CODE (t) == FUNCTION_DECL
  	  || TREE_CODE (t) == PARM_DECL
  	  || TREE_CODE (t) == RESULT_DECL
- 	  || TREE_CODE (t) == FIELD_DECL
- 	  || TREE_CODE (t) == LABEL_DECL
- 	  /* FIXME make this a decl.  */
- 	  || TREE_CODE (t) == EXC_PTR_EXPR
- 	  /* Allow the address of a function decl.  */
- 	  || (TREE_CODE (t) == ADDR_EXPR
- 	      && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL)
- 	  /* Allow string constants.  */
- 	  || TREE_CODE (t) == STRING_CST
  	  || TREE_CODE (t) == SSA_NAME);
  }
  
  
! /*  Return nonzero if T is an identifier or a constant.  */
  
  int
! is_gimple_val (tree t)
  {
!   if (t == NULL_TREE)
!     return 1;
  
    /* A volatile decl or _REF is not a valid operand, because we can't reuse
       it as needed.  We need to copy it into a temp first.  */
    if (TREE_THIS_VOLATILE (t))
      return 0;
  
!   return (is_gimple_id (t) || is_gimple_const (t));
  }
  
  
--- 400,475 ----
      }
  }
  
! /* Return nonzero if T is a variable.  */
  
  int
! is_gimple_variable (tree t)
  {
    return (TREE_CODE (t) == VAR_DECL
  	  || TREE_CODE (t) == PARM_DECL
  	  || TREE_CODE (t) == RESULT_DECL
  	  || TREE_CODE (t) == SSA_NAME);
  }
  
+ /*  Return nonzero if T is a GIMPLE identifier (something with an address).  */
  
! static int
! is_gimple_id (tree t)
! {
!   return (is_gimple_variable (t)
! 	  || TREE_CODE (t) == FUNCTION_DECL
! 	  || TREE_CODE (t) == LABEL_DECL
! 	  /* Allow string constants, since they are addressable.  */
! 	  || TREE_CODE (t) == STRING_CST);
! }
! 
! /* Return nonzero if T is a scalar register variable.  */
  
  int
! is_gimple_reg (tree t)
  {
!   return (is_gimple_variable (t)
! 	  && TYPE_MODE (TREE_TYPE (t)) != BLKmode
! 	  && ! TREE_STATIC (t)
! 	  && ! DECL_EXTERNAL (t)
! 	  && ! TREE_ADDRESSABLE (t)
! 	  /* A volatile decl is not acceptable because we can't reuse it as
! 	     needed.  We need to copy it into a temp first.  */
! 	  && ! TREE_THIS_VOLATILE (t));
! }
! 
! /*  Return nonzero if T is a GIMPLE rvalue, i.e. an identifier or a
!     constant.  */
  
+ int
+ is_gimple_val (tree t)
+ {
+ #if 0
+   /* Make loads from volatiles and memory vars explicit.  */
+   if (is_gimple_variable (t)
+       && !(is_gimple_reg (t)
+ 	   || TYPE_MODE (TREE_TYPE (t)) == BLKmode))
+     return 0;
+ #else
    /* A volatile decl or _REF is not a valid operand, because we can't reuse
       it as needed.  We need to copy it into a temp first.  */
    if (TREE_THIS_VOLATILE (t))
      return 0;
+ #endif
+ 
+   if (/* FIXME make this a decl.  */
+       TREE_CODE (t) == EXC_PTR_EXPR
+       /* Allow the address of a decl.  */
+       || (TREE_CODE (t) == ADDR_EXPR
+ #if 0
+ 	  && DECL_P (TREE_OPERAND (t, 0))
+ #else
+ 	  && TREE_CODE (TREE_OPERAND (t, 0)) == FUNCTION_DECL
+ #endif
+ 	  ))
+     return 1;
  
!   return (is_gimple_variable (t) || is_gimple_const (t));
  }
  
  
*************** is_gimple_val (tree t)
*** 733,828 ****
  int
  is_gimple_min_lval (tree t)
  {
-   if (t == NULL_TREE)
-     return 1;
- 
    return (is_gimple_id (t)
! 	  || (TREE_CODE (t) == INDIRECT_REF
! 	      && is_gimple_id (TREE_OPERAND (t, 0))));
  }
  
- #if 0
- /*  Return nonzero if T is an array reference of the form:
- 
-       arrayref
- 	      : ID reflist
- 	      | '(' '*' ID ')' reflist  => extension because ARRAY_REF
- 					   requires an ARRAY_TYPE argument.
- 
-       reflist
- 	      : '[' val ']'
- 	      | reflist '[' val ']'  */
- 
- int
- is_gimple_arrayref (tree t)
- {
-   if (t == NULL_TREE)
-     return 1;
- 
-   /* Allow arrays of complex types.  */
-   if (TREE_CODE (t) == REALPART_EXPR
-       || TREE_CODE (t) == IMAGPART_EXPR)
-     t = TREE_OPERAND (t, 0);
- 
-   if (TREE_CODE (t) != ARRAY_REF)
-     return 0;
- 
-   for (; TREE_CODE (t) == ARRAY_REF; t = TREE_OPERAND (t, 0))
-     if (! is_gimple_val (TREE_OPERAND (t, 1)))
-       return 0;
- 
-   return is_gimple_min_lval (t);
- }
- 
- 
- /*  Return nonzero if T is a component reference of the form:
- 
-       compref
- 	      : '(' '*' ID ')' '.' idlist
- 	      | idlist
- 
-       idlist
- 	      : idlist '.' ID
- 	      | ID  */
- 
- int
- is_gimple_compref (tree t)
- {
-   if (t == NULL_TREE)
-     return 1;
- 
-   if (TREE_CODE (t) != COMPONENT_REF)
-     return 0;
- 
-   for (; TREE_CODE (t) == COMPONENT_REF; t = TREE_OPERAND (t, 0))
-     if (! is_gimple_id (TREE_OPERAND (t, 1)))
-       abort ();
- 
-   return is_gimple_min_lval (t);
- }
- #endif
- 
  /*  Return nonzero if T is a typecast operation of the form
      '(' cast ')' val.  */
  
  int
  is_gimple_cast (tree t)
  {
-   if (t == NULL_TREE)
-     return 1;
- 
-   return (is_gimple_cast_op (t) && is_gimple_val (TREE_OPERAND (t, 0)));
- }
- 
- 
- /*  Return nonzero if T is a typecast operator.  */
- 
- int
- is_gimple_cast_op (tree t)
- {
-   if (t == NULL_TREE)
-     return 1;
- 
    return (TREE_CODE (t) == NOP_EXPR
  	  || TREE_CODE (t) == CONVERT_EXPR
            || TREE_CODE (t) == FIX_TRUNC_EXPR
--- 483,498 ----
  int
  is_gimple_min_lval (tree t)
  {
    return (is_gimple_id (t)
! 	  || TREE_CODE (t) == INDIRECT_REF);
  }
  
  /*  Return nonzero if T is a typecast operation of the form
      '(' cast ')' val.  */
  
  int
  is_gimple_cast (tree t)
  {
    return (TREE_CODE (t) == NOP_EXPR
  	  || TREE_CODE (t) == CONVERT_EXPR
            || TREE_CODE (t) == FIX_TRUNC_EXPR
*************** is_gimple_cast_op (tree t)
*** 831,876 ****
            || TREE_CODE (t) == FIX_ROUND_EXPR);
  }
  
- 
- /*  Return 1 if T is a GIMPLE expression sequence:
- 
-       exprseq
- 	      : exprseq ',' expr
- 	      | expr  */
- 
- int
- is_gimple_exprseq (tree t)
- {
-   /* Empty expression sequences are allowed.  */
-   if (t == NULL_TREE)
-     return 1;
- 
-   return (is_gimple_expr (t)
-           || (TREE_CODE (t) == COMPOUND_EXPR
- 	      && is_gimple_expr (TREE_OPERAND (t, 0))
- 	      && is_gimple_exprseq (TREE_OPERAND (t, 1))));
- }
- 
- /* Return nonzero if FNDECL can be gimplified.  This is needed for
-    target-defined builtins that may need specific tree nodes in their
-    argument list.  */
- 
- int
- is_gimplifiable_builtin (tree expr)
- {
-   tree decl;
- 
-   decl = get_callee_fndecl (expr);
- 
-   /* Do not gimplify target-defined builtin functions.
-      FIXME: Maybe we should add a target hook for allowing this in the
- 	    future?  */
-   if (decl && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_MD)
-     return 0;
- 
-   return 1;
- }
- 
  /* Given an _EXPR TOP, reorganize all of the nested _EXPRs with the same
     code so that they only appear as the second operand.  This should only
     be used for tree codes which are truly associative, such as
--- 501,506 ----
*** ./tree-alias-common.c.~1~	2003-08-21 14:40:25.000000000 -0400
--- ./tree-alias-common.c	2003-08-19 14:30:13.000000000 -0400
*************** find_func_aliases (tree *tp, int *walk_s
*** 419,425 ****
        return NULL_TREE;
      }
  
!   if (is_gimple_modify_expr (stp)
        || (DECL_P (stp) && DECL_INITIAL (stp) != NULL_TREE ))
      {
        tree op0, op1;
--- 419,425 ----
        return NULL_TREE;
      }
  
!   if (TREE_CODE (stp) == MODIFY_EXPR
        || (DECL_P (stp) && DECL_INITIAL (stp) != NULL_TREE ))
      {
        tree op0, op1;
*************** find_func_aliases (tree *tp, int *walk_s
*** 450,459 ****
  	 variable, since we can disambiguate based on TBAA first,
  	 and fall back on points-to. */
        /* x = <something> */
!       if (is_gimple_varname (op0))
  	{
  	  /* x = y or x = foo.y */
! 	  if (is_gimple_varname (op1))
  	    {
  	      if (rhsAV != NULL)
  		current_alias_ops->simple_assign (current_alias_ops, lhsAV,
--- 450,459 ----
  	 variable, since we can disambiguate based on TBAA first,
  	 and fall back on points-to. */
        /* x = <something> */
!       if (is_gimple_variable (op0))
  	{
  	  /* x = y or x = foo.y */
! 	  if (is_gimple_variable (op1))
  	    {
  	      if (rhsAV != NULL)
  		current_alias_ops->simple_assign (current_alias_ops, lhsAV,
*************** find_func_aliases (tree *tp, int *walk_s
*** 469,476 ****
  	      *walk_subtrees = 0;
  	    }
  	  /* x = *y or x = foo->y */
! 	  else if (TREE_CODE (op1) == INDIRECT_REF
! 		   && is_gimple_varname (TREE_OPERAND (op1, 0)))
  	    {
  	      if (rhsAV != NULL)
  		current_alias_ops->ptr_assign (current_alias_ops, lhsAV,
--- 469,475 ----
  	      *walk_subtrees = 0;
  	    }
  	  /* x = *y or x = foo->y */
! 	  else if (TREE_CODE (op1) == INDIRECT_REF)
  	    {
  	      if (rhsAV != NULL)
  		current_alias_ops->ptr_assign (current_alias_ops, lhsAV,
*************** find_func_aliases (tree *tp, int *walk_s
*** 478,486 ****
  	      *walk_subtrees = 0;
  	    }
  	  /* x = &y = x = &foo.y */
! 	  else if ((TREE_CODE (op1) == ADDR_EXPR
! 		    || TREE_CODE (op1) == REFERENCE_EXPR)
! 		   && is_gimple_varname (TREE_OPERAND (op1, 0)))
  	    {
  	      if (rhsAV != NULL)
  		current_alias_ops->addr_assign (current_alias_ops, lhsAV,
--- 477,483 ----
  	      *walk_subtrees = 0;
  	    }
  	  /* x = &y = x = &foo.y */
! 	  else if (TREE_CODE (op1) == ADDR_EXPR)
  	    {
  	      if (rhsAV != NULL)
  		current_alias_ops->addr_assign (current_alias_ops, lhsAV,
*************** find_func_aliases (tree *tp, int *walk_s
*** 488,494 ****
  	      *walk_subtrees = 0;
  	    }
  	  /* x = func(...) */
! 	  else if (is_gimple_call_expr (op1))
  	    {
  	      /* Heap assignment. These are __attribute__ malloc or
  		 something, i'll deal with it later. */
--- 485,491 ----
  	      *walk_subtrees = 0;
  	    }
  	  /* x = func(...) */
! 	  else if (TREE_CODE (op1) == CALL_EXPR)
  	    {
  	      /* Heap assignment. These are __attribute__ malloc or
  		 something, i'll deal with it later. */
*************** find_func_aliases (tree *tp, int *walk_s
*** 650,656 ****
  	}
      }
    /* Calls without return values. */
!   else if (is_gimple_call_expr (stp))
      {
        varray_type args;
        tree arg;
--- 647,653 ----
  	}
      }
    /* Calls without return values. */
!   else if (TREE_CODE (stp) == CALL_EXPR)
      {
        varray_type args;
        tree arg;
*** ./tree-simple.h.~1~	2003-08-21 14:40:25.000000000 -0400
--- ./tree-simple.h	2003-08-21 13:04:34.000000000 -0400
*************** Boston, MA 02111-1307, USA.  */
*** 25,75 ****
  
  #include "tree-iterator.h"
  
- /* Interface used in [break/goto]-elimination: to be declared in a .h file. */
- extern void insert_before_continue_end (tree, tree);
- extern void tree_build_scope (tree *);
  extern tree create_tmp_var (tree, const char *);
  extern tree create_tmp_alias_var (tree, const char *);
  extern bool is_gimple_tmp_var (tree);
  extern tree get_initialized_tmp_var (tree, tree *);
  extern tree get_formal_tmp_var (tree, tree *);
  extern void declare_tmp_vars (tree, tree);
- extern tree deep_copy_list (tree);
- extern tree deep_copy_node (tree);
- extern tree update_line_number (tree, int);
  
  extern tree rationalize_compound_expr (tree);
  extern tree right_assocify_expr (tree);
  extern void annotate_all_with_file_line (tree *, const char *, int);
  
! /* Validation of GIMPLE expressions.  */
! int is_gimple_expr (tree);
! int is_gimple_rhs (tree);
! int is_gimple_modify_expr (tree);
! int is_gimple_modify_expr_lhs (tree);
! bool is_gimple_relop (enum tree_code);
! int is_gimple_binary_expr (tree);
! int is_gimple_condexpr (tree);
! int is_gimple_unary_expr (tree);
! int is_gimple_call_expr (tree);
! int is_gimple_arglist (tree);
! int is_gimple_const (tree);
! int is_gimple_id (tree);
! int is_gimple_varname (tree);
  int is_gimple_addr_expr_arg (tree);
  int is_gimple_val (tree);
! int is_gimple_min_lval (tree);
! int is_gimple_compound_lval (tree);
! int is_gimple_arrayref (tree);
! int is_gimple_compref (tree);
  int is_gimple_cast (tree);
! int is_gimple_cast_op (tree);
! int is_gimple_exprseq (tree);
! int is_gimple_constructor (tree);
  int is_gimple_constructor_elt (tree);
  int is_gimple_initializer (tree);
- int is_gimplifiable_builtin (tree);
- int is_gimple_stmt (tree);
  
  void recalculate_side_effects (tree);
  
--- 25,77 ----
  
  #include "tree-iterator.h"
  
  extern tree create_tmp_var (tree, const char *);
  extern tree create_tmp_alias_var (tree, const char *);
  extern bool is_gimple_tmp_var (tree);
  extern tree get_initialized_tmp_var (tree, tree *);
  extern tree get_formal_tmp_var (tree, tree *);
  extern void declare_tmp_vars (tree, tree);
  
  extern tree rationalize_compound_expr (tree);
  extern tree right_assocify_expr (tree);
  extern void annotate_all_with_file_line (tree *, const char *, int);
  
! /* Validation of GIMPLE expressions.  Note that these predicates only check
!    the basic form of the expression, they don't recurse to make sure that
!    underlying nodes are also of the right form.  */
! 
! /* Returns 1 iff T is a valid GIMPLE statement.  */
! int is_gimple_stmt (tree);
! 
! /* Returns 1 iff T is a scalar register variable.  */
! int is_gimple_reg (tree);
! /* Returns 1 iff T is any sort of variable.  */
! int is_gimple_variable (tree);
! /* Returns 1 iff T is a variable or an INDIRECT_REF (of a variable).  */
! int is_gimple_min_lval (tree);
! /* Returns 1 iff T is an lvalue other than an INDIRECT_REF.  */
  int is_gimple_addr_expr_arg (tree);
+ /* Returns 1 iff T is any valid GIMPLE lvalue.  */
+ int is_gimple_lvalue (tree);
+ 
+ /* Returns 1 iff T is a GIMPLE constant.  */
+ int is_gimple_const (tree);
+ /* Returns 1 iff T is a GIMPLE rvalue.  */
  int is_gimple_val (tree);
! /* Returns 1 iff T is a valid rhs for a MODIFY_EXPR.  */
! int is_gimple_rhs (tree);
! 
! /* Returns 1 iff T is a valid if-statement condition.  */
! int is_gimple_condexpr (tree);
! 
! /* Returns 1 iff T is a type conversion.  */
  int is_gimple_cast (tree);
! /* Returns 1 iff T is a valid CONSTRUCTOR element (either an rvalue or
!    another CONSTRUCTOR).  */
  int is_gimple_constructor_elt (tree);
+ /* Returns 1 iff T is a valid initializer for a variable (like _rhs, but
+    without the magic treatment of CONSTRUCTOR).  */
  int is_gimple_initializer (tree);
  
  void recalculate_side_effects (tree);
  
*** ./fortran/trans-array.c.~1~	2003-08-21 14:40:25.000000000 -0400
--- ./fortran/trans-array.c	2003-08-19 14:30:51.000000000 -0400
*************** gfc_conv_expr_descriptor (gfc_se * se, g
*** 3388,3395 ****
  		se->expr = TREE_OPERAND (desc, 0);
  	      else
  		{
! 		  assert (is_gimple_varname (desc));
! 		  if (is_gimple_id (desc))
  		    TREE_ADDRESSABLE (desc) = 1;
  		  se->expr = build1 (ADDR_EXPR,
  				     build_pointer_type (TREE_TYPE (desc)),
--- 3388,3395 ----
  		se->expr = TREE_OPERAND (desc, 0);
  	      else
  		{
! 		  assert (is_gimple_lvalue (desc));
! 		  if (is_gimple_variable (desc))
  		    TREE_ADDRESSABLE (desc) = 1;
  		  se->expr = build1 (ADDR_EXPR,
  				     build_pointer_type (TREE_TYPE (desc)),
*************** gfc_conv_expr_descriptor (gfc_se * se, g
*** 3478,3484 ****
        tmp = gfc_conv_descriptor_stride (desc, gfc_rank_cst[0]);
        gfc_add_modify_expr (&loop.pre, tmp, integer_zero_node);
  
!       assert (is_gimple_varname (desc));
        TREE_ADDRESSABLE (desc) = 1;
        se->expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (desc)),
  			 desc);
--- 3478,3484 ----
        tmp = gfc_conv_descriptor_stride (desc, gfc_rank_cst[0]);
        gfc_add_modify_expr (&loop.pre, tmp, integer_zero_node);
  
!       assert (is_gimple_lvalue (desc));
        TREE_ADDRESSABLE (desc) = 1;
        se->expr = build1 (ADDR_EXPR, build_pointer_type (TREE_TYPE (desc)),
  			 desc);

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]