Search in sources :

Example 56 with Instruction

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

the class RewriteMemoryOperandsWithOversizedDisplacements method perform.

@Override
public void perform(IR ir) {
    for (Instruction inst = ir.firstInstructionInCodeOrder(); inst != null; inst = inst.nextInstructionInCodeOrder()) {
        for (int i = 0; i < inst.getNumberOfOperands(); i++) {
            Operand op = inst.getOperand(i);
            if (op instanceof MemoryOperand) {
                MemoryOperand mo = (MemoryOperand) op;
                disp64MemOperandConversion(ir, inst, mo);
            }
        }
    }
}
Also used : MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 57 with Instruction

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

the class StackManager method insertSpillBefore.

@Override
public void insertSpillBefore(Instruction s, Register r, Register type, int location) {
    Operator move = getMoveOperator(type);
    byte size = getSizeOfType(type);
    RegisterOperand rOp;
    if (type.isFloat()) {
        rOp = F(r);
    } else if (type.isDouble()) {
        rOp = D(r);
    } else {
        if (VM.BuildFor64Addr && type.isInteger()) {
            rOp = new RegisterOperand(r, TypeReference.Int);
        } else {
            rOp = new RegisterOperand(r, PRIMITIVE_TYPE_FOR_WORD);
        }
    }
    StackLocationOperand spillLoc = new StackLocationOperand(true, -location, size);
    Instruction spillOp = MIR_Move.create(move, spillLoc, rOp);
    if (VERBOSE_DEBUG) {
        System.out.println("INSERT_SPILL_BEFORE: " + "Inserting " + spillOp + " before " + s);
    }
    s.insertBefore(spillOp);
}
Also used : Operator(org.jikesrvm.compilers.opt.ir.Operator) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand)

Example 58 with Instruction

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

the class StackManager method rewriteStackLocations.

/**
 * Walks through the IR.  For each StackLocationOperand, replace the
 * operand with the appropriate MemoryOperand.
 */
private void rewriteStackLocations() {
    // ESP is initially WORDSIZE above where the framepointer is going to be.
    ESPOffset = getFrameFixedSize() + WORDSIZE;
    Register ESP = ((PhysicalRegisterSet) ir.regpool.getPhysicalRegisterSet()).getESP();
    boolean seenReturn = false;
    for (Enumeration<Instruction> e = ir.forwardInstrEnumerator(); e.hasMoreElements(); ) {
        Instruction s = e.nextElement();
        if (s.isReturn()) {
            seenReturn = true;
            continue;
        }
        if (s.isBranch()) {
            // restore ESP to home location at end of basic block.
            moveESPBefore(s, 0);
            continue;
        }
        if (s.operator() == BBEND) {
            if (seenReturn) {
                // at a return ESP will be at FrameFixedSize,
                seenReturn = false;
                ESPOffset = 0;
            } else {
                moveESPBefore(s, 0);
            }
            continue;
        }
        if (s.operator() == ADVISE_ESP) {
            ESPOffset = MIR_UnaryNoRes.getVal(s).asIntConstant().value;
            continue;
        }
        if (s.operator() == REQUIRE_ESP) {
            // ESP is required to be at the given offset from the bottom of the frame
            moveESPBefore(s, MIR_UnaryNoRes.getVal(s).asIntConstant().value);
            continue;
        }
        if (s.operator() == YIELDPOINT_PROLOGUE || s.operator() == YIELDPOINT_BACKEDGE || s.operator() == YIELDPOINT_EPILOGUE) {
            moveESPBefore(s, 0);
            continue;
        }
        if (s.operator() == IA32_MOV) {
            rewriteMoveInstruction(s);
        }
        // stacklocation and memory operands.
        if (s.operator() == IA32_POP) {
            ESPOffset += WORDSIZE;
        }
        for (Enumeration<Operand> ops = s.getOperands(); ops.hasMoreElements(); ) {
            Operand op = ops.nextElement();
            if (op instanceof StackLocationOperand) {
                StackLocationOperand sop = (StackLocationOperand) op;
                int offset = sop.getOffset();
                if (sop.isFromTop()) {
                    offset = FPOffset2SPOffset(offset);
                }
                offset -= ESPOffset;
                byte size = sop.getSize();
                MemoryOperand M = MemoryOperand.BD(new RegisterOperand(ESP, PRIMITIVE_TYPE_FOR_WORD), Offset.fromIntSignExtend(offset), size, null, null);
                s.replaceOperand(op, M);
            } else if (op instanceof MemoryOperand) {
                MemoryOperand M = op.asMemory();
                if ((M.base != null && M.base.getRegister() == ESP) || (M.index != null && M.index.getRegister() == ESP)) {
                    M.disp = M.disp.minus(ESPOffset);
                }
            }
        }
        // stacklocation and memory operands.
        if (s.operator() == IA32_PUSH) {
            ESPOffset -= WORDSIZE;
        }
    }
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) 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) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) GenericPhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet) PhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.ia32.PhysicalRegisterSet) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand)

Example 59 with Instruction

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

Example 60 with Instruction

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

the class RegisterPreferences method initialize.

/**
 * Set up register preferences based on instructions in an IR.
 */
@Override
public void initialize(IR ir) {
    for (Enumeration<Instruction> e = ir.forwardInstrEnumerator(); e.hasMoreElements(); ) {
        Instruction s = e.nextElement();
        switch(s.getOpcode()) {
            case PPC_MOVE_opcode:
                // add affinities produced by MOVE instructions
                Operand result = MIR_Move.getResult(s);
                Operand value = MIR_Move.getValue(s);
                if (result.isRegister() && value.isRegister()) {
                    Register r1 = result.asRegister().getRegister();
                    Register r2 = value.asRegister().getRegister();
                    addAffinity(1, r2, r1);
                    // above.
                    if (SYMBOLIC_SYMBOLIC_HEURISTIC && r1.isSymbolic() && r2.isSymbolic()) {
                        addAffinity(1, r2, r1);
                    }
                }
                break;
            default:
                break;
        }
    }
}
Also used : Register(org.jikesrvm.compilers.opt.ir.Register) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Aggregations

Instruction (org.jikesrvm.compilers.opt.ir.Instruction)356 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)204 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)144 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)117 Register (org.jikesrvm.compilers.opt.ir.Register)106 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)72 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)61 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)61 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)54 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)53 Test (org.junit.Test)49 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)46 TypeReference (org.jikesrvm.classloader.TypeReference)38 BranchOperand (org.jikesrvm.compilers.opt.ir.operand.BranchOperand)38 NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)35 BasicBlockOperand (org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand)33 HeapOperand (org.jikesrvm.compilers.opt.ir.operand.HeapOperand)33 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)31 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)28 TypeOperand (org.jikesrvm.compilers.opt.ir.operand.TypeOperand)27