Search in sources :

Example 41 with Register

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

the class CallingConvention method saveNonvolatilesBeforeSysCall.

/**
 * Save all nonvolatile registers before a syscall.
 * We do this in case the sys call does not respect our
 * register conventions.<p>
 *
 * We save/restore all nonvolatiles and the PR, whether
 * or not this routine uses them.  This may be a tad inefficient, but if
 * you're making a system call, you probably don't care.
 *
 * @param call the sys call
 * @param ir the IR that contains the call
 */
static void saveNonvolatilesBeforeSysCall(Instruction call, IR ir) {
    GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet();
    StackManager sm = (StackManager) ir.stackManager;
    // get the offset into the stack frame of where to stash the first
    // nonvolatile for this case.
    int location = sm.getOffsetForSysCall();
    // save each non-volatile
    for (Enumeration<Register> e = phys.enumerateNonvolatileGPRs(); e.hasMoreElements(); ) {
        Register r = e.nextElement();
        Operand M = new StackLocationOperand(true, -location, (byte) WORDSIZE);
        call.insertBefore(MIR_Move.create(IA32_MOV, M, new RegisterOperand(r, wordType)));
        location += WORDSIZE;
    }
    // save the thread register
    Operand M = new StackLocationOperand(true, -location, (byte) WORDSIZE);
    call.insertBefore(MIR_Move.create(IA32_MOV, M, ir.regpool.makeTROp()));
    // save the JTOC, if present
    if (JTOC_REGISTER != null) {
        location += WORDSIZE;
        Operand jtocSave = new StackLocationOperand(true, -location, (byte) WORDSIZE);
        call.insertBefore(MIR_Move.create(IA32_MOV, jtocSave, ir.regpool.makeTocOp()));
    }
}
Also used : GenericPhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) IA32ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ia32.IA32ConditionOperand) StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand)

Example 42 with Register

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

the class MIRSplitRanges method findOrCreateTemp.

/**
 * Finds or creates a temporary register to cache a symbolic register.
 *
 * @param rOp the symbolic register operand
 * @param map a mapping from symbolics to temporaries
 * @param ir the governing IR
 * @return a register operand to cache the symbolic register
 */
private static RegisterOperand findOrCreateTemp(RegisterOperand rOp, java.util.HashMap<Register, Register> map, IR ir) {
    Register tReg = map.get(rOp.getRegister());
    if (tReg == null) {
        RegisterOperand tOp = ir.regpool.makeTemp(rOp.getType());
        map.put(rOp.getRegister(), tOp.getRegister());
        return tOp;
    } else {
        return new RegisterOperand(tReg, rOp.getType());
    }
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register)

Example 43 with Register

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

the class MIRSplitRanges method perform.

/**
 * The main method.<p>
 *
 * We split live ranges for registers around PEIs which have catch
 * blocks.  Suppose we have a
 * PEI s which uses a symbolic register r1.  We must ensure that after
 * register allocation, r1 is NOT assigned to a scratch location in s,
 * since this would mess up code in the catch block that uses r1.<p>
 *
 * So, instead, we introduce a new temporary r2 which holds the value of
 * r1.  The live range for r2 spans only the instruction s.  Later, we
 * will ensure that r2 is never spilled.<p>
 *
 * TODO: This could be implemented more efficiently.
 *
 * @param ir the governing IR
 */
@Override
public final void perform(IR ir) {
    java.util.HashMap<Register, Register> newMap = new java.util.HashMap<Register, Register>(5);
    for (Enumeration<BasicBlock> be = ir.getBasicBlocks(); be.hasMoreElements(); ) {
        BasicBlock bb = be.nextElement();
        for (Enumeration<Instruction> ie = bb.forwardInstrEnumerator(); ie.hasMoreElements(); ) {
            Instruction s = ie.nextElement();
            ;
            // clear the cache of register assignments
            newMap.clear();
            // here and in RegisterRestrictions!
            if (s.isPEI() && s.operator() != IR_PROLOGUE) {
                if (bb.hasApplicableExceptionalOut(s) || !RegisterRestrictions.SCRATCH_IN_PEI) {
                    splitAllLiveRanges(s, newMap, ir, false);
                }
            }
            // (1) Some operands must be in registers
            switch(s.getOpcode()) {
                case MIR_LOWTABLESWITCH_opcode:
                    {
                        RegisterOperand rOp = MIR_LowTableSwitch.getIndex(s);
                        RegisterOperand temp = findOrCreateTemp(rOp, newMap, ir);
                        // NOTE: Index as marked as a DU because LowTableSwitch is
                        // going to destroy the value in the register.
                        // By construction (see ConvertToLowLevelIR), no one will
                        // ever read the value computed by a LowTableSwitch.
                        // Therefore, don't insert a move instruction after the
                        // LowTableSwitch (which would cause IR verification
                        // problems anyways, since LowTableSwitch is a branch).
                        // move r into 'temp' before s
                        insertMoveBefore(temp, rOp.copyRO(), s);
                        rOp.setRegister(temp.getRegister());
                    }
                    break;
            }
        }
    }
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 44 with Register

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

the class RegisterRestrictions method restrictTo8Bits.

/**
 * Ensures that a particular register is only assigned to AL, BL, CL, or
 * DL, since these are the only 8-bit registers we normally address.
 *
 * @param r the register that needs to be restricted to 8 bits
 */
void restrictTo8Bits(Register r) {
    PhysicalRegisterSet phys = (PhysicalRegisterSet) this.phys;
    Register ESP = phys.getESP();
    Register EBP = phys.getEBP();
    Register ESI = phys.getESI();
    Register EDI = phys.getEDI();
    addRestriction(r, ESP);
    addRestriction(r, EBP);
    addRestriction(r, ESI);
    addRestriction(r, EDI);
}
Also used : Register(org.jikesrvm.compilers.opt.ir.Register) GenericPhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet) PhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.ia32.PhysicalRegisterSet)

