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; |