use of org.graalvm.word.LocationIdentity in project graal by oracle.
the class PEReadEliminationClosure method processKilledLoopLocations.
@Override
protected void processKilledLoopLocations(Loop<Block> loop, PEReadEliminationBlockState initialState, PEReadEliminationBlockState mergedStates) {
assert initialState != null;
assert mergedStates != null;
if (initialState.readCache.size() > 0) {
LoopKillCache loopKilledLocations = loopLocationKillCache.get(loop);
// it is visited
if (loopKilledLocations == null) {
loopKilledLocations = new LoopKillCache(1);
loopLocationKillCache.put(loop, loopKilledLocations);
} else {
AbstractBeginNode beginNode = loop.getHeader().getBeginNode();
OptionValues options = beginNode.getOptions();
if (loopKilledLocations.visits() > ReadEliminationMaxLoopVisits.getValue(options)) {
// we have processed the loop too many times, kill all locations so the inner
// loop will never be processed more than once again on visit
loopKilledLocations.setKillsAll();
} else {
// we have fully processed this loop >1 times, update the killed locations
EconomicSet<LocationIdentity> forwardEndLiveLocations = EconomicSet.create(Equivalence.DEFAULT);
for (ReadCacheEntry entry : initialState.readCache.getKeys()) {
forwardEndLiveLocations.add(entry.identity);
}
for (ReadCacheEntry entry : mergedStates.readCache.getKeys()) {
forwardEndLiveLocations.remove(entry.identity);
}
// loop
for (LocationIdentity location : forwardEndLiveLocations) {
loopKilledLocations.rememberLoopKilledLocation(location);
}
if (debug.isLogEnabled() && loopKilledLocations != null) {
debug.log("[Early Read Elimination] Setting loop killed locations of loop at node %s with %s", beginNode, forwardEndLiveLocations);
}
}
// remember the loop visit
loopKilledLocations.visited();
}
}
}
use of org.graalvm.word.LocationIdentity in project graal by oracle.
the class PEReadEliminationClosure method processLoadIndexed.
private boolean processLoadIndexed(LoadIndexedNode load, PEReadEliminationBlockState state, GraphEffectList effects) {
if (load.index().isConstant()) {
int index = ((JavaConstant) load.index().asConstant()).asInt();
// BALOAD (with elementKind being Byte) can be used to retrieve values from boolean
// arrays.
JavaKind elementKind = load.elementKind();
if (elementKind == JavaKind.Byte) {
elementKind = getElementKindFromStamp(load.array());
if (elementKind == JavaKind.Illegal) {
return false;
}
}
LocationIdentity arrayLocation = NamedLocationIdentity.getArrayLocation(elementKind);
return processLoad(load, load.array(), arrayLocation, index, elementKind, state, effects);
}
return false;
}
use of org.graalvm.word.LocationIdentity in project graal by oracle.
the class PEReadEliminationClosure method processNode.
@Override
protected boolean processNode(Node node, PEReadEliminationBlockState state, GraphEffectList effects, FixedWithNextNode lastFixedNode) {
if (super.processNode(node, state, effects, lastFixedNode)) {
return true;
}
if (node instanceof LoadFieldNode) {
return processLoadField((LoadFieldNode) node, state, effects);
} else if (node instanceof StoreFieldNode) {
return processStoreField((StoreFieldNode) node, state, effects);
} else if (node instanceof LoadIndexedNode) {
return processLoadIndexed((LoadIndexedNode) node, state, effects);
} else if (node instanceof StoreIndexedNode) {
return processStoreIndexed((StoreIndexedNode) node, state, effects);
} else if (node instanceof ArrayLengthNode) {
return processArrayLength((ArrayLengthNode) node, state, effects);
} else if (node instanceof UnboxNode) {
return processUnbox((UnboxNode) node, state, effects);
} else if (node instanceof RawLoadNode) {
return processUnsafeLoad((RawLoadNode) node, state, effects);
} else if (node instanceof RawStoreNode) {
return processUnsafeStore((RawStoreNode) node, state, effects);
} else if (node instanceof MemoryCheckpoint.Single) {
COUNTER_MEMORYCHECKPOINT.increment(node.getDebug());
LocationIdentity identity = ((MemoryCheckpoint.Single) node).getLocationIdentity();
processIdentity(state, identity);
} else if (node instanceof MemoryCheckpoint.Multi) {
COUNTER_MEMORYCHECKPOINT.increment(node.getDebug());
for (LocationIdentity identity : ((MemoryCheckpoint.Multi) node).getLocationIdentities()) {
processIdentity(state, identity);
}
}
return false;
}
use of org.graalvm.word.LocationIdentity in project graal by oracle.
the class JNIJavaCallWrapperMethod method loadAndUnboxArguments.
private List<Pair<ValueNode, ResolvedJavaType>> loadAndUnboxArguments(JNIGraphKit kit, HostedProviders providers, ResolvedJavaMethod invokeMethod, Signature invokeSignature) {
MetaAccessProvider metaAccess = providers.getMetaAccess();
List<Pair<ValueNode, ResolvedJavaType>> args = new ArrayList<>();
int javaIndex = 0;
javaIndex += metaAccess.lookupJavaType(JNIEnvironment.class).getJavaKind().getSlotCount();
if (!invokeMethod.isStatic()) {
JavaKind kind = metaAccess.lookupJavaType(JNIObjectHandle.class).getJavaKind();
ValueNode handle = kit.loadLocal(javaIndex, kind);
ValueNode unboxed = kit.unboxHandle(handle);
ValueNode receiver;
ResolvedJavaType receiverClass = invokeMethod.getDeclaringClass();
if (invokeMethod.isConstructor()) {
/*
* Our target method is a constructor and we might be called via `NewObject`, in
* which case we need to allocate the object before calling the constructor. We can
* detect when this is the case because unlike with `Call<Type>Method`, we are
* passed the object hub of our target class in place of the receiver object.
*/
Constant hub = providers.getConstantReflection().asObjectHub(receiverClass);
ConstantNode hubNode = kit.createConstant(hub, JavaKind.Object);
kit.startIf(kit.unique(new ObjectEqualsNode(unboxed, hubNode)), BranchProbabilityNode.FAST_PATH_PROBABILITY);
kit.thenPart();
ValueNode created = kit.append(new NewInstanceNode(receiverClass, true));
AbstractMergeNode merge = kit.endIf();
receiver = kit.unique(new ValuePhiNode(StampFactory.object(), merge, new ValueNode[] { created, unboxed }));
} else {
receiver = unboxed;
}
args.add(Pair.create(receiver, receiverClass));
}
javaIndex += metaAccess.lookupJavaType(JNIObjectHandle.class).getJavaKind().getSlotCount();
if (nonVirtual) {
javaIndex += metaAccess.lookupJavaType(JNIObjectHandle.class).getJavaKind().getSlotCount();
}
javaIndex += metaAccess.lookupJavaType(JNIMethodId.class).getJavaKind().getSlotCount();
int count = invokeSignature.getParameterCount(false);
if (callVariant == CallVariant.VARARGS) {
for (int i = 0; i < count; i++) {
ResolvedJavaType type = (ResolvedJavaType) invokeSignature.getParameterType(i, null);
JavaKind kind = type.getJavaKind();
JavaKind loadKind = kind;
if (loadKind == JavaKind.Float) {
// C varargs promote float to double
loadKind = JavaKind.Double;
}
ValueNode value = kit.loadLocal(javaIndex, loadKind);
if (kind == JavaKind.Float) {
value = kit.unique(new FloatConvertNode(FloatConvert.D2F, value));
} else if (kind.isObject()) {
value = kit.unboxHandle(value);
}
args.add(Pair.create(value, type));
javaIndex += loadKind.getSlotCount();
}
} else if (callVariant == CallVariant.ARRAY) {
ResolvedJavaType elementType = metaAccess.lookupJavaType(JNIValue.class);
int elementSize = SizeOf.get(JNIValue.class);
ValueNode array = kit.loadLocal(javaIndex, elementType.getJavaKind());
for (int i = 0; i < count; i++) {
ResolvedJavaType type = (ResolvedJavaType) invokeSignature.getParameterType(i, null);
JavaKind readKind = type.getJavaKind();
StructFieldInfo fieldInfo = getJNIValueOffsetOf(elementType, readKind);
int offset = i * elementSize + fieldInfo.getOffsetInfo().getProperty();
ConstantNode offsetConstant = kit.createConstant(JavaConstant.forInt(offset), providers.getWordTypes().getWordKind());
OffsetAddressNode address = kit.unique(new OffsetAddressNode(array, offsetConstant));
LocationIdentity locationIdentity = fieldInfo.getLocationIdentity();
if (locationIdentity == null) {
locationIdentity = LocationIdentity.any();
}
Stamp readStamp = getNarrowStamp(providers, readKind);
ValueNode value = kit.append(new CInterfaceReadNode(address, locationIdentity, readStamp, BarrierType.NONE, "args[" + i + "]"));
JavaKind stackKind = readKind.getStackKind();
if (readKind != stackKind) {
assert stackKind.getBitCount() > readKind.getBitCount() : "read kind must be narrower than stack kind";
if (readKind.isUnsigned()) {
// needed or another op may illegally sign-extend
value = kit.unique(new ZeroExtendNode(value, stackKind.getBitCount()));
} else {
value = kit.unique(new SignExtendNode(value, stackKind.getBitCount()));
}
} else if (readKind.isObject()) {
value = kit.unboxHandle(value);
}
args.add(Pair.create(value, type));
}
} else if (callVariant == CallVariant.VA_LIST) {
ValueNode valist = kit.loadLocal(javaIndex, metaAccess.lookupJavaType(WordBase.class).getJavaKind());
for (int i = 0; i < count; i++) {
ResolvedJavaType type = (ResolvedJavaType) invokeSignature.getParameterType(i, null);
JavaKind loadKind = type.getJavaKind();
if (loadKind.isObject()) {
loadKind = providers.getWordTypes().getWordKind();
}
ValueNode value = kit.append(new VaListNextArgNode(loadKind, valist));
if (type.getJavaKind().isObject()) {
value = kit.unboxHandle(value);
}
args.add(Pair.create(value, type));
}
} else {
throw VMError.unsupportedFeature("Call variant: " + callVariant);
}
return args;
}
use of org.graalvm.word.LocationIdentity in project graal by oracle.
the class CInterfaceInvocationPlugin method replaceAccessor.
private boolean replaceAccessor(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode[] args, AccessorInfo accessorInfo, int displacement) {
StructuredGraph graph = b.getGraph();
SizableInfo sizableInfo = (SizableInfo) accessorInfo.getParent();
int elementSize = sizableInfo.getSizeInfo().getProperty();
boolean isUnsigned = sizableInfo.isUnsigned();
assert args.length == accessorInfo.parameterCount(true);
ValueNode base = args[accessorInfo.baseParameterNumber(true)];
switch(accessorInfo.getAccessorKind()) {
case ADDRESS:
{
ValueNode address = makeAddress(graph, args, accessorInfo, base, displacement, elementSize);
b.addPush(pushKind(method), address);
return true;
}
case GETTER:
{
JavaKind resultKind = wordTypes.asKind(b.getInvokeReturnType());
JavaKind readKind = kindFromSize(elementSize, resultKind);
if (readKind == JavaKind.Object) {
assert resultKind == JavaKind.Object;
} else if (readKind.getBitCount() > resultKind.getBitCount() && !readKind.isNumericFloat() && resultKind != JavaKind.Boolean) {
readKind = resultKind;
}
ValueNode address = makeAddress(graph, args, accessorInfo, base, displacement, elementSize);
LocationIdentity locationIdentity = makeLocationIdentity(b, method, args, accessorInfo);
Stamp stamp;
if (readKind == JavaKind.Object) {
stamp = b.getInvokeReturnStamp(null).getTrustedStamp();
} else if (readKind == JavaKind.Float || readKind == JavaKind.Double) {
stamp = StampFactory.forKind(readKind);
} else {
stamp = StampFactory.forInteger(readKind.getBitCount());
}
ValueNode read = readOp(b, address, locationIdentity, stamp, accessorInfo);
ValueNode adapted = adaptPrimitiveType(graph, read, readKind, resultKind == JavaKind.Boolean ? resultKind : resultKind.getStackKind(), isUnsigned);
b.push(pushKind(method), adapted);
return true;
}
case SETTER:
{
ValueNode value = args[accessorInfo.valueParameterNumber(true)];
JavaKind valueKind = value.getStackKind();
JavaKind writeKind = kindFromSize(elementSize, valueKind);
ValueNode address = makeAddress(graph, args, accessorInfo, base, displacement, elementSize);
LocationIdentity locationIdentity = makeLocationIdentity(b, method, args, accessorInfo);
ValueNode adaptedValue = adaptPrimitiveType(graph, value, valueKind, writeKind, isUnsigned);
writeOp(b, address, locationIdentity, adaptedValue, accessorInfo);
return true;
}
default:
throw shouldNotReachHere();
}
}
Aggregations