From patchwork Sun Jun 2 17:16:52 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Andi Kleen X-Patchwork-Id: 1942535 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=intel.com header.i=@intel.com header.a=rsa-sha256 header.s=Intel header.b=fM+UAN5q; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VskHw5Swlz20Pr for ; Mon, 3 Jun 2024 03:24:44 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 15ADE393743A for ; Sun, 2 Jun 2024 17:24:43 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mgamail.intel.com (mgamail.intel.com [198.175.65.11]) by sourceware.org (Postfix) with ESMTPS id 791E7392AC34 for ; Sun, 2 Jun 2024 17:22:27 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 791E7392AC34 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=linux.intel.com Authentication-Results: sourceware.org; spf=none smtp.mailfrom=linux.intel.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 791E7392AC34 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=198.175.65.11 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1717348951; cv=none; b=k8zhKm6+DlRQ8vpAtzrIXWnDQZr7vFr0e4Bpb/Mui+IhcbSd+VFmk+k6arIk/Z0ia/mLDzfrHkhd69vkwoLgGwx5xsZ7wIjibGseU5wWiWHrkeeF6V2oxrxwKZ5ZJp0+ptYVZZyG0yP8effLtRlp/gBxXlfGjpQgkDZjTlZETVQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1717348951; c=relaxed/simple; bh=r1EpWNPuk6GeQYLGXi4ViHeY+MOOMkruBxTnnVp2nJ0=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=A/Do2jmfpFNBepAcE83uWnbnVzDg4l6Zz8ewVUsqPN32H2mIG0/TjnuLctnhySbJ3NDFcftVIOyicjFRhv8UNB5OJqdOVX44ys0LtsbxyG1CvS9wuzduzdFq0f4/HUZ7jhloDWPYL35MbjdsaEY5puMDR+tShYzwJMJpuumH8Bw= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1717348949; x=1748884949; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=r1EpWNPuk6GeQYLGXi4ViHeY+MOOMkruBxTnnVp2nJ0=; b=fM+UAN5qWdRCiUv90hrdw81QwL/JJcehsGPrWyI8UnEPVAbQDDGdqKYm 1zNw1xH7Gg4Zajcraz0jpJkviDi/ZJFr/K03s7er94bRMK+1G4M3geEtu gs961z+phK6SqfIhV8nHM7xuWqcf4jR8W12MBHKLXkARwZA6ixv4JCkeA RJGKg6dVfl8bQtImF04YUdsx+IC8/lp64QJ2y2bkWSl20PvLBWYDzaXbM sQ5izH6tEqFueSeqhDNrbz6IP77HTIMIY9j/EYDHhO3BZPgOx15HVLOQ2 LzKqKKOMwvb5mx8/OQmsHAK8ePQdtzsn9DQuTLrRjIjzpwfs16sH2uZdS A==; X-CSE-ConnectionGUID: ZqvVOyokSJGQV7zSSfUuow== X-CSE-MsgGUID: wF5DI4xVRQaZz+JsktfJ/A== X-IronPort-AV: E=McAfee;i="6600,9927,11091"; a="24418948" X-IronPort-AV: E=Sophos;i="6.08,209,1712646000"; d="scan'208";a="24418948" Received: from fmviesa003.fm.intel.com ([10.60.135.143]) by orvoesa103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Jun 2024 10:22:19 -0700 X-CSE-ConnectionGUID: rvLrxx/MRmi4vRd66fu3Ew== X-CSE-MsgGUID: AAVMUaRfSOS8a7yd0PqvEw== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="6.08,209,1712646000"; d="scan'208";a="41088190" Received: from tassilo.jf.intel.com ([10.54.38.190]) by fmviesa003-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 02 Jun 2024 10:22:18 -0700 From: Andi Kleen To: gcc-patches@gcc.gnu.org Cc: richard.guenther@gmail.com, nathan@acm.org, josmyers@redhat.com, richard.sandiford@arm.com, jason@redhat.com, Andi Kleen Subject: [PATCH v7 8/9] Give better error messages for musttail Date: Sun, 2 Jun 2024 10:16:52 -0700 Message-ID: <20240602172205.2151579-9-ak@linux.intel.com> X-Mailer: git-send-email 2.44.0 In-Reply-To: <20240602172205.2151579-1-ak@linux.intel.com> References: <20240602172205.2151579-1-ak@linux.intel.com> MIME-Version: 1.0 X-Spam-Status: No, score=-11.2 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_NONE, SPF_NONE, TXREP, T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org When musttail is set, make tree-tailcall to give error messages when it cannot handle a call. This avoids vague "other reasons" error messages later at expand time. This doesn't always work, for example when find_tail_call walking gives up because the control flow is too complicated then it won't find the tail call and can't give a suitable error message. gcc/ChangeLog: * tree-tailcall.cc (maybe_error_musttail): Add. (bb_get_succ_edge_count): Add. (find_tail_calls): Add error messages. Keep searching for basic blocks with multiple BBs if all but one is EH only. --- gcc/tree-tailcall.cc | 70 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 62 insertions(+), 8 deletions(-) diff --git a/gcc/tree-tailcall.cc b/gcc/tree-tailcall.cc index 094856de22ef..d315be554418 100644 --- a/gcc/tree-tailcall.cc +++ b/gcc/tree-tailcall.cc @@ -43,6 +43,7 @@ along with GCC; see the file COPYING3. If not see #include "common/common-target.h" #include "ipa-utils.h" #include "tree-ssa-live.h" +#include "diagnostic-core.h" /* The file implements the tail recursion elimination. It is also used to analyze the tail calls in general, passing the results to the rtl level @@ -402,6 +403,36 @@ propagate_through_phis (tree var, edge e) return var; } +/* Report an error for failing to tail convert must call CALL + with error message ERR. */ + +static void +maybe_error_musttail (gcall *call, const char *err) +{ + if (gimple_call_must_tail_p (call)) + { + error_at (call->location, "cannot tail-call: %s", err); + gimple_call_set_must_tail (call, false); /* Avoid another error. */ + gimple_call_set_tail (call, false); + } +} + +/* Count succ edges for BB and return in NUM_OTHER and NUM_EH. */ + +static void +bb_get_succ_edge_count (basic_block bb, int &num_other, int &num_eh) +{ + edge e; + edge_iterator ei; + num_eh = 0; + num_other = 0; + FOR_EACH_EDGE (e, ei, bb->succs) + if (e->flags & EDGE_EH) + num_eh++; + else + num_other++; +} + /* Argument for compute_live_vars/live_vars_at_stmt and what compute_live_vars returns. Computed lazily, but just once for the function. */ static live_vars_map *live_vars; @@ -426,7 +457,14 @@ find_tail_calls (basic_block bb, struct tailcall **ret, bool only_musttail) tree var; if (!single_succ_p (bb)) - return; + { + int num_eh, num_other; + bb_get_succ_edge_count (bb, num_eh, num_other); + /* Allow a single EH edge so that we can give a better + error message later. */ + if (!(num_eh == 1 && num_other == 1)) + return; + } for (gsi = gsi_last_bb (bb); !gsi_end_p (gsi); gsi_prev (&gsi)) { @@ -489,13 +527,20 @@ find_tail_calls (basic_block bb, struct tailcall **ret, bool only_musttail) if (ass_var && !is_gimple_reg (ass_var) && !auto_var_in_fn_p (ass_var, cfun->decl)) - return; + { + maybe_error_musttail (call, "complex return value"); + return; + } /* If the call might throw an exception that wouldn't propagate out of cfun, we can't transform to a tail or sibling call (82081). */ if (stmt_could_throw_p (cfun, stmt) && !stmt_can_throw_external (cfun, stmt)) + { + maybe_error_musttail (call, + "call may throw exception that does not propagate"); return; + } /* If the function returns a value, then at present, the tail call must return the same type of value. There is conceptually a copy @@ -524,7 +569,10 @@ find_tail_calls (basic_block bb, struct tailcall **ret, bool only_musttail) if (result_decl && may_be_aliased (result_decl) && ref_maybe_used_by_stmt_p (call, result_decl, false)) - return; + { + maybe_error_musttail (call, "tail call must be same type"); + return; + } /* We found the call, check whether it is suitable. */ tail_recursion = false; @@ -605,6 +653,7 @@ find_tail_calls (basic_block bb, struct tailcall **ret, bool only_musttail) { if (local_live_vars) BITMAP_FREE (local_live_vars); + maybe_error_musttail (call, "call invocation refers to locals"); return; } else @@ -613,6 +662,7 @@ find_tail_calls (basic_block bb, struct tailcall **ret, bool only_musttail) if (bitmap_bit_p (local_live_vars, *v)) { BITMAP_FREE (local_live_vars); + maybe_error_musttail (call, "call invocation refers to locals"); return; } } @@ -663,12 +713,13 @@ find_tail_calls (basic_block bb, struct tailcall **ret, bool only_musttail) /* This is a gimple assign. */ par ret = process_assignment (as_a (stmt), gsi, &tmp_m, &tmp_a, &ass_var, to_move_defs); - if (ret == FAIL) - return; + if (ret == FAIL || (ret == TRY_MOVE && !tail_recursion)) + { + maybe_error_musttail (call, "return value changed after call"); + return; + } else if (ret == TRY_MOVE) { - if (! tail_recursion) - return; /* Do not deal with checking dominance, the real fix is to do path isolation for the transform phase anyway, removing the need to compute the accumulators with new stmts. */ @@ -716,7 +767,10 @@ find_tail_calls (basic_block bb, struct tailcall **ret, bool only_musttail) if (ret_var && (ret_var != ass_var && !(is_empty_type (TREE_TYPE (ret_var)) && !ass_var))) - return; + { + maybe_error_musttail (call, "call must be the same type"); + return; + } /* If this is not a tail recursive call, we cannot handle addends or multiplicands. */