use of org.graalvm.compiler.nodes.calc.SignExtendNode in project graal by oracle.
the class CInterfaceInvocationPlugin method adaptPrimitiveType.
static ValueNode adaptPrimitiveType(StructuredGraph graph, ValueNode value, JavaKind fromKind, JavaKind toKind, boolean isUnsigned) {
if (fromKind == toKind) {
return value;
}
assert fromKind.isNumericFloat() == toKind.isNumericFloat();
int fromBits = fromKind.getBitCount();
int toBits = toKind.getBitCount();
if (fromBits == toBits) {
return value;
} else if (fromKind.isNumericFloat()) {
FloatConvert op;
if (fromKind == JavaKind.Float && toKind == JavaKind.Double) {
op = FloatConvert.F2D;
} else if (fromKind == JavaKind.Double && toKind == JavaKind.Float) {
op = FloatConvert.D2F;
} else {
throw shouldNotReachHere();
}
return graph.unique(new FloatConvertNode(op, value));
} else if (toKind == JavaKind.Boolean) {
JavaKind computeKind = fromKind == JavaKind.Long ? JavaKind.Long : JavaKind.Int;
LogicNode comparison = graph.unique(new IntegerEqualsNode(adaptPrimitiveType(graph, value, fromKind, computeKind, true), ConstantNode.forIntegerKind(computeKind, 0, graph)));
return graph.unique(new ConditionalNode(comparison, ConstantNode.forBoolean(false, graph), ConstantNode.forBoolean(true, graph)));
} else if (fromBits > toBits) {
return graph.unique(new NarrowNode(value, toBits));
} else if (isUnsigned) {
return graph.unique(new ZeroExtendNode(value, toBits));
} else {
return graph.unique(new SignExtendNode(value, toBits));
}
}
use of org.graalvm.compiler.nodes.calc.SignExtendNode in project graal by oracle.
the class UnsafeAutomaticSubstitutionProcessor method extractValueStoreField.
/**
* If the value produced by valueNode is stored into a static final field then that field is
* returned. If the field is either not static or not final the method returns null and the
* reason is recorded in the unsuccessfulReasons parameter.
*/
private static ResolvedJavaField extractValueStoreField(ValueNode valueNode, List<String> unsuccessfulReasons) {
ResolvedJavaField offsetField = null;
NodeIterable<Node> valueNodeUsages = valueNode.usages();
NodeIterable<StoreFieldNode> valueNodeStoreFieldUsages = valueNodeUsages.filter(StoreFieldNode.class);
NodeIterable<SignExtendNode> valueNodeSignExtendUsages = valueNodeUsages.filter(SignExtendNode.class);
if (valueNodeStoreFieldUsages.count() == 1) {
offsetField = valueNodeStoreFieldUsages.first().field();
} else if (valueNodeSignExtendUsages.count() == 1) {
SignExtendNode signExtendNode = valueNodeSignExtendUsages.first();
NodeIterable<StoreFieldNode> signExtendFieldStoreUsages = signExtendNode.usages().filter(StoreFieldNode.class);
if (signExtendFieldStoreUsages.count() == 1) {
offsetField = signExtendFieldStoreUsages.first().field();
}
}
if (offsetField != null) {
if (offsetField.isStatic() && offsetField.isFinal()) {
return offsetField;
} else {
if (!offsetField.isStatic()) {
unsuccessfulReasons.add("The offset field " + offsetField.format("%H.%n") + " is not static.");
}
if (!offsetField.isFinal()) {
unsuccessfulReasons.add("The offset field " + offsetField.format("%H.%n") + " is not final.");
}
}
} else {
String producer;
String operation;
if (valueNode instanceof Invoke) {
Invoke invokeNode = (Invoke) valueNode;
producer = "call to " + invokeNode.callTarget().targetMethod().format("%H.%n(%p)");
operation = "call";
} else if (valueNode instanceof SubNode) {
producer = "subtraction operation " + valueNode;
operation = "subtraction";
} else {
throw VMError.shouldNotReachHere();
}
String message = "Could not determine the field where the value produced by the " + producer + " is stored. The " + operation + " is not directly followed by a field store or by a sign extend node followed directly by a field store. ";
unsuccessfulReasons.add(message);
}
return null;
}
use of org.graalvm.compiler.nodes.calc.SignExtendNode in project graal by oracle.
the class LoopEx method findInductionVariables.
/**
* Collect all the basic induction variables for the loop and the find any induction variables
* which are derived from the basic ones.
*
* @param loop
* @return a map from node to induction variable
*/
private static EconomicMap<Node, InductionVariable> findInductionVariables(LoopEx loop) {
EconomicMap<Node, InductionVariable> ivs = EconomicMap.create(Equivalence.IDENTITY);
Queue<InductionVariable> scanQueue = new LinkedList<>();
LoopBeginNode loopBegin = loop.loopBegin();
AbstractEndNode forwardEnd = loopBegin.forwardEnd();
for (PhiNode phi : loopBegin.valuePhis()) {
ValueNode backValue = phi.singleBackValueOrThis();
if (backValue == phi) {
continue;
}
ValueNode stride = addSub(loop, backValue, phi);
if (stride != null) {
BasicInductionVariable biv = new BasicInductionVariable(loop, (ValuePhiNode) phi, phi.valueAt(forwardEnd), stride, (BinaryArithmeticNode<?>) backValue);
ivs.put(phi, biv);
scanQueue.add(biv);
}
}
while (!scanQueue.isEmpty()) {
InductionVariable baseIv = scanQueue.remove();
ValueNode baseIvNode = baseIv.valueNode();
for (ValueNode op : baseIvNode.usages().filter(ValueNode.class)) {
if (loop.isOutsideLoop(op)) {
continue;
}
if (op.usages().count() == 1 && op.usages().first() == baseIvNode) {
/*
* This is just the base induction variable increment with no other uses so
* don't bother reporting it.
*/
continue;
}
InductionVariable iv = null;
ValueNode offset = addSub(loop, op, baseIvNode);
ValueNode scale;
if (offset != null) {
iv = new DerivedOffsetInductionVariable(loop, baseIv, offset, (BinaryArithmeticNode<?>) op);
} else if (op instanceof NegateNode) {
iv = new DerivedScaledInductionVariable(loop, baseIv, (NegateNode) op);
} else if ((scale = mul(loop, op, baseIvNode)) != null) {
iv = new DerivedScaledInductionVariable(loop, baseIv, scale, op);
} else {
boolean isValidConvert = op instanceof PiNode || op instanceof SignExtendNode;
if (!isValidConvert && op instanceof ZeroExtendNode) {
ZeroExtendNode zeroExtendNode = (ZeroExtendNode) op;
isValidConvert = zeroExtendNode.isInputAlwaysPositive() || ((IntegerStamp) zeroExtendNode.stamp(NodeView.DEFAULT)).isPositive();
}
if (isValidConvert) {
iv = new DerivedConvertedInductionVariable(loop, baseIv, op.stamp(NodeView.DEFAULT), op);
}
}
if (iv != null) {
ivs.put(op, iv);
scanQueue.offer(iv);
}
}
}
return ivs;
}
use of org.graalvm.compiler.nodes.calc.SignExtendNode in project graal by oracle.
the class StandardGraphBuilderPlugins method registerShortPlugins.
private static void registerShortPlugins(InvocationPlugins plugins) {
Registration r = new Registration(plugins, Short.class);
r.register1("reverseBytes", short.class, new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode value) {
// return (short) (Integer.reverse(i) >> 16);
ReverseBytesNode reverse = b.add(new ReverseBytesNode(value));
RightShiftNode rightShift = b.add(new RightShiftNode(reverse, b.add(ConstantNode.forInt(16))));
SignExtendNode charCast = b.add(new SignExtendNode(b.add(new NarrowNode(rightShift, 16)), 32));
b.push(JavaKind.Short, b.append(charCast.canonical(null)));
return true;
}
});
}
use of org.graalvm.compiler.nodes.calc.SignExtendNode in project graal by oracle.
the class CEntryPointCallStubMethod method generateExceptionHandler.
private void generateExceptionHandler(HostedProviders providers, SubstrateGraphKit kit, ExceptionObjectNode exception, JavaKind returnKind) {
if (entryPointData.getExceptionHandler() == CEntryPointOptions.FatalExceptionHandler.class) {
kit.append(new CEntryPointLeaveNode(LeaveAction.ExceptionAbort, exception));
kit.append(new DeadEndNode());
} else {
ResolvedJavaType throwable = providers.getMetaAccess().lookupJavaType(Throwable.class);
ResolvedJavaType handler = providers.getMetaAccess().lookupJavaType(entryPointData.getExceptionHandler());
ResolvedJavaMethod[] handlerMethods = handler.getDeclaredMethods();
UserError.guarantee(handlerMethods.length == 1 && handlerMethods[0].isStatic(), "Exception handler class must declare exactly one static method: " + targetMethod.format("%H.%n(%p)") + " -> " + handler.toJavaName());
JavaType[] handlerParameterTypes = handlerMethods[0].toParameterTypes();
UserError.guarantee(handlerParameterTypes.length == 1 && ((ResolvedJavaType) handlerParameterTypes[0]).isAssignableFrom(throwable), "Exception handler method must have exactly one parameter of type Throwable: " + targetMethod.format("%H.%n(%p)") + " -> " + handlerMethods[0].format("%H.%n(%p)"));
int handlerExceptionBci = kit.bci();
InvokeWithExceptionNode handlerInvoke = kit.startInvokeWithException(handlerMethods[0], InvokeKind.Static, kit.getFrameState(), kit.bci(), handlerExceptionBci, exception);
kit.noExceptionPart();
ValueNode returnValue = handlerInvoke;
if (handlerInvoke.getStackKind() != returnKind) {
JavaKind fromKind = handlerInvoke.getStackKind();
if (fromKind == JavaKind.Float && returnKind == JavaKind.Double) {
returnValue = kit.unique(new FloatConvertNode(FloatConvert.F2D, returnValue));
} else if (fromKind.isUnsigned() && returnKind.isNumericInteger() && returnKind.getBitCount() > fromKind.getBitCount()) {
returnValue = kit.unique(new ZeroExtendNode(returnValue, returnKind.getBitCount()));
} else if (fromKind.isNumericInteger() && returnKind.isNumericInteger() && returnKind.getBitCount() > fromKind.getBitCount()) {
returnValue = kit.unique(new SignExtendNode(returnValue, returnKind.getBitCount()));
} else {
throw UserError.abort("Exception handler method return type must be assignable to entry point method return type: " + targetMethod.format("%H.%n(%p)") + " -> " + handlerMethods[0].format("%H.%n(%p)"));
}
}
kit.createReturn(returnValue, returnValue.getStackKind());
// fail-safe for exceptions in exception handler
kit.exceptionPart();
kit.append(new CEntryPointLeaveNode(LeaveAction.ExceptionAbort, kit.exceptionObject()));
kit.append(new DeadEndNode());
kit.endInvokeWithException();
}
}
Aggregations