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.regalloc; 014 015import static org.jikesrvm.VM.NOT_REACHED; 016import static org.jikesrvm.compilers.opt.ir.Operators.BBEND; 017import static org.jikesrvm.compilers.opt.ir.Operators.IR_PROLOGUE; 018import static org.jikesrvm.compilers.opt.ir.Operators.IR_PROLOGUE_opcode; 019import static org.jikesrvm.compilers.opt.ir.Operators.LOWTABLESWITCH; 020import static org.jikesrvm.compilers.opt.ir.Operators.YIELDPOINT_OSR; 021import static org.jikesrvm.runtime.UnboxedSizeConstants.BYTES_IN_ADDRESS; 022 023import java.util.ArrayList; 024import java.util.Enumeration; 025import java.util.Iterator; 026 027import org.jikesrvm.VM; 028import org.jikesrvm.architecture.ArchConstants; 029import org.jikesrvm.architecture.StackFrameLayout; 030import org.jikesrvm.compilers.opt.OptimizingCompilerException; 031import org.jikesrvm.compilers.opt.ir.BasicBlock; 032import org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet; 033import org.jikesrvm.compilers.opt.ir.IR; 034import org.jikesrvm.compilers.opt.ir.IRTools; 035import org.jikesrvm.compilers.opt.ir.Instruction; 036import org.jikesrvm.compilers.opt.ir.Register; 037import org.jikesrvm.compilers.opt.ir.operand.Operand; 038import org.jikesrvm.compilers.opt.ir.operand.RegisterOperand; 039 040/** 041 * Class to manage the allocation of the "compiler-independent" portion of 042 * the stackframe. 043 */ 044public abstract class GenericStackManager extends IRTools { 045 046 /* 047 * Types of values stored in physical registers; 048 * These affect instruction selection for accessing 049 * the data 050 */ 051 public static final byte INT_VALUE = 0; 052 public static final byte DOUBLE_VALUE = 1; 053 public static final byte FLOAT_VALUE = 2; 054 public static final byte CONDITION_VALUE = 3; 055 056 protected static final boolean DEBUG = false; 057 protected static final boolean VERBOSE = false; 058 protected static final boolean VERBOSE_DEBUG = false; 059 060 /** 061 * Size of a word, in bytes 062 */ 063 protected static final int WORDSIZE = BYTES_IN_ADDRESS; 064 065 protected IR ir; 066 protected RegisterAllocatorState regAllocState; 067 protected int frameSize; 068 protected boolean allocFrame; 069 070 /** 071 * Object holding register preferences 072 */ 073 protected final GenericRegisterPreferences pref; 074 075 { 076 if (VM.BuildForIA32) { 077 pref = new org.jikesrvm.compilers.opt.regalloc.ia32.RegisterPreferences(); 078 } else { 079 if (VM.VerifyAssertions) VM._assert(VM.BuildForPowerPC); 080 pref = new org.jikesrvm.compilers.opt.regalloc.ppc.RegisterPreferences(); 081 } 082 } 083 084 GenericRegisterPreferences getPreferences() { 085 return pref; 086 } 087 088 /** 089 * Object holding register restrictions 090 */ 091 protected GenericRegisterRestrictions restrict; 092 093 GenericRegisterRestrictions getRestrictions() { 094 return restrict; 095 } 096 097 /** 098 * Spill pointer (in bytes) relative to the beginning of the 099 * stack frame (starts after the header). 100 */ 101 protected int spillPointer = StackFrameLayout.getStackFrameHeaderSize(); 102 103 /** 104 * Have we decided that a stack frame is required for this method? 105 */ 106 private boolean frameRequired; 107 108 /** 109 * Memory location (8 bytes) to be used for type conversions 110 */ 111 private int conversionOffset; 112 113 /** 114 * Memory location (4 bytes) to be used for caughtExceptions 115 */ 116 private int caughtExceptionOffset; 117 118 /** 119 * Is there a prologue yieldpoint in this method? 120 */ 121 private boolean prologueYieldpoint; 122 123 /** 124 * We will have to save and restore all non-volatile registers around 125 * system calls, to protect ourselve from malicious native code that may 126 * bash these registers. 127 * 128 * This field, when non-zero, holds the stack-frame offset reserved to 129 * hold this data. 130 */ 131 private int sysCallOffset = 0; 132 133 /** 134 * For each physical register, holds a ScratchRegister which records 135 * the current scratch assignment for the physical register. 136 */ 137 protected final ArrayList<ScratchRegister> scratchInUse = new ArrayList<ScratchRegister>(20); 138 139 /** 140 * An array which holds the spill location number used to stash nonvolatile 141 * registers. 142 */ 143 protected final int[] nonVolatileGPRLocation = new int[ArchConstants.getNumberOfGPRs()]; 144 protected final int[] nonVolatileFPRLocation = new int[ArchConstants.getNumberOfFPRs()]; 145 146 /** 147 * An array which holds the spill location number used to stash volatile 148 * registers in the SaveVolatile protocol. 149 */ 150 protected final int[] saveVolatileGPRLocation = new int[ArchConstants.getNumberOfGPRs()]; 151 protected final int[] saveVolatileFPRLocation = new int[ArchConstants.getNumberOfFPRs()]; 152 153 /** 154 * An object used to track adjustments to the GC maps induced by scratch 155 * registers 156 */ 157 protected ScratchMap scratchMap; 158 159 ScratchMap getScratchMap() { 160 return scratchMap; 161 } 162 163 /** 164 * Perform some architecture-specific initialization. 165 * 166 * @param ir the IR 167 */ 168 public abstract void initForArch(IR ir); 169 170 /** 171 * @param s the instruction to check 172 * @return whether the instruction is a system call? 173 */ 174 public abstract boolean isSysCall(Instruction s); 175 176 /** 177 * Given symbolic register r in instruction s, do we need to ensure that 178 * r is in a scratch register is s (as opposed to a memory operand) 179 * 180 * @param r the symbolic register 181 * @param s the instruction that has an occurrence of the register 182 * @return {@code true} if the symbolic register needs to be a scratch 183 * register 184 */ 185 public abstract boolean needScratch(Register r, Instruction s); 186 187 /** 188 * Allocates a new spill location and grows the 189 * frame size to reflect the new layout. 190 * 191 * @param type the type to spill 192 * @return the spill location 193 */ 194 public abstract int allocateNewSpillLocation(int type); 195 196 /** 197 * Cleans up some junk that's left in the IR after register allocation, 198 * and adds epilogue code. 199 */ 200 public abstract void cleanUpAndInsertEpilogue(); 201 202 /** 203 * Returns the size of the fixed portion of the stack. 204 * (in other words, the difference between the framepointer and 205 * the stackpointer after the prologue of the method completes). 206 * @return size in bytes of the fixed portion of the stackframe 207 */ 208 public abstract int getFrameFixedSize(); 209 210 /** 211 * Computes the number of stack words needed to hold nonvolatile 212 * registers. 213 * 214 * Side effects: 215 * <ul> 216 * <li> updates the OptCompiler structure 217 * <li> updates the <code>frameSize</code> field of this object 218 * <li> updates the <code>frameRequired</code> field of this object 219 * </ul> 220 */ 221 public abstract void computeNonVolatileArea(); 222 223 /** 224 * Inserts the prologue for a normal method. 225 */ 226 public abstract void insertNormalPrologue(); 227 228 /** 229 * Walk over the currently available scratch registers. 230 * 231 * <p>For any scratch register r which is def'ed by instruction s, 232 * spill r before s and remove r from the pool of available scratch 233 * registers. 234 * 235 * <p>For any scratch register r which is used by instruction s, 236 * restore r before s and remove r from the pool of available scratch 237 * registers. 238 * 239 * <p>For any scratch register r which has current contents symb, and 240 * symb is spilled to location M, and s defs M: the old value of symb is 241 * dead. Mark this. 242 * 243 * <p>Invalidate any scratch register assignments that are illegal in s. 244 * 245 * @param s the instruction to process 246 */ 247 public abstract void restoreScratchRegistersBefore(Instruction s); 248 249 /** 250 * In instruction s, replace all appearances of a symbolic register 251 * operand with uses of the appropriate spill location, as cached by the 252 * register allocator. 253 * 254 * @param s the instruction to mutate. 255 * @param symb the symbolic register operand to replace 256 */ 257 public abstract void replaceOperandWithSpillLocation(Instruction s, RegisterOperand symb); 258 259 /** 260 * Should we use information from linear scan in choosing scratch 261 * registers? 262 */ 263 private static boolean USE_LINEAR_SCAN = true; 264 265 /** 266 * We may rely on information from linear scan to choose scratch registers. 267 * If so, the following holds a pointer to some information from linear 268 * scan analysis. 269 */ 270 private ActiveSet activeSet = null; 271 272 /** 273 * Replaces all occurrences of register r1 in an instruction with register 274 * r2. 275 * 276 * Also, for any register r3 that is spilled to the same location as 277 * r1, replace r3 with r2. 278 * 279 * @param s instruction to process 280 * @param r1 register to replace 281 * @param r2 the replacement register 282 */ 283 private void replaceRegisterWithScratch(Instruction s, Register r1, Register r2) { 284 int spill1 = regAllocState.getSpill(r1); 285 for (Enumeration<Operand> e = s.getOperands(); e.hasMoreElements();) { 286 Operand op = e.nextElement(); 287 if (op != null) { 288 if (op.isRegister()) { 289 Register r3 = op.asRegister().getRegister(); 290 if (r3 == r1) { 291 op.asRegister().setRegister(r2); 292 } else if (regAllocState.getSpill(r3) == spill1) { 293 op.asRegister().setRegister(r2); 294 } 295 } 296 } 297 } 298 } 299 300 /** 301 * We will have to save and restore all non-volatile registers around 302 * system calls, to protect ourselves from malicious native code that may 303 * bash these registers. Call this routine before register allocation 304 * in order to allocate space on the stack frame to store these 305 * registers. 306 * 307 * @param n the number of GPR registers to save and restore. 308 * @return the offset into the stack where n*4 contiguous words are 309 * reserved 310 */ 311 public int allocateSpaceForSysCall(int n) { 312 int bytes = n * WORDSIZE; 313 if (sysCallOffset == 0) { 314 sysCallOffset = allocateOnStackFrame(bytes); 315 } 316 return sysCallOffset; 317 } 318 319 /** 320 * We will have to save and restore all non-volatile registers around 321 * system calls, to protect ourselves from malicious native code that may 322 * bash these registers. Call this routine before register allocation 323 * in order to get the stack-frame offset previously reserved for this 324 * data. 325 * 326 * @return the offset into the stack where n*4 contiguous words are 327 * reserved 328 */ 329 public int getOffsetForSysCall() { 330 return sysCallOffset; 331 } 332 333 /** 334 * Spills the contents of a scratch register to memory before 335 * instruction s. 336 * 337 * @param scratch the scratch register to spill 338 * @param s the instruction before which the spill needs to occur 339 */ 340 protected void unloadScratchRegisterBefore(Instruction s, ScratchRegister scratch) { 341 // if the scratch register is not dirty, don't need to write anything, 342 // since the stack holds the current value 343 if (!scratch.isDirty()) return; 344 345 // spill the contents of the scratch register 346 Register scratchContents = scratch.currentContents; 347 if (scratchContents != null) { 348 int location = regAllocState.getSpill(scratchContents); 349 insertSpillBefore(s, scratch.scratch, getValueType(scratchContents), location); 350 } 351 352 } 353 354 /** 355 * Restores the contents of a scratch register before instruction s if 356 * necessary. 357 * 358 * @param scratch the scratch register whose contents may need to be restored 359 * @param s the instruction before which the restores needs to occur 360 */ 361 protected void reloadScratchRegisterBefore(Instruction s, ScratchRegister scratch) { 362 if (scratch.hadToSpill()) { 363 // Restore the live contents into the scratch register. 364 int location = regAllocState.getSpill(scratch.scratch); 365 insertUnspillBefore(s, scratch.scratch, getValueType(scratch.scratch), location); 366 } 367 } 368 369 /** 370 * @param s the instruction whose reserved scratch registers are of interest 371 * @return the scratch registers which are currently reserved 372 * for use in the instruction (may be an empty list but will never be {@code null}) 373 */ 374 private ArrayList<Register> getReservedScratchRegisters(Instruction s) { 375 ArrayList<Register> result = new ArrayList<Register>(3); 376 377 for (ScratchRegister sr : scratchInUse) { 378 if (sr.currentContents != null && appearsIn(sr.currentContents, s)) { 379 result.add(sr.scratch); 380 } 381 } 382 return result; 383 } 384 385 /** 386 * If there is a scratch register available which currently holds the 387 * value of symbolic register r, then return that scratch register.<p> 388 * 389 * Additionally, if there is a scratch register available which is 390 * mapped to the same stack location as r, then return that scratch 391 * register.<p> 392 * 393 * Else return {@code null}. 394 * 395 * @param r the symbolic register to hold 396 * @param s the instruction for which we need r in a register 397 * @return a register as described above or {@code null} 398 */ 399 private ScratchRegister getCurrentScratchRegister(Register r, Instruction s) { 400 for (ScratchRegister sr : scratchInUse) { 401 if (sr.currentContents == r) { 402 return sr; 403 } 404 int location = regAllocState.getSpill(sr.currentContents); 405 int location2 = regAllocState.getSpill(r); 406 if (location == location2) { 407 // OK. We're currently holding a different symbolic register r2 in 408 // a scratch register, and r2 is mapped to the same spill location 409 // as r. So, coopt the scratch register for r, instead. 410 Register r2 = sr.currentContents; 411 sr.currentContents = r; 412 scratchMap.endScratchInterval(sr.scratch, s); 413 scratchMap.endSymbolicInterval(r2, s); 414 scratchMap.beginScratchInterval(sr.scratch, s); 415 scratchMap.beginSymbolicInterval(r, sr.scratch, s); 416 return sr; 417 } 418 } 419 return null; 420 } 421 422 /** 423 * @param r the register to check 424 * @return the scratch register for r if it's currently in use as a scratch register, 425 * {@code null} otherwise 426 */ 427 private ScratchRegister getPhysicalScratchRegister(Register r) { 428 for (ScratchRegister sr : scratchInUse) { 429 if (sr.scratch == r) { 430 return sr; 431 } 432 } 433 return null; 434 } 435 436 /** 437 * Walk over the currently available scratch registers.<p> 438 * 439 * For any register which is dirty, note this in the scratch map for 440 * instruction s. 441 * 442 * @param s the instruction which needs an update in the scratch map 443 */ 444 private void markDirtyScratchRegisters(Instruction s) { 445 for (ScratchRegister scratch : scratchInUse) { 446 if (scratch.isDirty()) { 447 scratchMap.markDirty(s, scratch.currentContents); 448 } 449 } 450 } 451 452 /** 453 * Walk over the currently available scratch registers, and spill their 454 * contents to memory before instruction s. Also restore the correct live 455 * value for each scratch register. Normally, s should end a 456 * basic block.<p> 457 * 458 * SPECIAL CASE: If s is a return instruction, only restore the scratch 459 * registers that are used by s. The others are dead. 460 * 461 * @param s the instruction before which the scratch registers need to be 462 * restored 463 */ 464 private void restoreAllScratchRegistersBefore(Instruction s) { 465 for (Iterator<ScratchRegister> i = scratchInUse.iterator(); i.hasNext();) { 466 ScratchRegister scratch = i.next(); 467 468 // SPECIAL CASE: If s is a return instruction, only restore the 469 // scratch 470 // registers that are used by s. The others are dead. 471 if (!s.isReturn() || usedIn(scratch.scratch, s)) { 472 unloadScratchRegisterBefore(s, scratch); 473 reloadScratchRegisterBefore(s, scratch); 474 } 475 // update the scratch maps, even if the scratch registers are now 476 // dead. 477 if (VERBOSE_DEBUG) { 478 System.out.println("RALL: End scratch interval " + scratch.scratch + " " + s); 479 } 480 i.remove(); 481 scratchMap.endScratchInterval(scratch.scratch, s); 482 Register scratchContents = scratch.currentContents; 483 if (scratchContents != null) { 484 if (VERBOSE_DEBUG) { 485 System.out.println("RALL: End symbolic interval " + scratchContents + " " + s); 486 } 487 scratchMap.endSymbolicInterval(scratchContents, s); 488 } 489 } 490 } 491 492 /** 493 * @param r the register 494 * @param s the instruction 495 * @return {@code true} if the register is dead immediately before 496 * the instruction 497 */ 498 public boolean isDeadBefore(Register r, Instruction s) { 499 500 BasicInterval bi = activeSet.getBasicInterval(r, s); 501 // If there is no basic interval containing s, then r is dead before 502 // s. 503 if (bi == null) { 504 return true; 505 } else { 506 // If the basic interval begins at s, then r is dead before 507 // s. 508 return bi.getBegin() == regAllocState.getDFN(s); 509 } 510 } 511 512 /** 513 * Inserts code as needed so that after instruction s, the value of 514 * a symbolic register will be held in a particular scratch physical 515 * register. 516 * 517 * @param s the instruction after which the value will be held in scratch 518 * @param symb the register whose value needs to be held in scratch 519 * @param beCheap don't expend much effort optimizing scratch 520 * assignments 521 * @return the physical scratch register that holds the value 522 * after instruction s 523 */ 524 private ScratchRegister holdInScratchAfter(Instruction s, Register symb, boolean beCheap) { 525 526 // Get a scratch register. 527 ScratchRegister sr = getScratchRegister(symb, s, beCheap); 528 529 // make the scratch register available to hold the new 530 // symbolic register 531 Register current = sr.currentContents; 532 533 if (current != null && current != symb) { 534 int location = regAllocState.getSpill(current); 535 int location2 = regAllocState.getSpill(symb); 536 if (location != location2) { 537 insertSpillBefore(s, sr.scratch, getValueType(current), location); 538 } 539 } 540 541 // Record the new contents of the scratch register 542 sr.currentContents = symb; 543 544 return sr; 545 } 546 547 /** 548 * @param symb the symbolic register that we want to assign 549 * @param phys the scratch register 550 * @param s the instruction where the assignment would take place 551 * @return whether it's legal to assign the symbolic register to the scratch register 552 * in the given instruction 553 */ 554 protected boolean isLegal(Register symb, Register phys, Instruction s) { 555 // If the physical scratch register already appears in s, so we can't 556 // use it as a scratch register for another value. 557 if (appearsIn(phys, s)) return false; 558 559 // Check register restrictions for symb. 560 if (getRestrictions().isForbidden(symb, phys, s)) return false; 561 562 // Further assure legality for all other symbolic registers in symb 563 // which are mapped to the same spill location as symb. 564 int location = regAllocState.getSpill(symb); 565 for (Enumeration<Operand> e = s.getOperands(); e.hasMoreElements();) { 566 Operand op = e.nextElement(); 567 if (op.isRegister()) { 568 Register r = op.asRegister().getRegister(); 569 if (r.isSymbolic()) { 570 if (location == regAllocState.getSpill(r)) { 571 if (getRestrictions().isForbidden(r, phys, s)) { 572 return false; 573 } 574 } 575 } 576 } 577 } 578 579 // Otherwise, all is kosher. 580 return true; 581 } 582 583 /** 584 * Gets a scratch register to hold symbolic register symb in instruction 585 * s. 586 * 587 * @param symb the symbolic register to hold 588 * @param s the instruction where the scratch register is needed 589 * @param beCheap don't expend too much effort 590 * @return a scratch register, never {@code null} 591 */ 592 private ScratchRegister getScratchRegister(Register symb, Instruction s, boolean beCheap) { 593 594 ScratchRegister r = getCurrentScratchRegister(symb, s); 595 if (r != null) { 596 // symb is currently assigned to scratch register r 597 if (isLegal(symb, r.scratch, s)) { 598 if (r.currentContents != symb) { 599 // we're reusing a scratch register based on the fact that symb 600 // shares a spill location with r.currentContents. However, 601 // update the mapping information. 602 if (r.currentContents != null) { 603 if (VERBOSE_DEBUG) { 604 System.out.println("GSR: End symbolic interval " + r.currentContents + " " + s); 605 } 606 scratchMap.endSymbolicInterval(r.currentContents, s); 607 } 608 if (VERBOSE_DEBUG) { 609 System.out.println("GSR: Begin symbolic interval " + symb + " " + r.scratch + " " + s); 610 } 611 scratchMap.beginSymbolicInterval(symb, r.scratch, s); 612 } 613 return r; 614 } 615 } 616 617 // if we get here, either there is no current scratch assignment, or 618 // the current assignment is illegal. Find a new scratch register. 619 ScratchRegister result = null; 620 if (beCheap || activeSet == null) { 621 result = getFirstAvailableScratchRegister(symb, s); 622 } else { 623 result = getScratchRegisterUsingIntervals(symb, s); 624 } 625 626 // Record that we will touch the scratch register. 627 result.scratch.touchRegister(); 628 return result; 629 } 630 631 /** 632 * Finds a register which can serve as a scratch 633 * register for symbolic register r in instruction s. 634 * 635 * <p> Inserts spills if necessary to ensure that the returned scratch 636 * register is free for use. 637 * 638 * @param r the symbolic register that needs a scratch 639 * @param s the instruction where the scratch register is needed 640 * @return a scratch register, never {@code null} 641 */ 642 private ScratchRegister getScratchRegisterUsingIntervals(Register r, Instruction s) { 643 ArrayList<Register> reservedScratch = getReservedScratchRegisters(s); 644 645 Register phys = null; 646 if (r.isFloatingPoint()) { 647 phys = getFirstDeadFPRNotUsedIn(r, s, reservedScratch); 648 } else { 649 phys = getFirstDeadGPRNotUsedIn(r, s, reservedScratch); 650 } 651 652 // if the version above failed, default to the dumber heuristics 653 if (phys == null) { 654 if (r.isFloatingPoint()) { 655 phys = getFirstFPRNotUsedIn(r, s, reservedScratch); 656 } else { 657 phys = getFirstGPRNotUsedIn(r, s, reservedScratch); 658 } 659 } 660 return createScratchBefore(regAllocState, s, phys, r); 661 } 662 663 /** 664 * Finds the first available register which can serve as a scratch 665 * register for symbolic register r in instruction s. 666 * 667 * <p> Inserts spills if necessary to ensure that the returned scratch 668 * register is free for use. 669 * 670 * @param r the symbolic register that needs a scratch 671 * @param s the instruction where the scratch register is needed 672 * @return a scratch register, never {@code null} 673 */ 674 private ScratchRegister getFirstAvailableScratchRegister(Register r, Instruction s) { 675 ArrayList<Register> reservedScratch = getReservedScratchRegisters(s); 676 677 Register phys = null; 678 if (r.isFloatingPoint()) { 679 phys = getFirstFPRNotUsedIn(r, s, reservedScratch); 680 } else { 681 phys = getFirstGPRNotUsedIn(r, s, reservedScratch); 682 } 683 return createScratchBefore(regAllocState, s, phys, r); 684 } 685 686 /** 687 * Assigns symbolic register symb to a physical register, and inserts code 688 * before instruction s to load the register from the appropriate stack 689 * location. 690 * 691 * @param s the instruction before which the register needs to be loaded 692 * @param symb the symbolic register to be assigned to a scratch 693 * @param beCheap don't expend to much effort to optimize scratch 694 * assignments 695 * @return the physical register used to hold the value when it is 696 * loaded from the spill location 697 */ 698 private ScratchRegister moveToScratchBefore(Instruction s, Register symb, boolean beCheap) { 699 700 ScratchRegister sr = getScratchRegister(symb, s, beCheap); 701 702 Register scratchContents = sr.currentContents; 703 if (scratchContents != symb) { 704 if (scratchContents != null) { 705 // the scratch register currently holds a different 706 // symbolic register. 707 // spill the contents of the scratch register to free it up. 708 unloadScratchRegisterBefore(s, sr); 709 } 710 711 // Now load up the scratch register. 712 // since symbReg must have been previously spilled, get the spill 713 // location previous assigned to symbReg 714 int location = regAllocState.getSpill(symb); 715 insertUnspillBefore(s, sr.scratch, getValueType(symb), location); 716 717 // we have not yet written to sr, so mark it 'clean' 718 sr.setDirty(false); 719 720 } else { 721 // In this case the scratch register already holds the desired 722 // symbolic register. So: do nothing. 723 } 724 725 // Record the current contents of the scratch register 726 sr.currentContents = symb; 727 728 return sr; 729 } 730 731 /** 732 * Make physicals register r available to be used as a scratch register 733 * before instruction s. In instruction s, r will hold the value of 734 * register symb. 735 * @param regAllocState TODO 736 * @param s the instruction before which the scratch register will be created 737 * @param r the physical register to be used as scratch 738 * @param symb the symbolic register which needs a scratch register 739 * 740 * @return the scratch register that will hold the value 741 */ 742 private ScratchRegister createScratchBefore(RegisterAllocatorState regAllocState, Instruction s, Register r, Register symb) { 743 int type = GenericPhysicalRegisterSet.getPhysicalRegisterType(r); 744 int spillLocation = regAllocState.getSpill(r); 745 if (spillLocation <= 0) { 746 // no spillLocation yet assigned to the physical register. 747 // allocate a new location and assign it for the physical register 748 spillLocation = allocateNewSpillLocation(type); 749 regAllocState.setSpill(r, spillLocation); 750 } 751 752 ScratchRegister sr = getPhysicalScratchRegister(r); 753 if (sr == null) { 754 sr = new ScratchRegister(r, null); 755 scratchInUse.add(sr); 756 // Since this is a new scratch register, spill the old contents of 757 // r if necessary. 758 if (activeSet == null) { 759 insertSpillBefore(s, r, (byte) type, spillLocation); 760 sr.setHadToSpill(true); 761 } else { 762 if (!isDeadBefore(r, s)) { 763 insertSpillBefore(s, r, (byte) type, spillLocation); 764 sr.setHadToSpill(true); 765 } 766 } 767 } else { 768 // update mapping information 769 if (VERBOSE_DEBUG) { 770 System.out.println("CSB: " + " End scratch interval " + sr.scratch + " " + s); 771 } 772 scratchMap.endScratchInterval(sr.scratch, s); 773 Register scratchContents = sr.currentContents; 774 if (scratchContents != null) { 775 if (VERBOSE_DEBUG) { 776 System.out.println("CSB: " + " End symbolic interval " + sr.currentContents + " " + s); 777 } 778 scratchMap.endSymbolicInterval(sr.currentContents, s); 779 } 780 } 781 782 // update mapping information 783 if (VERBOSE_DEBUG) { 784 System.out.println("CSB: Begin scratch interval " + r + " " + s); 785 } 786 scratchMap.beginScratchInterval(r, s); 787 788 if (VERBOSE_DEBUG) { 789 System.out.println("CSB: Begin symbolic interval " + symb + " " + r + " " + s); 790 } 791 scratchMap.beginSymbolicInterval(symb, r, s); 792 793 return sr; 794 } 795 796 private boolean usesSpillLocation(Register r, Instruction s) { 797 int location = regAllocState.getSpill(r); 798 return usesSpillLocation(location, s); 799 } 800 801 private Register spillLocationUse(Register r, Instruction s) { 802 int location = regAllocState.getSpill(r); 803 return spillLocationUse(location, s); 804 } 805 806 private boolean definesSpillLocation(Register r, Instruction s) { 807 int location = regAllocState.getSpill(r); 808 return definesSpillLocation(location, s); 809 } 810 811 private boolean definesSpillLocation(int loc, Instruction s) { 812 for (Enumeration<Operand> e = s.getDefs(); e.hasMoreElements();) { 813 Operand op = e.nextElement(); 814 if (op != null && op.isRegister()) { 815 Register r = op.asRegister().getRegister(); 816 if (regAllocState.getSpill(r) == loc) { 817 return true; 818 } 819 } 820 } 821 return false; 822 } 823 824 private boolean usesSpillLocation(int loc, Instruction s) { 825 for (Enumeration<Operand> e = s.getUses(); e.hasMoreElements();) { 826 Operand op = e.nextElement(); 827 if (op != null && op.isRegister()) { 828 Register r = op.asRegister().getRegister(); 829 if (regAllocState.getSpill(r) == loc) { 830 return true; 831 } 832 } 833 } 834 return false; 835 } 836 837 /** 838 * Assuming instruction s uses the spill location loc, 839 * return the symbolic register that embodies that use.<p> 840 * 841 * Note that at most one such register can be used, since at most one 842 * live register can use a given spill location. 843 * 844 * @param s instruction to check 845 * @param loc spill location 846 * @return the symbolic register that belongs to the spill location 847 */ 848 private Register spillLocationUse(int loc, Instruction s) { 849 for (Enumeration<Operand> e = s.getUses(); e.hasMoreElements();) { 850 Operand op = e.nextElement(); 851 if (op != null && op.isRegister()) { 852 Register r = op.asRegister().getRegister(); 853 if (regAllocState.getSpill(r) == loc) { 854 return r; 855 } 856 } 857 } 858 OptimizingCompilerException.UNREACHABLE("NO Matching use"); 859 return null; 860 } 861 862 /** 863 * Returns a FPR that does not appear in instruction s, to be used as a 864 * scratch register to hold register r. 865 * Except, does NOT return any register that is a member of the reserved set. 866 * <p> 867 * @param r the register that needs a scratch register 868 * @param s the instruction for which the scratch register is needed 869 * @param reserved the registers that must not be used 870 * @return a free FPR 871 * @throws OptimizingCompilerException if no free FPR was found 872 */ 873 private Register getFirstFPRNotUsedIn(Register r, Instruction s, ArrayList<Register> reserved) { 874 GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet(); 875 876 // first try the volatiles 877 for (Enumeration<Register> e = phys.enumerateVolatileFPRs(); e.hasMoreElements();) { 878 Register p = e.nextElement(); 879 if (!appearsIn(p, s) && !p.isPinned() && !reserved.contains(p) && isLegal(r, p, s)) { 880 return p; 881 } 882 } 883 884 OptimizingCompilerException.TODO("Could not find a free FPR in spill situation"); 885 return null; 886 } 887 888 /** 889 * Return a FPR that does not appear in instruction s, and is dead 890 * before instruction s, to hold symbolic register r. 891 * Except, do NOT 892 * return any register that is a member of the reserved set. 893 * 894 * @param r the register that needs a scratch register 895 * @param s the instruction for which the scratch register is needed 896 * @param reserved the registers that must not be used 897 * @return {@code null} if no register found, a dead and unused FPR otherwise 898 */ 899 private Register getFirstDeadFPRNotUsedIn(Register r, Instruction s, ArrayList<Register> reserved) { 900 GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet(); 901 902 // first try the volatiles 903 for (Enumeration<Register> e = phys.enumerateVolatileFPRs(); e.hasMoreElements();) { 904 Register p = e.nextElement(); 905 if (!appearsIn(p, s) && !p.isPinned() && !reserved.contains(p)) { 906 if (isDeadBefore(p, s) && isLegal(r, p, s)) return p; 907 } 908 } 909 910 return null; 911 } 912 913 /** 914 * Return a GPR that does not appear in instruction s, to hold symbolic 915 * register r. 916 * Except, do NOT 917 * return any register that is a member of the reserved set. 918 * @param r the register that needs a scratch register 919 * @param s the instruction for which the scratch register is needed 920 * @param reserved the registers that must not be used 921 * @return a free GPR 922 */ 923 private Register getFirstGPRNotUsedIn(Register r, Instruction s, ArrayList<Register> reserved) { 924 GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet(); 925 // first try the volatiles 926 for (Enumeration<Register> e = phys.enumerateVolatileGPRs(); e.hasMoreElements();) { 927 Register p = e.nextElement(); 928 if (!appearsIn(p, s) && !p.isPinned() && !reserved.contains(p) && isLegal(r, p, s)) { 929 return p; 930 } 931 } 932 // next try the non-volatiles. We allocate the nonvolatiles backwards 933 for (Enumeration<Register> e = phys.enumerateNonvolatileGPRsBackwards(); e.hasMoreElements();) { 934 Register p = e.nextElement(); 935 if (!appearsIn(p, s) && !p.isPinned() && !reserved.contains(p) && isLegal(r, p, s)) { 936 return p; 937 } 938 } 939 OptimizingCompilerException.TODO("Could not find a free GPR in spill situation"); 940 return null; 941 } 942 943 /** 944 * Return a GPR that does not appear in instruction s, and is dead 945 * before instruction s, to hold symbolic register r. 946 * Except, do NOT 947 * return any register that is a member of the reserved set. 948 * @param r the register that needs a scratch register 949 * @param s the instruction for which the scratch register is needed 950 * @param reserved the registers that must not be used 951 * @return {@code null} if no register found, a dead and unused GPR otherwise 952 */ 953 private Register getFirstDeadGPRNotUsedIn(Register r, Instruction s, ArrayList<Register> reserved) { 954 GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet(); 955 // first try the volatiles 956 for (Enumeration<Register> e = phys.enumerateVolatileGPRs(); e.hasMoreElements();) { 957 Register p = e.nextElement(); 958 if (!appearsIn(p, s) && !p.isPinned() && !reserved.contains(p)) { 959 if (isDeadBefore(p, s) && isLegal(r, p, s)) return p; 960 } 961 } 962 // next try the non-volatiles. We allocate the nonvolatiles backwards 963 for (Enumeration<Register> e = phys.enumerateNonvolatileGPRsBackwards(); e.hasMoreElements();) { 964 Register p = e.nextElement(); 965 if (!appearsIn(p, s) && !p.isPinned() && !reserved.contains(p)) { 966 if (isDeadBefore(p, s) && isLegal(r, p, s)) return p; 967 } 968 } 969 return null; 970 } 971 972 private boolean appearsIn(Register r, Instruction s) { 973 for (Enumeration<Operand> e = s.getOperands(); e.hasMoreElements();) { 974 Operand op = e.nextElement(); 975 if (op != null && op.isRegister()) { 976 if (op.asRegister().getRegister().number == r.number) { 977 return true; 978 } 979 } 980 } 981 if (VM 982 .BuildForIA32 && 983 r.isFloatingPoint() && 984 (s.operator().isFNInit() || s.operator().isFClear())) { 985 return true; 986 } 987 988 // Assume that all volatile registers 'appear' in all call 989 // instructions 990 return s.isCall() && !s.operator().isCallSaveVolatile() && r.isVolatile(); 991 } 992 993 /** 994 * @param s the instruction to check 995 * @param instructionsBB the block that contains the instruction 996 * @return whether the instruction is s a PEI (potentially excepting 997 * instruction, i.e. it can throw an exception) with a reachable catch 998 * block 999 */ 1000 private boolean isPEIWithCatch(Instruction s, BasicBlock instructionsBB) { 1001 if (s.isPEI()) { 1002 // TODO: add a more efficient accessor on BasicBlock to 1003 // determine whether there's a catch block for a particular 1004 // instruction. 1005 if (instructionsBB.getApplicableExceptionalOut(s).hasMoreElements()) { 1006 return true; 1007 } 1008 } 1009 return false; 1010 } 1011 1012 /** 1013 * @param n number of the non-volatile GPR 1014 * @return the offset from the frame pointer for the place to store the 1015 * nth nonvolatile GPR. 1016 */ 1017 protected int getNonvolatileGPROffset(int n) { 1018 return nonVolatileGPRLocation[n]; 1019 } 1020 1021 /** 1022 * @param n number of the non-volatile FPR 1023 * @return the offset from the frame pointer for the place to store the 1024 * nth nonvolatile FPR. 1025 */ 1026 protected int getNonvolatileFPROffset(int n) { 1027 return nonVolatileFPRLocation[n]; 1028 } 1029 1030 /** 1031 * PROLOGUE/EPILOGUE. Note: This must be done after register allocation! 1032 */ 1033 public final void insertPrologueAndEpilogue() { 1034 insertPrologue(); 1035 cleanUpAndInsertEpilogue(); 1036 } 1037 1038 private void insertPrologue() { 1039 // compute the number of stack words needed to hold nonvolatile 1040 // registers 1041 computeNonVolatileArea(); 1042 1043 if (frameIsRequired()) { 1044 insertNormalPrologue(); 1045 } else { 1046 Instruction inst = ir.firstInstructionInCodeOrder().nextInstructionInCodeOrder(); 1047 if (VM.VerifyAssertions) VM._assert(inst.getOpcode() == IR_PROLOGUE_opcode); 1048 inst.remove(); 1049 ir.MIRInfo.gcIRMap.delete(inst); 1050 } 1051 } 1052 1053 /** 1054 * After register allocation, go back through the IR and insert 1055 * compensating code to deal with spills. 1056 */ 1057 public void insertSpillCode() { 1058 insertSpillCode(null); 1059 } 1060 1061 /** 1062 * After register allocation, go back through the IR and insert 1063 * compensating code to deal with spills. 1064 * 1065 * @param set information from linear scan analysis (may be {@code null}) 1066 */ 1067 public void insertSpillCode(ActiveSet set) { 1068 if (USE_LINEAR_SCAN) { 1069 activeSet = set; 1070 } 1071 1072 if (VERBOSE_DEBUG) { 1073 System.out.println("INSERT SPILL CODE:"); 1074 } 1075 1076 // walk over each instruction in the IR 1077 for (Enumeration<BasicBlock> blocks = ir.getBasicBlocks(); blocks.hasMoreElements();) { 1078 BasicBlock bb = blocks.nextElement(); 1079 1080 // If the following is true, don't expend effort trying to 1081 // optimize scratch assignements 1082 boolean beCheap = (ir.options.FREQ_FOCUS_EFFORT && bb.getInfrequent()); 1083 1084 for (Enumeration<Instruction> e = bb.forwardInstrEnumerator(); e.hasMoreElements();) { 1085 Instruction s = e.nextElement(); 1086 if (VERBOSE_DEBUG) { 1087 System.out.println(s); 1088 } 1089 1090 // If any scratch registers are currently in use, but use physical 1091 // registers that appear in s, then free the scratch register. 1092 restoreScratchRegistersBefore(s); 1093 1094 // we must spill all scratch registers before leaving this basic block 1095 if (s.operator() == BBEND || isPEIWithCatch(s, bb) || s.isBranch() || s.isReturn()) { 1096 restoreAllScratchRegistersBefore(s); 1097 } 1098 1099 // If s is a GC point, and scratch register r currently caches the 1100 // value of symbolic symb, and r is dirty: Then update the GC map to 1101 // account for the fact that symb's spill location does not 1102 // currently hold a valid reference. 1103 if (s.isGCPoint()) { 1104 // note that if we're being cheap, no scratch registers are 1105 // currently dirty, since we've restored them all. 1106 markDirtyScratchRegisters(s); 1107 } 1108 1109 // Walk over each operand and insert the appropriate spill code. 1110 // for the operand. 1111 for (Enumeration<Operand> ops = s.getOperands(); ops.hasMoreElements();) { 1112 Operand op = ops.nextElement(); 1113 if (op != null && op.isRegister()) { 1114 Register r = op.asRegister().getRegister(); 1115 if (!r.isPhysical()) { 1116 // Is r currently assigned to a scratch register? 1117 // Note that if we're being cheap, the answer is always no (null) 1118 ScratchRegister scratch = getCurrentScratchRegister(r, s); 1119 if (VERBOSE_DEBUG) { 1120 System.out.println(r + " SCRATCH " + scratch); 1121 } 1122 if (scratch != null) { 1123 // r is currently assigned to a scratch register. Continue to 1124 // use the same scratch register. 1125 boolean defined = definedIn(r, s) || definesSpillLocation(r, s); 1126 if (defined) { 1127 scratch.setDirty(true); 1128 } 1129 replaceRegisterWithScratch(s, r, scratch.scratch); 1130 } else { 1131 // r is currently NOT assigned to a scratch register. 1132 // Do we need to create a new scratch register to hold r? 1133 // Note that we never need scratch floating point register 1134 // for FMOVs, since we already have a scratch stack location 1135 // reserved. 1136 // If we're being cheap, then always create a new scratch register. 1137 if (needScratch(r, s)) { 1138 // We must create a new scratch register. 1139 boolean used = usedIn(r, s) || usesSpillLocation(r, s); 1140 boolean defined = definedIn(r, s) || definesSpillLocation(r, s); 1141 if (used) { 1142 if (!usedIn(r, s)) { 1143 Register r2 = spillLocationUse(r, s); 1144 scratch = moveToScratchBefore(s, r2, beCheap); 1145 if (VERBOSE_DEBUG) { 1146 System.out.println("MOVED TO SCRATCH BEFORE " + r2 + " " + scratch); 1147 } 1148 } else { 1149 scratch = moveToScratchBefore(s, r, beCheap); 1150 if (VERBOSE_DEBUG) { 1151 System.out.println("MOVED TO SCRATCH BEFORE " + r + " " + scratch); 1152 } 1153 } 1154 } 1155 if (defined) { 1156 scratch = holdInScratchAfter(s, r, beCheap); 1157 scratch.setDirty(true); 1158 if (VERBOSE_DEBUG) { 1159 System.out.println("HELD IN SCRATCH AFTER" + r + " " + scratch); 1160 } 1161 } 1162 // replace the register in the target instruction. 1163 replaceRegisterWithScratch(s, r, scratch.scratch); 1164 } else { 1165 if (s.operator() != YIELDPOINT_OSR) { 1166 if (VM.BuildForIA32) { 1167 // No need to use a scratch register here. 1168 replaceOperandWithSpillLocation(s, op.asRegister()); 1169 } else { 1170 if (VM.VerifyAssertions) VM._assert(NOT_REACHED); 1171 } 1172 } 1173 } 1174 } 1175 } 1176 } 1177 } 1178 1179 // deal with sys calls that may bash non-volatiles 1180 if (isSysCall(s)) { 1181 if (VM.BuildForIA32) { 1182 org.jikesrvm.compilers.opt.regalloc.ia32.CallingConvention.saveNonvolatilesAroundSysCall(s, ir); 1183 } else { 1184 if (VM.VerifyAssertions) VM._assert(VM.BuildForPowerPC); 1185 org.jikesrvm.compilers.opt.regalloc.ppc.CallingConvention.saveNonvolatilesAroundSysCall(s, ir); 1186 } 1187 } 1188 } 1189 } 1190 } 1191 1192 /** 1193 * Insert a spill of a physical register before instruction s. 1194 * 1195 * @param s the instruction before which the spill should occur 1196 * @param r the register (should be physical) to spill 1197 * @param type one of INT_VALUE, FLOAT_VALUE, DOUBLE_VALUE, or 1198 * CONDITION_VALUE 1199 * @param location the spill location 1200 */ 1201 public abstract void insertSpillBefore(Instruction s, Register r, byte type, int location); 1202 1203 /** 1204 * Insert a spill of a physical register after instruction s. 1205 * 1206 * @param s the instruction after which the spill should occur 1207 * @param r the register (should be physical) to spill 1208 * @param type one of INT_VALUE, FLOAT_VALUE, DOUBLE_VALUE, or 1209 * CONDITION_VALUE 1210 * @param location the spill location 1211 */ 1212 public final void insertSpillAfter(Instruction s, Register r, byte type, int location) { 1213 insertSpillBefore(s.nextInstructionInCodeOrder(), r, type, location); 1214 } 1215 1216 /** 1217 * Insert a load of a physical register from a spill location before 1218 * instruction s. 1219 * 1220 * @param s the instruction before which the spill should occur 1221 * @param r the register (should be physical) to spill 1222 * @param type one of INT_VALUE, FLOAT_VALUE, DOUBLE_VALUE, or 1223 * CONDITION_VALUE 1224 * @param location the spill location 1225 */ 1226 public abstract void insertUnspillBefore(Instruction s, Register r, byte type, int location); 1227 1228 /** 1229 * Insert a load of a physical register from a spill location before 1230 * instruction s. 1231 * 1232 * @param s the instruction before which the spill should occur 1233 * @param r the register (should be physical) to spill 1234 * @param type one of INT_VALUE, FLOAT_VALUE, DOUBLE_VALUE, or 1235 * CONDITION_VALUE 1236 * @param location the spill location 1237 */ 1238 public final void insertUnspillAfter(Instruction s, Register r, byte type, int location) { 1239 insertUnspillBefore(s.nextInstructionInCodeOrder(), r, type, location); 1240 } 1241 1242 /** 1243 * @return {@code true} if and only if a stack frame 1244 * must be allocated for this method 1245l */ 1246 protected boolean frameIsRequired() { 1247 return frameRequired; 1248 } 1249 1250 /** 1251 * Records that we need a stack frame for this method. 1252 */ 1253 protected void setFrameRequired() { 1254 frameRequired = true; 1255 } 1256 1257 /** 1258 * @return {@code true} if and only if this IR has a prologue yieldpoint 1259 */ 1260 protected boolean hasPrologueYieldpoint() { 1261 return prologueYieldpoint; 1262 } 1263 1264 /** 1265 * Ensure that there's enough space for passing parameters. We need 1266 * {@code size - STACKFRAME_HEADER_SIZE} bytes. 1267 * 1268 * @param s space needed for parameters 1269 */ 1270 public void allocateParameterSpace(int s) { 1271 if (spillPointer < s) { 1272 spillPointer = s; 1273 frameRequired = true; 1274 } 1275 } 1276 1277 /** 1278 * Allocates the specified number of bytes in the stackframe, 1279 * returning the offset to the start of the allocated space. 1280 * 1281 * @param size the number of bytes to allocate 1282 * @return offset to the start of the allocated space. 1283 */ 1284 public int allocateOnStackFrame(int size) { 1285 int free = spillPointer; 1286 spillPointer += size; 1287 frameRequired = true; 1288 return free; 1289 } 1290 1291 /** 1292 * We encountered a magic (get/set framepointer) that is going to force 1293 * us to actually create the stack frame. 1294 */ 1295 public void forceFrameAllocation() { 1296 frameRequired = true; 1297 } 1298 1299 /** 1300 * We encountered a float/int conversion that uses 1301 * the stack as temporary storage. 1302 * 1303 * @return offset to the start of the allocated space 1304 */ 1305 public int allocateSpaceForConversion() { 1306 if (conversionOffset == 0) { 1307 conversionOffset = allocateOnStackFrame(8); 1308 } 1309 return conversionOffset; 1310 } 1311 1312 /** 1313 * We encountered a catch block that actually uses its caught 1314 * exception object; allocate a stack slot for the exception delivery 1315 * code to use to pass the exception object to us. 1316 * 1317 * @return offset to the start of the allocated space 1318 */ 1319 public int allocateSpaceForCaughtException() { 1320 if (caughtExceptionOffset == 0) { 1321 caughtExceptionOffset = allocateOnStackFrame(BYTES_IN_ADDRESS); 1322 } 1323 return caughtExceptionOffset; 1324 } 1325 1326 /** 1327 * Called as part of the register allocator startup. 1328 * <ol> 1329 * <li>examine the IR to determine whether or not we need to 1330 * allocate a stack frame</li> 1331 * <li>given that decison, determine whether or not we need to have 1332 * prologue/epilogue yieldpoints. If we don't need them, remove them. 1333 * Set up register preferences.</li> 1334 * <li>initialization code for the old RegisterManager</li> 1335 * <li>save caughtExceptionOffset where the exception deliverer can find it</li> 1336 * <li>initialize the restrictions object</li> 1337 * </ol> 1338 * @param ir the IR 1339 */ 1340 public void prepare(IR ir) { 1341 // (1) if we haven't yet committed to a stack frame we 1342 // will look for operators that would require a stack frame 1343 // - LOWTABLESWITCH 1344 // - a GC Point, except for YieldPoints or IR_PROLOGUE 1345 boolean preventYieldPointRemoval = false; 1346 if (!frameRequired) { 1347 for (Instruction s = ir.firstInstructionInCodeOrder(); s != null; s = s.nextInstructionInCodeOrder()) { 1348 if (s.operator() == LOWTABLESWITCH) { 1349 // uses BL to get pc relative addressing. 1350 frameRequired = true; 1351 preventYieldPointRemoval = true; 1352 break; 1353 } else if (s.isGCPoint() && !s.isYieldPoint() && s.operator() != IR_PROLOGUE) { 1354 // frame required for GCpoints that are not yield points 1355 // or IR_PROLOGUE, which is the stack overflow check 1356 frameRequired = true; 1357 preventYieldPointRemoval = true; 1358 break; 1359 } 1360 } 1361 } 1362 1363 // (2) 1364 // In non-adaptive configurations we can omit the yieldpoint if 1365 // the method contains exactly one basic block whose only successor 1366 // is the exit node. (The method may contain calls, but we believe that 1367 // in any program that isn't going to overflow its stack there must be 1368 // some invoked method that contains more than 1 basic block, and 1369 // we'll insert a yieldpoint in its prologue.) 1370 // In adaptive configurations the only methods we eliminate yieldpoints 1371 // from are those in which the yieldpoints are the only reason we would 1372 // have to allocate a stack frame for the method. Having more yieldpoints 1373 // gets us better sampling behavior. Thus, in the adaptive configuration 1374 // we only omit the yieldpoint in leaf methods with no PEIs that contain 1375 // exactly one basic block whose only successor is the exit node. 1376 // TODO: We may want to force yieldpoints in "large" PEI-free 1377 // single-block leaf methods (if any exist). 1378 // TODO: This is a kludge. Removing the yieldpoint removes 1379 // the adaptive system's ability to accurately sample program 1380 // behavior. Even if the method is absolutely trivial 1381 // eg boolean foo() { return false; }, we may still want to 1382 // sample it for the purposes of adaptive inlining. 1383 // On the other hand, the ability to do this inlining in some cases 1384 // may not be able to buy back having to create a stackframe 1385 // for all methods. 1386 // 1387 // Future feature: always insert a pseudo yield point that when taken will 1388 // create the stack frame on demand. 1389 1390 BasicBlock firstBB = ir.cfg.entry(); 1391 boolean isSingleBlock = firstBB.hasZeroIn() && firstBB.hasOneOut() && firstBB.pointsOut(ir.cfg.exit()); 1392 boolean removeYieldpoints = isSingleBlock && !preventYieldPointRemoval; 1393 1394 // In adaptive systems if we require a frame, we don't remove 1395 // any yield points 1396 if (VM.BuildForAdaptiveSystem && frameRequired) { 1397 removeYieldpoints = false; 1398 } 1399 1400 if (removeYieldpoints) { 1401 for (Instruction s = ir.firstInstructionInCodeOrder(); s != null; s = s.nextInstructionInCodeOrder()) { 1402 if (s.isYieldPoint()) { 1403 Instruction save = s; 1404 // get previous instruction, so we can continue 1405 // after we remove this instruction 1406 s = s.prevInstructionInCodeOrder(); 1407 save.remove(); 1408 ir.MIRInfo.gcIRMap.delete(save); 1409 } 1410 } 1411 prologueYieldpoint = false; 1412 } else { 1413 prologueYieldpoint = ir.method.isInterruptible(); 1414 frameRequired = true; 1415 } 1416 1417 // (3) initialization 1418 this.ir = ir; 1419 this.regAllocState = ir.MIRInfo.regAllocState; 1420 this.scratchMap = new ScratchMap(regAllocState); 1421 pref.initialize(ir); 1422 frameSize = spillPointer; 1423 initForArch(ir); 1424 1425 // (4) save caughtExceptionOffset where the exception deliverer can find it 1426 ir.compiledMethod.setUnsignedExceptionOffset(caughtExceptionOffset); 1427 1428 // (5) initialize the restrictions object 1429 if (VM.BuildForIA32) { 1430 restrict = new org.jikesrvm.compilers.opt.regalloc.ia32.RegisterRestrictions(ir.regpool.getPhysicalRegisterSet()); 1431 } else { 1432 if (VM.VerifyAssertions) VM._assert(VM.BuildForPowerPC); 1433 restrict = new org.jikesrvm.compilers.opt.regalloc.ppc.RegisterRestrictions(ir.regpool.getPhysicalRegisterSet()); 1434 } 1435 } 1436 1437 /** 1438 * Sets up register restrictions. 1439 * 1440 * @param ir the IR which will get the restrictions 1441 */ 1442 public final void computeRestrictions(IR ir) { 1443 restrict.init(ir); 1444 } 1445 1446 /** 1447 * Find an volatile register to allocate starting at the reg corresponding 1448 * to the symbolic register passed 1449 * @param symbReg the place to start the search 1450 * @return the allocated register or null 1451 */ 1452 public final Register allocateVolatileRegister(Register symbReg) { 1453 GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet(); 1454 1455 int physType = GenericPhysicalRegisterSet.getPhysicalRegisterType(symbReg); 1456 for (Enumeration<Register> e = phys.enumerateVolatiles(physType); e.hasMoreElements();) { 1457 Register realReg = e.nextElement(); 1458 if (realReg.isAvailable()) { 1459 realReg.allocateToRegister(symbReg); 1460 if (DEBUG) VM.sysWrite(" volat." + realReg + " to symb " + symbReg + '\n'); 1461 return realReg; 1462 } 1463 } 1464 return null; 1465 } 1466 1467 /** 1468 * Given a symbolic register, return a code that indicates the type 1469 * of the value stored in the register. 1470 * Note: This routine returns INT_VALUE for longs 1471 * 1472 * @param r a symbolic register 1473 * @return one of INT_VALUE, FLOAT_VALUE, DOUBLE_VALUE, CONDITION_VALUE 1474 */ 1475 public final byte getValueType(Register r) { 1476 if (r.isInteger() || r.isLong() || r.isAddress()) { 1477 return INT_VALUE; 1478 } else if (r.isCondition()) { 1479 return CONDITION_VALUE; 1480 } else if (r.isDouble()) { 1481 return DOUBLE_VALUE; 1482 } else if (r.isFloat()) { 1483 return FLOAT_VALUE; 1484 } else { 1485 throw new OptimizingCompilerException("getValueType: unsupported " + r); 1486 } 1487 } 1488 1489 protected static int align(int number, int alignment) { 1490 alignment--; 1491 return (number + alignment) & ~alignment; 1492 } 1493 1494 /** 1495 * Find a nonvolatile register to allocate starting at the reg corresponding 1496 * to the symbolic register passed. 1497 * <p> 1498 * TODO: Clean up this interface. 1499 * 1500 * @param symbReg the place to start the search 1501 * @return the allocated register or null 1502 */ 1503 public final Register allocateNonVolatileRegister(Register symbReg) { 1504 GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet(); 1505 int physType = GenericPhysicalRegisterSet.getPhysicalRegisterType(symbReg); 1506 for (Enumeration<Register> e = phys.enumerateNonvolatilesBackwards(physType); e.hasMoreElements();) { 1507 Register realReg = e.nextElement(); 1508 if (realReg.isAvailable()) { 1509 realReg.allocateToRegister(symbReg); 1510 return realReg; 1511 } 1512 } 1513 return null; 1514 } 1515 1516 /** 1517 * Class to represent a physical register currently allocated as a 1518 * scratch register. A scratch register is a register that is reserved 1519 * for use in spills and unspills. It is not available as a normal register 1520 * for the register allocation. 1521 */ 1522 protected static final class ScratchRegister { 1523 /** 1524 * The physical register used as scratch. 1525 */ 1526 public final Register scratch; 1527 1528 /** 1529 * The current contents of scratch 1530 */ 1531 public Register currentContents; 1532 1533 /** 1534 * Is this physical register currently dirty? (Must be written back to 1535 * memory?) 1536 */ 1537 private boolean dirty = false; 1538 1539 public boolean isDirty() { 1540 return dirty; 1541 } 1542 1543 public void setDirty(boolean b) { 1544 dirty = b; 1545 } 1546 1547 /** 1548 * Did we spill a value in order to free up this scratch register? 1549 */ 1550 private boolean spilledIt = false; 1551 1552 public boolean hadToSpill() { 1553 return spilledIt; 1554 } 1555 1556 public void setHadToSpill(boolean b) { 1557 spilledIt = b; 1558 } 1559 1560 public ScratchRegister(Register scratch, Register currentContents) { 1561 this.scratch = scratch; 1562 this.currentContents = currentContents; 1563 } 1564 1565 @Override 1566 public String toString() { 1567 String dirtyString = dirty ? "D" : "C"; 1568 return "SCRATCH<" + scratch + "," + currentContents + "," + dirtyString + ">"; 1569 } 1570 } 1571}