Commit 57632c51 by Richard Stallman

(simplify_subtraction): New function.

From-SVN: r2404
parent 1f1fd3b1
...@@ -32,6 +32,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ ...@@ -32,6 +32,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
#include "rtl.h" #include "rtl.h"
#include "tree.h" #include "tree.h"
#include "flags.h" #include "flags.h"
#include "function.h"
#include "expr.h" #include "expr.h"
#include "hard-reg-set.h" #include "hard-reg-set.h"
#include "regs.h" #include "regs.h"
...@@ -1228,7 +1229,10 @@ assemble_real (d, mode) ...@@ -1228,7 +1229,10 @@ assemble_real (d, mode)
They are chained through the CONST_DOUBLE_CHAIN. They are chained through the CONST_DOUBLE_CHAIN.
A CONST_DOUBLE rtx has CONST_DOUBLE_MEM != cc0_rtx iff it is on this chain. A CONST_DOUBLE rtx has CONST_DOUBLE_MEM != cc0_rtx iff it is on this chain.
In that case, CONST_DOUBLE_MEM is either a MEM, In that case, CONST_DOUBLE_MEM is either a MEM,
or const0_rtx if no MEM has been made for this CONST_DOUBLE yet. */ or const0_rtx if no MEM has been made for this CONST_DOUBLE yet.
(CONST_DOUBLE_MEM is used only for top-level functions.
See force_const_mem for explanation.) */
static rtx const_double_chain; static rtx const_double_chain;
...@@ -1409,6 +1413,11 @@ clear_const_double_mem () ...@@ -1409,6 +1413,11 @@ clear_const_double_mem ()
{ {
register rtx r, next; register rtx r, next;
/* Don't touch CONST_DOUBLE_MEM for nested functions.
See force_const_mem for explanation. */
if (outer_function_chain != 0)
return;
for (r = const_double_chain; r; r = next) for (r = const_double_chain; r; r = next)
{ {
next = CONST_DOUBLE_CHAIN (r); next = CONST_DOUBLE_CHAIN (r);
...@@ -2007,7 +2016,7 @@ output_constant_def (exp) ...@@ -2007,7 +2016,7 @@ output_constant_def (exp)
inlining, so they do not need to be allocated permanently. */ inlining, so they do not need to be allocated permanently. */
#define MAX_RTX_HASH_TABLE 61 #define MAX_RTX_HASH_TABLE 61
static struct constant_descriptor *const_rtx_hash_table[MAX_RTX_HASH_TABLE]; static struct constant_descriptor **const_rtx_hash_table;
/* Structure to represent sufficient information about a constant so that /* Structure to represent sufficient information about a constant so that
it can be output when the constant pool is output, so that function it can be output when the constant pool is output, so that function
...@@ -2044,7 +2053,7 @@ struct pool_sym ...@@ -2044,7 +2053,7 @@ struct pool_sym
struct pool_sym *next; struct pool_sym *next;
}; };
static struct pool_sym *const_rtx_sym_hash_table[MAX_RTX_HASH_TABLE]; static struct pool_sym **const_rtx_sym_hash_table;
/* Hash code for a SYMBOL_REF with CONSTANT_POOL_ADDRESS_P true. /* Hash code for a SYMBOL_REF with CONSTANT_POOL_ADDRESS_P true.
The argument is XSTR (... , 0) */ The argument is XSTR (... , 0) */
...@@ -2057,13 +2066,45 @@ static struct pool_sym *const_rtx_sym_hash_table[MAX_RTX_HASH_TABLE]; ...@@ -2057,13 +2066,45 @@ static struct pool_sym *const_rtx_sym_hash_table[MAX_RTX_HASH_TABLE];
void void
init_const_rtx_hash_table () init_const_rtx_hash_table ()
{ {
bzero (const_rtx_hash_table, sizeof const_rtx_hash_table); const_rtx_hash_table
bzero (const_rtx_sym_hash_table, sizeof const_rtx_sym_hash_table); = ((struct constant_descriptor **)
oballoc (MAX_RTX_HASH_TABLE * sizeof (struct constant_descriptor *)));
const_rtx_sym_hash_table
= ((struct pool_sym **)
oballoc (MAX_RTX_HASH_TABLE * sizeof (struct pool_sym *)));
bzero (const_rtx_hash_table,
MAX_RTX_HASH_TABLE * sizeof (struct constant_descriptor *));
bzero (const_rtx_sym_hash_table,
MAX_RTX_HASH_TABLE * sizeof (struct pool_sym *));
first_pool = last_pool = 0; first_pool = last_pool = 0;
pool_offset = 0; pool_offset = 0;
} }
/* Save and restore it for a nested function. */
void
save_varasm_status (p)
struct function *p;
{
p->const_rtx_hash_table = const_rtx_hash_table;
p->const_rtx_sym_hash_table = const_rtx_sym_hash_table;
p->first_pool = first_pool;
p->last_pool = last_pool;
p->pool_offset = pool_offset;
}
void
restore_varasm_status (p)
struct function *p;
{
const_rtx_hash_table = p->const_rtx_hash_table;
const_rtx_sym_hash_table = p->const_rtx_sym_hash_table;
first_pool = p->first_pool;
last_pool = p->last_pool;
pool_offset = p->pool_offset;
}
enum kind { RTX_DOUBLE, RTX_INT }; enum kind { RTX_DOUBLE, RTX_INT };
struct rtx_const struct rtx_const
...@@ -2156,6 +2197,23 @@ decode_rtx_const (mode, x, value) ...@@ -2156,6 +2197,23 @@ decode_rtx_const (mode, x, value)
} }
} }
/* Given a MINUS expression, simplify it if both sides
include the same symbol. */
rtx
simplify_subtraction (x)
rtx x;
{
struct rtx_const val0, val1;
decode_rtx_const (GET_MODE (x), XEXP (x, 0), &val0);
decode_rtx_const (GET_MODE (x), XEXP (x, 1), &val1);
if (val0.un.addr.base == val1.un.addr.base)
return GEN_INT (val0.un.addr.offset - val1.un.addr.offset);
return x;
}
/* Compute a hash code for a constant RTL expression. */ /* Compute a hash code for a constant RTL expression. */
int int
...@@ -2249,6 +2307,11 @@ force_const_mem (mode, x) ...@@ -2249,6 +2307,11 @@ force_const_mem (mode, x)
modes in an alternating fashion, we will allocate a lot of different modes in an alternating fashion, we will allocate a lot of different
memory locations, but this should be extremely rare. */ memory locations, but this should be extremely rare. */
/* Don't use CONST_DOUBLE_MEM in a nested function.
Nested functions have their own constant pools,
so they can't share the same values in CONST_DOUBLE_MEM
with the containing function. */
if (outer_function_chain == 0)
if (GET_CODE (x) == CONST_DOUBLE if (GET_CODE (x) == CONST_DOUBLE
&& GET_CODE (CONST_DOUBLE_MEM (x)) == MEM && GET_CODE (CONST_DOUBLE_MEM (x)) == MEM
&& GET_MODE (CONST_DOUBLE_MEM (x)) == mode) && GET_MODE (CONST_DOUBLE_MEM (x)) == mode)
...@@ -2335,6 +2398,7 @@ force_const_mem (mode, x) ...@@ -2335,6 +2398,7 @@ force_const_mem (mode, x)
CONSTANT_POOL_ADDRESS_P (XEXP (def, 0)) = 1; CONSTANT_POOL_ADDRESS_P (XEXP (def, 0)) = 1;
current_function_uses_const_pool = 1; current_function_uses_const_pool = 1;
if (outer_function_chain == 0)
if (GET_CODE (x) == CONST_DOUBLE) if (GET_CODE (x) == CONST_DOUBLE)
{ {
if (CONST_DOUBLE_MEM (x) == cc0_rtx) if (CONST_DOUBLE_MEM (x) == cc0_rtx)
......
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