summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/dbgcnt.def2
-rw-r--r--gcc/global.c5
-rw-r--r--gcc/haifa-sched.c124
4 files changed, 108 insertions, 36 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 95789e56955..e4086f2b0a9 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2007-06-20 Seongbae Park <seongbae.park@gmail.com>
+ Maxim Kuvyrkov <mkuvyrkov@ispras.ru>
+
+ * dbgcnt.def (global_alloc_at_func, global_alloc_at_reg):
+ New counters.
+ * haifa-sched.c (queue_to_ready): Don't requeue next insn
+ if dbg_cnt (sched_insn) reaches the limit.
+ (choose_ready): New parameter INSN_PTR and new return value.
+ (schedule_block): Handle dbg_cnt (sched_insn). Handle
+ the new return value from choose_ready.
+ * global.c (global_aloc): New dbgcnt global_alloc_at_reg.
+ (rest_of_handle_global_alloc): New global_alloc_at_func.
+
2007-06-20 Adam Nemet <anemet@caviumnetworks.com>
PR tree-optimization/25737
diff --git a/gcc/dbgcnt.def b/gcc/dbgcnt.def
index 854f3d922c3..ee9e32066ad 100644
--- a/gcc/dbgcnt.def
+++ b/gcc/dbgcnt.def
@@ -82,3 +82,5 @@ DEBUG_COUNTER (sched_insn)
DEBUG_COUNTER (sched_region)
DEBUG_COUNTER (split_for_sched2)
DEBUG_COUNTER (tail_call)
+DEBUG_COUNTER (global_alloc_at_func)
+DEBUG_COUNTER (global_alloc_at_reg)
diff --git a/gcc/global.c b/gcc/global.c
index 62b7b6273e3..fc2a4543f79 100644
--- a/gcc/global.c
+++ b/gcc/global.c
@@ -41,6 +41,7 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
#include "timevar.h"
#include "df.h"
#include "vecprim.h"
+#include "dbgcnt.h"
/* This pass of the compiler performs global register allocation.
It assigns hard register numbers to all the pseudo registers
@@ -653,6 +654,8 @@ global_alloc (void)
if (reg_renumber[allocno[allocno_order[i]].reg] < 0
&& REG_LIVE_LENGTH (allocno[allocno_order[i]].reg) >= 0)
{
+ if (!dbg_cnt (global_alloc_at_reg))
+ break;
/* If we have more than one register class,
first try allocating in the class that is cheapest
for this pseudo-reg. If that fails, try any reg. */
@@ -2049,7 +2052,7 @@ rest_of_handle_global_alloc (void)
/* If optimizing, allocate remaining pseudo-regs. Do the reload
pass fixing up any insns that are invalid. */
- if (optimize)
+ if (optimize && dbg_cnt (global_alloc_at_func))
failure = global_alloc ();
else
{
diff --git a/gcc/haifa-sched.c b/gcc/haifa-sched.c
index 92ed9bb492b..bf017e88495 100644
--- a/gcc/haifa-sched.c
+++ b/gcc/haifa-sched.c
@@ -539,7 +539,7 @@ static rtx ready_remove (struct ready_list *, int);
static void ready_remove_insn (rtx);
static int max_issue (struct ready_list *, int *, int);
-static rtx choose_ready (struct ready_list *);
+static int choose_ready (struct ready_list *, rtx *);
static void fix_inter_tick (rtx, rtx);
static int fix_tick_ready (rtx);
@@ -1483,9 +1483,17 @@ queue_to_ready (struct ready_list *ready)
{
rtx insn;
rtx link;
+ rtx skip_insn;
q_ptr = NEXT_Q (q_ptr);
+ if (dbg_cnt (sched_insn) == false)
+ /* If debug counter is activated do not requeue insn next after
+ last_scheduled_insn. */
+ skip_insn = next_nonnote_insn (last_scheduled_insn);
+ else
+ skip_insn = NULL_RTX;
+
/* Add all pending insns that can be scheduled without stalls to the
ready list. */
for (link = insn_queue[q_ptr]; link; link = XEXP (link, 1))
@@ -1501,7 +1509,8 @@ queue_to_ready (struct ready_list *ready)
See the comment in schedule_block for the rationale. */
if (!reload_completed
&& ready->n_ready > MAX_SCHED_READY_INSNS
- && !SCHED_GROUP_P (insn))
+ && !SCHED_GROUP_P (insn)
+ && insn != skip_insn)
{
if (sched_verbose >= 2)
fprintf (sched_dump, "requeued because ready full\n");
@@ -1980,17 +1989,43 @@ max_issue (struct ready_list *ready, int *index, int max_points)
/* The following function chooses insn from READY and modifies
*N_READY and READY. The following function is used only for first
- cycle multipass scheduling. */
-
-static rtx
-choose_ready (struct ready_list *ready)
+ cycle multipass scheduling.
+ Return:
+ -1 if cycle should be advanced,
+ 0 if INSN_PTR is set to point to the desirable insn,
+ 1 if choose_ready () should be restarted without advancing the cycle. */
+static int
+choose_ready (struct ready_list *ready, rtx *insn_ptr)
{
- int lookahead = 0;
+ int lookahead;
+
+ if (dbg_cnt (sched_insn) == false)
+ {
+ rtx insn;
+
+ insn = next_nonnote_insn (last_scheduled_insn);
+
+ if (QUEUE_INDEX (insn) == QUEUE_READY)
+ /* INSN is in the ready_list. */
+ {
+ ready_remove_insn (insn);
+ *insn_ptr = insn;
+ return 0;
+ }
+
+ /* INSN is in the queue. Advance cycle to move it to the ready list. */
+ return -1;
+ }
+
+ lookahead = 0;
if (targetm.sched.first_cycle_multipass_dfa_lookahead)
lookahead = targetm.sched.first_cycle_multipass_dfa_lookahead ();
if (lookahead <= 0 || SCHED_GROUP_P (ready_element (ready, 0)))
- return ready_remove_first (ready);
+ {
+ *insn_ptr = ready_remove_first (ready);
+ return 0;
+ }
else
{
/* Try to choose the better insn. */
@@ -2007,7 +2042,10 @@ choose_ready (struct ready_list *ready)
}
insn = ready_element (ready, 0);
if (INSN_CODE (insn) < 0)
- return ready_remove_first (ready);
+ {
+ *insn_ptr = ready_remove_first (ready);
+ return 0;
+ }
if (spec_info
&& spec_info->flags & (PREFER_NON_DATA_SPEC
@@ -2049,7 +2087,7 @@ choose_ready (struct ready_list *ready)
list. */
{
change_queue_index (insn, 1);
- return 0;
+ return 1;
}
max_points = ISSUE_POINTS (insn);
@@ -2071,9 +2109,15 @@ choose_ready (struct ready_list *ready)
}
if (max_issue (ready, &index, max_points) == 0)
- return ready_remove_first (ready);
+ {
+ *insn_ptr = ready_remove_first (ready);
+ return 0;
+ }
else
- return ready_remove (ready, index);
+ {
+ *insn_ptr = ready_remove (ready, index);
+ return 0;
+ }
}
}
@@ -2172,9 +2216,27 @@ schedule_block (basic_block *target_bb, int rgn_n_insns1)
";;\t\t before reload => truncated to %d insns\n", i);
}
- /* Delay all insns past it for 1 cycle. */
- while (i < ready.n_ready)
- queue_insn (ready_remove (&ready, i), 1);
+ /* Delay all insns past it for 1 cycle. If debug counter is
+ activated make an exception for the insn right after
+ last_scheduled_insn. */
+ {
+ rtx skip_insn;
+
+ if (dbg_cnt (sched_insn) == false)
+ skip_insn = next_nonnote_insn (last_scheduled_insn);
+ else
+ skip_insn = NULL_RTX;
+
+ while (i < ready.n_ready)
+ {
+ rtx insn;
+
+ insn = ready_remove (&ready, i);
+
+ if (insn != skip_insn)
+ queue_insn (insn, 1);
+ }
+ }
}
/* Now we can restore basic block notes and maintain precise cfg. */
@@ -2271,29 +2333,22 @@ schedule_block (basic_block *target_bb, int rgn_n_insns1)
|| !(*current_sched_info->schedule_more_p) ())
break;
- if (dbg_cnt (sched_insn) == false)
- {
- insn = NEXT_INSN (last_scheduled_insn);
- while ((*current_sched_info->schedule_more_p) ())
- {
- (*current_sched_info->begin_schedule_ready) (insn,
- last_scheduled_insn);
- if (QUEUE_INDEX (insn) >= 0)
- queue_remove (insn);
- last_scheduled_insn = insn;
- insn = NEXT_INSN (insn);
- }
- while (ready.n_ready)
- ready_remove_first (&ready);
- goto bail_out;
- }
-
/* Select and remove the insn from the ready list. */
if (sort_p)
{
- insn = choose_ready (&ready);
- if (!insn)
+ int res;
+
+ insn = NULL_RTX;
+ res = choose_ready (&ready, &insn);
+
+ if (res < 0)
+ /* Finish cycle. */
+ break;
+ if (res > 0)
+ /* Restart choose_ready (). */
continue;
+
+ gcc_assert (insn != NULL_RTX);
}
else
insn = ready_remove_first (&ready);
@@ -2445,7 +2500,6 @@ schedule_block (basic_block *target_bb, int rgn_n_insns1)
}
}
-bail_out:
/* Debug info. */
if (sched_verbose)
{