diff options
author | Jakub Jelinek <jakub@redhat.com> | 2015-01-23 20:55:16 +0100 |
---|---|---|
committer | Jakub Jelinek <jakub@gcc.gnu.org> | 2015-01-23 20:55:16 +0100 |
commit | 6c4d60f80aae979c4c317e5274babd404429f4cf (patch) | |
tree | 1e1f3b9630c3bd67e06282a119cee3f5d8c8a41f /gcc/cse.c | |
parent | b2d7aa9a6246ba1454c1ebd04bb25c96ad0ec974 (diff) | |
download | gcc-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.c | 40 |
1 files changed, 33 insertions, 7 deletions
@@ -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 |