https://gcc.gnu.org/g:445312f69adc4bd67476346ff00f6f276ffcc814

commit r17-5008-g445312f69adc4bd67476346ff00f6f276ffcc814
Author: Kugan Vivekanandarajah <[email protected]>
Date:   Fri Oct 9 10:57:32 2026 +1100

    [PATCH] Assign hierarchical copyids automatically on CFG duplication.
    
    Assign hierarchical copyids on CFG and statement duplication for AutoFDO.
    Key each duplicated region from the first block/stmt with a location, and
    drop manual discriminator updates that copy_bbs now covers.
    This lets sample profiles tell copies of the same source line apart.
    
    Regression tested on aarch64-linux-gnu with no new regressions
    
    gcc/ChangeLog:
    
            * hierarchical_discriminator.cc (assign_discriminators_to_bb):
            Handle RTL.
            * cfghooks.h (struct copy_bb_data): Add skip_copyid.
            * cfghooks.cc (copyid_location_from_bb): New.
            (duplicate_block): Assign a fresh copyid unless suppressed.
            (copy_bbs): Assign one shared copyid for the duplicated region.
            * cfgloopmanip.h (DLTHE_RECORD_HIERARCHICAL_DISCRIMINATOR): Remove.
            * cfgloopmanip.cc (duplicate_loop_body_to_header_edge): Remove
            manual hierarchical discriminator assignment.
            * gimple-loop-versioning.cc (loop_versioning::version_loop): Rely
            on copy_bbs for copyids.
            * tree-vect-loop-manip.cc (vect_do_peeling, vect_loop_versioning):
            Likewise.
            * tree-ssa-loop-ivcanon.cc (try_unroll_loop_completely): Drop
            DLTHE_RECORD_HIERARCHICAL_DISCRIMINATOR.
            * tree-vect-stmts.cc (hoist_defs_of_uses): Assign copyid to
            gimple_copy clones.
            * value-prof.cc (gimple_ic, gimple_stringop_fixed_value): Likewise.
    
    gcc/testsuite/ChangeLog:
    
            * gcc.dg/hierarchical-discriminator-ch.c: New test.
            * gcc.dg/hierarchical-discriminator-rtl-unroll.c: Likewise.
            * gcc.dg/hierarchical-discriminator-tracer.c: Likewise.
            * gcc.dg/hierarchical-discriminator-unroll-jam.c: Likewise.
            * gcc.dg/hierarchical-discriminator-unswitch.c: Likewise.
            * gcc.dg/hierarchical-discriminator-loop-version.c: Require a
            non-zero discriminator in the assembler scan.

Diff:
---
 gcc/cfghooks.cc                                    | 49 ++++++++++++++
 gcc/cfghooks.h                                     |  5 +-
 gcc/cfgloopmanip.cc                                | 77 ----------------------
 gcc/cfgloopmanip.h                                 |  4 --
 gcc/gimple-loop-versioning.cc                      | 20 ------
 gcc/hierarchical_discriminator.cc                  | 14 ++++
 .../gcc.dg/hierarchical-discriminator-ch.c         | 24 +++++++
 .../hierarchical-discriminator-loop-version.c      |  2 +-
 .../gcc.dg/hierarchical-discriminator-rtl-unroll.c | 21 ++++++
 .../gcc.dg/hierarchical-discriminator-tracer.c     | 24 +++++++
 .../gcc.dg/hierarchical-discriminator-unroll-jam.c | 19 ++++++
 .../gcc.dg/hierarchical-discriminator-unswitch.c   | 22 +++++++
 gcc/tree-ssa-loop-ivcanon.cc                       |  6 +-
 gcc/tree-vect-loop-manip.cc                        | 38 -----------
 gcc/tree-vect-stmts.cc                             |  3 +
 gcc/value-prof.cc                                  |  5 ++
 16 files changed, 188 insertions(+), 145 deletions(-)

