/* Instruction scheduling pass. Selective scheduler and pipeliner.
- Copyright (C) 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
This file is part of GCC.
#include "system.h"
#include "coretypes.h"
#include "tm.h"
+#include "diagnostic-core.h"
#include "toplev.h"
#include "rtl.h"
#include "tm_p.h"
#include "vec.h"
#include "langhooks.h"
#include "rtlhooks-def.h"
+#include "emit-rtl.h" /* FIXME: Can go away once crtl is moved to rtl.h. */
#ifdef INSN_SCHEDULING
#include "sel-sched-ir.h"
flist_add (flist_t *lp, insn_t insn, state_t state, deps_t dc, void *tc,
insn_t last_scheduled_insn, VEC(rtx,gc) *executing_insns,
int *ready_ticks, int ready_ticks_size, insn_t sched_next,
- int cycle, int cycle_issued_insns,
+ int cycle, int cycle_issued_insns, int issue_more,
bool starts_cycle_p, bool after_stall_p)
{
fence_t f;
FENCE_TC (f) = tc;
FENCE_LAST_SCHEDULED_INSN (f) = last_scheduled_insn;
+ FENCE_ISSUE_MORE (f) = issue_more;
FENCE_EXECUTING_INSNS (f) = executing_insns;
FENCE_READY_TICKS (f) = ready_ticks;
FENCE_READY_TICKS_SIZE (f) = ready_ticks_size;
}
\f
/* Functions to work with dependence contexts.
- Dc (aka deps context, aka deps_t, aka struct deps *) is short for dependence
+ Dc (aka deps context, aka deps_t, aka struct deps_desc *) is short for dependence
context. It accumulates information about processed insns to decide if
current insn is dependent on the processed ones. */
static deps_t
alloc_deps_context (void)
{
- return XNEW (struct deps);
+ return XNEW (struct deps_desc);
}
/* Allocate and initialize dep context. */
ready_ticks_size,
NULL_RTX /* sched_next */,
1 /* cycle */, 0 /* cycle_issued_insns */,
+ issue_rate, /* issue_more */
1 /* starts_cycle_p */, 0 /* after_stall_p */);
}
}
3) all other fields are set to corresponding constant values.
INSN, STATE, DC, TC, LAST_SCHEDULED_INSN, EXECUTING_INSNS,
- READY_TICKS, READY_TICKS_SIZE, SCHED_NEXT, CYCLE and AFTER_STALL_P
- are the corresponding fields of the second fence. */
+ READY_TICKS, READY_TICKS_SIZE, SCHED_NEXT, CYCLE, ISSUE_MORE
+ and AFTER_STALL_P are the corresponding fields of the second fence. */
static void
merge_fences (fence_t f, insn_t insn,
state_t state, deps_t dc, void *tc,
rtx last_scheduled_insn, VEC(rtx, gc) *executing_insns,
int *ready_ticks, int ready_ticks_size,
- rtx sched_next, int cycle, bool after_stall_p)
+ rtx sched_next, int cycle, int issue_more, bool after_stall_p)
{
insn_t last_scheduled_insn_old = FENCE_LAST_SCHEDULED_INSN (f);
FENCE_CYCLE (f) = cycle;
FENCE_LAST_SCHEDULED_INSN (f) = NULL;
+ FENCE_ISSUE_MORE (f) = issue_rate;
VEC_free (rtx, gc, executing_insns);
free (ready_ticks);
if (FENCE_EXECUTING_INSNS (f))
delete_target_context (tc);
FENCE_LAST_SCHEDULED_INSN (f) = NULL;
+ FENCE_ISSUE_MORE (f) = issue_rate;
}
else
if (candidate->src == BLOCK_FOR_INSN (last_scheduled_insn))
FENCE_TC (f) = tc;
FENCE_LAST_SCHEDULED_INSN (f) = last_scheduled_insn;
+ FENCE_ISSUE_MORE (f) = issue_more;
}
else
{
state_t state, deps_t dc, void *tc, rtx last_scheduled_insn,
VEC(rtx, gc) *executing_insns, int *ready_ticks,
int ready_ticks_size, rtx sched_next, int cycle,
- int cycle_issued_insns, bool starts_cycle_p, bool after_stall_p)
+ int cycle_issued_insns, int issue_rate,
+ bool starts_cycle_p, bool after_stall_p)
{
fence_t f = flist_lookup (FLIST_TAIL_HEAD (new_fences), insn);
flist_add (FLIST_TAIL_TAILP (new_fences), insn, state, dc, tc,
last_scheduled_insn, executing_insns, ready_ticks,
ready_ticks_size, sched_next, cycle, cycle_issued_insns,
- starts_cycle_p, after_stall_p);
+ issue_rate, starts_cycle_p, after_stall_p);
FLIST_TAIL_TAILP (new_fences)
= &FLIST_NEXT (*FLIST_TAIL_TAILP (new_fences));
{
merge_fences (f, insn, state, dc, tc, last_scheduled_insn,
executing_insns, ready_ticks, ready_ticks_size,
- sched_next, cycle, after_stall_p);
+ sched_next, cycle, issue_rate, after_stall_p);
}
}
merge_fences (f, old->insn, old->state, old->dc, old->tc,
old->last_scheduled_insn, old->executing_insns,
old->ready_ticks, old->ready_ticks_size,
- old->sched_next, old->cycle,
+ old->sched_next, old->cycle, old->issue_more,
old->after_stall_p);
}
else
NULL_RTX, NULL,
XCNEWVEC (int, ready_ticks_size), ready_ticks_size,
NULL_RTX, FENCE_CYCLE (fence) + 1,
- 0, 1, FENCE_AFTER_STALL_P (fence));
+ 0, issue_rate, 1, FENCE_AFTER_STALL_P (fence));
}
/* Add a new fence to NEW_FENCES list and initialize all of its data
FENCE_SCHED_NEXT (fence),
FENCE_CYCLE (fence),
FENCE_ISSUED_INSNS (fence),
+ FENCE_ISSUE_MORE (fence),
FENCE_STARTS_CYCLE_P (fence),
FENCE_AFTER_STALL_P (fence));
}
static void
deps_init_id (idata_t id, insn_t insn, bool force_unique_p)
{
- struct deps _dc, *dc = &_dc;
+ struct deps_desc _dc, *dc = &_dc;
deps_init_id_data.where = DEPS_IN_NOWHERE;
deps_init_id_data.id = id;
|| SCHED_GROUP_P (insn)
|| prologue_epilogue_contains (insn)
/* Exception handling insns are always unique. */
- || (flag_non_call_exceptions && can_throw_internal (insn))
+ || (cfun->can_throw_non_call_exceptions && can_throw_internal (insn))
/* TRAP_IF though have an INSN code is control_flow_insn_p (). */
|| control_flow_insn_p (insn))
force_unique_p = true;
{
int i;
ds_t ds;
- struct deps *dc;
+ struct deps_desc *dc;
if (INSN_SIMPLEJUMP_P (pred))
/* Unconditional jump is just a transfer of control flow.
sched_scan (&ssi, bbs, bb, new_insns, NULL);
}
-/* Restore other notes for the whole region. */
+/* Restore notes for the whole region. */
static void
-sel_restore_other_notes (void)
+sel_restore_notes (void)
{
int bb;
+ insn_t insn;
for (bb = 0; bb < current_nr_blocks; bb++)
{
restore_other_notes (NULL, first);
BB_NOTE_LIST (first) = NULL_RTX;
+ FOR_BB_INSNS (first, insn)
+ if (NONDEBUG_INSN_P (insn))
+ reemit_notes (insn);
+
first = first->next_bb;
}
while (first != last);
void
sel_finish_bbs (void)
{
- sel_restore_other_notes ();
+ sel_restore_notes ();
/* Remove current loop preheader from this loop. */
if (current_loop_nest)