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.Enumeration;
016    import org.jikesrvm.ArchitectureSpecificOpt.PhysicalRegisterSet;
017    import org.jikesrvm.compilers.opt.ir.IR;
018    import org.jikesrvm.compilers.opt.ir.Register;
019    
020    /**
021     * The register allocator currently caches a bunch of state in the IR;
022     * This class provides accessors to this state.
023     * <ul>
024     *   <li>TODO: Consider caching the state in a lookaside structure.
025     *   <li>TODO: Currently, the physical registers are STATIC! fix this.
026     * <ul>
027     */
028    public class RegisterAllocatorState {
029    
030      /**
031       *  Resets the physical register info
032       */
033      static void resetPhysicalRegisters(IR ir) {
034        PhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet();
035        for (Enumeration<Register> e = phys.enumerateAll(); e.hasMoreElements();) {
036          Register reg = e.nextElement();
037          reg.deallocateRegister();
038          reg.mapsToRegister = null;  // mapping from real to symbolic
039          //    putPhysicalRegResurrectList(reg, null);
040          reg.defList = null;
041          reg.useList = null;
042          setSpill(reg, 0);
043        }
044      }
045    
046      /**
047       * Special use of scratchObject field as "resurrect lists" for real registers
048       * TODO: use another field for safety; scratchObject is also used by
049       *  clan LinearScanLiveAnalysis
050       */
051      /*
052      static void putPhysicalRegResurrectList(Register r,
053                                              LinearScanLiveInterval li) {
054        if (VM.VerifyAssertions) VM._assert(r.isPhysical());
055        r.scratchObject = li;
056      }
057      */
058      /**
059       *
060       * Special use of scratchObject field as "resurrect lists" for real registers
061       * TODO: use another field for safety; scratchObject is also used by
062       *  clan LinearScanLiveAnalysis
063       */
064      /*
065      static LinearScanLiveInterval getPhysicalRegResurrectList(Register r) {
066        if (VM.VerifyAssertions) VM._assert(r.isPhysical());
067        return (LinearScanLiveInterval) r.scratchObject;
068      }
069      */
070      static void setSpill(Register reg, int spill) {
071        reg.spillRegister();
072        reg.scratch = spill;
073      }
074    
075      public static int getSpill(Register reg) {
076        return reg.scratch;
077      }
078    
079      /**
080       * Record that register A and register B are associated with each other
081       * in a bijection.<p>
082       *
083       * The register allocator uses this state to indicate that a symbolic
084       * register is presently allocated to a physical register.
085       */
086      static void mapOneToOne(Register A, Register B) {
087        Register aFriend = getMapping(A);
088        Register bFriend = getMapping(B);
089        if (aFriend != null) {
090          aFriend.mapsToRegister = null;
091        }
092        if (bFriend != null) {
093          bFriend.mapsToRegister = null;
094        }
095        A.mapsToRegister = B;
096        B.mapsToRegister = A;
097      }
098    
099      /**
100       * @return the register currently mapped 1-to-1 to r
101       */
102      static Register getMapping(Register r) {
103        return r.mapsToRegister;
104      }
105    
106      /**
107       * Clear any 1-to-1 mapping for register R.
108       */
109      static void clearOneToOne(Register r) {
110        if (r != null) {
111          Register s = getMapping(r);
112          if (s != null) {
113            s.mapsToRegister = null;
114          }
115          r.mapsToRegister = null;
116        }
117      }
118    }