Search in sources :

Example 26 with OptimizingCompilerException

use of org.jikesrvm.compilers.opt.OptimizingCompilerException 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 27 with OptimizingCompilerException

use of org.jikesrvm.compilers.opt.OptimizingCompilerException in project JikesRVM by JikesRVM.

the class PiNodes method getGenerator.

/*
   * TODO Convert to JavaDoc and add missing tags.
   * <p>
   * Get the instruction a Pi node is linked to.
   * <strong>PRECONDITION: </strong> register lists computed and valid.
   */
public static Instruction getGenerator(Instruction def) {
    if (def.operator() != PI) {
        throw new OptimizingCompilerException("Not a PI Node!");
    }
    Operand g = GuardedUnary.getGuard(def);
    Instruction link = g.asRegister().getRegister().defList.instruction;
    return link;
}
Also used : Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 28 with OptimizingCompilerException

use of org.jikesrvm.compilers.opt.OptimizingCompilerException in project JikesRVM by JikesRVM.

the class OptMachineCodeMap method generateMCInformation.

// //////////////////////////////////////////
// Create the map (at compile time)
// //////////////////////////////////////////
/**
 *  This method walks the IR map, and for each entry it creates
 *  the machine code mapping information for the entry.
 *  It is called during the compilation of the method, not at GC time.
 *  @param irMap  the irmap to translate from
 *  @param DUMP_MAPS dump while we work
 *  @param mcOffsets machine code offset information
 *  @return the machine code map
 */
