001 /*
002 * This file is part of the Jikes RVM project (http://jikesrvm.org).
003 *
004 * This file is licensed to You under the Eclipse Public License (EPL);
005 * You may not use this file except in compliance with the License. You
006 * may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/eclipse-1.0.php
009 *
010 * See the COPYRIGHT.txt file distributed with this work for information
011 * regarding copyright ownership.
012 */
013 package org.jikesrvm.compilers.opt.ir.operand;
014
015 import org.jikesrvm.VM;
016 import org.jikesrvm.classloader.TypeReference;
017 import org.jikesrvm.compilers.opt.ClassLoaderProxy;
018 import org.jikesrvm.compilers.opt.OptimizingCompilerException;
019 import org.jikesrvm.compilers.opt.bc2ir.BC2IR;
020 import org.jikesrvm.compilers.opt.bc2ir.IRGenOptions;
021 import org.jikesrvm.compilers.opt.driver.OptConstants;
022 import org.jikesrvm.compilers.opt.ir.Instruction;
023 import org.jikesrvm.compilers.opt.ir.Register;
024 import org.vmmagic.unboxed.Address;
025
026 /**
027 * An <code>Operand</code> identifies an operand for an
028 * {@link Instruction}. A single Operand object should
029 * not be shared between instructions (or even be used twice in
030 * the same instruction). Operands should not be shared between
031 * instructions because we use the
032 * {@link #instruction reference to the operand's containing instruction}
033 * to construct use/def chains. We also store program-point specific
034 * information about an {@link Register symbolic register}
035 * in the {@link RegisterOperand RegisterOperands} that
036 * {@link RegisterOperand#register refer} to the
037 * <code>Register</code>.
038 * <p>
039 * Operands are divided into several primary categories
040 * <ul>
041 * <li> {@link RegisterOperand} represent symbolic and
042 * and physical registers.
043 * <li> The subclasses of {@link ConstantOperand}
044 * represent various kinds of constant operands.
045 * <li> {@link MethodOperand} represents the targets of CALL instructions.
046 * <li> {@link BranchOperand}, {@link BasicBlockOperand},
047 * and {@link BranchOperand} are used to encode CFG
048 * information in LABEL, BBEND, and branch instructions.
049 * <li> {@link ConditionOperand} and {@link TrapCodeOperand}
050 * encode the conditions tested by conditional branches and
051 * trap instructions.
052 * <li> {@link LocationOperand} represents the memory location
053 * accessed by a load or store operation.
054 * <li> {@link TypeOperand} encodes a {@link org.jikesrvm.classloader.RVMType} for use
055 * in instructions such as NEW or INSTANCEOF that operate on the
056 * type hierarchy.
057 * </ul>
058 *
059 * @see Instruction
060 * @see BasicBlockOperand
061 * @see BranchOperand
062 * @see ConditionOperand
063 * @see ConstantOperand
064 * @see DoubleConstantOperand
065 * @see FloatConstantOperand
066 * @see IntConstantOperand
067 * @see LocationOperand
068 * @see LongConstantOperand
069 * @see MethodOperand
070 * @see NullConstantOperand
071 * @see RegisterOperand
072 * @see StringConstantOperand
073 * @see TrapCodeOperand
074 * @see TrueGuardOperand
075 * @see TypeOperand
076 */
077 public abstract class Operand {
078
079 /**
080 * Handle back to containing instruction.
081 */
082 public Instruction instruction;
083
084 /**
085 * Is the operand an {@link RegisterOperand}?
086 *
087 * @return <code>true</code> if <code>this</code> is an
088 * <code>instanceof</code> an {@link RegisterOperand}
089 * or <code>false</code> if it is not.
090 */
091 public final boolean isRegister() {
092 return this instanceof RegisterOperand;
093 }
094
095 /**
096 * Is the operand an {@link ConstantOperand}?
097 *
098 * @return <code>true</code> if <code>this</code> is an
099 * <code>instanceof</code> an {@link ConstantOperand}
100 * or <code>false</code> if it is not.
101 */
102 public final boolean isConstant() {
103 return this instanceof ConstantOperand;
104 }
105
106 /**
107 * Is the operand an {@link IntConstantOperand}?
108 *
109 * @return <code>true</code> if <code>this</code> is an
110 * <code>instanceof</code> an {@link IntConstantOperand}
111 * or <code>false</code> if it is not.
112 */
113 public final boolean isIntConstant() {
114 return this instanceof IntConstantOperand;
115 }
116
117 /**
118 * Is the operand an {@link AddressConstantOperand}?
119 *
120 * @return <code>true</code> if <code>this</code> is an
121 * <code>instanceof</code> an {@link AddressConstantOperand}
122 * or <code>false</code> if it is not.
123 */
124 public final boolean isAddressConstant() {
125 return this instanceof AddressConstantOperand;
126 }
127
128 /**
129 * Is the operand an {@link FloatConstantOperand}?
130 *
131 * @return <code>true</code> if <code>this</code> is an
132 * <code>instanceof</code> an {@link FloatConstantOperand}
133 * or <code>false</code> if it is not.
134 */
135 public final boolean isFloatConstant() {
136 return this instanceof FloatConstantOperand;
137 }
138
139 /**
140 * Is the operand an {@link LongConstantOperand}?
141 *
142 * @return <code>true</code> if <code>this</code> is an
143 * <code>instanceof</code> an {@link LongConstantOperand}
144 * or <code>false</code> if it is not.
145 */
146 public final boolean isLongConstant() {
147 return this instanceof LongConstantOperand;
148 }
149
150 /**
151 * Is the operand an {@link DoubleConstantOperand}?
152 *
153 * @return <code>true</code> if <code>this</code> is an
154 * <code>instanceof</code> an {@link DoubleConstantOperand}
155 * or <code>false</code> if it is not.
156 */
157 public final boolean isDoubleConstant() {
158 return this instanceof DoubleConstantOperand;
159 }
160
161 /**
162 * Is the operand an {@link StringConstantOperand}?
163 *
164 * @return <code>true</code> if <code>this</code> is an
165 * <code>instanceof</code> an {@link StringConstantOperand}
166 * or <code>false</code> if it is not.
167 */
168 public final boolean isStringConstant() {
169 return this instanceof StringConstantOperand;
170 }
171
172 /**
173 * Is the operand an {@link ClassConstantOperand}?
174 *
175 * @return <code>true</code> if <code>this</code> is an
176 * <code>instanceof</code> an {@link ClassConstantOperand}
177 * or <code>false</code> if it is not.
178 */
179 public final boolean isClassConstant() {
180 return this instanceof ClassConstantOperand;
181 }
182
183 /**
184 * Is the operand an {@link ObjectConstantOperand}?
185 *
186 * @return <code>true</code> if <code>this</code> is an
187 * <code>instanceof</code> an {@link ObjectConstantOperand}
188 * or <code>false</code> if it is not.
189 */
190 public final boolean isObjectConstant() {
191 return this instanceof ObjectConstantOperand;
192 }
193
194 /**
195 * Is the operand a movable {@link ObjectConstantOperand}?
196 *
197 * @return false
198 */
199 public boolean isMovableObjectConstant() {
200 return false;
201 }
202
203 /**
204 * Is the operand an {@link TIBConstantOperand}?
205 *
206 * @return <code>true</code> if <code>this</code> is an
207 * <code>instanceof</code> an {@link TIBConstantOperand}
208 * or <code>false</code> if it is not.
209 */
210 public final boolean isTIBConstant() {
211 return this instanceof TIBConstantOperand;
212 }
213
214 /**
215 * Is the operand an {@link NullConstantOperand}?
216 *
217 * @return <code>true</code> if <code>this</code> is an
218 * <code>instanceof</code> an {@link NullConstantOperand}
219 * or <code>false</code> if it is not.
220 */
221 public final boolean isNullConstant() {
222 return this instanceof NullConstantOperand;
223 }
224
225 /**
226 * Is the operand an {@link TrueGuardOperand}?
227 *
228 * @return <code>true</code> if <code>this</code> is an
229 * <code>instanceof</code> an {@link TrueGuardOperand}
230 * or <code>false</code> if it is not.
231 */
232 public final boolean isTrueGuard() {
233 return this instanceof TrueGuardOperand;
234 }
235
236 /**
237 * Is the operand an {@link BranchOperand}?
238 *
239 * @return <code>true</code> if <code>this</code> is an
240 * <code>instanceof</code> an {@link BranchOperand}
241 * or <code>false</code> if it is not.
242 */
243 public final boolean isBranch() {
244 return this instanceof BranchOperand;
245 }
246
247 /**
248 * Is the operand an {@link BasicBlockOperand}?
249 *
250 * @return <code>true</code> if <code>this</code> is an
251 * <code>instanceof</code> an {@link BasicBlockOperand}
252 * or <code>false</code> if it is not.
253 */
254 public final boolean isBlock() {
255 return this instanceof BasicBlockOperand;
256 }
257
258 /**
259 * Is the operand an {@link MemoryOperand}?
260 *
261 * @return <code>true</code> if <code>this</code> is an
262 * <code>instanceof</code> an {@link MemoryOperand}
263 * or <code>false</code> if it is not.
264 */
265 public final boolean isMemory() {
266 return this instanceof MemoryOperand;
267 }
268
269 /**
270 * Is the operand an {@link StackLocationOperand}?
271 *
272 * @return <code>true</code> if <code>this</code> is an
273 * <code>instanceof</code> an {@link StackLocationOperand}
274 * or <code>false</code> if it is not.
275 */
276 public final boolean isStackLocation() {
277 return this instanceof StackLocationOperand;
278 }
279
280 /**
281 * Is the operand an {@link MethodOperand}?
282 *
283 * @return <code>true</code> if <code>this</code> is an
284 * <code>instanceof</code> an {@link MethodOperand}
285 * or <code>false</code> if it is not.
286 */
287 public final boolean isMethod() {
288 return this instanceof MethodOperand;
289 }
290
291 /**
292 * Is the operand an {@link LocationOperand}?
293 *
294 * @return <code>true</code> if <code>this</code> is an
295 * <code>instanceof</code> an {@link LocationOperand}
296 * or <code>false</code> if it is not.
297 */
298 public final boolean isLocation() {
299 return this instanceof LocationOperand;
300 }
301
302 /**
303 * Is the operand an {@link TypeOperand}?
304 *
305 * @return <code>true</code> if <code>this</code> is an
306 * <code>instanceof</code> an {@link TypeOperand}
307 * or <code>false</code> if it is not.
308 */
309 public final boolean isType() {
310 return this instanceof TypeOperand;
311 }
312
313 /**
314 * Cast to an {@link RegisterOperand}.
315 *
316 * @return <code>this</code> cast as an {@link RegisterOperand}
317 */
318 public final RegisterOperand asRegister() {
319 return (RegisterOperand) this;
320 }
321
322 /**
323 * Cast to an {@link IntConstantOperand}.
324 *
325 * @return <code>this</code> cast as an {@link IntConstantOperand}
326 */
327 public final IntConstantOperand asIntConstant() {
328 return (IntConstantOperand) this;
329 }
330
331 /**
332 * Cast to an {@link AddressConstantOperand}.
333 *
334 * @return <code>this</code> cast as an {@link AddressConstantOperand}
335 */
336 public final AddressConstantOperand asAddressConstant() {
337 return (AddressConstantOperand) this;
338 }
339
340 /**
341 * Cast to an {@link FloatConstantOperand}.
342 *
343 * @return <code>this</code> cast as an {@link FloatConstantOperand}
344 */
345 public final FloatConstantOperand asFloatConstant() {
346 return (FloatConstantOperand) this;
347 }
348
349 /**
350 * Cast to an {@link LongConstantOperand}.
351 *
352 * @return <code>this</code> cast as an {@link LongConstantOperand}
353 */
354 public final LongConstantOperand asLongConstant() {
355 return (LongConstantOperand) this;
356 }
357
358 /**
359 * Cast to an {@link DoubleConstantOperand}.
360 *
361 * @return <code>this</code> cast as an {@link DoubleConstantOperand}
362 */
363 public final DoubleConstantOperand asDoubleConstant() {
364 return (DoubleConstantOperand) this;
365 }
366
367 /**
368 * Cast to an {@link StringConstantOperand}.
369 *
370 * @return <code>this</code> cast as an {@link StringConstantOperand}
371 */
372 public final StringConstantOperand asStringConstant() {
373 return (StringConstantOperand) this;
374 }
375
376 /**
377 * Cast to an {@link ClassConstantOperand}.
378 *
379 * @return <code>this</code> cast as an {@link ClassConstantOperand}
380 */
381 public final ClassConstantOperand asClassConstant() {
382 return (ClassConstantOperand) this;
383 }
384
385 /**
386 * Cast to an {@link ObjectConstantOperand}.
387 *
388 * @return <code>this</code> cast as an {@link ObjectConstantOperand}
389 */
390 public final ObjectConstantOperand asObjectConstant() {
391 return (ObjectConstantOperand) this;
392 }
393
394 /**
395 * Cast to an {@link TIBConstantOperand}.
396 *
397 * @return <code>this</code> cast as an {@link TIBConstantOperand}
398 */
399 public final TIBConstantOperand asTIBConstant() {
400 return (TIBConstantOperand) this;
401 }
402
403 /**
404 * Cast to an {@link NullConstantOperand}.
405 *
406 * @return <code>this</code> cast as an {@link NullConstantOperand}
407 */
408 public final NullConstantOperand asNullConstant() {
409 return (NullConstantOperand) this;
410 }
411
412 /**
413 * Cast to an {@link BranchOperand}.
414 *
415 * @return <code>this</code> cast as an {@link BranchOperand}
416 */
417 public final BranchOperand asBranch() {
418 return (BranchOperand) this;
419 }
420
421 /**
422 * Cast to an {@link BasicBlockOperand}.
423 *
424 * @return <code>this</code> cast as an {@link BasicBlockOperand}
425 */
426 public final BasicBlockOperand asBlock() {
427 return (BasicBlockOperand) this;
428 }
429
430 /**
431 * Cast to an {@link MemoryOperand}.
432 *
433 * @return <code>this</code> cast as an {@link MemoryOperand}
434 */
435 public final MemoryOperand asMemory() {
436 return (MemoryOperand) this;
437 }
438
439 /**
440 * Cast to an {@link StackLocationOperand}.
441 *
442 * @return <code>this</code> cast as an {@link StackLocationOperand}
443 */
444 public final StackLocationOperand asStackLocation() {
445 return (StackLocationOperand) this;
446 }
447
448 /**
449 * Cast to an {@link MethodOperand}.
450 *
451 * @return <code>this</code> cast as an {@link MethodOperand}
452 */
453 public final MethodOperand asMethod() {
454 return (MethodOperand) this;
455 }
456
457 /**
458 * Cast to an {@link TypeOperand}.
459 *
460 * @return <code>this</code> cast as an {@link TypeOperand}
461 */
462 public final TypeOperand asType() {
463 return (TypeOperand) this;
464 }
465
466 /**
467 * Cast to an {@link ConditionOperand}.
468 *
469 * @return <code>this</code> cast as an {@link ConditionOperand}
470 */
471 public final ConditionOperand asCondition() {
472 return (ConditionOperand) this;
473 }
474
475 /**
476 * Cast to an {@link LocationOperand}.
477 *
478 * @return <code>this</code> cast as an {@link LocationOperand}
479 */
480 public final LocationOperand asLocation() {
481 return (LocationOperand) this;
482 }
483
484 /**
485 * Does the operand represent a value of an int-like data type?
486 *
487 * @return <code>true</code> if the data type of <code>this</code>
488 * is int-like as defined by {@link TypeReference#isIntLikeType}
489 * or <code>false</code> if it is not.
490 */
491 public boolean isIntLike() {
492 // default to false and then override in subclasses
493 return false;
494 }
495
496 /**
497 * Does the operand represent a value of the int data type?
498 *
499 * @return <code>true</code> if the data type of <code>this</code>
500 * is an int as defined by {@link TypeReference#isIntType}
501 * or <code>false</code> if it is not.
502 */
503 public boolean isInt() {
504 // default to false and then override in subclasses
505 return false;
506 }
507
508 /**
509 * Does the operand represent a value of the long data type?
510 *
511 * @return <code>true</code> if the data type of <code>this</code>
512 * is a long as defined by {@link TypeReference#isLongType}
513 * or <code>false</code> if it is not.
514 */
515 public boolean isLong() {
516 // default to false and then override in subclasses
517 return false;
518 }
519
520 /**
521 * Does the operand represent a value of the float data type?
522 *
523 * @return <code>true</code> if the data type of <code>this</code>
524 * is a float as defined by {@link TypeReference#isFloatType}
525 * or <code>false</code> if it is not.
526 */
527 public boolean isFloat() {
528 // default to false and then override in subclasses
529 return false;
530 }
531
532 /**
533 * Does the operand represent a value of the double data type?
534 *
535 * @return <code>true</code> if the data type of <code>this</code>
536 * is a double as defined by {@link TypeReference#isDoubleType}
537 * or <code>false</code> if it is not.
538 */
539 public boolean isDouble() {
540 // default to false and then override in subclasses
541 return false;
542 }
543
544 /**
545 * Does the operand represent a value of the reference data type?
546 *
547 * @return <code>true</code> if the data type of <code>this</code>
548 * is a reference as defined by {@link TypeReference#isReferenceType}
549 * or <code>false</code> if it is not.
550 */
551 public boolean isRef() {
552 // default to false and then override in subclasses
553 return false;
554 }
555
556 /**
557 * Does the operand represent a value of the address data type?
558 *
559 * @return <code>true</code> if the data type of <code>this</code>
560 * is an address as defined by {@link TypeReference#isAddressType}
561 * or <code>false</code> if it is not.
562 */
563 public boolean isAddress() {
564 // default to false and then override in subclasses
565 return false;
566 }
567
568 /**
569 * Does the operand definitely represent <code>null</code>?
570 *
571 * @return <code>true</code> if the operand definitely represents
572 * <code>null</code> or <code>false</code> if it does not.
573 */
574 public boolean isDefinitelyNull() {
575 // default to false and then override in subclasses
576 return false;
577 }
578
579 /**
580 * Return a new operand that is semantically equivalent to <code>this</code>.
581 *
582 * @return a copy of <code>this</code>
583 */
584 public abstract Operand copy();
585
586 /**
587 * Are two operands semantically equivalent?
588 *
589 * @param op other operand
590 * @return <code>true</code> if <code>this</code> and <code>op</code>
591 * are semantically equivalent or <code>false</code>
592 * if they are not.
593 */
594 public abstract boolean similar(Operand op);
595
596 /**
597 * Return the {@link TypeReference} of the value represented by the operand.
598 *
599 * @return the type of the value represented by the operand
600 */
601 public TypeReference getType() {
602 // by default throw OptimizingCompilerException as not all
603 // operands have a type.
604 throw new OptimizingCompilerException("Getting the type for this operand has no defined meaning: " + this);
605 }
606
607 /**
608 * Return the index of the operand in its containing instruction (SLOW).
609 *
610 * @return the index of the operand in its containing instruction
611 */
612 public int getIndexInInstruction() {
613 for (int i = 0; i < instruction.getNumberOfOperands(); i++) {
614 Operand op = instruction.getOperand(i);
615 if (op == this) return i;
616 }
617 throw new OptimizingCompilerException("Operand.getIndexInInstruction");
618 }
619
620 /**
621 * Compare two operands based on their positions in the operand lattice.
622 * For the purposes of doing dataflow analysis, Operands can be
623 * thought of as forming a lattice.
624 * This function compares two operands and returns whether or
625 * not op1 is a conservative approximation of op2.
626 * Or in other words, if conservativelyApproximates(op1, op2)
627 * then meet(op1, op2) = op1.
628 * Note that lattices are partial orders, so it is quite
629 * possible for both conservativelyApproximates(op1, op2)
630 * and conservativelyApproximates(op2, op1) to return false.
631 *
632 * @param op1 the first operand to compare
633 * @param op2 the second operand to compare
634 * @return <code>true</code> if op1 conservatively approximates op2 or
635 * <code>false</code> if it does not.
636 */
637 public static boolean conservativelyApproximates(Operand op1, Operand op2) {
638 // Step 1: Handle pointer equality and bottom
639 if (op1 == op2) {
640 if (IRGenOptions.DBG_OPERAND_LATTICE) {
641 if (op2 == null) {
642 VM.sysWrite("operands are both bottom therefore trivially true\n");
643 } else {
644 VM.sysWrite("operands are identical therefore trivially true\n");
645 }
646 }
647 return true;
648 }
649 if (op1 == null) {
650 if (IRGenOptions.DBG_OPERAND_LATTICE) {
651 VM.sysWrite("op1 is bottom, therefore trivially true\n");
652 }
653 return true;
654 }
655 if (op2 == null) {
656 if (IRGenOptions.DBG_OPERAND_LATTICE) {
657 VM.sysWrite("op2 is bottom, therefore trivially false\n");
658 }
659 return false;
660 }
661
662 // Now, handle the non-trivial cases:
663
664 // Step 2: op1 is a constant but op2 is not the same constant
665 if (op1.isConstant()) {
666 if (op1.similar(op2)) {
667 if (IRGenOptions.DBG_OPERAND_LATTICE) {
668 VM.sysWrite("operands are similar constants\n");
669 }
670 return true;
671 } else {
672 if (IRGenOptions.DBG_OPERAND_LATTICE) {
673 VM.sysWrite("op1 is a constant but op2 is not the same constant\n");
674 }
675 return false;
676 }
677 }
678
679 // Step 3: op1 is a RegisterOperand
680 // This case is complicated by the need to ensure that the
681 // various Flag bits are considered as well....
682 if (op1.isRegister()) {
683 RegisterOperand rop1 = op1.asRegister();
684 TypeReference type1 = rop1.getType();
685 if (op2.isRegister()) {
686 RegisterOperand rop2 = op2.asRegister();
687 TypeReference type2 = rop2.getType();
688 if (type1 == type2) {
689 if (rop1.hasLessConservativeFlags(rop2)) {
690 if (IRGenOptions.DBG_OPERAND_LATTICE) {
691 VM.sysWrite("Operands are registers of identical type, but incompatible flags\n");
692 }
693 return false;
694 } else if (BC2IR.hasLessConservativeGuard(rop1, rop2)) {
695 if (IRGenOptions.DBG_OPERAND_LATTICE) {
696 VM.sysWrite("Operands are registers of identical type, but with incompatible non-null guards\n");
697 }
698 return false;
699 } else {
700 if (IRGenOptions.DBG_OPERAND_LATTICE) {
701 VM.sysWrite("Operands are compatible register operands\n");
702 }
703 return true;
704 }
705 } else if (compatiblePrimitives(type1, type2) ||
706 ClassLoaderProxy.includesType(type1, type2) == OptConstants.YES) {
707 // types are ok, only have to worry about the flags
708 if (rop1.isPreciseType() || rop1.hasLessConservativeFlags(rop2)) {
709 if (IRGenOptions.DBG_OPERAND_LATTICE) {
710 VM.sysWrite("Flag mismatch between type compatible register operands\n");
711 }
712 return false;
713 } else if (BC2IR.hasLessConservativeGuard(rop1, rop2)) {
714 if (IRGenOptions.DBG_OPERAND_LATTICE) {
715 VM.sysWrite("Non-null guard mismatch between type compatible register operands\n");
716 }
717 return false;
718 } else {
719 if (IRGenOptions.DBG_OPERAND_LATTICE) {
720 VM.sysWrite("Operands are compatible register operands\n");
721 }
722 return true;
723 }
724 } else {
725 if (IRGenOptions.DBG_OPERAND_LATTICE) {
726 VM.sysWrite("Operands are type incompatible register operands\n");
727 }
728 return false;
729 }
730 } else {
731 // op2 is not a register
732 if (op2 instanceof BC2IR.ReturnAddressOperand || op2 == BC2IR.DUMMY) {
733 if (IRGenOptions.DBG_OPERAND_LATTICE) {
734 VM.sysWrite("Operands are incompatibale values\n");
735 }
736 return false;
737 }
738
739 TypeReference type2 = op2.getType();
740 if (type1 == type2 ||
741 compatiblePrimitives(type1, type2) ||
742 (ClassLoaderProxy.includesType(type1, type2) == OptConstants.YES)) {
743 // only have to consider state of op1's flags. Types are ok.
744 if (rop1.isPreciseType() && (type1 != type2)) {
745 if (IRGenOptions.DBG_OPERAND_LATTICE) {
746 VM.sysWrite("op1 preciseType bit will be incorrect\n");
747 }
748 return false;
749 }
750 if ((rop1.scratchObject instanceof Operand) &&
751 ((type2 == TypeReference.NULL_TYPE) ||
752 (type2.isIntLikeType() && op2.asIntConstant().value == 0) ||
753 (type2.isWordLikeType() && op2.asAddressConstant().value.EQ(Address.zero())) ||
754 (type2.isLongType() && op2.asLongConstant().value == 0L))) {
755 if (IRGenOptions.DBG_OPERAND_LATTICE) {
756 VM.sysWrite("op1 non null guard will be incorrect");
757 }
758 return false;
759 }
760 if (IRGenOptions.DBG_OPERAND_LATTICE) {
761 VM.sysWrite("(Constant) op2 was compatible with register op1\n");
762 }
763 return true;
764 } else {
765 if (IRGenOptions.DBG_OPERAND_LATTICE) {
766 VM.sysWrite("Op2 not compatible with register op1\n");
767 }
768 return false;
769 }
770 }
771 }
772
773 // Step 4: op1 is a IRGEN operand of some form
774 if (op1.similar(op2)) {
775 if (IRGenOptions.DBG_OPERAND_LATTICE) {
776 VM.sysWrite("Compatible BC2IR.* operands\n");
777 }
778 return true;
779 } else {
780 if (IRGenOptions.DBG_OPERAND_LATTICE) {
781 VM.sysWrite("Incompatible BC2IR.* operands\n");
782 }
783 return false;
784 }
785 }
786
787 /**
788 * Meet two operands based on their positions in the operand lattice.
789 * For the purposes of doing dataflow analysis, Operands can be
790 * thought of as forming a lattice.
791 * This function takes two operands and returns their meet (glb).
792 * We use <code>null</code> to stand for bottom (the meet of
793 * the two operands is an illegal value). For exmaple,
794 * meet(5.0, "hi") would evalaute to bottom.
795 * Meet returns op1 iff conservativelyApproximates(op1, op2):
796 * this is exploited in BC2IR to avoid doing redundant
797 * work.
798 * <p>
799 * Unfortunately there is a fair amount of code duplication
800 * between {@link #conservativelyApproximates} and
801 * {@link #meet}, but factoring out the common control logic
802 * is a non-trivial task.
803 *
804 * @param op1 the first operand to meet
805 * @param op2 the second operand to meet
806 * @param reg the <code>Register</code> to use to
807 * create a new <code>RegisterOperand</code>
808 * if meeting op1 and op2 requires doing so.
809 * @return the Operand that is the meet of op1 and op2.
810 * This function will return <code>null</code> when
811 * the meet evaluates to bottom. It will return
812 * op1 when conservativelyApproximates(op1, op2)
813 * evaluates to <code>true</code>.
814 */
815 public static Operand meet(Operand op1, Operand op2, Register reg) {
816 // Step 1: Handler pointer equality and bottom
817 if (op1 == op2) {
818 if (IRGenOptions.DBG_OPERAND_LATTICE) {
819 if (op1 == null) {
820 VM.sysWrite("Both operands are bottom\n");
821 } else {
822 VM.sysWrite("Operands are identical\n");
823 }
824 }
825 return op1;
826 }
827 if (op1 == null) {
828 if (IRGenOptions.DBG_OPERAND_LATTICE) {
829 VM.sysWrite("Op1 was already bottom\n");
830 }
831 return op1;
832 }
833 if (op2 == null) {
834 if (IRGenOptions.DBG_OPERAND_LATTICE) {
835 VM.sysWrite("Op2 is bottom (but op1 was not)\n");
836 }
837 return op2;
838 }
839
840 // Now handle the nontrivial cases...
841
842 // Step 2: op1 is <null> (the null constant)
843 if (op1 instanceof NullConstantOperand) {
844 if (op2 instanceof NullConstantOperand) {
845 if (IRGenOptions.DBG_OPERAND_LATTICE) {
846 VM.sysWrite("Both operands are <null>\n");
847 }
848 return op1;
849 } else {
850 /*
851 * XXX Opt compiler guru please check :)
852 *
853 * Protect this code from crashing if op2 is DUMMY. As I understand
854 * the calling code this shouldn't happen, but the case for RegisterOperand
855 * handles it so I guess it's not too bad for a NullConstantOperand
856 * to do so.
857 *
858 * -- Robin Garner 1 Feb 7
859 */
860 if (op2 instanceof BC2IR.ReturnAddressOperand || op2 == BC2IR.DUMMY) {
861 if (IRGenOptions.DBG_OPERAND_LATTICE) {
862 VM.sysWrite("Incompatabily typed operands");
863 }
864 return null; // bottom
865 }
866 TypeReference type2 = op2.getType();
867 if (type2.isReferenceType()) {
868 if (IRGenOptions.DBG_OPERAND_LATTICE) {
869 VM.sysWrite("op1 is <null>, but op2 is other ref type\n");
870 }
871 return new RegisterOperand(reg, type2);
872 } else {
873 if (IRGenOptions.DBG_OPERAND_LATTICE) {
874 VM.sysWrite("op1 is <null>, but op2 is not a ref type\n");
875 }
876 return null; // bottom
877 }
878 }
879 }
880
881 // Step 3: op1 is some other constant
882 if (op1.isConstant()) {
883 if (op1.similar(op2)) {
884 if (IRGenOptions.DBG_OPERAND_LATTICE) {
885 VM.sysWrite("op1 and op2 are similar constants\n");
886 }
887 return op1;
888 } else {
889 TypeReference superType = ClassLoaderProxy.findCommonSuperclass(op1.getType(), op2.getType());
890 if (superType == null) {
891 if (IRGenOptions.DBG_OPERAND_LATTICE) {
892 VM.sysWrite("op1 and op2 have incompatible types\n");
893 }
894 return null; // bottom
895 } else {
896 return new RegisterOperand(reg, superType);
897 }
898 }
899 }
900
901 // Step 4: op1 is a register operand
902 // This case is complicated by the need to ensure that
903 // the various Flag bits are considered as well....
904 if (op1.isRegister()) {
905 RegisterOperand rop1 = op1.asRegister();
906 TypeReference type1 = rop1.getType();
907 if (op2.isRegister()) {
908 RegisterOperand rop2 = op2.asRegister();
909 TypeReference type2 = rop2.getType();
910 if (type1 == type2) {
911 if (IRGenOptions.DBG_OPERAND_LATTICE) {
912 VM.sysWrite("Identically typed register operands, checking flags...");
913 }
914 if (rop1.hasLessConservativeFlags(rop2)) {
915 if (IRGenOptions.DBG_OPERAND_LATTICE) {
916 VM.sysWrite("mismatch\n");
917 }
918 RegisterOperand res = new RegisterOperand(reg, type1, rop1.getFlags(), rop1.isPreciseType(), rop1.isDeclaredType());
919 if (rop1.scratchObject instanceof Operand &&
920 rop2.scratchObject instanceof Operand &&
921 (((Operand) rop1.scratchObject).similar(((Operand) rop2.scratchObject)))) {
922 res.scratchObject = rop1.scratchObject; // compatible, so preserve onto res
923 }
924 res.meetInheritableFlags(rop2);
925 return res;
926 } else if (BC2IR.hasLessConservativeGuard(rop1, rop2)) {
927 if (IRGenOptions.DBG_OPERAND_LATTICE) {
928 VM.sysWrite(
929 "Operands are registers of identical type with compatible flags but with incompatible non-null guards\n");
930 }
931 // by not setting scratchObject we mark as possible null
932 return new RegisterOperand(reg, type1, rop1.getFlags(), rop1.isPreciseType(), rop1.isDeclaredType());
933 } else {
934 if (IRGenOptions.DBG_OPERAND_LATTICE) {
935 VM.sysWrite("match\n");
936 }
937 return op1;
938 }
939 } else if (compatiblePrimitives(type1, type2) ||
940 ClassLoaderProxy.includesType(type1, type2) == OptConstants.YES) {
941 if (IRGenOptions.DBG_OPERAND_LATTICE) {
942 VM.sysWrite("Compatibly typed register operands, checking flags...");
943 }
944 if (rop1.isPreciseType() || rop1.hasLessConservativeFlags(rop2)) {
945 if (IRGenOptions.DBG_OPERAND_LATTICE) {
946 VM.sysWrite("mismatch\n");
947 }
948 RegisterOperand res = new RegisterOperand(reg, type1, rop1.getFlags(), rop1.isPreciseType(), rop1.isDeclaredType());
949 res.meetInheritableFlags(rop2);
950 // even if both op1 & op2 are precise,
951 // op1.type != op2.type, so clear it on res
952 res.clearPreciseType();
953 if (rop1.scratchObject instanceof Operand &&
954 rop2.scratchObject instanceof Operand &&
955 (((Operand) rop1.scratchObject).similar(((Operand) rop2.scratchObject)))) {
956 // it matched, so preserve onto res.
957 res.scratchObject = rop1.scratchObject;
958 }
959 return res;
960 } else if (BC2IR.hasLessConservativeGuard(rop1, rop2)) {
961 if (IRGenOptions.DBG_OPERAND_LATTICE) {
962 VM.sysWrite("Operands are registers of compatible type and flags but with incompatible non-null guards\n");
963 }
964 return new RegisterOperand(reg, type1, rop1.getFlags(), rop1.isPreciseType(), rop1.isDeclaredType());
965 } else {
966 if (IRGenOptions.DBG_OPERAND_LATTICE) {
967 VM.sysWrite("match\n");
968 }
969 return op1;
970 }
971 } else {
972 if (IRGenOptions.DBG_OPERAND_LATTICE) {
973 VM.sysWrite("Incompatibly typed register operands...(" + type1 + ", " + type2 + ")...");
974 }
975 TypeReference resType = ClassLoaderProxy.findCommonSuperclass(type1, type2);
976 if (resType == null) {
977 if (IRGenOptions.DBG_OPERAND_LATTICE) {
978 VM.sysWrite("no common supertype, returning bottom\n");
979 }
980 return null; // bottom
981 } else {
982 if (IRGenOptions.DBG_OPERAND_LATTICE) {
983 VM.sysWrite("found common supertype\n");
984 }
985 RegisterOperand res = new RegisterOperand(reg, resType, rop1.getFlags(), false, false);
986 res.meetInheritableFlags(rop2);
987 res.clearPreciseType(); // invalid on res
988 res.clearDeclaredType(); // invalid on res
989 if (rop1.scratchObject instanceof Operand &&
990 rop2.scratchObject instanceof Operand &&
991 (((Operand) rop1.scratchObject).similar(((Operand) rop2.scratchObject)))) {
992 // it matched, so preserve onto res.
993 res.scratchObject = rop1.scratchObject;
994 }
995 return res;
996 }
997 }
998 } else {
999 if (op2 instanceof BC2IR.ReturnAddressOperand || op2 == BC2IR.DUMMY) {
1000 if (IRGenOptions.DBG_OPERAND_LATTICE) {
1001 VM.sysWrite("Incompatibly typed operands");
1002 }
1003 return null; // bottom
1004 }
1005 TypeReference type2 = op2.getType();
1006 if (type1 == type2 ||
1007 compatiblePrimitives(type1, type2) ||
1008 (ClassLoaderProxy.includesType(type1, type2) == OptConstants.YES)) {
1009 if (IRGenOptions.DBG_OPERAND_LATTICE) {
1010 VM.sysWrite("Compatibly typed register & other operand, checking flags...");
1011 }
1012 RegisterOperand res = rop1;
1013 if (res.isPreciseType() && type1 != type2) {
1014 res = res.copyU2U();
1015 res.clearPreciseType();
1016 }
1017 if ((rop1.scratchObject instanceof Operand) &&
1018 ((type2 == TypeReference.NULL_TYPE) ||
1019 (type2.isIntLikeType() && op2.asIntConstant().value == 0) ||
1020 (type2.isWordLikeType() && op2.asAddressConstant().value.isZero()) ||
1021 (type2.isLongType() && op2.asLongConstant().value == 0L))) {
1022 res = res.copyU2U();
1023 res.scratchObject = null;
1024 }
1025 if (IRGenOptions.DBG_OPERAND_LATTICE) {
1026 if (res == rop1) {
1027 VM.sysWrite("match\n");
1028 } else {
1029 VM.sysWrite("mismatch\n");
1030 }
1031 }
1032 return res;
1033 } else {
1034 if (IRGenOptions.DBG_OPERAND_LATTICE) {
1035 VM.sysWrite("Incompatibly typed register & other operand...(" + type1 + ", " + type2 + ")...");
1036 }
1037 TypeReference resType = ClassLoaderProxy.findCommonSuperclass(type1, type2);
1038 if (resType == null) {
1039 if (IRGenOptions.DBG_OPERAND_LATTICE) {
1040 VM.sysWrite("no common supertype, returning bottom\n");
1041 }
1042 return null; // bottom
1043 } else {
1044 if (IRGenOptions.DBG_OPERAND_LATTICE) {
1045 VM.sysWrite("found common supertype\n");
1046 }
1047 return new RegisterOperand(reg, resType);
1048 }
1049 }
1050 }
1051 }
1052
1053 // Step 5: op1 is some IRGEN operand
1054 if (op1.similar(op2)) {
1055 if (IRGenOptions.DBG_OPERAND_LATTICE) {
1056 VM.sysWrite("Compatible BC2IR.* operands\n");
1057 }
1058 return op1;
1059 } else {
1060 if (IRGenOptions.DBG_OPERAND_LATTICE) {
1061 VM.sysWrite("Incompatible BC2IR.* operands, returning bottom\n");
1062 }
1063 return null; // bottom
1064 }
1065 }
1066
1067 private static boolean compatiblePrimitives(TypeReference type1, TypeReference type2) {
1068 if (type1.isIntLikeType() && type2.isIntLikeType()) {
1069 if (type1.isIntType()) {
1070 return type2.isBooleanType() || type2.isByteType() || type2.isShortType() || type2.isIntType();
1071 }
1072 if (type1.isShortType()) {
1073 return type2.isBooleanType() || type2.isByteType() || type2.isShortType();
1074 }
1075 if (type1.isByteType()) {
1076 return type2.isBooleanType() || type2.isByteType();
1077 }
1078 if (type1.isBooleanType()) {
1079 return type2.isBooleanType();
1080 }
1081 }
1082 return false;
1083 }
1084
1085 }