Branch data Line data Source code
1 : : /* Initialization of uninitialized regs.
2 : : Copyright (C) 2007-2025 Free Software Foundation, Inc.
3 : :
4 : : This file is part of GCC.
5 : :
6 : : GCC is free software; you can redistribute it and/or modify it under
7 : : the terms of the GNU General Public License as published by the Free
8 : : Software Foundation; either version 3, or (at your option) any later
9 : : version.
10 : :
11 : : GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12 : : WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 : : FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 : : for more details.
15 : :
16 : : You should have received a copy of the GNU General Public License
17 : : along with GCC; see the file COPYING3. If not see
18 : : <http://www.gnu.org/licenses/>. */
19 : :
20 : : #include "config.h"
21 : : #include "system.h"
22 : : #include "coretypes.h"
23 : : #include "backend.h"
24 : : #include "rtl.h"
25 : : #include "tree.h"
26 : : #include "df.h"
27 : : #include "memmodel.h"
28 : : #include "emit-rtl.h"
29 : : #include "expr.h"
30 : : #include "tree-pass.h"
31 : :
32 : : /* Check all of the uses of pseudo variables. If any use that is MUST
33 : : uninitialized, add a store of 0 immediately before it. For
34 : : subregs, this makes combine happy. For full word regs, this makes
35 : : other optimizations, like the register allocator and the reg-stack
36 : : happy as well as papers over some problems on the arm and other
37 : : processors where certain isa constraints cannot be handled by gcc.
38 : : These are of the form where two operands to an insn my not be the
39 : : same. The ra will only make them the same if they do not
40 : : interfere, and this can only happen if one is not initialized.
41 : :
42 : : There is also the unfortunate consequence that this may mask some
43 : : buggy programs where people forget to initialize stack variable.
44 : : Any programmer with half a brain would look at the uninitialized
45 : : variable warnings. */
46 : :
47 : : static void
48 : 1023797 : initialize_uninitialized_regs (void)
49 : : {
50 : 1023797 : basic_block bb;
51 : 1023797 : auto_bitmap already_genned;
52 : :
53 : 1023797 : if (optimize == 1)
54 : : {
55 : 75882 : df_live_add_problem ();
56 : 75882 : df_live_set_all_dirty ();
57 : : }
58 : :
59 : 1023797 : df_analyze ();
60 : :
61 : 11305043 : FOR_EACH_BB_FN (bb, cfun)
62 : : {
63 : 10281246 : rtx_insn *insn;
64 : 10281246 : bitmap lr = DF_LR_IN (bb);
65 : 10281246 : bitmap ur = DF_LIVE_IN (bb);
66 : 10281246 : bitmap_clear (already_genned);
67 : :
68 : 132502183 : FOR_BB_INSNS (bb, insn)
69 : : {
70 : 122220937 : df_ref use;
71 : 122220937 : if (!NONDEBUG_INSN_P (insn))
72 : 64055857 : continue;
73 : :
74 : 131257326 : FOR_EACH_INSN_USE (use, insn)
75 : : {
76 : 73092246 : unsigned int regno = DF_REF_REGNO (use);
77 : :
78 : : /* Only do this for the pseudos. */
79 : 73092246 : if (regno < FIRST_PSEUDO_REGISTER)
80 : 35000126 : continue;
81 : :
82 : : /* Ignore pseudo PIC register. */
83 : 38393882 : if (pic_offset_table_rtx
84 : 38092120 : && regno == REGNO (pic_offset_table_rtx))
85 : 301762 : continue;
86 : :
87 : : /* Do not generate multiple moves for the same regno.
88 : : This is common for sequences of subreg operations.
89 : : They would be deleted during combine but there is no
90 : : reason to churn the system. */
91 : 37790358 : if (bitmap_bit_p (already_genned, regno))
92 : 319285 : continue;
93 : :
94 : : /* A use is MUST uninitialized if it reaches the top of
95 : : the block from the inside of the block (the lr test)
96 : : and no def for it reaches the top of the block from
97 : : outside of the block (the ur test). */
98 : 37471073 : if (bitmap_bit_p (lr, regno)
99 : 37471073 : && (!bitmap_bit_p (ur, regno)))
100 : : {
101 : 184816 : rtx_insn *move_insn;
102 : 184816 : rtx reg = DF_REF_REAL_REG (use);
103 : :
104 : 184816 : bitmap_set_bit (already_genned, regno);
105 : :
106 : 184816 : start_sequence ();
107 : 184816 : emit_clobber (reg);
108 : : /* PR98872: Only emit an initialization if MODE has a
109 : : CONST0_RTX defined. */
110 : 184816 : if (CONST0_RTX (GET_MODE (reg)))
111 : 184816 : emit_move_insn (reg, CONST0_RTX (GET_MODE (reg)));
112 : 184816 : move_insn = end_sequence ();
113 : 184816 : emit_insn_before (move_insn, insn);
114 : 184816 : if (dump_file)
115 : 0 : fprintf (dump_file,
116 : : "adding initialization in %s of reg %d at in block %d for insn %d.\n",
117 : : current_function_name (), regno, bb->index,
118 : 0 : INSN_UID (insn));
119 : : }
120 : : }
121 : : }
122 : : }
123 : :
124 : 1023797 : if (optimize == 1)
125 : : {
126 : 75882 : if (dump_file)
127 : 8 : df_dump (dump_file);
128 : 75882 : df_remove_problem (df_live);
129 : : }
130 : 1023797 : }
131 : :
132 : : namespace {
133 : :
134 : : const pass_data pass_data_initialize_regs =
135 : : {
136 : : RTL_PASS, /* type */
137 : : "init-regs", /* name */
138 : : OPTGROUP_NONE, /* optinfo_flags */
139 : : TV_NONE, /* tv_id */
140 : : 0, /* properties_required */
141 : : 0, /* properties_provided */
142 : : 0, /* properties_destroyed */
143 : : 0, /* todo_flags_start */
144 : : TODO_df_finish, /* todo_flags_finish */
145 : : };
146 : :
147 : : class pass_initialize_regs : public rtl_opt_pass
148 : : {
149 : : public:
150 : 285081 : pass_initialize_regs (gcc::context *ctxt)
151 : 570162 : : rtl_opt_pass (pass_data_initialize_regs, ctxt)
152 : : {}
153 : :
154 : : /* opt_pass methods: */
155 : 1449863 : bool gate (function *) final override { return optimize > 0; }
156 : 1023797 : unsigned int execute (function *) final override
157 : : {
158 : 1023797 : initialize_uninitialized_regs ();
159 : 1023797 : return 0;
160 : : }
161 : :
162 : : }; // class pass_initialize_regs
163 : :
164 : : } // anon namespace
165 : :
166 : : rtl_opt_pass *
167 : 285081 : make_pass_initialize_regs (gcc::context *ctxt)
168 : : {
169 : 285081 : return new pass_initialize_regs (ctxt);
170 : : }
|