mirror of git://gcc.gnu.org/git/gcc.git
				
				
				
			re PR tree-optimization/71170 (ICE in rewrite_expr_tree, at tree-ssa-reassoc.c:3898)
gcc/ChangeLog: 2016-05-24 Kugan Vivekanandarajah <kuganv@linaro.org> PR middle-end/71170 * tree-ssa-reassoc.c (struct operand_entry): Add field stmt_to_insert. (add_to_ops_vec): Add stmt_to_insert. (add_repeat_to_ops_vec): Init stmt_to_insert. (insert_stmt_before_use): New. (transform_add_to_multiply): Remove mult_stmt insertion and add it to ops vector. (get_ops): Init stmt_to_insert. (maybe_optimize_range_tests): Likewise. (rewrite_expr_tree): Insert stmt_to_insert before use stmt. (rewrite_expr_tree_parallel): Likewise. (reassociate_bb): Likewise. From-SVN: r236619
This commit is contained in:
		
							parent
							
								
									fe3f334041
								
							
						
					
					
						commit
						d2db36ddd2
					
				|  | @ -1,3 +1,17 @@ | |||
| 2016-05-24  Kugan Vivekanandarajah  <kuganv@linaro.org> | ||||
| 
 | ||||
| 	PR middle-end/71170 | ||||
| 	* tree-ssa-reassoc.c (struct operand_entry): Add field stmt_to_insert. | ||||
| 	(add_to_ops_vec): Add stmt_to_insert. | ||||
| 	(add_repeat_to_ops_vec): Init stmt_to_insert. | ||||
| 	(insert_stmt_before_use): New. | ||||
| 	(transform_add_to_multiply): Remove mult_stmt insertion and add it to ops vector. | ||||
| 	(get_ops): Init stmt_to_insert. | ||||
| 	(maybe_optimize_range_tests): Likewise. | ||||
| 	(rewrite_expr_tree): Insert stmt_to_insert before use stmt. | ||||
| 	(rewrite_expr_tree_parallel): Likewise. | ||||
| 	(reassociate_bb): Likewise. | ||||
| 
 | ||||
| 2016-05-23  Michael Meissner  <meissner@linux.vnet.ibm.com> | ||||
| 
 | ||||
| 	PR target/71201 | ||||
|  |  | |||
|  | @ -195,6 +195,7 @@ struct operand_entry | |||
|   int id; | ||||
|   tree op; | ||||
|   unsigned int count; | ||||
|   gimple *stmt_to_insert; | ||||
| }; | ||||
| 
 | ||||
| static object_allocator<operand_entry> operand_entry_pool | ||||
|  | @ -553,7 +554,7 @@ sort_by_operand_rank (const void *pa, const void *pb) | |||
| /* Add an operand entry to *OPS for the tree operand OP.  */ | ||||
| 
 | ||||
| static void | ||||
| add_to_ops_vec (vec<operand_entry *> *ops, tree op) | ||||
| add_to_ops_vec (vec<operand_entry *> *ops, tree op, gimple *stmt_to_insert = NULL) | ||||
| { | ||||
|   operand_entry *oe = operand_entry_pool.allocate (); | ||||
| 
 | ||||
|  | @ -561,6 +562,7 @@ add_to_ops_vec (vec<operand_entry *> *ops, tree op) | |||
|   oe->rank = get_rank (op); | ||||
|   oe->id = next_operand_entry_id++; | ||||
|   oe->count = 1; | ||||
|   oe->stmt_to_insert = stmt_to_insert; | ||||
|   ops->safe_push (oe); | ||||
| } | ||||
| 
 | ||||
