Mercurial > hg > CbC > CbC_gcc
comparison gcc/init-regs.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | 77e2b8dfacca |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 /* Initialization of uninitialized regs. | 1 /* Initialization of uninitialized regs. |
2 Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc. | 2 Copyright (C) 2007-2017 Free Software Foundation, Inc. |
3 | 3 |
4 This file is part of GCC. | 4 This file is part of GCC. |
5 | 5 |
6 GCC is free software; you can redistribute it and/or modify it under | 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 | 7 the terms of the GNU General Public License as published by the Free |
18 <http://www.gnu.org/licenses/>. */ | 18 <http://www.gnu.org/licenses/>. */ |
19 | 19 |
20 #include "config.h" | 20 #include "config.h" |
21 #include "system.h" | 21 #include "system.h" |
22 #include "coretypes.h" | 22 #include "coretypes.h" |
23 #include "tm.h" | 23 #include "backend.h" |
24 #include "rtl.h" | |
24 #include "tree.h" | 25 #include "tree.h" |
25 #include "rtl.h" | 26 #include "df.h" |
26 #include "regs.h" | 27 #include "memmodel.h" |
28 #include "emit-rtl.h" | |
27 #include "expr.h" | 29 #include "expr.h" |
28 #include "tree-pass.h" | 30 #include "tree-pass.h" |
29 #include "basic-block.h" | |
30 #include "flags.h" | |
31 #include "df.h" | |
32 | 31 |
33 /* Check all of the uses of pseudo variables. If any use that is MUST | 32 /* Check all of the uses of pseudo variables. If any use that is MUST |
34 uninitialized, add a store of 0 immediately before it. For | 33 uninitialized, add a store of 0 immediately before it. For |
35 subregs, this makes combine happy. For full word regs, this makes | 34 subregs, this makes combine happy. For full word regs, this makes |
36 other optimizations, like the register allocator and the reg-stack | 35 other optimizations, like the register allocator and the reg-stack |
47 | 46 |
48 static void | 47 static void |
49 initialize_uninitialized_regs (void) | 48 initialize_uninitialized_regs (void) |
50 { | 49 { |
51 basic_block bb; | 50 basic_block bb; |
52 bitmap already_genned = BITMAP_ALLOC (NULL); | 51 auto_bitmap already_genned; |
53 | 52 |
54 if (optimize == 1) | 53 if (optimize == 1) |
55 { | 54 { |
56 df_live_add_problem (); | 55 df_live_add_problem (); |
57 df_live_set_all_dirty (); | 56 df_live_set_all_dirty (); |
58 } | 57 } |
59 | 58 |
60 df_analyze (); | 59 df_analyze (); |
61 | 60 |
62 FOR_EACH_BB (bb) | 61 FOR_EACH_BB_FN (bb, cfun) |
63 { | 62 { |
64 rtx insn; | 63 rtx_insn *insn; |
65 bitmap lr = DF_LR_IN (bb); | 64 bitmap lr = DF_LR_IN (bb); |
66 bitmap ur = DF_LIVE_IN (bb); | 65 bitmap ur = DF_LIVE_IN (bb); |
67 bitmap_clear (already_genned); | 66 bitmap_clear (already_genned); |
68 | 67 |
69 FOR_BB_INSNS (bb, insn) | 68 FOR_BB_INSNS (bb, insn) |
70 { | 69 { |
71 unsigned int uid = INSN_UID (insn); | 70 df_ref use; |
72 df_ref *use_rec; | |
73 if (!NONDEBUG_INSN_P (insn)) | 71 if (!NONDEBUG_INSN_P (insn)) |
74 continue; | 72 continue; |
75 | 73 |
76 for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++) | 74 FOR_EACH_INSN_USE (use, insn) |
77 { | 75 { |
78 df_ref use = *use_rec; | |
79 unsigned int regno = DF_REF_REGNO (use); | 76 unsigned int regno = DF_REF_REGNO (use); |
80 | 77 |
81 /* Only do this for the pseudos. */ | 78 /* Only do this for the pseudos. */ |
82 if (regno < FIRST_PSEUDO_REGISTER) | 79 if (regno < FIRST_PSEUDO_REGISTER) |
80 continue; | |
81 | |
82 /* Ignore pseudo PIC register. */ | |
83 if (pic_offset_table_rtx | |
84 && regno == REGNO (pic_offset_table_rtx)) | |
83 continue; | 85 continue; |
84 | 86 |
85 /* Do not generate multiple moves for the same regno. | 87 /* Do not generate multiple moves for the same regno. |
86 This is common for sequences of subreg operations. | 88 This is common for sequences of subreg operations. |
87 They would be deleted during combine but there is no | 89 They would be deleted during combine but there is no |
94 and no def for it reaches the top of the block from | 96 and no def for it reaches the top of the block from |
95 outside of the block (the ur test). */ | 97 outside of the block (the ur test). */ |
96 if (bitmap_bit_p (lr, regno) | 98 if (bitmap_bit_p (lr, regno) |
97 && (!bitmap_bit_p (ur, regno))) | 99 && (!bitmap_bit_p (ur, regno))) |
98 { | 100 { |
99 rtx move_insn; | 101 rtx_insn *move_insn; |
100 rtx reg = DF_REF_REAL_REG (use); | 102 rtx reg = DF_REF_REAL_REG (use); |
101 | 103 |
102 bitmap_set_bit (already_genned, regno); | 104 bitmap_set_bit (already_genned, regno); |
103 | 105 |
104 start_sequence (); | 106 start_sequence (); |
107 emit_clobber (reg); | |
105 emit_move_insn (reg, CONST0_RTX (GET_MODE (reg))); | 108 emit_move_insn (reg, CONST0_RTX (GET_MODE (reg))); |
106 move_insn = get_insns (); | 109 move_insn = get_insns (); |
107 end_sequence (); | 110 end_sequence (); |
108 emit_insn_before (move_insn, insn); | 111 emit_insn_before (move_insn, insn); |
109 if (dump_file) | 112 if (dump_file) |
110 fprintf (dump_file, | 113 fprintf (dump_file, |
111 "adding initialization in %s of reg %d at in block %d for insn %d.\n", | 114 "adding initialization in %s of reg %d at in block %d for insn %d.\n", |
112 current_function_name (), regno, bb->index, uid); | 115 current_function_name (), regno, bb->index, |
116 INSN_UID (insn)); | |
113 } | 117 } |
114 } | 118 } |
115 } | 119 } |
116 } | 120 } |
117 | 121 |
119 { | 123 { |
120 if (dump_file) | 124 if (dump_file) |
121 df_dump (dump_file); | 125 df_dump (dump_file); |
122 df_remove_problem (df_live); | 126 df_remove_problem (df_live); |
123 } | 127 } |
124 | |
125 BITMAP_FREE (already_genned); | |
126 } | 128 } |
127 | 129 |
128 static bool | 130 namespace { |
129 gate_initialize_regs (void) | 131 |
132 const pass_data pass_data_initialize_regs = | |
130 { | 133 { |
131 return optimize > 0; | 134 RTL_PASS, /* type */ |
135 "init-regs", /* name */ | |
136 OPTGROUP_NONE, /* optinfo_flags */ | |
137 TV_NONE, /* tv_id */ | |
138 0, /* properties_required */ | |
139 0, /* properties_provided */ | |
140 0, /* properties_destroyed */ | |
141 0, /* todo_flags_start */ | |
142 TODO_df_finish, /* todo_flags_finish */ | |
143 }; | |
144 | |
145 class pass_initialize_regs : public rtl_opt_pass | |
146 { | |
147 public: | |
148 pass_initialize_regs (gcc::context *ctxt) | |
149 : rtl_opt_pass (pass_data_initialize_regs, ctxt) | |
150 {} | |
151 | |
152 /* opt_pass methods: */ | |
153 virtual bool gate (function *) { return optimize > 0; } | |
154 virtual unsigned int execute (function *) | |
155 { | |
156 initialize_uninitialized_regs (); | |
157 return 0; | |
158 } | |
159 | |
160 }; // class pass_initialize_regs | |
161 | |
162 } // anon namespace | |
163 | |
164 rtl_opt_pass * | |
165 make_pass_initialize_regs (gcc::context *ctxt) | |
166 { | |
167 return new pass_initialize_regs (ctxt); | |
132 } | 168 } |
133 | |
134 static unsigned int | |
135 rest_of_handle_initialize_regs (void) | |
136 { | |
137 initialize_uninitialized_regs (); | |
138 return 0; | |
139 } | |
140 | |
141 struct rtl_opt_pass pass_initialize_regs = | |
142 { | |
143 { | |
144 RTL_PASS, | |
145 "init-regs", /* name */ | |
146 gate_initialize_regs, /* gate */ | |
147 rest_of_handle_initialize_regs, /* execute */ | |
148 NULL, /* sub */ | |
149 NULL, /* next */ | |
150 0, /* static_pass_number */ | |
151 TV_NONE, /* tv_id */ | |
152 0, /* properties_required */ | |
153 0, /* properties_provided */ | |
154 0, /* properties_destroyed */ | |
155 0, /* todo_flags_start */ | |
156 TODO_dump_func | | |
157 TODO_df_finish /* todo_flags_finish */ | |
158 } | |
159 }; |