aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@libertysurf.fr>2004-07-08 14:54:53 +0200
committerEric Botcazou <ebotcazou@gcc.gnu.org>2004-07-08 12:54:53 +0000
commit1d511ed5fc76892c3f5dca6b78a1b7254bc15bd1 (patch)
tree6e6c41a66a7717ee71e1a684bb8ced0c9f769712 /gcc
parent47293da3149269ec799f05bc446aeb7ca0133cb3 (diff)
downloadgcc-1d511ed5fc76892c3f5dca6b78a1b7254bc15bd1.zip
gcc-1d511ed5fc76892c3f5dca6b78a1b7254bc15bd1.tar.gz
gcc-1d511ed5fc76892c3f5dca6b78a1b7254bc15bd1.tar.bz2
re PR rtl-optimization/16199 (ICE while compiling apache 2.0.49)
PR target/16199 * config/sparc/sparc.c (sparc_emit_set_symbolic_const64): When 'temp' is zero, generate new pseudos as needed and emit the sequence of insns in single-assignment form. Resync comments with code. (sparc_emit_set_const64): Pass zero as 'temp' argument to above function before reload. From-SVN: r84285
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/config/sparc/sparc.c194
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.c-torture/compile/20040708-1.c68
4 files changed, 213 insertions, 63 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 74b28b3..d9cf195 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2004-07-08 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ PR target/16199
+ * config/sparc/sparc.c (sparc_emit_set_symbolic_const64): When
+ 'temp' is zero, generate new pseudos as needed and emit the
+ sequence of insns in single-assignment form. Resync comments
+ with code.
+ (sparc_emit_set_const64): Pass zero as 'temp' argument to above
+ function before reload.
+
2004-07-08 Nathan Sidwell <nathan@codesourcery.com>
* vec.c (vec_assert_fail): Remove duplicate 'function'.
diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c
index 75ce147..02a8040 100644
--- a/gcc/config/sparc/sparc.c
+++ b/gcc/config/sparc/sparc.c
@@ -1437,18 +1437,25 @@ sparc_emit_set_const32 (rtx op0, rtx op1)
}
-/* SPARC-v9 code-model support. */
+/* Load OP1, a symbolic 64-bit constant, into OP0, a DImode register.
+ If TEMP is non-zero, we are forbidden to use any other scratch
+ registers. Otherwise, we are allowed to generate them as needed.
+
+ Note that TEMP may have TImode if the code model is TARGET_CM_MEDANY
+ or TARGET_CM_EMBMEDANY (see the reload_indi and reload_outdi patterns). */
void
-sparc_emit_set_symbolic_const64 (rtx op0, rtx op1, rtx temp1)
+sparc_emit_set_symbolic_const64 (rtx op0, rtx op1, rtx temp)
{
- rtx ti_temp1 = 0;
+ rtx temp1, temp2, temp3, temp4, temp5;
+ rtx ti_temp = 0;
- if (temp1 && GET_MODE (temp1) == TImode)
+ if (temp && GET_MODE (temp) == TImode)
{
- ti_temp1 = temp1;
- temp1 = gen_rtx_REG (DImode, REGNO (temp1));
+ ti_temp = temp;
+ temp = gen_rtx_REG (DImode, REGNO (temp));
}
+ /* SPARC-V9 code-model support. */
switch (sparc_cmodel)
{
case CM_MEDLOW:
@@ -1460,8 +1467,13 @@ sparc_emit_set_symbolic_const64 (rtx op0, rtx op1, rtx temp1)
The executable must be in the low 4TB of the virtual address
space.
- sethi %hi(symbol), %temp
- or %temp, %lo(symbol), %reg */
+ sethi %hi(symbol), %temp1
+ or %temp1, %lo(symbol), %reg */
+ if (temp)
+ temp1 = temp; /* op0 is allowed. */
+ else
+ temp1 = gen_reg_rtx (DImode);
+
emit_insn (gen_rtx_SET (VOIDmode, temp1, gen_rtx_HIGH (DImode, op1)));
emit_insn (gen_rtx_SET (VOIDmode, op0, gen_rtx_LO_SUM (DImode, temp1, op1)));
break;
@@ -1479,11 +1491,24 @@ sparc_emit_set_symbolic_const64 (rtx op0, rtx op1, rtx temp1)
or %temp1, %m44(symbol), %temp2
sllx %temp2, 12, %temp3
or %temp3, %l44(symbol), %reg */
- emit_insn (gen_seth44 (op0, op1));
- emit_insn (gen_setm44 (op0, op0, op1));
- emit_insn (gen_rtx_SET (VOIDmode, temp1,
- gen_rtx_ASHIFT (DImode, op0, GEN_INT (12))));
- emit_insn (gen_setl44 (op0, temp1, op1));
+ if (temp)
+ {
+ temp1 = op0;
+ temp2 = op0;
+ temp3 = temp; /* op0 is allowed. */
+ }
+ else
+ {
+ temp1 = gen_reg_rtx (DImode);
+ temp2 = gen_reg_rtx (DImode);
+ temp3 = gen_reg_rtx (DImode);
+ }
+
+ emit_insn (gen_seth44 (temp1, op1));
+ emit_insn (gen_setm44 (temp2, temp1, op1));
+ emit_insn (gen_rtx_SET (VOIDmode, temp3,
+ gen_rtx_ASHIFT (DImode, temp2, GEN_INT (12))));
+ emit_insn (gen_setl44 (op0, temp3, op1));
break;
case CM_MEDANY:
@@ -1498,29 +1523,44 @@ sparc_emit_set_symbolic_const64 (rtx op0, rtx op1, rtx temp1)
sethi %hh(symbol), %temp1
sethi %lm(symbol), %temp2
or %temp1, %hm(symbol), %temp3
- or %temp2, %lo(symbol), %temp4
- sllx %temp3, 32, %temp5
- or %temp4, %temp5, %reg */
-
- /* It is possible that one of the registers we got for operands[2]
- might coincide with that of operands[0] (which is why we made
- it TImode). Pick the other one to use as our scratch. */
- if (rtx_equal_p (temp1, op0))
+ sllx %temp3, 32, %temp4
+ or %temp4, %temp2, %temp5
+ or %temp5, %lo(symbol), %reg */
+ if (temp)
{
- if (ti_temp1)
- temp1 = gen_rtx_REG (DImode, REGNO (temp1) + 1);
- else
- abort();
+ /* It is possible that one of the registers we got for operands[2]
+ might coincide with that of operands[0] (which is why we made
+ it TImode). Pick the other one to use as our scratch. */
+ if (rtx_equal_p (temp, op0))
+ {
+ if (ti_temp)
+ temp = gen_rtx_REG (DImode, REGNO (temp) + 1);
+ else
+ abort();
+ }
+ temp1 = op0;
+ temp2 = temp; /* op0 is _not_ allowed, see above. */
+ temp3 = op0;
+ temp4 = op0;
+ temp5 = op0;
+ }
+ else
+ {
+ temp1 = gen_reg_rtx (DImode);
+ temp2 = gen_reg_rtx (DImode);
+ temp3 = gen_reg_rtx (DImode);
+ temp4 = gen_reg_rtx (DImode);
+ temp5 = gen_reg_rtx (DImode);
}
- emit_insn (gen_sethh (op0, op1));
- emit_insn (gen_setlm (temp1, op1));
- emit_insn (gen_sethm (op0, op0, op1));
- emit_insn (gen_rtx_SET (VOIDmode, op0,
- gen_rtx_ASHIFT (DImode, op0, GEN_INT (32))));
- emit_insn (gen_rtx_SET (VOIDmode, op0,
- gen_rtx_PLUS (DImode, op0, temp1)));
- emit_insn (gen_setlo (op0, op0, op1));
+ emit_insn (gen_sethh (temp1, op1));
+ emit_insn (gen_setlm (temp2, op1));
+ emit_insn (gen_sethm (temp3, temp1, op1));
+ emit_insn (gen_rtx_SET (VOIDmode, temp4,
+ gen_rtx_ASHIFT (DImode, temp3, GEN_INT (32))));
+ emit_insn (gen_rtx_SET (VOIDmode, temp5,
+ gen_rtx_PLUS (DImode, temp4, temp2)));
+ emit_insn (gen_setlo (op0, temp5, op1));
break;
case CM_EMBMEDANY:
@@ -1532,42 +1572,69 @@ sparc_emit_set_symbolic_const64 (rtx op0, rtx op1, rtx temp1)
look different.
Data segment: sethi %hi(symbol), %temp1
- or %temp1, %lo(symbol), %temp2
- add %temp2, EMBMEDANY_BASE_REG, %reg
-
- Text segment: sethi %uhi(symbol), %temp1
- sethi %hi(symbol), %temp2
- or %temp1, %ulo(symbol), %temp3
- or %temp2, %lo(symbol), %temp4
- sllx %temp3, 32, %temp5
- or %temp4, %temp5, %reg */
+ add %temp1, EMBMEDANY_BASE_REG, %temp2
+ or %temp2, %lo(symbol), %reg */
if (data_segment_operand (op1, GET_MODE (op1)))
{
+ if (temp)
+ {
+ temp1 = temp; /* op0 is allowed. */
+ temp2 = op0;
+ }
+ else
+ {
+ temp1 = gen_reg_rtx (DImode);
+ temp2 = gen_reg_rtx (DImode);
+ }
+
emit_insn (gen_embmedany_sethi (temp1, op1));
- emit_insn (gen_embmedany_brsum (op0, temp1));
- emit_insn (gen_embmedany_losum (op0, op0, op1));
+ emit_insn (gen_embmedany_brsum (temp2, temp1));
+ emit_insn (gen_embmedany_losum (op0, temp2, op1));
}
+
+ /* Text segment: sethi %uhi(symbol), %temp1
+ sethi %hi(symbol), %temp2
+ or %temp1, %ulo(symbol), %temp3
+ sllx %temp3, 32, %temp4
+ or %temp4, %temp2, %temp5
+ or %temp5, %lo(symbol), %reg */
else
{
- /* It is possible that one of the registers we got for operands[2]
- might coincide with that of operands[0] (which is why we made
- it TImode). Pick the other one to use as our scratch. */
- if (rtx_equal_p (temp1, op0))
+ if (temp)
{
- if (ti_temp1)
- temp1 = gen_rtx_REG (DImode, REGNO (temp1) + 1);
- else
- abort();
+ /* It is possible that one of the registers we got for operands[2]
+ might coincide with that of operands[0] (which is why we made
+ it TImode). Pick the other one to use as our scratch. */
+ if (rtx_equal_p (temp, op0))
+ {
+ if (ti_temp)
+ temp = gen_rtx_REG (DImode, REGNO (temp) + 1);
+ else
+ abort();
+ }
+ temp1 = op0;
+ temp2 = temp; /* op0 is _not_ allowed, see above. */
+ temp3 = op0;
+ temp4 = op0;
+ temp5 = op0;
+ }
+ else
+ {
+ temp1 = gen_reg_rtx (DImode);
+ temp2 = gen_reg_rtx (DImode);
+ temp3 = gen_reg_rtx (DImode);
+ temp4 = gen_reg_rtx (DImode);
+ temp5 = gen_reg_rtx (DImode);
}
- emit_insn (gen_embmedany_textuhi (op0, op1));
- emit_insn (gen_embmedany_texthi (temp1, op1));
- emit_insn (gen_embmedany_textulo (op0, op0, op1));
- emit_insn (gen_rtx_SET (VOIDmode, op0,
- gen_rtx_ASHIFT (DImode, op0, GEN_INT (32))));
- emit_insn (gen_rtx_SET (VOIDmode, op0,
- gen_rtx_PLUS (DImode, op0, temp1)));
- emit_insn (gen_embmedany_textlo (op0, op0, op1));
+ emit_insn (gen_embmedany_textuhi (temp1, op1));
+ emit_insn (gen_embmedany_texthi (temp2, op1));
+ emit_insn (gen_embmedany_textulo (temp3, temp1, op1));
+ emit_insn (gen_rtx_SET (VOIDmode, temp4,
+ gen_rtx_ASHIFT (DImode, temp3, GEN_INT (32))));
+ emit_insn (gen_rtx_SET (VOIDmode, temp5,
+ gen_rtx_PLUS (DImode, temp4, temp2)));
+ emit_insn (gen_embmedany_textlo (op0, temp5, op1));
}
break;
@@ -1947,7 +2014,7 @@ sparc_emit_set_const64 (rtx op0, rtx op1)
unsigned HOST_WIDE_INT high_bits, low_bits;
int lowest_bit_set, highest_bit_set;
int all_bits_between_are_set;
- rtx temp;
+ rtx temp = 0;
/* Sanity check that we know what we are working with. */
if (! TARGET_ARCH64)
@@ -1963,8 +2030,6 @@ sparc_emit_set_const64 (rtx op0, rtx op1)
if (reload_in_progress || reload_completed)
temp = op0;
- else
- temp = gen_reg_rtx (DImode);
if (GET_CODE (op1) != CONST_DOUBLE
&& GET_CODE (op1) != CONST_INT)
@@ -1973,6 +2038,9 @@ sparc_emit_set_const64 (rtx op0, rtx op1)
return;
}
+ if (! temp)
+ temp = gen_reg_rtx (DImode);
+
if (GET_CODE (op1) == CONST_DOUBLE)
{
#if HOST_BITS_PER_WIDE_INT == 64
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1a3e2c0..8c6514a 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2004-07-08 Eric Botcazou <ebotcazou@libertysurf.fr>
+
+ * gcc.c-torture/compile/20040708-1.c: New test.
+
2004-07-08 Giovanni Bajo <giovannibajo@gcc.gnu.org>
PR c++/16169
diff --git a/gcc/testsuite/gcc.c-torture/compile/20040708-1.c b/gcc/testsuite/gcc.c-torture/compile/20040708-1.c
new file mode 100644
index 0000000..4a55391
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/compile/20040708-1.c
@@ -0,0 +1,68 @@
+/* PR rtl-optimization/16199 */
+/* Origin: Olaf Klein <oklein@smallo.ruhr.de> */
+
+typedef enum {
+ APR_LOCK_FCNTL,
+ APR_LOCK_FLOCK,
+ APR_LOCK_SYSVSEM,
+ APR_LOCK_PROC_PTHREAD,
+ APR_LOCK_POSIXSEM,
+ APR_LOCK_DEFAULT
+} apr_lockmech_e;
+
+struct apr_proc_mutex_unix_lock_methods_t {
+ unsigned int flags;
+ const char *name;
+};
+
+typedef struct apr_proc_mutex_unix_lock_methods_t apr_proc_mutex_unix_lock_methods_t;
+
+extern const apr_proc_mutex_unix_lock_methods_t apr_proc_mutex_unix_sysv_methods;
+
+struct apr_proc_mutex_t {
+ const apr_proc_mutex_unix_lock_methods_t *inter_meth;
+ int curr_locked;
+ char *fname;
+};
+
+typedef struct apr_proc_mutex_t apr_proc_mutex_t;
+
+extern const apr_proc_mutex_unix_lock_methods_t apr_proc_mutex_unix_proc_pthread_methods;
+
+extern const apr_proc_mutex_unix_lock_methods_t apr_proc_mutex_unix_fcntl_methods;
+
+static int proc_mutex_choose_method(apr_proc_mutex_t *new_mutex, apr_lockmech_e mech)
+{
+ switch (mech) {
+ case APR_LOCK_FCNTL:
+ new_mutex->inter_meth = &apr_proc_mutex_unix_fcntl_methods;
+ break;
+ case APR_LOCK_FLOCK:
+ return ((20000 + 50000) + 23);
+ break;
+ case APR_LOCK_SYSVSEM:
+ new_mutex->inter_meth = &apr_proc_mutex_unix_sysv_methods;
+ break;
+ case APR_LOCK_POSIXSEM:
+ return ((20000 + 50000) + 23);
+ break;
+ case APR_LOCK_PROC_PTHREAD:
+ new_mutex->inter_meth = &apr_proc_mutex_unix_proc_pthread_methods;
+ break;
+ case APR_LOCK_DEFAULT:
+ new_mutex->inter_meth = &apr_proc_mutex_unix_proc_pthread_methods;
+ break;
+ default:
+ return ((20000 + 50000) + 23);
+ }
+ return 0;
+}
+
+const char* apr_proc_mutex_defname(void)
+{
+ apr_proc_mutex_t mutex;
+
+ if (proc_mutex_choose_method(&mutex, APR_LOCK_DEFAULT) != 0) {
+ return "unknown";
+ }
+}