Rate This Document
Findability
Accuracy
Completeness
Readability

Tiancheng Code Optimizer

The Tiancheng Code Optimizer is a static code analysis tool built on Clang/LLVM, focusing on vectorized optimization of C/C++ code. The tool can automatically identify vectorizable loop patterns, detect factors that hinder vectorization, and generate vectorized code for automatic rewriting. It helps developers quickly convert scalar code into efficient SIMD vectorized code and fully leverage the performance benefits of NEON/SVE instruction sets.

Prerequisites

  • The Tiancheng Code Optimizer has been installed. See Installing a Compressed Package (.tar.gz).
  • The tool is contained in an independent package (tiancheng-xxx-Linux-Kunpeng.tar.gz). Extract the package and switch to the tool directory.

Command Function

Automatically identifies vectorizable loop patterns, detects factors that hinder vectorization, and generates vectorized code for automatic rewriting.

Syntax

./tiancheng -h

Parameter Description

Table 1 Parameter description

Parameter

Option

Description

-h/--help

-

Obtains help information. This parameter is optional.

-i

-

Specifies the input C/C++ source file. This parameter is mandatory.

-o

-

Specifies the directory and name of the output JSON report file. The file name extension is .json. This parameter is mandatory.

-r

-

Specifies the root path to the input C/C++ source file project. This path is used for header file searches to prevent missing headers. This parameter is optional.

-v

-

Enables detailed output mode to display additional debugging information and the analysis process. This parameter is optional. By default, this function is disabled.

--simd-target

neon/sve

Specifies the instruction set to convert to. The value is NEON or SVE and defaults to NEON. This parameter is optional.

  • NEON: SIMD instruction set in the Arm architecture. It uses 128-bit fixed-width vector registers for parallel data processing and supports 8-, 16-, 32-, and 64-bit integer operations, as well as single-precision floating-point operations. It is supported on servers based on the Kunpeng 920 series and Kunpeng 950 processors.
  • SVE: It is a vector-length-agnostic SIMD instruction set that allows the same code to automatically achieve optimal performance on Arm processors with different vector widths. It is supported on some of servers based on the new Kunpeng 920 models and Kunpeng 950 processors.

--enable-ifstmt-scan

-

Enables the scanning and analysis of if statements. This parameter is optional.

--version

-

Displays the tool version. This parameter is optional.

