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]

[PATCH][GRAPHITE] Fix PR80906, code-gen IVs in loop-closed position


We currently ICE when code generating loop-closed PHIs that are after-loop
used IVs.  I didn't manage to find the place during analysis that is
supposed to reject such SCOPs thus the following patch "simply" makes
us properly generate code for those (works fine on the testcase).

Bootstrapped and tested on x86_64-unknown-linux-gnu, ok?

If there's such rejection code it might be lifted now (and eventually
unconver the bugs I introduce with this patch).

Thanks,
Richard.

2017-05-30  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/80906
	* graphite-isl-ast-to-gimple.c (copy_loop_close_phi_nodes): Get
	and pass through iv_map.
	(copy_bb_and_scalar_dependences): Adjust.
	(translate_pending_phi_nodes): Likewise.
	(copy_loop_close_phi_args): Handle code-generating IVs instead
	of ICEing.

	* gcc.dg/graphite/pr80906.c: New testcase.

Index: gcc/graphite-isl-ast-to-gimple.c
===================================================================
*** gcc/graphite-isl-ast-to-gimple.c	(revision 248634)
--- gcc/graphite-isl-ast-to-gimple.c	(working copy)
*************** class translate_isl_ast_to_gimple
*** 229,236 ****
    tree add_close_phis_to_outer_loops (tree last_merge_name, edge merge_e,
  				      gimple *old_close_phi);
    bool copy_loop_close_phi_args (basic_block old_bb, basic_block new_bb,
! 				 bool postpone);
!   bool copy_loop_close_phi_nodes (basic_block old_bb, basic_block new_bb);
    bool copy_cond_phi_args (gphi *phi, gphi *new_phi, vec<tree> iv_map,
  			   bool postpone);
    bool copy_cond_phi_nodes (basic_block bb, basic_block new_bb,
--- 229,237 ----
    tree add_close_phis_to_outer_loops (tree last_merge_name, edge merge_e,
  				      gimple *old_close_phi);
    bool copy_loop_close_phi_args (basic_block old_bb, basic_block new_bb,
! 				 vec<tree> iv_map, bool postpone);
!   bool copy_loop_close_phi_nodes (basic_block old_bb, basic_block new_bb,
! 				  vec<tree> iv_map);
    bool copy_cond_phi_args (gphi *phi, gphi *new_phi, vec<tree> iv_map,
  			   bool postpone);
    bool copy_cond_phi_nodes (basic_block bb, basic_block new_bb,
*************** add_close_phis_to_merge_points (gphi *ol
*** 2079,2085 ****
  /* Copy all the loop-close phi args from BB to NEW_BB.  */
  
  bool translate_isl_ast_to_gimple::
! copy_loop_close_phi_args (basic_block old_bb, basic_block new_bb, bool postpone)
  {
    for (gphi_iterator psi = gsi_start_phis (old_bb); !gsi_end_p (psi);
         gsi_next (&psi))
--- 2080,2087 ----
  /* Copy all the loop-close phi args from BB to NEW_BB.  */
  
  bool translate_isl_ast_to_gimple::
! copy_loop_close_phi_args (basic_block old_bb, basic_block new_bb,
! 			  vec<tree> iv_map, bool postpone)
  {
    for (gphi_iterator psi = gsi_start_phis (old_bb); !gsi_end_p (psi);
         gsi_next (&psi))
*************** copy_loop_close_phi_args (basic_block ol
*** 2089,2110 ****
        if (virtual_operand_p (res))
  	continue;
  
-       if (is_gimple_reg (res) && scev_analyzable_p (res, region->region))
- 	/* Loop close phi nodes should not be scev_analyzable_p.  */
- 	gcc_unreachable ();
- 
        gphi *new_close_phi = create_phi_node (NULL_TREE, new_bb);
        tree new_res = create_new_def_for (res, new_close_phi,
  					 gimple_phi_result_ptr (new_close_phi));
        set_rename (res, new_res);
  
        tree old_name = gimple_phi_arg_def (old_close_phi, 0);
!       tree new_name = get_new_name (new_bb, old_name, old_bb, close_phi);
  
        /* Predecessor basic blocks of a loop close phi should have been code
  	 generated before.  FIXME: This is fixable by merging PHIs from inner
  	 loops as well.  See: gfortran.dg/graphite/interchange-3.f90.  */
!       if (!new_name)
  	return false;
  
        add_phi_arg (new_close_phi, new_name, single_pred_edge (new_bb),
--- 2091,2119 ----
        if (virtual_operand_p (res))
  	continue;
  
        gphi *new_close_phi = create_phi_node (NULL_TREE, new_bb);
        tree new_res = create_new_def_for (res, new_close_phi,
  					 gimple_phi_result_ptr (new_close_phi));
        set_rename (res, new_res);
  
        tree old_name = gimple_phi_arg_def (old_close_phi, 0);
!       tree new_name;
!       if (is_gimple_reg (res) && scev_analyzable_p (res, region->region))
! 	{
! 	  gimple_seq stmts;
! 	  new_name = get_rename_from_scev (old_name, &stmts,
! 					   old_bb->loop_father,
! 					   new_bb, old_bb, iv_map);
! 	  if (! codegen_error_p ())
! 	    gsi_insert_earliest (stmts);
! 	}
!       else
! 	new_name = get_new_name (new_bb, old_name, old_bb, close_phi);
  
        /* Predecessor basic blocks of a loop close phi should have been code
  	 generated before.  FIXME: This is fixable by merging PHIs from inner
  	 loops as well.  See: gfortran.dg/graphite/interchange-3.f90.  */
!       if (!new_name || codegen_error_p ())
  	return false;
  
        add_phi_arg (new_close_phi, new_name, single_pred_edge (new_bb),
*************** copy_loop_close_phi_args (basic_block ol
*** 2152,2158 ****
  /* Copy loop close phi nodes from BB to NEW_BB.  */
  
  bool translate_isl_ast_to_gimple::
! copy_loop_close_phi_nodes (basic_block old_bb, basic_block new_bb)
  {
    if (dump_file)
      fprintf (dump_file, "[codegen] copying loop close phi nodes in bb_%d.\n",
--- 2161,2168 ----
  /* Copy loop close phi nodes from BB to NEW_BB.  */
  
  bool translate_isl_ast_to_gimple::
! copy_loop_close_phi_nodes (basic_block old_bb, basic_block new_bb,
! 			   vec<tree> iv_map)
  {
    if (dump_file)
      fprintf (dump_file, "[codegen] copying loop close phi nodes in bb_%d.\n",
*************** copy_loop_close_phi_nodes (basic_block o
*** 2160,2166 ****
    /* Loop close phi nodes should have only one argument.  */
    gcc_assert (1 == EDGE_COUNT (old_bb->preds));
  
!   return copy_loop_close_phi_args (old_bb, new_bb, true);
  }
  
  
--- 2170,2176 ----
    /* Loop close phi nodes should have only one argument.  */
    gcc_assert (1 == EDGE_COUNT (old_bb->preds));
  
!   return copy_loop_close_phi_args (old_bb, new_bb, iv_map, true);
  }
  
  
*************** copy_bb_and_scalar_dependences (basic_bl
*** 2690,2696 ****
        gcc_assert (single_pred_edge (phi_bb)->src->loop_father
  		  != single_pred_edge (phi_bb)->dest->loop_father);
  
!       if (!copy_loop_close_phi_nodes (bb, phi_bb))
  	{
  	  codegen_error = true;
  	  return NULL;
--- 2700,2706 ----
        gcc_assert (single_pred_edge (phi_bb)->src->loop_father
  		  != single_pred_edge (phi_bb)->dest->loop_father);
  
!       if (!copy_loop_close_phi_nodes (bb, phi_bb, iv_map))
  	{
  	  codegen_error = true;
  	  return NULL;
*************** translate_pending_phi_nodes ()
*** 2824,2830 ****
  	codegen_error = !copy_loop_phi_args (old_phi, ibp_old_bb, new_phi,
  					    ibp_new_bb, false);
        else if (bb_contains_loop_close_phi_nodes (new_bb))
! 	codegen_error = !copy_loop_close_phi_args (old_bb, new_bb, false);
        else
  	codegen_error = !copy_cond_phi_args (old_phi, new_phi, iv_map, false);
  
--- 2834,2840 ----
  	codegen_error = !copy_loop_phi_args (old_phi, ibp_old_bb, new_phi,
  					    ibp_new_bb, false);
        else if (bb_contains_loop_close_phi_nodes (new_bb))
! 	codegen_error = !copy_loop_close_phi_args (old_bb, new_bb, iv_map, false);
        else
  	codegen_error = !copy_cond_phi_args (old_phi, new_phi, iv_map, false);
  
Index: gcc/testsuite/gcc.dg/graphite/pr80906.c
===================================================================
*** gcc/testsuite/gcc.dg/graphite/pr80906.c	(nonexistent)
--- gcc/testsuite/gcc.dg/graphite/pr80906.c	(working copy)
***************
*** 0 ****
--- 1,28 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O2 -floop-nest-optimize -fdump-tree-graphite" } */
+ 
+ int qc;
+ 
+ int
+ ec (int lh[][2])
+ {
+   const int jv = 3;
+   int zf, hp, c5 = 0, m3 = 1;
+ 
+   for (zf = 0; zf < jv; ++zf)
+     for (hp = 0; hp < jv; ++hp)
+       {
+ 	short int bm = 0;
+ 
+ 	for (qc = 0; qc < jv; ++qc)
+ 	  --bm;
+ 	if (bm != 0)
+ 	  --c5;
+ 	lh[0][0] = 0;
+ 	m3 *= jv;
+       }
+ 
+   return c5 + m3;
+ }
+ 
+ /* { dg-final { scan-tree-dump "isl AST to Gimple succeeded" "graphite" } } */


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