Search in sources :

Example 76 with Instruction

use of org.jikesrvm.compilers.opt.ir.Instruction 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)

Example 77 with Instruction

use of org.jikesrvm.compilers.opt.ir.Instruction 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 78 with Instruction

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

the class LeaveSSA method unSSAGuardsFinalize.

/**
 * Rename registers and delete Phis.
 *
 * @param ir the governing IR, currently in SSA form
 */
private void unSSAGuardsFinalize(IR ir) {
    DefUse.computeDU(ir);
    for (Register r = ir.regpool.getFirstSymbolicRegister(); r != null; r = r.getNext()) {
        if (!r.isValidation())
            continue;
        Register nreg = guardFind(r);
        Enumeration<RegisterOperand> uses = DefUse.uses(r);
        while (uses.hasMoreElements()) {
            RegisterOperand use = uses.nextElement();
            use.setRegister(nreg);
        }
        Enumeration<RegisterOperand> defs = DefUse.defs(r);
        while (defs.hasMoreElements()) {
            RegisterOperand def = defs.nextElement();
            def.setRegister(nreg);
        }
    }
    Instruction inst = guardPhis;
    while (inst != null) {
        inst.remove();
        inst = inst2guardPhi.get(inst);
    }
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 79 with Instruction

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

the class LeaveSSA method unSSAGuardsDetermineReg.

/**
 * Determine target register for guard phi operands
 *
 * @param ir the governing IR, currently in SSA form
 */
private void unSSAGuardsDetermineReg(IR ir) {
    Instruction inst = guardPhis;
    while (inst != null) {
        Register r = Phi.getResult(inst).asRegister().getRegister();
        int values = Phi.getNumberOfValues(inst);
        for (int i = 0; i < values; ++i) {
            Operand op = Phi.getValue(inst, i);
            if (op instanceof RegisterOperand) {
                guardUnion(op.asRegister().getRegister(), r);
            } else {
                if (VM.VerifyAssertions) {
                    VM._assert(op instanceof TrueGuardOperand || op instanceof UnreachableOperand);
                }
            }
        }
        inst = inst2guardPhi.get(inst);
    }
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) UnreachableOperand(org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand) UnreachableOperand(org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)

Example 80 with Instruction

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

the class LeaveSSA method performRename.

// substitute variables renamed in control parents
private void performRename(BasicBlock bb, DominatorTree dom, VariableStacks s) {
    if (DEBUG)
        VM.sysWriteln("performRename: " + bb);
    Enumeration<Instruction> e = bb.forwardRealInstrEnumerator();
    while (e.hasMoreElements()) {
        Instruction i = e.nextElement();
        Enumeration<Operand> ee = i.getUses();
        while (ee.hasMoreElements()) {
            Operand o = ee.nextElement();
            if (o instanceof RegisterOperand) {
                Register r1 = ((RegisterOperand) o).getRegister();
                if (r1.isValidation())
                    continue;
                Operand r2 = s.peek(r1);
                if (r2 != null) {
                    if (DEBUG) {
                        VM.sysWriteln("replace operand in " + i + "(" + r2 + " for " + o);
                    }
                    i.replaceOperand(o, r2.copy());
                }
            }
        }
    }
    // record renamings required in children
    e = bb.forwardRealInstrEnumerator();
    while (e.hasMoreElements()) {
        Instruction i = e.nextElement();
        if (globalRenameTable.contains(i)) {
            Register original = Move.getVal(i).asRegister().getRegister();
            RegisterOperand rename = Move.getResult(i);
            if (DEBUG)
                VM.sysWriteln("record rename " + rename + " for " + original);
            s.push(original, rename);
        }
    }
    // insert copies in control children
    Enumeration<TreeNode> children = dom.getChildren(bb);
    while (children.hasMoreElements()) {
        BasicBlock c = ((DominatorTreeNode) children.nextElement()).getBlock();
        performRename(c, dom, s);
    }
    // pop renamings from this block off stack
    e = bb.forwardRealInstrEnumerator();
    while (e.hasMoreElements()) {
        Instruction i = e.nextElement();
        if (globalRenameTable.contains(i)) {
            Register original = Move.getVal(i).asRegister().getRegister();
            s.pop(original);
        }
    }
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) DominatorTreeNode(org.jikesrvm.compilers.opt.controlflow.DominatorTreeNode) UnreachableOperand(org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand) TreeNode(org.jikesrvm.compilers.opt.util.TreeNode) DominatorTreeNode(org.jikesrvm.compilers.opt.controlflow.DominatorTreeNode) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Aggregations

Instruction (org.jikesrvm.compilers.opt.ir.Instruction)356 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)204 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)144 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)117 Register (org.jikesrvm.compilers.opt.ir.Register)106 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)72 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)61 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)61 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)54 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)53 Test (org.junit.Test)49 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)46 TypeReference (org.jikesrvm.classloader.TypeReference)38 BranchOperand (org.jikesrvm.compilers.opt.ir.operand.BranchOperand)38 NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)35 BasicBlockOperand (org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand)33 HeapOperand (org.jikesrvm.compilers.opt.ir.operand.HeapOperand)33 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)31 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)28 TypeOperand (org.jikesrvm.compilers.opt.ir.operand.TypeOperand)27