Search in sources :

Example 1 with RegSpillListElement

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());
            }
        }
    }
}
Also used : Register(org.jikesrvm.compilers.opt.ir.Register) GCIRMapElement(org.jikesrvm.compilers.opt.ir.GCIRMapElement) RegSpillListElement(org.jikesrvm.compilers.opt.ir.RegSpillListElement)

Example 2 with RegSpillListElement

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);
        }
    }
}
Also used : GenericPhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet) Register(org.jikesrvm.compilers.opt.ir.Register) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) GCIRMapElement(org.jikesrvm.compilers.opt.ir.GCIRMapElement) RegSpillListElement(org.jikesrvm.compilers.opt.ir.RegSpillListElement) HashSet(java.util.HashSet)

Example 3 with RegSpillListElement

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;
}
Also used : RegSpillListElement(org.jikesrvm.compilers.opt.ir.RegSpillListElement) Interruptible(org.vmmagic.pragma.Interruptible)

Example 4 with RegSpillListElement

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();
    }
}
Also used : InlinedOsrTypeInfoOperand(org.jikesrvm.compilers.opt.ir.operand.InlinedOsrTypeInfoOperand) BasicBlockOperand(org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) ExceptionHandlerBasicBlock(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) TypeReference(org.jikesrvm.classloader.TypeReference) ExceptionHandlerBasicBlock(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock) RegSpillListElement(org.jikesrvm.compilers.opt.ir.RegSpillListElement)

Aggregations

RegSpillListElement (org.jikesrvm.compilers.opt.ir.RegSpillListElement)4 GCIRMapElement (org.jikesrvm.compilers.opt.ir.GCIRMapElement)2 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)2 Register (org.jikesrvm.compilers.opt.ir.Register)2 HashSet (java.util.HashSet)1 TypeReference (org.jikesrvm.classloader.TypeReference)1 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)1 ExceptionHandlerBasicBlock (org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock)1 GenericPhysicalRegisterSet (org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet)1 BasicBlockOperand (org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand)1 InlinedOsrTypeInfoOperand (org.jikesrvm.compilers.opt.ir.operand.InlinedOsrTypeInfoOperand)1 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)1 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)1 Interruptible (org.vmmagic.pragma.Interruptible)1