47 IfNode* MathExactNode::if_node() const {
48 BoolNode* boolnode = bool_node();
49 IfNode* ifnode = boolnode->unique_out()->as_If();
50 assert(ifnode != NULL, "must have IfNode");
51 return ifnode;
52 }
53
54 Node* MathExactNode::control_node() const {
55 IfNode* ifnode = if_node();
56 return ifnode->in(0);
57 }
58
59 Node* MathExactNode::non_throwing_branch() const {
60 IfNode* ifnode = if_node();
61 if (bool_node()->_test._test == BoolTest::overflow) {
62 return ifnode->proj_out(0);
63 }
64 return ifnode->proj_out(1);
65 }
66
67 Node* AddExactINode::match(const ProjNode* proj, const Matcher* m) {
68 uint ideal_reg = proj->ideal_reg();
69 RegMask rm;
70 if (proj->_con == result_proj_node) {
71 rm = m->mathExactI_result_proj_mask();
72 } else {
73 assert(proj->_con == flags_proj_node, "must be result or flags");
74 assert(ideal_reg == Op_RegFlags, "sanity");
75 rm = m->mathExactI_flags_proj_mask();
76 }
77 return new (m->C) MachProjNode(this, proj->_con, rm, ideal_reg);
78 }
79
80 // If the MathExactNode won't overflow we have to replace the
81 // FlagsProjNode and ProjNode that is generated by the MathExactNode
82 Node* MathExactNode::no_overflow(PhaseGVN *phase, Node* new_result) {
83 PhaseIterGVN *igvn = phase->is_IterGVN();
84 if (igvn) {
85 ProjNode* result = result_node();
86 ProjNode* flags = flags_node();
87
88 if (result != NULL) {
89 igvn->replace_node(result, new_result);
90 }
91
92 if (flags != NULL) {
93 BoolNode* boolnode = bool_node();
94 switch (boolnode->_test._test) {
95 case BoolTest::overflow:
96 // if the check is for overflow - never taken
97 igvn->replace_node(boolnode, phase->intcon(0));
98 break;
99 case BoolTest::no_overflow:
100 // if the check is for no overflow - always taken
101 igvn->replace_node(boolnode, phase->intcon(1));
102 break;
103 default:
104 fatal("Unexpected value of BoolTest");
105 break;
106 }
107 flags->del_req(0);
108 }
109 }
110 return new_result;
111 }
112
113 Node *AddExactINode::Ideal(PhaseGVN *phase, bool can_reshape) {
114 Node *arg1 = in(1);
115 Node *arg2 = in(2);
116
117 const Type* type1 = phase->type(arg1);
118 const Type* type2 = phase->type(arg2);
119
120 if (type1 != Type::TOP && type1->singleton() &&
121 type2 != Type::TOP && type2->singleton()) {
122 jint val1 = arg1->get_int();
123 jint val2 = arg2->get_int();
124 jint result = val1 + val2;
125 // Hacker's Delight 2-12 Overflow if both arguments have the opposite sign of the result
126 if ( (((val1 ^ result) & (val2 ^ result)) >= 0)) {
127 Node* con_result = ConINode::make(phase->C, result);
128 return no_overflow(phase, con_result);
129 }
130 return NULL;
131 }
132
133 if (type1 == TypeInt::ZERO) { // (Add 0 x) == x
134 Node* add_result = new (phase->C) AddINode(arg1, arg2);
135 return no_overflow(phase, add_result);
136 }
137
138 if (type2 == TypeInt::ZERO) { // (Add x 0) == x
139 Node* add_result = new (phase->C) AddINode(arg1, arg2);
140 return no_overflow(phase, add_result);
141 }
142
143 if (type2->singleton()) {
144 return NULL; // no change - keep constant on the right
145 }
146
147 if (type1->singleton()) {
148 // Make it x + Constant - move constant to the right
149 swap_edges(1, 2);
150 return this;
151 }
152
153 if (arg2->is_Load()) {
154 return NULL; // no change - keep load on the right
155 }
156
157 if (arg1->is_Load()) {
158 // Make it x + Load - move load to the right
159 swap_edges(1, 2);
160 return this;
161 }
162
163 if (arg1->_idx > arg2->_idx) {
164 // Sort the edges
165 swap_edges(1, 2);
166 return this;
167 }
168
169 return NULL;
170 }
171
|
47 IfNode* MathExactNode::if_node() const {
48 BoolNode* boolnode = bool_node();
49 IfNode* ifnode = boolnode->unique_out()->as_If();
50 assert(ifnode != NULL, "must have IfNode");
51 return ifnode;
52 }
53
54 Node* MathExactNode::control_node() const {
55 IfNode* ifnode = if_node();
56 return ifnode->in(0);
57 }
58
59 Node* MathExactNode::non_throwing_branch() const {
60 IfNode* ifnode = if_node();
61 if (bool_node()->_test._test == BoolTest::overflow) {
62 return ifnode->proj_out(0);
63 }
64 return ifnode->proj_out(1);
65 }
66
67 MathExactNode::MathExactNode(Node* ctrl, Node* n1) : MultiNode(2) {
68 init_req(0, ctrl);
69 init_req(1, n1);
70 }
71
72 // If the MathExactNode won't overflow we have to replace the
73 // FlagsProjNode and ProjNode that is generated by the MathExactNode
74 Node* MathExactNode::no_overflow(PhaseGVN* phase, Node* new_result) {
75 PhaseIterGVN* igvn = phase->is_IterGVN();
76 if (igvn) {
77 ProjNode* result = result_node();
78 ProjNode* flags = flags_node();
79
80 if (result != NULL) {
81 igvn->replace_node(result, new_result);
82 }
83
84 if (flags != NULL) {
85 BoolNode* boolnode = bool_node();
86 switch (boolnode->_test._test) {
87 case BoolTest::overflow:
88 // if the check is for overflow - never taken
89 igvn->replace_node(boolnode, phase->intcon(0));
90 break;
91 case BoolTest::no_overflow:
92 // if the check is for no overflow - always taken
93 igvn->replace_node(boolnode, phase->intcon(1));
94 break;
95 default:
96 fatal("Unexpected value of BoolTest");
97 break;
98 }
99 flags->del_req(0);
100 }
101 }
102 return new_result;
103 }
104
105 bool MathExactNode::is_MathExactOpcode(int opcode) {
106 switch (opcode) {
107 case Op_AddExactI:
108 case Op_AddExactL:
109 case Op_SubExactI:
110 case Op_SubExactL:
111 case Op_MulExactI:
112 case Op_MulExactL:
113 case Op_NegExactI:
114 case Op_NegExactL:
115 return true;
116 default:
117 return false;
118 }
119 }
120
121 Node* MathExactINode::match(const ProjNode* proj, const Matcher* m) {
122 uint ideal_reg = proj->ideal_reg();
123 RegMask rm;
124 if (proj->_con == result_proj_node) {
125 rm = m->mathExactI_result_proj_mask();
126 } else {
127 assert(proj->_con == flags_proj_node, "must be result or flags");
128 assert(ideal_reg == Op_RegFlags, "sanity");
129 rm = m->mathExactI_flags_proj_mask();
130 }
131 return new (m->C) MachProjNode(this, proj->_con, rm, ideal_reg);
132 }
133
134 Node* MathExactLNode::match(const ProjNode* proj, const Matcher* m) {
135 uint ideal_reg = proj->ideal_reg();
136 RegMask rm;
137 if (proj->_con == result_proj_node) {
138 rm = m->mathExactL_result_proj_mask();
139 } else {
140 assert(proj->_con == flags_proj_node, "must be result or flags");
141 assert(ideal_reg == Op_RegFlags, "sanity");
142 rm = m->mathExactI_flags_proj_mask();
143 }
144 return new (m->C) MachProjNode(this, proj->_con, rm, ideal_reg);
145 }
146
147 Node* AddExactINode::Ideal(PhaseGVN* phase, bool can_reshape) {
148 Node* arg1 = in(1);
149 Node* arg2 = in(2);
150
151 const Type* type1 = phase->type(arg1);
152 const Type* type2 = phase->type(arg2);
153
154 if (type1 != Type::TOP && type1->singleton() &&
155 type2 != Type::TOP && type2->singleton()) {
156 jint val1 = arg1->get_int();
157 jint val2 = arg2->get_int();
158 jint result = val1 + val2;
159 // Hacker's Delight 2-12 Overflow if both arguments have the opposite sign of the result
160 if ( (((val1 ^ result) & (val2 ^ result)) >= 0)) {
161 Node* con_result = ConINode::make(phase->C, result);
162 return no_overflow(phase, con_result);
163 }
164 return NULL;
165 }
166
167 if (type1 == TypeInt::ZERO || type2 == TypeInt::ZERO) { // (Add 0 x) == x
168 Node* add_result = new (phase->C) AddINode(arg1, arg2);
169 return no_overflow(phase, add_result);
170 }
171
172 if (type2->singleton()) {
173 return NULL; // no change - keep constant on the right
174 }
175
176 if (type1->singleton()) {
177 // Make it x + Constant - move constant to the right
178 swap_edges(1, 2);
179 return this;
180 }
181
182 if (arg2->is_Load()) {
183 return NULL; // no change - keep load on the right
184 }
185
186 if (arg1->is_Load()) {
187 // Make it x + Load - move load to the right
188 swap_edges(1, 2);
189 return this;
190 }
191
192 if (arg1->_idx > arg2->_idx) {
193 // Sort the edges
194 swap_edges(1, 2);
195 return this;
196 }
197
198 return NULL;
199 }
200
201 Node* AddExactLNode::Ideal(PhaseGVN* phase, bool can_reshape) {
202 Node* arg1 = in(1);
203 Node* arg2 = in(2);
204
205 const Type* type1 = phase->type(arg1);
206 const Type* type2 = phase->type(arg2);
207
208 if (type1 != Type::TOP && type1->singleton() &&
209 type2 != Type::TOP && type2->singleton()) {
210 jlong val1 = arg1->get_long();
211 jlong val2 = arg2->get_long();
212 jlong result = val1 + val2;
213 // Hacker's Delight 2-12 Overflow if both arguments have the opposite sign of the result
214 if ( (((val1 ^ result) & (val2 ^ result)) >= 0)) {
215 Node* con_result = ConLNode::make(phase->C, result);
216 return no_overflow(phase, con_result);
217 }
218 return NULL;
219 }
220
221 if (type1 == TypeLong::ZERO || type2 == TypeLong::ZERO) { // (Add 0 x) == x
222 Node* add_result = new (phase->C) AddLNode(arg1, arg2);
223 return no_overflow(phase, add_result);
224 }
225
226 if (type2->singleton()) {
227 return NULL; // no change - keep constant on the right
228 }
229
230 if (type1->singleton()) {
231 // Make it x + Constant - move constant to the right
232 swap_edges(1, 2);
233 return this;
234 }
235
236 if (arg2->is_Load()) {
237 return NULL; // no change - keep load on the right
238 }
239
240 if (arg1->is_Load()) {
241 // Make it x + Load - move load to the right
242 swap_edges(1, 2);
243 return this;
244 }
245
246 if (arg1->_idx > arg2->_idx) {
247 // Sort the edges
248 swap_edges(1, 2);
249 return this;
250 }
251
252 return NULL;
253 }
254
255 Node* SubExactINode::Ideal(PhaseGVN* phase, bool can_reshape) {
256 Node* arg1 = in(1);
257 Node* arg2 = in(2);
258
259 const Type* type1 = phase->type(arg1);
260 const Type* type2 = phase->type(arg2);
261
262 if (type1 != Type::TOP && type1->singleton() &&
263 type2 != Type::TOP && type2->singleton()) {
264 jint val1 = arg1->get_int();
265 jint val2 = arg2->get_int();
266 jint result = val1 - val2;
267
268 // Hacker's Delight 2-12 Overflow iff the arguments have different signs and
269 // the sign of the result is different than the sign of arg1
270 if (((val1 ^ val2) & (val1 ^ result)) >= 0) {
271 Node* con_result = ConINode::make(phase->C, result);
272 return no_overflow(phase, con_result);
273 }
274 return NULL;
275 }
276
277 if (type1 == TypeInt::ZERO || type2 == TypeInt::ZERO) {
278 // Sub with zero is the same as add with zero
279 Node* add_result = new (phase->C) AddINode(arg1, arg2);
280 return no_overflow(phase, add_result);
281 }
282
283 return NULL;
284 }
285
286 Node* SubExactLNode::Ideal(PhaseGVN* phase, bool can_reshape) {
287 Node* arg1 = in(1);
288 Node* arg2 = in(2);
289
290 const Type* type1 = phase->type(arg1);
291 const Type* type2 = phase->type(arg2);
292
293 if (type1 != Type::TOP && type1->singleton() &&
294 type2 != Type::TOP && type2->singleton()) {
295 jlong val1 = arg1->get_long();
296 jlong val2 = arg2->get_long();
297 jlong result = val1 - val2;
298
299 // Hacker's Delight 2-12 Overflow iff the arguments have different signs and
300 // the sign of the result is different than the sign of arg1
301 if (((val1 ^ val2) & (val1 ^ result)) >= 0) {
302 Node* con_result = ConLNode::make(phase->C, result);
303 return no_overflow(phase, con_result);
304 }
305 return NULL;
306 }
307
308 if (type1 == TypeLong::ZERO || type2 == TypeLong::ZERO) {
309 // Sub with zero is the same as add with zero
310 Node* add_result = new (phase->C) AddLNode(arg1, arg2);
311 return no_overflow(phase, add_result);
312 }
313
314 return NULL;
315 }
316
317 Node* NegExactINode::Ideal(PhaseGVN* phase, bool can_reshape) {
318 Node *arg = in(1);
319
320 const Type* type = phase->type(arg);
321 if (type != Type::TOP && type->singleton()) {
322 jint value = arg->get_int();
323 if (value != min_jint) {
324 Node* neg_result = ConINode::make(phase->C, -value);
325 return no_overflow(phase, neg_result);
326 }
327 }
328 return NULL;
329 }
330
331 Node* NegExactLNode::Ideal(PhaseGVN* phase, bool can_reshape) {
332 Node *arg = in(1);
333
334 const Type* type = phase->type(arg);
335 if (type != Type::TOP && type->singleton()) {
336 jlong value = arg->get_long();
337 if (value != min_jlong) {
338 Node* neg_result = ConLNode::make(phase->C, -value);
339 return no_overflow(phase, neg_result);
340 }
341 }
342 return NULL;
343 }
344
345 Node* MulExactINode::Ideal(PhaseGVN* phase, bool can_reshape) {
346 Node* arg1 = in(1);
347 Node* arg2 = in(2);
348
349 const Type* type1 = phase->type(arg1);
350 const Type* type2 = phase->type(arg2);
351
352 if (type1 != Type::TOP && type1->singleton() &&
353 type2 != Type::TOP && type2->singleton()) {
354 jint val1 = arg1->get_int();
355 jint val2 = arg2->get_int();
356 jlong result = (jlong) val1 * (jlong) val2;
357 if ((jint) result == result) {
358 // no overflow
359 Node* mul_result = ConINode::make(phase->C, result);
360 return no_overflow(phase, mul_result);
361 }
362 }
363
364 if (type1 == TypeInt::ZERO || type2 == TypeInt::ZERO) {
365 return no_overflow(phase, ConINode::make(phase->C, 0));
366 }
367
368 if (type1 == TypeInt::ONE) {
369 Node* mul_result = new (phase->C) AddINode(arg2, phase->intcon(0));
370 return no_overflow(phase, mul_result);
371 }
372 if (type2 == TypeInt::ONE) {
373 Node* mul_result = new (phase->C) AddINode(arg1, phase->intcon(0));
374 return no_overflow(phase, mul_result);
375 }
376
377 if (type1 == TypeInt::MINUS_1) {
378 return new (phase->C) NegExactINode(NULL, arg2);
379 }
380
381 if (type2 == TypeInt::MINUS_1) {
382 return new (phase->C) NegExactINode(NULL, arg1);
383 }
384
385 return NULL;
386 }
387
388 Node* MulExactLNode::Ideal(PhaseGVN* phase, bool can_reshape) {
389 Node* arg1 = in(1);
390 Node* arg2 = in(2);
391
392 const Type* type1 = phase->type(arg1);
393 const Type* type2 = phase->type(arg2);
394
395 if (type1 != Type::TOP && type1->singleton() &&
396 type2 != Type::TOP && type2->singleton()) {
397 jlong val1 = arg1->get_long();
398 jlong val2 = arg2->get_long();
399
400 jlong result = val1 * val2;
401 jlong ax = (val1 < 0 ? -val1 : val1);
402 jlong ay = (val2 < 0 ? -val2 : val2);
403
404 bool overflow = false;
405 if ((ax | ay) & CONST64(0xFFFFFFFF00000000)) {
406 // potential overflow if any bit in upper 32 bits are set
407 if ((val1 == min_jlong && val2 == -1) || (val2 == min_jlong && val1 == -1)) {
408 // -1 * Long.MIN_VALUE will overflow
409 overflow = true;
410 } else if (val2 != 0 && (result / val2 != val1)) {
411 overflow = true;
412 }
413 }
414
415 if (!overflow) {
416 Node* mul_result = ConLNode::make(phase->C, result);
417 return no_overflow(phase, mul_result);
418 }
419 }
420
421 if (type1 == TypeLong::ZERO || type2 == TypeLong::ZERO) {
422 return no_overflow(phase, ConLNode::make(phase->C, 0));
423 }
424
425 if (type1 == TypeLong::ONE) {
426 Node* mul_result = new (phase->C) AddLNode(arg2, phase->longcon(0));
427 return no_overflow(phase, mul_result);
428 }
429 if (type2 == TypeLong::ONE) {
430 Node* mul_result = new (phase->C) AddLNode(arg1, phase->longcon(0));
431 return no_overflow(phase, mul_result);
432 }
433
434 if (type1 == TypeLong::MINUS_1) {
435 return new (phase->C) NegExactLNode(NULL, arg2);
436 }
437
438 if (type2 == TypeLong::MINUS_1) {
439 return new (phase->C) NegExactLNode(NULL, arg1);
440 }
441
442 return NULL;
443 }
444
|