private static OptMachineCodeMap generateMCInformation(GCIRMap irMap, boolean DUMP_MAPS, MachineCodeOffsets mcOffsets) {
    CallSiteTree inliningMap = new CallSiteTree();
    int numEntries = 0;
    // construct and encode the inlining information for those entries.
    for (GCIRMapElement irMapElem : irMap) {
        numEntries++;
        Instruction instr = irMapElem.getInstruction();
        if (instr.position() == null && instr.getBytecodeIndex() != INSTRUMENTATION_BCI) {
            if ((VM.BuildForIA32 && org.jikesrvm.compilers.opt.ir.ia32.MIR_Call.conforms(instr) && org.jikesrvm.compilers.opt.ir.ia32.MIR_Call.hasMethod(instr)) || (VM.BuildForPowerPC && org.jikesrvm.compilers.opt.ir.ppc.MIR_Call.conforms(instr) && org.jikesrvm.compilers.opt.ir.ppc.MIR_Call.hasMethod(instr))) {
                throw new OptimizingCompilerException("position required for all call instructions " + instr);
            }
        } else {
            inliningMap.addLocation(instr.position());
        }
    }
    // if no entries, then we are done.
    if (numEntries == 0)
        return emptyMachineCodeMap;
    int[] inlineEncoding = OptEncodedCallSiteTree.getEncoding(inliningMap);
    // (2) Encode the primary machine code mapping information and the GCMaps.
    OptGCMap gcMapBuilder = new OptGCMap();
    int[] tmpMC = new int[numEntries * SIZEOF_HUGE_ENTRY];
    int lastMCInfoEntry = 0;
    for (GCIRMapElement irMapElem : irMap) {
        Instruction instr = irMapElem.getInstruction();
        if (DUMP_MAPS)
            VM.sysWrite("IR Map for " + instr + "\n\t" + irMapElem);
        // retrieve the machine code offset (in bytes) from the instruction,
        ensureCorrectMapConstruction(mcOffsets, instr);
        int mco = mcOffsets.getMachineCodeOffset(instr);
        if (mco < 0) {
            VM.sysWrite("Negative machine code MCOffset found:" + mco);
            Instruction i = irMapElem.getInstruction();
            int machineCodeOffsetForI = mcOffsets.getMachineCodeOffset(i);
            VM.sysWriteln(i.getBytecodeIndex() + ", " + i + ", " + machineCodeOffsetForI);
            throw new OptimizingCompilerException("Negative machine code MCOffset found");
        }
        // create GC map and get GCI
        int gci = gcMapBuilder.generateGCMapEntry(irMapElem);
        // get bci information
        int bci = instr.getBytecodeIndex();
        if (bci < 0) {
            if ((bci == UNKNOWN_BCI) && ((VM.BuildForIA32 && org.jikesrvm.compilers.opt.ir.ia32.MIR_Call.conforms(instr) && org.jikesrvm.compilers.opt.ir.ia32.MIR_Call.hasMethod(instr)) || (VM.BuildForPowerPC && org.jikesrvm.compilers.opt.ir.ppc.MIR_Call.conforms(instr) && org.jikesrvm.compilers.opt.ir.ppc.MIR_Call.hasMethod(instr)))) {
                throw new OptimizingCompilerException("valid bytecode index required for all calls " + instr);
            }
            bci = -1;
        }
        // get index into inline encoding
        int iei = -1;
        if (instr.position() != null) {
            iei = inliningMap.find(instr.position()).encodedOffset;
        }
        // set the call info
        int cm = 0;
        if ((VM.BuildForIA32 && org.jikesrvm.compilers.opt.ir.ia32.MIR_Call.conforms(instr)) || (VM.BuildForPowerPC && org.jikesrvm.compilers.opt.ir.ppc.MIR_Call.conforms(instr))) {
            MethodOperand mo;
            if (VM.BuildForIA32) {
                mo = org.jikesrvm.compilers.opt.ir.ia32.MIR_Call.getMethod(instr);
            } else {
                if (VM.VerifyAssertions)
                    VM._assert(VM.BuildForPowerPC);
                mo = org.jikesrvm.compilers.opt.ir.ppc.MIR_Call.getMethod(instr);
            }
            if (mo != null && mo.isGuardedInlineOffBranch()) {
                cm = IS_GUARDED_CALL;
            } else {
                cm = IS_UNGUARDED_CALL;
            }
        }
        // Encode this entry into MCInformation
        if (bci < INVALID_BCI && iei < INVALID_IEI && gci < INVALID_GCI && mco < (OFFSET_MASK >>> OFFSET_SHIFT)) {
            // use a small entry
            if (bci == -1)
                bci = INVALID_BCI;
            if (iei == -1)
                iei = INVALID_IEI;
            if (gci == -1)
                gci = INVALID_GCI;
            if (VM.VerifyAssertions) {
                VM._assert((cm & (CALL_MASK >>> CALL_SHIFT)) == cm);
                VM._assert((bci & (BCI_MASK >>> BCI_SHIFT)) == bci);
                VM._assert((iei & (IEI_MASK >>> IEI_SHIFT)) == iei);
                VM._assert((gci & (GCI_MASK >>> GCI_SHIFT)) == gci);
                VM._assert((mco & (OFFSET_MASK >>> OFFSET_SHIFT)) == mco);
            }
            int t = START_OF_ENTRY;
            t |= (cm << CALL_SHIFT);
            t |= (bci << BCI_SHIFT);
            t |= (iei << IEI_SHIFT);
            t |= (gci << GCI_SHIFT);
            t |= (mco << OFFSET_SHIFT);
            tmpMC[lastMCInfoEntry++] = t;
        } else if (bci < BIG_INVALID_BCI && iei < BIG_INVALID_IEI && gci < BIG_INVALID_GCI && mco < (BIG_OFFSET_MASK >>> BIG_OFFSET_SHIFT)) {
            // use a big entry
            if (bci == -1)
                bci = BIG_INVALID_BCI;
            if (iei == -1)
                iei = BIG_INVALID_IEI;
            if (gci == -1)
                gci = BIG_INVALID_GCI;
            if (VM.VerifyAssertions) {
                VM._assert((cm & (BIG_CALL_MASK >>> BIG_CALL_SHIFT)) == cm);
                VM._assert((bci & (BIG_BCI_MASK >>> BIG_BCI_SHIFT)) == bci);
                VM._assert((iei & (BIG_IEI_MASK >>> BIG_IEI_SHIFT)) == iei);
                VM._assert((gci & (BIG_GCI_MASK >>> BIG_GCI_SHIFT)) == gci);
                VM._assert((mco & (BIG_OFFSET_MASK >>> BIG_OFFSET_SHIFT)) == mco);
            }
            int startIdx = lastMCInfoEntry;
            tmpMC[startIdx] = START_OF_BIG_ENTRY;
            tmpMC[startIdx + BIG_CALL_IDX_ADJ] |= (cm << BIG_CALL_SHIFT);
            tmpMC[startIdx + BIG_BCI_IDX_ADJ] |= (bci << BIG_BCI_SHIFT);
            tmpMC[startIdx + BIG_OFFSET_IDX_ADJ] |= (mco << BIG_OFFSET_SHIFT);
            tmpMC[startIdx + BIG_GCI_IDX_ADJ] |= (gci << BIG_GCI_SHIFT);
            tmpMC[startIdx + BIG_IEI_IDX_ADJ] |= (iei << BIG_IEI_SHIFT);
            lastMCInfoEntry += SIZEOF_BIG_ENTRY;
        } else {
            // use a huge entry
            if (bci == -1)
                bci = HUGE_INVALID_BCI;
            if (iei == -1)
                iei = HUGE_INVALID_IEI;
            if (gci == -1)
                gci = HUGE_INVALID_GCI;
            if (VM.VerifyAssertions) {
                VM._assert((cm & (HUGE_CALL_MASK >>> HUGE_CALL_SHIFT)) == cm);
                VM._assert((bci & (HUGE_BCI_MASK >>> HUGE_BCI_SHIFT)) == bci);
                VM._assert((iei & (HUGE_IEI_MASK >>> HUGE_IEI_SHIFT)) == iei);
                VM._assert((gci & (HUGE_GCI_MASK >>> HUGE_GCI_SHIFT)) == gci);
                VM._assert((mco & (HUGE_OFFSET_MASK >>> HUGE_OFFSET_SHIFT)) == mco);
            }
            int startIdx = lastMCInfoEntry;
            tmpMC[startIdx] = START_OF_HUGE_ENTRY;
            tmpMC[startIdx + HUGE_CALL_IDX_ADJ] |= (cm << HUGE_CALL_SHIFT);
            tmpMC[startIdx + HUGE_BCI_IDX_ADJ] |= (bci << HUGE_BCI_SHIFT);
            tmpMC[startIdx + HUGE_OFFSET_IDX_ADJ] |= (mco << HUGE_OFFSET_SHIFT);
            tmpMC[startIdx + HUGE_GCI_IDX_ADJ] |= (gci << HUGE_GCI_SHIFT);
            tmpMC[startIdx + HUGE_IEI_IDX_ADJ] |= (iei << HUGE_IEI_SHIFT);
            lastMCInfoEntry += SIZEOF_HUGE_ENTRY;
        }
    }
    int[] mcInformation = new int[lastMCInfoEntry];
    System.arraycopy(tmpMC, 0, mcInformation, 0, mcInformation.length);
    int[] gcMaps = gcMapBuilder.finish();
    return new OptMachineCodeMap(mcInformation, gcMaps, inlineEncoding);
}
Also used : CallSiteTree(org.jikesrvm.compilers.opt.inlining.CallSiteTree) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) GCIRMapElement(org.jikesrvm.compilers.opt.ir.GCIRMapElement) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand)

