From patchwork Mon Nov 10 15:48:43 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ilya Enkovich X-Patchwork-Id: 408983 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 11B2B14011B for ; Tue, 11 Nov 2014 02:49:06 +1100 (AEDT) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; q=dns; s= default; b=sG/nggbj5g/H/MHnH56LjvU3Thei95UDLCMQF3WnQzffQklIARtZM L40dhW4mEJ/0ERromHA7KjHj0mGQsoVcHoRF1gdbJGqC9vKwNzmiB36R80OtO7Ew U+mlUesBwIMQZxVJ6B9OafWave01BTNeQnbVxvDyZeKKnzIIRyzRxU= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:mime-version:content-type; s= default; bh=Xv7HE8gkPLatsWlaPF/J908nbWE=; b=RSqMf5b7wKmQ3eECWcaf 5SXPMgW3IOZi0wj9klor0Sx5/P9YSz2F+dD19VJ4Drbw0hDApylklHqVRP2MpxAA IEAdLw0s4Q/jCBawA9A0UGVL9nJlZz/TS9sN6BWoCjP7y7DYwEaUMm9cM3Vk4HKj 18B+AV4PZuUoE9bNPdT/TcQ= Received: (qmail 14914 invoked by alias); 10 Nov 2014 15:49:00 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 14903 invoked by uid 89); 10 Nov 2014 15:48:59 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.9 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pa0-f49.google.com Received: from mail-pa0-f49.google.com (HELO mail-pa0-f49.google.com) (209.85.220.49) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-SHA encrypted) ESMTPS; Mon, 10 Nov 2014 15:48:58 +0000 Received: by mail-pa0-f49.google.com with SMTP id lj1so8355338pab.8 for ; Mon, 10 Nov 2014 07:48:56 -0800 (PST) X-Received: by 10.70.91.40 with SMTP id cb8mr23969993pdb.19.1415634536170; Mon, 10 Nov 2014 07:48:56 -0800 (PST) Received: from msticlxl57.ims.intel.com (fmdmzpr01-ext.fm.intel.com. [192.55.54.36]) by mx.google.com with ESMTPSA id yb8sm14391155pab.7.2014.11.10.07.48.54 for (version=TLSv1 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 10 Nov 2014 07:48:55 -0800 (PST) Date: Mon, 10 Nov 2014 18:48:43 +0300 From: Ilya Enkovich To: gcc-patches@gcc.gnu.org Subject: [PATCH] Fix for PR63766 (handle removed functions in do_per_function_toporder) Message-ID: <20141110154843.GA52080@msticlxl57.ims.intel.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes Hi, Here is a fix for PR63766. Currently all functions are transformed into SSA before local optimizations and it allows function to be inlined and removed before it goes through local optimzations. But this requires removal of these functions from working queue. Bootstrapped and tested on x86_64-unknown-linux-gnu. OK for trunk? Thanks, Ilya --- gcc/ 2014-11-10 Ilya Enkovich * passes.c (remove_cgraph_node_from_order): New. (do_per_function_toporder): Register cgraph removal hook. gcc/testsuite/ 2014-11-10 Ilya Enkovich * g++.dg/pr63766.C: New. diff --git a/gcc/passes.c b/gcc/passes.c index 5e91a79..b6a0b0c 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -1609,6 +1609,24 @@ do_per_function (void (*callback) (function *, void *data), void *data) static int nnodes; static GTY ((length ("nnodes"))) cgraph_node **order; +/* Hook called when NODE is removed and therefore should be + excluded from order vector. DATA is an array of integers. + DATA[0] holds max index it may be accessed by. For cgraph + node DATA[node->uid + 1] holds index of this node in order + vector. */ +static void +remove_cgraph_node_from_order (cgraph_node *node, void *data) +{ + int *order_idx = (int *)data; + + if (node->uid >= order_idx[0]) + return; + + int idx = order_idx[node->uid + 1]; + if (idx >= 0 && idx < nnodes && order[idx] == node) + order[idx] = NULL; +} + /* If we are in IPA mode (i.e., current_function_decl is NULL), call function CALLBACK for every function in the call graph. Otherwise, call CALLBACK on the current function. @@ -1622,13 +1640,29 @@ do_per_function_toporder (void (*callback) (function *, void *data), void *data) callback (cfun, data); else { + cgraph_node_hook_list *hook; + int *order_idx; gcc_assert (!order); order = ggc_vec_alloc (symtab->cgraph_count); + + order_idx = (int *)xmalloc (sizeof(int) * (symtab->cgraph_max_uid + 1)); + memset (order_idx + 1, -1, sizeof (int) * symtab->cgraph_max_uid); + order_idx[0] = symtab->cgraph_max_uid; + nnodes = ipa_reverse_postorder (order); for (i = nnodes - 1; i >= 0; i--) - order[i]->process = 1; + { + order[i]->process = 1; + order_idx[order[i]->uid + 1] = i; + } + hook = symtab->add_cgraph_removal_hook (remove_cgraph_node_from_order, + order_idx); for (i = nnodes - 1; i >= 0; i--) { + /* Function could be inlined and removed as unreachable. */ + if (!order[i]) + continue; + struct cgraph_node *node = order[i]; /* Allow possibly removed nodes to be garbage collected. */ @@ -1637,6 +1671,8 @@ do_per_function_toporder (void (*callback) (function *, void *data), void *data) if (node->has_gimple_body_p ()) callback (DECL_STRUCT_FUNCTION (node->decl), data); } + symtab->remove_cgraph_removal_hook (hook); + free (order_idx); } ggc_free (order); order = NULL; diff --git a/gcc/testsuite/g++.dg/pr63766.C b/gcc/testsuite/g++.dg/pr63766.C new file mode 100644 index 0000000..1414fbe --- /dev/null +++ b/gcc/testsuite/g++.dg/pr63766.C @@ -0,0 +1,48 @@ +/* { dg-do compile } */ +/* { dg-options "-std=c++11 -O2" } */ + +class A +{ + public: + void + getValueType () + { + } + void getTypeClass (); +}; +template class B +{ + public: + void + Visit (A *p1) + { + p1->getTypeClass (); + static_cast (0)->VisitAtomicType (0); + } +}; +class C : B +{ + template + void + dumpChild (Fn p1) + { + p1 (); + } + + public: + void dumpTypeAsChild (int); + void + VisitAtomicType (A *p1) + { + p1->getValueType (); + dumpTypeAsChild (0); + } +}; +void +C::dumpTypeAsChild (int) +{ + dumpChild ([=] + { + Visit (0); + }); +}