[14] RFR (L): 8234391: C2: Generic vector operands
Tobias Hartmann
tobias.hartmann at oracle.com
Thu Nov 28 14:08:32 UTC 2019
Hi Vladimir,
thanks for the additional details. Looks all good to me.
Best regards,
Tobias
On 26.11.19 17:52, Vladimir Ivanov wrote:
> Thanks, Tobias.
>
>> hard to review the .ad file changes but this looks good to me.
>
> Yes, the changes are massive, but mostly straightforward. In addition to the code needed for generic
> vector operand, the changes are:
>
> (1) (x86.ad) switching vec[SDXYZ] => vec and legVec[SDXYZ] => legVec;
>
> (2) (x86.ad) after the switch reduction instructions need additional checks on input vector size
> (example [1]);
>
> (3) (x86_64.ad/x86_32.ad) rename operands with "vec" name to avoid name conflicts with vec operand;
>
> (4) (x86_64.ad) migrate compressed string instructions from legVecS to legRegD to keep it working
> when vector support is explicitly disabled (e.g., -XX:MaxVectorSize=0)
>
> (1) is needed to avoid explicit moves between concrete (legVec/vec[SDXYZ]) and generic vectors
> (vec/legVec).
>
> (2)-(4) could have been reviewed/integrated separately, but they did look trivial enough to avoid
> the effort.
>
>> Just noticed some code style issues:
>> - x86_64.ad:11284, 11346, 11410, 11426: indentation is wrong (already before your fix)
>> - whitespace in matcher.cpp:2598/2601 can be removed
>
> Good catch.
>
> Best regards,
> Vladimir Ivanov
>
> [1]
> -instruct rvadd2F_reduction_reg(regF dst, vecD src2, vecD tmp) %{
> - predicate(UseAVX > 0);
> +instruct rvadd2F_reduction_reg(regF dst, vec src2, vec tmp) %{
> + predicate(UseAVX > 0 && n->in(2)->bottom_type()->is_vect()->length() == 2);
>
>> On 19.11.19 15:30, Vladimir Ivanov wrote:
>>> http://cr.openjdk.java.net/~vlivanov/jbhateja/8234391/webrev.00/
>>> https://bugs.openjdk.java.net/browse/JDK-8234391
>>>
>>> Introduce generic vector operands and migrate existing usages from fixed sized operands (vec[SDXYZ])
>>> to generic ones.
>>>
>>> (It's an updated version of generic vector support posted for review in August, 2019 [1] [2]. AD
>>> instruction merges will be handled separately.)
>>>
>>> On a high-level it is organized as follows:
>>>
>>> (1) all AD instructions in x86.ad/x86_64.ad/x86_32.ad use vec/legVec;
>>>
>>> (2) at runtime, right after matching is over, a special pass is performed which does:
>>>
>>> * replaces vecOper with vec[SDXYZ] depending on mach node type
>>> - vector mach nodes capute bottom_type() of their ideal prototype;
>>>
>>> * eliminates redundant reg-to-reg vector moves (MoveVec2Leg /MoveLeg2Vec)
>>> - matcher needs them, but they are useless for register allocator (moreover, may cause
>>> additional spills);
>>>
>>>
>>> (3) after post-selection pass is over, all mach nodes should have fixed-size vector operands.
>>>
>>>
>>> Some details:
>>>
>>> (1) vec and legVec are marked as "dynamic" operands, so post-selection rewriting works
>>>
>>>
>>> (2) new logic is guarded by new matcher flag (Matcher::supports_generic_vector_operands)
>>> which is
>>> enabled only on x86
>>>
>>>
>>> (3) post-selection analysis is implemented as a single pass over the graph and processing
>>> individual nodes using their own (for DEF operands) or their inputs (USE operands) bottom_type()
>>> (which is an instance of TypeVect)
>>>
>>>
>>> (4) most of the analysis is cross-platform and interface with platform-specific code through 3
>>> methods:
>>>
>>> static bool is_generic_reg2reg_move(MachNode* m);
>>> // distinguishes MoveVec2Leg/MoveLeg2Vec nodes
>>>
>>> static bool is_generic_vector(MachOper* opnd);
>>> // distinguishes vec/legVec operands
>>>
>>> static MachOper* clone_generic_vector_operand(MachOper* generic_opnd, uint ideal_reg);
>>> // constructs fixed-sized vector operand based on ideal reg
>>> // vec + Op_Vec[SDXYZ] => vec[SDXYZ]
>>> // legVec + Op_Vec[SDXYZ] => legVec[SDXYZ]
>>>
>>>
>>> (5) TEMP operands are handled specially:
>>> - TEMP uses max_vector_size() to determine what fixed-sized operand to use
>>> * it is needed to cover reductions which don't produce vectors but scalars
>>> - TEMP_DEF inherits fixed-sized operand type from DEF;
>>>
>>>
>>> (6) there is limited number of special cases for mach nodes in
>>> Matcher::get_vector_operand_helper:
>>>
>>> - RShiftCntV/RShiftCntV: though it reports wide vector type as Node::bottom_type(), its
>>> ideal_reg is VecS! But for vector nodes only Node::bottom_type() is captured during matching and not
>>> ideal_reg().
>>>
>>> - vshiftcntimm: chain instructions which convert scalar to vector don't have vector type.
>>>
>>>
>>> (7) idealreg2regmask initialization logic is adjusted to handle generic vector operands (see
>>> Matcher::get_vector_regmask)
>>>
>>>
>>> (8) operand renaming in x86_32.ad & x86_64.ad to avoid name conflicts with new vec/legVec
>>> operands
>>>
>>>
>>> (9) x86_64.ad: all TEMP usages of vecS/legVecS are replaced with regD/legRegD
>>> - it aligns the code between x86_64.ad and x86_32.ad
>>> - strictly speaking, it's illegal to use vector operands on a non-vector node (e.g.,
>>> string_inflate) unless its usage is guarded by C2 vector support checks (-XX:MaxVectorSize=0)
>>>
>>>
>>> Contributed-by: Jatin Bhateja <jatin.bhateja at intel.com>
>>> Reviewed-by: vlivanov, sviswanathan, ?
>>>
>>> Testing: tier1-tier4, jtreg compiler tests on KNL and SKL,
>>> performance testing (SPEC* + Octane + micros / G1 + ParGC).
>>>
>>> Best regards,
>>> Vladimir Ivanov
>>>
>>> [1] https://mail.openjdk.java.net/pipermail/hotspot-compiler-dev/2019-August/034822.html
>>>
>>> [2] http://cr.openjdk.java.net/~jbhateja/genericVectorOperands/generic_operands_support_v1.0.pdf
More information about the hotspot-compiler-dev
mailing list