From dbf833ee1107ad90193bc01c9b073a5f5da1a1b7 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Sat, 20 Mar 2004 07:13:38 +0000 Subject: [PATCH] Makefile.in (dojump.o): Depend on $(GGC_H) and dojump.h. * Makefile.in (dojump.o): Depend on $(GGC_H) and dojump.h. (GTFILES): Add $(srcdir)/dojump.h. (gt-dojump.h): New dependency. * dojump.c (and_reg, and_test, shift_test): New static variables. (prefer_and_bit_test): New function. (do_jump): Use it to choose between (X & (1 << C)) and (X >> C) & 1. From-SVN: r79732 --- gcc/ChangeLog | 9 +++++++ gcc/Makefile.in | 5 ++-- gcc/dojump.c | 66 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 78 insertions(+), 2 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 292b9561ef8..551e551bd79 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2004-03-20 Richard Sandiford + + * Makefile.in (dojump.o): Depend on $(GGC_H) and dojump.h. + (GTFILES): Add $(srcdir)/dojump.h. + (gt-dojump.h): New dependency. + * dojump.c (and_reg, and_test, shift_test): New static variables. + (prefer_and_bit_test): New function. + (do_jump): Use it to choose between (X & (1 << C)) and (X >> C) & 1. + 2004-03-20 Kazu Hirata * c-common.c, cfgcleanup.c, cgraphunit.c, c-pretty-print.c, diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 84103f259c7..2b11c82a71c 100644 --- a/gcc/Makefile.in +++ b/gcc/Makefile.in @@ -1597,7 +1597,7 @@ expr.o : expr.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) f except.h reload.h $(GGC_H) langhooks.h intl.h $(TM_P_H) real.h $(TARGET_H) dojump.o : dojump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \ flags.h function.h $(EXPR_H) $(OPTABS_H) $(INSN_ATTR_H) insn-config.h \ - langhooks.h + langhooks.h $(GGC_H) gt-dojump.h builtins.o : builtins.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H)\ flags.h $(TARGET_H) function.h $(REGS_H) $(EXPR_H) $(OPTABS_H) insn-config.h \ $(RECOG_H) output.h typeclass.h hard-reg-set.h toplev.h hard-reg-set.h \ @@ -2086,6 +2086,7 @@ GTFILES = $(srcdir)/input.h $(srcdir)/coretypes.h $(srcdir)/cpplib.h \ $(srcdir)/c-common.h $(srcdir)/c-tree.h \ $(srcdir)/alias.c $(srcdir)/bitmap.c $(srcdir)/cselib.c $(srcdir)/cgraph.c \ $(srcdir)/dbxout.c $(srcdir)/dwarf2out.c $(srcdir)/dwarf2asm.c \ + $(srcdir)/dojump.c \ $(srcdir)/emit-rtl.c $(srcdir)/except.c $(srcdir)/explow.c $(srcdir)/expr.c \ $(srcdir)/fold-const.c $(srcdir)/function.c \ $(srcdir)/gcse.c $(srcdir)/integrate.c $(srcdir)/lists.c $(srcdir)/optabs.c \ @@ -2105,7 +2106,7 @@ gt-cgraph.h gt-coverage.h gtype-desc.h gtype-desc.c gt-except.h \ gt-function.h gt-integrate.h gt-stmt.h gt-tree.h gt-varasm.h \ gt-emit-rtl.h gt-explow.h gt-stor-layout.h gt-regclass.h \ gt-lists.h gt-alias.h gt-cselib.h gt-fold-const.h gt-gcse.h \ -gt-expr.h gt-sdbout.h gt-optabs.h gt-bitmap.h \ +gt-expr.h gt-sdbout.h gt-optabs.h gt-bitmap.h gt-dojump.h \ gt-dwarf2out.h gt-ra-build.h gt-reg-stack.h gt-dwarf2asm.h \ gt-dbxout.h gt-c-common.h gt-c-decl.h gt-c-parse.h \ gt-c-pragma.h gtype-c.h gt-input.h gt-cfglayout.h \ diff --git a/gcc/dojump.c b/gcc/dojump.c index d0cc13c45f3..83af19bb7f3 100644 --- a/gcc/dojump.c +++ b/gcc/dojump.c @@ -33,7 +33,9 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA #include "expr.h" #include "optabs.h" #include "langhooks.h" +#include "ggc.h" +static bool prefer_and_bit_test (enum machine_mode, int); static void do_jump_by_parts_greater (tree, int, rtx, rtx); static void do_jump_by_parts_equality (tree, rtx, rtx); static void do_compare_and_jump (tree, enum rtx_code, enum rtx_code, rtx, @@ -101,6 +103,45 @@ jumpif (tree exp, rtx label) do_jump (exp, NULL_RTX, label); } +/* Used internally by prefer_and_bit_test. */ + +static GTY(()) rtx and_reg; +static GTY(()) rtx and_test; +static GTY(()) rtx shift_test; + +/* Compare the relative costs of "(X & (1 << BITNUM))" and "(X >> BITNUM) & 1", + where X is an arbitrary register of mode MODE. Return true if the former + is preferred. */ + +static bool +prefer_and_bit_test (enum machine_mode mode, int bitnum) +{ + if (and_test == 0) + { + /* Set up rtxes for the two variations. Use NULL as a placeholder + for the BITNUM-based constants. */ + and_reg = gen_rtx_REG (mode, FIRST_PSEUDO_REGISTER); + and_test = gen_rtx_AND (mode, and_reg, NULL); + shift_test = gen_rtx_AND (mode, gen_rtx_ASHIFTRT (mode, and_reg, NULL), + const1_rtx); + } + else + { + /* Change the mode of the previously-created rtxes. */ + PUT_MODE (and_reg, mode); + PUT_MODE (and_test, mode); + PUT_MODE (shift_test, mode); + PUT_MODE (XEXP (shift_test, 0), mode); + } + + /* Fill in the integers. */ + XEXP (and_test, 0) = GEN_INT ((unsigned HOST_WIDE_INT) 1 << bitnum); + XEXP (XEXP (shift_test, 0), 1) = GEN_INT (bitnum); + + return (rtx_cost (and_test, IF_THEN_ELSE) + <= rtx_cost (shift_test, IF_THEN_ELSE)); +} + /* Generate code to evaluate EXP and jump to IF_FALSE_LABEL if the result is zero, or IF_TRUE_LABEL if the result is one. Either of IF_FALSE_LABEL and IF_TRUE_LABEL may be zero, @@ -206,6 +247,29 @@ do_jump (tree exp, rtx if_false_label, rtx if_true_label) break; case BIT_AND_EXPR: + /* fold_single_bit_test() converts (X & (1 << C)) into (X >> C) & 1. + See if the former is preferred for jump tests and restore it + if so. */ + if (TREE_CODE (TREE_OPERAND (exp, 0)) == RSHIFT_EXPR + && integer_onep (TREE_OPERAND (exp, 1))) + { + tree arg = TREE_OPERAND (TREE_OPERAND (exp, 0), 0); + tree shift = TREE_OPERAND (TREE_OPERAND (exp, 0), 1); + tree one = TREE_OPERAND (exp, 1); + tree argtype = TREE_TYPE (arg); + if (TREE_CODE (shift) == INTEGER_CST + && compare_tree_int (shift, 0) > 0 + && compare_tree_int (shift, HOST_BITS_PER_WIDE_INT) < 0 + && prefer_and_bit_test (TYPE_MODE (argtype), + TREE_INT_CST_LOW (shift))) + { + do_jump (build (BIT_AND_EXPR, argtype, arg, + fold (build (LSHIFT_EXPR, argtype, one, shift))), + if_false_label, if_true_label); + break; + } + } + /* If we are AND'ing with a small constant, do this comparison in the smallest type that fits. If the machine doesn't have comparisons that small, it will be converted back to the wider comparison. @@ -999,3 +1063,5 @@ do_compare_and_jump (tree exp, enum rtx_code signed_code, ? expr_size (TREE_OPERAND (exp, 0)) : NULL_RTX), if_false_label, if_true_label); } + +#include "gt-dojump.h" -- 2.30.2