diff mbox

Do not build callgraph for external functions when inlining

Message ID 20141214230517.GA20608@kam.mff.cuni.cz
State New
Headers show

Commit Message

Jan Hubicka Dec. 14, 2014, 11:05 p.m. UTC
Hi,
this patch implements analogous change I did to ipa.c reachability to remove
extern functions early when not optimizing.  These are common in C++ code and
it is not effective to process them until after inliner.

Bootstrapped/regtested x86_64-linux, will commit it shortly.

Honza

	* cgraphunit.c (analyze_functions): Do not analyze extern inline
	funtions when not optimizing; skip comdat locals.

Comments

Andreas Schwab Dec. 15, 2014, 11:27 a.m. UTC | #1
Jan Hubicka <hubicka@ucw.cz> writes:

> 	* cgraphunit.c (analyze_functions): Do not analyze extern inline
> 	funtions when not optimizing; skip comdat locals.

FAIL: g++.dg/torture/pr60854.C   -O0  (test for excess errors)
Excess errors:
/usr/local/gcc/gcc-20141215/gcc/testsuite/g++.dg/torture/pr60854.C:5:46: error: inlining failed in call to always_inline 'MyClass<T>::MyClass() [with T = double]': function body not available
/usr/local/gcc/gcc-20141215/gcc/testsuite/g++.dg/torture/pr60854.C:12:19: error: called from here

Andreas.
Jan Hubicka Dec. 15, 2014, 9:57 p.m. UTC | #2
> Jan Hubicka <hubicka@ucw.cz> writes:
> 
> > 	* cgraphunit.c (analyze_functions): Do not analyze extern inline
> > 	funtions when not optimizing; skip comdat locals.
> 
> FAIL: g++.dg/torture/pr60854.C   -O0  (test for excess errors)
> Excess errors:
> /usr/local/gcc/gcc-20141215/gcc/testsuite/g++.dg/torture/pr60854.C:5:46: error: inlining failed in call to always_inline 'MyClass<T>::MyClass() [with T = double]': function body not available
> /usr/local/gcc/gcc-20141215/gcc/testsuite/g++.dg/torture/pr60854.C:12:19: error: called from here

Hi,
this should be fixed by patch to handle extern aliases correctly I commited later that day.
Does the problem still reproduce for you?

Honza
> 
> Andreas.
> 
> -- 
> Andreas Schwab, SUSE Labs, schwab@suse.de
> GPG Key fingerprint = 0196 BAD8 1CE9 1970 F4BE  1748 E4D4 88E3 0EEA B9D7
> "And now for something completely different."
Andreas Schwab Dec. 16, 2014, 8:23 a.m. UTC | #3
Jan Hubicka <hubicka@ucw.cz> writes:

> this should be fixed by patch to handle extern aliases correctly I commited later that day.
> Does the problem still reproduce for you?

It works again.

Andreas.
diff mbox

Patch

Index: cgraphunit.c
===================================================================
--- cgraphunit.c	(revision 218701)
+++ cgraphunit.c	(working copy)
@@ -263,7 +264,7 @@  symtab_node::needed_p (void)
   if (forced_by_abi && TREE_PUBLIC (decl))
     return true;
 
- /* Keep constructors, destructors and virtual functions.  */
+  /* Keep constructors, destructors and virtual functions.  */
    if (TREE_CODE (decl) == FUNCTION_DECL
        && (DECL_STATIC_CONSTRUCTOR (decl) || DECL_STATIC_DESTRUCTOR (decl)))
     return true;
@@ -1000,7 +1001,20 @@  analyze_functions (void)
 		cnode->analyze ();
 
 	      for (edge = cnode->callees; edge; edge = edge->next_callee)
-		if (edge->callee->definition)
+		if (edge->callee->definition
+		    && (!DECL_EXTERNAL (edge->callee->decl)
+			/* When not optimizing, do not try to analyze extern
+			   inline functions.  Doing so is pointless.  */
+			|| opt_for_fn (edge->callee->decl, optimize)
+			/* Weakrefs needs to be preserved.  */
+			|| edge->callee->alias
+			/* always_inline functions are inlined aven at -O0.  */
+		        || lookup_attribute
+				 ("always_inline",
+			          DECL_ATTRIBUTES (edge->callee->decl))
+			/* Multiversioned functions needs the dispatcher to
+			   be produced locally even for extern functions.  */
+			|| edge->callee->function_version ()))
 		   enqueue_node (edge->callee);
 	      if (opt_for_fn (cnode->decl, optimize)
 		  && opt_for_fn (cnode->decl, flag_devirtualize))
@@ -1040,10 +1054,17 @@  analyze_functions (void)
 	      for (next = node->same_comdat_group;
 		   next != node;
 		   next = next->same_comdat_group)
-		enqueue_node (next);
+		if (!next->comdat_local_p ())
+		  enqueue_node (next);
 	    }
 	  for (i = 0; node->iterate_reference (i, ref); i++)
-	    if (ref->referred->definition)
+	    if (ref->referred->definition
+		&& (!DECL_EXTERNAL (ref->referred->decl)
+		    || ((TREE_CODE (ref->referred->decl) != FUNCTION_DECL
+			 && optimize)
+			|| (TREE_CODE (ref->referred->decl) == FUNCTION_DECL
+			    && opt_for_fn (ref->referred->decl, optimize))
+		    || ref->referred->alias)))
 	      enqueue_node (ref->referred);
 	  symtab->process_new_functions ();
 	}