From 6761cdfbbe2f681972950b1c868f12bd7c448dc6 Mon Sep 17 00:00:00 2001 From: vmakarov Date: Sat, 27 Sep 2008 03:26:45 +0000 Subject: [PATCH] 2008-09-26 Vladimir Makarov Revert: 2008-09-25 Vladimir Makarov * ira-lives.c:... * doc/rtl.texi:... git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@140721 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 7 ++++ gcc/doc/rtl.texi | 13 +++--- gcc/ira-lives.c | 125 +++++++++++++++++-------------------------------------- 3 files changed, 51 insertions(+), 94 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 456daf82f1d..9b32387518d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,10 @@ +2008-09-26 Vladimir Makarov + + Revert: + 2008-09-25 Vladimir Makarov + * ira-lives.c:... + * doc/rtl.texi:... + 2008-09-26 Adam Nemet * config/mips/mips.h (ISA_HAS_DMUL3, ISA_HAS_BADDU, ISA_HAS_BBIT, diff --git a/gcc/doc/rtl.texi b/gcc/doc/rtl.texi index 984ee432641..148e19ddc9a 100644 --- a/gcc/doc/rtl.texi +++ b/gcc/doc/rtl.texi @@ -2930,13 +2930,12 @@ constituent instructions might not. When a @code{clobber} expression for a register appears inside a @code{parallel} with other side effects, the register allocator guarantees that the register is unoccupied both before and after that -insn if the @samp{&} constraint is specified for at least one -alternative (@pxref{Modifiers}) of the clobber. However, the reload -phase may allocate a register used for one of the inputs unless the -@samp{&} constraint is specified for the selected alternative. You -can clobber either a specific hard register, a pseudo register, or a -@code{scratch} expression; in the latter two cases, GCC will allocate -a hard register that is available there for use as a temporary. +insn. However, the reload phase may allocate a register used for one of +the inputs unless the @samp{&} constraint is specified for the selected +alternative (@pxref{Modifiers}). You can clobber either a specific hard +register, a pseudo register, or a @code{scratch} expression; in the +latter two cases, GCC will allocate a hard register that is available +there for use as a temporary. For instructions that require a temporary register, you should use @code{scratch} instead of a pseudo-register because this will allow the diff --git a/gcc/ira-lives.c b/gcc/ira-lives.c index e49860fa927..609708e9069 100644 --- a/gcc/ira-lives.c +++ b/gcc/ira-lives.c @@ -209,15 +209,20 @@ clear_allocno_live (ira_allocno_t a) sparseset_clear_bit (allocnos_live, ALLOCNO_NUM (a)); } -/* Mark the register REG as live. Store a 1 in hard_regs_live or - allocnos_live for this register or the corresponding allocno, - record how many consecutive hardware registers it actually - needs. */ +/* Mark the register referenced by use or def REF as live + Store a 1 in hard_regs_live or allocnos_live for this register or + the corresponding allocno, record how many consecutive hardware + registers it actually needs. */ + static void -mark_reg_live (rtx reg) +mark_ref_live (struct df_ref *ref) { + rtx reg; int regno; + reg = DF_REF_REG (ref); + if (GET_CODE (reg) == SUBREG) + reg = SUBREG_REG (reg); gcc_assert (REG_P (reg)); regno = REGNO (reg); @@ -264,25 +269,32 @@ mark_reg_live (rtx reg) } } -/* Mark the register referenced by use or def REF as live. */ -static void -mark_ref_live (struct df_ref *ref) +/* Return true if the definition described by DEF conflicts with the + instruction's inputs. */ +static bool +def_conflicts_with_inputs_p (struct df_ref *def) { - rtx reg; - - reg = DF_REF_REG (ref); - if (GET_CODE (reg) == SUBREG) - reg = SUBREG_REG (reg); - mark_reg_live (reg); + /* Conservatively assume that the condition is true for all clobbers. */ + return DF_REF_FLAGS_IS_SET (def, DF_REF_MUST_CLOBBER); } -/* Mark the register REG as dead. Store a 0 in hard_regs_live or +/* Mark the register referenced by definition DEF as dead, if the + definition is a total one. Store a 0 in hard_regs_live or allocnos_live for the register. */ static void -mark_reg_dead (rtx reg) +mark_ref_dead (struct df_ref *def) { + unsigned int i; + rtx reg; int regno; + if (DF_REF_FLAGS_IS_SET (def, DF_REF_PARTIAL) + || DF_REF_FLAGS_IS_SET (def, DF_REF_CONDITIONAL)) + return; + + reg = DF_REF_REG (def); + if (GET_CODE (reg) == SUBREG) + reg = SUBREG_REG (reg); gcc_assert (REG_P (reg)); regno = REGNO (reg); @@ -300,7 +312,6 @@ mark_reg_dead (rtx reg) } else if (! TEST_HARD_REG_BIT (ira_no_alloc_regs, regno)) { - unsigned int i; int last = regno + hard_regno_nregs[regno][GET_MODE (reg)]; enum reg_class cover_class; @@ -332,71 +343,6 @@ mark_reg_dead (rtx reg) } } -/* Mark the register referenced by definition DEF as dead, if the - definition is a total one. */ -static void -mark_ref_dead (struct df_ref *def) -{ - rtx reg; - - if (DF_REF_FLAGS_IS_SET (def, DF_REF_PARTIAL) - || DF_REF_FLAGS_IS_SET (def, DF_REF_CONDITIONAL)) - return; - - reg = DF_REF_REG (def); - if (GET_CODE (reg) == SUBREG) - reg = SUBREG_REG (reg); - mark_reg_dead (reg); -} - -/* Mark early clobber registers of the current INSN as live (if - LIVE_P) or dead. Return true if there are such registers. */ -static bool -mark_early_clobbers (rtx insn, bool live_p) -{ - int alt; - int def; - struct df_ref **def_rec; - bool set_p = false; - bool asm_p = asm_noperands (PATTERN (insn)) >= 0; - - if (asm_p) - for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++) - if (DF_REF_FLAGS_IS_SET (*def_rec, DF_REF_MUST_CLOBBER)) - { - if (live_p) - mark_ref_live (*def_rec); - else - mark_ref_dead (*def_rec); - set_p = true; - } - - for (def = 0; def < recog_data.n_operands; def++) - { - rtx dreg = recog_data.operand[def]; - - if (GET_CODE (dreg) == SUBREG) - dreg = SUBREG_REG (dreg); - if (! REG_P (dreg)) - continue; - - for (alt = 0; alt < recog_data.n_alternatives; alt++) - if ((recog_op_alt[def][alt].earlyclobber) - && (recog_op_alt[def][alt].cl != NO_REGS)) - break; - - if (alt >= recog_data.n_alternatives) - continue; - - if (live_p) - mark_reg_live (dreg); - else - mark_reg_dead (dreg); - set_p = true; - } - return set_p; -} - /* Checks that CONSTRAINTS permits to use only one hard register. If it is so, the function returns the class of the hard register. Otherwise it returns NO_REGS. */ @@ -634,7 +580,6 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) bitmap_iterator bi; bitmap reg_live_out; unsigned int px; - bool set_p; bb = loop_tree_node->bb; if (bb != NULL) @@ -753,7 +698,6 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) } extract_insn (insn); - preprocess_constraints (); process_single_reg_class_operands (false, freq); /* See which defined values die here. */ @@ -789,12 +733,19 @@ process_bb_node_lives (ira_loop_tree_node_t loop_tree_node) for (use_rec = DF_INSN_USES (insn); *use_rec; use_rec++) mark_ref_live (*use_rec); - set_p = mark_early_clobbers (insn, true); + /* If any defined values conflict with the inputs, mark those + defined values as live. */ + for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++) + if (def_conflicts_with_inputs_p (*def_rec)) + mark_ref_live (*def_rec); process_single_reg_class_operands (true, freq); - if (set_p) - mark_early_clobbers (insn, false); + /* See which of the defined values we marked as live are dead + before the instruction. */ + for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++) + if (def_conflicts_with_inputs_p (*def_rec)) + mark_ref_dead (*def_rec); curr_point++; } -- 2.11.0