src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/dfa/LocationMarker.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Sdiff src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/dfa

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/dfa/LocationMarker.java

Print this page




  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package org.graalvm.compiler.lir.dfa;
  24 
  25 import static jdk.vm.ci.code.ValueUtil.isIllegal;
  26 
  27 import java.util.ArrayList;
  28 import java.util.EnumSet;
  29 
  30 import org.graalvm.compiler.core.common.LIRKind;
  31 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
  32 import org.graalvm.compiler.core.common.cfg.BlockMap;
  33 import org.graalvm.compiler.debug.Debug;
  34 import org.graalvm.compiler.debug.Indent;
  35 import org.graalvm.compiler.lir.InstructionStateProcedure;
  36 import org.graalvm.compiler.lir.LIR;
  37 import org.graalvm.compiler.lir.LIRFrameState;
  38 import org.graalvm.compiler.lir.LIRInstruction;
  39 import org.graalvm.compiler.lir.LIRInstruction.OperandFlag;
  40 import org.graalvm.compiler.lir.LIRInstruction.OperandMode;
  41 import org.graalvm.compiler.lir.ValueConsumer;
  42 import org.graalvm.compiler.lir.framemap.FrameMap;
  43 import org.graalvm.compiler.lir.util.ValueSet;
  44 
  45 import jdk.vm.ci.code.Register;
  46 import jdk.vm.ci.meta.PlatformKind;
  47 import jdk.vm.ci.meta.Value;
  48 
  49 public abstract class LocationMarker<S extends ValueSet<S>> {
  50 
  51     private final LIR lir;
  52     private final BlockMap<S> liveInMap;
  53     private final BlockMap<S> liveOutMap;


  85     /**
  86      * Merge outSet with in-set of successors.
  87      */
  88     private boolean updateOutBlock(AbstractBlockBase<?> block) {
  89         S union = newLiveValueSet();
  90         for (AbstractBlockBase<?> succ : block.getSuccessors()) {
  91             union.putAll(liveInMap.get(succ));
  92         }
  93         S outSet = liveOutMap.get(block);
  94         // check if changed
  95         if (outSet == null || !union.equals(outSet)) {
  96             liveOutMap.put(block, union);
  97             return true;
  98         }
  99         return false;
 100     }
 101 
 102     @SuppressWarnings("try")
 103     private void processBlock(AbstractBlockBase<?> block, UniqueWorkList worklist) {
 104         if (updateOutBlock(block)) {
 105             try (Indent indent = Debug.logAndIndent("handle block %s", block)) {

 106                 currentSet = liveOutMap.get(block).copy();
 107                 ArrayList<LIRInstruction> instructions = lir.getLIRforBlock(block);
 108                 for (int i = instructions.size() - 1; i >= 0; i--) {
 109                     LIRInstruction inst = instructions.get(i);
 110                     processInstructionBottomUp(inst);
 111                 }
 112                 liveInMap.put(block, currentSet);
 113                 currentSet = null;
 114                 for (AbstractBlockBase<?> b : block.getPredecessors()) {
 115                     worklist.add(b);
 116                 }
 117             }
 118         }
 119     }
 120 
 121     private static final EnumSet<OperandFlag> REGISTER_FLAG_SET = EnumSet.of(OperandFlag.REG);
 122 
 123     private S currentSet;
 124 
 125     /**
 126      * Process all values of an instruction bottom-up, i.e. definitions before usages. Values that
 127      * start or end at the current operation are not included.
 128      */
 129     @SuppressWarnings("try")
 130     private void processInstructionBottomUp(LIRInstruction op) {
 131         try (Indent indent = Debug.logAndIndent("handle op %d, %s", op.id(), op)) {

 132             // kills
 133 
 134             op.visitEachTemp(defConsumer);
 135             op.visitEachOutput(defConsumer);
 136             if (frameMap != null && op.destroysCallerSavedRegisters()) {
 137                 for (Register reg : frameMap.getRegisterConfig().getCallerSaveRegisters()) {
 138                     PlatformKind kind = frameMap.getTarget().arch.getLargestStorableKind(reg.getRegisterCategory());
 139                     defConsumer.visitValue(reg.asValue(LIRKind.value(kind)), OperandMode.TEMP, REGISTER_FLAG_SET);
 140                 }
 141             }
 142 
 143             // gen - values that are considered alive for this state
 144             op.visitEachAlive(useConsumer);
 145             op.visitEachState(useConsumer);
 146             // mark locations
 147             op.forEachState(stateConsumer);
 148             // gen
 149             op.visitEachInput(useConsumer);
 150         }
 151     }
 152 
 153     InstructionStateProcedure stateConsumer = new InstructionStateProcedure() {
 154         @Override
 155         public void doState(LIRInstruction inst, LIRFrameState info) {
 156             processState(inst, info, currentSet);
 157         }
 158     };
 159 
 160     ValueConsumer useConsumer = new ValueConsumer() {
 161         @Override
 162         public void visitValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
 163             if (shouldProcessValue(operand)) {
 164                 // no need to insert values and derived reference
 165                 if (Debug.isLogEnabled()) {
 166                     Debug.log("set operand: %s", operand);

 167                 }
 168                 currentSet.put(operand);
 169             }
 170         }
 171     };
 172 
 173     ValueConsumer defConsumer = new ValueConsumer() {
 174         @Override
 175         public void visitValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
 176             if (shouldProcessValue(operand)) {
 177                 if (Debug.isLogEnabled()) {
 178                     Debug.log("clear operand: %s", operand);

 179                 }
 180                 currentSet.remove(operand);
 181             } else {
 182                 assert isIllegal(operand) || !operand.getValueKind().equals(LIRKind.Illegal) || mode == OperandMode.TEMP : String.format("Illegal PlatformKind is only allowed for TEMP mode: %s, %s",
 183                                 operand, mode);
 184             }
 185         }
 186     };
 187 }


  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 package org.graalvm.compiler.lir.dfa;
  24 
  25 import static jdk.vm.ci.code.ValueUtil.isIllegal;
  26 
  27 import java.util.ArrayList;
  28 import java.util.EnumSet;
  29 
  30 import org.graalvm.compiler.core.common.LIRKind;
  31 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
  32 import org.graalvm.compiler.core.common.cfg.BlockMap;
  33 import org.graalvm.compiler.debug.DebugContext;
  34 import org.graalvm.compiler.debug.Indent;
  35 import org.graalvm.compiler.lir.InstructionStateProcedure;
  36 import org.graalvm.compiler.lir.LIR;
  37 import org.graalvm.compiler.lir.LIRFrameState;
  38 import org.graalvm.compiler.lir.LIRInstruction;
  39 import org.graalvm.compiler.lir.LIRInstruction.OperandFlag;
  40 import org.graalvm.compiler.lir.LIRInstruction.OperandMode;
  41 import org.graalvm.compiler.lir.ValueConsumer;
  42 import org.graalvm.compiler.lir.framemap.FrameMap;
  43 import org.graalvm.compiler.lir.util.ValueSet;
  44 
  45 import jdk.vm.ci.code.Register;
  46 import jdk.vm.ci.meta.PlatformKind;
  47 import jdk.vm.ci.meta.Value;
  48 
  49 public abstract class LocationMarker<S extends ValueSet<S>> {
  50 
  51     private final LIR lir;
  52     private final BlockMap<S> liveInMap;
  53     private final BlockMap<S> liveOutMap;


  85     /**
  86      * Merge outSet with in-set of successors.
  87      */
  88     private boolean updateOutBlock(AbstractBlockBase<?> block) {
  89         S union = newLiveValueSet();
  90         for (AbstractBlockBase<?> succ : block.getSuccessors()) {
  91             union.putAll(liveInMap.get(succ));
  92         }
  93         S outSet = liveOutMap.get(block);
  94         // check if changed
  95         if (outSet == null || !union.equals(outSet)) {
  96             liveOutMap.put(block, union);
  97             return true;
  98         }
  99         return false;
 100     }
 101 
 102     @SuppressWarnings("try")
 103     private void processBlock(AbstractBlockBase<?> block, UniqueWorkList worklist) {
 104         if (updateOutBlock(block)) {
 105             DebugContext debug = lir.getDebug();
 106             try (Indent indent = debug.logAndIndent("handle block %s", block)) {
 107                 currentSet = liveOutMap.get(block).copy();
 108                 ArrayList<LIRInstruction> instructions = lir.getLIRforBlock(block);
 109                 for (int i = instructions.size() - 1; i >= 0; i--) {
 110                     LIRInstruction inst = instructions.get(i);
 111                     processInstructionBottomUp(inst);
 112                 }
 113                 liveInMap.put(block, currentSet);
 114                 currentSet = null;
 115                 for (AbstractBlockBase<?> b : block.getPredecessors()) {
 116                     worklist.add(b);
 117                 }
 118             }
 119         }
 120     }
 121 
 122     private static final EnumSet<OperandFlag> REGISTER_FLAG_SET = EnumSet.of(OperandFlag.REG);
 123 
 124     private S currentSet;
 125 
 126     /**
 127      * Process all values of an instruction bottom-up, i.e. definitions before usages. Values that
 128      * start or end at the current operation are not included.
 129      */
 130     @SuppressWarnings("try")
 131     private void processInstructionBottomUp(LIRInstruction op) {
 132         DebugContext debug = lir.getDebug();
 133         try (Indent indent = debug.logAndIndent("handle op %d, %s", op.id(), op)) {
 134             // kills
 135 
 136             op.visitEachTemp(defConsumer);
 137             op.visitEachOutput(defConsumer);
 138             if (frameMap != null && op.destroysCallerSavedRegisters()) {
 139                 for (Register reg : frameMap.getRegisterConfig().getCallerSaveRegisters()) {
 140                     PlatformKind kind = frameMap.getTarget().arch.getLargestStorableKind(reg.getRegisterCategory());
 141                     defConsumer.visitValue(reg.asValue(LIRKind.value(kind)), OperandMode.TEMP, REGISTER_FLAG_SET);
 142                 }
 143             }
 144 
 145             // gen - values that are considered alive for this state
 146             op.visitEachAlive(useConsumer);
 147             op.visitEachState(useConsumer);
 148             // mark locations
 149             op.forEachState(stateConsumer);
 150             // gen
 151             op.visitEachInput(useConsumer);
 152         }
 153     }
 154 
 155     InstructionStateProcedure stateConsumer = new InstructionStateProcedure() {
 156         @Override
 157         public void doState(LIRInstruction inst, LIRFrameState info) {
 158             processState(inst, info, currentSet);
 159         }
 160     };
 161 
 162     ValueConsumer useConsumer = new ValueConsumer() {
 163         @Override
 164         public void visitValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
 165             if (shouldProcessValue(operand)) {
 166                 // no need to insert values and derived reference
 167                 DebugContext debug = lir.getDebug();
 168                 if (debug.isLogEnabled()) {
 169                     debug.log("set operand: %s", operand);
 170                 }
 171                 currentSet.put(operand);
 172             }
 173         }
 174     };
 175 
 176     ValueConsumer defConsumer = new ValueConsumer() {
 177         @Override
 178         public void visitValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) {
 179             if (shouldProcessValue(operand)) {
 180                 DebugContext debug = lir.getDebug();
 181                 if (debug.isLogEnabled()) {
 182                     debug.log("clear operand: %s", operand);
 183                 }
 184                 currentSet.remove(operand);
 185             } else {
 186                 assert isIllegal(operand) || !operand.getValueKind().equals(LIRKind.Illegal) || mode == OperandMode.TEMP : String.format("Illegal PlatformKind is only allowed for TEMP mode: %s, %s",
 187                                 operand, mode);
 188             }
 189         }
 190     };
 191 }
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/dfa/LocationMarker.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File