aboutsummaryrefslogtreecommitdiff
path: root/gcc/cse.c
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2015-01-23 20:55:16 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2015-01-23 20:55:16 +0100
commit6c4d60f80aae979c4c317e5274babd404429f4cf (patch)
tree1e1f3b9630c3bd67e06282a119cee3f5d8c8a41f /gcc/cse.c
parentb2d7aa9a6246ba1454c1ebd04bb25c96ad0ec974 (diff)
downloadgcc-6c4d60f80aae979c4c317e5274babd404429f4cf.zip
gcc-6c4d60f80aae979c4c317e5274babd404429f4cf.tar.gz
gcc-6c4d60f80aae979c4c317e5274babd404429f4cf.tar.bz2
re PR rtl-optimization/63637 (CSE on x86 asm()-s no longer working due to PR/60663 fix)
PR rtl-optimization/63637 PR rtl-optimization/60663 * cse.c (merge_equiv_classes): Set new_elt->cost to MAX_COST if elt->cost is MAX_COST for ASM_OPERANDS. (find_sets_in_insn): Fix up comment typo. (cse_insn): Don't set src_volatile for all non-volatile ASM_OPERANDS in PARALLELs, but just those with multiple outputs or with "memory" clobber. Set elt->cost to MAX_COST for ASM_OPERANDS in PARALLEL. Set src_elt->cost to MAX_COST if new_src is ASM_OPERANDS and elt->cost is MAX_COST. * gcc.dg/pr63637-1.c: New test. * gcc.dg/pr63637-2.c: New test. * gcc.dg/pr63637-3.c: New test. * gcc.dg/pr63637-4.c: New test. * gcc.dg/pr63637-5.c: New test. * gcc.dg/pr63637-6.c: New test. * gcc.target/i386/pr63637-1.c: New test. * gcc.target/i386/pr63637-2.c: New test. * gcc.target/i386/pr63637-3.c: New test. * gcc.target/i386/pr63637-4.c: New test. * gcc.target/i386/pr63637-5.c: New test. * gcc.target/i386/pr63637-6.c: New test. From-SVN: r220059
Diffstat (limited to 'gcc/cse.c')
-rw-r--r--gcc/cse.c40
1 files changed, 33 insertions, 7 deletions
diff --git a/gcc/cse.c b/gcc/cse.c
index 4732d81..7edd901 100644
--- a/gcc/cse.c
+++ b/gcc/cse.c
@@ -1807,6 +1807,8 @@ merge_equiv_classes (struct table_elt *class1, struct table_elt *class2)
}
new_elt = insert (exp, class1, hash, mode);
new_elt->in_memory = hash_arg_in_memory;
+ if (GET_CODE (exp) == ASM_OPERANDS && elt->cost == MAX_COST)
+ new_elt->cost = MAX_COST;
}
}
}
@@ -4275,7 +4277,7 @@ find_sets_in_insn (rtx_insn *insn, struct set **psets)
{
int i, lim = XVECLEN (x, 0);
- /* Go over the epressions of the PARALLEL in forward order, to
+ /* Go over the expressions of the PARALLEL in forward order, to
put them in the same order in the SETS array. */
for (i = 0; i < lim; i++)
{
@@ -4651,12 +4653,27 @@ cse_insn (rtx_insn *insn)
&& REGNO (dest) >= FIRST_PSEUDO_REGISTER)
sets[i].src_volatile = 1;
- /* Also do not record result of a non-volatile inline asm with
- more than one result or with clobbers, we do not want CSE to
- break the inline asm apart. */
else if (GET_CODE (src) == ASM_OPERANDS
&& GET_CODE (x) == PARALLEL)
- sets[i].src_volatile = 1;
+ {
+ /* Do not record result of a non-volatile inline asm with
+ more than one result. */
+ if (n_sets > 1)
+ sets[i].src_volatile = 1;
+
+ int j, lim = XVECLEN (x, 0);
+ for (j = 0; j < lim; j++)
+ {
+ rtx y = XVECEXP (x, 0, j);
+ /* And do not record result of a non-volatile inline asm
+ with "memory" clobber. */
+ if (GET_CODE (y) == CLOBBER && MEM_P (XEXP (y, 0)))
+ {
+ sets[i].src_volatile = 1;
+ break;
+ }
+ }
+ }
#if 0
/* It is no longer clear why we used to do this, but it doesn't
@@ -5247,8 +5264,8 @@ cse_insn (rtx_insn *insn)
;
/* Look for a substitution that makes a valid insn. */
- else if (validate_unshare_change
- (insn, &SET_SRC (sets[i].rtl), trial, 0))
+ else if (validate_unshare_change (insn, &SET_SRC (sets[i].rtl),
+ trial, 0))
{
rtx new_rtx = canon_reg (SET_SRC (sets[i].rtl), insn);
@@ -5610,6 +5627,12 @@ cse_insn (rtx_insn *insn)
}
elt = insert (src, classp, sets[i].src_hash, mode);
elt->in_memory = sets[i].src_in_memory;
+ /* If inline asm has any clobbers, ensure we only reuse
+ existing inline asms and never try to put the ASM_OPERANDS
+ into an insn that isn't inline asm. */
+ if (GET_CODE (src) == ASM_OPERANDS
+ && GET_CODE (x) == PARALLEL)
+ elt->cost = MAX_COST;
sets[i].src_elt = classp = elt;
}
if (sets[i].src_const && sets[i].src_const_elt == 0
@@ -5923,6 +5946,9 @@ cse_insn (rtx_insn *insn)
}
src_elt = insert (new_src, classp, src_hash, new_mode);
src_elt->in_memory = elt->in_memory;
+ if (GET_CODE (new_src) == ASM_OPERANDS
+ && elt->cost == MAX_COST)
+ src_elt->cost = MAX_COST;
}
else if (classp && classp != src_elt->first_same_value)
/* Show that two things that we've seen before are