From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 21693 invoked by alias); 12 Feb 2013 17:25:57 -0000 Received: (qmail 21526 invoked by uid 55); 12 Feb 2013 17:25:32 -0000 From: "hubicka at ucw dot cz" To: gcc-bugs@gcc.gnu.org Subject: [Bug tree-optimization/56265] [4.8 Regression] ICE in ipa_make_edge_direct_to_target Date: Tue, 12 Feb 2013 17:25:00 -0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: tree-optimization X-Bugzilla-Keywords: ice-on-valid-code X-Bugzilla-Severity: normal X-Bugzilla-Who: hubicka at ucw dot cz X-Bugzilla-Status: NEW X-Bugzilla-Priority: P1 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: 4.8.0 X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated Content-Type: text/plain; charset="UTF-8" MIME-Version: 1.0 Mailing-List: contact gcc-bugs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-bugs-owner@gcc.gnu.org X-SW-Source: 2013-02/txt/msg01228.txt.bz2 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56265 --- Comment #4 from Jan Hubicka 2013-02-12 17:25:31 UTC --- Hi, this patch should make ipa_make_edge_direct_to_target to behave properly when new symbol needs to be inserted into the symbol table. We already have canonicalize_constructor_val to do the right thing (i.e. check we can refer to the symbol), but we need to update symbol table in that case, too. I also took the chance to add more detailed debug output. I will give this patch more testing on Mozilla/Qt tomorrow and produce some statistic. here is some chance of provoking some latent bug in canonicalize_constructor_val since we get bit more devirtualizations tham previously. It however ought not be much of issue since all of them can be produced on old tree by adding another function allowing local devirtualization and inserting the symbol into symtab. Honza Index: ipa-prop.c =================================================================== --- ipa-prop.c (revision 195956) +++ ipa-prop.c (working copy) @@ -2100,10 +2100,65 @@ ipa_make_edge_direct_to_target (struct c if (TREE_CODE (target) == ADDR_EXPR) target = TREE_OPERAND (target, 0); if (TREE_CODE (target) != FUNCTION_DECL) - return NULL; + { + target = canonicalize_constructor_val (target, NULL); + if (!target || TREE_CODE (target) != FUNCTION_DECL) + { + if (dump_file) + fprintf (dump_file, "ipa-prop: Discovered direct call to non-function" + " in (%s/%i).\n", + cgraph_node_name (ie->caller), ie->caller->uid); + return NULL; + } + } callee = cgraph_get_node (target); - if (!callee) - return NULL; + + /* Because may-edges are not explicitely represented and vtable may be external, + we may create the first reference to the object in the unit. */ + if (!callee || callee->global.inlined_to) + { + struct cgraph_node *first_clone = callee; + + /* We are better to ensure we can refer to it. + In the case of static functions we are out of luck, since we already + removed its body. In the case of public functions we may or may + not introduce the reference. */ + if (!canonicalize_constructor_val (target, NULL) + || !TREE_PUBLIC (target)) + { + if (dump_file) + fprintf (dump_file, "ipa-prop: Discovered call to a known target " + "(%s/%i -> %s/%i) but can not refer to it. Giving up.\n", + xstrdup (cgraph_node_name (ie->caller)), ie->caller->uid, + xstrdup (cgraph_node_name (ie->callee)), ie->callee->uid); + return NULL; + } + + /* Create symbol table node. Even if inline clone exists, we can not take + it as a target of non-inlined call. */ + callee = cgraph_create_node (target); + + /* OK, we previously inlined the function, then removed the offline copy and + now we want it back for external call. This can happen when devirtualizing + while inlining function called once that happens after extern inlined and + virtuals are already removed. In this case introduce the external node + and make it available for call. */ + if (first_clone) + { + first_clone->clone_of = callee; + callee->clones = first_clone; + symtab_prevail_in_asm_name_hash ((symtab_node)callee); + symtab_insert_node_to_hashtable ((symtab_node)callee); + if (dump_file) + fprintf (dump_file, "ipa-prop: Introduced new external node " + "(%s/%i) and turned into root of the clone tree.\n", + xstrdup (cgraph_node_name (callee)), callee->uid); + } + else if (dump_file) + fprintf (dump_file, "ipa-prop: Introduced new external node " + "(%s/%i).\n", + xstrdup (cgraph_node_name (callee)), callee->uid); + } ipa_check_create_node_params (); /* We can not make edges to inline clones. It is bug that someone removed