Hyperword-level automatic vectorization method for variable-length vector architecture

By using storage instruction groups and assertion registers to implement vectorization based on the SLP algorithm, the problem of low performance when the super word length is smaller than the width of the vector register in the prior art is solved, and efficient automatic vectorization is realized on the scalable vector expansion architecture, improving code performance and utilization of vector registers.

CN119782254APending Publication Date: 2025-04-08NAT UNIV OF DEFENSE TECH
View PDF 0 Cites 0 Cited by

Patent Information

Application Number
CN202411611130.9
Authority / Receiving Office
CN · China
Patent Type
Applications(China)
Current Assignee / Owner
Filing Date
2024-11-12
Publication Date
2025-04-08

AI Technical Summary

Technical Problem

When the prior art uses SLP algorithm to achieve automatic vectorization in the scalable vector expansion architecture, when the super word length is less than the width of the vector register, it is usually chosen to use NEON vector expansion with weaker performance, resulting in the inability to fully utilize the computing resources of vector components and the generated code performance is not high.

Method used

Based on the SLP algorithm, using the storage instruction group as the starting point, searching up along the definition-use chain, add the isomorphic statement group to the SLP graph until a constant assignment statement or read statement is encountered, and in the process of constructing the SLP graph, the assertion register provided by the SVE vector extension is used as the mask to achieve vectorization.

Benefits of technology

It can efficiently realize word-level automatic vectorization on the scalable vector expansion architecture, give full play to the computational performance of processor vector computing, improve the performance of vector code generated by the compiler, and improve the utilization rate of vector registers.

✦ Generated by Eureka AI based on patent content.

Smart Images

  • Figure CN119782254A_ABST
    Figure CN119782254A_ABST
Patent Text Reader

Abstract

The invention discloses a hyperword-level automatic vectorization method for a variable-length vector architecture. The hyperword-level automatic vectorization method comprises the following steps: step 1, searching all storage instructions in a basic block of a target source scalar code; step 2, adding all searched storage instructions into a storage instruction group; step 3, constructing an SLP graph according to the storage instruction group, in the SLP graph construction process, taking the storage instruction group as a starting point, performing upward search along a definition-use chain, continuously adding isomorphic statement groups into the SLP graph until a constant assignment statement is encountered or statement reading is finished, and then completing the SLP graph construction. Wherein when the number of statements stored in the storage instruction group is smaller than the number of elements allowed to be stored in the SVE vector register, the assertion register is used as a mask; and step 4, generating a vector code according to the constructed SLP, and completing code vectorization. According to the method, efficient super-word-level automatic vectorization can be realized for a variable-length vector architecture, and the utilization rate of a vector register is improved, so that the vectorization performance of a program is improved.
Need to check novelty before this filing date? Find Prior Art

Description

Technical Field

[0001] The present invention relates to the technical field of super-word level (SLP) automatic vectorization, and in particular to a super-word level automatic vectorization method for a variable-length vector architecture. Background Art

[0002] Single Instruction Multiple Data (SIMD) is a key technology for processor performance improvement. The current mainstream instruction set architectures have designed SIMD vector instruction set extensions, such as INTEL's SSE, AVX, and ARM's NEON. With the rapid development of computer architecture, the shortcomings of traditional SIMD have gradually become prominent. In particular, due to the different vector register widths of different processors, the vector code compiled for one processor cannot be directly run on another processor with a different vector register width. The source code needs to be recompiled, and the portability is relatively poor. Scalable Vector Extension (SVE) is a new form of vector extension that can support variable-length vector register widths (128 to 2048 bits, that is, integer multiples of 128 bits) and VLA (Vector Length Agnostic) programming. The source code only needs to be compiled once and can run on processors with different vector register lengths.

[0003] Automatic vectorization is a method in which the compiler identifies serial codes in the source code that are suitable for data-level parallelism and converts them into SIMD vector codes. Automatic vectorization codes are divided into loop-level automatic vectorization codes and super-word level (SLP) automatic vectorization algorithms. The loop-level automatic vectorization algorithm can explore the parallelism between loop iterations, expand the loop a certain number of times, and then merge the scalar statements of the expanded multiple iterations into one vector statement for execution. The SLP algorithm can explore the parallelism in basic blocks and realize data-level parallelism by merging isomorphic statements (i.e. statements that perform the same operation, such as multiple multiplication statements, multiple addition statements, etc.) in the basic block into one vector statement.

[0004] However, on a scalable vector extension architecture, when the SLP algorithm is used in the prior art to implement automatic vectorization, if the superword length is smaller than the vector register width, the NEON (Advanced SIMD, single instruction multiple data) vector extension is usually used to complete the vectorization. Compared with the SVE vector extension, the performance of the NEON vector extension is weaker, resulting in the inability to fully utilize the computing resources of the vector component and the generated code has low performance. Summary of the invention

[0005] The technical problem to be solved by the present invention is: in response to the technical problems existing in the prior art, the present invention provides a super-word-level automatic vectorization method for a variable-length vector architecture with a simple implementation method, low cost, high efficiency and low overhead, which can be applied to a scalable vector extension architecture to efficiently implement word-level automatic vectorization, give full play to the computing performance of processor vector calculations, and improve the performance of vector code generated by the compiler.

[0006] In order to solve the above technical problems, the technical solution proposed by the present invention is:

[0007] A superword-level automatic vectorization method for a variable-length vector architecture, comprising the following steps:

[0008] Step 1. Store instruction search: Search all store instructions in the basic blocks of the target source scalar code;

[0009] Step 2. Packing storage instructions: Pack all storage instructions in the searched basic blocks and add them into the storage instruction group;

