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