/* Initialization of uninitialized regs.
- Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
+ Copyright (C) 2007-2020 Free Software Foundation, Inc.
This file is part of GCC.
#include "config.h"
#include "system.h"
#include "coretypes.h"
-#include "tm.h"
-#include "tree.h"
+#include "backend.h"
#include "rtl.h"
-#include "regs.h"
+#include "tree.h"
+#include "df.h"
+#include "memmodel.h"
+#include "emit-rtl.h"
#include "expr.h"
#include "tree-pass.h"
-#include "basic-block.h"
-#include "flags.h"
-#include "df.h"
/* Check all of the uses of pseudo variables. If any use that is MUST
uninitialized, add a store of 0 immediately before it. For
initialize_uninitialized_regs (void)
{
basic_block bb;
- bitmap already_genned = BITMAP_ALLOC (NULL);
+ auto_bitmap already_genned;
if (optimize == 1)
{
df_analyze ();
- FOR_EACH_BB (bb)
+ FOR_EACH_BB_FN (bb, cfun)
{
- rtx insn;
+ rtx_insn *insn;
bitmap lr = DF_LR_IN (bb);
bitmap ur = DF_LIVE_IN (bb);
bitmap_clear (already_genned);
FOR_BB_INSNS (bb, insn)
{
- unsigned int uid = INSN_UID (insn);
- df_ref *use_rec;
+ df_ref use;
if (!NONDEBUG_INSN_P (insn))
continue;
- for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++)
+ FOR_EACH_INSN_USE (use, insn)
{
- df_ref use = *use_rec;
unsigned int regno = DF_REF_REGNO (use);
/* Only do this for the pseudos. */
if (regno < FIRST_PSEUDO_REGISTER)
continue;
+ /* Ignore pseudo PIC register. */
+ if (pic_offset_table_rtx
+ && regno == REGNO (pic_offset_table_rtx))
+ continue;
+
/* Do not generate multiple moves for the same regno.
This is common for sequences of subreg operations.
They would be deleted during combine but there is no
if (bitmap_bit_p (lr, regno)
&& (!bitmap_bit_p (ur, regno)))
{
- rtx move_insn;
+ rtx_insn *move_insn;
rtx reg = DF_REF_REAL_REG (use);
bitmap_set_bit (already_genned, regno);
start_sequence ();
+ emit_clobber (reg);
emit_move_insn (reg, CONST0_RTX (GET_MODE (reg)));
move_insn = get_insns ();
end_sequence ();
if (dump_file)
fprintf (dump_file,
"adding initialization in %s of reg %d at in block %d for insn %d.\n",
- current_function_name (), regno, bb->index, uid);
+ current_function_name (), regno, bb->index,
+ INSN_UID (insn));
}
}
}
df_dump (dump_file);
df_remove_problem (df_live);
}
-
- BITMAP_FREE (already_genned);
}
-static bool
-gate_initialize_regs (void)
+namespace {
+
+const pass_data pass_data_initialize_regs =
{
- return optimize > 0;
-}
+ RTL_PASS, /* type */
+ "init-regs", /* name */
+ OPTGROUP_NONE, /* optinfo_flags */
+ TV_NONE, /* tv_id */
+ 0, /* properties_required */
+ 0, /* properties_provided */
+ 0, /* properties_destroyed */
+ 0, /* todo_flags_start */
+ TODO_df_finish, /* todo_flags_finish */
+};
-static unsigned int
-rest_of_handle_initialize_regs (void)
+class pass_initialize_regs : public rtl_opt_pass
{
- initialize_uninitialized_regs ();
- return 0;
-}
+public:
+ pass_initialize_regs (gcc::context *ctxt)
+ : rtl_opt_pass (pass_data_initialize_regs, ctxt)
+ {}
+
+ /* opt_pass methods: */
+ virtual bool gate (function *) { return optimize > 0; }
+ virtual unsigned int execute (function *)
+ {
+ initialize_uninitialized_regs ();
+ return 0;
+ }
-struct rtl_opt_pass pass_initialize_regs =
+}; // class pass_initialize_regs
+
+} // anon namespace
+
+rtl_opt_pass *
+make_pass_initialize_regs (gcc::context *ctxt)
{
- {
- RTL_PASS,
- "init-regs", /* name */
- OPTGROUP_NONE, /* optinfo_flags */
- gate_initialize_regs, /* gate */
- rest_of_handle_initialize_regs, /* execute */
- NULL, /* sub */
- NULL, /* next */
- 0, /* static_pass_number */
- TV_NONE, /* tv_id */
- 0, /* properties_required */
- 0, /* properties_provided */
- 0, /* properties_destroyed */
- 0, /* todo_flags_start */
- TODO_df_finish /* todo_flags_finish */
- }
-};
+ return new pass_initialize_regs (ctxt);
+}