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
- 1 Documentation
- 2 TI E2E Community - Where to get help
- 3 Defect Tracking Database
- 4 Vector typename conflicts
- 5 Moving data between vector predicate to/from general purpose registers
- 6 New performance optimization that may affect code size
- 7 Permute behavior
- 8 Atomic API removal
- 9 Machine learning floating-point types
fp8_e4m3_and_bf16_ - 10 MMA enum changes
- 11 Boolean vector operators
- 12 Performance changes due to improved alias analysis
- 13 OptiShare: multicore memory sharing
- 14 Silicon errata i2528 workaround
- 15 Silicon errata i2532 workaround
- 16 Errata i2505 host emulation warning
- 17 Resolved defects
- 18 Known defects
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)
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);
#endifBackwards 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.
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:
- Bitwise operators (
&,|,^,&=,|=,^=) now operate on bool vectors. - Logical operators (
&&,||,!) now only accept bool vectors as arguments. - Relational operators (
==,!=,>,<,<=,>=) accept bool vectors and return only bool vectors. - The ternary operator now only allows a boolean vector as its first argument (when that argument is a vector), and can now accept bool vectors as its second and third arguments.
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.
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:
- 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.
- 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):
End Of File