[PATCH][LTO] Remove all stmt fixup on readin

Richard Guenther rguenther@suse.de
Wed Jul 14 14:16:00 GMT 2010


This is the first step to a somewhat saner fixup for mismatched decls.
Something I promised that will be possible with MEM_REF.  So, here it is.
The key is to have all possibly conflicting (thus, non-automatic)
VAR_DECLs wrapped in a MEM_REF.  Something I do not (yet?) enforce
for all GIMPLE IL, so just make sure to wrap them during LTO stream
output.

Bootstrapped and tested on x86_64-unknown-linux-gnu, SPEC 2k6 build
tested.  Ok?

Thanks,
Richard.

2010-07-14  Richard Guenther  <rguenther@suse.de>

	* lto-streamer-in.c (maybe_fixup_handled_component): Remove.
	(maybe_fixup_decls): Likewise.
	(input_gimple_stmt): Do not fixup anything.
	* lto-streamer-out.c (output_gimple_stmt): Make sure all
	non-automatic variable uses are wrapped inside a MEM_REF.

Index: gcc/lto-streamer-in.c
===================================================================
*** gcc/lto-streamer-in.c	(revision 162176)
--- gcc/lto-streamer-in.c	(working copy)
*************** input_ssa_names (struct lto_input_block
*** 872,995 ****
      }
  }
  
- 
- /* Fixup the reference tree OP for replaced VAR_DECLs with mismatched
-    types.  */
- 
- static void
- maybe_fixup_handled_component (tree op)
- {
-   tree decl_type;
-   tree wanted_type;
- 
-   while (handled_component_p (TREE_OPERAND (op, 0)))
-     op = TREE_OPERAND (op, 0);
-   if (TREE_CODE (TREE_OPERAND (op, 0)) != VAR_DECL)
-     return;
- 
-   decl_type = TREE_TYPE (TREE_OPERAND (op, 0));
- 
-   switch (TREE_CODE (op))
-     {
-     case COMPONENT_REF:
-       /* The DECL_CONTEXT of the field-decl is the record type we look for.  */
-       wanted_type = DECL_CONTEXT (TREE_OPERAND (op, 1));
-       break;
- 
-     case ARRAY_REF:
-       if (TREE_CODE (decl_type) == ARRAY_TYPE
- 	  && (TREE_TYPE (decl_type) == TREE_TYPE (op)
- 	      || useless_type_conversion_p (TREE_TYPE (op),
- 					    TREE_TYPE (decl_type))))
- 	return;
-       /* An unknown size array type should be ok.  But we do not
-          lower the lower bound in all cases - ugh.  */
-       wanted_type = build_array_type (TREE_TYPE (op), NULL_TREE);
-       break;
- 
-     case ARRAY_RANGE_REF:
-       if (TREE_CODE (decl_type) == ARRAY_TYPE
- 	  && (TREE_TYPE (decl_type) == TREE_TYPE (TREE_TYPE (op))
- 	      || useless_type_conversion_p (TREE_TYPE (TREE_TYPE (op)),
- 					    TREE_TYPE (decl_type))))
- 	return;
-       /* An unknown size array type should be ok.  But we do not
-          lower the lower bound in all cases - ugh.  */
-       wanted_type = build_array_type (TREE_TYPE (TREE_TYPE (op)), NULL_TREE);
-       break;
- 
-     case BIT_FIELD_REF:
-     case VIEW_CONVERT_EXPR:
-       /* Very nice - nothing to do.  */
-       return;
- 
-     case REALPART_EXPR:
-     case IMAGPART_EXPR:
-       if (TREE_CODE (decl_type) == COMPLEX_TYPE
- 	  && (TREE_TYPE (decl_type) == TREE_TYPE (op)
- 	      || useless_type_conversion_p (TREE_TYPE (op),
- 					    TREE_TYPE (decl_type))))
- 	return;
-       wanted_type = build_complex_type (TREE_TYPE (op));
-       break;
- 
-     default:
-       gcc_unreachable ();
-     }
- 
-   if (!useless_type_conversion_p (wanted_type, decl_type))
-     TREE_OPERAND (op, 0) = build1 (VIEW_CONVERT_EXPR, wanted_type,
- 				   TREE_OPERAND (op, 0));
- }
- 
- /* Fixup reference tree operands for substituted prevailing decls
-    with mismatched types in STMT.  This handles plain DECLs where
-    we need the stmt for context to lookup the required type.  */
- 
- static void
- maybe_fixup_decls (gimple stmt)
- {
-   /* We have to fixup replaced decls here in case there were
-      inter-TU type mismatches.  Catch the most common cases
-      for now - this way we'll get testcases for the rest as
-      the type verifier will complain.  */
-   if (gimple_assign_single_p (stmt))
-     {
-       tree lhs = gimple_assign_lhs (stmt);
-       tree rhs = gimple_assign_rhs1 (stmt);
- 
-       /* First catch loads and aggregate copies by adjusting the rhs.  */
-       if (TREE_CODE (rhs) == VAR_DECL)
- 	{
- 	  if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
- 	    gimple_assign_set_rhs1 (stmt, build1 (VIEW_CONVERT_EXPR,
- 						  TREE_TYPE (lhs), rhs));
- 	}
-       /* Then catch scalar stores.  */
-       else if (TREE_CODE (lhs) == VAR_DECL)
- 	{
- 	  if (!useless_type_conversion_p (TREE_TYPE (lhs), TREE_TYPE (rhs)))
- 	    gimple_assign_set_lhs (stmt, build1 (VIEW_CONVERT_EXPR,
- 						 TREE_TYPE (rhs), lhs));
- 	}
-     }
-   else if (is_gimple_call (stmt))
-     {
-       tree lhs = gimple_call_lhs (stmt);
- 
-       if (lhs && TREE_CODE (lhs) == VAR_DECL)
- 	{
- 	  if (!useless_type_conversion_p (TREE_TYPE (lhs),
- 					  gimple_call_return_type (stmt)))
- 	    gimple_call_set_lhs (stmt, build1 (VIEW_CONVERT_EXPR,
- 					       gimple_call_return_type (stmt),
- 					       lhs));
- 	}
- 
-       /* Arguments, especially for varargs functions will be funny...  */
-     }
- }
- 
  /* Read a statement with tag TAG in function FN from block IB using
     descriptors in DATA_IN.  */
  
