Search in sources :

Example 91 with TypeReference

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

the class LoadElimination method getCandidates.

/**
 * Do a quick pass over the IR, and return types that are candidates
 * for redundant load elimination.<p>
 *
 * Algorithm: return those types T where
 * <ul>
 *   <li>there's a load L(i) of type T
 *   <li>there's another load or store M(j) of type T, M!=L and V(i) == V(j)
 * </ul>
 * <p>
 * The result contains objects of type RVMField and TypeReference, whose
 * narrowest common ancestor is Object.
 *
 * @param ir the governing IR
 *
 * @return the types that are candidates for redundant load elimination
 */
@SuppressWarnings("unchecked")
public static HashSet<Object> getCandidates(IR ir) {
    GlobalValueNumberState valueNumbers = ir.HIRInfo.valueNumbers;
    // which types have we seen loads for?
    HashSet<Object> seenLoad = new HashSet<Object>(10);
    // which static fields have we seen stores for?
    HashSet<RVMField> seenStore = new HashSet<RVMField>(10);
    HashSet<Object> resultSet = new HashSet<Object>(10);
    HashSet<FieldReference> forbidden = new HashSet<FieldReference>(10);
    // for each type T, indices(T) gives the set of value number (pairs)
    // that identify the indices seen in memory accesses to type T.
    HashMap indices = new HashMap(10);
    for (Enumeration be = ir.getBasicBlocks(); be.hasMoreElements(); ) {
        BasicBlock bb = (BasicBlock) be.nextElement();
        if (!ir.options.FREQ_FOCUS_EFFORT || !bb.getInfrequent()) {
            for (Enumeration<Instruction> e = bb.forwardInstrEnumerator(); e.hasMoreElements(); ) {
                Instruction s = e.nextElement();
                switch(s.getOpcode()) {
                    case GETFIELD_opcode:
                        {
                            Operand ref = GetField.getRef(s);
                            FieldReference fr = GetField.getLocation(s).getFieldRef();
                            RVMField f = fr.peekResolvedField();
                            if (f == null) {
                                forbidden.add(fr);
                            } else {
                                HashSet<Integer> numbers = findOrCreateIndexSet(indices, f);
                                int v = valueNumbers.getValueNumber(ref);
                                Integer V = v;
                                if (numbers.contains(V)) {
                                    resultSet.add(f);
                                } else {
                                    numbers.add(V);
                                }
                                seenLoad.add(f);
                            }
                        }
                        break;
                    case PUTFIELD_opcode:
                        {
                            Operand ref = PutField.getRef(s);
                            FieldReference fr = PutField.getLocation(s).getFieldRef();
                            RVMField f = fr.peekResolvedField();
                            if (f == null) {
                                forbidden.add(fr);
                            } else {
                                HashSet<Integer> numbers = findOrCreateIndexSet(indices, f);
                                int v = valueNumbers.getValueNumber(ref);
                                Integer V = v;
                                if (numbers.contains(V)) {
                                    if (seenLoad.contains(f)) {
                                        resultSet.add(f);
                                    }
                                } else {
                                    numbers.add(V);
                                }
                            }
                        }
                        break;
                    case GETSTATIC_opcode:
                        {
                            FieldReference fr = GetStatic.getLocation(s).getFieldRef();
                            RVMField f = fr.peekResolvedField();
                            if (f == null) {
                                forbidden.add(fr);
                            } else {
                                if (seenLoad.contains(f) || seenStore.contains(f)) {
                                    resultSet.add(f);
                                }
                                seenLoad.add(f);
                            }
                        }
                        break;
                    case PUTSTATIC_opcode:
                        {
                            FieldReference fr = PutStatic.getLocation(s).getFieldRef();
                            RVMField f = fr.peekResolvedField();
                            if (f == null) {
                                forbidden.add(fr);
                            } else {
                                if (seenLoad.contains(f)) {
                                    resultSet.add(f);
                                }
                                seenStore.add(f);
                            }
                        }
                        break;
                    case INT_ALOAD_opcode:
                    case LONG_ALOAD_opcode:
                    case FLOAT_ALOAD_opcode:
                    case DOUBLE_ALOAD_opcode:
                    case REF_ALOAD_opcode:
                    case BYTE_ALOAD_opcode:
                    case UBYTE_ALOAD_opcode:
                    case USHORT_ALOAD_opcode:
                    case SHORT_ALOAD_opcode:
                        {
                            Operand ref = ALoad.getArray(s);
                            TypeReference type = ref.getType();
                            if (type.isArrayType()) {
                                if (!type.getArrayElementType().isPrimitiveType()) {
                                    type = TypeReference.JavaLangObjectArray;
                                }
                            }
                            Operand index = ALoad.getIndex(s);
                            HashSet<ValueNumberPair> numbers = findOrCreateIndexSet(indices, type);
                            int v1 = valueNumbers.getValueNumber(ref);
                            int v2 = valueNumbers.getValueNumber(index);
                            ValueNumberPair V = new ValueNumberPair(v1, v2);
                            if (numbers.contains(V)) {
                                resultSet.add(type);
                            } else {
                                numbers.add(V);
                            }
                            seenLoad.add(type);
                        }
                        break;
                    case INT_ASTORE_opcode:
                    case LONG_ASTORE_opcode:
                    case FLOAT_ASTORE_opcode:
                    case DOUBLE_ASTORE_opcode:
                    case REF_ASTORE_opcode:
                    case BYTE_ASTORE_opcode:
                    case SHORT_ASTORE_opcode:
                        {
                            Operand ref = AStore.getArray(s);
                            TypeReference type = ref.getType();
                            if (type.isArrayType()) {
                                if (!type.getArrayElementType().isPrimitiveType()) {
                                    type = TypeReference.JavaLangObjectArray;
                                }
                            }
                            Operand index = AStore.getIndex(s);
                            HashSet<ValueNumberPair> numbers = findOrCreateIndexSet(indices, type);
                            int v1 = valueNumbers.getValueNumber(ref);
                            int v2 = valueNumbers.getValueNumber(index);
                            ValueNumberPair V = new ValueNumberPair(v1, v2);
                            if (numbers.contains(V)) {
                                if (seenLoad.contains(type)) {
                                    resultSet.add(type);
                                }
                            } else {
                                numbers.add(V);
                            }
                        }
                        break;
                    default:
                        break;
                }
            }
        }
    }
    // remove all fields that it might refer to from the resultSet.
    for (final FieldReference fieldReference : forbidden) {
        for (Iterator i2 = resultSet.iterator(); i2.hasNext(); ) {
            Object it = i2.next();
            if (it instanceof RVMField) {
                final RVMField field = (RVMField) it;
                if (!fieldReference.definitelyDifferent(field.getMemberRef().asFieldReference())) {
                    i2.remove();
                }
            }
        }
    }
    return resultSet;
}
Also used : FieldReference(org.jikesrvm.classloader.FieldReference) Enumeration(java.util.Enumeration) HashMap(java.util.HashMap) 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) RVMField(org.jikesrvm.classloader.RVMField) Iterator(java.util.Iterator) TypeReference(org.jikesrvm.classloader.TypeReference) HashSet(java.util.HashSet)

