Search in sources :

Example 11 with HeapOperand

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

the class LICM method replaceUses.

/*
   * In the consumers of `inst', replace uses of `inst's result
   * with uses of `replacement'
   */
private boolean replaceUses(Instruction inst, HeapOperand<?> replacement, BasicBlockOperand replacementBlock, boolean onlyPEIs) {
    if (VM.VerifyAssertions)
        VM._assert(Phi.conforms(inst));
    boolean changed = false;
    // Cast to generic HeapOperand
    @SuppressWarnings("unchecked") HeapOperand<Object> hop = (HeapOperand) Phi.getResult(inst);
    HeapVariable<Object> H = hop.value;
    Iterator<HeapOperand<Object>> it = ssad.iterateHeapUses(H);
    while (it.hasNext()) {
        hop = it.next();
        Instruction user = hop.instruction;
        if (onlyPEIs && !user.isPEI())
            continue;
        if (Phi.conforms(user)) {
            for (int i = 0; i < Phi.getNumberOfValues(user); i++) {
                if (Phi.getValue(user, i) == hop) {
                    Phi.setValue(user, i, replacement.copy());
                    Phi.setPred(user, i, (BasicBlockOperand) replacementBlock.copy());
                }
            }
            changed |= replacement.value != H;
        } else {
            HeapOperand<?>[] uses = ssad.getHeapUses(user);
            for (int i = uses.length - 1; i >= 0; --i) {
                if (uses[i].value == H) {
                    changed |= replacement.value != H;
                    uses[i] = replacement.copy();
                    uses[i].setInstruction(user);
                }
            }
        }
        if (DEBUG && changed) {
            VM.sysWriteln(" changing dependency of " + user + "\n" + "from " + H + " to " + replacement);
        }
    }
    if (!onlyPEIs) {
        for (int i = Phi.getNumberOfValues(inst) - 1; i >= 0; --i) {
            Phi.setValue(inst, i, replacement.copy());
        }
    }
    return changed;
}
Also used : HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 12 with HeapOperand

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

the class LICM method scheduleHeapUsesLate.

BasicBlock scheduleHeapUsesLate(Instruction inst, BasicBlock lateBlock) {
    // VM.sysWriteln (" scheduleHeapUsesLate");
    Operand[] defs = ssad.getHeapDefs(inst);
    if (defs == null)
        return lateBlock;
    // VM.sysWriteln (" defs: " + defs.length);
    for (Operand def : defs) {
        // Cast to generic HeapOperand
        @SuppressWarnings("unchecked") HeapOperand<Object> dhop = (HeapOperand) def;
        HeapVariable<Object> H = dhop.value;
        if (DEBUG)
            VM.sysWriteln("H: " + H);
        Iterator<HeapOperand<Object>> it = ssad.iterateHeapUses(H);
        // VM.sysWriteln (" H: " + H + " (" + ssad.getNumberOfUses (H) + ")");
        while (it.hasNext()) {
            HeapOperand<Object> uhop = it.next();
            // VM.sysWriteln (" uhop: " + uhop):
            Instruction use = uhop.instruction;
            // VM.sysWriteln ("use: " + use);
            BasicBlock _block = useBlock(use, uhop);
            lateBlock = commonDominator(_block, lateBlock);
        }
    }
    return lateBlock;
}
Also used : HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) BasicBlockOperand(org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand) HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) ExceptionHandlerBasicBlock(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 13 with HeapOperand

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

the class LoadElimination method replaceDefs.

/**
 * Perform scalar replacement actions for a Def of a heap variable.
 * <p>
 * NOTE: Even loads can def a heap variable.
 *
 * @param ir the governing IR
 * @param UseRepSet stores the uses(loads) that have been eliminated
 * @param registers mapping from valueNumber -&gt; temporary register
 */
static void replaceDefs(IR ir, UseRecordSet UseRepSet, HashMap<UseRecord, Register> registers) {
    SSADictionary ssa = ir.HIRInfo.dictionary;
    for (Enumeration<Instruction> e = ir.forwardInstrEnumerator(); e.hasMoreElements(); ) {
        Instruction s = e.nextElement();
        if (!GetField.conforms(s) && !GetStatic.conforms(s) && !PutField.conforms(s) && !PutStatic.conforms(s) && !ALoad.conforms(s) && !AStore.conforms(s)) {
            continue;
        }
        if (!ssa.defsHeapVariable(s)) {
            continue;
        }
        // this instruction is a DEF of heap variable H.
        // Check if UseRepSet needs the scalar assigned by this def
        HeapOperand<?>[] H = ssa.getHeapDefs(s);
        if (H.length != 1) {
            throw new OptimizingCompilerException("LoadElimination: encountered a store with more than one def? " + s);
        }
        int valueNumber = -1;
        Object index = null;
        if (AStore.conforms(s)) {
            Object address = AStore.getArray(s);
            index = AStore.getIndex(s);
            valueNumber = ir.HIRInfo.valueNumbers.getValueNumber(address);
        } else if (GetField.conforms(s)) {
            Object address = GetField.getRef(s);
            valueNumber = ir.HIRInfo.valueNumbers.getValueNumber(address);
        } else if (PutField.conforms(s)) {
            Object address = PutField.getRef(s);
            valueNumber = ir.HIRInfo.valueNumbers.getValueNumber(address);
        } else if (GetStatic.conforms(s)) {
            valueNumber = 0;
        } else if (PutStatic.conforms(s)) {
            valueNumber = 0;
        } else if (ALoad.conforms(s)) {
            Object address = ALoad.getArray(s);
            valueNumber = ir.HIRInfo.valueNumbers.getValueNumber(address);
            index = ALoad.getIndex(s);
        }
        if (index == null) {
            // Load/Store
            if (UseRepSet.containsMatchingUse(H[0].getHeapVariable(), valueNumber)) {
                Operand value = null;
                if (PutField.conforms(s)) {
                    value = PutField.getValue(s);
                } else if (PutStatic.conforms(s)) {
                    value = PutStatic.getValue(s);
                } else if (GetField.conforms(s) || GetStatic.conforms(s)) {
                    value = ResultCarrier.getResult(s);
                }
                TypeReference type = value.getType();
                Register r = findOrCreateRegister(H[0].getHeapType(), valueNumber, registers, ir.regpool, type);
                appendMove(r, value, s);
            }
        } else {
            // ALoad / AStore
            int v1 = valueNumber;
            int v2 = ir.HIRInfo.valueNumbers.getValueNumber(index);
            if (UseRepSet.containsMatchingUse(H[0].getHeapVariable(), v1, v2)) {
                Operand value = null;
                if (AStore.conforms(s)) {
                    value = AStore.getValue(s);
                } else if (ALoad.conforms(s)) {
                    value = ALoad.getResult(s);
                }
                TypeReference type = value.getType();
                Register r = findOrCreateRegister(H[0].getHeapType(), v1, v2, registers, ir.regpool, type);
                appendMove(r, value, s);
            }
        }
    }
}
Also used : HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) Register(org.jikesrvm.compilers.opt.ir.Register) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException) TypeReference(org.jikesrvm.classloader.TypeReference) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 14 with HeapOperand

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

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

