Search in sources :

Example 46 with Operand

use of org.jikesrvm.compilers.opt.ir.operand.Operand 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 47 with Operand

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

Example 48 with Operand

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

the class EnterSSA method removeUnreachableOperands.

@SuppressWarnings("unused")
private void removeUnreachableOperands(HashSet<Instruction> scalarPhis) {
    for (Instruction phi : scalarPhis) {
        boolean didSomething = true;
        while (didSomething) {
            didSomething = false;
            for (int j = 0; j < Phi.getNumberOfValues(phi); j++) {
                Operand v = Phi.getValue(phi, j);
                if (v instanceof UnreachableOperand) {
                    // rewrite the phi instruction to remove the unreachable
                    // operand
                    didSomething = true;
                    Instruction tmpPhi = phi.copyWithoutLinks();
                    Phi.mutate(phi, PHI, Phi.getResult(tmpPhi), Phi.getNumberOfValues(phi) - 1);
                    int m = 0;
                    for (int k = 0; k < Phi.getNumberOfValues(phi); k++) {
                        if (k == j)
                            continue;
                        Phi.setValue(phi, m, Phi.getValue(tmpPhi, k));
                        Phi.setPred(phi, m, Phi.getPred(tmpPhi, k));
                        m++;
                    }
                }
            }
        }
    }
}
Also used : UnreachableOperand(org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand) BasicBlockOperand(org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) UnreachableOperand(org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 49 with Operand

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

the class EnterSSA method meetPhiType.

/**
 * Return the meet of the types on the rhs of a phi instruction
 *
 * @param s phi instruction
 * @param phiTypes TODO
 * @return the meet of the types
 */
private static TypeReference meetPhiType(Instruction s, Map<Instruction, PhiTypeInformation> phiTypes) {
    TypeReference result = null;
    for (int i = 0; i < Phi.getNumberOfValues(s); i++) {
        Operand val = Phi.getValue(s, i);
        if (val instanceof UnreachableOperand)
            continue;
        TypeReference t = val.getType();
        if (t == null) {
            phiTypes.put(s, PhiTypeInformation.FOUND_NULL_TYPE);
        } else if (result == null) {
            result = t;
        } else {
            TypeReference meet = ClassLoaderProxy.findCommonSuperclass(result, t);
            if (meet == null) {
                // TODO: This horrific kludge should go away once we get rid of Address.toInt()
                if ((result.isIntLikeType() && (t.isReferenceType() || t.isWordLikeType())) || ((result.isReferenceType() || result.isWordLikeType()) && t.isIntLikeType())) {
                    meet = TypeReference.Int;
                } else if (result.isReferenceType() && t.isWordLikeType()) {
                    meet = t;
                } else if (result.isWordLikeType() && t.isReferenceType()) {
                    meet = result;
                }
            }
            if (VM.VerifyAssertions && meet == null) {
                String msg = result + " and " + t + " meet to null";
                VM._assert(VM.NOT_REACHED, msg);
            }
            result = meet;
        }
    }
    return result;
}
Also used : UnreachableOperand(org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand) BasicBlockOperand(org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) UnreachableOperand(org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand) TypeReference(org.jikesrvm.classloader.TypeReference)

Example 50 with Operand

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

the class EnterSSA method computeNonLocals.

/**
 * Pass through the IR and calculate which registers are not
 * local to a basic block.  Store the result in the <code> nonLocalRegisters
 * </code> field.
 */
@SuppressWarnings("unused")
private void computeNonLocals() {
    nonLocalRegisters = new HashSet<Register>(20);
    Enumeration<BasicBlock> blocks = ir.getBasicBlocks();
    while (blocks.hasMoreElements()) {
        HashSet<Register> killed = new HashSet<Register>(5);
        BasicBlock block = blocks.nextElement();
        Enumeration<Instruction> instrs = block.forwardRealInstrEnumerator();
        while (instrs.hasMoreElements()) {
            Instruction instr = instrs.nextElement();
            Enumeration<Operand> uses = instr.getUses();
            while (uses.hasMoreElements()) {
                Operand op = uses.nextElement();
                if (op instanceof RegisterOperand) {
                    if (!killed.contains(op.asRegister().getRegister())) {
                        nonLocalRegisters.add(op.asRegister().getRegister());
                    }
                }
            }
            Enumeration<Operand> defs = instr.getDefs();
            while (defs.hasMoreElements()) {
                Operand op = defs.nextElement();
                if (op instanceof RegisterOperand) {
                    killed.add(op.asRegister().getRegister());
                }
            }
        }
    }
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) UnreachableOperand(org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand) BasicBlockOperand(org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) HashSet(java.util.HashSet)

Aggregations

Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)355 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)328 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)242 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)217 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)212 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)210 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)207 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)185 LongConstantOperand (org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand)174 ConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)165 TypeOperand (org.jikesrvm.compilers.opt.ir.operand.TypeOperand)153 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)144 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)143 NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)141 ObjectConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand)128 TIBConstantOperand (org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand)121 UnreachableOperand (org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand)117 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)102 CodeConstantOperand (org.jikesrvm.compilers.opt.ir.operand.CodeConstantOperand)98 Register (org.jikesrvm.compilers.opt.ir.Register)82