From 5352b11a957b76eb6292bf20b9f4d4ab6a8e2e4e Mon Sep 17 00:00:00 2001 From: Richard Stallman Date: Mon, 22 Jun 1992 03:40:10 +0000 Subject: [PATCH] *** empty log message *** From-SVN: r1232 --- gcc/cse.c | 8 ++-- gcc/fold-const.c | 33 ++++++++++++++++- gcc/real.h | 3 ++ gcc/reload1.c | 95 +++++++++++++++++++++++++++++++++++++++++------- 4 files changed, 119 insertions(+), 20 deletions(-) diff --git a/gcc/cse.c b/gcc/cse.c index e945768f1fd..aaff8924399 100644 --- a/gcc/cse.c +++ b/gcc/cse.c @@ -2921,7 +2921,7 @@ simplify_unary_operation (code, mode, op, op_mode) break; case FLOAT_TRUNCATE: - d = (double) REAL_VALUE_TRUNCATE (mode, d); + d = (double) real_value_truncate (mode, d); break; case FLOAT_EXTEND: @@ -3061,8 +3061,8 @@ simplify_binary_operation (code, mode, op0, op1) REAL_VALUE_FROM_CONST_DOUBLE (f0, op0); REAL_VALUE_FROM_CONST_DOUBLE (f1, op1); - f0 = REAL_VALUE_TRUNCATE (mode, f0); - f1 = REAL_VALUE_TRUNCATE (mode, f1); + f0 = real_value_truncate (mode, f0); + f1 = real_value_truncate (mode, f1); #ifdef REAL_ARITHMETIC REAL_ARITHMETIC (value, code, f0, f1); @@ -3097,7 +3097,7 @@ simplify_binary_operation (code, mode, op0, op1) #endif set_float_handler (0); - value = REAL_VALUE_TRUNCATE (mode, value); + value = real_value_truncate (mode, value); return immed_real_const_1 (value, mode); } diff --git a/gcc/fold-const.c b/gcc/fold-const.c index 0bc6db3e55e..a8a3f370727 100644 --- a/gcc/fold-const.c +++ b/gcc/fold-const.c @@ -699,6 +699,35 @@ div_and_round_double (code, uns, add_double (lnum_orig, hnum_orig, *lrem, *hrem, lrem, hrem); } +/* Effectively truncate a real value to represent + the nearest possible value in a narrower mode. + The result is actually represented in the same data type as the argument, + but its value is usually different. */ + +REAL_VALUE_TYPE +real_value_truncate (mode, arg) + enum machine_mode mode; + REAL_VALUE_TYPE arg; +{ +#ifdef __STDC__ + /* Make sure the value is actually stored in memory before we turn off + the handler. */ + volatile +#endif + REAL_VALUE_TYPE value; + jmp_buf handler; + + if (setjmp (handler)) + { + error ("floating overflow"); + return dconst0; + } + set_float_handler (handler); + value = REAL_VALUE_TRUNCATE (mode, arg); + set_float_handler (0); + return value; +} + #if TARGET_FLOAT_FORMAT == IEEE_FLOAT_FORMAT /* Check for infinity in an IEEE double precision number. */ @@ -1215,7 +1244,7 @@ const_binop (code, arg1, arg2) } #endif /* no REAL_ARITHMETIC */ t = build_real (TREE_TYPE (arg1), - REAL_VALUE_TRUNCATE (TYPE_MODE (TREE_TYPE (arg1)), value)); + real_value_truncate (TYPE_MODE (TREE_TYPE (arg1)), value)); set_float_handler (0); return t; } @@ -1423,7 +1452,7 @@ fold_convert (t, arg1) } set_float_handler (float_error); - t = build_real (type, REAL_VALUE_TRUNCATE (TYPE_MODE (type), + t = build_real (type, real_value_truncate (TYPE_MODE (type), TREE_REAL_CST (arg1))); set_float_handler (0); return t; diff --git a/gcc/real.h b/gcc/real.h index 571eb5d453c..e191944cb2d 100644 --- a/gcc/real.h +++ b/gcc/real.h @@ -154,6 +154,9 @@ extern double (atof) (); for the most common case where the host and target have objects of the same size and where `float' is SFmode. */ +/* Don't use REAL_VALUE_TRUNCATE directly--always call real_value_truncate. */ +extern REAL_VALUE_TYPE real_value_truncate (); + #ifndef REAL_VALUE_TRUNCATE #define REAL_VALUE_TRUNCATE(mode, x) \ (GET_MODE_BITSIZE (mode) == sizeof (float) * HOST_BITS_PER_CHAR \ diff --git a/gcc/reload1.c b/gcc/reload1.c index 526e7db1328..4cf074c1963 100644 --- a/gcc/reload1.c +++ b/gcc/reload1.c @@ -319,6 +319,7 @@ static void reload_as_needed (); static int modes_equiv_for_class_p (); static void alter_reg (); static void delete_dead_insn (); +static void spill_failure (); static int new_spill_reg(); static void set_label_offsets (); static int eliminate_regs_in_insn (); @@ -477,9 +478,12 @@ init_reload () DUMPFILE is the global-reg debugging dump file stream, or 0. If it is nonzero, messages are written to it to describe which registers are seized as reload regs, which pseudo regs - are spilled from them, and where the pseudo regs are reallocated to. */ + are spilled from them, and where the pseudo regs are reallocated to. -void + Return value is nonzero if reload failed + and we must not do any more for this function. */ + +int reload (first, global, dumpfile) rtx first; int global; @@ -497,6 +501,9 @@ reload (first, global, dumpfile) enum reg_class caller_save_spill_class = NO_REGS; int caller_save_group_size = 1; + /* Nonzero means we couldn't get enough spill regs. */ + int failure = 0; + /* The basic block number currently being processed for INSN. */ int this_block; @@ -777,12 +784,19 @@ reload (first, global, dumpfile) they must be the same size and equally restrictive for that class, otherwise we can't handle the complexity. */ enum machine_mode group_mode[N_REG_CLASSES]; + /* Record the insn where each maximum need is first found. */ + rtx max_needs_insn[N_REG_CLASSES]; + rtx max_groups_insn[N_REG_CLASSES]; + rtx max_nongroups_insn[N_REG_CLASSES]; rtx x; something_changed = 0; bzero (max_needs, sizeof max_needs); bzero (max_groups, sizeof max_groups); bzero (max_nongroups, sizeof max_nongroups); + bzero (max_needs_insn, sizeof max_needs_insn); + bzero (max_groups_insn, sizeof max_groups_insn); + bzero (max_nongroups_insn, sizeof max_nongroups_insn); bzero (group_size, sizeof group_size); for (i = 0; i < N_REG_CLASSES; i++) group_mode[i] = VOIDmode; @@ -1271,12 +1285,21 @@ reload (first, global, dumpfile) for (i = 0; i < N_REG_CLASSES; i++) { if (max_needs[i] < insn_needs[i]) - max_needs[i] = insn_needs[i]; + { + max_needs[i] = insn_needs[i]; + max_needs_insn[i] = insn; + } if (max_groups[i] < insn_groups[i]) - max_groups[i] = insn_groups[i]; + { + max_groups[i] = insn_groups[i]; + max_groups_insn[i] = insn; + } if (insn_total_groups > 0) if (max_nongroups[i] < insn_needs[i]) - max_nongroups[i] = insn_needs[i]; + { + max_nongroups[i] = insn_needs[i]; + max_nongroups_insn[i] = insn; + } } } /* Note that there is a continue statement above. */ @@ -1567,9 +1590,17 @@ reload (first, global, dumpfile) /* I should be the index in potential_reload_regs of the new reload reg we have found. */ - something_changed - |= new_spill_reg (i, class, max_needs, 0, - global, dumpfile); + if (i >= FIRST_PSEUDO_REGISTER) + { + /* There are no groups left to spill. */ + spill_failure (max_groups_insn[class]); + failure = 1; + goto failed; + } + else + something_changed + |= new_spill_reg (i, class, max_needs, 0, + global, dumpfile); } else { @@ -1600,9 +1631,17 @@ reload (first, global, dumpfile) for (idx = 0; idx < FIRST_PSEUDO_REGISTER; idx++) if (potential_reload_regs[idx] == j + k) break; - something_changed - |= new_spill_reg (idx, class, max_needs, 0, - global, dumpfile); + if (i >= FIRST_PSEUDO_REGISTER) + { + /* There are no groups left. */ + spill_failure (max_groups_insn[class]); + failure = 1; + goto failed; + } + else + something_changed + |= new_spill_reg (idx, class, max_needs, 0, + global, dumpfile); } /* We have found one that will complete a group, @@ -1648,9 +1687,18 @@ reload (first, global, dumpfile) /* I should be the index in potential_reload_regs of the new reload reg we have found. */ - something_changed - |= new_spill_reg (i, class, max_needs, max_nongroups, - global, dumpfile); + if (i >= FIRST_PSEUDO_REGISTER) + { + /* There are no possible registers left to spill. */ + spill_failure (max_needs[class] > 0 ? max_needs_insn[class] + : max_nongroups_insn[class]); + failure = 1; + goto failed; + } + else + something_changed + |= new_spill_reg (i, class, max_needs, max_nongroups, + global, dumpfile); } } } @@ -1706,6 +1754,10 @@ reload (first, global, dumpfile) reload_in_progress = 0; + /* Come here (with failure set nonzero) if we can't get enough spill regs + and we decide not to abort about it. */ + failed: + /* Now eliminate all pseudo regs by modifying them into their equivalent memory references. The REG-rtx's for the pseudos are modified in place, @@ -1766,6 +1818,8 @@ reload (first, global, dumpfile) /* Indicate that we no longer have known memory locations or constants. */ reg_equiv_constant = 0; reg_equiv_memory_loc = 0; + + return failure; } /* Nonzero if, after spilling reg REGNO for non-groups, @@ -1917,6 +1971,19 @@ modes_equiv_for_class_p (allocate_mode, other_mode, class) return 1; } +/* Handle the failure to find a register to spill. + INSN should be one of the insns which needed this particular spill reg. */ + +static void +spill_failure (insn) + rtx insn; +{ + if (asm_noperands (PATTERN (insn)) >= 0) + error_for_asm (insn, "`asm' needs too many reloads"); + else + abort (); +} + /* Add a new register to the tables of available spill-registers (as well as spilling all pseudos allocated to the register). I is the index of this register in potential_reload_regs. -- 2.30.2