Search in sources :

Example 6 with HeapOperand

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

the class IndexPropagationSystem method processAStore.

/**
 * Update the set of dataflow equations to account for the actions
 * of AStore instruction s
 *
 * <p> The store is of the form A[k] = val.  let A_1 be the array SSA
 * variable before the store, and A_2 the array SSA variable after
 * the store.  Then we add the dataflow equation
 * L(A_2) = update(L(A_1), VALNUM(k))
 *
 * <p> Intuitively, this equation represents the fact that A[k] is available
 * after the store
 *
 * @param s the Astore instruction
 */
void processAStore(Instruction s) {
    HeapOperand<?>[] A1 = ssa.getHeapUses(s);
    HeapOperand<?>[] A2 = ssa.getHeapDefs(s);
    if ((A1.length != 1) || (A2.length != 1)) {
        throw new OptimizingCompilerException("IndexPropagation.processAStore: astore instruction defs or uses multiple heap variables?");
    }
    Operand array = AStore.getArray(s);
    Operand index = AStore.getIndex(s);
    addUpdateArrayDefEquation(A2[0].getHeapVariable(), A1[0].getHeapVariable(), array, index);
}
Also used : HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException)

Example 7 with HeapOperand

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

the class SSADictionary method makePhiInstruction.

/**
 * Create a phi-function instruction for a heap variable
 *
 * @param H a symbolic variable for a Heap variable
 * @param bb the basic block holding the new phi function
 * instruction
 * @return the instruction <code> H = phi H,H,..,H </code>
 */
private static Instruction makePhiInstruction(HeapVariable<Object> H, BasicBlock bb) {
    int n = bb.getNumberOfIn();
    Enumeration<BasicBlock> in = bb.getIn();
    HeapOperand<Object> lhs = new HeapOperand<Object>(H);
    Instruction s = Phi.create(PHI, lhs, n);
    lhs.setInstruction(s);
    for (int i = 0; i < n; i++) {
        HeapOperand<Object> op = new HeapOperand<Object>(H);
        op.setInstruction(s);
        Phi.setValue(s, i, op);
        BasicBlock pred = in.nextElement();
        Phi.setPred(s, i, new BasicBlockOperand(pred));
    }
    return s;
}
Also used : HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) BasicBlockOperand(org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 8 with HeapOperand

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

the class SSADictionary method registerUse.

/**
 * Register that an instruction uses a heap variable for a given
 * field.
 *
 * @param s the instruction in question
 * @param fr the field heap variable the instruction uses
 */
private void registerUse(Instruction s, FieldReference fr) {
    if (VM.VerifyAssertions)
        VM._assert(s.operator() != PHI);
    RVMField f = fr.peekResolvedField();
    HeapOperand<Object> H;
    if (f == null) {
        // can't resolve field at compile time.
        // This isn't quite correct, but is somewhat close.
        // See defect 3481.
        H = new HeapOperand<Object>(findOrCreateHeapVariable(fr));
    } else {
        // not included in the set
        if (heapTypes != null) {
            if (!heapTypes.contains(f)) {
                return;
            }
        }
        H = new HeapOperand<Object>(findOrCreateHeapVariable(f));
    }
    HeapOperand<Object>[] Hprime = new HeapOperand[1];
    Hprime[0] = H;
    Hprime[0].setInstruction(s);
    uses.put(s, Hprime);
}
Also used : HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) RVMField(org.jikesrvm.classloader.RVMField)

Example 9 with HeapOperand

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

the class LICM method simplify.

