Commit 509f4495 by Jakub Jelinek Committed by Jakub Jelinek

cselib.c (promote_debug_loc): Allow l->next non-NULL for cselib_preserve_constants.

	* cselib.c (promote_debug_loc): Allow l->next non-NULL for
	cselib_preserve_constants.
	(cselib_lookup_1): If cselib_preserve_constants,
	a new VALUE is being created for REG and there is a VALUE for the
	same register in wider mode, add another loc with lowpart SUBREG of
	the wider VALUE.
	(cselib_subst_to_values): Handle ENTRY_VALUE.
	* var-tracking.c  (replace_expr_with_values): Return NULL for
	ENTRY_VALUE too.
	* dwarf2out.c (convert_descriptor_to_signed): New function.
	(mem_loc_descriptor) <case ZERO_EXTEND>: Optimize using DW_OP_and
	instead of two shifts.
	(mem_loc_descriptor) <do_shift>: ZERO_EXTEND second argument to
	the right mode if needed.
	(mem_loc_descriptor) <case MOD>: For typed ops just use DW_OP_mod.
	(mem_loc_descriptor) <case UNSIGNED_FIX>: Use
	convert_descriptor_to_signed.
	(mem_loc_descriptor) <case UDIV, CLZ, CTZ, FFS, POPCOUNT, PARITY,
	BSWAP, ROTATE, ROTATERT>: Handle these rtls.

	* gcc.dg/guality/bswaptest.c: New test.
	* gcc.dg/guality/clztest.c: New test.
	* gcc.dg/guality/ctztest.c: New test.
	* gcc.dg/guality/rotatetest.c: New test.

From-SVN: r174508
parent 7351d8da
2011-05-31 Jakub Jelinek <jakub@redhat.com> 2011-05-31 Jakub Jelinek <jakub@redhat.com>
* cselib.c (promote_debug_loc): Allow l->next non-NULL for
cselib_preserve_constants.
(cselib_lookup_1): If cselib_preserve_constants,
a new VALUE is being created for REG and there is a VALUE for the
same register in wider mode, add another loc with lowpart SUBREG of
the wider VALUE.
(cselib_subst_to_values): Handle ENTRY_VALUE.
* var-tracking.c (replace_expr_with_values): Return NULL for
ENTRY_VALUE too.
* dwarf2out.c (convert_descriptor_to_signed): New function.
(mem_loc_descriptor) <case ZERO_EXTEND>: Optimize using DW_OP_and
instead of two shifts.
(mem_loc_descriptor) <do_shift>: ZERO_EXTEND second argument to
the right mode if needed.
(mem_loc_descriptor) <case MOD>: For typed ops just use DW_OP_mod.
(mem_loc_descriptor) <case UNSIGNED_FIX>: Use
convert_descriptor_to_signed.
(mem_loc_descriptor) <case UDIV, CLZ, CTZ, FFS, POPCOUNT, PARITY,
BSWAP, ROTATE, ROTATERT>: Handle these rtls.
PR target/48688 PR target/48688
* config/i386/i386.md (*lea_general_4): New define_insn_and_split. * config/i386/i386.md (*lea_general_4): New define_insn_and_split.
......
...@@ -257,7 +257,7 @@ promote_debug_loc (struct elt_loc_list *l) ...@@ -257,7 +257,7 @@ promote_debug_loc (struct elt_loc_list *l)
{ {
n_debug_values--; n_debug_values--;
l->setting_insn = cselib_current_insn; l->setting_insn = cselib_current_insn;
gcc_assert (!l->next); gcc_assert (!l->next || cselib_preserve_constants);
} }
} }
...@@ -1719,6 +1719,12 @@ cselib_subst_to_values (rtx x, enum machine_mode memmode) ...@@ -1719,6 +1719,12 @@ cselib_subst_to_values (rtx x, enum machine_mode memmode)
} }
return e->val_rtx; return e->val_rtx;
case ENTRY_VALUE:
e = cselib_lookup (x, GET_MODE (x), 0, memmode);
if (! e)
break;
return e->val_rtx;
case CONST_DOUBLE: case CONST_DOUBLE:
case CONST_VECTOR: case CONST_VECTOR:
case CONST_INT: case CONST_INT:
...@@ -1843,6 +1849,43 @@ cselib_lookup_1 (rtx x, enum machine_mode mode, ...@@ -1843,6 +1849,43 @@ cselib_lookup_1 (rtx x, enum machine_mode mode,
used_regs[n_used_regs++] = i; used_regs[n_used_regs++] = i;
REG_VALUES (i) = new_elt_list (REG_VALUES (i), NULL); REG_VALUES (i) = new_elt_list (REG_VALUES (i), NULL);
} }
else if (cselib_preserve_constants
&& GET_MODE_CLASS (mode) == MODE_INT)
{
/* During var-tracking, try harder to find equivalences
for SUBREGs. If a setter sets say a DImode register
and user uses that register only in SImode, add a lowpart
subreg location. */
struct elt_list *lwider = NULL;
l = REG_VALUES (i);
if (l && l->elt == NULL)
l = l->next;
for (; l; l = l->next)
if (GET_MODE_CLASS (GET_MODE (l->elt->val_rtx)) == MODE_INT
&& GET_MODE_SIZE (GET_MODE (l->elt->val_rtx))
> GET_MODE_SIZE (mode)
&& (lwider == NULL
|| GET_MODE_SIZE (GET_MODE (l->elt->val_rtx))
< GET_MODE_SIZE (GET_MODE (lwider->elt->val_rtx))))
{
struct elt_loc_list *el;
if (i < FIRST_PSEUDO_REGISTER
&& hard_regno_nregs[i][GET_MODE (l->elt->val_rtx)] != 1)
continue;
for (el = l->elt->locs; el; el = el->next)
if (!REG_P (el->loc))
break;
if (el)
lwider = l;
}
if (lwider)
{
rtx sub = lowpart_subreg (mode, lwider->elt->val_rtx,
GET_MODE (lwider->elt->val_rtx));
if (sub)
e->locs->next = new_elt_loc_list (e->locs->next, sub);
}
}
REG_VALUES (i)->next = new_elt_list (REG_VALUES (i)->next, e); REG_VALUES (i)->next = new_elt_list (REG_VALUES (i)->next, e);
slot = cselib_find_slot (x, e->hash, INSERT, memmode); slot = cselib_find_slot (x, e->hash, INSERT, memmode);
*slot = e; *slot = e;
......
2011-05-31 Jakub Jelinek <jakub@redhat.com> 2011-05-31 Jakub Jelinek <jakub@redhat.com>
* gcc.dg/guality/bswaptest.c: New test.
* gcc.dg/guality/clztest.c: New test.
* gcc.dg/guality/ctztest.c: New test.
* gcc.dg/guality/rotatetest.c: New test.
PR target/48688 PR target/48688
* gcc.target/i386/pr48688.c: New test. * gcc.target/i386/pr48688.c: New test.
......
/* { dg-do run { target { x86_64-*-* && lp64 } } } */
/* { dg-options "-g" } */
volatile int vv;
__attribute__((noclone, noinline)) long
foo (long x)
{
long f = __builtin_bswap64 (x);
long g = f;
asm volatile ("" : "+r" (f));
vv++; /* { dg-final { gdb-test 12 "g" "f" } } */
return f;
}
__attribute__((noclone, noinline)) int
bar (int x)
{
int f = __builtin_bswap32 (x);
int g = f;
asm volatile ("" : "+r" (f));
vv++; /* { dg-final { gdb-test 22 "g" "f" } } */
return f;
}
int
main ()
{
foo (0x123456789abcde0fUL);
bar (0x12345678);
return 0;
}
/* { dg-do run { target { x86_64-*-* && lp64 } } } */
/* { dg-options "-g" } */
volatile int vv;
__attribute__((noinline, noclone)) long
foo (long x)
{
long f = __builtin_clzl (x);
long g = f;
asm volatile ("" : "+r" (f));
vv++; /* { dg-final { gdb-test 12 "g" "f" } } */
return f;
}
__attribute__((noinline, noclone)) long
bar (long x)
{
long f = __builtin_clzl (x);
long g = f;
asm volatile ("" : "+r" (f));
vv++; /* { dg-final { gdb-test 22 "g" "f" } } */
return f;
}
int
main ()
{
long x = vv;
foo (x + 0x123456UL);
bar (x + 0x7fffffffUL);
return 0;
}
/* { dg-do run { target { x86_64-*-* && lp64 } } } */
/* { dg-options "-g" } */
volatile int vv;
__attribute__((noinline, noclone)) long
foo (long x)
{
long f = __builtin_ctzl (x);
long g = f;
asm volatile ("" : "+r" (f));
vv++; /* { dg-final { gdb-test 12 "g" "f" } } */
return f;
}
__attribute__((noinline, noclone)) long
bar (long x)
{
long f = __builtin_ctzl (x);
long g = f;
asm volatile ("" : "+r" (f));
vv++; /* { dg-final { gdb-test 22 "g" "f" } } */
return f;
}
int
main ()
{
long x = vv;
foo (x + 0x1234560UL);
bar (x + 0x7fff8000UL);
return 0;
}
/* { dg-do run { target { x86_64-*-* && lp64 } } } */
/* { dg-options "-g" } */
volatile int vv;
__attribute__((noclone, noinline)) long
f1 (unsigned long x)
{
long f = (x << 12) | (x >> (64 - 12));
long g = f;
asm volatile ("" : "+r" (f));
vv++; /* { dg-final { gdb-test 12 "g" "f" } } */
return f;
}
__attribute__((noclone, noinline)) long
f2 (unsigned long x, int y)
{
long f = (x << y) | (x >> (64 - y));
long g = f;
asm volatile ("" : "+r" (f));
vv++; /* { dg-final { gdb-test 22 "g" "f" } } */
return f;
}
__attribute__((noclone, noinline)) long
f3 (unsigned long x, int y)
{
long f = (x >> y) | (x << (64 - y));
long g = f;
asm volatile ("" : "+r" (f));
vv++; /* { dg-final { gdb-test 32 "g" "f" } } */
return f;
}
__attribute__((noclone, noinline)) unsigned int
f4 (unsigned int x)
{
unsigned int f = (x << 12) | (x >> (32 - 12));
unsigned int g = f;
asm volatile ("" : "+r" (f));
vv++; /* { dg-final { gdb-test 42 "g" "f" } } */
return f;
}
__attribute__((noclone, noinline)) unsigned int
f5 (unsigned int x, int y)
{
unsigned int f = (x << y) | (x >> (64 - y));
unsigned int g = f;
asm volatile ("" : "+r" (f));
vv++; /* { dg-final { gdb-test 52 "g" "f" } } */
return f;
}
__attribute__((noclone, noinline)) unsigned int
f6 (unsigned int x, int y)
{
unsigned int f = (x >> y) | (x << (64 - y));
unsigned int g = f;
asm volatile ("" : "+r" (f));
vv++; /* { dg-final { gdb-test 62 "g" "f" } } */
return f;
}
int
main ()
{
f1 (0x123456789abcde0fUL);
f2 (0x123456789abcde0fUL, 18);
f3 (0x123456789abcde0fUL, 17);
f4 (0x12345678);
f5 (0x12345678, 18);
f6 (0x12345678, 17);
return 0;
}
...@@ -4837,7 +4837,7 @@ get_address_mode (rtx mem) ...@@ -4837,7 +4837,7 @@ get_address_mode (rtx mem)
static rtx static rtx
replace_expr_with_values (rtx loc) replace_expr_with_values (rtx loc)
{ {
if (REG_P (loc)) if (REG_P (loc) || GET_CODE (loc) == ENTRY_VALUE)
return NULL; return NULL;
else if (MEM_P (loc)) else if (MEM_P (loc))
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment