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