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}