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