C++ PATCH: Remove break_out_calls

Mark Mitchell mark@codesourcery.com
Thu Jul 10 17:01:00 GMT 2003


Jan noticed that there was some ugliness in the C++ front end where we
ended up trying to share tree structure in invalid ways.  Fixed by
removing lots of gross code.  The code in question was transforming

  a = b ? c : d

into:

  b ? (a = c) : (a = d)

which is unncessary.  

We do have to transform:

  a ? b : c = d

(which is valid C++, but not C) into:

  a ? (b = d) : (c = d)

but that is different code.

Tested on i686-pc-linux-gnu, applied on the mainline.

Now I have to go fix up the dang mainline regressions Wolfgand and
Gerald reported...

--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com


2003-07-09  Mark Mitchell  <mark@codesourcery.com>

	* cp-tree.h (break_out_calls): Remove declaration.
	* tree.c (break_out_calls): Remove.
	* typeck.c (build_modify_expr): Avoid invalid sharing of trees.

Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.871
diff -c -5 -p -r1.871 cp-tree.h
*** cp/cp-tree.h	9 Jul 2003 08:47:58 -0000	1.871
--- cp/cp-tree.h	10 Jul 2003 16:44:28 -0000
*************** extern int non_cast_lvalue_or_else		(tre
*** 4172,4182 ****
  extern tree build_min				(enum tree_code, tree,
  							 ...);
  extern tree build_min_nt			(enum tree_code, ...);
  extern tree build_cplus_new			(tree, tree);
  extern tree get_target_expr			(tree);
- extern tree break_out_calls			(tree);
  extern tree build_cplus_method_type		(tree, tree, tree);
  extern tree build_cplus_staticfn_type		(tree, tree, tree);
  extern tree build_cplus_array_type		(tree, tree);
  extern tree hash_tree_cons			(tree, tree, tree);
  extern tree hash_tree_chain			(tree, tree);
--- 4172,4181 ----
Index: cp/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.335
diff -c -5 -p -r1.335 tree.c
*** cp/tree.c	9 Jul 2003 08:48:01 -0000	1.335
--- cp/tree.c	10 Jul 2003 16:44:37 -0000
*************** tree
*** 366,455 ****
  get_target_expr (tree init)
  {
    return build_target_expr_with_type (init, TREE_TYPE (init));
  }
  
- /* Recursively perform a preorder search EXP for CALL_EXPRs, making
-    copies where they are found.  Returns a deep copy all nodes transitively
-    containing CALL_EXPRs.  */
- 
- tree
- break_out_calls (tree exp)
- {
-   register tree t1, t2 = NULL_TREE;
-   register enum tree_code code;
-   register int changed = 0;
-   register int i;
- 
-   if (exp == NULL_TREE)
-     return exp;
- 
-   code = TREE_CODE (exp);
- 
-   if (code == CALL_EXPR)
-     return copy_node (exp);
- 
-   /* Don't try and defeat a save_expr, as it should only be done once.  */
-     if (code == SAVE_EXPR)
-        return exp;
- 
-   switch (TREE_CODE_CLASS (code))
-     {
-     default:
-       abort ();
- 
-     case 'c':  /* a constant */
-     case 't':  /* a type node */
-     case 'x':  /* something random, like an identifier or an ERROR_MARK.  */
-       return exp;
- 
-     case 'd':  /* A decl node */
-       return exp;
- 
-     case 'b':  /* A block node */
-       {
- 	/* Don't know how to handle these correctly yet.   Must do a
- 	   break_out_calls on all DECL_INITIAL values for local variables,
- 	   and also break_out_calls on all sub-blocks and sub-statements.  */
- 	abort ();
-       }
-       return exp;
- 
-     case 'e':  /* an expression */
-     case 'r':  /* a reference */
-     case 's':  /* an expression with side effects */
-       for (i = TREE_CODE_LENGTH (code) - 1; i >= 0; i--)
- 	{
- 	  t1 = break_out_calls (TREE_OPERAND (exp, i));
- 	  if (t1 != TREE_OPERAND (exp, i))
- 	    {
- 	      exp = copy_node (exp);
- 	      TREE_OPERAND (exp, i) = t1;
- 	    }
- 	}
-       return exp;
- 
-     case '<':  /* a comparison expression */
-     case '2':  /* a binary arithmetic expression */
-       t2 = break_out_calls (TREE_OPERAND (exp, 1));
-       if (t2 != TREE_OPERAND (exp, 1))
- 	changed = 1;
-     case '1':  /* a unary arithmetic expression */
-       t1 = break_out_calls (TREE_OPERAND (exp, 0));
-       if (t1 != TREE_OPERAND (exp, 0))
- 	changed = 1;
-       if (changed)
- 	{
- 	  if (TREE_CODE_LENGTH (code) == 1)
- 	    return build1 (code, TREE_TYPE (exp), t1);
- 	  else
- 	    return build (code, TREE_TYPE (exp), t1, t2);
- 	}
-       return exp;
-     }
- 
- }
  
  /* Construct, lay out and return the type of methods belonging to class
     BASETYPE and whose arguments are described by ARGTYPES and whose values
     are described by RETTYPE.  If each type exists already, reuse it.  */
  
--- 366,375 ----
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.478
diff -c -5 -p -r1.478 typeck.c
*** cp/typeck.c	9 Jul 2003 23:39:14 -0000	1.478
--- cp/typeck.c	10 Jul 2003 16:44:40 -0000
*************** build_modify_expr (tree lhs, enum tree_c
*** 5397,5444 ****
      }
  
    if (newrhs == error_mark_node)
      return error_mark_node;
  
!   if (TREE_CODE (newrhs) == COND_EXPR)
!     {
!       tree lhs1;
!       tree cond = TREE_OPERAND (newrhs, 0);
! 
!       if (TREE_SIDE_EFFECTS (lhs))
! 	cond = build_compound_expr (tree_cons
! 				    (NULL_TREE, lhs,
! 				     build_tree_list (NULL_TREE, cond)));
! 
!       /* Cannot have two identical lhs on this one tree (result) as preexpand
! 	 calls will rip them out and fill in RTL for them, but when the
! 	 rtl is generated, the calls will only be in the first side of the
! 	 condition, not on both, or before the conditional jump! (mrs) */
!       lhs1 = break_out_calls (lhs);
! 
!       if (lhs == lhs1)
! 	/* If there's no change, the COND_EXPR behaves like any other rhs.  */
! 	result = build (modifycode == NOP_EXPR ? MODIFY_EXPR : INIT_EXPR,
! 			lhstype, lhs, newrhs);
!       else
! 	{
! 	  tree result_type = TREE_TYPE (newrhs);
! 	  /* We have to convert each arm to the proper type because the
! 	     types may have been munged by constant folding.  */
! 	  result
! 	    = build (COND_EXPR, result_type, cond,
! 		     build_modify_expr (lhs, modifycode,
! 					cp_convert (result_type,
! 						    TREE_OPERAND (newrhs, 1))),
! 		     build_modify_expr (lhs1, modifycode,
! 					cp_convert (result_type,
! 						    TREE_OPERAND (newrhs, 2))));
! 	}
!     }
!   else
!     result = build (modifycode == NOP_EXPR ? MODIFY_EXPR : INIT_EXPR,
! 		    lhstype, lhs, newrhs);
  
    TREE_SIDE_EFFECTS (result) = 1;
  
    /* If we got the LHS in a different type for storing in,
       convert the result back to the nominal type of LHS
--- 5397,5408 ----
      }
  
    if (newrhs == error_mark_node)
      return error_mark_node;
  
!   result = build (modifycode == NOP_EXPR ? MODIFY_EXPR : INIT_EXPR,
! 		  lhstype, lhs, newrhs);
  
    TREE_SIDE_EFFECTS (result) = 1;
  
    /* If we got the LHS in a different type for storing in,
       convert the result back to the nominal type of LHS



More information about the Gcc-patches mailing list