Example 29 with OptimizingCompilerException

use of org.jikesrvm.compilers.opt.OptimizingCompilerException in project JikesRVM by JikesRVM.

the class UpdateOSRMaps method perform.

/**
 * Iterate over the IR-based OSR map, and update symbolic registers
 * with real reg number or spill locations.
 * Verify there are only two types of operands:
 *    ConstantOperand
 *    RegisterOperand
 *        for integer constant, we save the value of the integer
 *
 * The LONG register has another half part.
 *
 * CodeSpill replaces any allocated symbolic register by
 * physical registers.
 */
@Override
public void perform(IR ir) throws OptimizingCompilerException {
    /* for each osr instruction */
    for (VariableMapElement elm : ir.MIRInfo.osrVarMap.list) {
        // MethodVariables mvar = mvarsList.get(numMvars);
        for (MethodVariables mvar : elm.mvars) {
            // LocalRegPair tuple = tupleList.get(numTuple);
            for (LocalRegPair tuple : mvar.tupleList) {
                Operand op = tuple.operand;
                if (op.isRegister()) {
                    Register sym_reg = ((RegisterOperand) op).getRegister();
                    setRealPosition(ir, tuple, sym_reg);
                    // get another half part of long register
                    if (VM.BuildFor32Addr && (tuple.typeCode == LongTypeCode)) {
                        LocalRegPair other = tuple._otherHalf;
                        Operand other_op = other.operand;
                        if (VM.VerifyAssertions)
                            VM._assert(other_op.isRegister());
                        Register other_reg = ((RegisterOperand) other_op).getRegister();
                        setRealPosition(ir, other, other_reg);
                    }
                /* According to ConvertToLowLevelIR, StringConstant, LongConstant,
            * NullConstant, FloatConstant, and DoubleConstant are all materialized
            * The only thing left is the integer constants which could encode
            * non-moveable objects.
            * POTENTIAL DRAWBACKS: since any long, float, and double are moved
            * to register and treated as use, it may consume more registers and
            * add unnecessary MOVEs.
            *
            * Perhaps, ConvertToLowLevelIR can skip OsrPoint instruction.
            */
                } else if (op.isIntConstant()) {
                    setTupleValue(tuple, ICONST, ((IntConstantOperand) op).value);
                    if (VM.BuildFor32Addr && (tuple.typeCode == LongTypeCode)) {
                        LocalRegPair other = tuple._otherHalf;
                        Operand other_op = other.operand;
                        if (VM.VerifyAssertions)
                            VM._assert(other_op.isIntConstant());
                        setTupleValue(other, ICONST, ((IntConstantOperand) other_op).value);
                    }
                } else if (op.isAddressConstant()) {
                    setTupleValue(tuple, ACONST, ((AddressConstantOperand) op).value.toWord());
                } else if (VM.BuildFor64Addr && op.isLongConstant()) {
                    setTupleValue(tuple, LCONST, Word.fromLong(((LongConstantOperand) op).value));
                } else {
                    throw new OptimizingCompilerException("LinearScan", "Unexpected operand type at ", op.toString());
                }
            // for the op type
            }
        // for each tuple
        }
    // for each inlined method
    }
// for each osr instruction
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) Register(org.jikesrvm.compilers.opt.ir.Register) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) LocalRegPair(org.jikesrvm.osr.LocalRegPair) VariableMapElement(org.jikesrvm.osr.VariableMapElement) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException) MethodVariables(org.jikesrvm.osr.MethodVariables)

