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}