hotspot/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanAssignLocationsPhase.java
changeset 46459 7d4e637d3f21
parent 46393 d497d892ab11
child 46640 70bdce04c59b
equal deleted inserted replaced
46458:3c12af929e7d 46459:7d4e637d3f21
    35 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
    35 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
    36 import org.graalvm.compiler.debug.Debug;
    36 import org.graalvm.compiler.debug.Debug;
    37 import org.graalvm.compiler.debug.Indent;
    37 import org.graalvm.compiler.debug.Indent;
    38 import org.graalvm.compiler.lir.ConstantValue;
    38 import org.graalvm.compiler.lir.ConstantValue;
    39 import org.graalvm.compiler.lir.InstructionValueProcedure;
    39 import org.graalvm.compiler.lir.InstructionValueProcedure;
    40 import org.graalvm.compiler.lir.LIRFrameState;
       
    41 import org.graalvm.compiler.lir.LIRInstruction;
    40 import org.graalvm.compiler.lir.LIRInstruction;
    42 import org.graalvm.compiler.lir.LIRInstruction.OperandFlag;
    41 import org.graalvm.compiler.lir.LIRInstruction.OperandFlag;
    43 import org.graalvm.compiler.lir.LIRInstruction.OperandMode;
    42 import org.graalvm.compiler.lir.LIRInstruction.OperandMode;
    44 import org.graalvm.compiler.lir.StandardOp;
    43 import org.graalvm.compiler.lir.StandardOp;
    45 import org.graalvm.compiler.lir.StandardOp.MoveOp;
    44 import org.graalvm.compiler.lir.StandardOp.MoveOp;
   113             return new ConstantValue(interval.kind(), interval.getMaterializedValue());
   112             return new ConstantValue(interval.kind(), interval.getMaterializedValue());
   114         }
   113         }
   115         return interval.location();
   114         return interval.location();
   116     }
   115     }
   117 
   116 
   118     /**
   117     private Value debugInfoProcedure(LIRInstruction op, Value operand) {
   119      * @param op
       
   120      * @param operand
       
   121      * @param valueMode
       
   122      * @param flags
       
   123      * @see InstructionValueProcedure#doValue(LIRInstruction, Value, OperandMode, EnumSet)
       
   124      */
       
   125     private Value debugInfoProcedure(LIRInstruction op, Value operand, OperandMode valueMode, EnumSet<OperandFlag> flags) {
       
   126         if (isVirtualStackSlot(operand)) {
   118         if (isVirtualStackSlot(operand)) {
   127             return operand;
   119             return operand;
   128         }
   120         }
   129         int tempOpId = op.id();
   121         int tempOpId = op.id();
   130         OperandMode mode = OperandMode.USE;
   122         OperandMode mode = OperandMode.USE;
   155         Value result = colorLirOperand(op, (Variable) operand, mode);
   147         Value result = colorLirOperand(op, (Variable) operand, mode);
   156         assert !allocator.hasCall(tempOpId) || isStackSlotValue(result) || isJavaConstant(result) || !allocator.isCallerSave(result) : "cannot have caller-save register operands at calls";
   148         assert !allocator.hasCall(tempOpId) || isStackSlotValue(result) || isJavaConstant(result) || !allocator.isCallerSave(result) : "cannot have caller-save register operands at calls";
   157         return result;
   149         return result;
   158     }
   150     }
   159 
   151 
   160     private void computeDebugInfo(final LIRInstruction op, LIRFrameState info) {
       
   161         info.forEachState(op, this::debugInfoProcedure);
       
   162     }
       
   163 
       
   164     private void assignLocations(ArrayList<LIRInstruction> instructions) {
   152     private void assignLocations(ArrayList<LIRInstruction> instructions) {
   165         int numInst = instructions.size();
   153         int numInst = instructions.size();
   166         boolean hasDead = false;
   154         boolean hasDead = false;
   167 
   155 
   168         for (int j = 0; j < numInst; j++) {
   156         for (int j = 0; j < numInst; j++) {
   182             // Remove null values from the list.
   170             // Remove null values from the list.
   183             instructions.removeAll(Collections.singleton(null));
   171             instructions.removeAll(Collections.singleton(null));
   184         }
   172         }
   185     }
   173     }
   186 
   174 
       
   175     private final InstructionValueProcedure assignProc = new InstructionValueProcedure() {
       
   176         @Override
       
   177         public Value doValue(LIRInstruction instruction, Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
       
   178             if (isVariable(value)) {
       
   179                 return colorLirOperand(instruction, (Variable) value, mode);
       
   180             }
       
   181             return value;
       
   182         }
       
   183     };
       
   184     private final InstructionValueProcedure debugInfoProc = new InstructionValueProcedure() {
       
   185         @Override
       
   186         public Value doValue(LIRInstruction instruction, Value value, OperandMode mode, EnumSet<OperandFlag> flags) {
       
   187             return debugInfoProcedure(instruction, value);
       
   188         }
       
   189     };
       
   190 
   187     /**
   191     /**
   188      * Assigns the operand of an {@link LIRInstruction}.
   192      * Assigns the operand of an {@link LIRInstruction}.
   189      *
   193      *
   190      * @param op The {@link LIRInstruction} that should be colored.
   194      * @param op The {@link LIRInstruction} that should be colored.
   191      * @return {@code true} if the instruction should be deleted.
   195      * @return {@code true} if the instruction should be deleted.
   192      */
   196      */
   193     protected boolean assignLocations(LIRInstruction op) {
   197     protected boolean assignLocations(LIRInstruction op) {
   194         assert op != null;
   198         assert op != null;
   195 
   199 
   196         InstructionValueProcedure assignProc = (inst, operand, mode, flags) -> isVariable(operand) ? colorLirOperand(inst, (Variable) operand, mode) : operand;
       
   197         // remove useless moves
   200         // remove useless moves
   198         if (op instanceof MoveOp) {
   201         if (MoveOp.isMoveOp(op)) {
   199             AllocatableValue result = ((MoveOp) op).getResult();
   202             AllocatableValue result = MoveOp.asMoveOp(op).getResult();
   200             if (isVariable(result) && allocator.isMaterialized(result, op.id(), OperandMode.DEF)) {
   203             if (isVariable(result) && allocator.isMaterialized(result, op.id(), OperandMode.DEF)) {
   201                 /*
   204                 /*
   202                  * This happens if a materializable interval is originally not spilled but then
   205                  * This happens if a materializable interval is originally not spilled but then
   203                  * kicked out in LinearScanWalker.splitForSpilling(). When kicking out such an
   206                  * kicked out in LinearScanWalker.splitForSpilling(). When kicking out such an
   204                  * interval this move operation was already generated.
   207                  * interval this move operation was already generated.
   211         op.forEachAlive(assignProc);
   214         op.forEachAlive(assignProc);
   212         op.forEachTemp(assignProc);
   215         op.forEachTemp(assignProc);
   213         op.forEachOutput(assignProc);
   216         op.forEachOutput(assignProc);
   214 
   217 
   215         // compute reference map and debug information
   218         // compute reference map and debug information
   216         op.forEachState((inst, state) -> computeDebugInfo(inst, state));
   219         op.forEachState(debugInfoProc);
   217 
   220 
   218         // remove useless moves
   221         // remove useless moves
   219         if (op instanceof ValueMoveOp) {
   222         if (ValueMoveOp.isValueMoveOp(op)) {
   220             ValueMoveOp move = (ValueMoveOp) op;
   223             ValueMoveOp move = ValueMoveOp.asValueMoveOp(op);
   221             if (move.getInput().equals(move.getResult())) {
   224             if (move.getInput().equals(move.getResult())) {
   222                 return true;
   225                 return true;
   223             }
   226             }
   224         }
   227         }
   225         return false;
   228         return false;