diff --git a/gcc/cfghooks.cc b/gcc/cfghooks.cc
index 85311a282846..d0a24c031916 100644
--- a/gcc/cfghooks.cc
+++ b/gcc/cfghooks.cc
@@ -32,11 +32,35 @@ along with GCC; see the file COPYING3.  If not see
 #include "cfganal.h"
 #include "tree.h"
 #include "tree-ssa.h"
+#include "tree-cfg.h"
 #include "cfgloop.h"
 #include "sreal.h"
 #include "profile.h"
 #include "diagnostics/sarif-sink.h"
 #include "custom-sarif-properties/cfg.h"
+#include "hierarchical_discriminator.h"
+
+/* Location used to allocate a copyid for a duplicated BB.  */
+
+static location_t
+copyid_location_from_bb (basic_block bb)
+{
+  if (!bb)
+    return UNKNOWN_LOCATION;
+
+  if (current_ir_type () == IR_GIMPLE)
+    {
+      gimple *last = last_nondebug_stmt (bb);
+      return last ? gimple_location (last) : UNKNOWN_LOCATION;
+    }
+
+  rtx_insn *insn;
+  FOR_BB_INSNS_REVERSE (bb, insn)
+    if (INSN_P (insn) && INSN_HAS_LOCATION (insn))
+      return INSN_LOCATION (insn);
+
+  return UNKNOWN_LOCATION;
+}
 
 /* Disable warnings about missing quoting in GCC diagnostics.  */
 #if __GNUC__ >= 10
@@ -1249,6 +1273,15 @@ duplicate_block (basic_block bb, edge e, basic_block 
after, copy_bb_data *id)
        }
     }
 
+  /* Skip if copy_bbs assigns one copyid for the whole region.  */
+  if (!id || !id->skip_copyid)
+    {
+      location_t loc = copyid_location_from_bb (bb);
+      if (loc != UNKNOWN_LOCATION)
+       assign_discriminators_to_bb (new_bb, 0,
+                                    allocate_copyid_base (loc, 1));
+    }
+
   return new_bb;
 }
 
@@ -1471,6 +1504,9 @@ copy_bbs (basic_block *bbs, unsigned n, basic_block 
*new_bbs,
   edge e;
   copy_bb_data id;
 
+  /* One copyid for the region (not per BB).  */
+  id.skip_copyid = true;
+
   /* Mark the blocks to be copied.  This is used by edge creation hooks
      to decide whether to reallocate PHI nodes capacity to avoid reallocating
      PHIs in the set of source BBs.  */
@@ -1558,6 +1594,19 @@ copy_bbs (basic_block *bbs, unsigned n, basic_block 
*new_bbs,
   /* Clear information about duplicates.  */
   for (i = 0; i < n; i++)
     bbs[i]->flags &= ~BB_DUPLICATED;
+
+  /* One copyid for the whole region, keyed off the first source block that
+     has a location.  */
+  location_t loc = UNKNOWN_LOCATION;
+  for (i = 0; i < n && loc == UNKNOWN_LOCATION; i++)
+    loc = copyid_location_from_bb (bbs[i]);
+
+  if (loc != UNKNOWN_LOCATION)
+    {
+      unsigned int copyid = allocate_copyid_base (loc, 1);
+      for (i = 0; i < n; i++)
+       assign_discriminators_to_bb (new_bbs[i], 0, copyid);
+    }
 }
 
 /* Return true if BB contains only labels or non-executable
diff --git a/gcc/cfghooks.h b/gcc/cfghooks.h
index b342b2d4f23f..576f2912d5b6 100644
--- a/gcc/cfghooks.h
+++ b/gcc/cfghooks.h
@@ -67,12 +67,15 @@ typedef int_hash <unsigned short, 0> dependence_hash;
 class copy_bb_data
 {
 public:
-  copy_bb_data() : dependence_map (NULL) {}
+  copy_bb_data () : dependence_map (NULL), skip_copyid (false) {}
   ~copy_bb_data () { delete dependence_map; }
 
   /* A map from the copied BBs dependence info cliques to
      equivalents in the BBs duplicated to.  */
   hash_map<dependence_hash, unsigned short> *dependence_map;
+
+  /* If true copy_bbs assigns one copyid for the region.  */
+  bool skip_copyid;
 };
 
 struct cfg_hooks
