Commit b18e284e by Bernd Schmidt Committed by Bernd Schmidt

bfin.md (UNSPEC_NOP): New constant.

	* config/bfin/bfin.md (UNSPEC_NOP): New constant.
	(forced_nop): New pattern.
	* config/bfin/bfin.c: Include "df.h".
	(add_to_reg): Use df_regs_ever_live_p instead of regs_ever_live.
	(bfin_discover_loop): Use df_get_live_in instead of
	global_live_at_start.
	(bfin_reorder_loops): Pass 0 to cfg_layout_initialize.  Call
	df_analyze when done.
	(gen_one_bundle): Don't generate SEQUENCE insns, just put modes on
	the insns.  Use QImode for the final insn in a bundle.  Call
	df_insn_rescan on generated NOPs; use gen_forced_nop instead of
	gen_nop.
	(reorder_var_tracking_notes): New function.
	(bfin_reorg): Pass no argument to split_all_insns.  Don't call
	update_life_info.  Call df_analyze after scheduling and bundle
	generation.  Call reorder_var_tracking_notes if generating these notes.
	Call df_finish_pass at the end.

From-SVN: r125648
parent 8c8fa927
2007-06-12 Bernd Schmidt <bernd.schmidt@analog.com>
* config/bfin/bfin.md (UNSPEC_NOP): New constant.
(forced_nop): New pattern.
* config/bfin/bfin.c: Include "df.h".
(add_to_reg): Use df_regs_ever_live_p instead of regs_ever_live.
(bfin_discover_loop): Use df_get_live_in instead of
global_live_at_start.
(bfin_reorder_loops): Pass 0 to cfg_layout_initialize. Call
df_analyze when done.
(gen_one_bundle): Don't generate SEQUENCE insns, just put modes on
the insns. Use QImode for the final insn in a bundle. Call
df_insn_rescan on generated NOPs; use gen_forced_nop instead of
gen_nop.
(reorder_var_tracking_notes): New function.
(bfin_reorg): Pass no argument to split_all_insns. Don't call
update_life_info. Call df_analyze after scheduling and bundle
generation. Call reorder_var_tracking_notes if generating these notes.
Call df_finish_pass at the end.
2007-06-12 Dirk Mueller <dmueller@suse.de> 2007-06-12 Dirk Mueller <dmueller@suse.de>
* trans-stmt.c (gfc_trans_call): fix gcc_assert to * trans-stmt.c (gfc_trans_call): fix gcc_assert to
......
...@@ -54,6 +54,7 @@ ...@@ -54,6 +54,7 @@
#include "basic-block.h" #include "basic-block.h"
#include "cfglayout.h" #include "cfglayout.h"
#include "timevar.h" #include "timevar.h"
#include "df.h"
/* A C structure for machine-specific, per-function data. /* A C structure for machine-specific, per-function data.
This is added to the cfun structure. */ This is added to the cfun structure. */
...@@ -604,7 +605,7 @@ add_to_reg (rtx reg, HOST_WIDE_INT value, int frame, int epilogue_p) ...@@ -604,7 +605,7 @@ add_to_reg (rtx reg, HOST_WIDE_INT value, int frame, int epilogue_p)
{ {
int i; int i;
for (i = REG_P0; i <= REG_P5; i++) for (i = REG_P0; i <= REG_P5; i++)
if ((regs_ever_live[i] && ! call_used_regs[i]) if ((df_regs_ever_live_p (i) && ! call_used_regs[i])
|| (!TARGET_FDPIC || (!TARGET_FDPIC
&& i == PIC_OFFSET_TABLE_REGNUM && i == PIC_OFFSET_TABLE_REGNUM
&& (current_function_uses_pic_offset_table && (current_function_uses_pic_offset_table
...@@ -3745,7 +3746,7 @@ bfin_discover_loop (loop_info loop, basic_block tail_bb, rtx tail_insn) ...@@ -3745,7 +3746,7 @@ bfin_discover_loop (loop_info loop, basic_block tail_bb, rtx tail_insn)
FOR_EACH_EDGE (e, ei, bb->succs) FOR_EACH_EDGE (e, ei, bb->succs)
{ {
basic_block succ = EDGE_SUCC (bb, ei.index)->dest; basic_block succ = EDGE_SUCC (bb, ei.index)->dest;
if (!REGNO_REG_SET_P (succ->il.rtl->global_live_at_start, if (!REGNO_REG_SET_P (df_get_live_in (succ),
REGNO (loop->iter_reg))) REGNO (loop->iter_reg)))
continue; continue;
if (!VEC_space (basic_block, works, 1)) if (!VEC_space (basic_block, works, 1))
...@@ -3974,7 +3975,7 @@ bfin_reorder_loops (loop_info loops, FILE *dump_file) ...@@ -3974,7 +3975,7 @@ bfin_reorder_loops (loop_info loops, FILE *dump_file)
FOR_EACH_BB (bb) FOR_EACH_BB (bb)
bb->aux = NULL; bb->aux = NULL;
cfg_layout_initialize (CLEANUP_UPDATE_LIFE); cfg_layout_initialize (0);
for (loop = loops; loop; loop = loop->next) for (loop = loops; loop; loop = loop->next)
{ {
...@@ -4026,6 +4027,7 @@ bfin_reorder_loops (loop_info loops, FILE *dump_file) ...@@ -4026,6 +4027,7 @@ bfin_reorder_loops (loop_info loops, FILE *dump_file)
bb->aux = NULL; bb->aux = NULL;
} }
cfg_layout_finalize (); cfg_layout_finalize ();
df_analyze ();
} }
/* Run from machine_dependent_reorg, this pass looks for doloop_end insns /* Run from machine_dependent_reorg, this pass looks for doloop_end insns
...@@ -4087,7 +4089,7 @@ bfin_reorg_loops (FILE *dump_file) ...@@ -4087,7 +4089,7 @@ bfin_reorg_loops (FILE *dump_file)
static bool static bool
gen_one_bundle (rtx slot[3]) gen_one_bundle (rtx slot[3])
{ {
rtx bundle; rtx bundle, insn;
gcc_assert (slot[1] != NULL_RTX); gcc_assert (slot[1] != NULL_RTX);
...@@ -4116,9 +4118,15 @@ gen_one_bundle (rtx slot[3]) ...@@ -4116,9 +4118,15 @@ gen_one_bundle (rtx slot[3])
} }
if (slot[0] == NULL_RTX) if (slot[0] == NULL_RTX)
slot[0] = emit_insn_before (gen_mnop (), slot[1]); {
slot[0] = emit_insn_before (gen_mnop (), slot[1]);
df_insn_rescan (slot[0]);
}
if (slot[2] == NULL_RTX) if (slot[2] == NULL_RTX)
slot[2] = emit_insn_after (gen_nop (), slot[1]); {
slot[2] = emit_insn_after (gen_forced_nop (), slot[1]);
df_insn_rescan (slot[2]);
}
/* Avoid line number information being printed inside one bundle. */ /* Avoid line number information being printed inside one bundle. */
if (INSN_LOCATOR (slot[1]) if (INSN_LOCATOR (slot[1])
...@@ -4131,17 +4139,8 @@ gen_one_bundle (rtx slot[3]) ...@@ -4131,17 +4139,8 @@ gen_one_bundle (rtx slot[3])
/* Terminate them with "|| " instead of ";" in the output. */ /* Terminate them with "|| " instead of ";" in the output. */
PUT_MODE (slot[0], SImode); PUT_MODE (slot[0], SImode);
PUT_MODE (slot[1], SImode); PUT_MODE (slot[1], SImode);
/* Terminate the bundle, for the benefit of reorder_var_tracking_notes. */
/* This is a cheat to avoid emit_insn's special handling of SEQUENCEs. PUT_MODE (slot[2], QImode);
Generating a PARALLEL first and changing its code later is the
easiest way to emit a SEQUENCE insn. */
bundle = gen_rtx_PARALLEL (VOIDmode, gen_rtvec (3, slot[0], slot[1], slot[2]));
emit_insn_before (bundle, slot[0]);
remove_insn (slot[0]);
remove_insn (slot[1]);
remove_insn (slot[2]);
PUT_CODE (bundle, SEQUENCE);
return true; return true;
} }
...@@ -4199,6 +4198,7 @@ bfin_gen_bundles (void) ...@@ -4199,6 +4198,7 @@ bfin_gen_bundles (void)
{ {
SET_SRC (pat) = XVECEXP (SET_SRC (pat), 0, 0); SET_SRC (pat) = XVECEXP (SET_SRC (pat), 0, 0);
INSN_CODE (slot[0]) = -1; INSN_CODE (slot[0]) = -1;
df_insn_rescan (slot[0]);
} }
} }
n_filled = 0; n_filled = 0;
...@@ -4209,6 +4209,58 @@ bfin_gen_bundles (void) ...@@ -4209,6 +4209,58 @@ bfin_gen_bundles (void)
} }
} }
} }
/* Ensure that no var tracking notes are emitted in the middle of a
three-instruction bundle. */
static void
reorder_var_tracking_notes (void)
{
basic_block bb;
FOR_EACH_BB (bb)
{
rtx insn, next;
rtx queue = NULL_RTX;
bool in_bundle = false;
for (insn = BB_HEAD (bb); insn != BB_END (bb); insn = next)
{
next = NEXT_INSN (insn);
if (INSN_P (insn))
{
/* Emit queued up notes at the last instruction of a bundle. */
if (GET_MODE (insn) == QImode)
{
while (queue)
{
rtx next_queue = PREV_INSN (queue);
PREV_INSN (NEXT_INSN (insn)) = queue;
NEXT_INSN (queue) = NEXT_INSN (insn);
NEXT_INSN (insn) = queue;
PREV_INSN (queue) = insn;
queue = next_queue;
}
in_bundle = false;
}
else if (GET_MODE (insn) == SImode)
in_bundle = true;
}
else if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION)
{
if (in_bundle)
{
rtx prev = PREV_INSN (insn);
PREV_INSN (next) = prev;
NEXT_INSN (prev) = next;
PREV_INSN (insn) = queue;
queue = insn;
}
}
}
}
}
/* Return an insn type for INSN that can be used by the caller for anomaly /* Return an insn type for INSN that can be used by the caller for anomaly
workarounds. This differs from plain get_attr_type in that it handles workarounds. This differs from plain get_attr_type in that it handles
...@@ -4290,11 +4342,9 @@ bfin_reorg (void) ...@@ -4290,11 +4342,9 @@ bfin_reorg (void)
if (bfin_flag_schedule_insns2) if (bfin_flag_schedule_insns2)
{ {
splitting_for_sched = 1; splitting_for_sched = 1;
split_all_insns (0); split_all_insns ();
splitting_for_sched = 0; splitting_for_sched = 0;
update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES, PROP_DEATH_NOTES);
timevar_push (TV_SCHED2); timevar_push (TV_SCHED2);
schedule_insns (); schedule_insns ();
timevar_pop (TV_SCHED2); timevar_pop (TV_SCHED2);
...@@ -4304,6 +4354,8 @@ bfin_reorg (void) ...@@ -4304,6 +4354,8 @@ bfin_reorg (void)
bfin_gen_bundles (); bfin_gen_bundles ();
} }
df_analyze ();
/* Doloop optimization */ /* Doloop optimization */
if (cfun->machine->has_hardware_loops) if (cfun->machine->has_hardware_loops)
bfin_reorg_loops (dump_file); bfin_reorg_loops (dump_file);
...@@ -4451,8 +4503,10 @@ bfin_reorg (void) ...@@ -4451,8 +4503,10 @@ bfin_reorg (void)
{ {
timevar_push (TV_VAR_TRACKING); timevar_push (TV_VAR_TRACKING);
variable_tracking_main (); variable_tracking_main ();
reorder_var_tracking_notes ();
timevar_pop (TV_VAR_TRACKING); timevar_pop (TV_VAR_TRACKING);
} }
df_finish_pass ();
} }
/* Handle interrupt_handler, exception_handler and nmi_handler function /* Handle interrupt_handler, exception_handler and nmi_handler function
......
...@@ -137,7 +137,8 @@ ...@@ -137,7 +137,8 @@
(UNSPEC_FUNCDESC_GOT17M4 9) (UNSPEC_FUNCDESC_GOT17M4 9)
(UNSPEC_LSETUP_END 10) (UNSPEC_LSETUP_END 10)
;; Distinguish a 32-bit version of an insn from a 16-bit version. ;; Distinguish a 32-bit version of an insn from a 16-bit version.
(UNSPEC_32BIT 11)]) (UNSPEC_32BIT 11)
(UNSPEC_NOP 12)])
(define_constants (define_constants
[(UNSPEC_VOLATILE_EH_RETURN 0) [(UNSPEC_VOLATILE_EH_RETURN 0)
...@@ -2595,6 +2596,12 @@ ...@@ -2595,6 +2596,12 @@
"" ""
"nop;") "nop;")
;; A nop which stays there when emitted.
(define_insn "forced_nop"
[(unspec [(const_int 0)] UNSPEC_NOP)]
""
"nop;")
(define_insn "mnop" (define_insn "mnop"
[(unspec [(const_int 0)] UNSPEC_32BIT)] [(unspec [(const_int 0)] UNSPEC_32BIT)]
"" ""
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment