Readme for C7000 Code Generation Tools v.6.2.1

Table of Contents


0 Introduction to the C7000 Code Generation Tools v6.2.x LTS


This C7000 compiler release is a “Long-Term Support” (LTS) release.

Please note that 6.2.1.LTS is the first broadly available version of the C7000 6.x compilers. Versions 6.0.0 through 6.2.0 are not broadly available.

This release supports the C7100, C7120, C7504, C7524, C7604 ISA cores.

To compile code for the C7100 core, use the compiler command-line option -mv7100 or equivalently, --silicon_version=7100.

To compile code for the C7120 core, use the compiler command-line option -mv7120 or equivalently, --silicon_version=7120.

To compile code for the C7504 core, use the compiler command-line option -mv7504 or equivalently, --silicon_version=7504.

To compile code for the C7524 core, use the compiler command-line option -mv7524 or equivalently, --silicon_version=7524.

To compile code for the C7604 core, use the compiler command-line option -mv7604 or equivalently, --silicon_version=7604.

For definitions and explanations of STS, LTS, and the versioning number scheme, please see SDTO Compiler Version Numbers


1 Documentation


The following documents provide information on how to use, program, and migrate to the C7000 CPU.

C7000 C/C++ Optimizing Compiler Users Guide (SPRUIG8***.PDF)

C7000 Optimization Guide

C6000-to-C7000 Migration User’s Guide (SPRUIG5***.PDF)

C7000 Host Emulation User’s Guide (SPRUIG6***.PDF)


2 TI E2E Community - Where to get help


Post compiler related questions to the TI E2E design community forum and select the TI device being used.

If submitting a defect report, please attach a scaled-down test case with command-line options and the compiler version number to allow us to reproduce the issue easily.

The following is the top-level webpage for all of TI’s Code Generation Tools.


3 Defect Tracking Database


Compiler defect reports can be tracked at the Development Tools bug database, SIR. SIR is a JIRA-based view into all public tools defects.

A my.ti.com account is required to access this page. To find an issue in SIR, enter your defect id in the top right search box once logged in. Alternatively from the top red navigation bar, select “Issues” then “Search for Issues”.


4 Vector typename conflicts


Version 5.0.0.LTS adds 1024 bit vector types: char128, short64, int32, and their unsigned variants, along with float32, cchar64, cshort32 and cint16. Most of these will probably not lead to typename conflicts aside from int32. Some projects may fail to compile due to typename conflicts between the new int32 built-in type and a possibly project-defined int32. The recommended solution to such a problem is to add the --vectypes=off command-line flag to cl7x. This will cause the built-in vector types to be accessible only by __char128 or __int32, rather than char128 or int32.

Additionally, 5.0.0.LTS adds the equivalent of --vectypes=off to host emulation. When TI_VECTYPES_OFF is defined, such as with g++ -DTI_VECTYPES_OFF, vector types will only be accessible by __int32 or similar, rather than int32.


5 Moving data between vector predicate to/from general purpose registers


The original intrinsics for moving data between vector predicate registers and general purpose registers were vpred_t _mvrp(long) and long _mvpb(vpred). These intrinsics (and their variants) are now deprecated.

__create_boolN(ulong) and __create_scalar(vpred) are also now deprecated.

As of version 5.0.0, new APIs will use an unsigned char vector type rather than a long. This vector type must have the same number of bits as the vector predicate register for the target in question. That is, uchar4 for C7504; uchar8 for C7100, C7120; etc.

#if __C7X_VEC_SIZE_BITS__ == 256
__uchar4 __vpred_to_uchar_vec(__vpred);
#elif __C7X_VEC_SIZE_BITS__ == 512
__uchar8 __vpred_to_uchar_vec(__vpred);
#elif __C7X_VEC_SIZE_BITS__ == 1024
__uchar16 __vpred_to_uchar_vec(__vpred);
#endif

#if __C7X_VEC_SIZE_BITS__ == 256
__vpred __uchar_vec_to_vpred(__uchar4);
#elif __C7X_VEC_SIZE_BITS__ == 512
__vpred __uchar_vec_to_vpred(__uchar8);
#elif __C7X_VEC_SIZE_BITS__ == 1024
__vpred __uchar_vec_to_vpred(__uchar16);
#endif

Backwards compatibility

The behaviour of the old intrinsics can still be achieved using the new intrinsics, but one should strongly reconsider refactoring one’s code to avoid using these. Boolean vectors should be used for high-level applications, and the vpred_t type should be used for low-level applications where predicate bit manipulation is needed. Boolean vectors should be initialized using standard vector initialization syntax, not by using __create_boolN(ulong). The vpred_t type should be initialized by using __uchar_vec_to_vpred(), not by using _mvrp().

For 512-bit vector architectures

Old Intrinsic Replacement
__mvrp(ulong x) __uchar_vec_to_vpred(__as_uchar8((x)))
__mvpb(vpred x) __as_ulong(__vpred_to_uchar_vec((x)))
__create_bool2(ulong x) __create_bool2(__uchar_vec_to_vpred(__as_uchar8((x))))
__create_bool4(ulong x) __create_bool4(__uchar_vec_to_vpred(__as_uchar8((x))))
__create_bool8(ulong x) __create_bool8(__uchar_vec_to_vpred(__as_uchar8((x))))
__create_bool16(ulong x) __create_bool16(__uchar_vec_to_vpred(__as_uchar8((x))))
__create_bool32(ulong x) __create_bool32(__uchar_vec_to_vpred(__as_uchar8((x))))
__create_bool64(ulong x) __create_bool64(__uchar_vec_to_vpred(__as_uchar8((x))))
__create_scalar(bool_vec x) __as_ulong(__vpred_to_uchar_vec(__create_vpred(x)))

For 256-bit vector architectures

Old Intrinsic Replacement
__mvrp(ulong x) __uchar_vec_to_vpred(__as_uchar4((__uint) (x)))
__mvpb(vpred x) ((__ulong) __as_uint(__vpred_to_uchar_vec((x))))
__create_bool2(ulong x) __create_bool2(__uchar_vec_to_vpred(__as_uchar4((__uint) (x))))
__create_bool4(ulong x) __create_bool4(__uchar_vec_to_vpred(__as_uchar4((__uint) (x))))
__create_bool8(ulong x) __create_bool8(__uchar_vec_to_vpred(__as_uchar4((__uint) (x))))
__create_bool16(ulong x) __create_bool16(__uchar_vec_to_vpred(__as_uchar4((__uint) (x))))
__create_bool32(ulong x) __create_bool32(__uchar_vec_to_vpred(__as_uchar4((__uint) (x))))
__create_scalar(bool_vec x) ((__ulong) __as_uint(__vpred_to_uchar_vec(__create_vpred(x))))

6 New performance optimization that may affect code size


The 5.0.0 version of the C7000 compiler adds an optimization that improves performance in some cases, but may increase code size.

This optimization, called “run-time alias disambiguation,” attempts to significantly improve the performance of certain loops when the restrict keyword is not used. However, it may result in duplicated loops, which will increase code size.

Users that observe undesired code size growth may opt to use -mf3 or lower on those files that are affected. Run-time alias disambiguation is not performed by the compiler at –opt_for_speed=3 or lower. Also, users may want to investigate the possibility of using the restrict keyword on the pointers that are used in the affected loops, in order to prevent the compiler from needing to perform run-time alias disambiguation. Refer to the C7000 Optimization Guide for more information on the use of the –opt_for_speed/-mf option to control the code-size and performance tradeoff on C7000.

C7000 Optimization Guide


7 Permute behavior


As of version 5.0.0, permute intrinsics in c7x.h, such as __permute() or __permute_even_even_int(), will only specify/guarantee behavior for input index values that are in range for the input data vector. For example, an index of 63 is specified on C7100, but an index of 64 is not. If the out-of-range behavior of an underlying instruction is needed, such as VPERM or VPERMEEW, then the corresponding direct intrinsic should be used from c7x_direct.h. For example, __vperm_yvv() or __vpermeew_yvvv().


8 Atomic API removal


The following APIs have been removed from all C7000 versions except C7100 and C7120:

int  __atomic_swap(int*, int, int);            /* ASW */
long __atomic_swap(long*, long, long);         /* ASD */
int  __atomic_compare_swap(int*, int, int);    /* CASW */
long __atomic_compare_swap(long*, long, long); /* CASD */

The corresponding atomic instructions require cache coherency, which is only available on C7100 and C7120.


9 Machine learning floating-point types fp8_e4m3_ and _bf16_


Version 6.1.0.STS adds additional built-in datatypes: fp8_e4m3_ and bf16_ (trailing underscore optional). fp8_e4m3_ represents an 8-bit special floating-point number format with 1 sign bit, 4 bits of exponent and 3 bits of mantissa (plus the hidden implicit ‘1’ mantissa bit). bf16_ represents a 16-bit special floating-point number 1 sign bit, 8 bits of exponent and 7 bits of mantissa (plus the hidden implicit ‘1’ mantissa bit). Neither of these follow the IEEE-754 standard. Note that the compiler does not support initializing values with these types using literals. It is recommended to use __as_<type>() syntax to initialize them (Example: bf16 x = __as_bf16((uint16_t) 0xABCD);). Remember that __as_<type>() only reinterprets the bits. it does not perform numerical conversions. Only one native C operator is supported for these types: the assignment operator (‘=’). To do arithmetic or numerical conversions, use intrinsics.

Vector forms are also supported for fp8_e4m3_ and bf16_ (underscore required). They follow the syntax: fp8_e4m3_N and bf16_N respectively, where N is the number of elements in the vector. The largest supported fp8_e4m3_ vector is fp8_e4m3_128. The largest supported bf16_ vector is bf16_64.

The C7604 target introduces support of all four rounding modes for bf16. Previous C75x targets would unconditionally round to zero.

Although it is unlikely that typename conflicts are introduced with this type, it should be noted that the conflicts can be avoided by adding the --vectypes=off command-line flag to the cl7x invocation.

For more information on the fp8_e4m3, read the specification.


10 MMA enum changes


The MMA enum value __MMA_X_CONFIG_CTYPE_F32, representing a 32-bit floating-point CTYPE, is deprecated. Use __MMA_X_CONFIG_CTYPE_FLOAT32 instead.


11 Boolean vector operators


This release changes some syntax regarding boolean vectors.

The following operators have new syntax rules:

In order to compile under the old syntax rules, the --deprecated_logical_vector_semantics command line flag can be used. For host emulation, define the TI_DEPRECATED_LOGICAL_VECTOR_SEMANTICS preprocessor flag instead.


12 Performance changes due to improved alias analysis


Loops that access both struct fields and arrays or pointers may see slower performance. This is due to a correctness fix in the optimizer’s alias analysis where a read could be incorrectly scheduled before a write to overlapping memory.

How to recover performance:

Add the restrict keyword to pointer parameters to tell the compiler they do not point to overlapping memory. For example:

void func(int * restrict input, int * restrict output, int n) {
    // ...
}

Refer to the C7000 Optimization Guide for more information on using restrict.

C7000 Optimization Guide


13 OptiShare: multicore memory sharing


OptiShare reduces memory footprint in multicore applications by allowing multiple C7x cores to share identical code and data sections. Shared sections are collected into a Static Shared Object (SSO), a special ELF output file. Each core application links against the SSO so that shared sections reside in memory once and are referenced by all cores.

Step 1: compile and link each application with XML link info enabled

Use --gen_func_subsections to emit each function and data object into its own subsection, which is required for per-symbol sharing analysis. Use --gen_xml_func_hash and --xml_link_info to produce the XML files that opti-share.js will analyze:

cl7x app1.cpp -O2 --gen_func_subsections -z \
    --gen_xml_func_hash --xml_link_info app1.xml app1.cmd -o app1.out
cl7x app2.cpp -O2 --gen_func_subsections -z \
    --gen_xml_func_hash --xml_link_info app2.xml app2.cmd -o app2.out

Step 2: run opti-share.js to generate the SSO linker command file

The opti-share.js script analyzes the XML files, identifies sections that are identical across all inputs, and generates a linker command file for building the SSO. A memory specification file for your device is provided by the TI SDK:

node opti-share/opti-share.js -o sso.cmd \
    --mem_spec <sdk>/opti-share/mem_spec.json app1.xml app2.xml

Step 3: link the SSO

cl7x -z sso.cmd -o sso.out

Step 4: relink each application against the SSO

Use --import_sso to resolve shared symbols from the SSO. The original linker command files from step 1 are reused:

cl7x app1.o -z --import_sso sso.out app1.cmd -o app1_shared.out
cl7x app2.o -z --import_sso sso.out app2.cmd -o app2_shared.out

After relinking, shared function symbols in the application become absolute symbols set to the SSO load address. Runtime initialization of shared read/write data regions is handled by the TI SDK for your device.

The opti-share.js script requires the node JavaScript interpreter, which is bundled with CCS and SysConfig installations. Pass --nobss and --nodata to opti-share.js to disable read/write section sharing.

do_not_share attribute

To exclude a specific function or variable from OptiShare, apply the do_not_share attribute. The symbol will never be placed in the SSO even if its content is identical across all input executables:

__attribute__((do_not_share)) void sensitive_func(void) { ... }
__attribute__((do_not_share)) int sensitive_var;

14 Silicon errata i2528 workaround


