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);
}
}
}
}
}
}
}
}
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);
}
}
}
}
}
Aggregations