the class EnterSSA method renameHeapVariables.

/**
 * Rename the implicit heap variables in the SSA form so that
 * each heap variable has only one definition.
 *
 * <p> Algorithm: Cytron et. al 91  (see renameSymbolicRegisters)
 *
 * @param ir the governing IR
 */
private void renameHeapVariables(IR ir) {
    int n = ir.HIRInfo.dictionary.getNumberOfHeapVariables();
    if (n == 0) {
        return;
    }
    // we maintain a stack of names for each type of heap variable
    // stacks implements a mapping from type to Stack.
    // Example: to get the stack of names for HEAP<int> variables,
    // use stacks.get(ClassLoaderProxy.IntType);
    HashMap<Object, Stack<HeapOperand<Object>>> stacks = new HashMap<Object, Stack<HeapOperand<Object>>>(n);
    // names, currently stored in the SSADictionary
    for (Iterator<HeapVariable<Object>> e = ir.HIRInfo.dictionary.getHeapVariables(); e.hasNext(); ) {
        HeapVariable<Object> H = e.next();
        Stack<HeapOperand<Object>> S = new Stack<HeapOperand<Object>>();
        S.push(new HeapOperand<Object>(H));
        Object heapType = H.getHeapType();
        stacks.put(heapType, S);
    }
    BasicBlock entry = ir.cfg.entry();
    numPredProcessed = new int[ir.getMaxBasicBlockNumber()];
    search2(entry, stacks);
// registerRenamedHeapPhis(ir);
}
Also used : HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) HashMap(java.util.HashMap) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Stack(java.util.Stack)

Aggregations

HeapOperand (org.jikesrvm.compilers.opt.ir.operand.HeapOperand)20 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)13 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)8 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)7 BasicBlockOperand (org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand)5 OptimizingCompilerException (org.jikesrvm.compilers.opt.OptimizingCompilerException)4 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)4 Register (org.jikesrvm.compilers.opt.ir.Register)3 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)3 HashSet (java.util.HashSet)2 RVMField (org.jikesrvm.classloader.RVMField)2 TypeReference (org.jikesrvm.classloader.TypeReference)2 HashMap (java.util.HashMap)1 Iterator (java.util.Iterator)1 Stack (java.util.Stack)1 DominatorTreeNode (org.jikesrvm.compilers.opt.controlflow.DominatorTreeNode)1 DF_LatticeCell (org.jikesrvm.compilers.opt.dfsolver.DF_LatticeCell)1 ExceptionHandlerBasicBlock (org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock)1 IREnumeration (org.jikesrvm.compilers.opt.ir.IREnumeration)1 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)1