< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.core/src/org/graalvm/compiler/core/gen/NodeLIRBuilder.java

Print this page




  31 import static org.graalvm.compiler.core.common.SpeculativeExecutionAttacksMitigations.Options.MitigateSpeculativeExecutionAttacks;
  32 import static org.graalvm.compiler.core.common.GraalOptions.MatchExpressions;
  33 import static org.graalvm.compiler.debug.DebugOptions.LogVerbose;
  34 import static org.graalvm.compiler.lir.LIR.verifyBlock;
  35 
  36 import java.util.ArrayList;
  37 import java.util.Collection;
  38 import java.util.List;
  39 
  40 import jdk.internal.vm.compiler.collections.EconomicMap;
  41 import jdk.internal.vm.compiler.collections.UnmodifiableMapCursor;
  42 import org.graalvm.compiler.core.common.LIRKind;
  43 import org.graalvm.compiler.core.common.calc.Condition;
  44 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
  45 import org.graalvm.compiler.core.common.cfg.BlockMap;
  46 import org.graalvm.compiler.core.common.type.Stamp;
  47 import org.graalvm.compiler.core.match.ComplexMatchValue;
  48 import org.graalvm.compiler.core.match.MatchPattern;
  49 import org.graalvm.compiler.core.match.MatchRuleRegistry;
  50 import org.graalvm.compiler.core.match.MatchStatement;

  51 import org.graalvm.compiler.debug.DebugContext;
  52 import org.graalvm.compiler.debug.GraalError;
  53 import org.graalvm.compiler.debug.TTY;
  54 import org.graalvm.compiler.graph.GraalGraphError;
  55 import org.graalvm.compiler.graph.Node;
  56 import org.graalvm.compiler.graph.NodeMap;
  57 import org.graalvm.compiler.graph.NodeSourcePosition;
  58 import org.graalvm.compiler.graph.iterators.NodeIterable;
  59 import org.graalvm.compiler.lir.FullInfopointOp;
  60 import org.graalvm.compiler.lir.LIRFrameState;
  61 import org.graalvm.compiler.lir.LIRInstruction;
  62 import org.graalvm.compiler.lir.LabelRef;
  63 import org.graalvm.compiler.lir.StandardOp.JumpOp;
  64 import org.graalvm.compiler.lir.StandardOp.LabelOp;
  65 import org.graalvm.compiler.lir.SwitchStrategy;
  66 import org.graalvm.compiler.lir.Variable;
  67 import org.graalvm.compiler.lir.debug.LIRGenerationDebugContext;
  68 import org.graalvm.compiler.lir.framemap.FrameMapBuilder;
  69 import org.graalvm.compiler.lir.gen.LIRGenerator;
  70 import org.graalvm.compiler.lir.gen.LIRGenerator.Options;


 238     public final void append(LIRInstruction op) {
 239         if (Options.PrintIRWithLIR.getValue(nodeOperands.graph().getOptions()) && !TTY.isSuppressed()) {
 240             if (currentInstruction != null && lastInstructionPrinted != currentInstruction) {
 241                 lastInstructionPrinted = currentInstruction;
 242                 InstructionPrinter ip = new InstructionPrinter(TTY.out());
 243                 ip.printInstructionListing(currentInstruction);
 244             }
 245         }
 246         gen.append(op);
 247     }
 248 
 249     protected LIRKind getExactPhiKind(PhiNode phi) {
 250         LIRKind derivedKind = gen.toRegisterKind(gen.getLIRKind(phi.stamp(NodeView.DEFAULT)));
 251         /* Collect reference information. */
 252         for (int i = 0; i < phi.valueCount() && !derivedKind.isUnknownReference(); i++) {
 253             ValueNode node = phi.valueAt(i);
 254             Value value = getOperand(node);
 255 
 256             // get ValueKind for input
 257             final LIRKind valueKind;
 258             if (value != null) {
 259                 valueKind = value.getValueKind(LIRKind.class);
 260             } else {
 261                 assert isPhiInputFromBackedge(phi, i) : String.format("Input %s to phi node %s is not yet available although it is not coming from a loop back edge", node, phi);
 262                 LIRKind kind = gen.getLIRKind(node.stamp(NodeView.DEFAULT));
 263                 valueKind = gen.toRegisterKind(kind);
 264             }
 265             /* Merge the reference information of the derived kind and the input. */
 266             derivedKind = LIRKind.mergeReferenceInformation(derivedKind, valueKind);
 267         }
 268         return derivedKind;
 269     }
 270 
 271     private static boolean isPhiInputFromBackedge(PhiNode phi, int index) {
 272         AbstractMergeNode merge = phi.merge();
 273         AbstractEndNode end = merge.phiPredecessorAt(index);
 274         return end instanceof LoopEndNode && ((LoopEndNode) end).loopBegin().equals(merge);
 275     }
 276 
 277     private Value[] createPhiIn(AbstractMergeNode merge) {
 278         List<Value> values = new ArrayList<>();


 341                 assert block.getPredecessorCount() == 0;
 342                 emitPrologue(graph);
 343             } else {
 344                 assert block.getPredecessorCount() > 0;
 345                 // create phi-in value array
 346                 AbstractBeginNode begin = block.getBeginNode();
 347                 if (begin instanceof AbstractMergeNode) {
 348                     AbstractMergeNode merge = (AbstractMergeNode) begin;
 349                     LabelOp label = (LabelOp) gen.getResult().getLIR().getLIRforBlock(block).get(0);
 350                     label.setPhiValues(createPhiIn(merge));
 351                     if (Options.PrintIRWithLIR.getValue(options) && !TTY.isSuppressed()) {
 352                         TTY.println("Created PhiIn: " + label);
 353 
 354                     }
 355                 }
 356             }
 357             doBlockPrologue(block, options);
 358 
 359             List<Node> nodes = blockMap.get(block);
 360 
 361             // Allow NodeLIRBuilder subclass to specialize code generation of any interesting groups
 362             // of instructions
 363             matchComplexExpressions(nodes);
 364 
 365             boolean trace = traceLIRGeneratorLevel >= 3;
 366             for (int i = 0; i < nodes.size(); i++) {
 367                 Node node = nodes.get(i);
 368                 if (node instanceof ValueNode) {
 369                     setSourcePosition(node.getNodeSourcePosition());
 370                     DebugContext debug = node.getDebug();
 371                     ValueNode valueNode = (ValueNode) node;
 372                     if (trace) {
 373                         TTY.println("LIRGen for " + valueNode);
 374                     }
 375                     Value operand = getOperand(valueNode);
 376                     if (operand == null) {
 377                         if (!peephole(valueNode)) {
 378                             try {
 379                                 doRoot(valueNode);
 380                             } catch (GraalError e) {
 381                                 throw GraalGraphError.transformAndAddContext(e, valueNode);
 382                             } catch (Throwable e) {
 383                                 throw new GraalGraphError(e).addContext(valueNode);
 384                             }


 402                 }
 403             }
 404 
 405             if (!gen.hasBlockEnd(block)) {
 406                 NodeIterable<Node> successors = block.getEndNode().successors();
 407                 assert successors.count() == block.getSuccessorCount();
 408                 if (block.getSuccessorCount() != 1) {
 409                     /*
 410                      * If we have more than one successor, we cannot just use the first one. Since
 411                      * successors are unordered, this would be a random choice.
 412                      */
 413                     throw new GraalError("Block without BlockEndOp: " + block.getEndNode());
 414                 }
 415                 gen.emitJump(getLIRBlock((FixedNode) successors.first()));
 416             }
 417 
 418             assert verifyBlock(gen.getResult().getLIR(), block);
 419         }
 420     }
 421 

 422     @SuppressWarnings("try")
 423     protected void matchComplexExpressions(List<Node> nodes) {










 424         if (matchRules != null) {
 425             DebugContext debug = gen.getResult().getLIR().getDebug();
 426             try (DebugContext.Scope s = debug.scope("MatchComplexExpressions")) {

 427                 if (LogVerbose.getValue(nodeOperands.graph().getOptions())) {
 428                     int i = 0;
 429                     for (Node node : nodes) {
 430                         debug.log("%d: (%s) %1S", i++, node.getUsageCount(), node);
 431                     }
 432                 }
 433 
 434                 // Match the nodes in backwards order to encourage longer matches.
 435                 for (int index = nodes.size() - 1; index >= 0; index--) {
 436                     Node node = nodes.get(index);
 437                     if (getOperand(node) != null) {
 438                         continue;
 439                     }
 440                     // See if this node is the root of any MatchStatements
 441                     List<MatchStatement> statements = matchRules.get(node.getClass());
 442                     if (statements != null) {
 443                         for (MatchStatement statement : statements) {
 444                             if (statement.generate(this, index, node, nodes)) {
 445                                 // Found a match so skip to the next
 446                                 break;
 447                             }
 448                         }
 449                     }
 450                 }
 451             }
 452         }
 453     }
 454 
 455     protected abstract boolean peephole(ValueNode valueNode);
 456 
 457     private void doRoot(ValueNode instr) {
 458         if (traceLIRGeneratorLevel >= 2) {
 459             TTY.println("Emitting LIR for instruction " + instr);
 460         }
 461         currentInstruction = instr;
 462         DebugContext debug = instr.getDebug();
 463         debug.log("Visiting %s", instr);
 464         emitNode(instr);




  31 import static org.graalvm.compiler.core.common.SpeculativeExecutionAttacksMitigations.Options.MitigateSpeculativeExecutionAttacks;
  32 import static org.graalvm.compiler.core.common.GraalOptions.MatchExpressions;
  33 import static org.graalvm.compiler.debug.DebugOptions.LogVerbose;
  34 import static org.graalvm.compiler.lir.LIR.verifyBlock;
  35 
  36 import java.util.ArrayList;
  37 import java.util.Collection;
  38 import java.util.List;
  39 
  40 import jdk.internal.vm.compiler.collections.EconomicMap;
  41 import jdk.internal.vm.compiler.collections.UnmodifiableMapCursor;
  42 import org.graalvm.compiler.core.common.LIRKind;
  43 import org.graalvm.compiler.core.common.calc.Condition;
  44 import org.graalvm.compiler.core.common.cfg.AbstractBlockBase;
  45 import org.graalvm.compiler.core.common.cfg.BlockMap;
  46 import org.graalvm.compiler.core.common.type.Stamp;
  47 import org.graalvm.compiler.core.match.ComplexMatchValue;
  48 import org.graalvm.compiler.core.match.MatchPattern;
  49 import org.graalvm.compiler.core.match.MatchRuleRegistry;
  50 import org.graalvm.compiler.core.match.MatchStatement;
  51 import org.graalvm.compiler.debug.DebugCloseable;
  52 import org.graalvm.compiler.debug.DebugContext;
  53 import org.graalvm.compiler.debug.GraalError;
  54 import org.graalvm.compiler.debug.TTY;
  55 import org.graalvm.compiler.graph.GraalGraphError;
  56 import org.graalvm.compiler.graph.Node;
  57 import org.graalvm.compiler.graph.NodeMap;
  58 import org.graalvm.compiler.graph.NodeSourcePosition;
  59 import org.graalvm.compiler.graph.iterators.NodeIterable;
  60 import org.graalvm.compiler.lir.FullInfopointOp;
  61 import org.graalvm.compiler.lir.LIRFrameState;
  62 import org.graalvm.compiler.lir.LIRInstruction;
  63 import org.graalvm.compiler.lir.LabelRef;
  64 import org.graalvm.compiler.lir.StandardOp.JumpOp;
  65 import org.graalvm.compiler.lir.StandardOp.LabelOp;
  66 import org.graalvm.compiler.lir.SwitchStrategy;
  67 import org.graalvm.compiler.lir.Variable;
  68 import org.graalvm.compiler.lir.debug.LIRGenerationDebugContext;
  69 import org.graalvm.compiler.lir.framemap.FrameMapBuilder;
  70 import org.graalvm.compiler.lir.gen.LIRGenerator;
  71 import org.graalvm.compiler.lir.gen.LIRGenerator.Options;


 239     public final void append(LIRInstruction op) {
 240         if (Options.PrintIRWithLIR.getValue(nodeOperands.graph().getOptions()) && !TTY.isSuppressed()) {
 241             if (currentInstruction != null && lastInstructionPrinted != currentInstruction) {
 242                 lastInstructionPrinted = currentInstruction;
 243                 InstructionPrinter ip = new InstructionPrinter(TTY.out());
 244                 ip.printInstructionListing(currentInstruction);
 245             }
 246         }
 247         gen.append(op);
 248     }
 249 
 250     protected LIRKind getExactPhiKind(PhiNode phi) {
 251         LIRKind derivedKind = gen.toRegisterKind(gen.getLIRKind(phi.stamp(NodeView.DEFAULT)));
 252         /* Collect reference information. */
 253         for (int i = 0; i < phi.valueCount() && !derivedKind.isUnknownReference(); i++) {
 254             ValueNode node = phi.valueAt(i);
 255             Value value = getOperand(node);
 256 
 257             // get ValueKind for input
 258             final LIRKind valueKind;
 259             if (value != null && !(value instanceof ComplexMatchValue)) {
 260                 valueKind = value.getValueKind(LIRKind.class);
 261             } else {
 262                 assert isPhiInputFromBackedge(phi, i) : String.format("Input %s to phi node %s is not yet available although it is not coming from a loop back edge", node, phi);
 263                 LIRKind kind = gen.getLIRKind(node.stamp(NodeView.DEFAULT));
 264                 valueKind = gen.toRegisterKind(kind);
 265             }
 266             /* Merge the reference information of the derived kind and the input. */
 267             derivedKind = LIRKind.mergeReferenceInformation(derivedKind, valueKind);
 268         }
 269         return derivedKind;
 270     }
 271 
 272     private static boolean isPhiInputFromBackedge(PhiNode phi, int index) {
 273         AbstractMergeNode merge = phi.merge();
 274         AbstractEndNode end = merge.phiPredecessorAt(index);
 275         return end instanceof LoopEndNode && ((LoopEndNode) end).loopBegin().equals(merge);
 276     }
 277 
 278     private Value[] createPhiIn(AbstractMergeNode merge) {
 279         List<Value> values = new ArrayList<>();


 342                 assert block.getPredecessorCount() == 0;
 343                 emitPrologue(graph);
 344             } else {
 345                 assert block.getPredecessorCount() > 0;
 346                 // create phi-in value array
 347                 AbstractBeginNode begin = block.getBeginNode();
 348                 if (begin instanceof AbstractMergeNode) {
 349                     AbstractMergeNode merge = (AbstractMergeNode) begin;
 350                     LabelOp label = (LabelOp) gen.getResult().getLIR().getLIRforBlock(block).get(0);
 351                     label.setPhiValues(createPhiIn(merge));
 352                     if (Options.PrintIRWithLIR.getValue(options) && !TTY.isSuppressed()) {
 353                         TTY.println("Created PhiIn: " + label);
 354 
 355                     }
 356                 }
 357             }
 358             doBlockPrologue(block, options);
 359 
 360             List<Node> nodes = blockMap.get(block);
 361 




 362             boolean trace = traceLIRGeneratorLevel >= 3;
 363             for (int i = 0; i < nodes.size(); i++) {
 364                 Node node = nodes.get(i);
 365                 if (node instanceof ValueNode) {
 366                     setSourcePosition(node.getNodeSourcePosition());
 367                     DebugContext debug = node.getDebug();
 368                     ValueNode valueNode = (ValueNode) node;
 369                     if (trace) {
 370                         TTY.println("LIRGen for " + valueNode);
 371                     }
 372                     Value operand = getOperand(valueNode);
 373                     if (operand == null) {
 374                         if (!peephole(valueNode)) {
 375                             try {
 376                                 doRoot(valueNode);
 377                             } catch (GraalError e) {
 378                                 throw GraalGraphError.transformAndAddContext(e, valueNode);
 379                             } catch (Throwable e) {
 380                                 throw new GraalGraphError(e).addContext(valueNode);
 381                             }


 399                 }
 400             }
 401 
 402             if (!gen.hasBlockEnd(block)) {
 403                 NodeIterable<Node> successors = block.getEndNode().successors();
 404                 assert successors.count() == block.getSuccessorCount();
 405                 if (block.getSuccessorCount() != 1) {
 406                     /*
 407                      * If we have more than one successor, we cannot just use the first one. Since
 408                      * successors are unordered, this would be a random choice.
 409                      */
 410                     throw new GraalError("Block without BlockEndOp: " + block.getEndNode());
 411                 }
 412                 gen.emitJump(getLIRBlock((FixedNode) successors.first()));
 413             }
 414 
 415             assert verifyBlock(gen.getResult().getLIR(), block);
 416         }
 417     }
 418 
 419     @Override
 420     @SuppressWarnings("try")
 421     public void matchBlock(Block block, StructuredGraph graph, StructuredGraph.ScheduleResult schedule) {
 422         try (DebugCloseable matchScope = gen.getMatchScope(block)) {
 423             // Allow NodeLIRBuilder subclass to specialize code generation of any interesting groups
 424             // of instructions
 425             matchComplexExpressions(block, schedule);
 426         }
 427     }
 428 
 429     @SuppressWarnings("try")
 430     protected void matchComplexExpressions(Block block, StructuredGraph.ScheduleResult schedule) {
 431 
 432         if (matchRules != null) {
 433             DebugContext debug = gen.getResult().getLIR().getDebug();
 434             try (DebugContext.Scope s = debug.scope("MatchComplexExpressions")) {
 435                 List<Node> nodes = schedule.getBlockToNodesMap().get(block);
 436                 if (LogVerbose.getValue(nodeOperands.graph().getOptions())) {
 437                     int i = 0;
 438                     for (Node node : nodes) {
 439                         debug.log("%d: (%s) %1S", i++, node.getUsageCount(), node);
 440                     }
 441                 }
 442 
 443                 // Match the nodes in backwards order to encourage longer matches.
 444                 for (int index = nodes.size() - 1; index >= 0; index--) {
 445                     Node node = nodes.get(index);
 446                     if (getOperand(node) != null) {
 447                         continue;
 448                     }
 449                     // See if this node is the root of any MatchStatements
 450                     List<MatchStatement> statements = matchRules.get(node.getClass());
 451                     if (statements != null) {
 452                         for (MatchStatement statement : statements) {
 453                             if (statement.generate(this, index, node, block, schedule)) {
 454                                 // Found a match so skip to the next
 455                                 break;
 456                             }
 457                         }
 458                     }
 459                 }
 460             }
 461         }
 462     }
 463 
 464     protected abstract boolean peephole(ValueNode valueNode);
 465 
 466     private void doRoot(ValueNode instr) {
 467         if (traceLIRGeneratorLevel >= 2) {
 468             TTY.println("Emitting LIR for instruction " + instr);
 469         }
 470         currentInstruction = instr;
 471         DebugContext debug = instr.getDebug();
 472         debug.log("Visiting %s", instr);
 473         emitNode(instr);


< prev index next >