[0010] Step 3. SLP graph construction: construct an SLP graph according to the storage instruction group. In the process of constructing the SLP graph, the storage instruction group is used as the starting point, and the definition-use chain is searched upward, and isomorphic statement groups are continuously added to the SLP graph until a constant assignment statement or a read statement is encountered. When the number of storage statements in the storage instruction group is less than the number of elements allowed to be stored in the SVE vector register, the predicate register provided by the SVE vector extension is used as a mask;

[0011] Step 4. Vector code generation: Generate vector code based on the constructed SLP graph, where if the vector version code overhead of the instance in the SLP graph is less than the scalar version code overhead, the vector code is used to replace the scalar code to complete code vectorization.

[0012] Further, step S1 includes:

[0013] Step 1.1. Take out the first instruction in the basic block and use it as the current instruction inst;

[0014] Step 1.2. Determine whether the current instruction inst is a storage instruction. If it is a storage instruction, continue to execute step 1.3, otherwise jump to execute step 1.4;

[0015] Step 1.3. Add the current instruction inst to the storage instruction queue store_stmt_list;

[0016] Step 1.4. Determine whether all instructions in the basic block have been processed. If not, continue to step 1.5, otherwise exit the current step;

[0017] Step 1.5. Take the next instruction in the basic block and use it as the current inst, then jump to step 1.2.

[0018] Further, step S2 includes:

[0019] Step 2.1. Take the first instruction from the storage instruction queue store_stmt_list and use it as the current instruction inst;

[0020] Step 2.2. Set the address addr of the current instruction inst;

[0021] Step 2.3. Create a new empty storage instruction group store_group;

[0022] Step 2.4. Add the current instruction inst to the storage instruction group store_group;

[0023] Step 2.5. Take the next instruction inst_n from the storage instruction queue store_stmt_list;

[0024] Step 2.6. Determine whether the data types of the current instruction inst and the next instruction inst_n are consistent. If they are consistent, continue to execute step 2.7, otherwise jump to execute step 2.11;

[0025] Step 2.7. Determine whether the address addr of the current instruction inst is adjacent to the address inst_n.addr of the next instruction inst_n. If so, continue to execute step 2.8, otherwise jump to execute step 2.11;

[0026] Step 2.8. Add the next instruction inst_n to the storage instruction group store_group;

[0027] Step 2.9. Update the address addr to the address of the next instruction inst_n, that is, addr = inst_n.addr;

[0028] Step 2.10. Delete the next instruction inst_n from the storage instruction queue store_stmt_list;

[0029] Step 2.11. Determine whether the last instruction in the storage instruction queue store_stmt_list has been processed. If not, continue to execute step 2.12, otherwise jump to execute step 2.13;

[0030] Step 2.12. Take the next instruction of the next instruction inst_n from the storage instruction queue store_stmt_list and use it as the new next instruction inst_n, and jump to execute step 2.6;

[0031] Step 2.13. Determine whether the size of the storage instruction group store_group is greater than 1, if it is greater than 1, continue to execute step 2.14, otherwise jump to execute step 2.15;

[0032] Step 2.14. Add the storage instruction group store_group to the storage instruction group queue store_group_list;

[0033] Step 2.15. Determine whether the last instruction in the storage instruction group queue store_stmt_list has been processed. If not, continue to execute step 2.16, otherwise exit the current step;

[0034] Step 2.16. Take the next instruction of the current instruction inst from the storage instruction queue store_stmt_list and use it as the new current instruction inst, and jump to execute step 2.2.

[0035] Further, step S3 includes:

[0036] Step 3.1. Take out the first storage instruction group in the storage instruction group queue store_group_list and use it as the current storage instruction group store_group;

[0037] Step 3.2. Call build_slp_instance with the current storage instruction group store_group as a parameter to create an SLP graph instance;

[0038] Step 3.3. Add the created instance to the SLP graph queue;

[0039] Step 3.4. Determine whether all storage instruction groups in the storage instruction group queue store_group_list have been processed. If not, continue to step 3.5, otherwise end the current step;

[0040] Step 3.5. Take the next storage instruction group from the storage instruction group queue store_group_list and use it as the new current storage instruction group store_group, and jump to execute step 3.2.

[0041] Further, step 3.2 includes:

[0042] Step 3.2.1. Call create_slp_tree with the storage instruction group store_group as parameter to create an SLP tree root;

[0043] Step 3.2.2. Determine whether the statement in the storage instruction group store_group is a constant storage statement. If not, continue to execute step 3.2.3. Otherwise, jump to step 3.2.9 for execution;

[0044] Step 3.2.3. Get all operands ops of the storage instruction group;

[0045] Step 3.2.4. Take the first set of operands from all the operands ops obtained and use them as the current operand op;

[0046] Step 3.2.5. Search for the definition statement group def_stmts of the current operand op upward along the define-use chain;

[0047] Step 3.2.6. Call recursively_build_slp_tree with the SLP tree root and statement group def_stmts as parameters to recursively construct the SLP tree;

[0048] Step 3.2.7. Determine whether all operands ops have been processed. If not, continue to execute step 3.2.8. Otherwise, jump to execute step 3.2.9.

[0049] Step 3.2.8. Get the next set of operands from all operands ops and use them as the current operand op, then jump to step 3.2.5;

[0050] Step 3.2.9. Create a new SLP graph instance;

[0051] Step 3.2.10. Assign the SLP tree root to the instance root, i.e. instance.root = root;

[0052] Step 3.2.11. Determine whether the size of the storage instruction group store_group is less than nunits. If so, continue to execute step 3.2.12. Otherwise, jump to execute step 3.2.14, where nunits is the number of elements allowed to be stored in the SVE vector register;

[0053] Step 3.2.12. Create a mask mask according to the size of the storage instruction group store_group and nunits;

[0054] Step 3.2.13. Set the assertion register control bit to enable, that is, set instance.partial = YES, instance.mask = mask, and jump to step 3.2.15;

