543 throw GraalError.shouldNotReachHere("Unknown integer exact operation."); 544 } 545 } 546 547 private static IntegerExactArithmeticSplitNode createIntegerExactSplit(ValueNode x, ValueNode y, AbstractBeginNode exceptionEdge, IntegerExactOp op) { 548 switch (op) { 549 case INTEGER_ADD_EXACT: 550 case INTEGER_INCREMENT_EXACT: 551 return new IntegerAddExactSplitNode(x.stamp(NodeView.DEFAULT).unrestricted(), x, y, null, exceptionEdge); 552 case INTEGER_SUBTRACT_EXACT: 553 case INTEGER_DECREMENT_EXACT: 554 return new IntegerSubExactSplitNode(x.stamp(NodeView.DEFAULT).unrestricted(), x, y, null, exceptionEdge); 555 case INTEGER_MULTIPLY_EXACT: 556 return new IntegerMulExactSplitNode(x.stamp(NodeView.DEFAULT).unrestricted(), x, y, null, exceptionEdge); 557 default: 558 throw GraalError.shouldNotReachHere("Unknown integer exact operation."); 559 } 560 } 561 562 private static boolean createIntegerExactOperation(GraphBuilderContext b, JavaKind kind, ValueNode x, ValueNode y, IntegerExactOp op) { 563 if (x.isConstant() && y.isConstant()) { 564 b.addPush(kind, createIntegerExactArithmeticNode(x, y, null, op)); 565 return true; 566 } else { 567 BytecodeExceptionKind exceptionKind = kind == JavaKind.Int ? BytecodeExceptionKind.INTEGER_EXACT_OVERFLOW : BytecodeExceptionKind.LONG_EXACT_OVERFLOW; 568 AbstractBeginNode exceptionEdge = b.genExplicitExceptionEdge(exceptionKind); 569 if (exceptionEdge != null) { 570 IntegerExactArithmeticSplitNode split = b.addPush(kind, createIntegerExactSplit(x, y, exceptionEdge, op)); 571 split.setNext(b.add(new BeginNode())); 572 return true; 573 } 574 return false; 575 } 576 } 577 578 private static void registerMathPlugins(InvocationPlugins plugins, boolean allowDeoptimization) { 579 Registration r = new Registration(plugins, Math.class); 580 if (allowDeoptimization) { 581 for (JavaKind kind : new JavaKind[]{JavaKind.Int, JavaKind.Long}) { 582 Class<?> type = kind.toJavaClass(); 583 584 r.register1("decrementExact", type, new InvocationPlugin() { 585 @Override 586 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x) { 587 ConstantNode y = b.add(ConstantNode.forIntegerKind(kind, 1)); 588 return createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_DECREMENT_EXACT); 589 } 590 }); 591 592 r.register1("incrementExact", type, new InvocationPlugin() { 593 @Override 594 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x) { 595 ConstantNode y = b.add(ConstantNode.forIntegerKind(kind, 1)); 596 return createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_INCREMENT_EXACT); | 543 throw GraalError.shouldNotReachHere("Unknown integer exact operation."); 544 } 545 } 546 547 private static IntegerExactArithmeticSplitNode createIntegerExactSplit(ValueNode x, ValueNode y, AbstractBeginNode exceptionEdge, IntegerExactOp op) { 548 switch (op) { 549 case INTEGER_ADD_EXACT: 550 case INTEGER_INCREMENT_EXACT: 551 return new IntegerAddExactSplitNode(x.stamp(NodeView.DEFAULT).unrestricted(), x, y, null, exceptionEdge); 552 case INTEGER_SUBTRACT_EXACT: 553 case INTEGER_DECREMENT_EXACT: 554 return new IntegerSubExactSplitNode(x.stamp(NodeView.DEFAULT).unrestricted(), x, y, null, exceptionEdge); 555 case INTEGER_MULTIPLY_EXACT: 556 return new IntegerMulExactSplitNode(x.stamp(NodeView.DEFAULT).unrestricted(), x, y, null, exceptionEdge); 557 default: 558 throw GraalError.shouldNotReachHere("Unknown integer exact operation."); 559 } 560 } 561 562 private static boolean createIntegerExactOperation(GraphBuilderContext b, JavaKind kind, ValueNode x, ValueNode y, IntegerExactOp op) { 563 BytecodeExceptionKind exceptionKind = kind == JavaKind.Int ? BytecodeExceptionKind.INTEGER_EXACT_OVERFLOW : BytecodeExceptionKind.LONG_EXACT_OVERFLOW; 564 AbstractBeginNode exceptionEdge = b.genExplicitExceptionEdge(exceptionKind); 565 if (exceptionEdge != null) { 566 IntegerExactArithmeticSplitNode split = b.addPush(kind, createIntegerExactSplit(x, y, exceptionEdge, op)); 567 split.setNext(b.add(new BeginNode())); 568 return true; 569 } 570 return false; 571 } 572 573 private static void registerMathPlugins(InvocationPlugins plugins, boolean allowDeoptimization) { 574 Registration r = new Registration(plugins, Math.class); 575 if (allowDeoptimization) { 576 for (JavaKind kind : new JavaKind[]{JavaKind.Int, JavaKind.Long}) { 577 Class<?> type = kind.toJavaClass(); 578 579 r.register1("decrementExact", type, new InvocationPlugin() { 580 @Override 581 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x) { 582 ConstantNode y = b.add(ConstantNode.forIntegerKind(kind, 1)); 583 return createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_DECREMENT_EXACT); 584 } 585 }); 586 587 r.register1("incrementExact", type, new InvocationPlugin() { 588 @Override 589 public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode x) { 590 ConstantNode y = b.add(ConstantNode.forIntegerKind(kind, 1)); 591 return createIntegerExactOperation(b, kind, x, y, IntegerExactOp.INTEGER_INCREMENT_EXACT); |