]>
Commit | Line | Data |
---|---|---|
6de9cd9a | 1 | /* Java(TM) language-specific gimplification routines. |
5624e564 | 2 | Copyright (C) 2003-2015 Free Software Foundation, Inc. |
6de9cd9a DN |
3 | |
4 | This file is part of GCC. | |
5 | ||
6 | GCC is free software; you can redistribute it and/or modify | |
7 | it under the terms of the GNU General Public License as published by | |
8328d52a | 8 | the Free Software Foundation; either version 3, or (at your option) |
6de9cd9a DN |
9 | any later version. |
10 | ||
11 | GCC is distributed in the hope that it will be useful, | |
12 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
14 | GNU General Public License for more details. | |
15 | ||
16 | You should have received a copy of the GNU General Public License | |
8328d52a NC |
17 | along with GCC; see the file COPYING3. If not see |
18 | <http://www.gnu.org/licenses/>. | |
6de9cd9a DN |
19 | |
20 | Java and all Java-based marks are trademarks or registered trademarks | |
21 | of Sun Microsystems, Inc. in the United States and other countries. | |
22 | The Free Software Foundation is independent of Sun Microsystems, Inc. */ | |
23 | ||
24 | #include "config.h" | |
25 | #include "system.h" | |
26 | #include "coretypes.h" | |
40e23961 MC |
27 | #include "hash-set.h" |
28 | #include "machmode.h" | |
29 | #include "vec.h" | |
30 | #include "double-int.h" | |
31 | #include "input.h" | |
32 | #include "alias.h" | |
33 | #include "symtab.h" | |
34 | #include "options.h" | |
35 | #include "wide-int.h" | |
36 | #include "inchash.h" | |
6de9cd9a | 37 | #include "tree.h" |
40e23961 | 38 | #include "fold-const.h" |
6de9cd9a | 39 | #include "java-tree.h" |
7ee2468b | 40 | #include "dumpfile.h" |
60393bbc | 41 | #include "predict.h" |
60393bbc AM |
42 | #include "tm.h" |
43 | #include "hard-reg-set.h" | |
44 | #include "input.h" | |
45 | #include "function.h" | |
2fb9a547 AM |
46 | #include "basic-block.h" |
47 | #include "tree-ssa-alias.h" | |
48 | #include "internal-fn.h" | |
49 | #include "gimple-expr.h" | |
50 | #include "is-a.h" | |
18f429e2 | 51 | #include "gimple.h" |
45b0be94 | 52 | #include "gimplify.h" |
6de9cd9a | 53 | |
6de9cd9a | 54 | static tree java_gimplify_block (tree); |
279e32c9 | 55 | static enum gimplify_status java_gimplify_modify_expr (tree *); |
726a989a RB |
56 | static enum gimplify_status java_gimplify_self_mod_expr (tree *, gimple_seq *, |
57 | gimple_seq *); | |
6de9cd9a DN |
58 | |
59 | static void dump_java_tree (enum tree_dump_index, tree); | |
60 | ||
61 | /* Convert a Java tree to GENERIC. */ | |
62 | ||
63 | void | |
64 | java_genericize (tree fndecl) | |
65 | { | |
a406865a | 66 | walk_tree (&DECL_SAVED_TREE (fndecl), java_replace_references, NULL, NULL); |
6de9cd9a | 67 | dump_java_tree (TDI_original, fndecl); |
6de9cd9a DN |
68 | } |
69 | ||
70 | /* Gimplify a Java tree. */ | |
71 | ||
72 | int | |
726a989a | 73 | java_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) |
6de9cd9a | 74 | { |
17ad5b5e | 75 | enum tree_code code = TREE_CODE (*expr_p); |
6de9cd9a | 76 | |
17ad5b5e | 77 | switch (code) |
6de9cd9a DN |
78 | { |
79 | case BLOCK: | |
80 | *expr_p = java_gimplify_block (*expr_p); | |
81 | break; | |
82 | ||
00150bf9 | 83 | case MODIFY_EXPR: |
279e32c9 | 84 | return java_gimplify_modify_expr (expr_p); |
00150bf9 | 85 | |
572f9e47 AH |
86 | case POSTINCREMENT_EXPR: |
87 | case POSTDECREMENT_EXPR: | |
88 | case PREINCREMENT_EXPR: | |
89 | case PREDECREMENT_EXPR: | |
90 | return java_gimplify_self_mod_expr (expr_p, pre_p, post_p); | |
91 | ||
6de9cd9a DN |
92 | /* These should already be lowered before we get here. */ |
93 | case URSHIFT_EXPR: | |
94 | case COMPARE_EXPR: | |
95 | case COMPARE_L_EXPR: | |
96 | case COMPARE_G_EXPR: | |
ab184b2a | 97 | gcc_unreachable (); |
6de9cd9a DN |
98 | |
99 | default: | |
100 | return GS_UNHANDLED; | |
101 | } | |
102 | ||
103 | return GS_OK; | |
104 | } | |
105 | ||
572f9e47 | 106 | static enum gimplify_status |
279e32c9 | 107 | java_gimplify_modify_expr (tree *modify_expr_p) |
572f9e47 AH |
108 | { |
109 | tree modify_expr = *modify_expr_p; | |
00150bf9 AH |
110 | tree lhs = TREE_OPERAND (modify_expr, 0); |
111 | tree rhs = TREE_OPERAND (modify_expr, 1); | |
112 | tree lhs_type = TREE_TYPE (lhs); | |
74b002ba | 113 | |
a406865a | 114 | if (lhs_type != TREE_TYPE (rhs)) |
74b002ba AH |
115 | /* Fix up type mismatches to make legal GIMPLE. These are |
116 | generated in several places, in particular null pointer | |
117 | assignment and subclass assignment. */ | |
118 | TREE_OPERAND (modify_expr, 1) = convert (lhs_type, rhs); | |
119 | ||
572f9e47 AH |
120 | return GS_UNHANDLED; |
121 | } | |
122 | ||
123 | /* Special case handling for volatiles: we need to generate a barrier | |
124 | between the reading and the writing. */ | |
125 | ||
126 | static enum gimplify_status | |
726a989a RB |
127 | java_gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED, |
128 | gimple_seq *post_p ATTRIBUTE_UNUSED) | |
572f9e47 AH |
129 | { |
130 | tree lhs = TREE_OPERAND (*expr_p, 0); | |
131 | ||
132 | if (TREE_CODE (lhs) == COMPONENT_REF | |
133 | && TREE_THIS_VOLATILE (TREE_OPERAND (lhs, 1))) | |
134 | TREE_THIS_VOLATILE (lhs) = 1; | |
135 | ||
136 | return GS_UNHANDLED; | |
00150bf9 AH |
137 | } |
138 | ||
139 | ||
6de9cd9a DN |
140 | /* Gimplify BLOCK into a BIND_EXPR. */ |
141 | ||
142 | static tree | |
143 | java_gimplify_block (tree java_block) | |
144 | { | |
145 | tree decls = BLOCK_VARS (java_block); | |
146 | tree body = BLOCK_EXPR_BODY (java_block); | |
538dd0b7 | 147 | gbind *outer = gimple_current_bind_expr (); |
6de9cd9a DN |
148 | tree block; |
149 | ||
150 | /* Don't bother with empty blocks. */ | |
151 | if (! body) | |
c2255bc4 | 152 | return build_empty_stmt (input_location); |
6de9cd9a DN |
153 | |
154 | if (IS_EMPTY_STMT (body)) | |
155 | return body; | |
156 | ||
157 | /* Make a proper block. Java blocks are unsuitable for BIND_EXPR | |
158 | because they use BLOCK_SUBBLOCKS for another purpose. */ | |
159 | block = make_node (BLOCK); | |
160 | BLOCK_VARS (block) = decls; | |
979bf9a1 | 161 | |
375277f6 | 162 | /* The TREE_USED flag on a block determines whether the debug output |
979bf9a1 AH |
163 | routines generate info for the variables in that block. */ |
164 | TREE_USED (block) = 1; | |
165 | ||
726a989a | 166 | if (outer != NULL) |
6de9cd9a | 167 | { |
726a989a RB |
168 | tree b = gimple_bind_block (outer); |
169 | BLOCK_SUBBLOCKS (b) = chainon (BLOCK_SUBBLOCKS (b), block); | |
6de9cd9a | 170 | } |
3e248b83 | 171 | BLOCK_EXPR_BODY (java_block) = NULL_TREE; |
6de9cd9a | 172 | |
94cdeb1a | 173 | return build3 (BIND_EXPR, TREE_TYPE (java_block), decls, body, block); |
6de9cd9a DN |
174 | } |
175 | ||
6de9cd9a DN |
176 | /* Dump a tree of some kind. This is a convenience wrapper for the |
177 | dump_* functions in tree-dump.c. */ | |
178 | static void | |
179 | dump_java_tree (enum tree_dump_index phase, tree t) | |
180 | { | |
181 | FILE *stream; | |
182 | int flags; | |
183 | ||
184 | stream = dump_begin (phase, &flags); | |
185 | flags |= TDF_SLIM; | |
186 | if (stream) | |
187 | { | |
188 | dump_node (t, flags, stream); | |
189 | dump_end (phase, stream); | |
190 | } | |
191 | } |