Search in sources :

Example 6 with GenericPhysicalRegisterSet

use of org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet in project JikesRVM by JikesRVM.

the class StackManager method saveNonVolatiles.

/**
 * Insert code into the prologue to save any used non-volatile
 * registers.
 *
 * @param inst the first instruction after the prologue.
 */
private void saveNonVolatiles(Instruction inst) {
    GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet();
    int nNonvolatileGPRS = ir.compiledMethod.getNumberOfNonvolatileGPRs();
    if (ir.compiledMethod.isSaveVolatile()) {
        // pretend we use all non-volatiles
        nNonvolatileGPRS = PhysicalRegisterSet.getNumberOfNonvolatileGPRs();
    }
    // 1. save the nonvolatile GPRs
    int n = nNonvolatileGPRS - 1;
    Register FP = phys.getFP();
    if (VM.BuildFor32Addr && n > MULTIPLE_CUTOFF) {
        // use a stm
        Register nv = null;
        for (Enumeration<Register> e = phys.enumerateNonvolatileGPRsBackwards(); e.hasMoreElements() && n >= 0; n--) {
            nv = e.nextElement();
        }
        n++;
        RegisterOperand range = I(nv);
        // YUCK!!! Why is this crap in register operand??
        int offset = getNonvolatileGPROffset(n);
        inst.insertBefore(MIR_Store.create(PPC_STMW, range, A(FP), IC(offset)));
    } else {
        // use a sequence of load instructions
        for (Enumeration<Register> e = phys.enumerateNonvolatileGPRsBackwards(); e.hasMoreElements() && n >= 0; n--) {
            Register nv = e.nextElement();
            int offset = getNonvolatileGPROffset(n);
            inst.insertBefore(MIR_Store.create(PPC_STAddr, A(nv), A(FP), IC(offset)));
        }
    }
    // 1. save the nonvolatile FPRs
    if (ir.compiledMethod.isSaveVolatile()) {
    // DANGER: as an optimization, we assume that a SaveVolatile method
    // will never use nonvolatile FPRs.
    // this invariant is not checked!!!!!
    // TODO: We really need some way to verify that this is true.
    } else {
        int nNonvolatileFPRS = ir.compiledMethod.getNumberOfNonvolatileFPRs();
        n = nNonvolatileFPRS - 1;
        // use a sequence of load instructions
        for (Enumeration<Register> e = phys.enumerateNonvolatileFPRsBackwards(); e.hasMoreElements() && n >= 0; n--) {
            Register nv = e.nextElement();
            int offset = getNonvolatileFPROffset(n);
            inst.insertBefore(MIR_Store.create(PPC_STFD, D(nv), A(FP), IC(offset)));
        }
    }
}
Also used : GenericPhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register)

Example 7 with GenericPhysicalRegisterSet

use of org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet in project JikesRVM by JikesRVM.

the class StackManager method restoreNonVolatiles.

/**
 * Insert code before a return instruction to restore the nonvolatile
 * registers.
 *
 * @param inst the return instruction
 */
private void restoreNonVolatiles(Instruction inst) {
    GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet();
    int nNonvolatileGPRS = ir.compiledMethod.getNumberOfNonvolatileGPRs();
    // 1. restore the nonvolatile GPRs
    int n = nNonvolatileGPRS - 1;
    Register FP = phys.getFP();
    if (VM.BuildFor32Addr && n > MULTIPLE_CUTOFF) {
        // use an lm
        Register nv = null;
        for (Enumeration<Register> e = phys.enumerateNonvolatileGPRsBackwards(); e.hasMoreElements() && n >= 0; n--) {
            nv = e.nextElement();
        }
        n++;
        RegisterOperand range = I(nv);
        // YUCK!!! Why is this crap in register operand??
        int offset = getNonvolatileGPROffset(n);
        inst.insertBefore(MIR_Load.create(PPC_LMW, range, A(FP), IC(offset)));
    } else {
        for (Enumeration<Register> e = phys.enumerateNonvolatileGPRsBackwards(); e.hasMoreElements() && n >= 0; n--) {
            Register nv = e.nextElement();
            int offset = getNonvolatileGPROffset(n);
            inst.insertBefore(MIR_Load.create(PPC_LAddr, A(nv), A(FP), IC(offset)));
        }
    }
    // Note that save-volatiles are forbidden from using nonvolatile FPRs.
    if (!ir.compiledMethod.isSaveVolatile()) {
        // 1. restore the nonvolatile FPRs
        int nNonvolatileFPRS = ir.compiledMethod.getNumberOfNonvolatileFPRs();
        n = nNonvolatileFPRS - 1;
        // use a sequence of load instructions
        for (Enumeration<Register> e = phys.enumerateNonvolatileFPRsBackwards(); e.hasMoreElements() && n >= 0; n--) {
            Register nv = e.nextElement();
            int offset = getNonvolatileFPROffset(n);
            inst.insertBefore(MIR_Load.create(PPC_LFD, D(nv), A(FP), IC(offset)));
        }
    }
}
Also used : GenericPhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register)