Example

  1. Run the following command to view the functions supported by the Tiancheng Code Optimizer:
    ./tiancheng -h
    Command output:
    OVERVIEW: ARM Intrinsics Analyzer
    USAGE: tiancheng [options]
    
    OPTIONS:
      -h/--help                  Display available options
      -i <filename>              Specify input C/C++ source file
      -o <filename>              Specify output report file
      -r <pathname>              Inputfile root path
      -v                         Enable verbose output
      --simd-target=<value>      Convert simd type selection
        =neon                      Convert to ARM NEON intrinsics
        =sve                       Convert to ARM SVE intrinsics
      --enable-ifstmt-scan       Enable scanning of if statements
      --version                  Display the version of this program
  2. Scan the source file to generate an analysis report.
    ./tiancheng -i /home/demo/input.cpp -o /home/demo/output.json -r /home/demo/code_project

    Scan the input.cpp file in the /home/demo/ directory. A JSON report file named output.json is generated in the /home/demo/ directory. If the source file belongs to a project, you can use the -r parameter to specify the project's root directory to prevent missing header files.

    Command output:

    Analyzing file: /home/demo/input.cpp
    Output will be saved to: /home/demo/output.json
    Start to recognize process.
    Start to recognize file: /home/demo/input.cpp
    Start to scan code.
    In file included from /home/demo/input.cpp:5:
    In file included from /usr/lib/gcc/aarch64-linux-gnu/10.3.1/../../../../include/c++/10.3.1/iostream:39:
    In file included from /usr/lib/gcc/aarch64-linux-gnu/10.3.1/../../../../include/c++/10.3.1/ostream:38:
    In file included from /usr/lib/gcc/aarch64-linux-gnu/10.3.1/../../../../include/c++/10.3.1/ios:38:
    In file included from /usr/lib/gcc/aarch64-linux-gnu/10.3.1/../../../../include/c++/10.3.1/iosfwd:40:
    In file included from /usr/lib/gcc/aarch64-linux-gnu/10.3.1/../../../../include/c++/10.3.1/bits/postypes.h:40:
    In file included from /usr/lib/gcc/aarch64-linux-gnu/10.3.1/../../../../include/c++/10.3.1/cwchar:44:
    /usr/include/wchar.h:35:10: warning: 'stddef.h' file not found
       35 | #include <stddef.h>
          |          ^~~~~~~~~~
      [FilterAnchors] Limiting from 22 to 10 anchors
      [CallDepth] Function 'main': original anchors=22, filtered=10 → disabling interprocedural analysis
    Recognized pattern: ForStmt OTHER_PATTERN
    Recognized pattern: ForStmt OTHER_PATTERN
    Recognized pattern: ForStmt OTHER_PATTERN
    1 warning generated.
    End to recognize process.

    The command output shows the code to be modified. Open the JSON report file to view detailed information. If the system displays a message indicating that the header file is not found, rectify the fault following instructions in Header File Not Found During Source File Scan with the Tiancheng Code Optimizer.

  3. Open the generated JSON report file and analyze and confirm the modification points.
    vim /home/demo/output.json

    The JSON file content is as follows:

    {
      "advisor_items": [
        {
          "opt_file": {
            "begin_line": 18,
            "description": "",
            "end_line": 19,
            "fileName": "/home/demo/input.cpp",
            "headerFile": "#include <arm_neon.h>",
            "headerLocBegin": 9,
            "headerLocEnd": 9,
            "sample_code": "    int64_t j = 0;\n    for (; j + 4 < nb; j += 4) {\n        vst1q_f32(dis + j, vaddq_f32(vdupq_n_f32(qNorm), vld1q_f32(bNorms + j)));\n    }\n    for (; j < nb; j++) dis[j] = qNorm + bNorms[j];"
          }
        },
        {
          "opt_file": {
            "begin_line": 25,
            "description": "",
            "end_line": 27,
            "fileName": "/home/demo/input.cpp",
            "headerFile": "#include <arm_neon.h>",
            "headerLocBegin": 9,
            "headerLocEnd": 9,
            "sample_code": "    int64_t j = 0;\n    for (; j + 4 < nb; j += 4) {\n        vst1q_f32(dis + j, vaddq_f32(vdupq_n_f32(qNorm), vld1q_f32(bNorms + j)));\n    }\n    for (; j < nb; j++) {\n        dis[j] = qNorm + bNorms[j];\n    }"
          }
        },
        {
          "opt_file": {
            "begin_line": 48,
            "description": "",
            "end_line": 50,
            "fileName": "/home/demo/input.cpp",
            "headerFile": "#include <arm_neon.h>",
            "headerLocBegin": 9,
            "headerLocEnd": 9,
            "sample_code": "    int64_t j = 0;\n    for (; j + 4 < nb; j += 4) {\n        vst1q_f32(dis + j, vaddq_f32(vld1q_f32(dis + j), vdupq_n_f32(qNorm)));\n    }\n    for (; j < nb; j++) {\n        dis[j] += qNorm;\n    }"
          }
        }
      ],
      "code": 0,
      "recognizedPattern": 3
    }
    Table 2 Field description

    Field

    Description

    advisor_items

    Array of code optimization suggestions. Each item in the array is a code tuning optimization.

    opt_file

    Detailed information about a single optimization suggestion.

    begin_line

    Start line number of the code to be optimized.

    In the example, the start line number is 18.

    description

    Detailed description of the optimization suggestion.

    end_line

    End line number of the code to be optimized.

    In the example, the end line number is 19.

    fileName

    Path to the analyzed source file.

    In the example, the path is /home/demo/input.cpp.

    headerFile

    Header file to be added.

    In the example, #include <arm_neon.h> indicates that the Arm NEON header file must be included in this code snippet to use the NEON instruction set.

    headerLocBegin

    Start line number where the header file will be inserted.

    • If the value is -1, the header file is already included in the code and does not need to be manually added.
    • If the value is a positive integer, it indicates the start line number where the header file will be inserted.

    In the example, the start line number is 9.

    headerLocEnd

    End line number where the header file will be inserted.

    • If the value is -1, the header file is already included in the code and does not need to be manually added.
    • If the value is a positive integer, it indicates the end line number where the header file will be inserted.

    In the example, the end line number is 9.

    sample_code

    Recommended code vectorization sample, which can be directly used to replace the current code.

    The following is an example of optimized code:

        int64_t j = 0;\n    for (; j + 4 < nb; j += 4) {\n        vst1q_f32(dis + j, vaddq_f32(vdupq_n_f32(qNorm), vld1q_f32(bNorms + j)));\n    }\n    for (; j < nb; j++) dis[j] = qNorm + bNorms[j];

    code

    Tool execution status code.

    • The value 0 indicates execution success.
    • A non-zero value indicates an interruption.

    In the example, 0 indicates that the tool is executed successfully.

    recognizedPattern

    Number of code snippets to be optimized.

    In the example, the number is 3.

  4. Rewrite the code based on the JSON report.
    1. View advisor_items, which contains all identified optimization suggestions.
    2. For each optimization suggestion, check the begin_line and end_line fields to determine the code range to be replaced.
    3. Copy the vectorized code from sample_code and replace the code in the source file between begin_line and end_line.
    4. Check the headerLocBegin and headerLocEnd fields.
      • If the value is -1, the header file already exists and does not need to be added.
      • If the value is a positive integer, add the header file declaration in headerFile to the specified location.
    5. Save the modified file to complete the automatic rewrite.