Search in sources :

Example 11 with BasicBlockOperand

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

the class LiveAnalysis method getUsesFromPhis.

/**
 * The rvals of phi nodes are logically uses in the phi's predecessor
 * blocks, so here we collect phi rvals from the current block's
 * successors into the gen set for this block, being careful to
 * collect only the appropriate rval
 *
 * @param bblock the basic block of interest
 *
 * pre: Assumes the liveInfo array is allocated for this block
 * post: May add to liveInfo for this block
 */
private void getUsesFromPhis(BasicBlock bblock) {
    Enumeration<BasicBlock> successors = bblock.getOut();
    while (successors.hasMoreElements()) {
        BasicBlock sb = successors.nextElement();
        if (sb.isExit()) {
            continue;
        }
        for (Instruction phi = sb.firstInstruction(); phi != sb.lastInstruction(); phi = phi.nextInstructionInCodeOrder()) {
            if (phi.operator() == PHI) {
                for (int j = 0; j < Phi.getNumberOfValues(phi); j++) {
                    BasicBlockOperand bbop = Phi.getPred(phi, j);
                    if (bbop.block == bblock) {
                        Operand myRval = Phi.getValue(phi, j);
                        if (myRval instanceof RegisterOperand) {
                            RegisterOperand regOp = (RegisterOperand) myRval;
                            TypeReference regType = regOp.getType();
                            if (regOp.getRegister().spansBasicBlock() && regType != null) {
                                bbLiveInfo[bblock.getNumber()].getGen().add(regOp);
                            }
                        }
                    }
                }
            }
        }
    }
}
Also used : BasicBlockOperand(org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) InlinedOsrTypeInfoOperand(org.jikesrvm.compilers.opt.ir.operand.InlinedOsrTypeInfoOperand) BasicBlockOperand(org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) ExceptionHandlerBasicBlock(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) TypeReference(org.jikesrvm.classloader.TypeReference) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) OsrPoint(org.jikesrvm.compilers.opt.ir.OsrPoint)

Example 12 with BasicBlockOperand

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

the class AnnotatedLSTNode method processExit.

/**
 * Process the loop exit basic block.
 * @throws NonRegularLoopException if the loop was not regular
 */
