[GCC8,25/33] New loop constraint flags

Submitted by Bin Cheng on April 18, 2017, 10:51 a.m.

Details

Message ID VI1PR0802MB2176EA1E216A012420FE48C6E7190@VI1PR0802MB2176.eurprd08.prod.outlook.com
State New
Headers show

Commit Message

Bin Cheng April 18, 2017, 10:51 a.m.
Hi,
This patch adds new loop constraint flags marking prologue, epilogue and versioned loops generated
by vectorizer, unroller and versioning.  These flags will be used in IVOPTs in order to differentiate
possible hot innermost loop from others.  I also plan to use them to avoid unnecessary cunroll on
such loops.
Is it OK?

Thanks,
bin
2017-04-11  Bin Cheng  <bin.cheng@arm.com>

	* cfgloop.h (LOOP_C_PROLOG, LOOP_C_EPILOG, LOOP_C_VERSION): New.
	* tree-ssa-loop-manip.c (tree_transform_and_unroll_loop): Set
	LOOP_C_EPILOG for unrolled epilogue loop.
	(vect_do_peeling): Set LOOP_C_PROLOG and LOOP_C_EPILOG for peeled
	loops.
	(vect_loop_versioning): Set LOOP_C_VERSION for versioned loop.
From 432006f72b95826eadb4c972a55b1aeb89c9998b Mon Sep 17 00:00:00 2001
From: Bin Cheng <binche01@e108451-lin.cambridge.arm.com>
Date: Thu, 30 Mar 2017 10:56:19 +0100
Subject: [PATCH 25/33] new-loop-constraint-flags-20170310.txt

---
 gcc/cfgloop.h              | 6 ++++++
 gcc/tree-ssa-loop-manip.c  | 1 +
 gcc/tree-vect-loop-manip.c | 3 +++
 3 files changed, 10 insertions(+)

Comments

Richard Guenther April 26, 2017, 1:27 p.m.
On Tue, Apr 18, 2017 at 12:51 PM, Bin Cheng <Bin.Cheng@arm.com> wrote:
> Hi,
> This patch adds new loop constraint flags marking prologue, epilogue and versioned loops generated
> by vectorizer, unroller and versioning.  These flags will be used in IVOPTs in order to differentiate
> possible hot innermost loop from others.  I also plan to use them to avoid unnecessary cunroll on
> such loops.
> Is it OK?

Hmm, it doesn't really match "constraints".

I'd rather somehow track the "original" loop it was versioned / copied
from plus either a
"kind" (epilogue, prologue, version) or determine this from dominance
relationship between
the copy and the original loop.

Thus,

