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