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.HashMap;
018    import java.util.HashSet;
019    import org.jikesrvm.ArchitectureSpecificOpt.PhysicalRegisterSet;
020    import org.jikesrvm.VM;
021    import org.jikesrvm.compilers.opt.ir.BasicBlock;
022    import org.jikesrvm.compilers.opt.ir.IR;
023    import org.jikesrvm.compilers.opt.ir.Instruction;
024    import static org.jikesrvm.compilers.opt.ir.Operators.CALL_SAVE_VOLATILE;
025    import static org.jikesrvm.compilers.opt.ir.Operators.YIELDPOINT_OSR;
026    import org.jikesrvm.compilers.opt.ir.Register;
027    import org.jikesrvm.compilers.opt.util.BitSet;
028    
029    /**
030     * An instance of this class provides a mapping from symbolic register to
031     * a set of restricted registers.
032     * <p>
033     * Each architecture will subclass this in a class
034     * RegisterRestrictions.
035     */
036    public abstract class GenericRegisterRestrictions {
037      // for each symbolic register, the set of physical registers that are
038      // illegal for assignment
039      private final HashMap<Register, RestrictedRegisterSet> hash = new HashMap<Register, RestrictedRegisterSet>();
040    
041      // a set of symbolic registers that must not be spilled.
042      private final HashSet<Register> noSpill = new HashSet<Register>();
043    
044      protected final PhysicalRegisterSet phys;
045    
046      /**
047       * Default Constructor
048       */
049      protected GenericRegisterRestrictions(PhysicalRegisterSet phys) {
050        this.phys = phys;
051      }
052    
053      /**
054       * Record that the register allocator must not spill a symbolic
055       * register.
056       */
057      protected final void noteMustNotSpill(Register r) {
058        noSpill.add(r);
059      }
060    
061      /**
062       * Is spilling a register forbidden?
063       */
064      public final boolean mustNotSpill(Register r) {
065        return noSpill.contains(r);
066      }
067    
068      /**
069       * Record all the register restrictions dictated by an IR.
070       *
071       * PRECONDITION: the instructions in each basic block are numbered in
072       * increasing order before calling this.  The number for each
073       * instruction is stored in its <code>scratch</code> field.
074       */
075      public final void init(IR ir) {
076        // process each basic block
077        for (Enumeration<BasicBlock> e = ir.getBasicBlocks(); e.hasMoreElements();) {
078          BasicBlock b = e.nextElement();
079          processBlock(b);
080        }
081      }
082    
083      /**
084       * Record all the register restrictions dictated by live ranges on a
085       * particular basic block.<p>
086       *
087       * PRECONDITION: the instructions in each basic block are numbered in
088       * increasing order before calling this.  The number for each
089       * instruction is stored in its <code>scratch</code> field.
090       */
091      private void processBlock(BasicBlock bb) {
092        ArrayList<LiveIntervalElement> symbolic = new ArrayList<LiveIntervalElement>(20);
093        ArrayList<LiveIntervalElement> physical = new ArrayList<LiveIntervalElement>(20);
094    
095        // 1. walk through the live intervals and identify which correspond to
096        // physical and symbolic registers
097        for (Enumeration<LiveIntervalElement> e = bb.enumerateLiveIntervals(); e.hasMoreElements();) {
098          LiveIntervalElement li = e.nextElement();
099          Register r = li.getRegister();
100          if (r.isPhysical()) {
101            if (r.isVolatile() || r.isNonVolatile()) {
102              physical.add(li);
103            }
104          } else {
105            symbolic.add(li);
106          }
107        }
108    
109        // 2. walk through the live intervals for physical registers.  For
110        // each such interval, record the conflicts where the live range
111        // overlaps a live range for a symbolic register.
112        for (LiveIntervalElement phys : physical) {
113          for (LiveIntervalElement symb : symbolic) {
114            if (overlaps(phys, symb)) {
115              addRestriction(symb.getRegister(), phys.getRegister());
116            }
117          }
118        }
119    
120        // 3. Volatile registers used by CALL instructions do not appear in
121        // the liveness information.  Handle CALL instructions as a special
122        // case.
123        for (Enumeration<Instruction> ie = bb.forwardInstrEnumerator(); ie.hasMoreElements();) {
124          Instruction s = ie.nextElement();
125          if (s.operator.isCall() && s.operator != CALL_SAVE_VOLATILE) {
126            for (LiveIntervalElement symb : symbolic) {
127              if (contains(symb, s.scratch)) {
128                forbidAllVolatiles(symb.getRegister());
129              }
130            }
131          }
132    
133          // Before OSR points, we need to save all FPRs,
134          // On OptExecStateExtractor, all GPRs have to be recovered,
135          // but not FPRS.
136          //
137          if (s.operator == YIELDPOINT_OSR) {
138            for (LiveIntervalElement symb : symbolic) {
139              if (symb.getRegister().isFloatingPoint()) {
140                if (contains(symb, s.scratch)) {
141                  forbidAllVolatiles(symb.getRegister());
142                }
143              }
144            }
145          }
146        }
147    
148        // 3. architecture-specific restrictions
149        addArchRestrictions(bb, symbolic);
150      }
151    
152      /**
153       * Add architecture-specific register restrictions for a basic block.
154       * Override as needed.
155       *
156       * @param bb the basic block
157       * @param symbolics the live intervals for symbolic registers on this
158       * block
159       */
160      public void addArchRestrictions(BasicBlock bb, ArrayList<LiveIntervalElement> symbolics) {}
161    
162      /**
163       * Does a live range R contain an instruction with number n?<p>
164       *
165       * PRECONDITION: the instructions in each basic block are numbered in
166       * increasing order before calling this.  The number for each
167       * instruction is stored in its <code>scratch</code> field.
168       */
169      protected final boolean contains(LiveIntervalElement R, int n) {
170        int begin = -1;
171        int end = Integer.MAX_VALUE;
172        if (R.getBegin() != null) {
173          begin = R.getBegin().scratch;
174        }
175        if (R.getEnd() != null) {
176          end = R.getEnd().scratch;
177        }
178    
179        return ((begin <= n) && (n <= end));
180      }
181    
182      /**
183       * Do two live ranges overlap?<p>
184       *
185       * PRECONDITION: the instructions in each basic block are numbered in
186       * increasing order before calling this.  The number for each
187       * instruction is stored in its <code>scratch</code> field.
188       */
189      private boolean overlaps(LiveIntervalElement li1, LiveIntervalElement li2) {
190        // Under the following conditions: the live ranges do NOT overlap:
191        // 1. begin2 >= end1 > -1
192        // 2. begin1 >= end2 > -1
193        // Under all other cases, the ranges overlap
194    
195        int begin1 = -1;
196        int end1 = -1;
197        int begin2 = -1;
198        int end2 = -1;
199    
200        if (li1.getBegin() != null) {
201          begin1 = li1.getBegin().scratch;
202        }
203        if (li2.getEnd() != null) {
204          end2 = li2.getEnd().scratch;
205        }
206        if (end2 <= begin1 && end2 > -1) return false;
207    
208        if (li1.getEnd() != null) {
209          end1 = li1.getEnd().scratch;
210        }
211        if (li2.getBegin() != null) {
212          begin2 = li2.getBegin().scratch;
213        }
214        return end1 > begin2 || end1 <= -1;
215    
216      }
217    
218      /**
219       * Record that it is illegal to assign a symbolic register symb to any
220       * volatile physical registers
221       */
222      final void forbidAllVolatiles(Register symb) {
223        RestrictedRegisterSet r = hash.get(symb);
224        if (r == null) {
225          r = new RestrictedRegisterSet(phys);
226          hash.put(symb, r);
227        }
228        r.setNoVolatiles();
229      }
230    
231      /**
232       * Record that it is illegal to assign a symbolic register symb to any
233       * of a set of physical registers
234       */
235      protected final void addRestrictions(Register symb, BitSet set) {
236        RestrictedRegisterSet r = hash.get(symb);
237        if (r == null) {
238          r = new RestrictedRegisterSet(phys);
239          hash.put(symb, r);
240        }
241        r.addAll(set);
242      }
243    
244      /**
245       * Record that it is illegal to assign a symbolic register symb to a
246       * physical register p
247       */
248      protected final void addRestriction(Register symb, Register p) {
249        RestrictedRegisterSet r = hash.get(symb);
250        if (r == null) {
251          r = new RestrictedRegisterSet(phys);
252          hash.put(symb, r);
253        }
254        r.add(p);
255      }
256    
257      /**
258       * Return the set of restricted physical register for a given symbolic
259       * register. Return {@code null} if no restrictions.
260       */
261      final RestrictedRegisterSet getRestrictions(Register symb) {
262        return hash.get(symb);
263      }
264    
265      /**
266       * Is it forbidden to assign symbolic register symb to any volatile
267       * register?
268       * @return {@code true}: yes, all volatiles are forbidden.
269       *         {@code false} :maybe, maybe not
270       */
271      public final boolean allVolatilesForbidden(Register symb) {
272        if (VM.VerifyAssertions) {
273          VM._assert(symb != null);
274        }
275        RestrictedRegisterSet s = getRestrictions(symb);
276        if (s == null) return false;
277        return s.getNoVolatiles();
278      }
279    
280      /**
281       * Is it forbidden to assign symbolic register symb to physical register
282       * phys?
283       */
284      public final boolean isForbidden(Register symb, Register phys) {
285        if (VM.VerifyAssertions) {
286          VM._assert(symb != null);
287          VM._assert(phys != null);
288        }
289        RestrictedRegisterSet s = getRestrictions(symb);
290        if (s == null) return false;
291        return s.contains(phys);
292      }
293    
294      /**
295       * Is it forbidden to assign symbolic register symb to physical register r
296       * in instruction s?
297       */
298      public abstract boolean isForbidden(Register symb, Register r, Instruction s);
299    
300      /**
301       * An instance of this class represents restrictions on physical register
302       * assignment.
303       */
304      private static final class RestrictedRegisterSet {
305        /**
306         * The set of registers to which assignment is forbidden.
307         */
308        private final BitSet bitset;
309    
310        /**
311         * additionally, are all volatile registers forbidden?
312         */
313        private boolean noVolatiles = false;
314    
315        boolean getNoVolatiles() { return noVolatiles; }
316    
317        void setNoVolatiles() { noVolatiles = true; }
318    
319        /**
320         * Default constructor
321         */
322        RestrictedRegisterSet(PhysicalRegisterSet phys) {
323          bitset = new BitSet(phys);
324        }
325    
326        /**
327         * Add a particular physical register to the set.
328         */
329        void add(Register r) {
330          bitset.add(r);
331        }
332    
333        /**
334         * Add a set of physical registers to this set.
335         */
336        void addAll(BitSet set) {
337          bitset.addAll(set);
338        }
339    
340        /**
341         * Does this set contain a particular register?
342         */
343        boolean contains(Register r) {
344          if (r.isVolatile() && noVolatiles) {
345            return true;
346          } else {
347            return bitset.contains(r);
348          }
349        }
350      }
351    }