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