[0055] Step 3.2.14. Set the assertion register control bit to disabled, i.e., set instance.partial = NO, instance.mask = NULL;

[0056] Step 3.2.15. Return the SLP graph instance.

[0057] Furthermore, the specific steps of calling create_slp_tree in step 3.2.1 include:

[0058] Step 3.2.1.1 determines whether the scalar statements in the parameter statement group stmts are isomorphic. If yes, continue to execute step 3.2.1.2. Otherwise, return NULL.

[0059] Step 3.2.1.2. Create a new SLP tree tree;

[0060] Step 3.2.1.3. Construct the corresponding vector statement vec_stmts according to the scalar statement in the stmts group;

[0061] Step 3.2.1.4. Set the scalar statement of SLP tree tree.scalar_stmts = stmts;

[0062] Step 3.2.1.5. Set the vector statement of SLP tree tree.vec_stmts = vec_stmts;

[0063] Step 3.2.1.6. Return the currently constructed SLP tree tree and exit the current step.

[0064] Furthermore, the specific execution steps of calling recursively_build_slp_tree in step 3.2.6 include:

[0065] Step 3.2.6.1. Call create_slp_tree with the parameter statement group stmts as parameter to create a new SLP tree child;

[0066] Step 3.2.6.2. Add the SLP tree child to the child nodes of the parameter SLP tree tree;

[0067] Step 3.2.6.3. Determine whether the parameter statement group stmts is a constant assignment or read statement. If not, continue to execute step 3.2.6.4. Otherwise, jump to execute step 3.2.6.10;

[0068] Step 3.2.6.4. Get all operands ops of the scalar statement group;

[0069] Step 3.2.6.5. Get the first operand of all operands ops of the scalar statement group and use it as the current operand op;

[0070] Step 3.2.6.6. Search for the definition statement group def_stmts of the current operand op upward along the define-use chain;

[0071] Step 3.2.6.7. Call recursively_build_slp_tree with SLP tree child and statement group def_stmts as parameters to recursively construct the SLP tree;

[0072] Step 3.2.6.8. Determine whether all operands in all operands ops of the scalar statement group have been processed. If not, continue to execute step 3.2.6.9, otherwise exit the current step;

[0073] Step 3.2.6.9. Get the next set of operands from all operands ops of the scalar statement group and use them as the current operand op, and jump to execute step 3.2.6.6.

[0074] Further, step 4 includes:

[0075] Step 4.1. Take out the first SLP graph instance in the SLP graph queue instance and use it as the current SLP graph instance;

[0076] Step 4.2. Calculate the scalar version code cost scalar_cost and the vector version code cost vector_cost of the current SLP graph instance respectively;

[0077] Step 4.3. Determine whether the vector version code cost vector_cost is less than the scalar version code cost scalar_cost. If so, continue to execute step 4.4; otherwise, jump to execute step 4.5.

[0078] Step 4.4. Replace the scalar code of the current SLP graph instance with the vector code;

[0079] Step 4.5. Determine whether all SLP graphs in the SLP graph queue instance have been processed. If not, continue to step 4.6, otherwise exit the current step;

[0080] Step 4.6. Take out the next SLP graph instance in the SLP graph queue instance and jump to execute step 4.2.

[0081] A computer-readable storage medium storing a computer program, wherein the computer program implements the above method when executed by a processor.

[0082] A computer program product includes computer instructions, and the computer instructions are executed by a processor to enable a computer device to implement the above method.

[0083] Compared with the prior art, the advantages of the present invention are:

[0084] 1. The present invention aims at a scalable vector extension architecture, realizes automatic vectorization by adopting an SLP algorithm, takes a storage instruction group as a starting point, searches upward along a definition-use chain to continuously add isomorphic statement groups into an SLP graph, and can construct an SLP graph according to the storage instruction group. Meanwhile, in the process of constructing the SLP graph, when the number of storage statements in the storage instruction group is less than the number of elements allowed to be stored in an SVE vector register, an assertion register provided by the SVE vector extension is used as a mask so that vectorization can be completed using a more powerful SVE vector extension, which can maximize the performance of scalable vector extension components, improve the performance of vector codes generated by the compiler, and also improve the utilization rate of vector registers, explore more data-level parallelism within basic blocks, and improve program vectorization performance.

[0085] 2. The present invention takes the storage statement group as the starting point, searches upward according to the definition-use chain, and continuously adds isomorphic statement groups to the SLP graph until a constant assignment statement or a read statement is encountered, thereby constructing an SLP graph; further, a recursive method is used to construct an SLP tree, and each SLP tree in the SLP graph is constructed in the same way, which can further improve the compilation performance. BRIEF DESCRIPTION OF THE DRAWINGS

[0086] Figure 1 It is a schematic diagram of the implementation flow of the superword-level automatic vectorization method for the scalable vector extension architecture of this embodiment.

[0087] Figure 2 This is a flowchart of searching all storage instructions in a basic block in step 1 of this embodiment.

[0088] Figure 3 This is a flowchart of step 2 of this embodiment that packs a storage statement group according to all storage statements in a basic block.

[0089] Figure 4 This is a flowchart of constructing an SLP graph based on a storage statement group in step 3 of this implementation.

[0090] Figure 5 This is a flow chart of creating the SLP graph build_slp_instance in step 3.2 of this embodiment.

[0091] Figure 6 This is a flow chart of creating the SLP tree create_slp_tree in step 3.2.1 of this embodiment.

[0092] Figure 7 This is a flow chart of recursively constructing the SLP tree recursively_build_slp_tree in step 3.2.6 of this embodiment.

[0093] Figure 8 This is a flow chart of generating vector codes according to the SLP graph in step 4 of this embodiment. DETAILED DESCRIPTION

[0094] The present invention is further described below in conjunction with the accompanying drawings and specific preferred embodiments, but the protection scope of the present invention is not limited thereby.