--- 872,877 ----
*************** input_gimple_stmt (struct lto_input_bloc
*** 1064,1084 ****
  	  if (!op)
  	    continue;
  
- 	  /* Fixup reference tree operands for substituted prevailing decls
- 	     with mismatched types.  For plain VAR_DECLs we need to look
- 	     at context to determine the wanted type - we do that below
- 	     after the stmt is completed.  */
- 	  if (TREE_CODE (op) == ADDR_EXPR
- 	      && TREE_CODE (TREE_OPERAND (op, 0)) == VAR_DECL
- 	      && !useless_type_conversion_p (TREE_TYPE (TREE_TYPE (op)),
- 					     TREE_TYPE (TREE_OPERAND (op, 0))))
- 	    {
- 	      TREE_OPERAND (op, 0)
- 		= build1 (VIEW_CONVERT_EXPR, TREE_TYPE (TREE_TYPE (op)),
- 			  TREE_OPERAND (op, 0));
- 	      continue;
- 	    }
- 
  	  /* Fixup FIELD_DECLs in COMPONENT_REFs, they are not handled
  	     by decl merging.  */
  	  if (TREE_CODE (op) == ADDR_EXPR)
--- 946,951 ----
*************** input_gimple_stmt (struct lto_input_bloc
*** 1110,1126 ****
  		    TREE_OPERAND (op, 1) = tem;
  		}
  
- 	      /* Preserve the last handled component for the fixup of
- 	         its operand below.  */
- 	      if (!handled_component_p (TREE_OPERAND (op, 0)))
- 		break;
  	      op = TREE_OPERAND (op, 0);
  	    }
- 
- 	  /* Fixup reference tree operands for substituted prevailing decls
- 	     with mismatched types.  */
- 	  if (handled_component_p (op))
- 	    maybe_fixup_handled_component (op);
  	}
        break;
  
--- 977,984 ----
*************** input_gimple_stmt (struct lto_input_bloc
*** 1160,1169 ****
    if (code == GIMPLE_CALL)
      gimple_call_reset_alias_info (stmt);
  
-   /* Fixup reference tree operands for substituted prevailing decls
-      with mismatched types.  */
-   maybe_fixup_decls (stmt);
- 
    /* Mark the statement modified so its operand vectors can be filled in.  */
    gimple_set_modified (stmt, true);
  
--- 1018,1023 ----
Index: gcc/lto-streamer-out.c
===================================================================
*** gcc/lto-streamer-out.c	(revision 162176)
--- gcc/lto-streamer-out.c	(working copy)
*************** output_gimple_stmt (struct output_block
*** 1706,1711 ****
--- 1706,1730 ----
        for (i = 0; i < gimple_num_ops (stmt); i++)
  	{
  	  tree op = gimple_op (stmt, i);
+ 	  /* Wrap all uses of non-automatic variables inside MEM_REFs
+ 	     so that we do not have to deal with type mismatches on
+ 	     merged symbols during IL read in.  */
+ 	  if (op)
+ 	    {
+ 	      tree *basep = &op;
+ 	      if (handled_component_p (*basep))
+ 		basep = &TREE_OPERAND (*basep, 0);
+ 	      if (TREE_CODE (*basep) == VAR_DECL
+ 		  && !auto_var_in_fn_p (*basep, current_function_decl))
+ 		{
+ 		  bool volatilep = TREE_THIS_VOLATILE (*basep);
+ 		  *basep = build2 (MEM_REF, TREE_TYPE (*basep),
+ 				   build_fold_addr_expr (*basep),
+ 				   build_int_cst (build_pointer_type
+ 						  (TREE_TYPE (*basep)), 0));
+ 		  TREE_THIS_VOLATILE (*basep) = volatilep;
+ 		}
+ 	    }
  	  lto_output_tree_ref (ob, op);
  	}
        break;



More information about the Gcc-patches mailing list