summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/expmed.c111
-rw-r--r--gcc/expmed.h114
3 files changed, 129 insertions, 107 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 28e2273a2d6..7aca51933b6 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,16 @@
2010-07-12 Richard Sandiford <rdsandiford@googlemail.com>
+ * expmed.h (alg_code, mult_cost, MULT_COST_LESS, CHEAPER_MULT_COST)
+ (algorithm, alg_hash_entry, NUM_ALG_HASH_ENTRIES, alg_hash): Moved
+ from expmed.c.
+ (target_expmed): Add x_alg_hash and x_alg_hash_used_p.
+ (alg_hash, alg_hash_used_p): New macros.
+ * expmed.c (init_expmed): Clear alg_hash if reinitializing.
+ (alg_code, mult_cost, MULT_COST_LESS, CHEAPER_MULT_COST, algorithm)
+ (alg_hash_entry, NUM_ALG_HASH_ENTRIES, alg_hash): Moved to expmed.h.
+
+2010-07-12 Richard Sandiford <rdsandiford@googlemail.com>
+
* ira-int.h (target_ira_int): Add x_max_struct_costs_size, x_init_cost,
x_temp_costs, x_op_costs, x_this_op_costs and x_cost_classes.
* ira-costs.c (max_struct_costs_size, init_cost, temp_costs, op_costs)
diff --git a/gcc/expmed.c b/gcc/expmed.c
index c10d52ec8c4..186cf01777a 100644
--- a/gcc/expmed.c
+++ b/gcc/expmed.c
@@ -260,6 +260,10 @@ init_expmed (void)
}
}
}
+ if (alg_hash_used_p)
+ memset (alg_hash, 0, sizeof (alg_hash));
+ else
+ alg_hash_used_p = true;
default_rtl_profile ();
}
@@ -2283,113 +2287,6 @@ expand_shift (enum tree_code code, enum machine_mode mode, rtx shifted,
return temp;
}
-enum alg_code {
- alg_unknown,
- alg_zero,
- alg_m, alg_shift,
- alg_add_t_m2,
- alg_sub_t_m2,
- alg_add_factor,
- alg_sub_factor,
- alg_add_t2_m,
- alg_sub_t2_m,
- alg_impossible
-};
-
-/* This structure holds the "cost" of a multiply sequence. The
- "cost" field holds the total rtx_cost of every operator in the
- synthetic multiplication sequence, hence cost(a op b) is defined
- as rtx_cost(op) + cost(a) + cost(b), where cost(leaf) is zero.
- The "latency" field holds the minimum possible latency of the
- synthetic multiply, on a hypothetical infinitely parallel CPU.
- This is the critical path, or the maximum height, of the expression
- tree which is the sum of rtx_costs on the most expensive path from
- any leaf to the root. Hence latency(a op b) is defined as zero for
- leaves and rtx_cost(op) + max(latency(a), latency(b)) otherwise. */
-
-struct mult_cost {
- short cost; /* Total rtx_cost of the multiplication sequence. */
- short latency; /* The latency of the multiplication sequence. */
-};
-
-/* This macro is used to compare a pointer to a mult_cost against an
- single integer "rtx_cost" value. This is equivalent to the macro
- CHEAPER_MULT_COST(X,Z) where Z = {Y,Y}. */
-#define MULT_COST_LESS(X,Y) ((X)->cost < (Y) \
- || ((X)->cost == (Y) && (X)->latency < (Y)))
-
-/* This macro is used to compare two pointers to mult_costs against
- each other. The macro returns true if X is cheaper than Y.
- Currently, the cheaper of two mult_costs is the one with the
- lower "cost". If "cost"s are tied, the lower latency is cheaper. */
-#define CHEAPER_MULT_COST(X,Y) ((X)->cost < (Y)->cost \
- || ((X)->cost == (Y)->cost \
- && (X)->latency < (Y)->latency))
-
-/* This structure records a sequence of operations.
- `ops' is the number of operations recorded.
- `cost' is their total cost.
- The operations are stored in `op' and the corresponding
- logarithms of the integer coefficients in `log'.
-
- These are the operations:
- alg_zero total := 0;
- alg_m total := multiplicand;
- alg_shift total := total * coeff
- alg_add_t_m2 total := total + multiplicand * coeff;
- alg_sub_t_m2 total := total - multiplicand * coeff;
- alg_add_factor total := total * coeff + total;
- alg_sub_factor total := total * coeff - total;
- alg_add_t2_m total := total * coeff + multiplicand;
- alg_sub_t2_m total := total * coeff - multiplicand;
-
- The first operand must be either alg_zero or alg_m. */
-
-struct algorithm
-{
- struct mult_cost cost;
- short ops;
- /* The size of the OP and LOG fields are not directly related to the
- word size, but the worst-case algorithms will be if we have few
- consecutive ones or zeros, i.e., a multiplicand like 10101010101...
- In that case we will generate shift-by-2, add, shift-by-2, add,...,
- in total wordsize operations. */
- enum alg_code op[MAX_BITS_PER_WORD];
- char log[MAX_BITS_PER_WORD];
-};
-
-/* The entry for our multiplication cache/hash table. */
-struct alg_hash_entry {
- /* The number we are multiplying by. */
- unsigned HOST_WIDE_INT t;
-
- /* The mode in which we are multiplying something by T. */
- enum machine_mode mode;
-
- /* The best multiplication algorithm for t. */
- enum alg_code alg;
-
- /* The cost of multiplication if ALG_CODE is not alg_impossible.
- Otherwise, the cost within which multiplication by T is
- impossible. */
- struct mult_cost cost;
-
- /* OPtimized for speed? */
- bool speed;
-};
-
-/* The number of cache/hash entries. */
-#if HOST_BITS_PER_WIDE_INT == 64
-#define NUM_ALG_HASH_ENTRIES 1031
-#else
-#define NUM_ALG_HASH_ENTRIES 307
-#endif
-
-/* Each entry of ALG_HASH caches alg_code for some integer. This is
- actually a hash table. If we have a collision, that the older
- entry is kicked out. */
-static struct alg_hash_entry alg_hash[NUM_ALG_HASH_ENTRIES];
-
/* Indicates the type of fixup needed after a constant multiplication.
BASIC_VARIANT means no fixup is needed, NEGATE_VARIANT means that
the result should be negated, and ADD_VARIANT means that the
diff --git a/gcc/expmed.h b/gcc/expmed.h
index fcf16dca306..37f57557120 100644
--- a/gcc/expmed.h
+++ b/gcc/expmed.h
@@ -22,8 +22,118 @@ along with GCC; see the file COPYING3. If not see
#ifndef EXPMED_H
#define EXPMED_H 1
+enum alg_code {
+ alg_unknown,
+ alg_zero,
+ alg_m, alg_shift,
+ alg_add_t_m2,
+ alg_sub_t_m2,
+ alg_add_factor,
+ alg_sub_factor,
+ alg_add_t2_m,
+ alg_sub_t2_m,
+ alg_impossible
+};
+
+/* This structure holds the "cost" of a multiply sequence. The
+ "cost" field holds the total rtx_cost of every operator in the
+ synthetic multiplication sequence, hence cost(a op b) is defined
+ as rtx_cost(op) + cost(a) + cost(b), where cost(leaf) is zero.
+ The "latency" field holds the minimum possible latency of the
+ synthetic multiply, on a hypothetical infinitely parallel CPU.
+ This is the critical path, or the maximum height, of the expression
+ tree which is the sum of rtx_costs on the most expensive path from
+ any leaf to the root. Hence latency(a op b) is defined as zero for
+ leaves and rtx_cost(op) + max(latency(a), latency(b)) otherwise. */
+
+struct mult_cost {
+ short cost; /* Total rtx_cost of the multiplication sequence. */
+ short latency; /* The latency of the multiplication sequence. */
+};
+
+/* This macro is used to compare a pointer to a mult_cost against an
+ single integer "rtx_cost" value. This is equivalent to the macro
+ CHEAPER_MULT_COST(X,Z) where Z = {Y,Y}. */
+#define MULT_COST_LESS(X,Y) ((X)->cost < (Y) \
+ || ((X)->cost == (Y) && (X)->latency < (Y)))
+
+/* This macro is used to compare two pointers to mult_costs against
+ each other. The macro returns true if X is cheaper than Y.
+ Currently, the cheaper of two mult_costs is the one with the
+ lower "cost". If "cost"s are tied, the lower latency is cheaper. */
+#define CHEAPER_MULT_COST(X,Y) ((X)->cost < (Y)->cost \
+ || ((X)->cost == (Y)->cost \
+ && (X)->latency < (Y)->latency))
+
+/* This structure records a sequence of operations.
+ `ops' is the number of operations recorded.
+ `cost' is their total cost.
+ The operations are stored in `op' and the corresponding
+ logarithms of the integer coefficients in `log'.
+
+ These are the operations:
+ alg_zero total := 0;
+ alg_m total := multiplicand;
+ alg_shift total := total * coeff
+ alg_add_t_m2 total := total + multiplicand * coeff;
+ alg_sub_t_m2 total := total - multiplicand * coeff;
+ alg_add_factor total := total * coeff + total;
+ alg_sub_factor total := total * coeff - total;
+ alg_add_t2_m total := total * coeff + multiplicand;
+ alg_sub_t2_m total := total * coeff - multiplicand;
+
+ The first operand must be either alg_zero or alg_m. */
+
+struct algorithm
+{
+ struct mult_cost cost;
+ short ops;
+ /* The size of the OP and LOG fields are not directly related to the
+ word size, but the worst-case algorithms will be if we have few
+ consecutive ones or zeros, i.e., a multiplicand like 10101010101...
+ In that case we will generate shift-by-2, add, shift-by-2, add,...,
+ in total wordsize operations. */
+ enum alg_code op[MAX_BITS_PER_WORD];
+ char log[MAX_BITS_PER_WORD];
+};
+
+/* The entry for our multiplication cache/hash table. */
+struct alg_hash_entry {
+ /* The number we are multiplying by. */
+ unsigned HOST_WIDE_INT t;
+
+ /* The mode in which we are multiplying something by T. */
+ enum machine_mode mode;
+
+ /* The best multiplication algorithm for t. */
+ enum alg_code alg;
+
+ /* The cost of multiplication if ALG_CODE is not alg_impossible.
+ Otherwise, the cost within which multiplication by T is
+ impossible. */
+ struct mult_cost cost;
+
+ /* Optimized for speed? */
+ bool speed;
+};
+
+/* The number of cache/hash entries. */
+#if HOST_BITS_PER_WIDE_INT == 64
+#define NUM_ALG_HASH_ENTRIES 1031
+#else
+#define NUM_ALG_HASH_ENTRIES 307
+#endif
+
/* Target-dependent globals. */
struct target_expmed {
+ /* Each entry of ALG_HASH caches alg_code for some integer. This is
+ actually a hash table. If we have a collision, that the older
+ entry is kicked out. */
+ struct alg_hash_entry x_alg_hash[NUM_ALG_HASH_ENTRIES];
+
+ /* True if x_alg_hash might already have been used. */
+ bool x_alg_hash_used_p;
+
/* Nonzero means divides or modulus operations are relatively cheap for
powers of two, so don't use branches; emit the operation instead.
Usually, this will mean that the MD file will emit non-branch
@@ -54,6 +164,10 @@ extern struct target_expmed *this_target_expmed;
#define this_target_expmed (&default_target_expmed)
#endif
+#define alg_hash \
+ (this_target_expmed->x_alg_hash)
+#define alg_hash_used_p \
+ (this_target_expmed->x_alg_hash_used_p)
#define sdiv_pow2_cheap \
(this_target_expmed->x_sdiv_pow2_cheap)
#define smod_pow2_cheap \