Silicon errata i2528 affects C7100, C7120, C7504, and C7524. The defect causes the MMU to misclassify the load/store category of an instruction when checking memory permissions. The two problem sequences are:

  1. A load on a D unit followed by a store on the same D unit in the next cycle. The MMU may check the load as a store, potentially flagging a valid access to a read-only page.
  2. A store on a D unit followed by a non-store (including loads and arithmetic) on the same D unit in the next cycle. The MMU may check the store as a non-store, potentially allowing an illegal store to a read-only page.

The compiler avoids these sequences by default for potentially affected targets.

If no memory pages are configured to be read-only and the workaround is therefore not needed, it can be disabled with --silicon_errata_i2528=off.


15 Silicon errata i2532 workaround


Silicon errata i2532 affects C7100, C7120, C7504, C7524, and C7604. In very rare cases, for those targets, an instruction-predicated SAOPEN may receive a stale instruction predicate value during execution.

The compiler works around this issue by disallowing the use of instruction predicates with SAOPEN. The option --silicon_errata_i2532 is on by default for the affected targets.

This option typically has no performance impact for the vast majority of code. Worst case observed performance impact only reached 2%. If the workaround is not needed, it can be disabled with --silicon_errata_i2532=off.


16 Errata i2505 host emulation warning


On C7504 and C7524, opening two streaming engines simultaneously in transpose mode may result in a system hang when both SEs are reading from DDR while interrupts are being processed. Consult the errata document for your specific silicon to determine whether your program may be affected, and follow the actions listed there.

To help catch this condition during development, host emulation now emits a warning to stderr when SE0 and SE1 are both open in transpose mode at the same time. To suppress this warning, define TI_I2505_WARNING_OFF, such as with g++ -DTI_I2505_WARNING_OFF.


17 Resolved defects


Resolved defects in v6.2.1:

ID Summary
CODEGEN-16376 Compiler may incorrectly vectorize reduction with peeled loop and VSEL instruction
CODEGEN-16050 Compiler may generate invalid assembly for load or store instruction in a loop
CODEGEN-15934 Compiler may crash on an intrinsic call that is given a function call for its argument.
CODEGEN-15637 Linker ignores use of the option –honor_cmdfile_order
CODEGEN-15553 cg7x crash: silicon errata i2117 workaround
CODEGEN-15522 Incorrect code generated for restrict-qualified min/max reductions at -o2+
CODEGEN-15488 QKIT: setting COVFILELIST in CCS IDE for coverage compare needs workaround
CODEGEN-15223 Using –opt_level=0 with intrinsics like __complex_multiply generates incorrect code
CODEGEN-15129 Remove references to the section name .TI.crctab from the C7000 manuals
CODEGEN-15022 Write to a volatile vector may be discarded
CODEGEN-15018 Linker crashes while processing local common symbols
CODEGEN-14903 parser converts gnu statement expressions in for loops to incorrect loop increment that occurs too early in loop code
CODEGEN-14839 Under some conditions, including use of –opt_level=2, C++ code that throws an exception runs away
CODEGEN-14555 C7000 Host Emulation SE load of scalar floating point has incorrect value
CODEGEN-14463 Improve compiler documentation for -ft
CODEGEN-14324 Compiler fails with INTERNAL ERROR: opt2000 experienced a segmentation fault
CODEGEN-13914 Assignment to boolean vector elements may not be applied before conversion to vpred
CODEGEN-13615 Incorrect resource partition table in software pipeline information comment
CODEGEN-13506 Compiler may schedule SESUSPEND and SASUSPEND incorrectly
CODEGEN-13482 Apply restrict to pointer to cfloat causes compiler to fail with INTERNAL ERROR: no match for MCALL
CODEGEN-13324 symbol table entry for the compiled file should indicate source file name but instead has either a temp file name or the file's assembly file name
CODEGEN-12762 assignment to a bit field mistakenly overwrites entire bit field structure
CODEGEN-12546 Atomic APIs should only be available on C7100 and C7120
CODEGEN-12112 attribute constructor does not support optional priority input but silently accepts it
CODEGEN-11940 internal error generated for function with both vector code and struct param passed by value
CODEGEN-11521 Improve compiler documentation for -ft
CODEGEN-10306 For EABI cinit copy “compression”, the linker incorrectly sets the number of bytes to copy for smaller copy initialization sizes
CODEGEN-9407 Flexible array of structs does not correctly initialize last element with implicitly initialized struct members.
CODEGEN-4296 Undefined symbol isblank with -g or -ooff

18 Known defects


The up-to-date known defects in v6.2.1 can be found here (dynamically generated):

Known defects in v6.2.1

End Of File