Example 8 with GenericPhysicalRegisterSet

use of org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet in project JikesRVM by JikesRVM.

the class GenericStackManager method allocateNonVolatileRegister.

/**
 * Find a nonvolatile register to allocate starting at the reg corresponding
 * to the symbolic register passed.
 * <p>
 * TODO: Clean up this interface.
 *
 *  @param symbReg the place to start the search
 *  @return the allocated register or null
 */
public final Register allocateNonVolatileRegister(Register symbReg) {
    GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet();
    int physType = GenericPhysicalRegisterSet.getPhysicalRegisterType(symbReg);
    for (Enumeration<Register> e = phys.enumerateNonvolatilesBackwards(physType); e.hasMoreElements(); ) {
        Register realReg = e.nextElement();
        if (realReg.isAvailable()) {
            realReg.allocateToRegister(symbReg);
            return realReg;
        }
    }
    return null;
}
Also used : GenericPhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet) Register(org.jikesrvm.compilers.opt.ir.Register)

Example 9 with GenericPhysicalRegisterSet

use of org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet in project JikesRVM by JikesRVM.

the class GenericStackManager method allocateVolatileRegister.

/**
 *  Find an volatile register to allocate starting at the reg corresponding
 *  to the symbolic register passed
 *  @param symbReg the place to start the search
 *  @return the allocated register or null
 */
public final Register allocateVolatileRegister(Register symbReg) {
    GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet();
    int physType = GenericPhysicalRegisterSet.getPhysicalRegisterType(symbReg);
    for (Enumeration<Register> e = phys.enumerateVolatiles(physType); e.hasMoreElements(); ) {
        Register realReg = e.nextElement();
        if (realReg.isAvailable()) {
            realReg.allocateToRegister(symbReg);
            if (DEBUG)
                VM.sysWriteln(" volat." + realReg + " to symb " + symbReg);
            return realReg;
        }
    }
    return null;
}
Also used : GenericPhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet) Register(org.jikesrvm.compilers.opt.ir.Register)

Example 10 with GenericPhysicalRegisterSet

use of org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet in project JikesRVM by JikesRVM.

the class GenericStackManager method getFirstGPRNotUsedIn.

/**
 * Return a GPR that does not appear in instruction s, to hold symbolic
 * register r.
 * Except, do NOT
 * return any register that is a member of the reserved set.
 * @param r the register that needs a scratch register
 * @param s the instruction for which the scratch register is needed
 * @param reserved the registers that must not be used
 * @return a free GPR
 */
private Register getFirstGPRNotUsedIn(Register r, Instruction s, ArrayList<Register> reserved) {
    GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet();
    // first try the volatiles
    for (Enumeration<Register> e = phys.enumerateVolatileGPRs(); e.hasMoreElements(); ) {
        Register p = e.nextElement();
        if (!appearsIn(p, s) && !p.isPinned() && !reserved.contains(p) && isLegal(r, p, s)) {
            return p;
        }
    }
    // next try the non-volatiles. We allocate the nonvolatiles backwards
    for (Enumeration<Register> e = phys.enumerateNonvolatileGPRsBackwards(); e.hasMoreElements(); ) {
        Register p = e.nextElement();
        if (!appearsIn(p, s) && !p.isPinned() && !reserved.contains(p) && isLegal(r, p, s)) {
            return p;
        }
    }
    OptimizingCompilerException.TODO("Could not find a free GPR in spill situation");
    return null;
}
Also used : GenericPhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet) Register(org.jikesrvm.compilers.opt.ir.Register)

Aggregations

GenericPhysicalRegisterSet (org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet)25 Register (org.jikesrvm.compilers.opt.ir.Register)21 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)12 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)10 MemoryOperand (org.jikesrvm.compilers.opt.ir.operand.MemoryOperand)8 StackLocationOperand (org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand)8 IA32ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ia32.IA32ConditionOperand)8 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)6 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)3 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)2 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)2 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)2 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)2 HashSet (java.util.HashSet)1 TypeReference (org.jikesrvm.classloader.TypeReference)1 ControlFlowGraph (org.jikesrvm.compilers.opt.ir.ControlFlowGraph)1 GCIRMapElement (org.jikesrvm.compilers.opt.ir.GCIRMapElement)1 RegSpillListElement (org.jikesrvm.compilers.opt.ir.RegSpillListElement)1 DoubleConstantOperand (org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand)1 FloatConstantOperand (org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand)1