[0095] To facilitate understanding, the relevant technical principles and technical terms involved in this embodiment are first explained.

[0096] The characteristics of scalable vector extensions determine that they are more suitable for loop-level vectorization, but not so suitable for SLP vectorization. The reason is that the number of loop unrolling can be dynamically determined according to the vector register width of the processor, while the SLP algorithm needs to know the width of the processor vector register during the static compilation stage. Otherwise, in order to ensure the correctness of the program, only the minimum vector register width (i.e. 128 bits) can be conservatively selected, which cannot maximize the utilization of the vector components.

[0097] In order to give full play to the computing performance of processor vector computing, when the width of the processor vector register is known, the vector register length can be specified through the compilation option when compiling the code, and the SLP algorithm can choose to pack more isomorphic statements into vector statements for execution according to the vector register width. In the prior art, the SLP algorithm has defects when specifying the vector register length. When the superword length is less than the vector register width, it will conservatively choose to use the neon vector extension with weaker performance to complete vectorization instead of using the SVE vector extension to complete vectorization, resulting in it not being able to maximize the advantages of scalable vector computing components.

[0098] Specifically, when the vector register length is specified, the SLP algorithm in the prior art will use scalable vector registers to generate vector code only when the data of the isomorphic statement just fills up the vector register (for example, the vector register width is 256 bits, the number of isomorphic statements is 4, and the operand type is double-precision floating point, the width of the 4 double-precision floating point data is 4x 64bit=256bit, which just fills up the vector register). However, if the data of the isomorphic statement cannot fill the vector register (for example, the vector register width is 256 bits, the number of isomorphic statements is 6, and the operand type is single-precision floating point, then the width of the 6 single-precision floating point data is 6x 32bit=192bit, which cannot fill the vector register with a width of 256 bits), the SLP algorithm in the prior art will split the isomorphic statements based on the minimum width of the variable-length vector register (i.e., 128 bits). For the isomorphic statements after segmentation, if the data width meets the requirement of 128 bits, a vector register with a width of 128 bits will be selected for vectorization. For isomorphic statements whose data width does not meet the requirement of 128 bits, vectorization will be abandoned.

[0099] For example, when the vector register width is 256 bits, the number of isomorphic statements is 6, and the operand type is single-precision floating point, the SLP algorithm in the prior art will divide the original 6 isomorphic statements into two groups of isomorphic statements. The first group contains 4 isomorphic statements with a data width of 4x 32bit=128bit, and uses a vector register with a width of 128bit for vectorization. The second group contains 2 isomorphic statements with a data width of 2x 32bit=64bit, and vectorization is abandoned.

[0100] The present invention is aimed at a scalable vector extension architecture, and realizes automatic vectorization by adopting an SLP algorithm. With a storage instruction group as a starting point, the method searches upward along a definition-use chain to continuously add isomorphic statement groups into an SLP graph until a constant assignment statement or a read statement is encountered. The SLP graph can be constructed according to the storage instruction group. Meanwhile, in the process of constructing the SLP graph, when the number of storage statements in the storage instruction group is less than the number of elements allowed to be stored in an SVE vector register, an assertion register provided by the SVE vector extension is used as a mask so that the SVE vector extension with stronger performance can be used to complete vectorization. Thus, the assertion register provided by the scalable vector extension architecture can be used as a mask to effectively control whether the data in the vector register participates in the operation, and the performance of the scalable vector extension component can be squeezed to the maximum extent, and the performance of the vector code generated by the compiler can be improved. The utilization rate of the vector register can also be improved, more data-level parallelism within the basic block can be explored, and the program vectorization performance can be improved.

[0101] like Figure 1As shown, the steps of the superword-level automatic vectorization method for a variable-length vector architecture in this embodiment include:

[0102] Step 1. Store instruction search: Search all store instructions in the basic blocks of the target source scalar code;

[0103] Step 2. Packing storage instructions: Pack all storage instructions in the searched basic blocks and add them into the storage instruction group;

[0104] Step 3. SLP graph construction: construct the SLP graph according to the storage instruction group. In the process of constructing the SLP graph, the storage instruction group is used as the starting point, and the search is upward along the definition-use chain, and the isomorphic statement groups are continuously added to the SLP graph until a constant assignment statement or a read statement is encountered. When the number of storage statements in the storage instruction group is less than the number of elements allowed to be stored in the SVE vector register, the predicate register provided by the SVE vector extension is used as a mask;

[0105] Step 4. Vector code generation: Generate vector code based on the constructed SLP graph, where if the vector version code overhead of the instance in the SLP graph is less than the scalar version code overhead, the vector code is used to replace the scalar code to complete code vectorization.

[0106] Scalable vector extension introduces predicate registers based on vector registers, and predicate registers are used to control which data paths in vector registers actually participate in operations. The SLP graph is a graph composed of SLP trees with the SLP tree corresponding to the storage statement group as the root. This embodiment uses the predicate register provided by the scalable vector extension architecture as a mask in the process of SLP graph construction based on the SLP algorithm to control whether the data in the vector register participates in the operation. When the number of storage statements in the storage instruction group is less than the number of elements allowed to be stored in the SVE vector register, the more powerful SVE vector extension is used to complete vectorization, which can greatly improve the program vectorization performance and the utilization rate of the vector register.

[0107] like Figure 2 As shown, step S1 in this embodiment specifically includes:

[0108] Step 1.1. Take out the first instruction in the basic block and use it as the current instruction inst;

[0109] Step 1.2. Determine whether the current instruction inst is a storage instruction. If it is a storage instruction, continue to execute step 1.3, otherwise jump to execute step 1.4;

[0110] Step 1.3. Add the current instruction inst to the storage instruction queue store_stmt_list, i.e. store_stmt_list.push_back(inst);

[0111] Step 1.4. Determine whether all instructions in the basic block have been processed. If not, continue to step 1.5, otherwise exit the current step;

[0112] Step 1.5. Take the next instruction in the basic block and use it as the current inst, then jump to step 1.2.

[0113] Through the above steps, the set of all storage instructions in a basic block can be obtained from the storage instruction queue store_stmt_list.

[0114] like Figure 3 As shown, step S2 in this embodiment specifically includes:

[0115] Step 2.1. Take the first instruction from the storage instruction queue store_stmt_list and use it as the current instruction inst;

[0116] Step 2.2. Set the address addr of the current instruction inst, that is, addr = inst.addr;

[0117] Step 2.3. Create a new empty storage instruction group store_group;

[0118] Step 2.4. Add the current instruction inst to the storage instruction group store_group, i.e. store_group.push_back(inst);

[0119] Step 2.5. Take the next instruction inst_n from the storage instruction queue store_stmt_list;

[0120] Step 2.6. Determine whether the data types of the current instruction inst and the next instruction inst_n are consistent. If they are consistent, continue to execute step 2.7, otherwise jump to execute step 2.11;

[0121] Step 2.7. Determine whether the address addr of the current instruction inst is adjacent to the address inst_n.addr of the next instruction inst_n. If so, continue to execute step 2.8, otherwise jump to execute step 2.11;

[0122] Step 2.8. Add the next instruction inst_n to the storage instruction group store_group, that is

[0123] store_group.push_back(inst_n);

[0124] Step 2.9. Update the address addr to the address of the next instruction inst_n, that is, addr = inst_n.addr;

[0125] Step 2.10. Delete instruction inst_n from the storage instruction queue store_stmt_list, that is, store_stmt_list.delete(inst_n);

[0126] Step 2.11. Determine whether the last instruction in the storage instruction queue store_stmt_list has been processed. If not, continue to execute step 2.12, otherwise jump to execute step 2.13;

[0127] Step 2.12. Take the next instruction of the next instruction inst_n from the storage instruction queue store_stmt_list and use it as the new next instruction inst_n, and jump to execute step 2.6;

[0128] Step 2.13. Determine whether the size of the storage instruction group store_group is greater than 1. If it is greater than 1, continue to step 2.14; otherwise, jump to step 2.15;

[0129] Step 2.14. Add the storage instruction group store_group to the storage instruction group queue store_group_list, that is, store_group_list.push_back(store_group);

[0130] Step 2.15. Determine whether the last instruction in store_stmt_list has been processed. If not, continue to step 2.16. Otherwise, jump to step 2.17.

[0131] Step 2.16. Take the next instruction of the current instruction inst from the storage instruction queue store_stmt_list and use it as the new current instruction inst, and jump to execute step 2.2;

[0132] Step 2.17. End.

[0133] In the above steps, store_group stores a group of storage instructions, that is, a group of storage instructions with the same data type and continuous addresses. store_group_list stores the store_group queue, that is, the collection of all storage statement groups store_group in a basic block. After the above steps, all storage instructions in the basic block can be packaged and added to the storage instruction group queue store_group_list.

[0134] like Figure 4 As shown, step S3 in this embodiment specifically includes:

[0135] Step 3.1. Take out the first storage instruction group in the storage instruction group queue store_group_list and use it as the current storage instruction group store_group;

[0136] Step 3.2. Call build_slp_instance with the current storage instruction group store_group as a parameter to create an SLP graph instance;

[0137] Step 3.3. Add instance to the SLP graph queue instances, i.e. instances.push_back(instance);

[0138] Step 3.4 determines whether all storage statement groups in the storage statement group queue store_group_list have been processed. If not, continue to step 3.5; otherwise, jump to step 3.6;

[0139] Step 3.5. Take out the next group of storage instruction groups in the storage instruction group queue store_group_list and use it as the new current storage instruction group store_group, and jump to step 3.2 for execution;

[0140] Step 3.6. End.

[0141] The nodes in the SLP graph are a group of isomorphic statements, that is, statements with the same data type and performing the same operation. This embodiment takes the storage statement group as the starting point, searches upward according to the definition-use chain, and continuously adds isomorphic statement groups to the SLP graph until a constant assignment statement or a read statement is encountered, thereby constructing the SLP graph.

[0142] like Figure 5 As shown, step 3.2 in this embodiment specifically includes:

[0143] Step 3.2.1. Call create_slp_tree with the storage instruction group store_group as a parameter to create an SLP tree root (root node);

[0144] Step 3.2.2. Determine whether the statements in the storage statement group store_group are constant storage statements. If not, continue to execute step 3.2.3. Otherwise, jump to step 3.2.9 for execution;

[0145] Step 3.2.3. Get all operands ops of the storage statement group, that is, ops = store_group.operands();

[0146] Step 3.2.4. Take the first set of operands from all the operands ops obtained and use them as the current operand op;

[0147] Step 3.2.5. Search for the definition statement group def_stmts of op upward along the define-use chain;

[0148] Step 3.2.6. Call recursively_build_slp_tree with the SLP tree root and statement group def_stmts as parameters to recursively construct the SLP tree;

[0149] Step 3.2.7. Determine whether all operands in ops have been processed. If not, continue to execute 3.2.8. Otherwise, jump to execute step 3.2.9.

[0150] Step 3.2.8. Get the next set of operands from all operands ops and use them as the current operand op, then jump to 3.2.5 for execution;

[0151] Step 3.2.9. Create a new SLP graph instance;

[0152] Step 3.2.10. Assign the SLP tree root to the root of instance, i.e. instance.root = root;

[0153] Step 3.2.11. Determine whether the size of the storage instruction group store_group is less than nunits. If so, continue to execute step 3.2.12 to create and enable the predicate register provided by the SVE vector extension as a mask. Otherwise, jump to execute step 3.2.14 to disable the predicate register provided by the SVE vector extension as a mask.