Example 92 with TypeReference

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

the class LoadElimination method replaceLoads.

/**
 * Walk over each instruction.  If its a USE (load) of a heap
 * variable and the value is available, then replace the load
 * with a move from a register.
 * <p>
 * POSTCONDITION: sets up the mapping 'registers' from value number
 *                 to temporary register
 * @param ir the IR
 * @param available information on which values are available
 * @param registers a place to store information about temp registers
 * @return mapping from heap variables to value numbers
 */
static UseRecordSet replaceLoads(IR ir, DF_Solution available, HashMap<UseRecord, Register> registers) {
    UseRecordSet result = new UseRecordSet();
    SSADictionary ssa = ir.HIRInfo.dictionary;
    GlobalValueNumberState valueNumbers = ir.HIRInfo.valueNumbers;
    for (Enumeration<Instruction> e = ir.forwardInstrEnumerator(); e.hasMoreElements(); ) {
        Instruction s = e.nextElement();
        if (!GetField.conforms(s) && !GetStatic.conforms(s) && !ALoad.conforms(s)) {
            continue;
        }
        // this instruction is a USE of heap variable H.
        // get the lattice cell that holds the available indices
        // for this heap variable
        HeapOperand<?>[] H = ssa.getHeapUses(s);
        if (H == null) {
            // TODO: clean up HIR representation of these magics
            continue;
        }
        if (H.length != 1) {
            throw new OptimizingCompilerException("LoadElimination: load with wrong number of heap uses");
        }
        if (GetField.conforms(s) || GetStatic.conforms(s)) {
            int valueNumber = -1;
            if (GetField.conforms(s)) {
                Object address = GetField.getRef(s);
                valueNumber = valueNumbers.getValueNumber(address);
            } else {
                // for getStatic, always use the value number 0
                valueNumber = 0;
            }
            ObjectCell cell = (ObjectCell) available.lookup(H[0].getHeapVariable());
            if (cell == null) {
                // nothing available
                continue;
            }
            // .. if H{valueNumber} is available ...
            if (cell.contains(valueNumber)) {
                result.add(H[0].getHeapVariable(), valueNumber);
                TypeReference type = ResultCarrier.getResult(s).getType();
                Register r = findOrCreateRegister(H[0].getHeapType(), valueNumber, registers, ir.regpool, type);
                if (DEBUG) {
                    System.out.println("ELIMINATING LOAD " + s);
                }
                replaceLoadWithMove(r, s);
            }
        } else {
            // ALoad.conforms(s)
            Object array = ALoad.getArray(s);
            Object index = ALoad.getIndex(s);
            ArrayCell cell = (ArrayCell) available.lookup(H[0].getHeapVariable());
            if (cell == null) {
                // nothing available
                continue;
            }
            int v1 = valueNumbers.getValueNumber(array);
            int v2 = valueNumbers.getValueNumber(index);
            // .. if H{<v1,v2>} is available ...
            if (cell.contains(v1, v2)) {
                result.add(H[0].getHeapVariable(), v1, v2);
                TypeReference type = ALoad.getResult(s).getType();
                Register r = findOrCreateRegister(H[0].getHeapVariable().getHeapType(), v1, v2, registers, ir.regpool, type);
                if (DEBUG) {
                    System.out.println("ELIMINATING LOAD " + s);
                }
                replaceLoadWithMove(r, s);
            }
        }
    }
    return result;
}
Also used : ArrayCell(org.jikesrvm.compilers.opt.ssa.IndexPropagation.ArrayCell) ObjectCell(org.jikesrvm.compilers.opt.ssa.IndexPropagation.ObjectCell) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) Register(org.jikesrvm.compilers.opt.ir.Register) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException) TypeReference(org.jikesrvm.classloader.TypeReference)

