[PATCH] Remove gimplifier use from PRE

Richard Biener rguenther@suse.de
Thu Oct 1 13:39:00 GMT 2015


The following patch from the match-and-simplify branch removes
gimplifier use from PRE replacing it with use of the gimple_build API
building GIMPLE directly.

Bootstrapped on x86_64-unknown-linux-gnu, testing in progress.

Richard.

2015-10-01  Richard Biener  <rguenther@suse.de>

	* tree-ssa-pre.c (create_component_ref_by_pieces_1): Build
	GIMPLE calls directly.
	(create_expression_by_pieces): Use gimple_build API and avoid
	force_gimple_operand.
	(insert_into_preds_of_block): Likewise.
	(do_regular_insertion): Add comment.

Index: gcc/tree-ssa-pre.c
===================================================================
*** gcc/tree-ssa-pre.c	(revision 228320)
--- gcc/tree-ssa-pre.c	(working copy)
*************** create_component_ref_by_pieces_1 (basic_
*** 2475,2483 ****
      {
      case CALL_EXPR:
        {
! 	tree folded, sc = NULL_TREE;
! 	unsigned int nargs = 0;
! 	tree fn, *args;
  	if (TREE_CODE (currop->op0) == FUNCTION_DECL)
  	  fn = currop->op0;
  	else
--- 2475,2482 ----
      {
      case CALL_EXPR:
        {
! 	tree sc = NULL_TREE;
! 	tree fn;
  	if (TREE_CODE (currop->op0) == FUNCTION_DECL)
  	  fn = currop->op0;
  	else
*************** create_component_ref_by_pieces_1 (basic_
*** 2490,2514 ****
  	    if (!sc)
  	      return NULL_TREE;
  	  }
! 	args = XNEWVEC (tree, ref->operands.length () - 1);
  	while (*operand < ref->operands.length ())
  	  {
! 	    args[nargs] = create_component_ref_by_pieces_1 (block, ref,
! 							    operand, stmts);
! 	    if (!args[nargs])
  	      return NULL_TREE;
! 	    nargs++;
  	  }
! 	folded = build_call_array (currop->type,
! 				   (TREE_CODE (fn) == FUNCTION_DECL
! 				    ? build_fold_addr_expr (fn) : fn),
! 				   nargs, args);
! 	if (currop->with_bounds)
! 	  CALL_WITH_BOUNDS_P (folded) = true;
! 	free (args);
  	if (sc)
! 	  CALL_EXPR_STATIC_CHAIN (folded) = sc;
! 	return folded;
        }
  
      case MEM_REF:
--- 2489,2521 ----
  	    if (!sc)
  	      return NULL_TREE;
  	  }
! 	auto_vec<tree> args (ref->operands.length () - 1);
  	while (*operand < ref->operands.length ())
  	  {
! 	    tree arg = create_component_ref_by_pieces_1 (block, ref,
! 							 operand, stmts);
! 	    if (!arg)
  	      return NULL_TREE;
! 	    args.quick_push (arg);
  	  }
! 	gcall *call = gimple_build_call_vec ((TREE_CODE (fn) == FUNCTION_DECL
! 					      ? build_fold_addr_expr (fn) : fn),
! 					     args);
! 	gimple_call_set_with_bounds (call, currop->with_bounds);
  	if (sc)
! 	  gimple_call_set_chain (call, sc);
! 	tree forcedname = make_ssa_name (currop->type);
! 	gimple_call_set_lhs (call, forcedname);
! 	gimple_set_vuse (call, BB_LIVE_VOP_ON_EXIT (block));
! 	gimple_seq_add_stmt_without_update (stmts, call);
! 	bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (forcedname));
! 	VN_INFO_GET (forcedname)->valnum = forcedname;
! 	VN_INFO (forcedname)->value_id = get_next_value_id ();
! 	pre_expr nameexpr = get_or_alloc_expr_for_name (forcedname);
! 	add_to_value (VN_INFO (forcedname)->value_id, nameexpr);
! 	bitmap_value_replace_in_set (NEW_SETS (block), nameexpr);
! 	bitmap_value_replace_in_set (AVAIL_OUT (block), nameexpr);
! 	return forcedname;
        }
  
      case MEM_REF:
*************** create_expression_by_pieces (basic_block
*** 2851,2866 ****
  	    switch (nary->length)
  	      {
  	      case 1:
! 		folded = fold_build1 (nary->opcode, nary->type,
! 				      genop[0]);
  		break;
  	      case 2:
! 		folded = fold_build2 (nary->opcode, nary->type,
! 				      genop[0], genop[1]);
  		break;
  	      case 3:
! 		folded = fold_build3 (nary->opcode, nary->type,
! 				      genop[0], genop[1], genop[2]);
  		break;
  	      default:
  		gcc_unreachable ();
--- 2858,2873 ----
  	    switch (nary->length)
  	      {
  	      case 1:
! 		folded = gimple_build (&forced_stmts, nary->opcode, nary->type,
! 				       genop[0]);
  		break;
  	      case 2:
! 		folded = gimple_build (&forced_stmts, nary->opcode, nary->type,
! 				       genop[0], genop[1]);
  		break;
  	      case 3:
! 		folded = gimple_build (&forced_stmts, nary->opcode, nary->type,
! 				       genop[0], genop[1], genop[2]);
  		break;
  	      default:
  		gcc_unreachable ();
*************** create_expression_by_pieces (basic_block
*** 2872,2888 ****
        gcc_unreachable ();
      }
  
!   if (!useless_type_conversion_p (exprtype, TREE_TYPE (folded)))
!     folded = fold_convert (exprtype, folded);
! 
!   /* Force the generated expression to be a sequence of GIMPLE
!      statements.
!      We have to call unshare_expr because force_gimple_operand may
!      modify the tree we pass to it.  */
!   gimple_seq tem = NULL;
!   folded = force_gimple_operand (unshare_expr (folded), &tem,
! 				 false, NULL);
!   gimple_seq_add_seq_without_update (&forced_stmts, tem);
  
    /* If we have any intermediate expressions to the value sets, add them
       to the value sets and chain them in the instruction stream.  */
--- 2879,2885 ----
        gcc_unreachable ();
      }
  
!   folded = gimple_convert (&forced_stmts, exprtype, folded);
  
    /* If we have any intermediate expressions to the value sets, add them
       to the value sets and chain them in the instruction stream.  */
*************** create_expression_by_pieces (basic_block
*** 2915,2921 ****
    name = make_temp_ssa_name (exprtype, NULL, "pretmp");
    newstmt = gimple_build_assign (name, folded);
    gimple_set_vuse (newstmt, BB_LIVE_VOP_ON_EXIT (block));
-   gimple_set_modified (newstmt, true);
    gimple_set_plf (newstmt, NECESSARY, false);
  
    gimple_seq_add_stmt (stmts, newstmt);
--- 2912,2917 ----
*************** insert_into_preds_of_block (basic_block
*** 3026,3069 ****
  	  /* Constants may not have the right type, fold_convert
  	     should give us back a constant with the right type.  */
  	  tree constant = PRE_EXPR_CONSTANT (eprime);
! 	  if (!useless_type_conversion_p (type, TREE_TYPE (constant)))
  	    {
! 	      tree builtexpr = fold_convert (type, constant);
! 	      if (!is_gimple_min_invariant (builtexpr))
  		{
! 		  tree forcedexpr = force_gimple_operand (builtexpr,
! 							  &stmts, true,
! 							  NULL);
! 		  if (!is_gimple_min_invariant (forcedexpr))
  		    {
! 		      if (forcedexpr != builtexpr)
! 			{
! 			  VN_INFO_GET (forcedexpr)->valnum = PRE_EXPR_CONSTANT (eprime);
! 			  VN_INFO (forcedexpr)->value_id = get_expr_value_id (eprime);
! 			}
! 		      if (stmts)
! 			{
! 			  gimple_stmt_iterator gsi;
! 			  gsi = gsi_start (stmts);
! 			  for (; !gsi_end_p (gsi); gsi_next (&gsi))
! 			    {
! 			      gimple *stmt = gsi_stmt (gsi);
! 			      tree lhs = gimple_get_lhs (stmt);
! 			      if (TREE_CODE (lhs) == SSA_NAME)
! 				bitmap_set_bit (inserted_exprs,
! 						SSA_NAME_VERSION (lhs));
! 			      gimple_set_plf (stmt, NECESSARY, false);
! 			    }
! 			  gsi_insert_seq_on_edge (pred, stmts);
! 			}
! 		      avail[pred->dest_idx]
! 			= get_or_alloc_expr_for_name (forcedexpr);
  		    }
  		}
! 	      else
! 		avail[pred->dest_idx]
! 		    = get_or_alloc_expr_for_constant (builtexpr);
  	    }
  	}
        else if (eprime->kind == NAME)
  	{
--- 3022,3051 ----
  	  /* Constants may not have the right type, fold_convert
  	     should give us back a constant with the right type.  */
  	  tree constant = PRE_EXPR_CONSTANT (eprime);
! 	  tree forcedexpr = gimple_convert (&stmts, type, constant);
! 	  if (!is_gimple_min_invariant (forcedexpr))
  	    {
! 	      VN_INFO_GET (forcedexpr)->valnum = PRE_EXPR_CONSTANT (eprime);
! 	      VN_INFO (forcedexpr)->value_id = get_expr_value_id (eprime);
! 	      if (!gimple_seq_empty_p (stmts))
  		{
! 		  gimple_stmt_iterator gsi;
! 		  gsi = gsi_start (stmts);
! 		  for (; !gsi_end_p (gsi); gsi_next (&gsi))
  		    {
! 		      gimple *stmt = gsi_stmt (gsi);
! 		      tree lhs = gimple_get_lhs (stmt);
! 		      if (TREE_CODE (lhs) == SSA_NAME)
! 			bitmap_set_bit (inserted_exprs,
! 					SSA_NAME_VERSION (lhs));
! 		      gimple_set_plf (stmt, NECESSARY, false);
  		    }
+ 		  gsi_insert_seq_on_edge (pred, stmts);
  		}
! 	      avail[pred->dest_idx] = get_or_alloc_expr_for_name (forcedexpr);
  	    }
+ 	  else
+ 	    avail[pred->dest_idx] = get_or_alloc_expr_for_constant (forcedexpr);
  	}
        else if (eprime->kind == NAME)
  	{
*************** insert_into_preds_of_block (basic_block
*** 3072,3108 ****
  	     our IL requires all operands of a phi node have the same
  	     type.  */
  	  tree name = PRE_EXPR_NAME (eprime);
! 	  if (!useless_type_conversion_p (type, TREE_TYPE (name)))
  	    {
! 	      tree builtexpr;
! 	      tree forcedexpr;
! 	      builtexpr = fold_convert (type, name);
! 	      forcedexpr = force_gimple_operand (builtexpr,
! 						 &stmts, true,
! 						 NULL);
! 
! 	      if (forcedexpr != name)
! 		{
! 		  VN_INFO_GET (forcedexpr)->valnum = VN_INFO (name)->valnum;
! 		  VN_INFO (forcedexpr)->value_id = VN_INFO (name)->value_id;
! 		}
! 
! 	      if (stmts)
  		{
! 		  gimple_stmt_iterator gsi;
! 		  gsi = gsi_start (stmts);
! 		  for (; !gsi_end_p (gsi); gsi_next (&gsi))
! 		    {
! 		      gimple *stmt = gsi_stmt (gsi);
! 		      tree lhs = gimple_get_lhs (stmt);
! 		      if (TREE_CODE (lhs) == SSA_NAME)
! 			bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (lhs));
! 		      gimple_set_plf (stmt, NECESSARY, false);
! 		    }
! 		  gsi_insert_seq_on_edge (pred, stmts);
  		}
! 	      avail[pred->dest_idx] = get_or_alloc_expr_for_name (forcedexpr);
  	    }
  	}
      }
    /* If we didn't want a phi node, and we made insertions, we still have
--- 3054,3080 ----
  	     our IL requires all operands of a phi node have the same
  	     type.  */
  	  tree name = PRE_EXPR_NAME (eprime);
! 	  tree forcedexpr = gimple_convert (&stmts, type, name);
! 	  if (forcedexpr != name)
  	    {
! 	      VN_INFO_GET (forcedexpr)->valnum = VN_INFO (name)->valnum;
! 	      VN_INFO (forcedexpr)->value_id = VN_INFO (name)->value_id;
! 	    }
! 	  if (!gimple_seq_empty_p (stmts))
! 	    {
! 	      gimple_stmt_iterator gsi;
! 	      gsi = gsi_start (stmts);
! 	      for (; !gsi_end_p (gsi); gsi_next (&gsi))
  		{
! 		  gimple *stmt = gsi_stmt (gsi);
! 		  tree lhs = gimple_get_lhs (stmt);
! 		  if (TREE_CODE (lhs) == SSA_NAME)
! 		    bitmap_set_bit (inserted_exprs, SSA_NAME_VERSION (lhs));
! 		  gimple_set_plf (stmt, NECESSARY, false);
  		}
! 	      gsi_insert_seq_on_edge (pred, stmts);
  	    }
+ 	  avail[pred->dest_idx] = get_or_alloc_expr_for_name (forcedexpr);
  	}
      }
    /* If we didn't want a phi node, and we made insertions, we still have
*************** do_regular_insertion (basic_block block,
*** 3267,3272 ****
--- 3239,3245 ----
  	         and so not come across fake pred edges.  */
  	      gcc_assert (!(pred->flags & EDGE_FAKE));
  	      bprime = pred->src;
+ 	      /* We are looking at ANTIC_OUT of bprime.  */
  	      eprime = phi_translate (expr, ANTIC_IN (block), NULL,
  				      bprime, block);
  



More information about the Gcc-patches mailing list