use of org.graalvm.compiler.nodes.java.StoreFieldNode in project graal by oracle.
the class ObjectCloneNode method getLoweredSnippetGraph.
@Override
@SuppressWarnings("try")
protected StructuredGraph getLoweredSnippetGraph(LoweringTool tool) {
ResolvedJavaType type = StampTool.typeOrNull(getObject());
if (type != null) {
if (type.isArray()) {
Method method = ObjectCloneSnippets.arrayCloneMethods.get(type.getComponentType().getJavaKind());
if (method != null) {
final ResolvedJavaMethod snippetMethod = tool.getMetaAccess().lookupJavaMethod(method);
final Replacements replacements = tool.getReplacements();
StructuredGraph snippetGraph = null;
DebugContext debug = getDebug();
try (DebugContext.Scope s = debug.scope("ArrayCloneSnippet", snippetMethod)) {
snippetGraph = replacements.getSnippet(snippetMethod, null, graph().trackNodeSourcePosition(), this.getNodeSourcePosition());
} catch (Throwable e) {
throw debug.handle(e);
}
assert snippetGraph != null : "ObjectCloneSnippets should be installed";
assert getConcreteType(stamp(NodeView.DEFAULT)) != null;
return lowerReplacement((StructuredGraph) snippetGraph.copy(getDebug()), tool);
}
assert false : "unhandled array type " + type.getComponentType().getJavaKind();
} else {
Assumptions assumptions = graph().getAssumptions();
type = getConcreteType(getObject().stamp(NodeView.DEFAULT));
if (type != null) {
StructuredGraph newGraph = new StructuredGraph.Builder(graph().getOptions(), graph().getDebug(), AllowAssumptions.ifNonNull(assumptions)).build();
ParameterNode param = newGraph.addWithoutUnique(new ParameterNode(0, StampPair.createSingle(getObject().stamp(NodeView.DEFAULT))));
NewInstanceNode newInstance = newGraph.add(new NewInstanceNode(type, true));
newGraph.addAfterFixed(newGraph.start(), newInstance);
ReturnNode returnNode = newGraph.add(new ReturnNode(newInstance));
newGraph.addAfterFixed(newInstance, returnNode);
for (ResolvedJavaField field : type.getInstanceFields(true)) {
LoadFieldNode load = newGraph.add(LoadFieldNode.create(newGraph.getAssumptions(), param, field));
newGraph.addBeforeFixed(returnNode, load);
newGraph.addBeforeFixed(returnNode, newGraph.add(new StoreFieldNode(newInstance, field, load)));
}
assert getConcreteType(stamp(NodeView.DEFAULT)) != null;
return lowerReplacement(newGraph, tool);
}
}
}
assert getConcreteType(stamp(NodeView.DEFAULT)) == null;
return null;
}
use of org.graalvm.compiler.nodes.java.StoreFieldNode in project graal by oracle.
the class MethodTypeFlowBuilder method registerUsedElements.
public static void registerUsedElements(BigBang bb, StructuredGraph graph, MethodTypeFlow methodFlow) {
for (Node n : graph.getNodes()) {
if (n instanceof InstanceOfNode) {
InstanceOfNode node = (InstanceOfNode) n;
AnalysisType type = (AnalysisType) node.type().getType();
type.registerAsInTypeCheck();
} else if (n instanceof NewInstanceNode) {
NewInstanceNode node = (NewInstanceNode) n;
AnalysisType type = (AnalysisType) node.instanceClass();
type.registerAsAllocated(node);
} else if (n instanceof NewArrayNode) {
NewArrayNode node = (NewArrayNode) n;
AnalysisType type = ((AnalysisType) node.elementType()).getArrayClass();
type.registerAsAllocated(node);
} else if (n instanceof NewMultiArrayNode) {
NewMultiArrayNode node = (NewMultiArrayNode) n;
AnalysisType type = ((AnalysisType) node.type());
for (int i = 0; i < node.dimensionCount(); i++) {
type.registerAsAllocated(node);
type = type.getComponentType();
}
} else if (n instanceof BoxNode) {
BoxNode node = (BoxNode) n;
AnalysisType type = (AnalysisType) StampTool.typeOrNull(node);
type.registerAsAllocated(node);
} else if (n instanceof LoadFieldNode) {
LoadFieldNode node = (LoadFieldNode) n;
AnalysisField field = (AnalysisField) node.field();
field.registerAsRead(methodFlow);
} else if (n instanceof StoreFieldNode) {
StoreFieldNode node = (StoreFieldNode) n;
AnalysisField field = (AnalysisField) node.field();
field.registerAsWritten(methodFlow);
} else if (n instanceof StoreIndexedNode) {
StoreIndexedNode node = (StoreIndexedNode) n;
AnalysisType arrayType = (AnalysisType) StampTool.typeOrNull(node.array());
if (arrayType != null) {
assert arrayType.isArray();
arrayType.getComponentType().registerAsInTypeCheck();
}
} else if (n instanceof BytecodeExceptionNode) {
BytecodeExceptionNode node = (BytecodeExceptionNode) n;
AnalysisType type = bb.getMetaAccess().lookupJavaType(node.getExceptionClass());
type.registerAsInHeap();
} else if (n instanceof ConstantNode) {
ConstantNode cn = (ConstantNode) n;
if (cn.hasUsages() && cn.asJavaConstant().getJavaKind() == JavaKind.Object && cn.asJavaConstant().isNonNull()) {
assert StampTool.isExactType(cn);
AnalysisType type = (AnalysisType) StampTool.typeOrNull(cn);
type.registerAsInHeap();
}
} else if (n instanceof ForeignCallNode) {
ForeignCallNode node = (ForeignCallNode) n;
registerForeignCall(bb, node.getDescriptor());
} else if (n instanceof UnaryMathIntrinsicNode) {
UnaryMathIntrinsicNode node = (UnaryMathIntrinsicNode) n;
registerForeignCall(bb, node.getOperation().foreignCallDescriptor);
} else if (n instanceof BinaryMathIntrinsicNode) {
BinaryMathIntrinsicNode node = (BinaryMathIntrinsicNode) n;
registerForeignCall(bb, node.getOperation().foreignCallDescriptor);
}
}
}
use of org.graalvm.compiler.nodes.java.StoreFieldNode in project graal by oracle.
the class PEGraphDecoder method canonicalizeFixedNode.
@SuppressWarnings("try")
@Override
protected Node canonicalizeFixedNode(MethodScope s, Node node) {
PEMethodScope methodScope = (PEMethodScope) s;
Node replacedNode = node;
if (nodePlugins != null && nodePlugins.length > 0) {
if (node instanceof LoadFieldNode) {
LoadFieldNode loadFieldNode = (LoadFieldNode) node;
PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(methodScope, loadFieldNode);
ResolvedJavaField field = loadFieldNode.field();
if (loadFieldNode.isStatic()) {
for (NodePlugin nodePlugin : nodePlugins) {
if (nodePlugin.handleLoadStaticField(graphBuilderContext, field)) {
replacedNode = graphBuilderContext.pushedNode;
break;
}
}
} else {
ValueNode object = loadFieldNode.object();
for (NodePlugin nodePlugin : nodePlugins) {
if (nodePlugin.handleLoadField(graphBuilderContext, object, field)) {
replacedNode = graphBuilderContext.pushedNode;
break;
}
}
}
} else if (node instanceof StoreFieldNode) {
StoreFieldNode storeFieldNode = (StoreFieldNode) node;
PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(methodScope, storeFieldNode);
ResolvedJavaField field = storeFieldNode.field();
if (storeFieldNode.isStatic()) {
ValueNode value = storeFieldNode.value();
for (NodePlugin nodePlugin : nodePlugins) {
if (nodePlugin.handleStoreStaticField(graphBuilderContext, field, value)) {
replacedNode = graphBuilderContext.pushedNode;
break;
}
}
} else {
ValueNode object = storeFieldNode.object();
ValueNode value = storeFieldNode.value();
for (NodePlugin nodePlugin : nodePlugins) {
if (nodePlugin.handleStoreField(graphBuilderContext, object, field, value)) {
replacedNode = graphBuilderContext.pushedNode;
break;
}
}
}
} else if (node instanceof LoadIndexedNode) {
LoadIndexedNode loadIndexedNode = (LoadIndexedNode) node;
PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(methodScope, loadIndexedNode);
ValueNode array = loadIndexedNode.array();
ValueNode index = loadIndexedNode.index();
for (NodePlugin nodePlugin : nodePlugins) {
if (nodePlugin.handleLoadIndexed(graphBuilderContext, array, index, loadIndexedNode.elementKind())) {
replacedNode = graphBuilderContext.pushedNode;
break;
}
}
} else if (node instanceof StoreIndexedNode) {
StoreIndexedNode storeIndexedNode = (StoreIndexedNode) node;
PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(methodScope, storeIndexedNode);
ValueNode array = storeIndexedNode.array();
ValueNode index = storeIndexedNode.index();
ValueNode value = storeIndexedNode.value();
for (NodePlugin nodePlugin : nodePlugins) {
if (nodePlugin.handleStoreIndexed(graphBuilderContext, array, index, storeIndexedNode.elementKind(), value)) {
replacedNode = graphBuilderContext.pushedNode;
break;
}
}
} else if (node instanceof NewInstanceNode) {
NewInstanceNode newInstanceNode = (NewInstanceNode) node;
PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(methodScope, newInstanceNode);
ResolvedJavaType type = newInstanceNode.instanceClass();
for (NodePlugin nodePlugin : nodePlugins) {
if (nodePlugin.handleNewInstance(graphBuilderContext, type)) {
replacedNode = graphBuilderContext.pushedNode;
break;
}
}
} else if (node instanceof NewArrayNode) {
NewArrayNode newArrayNode = (NewArrayNode) node;
PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(methodScope, newArrayNode);
ResolvedJavaType elementType = newArrayNode.elementType();
ValueNode length = newArrayNode.length();
for (NodePlugin nodePlugin : nodePlugins) {
if (nodePlugin.handleNewArray(graphBuilderContext, elementType, length)) {
replacedNode = graphBuilderContext.pushedNode;
break;
}
}
} else if (node instanceof NewMultiArrayNode) {
NewMultiArrayNode newArrayNode = (NewMultiArrayNode) node;
PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(methodScope, newArrayNode);
ResolvedJavaType elementType = newArrayNode.type();
ValueNode[] dimensions = newArrayNode.dimensions().toArray(new ValueNode[0]);
for (NodePlugin nodePlugin : nodePlugins) {
if (nodePlugin.handleNewMultiArray(graphBuilderContext, elementType, dimensions)) {
replacedNode = graphBuilderContext.pushedNode;
break;
}
}
}
}
return super.canonicalizeFixedNode(methodScope, replacedNode);
}
use of org.graalvm.compiler.nodes.java.StoreFieldNode in project graal by oracle.
the class VerifyUpdateUsages method verify.
@Override
protected boolean verify(StructuredGraph graph, PhaseContext context) {
if (graph.method().isConstructor()) {
return true;
}
/*
* There are only two acceptable patterns for methods which update Node inputs, either a
* single StoreField node and invoke of updateUsages or updateUsagesInterface, or 2
* StoreFields that come from LoadFields on the same object. Other patterns can be added as
* needed but it would be best to keep things simple so that verification can be simple.
*/
List<StoreFieldNode> stores = graph.getNodes().filter(StoreFieldNode.class).snapshot();
ResolvedJavaType declaringClass = graph.method().getDeclaringClass();
ResolvedJavaType nodeInputList = context.getMetaAccess().lookupJavaType(NodeInputList.class);
StoreFieldNode storeField1 = null;
StoreFieldNode storeField2 = null;
for (StoreFieldNode store : stores) {
if (isNodeInput(store.field(), declaringClass, nodeInputList)) {
if (storeField1 == null) {
storeField1 = store;
} else if (storeField2 == null) {
storeField2 = store;
} else {
return false;
}
}
}
if (storeField1 == null) {
return true;
}
if (storeField2 == null) {
// Single input field update so just check for updateUsages or updateUsagesInterface
// call
ResolvedJavaType node = context.getMetaAccess().lookupJavaType(Node.class);
for (MethodCallTargetNode call : graph.getNodes().filter(MethodCallTargetNode.class)) {
ResolvedJavaMethod callee = call.targetMethod();
if (callee.getDeclaringClass().equals(node) && (callee.getName().equals("updateUsages") || callee.getName().equals("updateUsagesInterface"))) {
return true;
}
}
} else {
if (storeField1.value() instanceof LoadFieldNode && storeField2.value() instanceof LoadFieldNode) {
LoadFieldNode load1 = (LoadFieldNode) storeField1.value();
LoadFieldNode load2 = (LoadFieldNode) storeField2.value();
// Check for swapping values within the same object
if (load1.object() == storeField1.object() && load2.object() == storeField2.object() && storeField1.object() == storeField2.object() && load1.field().equals(storeField2.field()) && load2.field().equals(storeField1.field())) {
return true;
}
}
}
return false;
}
use of org.graalvm.compiler.nodes.java.StoreFieldNode in project graal by oracle.
the class ReadEliminationClosure method processNode.
@Override
protected boolean processNode(Node node, ReadEliminationBlockState state, GraphEffectList effects, FixedWithNextNode lastFixedNode) {
boolean deleted = false;
if (node instanceof AccessFieldNode) {
AccessFieldNode access = (AccessFieldNode) node;
if (access.isVolatile()) {
processIdentity(state, any());
} else {
ValueNode object = GraphUtil.unproxify(access.object());
LoadCacheEntry identifier = new LoadCacheEntry(object, new FieldLocationIdentity(access.field()));
ValueNode cachedValue = state.getCacheEntry(identifier);
if (node instanceof LoadFieldNode) {
if (cachedValue != null && access.stamp(NodeView.DEFAULT).isCompatible(cachedValue.stamp(NodeView.DEFAULT))) {
effects.replaceAtUsages(access, cachedValue, access);
addScalarAlias(access, cachedValue);
deleted = true;
} else {
state.addCacheEntry(identifier, access);
}
} else {
assert node instanceof StoreFieldNode;
StoreFieldNode store = (StoreFieldNode) node;
ValueNode value = getScalarAlias(store.value());
if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) {
effects.deleteNode(store);
deleted = true;
}
state.killReadCache(identifier.identity);
state.addCacheEntry(identifier, value);
}
}
} else if (node instanceof ReadNode) {
ReadNode read = (ReadNode) node;
if (read.getLocationIdentity().isSingle()) {
ValueNode object = GraphUtil.unproxify(read.getAddress());
LoadCacheEntry identifier = new LoadCacheEntry(object, read.getLocationIdentity());
ValueNode cachedValue = state.getCacheEntry(identifier);
if (cachedValue != null && areValuesReplaceable(read, cachedValue, considerGuards)) {
effects.replaceAtUsages(read, cachedValue, read);
addScalarAlias(read, cachedValue);
deleted = true;
} else {
state.addCacheEntry(identifier, read);
}
}
} else if (node instanceof WriteNode) {
WriteNode write = (WriteNode) node;
if (write.getLocationIdentity().isSingle()) {
ValueNode object = GraphUtil.unproxify(write.getAddress());
LoadCacheEntry identifier = new LoadCacheEntry(object, write.getLocationIdentity());
ValueNode cachedValue = state.getCacheEntry(identifier);
ValueNode value = getScalarAlias(write.value());
if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) {
effects.deleteNode(write);
deleted = true;
}
processIdentity(state, write.getLocationIdentity());
state.addCacheEntry(identifier, value);
} else {
processIdentity(state, write.getLocationIdentity());
}
} else if (node instanceof UnsafeAccessNode) {
ResolvedJavaType type = StampTool.typeOrNull(((UnsafeAccessNode) node).object());
if (type != null && !type.isArray()) {
if (node instanceof RawLoadNode) {
RawLoadNode load = (RawLoadNode) node;
if (load.getLocationIdentity().isSingle()) {
ValueNode object = GraphUtil.unproxify(load.object());
UnsafeLoadCacheEntry identifier = new UnsafeLoadCacheEntry(object, load.offset(), load.getLocationIdentity());
ValueNode cachedValue = state.getCacheEntry(identifier);
if (cachedValue != null && areValuesReplaceable(load, cachedValue, considerGuards)) {
effects.replaceAtUsages(load, cachedValue, load);
addScalarAlias(load, cachedValue);
deleted = true;
} else {
state.addCacheEntry(identifier, load);
}
}
} else {
assert node instanceof RawStoreNode;
RawStoreNode write = (RawStoreNode) node;
if (write.getLocationIdentity().isSingle()) {
ValueNode object = GraphUtil.unproxify(write.object());
UnsafeLoadCacheEntry identifier = new UnsafeLoadCacheEntry(object, write.offset(), write.getLocationIdentity());
ValueNode cachedValue = state.getCacheEntry(identifier);
ValueNode value = getScalarAlias(write.value());
if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) {
effects.deleteNode(write);
deleted = true;
}
processIdentity(state, write.getLocationIdentity());
state.addCacheEntry(identifier, value);
} else {
processIdentity(state, write.getLocationIdentity());
}
}
}
} else if (node instanceof MemoryCheckpoint.Single) {
LocationIdentity identity = ((MemoryCheckpoint.Single) node).getLocationIdentity();
processIdentity(state, identity);
} else if (node instanceof MemoryCheckpoint.Multi) {
for (LocationIdentity identity : ((MemoryCheckpoint.Multi) node).getLocationIdentities()) {
processIdentity(state, identity);
}
}
return deleted;
}
Aggregations