Example 30 with OptimizingCompilerException

use of org.jikesrvm.compilers.opt.OptimizingCompilerException in project JikesRVM by JikesRVM.

the class IndexPropagationSystem method makeCell.

/**
 * Create an DF_LatticeCell corresponding to an HeapVariable
 * @param o the heap variable
 * @return a new lattice cell corresponding to this heap variable
 */
@Override
protected DF_LatticeCell makeCell(Object o) {
    if (!(o instanceof HeapVariable)) {
        throw new OptimizingCompilerException("IndexPropagation:makeCell");
    }
    DF_LatticeCell result = null;
    Object heapType = ((HeapVariable<?>) o).getHeapType();
    if (heapType instanceof TypeReference) {
        result = new ArrayCell((HeapVariable<?>) o);
    } else {
        result = new ObjectCell((HeapVariable<?>) o);
    }
    return result;
}
Also used : ArrayCell(org.jikesrvm.compilers.opt.ssa.IndexPropagation.ArrayCell) DF_LatticeCell(org.jikesrvm.compilers.opt.dfsolver.DF_LatticeCell) ObjectCell(org.jikesrvm.compilers.opt.ssa.IndexPropagation.ObjectCell) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException) TypeReference(org.jikesrvm.classloader.TypeReference)

Aggregations

OptimizingCompilerException (org.jikesrvm.compilers.opt.OptimizingCompilerException)47 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)25 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)18 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)17 Register (org.jikesrvm.compilers.opt.ir.Register)16 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)14 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)11 LongConstantOperand (org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand)11 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)11 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)10 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)10 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)9 ConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)9 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)9 TypeReference (org.jikesrvm.classloader.TypeReference)8 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)8 BranchOperand (org.jikesrvm.compilers.opt.ir.operand.BranchOperand)8 DoubleConstantOperand (org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand)6 FloatConstantOperand (org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand)6 Offset (org.vmmagic.unboxed.Offset)6