Example 93 with TypeReference

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

the class LoopVersioning method generatePhiNodes.

/**
 * Generate into a new block phi nodes that define the original
 * register defined by the loop and use two newly created
 * registers.
 * @param loop the loop to process
 * @param registers - vector to which defined registers need to be
 * created registers.x used in creating phi nodes
 * @param types - vector of corresponding types of registers.
 * @param phiInstructions - created phi instructions
 * @param subOptimalRegMap - mapping of orignal destination to the
 * newly created destination for the unoptimized loop
 * @param optimalRegMap - mapping of orignal destination to the
 * newly created destination for the optimized loop
 */
private void generatePhiNodes(AnnotatedLSTNode loop, ArrayList<Register> registers, ArrayList<TypeReference> types, ArrayList<Instruction> phiInstructions, HashMap<Register, Register> subOptimalRegMap, HashMap<Register, Register> optimalRegMap) {
    // Get the carried loop iterator's register
    Register carriedLoopIteratorRegister = ((RegisterOperand) loop.getCarriedLoopIterator()).getRegister();
    for (int i = 0; i < registers.size(); i++) {
        Register register = registers.get(i);
        TypeReference type = types.get(i);
        Instruction phi = Phi.create(PHI, new RegisterOperand(register, type), 2);
        phi.setBytecodeIndex(SYNTH_LOOP_VERSIONING_BCI);
        // new operand for optimized loop
        Operand op0 = ir.regpool.makeTemp(type);
        Phi.setValue(phi, OPTIMIZED_LOOP_OPERAND, op0);
        optimalRegMap.put(register, op0.asRegister().getRegister());
        // new operand for unoptimized loop
        Operand op1 = ir.regpool.makeTemp(type);
        Phi.setValue(phi, UNOPTIMIZED_LOOP_OPERAND, op1);
        subOptimalRegMap.put(register, op1.asRegister().getRegister());
        // internal set to mark the optimized loops
        if (register == carriedLoopIteratorRegister) {
            setOptimizedLoop(op0.asRegister().getRegister());
            setOptimizedLoop(op1.asRegister().getRegister());
        }
        phiInstructions.add(phi);
    }
    // rename any optimized inner loops registers
    renameOptimizedLoops(subOptimalRegMap, optimalRegMap);
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) BasicBlockOperand(org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) TypeReference(org.jikesrvm.classloader.TypeReference) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 94 with TypeReference

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