diff --git a/gcc/cfgloopmanip.cc b/gcc/cfgloopmanip.cc
index f7551d5f30d1..5a0eb3c7bb3d 100644
--- a/gcc/cfgloopmanip.cc
+++ b/gcc/cfgloopmanip.cc
@@ -34,7 +34,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "sreal.h"
 #include "tree-cfg.h"
 #include "tree-pass.h"
-#include "hierarchical_discriminator.h"
 
 static void copy_loops_to (class loop **, int,
                           class loop *);
@@ -1419,39 +1418,6 @@ duplicate_loop_body_to_header_edge (class loop *loop, 
edge e,
   spec_edges[SE_LATCH] = latch_edge;
 
   place_after = e->src;
-  location_t loop_loc = UNKNOWN_LOCATION;
-  unsigned int loop_copyid_base = 0;
-
-  /* Find a location from the loop header - works for both GIMPLE and RTL.  */
-  if (current_ir_type () == IR_GIMPLE)
-    {
-      gimple *last = last_nondebug_stmt (loop->header);
-      loop_loc = last ? gimple_location (last) : UNKNOWN_LOCATION;
-    }
-  else
-    {
-      /* For RTL, try to find an instruction with a valid location.  */
-      rtx_insn *insn = BB_END (loop->header);
-      while (insn && insn != BB_HEAD (loop->header))
-       {
-         /* Only check location if this is a valid insn.  */
-         if (INSN_P (insn))
-           {
-             location_t loc = INSN_LOCATION (insn);
-             if (loc != UNKNOWN_LOCATION)
-               {
-                 loop_loc = get_pure_location (loc);
-                 break;
-               }
-           }
-         insn = PREV_INSN (insn);
-       }
-    }
-
-  /* Allocate copyid base for this loop duplication - works for both
-     GIMPLE and RTL since allocator is per-function.  */
-  if (loop_loc != UNKNOWN_LOCATION)
-    loop_copyid_base = allocate_copyid_base (loop_loc, ndupl);
 
   for (j = 0; j < ndupl; j++)
     {
@@ -1470,49 +1436,6 @@ duplicate_loop_body_to_header_edge (class loop *loop, 
edge e,
            new_bbs[i]->aux = (void *)(size_t)(j + 1);
          }
 
-      /* Assign hierarchical discriminators to distinguish loop iterations.  */
-      if (flags & DLTHE_RECORD_HIERARCHICAL_DISCRIMINATOR
-         && loop_copyid_base > 0)
-       {
-         /* Calculate copyid for this iteration.  */
-         unsigned int copyid = loop_copyid_base + j;
-         if (copyid > DISCR_COPYID_MAX)
-           copyid = DISCR_COPYID_MAX;
-
-         if (current_ir_type () == IR_GIMPLE)
-           {
-             /* Update all basic blocks created in this iteration.  */
-             for (i = 0; i < n; i++)
-               assign_discriminators_to_bb (new_bbs[i], 0, copyid);
-           }
-         else
-           {
-             /* For RTL, manually update instruction locations.  */
-             for (i = 0; i < n; i++)
-               {
-                 basic_block bb = new_bbs[i];
-                 rtx_insn *insn;
-
-                 /* Iterate through all instructions in the block.  */
-                 FOR_BB_INSNS (bb, insn)
-                   {
-                     if (INSN_HAS_LOCATION (insn))
-                       {
-                         location_t loc = INSN_LOCATION (insn);
-                         /* Get existing discriminator components.  */
-                         discriminator_components comp
-                           = get_discriminator_components_from_loc (loc);
-                         comp.copyid = copyid;
-
-                         /* Apply hierarchical discriminator format.  */
-                         INSN_LOCATION (insn)
-                           = location_with_discriminator_components (loc, 
comp);
-                       }
-                   }
-               }
-           }
-       }
-
       /* Note whether the blocks and edges belong to an irreducible loop.  */
       if (add_irreducible_flag)
        {
diff --git a/gcc/cfgloopmanip.h b/gcc/cfgloopmanip.h
index 106cc7d005af..86d58bec86fd 100644
--- a/gcc/cfgloopmanip.h
+++ b/gcc/cfgloopmanip.h
@@ -34,10 +34,6 @@ enum
                                           a complete peeling.  */
 #define DLTHE_FLAG_FLAT_PROFILE 8      /* Profile is flat; do not reduce
                                           count by unroll factor.  */
-#define DLTHE_RECORD_HIERARCHICAL_DISCRIMINATOR 16 /* Assign hierarchical
-                                                     discriminators to
-                                                     distinguish loop
-                                                     iterations.  */
 extern bool remove_path (edge, bool * = NULL, bitmap = NULL);
 extern void place_new_loop (struct function *, class loop *);
 extern void add_loop (class loop *, class loop *);
diff --git a/gcc/gimple-loop-versioning.cc b/gcc/gimple-loop-versioning.cc
index fa014f47b8e5..2bcd72246c6b 100644
--- a/gcc/gimple-loop-versioning.cc
+++ b/gcc/gimple-loop-versioning.cc
@@ -41,7 +41,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-into-ssa.h"
 #include "gimple-range.h"
 #include "tree-cfg.h"
-#include "hierarchical_discriminator.h"
 
 namespace {
 
@@ -1700,25 +1699,6 @@ loop_versioning::version_loop (class loop *loop)
       return false;
     }
 
-  /* Assign hierarchical discriminators to distinguish loop versions.
-     This allows AutoFDO to distinguish profile data from different
-     versions.  No multiplicity for non-vectorized loop versioning.  */
-  gimple *optimized_last = last_nondebug_stmt (li.optimized_loop->header);
-  location_t optimized_loc
-    = optimized_last ? gimple_location (optimized_last) : UNKNOWN_LOCATION;
-  if (optimized_loc != UNKNOWN_LOCATION)
-    {
-      unsigned int optimized_copyid = allocate_copyid_base (optimized_loc, 1);
-      assign_discriminators_to_loop (li.optimized_loop, 0, optimized_copyid);
-    }
-  gimple *loop_last = last_nondebug_stmt (loop->header);
-  location_t loop_loc
-    = loop_last ? gimple_location (loop_last) : UNKNOWN_LOCATION;
-  if (loop_loc != UNKNOWN_LOCATION)
-    {
-      unsigned int loop_copyid = allocate_copyid_base (loop_loc, 1);
-      assign_discriminators_to_loop (loop, 0, loop_copyid);
-    }
   if (dump_enabled_p ())
     dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, find_loop_location (loop),
                     "versioned this loop for when certain strides are 1\n");
diff --git a/gcc/hierarchical_discriminator.cc 
b/gcc/hierarchical_discriminator.cc
index 009b1a83f1e8..65e1184cae30 100644
--- a/gcc/hierarchical_discriminator.cc
+++ b/gcc/hierarchical_discriminator.cc
@@ -105,6 +105,20 @@ assign_discriminators_to_bb (basic_block bb,
                             unsigned int multiplicity_factor,
                             unsigned int copyid)
 {
+  if (current_ir_type () != IR_GIMPLE)
+    {
+      rtx_insn *insn;
+      FOR_BB_INSNS (bb, insn)
+       {
+         if (!INSN_P (insn) || !INSN_HAS_LOCATION (insn))
+           continue;
+         location_t loc = INSN_LOCATION (insn);
+         INSN_LOCATION (insn)
+           = update_location_discriminator (loc, multiplicity_factor, copyid);
+       }
+      return;
+    }
+
   gimple_stmt_iterator gsi;
   gphi_iterator phi_gsi;
   edge e;
diff --git a/gcc/testsuite/gcc.dg/hierarchical-discriminator-ch.c 
b/gcc/testsuite/gcc.dg/hierarchical-discriminator-ch.c
new file mode 100644
index 000000000000..2eb0d747bbec
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/hierarchical-discriminator-ch.c
@@ -0,0 +1,24 @@
+/* Test hierarchical discriminators for loop header copying.
+   { dg-do compile }
+   { dg-options "-O2 -g -fno-tree-vectorize -fdump-tree-ch2-details" } */
+
+int a[100];
+
+int
+test_ch (int n)
+{
+  int sum = 0;
+  int i = 0;
+  while (i < n)
+    {
+      asm volatile ("" : "+r" (sum));
+      sum += a[i];
+      i++;
+    }
+  return sum;
+}
+
+/* Header copying peels the exit check; the peeled copy should get a
+   non-zero hierarchical discriminator.  */
+/* { dg-final { scan-tree-dump "Duplicating header of the loop" "ch2" } } */
+/* { dg-final { scan-assembler "discriminator 
(\[1-9\]\[0-9\]*|0x\[1-9a-fA-F\]\[0-9a-fA-F\]*)" { target gas } } } */
diff --git a/gcc/testsuite/gcc.dg/hierarchical-discriminator-loop-version.c 
b/gcc/testsuite/gcc.dg/hierarchical-discriminator-loop-version.c
index 16e64d8f918c..f90cb14f7775 100644
--- a/gcc/testsuite/gcc.dg/hierarchical-discriminator-loop-version.c
+++ b/gcc/testsuite/gcc.dg/hierarchical-discriminator-loop-version.c
@@ -17,4 +17,4 @@ test_loop_versioning (double *x, int stepx, int n)
 
 /* Check that loop versioning occurred and discriminators are present on the 
loop body. */
 /* { dg-final { scan-tree-dump "versioned this loop for when certain strides 
are 1" "lversion" } } */
-/* { dg-final { scan-assembler "\\.loc 1 (9|10) \[0-9\]+ is_stmt 0 
discriminator \[0-9\]+" { target gas } } } */
+/* { dg-final { scan-assembler "\\.loc 1 (9|10) \[0-9\]+ is_stmt 0 
discriminator (\[1-9\]\[0-9\]*|0x\[1-9a-fA-F\]\[0-9a-fA-F\]*)" { target gas } } 
} */
diff --git a/gcc/testsuite/gcc.dg/hierarchical-discriminator-rtl-unroll.c 
b/gcc/testsuite/gcc.dg/hierarchical-discriminator-rtl-unroll.c
new file mode 100644
index 000000000000..ff771224e7a8
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/hierarchical-discriminator-rtl-unroll.c
@@ -0,0 +1,21 @@
+/* Test hierarchical discriminators for RTL loop unrolling.
+   { dg-do compile }
+   { dg-options "-O2 -g -funroll-loops -fno-tree-vectorize" } */
+
+int a[256];
+
+int
+test_rtl_unroll (void)
+{
+  int sum = 0;
+  for (int i = 0; i < 32; i++)
+    {
+      asm volatile ("" : "+r" (sum));
+      sum += a[i] * 3;
+    }
+  return sum;
+}
+
+/* RTL unroll via loop-unroll.cc should assign non-zero copyid
+   discriminators via copy_bbs.  */
+/* { dg-final { scan-assembler "discriminator 
(\[1-9\]\[0-9\]*|0x\[1-9a-fA-F\]\[0-9a-fA-F\]*)" { target gas } } } */
diff --git a/gcc/testsuite/gcc.dg/hierarchical-discriminator-tracer.c 
b/gcc/testsuite/gcc.dg/hierarchical-discriminator-tracer.c
new file mode 100644
index 000000000000..84b804cd7528
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/hierarchical-discriminator-tracer.c
@@ -0,0 +1,24 @@
+/* Test hierarchical discriminators for tracer tail duplication.
+   { dg-do compile }
+   { dg-options "-O2 -g -ftracer -fno-tree-vectorize -fdump-tree-tracer" } */
+
+volatile int a, b, c;
+
+int
+test_tracer (void)
+{
+  int i;
+  for (i = 0; i < 1000; i++)
+    {
+      if (i % 17)
+       a++;
+      else
+       b++;
+      c++;
+    }
+  return c;
+}
+
+/* Superblock formation duplicates the increment of c.  */
+/* { dg-final { scan-tree-dump "Duplicated" "tracer" } } */
+/* { dg-final { scan-assembler "discriminator 
(\[1-9\]\[0-9\]*|0x\[1-9a-fA-F\]\[0-9a-fA-F\]*)" { target gas } } } */
diff --git a/gcc/testsuite/gcc.dg/hierarchical-discriminator-unroll-jam.c 
b/gcc/testsuite/gcc.dg/hierarchical-discriminator-unroll-jam.c
new file mode 100644
index 000000000000..bdea95b941fb
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/hierarchical-discriminator-unroll-jam.c
@@ -0,0 +1,19 @@
+/* Test hierarchical discriminators for GIMPLE partial unroll
+   via unroll-and-jam (tree_unroll_loop -> tree_transform_and_unroll_loop).
+   { dg-do compile }
+   { dg-options "-O3 -g -floop-unroll-and-jam -fno-tree-vectorize --param 
unroll-jam-min-percent=0 -fdump-tree-unrolljam-details" } */
+/* { dg-require-effective-target int32plus } */
+
+unsigned int aa[16][1024];
+
+void
+test_unroll_jam (unsigned long n, unsigned long m)
+{
+  unsigned i, j;
+  for (i = 1; i < m; i++)
+    for (j = 1; j < n; j++)
+      aa[i][j] = aa[i - 1][j] * aa[i - 1][j] / 2;
+}
+
+/* { dg-final { scan-tree-dump "applying unroll and jam" "unrolljam" } } */
+/* { dg-final { scan-assembler "discriminator 
(\[1-9\]\[0-9\]*|0x\[1-9a-fA-F\]\[0-9a-fA-F\]*)" { target gas } } } */
diff --git a/gcc/testsuite/gcc.dg/hierarchical-discriminator-unswitch.c 
b/gcc/testsuite/gcc.dg/hierarchical-discriminator-unswitch.c
new file mode 100644
index 000000000000..7a8b8a6a459c
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/hierarchical-discriminator-unswitch.c
@@ -0,0 +1,22 @@
+/* Test hierarchical discriminators for loop unswitching
+   (new version gets a copyid via copy_bbs in loop_version).
+   { dg-do compile }
+   { dg-options "-O2 -g -funswitch-loops -fno-tree-vectorize 
-fdump-tree-unswitch-optimized" } */
+
+void
+test_unswitch (int *a, int *b, int *r, int size, int order)
+{
+  for (int i = 0; i < size; i++)
+    {
+      int tmp;
+      if (order == 1)
+       tmp = -8 * a[i];
+      else
+       tmp = a[i];
+      asm volatile ("" : "+r" (tmp));
+      r[i] = 3 * tmp + b[i];
+    }
+}
+
+/* { dg-final { scan-tree-dump "unswitching loop" "unswitch" } } */
+/* { dg-final { scan-assembler "discriminator 
(\[1-9\]\[0-9\]*|0x\[1-9a-fA-F\]\[0-9a-fA-F\]*)" { target gas } } } */
diff --git a/gcc/tree-ssa-loop-ivcanon.cc b/gcc/tree-ssa-loop-ivcanon.cc
index c35a49189a1a..8659d87f621a 100644
--- a/gcc/tree-ssa-loop-ivcanon.cc
+++ b/gcc/tree-ssa-loop-ivcanon.cc
@@ -65,7 +65,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-ssa-sccvn.h"
 #include "tree-vectorizer.h" /* For find_loop_location */
 #include "dbgcnt.h"
-#include "hierarchical_discriminator.h"
 
 /* Specifies types of loops that may be unrolled.  */
 
@@ -981,8 +980,7 @@ try_unroll_loop_completely (class loop *loop,
       if (!gimple_duplicate_loop_body_to_header_edge (
            loop, loop_preheader_edge (loop), n_unroll, wont_exit, exit,
            &edges_to_remove,
-           DLTHE_FLAG_UPDATE_FREQ | DLTHE_FLAG_COMPLETTE_PEEL
-           | DLTHE_RECORD_HIERARCHICAL_DISCRIMINATOR))
+           DLTHE_FLAG_UPDATE_FREQ | DLTHE_FLAG_COMPLETTE_PEEL))
        {
           free_original_copy_tables ();
          if (dump_file && (dump_flags & TDF_DETAILS))
@@ -1225,7 +1223,7 @@ try_peel_loop (class loop *loop,
   if (!gimple_duplicate_loop_body_to_header_edge (
        loop, loop_preheader_edge (loop), npeel, wont_exit, exit,
        &edges_to_remove,
-       DLTHE_FLAG_UPDATE_FREQ | DLTHE_RECORD_HIERARCHICAL_DISCRIMINATOR))
+       DLTHE_FLAG_UPDATE_FREQ))
     {
       free_original_copy_tables ();
       return false;
diff --git a/gcc/tree-vect-loop-manip.cc b/gcc/tree-vect-loop-manip.cc
index 385353bda2ba..8a75c056f6dc 100644
--- a/gcc/tree-vect-loop-manip.cc
+++ b/gcc/tree-vect-loop-manip.cc
@@ -53,7 +53,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "langhooks.h"
 #include "tree-vector-builder.h"
 #include "optabs-tree.h"
-#include "hierarchical_discriminator.h"
 
 
 /*************************************************************************
@@ -3706,15 +3705,6 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, 
tree nitersm1,
       gcc_assert (prolog);
       prolog->force_vectorize = false;
 
-      /* Assign hierarchical discriminators to distinguish prolog loop.  */
-      gimple *prolog_last = last_nondebug_stmt (prolog->header);
-      location_t prolog_loc
-               = prolog_last ? gimple_location (prolog_last) : 
UNKNOWN_LOCATION;
-      if (prolog_loc != UNKNOWN_LOCATION)
-       {
-         unsigned int prolog_copyid = allocate_copyid_base (prolog_loc, 1);
-         assign_discriminators_to_loop (prolog, 0, prolog_copyid);
-       }
       first_loop = prolog;
       reset_original_copy_tables ();
 
@@ -3826,22 +3816,6 @@ vect_do_peeling (loop_vec_info loop_vinfo, tree niters, 
tree nitersm1,
       epilog->force_vectorize = false;
       bb_before_epilog = loop_preheader_edge (epilog)->src;
 
-      /* Assign hierarchical discriminators to distinguish epilog loop.
-        Only assign if it's a scalar epilog.  If it will be vectorized
-        (vect_epilogues), discriminators will be assigned.
-        Use dynamic copy_id allocation instead of hardcoded constants.  */
-      if (!vect_epilogues)
-       {
-         gimple *epilog_last = last_nondebug_stmt (epilog->header);
-         location_t epilog_loc
-           = epilog_last ? gimple_location (epilog_last) : UNKNOWN_LOCATION;
-         if (epilog_loc != UNKNOWN_LOCATION)
-           {
-             unsigned int epilog_copyid = allocate_copyid_base (epilog_loc, 1);
-             assign_discriminators_to_loop (epilog, 0, epilog_copyid);
-           }
-       }
-
       /* Scalar version loop may be preferred.  In this case, add guard
         and skip to epilog.  Note this only happens when the number of
         iterations of loop is unknown at compile time, otherwise this
@@ -4782,18 +4756,6 @@ vect_loop_versioning (loop_vec_info loop_vinfo,
       gcc_assert (nloop);
       nloop = get_loop_copy (loop);
 
-      /* Assign hierarchical discriminators to distinguish loop versions.
-        Only assign to the scalar version here; the vectorized version will
-        get discriminators later during transformation/peeling.
-        Use dynamic copy_id allocation instead of hardcoded constants.  */
-      gimple *nloop_last = last_nondebug_stmt (nloop->header);
-      location_t nloop_loc
-               = nloop_last ? gimple_location (nloop_last) : UNKNOWN_LOCATION;
-      if (nloop_loc != UNKNOWN_LOCATION)
-       {
-         unsigned int nloop_copyid = allocate_copyid_base (nloop_loc, 1);
-         assign_discriminators_to_loop (nloop, 0, nloop_copyid);
-       }
       /* For cycle vectorization with SLP we rely on the PHI arguments
         appearing in the same order as the SLP node operands which for the
         loop PHI nodes means the preheader edge dest index needs to remain
diff --git a/gcc/tree-vect-stmts.cc b/gcc/tree-vect-stmts.cc
index 6a2e42aac961..f341afb10ca8 100644
--- a/gcc/tree-vect-stmts.cc
+++ b/gcc/tree-vect-stmts.cc
@@ -58,6 +58,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "attribs.h"
 #include "optabs-libfuncs.h"
 #include "tree-dfa.h"
+#include "hierarchical_discriminator.h"
 
 /* For lang_hooks.types.type_for_mode.  */
 #include "langhooks.h"
@@ -9707,6 +9708,8 @@ hoist_defs_of_uses (gimple *stmt, class loop *loop, bool 
hoist_p)
     {
       gimple *def_stmt = SSA_NAME_DEF_STMT (USE_FROM_PTR (use_p));
       gimple *copy = gimple_copy (def_stmt);
+      assign_discriminators_to_stmt
+       (copy, 0, allocate_copyid_base (gimple_location (copy), 1));
       gimple_set_uid (copy, 0);
       def_operand_p def_p = single_ssa_def_operand (def_stmt, SSA_OP_DEF);
       tree new_def = duplicate_ssa_name (DEF_FROM_PTR (def_p), copy);
diff --git a/gcc/value-prof.cc b/gcc/value-prof.cc
index a7207bb8231c..93a540314dca 100644
--- a/gcc/value-prof.cc
+++ b/gcc/value-prof.cc
@@ -42,6 +42,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "gimple-pretty-print.h"
 #include "dumpfile.h"
 #include "builtins.h"
+#include "hierarchical_discriminator.h"
 
 /* In this file value profile based optimizations are placed.  Currently the
    following optimizations are implemented (for more detailed descriptions
@@ -1344,6 +1345,8 @@ gimple_ic (gcall *icall_stmt, struct cgraph_node 
*direct_call,
   gimple_set_vuse (icall_stmt, NULL_TREE);
   update_stmt (icall_stmt);
   dcall_stmt = as_a <gcall *> (gimple_copy (icall_stmt));
+  assign_discriminators_to_stmt
+    (dcall_stmt, 0, allocate_copyid_base (gimple_location (dcall_stmt), 1));
   gimple_call_set_fndecl (dcall_stmt, direct_call->decl);
   dflags = flags_from_decl_or_type (direct_call->decl);
   if ((dflags & ECF_NORETURN) != 0
@@ -1572,6 +1575,8 @@ gimple_stringop_fixed_value (gcall *vcall_stmt, tree 
icall_size, profile_probabi
   gimple_set_vuse (vcall_stmt, NULL);
   update_stmt (vcall_stmt);
   icall_stmt = as_a <gcall *> (gimple_copy (vcall_stmt));
+  assign_discriminators_to_stmt
+    (icall_stmt, 0, allocate_copyid_base (gimple_location (icall_stmt), 1));
   gimple_call_set_arg (icall_stmt, size_arg,
                       fold_convert (optype, icall_size));
   gsi_insert_before (&gsi, icall_stmt, GSI_SAME_STMT);

Reply via email to