# HG changeset patch # User Josef Eisl # Date 1423249598 -3600 # Node ID 6081b30fe164b274974be20991854d3886cecc2c # Parent de456294b59a77afc4cca7b9a85022521a7a7596 Make LocationMarker a LowLevelMidTierPhase. diff -r de456294b59a -r 6081b30fe164 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Fri Feb 06 20:00:32 2015 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Fri Feb 06 20:06:38 2015 +0100 @@ -361,6 +361,7 @@ } try (Scope s0 = Debug.scope("MidTier")) { + LowLevelMidTierPhase.Context c = new LowLevelMidTierPhase.Context<>(codeEmittingOrder, linearScanOrder); try (Scope s = Debug.scope("Allocator")) { if (backend.shouldAllocateRegisters()) { LinearScan.allocate(target, lirGenRes); @@ -381,7 +382,7 @@ try (Scope s1 = Debug.scope("MarkLocations")) { if (backend.shouldAllocateRegisters()) { // currently we mark locations only if we do register allocation - LocationMarker.markLocations(lirGenRes); + new LocationMarker().apply(target, lirGenRes, c); } } } diff -r de456294b59a -r 6081b30fe164 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LocationMarker.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LocationMarker.java Fri Feb 06 20:00:32 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LocationMarker.java Fri Feb 06 20:06:38 2015 +0100 @@ -35,9 +35,14 @@ import com.oracle.graal.lir.LIRInstruction.OperandMode; import com.oracle.graal.lir.framemap.*; import com.oracle.graal.lir.gen.*; +import com.oracle.graal.lir.phases.*; import com.oracle.graal.options.*; -public final class LocationMarker { +/** + * Mark all live references for a frame state. The frame state use this information to build the OOP + * maps. + */ +public final class LocationMarker> extends LowLevelMidTierPhase { public static class Options { // @formatter:off @@ -46,178 +51,177 @@ // @formatter:on } - /** - * Mark all live references for a frame state. The frame state use this information to build the - * OOP maps. - */ - public static void markLocations(LIRGenerationResult lirGenRes) { - new LocationMarker(lirGenRes.getLIR(), lirGenRes.getFrameMap()).build(); - } - - private final LIR lir; - private final FrameMap frameMap; - private final RegisterAttributes[] registerAttributes; - private final BlockMap liveInMap; - private final BlockMap liveOutMap; - - private LocationMarker(LIR lir, FrameMap frameMap) { - this.lir = lir; - this.frameMap = frameMap; - this.registerAttributes = frameMap.getRegisterConfig().getAttributesMap(); - liveInMap = new BlockMap<>(lir.getControlFlowGraph()); - liveOutMap = new BlockMap<>(lir.getControlFlowGraph()); + @Override + protected void run(TargetDescription target, LIRGenerationResult lirGenRes, List codeEmittingOrder, List linearScanOrder) { + new Marker(lirGenRes.getLIR(), lirGenRes.getFrameMap()).build(); } - private void build() { - Deque> worklist = new ArrayDeque<>(); - for (int i = lir.getControlFlowGraph().getBlocks().size() - 1; i >= 0; i--) { - worklist.add(lir.getControlFlowGraph().getBlocks().get(i)); - } - for (AbstractBlock block : lir.getControlFlowGraph().getBlocks()) { - liveInMap.put(block, frameMap.initReferenceMap(true)); - } - while (!worklist.isEmpty()) { - AbstractBlock block = worklist.poll(); - processBlock(block, worklist); - } - // finish states - for (AbstractBlock block : lir.getControlFlowGraph().getBlocks()) { - List instructions = lir.getLIRforBlock(block); - for (int i = instructions.size() - 1; i >= 0; i--) { - LIRInstruction inst = instructions.get(i); - inst.forEachState((op, info) -> info.finish(op, frameMap)); - } + private static final class Marker { + private final LIR lir; + private final FrameMap frameMap; + private final RegisterAttributes[] registerAttributes; + private final BlockMap liveInMap; + private final BlockMap liveOutMap; + private Marker(LIR lir, FrameMap frameMap) { + this.lir = lir; + this.frameMap = frameMap; + this.registerAttributes = frameMap.getRegisterConfig().getAttributesMap(); + liveInMap = new BlockMap<>(lir.getControlFlowGraph()); + liveOutMap = new BlockMap<>(lir.getControlFlowGraph()); } - } - /** - * Merge outSet with in-set of successors. - */ - private boolean updateOutBlock(AbstractBlock block) { - ReferenceMap union = frameMap.initReferenceMap(true); - block.getSuccessors().forEach(succ -> union.updateUnion(liveInMap.get(succ))); - ReferenceMap outSet = liveOutMap.get(block); - // check if changed - if (outSet == null || !union.equals(outSet)) { - liveOutMap.put(block, union); - return true; - } - return false; - } - - private void processBlock(AbstractBlock block, Deque> worklist) { - if (updateOutBlock(block)) { - try (Indent indent = Debug.logAndIndent("handle block %s", block)) { - BlockClosure closure = new BlockClosure(liveOutMap.get(block).clone()); + private void build() { + Deque> worklist = new ArrayDeque<>(); + for (int i = lir.getControlFlowGraph().getBlocks().size() - 1; i >= 0; i--) { + worklist.add(lir.getControlFlowGraph().getBlocks().get(i)); + } + for (AbstractBlock block : lir.getControlFlowGraph().getBlocks()) { + liveInMap.put(block, frameMap.initReferenceMap(true)); + } + while (!worklist.isEmpty()) { + AbstractBlock block = worklist.poll(); + processBlock(block, worklist); + } + // finish states + for (AbstractBlock block : lir.getControlFlowGraph().getBlocks()) { List instructions = lir.getLIRforBlock(block); for (int i = instructions.size() - 1; i >= 0; i--) { LIRInstruction inst = instructions.get(i); - closure.processInstructionBottomUp(inst); + inst.forEachState((op, info) -> info.finish(op, frameMap)); } - liveInMap.put(block, closure.getCurrentSet()); - worklist.addAll(block.getPredecessors()); - } - } - } - - private static final EnumSet REGISTER_FLAG_SET = EnumSet.of(OperandFlag.REG); - private static final LIRKind REFERENCE_KIND = LIRKind.reference(Kind.Object); - - private void forEachDestroyedCallerSavedRegister(LIRInstruction op, ValueConsumer consumer) { - if (op.destroysCallerSavedRegisters()) { - for (Register reg : frameMap.getRegisterConfig().getCallerSaveRegisters()) { - consumer.visitValue(reg.asValue(REFERENCE_KIND), OperandMode.TEMP, REGISTER_FLAG_SET); - } - } - } - - private final class BlockClosure { - private final ReferenceMap currentSet; - private BlockClosure(ReferenceMap set) { - currentSet = set; - } - - private ReferenceMap getCurrentSet() { - return currentSet; - } - - /** - * Process all values of an instruction bottom-up, i.e. definitions before usages. Values - * that start or end at the current operation are not included. - */ - private void processInstructionBottomUp(LIRInstruction op) { - try (Indent indent = Debug.logAndIndent("handle op %d, %s", op.id(), op)) { - // kills - op.visitEachTemp(this::defConsumer); - op.visitEachOutput(this::defConsumer); - forEachDestroyedCallerSavedRegister(op, this::defConsumer); - - // gen - values that are considered alive for this state - op.visitEachAlive(this::useConsumer); - op.visitEachState(this::useConsumer); - // mark locations - op.forEachState((inst, info) -> markLocation(inst, info, this.getCurrentSet())); - // gen - op.visitEachInput(this::useConsumer); } } /** - * @see InstructionValueConsumer - * @param operand - * @param mode - * @param flags + * Merge outSet with in-set of successors. */ - private void useConsumer(Value operand, OperandMode mode, EnumSet flags) { - LIRKind kind = operand.getLIRKind(); - if (shouldProcessValue(operand) && !kind.isValue() && !kind.isDerivedReference()) { - // no need to insert values and derived reference - Debug.log("set operand: %s", operand); - frameMap.setReference(operand, currentSet); + private boolean updateOutBlock(AbstractBlock block) { + ReferenceMap union = frameMap.initReferenceMap(true); + block.getSuccessors().forEach(succ -> union.updateUnion(liveInMap.get(succ))); + ReferenceMap outSet = liveOutMap.get(block); + // check if changed + if (outSet == null || !union.equals(outSet)) { + liveOutMap.put(block, union); + return true; + } + return false; + } + + private void processBlock(AbstractBlock block, Deque> worklist) { + if (updateOutBlock(block)) { + try (Indent indent = Debug.logAndIndent("handle block %s", block)) { + BlockClosure closure = new BlockClosure(liveOutMap.get(block).clone()); + List instructions = lir.getLIRforBlock(block); + for (int i = instructions.size() - 1; i >= 0; i--) { + LIRInstruction inst = instructions.get(i); + closure.processInstructionBottomUp(inst); + } + liveInMap.put(block, closure.getCurrentSet()); + worklist.addAll(block.getPredecessors()); + } + } + } + + private static final EnumSet REGISTER_FLAG_SET = EnumSet.of(OperandFlag.REG); + private static final LIRKind REFERENCE_KIND = LIRKind.reference(Kind.Object); + + private void forEachDestroyedCallerSavedRegister(LIRInstruction op, ValueConsumer consumer) { + if (op.destroysCallerSavedRegisters()) { + for (Register reg : frameMap.getRegisterConfig().getCallerSaveRegisters()) { + consumer.visitValue(reg.asValue(REFERENCE_KIND), OperandMode.TEMP, REGISTER_FLAG_SET); + } + } + } + + private final class BlockClosure { + private final ReferenceMap currentSet; + + private BlockClosure(ReferenceMap set) { + currentSet = set; + } + + private ReferenceMap getCurrentSet() { + return currentSet; + } + + /** + * Process all values of an instruction bottom-up, i.e. definitions before usages. + * Values that start or end at the current operation are not included. + */ + private void processInstructionBottomUp(LIRInstruction op) { + try (Indent indent = Debug.logAndIndent("handle op %d, %s", op.id(), op)) { + // kills + op.visitEachTemp(this::defConsumer); + op.visitEachOutput(this::defConsumer); + forEachDestroyedCallerSavedRegister(op, this::defConsumer); + + // gen - values that are considered alive for this state + op.visitEachAlive(this::useConsumer); + op.visitEachState(this::useConsumer); + // mark locations + op.forEachState((inst, info) -> markLocation(inst, info, this.getCurrentSet())); + // gen + op.visitEachInput(this::useConsumer); + } + } + + /** + * @see InstructionValueConsumer + * @param operand + * @param mode + * @param flags + */ + private void useConsumer(Value operand, OperandMode mode, EnumSet flags) { + LIRKind kind = operand.getLIRKind(); + if (shouldProcessValue(operand) && !kind.isValue() && !kind.isDerivedReference()) { + // no need to insert values and derived reference + Debug.log("set operand: %s", operand); + frameMap.setReference(operand, currentSet); + } + } + + /** + * @see InstructionValueConsumer + * @param operand + * @param mode + * @param flags + */ + private void defConsumer(Value operand, OperandMode mode, EnumSet flags) { + if (shouldProcessValue(operand)) { + Debug.log("clear operand: %s", operand); + frameMap.clearReference(operand, currentSet); + } else { + assert isIllegal(operand) || operand.getPlatformKind() != Kind.Illegal || mode == OperandMode.TEMP : String.format("Illegal PlatformKind is only allowed for TEMP mode: %s, %s", + operand, mode); + } + } + + protected boolean shouldProcessValue(Value operand) { + return (isRegister(operand) && attributes(asRegister(operand)).isAllocatable() || isStackSlot(operand)) && operand.getPlatformKind() != Kind.Illegal; } } /** - * @see InstructionValueConsumer - * @param operand - * @param mode - * @param flags + * This method does the actual marking. */ - private void defConsumer(Value operand, OperandMode mode, EnumSet flags) { - if (shouldProcessValue(operand)) { - Debug.log("clear operand: %s", operand); - frameMap.clearReference(operand, currentSet); - } else { - assert isIllegal(operand) || operand.getPlatformKind() != Kind.Illegal || mode == OperandMode.TEMP : String.format("Illegal PlatformKind is only allowed for TEMP mode: %s, %s", - operand, mode); + private void markLocation(LIRInstruction op, LIRFrameState info, ReferenceMap refMap) { + if (!info.hasDebugInfo()) { + info.initDebugInfo(frameMap, !op.destroysCallerSavedRegisters() || !frameMap.getRegisterConfig().areAllAllocatableRegistersCallerSaved()); } + info.updateUnion(refMap); } - protected boolean shouldProcessValue(Value operand) { - return (isRegister(operand) && attributes(asRegister(operand)).isAllocatable() || isStackSlot(operand)) && operand.getPlatformKind() != Kind.Illegal; - } - } - - /** - * This method does the actual marking. - */ - private void markLocation(LIRInstruction op, LIRFrameState info, ReferenceMap refMap) { - if (!info.hasDebugInfo()) { - info.initDebugInfo(frameMap, !op.destroysCallerSavedRegisters() || !frameMap.getRegisterConfig().areAllAllocatableRegistersCallerSaved()); + /** + * Gets an object describing the attributes of a given register according to this register + * configuration. + * + * @see LinearScan#attributes + */ + private RegisterAttributes attributes(Register reg) { + return registerAttributes[reg.number]; } - info.updateUnion(refMap); + } - - /** - * Gets an object describing the attributes of a given register according to this register - * configuration. - * - * @see LinearScan#attributes - */ - private RegisterAttributes attributes(Register reg) { - return registerAttributes[reg.number]; - } - -} +} \ No newline at end of file