struct loop {
 ...
 /* If not zero the loop number this loop was copied from.  */
 unsigned clone_of;

would that help?  With knowing loop relation we can also more
aggressively version
and eventually later collapse the two versions again if we can still
identify them and
they are still reasonably similar.

Richard.

>
> Thanks,
> bin
> 2017-04-11  Bin Cheng  <bin.cheng@arm.com>
>
>         * cfgloop.h (LOOP_C_PROLOG, LOOP_C_EPILOG, LOOP_C_VERSION): New.
>         * tree-ssa-loop-manip.c (tree_transform_and_unroll_loop): Set
>         LOOP_C_EPILOG for unrolled epilogue loop.
>         (vect_do_peeling): Set LOOP_C_PROLOG and LOOP_C_EPILOG for peeled
>         loops.
>         (vect_loop_versioning): Set LOOP_C_VERSION for versioned loop.
Bin.Cheng April 26, 2017, 2:01 p.m.
On Wed, Apr 26, 2017 at 2:27 PM, Richard Biener
<richard.guenther@gmail.com> wrote:
> On Tue, Apr 18, 2017 at 12:51 PM, Bin Cheng <Bin.Cheng@arm.com> wrote:
>> Hi,
>> This patch adds new loop constraint flags marking prologue, epilogue and versioned loops generated
>> by vectorizer, unroller and versioning.  These flags will be used in IVOPTs in order to differentiate
>> possible hot innermost loop from others.  I also plan to use them to avoid unnecessary cunroll on
>> such loops.
>> Is it OK?
>
> Hmm, it doesn't really match "constraints".
>
> I'd rather somehow track the "original" loop it was versioned / copied
> from plus either a
> "kind" (epilogue, prologue, version) or determine this from dominance
> relationship between
> the copy and the original loop.
Or we generalize "constraints flags", saying to introduce general
bit-wise flags for loop structure.  Among these flags, one kind is
constraint flags, the rest are general flags.  We could also change
boolean fields into such flags?
I do have following patches relying on this to avoid complete unroll
for prologue/epilogue loops.
>
> Thus,
>
> struct loop {
>  ...
>  /* If not zero the loop number this loop was copied from.  */
>  unsigned clone_of;
In this case, we need to track between different loops, which looks
like a burden.  For example, we need to make sure loop number won't be
reused.  Even more complicated, considering in extreme case that the
original loop could be removed.

>
> would that help?  With knowing loop relation we can also more
> aggressively version
> and eventually later collapse the two versions again if we can still
> identify them and
> they are still reasonably similar.
>
> Richard.
>
>>
>> Thanks,
>> bin
>> 2017-04-11  Bin Cheng  <bin.cheng@arm.com>
>>
>>         * cfgloop.h (LOOP_C_PROLOG, LOOP_C_EPILOG, LOOP_C_VERSION): New.
>>         * tree-ssa-loop-manip.c (tree_transform_and_unroll_loop): Set
>>         LOOP_C_EPILOG for unrolled epilogue loop.
>>         (vect_do_peeling): Set LOOP_C_PROLOG and LOOP_C_EPILOG for peeled
>>         loops.
>>         (vect_loop_versioning): Set LOOP_C_VERSION for versioned loop.

Patch hide | download patch | download mbox

diff --git a/gcc/cfgloop.h b/gcc/cfgloop.h
index a8bec1d..90be4cc 100644
--- a/gcc/cfgloop.h
+++ b/gcc/cfgloop.h
@@ -248,6 +248,12 @@  struct GTY ((chain_next ("%h.next"))) loop {
 #define LOOP_C_INFINITE		(1 << 0)
 /* Set if the loop is known to be finite without any assumptions.  */
 #define LOOP_C_FINITE		(1 << 1)
+/* Set if the loop is peeled prologue loop.  */
+#define LOOP_C_PROLOG		(1 << 2)
+/* Set if the loop is peeled epilogue loop.  */
+#define LOOP_C_EPILOG		(1 << 3)
+/* Set if the loop is versioned loop.  */
+#define LOOP_C_VERSION		(1 << 4)
 
 /* Set C to the LOOP constraint.  */
 static inline void
diff --git a/gcc/tree-ssa-loop-manip.c b/gcc/tree-ssa-loop-manip.c
index 22c832a..0559904 100644
--- a/gcc/tree-ssa-loop-manip.c
+++ b/gcc/tree-ssa-loop-manip.c
@@ -1233,6 +1233,7 @@  tree_transform_and_unroll_loop (struct loop *loop, unsigned factor,
 			   scale_unrolled, scale_rest, true);
   gcc_assert (new_loop != NULL);
   update_ssa (TODO_update_ssa);
+  loop_constraint_set (new_loop, LOOP_C_EPILOG);
 
   /* Prepare the cfg and update the phi nodes.  Move the loop exit to the
      loop latch (and make its condition dummy, for the moment).  */
diff --git a/gcc/tree-vect-loop-manip.c b/gcc/tree-vect-loop-manip.c
index f48336b..faeaa6d 100644
--- a/gcc/tree-vect-loop-manip.c
+++ b/gcc/tree-vect-loop-manip.c
@@ -1735,6 +1735,7 @@  vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1,
 	  gcc_unreachable ();
 	}
       slpeel_update_phi_nodes_for_loops (loop_vinfo, prolog, loop, true);
+      loop_constraint_set (prolog, LOOP_C_PROLOG);
       first_loop = prolog;
       reset_original_copy_tables ();
 
@@ -1799,6 +1800,7 @@  vect_do_peeling (loop_vec_info loop_vinfo, tree niters, tree nitersm1,
 	  gcc_unreachable ();
 	}
       slpeel_update_phi_nodes_for_loops (loop_vinfo, loop, epilog, false);
+      loop_constraint_set (epilog, LOOP_C_EPILOG);
 
       /* Scalar version loop may be preferred.  In this case, add guard
 	 and skip to epilog.  Note this only happens when the number of
@@ -2400,6 +2402,7 @@  vect_loop_versioning (loop_vec_info loop_vinfo,
 			  prob, REG_BR_PROB_BASE - prob,
 			  prob, REG_BR_PROB_BASE - prob, true);
 
+  loop_constraint_set (nloop, LOOP_C_VERSION);
   if (version_niter)
     {
       /* The versioned loop could be infinite, we need to clear existing