explow.c (force_reg): Call mark_reg_pointer as appropriate.

* explow.c (force_reg): Call mark_reg_pointer as appropriate.
        * config/alpha/alpha.c (alpha_emit_conditional_branch): Don't
        use (op0-op1) == 0 if op0 is a pointer.
        * config/alpha/alpha.md (cmpdi): Use some_operand.
        (three comparison combine splits): Remove.

From-SVN: r78475
This commit is contained in:
Richard Henderson 2004-02-25 17:45:32 -08:00 committed by Richard Henderson
parent 0d593f318b
commit 4a4f95d919
4 changed files with 51 additions and 97 deletions

View file

@ -1,3 +1,11 @@
2004-02-25 Richard Henderson <rth@redhat.com>
* explow.c (force_reg): Call mark_reg_pointer as appropriate.
* config/alpha/alpha.c (alpha_emit_conditional_branch): Don't
use (op0-op1) == 0 if op0 is a pointer.
* config/alpha/alpha.md (cmpdi): Use some_operand.
(three comparison combine splits): Remove.
2004-02-25 Richard Henderson <rth@redhat.com>
PR c/12794

View file

@ -3179,7 +3179,13 @@ alpha_emit_conditional_branch (enum rtx_code code)
/* If the constants doesn't fit into an immediate, but can
be generated by lda/ldah, we adjust the argument and
compare against zero, so we can use beq/bne directly. */
else if (GET_CODE (op1) == CONST_INT && (code == EQ || code == NE))
/* ??? Don't do this when comparing against symbols, otherwise
we'll reduce (&x == 0x1234) to (&x-0x1234 == 0), which will
be declared false out of hand (at least for non-weak). */
else if (GET_CODE (op1) == CONST_INT
&& (code == EQ || code == NE)
&& !(symbolic_operand (op0, VOIDmode)
|| (GET_CODE (op0) == REG && REG_POINTER (op0))))
{
HOST_WIDE_INT v = INTVAL (op1), n = -v;

View file

@ -3827,8 +3827,8 @@
})
(define_expand "cmpdi"
[(set (cc0) (compare (match_operand:DI 0 "general_operand" "")
(match_operand:DI 1 "general_operand" "")))]
[(set (cc0) (compare (match_operand:DI 0 "some_operand" "")
(match_operand:DI 1 "some_operand" "")))]
""
{
alpha_compare.op0 = operands[0];
@ -4160,100 +4160,6 @@
operands[6], const0_rtx);
})
(define_split
[(set (pc)
(if_then_else
(match_operator 1 "comparison_operator"
[(match_operand:DI 2 "reg_or_0_operand" "")
(match_operand:DI 3 "reg_or_cint_operand" "")])
(label_ref (match_operand 0 "" ""))
(pc)))
(clobber (match_operand:DI 4 "register_operand" ""))]
"operands[3] != const0_rtx"
[(set (match_dup 4) (match_dup 5))
(set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
{
enum rtx_code code = GET_CODE (operands[1]);
int unsignedp = (code == GEU || code == LEU || code == GTU || code == LTU);
if (code == NE || code == EQ
|| (extended_count (operands[2], DImode, unsignedp) >= 1
&& extended_count (operands[3], DImode, unsignedp) >= 1))
{
if (GET_CODE (operands[3]) == CONST_INT)
operands[5] = gen_rtx_PLUS (DImode, operands[2],
GEN_INT (- INTVAL (operands[3])));
else
operands[5] = gen_rtx_MINUS (DImode, operands[2], operands[3]);
operands[6] = gen_rtx_fmt_ee (code, VOIDmode, operands[4], const0_rtx);
}
else if (code == EQ || code == LE || code == LT
|| code == LEU || code == LTU)
{
operands[5] = gen_rtx_fmt_ee (code, DImode, operands[2], operands[3]);
operands[6] = gen_rtx_NE (VOIDmode, operands[4], const0_rtx);
}
else
{
operands[5] = gen_rtx_fmt_ee (reverse_condition (code), DImode,
operands[2], operands[3]);
operands[6] = gen_rtx_EQ (VOIDmode, operands[4], const0_rtx);
}
})
(define_split
[(set (pc)
(if_then_else
(match_operator 1 "comparison_operator"
[(match_operand:SI 2 "reg_or_0_operand" "")
(match_operand:SI 3 "const_int_operand" "")])
(label_ref (match_operand 0 "" ""))
(pc)))
(clobber (match_operand:DI 4 "register_operand" ""))]
"operands[3] != const0_rtx
&& (GET_CODE (operands[1]) == EQ || GET_CODE (operands[1]) == NE)"
[(set (match_dup 4) (match_dup 5))
(set (pc) (if_then_else (match_dup 6) (label_ref (match_dup 0)) (pc)))]
{
rtx tem;
if (GET_CODE (operands[3]) == CONST_INT)
tem = gen_rtx_PLUS (SImode, operands[2],
GEN_INT (- INTVAL (operands[3])));
else
tem = gen_rtx_MINUS (SImode, operands[2], operands[3]);
operands[5] = gen_rtx_SIGN_EXTEND (DImode, tem);
operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[1]), VOIDmode,
operands[4], const0_rtx);
})
;; We can convert such things as "a > 0xffff" to "t = a & ~ 0xffff; t != 0".
;; This eliminates one, and sometimes two, insns when the AND can be done
;; with a ZAP.
(define_split
[(set (match_operand:DI 0 "register_operand" "")
(match_operator:DI 1 "comparison_operator"
[(match_operand:DI 2 "register_operand" "")
(match_operand:DI 3 "const_int_operand" "")]))
(clobber (match_operand:DI 4 "register_operand" ""))]
"exact_log2 (INTVAL (operands[3]) + 1) >= 0
&& (GET_CODE (operands[1]) == GTU
|| GET_CODE (operands[1]) == LEU
|| ((GET_CODE (operands[1]) == GT || GET_CODE (operands[1]) == LE)
&& extended_count (operands[2], DImode, 1) > 0))"
[(set (match_dup 4) (and:DI (match_dup 2) (match_dup 5)))
(set (match_dup 0) (match_dup 6))]
{
operands[5] = GEN_INT (~ INTVAL (operands[3]));
operands[6] = gen_rtx_fmt_ee (((GET_CODE (operands[1]) == GTU
|| GET_CODE (operands[1]) == GT)
? NE : EQ),
DImode, operands[4], const0_rtx);
})
;; Prefer to use cmp and arithmetic when possible instead of a cmove.
(define_split

View file

@ -721,6 +721,40 @@ force_reg (enum machine_mode mode, rtx x)
&& ! rtx_equal_p (x, SET_SRC (set)))
set_unique_reg_note (insn, REG_EQUAL, x);
/* Let optimizers know that TEMP is a pointer, and if so, the
known alignment of that pointer. */
{
unsigned align = 0;
if (GET_CODE (x) == SYMBOL_REF)
{
align = BITS_PER_UNIT;
if (SYMBOL_REF_DECL (x) && DECL_P (SYMBOL_REF_DECL (x)))
align = DECL_ALIGN (SYMBOL_REF_DECL (x));
}
else if (GET_CODE (x) == LABEL_REF)
align = BITS_PER_UNIT;
else if (GET_CODE (x) == CONST
&& GET_CODE (XEXP (x, 0)) == PLUS
&& GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF
&& GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
{
rtx s = XEXP (XEXP (x, 0), 0);
rtx c = XEXP (XEXP (x, 0), 1);
unsigned sa, ca;
sa = BITS_PER_UNIT;
if (SYMBOL_REF_DECL (s) && DECL_P (SYMBOL_REF_DECL (s)))
sa = DECL_ALIGN (SYMBOL_REF_DECL (s));
ca = exact_log2 (INTVAL (c) & -INTVAL (c)) * BITS_PER_UNIT;
align = MIN (sa, ca);
}
if (align)
mark_reg_pointer (temp, align);
}
return temp;
}