changeset 19211:6081b30fe164

Make LocationMarker a LowLevelMidTierPhase.
author Josef Eisl <josef.eisl@jku.at>
date Fri, 06 Feb 2015 20:06:38 +0100
parents de456294b59a
children 95a7954ea155
files graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LocationMarker.java
diffstat 2 files changed, 157 insertions(+), 152 deletions(-) [+]
line wrap: on
line diff
--- 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<T> 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<T>().apply(target, lirGenRes, c);
                 }
             }
         }
--- 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<B extends AbstractBlock<B>> extends LowLevelMidTierPhase<B> {
 
     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<ReferenceMap> liveInMap;
-    private final BlockMap<ReferenceMap> 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<B> codeEmittingOrder, List<B> linearScanOrder) {
+        new Marker(lirGenRes.getLIR(), lirGenRes.getFrameMap()).build();
     }
 
-    private void build() {
-        Deque<AbstractBlock<?>> 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<LIRInstruction> 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<ReferenceMap> liveInMap;
+        private final BlockMap<ReferenceMap> 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<AbstractBlock<?>> 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<AbstractBlock<?>> 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<LIRInstruction> 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<OperandFlag> 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<OperandFlag> 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<AbstractBlock<?>> worklist) {
+            if (updateOutBlock(block)) {
+                try (Indent indent = Debug.logAndIndent("handle block %s", block)) {
+                    BlockClosure closure = new BlockClosure(liveOutMap.get(block).clone());
+                    List<LIRInstruction> 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<OperandFlag> 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<OperandFlag> 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<OperandFlag> 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<OperandFlag> 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