This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Compiler/TMS320F28335: Const data is optimised out in function which doesn't call other functions (optimiisation level 3 and 4)

Part Number: TMS320F28335

Tool/software: TI C/C++ Compiler

There is a bug in the TI compiler in at least versions C2000 6.2.11 and 18.9.0.STS.  If a function has constant local data which is initialised with the address of an external variable or function, and the function doesn't call another external function, and the optimisation level is set to 3 or 4 then constant local data is not initialised.  See example below.  I have listed the source code which has a commented out call to function CONSOLE_Init.  If this is uncommented then the constant local data is initialised correctly.  See generated machine code.  Note that the original intention of the code was to copy a locally defined interrupt vector table to the TMS320F28335's PIE vector memory at 0xD00, which is why the copying code has a loop that copies 128 uint32_t's.  I know that code isn't technically correct as the source structure only has one uint32_t (it has been reduced to one entry to simplify the code).

Example Source Code

extern uint32_t myvar1;

extern void CONSOLE_Init();

struct MyStruct_t {
    uint32_t* pValue;
};


void MyFunc(void)
{
    // Structure containing the vector table which we want to use.
    const struct MyStruct_t MyData =
    {
        &myvar1,
    };

    uint16_t Index;

    const uint32_t* p_Source = (const uint32_t*)&MyData;

    uint32_t* p_Dest   = (uint32_t*)0xD00;    //&PieVectTable;

    EALLOW;

    for (Index = 0u; Index < 128u; Index++)
    {
        *p_Dest = *p_Source;
        p_Dest++;
        p_Source++;
    }

    EDIS;

    //CONSOLE_Init();
}

Generated Machine Instructions (when CONSOLE_Init() is not called)

        MyFunc():
301afb:   FE02        ADDB         SP, #2
301afc:   7622        EALLOW       
607         const uint32_t* p_Source = (const uint32_t*)&MyData;
301afd:   5CAD        MOVZ         AR4, @SP
301afe:   DC82        SUBB         XAR4, #2
301aff:   5CA4        MOVZ         AR4, @AR4
301b00:   BE7F        MOVB         XAR6, #0x7f
609         uint32_t* p_Dest   = (uint32_t*)0xD00;    //&PieVectTable;
301b01:   8F400D00    MOVL         XAR5, #0x000d00
615             *p_Dest = *p_Source;
        C$L4:
301b03:   0684        MOVL         ACC, *XAR4++
301b04:   1E85        MOVL         *XAR5++, ACC
613         for (Index = 0u; Index < 128u; Index++)
301b05:   000EFFFE    BANZ         65534,AR6--
301b07:   761A        EDIS         
301b08:   FE82        SUBB         SP, #2
301b09:   FF69        SPM          #0
301b0a:   0006        LRETR 

Generated Machine Instructions (when CONSOLE_Init() is called):

        MyFunc():
3025d5:   FE02        ADDB         SP, #2
600         const struct MyStruct_t MyData =
3025d6:   8F00B1AE    MOVL         XAR4, #0x00b1ae
3025d8:   A842        MOVL         *-SP[2], XAR4
3025d9:   7622        EALLOW       
607         const uint32_t* p_Source = (const uint32_t*)&MyData;
3025da:   5CAD        MOVZ         AR4, @SP
3025db:   DC82        SUBB         XAR4, #2
3025dc:   5CA4        MOVZ         AR4, @AR4
3025dd:   BE7F        MOVB         XAR6, #0x7f
609         uint32_t* p_Dest   = (uint32_t*)0xD00;    //&PieVectTable;
3025de:   8F400D00    MOVL         XAR5, #0x000d00
615             *p_Dest = *p_Source;
        C$L4:
