use of org.graalvm.compiler.core.common.type.ObjectStamp in project graal by oracle.
the class InstanceOfNode method tryFold.
@Override
public TriState tryFold(Stamp valueStamp) {
if (valueStamp instanceof ObjectStamp) {
ObjectStamp inputStamp = (ObjectStamp) valueStamp;
ObjectStamp joinedStamp = (ObjectStamp) checkedStamp.join(inputStamp);
if (joinedStamp.isEmpty()) {
// The check can never succeed, the intersection of the two stamps is empty.
return TriState.FALSE;
} else {
ObjectStamp meetStamp = (ObjectStamp) checkedStamp.meet(inputStamp);
if (checkedStamp.equals(meetStamp)) {
// checked stamp.
return TriState.TRUE;
}
}
}
return TriState.UNKNOWN;
}
use of org.graalvm.compiler.core.common.type.ObjectStamp in project graal by oracle.
the class InstanceOfNode method findSynonym.
public static LogicNode findSynonym(ObjectStamp checkedStamp, ValueNode object, NodeView view) {
ObjectStamp inputStamp = (ObjectStamp) object.stamp(view);
ObjectStamp joinedStamp = (ObjectStamp) checkedStamp.join(inputStamp);
if (joinedStamp.isEmpty()) {
// The check can never succeed, the intersection of the two stamps is empty.
return LogicConstantNode.contradiction();
} else {
ObjectStamp meetStamp = (ObjectStamp) checkedStamp.meet(inputStamp);
if (checkedStamp.equals(meetStamp)) {
// checked stamp.
return LogicConstantNode.tautology();
} else if (checkedStamp.alwaysNull()) {
return IsNullNode.create(object);
} else if (Objects.equals(checkedStamp.type(), meetStamp.type()) && checkedStamp.isExactType() == meetStamp.isExactType() && checkedStamp.alwaysNull() == meetStamp.alwaysNull()) {
assert checkedStamp.nonNull() != inputStamp.nonNull();
// The only difference makes the null-ness of the value => simplify the check.
if (checkedStamp.nonNull()) {
return LogicNegationNode.create(IsNullNode.create(object));
} else {
return IsNullNode.create(object);
}
}
assert checkedStamp.type() != null;
}
return null;
}
use of org.graalvm.compiler.core.common.type.ObjectStamp in project graal by oracle.
the class TypeSwitchNode method simplify.
@Override
public void simplify(SimplifierTool tool) {
NodeView view = NodeView.from(tool);
if (value() instanceof ConstantNode) {
Constant constant = value().asConstant();
int survivingEdge = keySuccessorIndex(keyCount());
for (int i = 0; i < keyCount(); i++) {
Constant typeHub = keyAt(i);
Boolean equal = tool.getConstantReflection().constantEquals(constant, typeHub);
if (equal == null) {
/* We don't know if this key is a match or not, so we cannot simplify. */
return;
} else if (equal.booleanValue()) {
survivingEdge = keySuccessorIndex(i);
}
}
killOtherSuccessors(tool, survivingEdge);
}
if (value() instanceof LoadHubNode && ((LoadHubNode) value()).getValue().stamp(view) instanceof ObjectStamp) {
ObjectStamp objectStamp = (ObjectStamp) ((LoadHubNode) value()).getValue().stamp(view);
if (objectStamp.type() != null) {
int validKeys = 0;
for (int i = 0; i < keyCount(); i++) {
if (objectStamp.type().isAssignableFrom(keys[i])) {
validKeys++;
}
}
if (validKeys == 0) {
tool.addToWorkList(defaultSuccessor());
graph().removeSplitPropagate(this, defaultSuccessor());
} else if (validKeys != keys.length) {
ArrayList<AbstractBeginNode> newSuccessors = new ArrayList<>(blockSuccessorCount());
ResolvedJavaType[] newKeys = new ResolvedJavaType[validKeys];
int[] newKeySuccessors = new int[validKeys + 1];
double[] newKeyProbabilities = new double[validKeys + 1];
double totalProbability = 0;
int current = 0;
for (int i = 0; i < keyCount() + 1; i++) {
if (i == keyCount() || objectStamp.type().isAssignableFrom(keys[i])) {
int index = newSuccessors.indexOf(keySuccessor(i));
if (index == -1) {
index = newSuccessors.size();
newSuccessors.add(keySuccessor(i));
}
newKeySuccessors[current] = index;
if (i < keyCount()) {
newKeys[current] = keys[i];
}
newKeyProbabilities[current] = keyProbability(i);
totalProbability += keyProbability(i);
current++;
}
}
if (totalProbability > 0) {
for (int i = 0; i < current; i++) {
newKeyProbabilities[i] /= totalProbability;
}
} else {
for (int i = 0; i < current; i++) {
newKeyProbabilities[i] = 1.0 / current;
}
}
for (int i = 0; i < blockSuccessorCount(); i++) {
AbstractBeginNode successor = blockSuccessor(i);
if (!newSuccessors.contains(successor)) {
tool.deleteBranch(successor);
}
setBlockSuccessor(i, null);
}
AbstractBeginNode[] successorsArray = newSuccessors.toArray(new AbstractBeginNode[newSuccessors.size()]);
TypeSwitchNode newSwitch = graph().add(new TypeSwitchNode(value(), successorsArray, newKeys, newKeyProbabilities, newKeySuccessors, tool.getConstantReflection()));
((FixedWithNextNode) predecessor()).setNext(newSwitch);
GraphUtil.killWithUnusedFloatingInputs(this);
}
}
}
}
use of org.graalvm.compiler.core.common.type.ObjectStamp in project graal by oracle.
the class VerifyUsageWithEquals method isAssignableToRestrictedType.
/**
* Determines whether the type of {@code node} is assignable to the {@link #restrictedClass}.
*/
private boolean isAssignableToRestrictedType(ValueNode node, MetaAccessProvider metaAccess) {
if (node.stamp(NodeView.DEFAULT) instanceof ObjectStamp) {
ResolvedJavaType restrictedType = metaAccess.lookupJavaType(restrictedClass);
ResolvedJavaType nodeType = StampTool.typeOrNull(node);
if (nodeType == null && node instanceof LoadFieldNode) {
nodeType = (ResolvedJavaType) ((LoadFieldNode) node).field().getType();
}
if (nodeType == null && node instanceof Invoke) {
ResolvedJavaMethod target = ((Invoke) node).callTarget().targetMethod();
nodeType = (ResolvedJavaType) target.getSignature().getReturnType(target.getDeclaringClass());
}
if (nodeType == null && node instanceof UncheckedInterfaceProvider) {
nodeType = StampTool.typeOrNull(((UncheckedInterfaceProvider) node).uncheckedStamp());
}
if (nodeType != null && restrictedType.isAssignableFrom(nodeType)) {
return true;
}
}
return false;
}
use of org.graalvm.compiler.core.common.type.ObjectStamp in project graal by oracle.
the class InliningData method getInlineInfo.
/**
* Determines if inlining is possible at the given invoke node.
*
* @param invoke the invoke that should be inlined
* @return an instance of InlineInfo, or null if no inlining is possible at the given invoke
*/
private InlineInfo getInlineInfo(Invoke invoke) {
final String failureMessage = InliningUtil.checkInvokeConditions(invoke);
if (failureMessage != null) {
InliningUtil.logNotInlinedMethod(invoke, failureMessage);
return null;
}
MethodCallTargetNode callTarget = (MethodCallTargetNode) invoke.callTarget();
ResolvedJavaMethod targetMethod = callTarget.targetMethod();
if (callTarget.invokeKind() == CallTargetNode.InvokeKind.Special || targetMethod.canBeStaticallyBound()) {
return getExactInlineInfo(invoke, targetMethod);
}
assert callTarget.invokeKind().isIndirect();
ResolvedJavaType holder = targetMethod.getDeclaringClass();
if (!(callTarget.receiver().stamp(NodeView.DEFAULT) instanceof ObjectStamp)) {
return null;
}
ObjectStamp receiverStamp = (ObjectStamp) callTarget.receiver().stamp(NodeView.DEFAULT);
if (receiverStamp.alwaysNull()) {
// Don't inline if receiver is known to be null
return null;
}
ResolvedJavaType contextType = invoke.getContextType();
if (receiverStamp.type() != null) {
// the invoke target might be more specific than the holder (happens after inlining:
// parameters lose their declared type...)
ResolvedJavaType receiverType = receiverStamp.type();
if (receiverType != null && holder.isAssignableFrom(receiverType)) {
holder = receiverType;
if (receiverStamp.isExactType()) {
assert targetMethod.getDeclaringClass().isAssignableFrom(holder) : holder + " subtype of " + targetMethod.getDeclaringClass() + " for " + targetMethod;
ResolvedJavaMethod resolvedMethod = holder.resolveConcreteMethod(targetMethod, contextType);
if (resolvedMethod != null) {
return getExactInlineInfo(invoke, resolvedMethod);
}
}
}
}
if (holder.isArray()) {
// arrays can be treated as Objects
ResolvedJavaMethod resolvedMethod = holder.resolveConcreteMethod(targetMethod, contextType);
if (resolvedMethod != null) {
return getExactInlineInfo(invoke, resolvedMethod);
}
}
AssumptionResult<ResolvedJavaType> leafConcreteSubtype = holder.findLeafConcreteSubtype();
if (leafConcreteSubtype != null) {
ResolvedJavaMethod resolvedMethod = leafConcreteSubtype.getResult().resolveConcreteMethod(targetMethod, contextType);
if (resolvedMethod != null) {
if (leafConcreteSubtype.canRecordTo(callTarget.graph().getAssumptions())) {
return getAssumptionInlineInfo(invoke, resolvedMethod, leafConcreteSubtype);
} else {
return getTypeCheckedAssumptionInfo(invoke, resolvedMethod, leafConcreteSubtype.getResult());
}
}
}
AssumptionResult<ResolvedJavaMethod> concrete = holder.findUniqueConcreteMethod(targetMethod);
if (concrete != null && concrete.canRecordTo(callTarget.graph().getAssumptions())) {
return getAssumptionInlineInfo(invoke, concrete.getResult(), concrete);
}
// type check based inlining
return getTypeCheckedInlineInfo(invoke, targetMethod);
}
Aggregations