]>
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 | 27 | #include "hash-set.h" |
40e23961 | 28 | #include "vec.h" |
40e23961 MC |
29 | #include "input.h" |
30 | #include "alias.h" | |
31 | #include "symtab.h" | |
32 | #include "options.h" | |
40e23961 | 33 | #include "inchash.h" |
6de9cd9a | 34 | #include "tree.h" |
40e23961 | 35 | #include "fold-const.h" |
6de9cd9a | 36 | #include "java-tree.h" |
7ee2468b | 37 | #include "dumpfile.h" |
60393bbc | 38 | #include "predict.h" |
60393bbc AM |
39 | #include "tm.h" |
40 | #include "hard-reg-set.h" | |
41 | #include "input.h" | |
42 | #include "function.h" | |
2fb9a547 AM |
43 | #include "basic-block.h" |
44 | #include "tree-ssa-alias.h" | |
45 | #include "internal-fn.h" | |
46 | #include "gimple-expr.h" | |
47 | #include "is-a.h" | |
18f429e2 | 48 | #include "gimple.h" |
45b0be94 | 49 | #include "gimplify.h" |
6de9cd9a | 50 | |
6de9cd9a | 51 | static tree java_gimplify_block (tree); |
279e32c9 | 52 | static enum gimplify_status java_gimplify_modify_expr (tree *); |
726a989a RB |
53 | static enum gimplify_status java_gimplify_self_mod_expr (tree *, gimple_seq *, |
54 | gimple_seq *); | |
6de9cd9a DN |
55 | |
56 | static void dump_java_tree (enum tree_dump_index, tree); | |
57 | ||
58 | /* Convert a Java tree to GENERIC. */ | |
59 | ||
60 | void | |
61 | java_genericize (tree fndecl) | |
62 | { | |
a406865a | 63 | walk_tree (&DECL_SAVED_TREE (fndecl), java_replace_references, NULL, NULL); |
6de9cd9a | 64 | dump_java_tree (TDI_original, fndecl); |
6de9cd9a DN |
65 | } |
66 | ||
67 | /* Gimplify a Java tree. */ | |
68 | ||
69 | int | |
726a989a | 70 | java_gimplify_expr (tree *expr_p, gimple_seq *pre_p, gimple_seq *post_p) |
6de9cd9a | 71 | { |
17ad5b5e | 72 | enum tree_code code = TREE_CODE (*expr_p); |
6de9cd9a | 73 | |
17ad5b5e | 74 | switch (code) |
6de9cd9a DN |
75 | { |
76 | case BLOCK: | |
77 | *expr_p = java_gimplify_block (*expr_p); | |
78 | break; | |
79 | ||
00150bf9 | 80 | case MODIFY_EXPR: |
279e32c9 | 81 | return java_gimplify_modify_expr (expr_p); |
00150bf9 | 82 | |
572f9e47 AH |
83 | case POSTINCREMENT_EXPR: |
84 | case POSTDECREMENT_EXPR: | |
85 | case PREINCREMENT_EXPR: | |
86 | case PREDECREMENT_EXPR: | |
87 | return java_gimplify_self_mod_expr (expr_p, pre_p, post_p); | |
88 | ||
6de9cd9a DN |
89 | /* These should already be lowered before we get here. */ |
90 | case URSHIFT_EXPR: | |
91 | case COMPARE_EXPR: | |
92 | case COMPARE_L_EXPR: | |
93 | case COMPARE_G_EXPR: | |
ab184b2a | 94 | gcc_unreachable (); |
6de9cd9a DN |
95 | |
96 | default: | |
97 | return GS_UNHANDLED; | |
98 | } | |
99 | ||
100 | return GS_OK; | |
101 | } | |
102 | ||
572f9e47 | 103 | static enum gimplify_status |
279e32c9 | 104 | java_gimplify_modify_expr (tree *modify_expr_p) |
572f9e47 AH |
105 | { |
106 | tree modify_expr = *modify_expr_p; | |
00150bf9 AH |
107 | tree lhs = TREE_OPERAND (modify_expr, 0); |
108 | tree rhs = TREE_OPERAND (modify_expr, 1); | |
109 | tree lhs_type = TREE_TYPE (lhs); | |
74b002ba | 110 | |
a406865a | 111 | if (lhs_type != TREE_TYPE (rhs)) |
74b002ba AH |
112 | /* Fix up type mismatches to make legal GIMPLE. These are |
113 | generated in several places, in particular null pointer | |
114 | assignment and subclass assignment. */ | |
115 | TREE_OPERAND (modify_expr, 1) = convert (lhs_type, rhs); | |
116 | ||
572f9e47 AH |
117 | return GS_UNHANDLED; |
118 | } | |
119 | ||
120 | /* Special case handling for volatiles: we need to generate a barrier | |
121 | between the reading and the writing. */ | |
122 | ||
123 | static enum gimplify_status | |
726a989a RB |
124 | java_gimplify_self_mod_expr (tree *expr_p, gimple_seq *pre_p ATTRIBUTE_UNUSED, |
125 | gimple_seq *post_p ATTRIBUTE_UNUSED) | |
572f9e47 AH |
126 | { |
127 | tree lhs = TREE_OPERAND (*expr_p, 0); | |
128 | ||
129 | if (TREE_CODE (lhs) == COMPONENT_REF | |
130 | && TREE_THIS_VOLATILE (TREE_OPERAND (lhs, 1))) | |
131 | TREE_THIS_VOLATILE (lhs) = 1; | |
132 | ||
133 | return GS_UNHANDLED; | |
00150bf9 AH |
134 | } |
135 | ||
136 | ||
6de9cd9a DN |
137 | /* Gimplify BLOCK into a BIND_EXPR. */ |
138 | ||
139 | static tree | |
140 | java_gimplify_block (tree java_block) | |
141 | { | |
142 | tree decls = BLOCK_VARS (java_block); | |
143 | tree body = BLOCK_EXPR_BODY (java_block); | |
538dd0b7 | 144 | gbind *outer = gimple_current_bind_expr (); |
6de9cd9a DN |
145 | tree block; |
146 | ||
147 | /* Don't bother with empty blocks. */ | |
148 | if (! body) | |
c2255bc4 | 149 | return build_empty_stmt (input_location); |
6de9cd9a DN |
150 | |
151 | if (IS_EMPTY_STMT (body)) | |
152 | return body; | |
153 | ||
154 | /* Make a proper block. Java blocks are unsuitable for BIND_EXPR | |
155 | because they use BLOCK_SUBBLOCKS for another purpose. */ | |
156 | block = make_node (BLOCK); | |
157 | BLOCK_VARS (block) = decls; | |
979bf9a1 | 158 | |
375277f6 | 159 | /* The TREE_USED flag on a block determines whether the debug output |
979bf9a1 AH |
160 | routines generate info for the variables in that block. */ |
161 | TREE_USED (block) = 1; | |
162 | ||
726a989a | 163 | if (outer != NULL) |
6de9cd9a | 164 | { |
726a989a RB |
165 | tree b = gimple_bind_block (outer); |
166 | BLOCK_SUBBLOCKS (b) = chainon (BLOCK_SUBBLOCKS (b), block); | |
6de9cd9a | 167 | } |
3e248b83 | 168 | BLOCK_EXPR_BODY (java_block) = NULL_TREE; |
6de9cd9a | 169 | |
94cdeb1a | 170 | return build3 (BIND_EXPR, TREE_TYPE (java_block), decls, body, block); |
6de9cd9a DN |
171 | } |
172 | ||
6de9cd9a DN |
173 | /* Dump a tree of some kind. This is a convenience wrapper for the |
174 | dump_* functions in tree-dump.c. */ | |
175 | static void | |
176 | dump_java_tree (enum tree_dump_index phase, tree t) | |
177 | { | |
178 | FILE *stream; | |
179 | int flags; | |
180 | ||
181 | stream = dump_begin (phase, &flags); | |
182 | flags |= TDF_SLIM; | |
183 | if (stream) | |
184 | { | |
185 | dump_node (t, flags, stream); | |
186 | dump_end (phase, stream); | |
187 | } | |
188 | } |