private void processExit() throws NonRegularLoopException {
    // If the exit isn't the header block, check it doesn't have in edges from outside the loop
    if (header != exit) {
        checkInEdgesAreInLoop(exit);
    }
    // Check the exit block leaves the loop
    Enumeration<BasicBlock> exitBlock_outEdges = exit.getOut();
    boolean exits = false;
    // check_exit_block_exits:
    while (exitBlock_outEdges.hasMoreElements()) {
        BasicBlock curExitBlockOutEdgeBB = exitBlock_outEdges.nextElement();
        if (isInLoop(curExitBlockOutEdgeBB)) {
        // An in loop out edge from the exit block
        } else {
            // An out of loop edge from the exit block
            exits = true;
            successor = curExitBlockOutEdgeBB;
            if (successor == header) {
                throw new NonRegularLoopException("Unimplemented condition - see LoopUnrolling.java : 240");
            }
        }
    }
    // end of check_exit_block_exits
    if (!exits) {
        throw new NonRegularLoopException("Exit block (containing back edge to header) doesn't have an out of loop out edge.");
    } else {
        // Get the if instruction used to loop in the exit block
        ifCmpInstr = exit.firstBranchInstruction();
        if (ifCmpInstr == null) {
            throw new NonRegularLoopException("Exit block branch doesn't have a (1st) branching instruction.");
        } else if (ifCmpInstr.getOpcode() != INT_IFCMP_opcode) {
            throw new NonRegularLoopException("branch is int_ifcmp but " + ifCmpInstr.operator() + "\n");
        } else {
            // Get the terminal and iterator operations
            carriedLoopIterator = follow(IfCmp.getVal1(ifCmpInstr));
            terminalIteratorValue = follow(IfCmp.getVal2(ifCmpInstr));
            condition = (ConditionOperand) IfCmp.getCond(ifCmpInstr).copy();
            // Check we have them the right way around and that they do the job we expect
            {
                boolean iteratorInvariant = isLoopInvariant(carriedLoopIterator, loop, header);
                boolean terminalValueInvariant = isLoopInvariant(terminalIteratorValue, loop, header);
                // Is the iterator loop invariant?
                if (iteratorInvariant) {
                    // Yes - Is the terminal value loop invariant?
                    if (terminalValueInvariant) {
                        // Yes - both parameters to the condition are invariant
                        throw new NonRegularLoopException("Exit block condition values are both invariant (single or infinite loop):\n" + "Loop = " + loop.toString() + "\nIterator = " + carriedLoopIterator + "\nTerminal = " + terminalIteratorValue);
                    } else {
                        // No - swap values over
                        Operand temp = terminalIteratorValue;
                        terminalIteratorValue = carriedLoopIterator;
                        carriedLoopIterator = temp;
                    }
                } else {
                    // No - Is the terminal value loop invariant?
                    if (terminalValueInvariant) {
                    // Yes - this is the condition we hoped for
                    } else {
                        // No - both loop values are variant and loop is too complex to analyse
                        throw new NonRegularLoopException("Exit block condition values are both variant.");
                    }
                }
            }
            // Check target of "if" is the header
            if (Label.getBlock(IfCmp.getTarget(ifCmpInstr).target).block != header) {
                // TODO: swap ifxxx around so that branch is to header and fall-through is exit
                throw new NonRegularLoopException("Target of exit block branch isn't the loop header.");
            }
            // Calculate stride value
            Enumeration<RegisterOperand> iteratorDefs = DefUse.defs(((RegisterOperand) carriedLoopIterator).getRegister());
            // Loop over definitions of the iterator operand ignoring moves
            while (iteratorDefs.hasMoreElements()) {
                Operand curDef = follow(iteratorDefs.nextElement());
                // Is this definition within the loop?
                if (isInLoop(curDef.instruction.getBasicBlock())) {
                    // Yes - have we already got an iterator instruction
                    if ((iteratorInstr == null) || (iteratorInstr == curDef.instruction)) {
                        // No - record
                        iteratorInstr = curDef.instruction;
                    } else {
                        // Yes - loop too complex again
                        throw new NonRegularLoopException("Multiple definitions of the iterator.");
                    }
                }
            }
            // Did we find an instruction?
            if (iteratorInstr == null) {
                // No => error
                throw new NonRegularLoopException("No iterator definition found.");
            } else if ((iteratorInstr.getOpcode() != INT_ADD_opcode) && (iteratorInstr.getOpcode() != INT_SUB_opcode)) {
                // TODO: support more iterator instructions
                throw new NonRegularLoopException("Unrecognized iterator operator " + iteratorInstr.operator());
            } else {
                // only carry on further analysis if we think we can understand the loop
                // Does this iterator instruction use the same register as it defines
                Operand iteratorUse = follow(Binary.getVal1(iteratorInstr));
                // The iterator should be using a phi node of the initial and generated value
                if (!carriedLoopIterator.similar(iteratorUse)) {
                    // SSA ok so far, read PHI node
                    Instruction phiInstr = iteratorUse.instruction;
                    if (!Phi.conforms(phiInstr)) {
                        // We didn't find a PHI instruction
                        throw new NonRegularLoopException("Iterator (" + iteratorUse + ") not using a phi instruction but " + phiInstr);
                    }
                    // We have the SSA we hoped for - tidy up
                    strideValue = follow(Binary.getVal2(iteratorInstr));
                    initialIteratorValue = follow(Phi.getValue(phiInstr, 0));
                    phiLoopIterator = iteratorUse;
                    if (initialIteratorValue instanceof BasicBlockOperand) {
                        throw new Error("BasicBlock mess up!");
                    }
                    if (initialIteratorValue == iteratorUse) {
                        initialIteratorValue = follow(Phi.getValue(phiInstr, 1));
                    }
                    if (initialIteratorValue instanceof BasicBlockOperand) {
                        throw new Error("BasicBlock mess up!2");
                    }
                } else {
                    // Not in SSA form as iterator modifies an operand
                    throw new NonRegularLoopException("Iterator modifies (uses and defines) operand " + iteratorUse + " and is therefore not in SSA form.");
                }
                // Check the initialIteratorValue was defined outside of (before) the loop header or is constant
                if (!isLoopInvariant(initialIteratorValue, loop, header)) {
                    throw new NonRegularLoopException("Initial iterator not constant or defined outside the loop - " + initialIteratorValue);
                } else if (!(strideValue instanceof ConstantOperand)) {
                    // Check the stride value constant
                    throw new NonRegularLoopException("Stride not constant - " + strideValue);
                }
            }
        }
    }
}
Also used : IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand) BasicBlockOperand(org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand) Enumeration(java.util.Enumeration) IREnumeration(org.jikesrvm.compilers.opt.ir.IREnumeration) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) 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) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Aggregations

Instruction (org.jikesrvm.compilers.opt.ir.Instruction)12 BasicBlockOperand (org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand)12 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)9 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)8 HeapOperand (org.jikesrvm.compilers.opt.ir.operand.HeapOperand)7 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)7 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)5 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)5 IREnumeration (org.jikesrvm.compilers.opt.ir.IREnumeration)4 Register (org.jikesrvm.compilers.opt.ir.Register)4 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)4 NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)4 HashMap (java.util.HashMap)3 Enumeration (java.util.Enumeration)2 TypeReference (org.jikesrvm.classloader.TypeReference)2 DominatorTreeNode (org.jikesrvm.compilers.opt.controlflow.DominatorTreeNode)2 TreeNode (org.jikesrvm.compilers.opt.util.TreeNode)2 ExceptionHandlerBasicBlock (org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock)1 OsrPoint (org.jikesrvm.compilers.opt.ir.OsrPoint)1 ConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)1