[0154] Step 3.2.12. Create a mask mask according to the store_group size and nunits, that is, mask = build_mask (store_group.size(), nunits);

[0155] Step 3.2.13. Set the assertion register control bit to enable, that is, set instance.partial = YES, instance.mask = mask, and jump to step 3.2.15 to execute;

[0156] Step 3.2.14. Set the assertion register control bit to disabled, i.e., set instance.partial = NO, instance.mask = NULL;

[0157] Step 3.2.15. Return the SLP graph instance.

[0158] In view of the situation where the superword length is smaller than the vector register width, this embodiment uses the predicate register provided by the scalable vector extension architecture as a mask to control whether the data in the vector register participates in the operation. For the data within the superword length, the predicate register control bit is set to enable to control the data within the superword length to participate in the operation. For the data exceeding the superword length, the predicate register control bit is set to disable to prohibit the data outside the superword length from participating in the operation. This can maximize the performance of the scalable vector extension component, improve the performance of the vector code generated by the compiler, and also improve the utilization rate of the vector register and the program vectorization performance.

[0159] like Figure 6 As shown, the specific process of calling create_slp_tree in step 3.2.1 of this embodiment is as follows:

[0160] Step 3.2.1.1 determines whether the scalar statements in the parameter statement group stmts are isomorphic. If so, continue to execute 3.2.1.2. Otherwise, return NULL.

[0161] Step 3.2.1.2. Create a new SLP tree tree;

[0162] Step 3.2.1.3. Construct the corresponding vector statement vec stmts according to the scalar statement in the stmts group;

[0163] Step 3.2.1.4. Set the scalar statement of SLP tree tree.scalar_stmts = stmts;

[0164] Step 3.2.1.5. Set the vector statement of SLP tree tree.vec_stmts = vec_stmts;

[0165] Step 3.2.1.6. Return the currently constructed SLP tree tree and exit the current step.

[0166] like Figure 7 As shown, the specific execution steps of calling recursively_build_slp_tree in step 3.2.6 of this embodiment include:

[0167] Step 3.2.6.1. Call create_slp_tree with the parameter statement group stmts as the parameter to create a new SLP tree child, that is, child = create_slp_tree (stmts);

[0168] Step 3.2.6.2. Add the SLP tree child to the child nodes of the parameter SLP tree tree, that is, tree.children.push_back(child);

[0169] Step 3.2.6.3. Determine whether the parameter statement group stmts is a constant assignment or read statement. If not, continue to execute 3.2.6.4. Otherwise, jump to execute step 3.2.6.10.

[0170] Step 3.2.6.4. Get all operands ops of the scalar statement group, that is, ops = stmts.operands();

[0171] Step 3.2.6.5. Get the first operand of all operands ops of the scalar statement group and use it as the current operand op;

[0172] Step 3.2.6.6. Search for the definition statement group def_stmts of op upward along the define-use chain;

[0173] Step 3.2.6.7. Call recursively_build_slp_tree with SLP tree child and statement group def_stmts as parameters to recursively construct the SLP tree;

[0174] Step 3.2.6.8. Determine whether all operands in ops have been processed. If not, continue to step 3.2.6.9. Otherwise, jump to step 3.2.6.10.

[0175] Step 3.2.6.9. Get the next set of operands from all operands ops of the scalar statement group and use them as the current operand op, and jump to step 3.2.6.6 for execution;

[0176] Step 3.2.6.10 ends.

[0177] The SLP tree is a data structure used in the compiler's SLP algorithm, which contains a set of isomorphic scalar statements and corresponding vector statements, and subtrees corresponding to variable statement operands. This embodiment uses the idea of ​​recursion to construct the SLP tree. Each SLP tree in the SLP graph is constructed in the same way. Using a recursive method to construct the SLP tree can further improve compilation performance.

[0178] like Figure 8 As shown, step 4 in this embodiment specifically includes:

[0179] Step 4.1. Take out the first SLP graph instance in the SLP graph queue instance and use it as the current SLP graph instance;

[0180] Step 4.2. Calculate the scalar version code cost scalar_cost and the vector version code cost vector_cost of the current SLP graph instance respectively;

[0181] Step 4.3. Determine whether the vector version code cost vector_cost is less than the scalar version code cost scalar_cost. If so, continue to execute step 4.4; otherwise, jump to execute step 4.5.

[0182] Step 4.4. Replace the scalar code of the current SLP graph instance with the vector code;

[0183] Step 4.5. Determine whether all SLP graphs in the SLP graph queue instance have been processed. If not, continue to step 4.6, otherwise exit the current step;

[0184] Step 4.6. Take out the next SLP graph instance in the SLP graph queue instance and jump to execute step 4.2.

[0185] The code overhead is the estimated number of cycles required for the code to run during the compilation phase. This embodiment estimates the runtime overhead of a section of code by using the performance calculation model inside the compiler, that is, the number of cycles required to execute the section of code. The model records the overhead of each instruction in detail (including scalar instructions and vector instructions). By calculating the sum of the overhead corresponding to each instruction in a section of code, the overhead of the section of code can be calculated. By judging the size of the vector version code overhead vector_cost and the scalar version code overhead scalar_cost, when the vector version code overhead vector_cost is less than the scalar version code overhead scalar_cost, the scalar code of the current SLP graph instance is replaced with the vector code, which can complete the vectorization process and effectively reduce the code overhead.

[0186] This embodiment further provides a computer-readable storage medium storing a computer program, and when the computer program is executed by a processor, the above method is implemented.

[0187] This embodiment further provides a computer program product, which includes computer instructions. The computer instructions are executed by a processor to enable a computer device to implement the above method.

