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:
parent
0d593f318b
commit
4a4f95d919
4 changed files with 51 additions and 97 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
34
gcc/explow.c
34
gcc/explow.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue