aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Kenner <kenner@gcc.gnu.org>1992-04-02 06:03:52 -0500
committerRichard Kenner <kenner@gcc.gnu.org>1992-04-02 06:03:52 -0500
commit29ebe69a723a07771383e4cddc917521ee6e82bd (patch)
tree672b626b63ce454b1ae9629f4e26a65581e0e2f3 /gcc
parentd64be5ecc9c27800b5e6cf09ec50a1e1ad1d5d2a (diff)
downloadgcc-29ebe69a723a07771383e4cddc917521ee6e82bd.zip
gcc-29ebe69a723a07771383e4cddc917521ee6e82bd.tar.gz
gcc-29ebe69a723a07771383e4cddc917521ee6e82bd.tar.bz2
*** empty log message ***
From-SVN: r666
Diffstat (limited to 'gcc')
-rw-r--r--gcc/fold-const.c2
-rw-r--r--gcc/genattrtab.c8
-rw-r--r--gcc/optabs.c18
3 files changed, 21 insertions, 7 deletions
diff --git a/gcc/fold-const.c b/gcc/fold-const.c
index 3801fbf..fab7300 100644
--- a/gcc/fold-const.c
+++ b/gcc/fold-const.c
@@ -3680,7 +3680,7 @@ fold (expr)
/* If this is A != 0 ? A : 0, this is simply A. For ==, it is
always zero. */
- if (integer_zerop (arg2))
+ if (integer_zerop (TREE_OPERAND (arg0, 1)) && integer_zerop (arg2))
{
if (comp_code == NE_EXPR)
return arg1;
diff --git a/gcc/genattrtab.c b/gcc/genattrtab.c
index 469c31d..a9524a1 100644
--- a/gcc/genattrtab.c
+++ b/gcc/genattrtab.c
@@ -396,7 +396,7 @@ attr_rtx (va_alist)
{
rtx arg0 = va_arg (p, rtx);
- hashcode = (code + RTL_HASH (arg0));
+ hashcode = ((int) code + RTL_HASH (arg0));
for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
if (h->hashcode == hashcode
&& GET_CODE (h->u.rtl) == code
@@ -416,7 +416,7 @@ attr_rtx (va_alist)
rtx arg0 = va_arg (p, rtx);
rtx arg1 = va_arg (p, rtx);
- hashcode = (code + RTL_HASH (arg0) + RTL_HASH (arg1));
+ hashcode = ((int) code + RTL_HASH (arg0) + RTL_HASH (arg1));
for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
if (h->hashcode == hashcode
&& GET_CODE (h->u.rtl) == code
@@ -436,7 +436,7 @@ attr_rtx (va_alist)
{
char * arg0 = va_arg (p, char *);
- hashcode = (code + RTL_HASH (arg0));
+ hashcode = ((int) code + RTL_HASH (arg0));
for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
if (h->hashcode == hashcode
&& GET_CODE (h->u.rtl) == code
@@ -456,7 +456,7 @@ attr_rtx (va_alist)
char * arg0 = va_arg (p, char *);
char * arg1 = va_arg (p, char *);
- hashcode = (code + RTL_HASH (arg0) + RTL_HASH (arg1));
+ hashcode = ((int) code + RTL_HASH (arg0) + RTL_HASH (arg1));
for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next)
if (h->hashcode == hashcode
&& GET_CODE (h->u.rtl) == code
diff --git a/gcc/optabs.c b/gcc/optabs.c
index b157853..c345fc9 100644
--- a/gcc/optabs.c
+++ b/gcc/optabs.c
@@ -1315,6 +1315,16 @@ emit_no_conflict_block (insns, target, op0, op1, equiv)
an insn to move RESULT to TARGET. This last insn will have a REQ_EQUAL
note with an operand of EQUIV.
+ Moving assignments to pseudos outside of the block is done to improve
+ the generated code, but is not required to generate correct code,
+ hence being unable to move an assignment is not grounds for not making
+ a libcall block. There are two reasons why it is safe to leave these
+ insns inside the block: First, we know that these pseudos cannot be
+ used in generated RTL outside the block since they are created for
+ temporary purposes within the block. Second, CSE will not record the
+ values of anything set inside a libcall block, so we know they must
+ be dead at the end of the block.
+
Except for the first group of insns (the ones setting pseudos), the
block is delimited by REG_RETVAL and REG_LIBCALL notes. */
@@ -1328,7 +1338,9 @@ emit_libcall_block (insns, target, result, equiv)
rtx prev, next, first, last, insn;
/* First emit all insns that set pseudos. Remove them from the list as
- we go. */
+ we go. Avoid insns that set pseudo which were referenced in previous
+ insns. These can be generated by move_by_pieces, for example,
+ to update an address. */
for (insn = insns; insn; insn = next)
{
@@ -1337,7 +1349,9 @@ emit_libcall_block (insns, target, result, equiv)
next = NEXT_INSN (insn);
if (set != 0 && GET_CODE (SET_DEST (set)) == REG
- && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER)
+ && REGNO (SET_DEST (set)) >= FIRST_PSEUDO_REGISTER
+ && ! reg_mentioned_p (SET_DEST (set), PATTERN (insns))
+ && ! reg_used_between_p (SET_DEST (set), insns, insn))
{
if (PREV_INSN (insn))
NEXT_INSN (PREV_INSN (insn)) = next;