[0188] Those skilled in the art will appreciate that the above-mentioned embodiments of the present application may be provided as methods, systems, or computer program products. Therefore, the present application may take the form of a complete hardware embodiment, a complete software embodiment, or an embodiment combining software and hardware. Moreover, the present application may take the form of a computer program product implemented on one or more computer-readable storage media (including but not limited to disk storage, CD-ROM, optical storage, etc.) containing computer-usable program codes. The present application is described with reference to the flowcharts and / or block diagrams of the methods, devices (systems), and computer program products according to the embodiments of the present application. It should be understood that each process and / or box in the flowchart and / or block diagram, as well as the combination of the processes and / or boxes in the flowchart and / or block diagram, may be implemented by computer program instructions. These computer program instructions may be provided to a processor of a general-purpose computer, a special-purpose computer, an embedded processor, or other programmable data processing device to produce a machine, so that the instructions executed by the processor of the computer or other programmable data processing device generate instructions for implementing the functions in the process. Figure 1 A process or multiple processes and / or boxes Figure 1 These computer program instructions can also be stored in a computer-readable memory that can guide a computer or other programmable data processing device to work in a specific way, so that the instructions stored in the computer-readable memory produce a product including an instruction device, which implements the functions specified in the process. Figure 1 A process or multiple processes and / or boxes Figure 1 These computer program instructions can also be loaded onto a computer or other programmable data processing device, so that a series of operation steps are executed on the computer or other programmable device to produce a computer-implemented process, so that the instructions executed on the computer or other programmable device provide for implementing the process in the process. Figure 1 A process or multiple processes and / or boxes Figure 1 The steps for the functions specified in one or more boxes.

[0189] The above is only a preferred embodiment of the present invention, and does not limit the present invention in any form. Although the present invention has been disclosed as a preferred embodiment, it is not intended to limit the present invention. Therefore, any simple modification, equivalent change and modification made to the above embodiment according to the technical essence of the present invention without departing from the content of the technical solution of the present invention shall fall within the scope of protection of the technical solution of the present invention.

Claims

1. A superword-level automatic vectorization method for a variable-length vector architecture, characterized in that the steps include: Step 1. Store instruction search: Search all store instructions in the basic blocks of the target source scalar code; Step 2. Packing storage instructions: Pack all storage instructions in the searched basic blocks and add them into the storage instruction group; Step 3. SLP graph construction: construct an SLP graph according to the storage instruction group. During the construction of the SLP graph, the storage instruction group is used as the starting point, and the search is upward along the definition-use chain, and isomorphic statement groups are continuously added to the SLP graph until a constant assignment statement or a read statement is encountered. When the number of storage statements in the storage instruction group is less than the number of elements allowed to be stored in the SVE vector register, the predicate register provided by the SVE vector extension is used as a mask; Step 4. Vector code generation: Generate vector code based on the constructed SLP graph, where if the vector version code overhead of the instance in the SLP graph is less than the scalar version code overhead, the vector code is used to replace the scalar code to complete code vectorization.

2. The superword-level automatic vectorization method for variable-length vector architecture according to claim 1, characterized in that: Step S1 includes: Step 1.

1. Take out the first instruction in the basic block and use it as the current instruction inst; Step 1.

2. Determine whether the current instruction inst is a storage instruction. If it is a storage instruction, continue to execute step 1.3, otherwise jump to execute step 1.4; Step 1.

3. Add the current instruction inst to the storage instruction queue store_stmt_list; Step 1.

4. Determine whether all instructions in the basic block have been processed. If not, continue to step 1.5, otherwise exit the current step; Step 1.

5. Take the next instruction in the basic block and use it as the current inst, then jump to step 1.

2.

3. The superword-level automatic vectorization method for variable-length vector architecture according to claim 2, characterized in that: Step S2 includes: Step 2.

1. Take the first instruction from the storage instruction queue store_stmt_list and use it as the current instruction inst; Step 2.

2. Set the address addr of the current instruction inst; Step 2.

3. Create a new empty storage instruction group store_group; Step 2.

4. Add the current instruction inst to the storage instruction group store_group; Step 2.

5. Take the next instruction inst_n from the storage instruction queue store_stmt_list; Step 2.

6. Determine whether the data types of the current instruction inst and the next instruction inst_n are consistent. If they are consistent, continue to execute step 2.7, otherwise jump to execute step 2.11; Step 2.

7. Determine whether the address addr of the current instruction inst is adjacent to the address inst_n.addr of the next instruction inst_n. If so, continue to execute step 2.8, otherwise jump to execute step 2.11; Step 2.

8. Add the next instruction inst_n to the storage instruction group store_group; Step 2.

9. Update the address addr to the address of the next instruction inst_n, that is, addr = inst_n.addr; Step 2.

10. Delete the next instruction inst_n from the storage instruction queue store_stmt_list; Step 2.

11. Determine whether the last instruction in the storage instruction queue store_stmt_list has been processed. If not, continue to execute step 2.12, otherwise jump to execute step 2.13; Step 2.

12. Take the next instruction of the next instruction inst_n from the storage instruction queue store_stmt_list and use it as the new next instruction inst_n, and jump to execute step 2.6; Step 2.

13. Determine whether the size of the storage instruction group store_group is greater than 1, if it is greater than 1, continue to execute step 2.14, otherwise jump to execute step 2.15; Step 2.

14. Add the storage instruction group store_group to the storage instruction group queue store_group_list; Step 2.

15. Determine whether the last instruction in the storage instruction group queue store_stmt_list has been processed. If not, continue to execute step 2.16, otherwise exit the current step; Step 2.

16. Take the next instruction of the current instruction inst from the storage instruction queue store_stmt_list and use it as the new current instruction inst, and jump to execute step 2.

2.

4. The superword-level automatic vectorization method for variable-length vector architecture according to claim 3, characterized in that: Step S3 includes: Step 3.

