From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 31423 invoked by alias); 8 Apr 2011 12:15:20 -0000 Received: (qmail 31375 invoked by uid 22791); 8 Apr 2011 12:15:14 -0000 X-SWARE-Spam-Status: No, hits=-5.8 required=5.0 tests=AWL,BAYES_00,RCVD_IN_DNSWL_HI,TW_FN,TW_TM,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from cantor.suse.de (HELO mx1.suse.de) (195.135.220.2) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 08 Apr 2011 12:15:08 +0000 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.221.2]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.suse.de (Postfix) with ESMTP id 2D6618FEA2 for ; Fri, 8 Apr 2011 14:15:07 +0200 (CEST) Date: Fri, 08 Apr 2011 12:15:00 -0000 From: Richard Guenther To: gcc-patches@gcc.gnu.org Subject: [PATCH] Abstract call stmt function type Message-ID: User-Agent: Alpine 2.00 (LNX 1167 2008-08-23) MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2011-04/txt/msg00618.txt.bz2 This prepares a patch that makes the type of the called function explicit in gimple calls rather than taking this information from the called function pointer. It introduces a gimple_call_fntype accessor that the replaces TREE_TYPE (TREE_TYPE (gimple_call_fn ()))) pattern used everywhere (which also exposes the fact that the call-fn is a pointer-to-function). gimple_call_fn () calls should be rare, and now they are even rarer. Bootstrapped and tested on x86_64-unknown-linux-gnu, applied to trunk. Richard. 2011-04-08 Richard Guenther * gimple.h (gimple_call_fntype): New function. (gimple_call_return_type): Use it. * expr.c (expand_expr_real_1): Use gimple_call_fntype. * gimple-low.c (gimple_check_call_args): Likewise. * gimple.c (gimple_call_flags): Likewise. (gimple_call_arg_flags): Likewise. (gimple_call_return_flags): Likewise. * tree-cfg.c (verify_gimple_call): Likewise. (do_warn_unused_result): Likewise. * tree-ssa-ccp.c (ccp_fold_stmt): Likewise. * value-prof.c (gimple_ic_transform): Fix fndecl check. Index: trunk/gcc/expr.c =================================================================== *** trunk.orig/gcc/expr.c 2011-04-05 12:52:46.000000000 +0200 --- trunk/gcc/expr.c 2011-04-07 15:50:04.000000000 +0200 *************** expand_expr_real_1 (tree exp, rtx target *** 8533,8540 **** && (g = SSA_NAME_DEF_STMT (ssa_name)) && gimple_code (g) == GIMPLE_CALL) pmode = promote_function_mode (type, mode, &unsignedp, ! TREE_TYPE ! (TREE_TYPE (gimple_call_fn (g))), 2); else pmode = promote_decl_mode (exp, &unsignedp); --- 8533,8539 ---- && (g = SSA_NAME_DEF_STMT (ssa_name)) && gimple_code (g) == GIMPLE_CALL) pmode = promote_function_mode (type, mode, &unsignedp, ! gimple_call_fntype (g), 2); else pmode = promote_decl_mode (exp, &unsignedp); Index: trunk/gcc/gimple-low.c =================================================================== *** trunk.orig/gcc/gimple-low.c 2011-04-06 12:18:25.000000000 +0200 --- trunk/gcc/gimple-low.c 2011-04-07 15:49:29.000000000 +0200 *************** gimple_check_call_args (gimple stmt) *** 222,232 **** /* Get argument types for verification. */ fndecl = gimple_call_fndecl (stmt); - parms = NULL_TREE; if (fndecl) parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); ! else if (POINTER_TYPE_P (TREE_TYPE (gimple_call_fn (stmt)))) ! parms = TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (gimple_call_fn (stmt)))); /* Verify if the type of the argument matches that of the function declaration. If we cannot verify this or there is a mismatch, --- 222,231 ---- /* Get argument types for verification. */ fndecl = gimple_call_fndecl (stmt); if (fndecl) parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl)); ! else ! parms = TYPE_ARG_TYPES (gimple_call_fntype (stmt)); /* Verify if the type of the argument matches that of the function declaration. If we cannot verify this or there is a mismatch, Index: trunk/gcc/gimple.c =================================================================== *** trunk.orig/gcc/gimple.c 2011-04-05 12:52:47.000000000 +0200 --- trunk/gcc/gimple.c 2011-04-08 12:55:31.000000000 +0200 *************** gimple_call_flags (const_gimple stmt) *** 1780,1794 **** { int flags; tree decl = gimple_call_fndecl (stmt); - tree t; if (decl) flags = flags_from_decl_or_type (decl); else { ! t = TREE_TYPE (gimple_call_fn (stmt)); ! if (t && TREE_CODE (t) == POINTER_TYPE) ! flags = flags_from_decl_or_type (TREE_TYPE (t)); else flags = 0; } --- 1780,1796 ---- { int flags; tree decl = gimple_call_fndecl (stmt); if (decl) flags = flags_from_decl_or_type (decl); else { ! tree t = TREE_TYPE (gimple_call_fn (stmt)); ! /* ??? We can end up being called from gimple_set_modified from ! gsi_remove in which case the function being called can ! be a released SSA name. Give up in that case. */ ! if (t) ! flags = flags_from_decl_or_type (gimple_call_fntype (stmt)); else flags = 0; } *************** gimple_call_flags (const_gimple stmt) *** 1804,1810 **** int gimple_call_arg_flags (const_gimple stmt, unsigned arg) { ! tree type = TREE_TYPE (TREE_TYPE (gimple_call_fn (stmt))); tree attr = lookup_attribute ("fn spec", TYPE_ATTRIBUTES (type)); if (!attr) return 0; --- 1806,1812 ---- int gimple_call_arg_flags (const_gimple stmt, unsigned arg) { ! tree type = gimple_call_fntype (stmt); tree attr = lookup_attribute ("fn spec", TYPE_ATTRIBUTES (type)); if (!attr) return 0; *************** gimple_call_return_flags (const_gimple s *** 1848,1854 **** if (gimple_call_flags (stmt) & ECF_MALLOC) return ERF_NOALIAS; ! type = TREE_TYPE (TREE_TYPE (gimple_call_fn (stmt))); attr = lookup_attribute ("fn spec", TYPE_ATTRIBUTES (type)); if (!attr) return 0; --- 1850,1856 ---- if (gimple_call_flags (stmt) & ECF_MALLOC) return ERF_NOALIAS; ! type = gimple_call_fntype (stmt); attr = lookup_attribute ("fn spec", TYPE_ATTRIBUTES (type)); if (!attr) return 0; Index: trunk/gcc/gimple.h =================================================================== *** trunk.orig/gcc/gimple.h 2011-03-17 13:38:06.000000000 +0100 --- trunk/gcc/gimple.h 2011-04-07 15:51:37.000000000 +0200 *************** gimple_call_fn (const_gimple gs) *** 2011,2016 **** --- 2011,2023 ---- return gimple_op (gs, 1); } + /* Return the function type of the function called by GS. */ + + static inline tree + gimple_call_fntype (const_gimple gs) + { + return TREE_TYPE (TREE_TYPE (gimple_call_fn (gs))); + } /* Return a pointer to the tree node representing the function called by call statement GS. */ *************** gimple_call_fndecl (const_gimple gs) *** 2073,2085 **** static inline tree gimple_call_return_type (const_gimple gs) { ! tree fn = gimple_call_fn (gs); ! tree type = TREE_TYPE (fn); ! ! /* See through the pointer. */ ! type = TREE_TYPE (type); ! /* The type returned by a FUNCTION_DECL is the type of its function type. */ return TREE_TYPE (type); } --- 2080,2088 ---- static inline tree gimple_call_return_type (const_gimple gs) { ! tree type = gimple_call_fntype (gs); ! /* The type returned by a function is the type of its function type. */ return TREE_TYPE (type); } Index: trunk/gcc/tree-cfg.c =================================================================== *** trunk.orig/gcc/tree-cfg.c 2011-03-31 12:01:01.000000000 +0200 --- trunk/gcc/tree-cfg.c 2011-04-07 15:45:54.000000000 +0200 *************** verify_gimple_call (gimple stmt) *** 3159,3165 **** return true; } ! fntype = TREE_TYPE (TREE_TYPE (fn)); if (gimple_call_lhs (stmt) && !useless_type_conversion_p (TREE_TYPE (gimple_call_lhs (stmt)), TREE_TYPE (fntype)) --- 3159,3165 ---- return true; } ! fntype = gimple_call_fntype (stmt); if (gimple_call_lhs (stmt) && !useless_type_conversion_p (TREE_TYPE (gimple_call_lhs (stmt)), TREE_TYPE (fntype)) *************** do_warn_unused_result (gimple_seq seq) *** 7513,7519 **** LHS. All calls whose value is ignored should be represented like this. Look for the attribute. */ fdecl = gimple_call_fndecl (g); ! ftype = TREE_TYPE (TREE_TYPE (gimple_call_fn (g))); if (lookup_attribute ("warn_unused_result", TYPE_ATTRIBUTES (ftype))) { --- 7513,7519 ---- LHS. All calls whose value is ignored should be represented like this. Look for the attribute. */ fdecl = gimple_call_fndecl (g); ! ftype = gimple_call_fntype (g); if (lookup_attribute ("warn_unused_result", TYPE_ATTRIBUTES (ftype))) { Index: trunk/gcc/tree-ssa-ccp.c =================================================================== *** trunk.orig/gcc/tree-ssa-ccp.c 2011-03-24 13:33:34.000000000 +0100 --- trunk/gcc/tree-ssa-ccp.c 2011-04-07 15:43:51.000000000 +0200 *************** ccp_fold_stmt (gimple_stmt_iterator *gsi *** 1727,1733 **** this can use the argument slot types for type verification instead of the current argument type. We also can safely drop qualifiers here as we are dealing with constants anyway. */ ! argt = TYPE_ARG_TYPES (TREE_TYPE (TREE_TYPE (gimple_call_fn (stmt)))); for (i = 0; i < gimple_call_num_args (stmt) && argt; ++i, argt = TREE_CHAIN (argt)) { --- 1727,1733 ---- this can use the argument slot types for type verification instead of the current argument type. We also can safely drop qualifiers here as we are dealing with constants anyway. */ ! argt = TYPE_ARG_TYPES (gimple_call_fntype (stmt)); for (i = 0; i < gimple_call_num_args (stmt) && argt; ++i, argt = TREE_CHAIN (argt)) { Index: trunk/gcc/value-prof.c =================================================================== *** trunk.orig/gcc/value-prof.c 2011-01-31 12:48:06.000000000 +0100 --- trunk/gcc/value-prof.c 2011-04-07 16:10:42.000000000 +0200 *************** gimple_ic_transform (gimple stmt) *** 1230,1245 **** histogram_value histogram; gcov_type val, count, all, bb_all; gcov_type prob; - tree callee; gimple modify; struct cgraph_node *direct_call; if (gimple_code (stmt) != GIMPLE_CALL) return false; ! callee = gimple_call_fn (stmt); ! ! if (TREE_CODE (callee) == FUNCTION_DECL) return false; histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_INDIR_CALL); --- 1230,1242 ---- histogram_value histogram; gcov_type val, count, all, bb_all; gcov_type prob; gimple modify; struct cgraph_node *direct_call; if (gimple_code (stmt) != GIMPLE_CALL) return false; ! if (gimple_call_fndecl (stmt) != NULL_TREE) return false; histogram = gimple_histogram_value_of_type (cfun, stmt, HIST_TYPE_INDIR_CALL);