|  | @ -577,6 +579,7 @@ add_repeat_to_ops_vec (vec<operand_entry *> *ops, tree op, | |||
|   oe->rank = get_rank (op); | ||||
|   oe->id = next_operand_entry_id++; | ||||
|   oe->count = repeat; | ||||
|   oe->stmt_to_insert = NULL; | ||||
|   ops->safe_push (oe); | ||||
| 
 | ||||
|   reassociate_stats.pows_encountered++; | ||||
|  | @ -1756,10 +1759,21 @@ eliminate_redundant_comparison (enum tree_code opcode, | |||
|   return false; | ||||
| } | ||||
| 
 | ||||
| /* If the stmt that defines operand has to be inserted, insert it
 | ||||
|    before the use.  */ | ||||
| static void | ||||
| insert_stmt_before_use (gimple *stmt, gimple *stmt_to_insert) | ||||
| { | ||||
|   gimple_stmt_iterator gsi = gsi_for_stmt (stmt); | ||||
|   gimple_set_uid (stmt_to_insert, gimple_uid (stmt)); | ||||
|   gsi_insert_before (&gsi, stmt_to_insert, GSI_NEW_STMT); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| /* Transform repeated addition of same values into multiply with
 | ||||
|    constant.  */ | ||||
| static bool | ||||
| transform_add_to_multiply (gimple *stmt, vec<operand_entry *> *ops) | ||||
| transform_add_to_multiply (vec<operand_entry *> *ops) | ||||
| { | ||||
|   operand_entry *oe; | ||||
|   tree op = NULL_TREE; | ||||
|  | @ -1811,21 +1825,11 @@ transform_add_to_multiply (gimple *stmt, vec<operand_entry *> *ops) | |||
| 	ops->unordered_remove (i); | ||||
|       tree tmp = make_ssa_name (TREE_TYPE (op)); | ||||
|       tree cst = build_int_cst (integer_type_node, count); | ||||
|       gimple *def_stmt = SSA_NAME_DEF_STMT (op); | ||||
|       gassign *mul_stmt | ||||
| 	= gimple_build_assign (tmp, MULT_EXPR, | ||||
| 			       op, fold_convert (TREE_TYPE (op), cst)); | ||||
|       if (gimple_code (def_stmt) == GIMPLE_NOP | ||||
| 	  || gimple_bb (stmt) != gimple_bb (def_stmt)) | ||||
| 	{ | ||||
| 	  gimple_stmt_iterator gsi = gsi_for_stmt (stmt); | ||||
| 	  gimple_set_uid (mul_stmt, gimple_uid (stmt)); | ||||
| 	  gsi_insert_before (&gsi, mul_stmt, GSI_NEW_STMT); | ||||
| 	} | ||||
|       else | ||||
| 	insert_stmt_after (mul_stmt, def_stmt); | ||||
|       gimple_set_visited (mul_stmt, true); | ||||
|       add_to_ops_vec (ops, tmp); | ||||
|       add_to_ops_vec (ops, tmp, mul_stmt); | ||||
|       changed = true; | ||||
|     } | ||||
| 
 | ||||
|  | @ -3225,6 +3229,7 @@ get_ops (tree var, enum tree_code code, vec<operand_entry *> *ops, | |||
| 	oe->rank = code; | ||||
| 	oe->id = 0; | ||||
| 	oe->count = 1; | ||||
| 	oe->stmt_to_insert = NULL; | ||||
| 	ops->safe_push (oe); | ||||
|       } | ||||
|   return true; | ||||
|  | @ -3465,6 +3470,7 @@ maybe_optimize_range_tests (gimple *stmt) | |||
| 	      oe->rank = code; | ||||
| 	      oe->id = 0; | ||||
| 	      oe->count = 1; | ||||
| 	      oe->stmt_to_insert = NULL; | ||||
| 	      ops.safe_push (oe); | ||||
| 	      bb_ent.last_idx++; | ||||
| 	    } | ||||
|  | @ -3502,6 +3508,7 @@ maybe_optimize_range_tests (gimple *stmt) | |||
| 	     is.  */ | ||||
| 	  oe->id = bb->index; | ||||
| 	  oe->count = 1; | ||||
| 	  oe->stmt_to_insert = NULL; | ||||
| 	  ops.safe_push (oe); | ||||
| 	  bb_ent.op = NULL; | ||||
| 	  bb_ent.last_idx++; | ||||
|  | @ -3818,6 +3825,12 @@ rewrite_expr_tree (gimple *stmt, unsigned int opindex, | |||
| 	    { | ||||
| 	      gimple *insert_point | ||||
| 		= find_insert_point (stmt, oe1->op, oe2->op); | ||||
| 	      /* If the stmt that defines operand has to be inserted, insert it
 | ||||
| 		 before the use.  */ | ||||
| 	      if (oe1->stmt_to_insert) | ||||
| 		insert_stmt_before_use (stmt, oe1->stmt_to_insert); | ||||
| 	      if (oe2->stmt_to_insert) | ||||
| 		insert_stmt_before_use (stmt, oe2->stmt_to_insert); | ||||
| 	      lhs = make_ssa_name (TREE_TYPE (lhs)); | ||||
| 	      stmt | ||||
| 		= gimple_build_assign (lhs, gimple_assign_rhs_code (stmt), | ||||
|  | @ -3833,6 +3846,12 @@ rewrite_expr_tree (gimple *stmt, unsigned int opindex, | |||
| 	    { | ||||
| 	      gcc_checking_assert (find_insert_point (stmt, oe1->op, oe2->op) | ||||
| 				   == stmt); | ||||
| 	      /* If the stmt that defines operand has to be inserted, insert it
 | ||||
| 		 before the use.  */ | ||||
| 	      if (oe1->stmt_to_insert) | ||||
| 		insert_stmt_before_use (stmt, oe1->stmt_to_insert); | ||||
| 	      if (oe2->stmt_to_insert) | ||||
| 		insert_stmt_before_use (stmt, oe2->stmt_to_insert); | ||||
| 	      gimple_assign_set_rhs1 (stmt, oe1->op); | ||||
| 	      gimple_assign_set_rhs2 (stmt, oe2->op); | ||||
| 	      update_stmt (stmt); | ||||
|  | @ -3856,6 +3875,11 @@ rewrite_expr_tree (gimple *stmt, unsigned int opindex, | |||
|   /* Rewrite the next operator.  */ | ||||
|   oe = ops[opindex]; | ||||
| 
 | ||||
|   /* If the stmt that defines operand has to be inserted, insert it
 | ||||
|      before the use.  */ | ||||
|   if (oe->stmt_to_insert) | ||||
|     insert_stmt_before_use (stmt, oe->stmt_to_insert); | ||||
| 
 | ||||
|   /* Recurse on the LHS of the binary operator, which is guaranteed to
 | ||||
|      be the non-leaf side.  */ | ||||
|   tree new_rhs1 | ||||
|  | @ -4000,6 +4024,7 @@ rewrite_expr_tree_parallel (gassign *stmt, int width, | |||
|   int stmt_index = 0; | ||||
|   int ready_stmts_end = 0; | ||||
|   int i = 0; | ||||
|   gimple *stmt1 = NULL, *stmt2 = NULL; | ||||
|   tree last_rhs1 = gimple_assign_rhs1 (stmt); | ||||
| 
 | ||||
|   /* We start expression rewriting from the top statements.
 | ||||
|  | @ -4028,7 +4053,11 @@ rewrite_expr_tree_parallel (gassign *stmt, int width, | |||
| 	  if (ready_stmts_end > stmt_index) | ||||
| 	    op2 = gimple_assign_lhs (stmts[stmt_index++]); | ||||
| 	  else if (op_index >= 0) | ||||
| 	    op2 = ops[op_index--]->op; | ||||
| 	    { | ||||
| 	      operand_entry *oe = ops[op_index--]; | ||||
| 	      stmt2 = oe->stmt_to_insert; | ||||
| 	      op2 = oe->op; | ||||
| 	    } | ||||
| 	  else | ||||
| 	    { | ||||
| 	      gcc_assert (stmt_index < i); | ||||
|  | @ -4042,8 +4071,12 @@ rewrite_expr_tree_parallel (gassign *stmt, int width, | |||
| 	{ | ||||
| 	  if (op_index > 1) | ||||
| 	    swap_ops_for_binary_stmt (ops, op_index - 2, NULL); | ||||
| 	  op2 = ops[op_index--]->op; | ||||
| 	  op1 = ops[op_index--]->op; | ||||
| 	  operand_entry *oe2 = ops[op_index--]; | ||||
| 	  operand_entry *oe1 = ops[op_index--]; | ||||
| 	  op2 = oe2->op; | ||||
| 	  stmt2 = oe2->stmt_to_insert; | ||||
| 	  op1 = oe1->op; | ||||
| 	  stmt1 = oe1->stmt_to_insert; | ||||
| 	} | ||||
| 
 | ||||
|       /* If we emit the last statement then we should put
 | ||||
|  | @ -4058,6 +4091,13 @@ rewrite_expr_tree_parallel (gassign *stmt, int width, | |||
| 	  print_gimple_stmt (dump_file, stmts[i], 0, 0); | ||||
| 	} | ||||
| 
 | ||||
|       /* If the stmt that defines operand has to be inserted, insert it
 | ||||
| 	 before the use.  */ | ||||
|       if (stmt1) | ||||
| 	insert_stmt_before_use (stmts[i], stmt1); | ||||
|       if (stmt2) | ||||
| 	insert_stmt_before_use (stmts[i], stmt2); | ||||
| 
 | ||||
|       /* We keep original statement only for the last one.  All
 | ||||
| 	 others are recreated.  */ | ||||
|       if (i == stmt_num - 1) | ||||
|  | @ -5202,7 +5242,7 @@ reassociate_bb (basic_block bb) | |||
| 		} | ||||
| 
 | ||||
| 	      if (rhs_code == PLUS_EXPR | ||||
| 		  && transform_add_to_multiply (stmt, &ops)) | ||||
| 		  && transform_add_to_multiply (&ops)) | ||||
| 		ops.qsort (sort_by_operand_rank); | ||||
| 
 | ||||
| 	      if (rhs_code == BIT_IOR_EXPR || rhs_code == BIT_AND_EXPR) | ||||
|  | @ -5248,6 +5288,10 @@ reassociate_bb (basic_block bb) | |||
| 		{ | ||||
| 		  tree last_op = ops.last ()->op; | ||||
| 
 | ||||
| 		  /* If the stmt that defines operand has to be inserted, insert it
 | ||||
| 		     before the use.  */ | ||||
| 		  if (ops.last ()->stmt_to_insert) | ||||
| 		    insert_stmt_before_use (stmt, ops.last ()->stmt_to_insert); | ||||
| 		  if (powi_result) | ||||
| 		    transform_stmt_to_multiply (&gsi, stmt, last_op, | ||||
| 						powi_result); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Kugan Vivekanandarajah
						Kugan Vivekanandarajah