RFR: 8342662: C2: Add new phase for backend-specific lowering [v2]

Quan Anh Mai qamai at openjdk.org
Mon Oct 28 04:59:23 UTC 2024


On Mon, 28 Oct 2024 03:55:57 GMT, Jasmine Karthikeyan <jkarthikeyan at openjdk.org> wrote:

>> I mean we might want to run another kind of `Ideal` that will replace the normal `Ideal` on a node after its lowering. For example, consider this:
>> 
>>     vector<int,8> v;
>>     u = v.withLane(0, a).withLane(1, b);
>> 
>> This will be parsed into:
>> 
>>     vector<int,8> v;
>>     v0 = InsertI(v, 4, a);
>>     u = InsertI(v0, 5, b);
>> 
>> And can be lowered to:
>> 
>>     vector<int,8> v;
>>     vector<int,4> v1 = VectorExtract(v, 1);
>>     v2 = InsertI(v1, 0, a);
>>     v0 = VectorInsert(v, 1, v2);
>>     vector<int,4> v3 = VectorExtract(v0, 1);
>>     v4 = InsertI(v3, 1, b);
>>     u = VectorInsert(v0, 1, v4);
>> 
>> Which represents this sequence:
>> 
>>     ymm0;
>>     vextracti128 xmm1, ymm0, 1;
>>     vpinsrd xmm1, xmm1, a, 0;
>>     vinserti128 ymm0, ymm0, xmm1, 1;
>>     vextracti128 xmm1, ymm0, 1;
>>     vpinsrd xmm1, xmm1, b, 1;
>>     vinserti128 ymm0, ymm0, xmm1, 1;
>> 
>> As you can imagine this sequence is pretty inefficient, what we really want is:
>> 
>>     ymm0;
>>     vextracti128 xmm1, ymm0, 1;
>>     vpinsrd xmm1, xmm1, a, 0;
>>     vpinsrd xmm1, xmm1, b, 1;
>>     vinserti128 ymm0, ymm0, xmm1, 1;
>> 
>> Looking back at the graph, we can `Identity` `v3` into `v2` since it is pretty obvious that we just do an insert and extract from the same place. However, to transform `u = VectorInsert(v0, 1, v4)` into `u = VectorInsert(v, 1, v4)`, we would need  an `Ideal`-like transformation to see that we just insert into a location twice and remove the intermediate `VectorInsert`.
>> 
>> As a result, in addition to ease of implementation, I think you may extend `PhaseIterGVN` and override its `PhaseGVN::apply_ideal` to return `nullptr` for now, and take advantages of `PhaseIterGVN::optimize` to do the iterative transformation for you.
>
> Ah, I see what you mean now. I think this makes extending IGVN more appealing because we could continue to do Ideal on lowered nodes, as you mentioned. We could override `PhaseGVN::apply_ideal` to return `nullptr` when processing regular nodes, but run the other `Ideal` type when encountering lowered nodes. Do you think it would be better to add another method to `Node` or should we re-use the existing Ideal call, but lowering specific nodes are guarded with a new node flag?

I think having a new method in `Node` would be more manageable, I can imagine it allows us to reuse pre-lowered nodes for lowering. The example I gave above we reuse `ExtractI` since the semantics is still the same, the only difference is that from here `ExtractI` can only appear with the index parameter being smaller than 4.

-------------

PR Review Comment: https://git.openjdk.org/jdk/pull/21599#discussion_r1818374892


More information about the build-dev mailing list