# HG changeset patch # User Josef Eisl # Date 1403094070 -7200 # Node ID f315b1c0a590561b88b06abd38a8752db20ca92d # Parent 0eb8270ae69d0fd1d7df941dc5d33234fb00f578 Introduce InstructionValueProcedure. diff -r 0eb8270ae69d -r f315b1c0a590 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java Wed Jun 04 14:52:17 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/backend/AllocatorTest.java Wed Jun 18 14:21:10 2014 +0200 @@ -80,18 +80,20 @@ } } - private void collectStats(final LIRInstruction instr) { - instr.forEachOutput(new ValueProcedure() { + private ValueProcedure collectStatsProc = new ValueProcedure() { - @Override - public Value doValue(Value value) { - if (ValueUtil.isRegister(value)) { - final Register reg = ValueUtil.asRegister(value); - registers.add(reg); - } - return value; + @Override + public Value doValue(Value value) { + if (ValueUtil.isRegister(value)) { + final Register reg = ValueUtil.asRegister(value); + registers.add(reg); } - }); + return value; + } + }; + + private void collectStats(final LIRInstruction instr) { + instr.forEachOutput(collectStatsProc); if (instr instanceof MoveOp) { MoveOp move = (MoveOp) instr; diff -r 0eb8270ae69d -r f315b1c0a590 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Wed Jun 04 14:52:17 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Wed Jun 18 14:21:10 2014 +0200 @@ -41,6 +41,7 @@ import com.oracle.graal.debug.*; import com.oracle.graal.debug.Debug.Scope; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.LIRInstruction.InstructionValueProcedure; import com.oracle.graal.lir.LIRInstruction.OperandFlag; import com.oracle.graal.lir.LIRInstruction.OperandMode; import com.oracle.graal.lir.LIRInstruction.StateProcedure; @@ -1123,6 +1124,70 @@ void buildIntervals() { try (Indent indent = Debug.logAndIndent("build intervals")) { + InstructionValueProcedure outputProc = new InstructionValueProcedure() { + + @Override + public Value doValue(LIRInstruction op, Value operand, OperandMode mode, EnumSet flags) { + if (isVariableOrRegister(operand)) { + addDef((AllocatableValue) operand, op, registerPriorityOfOutputOperand(op), operand.getLIRKind()); + addRegisterHint(op, operand, mode, flags, true); + } + return operand; + } + }; + + InstructionValueProcedure tempProc = new InstructionValueProcedure() { + + @Override + public Value doValue(LIRInstruction op, Value operand, OperandMode mode, EnumSet flags) { + if (isVariableOrRegister(operand)) { + addTemp((AllocatableValue) operand, op.id(), RegisterPriority.MustHaveRegister, operand.getLIRKind()); + addRegisterHint(op, operand, mode, flags, false); + } + return operand; + } + }; + + InstructionValueProcedure aliveProc = new InstructionValueProcedure() { + + @Override + public Value doValue(LIRInstruction op, Value operand, OperandMode mode, EnumSet flags) { + if (isVariableOrRegister(operand)) { + RegisterPriority p = registerPriorityOfInputOperand(flags); + final int opId = op.id(); + final int blockFrom = getFirstLirInstructionId((blockForId(opId))); + addUse((AllocatableValue) operand, blockFrom, opId + 1, p, operand.getLIRKind()); + addRegisterHint(op, operand, mode, flags, false); + } + return operand; + } + }; + + InstructionValueProcedure inputProc = new InstructionValueProcedure() { + + @Override + public Value doValue(LIRInstruction op, Value operand, OperandMode mode, EnumSet flags) { + if (isVariableOrRegister(operand)) { + final int opId = op.id(); + final int blockFrom = getFirstLirInstructionId((blockForId(opId))); + RegisterPriority p = registerPriorityOfInputOperand(flags); + addUse((AllocatableValue) operand, blockFrom, opId, p, operand.getLIRKind()); + addRegisterHint(op, operand, mode, flags, false); + } + return operand; + } + }; + + InstructionValueProcedure stateProc = new InstructionValueProcedure() { + + @Override + public Value doValue(LIRInstruction op, Value operand) { + final int opId = op.id(); + final int blockFrom = getFirstLirInstructionId((blockForId(opId))); + addUse((AllocatableValue) operand, blockFrom, opId + 1, RegisterPriority.None, operand.getLIRKind()); + return operand; + } + }; // create a list with all caller-save registers (cpu, fpu, xmm) Register[] callerSaveRegs = frameMap.registerConfig.getCallerSaveRegisters(); @@ -1177,66 +1242,17 @@ Debug.log("operation destroys all caller-save registers"); } - op.forEachOutput(new ValueProcedure() { - - @Override - public Value doValue(Value operand, OperandMode mode, EnumSet flags) { - if (isVariableOrRegister(operand)) { - addDef((AllocatableValue) operand, op, registerPriorityOfOutputOperand(op), operand.getLIRKind()); - addRegisterHint(op, operand, mode, flags, true); - } - return operand; - } - }); - op.forEachTemp(new ValueProcedure() { - - @Override - public Value doValue(Value operand, OperandMode mode, EnumSet flags) { - if (isVariableOrRegister(operand)) { - addTemp((AllocatableValue) operand, opId, RegisterPriority.MustHaveRegister, operand.getLIRKind()); - addRegisterHint(op, operand, mode, flags, false); - } - return operand; - } - }); - op.forEachAlive(new ValueProcedure() { - - @Override - public Value doValue(Value operand, OperandMode mode, EnumSet flags) { - if (isVariableOrRegister(operand)) { - RegisterPriority p = registerPriorityOfInputOperand(flags); - addUse((AllocatableValue) operand, blockFrom, opId + 1, p, operand.getLIRKind()); - addRegisterHint(op, operand, mode, flags, false); - } - return operand; - } - }); - op.forEachInput(new ValueProcedure() { - - @Override - public Value doValue(Value operand, OperandMode mode, EnumSet flags) { - if (isVariableOrRegister(operand)) { - RegisterPriority p = registerPriorityOfInputOperand(flags); - addUse((AllocatableValue) operand, blockFrom, opId, p, operand.getLIRKind()); - addRegisterHint(op, operand, mode, flags, false); - } - return operand; - } - }); + op.forEachOutput(outputProc); + op.forEachTemp(tempProc); + op.forEachAlive(aliveProc); + op.forEachInput(inputProc); // Add uses of live locals from interpreter's point of view for proper // debug information generation // Treat these operands as temp values (if the live range is extended // to a call site, the value would be in a register at // the call otherwise) - op.forEachState(new ValueProcedure() { - - @Override - public Value doValue(Value operand) { - addUse((AllocatableValue) operand, blockFrom, opId + 1, RegisterPriority.None, operand.getLIRKind()); - return operand; - } - }); + op.forEachState(stateProc); // special steps for some instructions (especially moves) handleMethodArguments(op); @@ -1682,42 +1698,44 @@ return attributes(asRegister(operand)).isCallerSave(); } + private InstructionValueProcedure debugInfoProc = new InstructionValueProcedure() { + + @Override + public Value doValue(LIRInstruction op, Value operand) { + int tempOpId = op.id(); + OperandMode mode = OperandMode.USE; + AbstractBlock block = blockForId(tempOpId); + if (block.getSuccessorCount() == 1 && tempOpId == getLastLirInstructionId(block)) { + // generating debug information for the last instruction of a block. + // if this instruction is a branch, spill moves are inserted before this branch + // and so the wrong operand would be returned (spill moves at block boundaries + // are not + // considered in the live ranges of intervals) + // Solution: use the first opId of the branch target block instead. + final LIRInstruction instr = ir.getLIRforBlock(block).get(ir.getLIRforBlock(block).size() - 1); + if (instr instanceof StandardOp.JumpOp) { + if (blockData.get(block).liveOut.get(operandNumber(operand))) { + tempOpId = getFirstLirInstructionId(block.getSuccessors().iterator().next()); + mode = OperandMode.DEF; + } + } + } + + // Get current location of operand + // The operand must be live because debug information is considered when building + // the intervals + // if the interval is not live, colorLirOperand will cause an assert on failure + Value result = colorLirOperand((Variable) operand, tempOpId, mode); + assert !hasCall(tempOpId) || isStackSlot(result) || isConstant(result) || !isCallerSave(result) : "cannot have caller-save register operands at calls"; + return result; + } + }; + private void computeDebugInfo(IntervalWalker iw, final LIRInstruction op, LIRFrameState info) { info.initDebugInfo(frameMap, !op.destroysCallerSavedRegisters() || !callKillsRegisters); markFrameLocations(iw, op, info); - info.forEachState(new ValueProcedure() { - - @Override - public Value doValue(Value operand) { - int tempOpId = op.id(); - OperandMode mode = OperandMode.USE; - AbstractBlock block = blockForId(tempOpId); - if (block.getSuccessorCount() == 1 && tempOpId == getLastLirInstructionId(block)) { - // generating debug information for the last instruction of a block. - // if this instruction is a branch, spill moves are inserted before this branch - // and so the wrong operand would be returned (spill moves at block boundaries - // are not - // considered in the live ranges of intervals) - // Solution: use the first opId of the branch target block instead. - final LIRInstruction instr = ir.getLIRforBlock(block).get(ir.getLIRforBlock(block).size() - 1); - if (instr instanceof StandardOp.JumpOp) { - if (blockData.get(block).liveOut.get(operandNumber(operand))) { - tempOpId = getFirstLirInstructionId(block.getSuccessors().iterator().next()); - mode = OperandMode.DEF; - } - } - } - - // Get current location of operand - // The operand must be live because debug information is considered when building - // the intervals - // if the interval is not live, colorLirOperand will cause an assert on failure - Value result = colorLirOperand((Variable) operand, tempOpId, mode); - assert !hasCall(tempOpId) || isStackSlot(result) || isConstant(result) || !isCallerSave(result) : "cannot have caller-save register operands at calls"; - return result; - } - }); + info.forEachState(op, debugInfoProc); info.finish(op, frameMap); } @@ -1725,6 +1743,17 @@ int numInst = instructions.size(); boolean hasDead = false; + InstructionValueProcedure assignProc = new InstructionValueProcedure() { + + @Override + public Value doValue(LIRInstruction op, Value operand, OperandMode mode, EnumSet flags) { + if (isVariable(operand)) { + return colorLirOperand((Variable) operand, op.id(), mode); + } + return operand; + } + }; + for (int j = 0; j < numInst; j++) { final LIRInstruction op = instructions.get(j); if (op == null) { // this can happen when spill-moves are removed in eliminateSpillMoves @@ -1749,17 +1778,6 @@ } } - ValueProcedure assignProc = new ValueProcedure() { - - @Override - public Value doValue(Value operand, OperandMode mode, EnumSet flags) { - if (isVariable(operand)) { - return colorLirOperand((Variable) operand, op.id(), mode); - } - return operand; - } - }; - op.forEachInput(assignProc); op.forEachAlive(assignProc); op.forEachTemp(assignProc); diff -r 0eb8270ae69d -r f315b1c0a590 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/RegisterVerifier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/RegisterVerifier.java Wed Jun 04 14:52:17 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/RegisterVerifier.java Wed Jun 18 14:21:10 2014 +0200 @@ -32,9 +32,9 @@ import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.debug.*; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.LIRInstruction.InstructionValueProcedure; import com.oracle.graal.lir.LIRInstruction.OperandFlag; import com.oracle.graal.lir.LIRInstruction.OperandMode; -import com.oracle.graal.lir.LIRInstruction.ValueProcedure; import com.oracle.graal.phases.util.*; /** @@ -187,6 +187,38 @@ } void processOperations(List ops, final Interval[] inputState) { + InstructionValueProcedure useProc = new InstructionValueProcedure() { + + @Override + public Value doValue(LIRInstruction op, Value operand, OperandMode mode, EnumSet flags) { + if (LinearScan.isVariableOrRegister(operand) && allocator.isProcessed(operand)) { + Interval interval = intervalAt(operand); + if (op.id() != -1) { + interval = interval.getSplitChildAtOpId(op.id(), mode, allocator); + } + + assert checkState(inputState, interval.location(), interval.splitParent()); + } + return operand; + } + }; + + InstructionValueProcedure defProc = new InstructionValueProcedure() { + + @Override + public Value doValue(LIRInstruction op, Value operand, OperandMode mode, EnumSet flags) { + if (LinearScan.isVariableOrRegister(operand) && allocator.isProcessed(operand)) { + Interval interval = intervalAt(operand); + if (op.id() != -1) { + interval = interval.getSplitChildAtOpId(op.id(), mode, allocator); + } + + statePut(inputState, interval.location(), interval.splitParent()); + } + return operand; + } + }; + // visit all instructions of the block for (int i = 0; i < ops.size(); i++) { final LIRInstruction op = ops.get(i); @@ -195,38 +227,6 @@ Debug.log("%s", op.toStringWithIdPrefix()); } - ValueProcedure useProc = new ValueProcedure() { - - @Override - public Value doValue(Value operand, OperandMode mode, EnumSet flags) { - if (LinearScan.isVariableOrRegister(operand) && allocator.isProcessed(operand)) { - Interval interval = intervalAt(operand); - if (op.id() != -1) { - interval = interval.getSplitChildAtOpId(op.id(), mode, allocator); - } - - assert checkState(inputState, interval.location(), interval.splitParent()); - } - return operand; - } - }; - - ValueProcedure defProc = new ValueProcedure() { - - @Override - public Value doValue(Value operand, OperandMode mode, EnumSet flags) { - if (LinearScan.isVariableOrRegister(operand) && allocator.isProcessed(operand)) { - Interval interval = intervalAt(operand); - if (op.id() != -1) { - interval = interval.getSplitChildAtOpId(op.id(), mode, allocator); - } - - statePut(inputState, interval.location(), interval.splitParent()); - } - return operand; - } - }; - // check if input operands are correct op.forEachInput(useProc); // invalidate all caller save registers at calls diff -r 0eb8270ae69d -r f315b1c0a590 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRFrameState.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRFrameState.java Wed Jun 04 14:52:17 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRFrameState.java Wed Jun 18 14:21:10 2014 +0200 @@ -26,6 +26,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.lir.*; +import com.oracle.graal.lir.LIRInstruction.InstructionValueProcedure; import com.oracle.graal.lir.LIRInstruction.OperandMode; import com.oracle.graal.lir.LIRInstruction.ValueProcedure; @@ -50,4 +51,17 @@ return super.processValue(proc, value); } } + + @Override + protected Value processValue(LIRInstruction inst, InstructionValueProcedure proc, Value value) { + if (value instanceof HotSpotMonitorValue) { + HotSpotMonitorValue monitor = (HotSpotMonitorValue) value; + if (processed(monitor.getOwner())) { + monitor.setOwner(proc.doValue(inst, monitor.getOwner(), OperandMode.ALIVE, STATE_FLAGS)); + } + return value; + } else { + return super.processValue(inst, proc, value); + } + } } diff -r 0eb8270ae69d -r f315b1c0a590 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValue.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValue.java Wed Jun 04 14:52:17 2014 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValue.java Wed Jun 18 14:21:10 2014 +0200 @@ -26,6 +26,7 @@ import com.oracle.graal.api.meta.*; import com.oracle.graal.debug.*; +import com.oracle.graal.lir.LIRInstruction.InstructionValueProcedure; import com.oracle.graal.lir.LIRInstruction.OperandFlag; import com.oracle.graal.lir.LIRInstruction.OperandMode; import com.oracle.graal.lir.LIRInstruction.ValueProcedure; @@ -58,6 +59,10 @@ valueClass.forEachComponent(this, mode, proc); } + public final void forEachComponent(LIRInstruction inst, OperandMode mode, InstructionValueProcedure proc) { + valueClass.forEachComponent(inst, this, mode, proc); + } + @Override public String toString() { return valueClass.toString(this); diff -r 0eb8270ae69d -r f315b1c0a590 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java Wed Jun 04 14:52:17 2014 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/CompositeValueClass.java Wed Jun 18 14:21:10 2014 +0200 @@ -27,6 +27,7 @@ import com.oracle.graal.compiler.common.*; import com.oracle.graal.lir.CompositeValue.Component; +import com.oracle.graal.lir.LIRInstruction.InstructionValueProcedure; import com.oracle.graal.lir.LIRInstruction.OperandFlag; import com.oracle.graal.lir.LIRInstruction.OperandMode; import com.oracle.graal.lir.LIRInstruction.ValueProcedure; @@ -143,6 +144,10 @@ forEach(obj, directComponentCount, componentOffsets, mode, componentFlags, proc); } + public final void forEachComponent(LIRInstruction inst, CompositeValue obj, OperandMode mode, InstructionValueProcedure proc) { + forEach(inst, obj, directComponentCount, componentOffsets, mode, componentFlags, proc); + } + public String toString(CompositeValue obj) { StringBuilder result = new StringBuilder(); diff -r 0eb8270ae69d -r f315b1c0a590 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java Wed Jun 04 14:52:17 2014 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRFrameState.java Wed Jun 18 14:21:10 2014 +0200 @@ -28,6 +28,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; +import com.oracle.graal.lir.LIRInstruction.InstructionValueProcedure; import com.oracle.graal.lir.LIRInstruction.OperandFlag; import com.oracle.graal.lir.LIRInstruction.OperandMode; import com.oracle.graal.lir.LIRInstruction.ValueProcedure; @@ -60,7 +61,7 @@ /** * Iterates the frame state and calls the {@link ValueProcedure} for every variable. - * + * * @param proc The procedure called for variables. */ public void forEachState(ValueProcedure proc) { @@ -75,6 +76,22 @@ } /** + * Iterates the frame state and calls the {@link InstructionValueProcedure} for every variable. + * + * @param proc The procedure called for variables. + */ + public void forEachState(LIRInstruction inst, InstructionValueProcedure proc) { + for (BytecodeFrame cur = topFrame; cur != null; cur = cur.caller()) { + processValues(inst, cur.values, proc); + } + if (virtualObjects != null) { + for (VirtualObject obj : virtualObjects) { + processValues(inst, obj.getValues(), proc); + } + } + } + + /** * We filter out constant and illegal values ourself before calling the procedure, so * {@link OperandFlag#CONST} and {@link OperandFlag#ILLEGAL} need not be set. */ @@ -94,6 +111,20 @@ return value; } + protected void processValues(LIRInstruction inst, Value[] values, InstructionValueProcedure proc) { + for (int i = 0; i < values.length; i++) { + Value value = values[i]; + values[i] = processValue(inst, proc, value); + } + } + + protected Value processValue(LIRInstruction inst, InstructionValueProcedure proc, Value value) { + if (processed(value)) { + return proc.doValue(inst, value, OperandMode.ALIVE, STATE_FLAGS); + } + return value; + } + protected boolean processed(Value value) { if (isIllegal(value)) { // Ignore dead local variables. @@ -111,7 +142,7 @@ /** * Called by the register allocator before {@link #markLocation} to initialize the frame state. - * + * * @param frameMap The frame map. * @param canHaveRegisters True if there can be any register map entries. */ @@ -123,7 +154,7 @@ * Called by the register allocator to mark the specified location as a reference in the * reference map of the debug information. The tracked location can be a {@link RegisterValue} * or a {@link StackSlot}. Note that a {@link Constant} is automatically tracked. - * + * * @param location The location to be added to the reference map. * @param frameMap The frame map. */ @@ -133,7 +164,7 @@ /** * Called by the register allocator after all locations are marked. - * + * * @param op The instruction to which this frame state belongs. * @param frameMap The frame map. */ diff -r 0eb8270ae69d -r f315b1c0a590 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java Wed Jun 04 14:52:17 2014 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstruction.java Wed Jun 18 14:21:10 2014 +0200 @@ -51,7 +51,7 @@ /** * Iterator method to be overwritten. This version of the iterator does not take additional * parameters to keep the signature short. - * + * * @param value The value that is iterated. * @return The new value to replace the value that was passed in. */ @@ -62,7 +62,7 @@ /** * Iterator method to be overwritten. This version of the iterator gets additional * parameters about the processed value. - * + * * @param value The value that is iterated. * @param mode The operand mode for the value. * @param flags A set of flags for the value. @@ -73,6 +73,38 @@ } } + /** + * Similar to {@link ValueProcedure} but with an {@link LIRInstruction} parameter. + */ + public abstract static class InstructionValueProcedure { + + /** + * Iterator method to be overwritten. This version of the iterator does not take additional + * parameters to keep the signature short. + * + * @param instruction The current instruction. + * @param value The value that is iterated. + * @return The new value to replace the value that was passed in. + */ + protected Value doValue(LIRInstruction instruction, Value value) { + throw GraalInternalError.shouldNotReachHere("One of the doValue() methods must be overwritten"); + } + + /** + * Iterator method to be overwritten. This version of the iterator gets additional + * parameters about the processed value. + * + * @param instruction The current instruction. + * @param value The value that is iterated. + * @param mode The operand mode for the value. + * @param flags A set of flags for the value. + * @return The new value to replace the value that was passed in. + */ + public Value doValue(LIRInstruction instruction, Value value, OperandMode mode, EnumSet flags) { + return doValue(instruction, value); + } + } + public abstract static class StateProcedure { protected abstract void doState(LIRFrameState state); @@ -275,6 +307,26 @@ instructionClass.forEachState(this, proc); } + public final void forEachInput(InstructionValueProcedure proc) { + instructionClass.forEachUse(this, proc); + } + + public final void forEachAlive(InstructionValueProcedure proc) { + instructionClass.forEachAlive(this, proc); + } + + public final void forEachTemp(InstructionValueProcedure proc) { + instructionClass.forEachTemp(this, proc); + } + + public final void forEachOutput(InstructionValueProcedure proc) { + instructionClass.forEachDef(this, proc); + } + + public final void forEachState(InstructionValueProcedure proc) { + instructionClass.forEachState(this, proc); + } + public final void forEachState(StateProcedure proc) { instructionClass.forEachState(this, proc); } @@ -286,7 +338,7 @@ * Subclasses can override this method. The default implementation processes all Input operands * as the hints for an Output operand, and all Output operands as the hints for an Input * operand. - * + * * @param value The value the hints are needed for. * @param mode The operand mode of the value. * @param proc The procedure invoked for all the hints. If the procedure returns a non-null diff -r 0eb8270ae69d -r f315b1c0a590 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java Wed Jun 04 14:52:17 2014 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRInstructionClass.java Wed Jun 18 14:21:10 2014 +0200 @@ -28,6 +28,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; +import com.oracle.graal.lir.LIRInstruction.InstructionValueProcedure; import com.oracle.graal.lir.LIRInstruction.OperandFlag; import com.oracle.graal.lir.LIRInstruction.OperandMode; import com.oracle.graal.lir.LIRInstruction.StateProcedure; @@ -278,6 +279,22 @@ forEach(obj, directDefCount, defOffsets, OperandMode.DEF, defFlags, proc); } + public final void forEachUse(LIRInstruction obj, InstructionValueProcedure proc) { + forEach(obj, obj, directUseCount, useOffsets, OperandMode.USE, useFlags, proc); + } + + public final void forEachAlive(LIRInstruction obj, InstructionValueProcedure proc) { + forEach(obj, obj, directAliveCount, aliveOffsets, OperandMode.ALIVE, aliveFlags, proc); + } + + public final void forEachTemp(LIRInstruction obj, InstructionValueProcedure proc) { + forEach(obj, obj, directTempCount, tempOffsets, OperandMode.TEMP, tempFlags, proc); + } + + public final void forEachDef(LIRInstruction obj, InstructionValueProcedure proc) { + forEach(obj, obj, directDefCount, defOffsets, OperandMode.DEF, defFlags, proc); + } + public final void forEachState(LIRInstruction obj, ValueProcedure proc) { for (int i = 0; i < stateOffsets.length; i++) { LIRFrameState state = getState(obj, stateOffsets[i]); @@ -287,6 +304,15 @@ } } + public final void forEachState(LIRInstruction obj, InstructionValueProcedure proc) { + for (int i = 0; i < stateOffsets.length; i++) { + LIRFrameState state = getState(obj, stateOffsets[i]); + if (state != null) { + state.forEachState(obj, proc); + } + } + } + public final void forEachState(LIRInstruction obj, StateProcedure proc) { for (int i = 0; i < stateOffsets.length; i++) { LIRFrameState state = getState(obj, stateOffsets[i]); diff -r 0eb8270ae69d -r f315b1c0a590 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java Wed Jun 04 14:52:17 2014 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRIntrospection.java Wed Jun 18 14:21:10 2014 +0200 @@ -32,6 +32,7 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.common.*; +import com.oracle.graal.lir.LIRInstruction.InstructionValueProcedure; import com.oracle.graal.lir.LIRInstruction.OperandFlag; import com.oracle.graal.lir.LIRInstruction.OperandMode; import com.oracle.graal.lir.LIRInstruction.ValueProcedure; @@ -146,6 +147,33 @@ } } + protected static void forEach(LIRInstruction inst, Object obj, int directCount, long[] offsets, OperandMode mode, EnumSet[] flags, InstructionValueProcedure proc) { + for (int i = 0; i < offsets.length; i++) { + assert LIRInstruction.ALLOWED_FLAGS.get(mode).containsAll(flags[i]); + + if (i < directCount) { + Value value = getValue(obj, offsets[i]); + if (value instanceof CompositeValue) { + CompositeValue composite = (CompositeValue) value; + composite.forEachComponent(inst, mode, proc); + } else { + setValue(obj, offsets[i], proc.doValue(inst, value, mode, flags[i])); + } + } else { + Value[] values = getValueArray(obj, offsets[i]); + for (int j = 0; j < values.length; j++) { + Value value = values[j]; + if (value instanceof CompositeValue) { + CompositeValue composite = (CompositeValue) value; + composite.forEachComponent(inst, mode, proc); + } else { + values[j] = proc.doValue(inst, value, mode, flags[i]); + } + } + } + } + } + protected static Value getValue(Object obj, long offset) { return (Value) unsafe.getObject(obj, offset); } diff -r 0eb8270ae69d -r f315b1c0a590 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java Wed Jun 04 14:52:17 2014 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/LIRVerifier.java Wed Jun 18 14:21:10 2014 +0200 @@ -32,6 +32,7 @@ import com.oracle.graal.compiler.common.*; import com.oracle.graal.compiler.common.cfg.*; import com.oracle.graal.debug.*; +import com.oracle.graal.lir.LIRInstruction.InstructionValueProcedure; import com.oracle.graal.lir.LIRInstruction.OperandFlag; import com.oracle.graal.lir.LIRInstruction.OperandMode; import com.oracle.graal.lir.LIRInstruction.ValueProcedure; @@ -62,14 +63,15 @@ return isRegister(value) && frameMap.registerConfig.getAttributesMap()[asRegister(value).number].isAllocatable(); } - public static boolean verify(final LIRInstruction op) { - ValueProcedure allowedProc = new ValueProcedure() { + private static InstructionValueProcedure allowedProc = new InstructionValueProcedure() { - @Override - public Value doValue(Value value, OperandMode mode, EnumSet flags) { - return allowed(op, value, mode, flags); - } - }; + @Override + public Value doValue(LIRInstruction op, Value value, OperandMode mode, EnumSet flags) { + return allowed(op, value, mode, flags); + } + }; + + public static boolean verify(final LIRInstruction op) { op.forEachInput(allowedProc); op.forEachAlive(allowedProc);