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
This commit is contained in:
Richard Sandiford 2004-03-20 07:13:38 +00:00 committed by Richard Sandiford
parent ab16524d62
commit dbf833ee11
3 changed files with 78 additions and 2 deletions

View file

@ -1,3 +1,12 @@
2004-03-20 Richard Sandiford <rsandifo@redhat.com>
* 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 <kazu@cs.umass.edu>
* c-common.c, cfgcleanup.c, cgraphunit.c, c-pretty-print.c,

View file

@ -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 \

View file

@ -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"