the class LoopVersioning method findLoopToOptimise.

// -oO Optimisation routines Oo-
/**
 * Find an outermost loop to optimise and optimise it. Focus on
 * annotated regular loops, LICM should handle possible
 * optimisation for the non-regular loops
 *
 * @param loop  Loop to search
 * @return was optimisation performed
 */
private boolean findLoopToOptimise(AnnotatedLSTNode loop) {
    // Has this loop already been optimised?
    Operand carriedLoopIterator = loop.getCarriedLoopIterator();
    if ((carriedLoopIterator instanceof RegisterOperand) && (isOptimizedLoop(carriedLoopIterator.asRegister().getRegister()))) {
        return false;
    }
    // Process inner loops first
    Enumeration<GraphNode> innerLoops = loop.outNodes();
    // Iterate over loops
    while (innerLoops.hasMoreElements()) {
        AnnotatedLSTNode nestedLoop = (AnnotatedLSTNode) innerLoops.nextElement();
        // Try to optimise inner loops first
        if (findLoopToOptimise(nestedLoop)) {
            // Exit early if inner loop optimisation succeeded
            return true;
        }
    }
    // Don't try to optimise irregular loops
    if (loop.isNonRegularLoop()) {
        return false;
    }
    if (DEBUG) {
        report("LoopFissionOfArrayGuards: found loop in " + ir.getMethod());
        VM.sysWriteln("dominator tree:");
        VM.sysWriteln(ir.HIRInfo.dominatorTree.toString());
    }
    // 1) Determine the bound and null checks to be eliminated. The
    // bound checks are the ones that operate on the loop iterator. If
    // no checks can be eliminated, stop optimising this loop.
    ArrayList<Instruction> checksToEliminate = new ArrayList<Instruction>();
    getListOfChecksToEliminate(loop, checksToEliminate);
    if (checksToEliminate.isEmpty()) {
        return false;
    } else {
        // We found instructions to eliminate
        if (DEBUG) {
            VM.sysWriteln("Loop being optimised:");
            VM.sysWriteln(loop.toString());
            VM.sysWriteln("Checks to eliminate:");
            for (Instruction instruction : checksToEliminate) {
                VM.sysWriteln(instruction.toString());
            }
        }
        // 2) Determine the registers defined in the loop.
        ArrayList<Register> registersDefinedInOriginalLoop = new ArrayList<Register>();
        ArrayList<TypeReference> typesOfRegistersDefinedInOriginalLoop = new ArrayList<TypeReference>();
        ArrayList<Instruction> definingInstructionsInOriginalLoop = new ArrayList<Instruction>();
        getRegistersDefinedInLoop(loop, registersDefinedInOriginalLoop, typesOfRegistersDefinedInOriginalLoop, definingInstructionsInOriginalLoop);
        if (DEBUG) {
            VM.sysWrite("Registers in original loop:\n{");
            for (int i = 0; i < registersDefinedInOriginalLoop.size(); i++) {
                VM.sysWrite(registersDefinedInOriginalLoop.get(i).toString());
                if (definingInstructionsInOriginalLoop.get(i) != null) {
                    VM.sysWrite("(escapes),");
                } else {
                    VM.sysWrite(",");
                }
            }
            VM.sysWriteln("}");
        }
        // 3) Generate phi nodes that define the original register
        // defined by the loop and use two newly created registers.
        ArrayList<Instruction> phiInstructions = new ArrayList<Instruction>();
        HashMap<Register, Register> subOptimalRegMap = new HashMap<Register, Register>();
        HashMap<Register, Register> optimalRegMap = new HashMap<Register, Register>();
        generatePhiNodes(loop, registersDefinedInOriginalLoop, typesOfRegistersDefinedInOriginalLoop, phiInstructions, subOptimalRegMap, optimalRegMap);
        if (DEBUG) {
            VM.sysWriteln("subOptimalRegMap");
            VM.sysWriteln(subOptimalRegMap.toString());
            VM.sysWriteln("optimalRegMap");
            VM.sysWriteln(optimalRegMap.toString());
        }
        // 4) Create a version of the original loop that uses the first of
        // the newly created registers instead of the original
        // registers.
        HashMap<Register, BasicBlock> regToUnoptimizedBlockMap = new HashMap<Register, BasicBlock>();
        HashMap<BasicBlock, BasicBlock> unoptimizedLoopMap = createCloneLoop(loop, subOptimalRegMap, regToUnoptimizedBlockMap);
        if (DEBUG) {
            VM.sysWriteln("subOptimalLoopMap");
            VM.sysWriteln(unoptimizedLoopMap.toString());
        }
        // 5) Create a second version, this time with the result of the
        // eliminated checks set to explicit test guards.
        HashMap<Register, BasicBlock> regToOptimizedBlockMap = new HashMap<Register, BasicBlock>();
        HashMap<BasicBlock, BasicBlock> optimizedLoopMap = createOptimizedLoop(loop, optimalRegMap, checksToEliminate, regToOptimizedBlockMap);
        if (DEBUG) {
            VM.sysWriteln("optimalLoopMap");
            VM.sysWriteln(optimizedLoopMap.toString());
        }
        // 6) Work out what the maximum value for all the bounds checks
        // are and create branches to optimal or suboptimal loops - with
        // the unoptimized loop possibly being unreachable
        BasicBlock firstBranchBlock = loop.header.createSubBlock(SYNTH_LOOP_VERSIONING_BCI, ir);
        BasicBlock temp = (BasicBlock) loop.header.prev;
        ir.cfg.breakCodeOrder(temp, loop.header);
        ir.cfg.linkInCodeOrder(temp, firstBranchBlock);
        ir.cfg.linkInCodeOrder(firstBranchBlock, loop.header);
        temp.redirectOuts(loop.header, firstBranchBlock, ir);
        boolean isUnoptimizedLoopReachable = createBranchBlocks(loop, firstBranchBlock, checksToEliminate, unoptimizedLoopMap.get(loop.predecessor), optimizedLoopMap.get(loop.predecessor), optimalRegMap);
        // 7) Fix up the phi node predecessors
        fixUpPhiPredecessors(phiInstructions, isUnoptimizedLoopReachable ? unoptimizedLoopMap.get(loop.exit) : null, optimizedLoopMap.get(loop.exit));
        // 8) Remove the unoptimized loop if its redundant
        if (!isUnoptimizedLoopReachable) {
            removeUnoptimizedLoop(loop, unoptimizedLoopMap);
        }
        // 9) Replace register definitions in the original
        // loop with phi instructions
        modifyOriginalLoop(loop, phiInstructions, definingInstructionsInOriginalLoop, subOptimalRegMap, optimalRegMap);
        // 10) Compact node numbering so that CFG number of nodes
        // reflects that some basic blocks may have been deleted
        ir.cfg.compactNodeNumbering();
        return true;
    }
}
Also used : HashMap(java.util.HashMap) BasicBlockOperand(org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) AnnotatedLSTNode(org.jikesrvm.compilers.opt.controlflow.AnnotatedLSTNode) ArrayList(java.util.ArrayList) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) GraphNode(org.jikesrvm.compilers.opt.util.GraphNode) 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)

Example 95 with TypeReference

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

the class RewriteMemoryOperandsWithOversizedDisplacements method disp64MemOperandConversion.

private static void disp64MemOperandConversion(IR ir, Instruction inst, MemoryOperand mo) {
    if (!mo.disp.isZero() && !Bits.fits(mo.disp, 32)) {
        RegisterOperand effectiveAddress = ir.regpool.makeTempLong();
        RegisterOperand temp = null;
        inst.insertBefore(MIR_Move.create(IMMQ_MOV, effectiveAddress, LC(mo.disp.toLong())));
        if (mo.index != null) {
            if (mo.scale != 0) {
                temp = ir.regpool.makeTempLong();
                TypeReference indexType = mo.index.getType();
                if (indexType.isLongType() || indexType.isWordLikeType()) {
                    inst.insertBefore(MIR_Move.create(IA32_MOV, temp, mo.index.copy()));
                } else if (indexType.isIntType()) {
                    inst.insertBefore(MIR_Unary.create(IA32_MOVSXDQ, temp, mo.index.copy()));
                } else if (indexType.isByteType()) {
                    inst.insertBefore(MIR_Unary.create(IA32_MOVSXQ__B, temp, mo.index.copy()));
                } else if (indexType.isShortType() || indexType.isCharType()) {
                    inst.insertBefore(MIR_Unary.create(IA32_MOVSXQ__W, temp, mo.index.copy()));
                } else {
                    String msg = "Unhandled type: " + indexType;
                    if (VM.VerifyAssertions)
                        VM._assert(VM.NOT_REACHED, msg);
                }
                inst.insertBefore(MIR_BinaryAcc.create(IA32_SHL, temp.copy(), IC(mo.scale)));
                inst.insertBefore(MIR_BinaryAcc.create(IA32_ADD, effectiveAddress.copy(), temp.copy()));
            } else {
                TypeReference indexType = mo.index.getType();
                if (indexType.isLongType() || indexType.isWordLikeType()) {
                    inst.insertBefore(MIR_BinaryAcc.create(IA32_ADD, effectiveAddress.copy(), mo.index.copy()));
                } else {
                    temp = ir.regpool.makeTempLong();
                    if (indexType.isIntType()) {
                        inst.insertBefore(MIR_Unary.create(IA32_MOVSXDQ, temp, mo.index.copy()));
                    } else if (indexType.isByteType()) {
                        inst.insertBefore(MIR_Unary.create(IA32_MOVSXQ__B, temp, mo.index.copy()));
                    } else if (indexType.isShortType() || indexType.isCharType()) {
                        inst.insertBefore(MIR_Unary.create(IA32_MOVSXQ__W, temp, mo.index.copy()));
                    } else {
                        String msg = "Unhandled type: " + indexType;
                        if (VM.VerifyAssertions)
                            VM._assert(VM.NOT_REACHED, msg);
                    }
                    inst.insertBefore(MIR_BinaryAcc.create(IA32_ADD, effectiveAddress.copy(), temp.copy()));
                }
            }
        }
        if (mo.base != null) {
            inst.insertBefore(MIR_BinaryAcc.create(IA32_ADD, effectiveAddress.copy(), mo.base.copy()));
        }
        MemoryOperand newMo = MemoryOperand.I(effectiveAddress.copy().asRegister(), mo.size, null != mo.loc ? (LocationOperand) mo.loc.copy() : null, mo.guard != null ? mo.guard.copy() : null);
        inst.replaceOperand(mo, newMo);
    }
}
Also used : LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) 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