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:
parent
ab16524d62
commit
dbf833ee11
3 changed files with 78 additions and 2 deletions
|
@ -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,
|
||||
|
|
|
@ -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 \
|
||||
|
|
66
gcc/dojump.c
66
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"
|
||||
|
|
Loading…
Add table
Reference in a new issue