This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Re: [PATCH] Value profile based optimizations, part 1
Hello,
> > + regset mkr_live;
>
> Don't like the use of the global variable.
>
> > + SET_REGNO_REG_SET (killed, regno);
>
> Need to iterate over HARD_REG_NREGS.
>
> > + mkr_live = e->dest->global_live_at_start;
> > + for (x = insn; x; x = NEXT_INSN (x))
> > + if (INSN_P (x))
> > + note_stores (PATTERN (x), mark_killed_regs, killed);
>
> Just clear global_live_at_start from killed after this loop
> to avoid the global variable.
>
> > + y = emit_insn (gen_rtx_SET (VOIDmode, to, from));
>
> emit_move_insn, surely?
OK now (provided it passes testing)?
Zdenek
Index: cfgrtl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cfgrtl.c,v
retrieving revision 1.80
diff -c -3 -p -r1.80 cfgrtl.c
*** cfgrtl.c 12 Jun 2003 18:09:55 -0000 1.80
--- cfgrtl.c 19 Jun 2003 00:58:54 -0000
*************** Software Foundation, 59 Temple Place - S
*** 56,61 ****
--- 56,63 ----
#include "obstack.h"
#include "insn-config.h"
#include "cfglayout.h"
+ #include "recog.h"
+ #include "expr.h"
/* Stubs in case we don't have a return insn. */
#ifndef HAVE_return
*************** static bool rtl_redirect_edge_and_branch
*** 88,93 ****
--- 90,96 ----
static edge rtl_split_block PARAMS ((basic_block, void *));
static void rtl_dump_bb PARAMS ((basic_block, FILE *));
static int rtl_verify_flow_info_1 PARAMS ((void));
+ static void mark_killed_regs (rtx, rtx, void *);
/* Return true if NOTE is not one of the ones that must be kept paired,
so that we may simply delete it. */
*************** insert_insn_on_edge (pattern, e)
*** 1335,1340 ****
--- 1338,1433 ----
e->insns = get_insns ();
end_sequence ();
+ }
+
+ /* Called from safe_insert_insn_on_edge through note_stores, marks live
+ registers that are killed by the store. */
+ static void
+ mark_killed_regs (rtx reg, rtx set ATTRIBUTE_UNUSED, void *data)
+ {
+ regset killed = data;
+ int regno, i;
+
+ if (GET_CODE (reg) == SUBREG)
+ reg = SUBREG_REG (reg);
+ if (!REG_P (reg))
+ return;
+ regno = REGNO (reg);
+
+ for (i = 0; i < HARD_REGNO_NREGS (regno, GET_MODE (reg)); i++)
+ SET_REGNO_REG_SET (killed, regno + i);
+ }
+
+ /* Similar to insert_insn_on_edge, tries to put INSN to edge E. Additionally
+ it checks whether this will not clobber the registers that are live on the
+ edge (i.e. it requieres liveness information to be up-to-date) and if there
+ are some, then it tries to save and restore them. Returns true if
+ succesful. */
+ bool
+ safe_insert_insn_on_edge (rtx insn, edge e)
+ {
+ rtx x;
+ regset_head killed_head;
+ regset killed = INITIALIZE_REG_SET (killed_head);
+ rtx save_regs = NULL_RTX;
+ int regno;
+ enum machine_mode mode;
+
+ for (x = insn; x; x = NEXT_INSN (x))
+ if (INSN_P (x))
+ note_stores (PATTERN (x), mark_killed_regs, killed);
+ bitmap_operation (killed, killed, e->dest->global_live_at_start, BITMAP_AND);
+
+ EXECUTE_IF_SET_IN_REG_SET (killed, 0, regno,
+ {
+ mode = regno < FIRST_PSEUDO_REGISTER
+ ? reg_raw_mode[regno]
+ : GET_MODE (regno_reg_rtx[regno]);
+ if (mode == VOIDmode)
+ return false;
+ save_regs = alloc_EXPR_LIST (0,
+ alloc_EXPR_LIST (0,
+ gen_reg_rtx (mode),
+ gen_raw_REG (mode, regno)),
+ save_regs);
+ });
+
+ if (save_regs)
+ {
+ rtx from, to, y;
+
+ start_sequence ();
+ for (x = save_regs; x; x = XEXP (x, 1))
+ {
+ from = XEXP (XEXP (x, 0), 1);
+ to = XEXP (XEXP (x, 0), 0);
+ y = emit_move_insn (to, from);
+ if (recog (PATTERN (y), y, NULL) < 0)
+ {
+ end_sequence ();
+ return false;
+ }
+ }
+ emit_insn (insn);
+ for (x = save_regs; x; x = XEXP (x, 1))
+ {
+ from = XEXP (XEXP (x, 0), 0);
+ to = XEXP (XEXP (x, 0), 1);
+ y = emit_move_insn (to, from);
+ if (recog (PATTERN (y), y, NULL) < 0)
+ {
+ end_sequence ();
+ return false;
+ }
+ }
+ insn = get_insns ();
+ end_sequence ();
+ free_EXPR_LIST_list (&save_regs);
+ }
+ insert_insn_on_edge (insn, e);
+
+ FREE_REG_SET (killed);
+ return true;
}
/* Update the CFG for the instructions queued on edge E. */