1. Take out the first storage instruction group in the storage instruction group queue store_group_list and use it as the current storage instruction group store_group; Step 3.

2. Call build_slp_instance with the current storage instruction group store_group as a parameter to create an SLP graph instance; Step 3.

3. Add the created instance to the SLP graph queue; Step 3.

4. Determine whether all storage instruction groups in the storage instruction group queue store_group_list have been processed. If not, continue to step 3.5, otherwise end the current step; Step 3.

5. Take the next storage instruction group from the storage instruction group queue store_group_list and use it as the new current storage instruction group store_group, and jump to execute step 3.

2.

5. The superword-level automatic vectorization method for variable-length vector architecture according to claim 4, characterized in that: Step 3.2 includes: Step 3.2.

1. Call create_slp_tree with the storage instruction group store_group as parameter to create an SLP tree root; Step 3.2.

2. Determine whether the statement in the storage instruction group store_group is a constant storage statement. If not, continue to execute step 3.2.

3. Otherwise, jump to step 3.2.9 for execution; Step 3.2.

3. Get all operands ops of the storage instruction group; Step 3.2.

4. Take the first set of operands from all the operands ops obtained and use them as the current operand op; Step 3.2.

5. Search for the definition statement group def_stmts of the current operand op upward along the define-use chain; Step 3.2.

6. Call recursively_build_slp_tree with the SLP tree root and statement group def_stmts as parameters to recursively construct the SLP tree; Step 3.2.

7. Determine whether all operands ops have been processed. If not, continue to execute step 3.2.

8. Otherwise, jump to execute step 3.2.

9. Step 3.2.

8. Get the next set of operands from all operands ops and use them as the current operand op, then jump to step 3.2.5; Step 3.2.

9. Create a new SLP graph instance; Step 3.2.

10. Assign the SLP tree root to the instance root, i.e. instance.root = root; Step 3.2.

11. Determine whether the size of the storage instruction group store_group is less than nunits. If so, continue to execute step 3.2.

12. Otherwise, jump to execute step 3.2.14, where nunits is the number of elements allowed to be stored in the SVE vector register; Step 3.2.

12. Create a mask mask according to the size of the storage instruction group store_group and nunits to use the predicate register provided by the scalable vector extension architecture as a mask; Step 3.2.

13. Set the assertion register control bit to enable, that is, set instance.partial = YES, instance.mask = mask, and jump to step 3.2.15; Step 3.2.

14. Set the assertion register control bit to disabled, i.e., set instance.partial = NO, instance.mask = NULL; Step 3.2.

15. Return the SLP graph instance.

6. The superword-level automatic vectorization method for variable-length vector architecture according to claim 5, characterized in that: The specific steps of calling create_slp_tree in step 3.2.1 include: Step 3.2.1.1 determines whether the scalar statements in the parameter statement group stmts are isomorphic. If yes, continue to execute step 3.2.1.

2. Otherwise, return NULL. Step 3.2.1.

2. Create a new SLP tree tree; Step 3.2.1.

3. Construct the corresponding vector statement vec_stmts according to the scalar statement in the stmts group; Step 3.2.1.

4. Set the scalar statement of SLP tree tree.scalar_stmts = stmts; Step 3.2.1.

5. Set the vector statement of SLP tree tree.vec_stmts = vec_stmts; Step 3.2.1.

6. Return the currently constructed SLP tree tree and exit the current step.

7. The superword-level automatic vectorization method for variable-length vector architecture according to claim 5, characterized in that: The specific execution steps of calling recursively_build_slp_tree in step 3.2.6 include: Step 3.2.6.

1. Call create_slp_tree with the parameter statement group stmts as parameter to create a new SLP tree child; Step 3.2.6.

2. Add the SLP tree child to the child nodes of the parameter SLP tree tree; Step 3.2.6.

3. Determine whether the parameter statement group stmts is a constant assignment or read statement. If not, continue to execute step 3.2.6.

4. Otherwise, jump to execute step 3.2.6.10; Step 3.2.6.

4. Get all operands ops of the scalar statement group; Step 3.2.6.

5. Get the first operand of all operands ops of the scalar statement group and use it as the current operand op; Step 3.2.6.

6. Search for the definition statement group def_stmts of the current operand op upward along the define-use chain; Step 3.2.6.

7. Call recursively_build_slp_tree with SLP tree child and statement group def_stmts as parameters to recursively construct the SLP tree; Step 3.2.6.

8. Determine whether all operands in all operands ops of the scalar statement group have been processed. If not, continue to execute step 3.2.6.9, otherwise exit the current step; Step 3.2.6.

9. Get the next set of operands from all operands ops of the scalar statement group and use them as the current operand op, and jump to execute step 3.2.6.

6.

8. The superword-level automatic vectorization method for variable-length vector architecture according to any one of claims 1 to 7, characterized in that: Step 4 includes: Step 4.

1. Take out the first SLP graph instance in the SLP graph queue instance; Step 4.

2. Calculate the scalar version code cost scalar_cost and the vector version code cost vector_cost respectively; Step 4.

3. Determine whether the vector version code cost vector_cost is less than the scalar version code cost scalar_cost. If so, continue to execute step 4.4; otherwise, jump to execute step 4.

5. Step 4.

4. Replace scalar code with vector code; Step 4.

5. Determine whether all SLP graphs in the SLP graph queue instance have been processed. If not, continue to step 4.6, otherwise exit the current step; Step 4.

6. Take out the next SLP graph instance in the SLP graph queue instance and jump to execute step 4.

2.

9. A computer-readable storage medium storing a computer program, characterized in that: When the computer program is executed by a processor, the method according to any one of claims 1 to 8 is implemented.

10. A computer program product, characterized in that The computer program product comprises computer instructions, and the computer instructions are executed by a processor to enable a computer device to implement the method according to any one of claims 1 to 8.