Skip to content

Commit 84c96ca

Browse files
committed
[GR-68269] Support boxing certain phis in Vector API expansion
PullRequest: graal/22283
2 parents 7a75112 + bd9129a commit 84c96ca

File tree

4 files changed

+153
-65
lines changed

4 files changed

+153
-65
lines changed

compiler/OWNERS.toml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,4 @@ any = [
77
"gergo.barany@oracle.com",
88
"yudi.zheng@oracle.com",
99
"raphael.m.mosaner@oracle.com",
10-
"quan.anh.mai@oracle.com",
1110
]

compiler/src/jdk.graal.compiler.processor/src/jdk/graal/compiler/options/processor/OptionProcessor.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -396,6 +396,7 @@ record OptionsDeclarer(Element element,
396396
Set<Element> originatingElements) {
397397

398398
static OptionsDeclarer ERROR = new OptionsDeclarer(null, null, null, false, null, null);
399+
399400
static OptionsDeclarer create(ProcessingEnvironment env, Element optionsDeclarerElement, boolean implementsOptionsContainer) {
400401
Element e = optionsDeclarerElement;
401402

compiler/src/jdk.graal.compiler/src/jdk/graal/compiler/vector/replacements/vectorapi/VectorAPIBoxingUtils.java

Lines changed: 55 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import jdk.graal.compiler.nodes.PiNode;
4444
import jdk.graal.compiler.nodes.StructuredGraph;
4545
import jdk.graal.compiler.nodes.ValueNode;
46+
import jdk.graal.compiler.nodes.ValuePhiNode;
4647
import jdk.graal.compiler.nodes.calc.NarrowNode;
4748
import jdk.graal.compiler.nodes.calc.NotNode;
4849
import jdk.graal.compiler.nodes.calc.SignExtendNode;
@@ -51,22 +52,24 @@
5152
import jdk.graal.compiler.nodes.java.LoadFieldNode;
5253
import jdk.graal.compiler.nodes.java.NewArrayNode;
5354
import jdk.graal.compiler.nodes.java.NewInstanceNode;
54-
import jdk.graal.compiler.nodes.java.StoreFieldNode;
5555
import jdk.graal.compiler.nodes.memory.ReadNode;
5656
import jdk.graal.compiler.nodes.memory.WriteNode;
5757
import jdk.graal.compiler.nodes.memory.address.AddressNode;
5858
import jdk.graal.compiler.nodes.memory.address.IndexAddressNode;
5959
import jdk.graal.compiler.nodes.memory.address.OffsetAddressNode;
6060
import jdk.graal.compiler.nodes.spi.CoreProviders;
6161
import jdk.graal.compiler.nodes.spi.ValueProxy;
62+
import jdk.graal.compiler.replacements.DefaultJavaLoweringProvider;
6263
import jdk.graal.compiler.vector.architecture.VectorArchitecture;
6364
import jdk.graal.compiler.vector.architecture.VectorLoweringProvider;
6465
import jdk.graal.compiler.vector.nodes.simd.LogicValueStamp;
6566
import jdk.graal.compiler.vector.nodes.simd.SimdBlendWithLogicMaskNode;
6667
import jdk.graal.compiler.vector.nodes.simd.SimdConstant;
6768
import jdk.graal.compiler.vector.nodes.simd.SimdStamp;
69+
import jdk.graal.compiler.vector.replacements.vectorapi.nodes.VectorAPIMacroNode;
6870
import jdk.vm.ci.meta.ConstantReflectionProvider;
6971
import jdk.vm.ci.meta.JavaConstant;
72+
import jdk.vm.ci.meta.JavaKind;
7073
import jdk.vm.ci.meta.MetaAccessProvider;
7174
import jdk.vm.ci.meta.ResolvedJavaField;
7275
import jdk.vm.ci.meta.ResolvedJavaType;
@@ -167,6 +170,20 @@ public static int[] tryReadShuffleConstant(JavaConstant constant, CoreProviders
167170
return elements;
168171
}
169172

173+
/**
174+
* Determine if the given object is a non-null instance of a concrete Vector API vector type. If
175+
* yes, return its type; return {@code null} otherwise.
176+
*/
177+
public static VectorAPIType isBoxedVectorAPIObject(ValueNode value, CoreProviders providers) {
178+
if (value.stamp(NodeView.DEFAULT) instanceof ObjectStamp objectStamp && objectStamp.nonNull() && objectStamp.isExactType()) {
179+
ResolvedJavaType maybeVectorType = objectStamp.type();
180+
if (maybeVectorType != null) {
181+
return VectorAPIType.ofType(maybeVectorType, providers);
182+
}
183+
}
184+
return null;
185+
}
186+
170187
/**
171188
* Determine if the given object is a non-null instance of a concrete Vector API vector type
172189
* that we can unbox to a SIMD value. Such objects can occur as inputs to macro nodes via things
@@ -178,36 +195,33 @@ public static int[] tryReadShuffleConstant(JavaConstant constant, CoreProviders
178195
static VectorAPIType asUnboxableVectorType(ValueNode value, CoreProviders providers) {
179196
/*
180197
* Unboxing an object involves placing fixed read nodes. Therefore the value must be fixed,
181-
* or it must be a pi with a fixed guard so we have a valid insertion position.
198+
* or it must be a phi or a pi with a fixed guard so we have a valid insertion position.
182199
*/
183-
if (!(value instanceof FixedWithNextNode || (value instanceof ValueProxy pi && pi.getGuard() != null && pi.getGuard() instanceof FixedWithNextNode))) {
200+
if (!(value instanceof FixedWithNextNode || value instanceof VectorAPIMacroNode ||
201+
value instanceof ValuePhiNode ||
202+
(value instanceof ValueProxy pi && pi.getGuard() != null && pi.getGuard() instanceof FixedWithNextNode))) {
184203
return null;
185204
}
186205
/* Now check if this is a Vector API object we can do a SIMD read from. */
187-
if (value.stamp(NodeView.DEFAULT) instanceof ObjectStamp objectStamp && objectStamp.nonNull() && objectStamp.isExactType()) {
188-
ResolvedJavaType maybeVectorType = objectStamp.type();
189-
if (maybeVectorType != null) {
190-
VectorLoweringProvider vectorLowerer = (VectorLoweringProvider) providers.getLowerer();
191-
VectorAPIType vectorType = VectorAPIType.ofType(maybeVectorType, providers);
192-
if (vectorType != null && vectorType.vectorLength > 1) {
193-
VectorArchitecture vectorArch = vectorLowerer.getVectorArchitecture();
194-
Stamp elementStamp = vectorType.payloadStamp.getComponent(0);
195-
if (vectorType.isMask) {
196-
/*
197-
* The mask is represented as booleans in memory, to unbox it to a logic
198-
* vector we must be able to compare against zero.
199-
*/
200-
if (!canConvertBooleansToLogic(vectorType, vectorArch)) {
201-
return null;
202-
}
203-
if (vectorArch.getSupportedVectorComparisonLength(elementStamp, CanonicalCondition.EQ, vectorType.vectorLength) != vectorType.vectorLength) {
204-
return null;
205-
}
206-
}
207-
if (vectorArch.getSupportedVectorMoveLength(elementStamp, vectorType.vectorLength) == vectorType.vectorLength) {
208-
return vectorType;
209-
}
206+
VectorAPIType vectorType = isBoxedVectorAPIObject(value, providers);
207+
if (vectorType != null && vectorType.vectorLength > 1) {
208+
VectorLoweringProvider vectorLowerer = (VectorLoweringProvider) providers.getLowerer();
209+
VectorArchitecture vectorArch = vectorLowerer.getVectorArchitecture();
210+
Stamp elementStamp = vectorType.payloadStamp.getComponent(0);
211+
if (vectorType.isMask) {
212+
/*
213+
* The mask is represented as booleans in memory, to unbox it to a logic vector we
214+
* must be able to compare against zero.
215+
*/
216+
if (!canConvertBooleansToLogic(vectorType, vectorArch)) {
217+
return null;
210218
}
219+
if (vectorArch.getSupportedVectorComparisonLength(elementStamp, CanonicalCondition.EQ, vectorType.vectorLength) != vectorType.vectorLength) {
220+
return null;
221+
}
222+
}
223+
if (vectorArch.getSupportedVectorMoveLength(elementStamp, vectorType.vectorLength) == vectorType.vectorLength) {
224+
return vectorType;
211225
}
212226
}
213227
return null;
@@ -220,7 +234,7 @@ static VectorAPIType asUnboxableVectorType(ValueNode value, CoreProviders provid
220234
*/
221235
static ValueNode boxVector(ResolvedJavaType boxType, FixedNode successor, ValueNode vector, CoreProviders providers) {
222236
VectorAPIType typeMeta = VectorAPIType.ofType(boxType, providers);
223-
GraalError.guarantee(typeMeta != null, "unexpected vector type %s", boxType);
237+
GraalError.guarantee(typeMeta != null, "unexpected vector type %s, vector %s", boxType, vector);
224238
StructuredGraph graph = vector.graph();
225239

226240
// Allocate the payload array
@@ -248,12 +262,20 @@ static ValueNode boxVector(ResolvedJavaType boxType, FixedNode successor, ValueN
248262
NewInstanceNode box = graph.add(new NewInstanceNode(boxType, true));
249263
graph.addBeforeFixed(successor, box);
250264

251-
// Store the allocated payload array into the corresponding field of the box instance
265+
/*
266+
* Store the allocated payload array into the corresponding field of the box instance. We
267+
* use a lowered write instead of a StoreField because we want to use the init location.
268+
*/
252269
ResolvedJavaField[] boxFields = boxType.getInstanceFields(true);
253270
GraalError.guarantee(boxFields.length == 1, "unexpected field count in %s", boxType);
254271
ResolvedJavaField payloadField = boxFields[0];
255272
GraalError.guarantee(payloadField.getName().equals("payload"), "unexpected field %s %s in %s", payloadField.getDeclaringClass(), payloadField.getName(), boxType);
256-
StoreFieldNode storeToBox = graph.add(new StoreFieldNode(box, payloadField, publishedPayloadArray));
273+
DefaultJavaLoweringProvider javaLowerer = ((VectorLoweringProvider) providers.getLowerer()).getBasicLoweringProvider();
274+
int fieldOffset = javaLowerer.getBasicLoweringProvider().fieldOffset(payloadField);
275+
AddressNode payloadFieldAddress = graph.addOrUnique(new OffsetAddressNode(box, ConstantNode.forLong(fieldOffset, graph)));
276+
ValueNode compressedPayloadArray = javaLowerer.getBasicLoweringProvider().implicitStoreConvert(graph, JavaKind.Object, publishedPayloadArray);
277+
BarrierType barrierType = providers.getLowerer().getBarrierSet().fieldWriteBarrierType(payloadField, JavaKind.Object);
278+
WriteNode storeToBox = graph.add(new WriteNode(payloadFieldAddress, LocationIdentity.INIT_LOCATION, compressedPayloadArray, barrierType, MemoryOrderMode.PLAIN));
257279
graph.addBeforeFixed(successor, storeToBox);
258280

259281
// Publish the allocated box instance
@@ -280,6 +302,10 @@ static ValueNode unboxObject(ValueNode value, CoreProviders providers) {
280302
FixedWithNextNode insertionPoint;
281303
if (value instanceof FixedWithNextNode fixed) {
282304
insertionPoint = fixed;
305+
} else if (value instanceof VectorAPIMacroNode macro) {
306+
insertionPoint = macro.next();
307+
} else if (value instanceof ValuePhiNode phi) {
308+
insertionPoint = phi.merge();
283309
} else {
284310
insertionPoint = (FixedWithNextNode) ((ValueProxy) value).getGuard();
285311
}

0 commit comments

Comments
 (0)