Commit 210ac0b7 by Andrew Pinski Committed by Andrew Pinski

re PR tree-optimization/51988 (value_replacement in PHIOPT should handle even…

re PR tree-optimization/51988 (value_replacement in PHIOPT should handle even the cases where there are other PHIs even with non equal value)

2012-03-09  Andrew Pinski  <apinski@cavium.com>

	PR middle-end/51988
	* tree-ssa-phiopt.c: Include tree-pretty-print.h for
	print_generic_expr.
	(tree_ssa_phiopt_worker): Go through all the PHIs for
	value_replacement instead of just the singleton one.
	(value_replacement): Change return type to int.  Return 0 instead of
	false.
	Allow the middle basic block to contain more than just the definings
	tatement. 
	Handle non empty middle basic blocks.
	* Makefile.in (tree-ssa-phiopt.o): Add tree-pretty-print.h.

2012-03-09  Andrew Pinski  <apinski@cavium.com>

	PR middle-end/51988
	* gcc.dg/tree-ssa/phi-opt-8.c: New testcase.
	* gcc.dg/tree-ssa/phi-opt-9.c: New testcase.

From-SVN: r185131
parent bef28ced
2012-03-09 Andrew Pinski <apinski@cavium.com>
PR middle-end/51988
* tree-ssa-phiopt.c: Include tree-pretty-print.h for
print_generic_expr.
(tree_ssa_phiopt_worker): Go through all the PHIs for
value_replacement instead of just the singleton one.
(value_replacement): Change return type to int. Return 0 instead of
false.
Allow the middle basic block to contain more than just the definings
tatement.
Handle non empty middle basic blocks.
* Makefile.in (tree-ssa-phiopt.o): Add tree-pretty-print.h.
2012-03-09 Jiangning Liu <jiangning.liu@arm.com> 2012-03-09 Jiangning Liu <jiangning.liu@arm.com>
* tree-scalar-evolution (interpret_rhs_expr): generate chrec for * tree-scalar-evolution (interpret_rhs_expr): generate chrec for
......
...@@ -2355,7 +2355,7 @@ tree-ssa-phiopt.o : tree-ssa-phiopt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ ...@@ -2355,7 +2355,7 @@ tree-ssa-phiopt.o : tree-ssa-phiopt.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(GGC_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) \ $(TM_H) $(GGC_H) $(TREE_H) $(TM_P_H) $(BASIC_BLOCK_H) \
$(TREE_FLOW_H) $(TREE_PASS_H) $(TREE_DUMP_H) langhooks.h $(FLAGS_H) \ $(TREE_FLOW_H) $(TREE_PASS_H) $(TREE_DUMP_H) langhooks.h $(FLAGS_H) \
$(DIAGNOSTIC_H) $(TIMEVAR_H) pointer-set.h domwalk.h $(CFGLOOP_H) \ $(DIAGNOSTIC_H) $(TIMEVAR_H) pointer-set.h domwalk.h $(CFGLOOP_H) \
$(TREE_DATA_REF_H) $(TREE_DATA_REF_H) tree-pretty-print.h
tree-nrv.o : tree-nrv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \ tree-nrv.o : tree-nrv.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TM_H) $(TREE_H) $(FUNCTION_H) $(BASIC_BLOCK_H) $(FLAGS_H) \ $(TM_H) $(TREE_H) $(FUNCTION_H) $(BASIC_BLOCK_H) $(FLAGS_H) \
$(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TIMEVAR_H) $(TREE_DUMP_H) $(TREE_PASS_H) \ $(DIAGNOSTIC_H) $(TREE_FLOW_H) $(TIMEVAR_H) $(TREE_DUMP_H) $(TREE_PASS_H) \
......
2012-03-09 Andrew Pinski <apinski@cavium.com>
PR middle-end/51988
* gcc.dg/tree-ssa/phi-opt-8.c: New testcase.
* gcc.dg/tree-ssa/phi-opt-9.c: New testcase.
2012-03-09 Jiangning Liu <jiangning.liu@arm.com> 2012-03-09 Jiangning Liu <jiangning.liu@arm.com>
* gcc.dg/tree-ssa/scev-3.c: New. * gcc.dg/tree-ssa/scev-3.c: New.
......
/* { dg-do compile } */
/* { dg-options "-O -fdump-tree-optimized -fdump-tree-phiopt1" } */
int g(int,int);
int f(int t, int c)
{
int d = 0;
int e = 0;
if (t)
{
d = 1;
e = t;
}
else d = 0, e = 0;
return g(e,d);
}
/* This testcase should be reduced to e = t; d = t != 0; in phiopt1
but currently is not as PHI-OPT does not reduce the t PHI as we have
two phis. Note this is fixed with
http://gcc.gnu.org/ml/gcc-patches/2012-01/msg01195.html . */
/* { dg-final { scan-tree-dump-not "if" "phiopt1" { xfail *-*-* } } } */
/* { dg-final { scan-tree-dump "g .t_\[0-9\]*.D.," "optimized" } } */
/* { dg-final { scan-tree-dump-not "PHI" "optimized" } } */
/* { dg-final { cleanup-tree-dump "phiopt1" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
/* { dg-do compile } */
/* { dg-options "-O -fdump-tree-optimized" } */
int g(int,int);
int f(int t, int c)
{
int d = 0;
int e = 0;
if (t)
{
d = c+1;
e = t;
}
else d = 0, e = 0;
return g(e,d);
}
/* The value e should have been replaced with t and there should be only one PHI. */
/* { dg-final { scan-tree-dump "g .t_\[0-9\]*.D.," "optimized" } } */
/* { dg-final { scan-tree-dump-times "PHI" 1 "optimized" } } */
/* { dg-final { cleanup-tree-dump "optimized" } } */
...@@ -36,13 +36,14 @@ along with GCC; see the file COPYING3. If not see ...@@ -36,13 +36,14 @@ along with GCC; see the file COPYING3. If not see
#include "domwalk.h" #include "domwalk.h"
#include "cfgloop.h" #include "cfgloop.h"
#include "tree-data-ref.h" #include "tree-data-ref.h"
#include "tree-pretty-print.h"
static unsigned int tree_ssa_phiopt (void); static unsigned int tree_ssa_phiopt (void);
static unsigned int tree_ssa_phiopt_worker (bool); static unsigned int tree_ssa_phiopt_worker (bool);
static bool conditional_replacement (basic_block, basic_block, static bool conditional_replacement (basic_block, basic_block,
edge, edge, gimple, tree, tree); edge, edge, gimple, tree, tree);
static bool value_replacement (basic_block, basic_block, static int value_replacement (basic_block, basic_block,
edge, edge, gimple, tree, tree); edge, edge, gimple, tree, tree);
static bool minmax_replacement (basic_block, basic_block, static bool minmax_replacement (basic_block, basic_block,
edge, edge, gimple, tree, tree); edge, edge, gimple, tree, tree);
static bool abs_replacement (basic_block, basic_block, static bool abs_replacement (basic_block, basic_block,
...@@ -314,7 +315,24 @@ tree_ssa_phiopt_worker (bool do_store_elim) ...@@ -314,7 +315,24 @@ tree_ssa_phiopt_worker (bool do_store_elim)
{ {
gimple_seq phis = phi_nodes (bb2); gimple_seq phis = phi_nodes (bb2);
gimple_stmt_iterator gsi; gimple_stmt_iterator gsi;
bool candorest = true;
/* Value replacement can work with more than one PHI
so try that first. */
for (gsi = gsi_start (phis); !gsi_end_p (gsi); gsi_next (&gsi))
{
phi = gsi_stmt (gsi);
arg0 = gimple_phi_arg_def (phi, e1->dest_idx);
arg1 = gimple_phi_arg_def (phi, e2->dest_idx);
if (value_replacement (bb, bb1, e1, e2, phi, arg0, arg1) == 2)
{
candorest = false;
cfgchanged = true;
break;
}
}
if (!candorest)
continue;
/* Check to make sure that there is only one non-virtual PHI node. /* Check to make sure that there is only one non-virtual PHI node.
TODO: we could do it with more than one iff the other PHI nodes TODO: we could do it with more than one iff the other PHI nodes
have the same elements for these two edges. */ have the same elements for these two edges. */
...@@ -343,8 +361,6 @@ tree_ssa_phiopt_worker (bool do_store_elim) ...@@ -343,8 +361,6 @@ tree_ssa_phiopt_worker (bool do_store_elim)
/* Do the replacement of conditional if it can be done. */ /* Do the replacement of conditional if it can be done. */
if (conditional_replacement (bb, bb1, e1, e2, phi, arg0, arg1)) if (conditional_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
cfgchanged = true; cfgchanged = true;
else if (value_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
cfgchanged = true;
else if (abs_replacement (bb, bb1, e1, e2, phi, arg0, arg1)) else if (abs_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
cfgchanged = true; cfgchanged = true;
else if (minmax_replacement (bb, bb1, e1, e2, phi, arg0, arg1)) else if (minmax_replacement (bb, bb1, e1, e2, phi, arg0, arg1))
...@@ -624,12 +640,12 @@ jump_function_from_stmt (tree *arg, gimple stmt) ...@@ -624,12 +640,12 @@ jump_function_from_stmt (tree *arg, gimple stmt)
} }
/* The function value_replacement does the main work of doing the value /* The function value_replacement does the main work of doing the value
replacement. Return true if the replacement is done. Otherwise return replacement. Return non-zero if the replacement is done. Otherwise return
false. 0. If we remove the middle basic block, return 2.
BB is the basic block where the replacement is going to be done on. ARG0 BB is the basic block where the replacement is going to be done on. ARG0
is argument 0 from the PHI. Likewise for ARG1. */ is argument 0 from the PHI. Likewise for ARG1. */
static bool static int
value_replacement (basic_block cond_bb, basic_block middle_bb, value_replacement (basic_block cond_bb, basic_block middle_bb,
edge e0, edge e1, gimple phi, edge e0, edge e1, gimple phi,
tree arg0, tree arg1) tree arg0, tree arg1)
...@@ -638,37 +654,36 @@ value_replacement (basic_block cond_bb, basic_block middle_bb, ...@@ -638,37 +654,36 @@ value_replacement (basic_block cond_bb, basic_block middle_bb,
gimple cond; gimple cond;
edge true_edge, false_edge; edge true_edge, false_edge;
enum tree_code code; enum tree_code code;
bool emtpy_or_with_defined_p = true;
/* If the type says honor signed zeros we cannot do this /* If the type says honor signed zeros we cannot do this
optimization. */ optimization. */
if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1)))) if (HONOR_SIGNED_ZEROS (TYPE_MODE (TREE_TYPE (arg1))))
return false; return 0;
/* Allow a single statement in MIDDLE_BB that defines one of the PHI /* If there is a statement in MIDDLE_BB that defines one of the PHI
arguments. */ arguments, then adjust arg0 or arg1. */
gsi = gsi_after_labels (middle_bb); gsi = gsi_after_labels (middle_bb);
if (!gsi_end_p (gsi)) if (!gsi_end_p (gsi) && is_gimple_debug (gsi_stmt (gsi)))
gsi_next_nondebug (&gsi);
while (!gsi_end_p (gsi))
{ {
if (is_gimple_debug (gsi_stmt (gsi))) gimple stmt = gsi_stmt (gsi);
gsi_next_nondebug (&gsi); tree lhs;
if (!gsi_end_p (gsi)) gsi_next_nondebug (&gsi);
if (!is_gimple_assign (stmt))
{ {
gimple stmt = gsi_stmt (gsi); emtpy_or_with_defined_p = false;
tree lhs; continue;
gsi_next_nondebug (&gsi);
if (!gsi_end_p (gsi))
return false;
if (!is_gimple_assign (stmt))
return false;
/* Now try to adjust arg0 or arg1 according to the computation
in the single statement. */
lhs = gimple_assign_lhs (stmt);
if (!((lhs == arg0
&& jump_function_from_stmt (&arg0, stmt))
|| (lhs == arg1
&& jump_function_from_stmt (&arg1, stmt))))
return false;
} }
/* Now try to adjust arg0 or arg1 according to the computation
in the statement. */
lhs = gimple_assign_lhs (stmt);
if (!(lhs == arg0
&& jump_function_from_stmt (&arg0, stmt))
|| (lhs == arg1
&& jump_function_from_stmt (&arg1, stmt)))
emtpy_or_with_defined_p = false;
} }
cond = last_stmt (cond_bb); cond = last_stmt (cond_bb);
...@@ -676,7 +691,7 @@ value_replacement (basic_block cond_bb, basic_block middle_bb, ...@@ -676,7 +691,7 @@ value_replacement (basic_block cond_bb, basic_block middle_bb,
/* This transformation is only valid for equality comparisons. */ /* This transformation is only valid for equality comparisons. */
if (code != NE_EXPR && code != EQ_EXPR) if (code != NE_EXPR && code != EQ_EXPR)
return false; return 0;
/* We need to know which is the true edge and which is the false /* We need to know which is the true edge and which is the false
edge so that we know if have abs or negative abs. */ edge so that we know if have abs or negative abs. */
...@@ -720,12 +735,34 @@ value_replacement (basic_block cond_bb, basic_block middle_bb, ...@@ -720,12 +735,34 @@ value_replacement (basic_block cond_bb, basic_block middle_bb,
else else
arg = arg1; arg = arg1;
replace_phi_edge_with_variable (cond_bb, e1, phi, arg); /* If the middle basic block was empty or is defining the
PHI arguments and this is a singleton phi then we can remove
the middle basic block. */
if (emtpy_or_with_defined_p
&& gimple_seq_singleton_p (phi_nodes (gimple_bb (phi))))
{
replace_phi_edge_with_variable (cond_bb, e1, phi, arg);
/* Note that we optimized this PHI. */
return 2;
}
else
{
/* Replace the PHI arguments with arg. */
SET_PHI_ARG_DEF (phi, e0->dest_idx, arg);
SET_PHI_ARG_DEF (phi, e1->dest_idx, arg);
if (dump_file && (dump_flags & TDF_DETAILS))
{
fprintf (dump_file, "PHI ");
print_generic_expr (dump_file, gimple_phi_result (phi), 0);
fprintf (dump_file, " reduced for COND_EXPR in block %d to ", cond_bb->index);
print_generic_expr (dump_file, arg, 0);
fprintf (dump_file, ".\n");
}
return 1;
}
/* Note that we optimized this PHI. */
return true;
} }
return false; return 0;
} }
/* The function minmax_replacement does the main work of doing the minmax /* The function minmax_replacement does the main work of doing the minmax
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment