]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
gensupport.c: Include hashtab.h.
authorZack Weinberg <zack@gcc.gnu.org>
Mon, 29 Jul 2002 18:02:47 +0000 (18:02 +0000)
committerZack Weinberg <zack@gcc.gnu.org>
Mon, 29 Jul 2002 18:02:47 +0000 (18:02 +0000)
* gensupport.c: Include hashtab.h.
(insn_elision, condition_table, hash_c_test, cmp_c_test,
maybe_eval_c_test): New routines and data structures to
support insn elision.
(init_md_reader): Read and initialize the condition_table.
(read_md_rtx): Discard insn patterns whose C test is provably
always false.
* gensupport.h: Declare new functions and data structures.

* genconditions.c, dummy-conditions.c: New files.
* Makefile.in: Build genconditions; run it to construct
insn-conditions.c; build that and link it into most gen*
programs.
(HOST_SUPPORT, HOST_EARLY_SUPPORT): New variables.
(GEN): Delete, unused.
(STAGESTUFF): Update.

* gencodes.c: (gen_insn): #define CODE_FOR_xxx equal to
CODE_FOR_nothing for all elided patterns.
(main): Tweaked to support this.
* genflags.c (gen_proto): Emit a static inline generator
function here for all elided patterns, which simply returns
NULL_RTX.
(gen_insn): Do not define HAVE_xxx for elided patterns.
(main): Tweaked to support this.  No need to forward-declare
struct rtx_def.
* genrecog.c: Do not bother emitting the C test if it's known
to be true at compile time.

From-SVN: r55839

gcc/ChangeLog
gcc/Makefile.in
gcc/dummy-conditions.c [new file with mode: 0644]
gcc/gencodes.c
gcc/genconditions.c [new file with mode: 0644]
gcc/genflags.c
gcc/genrecog.c
gcc/gensupport.c
gcc/gensupport.h

index f4e5c0f20a516f0f27f8e4682be29757b7fb6dc1..e1e8fcaef8bf8938b9a59b4741f3c94edae2b00d 100644 (file)
@@ -1,7 +1,38 @@
+2002-07-29  Zack Weinberg  <zack@codesourcery.com>
+
+       * gensupport.c: Include hashtab.h.
+       (insn_elision, condition_table, hash_c_test, cmp_c_test,
+       maybe_eval_c_test): New routines and data structures to
+       support insn elision.
+       (init_md_reader): Read and initialize the condition_table.
+       (read_md_rtx): Discard insn patterns whose C test is provably
+       always false.
+       * gensupport.h: Declare new functions and data structures.
+
+       * genconditions.c, dummy-conditions.c: New files.
+       * Makefile.in: Build genconditions; run it to construct
+       insn-conditions.c; build that and link it into most gen*
+       programs.
+       (HOST_SUPPORT, HOST_EARLY_SUPPORT): New variables.
+       (GEN): Delete, unused.
+       (STAGESTUFF): Update.
+
+       * gencodes.c: (gen_insn): #define CODE_FOR_xxx equal to
+       CODE_FOR_nothing for all elided patterns.
+       (main): Tweaked to support this.
+       * genflags.c (gen_proto): Emit a static inline generator
+       function here for all elided patterns, which simply returns
+       NULL_RTX.
+       (gen_insn): Do not define HAVE_xxx for elided patterns.
+       (main): Tweaked to support this.  No need to forward-declare
+       struct rtx_def.
+       * genrecog.c: Do not bother emitting the C test if it's known
+       to be true at compile time.
+
 2002-07-29  Mike Stump  <mrs@apple.com>
 
-       * config.gcc (target_gtfiles): Initialize, as otherwise cross compilers hosted on
-       powerpc-apple-darwin6.0 won't even build.
+       * config.gcc (target_gtfiles): Initialize, as otherwise cross 
+       compilers hosted on powerpc-apple-darwin6.0 won't even build.
 
 2002-07-29  Richard Earnshaw  <rearnsha@arm.com>
 
index e256187dd34c57c2fc0b88d94952d2ae62fecc4e..3fdd3023e305f10457ab8ed320a35fd338df37e6 100644 (file)
@@ -622,7 +622,9 @@ SYSLIBS = @GNAT_LIBEXC@
 HOST_LIBS = $(BUILD_LIBIBERTY)
 
 HOST_RTL = $(BUILD_PREFIX)rtl.o read-rtl.o $(BUILD_PREFIX)bitmap.o \
-               $(BUILD_PREFIX)ggc-none.o gensupport.o
+               $(BUILD_PREFIX)ggc-none.o
+HOST_SUPPORT = gensupport.o insn-conditions.o
+HOST_EARLY_SUPPORT = gensupport.o dummy-conditions.o
 
 HOST_PRINT = $(BUILD_PREFIX)print-rtl.o
 HOST_ERRORS = $(BUILD_PREFIX)errors.o
@@ -742,29 +744,20 @@ OBJS = alias.o bb-reorder.o bitmap.o builtins.o caller-save.o calls.o        \
 
 BACKEND = main.o libbackend.a
 
-# GEN files are listed separately, so they can be built before doing parallel
-#  makes for cc1 or cc1plus.  Otherwise sequent parallel make attempts to load
-#  them before rtl.o is compiled.
-GEN= genemit$(build_exeext) genoutput$(build_exeext) genrecog$(build_exeext) \
- genextract$(build_exeext) genflags$(build_exeext) gencodes$(build_exeext)   \
- genconfig$(build_exeext) genpeep$(build_exeext) gengenrtl$(build_exeext)    \
- gencheck$(build_exeext) genpreds$(build_exeext) genconstants$(build_exeext) \
- gengtype$(build_exeext)
-
 # Files to be copied away after each stage in building.
 STAGESTUFF = *$(objext) insn-flags.h insn-config.h insn-codes.h \
  insn-output.c insn-recog.c insn-emit.c insn-extract.c insn-peep.c \
  insn-attr.h insn-attrtab.c insn-opinit.c insn-constants.h tm-preds.h \
- tree-check.h \
+ tree-check.h insn-conditions.c \
  s-flags s-config s-codes s-mlib s-under s-genrtl s-gtype gtyp-gen.h \
- s-output s-recog s-emit s-extract s-peep s-check \
+ s-output s-recog s-emit s-extract s-peep s-check s-conditions \
  s-attr s-attrtab s-opinit s-preds s-constants s-crt0 \
  genemit$(build_exeext) genoutput$(build_exeext) genrecog$(build_exeext) \
  genextract$(build_exeext) genflags$(build_exeext) gencodes$(build_exeext) \
  genconfig$(build_exeext) genpeep$(build_exeext) genattrtab$(build_exeext) \
  genattr$(build_exeext) genopinit$(build_exeext) gengenrtl$(build_exeext) \
  gencheck$(build_exeext) genpreds$(build_exeext) genconstants$(build_exeext) \
- gengtype$(build_exeext) \
+ gengtype$(build_exeext) genconditions$(build_exeext) \
  genrtl.c genrtl.h gt-*.h gtype-*.h gtype-desc.c \
  xgcc$(exeext) cpp$(exeext) cc1$(exeext) $(EXTRA_PASSES) \
  $(EXTRA_PARTS) $(EXTRA_PROGRAMS) gcc-cross$(exeext) cc1obj$(exeext) \
@@ -1698,6 +1691,21 @@ s-config : $(md_file) genconfig$(build_exeext) $(srcdir)/move-if-change
        $(SHELL) $(srcdir)/move-if-change tmp-config.h insn-config.h
        $(STAMP) s-config
 
+insn-conditions.c: s-conditions ; @true
+s-conditions : $(md_file) genconditions$(build_exeext) $(srcdir)/move-if-change
+       ./genconditions$(build_exeext) $(md_file) > tmp-conditions.c
+       $(SHELL) $(srcdir)/move-if-change tmp-conditions.c insn-conditions.c
+       $(STAMP) s-conditions
+
+insn-conditions.o : insn-conditions.c $(GCONFIG_H) $(SYSTEM_H) $(RTL_H) \
+  $(TM_P_H) $(REGS_H) function.h $(RECOG_H) real.h output.h flags.h \
+  hard-reg-set.h resource.h toplev.h reload.h gensupport.h insn-constants.h
+       $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) insn-conditions.c
+
+dummy-conditions.o : dummy-conditions.c $(GCONFIG_H) $(SYSTEM_H) gensupport.h
+       $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \
+           $(srcdir)/dummy-conditions.c $(OUTPUT_OPTION)
+
 insn-flags.h: s-flags ; @true
 s-flags : $(md_file) genflags$(build_exeext) $(srcdir)/move-if-change
        ./genflags$(build_exeext) $(md_file) > tmp-flags.h
@@ -1904,88 +1912,109 @@ read-rtl.o: read-rtl.c $(HCONFIG_H) $(SYSTEM_H) $(RTL_H) \
 gensupport.o: gensupport.c $(RTL_H) $(OBSTACK_H) $(SYSTEM_H) errors.h gensupport.h
        $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/gensupport.c $(OUTPUT_OPTION)
 
-genconfig$(build_exeext) : genconfig.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
+genconfig$(build_exeext) : genconfig.o $(HOST_RTL) $(HOST_SUPPORT) \
+  $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
        $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-         genconfig.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBS)
+         genconfig.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
+           $(HOST_ERRORS) $(HOST_LIBS)
 
 genconfig.o : genconfig.c $(RTL_H) $(HCONFIG_H) \
   $(SYSTEM_H) errors.h gensupport.h
        $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genconfig.c $(OUTPUT_OPTION)
 
-genflags$(build_exeext) : genflags.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
+genflags$(build_exeext) : genflags.o $(HOST_RTL) $(HOST_SUPPORT) \
+  $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
        $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-        genflags.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBS)
+        genflags.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
+           $(HOST_ERRORS) $(HOST_LIBS)
 
 genflags.o : genflags.c $(RTL_H) $(OBSTACK_H) $(HCONFIG_H) \
   $(SYSTEM_H) errors.h gensupport.h
        $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genflags.c $(OUTPUT_OPTION)
 
-gencodes$(build_exeext) : gencodes.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
+gencodes$(build_exeext) : gencodes.o $(HOST_RTL) $(HOST_SUPPORT) \
+  $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
        $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-        gencodes.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBS)
+        gencodes.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
+           $(HOST_ERRORS) $(HOST_LIBS)
 
 gencodes.o : gencodes.c $(RTL_H) $(HCONFIG_H) \
   $(SYSTEM_H) errors.h gensupport.h
        $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/gencodes.c $(OUTPUT_OPTION)
 
-genconstants$(build_exeext) : genconstants.o $(HOST_RTL) $(HOST_ERRORS) $(HOST_LIBDEPS)
+genconstants$(build_exeext) : genconstants.o $(HOST_RTL) $(HOST_EARLY_SUPPORT) \
+  $(HOST_ERRORS) $(HOST_LIBDEPS)
        $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-        genconstants.o $(HOST_RTL) $(HOST_ERRORS) $(HOST_LIBS)
+        genconstants.o $(HOST_EARLY_SUPPORT) $(HOST_RTL) \
+           $(HOST_ERRORS) $(HOST_LIBS)
 
 genconstants.o : genconstants.c $(RTL_H) $(HCONFIG_H) $(SYSTEM_H) errors.h
        $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genconstants.c $(OUTPUT_OPTION)
 
-genemit$(build_exeext) : genemit.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
+genemit$(build_exeext) : genemit.o $(HOST_RTL) $(HOST_SUPPORT) \
+  $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
        $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-        genemit.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBS)
+        genemit.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
+           $(HOST_ERRORS) $(HOST_LIBS)
 
 genemit.o : genemit.c $(RTL_H) $(HCONFIG_H) $(SYSTEM_H) errors.h gensupport.h
        $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genemit.c $(OUTPUT_OPTION)
 
-genopinit$(build_exeext) : genopinit.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
+genopinit$(build_exeext) : genopinit.o $(HOST_RTL) $(HOST_SUPPORT) \
+  $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
        $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-        genopinit.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBS)
+        genopinit.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
+           $(HOST_ERRORS) $(HOST_LIBS)
 
 genopinit.o : genopinit.c $(RTL_H) $(HCONFIG_H) \
   $(SYSTEM_H) errors.h gensupport.h
        $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genopinit.c $(OUTPUT_OPTION)
 
-genrecog$(build_exeext) : genrecog.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
+genrecog$(build_exeext) : genrecog.o $(HOST_RTL) $(HOST_SUPPORT) \
+    $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
        $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-        genrecog.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBS)
+        genrecog.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
+           $(HOST_ERRORS) $(HOST_LIBS)
 
 genrecog.o : genrecog.c $(RTL_H) $(HCONFIG_H) \
   $(SYSTEM_H) errors.h gensupport.h
        $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genrecog.c $(OUTPUT_OPTION)
 
-genextract$(build_exeext) : genextract.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
+genextract$(build_exeext) : genextract.o $(HOST_RTL) $(HOST_SUPPORT) \
+  $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
        $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-        genextract.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBS)
+        genextract.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
+           $(HOST_ERRORS) $(HOST_LIBS)
 
 genextract.o : genextract.c $(RTL_H) $(HCONFIG_H) \
   $(SYSTEM_H) insn-config.h errors.h gensupport.h
        $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genextract.c $(OUTPUT_OPTION)
 
-genpeep$(build_exeext) : genpeep.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
+genpeep$(build_exeext) : genpeep.o $(HOST_RTL) $(HOST_SUPPORT) \
+  $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
        $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-        genpeep.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBS)
+        genpeep.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
+           $(HOST_ERRORS) $(HOST_LIBS)
 
 genpeep.o : genpeep.c $(RTL_H) $(HCONFIG_H) $(SYSTEM_H) errors.h gensupport.h
        $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genpeep.c $(OUTPUT_OPTION)
 
-genattr$(build_exeext) : genattr.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
+genattr$(build_exeext) : genattr.o $(HOST_RTL) $(HOST_SUPPORT) \
+  $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
        $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-        genattr.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBS)
+        genattr.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
+           $(HOST_ERRORS) $(HOST_LIBS)
 
 genattr.o : genattr.c $(RTL_H) $(HCONFIG_H) $(SYSTEM_H) errors.h gensupport.h
        $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genattr.c $(OUTPUT_OPTION)
 
 genattrtab$(build_exeext) : genattrtab.o genautomata.o \
-  $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_VARRAY) $(HOST_LIBDEPS)
+  $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_VARRAY) \
+  $(HOST_LIBDEPS)
        $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
         genattrtab.o genautomata.o \
-        $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_VARRAY) \
-        $(HOST_LIBS) -lm
+        $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) $(HOST_ERRORS) \
+        $(HOST_VARRAY) $(HOST_LIBS) -lm
 
 genattrtab.o : genattrtab.c $(RTL_H) $(OBSTACK_H) $(HCONFIG_H) \
   $(SYSTEM_H) errors.h $(GGC_H) gensupport.h genattrtab.h
@@ -1995,9 +2024,11 @@ genautomata.o : genautomata.c $(RTL_H) $(OBSTACK_H) $(HCONFIG_H) \
   $(SYSTEM_H) errors.h varray.h genattrtab.h $(HASHTAB_H)
        $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) $(srcdir)/genautomata.c $(OUTPUT_OPTION)
 
-genoutput$(build_exeext) : genoutput.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
+genoutput$(build_exeext) : genoutput.o $(HOST_RTL) $(HOST_SUPPORT) \
+  $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBDEPS)
        $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
-        genoutput.o $(HOST_RTL) $(HOST_PRINT) $(HOST_ERRORS) $(HOST_LIBS)
+        genoutput.o $(HOST_RTL) $(HOST_SUPPORT) $(HOST_PRINT) \
+           $(HOST_ERRORS) $(HOST_LIBS)
 
 genoutput.o : genoutput.c $(RTL_H) $(HCONFIG_H) \
   $(SYSTEM_H) errors.h gensupport.h
@@ -2052,6 +2083,16 @@ $(srcdir)/gengtype-yacc.c: $(srcdir)/gengtype-yacc.y
         $(BISON) $(BISONFLAGS) -d -o gengtype-yacc.c gengtype-yacc.y || \
         ( rm -f $@ && false ) )
 
+genconditions$(build_exeext) : genconditions.o $(HOST_EARLY_SUPPORT) \
+  $(HOST_RTL) $(HOST_ERRORS) $(HOST_LIBDEPS)
+       $(HOST_CC) $(HOST_CFLAGS) $(HOST_LDFLAGS) -o $@ \
+        genconditions.o $(HOST_EARLY_SUPPORT) $(HOST_RTL) \
+           $(HOST_ERRORS) $(HOST_LIBS)
+
+genconditions.o : genconditions.c $(RTL_H) $(HCONFIG_H) $(SYSTEM_H) errors.h
+       $(HOST_CC) -c $(HOST_CFLAGS) $(HOST_CPPFLAGS) $(INCLUDES) \
+               $(srcdir)/genconditions.c $(OUTPUT_OPTION)
+
 #\f
 # Compile the libraries to be used by gen*.
 # If we are not cross-building, gen* use the same .o's that cc1 will use,
diff --git a/gcc/dummy-conditions.c b/gcc/dummy-conditions.c
new file mode 100644 (file)
index 0000000..157f86b
--- /dev/null
@@ -0,0 +1,34 @@
+/* Support for calculating constant conditions.
+   Copyright (C) 2002 Free Software Foundation, Inc.
+
+   This file is part of GNU CC.
+
+   GNU CC 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 2, or (at your option)
+   any later version.
+
+   GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+   the Free Software Foundation, 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+#include "hconfig.h"
+#include "system.h"
+#include "gensupport.h"
+
+/* MD generators that are run before insn-conditions.c exists should
+   link against this file instead.  Currently that is genconditions
+   and genconstants.  */
+
+/* Empty conditions table to prevent link errors.  */
+const struct c_test insn_conditions[1] = { { 0, 0 } };
+const size_t n_insn_conditions = 0;
+
+/* Disable insn elision, since it is currently impossible.  */
+const int insn_elision_unavailable = 1;
index 0611eecaf03210e0a8bf081eb583600eae6d722c..5a292821c393152364f245c6035595fc8fe92cba 100644 (file)
@@ -28,18 +28,26 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "errors.h"
 #include "gensupport.h"
 
-static void gen_insn PARAMS ((const char *, int));
+static void gen_insn PARAMS ((rtx, int));
 
 static void
-gen_insn (name, code)
-     const char *name;
+gen_insn (insn, code)
+     rtx insn;
      int code;
 {
+  const char *name = XSTR (insn, 0);
+  int truth = maybe_eval_c_test (XSTR (insn, 2));
+
   /* Don't mention instructions whose names are the null string
      or begin with '*'.  They are in the machine description just
      to be recognized.  */
   if (name[0] != 0 && name[0] != '*')
-    printf ("  CODE_FOR_%s = %d,\n", name, code);
+    {
+      if (truth == 0)
+       printf ("#define CODE_FOR_%s CODE_FOR_nothing\n", name);
+      else
+       printf ("  CODE_FOR_%s = %d,\n", name, code);
+    }
 }
 
 extern int main PARAMS ((int, char **));
@@ -53,6 +61,10 @@ main (argc, argv)
 
   progname = "gencodes";
 
+  /* We need to see all the possibilities.  Elided insns may have
+     direct references to CODE_FOR_xxx in C code.  */
+  insn_elision = 0;
+
   if (argc <= 1)
     fatal ("no input file name");
 
@@ -80,10 +92,10 @@ enum insn_code {");
        break;
 
       if (GET_CODE (desc) == DEFINE_INSN || GET_CODE (desc) == DEFINE_EXPAND)
-       gen_insn (XSTR (desc, 0), insn_code_number);
+       gen_insn (desc, insn_code_number);
     }
 
-  puts ("CODE_FOR_nothing\n\
+  puts ("  CODE_FOR_nothing\n\
 };\n\
 \n\
 #endif /* GCC_INSN_CODES_H */");
diff --git a/gcc/genconditions.c b/gcc/genconditions.c
new file mode 100644 (file)
index 0000000..02f80ee
--- /dev/null
@@ -0,0 +1,240 @@
+/* Process machine description and calculate constant conditions.
+   Copyright (C) 2001, 2002 Free Software Foundation, Inc.
+
+   This file is part of GNU CC.
+
+   GNU CC 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 2, or (at your option)
+   any later version.
+
+   GNU CC 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 GNU CC; see the file COPYING.  If not, write to
+   the Free Software Foundation, 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.  */
+
+/* In a machine description, all of the insn patterns - define_insn,
+   define_expand, define_split, define_peephole, define_peephole2 -
+   contain an optional C expression which makes the final decision
+   about whether or not this pattern is usable.  That expression may
+   turn out to be always false when the compiler is built.  If it is,
+   most of the programs that generate code from the machine
+   description can simply ignore the entire pattern.  */
+
+#include "hconfig.h"
+#include "system.h"
+#include "rtl.h"
+#include "errors.h"
+#include "hashtab.h"
+#include "gensupport.h"
+
+/* so we can include except.h in the generated file */
+static int saw_eh_return;
+
+static htab_t condition_table;
+
+static void add_condition      PARAMS ((const char *));
+static void write_header       PARAMS ((void));
+static void write_conditions   PARAMS ((void));
+static int write_one_condition PARAMS ((PTR *, PTR));
+
+extern int main                        PARAMS ((int, char **));
+
+/* Record the C test expression EXPR in the condition_table.
+   Duplicates clobber previous entries, which leaks memory, but
+   we don't care for this application.  */
+
+static void
+add_condition (expr)
+     const char *expr;
+{
+  struct c_test *test;
+
+  if (expr[0] == 0)
+    return;
+
+  test = (struct c_test *) xmalloc (sizeof (struct c_test));
+  test->expr = expr;
+
+  *(htab_find_slot (condition_table, test, INSERT)) = test;
+}
+
+/* Generate the header for insn-conditions.c.  */
+
+static void
+write_header ()
+{
+  puts ("\
+/* Generated automatically by the program `genconditions' from the target\n\
+   machine description file.  */\n\
+\n\
+#include \"hconfig.h\"\n\
+#include \"insn-constants.h\"\n");
+
+  puts ("\
+/* Do not allow checking to confuse the issue.  */\n\
+#undef ENABLE_CHECKING\n\
+#undef ENABLE_TREE_CHECKING\n\
+#undef ENABLE_RTL_CHECKING\n\
+#undef ENABLE_RTL_FLAG_CHECKING\n\
+#undef ENABLE_GC_CHECKING\n\
+#undef ENABLE_GC_ALWAYS_COLLECT\n");
+
+  puts ("\
+#include \"system.h\"\n\
+#include \"rtl.h\"\n\
+#include \"tm_p.h\"\n\
+#include \"function.h\"\n");
+
+  puts ("\
+/* Fake - insn-config.h doesn't exist yet.  */\n\
+#define MAX_RECOG_OPERANDS 10\n\
+#define MAX_DUP_OPERANDS 10\n\
+#define MAX_INSNS_PER_SPLIT 5\n");
+
+  puts ("\
+#include \"regs.h\"\n\
+#include \"recog.h\"\n\
+#include \"real.h\"\n\
+#include \"output.h\"\n\
+#include \"flags.h\"\n\
+#include \"hard-reg-set.h\"\n\
+#include \"resource.h\"\n\
+#include \"toplev.h\"\n\
+#include \"reload.h\"\n\
+#include \"gensupport.h\"\n");
+
+  if (saw_eh_return)
+    puts ("#define HAVE_eh_return 1");
+  puts ("#include \"except.h\"\n");
+
+  puts ("\
+/* Dummy external declarations.  */\n\
+extern rtx insn;\n\
+extern rtx ins1;\n\
+extern rtx operands[];\n\
+extern int next_insn_tests_no_inequality PARAMS ((rtx));\n");
+
+  puts ("\
+/* If we don't have __builtin_constant_p, or it's not acceptable in\n\
+   array initializers, fall back to assuming that all conditions\n\
+   potentially vary at run time.  It works in 3.0.1 and later; 3.0\n\
+   only when not optimizing.  */\n\
+#if (GCC_VERSION >= 3001) || ((GCC_VERSION == 3000) && !__OPTIMIZE__)\n\
+# define MAYBE_EVAL(expr) (__builtin_constant_p(expr) ? (int) (expr) : -1)\n\
+#else\n\
+# define MAYBE_EVAL(expr) -1\n\
+#endif\n");
+}
+
+/* Write out one entry in the conditions table, using the data pointed
+   to by SLOT.  Each entry looks like this:
+  { "! optimize_size && ! TARGET_READ_MODIFY_WRITE",
+    MAYBE_EVAL (! optimize_size && ! TARGET_READ_MODIFY_WRITE) },  */
+
+static int
+write_one_condition (slot, dummy)
+     PTR *slot;
+     PTR dummy ATTRIBUTE_UNUSED;
+{
+  const struct c_test *test = * (const struct c_test **) slot;
+  const char *p;
+
+  fputs ("  { \"", stdout);
+  for (p = test->expr; *p; p++)
+    {
+      if (*p == '\n')
+       fputs ("\\n\\\n", stdout);
+      else if (*p == '"')
+       fputs ("\\\"", stdout);
+      else
+       putchar (*p);
+    }
+
+  printf ("\",\n    MAYBE_EVAL (%s) },\n", test->expr);
+  return 1;
+}
+
+/* Write out the complete conditions table, its size, and a flag
+   indicating that gensupport.c can now do insn elision.  */
+static void
+write_conditions ()
+{
+  puts ("\
+/* This table lists each condition found in the machine description.\n\
+   Each condition is mapped to its truth value (0 or 1), or -1 if that\n\
+   cannot be calculated at compile time. */\n\
+\n\
+const struct c_test insn_conditions[] = {");
+
+  htab_traverse (condition_table, write_one_condition, 0);
+
+  puts ("};\n");
+
+  printf ("const size_t n_insn_conditions = %lu;\n",
+         (unsigned long) htab_elements (condition_table));
+  puts ("const int insn_elision_unavailable = 0;");
+}
+
+int
+main (argc, argv)
+     int argc;
+     char **argv;
+{
+  rtx desc;
+  int pattern_lineno; /* not used */
+  int code;
+
+  progname = "genconditions";
+
+  if (argc <= 1)
+    fatal ("No input file name.");
+
+  if (init_md_reader (argv[1]) != SUCCESS_EXIT_CODE)
+    return (FATAL_EXIT_CODE);
+
+  condition_table = htab_create (1000, hash_c_test, cmp_c_test, NULL);
+
+  /* Read the machine description.  */
+
+  while (1)
+    {
+      desc = read_md_rtx (&pattern_lineno, &code);
+      if (desc == NULL)
+       break;
+
+      /* N.B. define_insn_and_split, define_cond_exec are handled
+        entirely within read_md_rtx; we never see them.  */
+      switch (GET_CODE (desc))
+       {
+       default:
+         break;
+
+       case DEFINE_INSN:
+       case DEFINE_EXPAND:
+         add_condition (XSTR (desc, 2));
+         /* except.h needs to know whether there is an eh_return
+            pattern in the machine description.  */
+         if (!strcmp (XSTR (desc, 0), "eh_return"))
+           saw_eh_return = 1;
+         break;
+
+       case DEFINE_SPLIT:
+       case DEFINE_PEEPHOLE:
+       case DEFINE_PEEPHOLE2:
+         add_condition (XSTR (desc, 1));
+         break;
+       }
+    }
+
+  write_header ();
+  write_conditions ();
+
+  fflush (stdout);
+  return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
+}
index 114b98b837e211a14c87197081e3b03bf0be09cd..948068167627c1d07b76cb650aab87d23fccbcf3 100644 (file)
@@ -124,14 +124,18 @@ gen_macro (name, real, expect)
   printf ("(%c))\n", i + 'A');
 }
 
-/* Print out prototype information for a function.  */
+/* Print out prototype information for a generator function.  If the
+   insn pattern has been elided, print out a dummy generator that
+   does nothing.  */
 
 static void
 gen_proto (insn)
      rtx insn;
 {
   int num = num_operands (insn);
+  int i;
   const char *name = XSTR (insn, 0);
+  int truth = maybe_eval_c_test (XSTR (insn, 2));
 
   /* Many md files don't refer to the last two operands passed to the
      call patterns.  This means their generator functions will be two
@@ -152,19 +156,41 @@ gen_proto (insn)
        gen_macro (name, num, 5);
     }
 
-  printf ("extern struct rtx_def *gen_%-*s PARAMS ((", max_id_len, name);
+  if (truth != 0)
+    printf ("extern rtx        gen_%-*s PARAMS ((", max_id_len, name);
+  else
+    printf ("static inline rtx gen_%-*s PARAMS ((", max_id_len, name);
 
   if (num == 0)
-    printf ("void");
+    fputs ("void", stdout);
   else
     {
-      while (num-- > 1)
-       printf ("struct rtx_def *, ");
-
-      printf ("struct rtx_def *");
+      for (i = 1; i < num; i++)
+       fputs ("rtx, ", stdout);
+      
+      fputs ("rtx", stdout);
     }
 
-  printf ("));\n");
+  puts ("));");
+
+  /* Some back ends want to take the address of generator functions,
+     so we cannot simply use #define for these dummy definitions.  */
+  if (truth == 0)
+    {
+      printf ("static inline rtx\ngen_%s", name);
+      if (num > 0)
+       {
+         putchar ('(');
+         for (i = 0; i < num-1; i++)
+           printf ("%c, ", 'a' + i);
+         printf ("%c)\n", 'a' + i);
+         for (i = 0; i < num; i++)
+           printf ("     rtx %c ATTRIBUTE_UNUSED;\n", 'a' + i);
+       }
+      else
+       puts ("()");
+      puts ("{\n  return 0;\n}");
+    }
 
 }
 
@@ -175,6 +201,7 @@ gen_insn (insn)
   const char *name = XSTR (insn, 0);
   const char *p;
   int len;
+  int truth = maybe_eval_c_test (XSTR (insn, 2));
 
   /* Don't mention instructions whose names are the null string
      or begin with '*'.  They are in the machine description just
@@ -187,22 +214,23 @@ gen_insn (insn)
   if (len > max_id_len)
     max_id_len = len;
 
-  printf ("#define HAVE_%s ", name);
-  if (strlen (XSTR (insn, 2)) == 0)
-    printf ("1\n");
+  if (truth == 0)
+    /* emit nothing */;
+  else if (truth == 1)
+    printf ("#define HAVE_%s 1\n", name);
   else
     {
       /* Write the macro definition, putting \'s at the end of each line,
         if more than one.  */
-      printf ("(");
+      printf ("#define HAVE_%s (", name);
       for (p = XSTR (insn, 2); *p; p++)
        {
          if (IS_VSPACE (*p))
-           printf (" \\\n");
+           fputs (" \\\n", stdout);
          else
-           printf ("%c", *p);
+           putchar (*p);
        }
-      printf (")\n");
+      fputs (")\n", stdout);
     }
 
   obstack_grow (&obstack, &insn, sizeof (rtx));
@@ -223,6 +251,10 @@ main (argc, argv)
   progname = "genflags";
   obstack_init (&obstack);
 
+  /* We need to see all the possibilities.  Elided insns may have
+     direct calls to their generators in C code.  */
+  insn_elision = 0;
+
   if (argc <= 1)
     fatal ("no input file name");
 
@@ -252,7 +284,6 @@ main (argc, argv)
   obstack_grow (&obstack, &dummy, sizeof (rtx));
   insns = (rtx *) obstack_finish (&obstack);
 
-  printf ("struct rtx_def;\n");
   for (insn_ptr = insns; *insn_ptr; insn_ptr++)
     gen_proto (*insn_ptr);
 
index 5492fa0807ec46ad1ff747816397ad2012932cc8..7709eb8b6a65b963fbcfc1240fb6a3cf5874908f 100644 (file)
@@ -2452,11 +2452,16 @@ make_insn_sequence (insn, type)
 {
   rtx x;
   const char *c_test = XSTR (insn, type == RECOG ? 2 : 1);
+  int truth = maybe_eval_c_test (c_test);
   struct decision *last;
   struct decision_test *test, **place;
   struct decision_head head;
   char c_test_pos[2];
 
+  /* We should never see an insn whose C test is false at compile time.  */
+  if (truth == 0)
+    abort ();
+
   record_insn_name (next_insn_code, (type == RECOG ? XSTR (insn, 0) : NULL));
 
   c_test_pos[0] = '\0';
@@ -2504,7 +2509,8 @@ make_insn_sequence (insn, type)
     continue;
   place = &test->next;
 
-  if (c_test[0])
+  /* Skip the C test if it's known to be true at compile time.  */
+  if (truth == -1)
     {
       /* Need a new node if we have another test to add.  */
       if (test->type == DT_accept_op)
@@ -2577,7 +2583,9 @@ make_insn_sequence (insn, type)
                  place = &last->tests;
                }
 
-             if (c_test[0])
+             /* Skip the C test if it's known to be true at compile
+                 time.  */
+             if (truth == -1)
                {
                  test = new_decision_test (DT_c_test, &place);
                  test->u.c_test = c_test;
index 9e3d0bbcb1fa8a747da362045c4fbd9b1579cbf8..5a9ff21f9782d3fb070429b2b3758df32148bbfc 100644 (file)
 #include "rtl.h"
 #include "obstack.h"
 #include "errors.h"
+#include "hashtab.h"
 #include "gensupport.h"
 
 
 /* In case some macros used by files we include need it, define this here.  */
 int target_flags;
 
+int insn_elision = 1;
+
 static struct obstack obstack;
 struct obstack *rtl_obstack = &obstack;
 
@@ -39,6 +42,8 @@ static int predicable_default;
 static const char *predicable_true;
 static const char *predicable_false;
 
+static htab_t condition_table;
+
 static char *base_dir = NULL;
 
 /* We initially queue all patterns, process the define_insn and
@@ -950,6 +955,7 @@ init_md_reader (filename)
 {
   FILE *input_file;
   int c;
+  size_t i;
   char *lastsl;
 
   lastsl = strrchr (filename, '/');
@@ -964,6 +970,14 @@ init_md_reader (filename)
       return FATAL_EXIT_CODE;
     }
 
+  /* Initialize the table of insn conditions.  */
+  condition_table = htab_create (n_insn_conditions,
+                                hash_c_test, cmp_c_test, NULL);
+
+  for (i = 0; i < n_insn_conditions; i++)
+    *(htab_find_slot (condition_table, (PTR) &insn_conditions[i], INSERT))
+      = (PTR) &insn_conditions[i];
+
   obstack_init (rtl_obstack);
   errors = 0;
   sequence_num = 0;
@@ -1002,6 +1016,8 @@ read_md_rtx (lineno, seqnr)
   struct queue_elem **queue, *elem;
   rtx desc;
 
+ discard:
+
   /* Read all patterns from a given queue before moving on to the next.  */
   if (define_attr_queue != NULL)
     queue = &define_attr_queue;
@@ -1021,14 +1037,29 @@ read_md_rtx (lineno, seqnr)
 
   free (elem);
 
+  /* Discard insn patterns which we know can never match (because
+     their C test is provably always false).  If insn_elision is
+     false, our caller needs to see all the patterns.  Note that the
+     elided patterns are never counted by the sequence numbering; it
+     it is the caller's responsibility, when insn_elision is false, not
+     to use elided pattern numbers for anything.  */
   switch (GET_CODE (desc))
     {
     case DEFINE_INSN:
     case DEFINE_EXPAND:
+      if (maybe_eval_c_test (XSTR (desc, 2)) != 0)
+       sequence_num++;
+      else if (insn_elision)
+       goto discard;
+      break;
+
     case DEFINE_SPLIT:
     case DEFINE_PEEPHOLE:
     case DEFINE_PEEPHOLE2:
-      sequence_num++;
+      if (maybe_eval_c_test (XSTR (desc, 1)) != 0)
+       sequence_num++;
+      else if (insn_elision)
+           goto discard;
       break;
 
     default:
@@ -1038,6 +1069,73 @@ read_md_rtx (lineno, seqnr)
   return desc;
 }
 
+/* Helper functions for insn elision.  */
+
+/* Compute a hash function of a c_test structure, which is keyed
+   by its ->expr field.  */
+hashval_t
+hash_c_test (x)
+     const PTR x;
+{
+  const struct c_test *a = (const struct c_test *) x;
+  const unsigned char *base, *s = (const unsigned char *) a->expr;
+  hashval_t hash;
+  unsigned char c;
+  unsigned int len;
+
+  base = s;
+  hash = 0;
+
+  while ((c = *s++) != '\0')
+    {
+      hash += c + (c << 17);
+      hash ^= hash >> 2;
+    }
+
+  len = s - base;
+  hash += len + (len << 17);
+  hash ^= hash >> 2;
+
+  return hash;
+}
+
+/* Compare two c_test expression structures.  */
+int
+cmp_c_test (x, y)
+     const PTR x;
+     const PTR y;
+{
+  const struct c_test *a = (const struct c_test *) x;
+  const struct c_test *b = (const struct c_test *) y;
+
+  return !strcmp (a->expr, b->expr);
+}
+
+/* Given a string representing a C test expression, look it up in the
+   condition_table and report whether or not its value is known
+   at compile time.  Returns a tristate: 1 for known true, 0 for
+   known false, -1 for unknown.  */
+int
+maybe_eval_c_test (expr)
+     const char *expr;
+{
+  const struct c_test *test;
+  struct c_test dummy;
+
+  if (expr[0] == 0)
+    return 1;
+
+  if (insn_elision_unavailable)
+    return -1;
+
+  dummy.expr = expr;
+  test = (const struct c_test *) htab_find (condition_table, &dummy);
+  if (!test)
+    abort ();
+
+  return test->value;
+}
+
 /* Given a string, return the number of comma-separated elements in it.
    Return 0 for the null string.  */
 int
index bac804b22a6b9a0ee84353b8f14252ba79c4f1af..8dbd0b70ea955374155acc45e139bd6daacbf73e 100644 (file)
@@ -18,6 +18,9 @@ along with GCC; see the file COPYING.  If not, write to the Free
 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 02111-1307, USA.  */
 
+#ifndef GCC_GENSUPPORT_H
+#define GCC_GENSUPPORT_H
+
 struct obstack;
 extern struct obstack *rtl_obstack;
 
@@ -28,6 +31,39 @@ extern rtx read_md_rtx               PARAMS ((int *, int *));
 extern void message_with_line  PARAMS ((int, const char *, ...))
      ATTRIBUTE_PRINTF_2;
 
+/* Set this to 0 to disable automatic elision of insn patterns which
+   can never be used in this configuration.  See genconditions.c.
+   Must be set before calling init_md_reader.  */
+extern int insn_elision;
+
+/* If this is 1, the insn elision table doesn't even exist yet;
+   maybe_eval_c_test will always return -1.  This is distinct from
+   insn_elision because genflags and gencodes need to see all the
+   patterns, but treat elided patterns differently.  */
+extern const int insn_elision_unavailable;
+
+/* If the C test passed as the argument can be evaluated at compile
+   time, return its truth value; else return -1.  The test must have
+   appeared somewhere in the machine description when genconditions
+   was run.  */
+extern int maybe_eval_c_test   PARAMS ((const char *));
+
+/* This table should not be accessed directly; use maybe_eval_c_test.  */
+struct c_test
+{
+  const char *expr;
+  int value;
+};
+
+extern const struct c_test insn_conditions[];
+extern const size_t n_insn_conditions;
+
+#ifdef __HASHTAB_H__
+extern hashval_t hash_c_test PARAMS ((const PTR));
+extern int cmp_c_test PARAMS ((const PTR, const PTR));
+#endif
+
 extern int n_comma_elts                PARAMS ((const char *));
 extern const char *scan_comma_elt PARAMS ((const char **));
 
+#endif /* GCC_GENSUPPORT_H */