Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/patches/809594/?format=api
{ "id": 809594, "url": "http://patchwork.ozlabs.org/api/patches/809594/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/patch/alpine.LSU.2.20.1709041239400.14191@zhemvz.fhfr.qr/", "project": { "id": 17, "url": "http://patchwork.ozlabs.org/api/projects/17/?format=api", "name": "GNU Compiler Collection", "link_name": "gcc", "list_id": "gcc-patches.gcc.gnu.org", "list_email": "gcc-patches@gcc.gnu.org", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<alpine.LSU.2.20.1709041239400.14191@zhemvz.fhfr.qr>", "list_archive_url": null, "date": "2017-09-04T10:40:19", "name": "Fix PR82060", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "fb997db9c8e503fa278cc86620a6fd7b52aff401", "submitter": { "id": 4338, "url": "http://patchwork.ozlabs.org/api/people/4338/?format=api", "name": "Richard Biener", "email": "rguenther@suse.de" }, "delegate": null, "mbox": "http://patchwork.ozlabs.org/project/gcc/patch/alpine.LSU.2.20.1709041239400.14191@zhemvz.fhfr.qr/mbox/", "series": [ { "id": 1353, "url": "http://patchwork.ozlabs.org/api/series/1353/?format=api", "web_url": "http://patchwork.ozlabs.org/project/gcc/list/?series=1353", "date": "2017-09-04T10:40:19", "name": "Fix PR82060", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/1353/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/809594/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/809594/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<gcc-patches-return-461397-incoming=patchwork.ozlabs.org@gcc.gnu.org>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": [ "patchwork-incoming@bilbo.ozlabs.org", "mailing list gcc-patches@gcc.gnu.org" ], "Authentication-Results": [ "ozlabs.org;\n\tspf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org\n\t(client-ip=209.132.180.131; helo=sourceware.org;\n\tenvelope-from=gcc-patches-return-461397-incoming=patchwork.ozlabs.org@gcc.gnu.org;\n\treceiver=<UNKNOWN>)", "ozlabs.org; dkim=pass (1024-bit key;\n\tunprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org\n\theader.b=\"KdsjA+R8\"; dkim-atps=neutral", "sourceware.org; auth=none" ], "Received": [ "from sourceware.org (server1.sourceware.org [209.132.180.131])\n\t(using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256\n\tbits)) (No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3xm5wQ0y2vz9s8J\n\tfor <incoming@patchwork.ozlabs.org>;\n\tMon, 4 Sep 2017 20:40:36 +1000 (AEST)", "(qmail 41451 invoked by alias); 4 Sep 2017 10:40:29 -0000", "(qmail 41433 invoked by uid 89); 4 Sep 2017 10:40:28 -0000", "from mx2.suse.de (HELO mx1.suse.de) (195.135.220.15) by\n\tsourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP;\n\tMon, 04 Sep 2017 10:40:22 +0000", "from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254])\tby\n\tmx1.suse.de (Postfix) with ESMTP id 31BBBAAB6\tfor\n\t<gcc-patches@gcc.gnu.org>; Mon, 4 Sep 2017 10:40:20 +0000 (UTC)" ], "DomainKey-Signature": "a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id\n\t:list-unsubscribe:list-archive:list-post:list-help:sender:date\n\t:from:to:subject:message-id:mime-version:content-type; q=dns; s=\n\tdefault; b=rIoqiy2xY+1QMHArCsd0apDuAlV+nnLQY09TFpyzsRiJ/aE0x6bk/\n\ts9on2MdHiNu5vbjrKAFNEjCG5bOhUHk2f0R/e67ob7J1oQFZcQyVVPyU4dW46zrJ\n\tQkRdpsUAbes1XMMYj2rbHwv4EyOkzxRlsD8SC6/lkSThXwOG5WZonw=", "DKIM-Signature": "v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id\n\t:list-unsubscribe:list-archive:list-post:list-help:sender:date\n\t:from:to:subject:message-id:mime-version:content-type; s=\n\tdefault; bh=YCC0JwT/XCDi014JIzSwCVgYQk4=; b=KdsjA+R8shARMl0MRxzV\n\tUY/J1K5A2iHXs8aBm55gIoJKszz/MqHwbxPiZWpS4NwqhNjeM/z71dp1hRx5s+Fn\n\t3bT/dN/UMnwLivyyQ/ZcZShBEX8S9NlengPmYZB7SL5sIKn+eBD3crpkaAX7H//V\n\t/bFIetBxpTobkeccHoj0HiU=", "Mailing-List": "contact gcc-patches-help@gcc.gnu.org; run by ezmlm", "Precedence": "bulk", "List-Id": "<gcc-patches.gcc.gnu.org>", "List-Unsubscribe": "<mailto:gcc-patches-unsubscribe-incoming=patchwork.ozlabs.org@gcc.gnu.org>", "List-Archive": "<http://gcc.gnu.org/ml/gcc-patches/>", "List-Post": "<mailto:gcc-patches@gcc.gnu.org>", "List-Help": "<mailto:gcc-patches-help@gcc.gnu.org>", "Sender": "gcc-patches-owner@gcc.gnu.org", "X-Virus-Found": "No", "X-Spam-SWARE-Status": "No, score=-11.1 required=5.0 tests=BAYES_00, GIT_PATCH_2,\n\tGIT_PATCH_3, KAM_ASCII_DIVIDERS, RP_MATCHES_RCVD,\n\tSPF_PASS autolearn=ham version=3.3.2 spammy=cb", "X-HELO": "mx1.suse.de", "Date": "Mon, 4 Sep 2017 12:40:19 +0200 (CEST)", "From": "Richard Biener <rguenther@suse.de>", "To": "gcc-patches@gcc.gnu.org", "Subject": "[PATCH] Fix PR82060", "Message-ID": "<alpine.LSU.2.20.1709041239400.14191@zhemvz.fhfr.qr>", "User-Agent": "Alpine 2.20 (LSU 67 2015-01-07)", "MIME-Version": "1.0", "Content-Type": "text/plain; charset=US-ASCII" }, "content": "The following fixes PR82060 but canonicalizing mems before dispatching\nto the devrit machinery.\n\nBootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk.\n\nRichard.\n\n2017-09-04 Richard Biener <rguenther@suse.de>\n\n\tPR tree-optimization/82060\n\t* tree-ssa-pre.c (eliminate_dom_walker::before_dom_children):\n\tMove devirtualization after stmt folding and before EH/AB/noreturn\n\tcleanup to get the stmt refs canonicalized. Use a bool instead\n\tof gimple_modified_p since that doesn't work for NOPs. Schedule\n\tNOPs generated by folding for removal.\n\n\t* g++.dg/torture/pr82060.C: New testcase.", "diff": "Index: gcc/tree-ssa-pre.c\n===================================================================\n--- gcc/tree-ssa-pre.c\t(revision 251559)\n+++ gcc/tree-ssa-pre.c\t(working copy)\n@@ -4592,6 +4592,7 @@ eliminate_dom_walker::before_dom_childre\n /* If we didn't replace the whole stmt (or propagate the result\n into all uses), replace all uses on this stmt with their\n \t leaders. */\n+ bool modified = false;\n use_operand_p use_p;\n ssa_op_iter iter;\n FOR_EACH_SSA_USE_OPERAND (use_p, stmt, iter, SSA_OP_USE)\n@@ -4613,7 +4614,7 @@ eliminate_dom_walker::before_dom_childre\n \t\t || !bitmap_bit_p (inserted_exprs, SSA_NAME_VERSION (sprime))))\n \t {\n \t propagate_value (use_p, sprime);\n-\t gimple_set_modified (stmt, true);\n+\t modified = true;\n \t if (TREE_CODE (sprime) == SSA_NAME\n \t\t && !is_gimple_debug (stmt))\n \t\tgimple_set_plf (SSA_NAME_DEF_STMT (sprime),\n@@ -4621,8 +4622,56 @@ eliminate_dom_walker::before_dom_childre\n \t }\n \t}\n \n+ /* Fold the stmt if modified, this canonicalizes MEM_REFs we propagated\n+ into which is a requirement for the IPA devirt machinery. */\n+ gimple *old_stmt = stmt;\n+ if (modified)\n+\t{\n+\t /* If a formerly non-invariant ADDR_EXPR is turned into an\n+\t invariant one it was on a separate stmt. */\n+\t if (gimple_assign_single_p (stmt)\n+\t && TREE_CODE (gimple_assign_rhs1 (stmt)) == ADDR_EXPR)\n+\t recompute_tree_invariant_for_addr_expr (gimple_assign_rhs1 (stmt));\n+\t gimple_stmt_iterator prev = gsi;\n+\t gsi_prev (&prev);\n+\t if (fold_stmt (&gsi))\n+\t {\n+\t /* fold_stmt may have created new stmts inbetween\n+\t\t the previous stmt and the folded stmt. Mark\n+\t\t all defs created there as varying to not confuse\n+\t\t the SCCVN machinery as we're using that even during\n+\t\t elimination. */\n+\t if (gsi_end_p (prev))\n+\t\tprev = gsi_start_bb (b);\n+\t else\n+\t\tgsi_next (&prev);\n+\t if (gsi_stmt (prev) != gsi_stmt (gsi))\n+\t\tdo\n+\t\t {\n+\t\t tree def;\n+\t\t ssa_op_iter dit;\n+\t\t FOR_EACH_SSA_TREE_OPERAND (def, gsi_stmt (prev),\n+\t\t\t\t\t dit, SSA_OP_ALL_DEFS)\n+\t\t /* As existing DEFs may move between stmts\n+\t\t\t we have to guard VN_INFO_GET. */\n+\t\t if (! has_VN_INFO (def))\n+\t\t\tVN_INFO_GET (def)->valnum = def;\n+\t\t if (gsi_stmt (prev) == gsi_stmt (gsi))\n+\t\t break;\n+\t\t gsi_next (&prev);\n+\t\t }\n+\t\twhile (1);\n+\t }\n+\t stmt = gsi_stmt (gsi);\n+\t /* In case we folded the stmt away schedule the NOP for removal. */\n+\t if (gimple_nop_p (stmt))\n+\t el_to_remove.safe_push (stmt);\n+\t}\n+\n /* Visit indirect calls and turn them into direct calls if\n-\t possible using the devirtualization machinery. */\n+\t possible using the devirtualization machinery. Do this before\n+\t checking for required EH/abnormal/noreturn cleanup as devird\n+\t may expose more of those. */\n if (gcall *call_stmt = dyn_cast <gcall *> (stmt))\n \t{\n \t tree fn = gimple_call_fn (call_stmt);\n@@ -4631,24 +4680,21 @@ eliminate_dom_walker::before_dom_childre\n \t && virtual_method_call_p (fn))\n \t {\n \t tree otr_type = obj_type_ref_class (fn);\n+\t unsigned HOST_WIDE_INT otr_tok\n+\t\t= tree_to_uhwi (OBJ_TYPE_REF_TOKEN (fn));\n \t tree instance;\n-\t ipa_polymorphic_call_context context (current_function_decl, fn, stmt, &instance);\n+\t ipa_polymorphic_call_context context (current_function_decl,\n+\t\t\t\t\t\t fn, stmt, &instance);\n+\t context.get_dynamic_type (instance, OBJ_TYPE_REF_OBJECT (fn),\n+\t\t\t\t\totr_type, stmt);\n \t bool final;\n-\n-\t context.get_dynamic_type (instance, OBJ_TYPE_REF_OBJECT (fn), otr_type, stmt);\n-\n-\t vec <cgraph_node *>targets\n+\t vec <cgraph_node *> targets\n \t\t= possible_polymorphic_call_targets (obj_type_ref_class (fn),\n-\t\t\t\t\t\t tree_to_uhwi\n-\t\t\t\t\t\t (OBJ_TYPE_REF_TOKEN (fn)),\n-\t\t\t\t\t\t context,\n-\t\t\t\t\t\t &final);\n+\t\t\t\t\t\t otr_tok, context, &final);\n \t if (dump_file)\n \t\tdump_possible_polymorphic_call_targets (dump_file, \n \t\t\t\t\t\t\tobj_type_ref_class (fn),\n-\t\t\t\t\t\t\ttree_to_uhwi\n-\t\t\t\t\t\t\t (OBJ_TYPE_REF_TOKEN (fn)),\n-\t\t\t\t\t\t\tcontext);\n+\t\t\t\t\t\t\totr_tok, context);\n \t if (final && targets.length () <= 1 && dbg_cnt (devirt))\n \t\t{\n \t\t tree fn;\n@@ -4658,7 +4704,7 @@ eliminate_dom_walker::before_dom_childre\n \t\t fn = builtin_decl_implicit (BUILT_IN_UNREACHABLE);\n \t\t if (dump_enabled_p ())\n \t\t {\n-\t\t location_t loc = gimple_location_safe (stmt);\n+\t\t location_t loc = gimple_location (stmt);\n \t\t dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, loc,\n \t\t\t\t \"converting indirect call to \"\n \t\t\t\t \"function %s\\n\",\n@@ -4675,50 +4721,13 @@ eliminate_dom_walker::before_dom_childre\n \t\t\t == void_type_node))\n \t\t gimple_call_set_fntype (call_stmt, TREE_TYPE (fn));\n \t\t maybe_remove_unused_call_args (cfun, call_stmt);\n-\t\t gimple_set_modified (stmt, true);\n+\t\t modified = true;\n \t\t}\n \t }\n \t}\n \n- if (gimple_modified_p (stmt))\n+ if (modified)\n \t{\n-\t /* If a formerly non-invariant ADDR_EXPR is turned into an\n-\t invariant one it was on a separate stmt. */\n-\t if (gimple_assign_single_p (stmt)\n-\t && TREE_CODE (gimple_assign_rhs1 (stmt)) == ADDR_EXPR)\n-\t recompute_tree_invariant_for_addr_expr (gimple_assign_rhs1 (stmt));\n-\t gimple *old_stmt = stmt;\n-\t gimple_stmt_iterator prev = gsi;\n-\t gsi_prev (&prev);\n-\t if (fold_stmt (&gsi))\n-\t {\n-\t /* fold_stmt may have created new stmts inbetween\n-\t\t the previous stmt and the folded stmt. Mark\n-\t\t all defs created there as varying to not confuse\n-\t\t the SCCVN machinery as we're using that even during\n-\t\t elimination. */\n-\t if (gsi_end_p (prev))\n-\t\tprev = gsi_start_bb (b);\n-\t else\n-\t\tgsi_next (&prev);\n-\t if (gsi_stmt (prev) != gsi_stmt (gsi))\n-\t\tdo\n-\t\t {\n-\t\t tree def;\n-\t\t ssa_op_iter dit;\n-\t\t FOR_EACH_SSA_TREE_OPERAND (def, gsi_stmt (prev),\n-\t\t\t\t\t dit, SSA_OP_ALL_DEFS)\n-\t\t /* As existing DEFs may move between stmts\n-\t\t\t we have to guard VN_INFO_GET. */\n-\t\t if (! has_VN_INFO (def))\n-\t\t\tVN_INFO_GET (def)->valnum = def;\n-\t\t if (gsi_stmt (prev) == gsi_stmt (gsi))\n-\t\t break;\n-\t\t gsi_next (&prev);\n-\t\t }\n-\t\twhile (1);\n-\t }\n-\t stmt = gsi_stmt (gsi);\n \t /* When changing a call into a noreturn call, cfg cleanup\n \t is needed to fix up the noreturn call. */\n \t if (!was_noreturn\nIndex: gcc/testsuite/g++.dg/torture/pr82060.C\n===================================================================\n--- gcc/testsuite/g++.dg/torture/pr82060.C\t(nonexistent)\n+++ gcc/testsuite/g++.dg/torture/pr82060.C\t(working copy)\n@@ -0,0 +1,32 @@\n+// { dg-do compile }\n+\n+struct A\n+{\n+ char a[1]; // must be char array\n+};\n+\n+struct B\n+{\n+ A& a() { return ma; } // must be accessed through a getter\n+ A ma;\n+};\n+\n+struct C\n+{\n+ B& b() { return mb; } // must be accessed through a getter\n+ B mb;\n+};\n+\n+struct D\n+{\n+ virtual A getA() = 0; // must be virtual\n+};\n+\n+void\n+foo(D& d) // The D object must not be created locally\n+ // (so that getA implementation is not known at compile time?)\n+{\n+ C c;\n+ for (;;) // must be in a loop\n+ c.b().a() = d.getA();\n+}\n", "prefixes": [] }