annotate gcc/gimple-low.c @ 118:fd00160c1b76

ifdef TARGET_64BIT
author mir3636
date Tue, 27 Feb 2018 15:01:35 +0900
parents 04ced10e8804
children 84e7813d76e9
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 /* GIMPLE lowering pass. Converts High GIMPLE into Low GIMPLE.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
2
111
kono
parents: 67
diff changeset
3 Copyright (C) 2003-2017 Free Software Foundation, Inc.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5 This file is part of GCC.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 GCC is free software; you can redistribute it and/or modify it under
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 the terms of the GNU General Public License as published by the Free
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 Software Foundation; either version 3, or (at your option) any later
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10 version.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15 for more details.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 You should have received a copy of the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 along with GCC; see the file COPYING3. If not see
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19 <http://www.gnu.org/licenses/>. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 #include "config.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 #include "system.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
23 #include "coretypes.h"
111
kono
parents: 67
diff changeset
24 #include "backend.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 #include "tree.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 #include "gimple.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 #include "tree-pass.h"
111
kono
parents: 67
diff changeset
28 #include "fold-const.h"
kono
parents: 67
diff changeset
29 #include "tree-nested.h"
kono
parents: 67
diff changeset
30 #include "calls.h"
kono
parents: 67
diff changeset
31 #include "gimple-iterator.h"
kono
parents: 67
diff changeset
32 #include "gimple-low.h"
kono
parents: 67
diff changeset
33 #include "predict.h"
kono
parents: 67
diff changeset
34 #include "gimple-predict.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
35
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 /* The differences between High GIMPLE and Low GIMPLE are the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
37 following:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
38
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
39 1- Lexical scopes are removed (i.e., GIMPLE_BIND disappears).
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
40
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 2- GIMPLE_TRY and GIMPLE_CATCH are converted to abnormal control
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
42 flow and exception regions are built as an on-the-side region
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
43 hierarchy (See tree-eh.c:lower_eh_constructs).
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
44
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 3- Multiple identical return statements are grouped into a single
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
46 return and gotos to the unique return site. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
47
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
48 /* Match a return statement with a label. During lowering, we identify
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
49 identical return statements and replace duplicates with a jump to
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 the corresponding label. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
51 struct return_statements_t
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
53 tree label;
111
kono
parents: 67
diff changeset
54 greturn *stmt;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
55 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
56 typedef struct return_statements_t return_statements_t;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
57
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
58
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
59 struct lower_data
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
60 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
61 /* Block the current statement belongs to. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
62 tree block;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
63
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
64 /* A vector of label and return statements to be moved to the end
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
65 of the function. */
111
kono
parents: 67
diff changeset
66 vec<return_statements_t> return_statements;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
67
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
68 /* True if the current statement cannot fall through. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
69 bool cannot_fallthru;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
70 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
71
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
72 static void lower_stmt (gimple_stmt_iterator *, struct lower_data *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
73 static void lower_gimple_bind (gimple_stmt_iterator *, struct lower_data *);
111
kono
parents: 67
diff changeset
74 static void lower_try_catch (gimple_stmt_iterator *, struct lower_data *);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
75 static void lower_gimple_return (gimple_stmt_iterator *, struct lower_data *);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
76 static void lower_builtin_setjmp (gimple_stmt_iterator *);
111
kono
parents: 67
diff changeset
77 static void lower_builtin_posix_memalign (gimple_stmt_iterator *);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
78
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
79
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
80 /* Lower the body of current_function_decl from High GIMPLE into Low
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
81 GIMPLE. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
82
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
83 static unsigned int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
84 lower_function_body (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
85 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
86 struct lower_data data;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
87 gimple_seq body = gimple_body (current_function_decl);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
88 gimple_seq lowered_body;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
89 gimple_stmt_iterator i;
111
kono
parents: 67
diff changeset
90 gimple *bind;
kono
parents: 67
diff changeset
91 gimple *x;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
92
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 /* The gimplifier should've left a body of exactly one statement,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
94 namely a GIMPLE_BIND. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
95 gcc_assert (gimple_seq_first (body) == gimple_seq_last (body)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
96 && gimple_code (gimple_seq_first_stmt (body)) == GIMPLE_BIND);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
97
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 memset (&data, 0, sizeof (data));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
99 data.block = DECL_INITIAL (current_function_decl);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
100 BLOCK_SUBBLOCKS (data.block) = NULL_TREE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
101 BLOCK_CHAIN (data.block) = NULL_TREE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
102 TREE_ASM_WRITTEN (data.block) = 1;
111
kono
parents: 67
diff changeset
103 data.return_statements.create (8);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
104
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
105 bind = gimple_seq_first_stmt (body);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
106 lowered_body = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
107 gimple_seq_add_stmt (&lowered_body, bind);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 i = gsi_start (lowered_body);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
109 lower_gimple_bind (&i, &data);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
110
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
111 i = gsi_last (lowered_body);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
112
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
113 /* If the function falls off the end, we need a null return statement.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
114 If we've already got one in the return_statements vector, we don't
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
115 need to do anything special. Otherwise build one by hand. */
111
kono
parents: 67
diff changeset
116 bool may_fallthru = gimple_seq_may_fallthru (lowered_body);
kono
parents: 67
diff changeset
117 if (may_fallthru
kono
parents: 67
diff changeset
118 && (data.return_statements.is_empty ()
kono
parents: 67
diff changeset
119 || (gimple_return_retval (data.return_statements.last().stmt)
kono
parents: 67
diff changeset
120 != NULL)))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
121 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
122 x = gimple_build_return (NULL);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
123 gimple_set_location (x, cfun->function_end_locus);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
124 gimple_set_block (x, DECL_INITIAL (current_function_decl));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
125 gsi_insert_after (&i, x, GSI_CONTINUE_LINKING);
111
kono
parents: 67
diff changeset
126 may_fallthru = false;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
127 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
128
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
129 /* If we lowered any return statements, emit the representative
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
130 at the end of the function. */
111
kono
parents: 67
diff changeset
131 while (!data.return_statements.is_empty ())
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
132 {
111
kono
parents: 67
diff changeset
133 return_statements_t t = data.return_statements.pop ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
134 x = gimple_build_label (t.label);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
135 gsi_insert_after (&i, x, GSI_CONTINUE_LINKING);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
136 gsi_insert_after (&i, t.stmt, GSI_CONTINUE_LINKING);
111
kono
parents: 67
diff changeset
137 if (may_fallthru)
kono
parents: 67
diff changeset
138 {
kono
parents: 67
diff changeset
139 /* Remove the line number from the representative return statement.
kono
parents: 67
diff changeset
140 It now fills in for the fallthru too. Failure to remove this
kono
parents: 67
diff changeset
141 will result in incorrect results for coverage analysis. */
kono
parents: 67
diff changeset
142 gimple_set_location (t.stmt, UNKNOWN_LOCATION);
kono
parents: 67
diff changeset
143 may_fallthru = false;
kono
parents: 67
diff changeset
144 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
145 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
146
111
kono
parents: 67
diff changeset
147 /* Once the old body has been lowered, replace it with the new
kono
parents: 67
diff changeset
148 lowered sequence. */
kono
parents: 67
diff changeset
149 gimple_set_body (current_function_decl, lowered_body);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
150
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
151 gcc_assert (data.block == DECL_INITIAL (current_function_decl));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
152 BLOCK_SUBBLOCKS (data.block)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
153 = blocks_nreverse (BLOCK_SUBBLOCKS (data.block));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
154
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
155 clear_block_marks (data.block);
111
kono
parents: 67
diff changeset
156 data.return_statements.release ();
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
157 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
158 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
159
111
kono
parents: 67
diff changeset
160 namespace {
kono
parents: 67
diff changeset
161
kono
parents: 67
diff changeset
162 const pass_data pass_data_lower_cf =
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
163 {
111
kono
parents: 67
diff changeset
164 GIMPLE_PASS, /* type */
kono
parents: 67
diff changeset
165 "lower", /* name */
kono
parents: 67
diff changeset
166 OPTGROUP_NONE, /* optinfo_flags */
kono
parents: 67
diff changeset
167 TV_NONE, /* tv_id */
kono
parents: 67
diff changeset
168 PROP_gimple_any, /* properties_required */
kono
parents: 67
diff changeset
169 PROP_gimple_lcf, /* properties_provided */
kono
parents: 67
diff changeset
170 0, /* properties_destroyed */
kono
parents: 67
diff changeset
171 0, /* todo_flags_start */
kono
parents: 67
diff changeset
172 0, /* todo_flags_finish */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
173 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
174
111
kono
parents: 67
diff changeset
175 class pass_lower_cf : public gimple_opt_pass
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
176 {
111
kono
parents: 67
diff changeset
177 public:
kono
parents: 67
diff changeset
178 pass_lower_cf (gcc::context *ctxt)
kono
parents: 67
diff changeset
179 : gimple_opt_pass (pass_data_lower_cf, ctxt)
kono
parents: 67
diff changeset
180 {}
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
181
111
kono
parents: 67
diff changeset
182 /* opt_pass methods: */
kono
parents: 67
diff changeset
183 virtual unsigned int execute (function *) { return lower_function_body (); }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
184
111
kono
parents: 67
diff changeset
185 }; // class pass_lower_cf
kono
parents: 67
diff changeset
186
kono
parents: 67
diff changeset
187 } // anon namespace
kono
parents: 67
diff changeset
188
kono
parents: 67
diff changeset
189 gimple_opt_pass *
kono
parents: 67
diff changeset
190 make_pass_lower_cf (gcc::context *ctxt)
kono
parents: 67
diff changeset
191 {
kono
parents: 67
diff changeset
192 return new pass_lower_cf (ctxt);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
193 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
194
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
195 /* Lower sequence SEQ. Unlike gimplification the statements are not relowered
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
196 when they are changed -- if this has to be done, the lowering routine must
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
197 do it explicitly. DATA is passed through the recursion. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
198
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
199 static void
111
kono
parents: 67
diff changeset
200 lower_sequence (gimple_seq *seq, struct lower_data *data)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
201 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
202 gimple_stmt_iterator gsi;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
203
111
kono
parents: 67
diff changeset
204 for (gsi = gsi_start (*seq); !gsi_end_p (gsi); )
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
205 lower_stmt (&gsi, data);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
206 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
207
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
208
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
209 /* Lower the OpenMP directive statement pointed by GSI. DATA is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
210 passed through the recursion. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
211
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
212 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
213 lower_omp_directive (gimple_stmt_iterator *gsi, struct lower_data *data)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
214 {
111
kono
parents: 67
diff changeset
215 gimple *stmt;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
216
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
217 stmt = gsi_stmt (*gsi);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
218
111
kono
parents: 67
diff changeset
219 lower_sequence (gimple_omp_body_ptr (stmt), data);
kono
parents: 67
diff changeset
220 gsi_insert_seq_after (gsi, gimple_omp_body (stmt), GSI_CONTINUE_LINKING);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
221 gimple_omp_set_body (stmt, NULL);
111
kono
parents: 67
diff changeset
222 gsi_next (gsi);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
223 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
224
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
225
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
226 /* Lower statement GSI. DATA is passed through the recursion. We try to
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
227 track the fallthruness of statements and get rid of unreachable return
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
228 statements in order to prevent the EH lowering pass from adding useless
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
229 edges that can cause bogus warnings to be issued later; this guess need
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
230 not be 100% accurate, simply be conservative and reset cannot_fallthru
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
231 to false if we don't know. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
232
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
233 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
234 lower_stmt (gimple_stmt_iterator *gsi, struct lower_data *data)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
235 {
111
kono
parents: 67
diff changeset
236 gimple *stmt = gsi_stmt (*gsi);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
237
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
238 gimple_set_block (stmt, data->block);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
239
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
240 switch (gimple_code (stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
241 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
242 case GIMPLE_BIND:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
243 lower_gimple_bind (gsi, data);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
244 /* Propagate fallthruness. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
245 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
246
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
247 case GIMPLE_COND:
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
248 case GIMPLE_GOTO:
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
249 case GIMPLE_SWITCH:
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
250 data->cannot_fallthru = true;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
251 gsi_next (gsi);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
252 return;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
253
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
254 case GIMPLE_RETURN:
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
255 if (data->cannot_fallthru)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
256 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
257 gsi_remove (gsi, false);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
258 /* Propagate fallthruness. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
259 }
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
260 else
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
261 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
262 lower_gimple_return (gsi, data);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
263 data->cannot_fallthru = true;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
264 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
265 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
266
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
267 case GIMPLE_TRY:
111
kono
parents: 67
diff changeset
268 if (gimple_try_kind (stmt) == GIMPLE_TRY_CATCH)
kono
parents: 67
diff changeset
269 lower_try_catch (gsi, data);
kono
parents: 67
diff changeset
270 else
kono
parents: 67
diff changeset
271 {
kono
parents: 67
diff changeset
272 /* It must be a GIMPLE_TRY_FINALLY. */
kono
parents: 67
diff changeset
273 bool cannot_fallthru;
kono
parents: 67
diff changeset
274 lower_sequence (gimple_try_eval_ptr (stmt), data);
kono
parents: 67
diff changeset
275 cannot_fallthru = data->cannot_fallthru;
kono
parents: 67
diff changeset
276
kono
parents: 67
diff changeset
277 /* The finally clause is always executed after the try clause,
kono
parents: 67
diff changeset
278 so if it does not fall through, then the try-finally will not
kono
parents: 67
diff changeset
279 fall through. Otherwise, if the try clause does not fall
kono
parents: 67
diff changeset
280 through, then when the finally clause falls through it will
kono
parents: 67
diff changeset
281 resume execution wherever the try clause was going. So the
kono
parents: 67
diff changeset
282 whole try-finally will only fall through if both the try
kono
parents: 67
diff changeset
283 clause and the finally clause fall through. */
kono
parents: 67
diff changeset
284 data->cannot_fallthru = false;
kono
parents: 67
diff changeset
285 lower_sequence (gimple_try_cleanup_ptr (stmt), data);
kono
parents: 67
diff changeset
286 data->cannot_fallthru |= cannot_fallthru;
kono
parents: 67
diff changeset
287 gsi_next (gsi);
kono
parents: 67
diff changeset
288 }
kono
parents: 67
diff changeset
289 return;
kono
parents: 67
diff changeset
290
kono
parents: 67
diff changeset
291 case GIMPLE_EH_ELSE:
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
292 {
111
kono
parents: 67
diff changeset
293 geh_else *eh_else_stmt = as_a <geh_else *> (stmt);
kono
parents: 67
diff changeset
294 lower_sequence (gimple_eh_else_n_body_ptr (eh_else_stmt), data);
kono
parents: 67
diff changeset
295 lower_sequence (gimple_eh_else_e_body_ptr (eh_else_stmt), data);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
296 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
297 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
298
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
299 case GIMPLE_NOP:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
300 case GIMPLE_ASM:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
301 case GIMPLE_ASSIGN:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
302 case GIMPLE_PREDICT:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
303 case GIMPLE_LABEL:
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
304 case GIMPLE_EH_MUST_NOT_THROW:
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
305 case GIMPLE_OMP_FOR:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
306 case GIMPLE_OMP_SECTIONS:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
307 case GIMPLE_OMP_SECTIONS_SWITCH:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
308 case GIMPLE_OMP_SECTION:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
309 case GIMPLE_OMP_SINGLE:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
310 case GIMPLE_OMP_MASTER:
111
kono
parents: 67
diff changeset
311 case GIMPLE_OMP_TASKGROUP:
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
312 case GIMPLE_OMP_ORDERED:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
313 case GIMPLE_OMP_CRITICAL:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
314 case GIMPLE_OMP_RETURN:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
315 case GIMPLE_OMP_ATOMIC_LOAD:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
316 case GIMPLE_OMP_ATOMIC_STORE:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
317 case GIMPLE_OMP_CONTINUE:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
318 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
319
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
320 case GIMPLE_CALL:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
321 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
322 tree decl = gimple_call_fndecl (stmt);
111
kono
parents: 67
diff changeset
323 unsigned i;
kono
parents: 67
diff changeset
324
kono
parents: 67
diff changeset
325 for (i = 0; i < gimple_call_num_args (stmt); i++)
kono
parents: 67
diff changeset
326 {
kono
parents: 67
diff changeset
327 tree arg = gimple_call_arg (stmt, i);
kono
parents: 67
diff changeset
328 if (EXPR_P (arg))
kono
parents: 67
diff changeset
329 TREE_SET_BLOCK (arg, data->block);
kono
parents: 67
diff changeset
330 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
331
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
332 if (decl
111
kono
parents: 67
diff changeset
333 && DECL_BUILT_IN_CLASS (decl) == BUILT_IN_NORMAL)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
334 {
111
kono
parents: 67
diff changeset
335 if (DECL_FUNCTION_CODE (decl) == BUILT_IN_SETJMP)
kono
parents: 67
diff changeset
336 {
kono
parents: 67
diff changeset
337 lower_builtin_setjmp (gsi);
kono
parents: 67
diff changeset
338 data->cannot_fallthru = false;
kono
parents: 67
diff changeset
339 return;
kono
parents: 67
diff changeset
340 }
kono
parents: 67
diff changeset
341 else if (DECL_FUNCTION_CODE (decl) == BUILT_IN_POSIX_MEMALIGN
kono
parents: 67
diff changeset
342 && flag_tree_bit_ccp
kono
parents: 67
diff changeset
343 && gimple_builtin_call_types_compatible_p (stmt, decl))
kono
parents: 67
diff changeset
344 {
kono
parents: 67
diff changeset
345 lower_builtin_posix_memalign (gsi);
kono
parents: 67
diff changeset
346 return;
kono
parents: 67
diff changeset
347 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
348 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
349
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
350 if (decl && (flags_from_decl_or_type (decl) & ECF_NORETURN))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
351 {
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
352 data->cannot_fallthru = true;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
353 gsi_next (gsi);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
354 return;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
355 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
356 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
357 break;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
358
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
359 case GIMPLE_OMP_PARALLEL:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
360 case GIMPLE_OMP_TASK:
111
kono
parents: 67
diff changeset
361 case GIMPLE_OMP_TARGET:
kono
parents: 67
diff changeset
362 case GIMPLE_OMP_TEAMS:
kono
parents: 67
diff changeset
363 case GIMPLE_OMP_GRID_BODY:
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
364 data->cannot_fallthru = false;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
365 lower_omp_directive (gsi, data);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
366 data->cannot_fallthru = false;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
367 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
368
111
kono
parents: 67
diff changeset
369 case GIMPLE_TRANSACTION:
kono
parents: 67
diff changeset
370 lower_sequence (gimple_transaction_body_ptr (
kono
parents: 67
diff changeset
371 as_a <gtransaction *> (stmt)),
kono
parents: 67
diff changeset
372 data);
kono
parents: 67
diff changeset
373 break;
kono
parents: 67
diff changeset
374
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
375 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
376 gcc_unreachable ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
377 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
378
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
379 data->cannot_fallthru = false;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
380 gsi_next (gsi);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
381 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
382
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
383 /* Lower a bind_expr TSI. DATA is passed through the recursion. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
384
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
385 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
386 lower_gimple_bind (gimple_stmt_iterator *gsi, struct lower_data *data)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
387 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
388 tree old_block = data->block;
111
kono
parents: 67
diff changeset
389 gbind *stmt = as_a <gbind *> (gsi_stmt (*gsi));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
390 tree new_block = gimple_bind_block (stmt);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
391
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
392 if (new_block)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
393 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
394 if (new_block == old_block)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
395 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
396 /* The outermost block of the original function may not be the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
397 outermost statement chain of the gimplified function. So we
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
398 may see the outermost block just inside the function. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
399 gcc_assert (new_block == DECL_INITIAL (current_function_decl));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
400 new_block = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
401 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
402 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
403 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
404 /* We do not expect to handle duplicate blocks. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
405 gcc_assert (!TREE_ASM_WRITTEN (new_block));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
406 TREE_ASM_WRITTEN (new_block) = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
407
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
408 /* Block tree may get clobbered by inlining. Normally this would
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
409 be fixed in rest_of_decl_compilation using block notes, but
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
410 since we are not going to emit them, it is up to us. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
411 BLOCK_CHAIN (new_block) = BLOCK_SUBBLOCKS (old_block);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
412 BLOCK_SUBBLOCKS (old_block) = new_block;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
413 BLOCK_SUBBLOCKS (new_block) = NULL_TREE;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
414 BLOCK_SUPERCONTEXT (new_block) = old_block;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
415
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
416 data->block = new_block;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
417 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
418 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
419
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
420 record_vars (gimple_bind_vars (stmt));
111
kono
parents: 67
diff changeset
421
kono
parents: 67
diff changeset
422 /* Scrap DECL_CHAIN up to BLOCK_VARS to ease GC after we no longer
kono
parents: 67
diff changeset
423 need gimple_bind_vars. */
kono
parents: 67
diff changeset
424 tree next;
kono
parents: 67
diff changeset
425 /* BLOCK_VARS and gimple_bind_vars share a common sub-chain. Find
kono
parents: 67
diff changeset
426 it by marking all BLOCK_VARS. */
kono
parents: 67
diff changeset
427 if (gimple_bind_block (stmt))
kono
parents: 67
diff changeset
428 for (tree t = BLOCK_VARS (gimple_bind_block (stmt)); t; t = DECL_CHAIN (t))
kono
parents: 67
diff changeset
429 TREE_VISITED (t) = 1;
kono
parents: 67
diff changeset
430 for (tree var = gimple_bind_vars (stmt);
kono
parents: 67
diff changeset
431 var && ! TREE_VISITED (var); var = next)
kono
parents: 67
diff changeset
432 {
kono
parents: 67
diff changeset
433 next = DECL_CHAIN (var);
kono
parents: 67
diff changeset
434 DECL_CHAIN (var) = NULL_TREE;
kono
parents: 67
diff changeset
435 }
kono
parents: 67
diff changeset
436 /* Unmark BLOCK_VARS. */
kono
parents: 67
diff changeset
437 if (gimple_bind_block (stmt))
kono
parents: 67
diff changeset
438 for (tree t = BLOCK_VARS (gimple_bind_block (stmt)); t; t = DECL_CHAIN (t))
kono
parents: 67
diff changeset
439 TREE_VISITED (t) = 0;
kono
parents: 67
diff changeset
440
kono
parents: 67
diff changeset
441 lower_sequence (gimple_bind_body_ptr (stmt), data);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
442
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
443 if (new_block)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
444 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
445 gcc_assert (data->block == new_block);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
446
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
447 BLOCK_SUBBLOCKS (new_block)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
448 = blocks_nreverse (BLOCK_SUBBLOCKS (new_block));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
449 data->block = old_block;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
450 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
451
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
452 /* The GIMPLE_BIND no longer carries any useful information -- kill it. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
453 gsi_insert_seq_before (gsi, gimple_bind_body (stmt), GSI_SAME_STMT);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
454 gsi_remove (gsi, false);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
455 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
456
111
kono
parents: 67
diff changeset
457 /* Same as above, but for a GIMPLE_TRY_CATCH. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
458
111
kono
parents: 67
diff changeset
459 static void
kono
parents: 67
diff changeset
460 lower_try_catch (gimple_stmt_iterator *gsi, struct lower_data *data)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
461 {
111
kono
parents: 67
diff changeset
462 bool cannot_fallthru;
kono
parents: 67
diff changeset
463 gimple *stmt = gsi_stmt (*gsi);
kono
parents: 67
diff changeset
464 gimple_stmt_iterator i;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
465
111
kono
parents: 67
diff changeset
466 /* We don't handle GIMPLE_TRY_FINALLY. */
kono
parents: 67
diff changeset
467 gcc_assert (gimple_try_kind (stmt) == GIMPLE_TRY_CATCH);
kono
parents: 67
diff changeset
468
kono
parents: 67
diff changeset
469 lower_sequence (gimple_try_eval_ptr (stmt), data);
kono
parents: 67
diff changeset
470 cannot_fallthru = data->cannot_fallthru;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
471
111
kono
parents: 67
diff changeset
472 i = gsi_start (*gimple_try_cleanup_ptr (stmt));
kono
parents: 67
diff changeset
473 switch (gimple_code (gsi_stmt (i)))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
474 {
111
kono
parents: 67
diff changeset
475 case GIMPLE_CATCH:
kono
parents: 67
diff changeset
476 /* We expect to see a sequence of GIMPLE_CATCH stmts, each with a
kono
parents: 67
diff changeset
477 catch expression and a body. The whole try/catch may fall
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
478 through iff any of the catch bodies falls through. */
111
kono
parents: 67
diff changeset
479 for (; !gsi_end_p (i); gsi_next (&i))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
480 {
111
kono
parents: 67
diff changeset
481 data->cannot_fallthru = false;
kono
parents: 67
diff changeset
482 lower_sequence (gimple_catch_handler_ptr (
kono
parents: 67
diff changeset
483 as_a <gcatch *> (gsi_stmt (i))),
kono
parents: 67
diff changeset
484 data);
kono
parents: 67
diff changeset
485 if (!data->cannot_fallthru)
kono
parents: 67
diff changeset
486 cannot_fallthru = false;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
487 }
111
kono
parents: 67
diff changeset
488 break;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
489
111
kono
parents: 67
diff changeset
490 case GIMPLE_EH_FILTER:
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
491 /* The exception filter expression only matters if there is an
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
492 exception. If the exception does not match EH_FILTER_TYPES,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
493 we will execute EH_FILTER_FAILURE, and we will fall through
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
494 if that falls through. If the exception does match
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
495 EH_FILTER_TYPES, the stack unwinder will continue up the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
496 stack, so we will not fall through. We don't know whether we
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
497 will throw an exception which matches EH_FILTER_TYPES or not,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
498 so we just ignore EH_FILTER_TYPES and assume that we might
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
499 throw an exception which doesn't match. */
111
kono
parents: 67
diff changeset
500 data->cannot_fallthru = false;
kono
parents: 67
diff changeset
501 lower_sequence (gimple_eh_filter_failure_ptr (gsi_stmt (i)), data);
kono
parents: 67
diff changeset
502 if (!data->cannot_fallthru)
kono
parents: 67
diff changeset
503 cannot_fallthru = false;
kono
parents: 67
diff changeset
504 break;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
505
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
506 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
507 /* This case represents statements to be executed when an
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
508 exception occurs. Those statements are implicitly followed
111
kono
parents: 67
diff changeset
509 by a GIMPLE_RESX to resume execution after the exception. So
kono
parents: 67
diff changeset
510 in this case the try/catch never falls through. */
kono
parents: 67
diff changeset
511 data->cannot_fallthru = false;
kono
parents: 67
diff changeset
512 lower_sequence (gimple_try_cleanup_ptr (stmt), data);
kono
parents: 67
diff changeset
513 break;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
514 }
111
kono
parents: 67
diff changeset
515
kono
parents: 67
diff changeset
516 data->cannot_fallthru = cannot_fallthru;
kono
parents: 67
diff changeset
517 gsi_next (gsi);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
518 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
519
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
520
111
kono
parents: 67
diff changeset
521 /* Try to determine whether a TRY_CATCH expression can fall through.
kono
parents: 67
diff changeset
522 This is a subroutine of gimple_stmt_may_fallthru. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
523
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
524 static bool
111
kono
parents: 67
diff changeset
525 gimple_try_catch_may_fallthru (gtry *stmt)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
526 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
527 gimple_stmt_iterator i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
528
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
529 /* We don't handle GIMPLE_TRY_FINALLY. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
530 gcc_assert (gimple_try_kind (stmt) == GIMPLE_TRY_CATCH);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
531
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
532 /* If the TRY block can fall through, the whole TRY_CATCH can
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
533 fall through. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
534 if (gimple_seq_may_fallthru (gimple_try_eval (stmt)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
535 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
536
111
kono
parents: 67
diff changeset
537 i = gsi_start (*gimple_try_cleanup_ptr (stmt));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
538 switch (gimple_code (gsi_stmt (i)))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
539 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
540 case GIMPLE_CATCH:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
541 /* We expect to see a sequence of GIMPLE_CATCH stmts, each with a
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
542 catch expression and a body. The whole try/catch may fall
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
543 through iff any of the catch bodies falls through. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
544 for (; !gsi_end_p (i); gsi_next (&i))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
545 {
111
kono
parents: 67
diff changeset
546 if (gimple_seq_may_fallthru (gimple_catch_handler (
kono
parents: 67
diff changeset
547 as_a <gcatch *> (gsi_stmt (i)))))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
548 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
549 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
550 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
551
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
552 case GIMPLE_EH_FILTER:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
553 /* The exception filter expression only matters if there is an
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
554 exception. If the exception does not match EH_FILTER_TYPES,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
555 we will execute EH_FILTER_FAILURE, and we will fall through
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
556 if that falls through. If the exception does match
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
557 EH_FILTER_TYPES, the stack unwinder will continue up the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
558 stack, so we will not fall through. We don't know whether we
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
559 will throw an exception which matches EH_FILTER_TYPES or not,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
560 so we just ignore EH_FILTER_TYPES and assume that we might
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
561 throw an exception which doesn't match. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
562 return gimple_seq_may_fallthru (gimple_eh_filter_failure (gsi_stmt (i)));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
563
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
564 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
565 /* This case represents statements to be executed when an
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
566 exception occurs. Those statements are implicitly followed
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
567 by a GIMPLE_RESX to resume execution after the exception. So
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
568 in this case the try/catch never falls through. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
569 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
570 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
571 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
572
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
573
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
574 /* Try to determine if we can continue executing the statement
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
575 immediately following STMT. This guess need not be 100% accurate;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
576 simply be conservative and return true if we don't know. This is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
577 used only to avoid stupidly generating extra code. If we're wrong,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
578 we'll just delete the extra code later. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
579
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
580 bool
111
kono
parents: 67
diff changeset
581 gimple_stmt_may_fallthru (gimple *stmt)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
582 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
583 if (!stmt)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
584 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
585
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
586 switch (gimple_code (stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
587 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
588 case GIMPLE_GOTO:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
589 case GIMPLE_RETURN:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
590 case GIMPLE_RESX:
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
591 /* Easy cases. If the last statement of the seq implies
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
592 control transfer, then we can't fall through. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
593 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
594
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
595 case GIMPLE_SWITCH:
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
596 /* Switch has already been lowered and represents a branch
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
597 to a selected label and hence can't fall through. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
598 return false;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
599
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
600 case GIMPLE_COND:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
601 /* GIMPLE_COND's are already lowered into a two-way branch. They
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
602 can't fall through. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
603 return false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
604
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
605 case GIMPLE_BIND:
111
kono
parents: 67
diff changeset
606 return gimple_seq_may_fallthru (
kono
parents: 67
diff changeset
607 gimple_bind_body (as_a <gbind *> (stmt)));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
608
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
609 case GIMPLE_TRY:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
610 if (gimple_try_kind (stmt) == GIMPLE_TRY_CATCH)
111
kono
parents: 67
diff changeset
611 return gimple_try_catch_may_fallthru (as_a <gtry *> (stmt));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
612
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
613 /* It must be a GIMPLE_TRY_FINALLY. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
614
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
615 /* The finally clause is always executed after the try clause,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
616 so if it does not fall through, then the try-finally will not
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
617 fall through. Otherwise, if the try clause does not fall
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
618 through, then when the finally clause falls through it will
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
619 resume execution wherever the try clause was going. So the
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
620 whole try-finally will only fall through if both the try
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
621 clause and the finally clause fall through. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
622 return (gimple_seq_may_fallthru (gimple_try_eval (stmt))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
623 && gimple_seq_may_fallthru (gimple_try_cleanup (stmt)));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
624
111
kono
parents: 67
diff changeset
625 case GIMPLE_EH_ELSE:
kono
parents: 67
diff changeset
626 {
kono
parents: 67
diff changeset
627 geh_else *eh_else_stmt = as_a <geh_else *> (stmt);
kono
parents: 67
diff changeset
628 return (gimple_seq_may_fallthru (gimple_eh_else_n_body (eh_else_stmt))
kono
parents: 67
diff changeset
629 || gimple_seq_may_fallthru (gimple_eh_else_e_body (
kono
parents: 67
diff changeset
630 eh_else_stmt)));
kono
parents: 67
diff changeset
631 }
kono
parents: 67
diff changeset
632
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
633 case GIMPLE_CALL:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
634 /* Functions that do not return do not fall through. */
111
kono
parents: 67
diff changeset
635 return !gimple_call_noreturn_p (stmt);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
636
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
637 default:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
638 return true;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
639 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
640 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
641
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
642
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
643 /* Same as gimple_stmt_may_fallthru, but for the gimple sequence SEQ. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
644
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
645 bool
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
646 gimple_seq_may_fallthru (gimple_seq seq)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
647 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
648 return gimple_stmt_may_fallthru (gimple_seq_last_stmt (seq));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
649 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
650
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
651
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
652 /* Lower a GIMPLE_RETURN GSI. DATA is passed through the recursion. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
653
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
654 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
655 lower_gimple_return (gimple_stmt_iterator *gsi, struct lower_data *data)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
656 {
111
kono
parents: 67
diff changeset
657 greturn *stmt = as_a <greturn *> (gsi_stmt (*gsi));
kono
parents: 67
diff changeset
658 gimple *t;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
659 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
660 return_statements_t tmp_rs;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
661
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
662 /* Match this up with an existing return statement that's been created. */
111
kono
parents: 67
diff changeset
663 for (i = data->return_statements.length () - 1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
664 i >= 0; i--)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
665 {
111
kono
parents: 67
diff changeset
666 tmp_rs = data->return_statements[i];
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
667
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
668 if (gimple_return_retval (stmt) == gimple_return_retval (tmp_rs.stmt))
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
669 {
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
670 /* Remove the line number from the representative return statement.
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
671 It now fills in for many such returns. Failure to remove this
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
672 will result in incorrect results for coverage analysis. */
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
673 gimple_set_location (tmp_rs.stmt, UNKNOWN_LOCATION);
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
674
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
675 goto found;
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
676 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
677 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
678
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
679 /* Not found. Create a new label and record the return statement. */
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
680 tmp_rs.label = create_artificial_label (cfun->function_end_locus);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
681 tmp_rs.stmt = stmt;
111
kono
parents: 67
diff changeset
682 data->return_statements.safe_push (tmp_rs);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
683
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
684 /* Generate a goto statement and remove the return statement. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
685 found:
111
kono
parents: 67
diff changeset
686 /* When not optimizing, make sure user returns are preserved. */
kono
parents: 67
diff changeset
687 if (!optimize && gimple_has_location (stmt))
kono
parents: 67
diff changeset
688 DECL_ARTIFICIAL (tmp_rs.label) = 0;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
689 t = gimple_build_goto (tmp_rs.label);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
690 gimple_set_location (t, gimple_location (stmt));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
691 gimple_set_block (t, gimple_block (stmt));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
692 gsi_insert_before (gsi, t, GSI_SAME_STMT);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
693 gsi_remove (gsi, false);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
694 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
695
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
696 /* Lower a __builtin_setjmp GSI.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
697
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
698 __builtin_setjmp is passed a pointer to an array of five words (not
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
699 all will be used on all machines). It operates similarly to the C
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
700 library function of the same name, but is more efficient.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
701
111
kono
parents: 67
diff changeset
702 It is lowered into 2 other builtins, namely __builtin_setjmp_setup,
kono
parents: 67
diff changeset
703 __builtin_setjmp_receiver.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
704
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
705 After full lowering, the body of the function should look like:
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
706
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
707 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
708 int D.1844;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
709 int D.2844;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
710
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
711 [...]
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
712
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
713 __builtin_setjmp_setup (&buf, &<D1847>);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
714 D.1844 = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
715 goto <D1846>;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
716 <D1847>:;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
717 __builtin_setjmp_receiver (&<D1847>);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
718 D.1844 = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
719 <D1846>:;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
720 if (D.1844 == 0) goto <D1848>; else goto <D1849>;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
721
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
722 [...]
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
723
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
724 __builtin_setjmp_setup (&buf, &<D2847>);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
725 D.2844 = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
726 goto <D2846>;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
727 <D2847>:;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
728 __builtin_setjmp_receiver (&<D2847>);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
729 D.2844 = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
730 <D2846>:;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
731 if (D.2844 == 0) goto <D2848>; else goto <D2849>;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
732
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
733 [...]
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
734
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
735 <D3850>:;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
736 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
737 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
738
111
kono
parents: 67
diff changeset
739 During cfg creation an extra per-function (or per-OpenMP region)
kono
parents: 67
diff changeset
740 block with ABNORMAL_DISPATCHER internal call will be added, unique
kono
parents: 67
diff changeset
741 destination of all the abnormal call edges and the unique source of
kono
parents: 67
diff changeset
742 all the abnormal edges to the receivers, thus keeping the complexity
kono
parents: 67
diff changeset
743 explosion localized. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
744
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
745 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
746 lower_builtin_setjmp (gimple_stmt_iterator *gsi)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
747 {
111
kono
parents: 67
diff changeset
748 gimple *stmt = gsi_stmt (*gsi);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
749 location_t loc = gimple_location (stmt);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
750 tree cont_label = create_artificial_label (loc);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
751 tree next_label = create_artificial_label (loc);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
752 tree dest, t, arg;
111
kono
parents: 67
diff changeset
753 gimple *g;
kono
parents: 67
diff changeset
754
kono
parents: 67
diff changeset
755 /* __builtin_setjmp_{setup,receiver} aren't ECF_RETURNS_TWICE and for RTL
kono
parents: 67
diff changeset
756 these builtins are modelled as non-local label jumps to the label
kono
parents: 67
diff changeset
757 that is passed to these two builtins, so pretend we have a non-local
kono
parents: 67
diff changeset
758 label during GIMPLE passes too. See PR60003. */
kono
parents: 67
diff changeset
759 cfun->has_nonlocal_label = 1;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
760
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
761 /* NEXT_LABEL is the label __builtin_longjmp will jump to. Its address is
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
762 passed to both __builtin_setjmp_setup and __builtin_setjmp_receiver. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
763 FORCED_LABEL (next_label) = 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
764
111
kono
parents: 67
diff changeset
765 tree orig_dest = dest = gimple_call_lhs (stmt);
kono
parents: 67
diff changeset
766 if (orig_dest && TREE_CODE (orig_dest) == SSA_NAME)
kono
parents: 67
diff changeset
767 dest = create_tmp_reg (TREE_TYPE (orig_dest));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
768
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
769 /* Build '__builtin_setjmp_setup (BUF, NEXT_LABEL)' and insert. */
111
kono
parents: 67
diff changeset
770 arg = build_addr (next_label);
kono
parents: 67
diff changeset
771 t = builtin_decl_implicit (BUILT_IN_SETJMP_SETUP);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
772 g = gimple_build_call (t, 2, gimple_call_arg (stmt, 0), arg);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
773 gimple_set_location (g, loc);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
774 gimple_set_block (g, gimple_block (stmt));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
775 gsi_insert_before (gsi, g, GSI_SAME_STMT);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
776
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
777 /* Build 'DEST = 0' and insert. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
778 if (dest)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
779 {
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
780 g = gimple_build_assign (dest, build_zero_cst (TREE_TYPE (dest)));
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
781 gimple_set_location (g, loc);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
782 gimple_set_block (g, gimple_block (stmt));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
783 gsi_insert_before (gsi, g, GSI_SAME_STMT);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
784 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
785
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
786 /* Build 'goto CONT_LABEL' and insert. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
787 g = gimple_build_goto (cont_label);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
788 gsi_insert_before (gsi, g, GSI_SAME_STMT);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
789
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
790 /* Build 'NEXT_LABEL:' and insert. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
791 g = gimple_build_label (next_label);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
792 gsi_insert_before (gsi, g, GSI_SAME_STMT);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
793
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
794 /* Build '__builtin_setjmp_receiver (NEXT_LABEL)' and insert. */
111
kono
parents: 67
diff changeset
795 arg = build_addr (next_label);
kono
parents: 67
diff changeset
796 t = builtin_decl_implicit (BUILT_IN_SETJMP_RECEIVER);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
797 g = gimple_build_call (t, 1, arg);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
798 gimple_set_location (g, loc);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
799 gimple_set_block (g, gimple_block (stmt));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
800 gsi_insert_before (gsi, g, GSI_SAME_STMT);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
801
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
802 /* Build 'DEST = 1' and insert. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
803 if (dest)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
804 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
805 g = gimple_build_assign (dest, fold_convert_loc (loc, TREE_TYPE (dest),
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
806 integer_one_node));
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
807 gimple_set_location (g, loc);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
808 gimple_set_block (g, gimple_block (stmt));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
809 gsi_insert_before (gsi, g, GSI_SAME_STMT);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
810 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
811
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
812 /* Build 'CONT_LABEL:' and insert. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
813 g = gimple_build_label (cont_label);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
814 gsi_insert_before (gsi, g, GSI_SAME_STMT);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
815
111
kono
parents: 67
diff changeset
816 /* Build orig_dest = dest if necessary. */
kono
parents: 67
diff changeset
817 if (dest != orig_dest)
kono
parents: 67
diff changeset
818 {
kono
parents: 67
diff changeset
819 g = gimple_build_assign (orig_dest, dest);
kono
parents: 67
diff changeset
820 gsi_insert_before (gsi, g, GSI_SAME_STMT);
kono
parents: 67
diff changeset
821 }
kono
parents: 67
diff changeset
822
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
823 /* Remove the call to __builtin_setjmp. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
824 gsi_remove (gsi, false);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
825 }
111
kono
parents: 67
diff changeset
826
kono
parents: 67
diff changeset
827 /* Lower calls to posix_memalign to
kono
parents: 67
diff changeset
828 res = posix_memalign (ptr, align, size);
kono
parents: 67
diff changeset
829 if (res == 0)
kono
parents: 67
diff changeset
830 *ptr = __builtin_assume_aligned (*ptr, align);
kono
parents: 67
diff changeset
831 or to
kono
parents: 67
diff changeset
832 void *tem;
kono
parents: 67
diff changeset
833 res = posix_memalign (&tem, align, size);
kono
parents: 67
diff changeset
834 if (res == 0)
kono
parents: 67
diff changeset
835 ptr = __builtin_assume_aligned (tem, align);
kono
parents: 67
diff changeset
836 in case the first argument was &ptr. That way we can get at the
kono
parents: 67
diff changeset
837 alignment of the heap pointer in CCP. */
kono
parents: 67
diff changeset
838
kono
parents: 67
diff changeset
839 static void
kono
parents: 67
diff changeset
840 lower_builtin_posix_memalign (gimple_stmt_iterator *gsi)
kono
parents: 67
diff changeset
841 {
kono
parents: 67
diff changeset
842 gimple *stmt, *call = gsi_stmt (*gsi);
kono
parents: 67
diff changeset
843 tree pptr = gimple_call_arg (call, 0);
kono
parents: 67
diff changeset
844 tree align = gimple_call_arg (call, 1);
kono
parents: 67
diff changeset
845 tree res = gimple_call_lhs (call);
kono
parents: 67
diff changeset
846 tree ptr = create_tmp_reg (ptr_type_node);
kono
parents: 67
diff changeset
847 if (TREE_CODE (pptr) == ADDR_EXPR)
kono
parents: 67
diff changeset
848 {
kono
parents: 67
diff changeset
849 tree tem = create_tmp_var (ptr_type_node);
kono
parents: 67
diff changeset
850 TREE_ADDRESSABLE (tem) = 1;
kono
parents: 67
diff changeset
851 gimple_call_set_arg (call, 0, build_fold_addr_expr (tem));
kono
parents: 67
diff changeset
852 stmt = gimple_build_assign (ptr, tem);
kono
parents: 67
diff changeset
853 }
kono
parents: 67
diff changeset
854 else
kono
parents: 67
diff changeset
855 stmt = gimple_build_assign (ptr,
kono
parents: 67
diff changeset
856 fold_build2 (MEM_REF, ptr_type_node, pptr,
kono
parents: 67
diff changeset
857 build_int_cst (ptr_type_node, 0)));
kono
parents: 67
diff changeset
858 if (res == NULL_TREE)
kono
parents: 67
diff changeset
859 {
kono
parents: 67
diff changeset
860 res = create_tmp_reg (integer_type_node);
kono
parents: 67
diff changeset
861 gimple_call_set_lhs (call, res);
kono
parents: 67
diff changeset
862 }
kono
parents: 67
diff changeset
863 tree align_label = create_artificial_label (UNKNOWN_LOCATION);
kono
parents: 67
diff changeset
864 tree noalign_label = create_artificial_label (UNKNOWN_LOCATION);
kono
parents: 67
diff changeset
865 gimple *cond = gimple_build_cond (EQ_EXPR, res, integer_zero_node,
kono
parents: 67
diff changeset
866 align_label, noalign_label);
kono
parents: 67
diff changeset
867 gsi_insert_after (gsi, cond, GSI_NEW_STMT);
kono
parents: 67
diff changeset
868 gsi_insert_after (gsi, gimple_build_label (align_label), GSI_NEW_STMT);
kono
parents: 67
diff changeset
869 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
kono
parents: 67
diff changeset
870 stmt = gimple_build_call (builtin_decl_implicit (BUILT_IN_ASSUME_ALIGNED),
kono
parents: 67
diff changeset
871 2, ptr, align);
kono
parents: 67
diff changeset
872 gimple_call_set_lhs (stmt, ptr);
kono
parents: 67
diff changeset
873 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
kono
parents: 67
diff changeset
874 stmt = gimple_build_assign (fold_build2 (MEM_REF, ptr_type_node, pptr,
kono
parents: 67
diff changeset
875 build_int_cst (ptr_type_node, 0)),
kono
parents: 67
diff changeset
876 ptr);
kono
parents: 67
diff changeset
877 gsi_insert_after (gsi, stmt, GSI_NEW_STMT);
kono
parents: 67
diff changeset
878 gsi_insert_after (gsi, gimple_build_label (noalign_label), GSI_NEW_STMT);
kono
parents: 67
diff changeset
879 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
880
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
881
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
882 /* Record the variables in VARS into function FN. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
883
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
884 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
885 record_vars_into (tree vars, tree fn)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
886 {
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 63
diff changeset
887 for (; vars; vars = DECL_CHAIN (vars))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
888 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
889 tree var = vars;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
890
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
891 /* BIND_EXPRs contains also function/type/constant declarations
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
892 we don't need to care about. */
111
kono
parents: 67
diff changeset
893 if (!VAR_P (var))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
894 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
895
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
896 /* Nothing to do in this case. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
897 if (DECL_EXTERNAL (var))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
898 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
899
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
900 /* Record the variable. */
111
kono
parents: 67
diff changeset
901 add_local_decl (DECL_STRUCT_FUNCTION (fn), var);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
902 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
903 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
904
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
905
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
906 /* Record the variables in VARS into current_function_decl. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
907
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
908 void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
909 record_vars (tree vars)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
910 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
911 record_vars_into (vars, current_function_decl);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
912 }