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