Loop split on semi-invariant conditional statement

2019-11-07  Feng Xue <fxue@os.amperecomputing.com>

        PR tree-optimization/89134
        * doc/invoke.texi (min-loop-cond-split-prob): Document new --params.
        * params.def: Add min-loop-cond-split-prob.
        * tree-ssa-loop-split.c (split_loop): Remove niter parameter, move some
        outside checks on loop into the function.
        (split_info): New class.
        (find_vdef_in_loop, get_control_equiv_head_block): New functions.
        (find_control_dep_blocks, vuse_semi_invariant_p): Likewise.
        (ssa_semi_invariant_p, loop_iter_phi_semi_invariant_p): Likewise.
        (control_dep_semi_invariant_p, stmt_semi_invariant_p_1): Likewise.
        (stmt_semi_invariant_p, branch_removable_p): Likewise.
        (get_cond_invariant_branch, compute_added_num_insns): Likewise.
        (get_cond_branch_to_split_loop, do_split_loop_on_cond): Likewise.
        (split_loop_on_cond): Likewise.
        (tree_ssa_split_loops): Add loop split on conditional statement.

2019-11-07  Feng Xue  <fxue@os.amperecomputing.com>

        PR tree-optimization/89134
        * gcc.dg/tree-ssa/loop-cond-split-1.c: New test.
        * g++.dg/tree-ssa/loop-cond-split-1.C: New test.
        * gcc.dg/torture/pr55107.c: Add -fno-split-loops.

From-SVN: r277923
This commit is contained in:
Feng Xue 2019-11-07 15:43:01 +00:00 committed by Feng Xue
parent 163f23d21e
commit 095f78c621
8 changed files with 1162 additions and 28 deletions

View File

@ -1,3 +1,21 @@
2019-11-07 Feng Xue <fxue@os.amperecomputing.com>
PR tree-optimization/89134
* doc/invoke.texi (min-loop-cond-split-prob): Document new --params.
* params.def: Add min-loop-cond-split-prob.
* tree-ssa-loop-split.c (split_loop): Remove niter parameter, move some
outside checks on loop into the function.
(split_info): New class.
(find_vdef_in_loop, get_control_equiv_head_block): New functions.
(find_control_dep_blocks, vuse_semi_invariant_p): Likewise.
(ssa_semi_invariant_p, loop_iter_phi_semi_invariant_p): Likewise.
(control_dep_semi_invariant_p, stmt_semi_invariant_p_1): Likewise.
(stmt_semi_invariant_p, branch_removable_p): Likewise.
(get_cond_invariant_branch, compute_added_num_insns): Likewise.
(get_cond_branch_to_split_loop, do_split_loop_on_cond): Likewise.
(split_loop_on_cond): Likewise.
(tree_ssa_split_loops): Add loop split on conditional statement.
2019-11-07 Andreas Krebbel <krebbel@linux.ibm.com>
* config/s390/s390.md ("*cstorecc<mode>_z13"): New insn_and_split

View File

@ -11517,6 +11517,11 @@ The maximum number of branches unswitched in a single loop.
@item lim-expensive
The minimum cost of an expensive expression in the loop invariant motion.
@item min-loop-cond-split-prob
When FDO profile information is available, @option{min-loop-cond-split-prob}
specifies minimum threshold for probability of semi-invariant condition
statement to trigger loop split.
@item iv-consider-all-candidates-bound
Bound on number of candidates for induction variables, below which
all candidates are considered for each use in induction variable

View File

@ -415,6 +415,12 @@ DEFPARAM(PARAM_MAX_UNSWITCH_LEVEL,
"The maximum number of unswitchings in a single loop.",
3, 0, 0)
DEFPARAM(PARAM_MIN_LOOP_COND_SPLIT_PROB,
"min-loop-cond-split-prob",
"The minimum threshold for probability of semi-invariant condition "
"statement to trigger loop split.",
30, 0, 100)
/* The maximum number of insns in loop header duplicated by the copy loop
headers pass. */
DEFPARAM(PARAM_MAX_LOOP_HEADER_INSNS,

View File

@ -1,3 +1,10 @@
2019-11-07 Feng Xue <fxue@os.amperecomputing.com>
PR tree-optimization/89134
* gcc.dg/tree-ssa/loop-cond-split-1.c: New test.
* g++.dg/tree-ssa/loop-cond-split-1.C: New test.
* gcc.dg/torture/pr55107.c: Add -fno-split-loops.
2019-11-07 Andreas Krebbel <krebbel@linux.ibm.com>
* gcc.target/s390/addsub-signed-overflow-1.c: Expect lochi

View File

@ -0,0 +1,33 @@
/* { dg-do compile } */
/* { dg-options "-O3 -fdump-tree-lsplit-details" } */
#include <string>
#include <map>
using namespace std;
class A
{
public:
bool empty;
void set (string s);
};
class B
{
map<int, string> m;
void f ();
};
extern A *ga;
void B::f ()
{
for (map<int, string>::iterator iter = m.begin (); iter != m.end (); ++iter)
{
if (ga->empty)
ga->set (iter->second);
}
}
/* { dg-final { scan-tree-dump-times "loop split on semi-invariant condition at false branch" 1 "lsplit" } } */

View File

@ -1,4 +1,5 @@
/* { dg-do compile } */
/* { dg-additional-options "-fno-split-loops" } */
typedef unsigned short uint16_t;

View File

@ -0,0 +1,97 @@
/* { dg-do compile } */
/* { dg-options "-O3 -fdump-tree-lsplit-details" } */
extern const int step;
int ga, gb;
__attribute__((pure)) __attribute__((noinline)) int inc (int i)
{
return i + step;
}
extern int do_something (void);
void test1 (int n)
{
int i;
for (i = 0; i < n; i = inc (i))
{
if (ga)
ga = do_something ();
}
}
void test2 (int n, int p)
{
int i;
int v;
for (i = 0; i < n ; i = inc (i))
{
if (ga)
{
v = inc (2);
gb += 1;
}
else
{
v = p * p;
gb *= 3;
}
if (v < 10)
ga = do_something ();
}
}
void test3 (int n, int p)
{
int i;
int c = p + 1;
int v;
for (i = 0; i < n ; i = inc (i))
{
if (c)
{
v = inc (c);
gb += 1;
}
else
{
v = p * p;
gb *= 3;
}
if (v < 10)
c = do_something ();
}
}
void test4 (int n, int p)
{
int i;
int v;
for (i = 0; i < n ; i = inc (i))
{
if (ga)
{
v = inc (2);
if (gb > 16)
v = inc (5);
}
else
{
v = p * p;
gb += 2;
}
if (v < 10)
ga = do_something ();
}
}
/* { dg-final { scan-tree-dump-times "loop split on semi-invariant condition at false branch" 3 "lsplit" } } */

File diff suppressed because it is too large Load Diff