Search in sources :

Example 31 with TypeReference

use of org.jikesrvm.classloader.TypeReference 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 32 with TypeReference

use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.

the class EnterSSA method makePhiInstruction.

/**
 * Create a phi-function instruction
 *
 * @param r the symbolic register
 * @param bb the basic block holding the new phi function
 * @return the instruction r = PHI null,null,..,null
 */
private Instruction makePhiInstruction(Register r, BasicBlock bb) {
    int n = bb.getNumberOfIn();
    Enumeration<BasicBlock> in = bb.getIn();
    TypeReference type = null;
    Instruction s = Phi.create(PHI, new RegisterOperand(r, type), n);
    for (int i = 0; i < n; i++) {
        RegisterOperand junk = new RegisterOperand(r, type);
        Phi.setValue(s, i, junk);
        BasicBlock pred = in.nextElement();
        Phi.setPred(s, i, new BasicBlockOperand(pred));
    }
    s.setSourcePosition(SSA_SYNTH_BCI, ir.getGc().getInlineSequence());
    return s;
}
Also used : BasicBlockOperand(org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) TypeReference(org.jikesrvm.classloader.TypeReference) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 33 with TypeReference

use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.

the class EnterSSA method rectifyPhiTypes.

/*
   * Compute type information for operands in each phi instruction.
   *
   * PRECONDITION: Def-use chains computed.
   * SIDE EFFECT: empties the scalarPhis set
   */
private void rectifyPhiTypes() {
    if (DEBUG)
        System.out.println("Rectify phi types.");
    removeAllUnreachablePhis(scalarPhis);
    int noRehashCapacity = (int) (scalarPhis.size() * 1.5f);
    HashMap<Instruction, PhiTypeInformation> phiTypes = new HashMap<Instruction, PhiTypeInformation>(noRehashCapacity);
    while (!scalarPhis.isEmpty()) {
        boolean didSomething = false;
        for (Iterator<Instruction> i = scalarPhis.iterator(); i.hasNext(); ) {
            Instruction phi = i.next();
            phiTypes.put(phi, PhiTypeInformation.NO_NULL_TYPE);
            if (DEBUG)
                System.out.println("PHI: " + phi);
            TypeReference meet = meetPhiType(phi, phiTypes);
            if (DEBUG)
                System.out.println("MEET: " + meet);
            if (meet != null) {
                didSomething = true;
                if (phiTypes.get(phi) == PhiTypeInformation.NO_NULL_TYPE)
                    i.remove();
                RegisterOperand result = (RegisterOperand) Phi.getResult(phi);
                result.setType(meet);
                for (Enumeration<RegisterOperand> e = DefUse.uses(result.getRegister()); e.hasMoreElements(); ) {
                    RegisterOperand rop = e.nextElement();
                    if (rop.getType() != meet) {
                        rop.clearPreciseType();
                        rop.setType(meet);
                    }
                }
            }
        }
        if (!didSomething) {
            // iteration has bottomed out.
            return;
        }
    }
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) HashMap(java.util.HashMap) TypeReference(org.jikesrvm.classloader.TypeReference) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 34 with TypeReference

use of org.jikesrvm.classloader.TypeReference in project JikesRVM by JikesRVM.

the class EnterSSA method patchPEIgeneratedValues.

/**
 * Work around some problems with PEI-generated values and
 * handlers.  Namely, if a PEI has a return value, rename the
 * result register before and after the PEI in order to reflect the fact
 * that the PEI may not actually assign the result register.
 */
private void patchPEIgeneratedValues() {
    // this only applies if there are exception handlers
    if (!ir.hasReachableExceptionHandlers())
        return;
    HashSet<Pair<BasicBlock, RegisterOperand>> needed = new HashSet<Pair<BasicBlock, RegisterOperand>>(4);
    Enumeration<BasicBlock> blocks = ir.getBasicBlocks();
    while (blocks.hasMoreElements()) {
        BasicBlock block = blocks.nextElement();
        if (block.getExceptionalOut().hasMoreElements()) {
            Instruction pei = block.lastRealInstruction();
            if (pei != null && pei.isPEI() && ResultCarrier.conforms(pei)) {
                boolean copyNeeded = false;
                RegisterOperand v = ResultCarrier.getResult(pei);
                // void calls and the like... :(
                if (v != null) {
                    Register orig = v.getRegister();
                    {
                        Enumeration<BasicBlock> out = block.getApplicableExceptionalOut(pei);
                        while (out.hasMoreElements()) {
                            BasicBlock exp = out.nextElement();
                            LiveSet explive = live.getLiveInfo(exp).getIn();
                            if (explive.contains(orig)) {
                                copyNeeded = true;
                                break;
                            }
                        }
                    }
                    if (copyNeeded) {
                        Enumeration<BasicBlock> out = block.getApplicableExceptionalOut(pei);
                        while (out.hasMoreElements()) {
                            BasicBlock exp = out.nextElement();
                            needed.add(new Pair<BasicBlock, RegisterOperand>(exp, v));
                        }
                    }
                }
            }
        }
    }
    // having determine where copies should be inserted, now insert them.
    if (!needed.isEmpty()) {
        for (Pair<BasicBlock, RegisterOperand> copy : needed) {
            BasicBlock inBlock = copy.first;
            RegisterOperand registerOp = copy.second;
            TypeReference type = registerOp.getType();
            Register register = registerOp.getRegister();
            Register temp = ir.regpool.getReg(register);
            inBlock.prependInstruction(SSA.makeMoveInstruction(ir, register, temp, type));
            Enumeration<BasicBlock> outBlocks = inBlock.getIn();
            while (outBlocks.hasMoreElements()) {
                BasicBlock outBlock = outBlocks.nextElement();
                Instruction x = SSA.makeMoveInstruction(ir, temp, register, type);
                SSA.addAtEnd(ir, outBlock, x, true);
            }
        }
        // Recompute liveness information.  You might be tempted to incrementally
        // update it, but it's tricky, so resist.....do the obvious, but easy thing!
        prepare();
    }
}
Also used : LiveSet(org.jikesrvm.compilers.opt.liveness.LiveSet) Enumeration(java.util.Enumeration) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) TypeReference(org.jikesrvm.classloader.TypeReference) Pair(org.jikesrvm.util.Pair) HashSet(java.util.HashSet)

Example 35 with TypeReference

use of org.jikesrvm.classloader.TypeReference 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)

Aggregations

TypeReference (org.jikesrvm.classloader.TypeReference)164 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)58 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)43 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)38 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)30 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)28 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)27 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)25 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)24 RVMClass (org.jikesrvm.classloader.RVMClass)23 RVMField (org.jikesrvm.classloader.RVMField)21 Register (org.jikesrvm.compilers.opt.ir.Register)21 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)21 NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)21 Address (org.vmmagic.unboxed.Address)21 RVMType (org.jikesrvm.classloader.RVMType)18 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)18 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)18 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)18 RVMMethod (org.jikesrvm.classloader.RVMMethod)17