summaryrefslogtreecommitdiff
path: root/gcc/haifa-sched.c
diff options
context:
space:
mode:
authormkuvyrkov <mkuvyrkov@138bc75d-0d04-0410-961f-82ee72b054a4>2007-05-04 07:21:20 +0000
committermkuvyrkov <mkuvyrkov@138bc75d-0d04-0410-961f-82ee72b054a4>2007-05-04 07:21:20 +0000
commit3588ab9c6295532eee9ead7afa9bfa09293c46fc (patch)
tree26fd4a2f3e219cdad90c93bb12aee00782e48f9e /gcc/haifa-sched.c
parenta2819fc2b976fad809e14cdf2351a247f17684ed (diff)
downloadgcc-3588ab9c6295532eee9ead7afa9bfa09293c46fc.tar.gz
* haifa-sched.c (rtx_vec_t): New typedef.
(contributes_to_priority_p): Extract piece of priority () into new static function. (priority): Use the function. Add assertion. (rank_for_schedule, set_priorities): Add assertion to check that insn's priority is initialized. (clear_priorities, calc_priorities): Change signature. Make it update all relevant insns. Update all callers ('add_to_speculative_block ()' and 'create_block_check_twin ()'). * sched-int.h (struct haifa_insn_data): Remove field 'priority_known'. Add new field 'priority_status'. (INSN_PRIORITY_STATUS): New macro. (INSN_PRIORITY_KNOWN): Change to use INSN_PRIORITY_STATUS. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@124410 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/haifa-sched.c')
-rw-r--r--gcc/haifa-sched.c126
1 files changed, 80 insertions, 46 deletions
diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c
index ed354599969..fdc92ec27c6 100644
--- a/gcc/haifa-sched.c
+++ b/gcc/haifa-sched.c
@@ -487,6 +487,9 @@ haifa_classify_insn (rtx insn)
return insn_class;
}
+/* A typedef for rtx vector. */
+typedef VEC(rtx, heap) *rtx_vec_t;
+
/* Forward declarations. */
static int priority (rtx);
@@ -575,9 +578,9 @@ static void init_glat1 (basic_block);
static void attach_life_info1 (basic_block);
static void free_glat (void);
static void sched_remove_insn (rtx);
-static void clear_priorities (rtx);
+static void clear_priorities (rtx, rtx_vec_t *);
+static void calc_priorities (rtx_vec_t);
static void add_jump_dependencies (rtx, rtx);
-static void calc_priorities (rtx);
#ifdef ENABLE_CHECKING
static int has_edge_p (VEC(edge,gc) *, int);
static void check_cfg (rtx, rtx);
@@ -703,8 +706,30 @@ dep_cost (dep_t link)
return cost;
}
-/* Compute the priority number for INSN. */
+/* Return 'true' if DEP should be included in priority calculations. */
+static bool
+contributes_to_priority_p (dep_t dep)
+{
+ /* Critical path is meaningful in block boundaries only. */
+ if (!current_sched_info->contributes_to_priority (DEP_CON (dep),
+ DEP_PRO (dep)))
+ return false;
+
+ /* If flag COUNT_SPEC_IN_CRITICAL_PATH is set,
+ then speculative instructions will less likely be
+ scheduled. That is because the priority of
+ their producers will increase, and, thus, the
+ producers will more likely be scheduled, thus,
+ resolving the dependence. */
+ if ((current_sched_info->flags & DO_SPECULATION)
+ && !(spec_info->flags & COUNT_SPEC_IN_CRITICAL_PATH)
+ && (DEP_STATUS (dep) & SPECULATIVE))
+ return false;
+ return true;
+}
+
+/* Compute the priority number for INSN. */
static int
priority (rtx insn)
{
@@ -713,7 +738,10 @@ priority (rtx insn)
if (! INSN_P (insn))
return 0;
- if (! INSN_PRIORITY_KNOWN (insn))
+ /* We should not be insterested in priority of an already scheduled insn. */
+ gcc_assert (QUEUE_INDEX (insn) != QUEUE_SCHEDULED);
+
+ if (!INSN_PRIORITY_KNOWN (insn))
{
int this_priority = 0;
@@ -760,20 +788,7 @@ priority (rtx insn)
{
int cost;
- /* Critical path is meaningful in block boundaries
- only. */
- if (! (*current_sched_info->contributes_to_priority)
- (next, insn)
- /* If flag COUNT_SPEC_IN_CRITICAL_PATH is set,
- then speculative instructions will less likely be
- scheduled. That is because the priority of
- their producers will increase, and, thus, the
- producers will more likely be scheduled, thus,
- resolving the dependence. */
- || ((current_sched_info->flags & DO_SPECULATION)
- && (DEP_STATUS (dep) & SPECULATIVE)
- && !(spec_info->flags
- & COUNT_SPEC_IN_CRITICAL_PATH)))
+ if (!contributes_to_priority_p (dep))
continue;
if (twin == insn)
@@ -799,7 +814,7 @@ priority (rtx insn)
while (twin != prev_first);
}
INSN_PRIORITY (insn) = this_priority;
- INSN_PRIORITY_KNOWN (insn) = 1;
+ INSN_PRIORITY_STATUS (insn) = 1;
}
return INSN_PRIORITY (insn);
@@ -832,6 +847,9 @@ rank_for_schedule (const void *x, const void *y)
if (SCHED_GROUP_P (tmp) != SCHED_GROUP_P (tmp2))
return SCHED_GROUP_P (tmp2) ? 1 : -1;
+ /* Make sure that priority of TMP and TMP2 are initialized. */
+ gcc_assert (INSN_PRIORITY_KNOWN (tmp) && INSN_PRIORITY_KNOWN (tmp2));
+
/* Prefer insn with higher priority. */
priority_val = INSN_PRIORITY (tmp2) - INSN_PRIORITY (tmp);
@@ -2541,9 +2559,10 @@ set_priorities (rtx head, rtx tail)
n_insn++;
(void) priority (insn);
- if (INSN_PRIORITY_KNOWN (insn))
- sched_max_insns_priority =
- MAX (sched_max_insns_priority, INSN_PRIORITY (insn));
+ gcc_assert (INSN_PRIORITY_KNOWN (insn));
+
+ sched_max_insns_priority = MAX (sched_max_insns_priority,
+ INSN_PRIORITY (insn));
}
current_sched_info->sched_max_insns_priority = sched_max_insns_priority;
@@ -3224,6 +3243,7 @@ add_to_speculative_block (rtx insn)
ds_t ts;
dep_link_t link;
rtx twins = NULL;
+ rtx_vec_t priorities_roots;
ts = TODO_SPEC (insn);
gcc_assert (!(ts & ~BE_IN_SPEC));
@@ -3255,7 +3275,8 @@ add_to_speculative_block (rtx insn)
link = DEP_LINK_NEXT (link);
}
- clear_priorities (insn);
+ priorities_roots = NULL;
+ clear_priorities (insn, &priorities_roots);
do
{
@@ -3342,13 +3363,15 @@ add_to_speculative_block (rtx insn)
rtx twin;
twin = XEXP (twins, 0);
- calc_priorities (twin);
add_back_forw_dep (twin, insn, REG_DEP_OUTPUT, DEP_OUTPUT);
twin = XEXP (twins, 1);
free_INSN_LIST_node (twins);
twins = twin;
}
+
+ calc_priorities (priorities_roots);
+ VEC_free (rtx, heap, priorities_roots);
}
/* Extends and fills with zeros (only the new part) array pointed to by P. */
@@ -3793,8 +3816,11 @@ create_check_block_twin (rtx insn, bool mutate_p)
/* Fix priorities. If MUTATE_P is nonzero, this is not necessary,
because it'll be done later in add_to_speculative_block. */
{
- clear_priorities (twin);
- calc_priorities (twin);
+ rtx_vec_t priorities_roots = NULL;
+
+ clear_priorities (twin, &priorities_roots);
+ calc_priorities (priorities_roots);
+ VEC_free (rtx, heap, priorities_roots);
}
}
@@ -4281,42 +4307,50 @@ sched_remove_insn (rtx insn)
remove_insn (insn);
}
-/* Clear priorities of all instructions, that are
- forward dependent on INSN. */
+/* Clear priorities of all instructions, that are forward dependent on INSN.
+ Store in vector pointed to by ROOTS_PTR insns on which priority () should
+ be invoked to initialize all cleared priorities. */
static void
-clear_priorities (rtx insn)
+clear_priorities (rtx insn, rtx_vec_t *roots_ptr)
{
dep_link_t link;
+ bool insn_is_root_p = true;
+
+ gcc_assert (QUEUE_INDEX (insn) != QUEUE_SCHEDULED);
FOR_EACH_DEP_LINK (link, INSN_BACK_DEPS (insn))
{
- rtx pro = DEP_LINK_PRO (link);
+ dep_t dep = DEP_LINK_DEP (link);
+ rtx pro = DEP_PRO (dep);
- if (INSN_PRIORITY_KNOWN (pro))
+ if (INSN_PRIORITY_STATUS (pro) >= 0
+ && QUEUE_INDEX (insn) != QUEUE_SCHEDULED)
{
- INSN_PRIORITY_KNOWN (pro) = 0;
- clear_priorities (pro);
+ /* If DEP doesn't contribute to priority then INSN itself should
+ be added to priority roots. */
+ if (contributes_to_priority_p (dep))
+ insn_is_root_p = false;
+
+ INSN_PRIORITY_STATUS (pro) = -1;
+ clear_priorities (pro, roots_ptr);
}
}
+
+ if (insn_is_root_p)
+ VEC_safe_push (rtx, heap, *roots_ptr, insn);
}
/* Recompute priorities of instructions, whose priorities might have been
- changed due to changes in INSN. */
+ changed. ROOTS is a vector of instructions whose priority computation will
+ trigger initialization of all cleared priorities. */
static void
-calc_priorities (rtx insn)
+calc_priorities (rtx_vec_t roots)
{
- dep_link_t link;
-
- FOR_EACH_DEP_LINK (link, INSN_BACK_DEPS (insn))
- {
- rtx pro = DEP_LINK_PRO (link);
+ int i;
+ rtx insn;
- if (!INSN_PRIORITY_KNOWN (pro))
- {
- priority (pro);
- calc_priorities (pro);
- }
- }
+ for (i = 0; VEC_iterate (rtx, roots, i, insn); i++)
+ priority (insn);
}