From patchwork Thu Mar 26 21:12:37 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 455200 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 9B7F61400B6 for ; Fri, 27 Mar 2015 08:12:51 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass reason="1024-bit key; unprotected key" header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=Euyfqk0I; dkim-adsp=none (unprotected policy); dkim-atps=neutral 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:cc:subject:message-id:references:mime-version :content-type:in-reply-to; q=dns; s=default; b=XzLp09NiyCkYJO9T5 MvsCbm2pLB9+z77amkisj6EuWgGfbqflKNab9Auyr3BR6g0QOsh9GMoiSXUae1xr jgncAcJZ8EzV7RDMDxJLblJptExqNEJVv6N6Ieho1d4vQDr6bl+7GhJu+Zi7BEa4 wctIDMD1u9L+LtywqJtyLzaots= 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:cc:subject:message-id:references:mime-version :content-type:in-reply-to; s=default; bh=SYpDXtyHn9Ad2YEiokFxtAn 0Tks=; b=Euyfqk0IcXFeoSQIuZqV0/m6tvoXK4XF64eAr1KihLcItUXHzGhVYKN 3IjYr/qQX712pf4arkgs6/kEAyKuBQLveUcQMGZrZfb66ZoCSRj6ctABM4G54nWn Uv4ws4GP0JkFrTzUupNE8RfP6MTKxjOlL32vZzG7YCZ4+3V7S6+k= Received: (qmail 124047 invoked by alias); 26 Mar 2015 21:12:44 -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 124036 invoked by uid 89); 26 Mar 2015 21:12:43 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.0 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD autolearn=ham version=3.3.2 X-HELO: nikam.ms.mff.cuni.cz Received: from nikam.ms.mff.cuni.cz (HELO nikam.ms.mff.cuni.cz) (195.113.20.16) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Thu, 26 Mar 2015 21:12:41 +0000 Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id ACD30546A33; Thu, 26 Mar 2015 22:12:37 +0100 (CET) Date: Thu, 26 Mar 2015 22:12:37 +0100 From: Jan Hubicka To: Jan Hubicka Cc: gcc-patches@gcc.gnu.org Subject: Re: Fix can_inline_edge_p and code marking calls unreachable Message-ID: <20150326211237.GA75710@kam.mff.cuni.cz> References: <20150326183209.GA66722@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20150326183209.GA66722@kam.mff.cuni.cz> User-Agent: Mutt/1.5.21 (2010-09-15) Hi, this patch missed hunk adding CIF code that I commited now * cif-code.def (CILK_SPAWN): New code. --- trunk/gcc/cif-code.def 2015/03/26 20:37:53 221709 +++ trunk/gcc/cif-code.def 2015/03/26 21:10:28 221710 @@ -124,6 +124,10 @@ DEFCIFCODE(ATTRIBUTE_MISMATCH, CIF_FINAL_ERROR, N_("function attribute mismatch")) +/* We can't inline because of mismatched caller/callee attributes. */ +DEFCIFCODE(CILK_SPAWN, CIF_FINAL_ERROR, + N_("caller function contains cilk spawn")) + /* We proved that the call is unreachable. */ DEFCIFCODE(UNREACHABLE, CIF_FINAL_ERROR, N_("unreachable")) I also noticed that this breaks one testcase which is cured by the following patch I am testing and will commit once it concludes. I apologize for the breakage. Honza * ipa-inline.c (check_maybe_up, check_maybe_down, check_match): New macros. (can_inline_edge_p): Relax option matching for always inline functions. Index: ipa-inline.c =================================================================== --- ipa-inline.c (revision 221706) +++ ipa-inline.c (working copy) @@ -298,6 +298,27 @@ sanitize_attrs_match_for_inline_p (const DECL_ATTRIBUTES (callee)); } +/* Used for flags where it is safe to inline when caller's value is + grater than callee's. */ +#define check_maybe_up(flag) \ + (opts_for_fn (caller->decl)->x_##flag \ + != opts_for_fn (callee->decl)->x_##flag \ + && (!always_inline \ + || opts_for_fn (caller->decl)->x_##flag \ + < opts_for_fn (callee->decl)->x_##flag)) +/* Used for flags where it is safe to inline when caller's value is + smaller than callee's. */ +#define check_maybe_down(flag) \ + (opts_for_fn (caller->decl)->x_##flag \ + != opts_for_fn (callee->decl)->x_##flag \ + && (!always_inline \ + || opts_for_fn (caller->decl)->x_##flag \ + > opts_for_fn (callee->decl)->x_##flag)) +/* Used for flags where exact match is needed for correctness. */ +#define check_match(flag) \ + (opts_for_fn (caller->decl)->x_##flag \ + != opts_for_fn (callee->decl)->x_##flag) + /* Decide if we can inline the edge and possibly update inline_failed reason. We check whether inlining is possible at all and whether @@ -401,74 +422,60 @@ can_inline_edge_p (struct cgraph_edge *e optimization attribute. */ else if (caller_tree != callee_tree) { + bool always_inline = + (DECL_DISREGARD_INLINE_LIMITS (callee->decl) + && lookup_attribute ("always_inline", + DECL_ATTRIBUTES (callee->decl))); + /* There are some options that change IL semantics which means we cannot inline in these cases for correctness reason. Not even for always_inline declared functions. */ /* Strictly speaking only when the callee contains signed integer math where overflow is undefined. */ - if ((opt_for_fn (caller->decl, flag_strict_overflow) - != opt_for_fn (callee->decl, flag_strict_overflow)) - || (opt_for_fn (caller->decl, flag_wrapv) - != opt_for_fn (callee->decl, flag_wrapv)) - || (opt_for_fn (caller->decl, flag_trapv) - != opt_for_fn (callee->decl, flag_trapv)) + if ((check_maybe_up (flag_strict_overflow) + /* this flag is set by optimize. Allow inlining across + optimize boundary. */ + && (!opt_for_fn (caller->decl, optimize) + == !opt_for_fn (callee->decl, optimize) || !always_inline)) + || check_match (flag_wrapv) + || check_match (flag_trapv) /* Strictly speaking only when the callee contains memory accesses that are not using alias-set zero anyway. */ - || (opt_for_fn (caller->decl, flag_strict_aliasing) - != opt_for_fn (callee->decl, flag_strict_aliasing)) + || check_maybe_down (flag_strict_aliasing) /* Strictly speaking only when the callee uses FP math. */ - || (opt_for_fn (caller->decl, flag_rounding_math) - != opt_for_fn (callee->decl, flag_rounding_math)) - || (opt_for_fn (caller->decl, flag_trapping_math) - != opt_for_fn (callee->decl, flag_trapping_math)) - || (opt_for_fn (caller->decl, flag_unsafe_math_optimizations) - != opt_for_fn (callee->decl, flag_unsafe_math_optimizations)) - || (opt_for_fn (caller->decl, flag_finite_math_only) - != opt_for_fn (callee->decl, flag_finite_math_only)) - || (opt_for_fn (caller->decl, flag_signaling_nans) - != opt_for_fn (callee->decl, flag_signaling_nans)) - || (opt_for_fn (caller->decl, flag_cx_limited_range) - != opt_for_fn (callee->decl, flag_cx_limited_range)) - || (opt_for_fn (caller->decl, flag_signed_zeros) - != opt_for_fn (callee->decl, flag_signed_zeros)) - || (opt_for_fn (caller->decl, flag_associative_math) - != opt_for_fn (callee->decl, flag_associative_math)) - || (opt_for_fn (caller->decl, flag_reciprocal_math) - != opt_for_fn (callee->decl, flag_reciprocal_math)) + || check_maybe_up (flag_rounding_math) + || check_maybe_up (flag_trapping_math) + || check_maybe_down (flag_unsafe_math_optimizations) + || check_maybe_down (flag_finite_math_only) + || check_maybe_up (flag_signaling_nans) + || check_maybe_down (flag_cx_limited_range) + || check_maybe_up (flag_signed_zeros) + || check_maybe_down (flag_associative_math) + || check_maybe_down (flag_reciprocal_math) /* We do not want to make code compiled with exceptions to be brought into a non-EH function unless we know that the callee does not throw. This is tracked by DECL_FUNCTION_PERSONALITY. */ - || (opt_for_fn (caller->decl, flag_non_call_exceptions) - != opt_for_fn (callee->decl, flag_non_call_exceptions) + || (check_match (flag_non_call_exceptions) /* TODO: We also may allow bringing !flag_non_call_exceptions to flag_non_call_exceptions function, but that may need extra work in tree-inline to add the extra EH edges. */ && (!opt_for_fn (callee->decl, flag_non_call_exceptions) || DECL_FUNCTION_PERSONALITY (callee->decl))) - || (!opt_for_fn (caller->decl, flag_exceptions) - && opt_for_fn (callee->decl, flag_exceptions) + || (check_maybe_up (flag_exceptions) && DECL_FUNCTION_PERSONALITY (callee->decl)) /* Strictly speaking only when the callee contains function calls that may end up setting errno. */ - || (opt_for_fn (caller->decl, flag_errno_math) - != opt_for_fn (callee->decl, flag_errno_math)) + || check_maybe_up (flag_errno_math) /* When devirtualization is diabled for callee, it is not safe to inline it as we possibly mangled the type info. Allow early inlining of always inlines. */ - || (opt_for_fn (caller->decl, flag_devirtualize) - && !opt_for_fn (callee->decl, flag_devirtualize) - && (!early - || (!DECL_DISREGARD_INLINE_LIMITS (callee->decl) - || !lookup_attribute ("always_inline", - DECL_ATTRIBUTES (callee->decl)))))) + || (!early && check_maybe_down (flag_devirtualize))) { e->inline_failed = CIF_OPTIMIZATION_MISMATCH; inlinable = false; } /* gcc.dg/pr43564.c. Apply user-forced inline even at -O0. */ - else if (DECL_DISREGARD_INLINE_LIMITS (callee->decl) - && lookup_attribute ("always_inline", - DECL_ATTRIBUTES (callee->decl))) + else if (always_inline) ; /* When user added an attribute to the callee honor it. */ else if (lookup_attribute ("optimize", DECL_ATTRIBUTES (callee->decl))