diff options
author | 2022-09-14 22:06:57 +0100 | |
---|---|---|
committer | 2023-07-11 13:02:48 +0000 | |
commit | 406de8fbbe4a7e3e1d02807d09e4b65b808b5a31 (patch) | |
tree | bc95ae244583b4776da749532ed28dc3dadb2969 /compiler/optimizing/loop_optimization.h | |
parent | 45710e71e371ec4c26c4a5b105f42d9db873099b (diff) |
Refactor vectorization general pipeline.
Currently, vectorization methods such as GenerateNewLoop and
Vectorize process loops for both traditional and predicated
modes with multiple IsInPredicatedVectorizationMode() checks
which control the behavior. This makes the code have many
implicit assumptions and rather difficult to extend.
The aim of this CL is to create two separate pipelines
for traditional and predicated vectorization and to share
as much common helpers as possible.
Original author: Artem Serov <Artem.Serov@linaro.org>
Test: ./art/test/testrunner/testrunner.py --host --optimizing --jit
Test: ./art/test/testrunner/testrunner.py --target --optimizing --jit
Test: target tests on arm64 with SVE (for details see
art/test/README.arm_fvp).
Change-Id: I35a57e8585aa0d24aaf7cdcdd852199e24767172
Diffstat (limited to 'compiler/optimizing/loop_optimization.h')
-rw-r--r-- | compiler/optimizing/loop_optimization.h | 80 |
1 files changed, 71 insertions, 9 deletions
diff --git a/compiler/optimizing/loop_optimization.h b/compiler/optimizing/loop_optimization.h index 27afc07f4e..3da8f8fe39 100644 --- a/compiler/optimizing/loop_optimization.h +++ b/compiler/optimizing/loop_optimization.h @@ -203,15 +203,76 @@ class HLoopOptimization : public HOptimization { // Vectorization analysis and synthesis. // - bool ShouldVectorize(LoopNode* node, HBasicBlock* block, int64_t trip_count); - void Vectorize(LoopNode* node, HBasicBlock* block, HBasicBlock* exit, int64_t trip_count); - void GenerateNewLoop(LoopNode* node, - HBasicBlock* block, - HBasicBlock* new_preheader, - HInstruction* lo, - HInstruction* hi, - HInstruction* step, - uint32_t unroll); + // Returns whether the data flow requirements are met for vectorization. + // + // - checks whether instructions are vectorizable for the target. + // - conducts data dependence analysis for array references. + // - additionally, collects info on peeling and aligment strategy. + bool CanVectorizeDataFlow(LoopNode* node, HBasicBlock* block, bool collect_alignment_info); + + + // Vectorizes the loop for which all checks have been already done. + // + // There are two versions/algorithms: + // - Predicated: all the vector operations have governing predicates which control + // which individual vector lanes will be active (see HVecPredSetOperation for more details). + // Example: vectorization using AArch64 SVE. + // - Traditional: a regular mode in which all vector operations lanes are unconditionally + // active. + // Example: vectoriation using AArch64 NEON. + void VectorizePredicated(LoopNode* node, + HBasicBlock* block, + HBasicBlock* exit); + void VectorizeTraditional(LoopNode* node, + HBasicBlock* block, + HBasicBlock* exit, + int64_t trip_count); + + // Performs final steps for whole vectorization process: links reduction, removes the original + // scalar loop, updates loop info. + void FinalizeVectorization(LoopNode* node, HBasicBlock* block); + + // Helpers that do the vector instruction synthesis for the previously created loop; create + // and fill the loop body with instructions. + // + // A version to generate a vector loop in predicated mode. + void GenerateNewLoopPredicated(LoopNode* node, + HBasicBlock* block, + HBasicBlock* new_preheader, + HInstruction* lo, + HInstruction* hi, + HInstruction* step); + + // A version to generate a vector loop in traditional mode or to generate + // a scalar loop for both modes. + void GenerateNewLoopScalarOrTraditional(LoopNode* node, + HBasicBlock* block, + HBasicBlock* new_preheader, + HInstruction* lo, + HInstruction* hi, + HInstruction* step, + uint32_t unroll); + + // + // Helpers for GenerateNewLoop*. + // + + // Updates vectorization bookkeeping date for the new loop, creates and returns + // its main induction Phi. + HPhi* InitializeForNewLoop(HBasicBlock* new_preheader, HInstruction* lo); + + // Finalizes reduction and induction phis' inputs for the newly created loop. + void FinalizePhisForNewLoop(HPhi* phi, HInstruction* lo); + + // Performs instruction synthesis for the loop body. + void GenerateNewLoopBodyOnce(LoopNode* node, + HBasicBlock* body, + DataType::Type induc_type, + HInstruction* step); + + // Returns whether the vector loop needs runtime disambiguation test for array refs. + bool NeedsArrayRefsDisambiguationTest() const { return vector_runtime_test_a_ != nullptr; } + bool VectorizeDef(LoopNode* node, HInstruction* instruction, bool generate_code); bool VectorizeUse(LoopNode* node, HInstruction* instruction, @@ -380,6 +441,7 @@ class HLoopOptimization : public HOptimization { HBasicBlock* vector_header_; // header of the new loop HBasicBlock* vector_body_; // body of the new loop HInstruction* vector_index_; // normalized index of the new loop + HInstruction* loop_main_pred_; // Loop main predicate - for predicated mode. // Helper for target-specific behaviour for loop optimizations. ArchNoOptsLoopHelper* arch_loop_helper_; |