From 1d511ed5fc76892c3f5dca6b78a1b7254bc15bd1 Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Thu, 8 Jul 2004 14:54:53 +0200 Subject: [PATCH] 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 --- gcc/ChangeLog | 10 + gcc/config/sparc/sparc.c | 194 ++++++++++++------ gcc/testsuite/ChangeLog | 4 + .../gcc.c-torture/compile/20040708-1.c | 68 ++++++ 4 files changed, 213 insertions(+), 63 deletions(-) create mode 100644 gcc/testsuite/gcc.c-torture/compile/20040708-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 74b28b3a8c8..d9cf1950f88 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2004-07-08 Eric Botcazou + + 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 * vec.c (vec_assert_fail): Remove duplicate 'function'. diff --git a/gcc/config/sparc/sparc.c b/gcc/config/sparc/sparc.c index 75ce1471cc9..02a804013a6 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 1a3e2c09e71..8c6514a918f 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2004-07-08 Eric Botcazou + + * gcc.c-torture/compile/20040708-1.c: New test. + 2004-07-08 Giovanni Bajo 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 00000000000..4a553917e44 --- /dev/null +++ b/gcc/testsuite/gcc.c-torture/compile/20040708-1.c @@ -0,0 +1,68 @@ +/* PR rtl-optimization/16199 */ +/* Origin: Olaf Klein */ + +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"; + } +} -- 2.30.2