Commit 1d511ed5 by Eric Botcazou Committed by Eric Botcazou

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
parent 47293da3
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> 2004-07-08 Nathan Sidwell <nathan@codesourcery.com>
* vec.c (vec_assert_fail): Remove duplicate 'function'. * vec.c (vec_assert_fail): Remove duplicate 'function'.
......
...@@ -1437,18 +1437,25 @@ sparc_emit_set_const32 (rtx op0, rtx op1) ...@@ -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 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; ti_temp = temp;
temp1 = gen_rtx_REG (DImode, REGNO (temp1)); temp = gen_rtx_REG (DImode, REGNO (temp));
} }
/* SPARC-V9 code-model support. */
switch (sparc_cmodel) switch (sparc_cmodel)
{ {
case CM_MEDLOW: case CM_MEDLOW:
...@@ -1460,8 +1467,13 @@ sparc_emit_set_symbolic_const64 (rtx op0, rtx op1, rtx temp1) ...@@ -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 The executable must be in the low 4TB of the virtual address
space. space.
sethi %hi(symbol), %temp sethi %hi(symbol), %temp1
or %temp, %lo(symbol), %reg */ 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, temp1, gen_rtx_HIGH (DImode, op1)));
emit_insn (gen_rtx_SET (VOIDmode, op0, gen_rtx_LO_SUM (DImode, temp1, op1))); emit_insn (gen_rtx_SET (VOIDmode, op0, gen_rtx_LO_SUM (DImode, temp1, op1)));
break; break;
...@@ -1479,11 +1491,24 @@ sparc_emit_set_symbolic_const64 (rtx op0, rtx op1, rtx temp1) ...@@ -1479,11 +1491,24 @@ sparc_emit_set_symbolic_const64 (rtx op0, rtx op1, rtx temp1)
or %temp1, %m44(symbol), %temp2 or %temp1, %m44(symbol), %temp2
sllx %temp2, 12, %temp3 sllx %temp2, 12, %temp3
or %temp3, %l44(symbol), %reg */ or %temp3, %l44(symbol), %reg */
emit_insn (gen_seth44 (op0, op1)); if (temp)
emit_insn (gen_setm44 (op0, op0, op1)); {
emit_insn (gen_rtx_SET (VOIDmode, temp1, temp1 = op0;
gen_rtx_ASHIFT (DImode, op0, GEN_INT (12)))); temp2 = op0;
emit_insn (gen_setl44 (op0, temp1, op1)); 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; break;
case CM_MEDANY: case CM_MEDANY:
...@@ -1498,29 +1523,44 @@ sparc_emit_set_symbolic_const64 (rtx op0, rtx op1, rtx temp1) ...@@ -1498,29 +1523,44 @@ sparc_emit_set_symbolic_const64 (rtx op0, rtx op1, rtx temp1)
sethi %hh(symbol), %temp1 sethi %hh(symbol), %temp1
sethi %lm(symbol), %temp2 sethi %lm(symbol), %temp2
or %temp1, %hm(symbol), %temp3 or %temp1, %hm(symbol), %temp3
or %temp2, %lo(symbol), %temp4 sllx %temp3, 32, %temp4
sllx %temp3, 32, %temp5 or %temp4, %temp2, %temp5
or %temp4, %temp5, %reg */ or %temp5, %lo(symbol), %reg */
if (temp)
/* 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 (ti_temp1) /* It is possible that one of the registers we got for operands[2]
temp1 = gen_rtx_REG (DImode, REGNO (temp1) + 1); might coincide with that of operands[0] (which is why we made
else it TImode). Pick the other one to use as our scratch. */
abort(); 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_sethh (temp1, op1));
emit_insn (gen_setlm (temp1, op1)); emit_insn (gen_setlm (temp2, op1));
emit_insn (gen_sethm (op0, op0, op1)); emit_insn (gen_sethm (temp3, temp1, op1));
emit_insn (gen_rtx_SET (VOIDmode, op0, emit_insn (gen_rtx_SET (VOIDmode, temp4,
gen_rtx_ASHIFT (DImode, op0, GEN_INT (32)))); gen_rtx_ASHIFT (DImode, temp3, GEN_INT (32))));
emit_insn (gen_rtx_SET (VOIDmode, op0, emit_insn (gen_rtx_SET (VOIDmode, temp5,
gen_rtx_PLUS (DImode, op0, temp1))); gen_rtx_PLUS (DImode, temp4, temp2)));
emit_insn (gen_setlo (op0, op0, op1)); emit_insn (gen_setlo (op0, temp5, op1));
break; break;
case CM_EMBMEDANY: case CM_EMBMEDANY:
...@@ -1532,42 +1572,69 @@ sparc_emit_set_symbolic_const64 (rtx op0, rtx op1, rtx temp1) ...@@ -1532,42 +1572,69 @@ sparc_emit_set_symbolic_const64 (rtx op0, rtx op1, rtx temp1)
look different. look different.
Data segment: sethi %hi(symbol), %temp1 Data segment: sethi %hi(symbol), %temp1
or %temp1, %lo(symbol), %temp2 add %temp1, EMBMEDANY_BASE_REG, %temp2
add %temp2, EMBMEDANY_BASE_REG, %reg or %temp2, %lo(symbol), %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 */
if (data_segment_operand (op1, GET_MODE (op1))) 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_sethi (temp1, op1));
emit_insn (gen_embmedany_brsum (op0, temp1)); emit_insn (gen_embmedany_brsum (temp2, temp1));
emit_insn (gen_embmedany_losum (op0, op0, op1)); 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 else
{ {
/* It is possible that one of the registers we got for operands[2] if (temp)
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 (ti_temp1) /* It is possible that one of the registers we got for operands[2]
temp1 = gen_rtx_REG (DImode, REGNO (temp1) + 1); might coincide with that of operands[0] (which is why we made
else it TImode). Pick the other one to use as our scratch. */
abort(); 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_textuhi (temp1, op1));
emit_insn (gen_embmedany_texthi (temp1, op1)); emit_insn (gen_embmedany_texthi (temp2, op1));
emit_insn (gen_embmedany_textulo (op0, op0, op1)); emit_insn (gen_embmedany_textulo (temp3, temp1, op1));
emit_insn (gen_rtx_SET (VOIDmode, op0, emit_insn (gen_rtx_SET (VOIDmode, temp4,
gen_rtx_ASHIFT (DImode, op0, GEN_INT (32)))); gen_rtx_ASHIFT (DImode, temp3, GEN_INT (32))));
emit_insn (gen_rtx_SET (VOIDmode, op0, emit_insn (gen_rtx_SET (VOIDmode, temp5,
gen_rtx_PLUS (DImode, op0, temp1))); gen_rtx_PLUS (DImode, temp4, temp2)));
emit_insn (gen_embmedany_textlo (op0, op0, op1)); emit_insn (gen_embmedany_textlo (op0, temp5, op1));
} }
break; break;
...@@ -1947,7 +2014,7 @@ sparc_emit_set_const64 (rtx op0, rtx op1) ...@@ -1947,7 +2014,7 @@ sparc_emit_set_const64 (rtx op0, rtx op1)
unsigned HOST_WIDE_INT high_bits, low_bits; unsigned HOST_WIDE_INT high_bits, low_bits;
int lowest_bit_set, highest_bit_set; int lowest_bit_set, highest_bit_set;
int all_bits_between_are_set; int all_bits_between_are_set;
rtx temp; rtx temp = 0;
/* Sanity check that we know what we are working with. */ /* Sanity check that we know what we are working with. */
if (! TARGET_ARCH64) if (! TARGET_ARCH64)
...@@ -1963,8 +2030,6 @@ sparc_emit_set_const64 (rtx op0, rtx op1) ...@@ -1963,8 +2030,6 @@ sparc_emit_set_const64 (rtx op0, rtx op1)
if (reload_in_progress || reload_completed) if (reload_in_progress || reload_completed)
temp = op0; temp = op0;
else
temp = gen_reg_rtx (DImode);
if (GET_CODE (op1) != CONST_DOUBLE if (GET_CODE (op1) != CONST_DOUBLE
&& GET_CODE (op1) != CONST_INT) && GET_CODE (op1) != CONST_INT)
...@@ -1973,6 +2038,9 @@ sparc_emit_set_const64 (rtx op0, rtx op1) ...@@ -1973,6 +2038,9 @@ sparc_emit_set_const64 (rtx op0, rtx op1)
return; return;
} }
if (! temp)
temp = gen_reg_rtx (DImode);
if (GET_CODE (op1) == CONST_DOUBLE) if (GET_CODE (op1) == CONST_DOUBLE)
{ {
#if HOST_BITS_PER_WIDE_INT == 64 #if HOST_BITS_PER_WIDE_INT == 64
......
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> 2004-07-08 Giovanni Bajo <giovannibajo@gcc.gnu.org>
PR c++/16169 PR c++/16169
......
/* 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";
}
}
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