use of org.jikesrvm.compilers.opt.ir.RegSpillListElement in project JikesRVM by JikesRVM.
the class UpdateGCMaps1 method perform.
/**
* Iterate over the IR-based GC map collection and for each entry
* replace the symbolic reg with the real reg or spill it was allocated
* @param ir the IR
*/
@Override
public void perform(IR ir) {
RegisterAllocatorState regAllocState = ir.MIRInfo.regAllocState;
for (GCIRMapElement GCelement : ir.MIRInfo.gcIRMap) {
if (LinearScan.GC_DEBUG) {
VM.sysWrite("GCelement " + GCelement);
}
for (RegSpillListElement elem : GCelement.regSpillList()) {
Register symbolic = elem.getSymbolicReg();
if (LinearScan.GC_DEBUG) {
VM.sysWriteln("get location for " + symbolic);
}
if (symbolic.isAllocated()) {
Register ra = regAllocState.getMapping(symbolic);
elem.setRealReg(ra);
if (LinearScan.GC_DEBUG) {
VM.sysWriteln(ra.toString());
}
} else if (symbolic.isSpilled()) {
int spill = ir.MIRInfo.regAllocState.getSpill(symbolic);
elem.setSpill(spill);
if (LinearScan.GC_DEBUG) {
VM.sysWriteln(Integer.toString(spill));
}
} else {
OptimizingCompilerException.UNREACHABLE("LinearScan", "register not alive:", symbolic.toString());
}
}
}
}
use of org.jikesrvm.compilers.opt.ir.RegSpillListElement in project JikesRVM by JikesRVM.
the class UpdateGCMaps2 method perform.
/**
* @param ir the IR
*/
@Override
public void perform(IR ir) {
GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet();
ScratchMap scratchMap = ir.stackManager.getScratchMap();
RegisterAllocatorState regAllocState = ir.MIRInfo.regAllocState;
if (LinearScan.GC_DEBUG) {
System.out.println("SCRATCH MAP:");
System.out.println();
System.out.println(scratchMap);
}
if (scratchMap.isEmpty())
return;
// Walk over each instruction that has a GC point.
for (GCIRMapElement GCelement : ir.MIRInfo.gcIRMap) {
// new elements to add to the gc map
HashSet<RegSpillListElement> newElements = new HashSet<RegSpillListElement>();
Instruction GCinst = GCelement.getInstruction();
int dfn = regAllocState.getDFN(GCinst);
if (LinearScan.GC_DEBUG) {
VM.sysWrite("GCelement at " + dfn + " , " + GCelement);
}
// a set of elements to delete from the GC Map
HashSet<RegSpillListElement> toDelete = new HashSet<RegSpillListElement>(3);
// For each element in the GC Map ...
for (RegSpillListElement elem : GCelement.regSpillList()) {
if (LinearScan.GC_DEBUG) {
VM.sysWriteln("Update " + elem);
}
if (elem.isSpill()) {
// check if the spilled value currently is cached in a scratch
// register
Register r = elem.getSymbolicReg();
Register scratch = scratchMap.getScratch(r, dfn);
if (scratch != null) {
if (LinearScan.GC_DEBUG) {
VM.sysWriteln("cached in scratch register " + scratch);
}
// we will add a new element noting that the scratch register
// also must be including in the GC map
RegSpillListElement newElem = new RegSpillListElement(r);
newElem.setRealReg(scratch);
newElements.add(newElem);
// valid value
if (scratchMap.isDirty(GCinst, r)) {
toDelete.add(elem);
}
}
} else {
// check if the physical register is currently spilled.
int n = elem.getRealRegNumber();
Register r = phys.get(n);
if (scratchMap.isScratch(r, dfn)) {
// spilled.
if (LinearScan.GC_DEBUG) {
VM.sysWriteln("CHANGE to spill location " + regAllocState.getSpill(r));
}
elem.setSpill(regAllocState.getSpill(r));
}
}
}
// delete all obsolete elements
for (RegSpillListElement deadElem : toDelete) {
GCelement.deleteRegSpillElement(deadElem);
}
// add each new Element to the gc map
for (RegSpillListElement newElem : newElements) {
GCelement.addRegSpillElement(newElem);
}
}
}
use of org.jikesrvm.compilers.opt.ir.RegSpillListElement in project JikesRVM by JikesRVM.
the class OptGCMap method generateGCMapEntry.
/**
* Construct the GCMap for the argument GCIRMapElement
* @param irMapElem The IR Map element to create a GCMap for
* @return the GCMap index.
*/
@Interruptible
public int generateGCMapEntry(GCIRMapElement irMapElem) {
// the index into the GC maps we will use for this instruction.
int mapIndex = NO_MAP_ENTRY;
// Before requesting the (first) map entry, lets make sure we
// will need it. If the reg/spill list is empty, we don't
// need a map slot, i.e., no references are live at this instruction
List<RegSpillListElement> regSpillList = irMapElem.regSpillList();
if (!regSpillList.isEmpty()) {
// For efficiency we create our own bit map and then set the
// appropriate array value
int bitMap = 0;
// count the spills so we know how big of an array we'll need
int numSpills = 0;
int numRegs = 0;
// process the register
for (RegSpillListElement elem : regSpillList) {
if (elem.isSpill()) {
numSpills++;
} else {
numRegs++;
int realRegNumber = elem.getRealRegNumber();
if (VM.VerifyAssertions && realRegNumber > LAST_GCMAP_REG) {
System.out.println(elem);
System.out.println(LAST_GCMAP_REG);
VM._assert(VM.NOT_REACHED, "reg > last GC Map Reg!!");
}
// get the bit position for this register number
int bitPosition = getRegBitPosition(realRegNumber);
// Set the appropriate bit
bitMap = bitMap | (NEXT_BIT >>> bitPosition);
}
}
// get the next free Map entry
int index = setRegisterBitMap(bitMap);
int[] spillArray = new int[numSpills];
int spillIndex = 0;
// first, get a fresh enumerator
for (RegSpillListElement elem : regSpillList) {
if (elem.isSpill()) {
spillArray[spillIndex++] = elem.getSpill();
}
}
// add the spills into the map
addAllSpills(spillArray);
// don't forget to report that there are no more spills
mapIndex = endCurrentMap(index);
}
return mapIndex;
}
use of org.jikesrvm.compilers.opt.ir.RegSpillListElement in project JikesRVM by JikesRVM.
the class LiveAnalysis method performLocalPropagation.
/**
* This method performs the last phase of the analysis, local propagation.
* It uses the results from the fixed point analysis to determine the
* local live information within a basic block.<p>
*
* It walks the IR and, using the live information computed for each
* basic block, i.e., the results of the iterative solution, makes a single
* pass backward walk through the basic block, GENing and KILLing
* local information. This produces the set of live variables at each
* instruction.<p>
*
* This information is saved into two data structures:
* <ul>
* <li>at all GC points, live references are recorded
* <li>at all instructions, live range information is recorded
* </ul>
*
* @param ir the IR
* @param createGCMaps whether GC maps need to be created
*/
private void performLocalPropagation(IR ir, boolean createGCMaps) {
if (DEBUG) {
System.out.println(" .... starting local propagation");
System.out.println();
}
Stack<MapElement> blockStack = null;
if (createGCMaps) {
// We want to add GC map entries in IR instruction order. However, we are
// visiting instructions in reverse order within a block. We solve this
// by pushing all additions to a local stack and pop (and add)
// the information to the GC map after the block has been processed.
blockStack = new Stack<MapElement>();
}
for (BasicBlock block = ir.firstBasicBlockInCodeOrder(); block != null; block = block.nextBasicBlockInCodeOrder()) {
if (VERBOSE) {
System.out.print(" .... processing block # " + block.getNumber() + " ...");
}
// This set will hold the live variables for the current
// instruction. It is initialized from the "In" set of the block's
// successors and updated during the walk up the basic block.
LiveSet local = new LiveSet();
// The union of the IN sets of all exception blocks that can
// be reached (directly) from this block
LiveSet exceptionBlockSummary = new LiveSet();
// statements in this block
for (Enumeration<BasicBlock> bbEnum = block.getOut(); bbEnum.hasMoreElements(); ) {
BasicBlock succ = bbEnum.nextElement();
if (succ.isExceptionHandlerBasicBlock()) {
exceptionBlockSummary.add(bbLiveInfo[succ.getNumber()].getIn());
} else {
local.add(bbLiveInfo[succ.getNumber()].getIn());
}
}
if (VERBOSE) {
System.out.println(" Completed succ walk. exceptionBlockSummary: " + exceptionBlockSummary + "\n local: " + local);
}
// For each item in "local", create live interval info for this block.
liveIntervals.createEndLiveRange(local, block, null);
// Process the block, an instruction at a time.
for (Instruction inst = block.lastInstruction(); inst != block.firstInstruction(); inst = inst.prevInstructionInCodeOrder()) {
if (VERBOSE) {
System.out.println("Processing: " + inst);
}
// in "exceptionBlockSummary"
if (inst.isPEI()) {
local.add(exceptionBlockSummary);
// For each item in "exceptionBlockSummary", create live interval
// info for this block.
liveIntervals.createEndLiveRange(exceptionBlockSummary, block, inst);
}
// Def loop
for (Enumeration<Operand> defs = inst.getPureDefs(); defs.hasMoreElements(); ) {
Operand op = defs.nextElement();
if (op instanceof RegisterOperand) {
RegisterOperand regOp = (RegisterOperand) op;
// about validation reges. (Reg Alloc cares about physical regs.)
if (isSkippableReg(regOp, ir)) {
continue;
}
if (regOp.getType() != null) {
// process the def as a kill
local.remove(regOp);
if (VERBOSE) {
System.out.println(" Killing: " + regOp + "\n local: " + local);
}
// mark this instruction as the start of the live range for reg
liveIntervals.setStartLiveRange(regOp.getRegister(), inst, block);
}
}
// if operand is a Register
}
// -- Feng July 15, 2003
if (createGCMaps && !OsrPoint.conforms(inst) && inst.isGCPoint()) {
// make deep copy (and translate to regList) because we reuse
// local above.
// NOTE: this translation does some screening, see GCIRMap.java
List<RegSpillListElement> regList = map.createDU(local);
blockStack.push(new MapElement(inst, regList));
if (VERBOSE) {
System.out.println("SAVING GC Map");
}
}
// now process the uses
for (Enumeration<Operand> uses = inst.getUses(); uses.hasMoreElements(); ) {
Operand op = uses.nextElement();
if (op instanceof RegisterOperand) {
RegisterOperand regOp = (RegisterOperand) op;
// Do we care about this reg?
if (isSkippableReg(regOp, ir)) {
continue;
}
TypeReference regType = regOp.getType();
// see Def loop comment about magics
if (regType != null) {
// process the use as a gen
local.add(regOp);
if (VERBOSE) {
System.out.println(" Gen-ing: " + regOp);
System.out.println("local: " + local);
}
// mark this instruction as the end of the live range for reg
liveIntervals.createEndLiveRange(regOp.getRegister(), block, inst);
}
}
// if operand is a Register
}
if (createGCMaps && OsrPoint.conforms(inst)) {
// delayed gc map generation for Osr instruction,
// see comments before processing uses -- Feng, July 15, 2003
List<RegSpillListElement> regList = map.createDU(local);
blockStack.push(new MapElement(inst, regList));
// collect osr info using live set
collectOsrInfo(inst, local);
}
}
// end instruction loop
// The register allocator prefers that any registers that are live
// on entry be listed first. This call makes it so.
liveIntervals.moveUpwardExposedRegsToFront(block);
if (createGCMaps) {
// empty the stack, insert the information into the map
while (!blockStack.isEmpty()) {
MapElement elem = blockStack.pop();
map.insert(elem.getInst(), elem.getList());
}
}
if (storeLiveAtHandlers && block.isExceptionHandlerBasicBlock()) {
ExceptionHandlerBasicBlock handlerBlock = (ExceptionHandlerBasicBlock) block;
// use local because we need to get a fresh one anyway.
handlerBlock.setLiveSet(local);
local = null;
} else {
// clear the local set for the next block
local.clear();
}
}
// end basic block for loop
if (DEBUG) {
System.out.println(" .... completed local propagation");
System.out.println();
}
}
Aggregations