rtx insn;
/* Find the largest UID and create a mapping from UIDs to CUIDs. */
- uid_cuid = xcalloc (get_max_uid () + 1, sizeof (int));
+ uid_cuid = XCNEWVEC (int, get_max_uid () + 1);
i = 1;
FOR_EACH_BB (bb)
FOR_BB_INSNS (bb, insn)
if (REG_P (dest))
record_last_reg_set_info (last_set_insn, REGNO (dest));
- else if (MEM_P (dest)
- /* Ignore pushes, they clobber nothing. */
- && ! push_operand (dest, GET_MODE (dest)))
- record_last_mem_set_info (last_set_insn);
+ else if (MEM_P (dest))
+ {
+ /* Ignore pushes, they don't clobber memory. They may still
+ clobber the stack pointer though. Some targets do argument
+ pushes without adding REG_INC notes. See e.g. PR25196,
+ where a pushsi2 on i386 doesn't have REG_INC notes. Note
+ such changes here too. */
+ if (! push_operand (dest, GET_MODE (dest)))
+ record_last_mem_set_info (last_set_insn);
+ else
+ record_last_reg_set_info (last_set_insn, STACK_POINTER_REGNUM);
+ }
}
can_copy_p (GET_MODE (dest))
/* Is SET_SRC something we want to gcse? */
&& general_operand (src, GET_MODE (src))
+#ifdef STACK_REGS
+ /* Never consider insns touching the register stack. It may
+ create situations that reg-stack cannot handle (e.g. a stack
+ register live across an abnormal edge). */
+ && (REGNO (dest) < FIRST_STACK_REG || REGNO (dest) > LAST_STACK_REG)
+#endif
/* An expression is not available if its operands are
subsequently modified, including this insn. */
&& oprs_unchanged_p (src, insn, true))
can_copy_p (GET_MODE (src))
/* Is SET_DEST something we want to gcse? */
&& general_operand (dest, GET_MODE (dest))
+#ifdef STACK_REGS
+ /* As above for STACK_REGS. */
+ && (REGNO (src) < FIRST_STACK_REG || REGNO (src) > LAST_STACK_REG)
+#endif
&& ! (flag_float_store && FLOAT_MODE_P (GET_MODE (dest)))
/* Check if the memory expression is killed after insn. */
&& ! load_killed_in_block_p (INSN_CUID (insn) + 1, dest, true)
}
else
{
- /* Adding a load on a critical edge will cuase a split. */
+ /* Adding a load on a critical edge will cause a split. */
if (EDGE_CRITICAL_P (pred))
critical_edge_split = true;
not_ok_count += pred->count;
/* Main entry point of the GCSE after reload - clean some redundant loads
due to spilling. */
-void
+static void
gcse_after_reload_main (rtx f ATTRIBUTE_UNUSED)
{
}
-static void
+static unsigned int
rest_of_handle_gcse2 (void)
{
gcse_after_reload_main (get_insns ());
rebuild_jump_labels (get_insns ());
delete_trivially_dead_insns (get_insns (), max_reg_num ());
+ return 0;
}
struct tree_opt_pass pass_gcse2 =