From patchwork Sat Nov 7 12:35:56 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 541280 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 799ED1402D4 for ; Sat, 7 Nov 2015 23:36:13 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=PvViS4D/; 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:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=voOAe/oja1Hp8kBb yWSA7K0ZQYZwehELtLZiFcTPfsGxI9GOkyuJyA0ISWrjHRVJMHfZMqrZ1+ahByMs fuZMoMz1JkB04wKrlZ70p3D2C2Zya79s9nL/uek9fmjIAsNLOpwwqKxa7q0YwByi r2wh4jCUrvjroIGT/VGUwLGYvEQ= 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:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; s=default; bh=2xU/oCDA0rbBmt1gUwCnRr lRPRk=; b=PvViS4D/tK3TZnNzy/AIk2a02Da/Ih52ncdi6bjqyk6kdDdkDMVWcY PHRwub90HnKVe21PCYfx5MxOG7oz5aD8oFrPdgrnZrMCa+zPMlgS/eFVu9MYzC7s nBS0gqLB6yCbFYwfrRzwEUuRK5Fw4qkRinrZorPNcRUCFn8dHOjlw= Received: (qmail 13181 invoked by alias); 7 Nov 2015 12:36:05 -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 13167 invoked by uid 89); 7 Nov 2015 12:36:03 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.8 required=5.0 tests=AWL, BAYES_05, SPF_PASS autolearn=ham version=3.3.2 X-HELO: eu-smtp-delivery-143.mimecast.com Received: from eu-smtp-delivery-143.mimecast.com (HELO eu-smtp-delivery-143.mimecast.com) (146.101.78.143) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Sat, 07 Nov 2015 12:36:01 +0000 Received: from cam-owa1.Emea.Arm.com (fw-tnat.cambridge.arm.com [217.140.96.140]) by eu-smtp-1.mimecast.com with ESMTP id uk-mta-1-mWa9SPUWRtSGCXjYgLpenA-1; Sat, 07 Nov 2015 12:35:56 +0000 Received: from localhost ([10.1.2.79]) by cam-owa1.Emea.Arm.com with Microsoft SMTPSVC(6.0.3790.3959); Sat, 7 Nov 2015 12:35:56 +0000 From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: Add gencfn-macros.c Date: Sat, 07 Nov 2015 12:35:56 +0000 Message-ID: <87y4eaq95f.fsf@e105548-lin.cambridge.arm.com> User-Agent: Gnus/5.130012 (Ma Gnus v0.12) Emacs/24.3 (gnu/linux) MIME-Version: 1.0 X-MC-Unique: mWa9SPUWRtSGCXjYgLpenA-1 This patch automatically generates case macros such as: CASE_CFN_SQRT for each {F,,L} floating-point built-in function and each {,L,LL,IMAX} integer built-in function. The macros match the same built-in functions as CASE_FLT_FN and CASE_INT_FN but in addition include the associated internal function, if any. The idea is to make sure that users of combined_fn don't need to know which built-in functions have internal-function equivalents. If we add a new function to internal-fn.def, all combined_fn users should pick it up automatically. The generator wants to use "hash_set ", so the patch follows hash_map in using the types given by the traits as the key. This is a no-op for current users of hash_set. Tested on x86_64-linux-gnu, aarch64-linux-gnu and arm-linux-gnueabi. OK to install? Thanks, Richard gcc/ * Makefile.in (HASH_TABLE_H): Add GGC_H. (MOSTLYCLEANFILES, generated_files): Add case-fn-macros.h. (s-case-cfn-macros, case-cfn-macros.h, build/gencfn-macros.o) (build/gencfn-macros$(build_exeext): New rules. (genprogerr): Add cfn-macros. * hash-set.h (hash_set): Use the traits value_type as the key. * gencfn-macros.c: New file. diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 34d2356..298bb38 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -876,7 +876,7 @@ endif # Shorthand variables for dependency lists. DUMPFILE_H = $(srcdir)/../libcpp/include/line-map.h dumpfile.h VEC_H = vec.h statistics.h $(GGC_H) -HASH_TABLE_H = $(HASHTAB_H) hash-table.h +HASH_TABLE_H = $(HASHTAB_H) hash-table.h $(GGC_H) EXCEPT_H = except.h $(HASHTAB_H) TARGET_DEF = target.def target-hooks-macros.h target-insns.def C_TARGET_DEF = c-family/c-target.def target-hooks-macros.h @@ -1566,6 +1566,7 @@ MOSTLYCLEANFILES = insn-flags.h insn-config.h insn-codes.h \ tm-preds.h tm-constrs.h checksum-options gimple-match.c generic-match.c \ tree-check.h min-insn-modes.c insn-modes.c insn-modes.h \ genrtl.h gt-*.h gtype-*.h gtype-desc.c gtyp-input.list \ + case-cfn-macros.h \ xgcc$(exeext) cpp$(exeext) $(FULL_DRIVER_NAME) \ $(EXTRA_PROGRAMS) gcc-cross$(exeext) \ $(SPECS) collect2$(exeext) gcc-ar$(exeext) gcc-nm$(exeext) \ @@ -2243,6 +2244,14 @@ s-constrs-h: $(MD_DEPS) build/genpreds$(build_exeext) $(SHELL) $(srcdir)/../move-if-change tmp-constrs.h tm-constrs.h $(STAMP) s-constrs-h +s-case-cfn-macros: build/gencfn-macros$(build_exeext) + $(RUN_GEN) build/gencfn-macros$(build_exeext) -c \ + > tmp-case-cfn-macros.h + $(SHELL) $(srcdir)/../move-if-change tmp-case-cfn-macros.h \ + case-cfn-macros.h + $(STAMP) s-case-cfn-macros +case-cfn-macros.h: s-case-cfn-macros; @true + target-hooks-def.h: s-target-hooks-def-h; @true # make sure that when we build info files, the used tm.texi is up to date. $(srcdir)/doc/tm.texi: s-tm-texi; @true @@ -2430,7 +2439,7 @@ generated_files = config.h tm.h $(TM_P_H) $(TM_H) multilib.h \ $(ALL_GTFILES_H) gtype-desc.c gtype-desc.h gcov-iov.h \ options.h target-hooks-def.h insn-opinit.h \ common/common-target-hooks-def.h pass-instances.def \ - c-family/c-target-hooks-def.h params.list + c-family/c-target-hooks-def.h params.list case-cfn-macros.h # # How to compile object files to run on the build machine. @@ -2577,6 +2586,8 @@ build/genmddump.o : genmddump.c $(RTL_BASE_H) $(BCONFIG_H) $(SYSTEM_H) \ build/genmatch.o : genmatch.c $(BCONFIG_H) $(SYSTEM_H) \ coretypes.h errors.h $(HASH_TABLE_H) hash-map.h $(GGC_H) is-a.h \ tree.def builtins.def +build/gencfn-macros.o : gencfn-macros.c $(BCONFIG_H) $(SYSTEM_H) \ + coretypes.h errors.h $(HASH_TABLE_H) hash-set.h builtins.def internal-fn.def # Compile the programs that generate insn-* from the machine description. # They are compiled with $(COMPILER_FOR_BUILD), and associated libraries, @@ -2593,7 +2604,7 @@ genprogmd = $(genprogrtl) mddeps constants enums $(genprogmd:%=build/gen%$(build_exeext)): $(BUILD_MD) # All these programs need to report errors. -genprogerr = $(genprogmd) genrtl modes gtype hooks +genprogerr = $(genprogmd) genrtl modes gtype hooks cfn-macros $(genprogerr:%=build/gen%$(build_exeext)): $(BUILD_ERRORS) # Remaining build programs. @@ -2603,6 +2614,7 @@ genprog = $(genprogerr) check checksum condmd match build/genautomata$(build_exeext) : BUILD_LIBS += -lm build/genrecog$(build_exeext) : build/hash-table.o build/inchash.o +build/gencfn-macros$(build_exeext) : build/hash-table.o build/ggc-none.o # For stage1 and when cross-compiling use the build libcpp which is # built with NLS disabled. For stage2+ use the host library and diff --git a/gcc/gencfn-macros.c b/gcc/gencfn-macros.c new file mode 100644 index 0000000..5ee3af0 --- /dev/null +++ b/gcc/gencfn-macros.c @@ -0,0 +1,176 @@ +/* Generate macros based on the combined_fn enum. + Copyright (C) 2015 Free Software Foundation, Inc. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +. */ + +/* Automatically generate code fragments related to combined_fn. + + The program looks for math built-in functions that have float, double + and long double variants, such as {sqrtf, sqrt, sqrtl}, and that may + or may not have an associated internal function as well. It also looks + for integer built-in functions that have int, long, long long and + intmax_t variants, such as {clz, clzl, clzll, clzimax}, and that + again may or may not have an associated internal function as well. + + When run with -c, the generator prints a list of macros such as: + + CASE_CFN_SQRT + + for each group of functions described above, with 'case CFN_*' + statements for each built-in and internal function in the group. + For example, there are both built-in and internal implementations + of SQRT, so "CASE_CFN_SQRT:" is equivalent to: + + case CFN_BUILT_IN_SQRTF: + case CFN_BUILT_IN_SQRT: + case CFN_BUILT_IN_SQRTL: + case CFN_SQRT: + + The macros for groups with no internal function drop the last line. */ + +#include "bconfig.h" +#include "system.h" +#include "coretypes.h" +#include "hash-table.h" +#include "hash-set.h" +#include "errors.h" + +typedef hash_set string_set; + +/* Add all names in null-terminated list NAMES to SET. */ + +static void +add_to_set (string_set *set, const char *const *names) +{ + for (unsigned int i = 0; names[i]; ++i) + set->add (names[i]); +} + +/* Return true if *BUILTINS contains BUILT_IN_ for all + suffixes in null-terminated list SUFFIXES. */ + +static bool +is_group (string_set *builtins, const char *name, const char *const *suffixes) +{ + for (unsigned int i = 0; suffixes[i]; ++i) + if (!builtins->contains (ACONCAT (("BUILT_IN_", name, suffixes[i], NULL)))) + return false; + return true; +} + +/* Print a macro for all combined functions related to NAME, with the + null-terminated list of suffixes in SUFFIXES. INTERNAL_P says whether + CFN_ also exists. */ + +static void +print_case_cfn (const char *name, bool internal_p, + const char *const *suffixes) +{ + printf ("#define CASE_CFN_%s", name); + if (internal_p) + printf (" \\\n case CFN_%s", name); + for (unsigned int i = 0; suffixes[i]; ++i) + printf ("%s \\\n case CFN_BUILT_IN_%s%s", + internal_p || i > 0 ? ":" : "", name, suffixes[i]); + printf ("\n"); +} + +const char *const builtin_names[] = { +#define DEF_BUILTIN(ENUM, N, C, T, LT, B, F, NA, AT, IM, COND) \ + #ENUM, +#include "builtins.def" + NULL +}; + +const char *const internal_fn_flt_names[] = { +#define DEF_INTERNAL_FLT_FN(NAME, FLAGS, OPTAB, TYPE) \ + #NAME, +#include "internal-fn.def" + NULL +}; + +const char *const internal_fn_int_names[] = { +#define DEF_INTERNAL_INT_FN(NAME, FLAGS, OPTAB, TYPE) \ + #NAME, +#include "internal-fn.def" + NULL +}; + +static const char *const flt_suffixes[] = { "F", "", "L", NULL }; +static const char *const int_suffixes[] = { "", "L", "LL", "IMAX", NULL }; + +static const char *const *const suffix_lists[] = { + flt_suffixes, + int_suffixes, + NULL +}; + +int +main (int argc, char **argv) +{ + /* Check arguments. */ + progname = argv[0]; + if (argc != 2 + || argv[1][0] != '-' + || argv[1][1] != 'c' + || argv[1][2]) + fatal ("usage: %s -c > file", progname); + + /* Collect the set of built-in and internal functions. */ + string_set builtins; + string_set internal_fns; + add_to_set (&builtins, builtin_names); + add_to_set (&internal_fns, internal_fn_flt_names); + add_to_set (&internal_fns, internal_fn_int_names); + + /* Check the functions. */ + for (unsigned int i = 0; internal_fn_flt_names[i]; ++i) + { + const char *name = internal_fn_flt_names[i]; + if (!is_group (&builtins, name, flt_suffixes)) + error ("DEF_INTERNAL_FLT_FN (%s) has no associated built-in" + " functions", name); + } + for (unsigned int i = 0; internal_fn_int_names[i]; ++i) + { + const char *name = internal_fn_int_names[i]; + if (!is_group (&builtins, name, int_suffixes)) + error ("DEF_INTERNAL_INT_FN (%s) has no associated built-in" + " functions", name); + } + + /* Go through the built-in functions in declaration order, outputting + definitions as appropriate. */ + for (unsigned int i = 0; builtin_names[i]; ++i) + { + const char *name = builtin_names[i]; + if (strncmp (name, "BUILT_IN_", 9) == 0) + { + const char *root = name + 9; + for (unsigned int j = 0; suffix_lists[j]; ++j) + if (is_group (&builtins, root, suffix_lists[j])) + { + bool internal_p = internal_fns.contains (root); + print_case_cfn (root, internal_p, suffix_lists[j]); + } + } + } + + if (fflush (stdout) || fclose (stdout) || have_error) + return FATAL_EXIT_CODE; + return SUCCESS_EXIT_CODE; +} diff --git a/gcc/hash-set.h b/gcc/hash-set.h index e85af2a..679d2b6 100644 --- a/gcc/hash-set.h +++ b/gcc/hash-set.h @@ -21,10 +21,11 @@ along with GCC; see the file COPYING3. If not see #ifndef hash_set_h #define hash_set_h -template > +template > class hash_set { public: + typedef typename Traits::value_type Key; explicit hash_set (size_t n = 13, bool ggc = false CXX_MEM_STAT_INFO) : m_table (n, ggc, true, HASH_SET_ORIGIN PASS_MEM_STAT) {}