Search in sources :

Example 1 with GenericPhysicalRegisterSet

use of org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet 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 2 with GenericPhysicalRegisterSet

use of org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet 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 3 with GenericPhysicalRegisterSet

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

the class StackManager method saveFloatingPointState.

/**
 * Insert code into the prologue to save the floating point state.
 *
 * @param inst the first instruction after the prologue.
 */
private void saveFloatingPointState(Instruction inst) {
    if (SSE2_FULL) {
        GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet();
        for (int i = 0; i < 8; i++) {
            inst.insertBefore(MIR_Move.create(IA32_MOVQ, new StackLocationOperand(true, -fsaveLocation + (i * BYTES_IN_DOUBLE), BYTES_IN_DOUBLE), new RegisterOperand(phys.getFPR(i), TypeReference.Double)));
        }
    } else {
        Operand M = new StackLocationOperand(true, -fsaveLocation, 4);
        inst.insertBefore(MIR_FSave.create(IA32_FNSAVE, M));
    }
}
Also used : GenericPhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) 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) TrapCodeOperand(org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand)

Example 4 with GenericPhysicalRegisterSet

use of org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet 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)

Example 5 with GenericPhysicalRegisterSet

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

the class CallingConvention method prologueExpand.

// ///////////////////
// Implementation
// ///////////////////
/**
 * Expand the prologue instruction to make calling convention explicit.
 */
private static void prologueExpand(IR ir) {
    // set up register lists for dead code elimination.
    boolean useDU = ir.options.getOptLevel() >= 1;
    if (useDU) {
        DefUse.computeDU(ir);
    }
    Instruction prologueInstr = ir.firstInstructionInCodeOrder().nextInstructionInCodeOrder();
    if (VM.VerifyAssertions)
        VM._assert(prologueInstr.operator() == IR_PROLOGUE);
    Instruction start = prologueInstr.nextInstructionInCodeOrder();
    int int_index = 0;
    int double_index = 0;
    int spilledArgumentCounter = (-256 - STACKFRAME_HEADER_SIZE) >> LOG_BYTES_IN_ADDRESS;
    GenericPhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet();
    Register FP = phys.getFP();
    for (Enumeration<Operand> symParams = prologueInstr.getDefs(); symParams.hasMoreElements(); ) {
        RegisterOperand symParamOp = (RegisterOperand) symParams.nextElement();
        Register symParam = symParamOp.getRegister();
        TypeReference t = symParamOp.getType();
        if (t.isFloatType()) {
            // Why? TODO: figure this out and remove the 'true' case below
            if (true || !useDU || symParam.useList != null) {
                if (double_index < NUMBER_DOUBLE_PARAM) {
                    Register param = phys.get(FIRST_DOUBLE_PARAM + (double_index));
                    start.insertBefore(MIR_Move.create(PPC_FMR, F(symParam), F(param)));
                } else {
                    // spilled parameter
                    start.insertBefore(MIR_Load.create(PPC_LFS, F(symParam), A(FP), IC((spilledArgumentCounter << LOG_BYTES_IN_ADDRESS) - BYTES_IN_ADDRESS + BYTES_IN_FLOAT)));
                    spilledArgumentCounter--;
                }
            }
            double_index++;
        } else if (t.isDoubleType()) {
            // Why? TODO: figure this out and remove the 'true' case below
            if (true || !useDU || symParam.useList != null) {
                if (double_index < NUMBER_DOUBLE_PARAM) {
                    Register param = phys.get(FIRST_DOUBLE_PARAM + (double_index));
                    start.insertBefore(MIR_Move.create(PPC_FMR, D(symParam), D(param)));
                } else {
                    // spilled parameter
                    start.insertBefore(MIR_Load.create(PPC_LFD, D(symParam), A(FP), IC(spilledArgumentCounter << LOG_BYTES_IN_ADDRESS)));
                    spilledArgumentCounter -= BYTES_IN_DOUBLE / BYTES_IN_ADDRESS;
                }
            }
            double_index++;
        } else {
            // Why? TODO: figure this out and remove the 'true' case below
            if (true || !useDU || symParam.useList != null) {
                if (int_index < NUMBER_INT_PARAM) {
                    Register param = phys.get(FIRST_INT_PARAM + (int_index));
                    start.insertBefore(MIR_Move.create(PPC_MOVE, new RegisterOperand(symParam, t), A(param)));
                } else {
                    // spilled parameter
                    if (VM.BuildFor64Addr && (t.isIntType() || t.isShortType() || t.isByteType() || t.isCharType() || t.isBooleanType())) {
                        start.insertBefore(MIR_Load.create(PPC_LInt, new RegisterOperand(symParam, t), A(FP), IC((spilledArgumentCounter << LOG_BYTES_IN_ADDRESS) - BYTES_IN_ADDRESS + BYTES_IN_INT)));
                    } else {
                        // same size as addr (ie, either we're in 32 bit mode or we're in 64 bit mode and it's a reference or long)
                        start.insertBefore(MIR_Load.create(PPC_LAddr, new RegisterOperand(symParam, t), A(FP), IC(spilledArgumentCounter << LOG_BYTES_IN_ADDRESS)));
                    }
                    spilledArgumentCounter--;
                }
            }
            int_index++;
        }
    }
    removeDefsFromPrologue(prologueInstr);
}
Also used : GenericPhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) DoubleConstantOperand(org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) FloatConstantOperand(org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand) TypeReference(org.jikesrvm.classloader.TypeReference) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

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