Example 45 with Register

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

the class StackManager method computeNonVolatileArea.

@Override
public void computeNonVolatileArea() {
    GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet();
    if (ir.compiledMethod.isSaveVolatile()) {
        // Record that we use every nonvolatile GPR
        int numGprNv = PhysicalRegisterSet.getNumberOfNonvolatileGPRs();
        ir.compiledMethod.setNumberOfNonvolatileGPRs((short) numGprNv);
        // set the frame size
        frameSize += numGprNv * WORDSIZE;
        frameSize = align(frameSize, STACKFRAME_ALIGNMENT);
        // TODO!!
        ir.compiledMethod.setNumberOfNonvolatileFPRs((short) 0);
        // Record that we need a stack frame.
        setFrameRequired();
        int fpuStateSaveAreaBegin = spillPointer;
        // and saveFloatingPointState(..)
        if (SSE2_FULL) {
            for (int i = 0; i < 8; i++) {
                fsaveLocation = allocateNewSpillLocation(DOUBLE_REG);
            }
        } else {
            // frame, as a place to store the floating-point state with FSAVE
            for (int i = 0; i < 27; i++) {
                fsaveLocation = allocateNewSpillLocation(INT_REG);
            }
        }
        int fpuStateSaveAreaEnd = spillPointer;
        int fpuStateSize = fpuStateSaveAreaEnd - fpuStateSaveAreaBegin;
        if (VM.VerifyAssertions) {
            VM._assert(fpuStateSize == OPT_SAVE_VOLATILE_SPACE_FOR_FPU_STATE);
        }
        int volatileGPRSaveAreaBegin = spillPointer;
        // Map each volatile register to a spill location.
        int i = 0;
        for (Enumeration<Register> e = phys.enumerateVolatileGPRs(); e.hasMoreElements(); i++) {
            e.nextElement();
            // Note that as a side effect, the following call bumps up the
            // frame size.
            saveVolatileGPRLocation[i] = allocateNewSpillLocation(INT_REG);
        }
        int volatileGPRSaveAreaEnd = spillPointer;
        int volatileGPRSaveAreaSize = volatileGPRSaveAreaEnd - volatileGPRSaveAreaBegin;
        if (VM.VerifyAssertions) {
            VM._assert(volatileGPRSaveAreaSize == OPT_SAVE_VOLATILE_SPACE_FOR_VOLATILE_GPRS);
            VM._assert((volatileGPRSaveAreaSize + fpuStateSize) == OPT_SAVE_VOLATILE_TOTAL_SIZE);
        }
        // Map each non-volatile register to a spill location.
        i = 0;
        for (Enumeration<Register> e = phys.enumerateNonvolatileGPRs(); e.hasMoreElements(); i++) {
            e.nextElement();
            // Note that as a side effect, the following call bumps up the
            // frame size.
            nonVolatileGPRLocation[i] = allocateNewSpillLocation(INT_REG);
        }
        // Set the offset to find non-volatiles.
        int gprOffset = getNonvolatileGPROffset(0);
        ir.compiledMethod.setUnsignedNonVolatileOffset(gprOffset);
    } else {
        // Count the number of nonvolatiles used.
        int numGprNv = 0;
        int i = 0;
        for (Enumeration<Register> e = phys.enumerateNonvolatileGPRs(); e.hasMoreElements(); ) {
            Register r = e.nextElement();
            if (r.isTouched()) {
                // Note that as a side effect, the following call bumps up the
                // frame size.
                nonVolatileGPRLocation[i++] = allocateNewSpillLocation(INT_REG);
                numGprNv++;
            }
        }
        // Update the OptCompiledMethod object.
        ir.compiledMethod.setNumberOfNonvolatileGPRs((short) numGprNv);
        if (numGprNv > 0) {
            int gprOffset = getNonvolatileGPROffset(0);
            ir.compiledMethod.setUnsignedNonVolatileOffset(gprOffset);
            // record that we need a stack frame
            setFrameRequired();
        } else {
            ir.compiledMethod.setUnsignedNonVolatileOffset(0);
        }
        ir.compiledMethod.setNumberOfNonvolatileFPRs((short) 0);
    }
}
Also used : GenericPhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet) Register(org.jikesrvm.compilers.opt.ir.Register)

Aggregations

Register (org.jikesrvm.compilers.opt.ir.Register)279 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)144 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)106 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)82 Test (org.junit.Test)52 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)50 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)45 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)43 GenericPhysicalRegisterSet (org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet)40 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)39 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)32 MemoryOperand (org.jikesrvm.compilers.opt.ir.operand.MemoryOperand)30 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)29 LongConstantOperand (org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand)27 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)26 OsrPoint (org.jikesrvm.compilers.opt.ir.OsrPoint)25 ConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)24 IA32ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ia32.IA32ConditionOperand)23 BranchOperand (org.jikesrvm.compilers.opt.ir.operand.BranchOperand)22 StackLocationOperand (org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand)22