Fix partitioning ICE

Message ID 20180515155945.GA66495@kam.mff.cuni.cz
State New
Headers show
Series
  • Fix partitioning ICE
Related show

Commit Message

Jan Hubicka May 15, 2018, 3:59 p.m.
Hi,
this patch silences sanity check that makes sure that everything is in
partition 0 and thus boundary cost is 0 when there is only one partition.
In the testcase there is external initializer which does not get partitioned
and thus we end up with cost 1.  Fixed by not accounting references from
external initializers.

Bootstrapped/regtsted x86_64-linux, will commit it after finishing ltobootstrap.

Honza

	* torture/pr85583.C: New testcase.

	* lto-partition.c (account_reference_p): Do not account
	references from aliases; do not account refernces from
	external initializers.

Patch

Index: testsuite/g++.dg/torture/pr85583.C
===================================================================
--- testsuite/g++.dg/torture/pr85583.C	(nonexistent)
+++ testsuite/g++.dg/torture/pr85583.C	(working copy)
@@ -0,0 +1,13 @@ 
+/* { dg-do link } */
+class b {
+public:
+  virtual ~b();
+};
+template <typename> class c : b {};
+class B {
+  c<char> d;
+};
+extern template class c<char>;
+int
+main(void) { B a; return 0; }
+
Index: lto/lto-partition.c
===================================================================
--- lto/lto-partition.c	(revision 260258)
+++ lto/lto-partition.c	(working copy)
@@ -439,13 +439,28 @@ 
 {
   if (cgraph_node *cnode = dyn_cast <cgraph_node *> (n1))
     n1 = cnode;
+  /* Do not account references from aliases - they are never split across
+     partitions.  */
+  if (n1->alias)
+    return false;
   /* Do not account recursion - the code below will handle it incorrectly
-     otherwise.  Also do not account references to external symbols.
-     They will never become local.  */
+     otherwise.  Do not account references to external symbols: they will
+     never become local.  Finally do not account references to duplicated
+     symbols: they will be always local.  */
   if (n1 == n2 
-      || DECL_EXTERNAL (n2->decl)
-      || !n2->definition)
+      || !n2->definition
+      || n2->get_partitioning_class () != SYMBOL_PARTITION)
     return false;
+  /* If referring node is external symbol do not account it to boundary
+     cost. Those are added into units only to enable possible constant
+     folding and devirtulization.
+
+     Here we do not know if it will ever be added to some partition
+     (this is decided by compute_ltrans_boundary) and second it is not
+     that likely that constant folding will actually use the reference.  */
+  if (contained_in_symbol (n1)
+	->get_partitioning_class () == SYMBOL_EXTERNAL)
+    return false;
   return true;
 }