re PR tree-optimization/70754 (ICE during predictive commoning)
PR tree-optimization/70754 * tree-predcom.c (stmt_combining_refs): New parameter INSERT_BEFORE. (reassociate_to_the_same_stmt): New parameter INSERT_BEFORE. Insert combined stmt before it if not NULL. (combine_chains): Process refs reversely and compute dominance point for root ref. gcc/testsuite PR tree-optimization/70754 * gfortran.dg/pr70754.f90: New test. From-SVN: r244815
This commit is contained in:
parent
61ad58f3aa
commit
8539a302cd
@ -1,3 +1,12 @@
|
||||
2017-01-23 Bin Cheng <bin.cheng@arm.com>
|
||||
|
||||
PR tree-optimization/70754
|
||||
* tree-predcom.c (stmt_combining_refs): New parameter INSERT_BEFORE.
|
||||
(reassociate_to_the_same_stmt): New parameter INSERT_BEFORE. Insert
|
||||
combined stmt before it if not NULL.
|
||||
(combine_chains): Process refs reversely and compute dominance point
|
||||
for root ref.
|
||||
|
||||
2017-01-23 Martin Liska <mliska@suse.cz>
|
||||
|
||||
PR tree-optimization/79196
|
||||
|
@ -1,3 +1,8 @@
|
||||
2017-01-23 Bin Cheng <bin.cheng@arm.com>
|
||||
|
||||
PR tree-optimization/70754
|
||||
* gfortran.dg/pr70754.f90: New test.
|
||||
|
||||
2017-01-23 Martin Liska <mliska@suse.cz>
|
||||
|
||||
PR tree-optimization/79196
|
||||
|
35
gcc/testsuite/gfortran.dg/pr70754.f90
Normal file
35
gcc/testsuite/gfortran.dg/pr70754.f90
Normal file
@ -0,0 +1,35 @@
|
||||
! { dg-do compile }
|
||||
! { dg-options "-Ofast" }
|
||||
module m
|
||||
implicit none
|
||||
private
|
||||
save
|
||||
|
||||
integer, parameter, public :: &
|
||||
ii4 = selected_int_kind(6), &
|
||||
rr8 = selected_real_kind(13)
|
||||
|
||||
integer (ii4), dimension(40,40,199), public :: xyz
|
||||
public :: foo
|
||||
contains
|
||||
subroutine foo(a)
|
||||
real (rr8), dimension(40,40), intent(out) :: a
|
||||
real (rr8), dimension(40,40) :: b
|
||||
integer (ii4), dimension(40,40) :: c
|
||||
integer i, j
|
||||
|
||||
do i=1,20
|
||||
b(i,j) = 123 * a(i,j) + 34 * a(i,j+1) &
|
||||
+ 34 * a(i,j-1) + a(i+1,j+1) &
|
||||
+ a(i+1,j-1) + a(i-1,j+1) &
|
||||
+ a(i-1,j-1)
|
||||
c(i,j) = 123
|
||||
end do
|
||||
|
||||
where ((xyz(:,:,2) /= 0) .and. (c /= 0))
|
||||
a = b/real(c)
|
||||
elsewhere
|
||||
a = 456
|
||||
endwhere
|
||||
end subroutine foo
|
||||
end module m
|
@ -2164,10 +2164,11 @@ remove_name_from_operation (gimple *stmt, tree op)
|
||||
}
|
||||
|
||||
/* Reassociates the expression in that NAME1 and NAME2 are used so that they
|
||||
are combined in a single statement, and returns this statement. */
|
||||
are combined in a single statement, and returns this statement. Note the
|
||||
statement is inserted before INSERT_BEFORE if it's not NULL. */
|
||||
|
||||
static gimple *
|
||||
reassociate_to_the_same_stmt (tree name1, tree name2)
|
||||
reassociate_to_the_same_stmt (tree name1, tree name2, gimple *insert_before)
|
||||
{
|
||||
gimple *stmt1, *stmt2, *root1, *root2, *s1, *s2;
|
||||
gassign *new_stmt, *tmp_stmt;
|
||||
@ -2224,6 +2225,12 @@ reassociate_to_the_same_stmt (tree name1, tree name2)
|
||||
var = create_tmp_reg (type, "predreastmp");
|
||||
new_name = make_ssa_name (var);
|
||||
new_stmt = gimple_build_assign (new_name, code, name1, name2);
|
||||
if (insert_before && stmt_dominates_stmt_p (insert_before, s1))
|
||||
bsi = gsi_for_stmt (insert_before);
|
||||
else
|
||||
bsi = gsi_for_stmt (s1);
|
||||
|
||||
gsi_insert_before (&bsi, new_stmt, GSI_SAME_STMT);
|
||||
|
||||
var = create_tmp_reg (type, "predreastmp");
|
||||
tmp_name = make_ssa_name (var);
|
||||
@ -2240,7 +2247,6 @@ reassociate_to_the_same_stmt (tree name1, tree name2)
|
||||
s1 = gsi_stmt (bsi);
|
||||
update_stmt (s1);
|
||||
|
||||
gsi_insert_before (&bsi, new_stmt, GSI_SAME_STMT);
|
||||
gsi_insert_before (&bsi, tmp_stmt, GSI_SAME_STMT);
|
||||
|
||||
return new_stmt;
|
||||
@ -2249,10 +2255,11 @@ reassociate_to_the_same_stmt (tree name1, tree name2)
|
||||
/* Returns the statement that combines references R1 and R2. In case R1
|
||||
and R2 are not used in the same statement, but they are used with an
|
||||
associative and commutative operation in the same expression, reassociate
|
||||
the expression so that they are used in the same statement. */
|
||||
the expression so that they are used in the same statement. The combined
|
||||
statement is inserted before INSERT_BEFORE if it's not NULL. */
|
||||
|
||||
static gimple *
|
||||
stmt_combining_refs (dref r1, dref r2)
|
||||
stmt_combining_refs (dref r1, dref r2, gimple *insert_before)
|
||||
{
|
||||
gimple *stmt1, *stmt2;
|
||||
tree name1 = name_for_ref (r1);
|
||||
@ -2263,7 +2270,7 @@ stmt_combining_refs (dref r1, dref r2)
|
||||
if (stmt1 == stmt2)
|
||||
return stmt1;
|
||||
|
||||
return reassociate_to_the_same_stmt (name1, name2);
|
||||
return reassociate_to_the_same_stmt (name1, name2, insert_before);
|
||||
}
|
||||
|
||||
/* Tries to combine chains CH1 and CH2 together. If this succeeds, the
|
||||
@ -2309,14 +2316,42 @@ combine_chains (chain_p ch1, chain_p ch2)
|
||||
new_chain->rslt_type = rslt_type;
|
||||
new_chain->length = ch1->length;
|
||||
|
||||
for (i = 0; (ch1->refs.iterate (i, &r1)
|
||||
&& ch2->refs.iterate (i, &r2)); i++)
|
||||
gimple *insert = NULL;
|
||||
auto_vec<dref> tmp_refs;
|
||||
gcc_assert (ch1->refs.length () == ch2->refs.length ());
|
||||
/* Process in reverse order so dominance point is ready when it comes
|
||||
to the root ref. */
|
||||
for (i = ch1->refs.length (); i > 0; i--)
|
||||
{
|
||||
r1 = ch1->refs[i - 1];
|
||||
r2 = ch2->refs[i - 1];
|
||||
nw = XCNEW (struct dref_d);
|
||||
nw->stmt = stmt_combining_refs (r1, r2);
|
||||
nw->distance = r1->distance;
|
||||
nw->stmt = stmt_combining_refs (r1, r2, i == 1 ? insert : NULL);
|
||||
|
||||
new_chain->refs.safe_push (nw);
|
||||
/* Record dominance point where root combined stmt should be inserted
|
||||
for chains with 0 length. Though all root refs dominate following
|
||||
refs, it's possible the combined stmt doesn't. See PR70754. */
|
||||
if (ch1->length == 0
|
||||
&& (insert == NULL || stmt_dominates_stmt_p (nw->stmt, insert)))
|
||||
insert = nw->stmt;
|
||||
|
||||
tmp_refs.safe_push (nw);
|
||||
}
|
||||
|
||||
/* Restore the order for new chain's refs. */
|
||||
for (i = tmp_refs.length (); i > 0; i--)
|
||||
new_chain->refs.safe_push (tmp_refs[i - 1]);
|
||||
|
||||
ch1->combined = true;
|
||||
ch2->combined = true;
|
||||
|
||||
/* For chains with 0 length, has_max_use_after must be true since root
|
||||
combined stmt must dominates others. */
|
||||
if (new_chain->length == 0)
|
||||
{
|
||||
new_chain->has_max_use_after = true;
|
||||
return new_chain;
|
||||
}
|
||||
|
||||
new_chain->has_max_use_after = false;
|
||||
@ -2331,8 +2366,6 @@ combine_chains (chain_p ch1, chain_p ch2)
|
||||
}
|
||||
}
|
||||
|
||||
ch1->combined = true;
|
||||
ch2->combined = true;
|
||||
return new_chain;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user