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    }