3025e0:   0684        MOVL         ACC, *XAR4++
3025e1:   1E85        MOVL         *XAR5++, ACC
613         for (Index = 0u; Index < 128u; Index++)
3025e2:   000EFFFE    BANZ         65534,AR6--
3025e4:   761A        EDIS         
3025e5:   FF69        SPM          #0
622         CONSOLE_Init();
3025e6:   7670177A    LCR          CONSOLE_Init
3025e8:   FE82        SUBB         SP, #2
3025e9:   0006        LRETR 

  • Thank you for submitting the problem source code.  Unfortunately, I am unable to reproduce the same assembly code.  One possible reason: I had to guess at which compiler build options to use.  So that I can reproduce the problem, please submit a test case as described in the article How to Submit a Compiler Test Case.

    Thanks and regards,

    -George

  • Hi George

    I will try to do that, but in the mean time here is the compiler version and options:

    C:/ti/ccsv7/tools/compiler/ti-cgt-c2000_18.9.0.STS/bin/cl2000 -v28 -ml -mt --float_support=fpu32 -O4 -g --gcc --diag_warning=225 --diag_wrap=off --display_error_number --abi=coffabi --preproc_with_compile

  • Here's stripped down source code:

    typedef unsigned int uint32_t;
    typedef unsigned short uint16_t;

    extern uint32_t myvar1;
    extern void CONSOLE_Init();

    struct MyStruct_t {
    uint32_t* pValue;
    };

    void MyFunc(void)
    {
    // Structure containing the vector table which we want to use.
    const struct MyStruct_t MyData =
    {
    &myvar1,
    };

    uint16_t Index;

    const uint32_t* p_Source = (const uint32_t*)&MyData;

    uint32_t* p_Dest = (uint32_t*)0xD00; //&PieVectTable;

    for (Index = 0u; Index < 128u; Index++)
    {
    *p_Dest = *p_Source;
    p_Dest++;
    p_Source++;
    }

    //CONSOLE_Init();
    }

    This is the command line to compile it:

    C:/ti/ccsv7/tools/compiler/ti-cgt-c2000_18.9.0.STS/bin/cl2000 -v28 -ml -mt --float_support=fpu32 -O4 -g --gcc --diag_warning=225 --diag_wrap=off --display_error_number --abi=coffabi --preproc_with_compile .\Example.c

    This is the generated machine code without the call to CONSOLE_Init:

    Disassembly of .\Example.obj:

    TEXT Section .text (Little Endian), 0xa words at 0x00000000
    00000000 _MyFunc:
    00000000 fe02 ADDB SP, #2
    00000001 5cad MOVZ AR4, SP
    00000002 dc82 SUBB XAR4, #2
    00000003 80a4 MOVZ AR7, AR4
    00000004 8f00 MOVL XAR4, #0x000d00
    00000005 0d00
    00000006 f67f RPT #127
    00000007 2484 ||PREAD *XAR4++, *XAR7
    00000008 fe82 SUBB SP, #2
    00000009 0006 LRETR

    This is the generated machine code with the call to CONSOLE_Init:

    Disassembly of .\Example.obj:

    TEXT Section .text (Little Endian), 0xf words at 0x00000000
    00000000 _MyFunc:
    00000000 fe02 ADDB SP, #2
    00000001 5cad MOVZ AR4, SP
    00000002 8f40 MOVL XAR5, #0x000000
    00000003 0000
    00000004 a042 MOVL *-SP[2], XAR5
    00000005 dc82 SUBB XAR4, #2
    00000006 80a4 MOVZ AR7, AR4
    00000007 8f00 MOVL XAR4, #0x000d00
    00000008 0d00
    00000009 f67f RPT #127
    0000000a 2484 ||PREAD *XAR4++, *XAR7
    0000000b 7640 LCR 0x000000
    0000000c 0000
    0000000d fe82 SUBB SP, #2
    0000000e 0006 LRETR

    It can be seen that in this code the local variable is initialised with the line:

    00000002 8f40 MOVL XAR5, #0x000000
  • I'm sorry I didn't notice this sooner.

    It appears that, in your attempt to create a cut-down test case from your original code, you have written something which, when executed, makes little sense.  The pointer p_Source points to the structure MyData.  That structure is small.  It only contains 1 pointer.  So it is 2 words long (32-bits on C28x).  Yet the for loop copies, starting at the address of the MyData structure, many more than 2 words.  After the first loop iteration, it is reading memory locations which are not valid.

    I suspect you need to fill out the MyData structure with more fields from your original code.

    Thanks and regards,

    -George

  • Hi George

    I've modified the loop counter to 1, I know it's a bit unrealistic, but it demonstrates the problem.  With the modified code the compiler generates the following code:

    EXT Section .text (Little Endian), 0x5 words at 0x00000000
    0000000        _MyFunc:
    0000000   fe02   ADDB         SP, #2
    0000001   f442   MOV          *(0:0x0d00), *-SP[2]
    0000002   0d00
    0000003   fe82   SUBB         SP, #2
    0000004   0006   LRETR

    You can see that it doesn't initialise the structure.  If the CONSOLE_Init function is called, then it does initialise the structure:

    EXT Section .text (Little Endian), 0xa words at 0x00000000
    0000000        _MyFunc:
    0000000   fe02   ADDB         SP, #2
    0000001   8f00   MOVL         XAR4, #0x000000
    0000002   0000
    0000003   a842   MOVL         *-SP[2], XAR4
    0000004   f442   MOV          *(0:0x0d00), *-SP[2]
    0000005   0d00
    0000006   7640   LCR          0x000000
    0000007   0000
    0000008   fe82   SUBB         SP, #2
    0000009   0006   LRETR

  • Thank you for your patience, and for submitting the test case more than once.  I can reproduce the problem.  I filed CODEGEN-5527 in the SDOWP system to have this investigated.  You are welcome to follow it with the SDOWP link below in my signature.

    Thanks and regards,

    -George

  • Thanks for looking into this.

    Kind regards

    Chris