From patchwork Tue Oct 16 15:14:00 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 191814 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]) by ozlabs.org (Postfix) with SMTP id 46A3E2C009A for ; Wed, 17 Oct 2012 02:14:19 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1351005259; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Date: From:To:Subject:Message-ID:MIME-Version:Content-Type: Content-Disposition:User-Agent:Mailing-List:Precedence:List-Id: List-Unsubscribe:List-Archive:List-Post:List-Help:Sender: Delivered-To; bh=j+xaMU2Sjjvupzl4Xo+U5Vb0b/E=; b=gb0FRsn19CYU94o BD031Y0/WyIJD2GnBC6stEy7wHh8H1hP7YbG/QlLdk00v8mhiyXiaFjpY8LKR1wb pB8FapdXsQ88ub7+BEgW+HnXpujvUGz154PHmXbJp85mO5iu+srQQYZZ7o4M+I2Y nn3oSN+yqp25zchPtkFTESyhldNM= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Date:From:To:Subject:Message-ID:MIME-Version:Content-Type:Content-Disposition:User-Agent:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=rMGMHtOkVesZQrdUEMPnl9F4CaOEdkjf7xZFKa47hPaN0hfKJX1QVeQAFAlK3P 1J/C16lws7iGmO5R+6HcjYcJZA2/8VjskhqPi340OCTwt1it04w/tLjmreaC9/9p ZwNAaDdZ7o86dnQjkFZPyFRCwHD5Kdu33MEQT7ftFNCqs=; Received: (qmail 17974 invoked by alias); 16 Oct 2012 15:14:12 -0000 Received: (qmail 17945 invoked by uid 22791); 16 Oct 2012 15:14:11 -0000 X-SWARE-Spam-Status: No, hits=-4.0 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, RCVD_IN_DNSWL_LOW, RCVD_IN_HOSTKARMA_W, RCVD_IN_HOSTKARMA_WL, RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from nikam.ms.mff.cuni.cz (HELO nikam.ms.mff.cuni.cz) (195.113.20.16) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 16 Oct 2012 15:14:02 +0000 Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id 468CF5437C7; Tue, 16 Oct 2012 17:14:00 +0200 (CEST) Date: Tue, 16 Oct 2012 17:14:00 +0200 From: Jan Hubicka To: gcc-patches@gcc.gnu.org, ian@airs.com Subject: [go] bulitins housekeeping; add __bultin_unreachable Message-ID: <20121016151400.GB4090@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) 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 Hi, this patch udpates go-frontend to deifine unreachable bultin I need for loop and LTO optimizations. I also noticed that GO ignores existence of all flags except for CONST and thus I synchronized the flags with C FE variants. (I plan to use set_call_expr_flags in other FEs too) Regtested x86_64-linux, OK? Honza * gofrontend/gogo-tree.cc (define_bultin): Accept ECF flags and use set_call_expr_flags. (define_builtin_function_trees): Update; add BULIT_IN_UNREACHALE. * calls.c (set_call_expr_flags): New. * tree.h (set_call_expr_flags): Declare. Index: go/gofrontend/gogo-tree.cc =================================================================== --- go/gofrontend/gogo-tree.cc (revision 192483) +++ go/gofrontend/gogo-tree.cc (working copy) @@ -50,24 +50,22 @@ static std::map built // defined by builtins.def. NAME is the name of the builtin function. // LIBNAME is the name of the corresponding library function, and is // NULL if there isn't one. FNTYPE is the type of the function. -// CONST_P is true if the function has the const attribute. +// FLAGS specify fnction attributes. static void define_builtin(built_in_function bcode, const char* name, const char* libname, - tree fntype, bool const_p) + tree fntype, int flags) { tree decl = add_builtin_function(name, fntype, bcode, BUILT_IN_NORMAL, libname, NULL_TREE); - if (const_p) - TREE_READONLY(decl) = 1; set_builtin_decl(bcode, decl, true); + set_call_expr_flags (decl, flags); builtin_functions[name] = decl; if (libname != NULL) { decl = add_builtin_function(libname, fntype, bcode, BUILT_IN_NORMAL, NULL, NULL_TREE); - if (const_p) - TREE_READONLY(decl) = 1; + set_call_expr_flags (decl, flags); builtin_functions[libname] = decl; } } @@ -82,22 +80,22 @@ Gogo::define_builtin_function_trees() tree t = go_type_for_size(BITS_PER_UNIT, 1); tree p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE)); define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_1, "__sync_fetch_and_add_1", NULL, - build_function_type_list(t, p, t, NULL_TREE), false); + build_function_type_list(t, p, t, NULL_TREE), ECF_LEAF | ECF_NOTHROW); t = go_type_for_size(BITS_PER_UNIT * 2, 1); p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE)); define_builtin (BUILT_IN_SYNC_ADD_AND_FETCH_2, "__sync_fetch_and_add_2", NULL, - build_function_type_list(t, p, t, NULL_TREE), false); + build_function_type_list(t, p, t, NULL_TREE), ECF_LEAF | ECF_NOTHROW); t = go_type_for_size(BITS_PER_UNIT * 4, 1); p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE)); define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_4, "__sync_fetch_and_add_4", NULL, - build_function_type_list(t, p, t, NULL_TREE), false); + build_function_type_list(t, p, t, NULL_TREE), ECF_LEAF | ECF_NOTHROW); t = go_type_for_size(BITS_PER_UNIT * 8, 1); p = build_pointer_type(build_qualified_type(t, TYPE_QUAL_VOLATILE)); define_builtin(BUILT_IN_SYNC_ADD_AND_FETCH_8, "__sync_fetch_and_add_8", NULL, - build_function_type_list(t, p, t, NULL_TREE), false); + build_function_type_list(t, p, t, NULL_TREE), ECF_LEAF | ECF_NOTHROW); // We use __builtin_expect for magic import functions. define_builtin(BUILT_IN_EXPECT, "__builtin_expect", NULL, @@ -105,7 +103,13 @@ Gogo::define_builtin_function_trees() long_integer_type_node, long_integer_type_node, NULL_TREE), - true); + ECF_CONST | ECF_NOTHROW | ECF_LEAF); + + // Middle-end use __builtin_unreachable + define_builtin(BUILT_IN_UNREACHABLE, "__builtin_unreachable", NULL, + build_function_type(void_type_node, + void_list_node), + ECF_NOTHROW | ECF_LEAF | ECF_NORETURN); // We use __builtin_memcmp for struct comparisons. define_builtin(BUILT_IN_MEMCMP, "__builtin_memcmp", "memcmp", @@ -114,7 +118,8 @@ Gogo::define_builtin_function_trees() const_ptr_type_node, size_type_node, NULL_TREE), - false); + ECF_LEAF | ECF_NOTHROW | ECF_PURE); + /* TODO: add non-null attribute. */ // We provide some functions for the math library. tree math_function_type = build_function_type_list(double_type_node, @@ -131,93 +136,93 @@ Gogo::define_builtin_function_trees() build_function_type_list(long_double_type_node, long_double_type_node, long_double_type_node, NULL_TREE); define_builtin(BUILT_IN_ACOS, "__builtin_acos", "acos", - math_function_type, true); + math_function_type, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_ACOSL, "__builtin_acosl", "acosl", - math_function_type_long, true); + math_function_type_long, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_ASIN, "__builtin_asin", "asin", - math_function_type, true); + math_function_type, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_ASINL, "__builtin_asinl", "asinl", - math_function_type_long, true); + math_function_type_long, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_ATAN, "__builtin_atan", "atan", - math_function_type, true); + math_function_type, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_ATANL, "__builtin_atanl", "atanl", - math_function_type_long, true); + math_function_type_long, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_ATAN2, "__builtin_atan2", "atan2", - math_function_type_two, true); + math_function_type_two, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_ATAN2L, "__builtin_atan2l", "atan2l", - math_function_type_long_two, true); + math_function_type_long_two, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_CEIL, "__builtin_ceil", "ceil", - math_function_type, true); + math_function_type, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_CEILL, "__builtin_ceill", "ceill", - math_function_type_long, true); + math_function_type_long, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_COS, "__builtin_cos", "cos", - math_function_type, true); + math_function_type, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_COSL, "__builtin_cosl", "cosl", - math_function_type_long, true); + math_function_type_long, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_EXP, "__builtin_exp", "exp", - math_function_type, true); + math_function_type, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_EXPL, "__builtin_expl", "expl", - math_function_type_long, true); + math_function_type_long, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_EXPM1, "__builtin_expm1", "expm1", - math_function_type, true); + math_function_type, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_EXPM1L, "__builtin_expm1l", "expm1l", - math_function_type_long, true); + math_function_type_long, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_FABS, "__builtin_fabs", "fabs", - math_function_type, true); + math_function_type, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_FABSL, "__builtin_fabsl", "fabsl", - math_function_type_long, true); + math_function_type_long, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_FLOOR, "__builtin_floor", "floor", - math_function_type, true); + math_function_type, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_FLOORL, "__builtin_floorl", "floorl", - math_function_type_long, true); + math_function_type_long, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_FMOD, "__builtin_fmod", "fmod", - math_function_type_two, true); + math_function_type_two, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_FMODL, "__builtin_fmodl", "fmodl", - math_function_type_long_two, true); + math_function_type_long_two, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_LDEXP, "__builtin_ldexp", "ldexp", build_function_type_list(double_type_node, double_type_node, integer_type_node, NULL_TREE), - true); + ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_LDEXPL, "__builtin_ldexpl", "ldexpl", build_function_type_list(long_double_type_node, long_double_type_node, integer_type_node, NULL_TREE), - true); + ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_LOG, "__builtin_log", "log", - math_function_type, true); + math_function_type, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_LOGL, "__builtin_logl", "logl", - math_function_type_long, true); + math_function_type_long, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_LOG1P, "__builtin_log1p", "log1p", - math_function_type, true); + math_function_type, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_LOG1PL, "__builtin_log1pl", "log1pl", - math_function_type_long, true); + math_function_type_long, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_LOG10, "__builtin_log10", "log10", - math_function_type, true); + math_function_type, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_LOG10L, "__builtin_log10l", "log10l", - math_function_type_long, true); + math_function_type_long, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_LOG2, "__builtin_log2", "log2", - math_function_type, true); + math_function_type, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_LOG2L, "__builtin_log2l", "log2l", - math_function_type_long, true); + math_function_type_long, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_SIN, "__builtin_sin", "sin", - math_function_type, true); + math_function_type, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_SINL, "__builtin_sinl", "sinl", - math_function_type_long, true); + math_function_type_long, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_SQRT, "__builtin_sqrt", "sqrt", - math_function_type, true); + math_function_type, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_SQRTL, "__builtin_sqrtl", "sqrtl", - math_function_type_long, true); + math_function_type_long, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_TAN, "__builtin_tan", "tan", - math_function_type, true); + math_function_type, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_TANL, "__builtin_tanl", "tanl", - math_function_type_long, true); + math_function_type_long, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_TRUNC, "__builtin_trunc", "trunc", - math_function_type, true); + math_function_type, ECF_CONST | ECF_NOTHROW | ECF_LEAF); define_builtin(BUILT_IN_TRUNCL, "__builtin_truncl", "truncl", - math_function_type_long, true); + math_function_type_long, ECF_CONST | ECF_NOTHROW | ECF_LEAF); // We use __builtin_return_address in the thunk we build for // functions which call recover. @@ -225,13 +230,13 @@ Gogo::define_builtin_function_trees() build_function_type_list(ptr_type_node, unsigned_type_node, NULL_TREE), - false); + ECF_LEAF); // The compiler uses __builtin_trap for some exception handling // cases. define_builtin(BUILT_IN_TRAP, "__builtin_trap", NULL, build_function_type(void_type_node, void_list_node), - false); + ECF_NOTHROW | ECF_LEAF | ECF_NORETURN); } // Get the name to use for the import control function. If there is a Index: calls.c =================================================================== --- calls.c (revision 192483) +++ calls.c (working copy) @@ -802,6 +802,36 @@ call_expr_flags (const_tree t) return flags; } +/* Modify DECL for given flags. */ +void +set_call_expr_flags (tree decl, int flags) +{ + if (flags & ECF_NOTHROW) + TREE_NOTHROW (decl) = 1; + if (flags & ECF_CONST) + TREE_READONLY (decl) = 1; + if (flags & ECF_PURE) + DECL_PURE_P (decl) = 1; + if (flags & ECF_NOVOPS) + DECL_IS_NOVOPS (decl) = 1; + if (flags & ECF_NORETURN) + TREE_THIS_VOLATILE (decl) = 1; + if (flags & ECF_MALLOC) + DECL_IS_MALLOC (decl) = 1; + if (flags & ECF_RETURNS_TWICE) + DECL_IS_RETURNS_TWICE (decl) = 1; + if (flags & ECF_LEAF) + DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("leaf"), + NULL, DECL_ATTRIBUTES (decl)); + if (flags & ECF_TM_PURE) + DECL_ATTRIBUTES (decl) = tree_cons (get_identifier ("transaction_pure"), + NULL, DECL_ATTRIBUTES (decl)); + /* Looping const or pure is imlpies by noreturn. + There is currently no way to declare looping const or looping pure alone. */ + gcc_assert (!(flags & ECF_LOOPING_CONST_OR_PURE) + || ((flags & ECF_NORETURN) && (flags & (ECF_CONST | ECF_PURE)))); +} + /* Precompute all register parameters as described by ARGS, storing values into fields within the ARGS array. Index: tree.h =================================================================== --- tree.h (revision 192483) +++ tree.h (working copy) @@ -6025,6 +6025,7 @@ extern tree build_duplicate_type (tree); extern int flags_from_decl_or_type (const_tree); extern int call_expr_flags (const_tree); +extern void set_call_expr_flags (tree, int); /* Call argument flags. */