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