expmed.c (alg_code): Add alg_impossible.
* expmed.c (alg_code): Add alg_impossible. (alg_hash_entry): Add cost. (synth_mult): Record alg_impossible in the hash table if multiplication by a given integer is impossble within the limit. Speed up using alg_impossible. From-SVN: r104492
This commit is contained in:
parent
1bf83ca3dd
commit
0178027cd5
@ -1,3 +1,11 @@
|
|||||||
|
2005-09-21 Kazu Hirata <kazu@codesourcery.com>
|
||||||
|
|
||||||
|
* expmed.c (alg_code): Add alg_impossible.
|
||||||
|
(alg_hash_entry): Add cost.
|
||||||
|
(synth_mult): Record alg_impossible in the hash table if
|
||||||
|
multiplication by a given integer is impossble within the
|
||||||
|
limit. Speed up using alg_impossible.
|
||||||
|
|
||||||
2005-09-20 Daniel Berlin <dberlin@dberlin.org>
|
2005-09-20 Daniel Berlin <dberlin@dberlin.org>
|
||||||
|
|
||||||
* tree-ssa-structalias.c (get_constraint_for_component_ref): Add
|
* tree-ssa-structalias.c (get_constraint_for_component_ref): Add
|
||||||
|
96
gcc/expmed.c
96
gcc/expmed.c
@ -2286,10 +2286,18 @@ expand_shift (enum tree_code code, enum machine_mode mode, rtx shifted,
|
|||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
enum alg_code { alg_unknown, alg_zero, alg_m, alg_shift,
|
enum alg_code {
|
||||||
alg_add_t_m2, alg_sub_t_m2,
|
alg_unknown,
|
||||||
alg_add_factor, alg_sub_factor,
|
alg_zero,
|
||||||
alg_add_t2_m, alg_sub_t2_m };
|
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
|
/* This structure holds the "cost" of a multiply sequence. The
|
||||||
"cost" field holds the total rtx_cost of every operator in the
|
"cost" field holds the total rtx_cost of every operator in the
|
||||||
@ -2363,6 +2371,11 @@ struct alg_hash_entry {
|
|||||||
|
|
||||||
/* The best multiplication algorithm for t. */
|
/* The best multiplication algorithm for t. */
|
||||||
enum alg_code alg;
|
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;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* The number of cache/hash entries. */
|
/* The number of cache/hash entries. */
|
||||||
@ -2465,29 +2478,57 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
|
|||||||
&& alg_hash[hash_index].mode == mode
|
&& alg_hash[hash_index].mode == mode
|
||||||
&& alg_hash[hash_index].alg != alg_unknown)
|
&& alg_hash[hash_index].alg != alg_unknown)
|
||||||
{
|
{
|
||||||
cache_hit = true;
|
|
||||||
cache_alg = alg_hash[hash_index].alg;
|
cache_alg = alg_hash[hash_index].alg;
|
||||||
switch (cache_alg)
|
|
||||||
|
if (cache_alg == alg_impossible)
|
||||||
{
|
{
|
||||||
case alg_shift:
|
/* The cache tells us that it's impossible to synthesize
|
||||||
goto do_alg_shift;
|
multiplication by T within alg_hash[hash_index].cost. */
|
||||||
|
if (!CHEAPER_MULT_COST (&alg_hash[hash_index].cost, cost_limit))
|
||||||
|
/* COST_LIMIT is at least as restrictive as the one
|
||||||
|
recorded in the hash table, in which case we have no
|
||||||
|
hope of synthesizing a multiplication. Just
|
||||||
|
return. */
|
||||||
|
return;
|
||||||
|
|
||||||
case alg_add_t_m2:
|
/* If we get here, COST_LIMIT is less restrictive than the
|
||||||
case alg_sub_t_m2:
|
one recorded in the hash table, so we may be able to
|
||||||
goto do_alg_addsub_t_m2;
|
synthesize a multiplication. Proceed as if we didn't
|
||||||
|
have the cache entry. */
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (CHEAPER_MULT_COST (cost_limit, &alg_hash[hash_index].cost))
|
||||||
|
/* The cached algorithm shows that this multiplication
|
||||||
|
requires more cost than COST_LIMIT. Just return. This
|
||||||
|
way, we don't clobber this cache entry with
|
||||||
|
alg_impossible but retain useful information. */
|
||||||
|
return;
|
||||||
|
|
||||||
case alg_add_factor:
|
cache_hit = true;
|
||||||
case alg_sub_factor:
|
|
||||||
goto do_alg_addsub_factor;
|
|
||||||
|
|
||||||
case alg_add_t2_m:
|
switch (cache_alg)
|
||||||
goto do_alg_add_t2_m;
|
{
|
||||||
|
case alg_shift:
|
||||||
|
goto do_alg_shift;
|
||||||
|
|
||||||
case alg_sub_t2_m:
|
case alg_add_t_m2:
|
||||||
goto do_alg_sub_t2_m;
|
case alg_sub_t_m2:
|
||||||
|
goto do_alg_addsub_t_m2;
|
||||||
|
|
||||||
default:
|
case alg_add_factor:
|
||||||
gcc_unreachable ();
|
case alg_sub_factor:
|
||||||
|
goto do_alg_addsub_factor;
|
||||||
|
|
||||||
|
case alg_add_t2_m:
|
||||||
|
goto do_alg_add_t2_m;
|
||||||
|
|
||||||
|
case alg_sub_t2_m:
|
||||||
|
goto do_alg_sub_t2_m;
|
||||||
|
|
||||||
|
default:
|
||||||
|
gcc_unreachable ();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2740,7 +2781,18 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
|
|||||||
done:
|
done:
|
||||||
/* If best_cost has not decreased, we have not found any algorithm. */
|
/* If best_cost has not decreased, we have not found any algorithm. */
|
||||||
if (!CHEAPER_MULT_COST (&best_cost, cost_limit))
|
if (!CHEAPER_MULT_COST (&best_cost, cost_limit))
|
||||||
return;
|
{
|
||||||
|
/* We failed to find an algorithm. Record alg_impossible for
|
||||||
|
this case (that is, <T, MODE, COST_LIMIT>) so that next time
|
||||||
|
we are asked to find an algorithm for T within the same or
|
||||||
|
lower COST_LIMIT, we can immediately return to the
|
||||||
|
caller. */
|
||||||
|
alg_hash[hash_index].t = t;
|
||||||
|
alg_hash[hash_index].mode = mode;
|
||||||
|
alg_hash[hash_index].alg = alg_impossible;
|
||||||
|
alg_hash[hash_index].cost = *cost_limit;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/* Cache the result. */
|
/* Cache the result. */
|
||||||
if (!cache_hit)
|
if (!cache_hit)
|
||||||
@ -2748,6 +2800,8 @@ synth_mult (struct algorithm *alg_out, unsigned HOST_WIDE_INT t,
|
|||||||
alg_hash[hash_index].t = t;
|
alg_hash[hash_index].t = t;
|
||||||
alg_hash[hash_index].mode = mode;
|
alg_hash[hash_index].mode = mode;
|
||||||
alg_hash[hash_index].alg = best_alg->op[best_alg->ops];
|
alg_hash[hash_index].alg = best_alg->op[best_alg->ops];
|
||||||
|
alg_hash[hash_index].cost.cost = best_cost.cost;
|
||||||
|
alg_hash[hash_index].cost.latency = best_cost.latency;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we are getting a too long sequence for `struct algorithm'
|
/* If we are getting a too long sequence for `struct algorithm'
|
||||||
|
Loading…
Reference in New Issue
Block a user