4343import jdk .graal .compiler .nodes .PiNode ;
4444import jdk .graal .compiler .nodes .StructuredGraph ;
4545import jdk .graal .compiler .nodes .ValueNode ;
46+ import jdk .graal .compiler .nodes .ValuePhiNode ;
4647import jdk .graal .compiler .nodes .calc .NarrowNode ;
4748import jdk .graal .compiler .nodes .calc .NotNode ;
4849import jdk .graal .compiler .nodes .calc .SignExtendNode ;
5152import jdk .graal .compiler .nodes .java .LoadFieldNode ;
5253import jdk .graal .compiler .nodes .java .NewArrayNode ;
5354import jdk .graal .compiler .nodes .java .NewInstanceNode ;
54- import jdk .graal .compiler .nodes .java .StoreFieldNode ;
5555import jdk .graal .compiler .nodes .memory .ReadNode ;
5656import jdk .graal .compiler .nodes .memory .WriteNode ;
5757import jdk .graal .compiler .nodes .memory .address .AddressNode ;
5858import jdk .graal .compiler .nodes .memory .address .IndexAddressNode ;
5959import jdk .graal .compiler .nodes .memory .address .OffsetAddressNode ;
6060import jdk .graal .compiler .nodes .spi .CoreProviders ;
6161import jdk .graal .compiler .nodes .spi .ValueProxy ;
62+ import jdk .graal .compiler .replacements .DefaultJavaLoweringProvider ;
6263import jdk .graal .compiler .vector .architecture .VectorArchitecture ;
6364import jdk .graal .compiler .vector .architecture .VectorLoweringProvider ;
6465import jdk .graal .compiler .vector .nodes .simd .LogicValueStamp ;
6566import jdk .graal .compiler .vector .nodes .simd .SimdBlendWithLogicMaskNode ;
6667import jdk .graal .compiler .vector .nodes .simd .SimdConstant ;
6768import jdk .graal .compiler .vector .nodes .simd .SimdStamp ;
69+ import jdk .graal .compiler .vector .replacements .vectorapi .nodes .VectorAPIMacroNode ;
6870import jdk .vm .ci .meta .ConstantReflectionProvider ;
6971import jdk .vm .ci .meta .JavaConstant ;
72+ import jdk .vm .ci .meta .JavaKind ;
7073import jdk .vm .ci .meta .MetaAccessProvider ;
7174import jdk .vm .ci .meta .ResolvedJavaField ;
7275import 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