private boolean simplify(Instruction inst, BasicBlock block) {
    // no phi
    if (!Phi.conforms(inst))
        return false;
    // if (Phi.getNumberOfValues (inst) != 2) return false; // want exactly 2 inputs
    // VM.sysWriteln ("Simplify " + inst);
    Operand resOp = Phi.getResult(inst);
    if (!(resOp instanceof HeapOperand)) {
        // scalar phi
        return false;
    }
    int xidx = -1;
    Instruction x = null;
    for (int i = Phi.getNumberOfValues(inst) - 1; i >= 0; --i) {
        Instruction in = definingInstruction(Phi.getValue(inst, i));
        if (getOrigBlock(in) != getOrigBlock(inst) && dominator.dominates(getOrigBlock(in), getOrigBlock(inst))) {
            if (xidx != -1)
                return false;
            xidx = i;
            x = in;
        } else if (!dominator.dominates(getOrigBlock(inst), getOrigBlock(in))) {
            return false;
        }
    }
    if (x == null)
        return false;
    replaceUses(inst, (HeapOperand<?>) Phi.getValue(inst, xidx), Phi.getPred(inst, xidx), true);
    // Cast to generic HeapOperand
    @SuppressWarnings("unchecked") HeapOperand<Object> hop = (HeapOperand) resOp;
    if (hop.value.isExceptionHeapType())
        return false;
    /* check that inside the loop, the heap variable is only used/defed
       by simple, non-volatile loads or only by stores

       if so, replace uses of inst (a memory phi) with its dominating input
    */
    int type = checkLoop(inst, hop, xidx, block);
    if (type == CL_LOADS_ONLY || type == CL_STORES_ONLY || type == CL_NONE) {
        replaceUses(inst, (HeapOperand<?>) Phi.getValue(inst, xidx), Phi.getPred(inst, xidx), false);
    }
    return false;
}
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) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 10 with HeapOperand

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

the class LICM method checkLoop.

/*
   * TODO document xidx parameter and turn this comment into proper JavaDoc.
   * <p>
   * Checks that inside the loop, the heap variable is only used/defed
   * by simple, non-volatile loads/stores
   *
   * @param inst a phi instruction
   * @param hop the result operand of the phi instruction
   * @param xidx
   * @param block the block that contains the phi instruction
   *
   * @return one of {@link #CL_LOADS_ONLY}, {@link #CL_STORES_ONLY},
   * {@link #CL_LOADS_AND_STORES}, {@link #CL_COMPLEX}
   */
private int checkLoop(Instruction inst, HeapOperand<Object> hop, int xidx, BasicBlock block) {
    HashSet<Instruction> seen = new HashSet<Instruction>();
    Queue<Instruction> workList = new Queue<Instruction>();
    int _state = CL_NONE;
    int instUses = 0;
    seen.add(inst);
    for (int i = Phi.getNumberOfValues(inst) - 1; i >= 0; --i) {
        if (i == xidx)
            continue;
        Instruction y = definingInstruction(Phi.getValue(inst, i));
        if (y == inst)
            instUses++;
        if (!(seen.contains(y))) {
            seen.add(y);
            workList.insert(y);
        }
    }
    while (!(workList.isEmpty())) {
        Instruction y = workList.remove();
        if (Phi.conforms(y)) {
            for (int i = Phi.getNumberOfValues(y) - 1; i >= 0; --i) {
                Instruction z = definingInstruction(Phi.getValue(y, i));
                if (z == inst)
                    instUses++;
                if (!(seen.contains(z))) {
                    seen.add(z);
                    workList.insert(z);
                }
            }
        } else if ((y.isPEI()) || !LocationCarrier.conforms(y) || y.operator().isAcquire() || y.operator().isRelease()) {
            return CL_COMPLEX;
        } else {
            // check for access to volatile field
            LocationOperand loc = LocationCarrier.getLocation(y);
            if (loc == null || loc.mayBeVolatile()) {
                // VM.sysWriteln (" no loc or volatile field");
                return CL_COMPLEX;
            }
            if (y.isImplicitStore()) {
                // conservatively estimate loop-invariance by header domination
                if (!inVariantLocation(y, block))
                    return CL_COMPLEX;
                _state |= CL_STORES_ONLY;
            } else {
                _state |= CL_LOADS_ONLY;
            }
            for (HeapOperand<?> op : ssad.getHeapUses(y)) {
                if (op.value.isExceptionHeapType())
                    continue;
                if (op.getHeapType() != hop.getHeapType())
                    return CL_COMPLEX;
                y = definingInstruction(op);
                if (y == inst)
                    instUses++;
                if (!(seen.contains(y))) {
                    seen.add(y);
                    workList.insert(y);
                }
            }
        }
    }
    if (_state == CL_STORES_ONLY && ssad.getNumberOfUses(hop.value) != instUses) {
        return CL_COMPLEX;
    }
    return _state;
}
Also used : HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) Queue(org.jikesrvm.compilers.opt.util.Queue) HashSet(java.util.HashSet)

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