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 : 1008563 : initialize_uninitialized_regs (void)
49 : : {
50 : 1008563 : basic_block bb;
51 : 1008563 : auto_bitmap already_genned;
52 : :
53 : 1008563 : if (optimize == 1)
54 : : {
55 : 75525 : df_live_add_problem ();
56 : 75525 : df_live_set_all_dirty ();
57 : : }
58 : :
59 : 1008563 : df_analyze ();
60 : :
61 : 10771881 : FOR_EACH_BB_FN (bb, cfun)
62 : : {
63 : 9763318 : rtx_insn *insn;
64 : 9763318 : bitmap lr = DF_LR_IN (bb);
65 : 9763318 : bitmap ur = DF_LIVE_IN (bb);
66 : 9763318 : bitmap_clear (already_genned);
67 : :
68 : 123009791 : FOR_BB_INSNS (bb, insn)
69 : : {
70 : 113246473 : df_ref use;
71 : 113246473 : if (!NONDEBUG_INSN_P (insn))
72 : 57589472 : continue;
73 : :
74 : 125624505 : FOR_EACH_INSN_USE (use, insn)
75 : : {
76 : 69967504 : unsigned int regno = DF_REF_REGNO (use);
77 : :
78 : : /* Only do this for the pseudos. */
79 : 69967504 : if (regno < FIRST_PSEUDO_REGISTER)
80 : 33735057 : continue;
81 : :
82 : : /* Ignore pseudo PIC register. */
83 : 36534029 : if (pic_offset_table_rtx
84 : 36232447 : && regno == REGNO (pic_offset_table_rtx))
85 : 301582 : 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 : 35930865 : if (bitmap_bit_p (already_genned, regno))
92 : 324602 : 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 : 35606263 : if (bitmap_bit_p (lr, regno)
99 : 35606263 : && (!bitmap_bit_p (ur, regno)))
100 : : {
101 : 183660 : rtx_insn *move_insn;
102 : 183660 : rtx reg = DF_REF_REAL_REG (use);
103 : :
104 : 183660 : bitmap_set_bit (already_genned, regno);
105 : :
106 : 183660 : start_sequence ();
107 : 183660 : emit_clobber (reg);
108 : : /* PR98872: Only emit an initialization if MODE has a
109 : : CONST0_RTX defined. */
110 : 183660 : if (CONST0_RTX (GET_MODE (reg)))
111 : 183660 : emit_move_insn (reg, CONST0_RTX (GET_MODE (reg)));
112 : 183660 : move_insn = get_insns ();
113 : 183660 : end_sequence ();
114 : 183660 : emit_insn_before (move_insn, insn);
115 : 183660 : if (dump_file)
116 : 0 : fprintf (dump_file,
117 : : "adding initialization in %s of reg %d at in block %d for insn %d.\n",
118 : : current_function_name (), regno, bb->index,
119 : 0 : INSN_UID (insn));
120 : : }
121 : : }
122 : : }
123 : : }
124 : :
125 : 1008563 : if (optimize == 1)
126 : : {
127 : 75525 : if (dump_file)
128 : 8 : df_dump (dump_file);
129 : 75525 : df_remove_problem (df_live);
130 : : }
131 : 1008563 : }
132 : :
133 : : namespace {
134 : :
135 : : const pass_data pass_data_initialize_regs =
136 : : {
137 : : RTL_PASS, /* type */
138 : : "init-regs", /* name */
139 : : OPTGROUP_NONE, /* optinfo_flags */
140 : : TV_NONE, /* tv_id */
141 : : 0, /* properties_required */
142 : : 0, /* properties_provided */
143 : : 0, /* properties_destroyed */
144 : : 0, /* todo_flags_start */
145 : : TODO_df_finish, /* todo_flags_finish */
146 : : };
147 : :
148 : : class pass_initialize_regs : public rtl_opt_pass
149 : : {
150 : : public:
151 : 283157 : pass_initialize_regs (gcc::context *ctxt)
152 : 566314 : : rtl_opt_pass (pass_data_initialize_regs, ctxt)
153 : : {}
154 : :
155 : : /* opt_pass methods: */
156 : 1435849 : bool gate (function *) final override { return optimize > 0; }
157 : 1008563 : unsigned int execute (function *) final override
158 : : {
159 : 1008563 : initialize_uninitialized_regs ();
160 : 1008563 : return 0;
161 : : }
162 : :
163 : : }; // class pass_initialize_regs
164 : :
165 : : } // anon namespace
166 : :
167 : : rtl_opt_pass *
168 : 283157 : make_pass_initialize_regs (gcc::context *ctxt)
169 : : {
170 : 283157 : return new pass_initialize_regs (ctxt);
171 : : }
|