Blame SOURCES/gcc8-rh2117838.patch

6f08b4
diff --git a/gcc/testsuite/g++.dg/torture/phi-1.C b/gcc/testsuite/g++.dg/torture/phi-1.C
6f08b4
new file mode 100644
6f08b4
index 00000000000..69fb3d7ba38
6f08b4
--- /dev/null
6f08b4
+++ b/gcc/testsuite/g++.dg/torture/phi-1.C
6f08b4
@@ -0,0 +1,28 @@
6f08b4
+// { dg-do compile { target c++11 } }
6f08b4
+// { dg-options "--param early-inlining-insns=14" }
6f08b4
+
6f08b4
+struct Element;
6f08b4
+template <int _Nm> struct __array_traits { typedef Element _Type[_Nm]; };
6f08b4
+template <int _Nm> struct array {
6f08b4
+  typename __array_traits<_Nm>::_Type _M_elems;
6f08b4
+};
6f08b4
+bool logLevel();
6f08b4
+struct LogCapture {
6f08b4
+  void stream();
6f08b4
+};
6f08b4
+struct Element {
6f08b4
+  Element();
6f08b4
+  long data_;
6f08b4
+};
6f08b4
+using ElementArray = array<6>;
6f08b4
+struct ElementManager {
6f08b4
+  ElementManager();
6f08b4
+  ElementArray array_;
6f08b4
+};
6f08b4
+static ElementArray makeArray() {
6f08b4
+  if (logLevel())
6f08b4
+    LogCapture().stream();
6f08b4
+  ElementArray foo;
6f08b4
+  return foo;
6f08b4
+}
6f08b4
+ElementManager::ElementManager() : array_(makeArray()) {}
6f08b4
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
6f08b4
index 84e58e66628..78c0c6a4189 100644
6f08b4
--- a/gcc/tree-cfg.c
6f08b4
+++ b/gcc/tree-cfg.c
6f08b4
@@ -2944,35 +2944,6 @@ last_and_only_stmt (basic_block bb)
6f08b4
     return NULL;
6f08b4
 }
6f08b4
 
6f08b4
-/* Reinstall those PHI arguments queued in OLD_EDGE to NEW_EDGE.  */
6f08b4
-
6f08b4
-static void
6f08b4
-reinstall_phi_args (edge new_edge, edge old_edge)
6f08b4
-{
6f08b4
-  edge_var_map *vm;
6f08b4
-  int i;
6f08b4
-  gphi_iterator phis;
6f08b4
-
6f08b4
-  vec<edge_var_map> *v = redirect_edge_var_map_vector (old_edge);
6f08b4
-  if (!v)
6f08b4
-    return;
6f08b4
-
6f08b4
-  for (i = 0, phis = gsi_start_phis (new_edge->dest);
6f08b4
-       v->iterate (i, &vm) && !gsi_end_p (phis);
6f08b4
-       i++, gsi_next (&phis))
6f08b4
-    {
6f08b4
-      gphi *phi = phis.phi ();
6f08b4
-      tree result = redirect_edge_var_map_result (vm);
6f08b4
-      tree arg = redirect_edge_var_map_def (vm);
6f08b4
-
6f08b4
-      gcc_assert (result == gimple_phi_result (phi));
6f08b4
-
6f08b4
-      add_phi_arg (phi, arg, new_edge, redirect_edge_var_map_location (vm));
6f08b4
-    }
6f08b4
-
6f08b4
-  redirect_edge_var_map_clear (old_edge);
6f08b4
-}
6f08b4
-
6f08b4
 /* Returns the basic block after which the new basic block created
6f08b4
    by splitting edge EDGE_IN should be placed.  Tries to keep the new block
6f08b4
    near its "logical" location.  This is of most help to humans looking
6f08b4
@@ -3012,11 +2983,24 @@ gimple_split_edge (edge edge_in)
6f08b4
   new_bb = create_empty_bb (after_bb);
6f08b4
   new_bb->count = edge_in->count ();
6f08b4
 
6f08b4
-  e = redirect_edge_and_branch (edge_in, new_bb);
6f08b4
-  gcc_assert (e == edge_in);
6f08b4
-
6f08b4
+  /* We want to avoid re-allocating PHIs when we first
6f08b4
+     add the fallthru edge from new_bb to dest but we also
6f08b4
+     want to avoid changing PHI argument order when
6f08b4
+     first redirecting edge_in away from dest.  The former
6f08b4
+     avoids changing PHI argument order by adding them
6f08b4
+     last and then the redirection swapping it back into
6f08b4
+     place by means of unordered remove.
6f08b4
+     So hack around things by temporarily removing all PHIs
6f08b4
+     from the destination during the edge redirection and then
6f08b4
+     making sure the edges stay in order.  */
6f08b4
+  gimple_seq saved_phis = phi_nodes (dest);
6f08b4
+  unsigned old_dest_idx = edge_in->dest_idx;
6f08b4
+  set_phi_nodes (dest, NULL);
6f08b4
   new_edge = make_single_succ_edge (new_bb, dest, EDGE_FALLTHRU);
6f08b4
-  reinstall_phi_args (new_edge, e);
6f08b4
+  e = redirect_edge_and_branch (edge_in, new_bb);
6f08b4
+  gcc_assert (e == edge_in && new_edge->dest_idx == old_dest_idx);
6f08b4
+  /* set_phi_nodes sets the BB of the PHI nodes, so do it manually here.  */
6f08b4
+  dest->il.gimple.phi_nodes = saved_phis;
6f08b4
 
6f08b4
   return new_bb;
6f08b4
 }