Tool/software: TI C/C++ Compiler
Hello,
I have problem with compiler optimization in FREErtos project. Maybe I try to explain that on example.
FREE rtos uses the following macro:
#define listGET_OWNER_OF_NEXT_ENTRY( pxTCB, pxList ) \ { \ List_t * const pxConstList = ( pxList ); \ /* Increment the index to the next item and return the item, ensuring */ \ /* we don't return the marker used at the end of the list. */ \ ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) ) \ { \ ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext; \ } \ ( pxTCB ) = ( pxConstList )->pxIndex->pvOwner; \ }
First line update ( pxConstList )->pxIndex with new value. Then there is address comparison, and if address are equal ( pxConstList )->pxIndex is updated again, but it should be different value than in first line. Unfortunately compiler used value estimated in first line.
Compilation result:
; pxConstList address is putted into R14
01014c: 00AE 1C00 ADDA #0x01c00,R14
;( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;
;( pxConstList )->pxIndex->pxNext address is putted into R12
010150: 0E3C 0002 MOVA 0x0002(R14),R12
; ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;
010154: 1800 4CDE 0004 0002 MOVX.A 0x00004(R12),0x00002(R14)
; if( ( void * ) ( pxConstList )->pxIndex == ( void * ) &( ( pxConstList )->xListEnd ) )
01015c: 0ECD MOVA R14,R13
01015e: 00AD 0006 ADDA #0x00006,R13
010162: 1800 9DCE 0002 CMPX.A R13,0x00002(R14)
010168: 2004 JNE (0x0172)
; ( pxConstList )->pxIndex = ( pxConstList )->pxIndex->pxNext;
01016a: 1800 4CDE 0004 0002 MOVX.A 0x00004(R12),0x00002(R14)
At this line compiler uses value calculated before pxIndex was updated.
I have prepared example project for this error, so if someone can help me with this, I send this project
Structure definitions (configLIST_VOLATILE macro is set to volatile):
struct xLIST_ITEM { configLIST_VOLATILE TickType_t xItemValue; /*< The value being listed. In most cases this is used to sort the list in descending order. */ struct xLIST_ITEM * configLIST_VOLATILE pxNext; /*< Pointer to the next ListItem_t in the list. */ struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; /*< Pointer to the previous ListItem_t in the list. */ void * pvOwner; /*< Pointer to the object (normally a TCB) that contains the list item. There is therefore a two way link between the object containing the list item and the list item itself. */ void * configLIST_VOLATILE pvContainer; /*< Pointer to the list in which this list item is placed (if any). */ }; typedef struct xLIST_ITEM ListItem_t; /* For some reason lint wants this as two separate definitions. */ struct xMINI_LIST_ITEM { configLIST_VOLATILE TickType_t xItemValue; struct xLIST_ITEM * configLIST_VOLATILE pxNext; struct xLIST_ITEM * configLIST_VOLATILE pxPrevious; }; typedef struct xMINI_LIST_ITEM MiniListItem_t; /* * Definition of the type of queue used by the scheduler. */ typedef struct xLIST { configLIST_VOLATILE UBaseType_t uxNumberOfItems; ListItem_t * configLIST_VOLATILE pxIndex; /*< Used to walk through the list. Points to the last item returned by a call to listGET_OWNER_OF_NEXT_ENTRY (). */ MiniListItem_t xListEnd; /*< List item that contains the maximum possible item value meaning it is always at the end of the list and is therefore used as a marker. */ } List_t; #endif /* LIST_H */
Best regards,