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/TMS320C6727: Support for copy elision/RVO/NRVO in CGT v7.4.24

Part Number: TMS320C6727

Tool/software: TI C/C++ Compiler

Hi all,

I'm struggling to get the C++ compiler in CGT v7.4.24 to trigger any kind of (N)RVO. That is, I expect a function f() returning a local Foo x to allocate x onto the caller's stack frame. But no matter what I do, the resulting assembly for f() always seems to follow the pattern of:

  • Push stack sizeof(Foo)
  • Do work on Foo x via SP+n
  • copy x via memcpy() to A3 from SP+n for sizeof(Foo)
  • Pop stack sizeof(Foo)

Where the caller is doing:

  • Push stack sizeof(Foo)
  • call f() with A3 = SP+n (Foo x in caller frame)
  • ...
  • Pop stack sizeof(Foo)

So the stack usage is twice what it should be, and an otherwise-unnecessary call to memcpy() is generated.

What I would expect for f() given that A3 points to an already-allocated Foo is simply:

  • Do work on Foo x via A3

The only way I've been able to get any reasonable assembly code is to explicitly allocate Foo x in the caller frame, modify f() to accept e.g. a Foo & result, and operate directly on that reference inside f(). But this pattern breaks support for e.g. operator*(lhs,rhs).

Does "legacy" CGT support (N)RVO? Is there any way to get the compiler to optimize out the unnecessary stack push/pop and memcpy? Or is there a newer CGT with support for C6727?

  • I'm pretty sure the return value optimization (RVO) you expect is not available in the C6000 compiler.  To be certain on that point, I'd appreciate if I could get a test case.  Experience has shown that all the subtle details are important, and those details can only be supplied by you in the form of a test case.  I'd like to run that test case by a few folks.  For one source file that has this problem, please follow the directions in the article How to Submit a Compiler Test Case.

    Thanks and regards,

    -George

  • Edward Kaszubski said:
    So the stack usage is twice what it should be, and an otherwise-unnecessary call to memcpy() is generated.

    This sounds like might be related to the issue reported in Compiler/C6000-CGT: Increased stack usage in specific constructors. However, as requested by George a test case would help to confirm this.

  • Here are the relevant files:

    main.lst.sanitized.txt

    main.pp.sanitized.txt
    // cstddef standard header
    /* yvals.h values header for conforming compilers on various systems */
    /*****************************************************************************/
    /* stdarg.h   v7.4.24                                                        */
    /*                                                                           */
    /* Copyright (c) 1993-2018 Texas Instruments Incorporated                    */
    /* http://www.ti.com/                                                        */
    /*                                                                           */
    /*  Redistribution and  use in source  and binary forms, with  or without    */
    /*  modification,  are permitted provided  that the  following conditions    */
    /*  are met:                                                                 */
    /*                                                                           */
    /*     Redistributions  of source  code must  retain the  above copyright    */
    /*     notice, this list of conditions and the following disclaimer.         */
    /*                                                                           */
    /*     Redistributions in binary form  must reproduce the above copyright    */
    /*     notice, this  list of conditions  and the following  disclaimer in    */
    /*     the  documentation  and/or   other  materials  provided  with  the    */
    /*     distribution.                                                         */
    /*                                                                           */
    /*     Neither the  name of Texas Instruments Incorporated  nor the names    */
    /*     of its  contributors may  be used to  endorse or  promote products    */
    /*     derived  from   this  software  without   specific  prior  written    */
    /*     permission.                                                           */
    /*                                                                           */
    /*  THIS SOFTWARE  IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS    */
    /*  "AS IS"  AND ANY  EXPRESS OR IMPLIED  WARRANTIES, INCLUDING,  BUT NOT    */
    /*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR    */
    /*  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT    */
    /*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
    /*  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL  DAMAGES  (INCLUDING, BUT  NOT    */
    /*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,    */
    /*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY    */
    /*  THEORY OF  LIABILITY, WHETHER IN CONTRACT, STRICT  LIABILITY, OR TORT    */
    /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE    */
    /*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.     */
    /*                                                                           */
    /*****************************************************************************/
    
    
    namespace std
    {
    
       typedef char *va_list;
    
    }
    
    /*****************************************************************************/
    /* VA_END - Reclaim resources used by varargs handling.                      */
    /*                                                                           */
    /* No action needed                                                          */
    /*****************************************************************************/
    
    
    /*****************************************************************************/
    /* VA_START - Set up the va_list pointer.				     */
    /*****************************************************************************/
    
    
    
    /*---------------------------------------------------------------------------*/
    /* COFF ABI convention:                                                      */
    /* - va_list is kept aligned to 4 bytes.				     */
    /* - va_list pointer points one word beyond the start of the last argument.  */
    /*---------------------------------------------------------------------------*/
    
    
    
    /*****************************************************************************/
    /* VA_ARG - Return the next argument, adjust va_list pointer		     */
    /*                                                                           */
    /* Some arguments passed by value are turned into pass-by-reference by	     */
    /* making a temporary object and passing a pointer to this temporary.  For   */
    /* such an argument (indicated by __va_argref(_type)) the actual argument    */
    /* passed is a pointer, so it must be dealt with specially.		     */
    /*                                                                           */
    /* When an argument is larger than the maximum alignment (8 bytes for double */
    /* or long long), we only align to 8 bytes.				     */
    /*****************************************************************************/
    
    /*---------------------------------------------------------------------------*/
    /* What happens on every va_arg(_ap, _type) call is:			     */
    /* 1) Align the value of _ap (the va_list pointer) appropriately for _type   */
    /*    (the requested type).						     */
    /* 2) Increment _ap appropriately for _type.				     */
    /* 3) Return the value desired by dereferencing _ap.			     */
    /*---------------------------------------------------------------------------*/
    
    
    /*---------------------------------------------------------------------------*/
    /* The big- and little-endian variants are different only because we are     */
    /* trying to support the case of the user asking for "char" or "short",	     */
    /* which is actually undefined behavior (See ISO/IEC 9899:1999 7.15.1.1),    */
    /* but we are trying to be friendly.					     */
    /*---------------------------------------------------------------------------*/
    
    
    
    
    using std::va_list;
    
    
    
    /* You can predefine (on the compile command line, for example):
    
    _ALT_NS=1 -- to use namespace _Dinkum_std for C++
    _ALT_NS=2 -- to use namespace _Dinkum_std for C++ and C
    _C_AS_CPP -- to compile C library as C++
    _C_IN_NS -- to define C names in std/_Dinkum_std instead of global namespace
    _C99 -- to turn ON C99 library support
    _ABRCPP -- to turn ON Abridged C++ dialect (implies _ECPP)
    _ECPP -- to turn ON Embedded C++ dialect
    _NO_EX -- to turn OFF use of try/throw
    _NO_MT -- to turn OFF thread synchronization
    _NO_NS -- to turn OFF use of namespace declarations
    _STL_DB (or _STLP_DEBUG) -- to turn ON iterator/range debugging
    __NO_LONG_LONG -- to define _Longlong as long, not long long
    
    You can change (in this header):
    
    _ADDED_C_LIB -- from 1 to 0 to omit declarations for C extensions
    _COMPILER_TLS -- from 0 to 1 if _TLS_QUAL is not nil
    _EXFAIL -- from 1 to any nonzero value for EXIT_FAILURE
    _FILE_OP_LOCKS -- from 0 to 1 for file atomic locks
    _GLOBAL_LOCALE -- from 0 to 1 for shared locales instead of per-thread
    _HAS_IMMUTABLE_SETS -- from 1 to 0 to permit alterable set elements
    _HAS_STRICT_CONFORMANCE -- from 0 to 1 to disable nonconforming extensions
    _HAS_TRADITIONAL_IOSTREAMS -- from 1 to 0 to omit old iostreams functions
    _HAS_TRADITIONAL_ITERATORS -- from 0 to 1 for vector/string pointer iterators
    _HAS_TRADITIONAL_POS_TYPE -- from 0 to 1 for streampos same as streamoff
    _HAS_TRADITIONAL_STL -- from 1 to 0 to omit old STL functions
    _IOSTREAM_OP_LOCKS -- from 0 to 1 for iostream atomic locks
    _TLS_QUAL -- from nil to compiler TLS qualifier, such as __declspec(thread)
    _USE_EXISTING_SYSTEM_NAMES -- from 1 to 0 to disable mappings (_Open to open)
    
    Include directories needed to compile with Dinkum C:
    
    C -- include/c
    C99 -- include/c (define _C99)
    Embedded C++ -- include/c include/embedded (define _ECPP)
    Abridged C++ -- include/c include/embedded include (define _ABRCPP)
    Standard C++ -- include/c include
    Standard C++ with export -- include/c include/export include
    	(--export --template_dir=lib/export)
    
    Include directories needed to compile with native C:
    
    C -- none
    C99 -- N/A
    Embedded C++ -- include/embedded (define _ECPP)
    Abridged C++ -- include/embedded include (define _ABRCPP)
    Standard C++ -- include
    Standard C++ with export -- include/export include
    	(--export --template_dir=lib/export)
     */
    
    
     /* targets with "native" mode libraries don't support C9X */
    
     /* TI RTS supports the C9X snprintf() and vsnprintf() functions */
    
     /* TI C6x supports complex arithmetic */
    
    
    
    
    
    		/* DETERMINE MACHINE TYPE */
    
    
    
    		/* DETERMINE _Ptrdifft AND _Sizet FROM MACHINE TYPE */
    
    typedef long _Int32t;
    typedef unsigned long _Uint32t;
    
    typedef  int  _Ptrdifft;
    
    typedef  unsigned _Sizet;
    
    
    
    
    
    
    
    		/* EXCEPTION CONTROL */
    
    
    		/* NAMING PROPERTIES */
    /* #define _STD_LINKAGE	defines C names as extern "C++" */
    /* #define _STD_USING	defines C names in namespace std or _Dinkum_std */
    
    
    
     
    
    
    
    		/* THREAD AND LOCALE CONTROL */
     
    
    		/* THREAD-LOCAL STORAGE */
    
    
    
    
    
    		/* NAMESPACE CONTROL */
    
    
    namespace std {}
    
    
    
    
    
    
    
    
    
    
    
    
    
    namespace std {
    typedef bool _Bool;
    }
    
    		/* VC++ COMPILER PARAMETERS */
    
    
            /* defined(__NO_LONG_LONG) && !defined (_MSC_VER) && ! TI 32 bit processor*/
    
    		/* MAKE MINGW LOOK LIKE WIN32 HEREAFTER */
    
    
    
    namespace std {
    		/* FLOATING-POINT PROPERTIES */
    
    		/* INTEGER PROPERTIES */
    
    
    
    typedef long long _Longlong;
    typedef unsigned long long _ULonglong;
    
    
    		/* wchar_t AND wint_t PROPERTIES */
    
    
    typedef wchar_t _Wchart;
    typedef wchar_t _Wintt;
    
    
    		/* POINTER PROPERTIES */
    
    		/* signal PROPERTIES */
    
    
    		/* stdarg PROPERTIES */
    typedef ::std:: va_list _Va_list;
    
    
    		/* stdlib PROPERTIES */
    
    extern "C" {
    void _Atexit(void (*)(void));
    }
    
    		/* stdio PROPERTIES */
    
    typedef char _Sysch_t;
    
    		/* STORAGE ALIGNMENT PROPERTIES */
    
    		/* time PROPERTIES */
    }
    
    		/* MULTITHREAD PROPERTIES */
    
    		/* LOCK MACROS */
    
    
    namespace std {
    extern "C++" {	// in case of _C_AS_CPP
    		// CLASS _Lockit
    class _Lockit
    	{	// lock while object in existence -- MUST NEST
    public:
    
    
    	explicit _Lockit()
    		{	// do nothing
    		}
    
    	explicit _Lockit(int)
    		{	// do nothing
    		}
    
    	~_Lockit()
    		{	// do nothing
    		}
    
    
    public:
    	_Lockit(const _Lockit&);			// not defined
    	_Lockit& operator=(const _Lockit&);	// not defined
    	};
    
    class _Mutex
    	{	// lock under program control
    public:
    
        void _Lock()
    		{	// do nothing
    		}
    
    	void _Unlock()
    		{	// do nothing
    	}
    
    
    	};
    }	// extern "C++"
    }
    
    		/* MISCELLANEOUS MACROS */
    
    
    
    
    
    
    /*****************************************************************************/
    /* linkage.h   v7.4.24                                                       */
    /*                                                                           */
    /* Copyright (c) 1998-2018 Texas Instruments Incorporated                    */
    /* http://www.ti.com/                                                        */
    /*                                                                           */
    /*  Redistribution and  use in source  and binary forms, with  or without    */
    /*  modification,  are permitted provided  that the  following conditions    */
    /*  are met:                                                                 */
    /*                                                                           */
    /*     Redistributions  of source  code must  retain the  above copyright    */
    /*     notice, this list of conditions and the following disclaimer.         */
    /*                                                                           */
    /*     Redistributions in binary form  must reproduce the above copyright    */
    /*     notice, this  list of conditions  and the following  disclaimer in    */
    /*     the  documentation  and/or   other  materials  provided  with  the    */
    /*     distribution.                                                         */
    /*                                                                           */
    /*     Neither the  name of Texas Instruments Incorporated  nor the names    */
    /*     of its  contributors may  be used to  endorse or  promote products    */
    /*     derived  from   this  software  without   specific  prior  written    */
    /*     permission.                                                           */
    /*                                                                           */
    /*  THIS SOFTWARE  IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS    */
    /*  "AS IS"  AND ANY  EXPRESS OR IMPLIED  WARRANTIES, INCLUDING,  BUT NOT    */
    /*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR    */
    /*  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT    */
    /*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
    /*  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL  DAMAGES  (INCLUDING, BUT  NOT    */
    /*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,    */
    /*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY    */
    /*  THEORY OF  LIABILITY, WHETHER IN CONTRACT, STRICT  LIABILITY, OR TORT    */
    /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE    */
    /*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.     */
    /*                                                                           */
    /*****************************************************************************/
    
    
    /*--------------------------------------------------------------------------*/
    /* Define _CODE_ACCESS ==> how to call RTS functions                        */
    /*--------------------------------------------------------------------------*/
    
    /*--------------------------------------------------------------------------*/
    /* Define _DATA_ACCESS ==> how to access RTS global or static data          */
    /*--------------------------------------------------------------------------*/
    /*--------------------------------------------------------------------------*/
    /* Define _DATA_ACCESS_NEAR ==> some C6000 RTS data must always be near     */
    /*--------------------------------------------------------------------------*/
    
    /*--------------------------------------------------------------------------*/
    /* Define _IDECL ==> how inline functions are declared                      */
    /*--------------------------------------------------------------------------*/
    
    /*--------------------------------------------------------------------------*/
    /* If compiling with non-TI compiler (e.g. GCC), nullify any TI-specific    */
    /* language extensions.                                                     */
    /*--------------------------------------------------------------------------*/
    
    /*****************************************************************************/
    /*  _lock.h v7.4.24                                                          */
    /*                                                                           */
    /* Copyright (c) 2000-2018 Texas Instruments Incorporated                    */
    /* http://www.ti.com/                                                        */
    /*                                                                           */
    /*  Redistribution and  use in source  and binary forms, with  or without    */
    /*  modification,  are permitted provided  that the  following conditions    */
    /*  are met:                                                                 */
    /*                                                                           */
    /*     Redistributions  of source  code must  retain the  above copyright    */
    /*     notice, this list of conditions and the following disclaimer.         */
    /*                                                                           */
    /*     Redistributions in binary form  must reproduce the above copyright    */
    /*     notice, this  list of conditions  and the following  disclaimer in    */
    /*     the  documentation  and/or   other  materials  provided  with  the    */
    /*     distribution.                                                         */
    /*                                                                           */
    /*     Neither the  name of Texas Instruments Incorporated  nor the names    */
    /*     of its  contributors may  be used to  endorse or  promote products    */
    /*     derived  from   this  software  without   specific  prior  written    */
    /*     permission.                                                           */
    /*                                                                           */
    /*  THIS SOFTWARE  IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS    */
    /*  "AS IS"  AND ANY  EXPRESS OR IMPLIED  WARRANTIES, INCLUDING,  BUT NOT    */
    /*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR    */
    /*  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT    */
    /*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
    /*  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL  DAMAGES  (INCLUDING, BUT  NOT    */
    /*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,    */
    /*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY    */
    /*  THEORY OF  LIABILITY, WHETHER IN CONTRACT, STRICT  LIABILITY, OR TORT    */
    /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE    */
    /*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.     */
    /*                                                                           */
    /*****************************************************************************/
    
    
    
    extern "C" {
    
     void _nop();
    
    extern far void (  *_lock)();
    extern far void (*_unlock)();
    
     void _register_lock  (void (  *lock)());
     void _register_unlock(void (*unlock)());
    
    
    } /* extern "C" */
    
    
    
    /*
     * Copyright (c) 1992-2004 by P.J. Plauger.  ALL RIGHTS RESERVED.
     * Consult your license regarding permissions and restrictions.
    V4.02:1476 */
    
    
    /*****************************************************************************/
    /* stddef.h   v7.4.24                                                        */
    /*                                                                           */
    /* Copyright (c) 1993-2018 Texas Instruments Incorporated                    */
    /* http://www.ti.com/                                                        */
    /*                                                                           */
    /*  Redistribution and  use in source  and binary forms, with  or without    */
    /*  modification,  are permitted provided  that the  following conditions    */
    /*  are met:                                                                 */
    /*                                                                           */
    /*     Redistributions  of source  code must  retain the  above copyright    */
    /*     notice, this list of conditions and the following disclaimer.         */
    /*                                                                           */
    /*     Redistributions in binary form  must reproduce the above copyright    */
    /*     notice, this  list of conditions  and the following  disclaimer in    */
    /*     the  documentation  and/or   other  materials  provided  with  the    */
    /*     distribution.                                                         */
    /*                                                                           */
    /*     Neither the  name of Texas Instruments Incorporated  nor the names    */
    /*     of its  contributors may  be used to  endorse or  promote products    */
    /*     derived  from   this  software  without   specific  prior  written    */
    /*     permission.                                                           */
    /*                                                                           */
    /*  THIS SOFTWARE  IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS    */
    /*  "AS IS"  AND ANY  EXPRESS OR IMPLIED  WARRANTIES, INCLUDING,  BUT NOT    */
    /*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR    */
    /*  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT    */
    /*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
    /*  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL  DAMAGES  (INCLUDING, BUT  NOT    */
    /*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,    */
    /*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY    */
    /*  THEORY OF  LIABILITY, WHETHER IN CONTRACT, STRICT  LIABILITY, OR TORT    */
    /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE    */
    /*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.     */
    /*                                                                           */
    /*****************************************************************************/
    
    
    extern "C" namespace std {
    
    
    typedef int ptrdiff_t;
    
    typedef unsigned size_t;
    
    
    
    } /* extern "C" namespace std */
    
    
    
    /*-----------------------------------------------------------------------*/
    /* Define _win_t, for compiling GCC libraries with the TI compiler.      */
    /* GCC's library (newlib) expects wint_t to be defined here, in stddef.h,*/
    /* which is arguably incorrect, but we go along for compatibility.       */
    /* This is outside the _STDDEF guard in case this file has already       */
    /* been included without __need_wint_t.                                  */
    /*-----------------------------------------------------------------------*/
    
    
    /*
     * Copyright (c) 1992-2004 by P.J. Plauger.  ALL RIGHTS RESERVED.
     * Consult your license regarding permissions and restrictions.
    V4.02:1476 */
    /*****************************************************************************/
    /* STDINT.H v7.4.24                                                          */
    /*                                                                           */
    /* Copyright (c) 2002-2018 Texas Instruments Incorporated                    */
    /* http://www.ti.com/                                                        */
    /*                                                                           */
    /*  Redistribution and  use in source  and binary forms, with  or without    */
    /*  modification,  are permitted provided  that the  following conditions    */
    /*  are met:                                                                 */
    /*                                                                           */
    /*     Redistributions  of source  code must  retain the  above copyright    */
    /*     notice, this list of conditions and the following disclaimer.         */
    /*                                                                           */
    /*     Redistributions in binary form  must reproduce the above copyright    */
    /*     notice, this  list of conditions  and the following  disclaimer in    */
    /*     the  documentation  and/or   other  materials  provided  with  the    */
    /*     distribution.                                                         */
    /*                                                                           */
    /*     Neither the  name of Texas Instruments Incorporated  nor the names    */
    /*     of its  contributors may  be used to  endorse or  promote products    */
    /*     derived  from   this  software  without   specific  prior  written    */
    /*     permission.                                                           */
    /*                                                                           */
    /*  THIS SOFTWARE  IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS    */
    /*  "AS IS"  AND ANY  EXPRESS OR IMPLIED  WARRANTIES, INCLUDING,  BUT NOT    */
    /*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR    */
    /*  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT    */
    /*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
    /*  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL  DAMAGES  (INCLUDING, BUT  NOT    */
    /*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,    */
    /*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY    */
    /*  THEORY OF  LIABILITY, WHETHER IN CONTRACT, STRICT  LIABILITY, OR TORT    */
    /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE    */
    /*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.     */
    /*                                                                           */
    /*****************************************************************************/
    
    /* 7.18.1.1 Exact-width integer types */
    
        typedef   signed char   int8_t;
        typedef unsigned char  uint8_t;
        typedef          short  int16_t;
        typedef unsigned short uint16_t;
        typedef          int    int32_t;
        typedef unsigned int   uint32_t;
    
        typedef          __int40_t  int40_t;
        typedef unsigned __int40_t uint40_t;
    
        typedef          long long  int64_t;
        typedef unsigned long long uint64_t;
    
    /* 7.18.1.2 Minimum-width integer types */
    
        typedef  int8_t   int_least8_t;
        typedef uint8_t  uint_least8_t;
    
        typedef  int16_t  int_least16_t;
        typedef uint16_t uint_least16_t;
        typedef  int32_t  int_least32_t;
        typedef uint32_t uint_least32_t;
    
        typedef  int40_t  int_least40_t;
        typedef uint40_t uint_least40_t;
    
        typedef  int64_t  int_least64_t;
        typedef uint64_t uint_least64_t;
    
    /* 7.18.1.3 Fastest minimum-width integer types */
    
        typedef  int32_t  int_fast8_t;
        typedef uint32_t uint_fast8_t;
        typedef  int32_t  int_fast16_t;
        typedef uint32_t uint_fast16_t;
    
        typedef  int32_t  int_fast32_t;
        typedef uint32_t uint_fast32_t;
    
        typedef  int40_t  int_fast40_t;
        typedef uint40_t uint_fast40_t;
    
        typedef  int64_t  int_fast64_t;
        typedef uint64_t uint_fast64_t;
    
    /* 7.18.1.4 Integer types capable of holding object pointers */
        typedef          int intptr_t;
        typedef unsigned int uintptr_t;
    
    /* 7.18.1.5 Greatest-width integer types */
        typedef          long long intmax_t;
        typedef unsigned long long uintmax_t;
    
    /* 
       According to footnotes in the 1999 C standard, "C++ implementations
       should define these macros only when __STDC_LIMIT_MACROS is defined
       before <stdint.h> is included." 
    */
    
    
    struct Matrix3x3
    {
    	struct _Alloc
    	{
    		float linear[3*3];
    	} __attribute__((aligned(sizeof(uint64_t))));
    
    	_Alloc alloc;
    
    	Matrix3x3()
    	{
    		*(volatile uint32_t *)0x01234567 = 5432;
    	}
    
    	Matrix3x3(_Alloc const & _alloc) : alloc(_alloc)
    	{
    		*(volatile uint32_t *)0x12345678 = 4321;
    	}
    
    	Matrix3x3(Matrix3x3 const & other)
    	:
    		alloc(other.alloc)
    	{
    		*(volatile uint32_t *)0x23456789 = 3210;
    	}
    
    	Matrix3x3
    	operator-(Matrix3x3 const & restrict rhs) const;
    
    	friend Matrix3x3
    	operator+(Matrix3x3 const & restrict lhs, Matrix3x3 const & restrict rhs);
    };
    
    int main()
    {
    	Matrix3x3 const a((Matrix3x3::_Alloc){ 0, 1, 2, 3, 4, 5, 6, 7, 8});
    
    	Matrix3x3 const b((Matrix3x3::_Alloc){ 1, 2, 3, 4, 5, 6, 7, 8, 9});
    
    	Matrix3x3 x = a + b;
    
    	*(volatile float *)0x34567890 = x.alloc.linear[4];
    
    	Matrix3x3 y = a - b;
    
    	*(volatile float *)0x45678901 = y.alloc.linear[4];
    
    	return 0;
    }
    
    

    make.sh.sanitized.txt
    #!/bin/sh
    
    # output dir setup
    dirs="src/common/math/util/math src/common/platform/variant/cpp"
    for dir in $dirs; do mkdir -p $dir pp/$dir; done
    
    # compile
    "/home/eng/ti/ccsv7/tools/compiler/c6000_7.4.24/bin/cl6x" -mv67p --abi=coffabi -O3 --symdebug:skeletal --optimize_with_debug=on --include_path="/home/eng/ti/ccsv7/tools/compiler/c6000_7.4.24/include" --include_path="../src/common/math" --relaxed_ansi --gcc --define="CHIP_6727" --define=C67X --diag_suppress=179 --diag_suppress=230 --diag_suppress=270 --display_error_number --issue_remarks --diag_error=225 --diag_error=551 --gen_func_subsections=on --use_const_for_alias_analysis --sat_reassoc=on --mem_model:data=far_aggregates --gen_opt_info=2 --opt_for_speed=5 --fp_mode=relaxed --asm_listing --asm_directory="pp" --preproc_with_compile --preproc_dependency="pp/src/common/math/util/math/matrix2.d" --obj_directory="src/common/math/util/math" --define=VARIANT_cpp "../src/common/math/util/math/matrix2.cpp"
    
    "/home/eng/ti/ccsv7/tools/compiler/c6000_7.4.24/bin/cl6x" -mv67p --abi=coffabi -O3 --symdebug:skeletal --optimize_with_debug=on --include_path="/home/eng/ti/ccsv7/tools/compiler/c6000_7.4.24/include" --include_path="../src/common/math" --relaxed_ansi --gcc --define="CHIP_6727" --define=C67X --diag_suppress=179 --diag_suppress=230 --diag_suppress=270 --display_error_number --issue_remarks --diag_error=225 --diag_error=551 --gen_func_subsections=on --use_const_for_alias_analysis --sat_reassoc=on --mem_model:data=far_aggregates --gen_opt_info=2 --opt_for_speed=5 --fp_mode=relaxed --asm_listing --asm_directory="pp" --preproc_with_compile --preproc_dependency="pp/src/common/platform/variant/cpp/main.d" --obj_directory="src/common/platform/variant/cpp" --define=VARIANT_cpp "../src/common/platform/variant/cpp/main.cpp"
    
    # generate preprocessed source
    "/home/eng/ti/ccsv7/tools/compiler/c6000_7.4.24/bin/cl6x" -mv67p --abi=coffabi -O3 --symdebug:skeletal --optimize_with_debug=on --include_path="/home/eng/ti/ccsv7/tools/compiler/c6000_7.4.24/include" --include_path="../src/common/math" --relaxed_ansi --gcc --define="CHIP_6727" --define=C67X --diag_suppress=179 --diag_suppress=230 --diag_suppress=270 --display_error_number --issue_remarks --diag_error=225 --diag_error=551 --gen_func_subsections=on --use_const_for_alias_analysis --sat_reassoc=on --mem_model:data=far_aggregates --gen_opt_info=2 --opt_for_speed=5 --fp_mode=relaxed --asm_listing --asm_directory="pp" -ppc --obj_directory="src/common/math/util/math" --define=VARIANT_cpp "../src/common/math/util/math/matrix2.cpp"
    
    "/home/eng/ti/ccsv7/tools/compiler/c6000_7.4.24/bin/cl6x" -mv67p --abi=coffabi -O3 --symdebug:skeletal --optimize_with_debug=on --include_path="/home/eng/ti/ccsv7/tools/compiler/c6000_7.4.24/include" --include_path="../src/common/math" --relaxed_ansi --gcc --define="CHIP_6727" --define=C67X --diag_suppress=179 --diag_suppress=230 --diag_suppress=270 --display_error_number --issue_remarks --diag_error=225 --diag_error=551 --gen_func_subsections=on --use_const_for_alias_analysis --sat_reassoc=on --mem_model:data=far_aggregates --gen_opt_info=2 --opt_for_speed=5 --fp_mode=relaxed --asm_listing --asm_directory="pp" -ppc --obj_directory="src/common/platform/variant/cpp" --define=VARIANT_cpp "../src/common/platform/variant/cpp/main.cpp"
    

    matrix2.lst.sanitized.txt

    matrix2.pp.sanitized.txt
    // cstddef standard header
    /* yvals.h values header for conforming compilers on various systems */
    /*****************************************************************************/
    /* stdarg.h   v7.4.24                                                        */
    /*                                                                           */
    /* Copyright (c) 1993-2018 Texas Instruments Incorporated                    */
    /* http://www.ti.com/                                                        */
    /*                                                                           */
    /*  Redistribution and  use in source  and binary forms, with  or without    */
    /*  modification,  are permitted provided  that the  following conditions    */
    /*  are met:                                                                 */
    /*                                                                           */
    /*     Redistributions  of source  code must  retain the  above copyright    */
    /*     notice, this list of conditions and the following disclaimer.         */
    /*                                                                           */
    /*     Redistributions in binary form  must reproduce the above copyright    */
    /*     notice, this  list of conditions  and the following  disclaimer in    */
    /*     the  documentation  and/or   other  materials  provided  with  the    */
    /*     distribution.                                                         */
    /*                                                                           */
    /*     Neither the  name of Texas Instruments Incorporated  nor the names    */
    /*     of its  contributors may  be used to  endorse or  promote products    */
    /*     derived  from   this  software  without   specific  prior  written    */
    /*     permission.                                                           */
    /*                                                                           */
    /*  THIS SOFTWARE  IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS    */
    /*  "AS IS"  AND ANY  EXPRESS OR IMPLIED  WARRANTIES, INCLUDING,  BUT NOT    */
    /*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR    */
    /*  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT    */
    /*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
    /*  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL  DAMAGES  (INCLUDING, BUT  NOT    */
    /*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,    */
    /*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY    */
    /*  THEORY OF  LIABILITY, WHETHER IN CONTRACT, STRICT  LIABILITY, OR TORT    */
    /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE    */
    /*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.     */
    /*                                                                           */
    /*****************************************************************************/
    
    
    namespace std
    {
    
       typedef char *va_list;
    
    }
    
    /*****************************************************************************/
    /* VA_END - Reclaim resources used by varargs handling.                      */
    /*                                                                           */
    /* No action needed                                                          */
    /*****************************************************************************/
    
    
    /*****************************************************************************/
    /* VA_START - Set up the va_list pointer.				     */
    /*****************************************************************************/
    
    
    
    /*---------------------------------------------------------------------------*/
    /* COFF ABI convention:                                                      */
    /* - va_list is kept aligned to 4 bytes.				     */
    /* - va_list pointer points one word beyond the start of the last argument.  */
    /*---------------------------------------------------------------------------*/
    
    
    
    /*****************************************************************************/
    /* VA_ARG - Return the next argument, adjust va_list pointer		     */
    /*                                                                           */
    /* Some arguments passed by value are turned into pass-by-reference by	     */
    /* making a temporary object and passing a pointer to this temporary.  For   */
    /* such an argument (indicated by __va_argref(_type)) the actual argument    */
    /* passed is a pointer, so it must be dealt with specially.		     */
    /*                                                                           */
    /* When an argument is larger than the maximum alignment (8 bytes for double */
    /* or long long), we only align to 8 bytes.				     */
    /*****************************************************************************/
    
    /*---------------------------------------------------------------------------*/
    /* What happens on every va_arg(_ap, _type) call is:			     */
    /* 1) Align the value of _ap (the va_list pointer) appropriately for _type   */
    /*    (the requested type).						     */
    /* 2) Increment _ap appropriately for _type.				     */
    /* 3) Return the value desired by dereferencing _ap.			     */
    /*---------------------------------------------------------------------------*/
    
    
    /*---------------------------------------------------------------------------*/
    /* The big- and little-endian variants are different only because we are     */
    /* trying to support the case of the user asking for "char" or "short",	     */
    /* which is actually undefined behavior (See ISO/IEC 9899:1999 7.15.1.1),    */
    /* but we are trying to be friendly.					     */
    /*---------------------------------------------------------------------------*/
    
    
    
    
    using std::va_list;
    
    
    
    /* You can predefine (on the compile command line, for example):
    
    _ALT_NS=1 -- to use namespace _Dinkum_std for C++
    _ALT_NS=2 -- to use namespace _Dinkum_std for C++ and C
    _C_AS_CPP -- to compile C library as C++
    _C_IN_NS -- to define C names in std/_Dinkum_std instead of global namespace
    _C99 -- to turn ON C99 library support
    _ABRCPP -- to turn ON Abridged C++ dialect (implies _ECPP)
    _ECPP -- to turn ON Embedded C++ dialect
    _NO_EX -- to turn OFF use of try/throw
    _NO_MT -- to turn OFF thread synchronization
    _NO_NS -- to turn OFF use of namespace declarations
    _STL_DB (or _STLP_DEBUG) -- to turn ON iterator/range debugging
    __NO_LONG_LONG -- to define _Longlong as long, not long long
    
    You can change (in this header):
    
    _ADDED_C_LIB -- from 1 to 0 to omit declarations for C extensions
    _COMPILER_TLS -- from 0 to 1 if _TLS_QUAL is not nil
    _EXFAIL -- from 1 to any nonzero value for EXIT_FAILURE
    _FILE_OP_LOCKS -- from 0 to 1 for file atomic locks
    _GLOBAL_LOCALE -- from 0 to 1 for shared locales instead of per-thread
    _HAS_IMMUTABLE_SETS -- from 1 to 0 to permit alterable set elements
    _HAS_STRICT_CONFORMANCE -- from 0 to 1 to disable nonconforming extensions
    _HAS_TRADITIONAL_IOSTREAMS -- from 1 to 0 to omit old iostreams functions
    _HAS_TRADITIONAL_ITERATORS -- from 0 to 1 for vector/string pointer iterators
    _HAS_TRADITIONAL_POS_TYPE -- from 0 to 1 for streampos same as streamoff
    _HAS_TRADITIONAL_STL -- from 1 to 0 to omit old STL functions
    _IOSTREAM_OP_LOCKS -- from 0 to 1 for iostream atomic locks
    _TLS_QUAL -- from nil to compiler TLS qualifier, such as __declspec(thread)
    _USE_EXISTING_SYSTEM_NAMES -- from 1 to 0 to disable mappings (_Open to open)
    
    Include directories needed to compile with Dinkum C:
    
    C -- include/c
    C99 -- include/c (define _C99)
    Embedded C++ -- include/c include/embedded (define _ECPP)
    Abridged C++ -- include/c include/embedded include (define _ABRCPP)
    Standard C++ -- include/c include
    Standard C++ with export -- include/c include/export include
    	(--export --template_dir=lib/export)
    
    Include directories needed to compile with native C:
    
    C -- none
    C99 -- N/A
    Embedded C++ -- include/embedded (define _ECPP)
    Abridged C++ -- include/embedded include (define _ABRCPP)
    Standard C++ -- include
    Standard C++ with export -- include/export include
    	(--export --template_dir=lib/export)
     */
    
    
     /* targets with "native" mode libraries don't support C9X */
    
     /* TI RTS supports the C9X snprintf() and vsnprintf() functions */
    
     /* TI C6x supports complex arithmetic */
    
    
    
    
    
    		/* DETERMINE MACHINE TYPE */
    
    
    
    		/* DETERMINE _Ptrdifft AND _Sizet FROM MACHINE TYPE */
    
    typedef long _Int32t;
    typedef unsigned long _Uint32t;
    
    typedef  int  _Ptrdifft;
    
    typedef  unsigned _Sizet;
    
    
    
    
    
    
    
    		/* EXCEPTION CONTROL */
    
    
    		/* NAMING PROPERTIES */
    /* #define _STD_LINKAGE	defines C names as extern "C++" */
    /* #define _STD_USING	defines C names in namespace std or _Dinkum_std */
    
    
    
     
    
    
    
    		/* THREAD AND LOCALE CONTROL */
     
    
    		/* THREAD-LOCAL STORAGE */
    
    
    
    
    
    		/* NAMESPACE CONTROL */
    
    
    namespace std {}
    
    
    
    
    
    
    
    
    
    
    
    
    
    namespace std {
    typedef bool _Bool;
    }
    
    		/* VC++ COMPILER PARAMETERS */
    
    
            /* defined(__NO_LONG_LONG) && !defined (_MSC_VER) && ! TI 32 bit processor*/
    
    		/* MAKE MINGW LOOK LIKE WIN32 HEREAFTER */
    
    
    
    namespace std {
    		/* FLOATING-POINT PROPERTIES */
    
    		/* INTEGER PROPERTIES */
    
    
    
    typedef long long _Longlong;
    typedef unsigned long long _ULonglong;
    
    
    		/* wchar_t AND wint_t PROPERTIES */
    
    
    typedef wchar_t _Wchart;
    typedef wchar_t _Wintt;
    
    
    		/* POINTER PROPERTIES */
    
    		/* signal PROPERTIES */
    
    
    		/* stdarg PROPERTIES */
    typedef ::std:: va_list _Va_list;
    
    
    		/* stdlib PROPERTIES */
    
    extern "C" {
    void _Atexit(void (*)(void));
    }
    
    		/* stdio PROPERTIES */
    
    typedef char _Sysch_t;
    
    		/* STORAGE ALIGNMENT PROPERTIES */
    
    		/* time PROPERTIES */
    }
    
    		/* MULTITHREAD PROPERTIES */
    
    		/* LOCK MACROS */
    
    
    namespace std {
    extern "C++" {	// in case of _C_AS_CPP
    		// CLASS _Lockit
    class _Lockit
    	{	// lock while object in existence -- MUST NEST
    public:
    
    
    	explicit _Lockit()
    		{	// do nothing
    		}
    
    	explicit _Lockit(int)
    		{	// do nothing
    		}
    
    	~_Lockit()
    		{	// do nothing
    		}
    
    
    public:
    	_Lockit(const _Lockit&);			// not defined
    	_Lockit& operator=(const _Lockit&);	// not defined
    	};
    
    class _Mutex
    	{	// lock under program control
    public:
    
        void _Lock()
    		{	// do nothing
    		}
    
    	void _Unlock()
    		{	// do nothing
    	}
    
    
    	};
    }	// extern "C++"
    }
    
    		/* MISCELLANEOUS MACROS */
    
    
    
    
    
    
    /*****************************************************************************/
    /* linkage.h   v7.4.24                                                       */
    /*                                                                           */
    /* Copyright (c) 1998-2018 Texas Instruments Incorporated                    */
    /* http://www.ti.com/                                                        */
    /*                                                                           */
    /*  Redistribution and  use in source  and binary forms, with  or without    */
    /*  modification,  are permitted provided  that the  following conditions    */
    /*  are met:                                                                 */
    /*                                                                           */
    /*     Redistributions  of source  code must  retain the  above copyright    */
    /*     notice, this list of conditions and the following disclaimer.         */
    /*                                                                           */
    /*     Redistributions in binary form  must reproduce the above copyright    */
    /*     notice, this  list of conditions  and the following  disclaimer in    */
    /*     the  documentation  and/or   other  materials  provided  with  the    */
    /*     distribution.                                                         */
    /*                                                                           */
    /*     Neither the  name of Texas Instruments Incorporated  nor the names    */
    /*     of its  contributors may  be used to  endorse or  promote products    */
    /*     derived  from   this  software  without   specific  prior  written    */
    /*     permission.                                                           */
    /*                                                                           */
    /*  THIS SOFTWARE  IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS    */
    /*  "AS IS"  AND ANY  EXPRESS OR IMPLIED  WARRANTIES, INCLUDING,  BUT NOT    */
    /*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR    */
    /*  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT    */
    /*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
    /*  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL  DAMAGES  (INCLUDING, BUT  NOT    */
    /*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,    */
    /*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY    */
    /*  THEORY OF  LIABILITY, WHETHER IN CONTRACT, STRICT  LIABILITY, OR TORT    */
    /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE    */
    /*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.     */
    /*                                                                           */
    /*****************************************************************************/
    
    
    /*--------------------------------------------------------------------------*/
    /* Define _CODE_ACCESS ==> how to call RTS functions                        */
    /*--------------------------------------------------------------------------*/
    
    /*--------------------------------------------------------------------------*/
    /* Define _DATA_ACCESS ==> how to access RTS global or static data          */
    /*--------------------------------------------------------------------------*/
    /*--------------------------------------------------------------------------*/
    /* Define _DATA_ACCESS_NEAR ==> some C6000 RTS data must always be near     */
    /*--------------------------------------------------------------------------*/
    
    /*--------------------------------------------------------------------------*/
    /* Define _IDECL ==> how inline functions are declared                      */
    /*--------------------------------------------------------------------------*/
    
    /*--------------------------------------------------------------------------*/
    /* If compiling with non-TI compiler (e.g. GCC), nullify any TI-specific    */
    /* language extensions.                                                     */
    /*--------------------------------------------------------------------------*/
    
    /*****************************************************************************/
    /*  _lock.h v7.4.24                                                          */
    /*                                                                           */
    /* Copyright (c) 2000-2018 Texas Instruments Incorporated                    */
    /* http://www.ti.com/                                                        */
    /*                                                                           */
    /*  Redistribution and  use in source  and binary forms, with  or without    */
    /*  modification,  are permitted provided  that the  following conditions    */
    /*  are met:                                                                 */
    /*                                                                           */
    /*     Redistributions  of source  code must  retain the  above copyright    */
    /*     notice, this list of conditions and the following disclaimer.         */
    /*                                                                           */
    /*     Redistributions in binary form  must reproduce the above copyright    */
    /*     notice, this  list of conditions  and the following  disclaimer in    */
    /*     the  documentation  and/or   other  materials  provided  with  the    */
    /*     distribution.                                                         */
    /*                                                                           */
    /*     Neither the  name of Texas Instruments Incorporated  nor the names    */
    /*     of its  contributors may  be used to  endorse or  promote products    */
    /*     derived  from   this  software  without   specific  prior  written    */
    /*     permission.                                                           */
    /*                                                                           */
    /*  THIS SOFTWARE  IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS    */
    /*  "AS IS"  AND ANY  EXPRESS OR IMPLIED  WARRANTIES, INCLUDING,  BUT NOT    */
    /*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR    */
    /*  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT    */
    /*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
    /*  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL  DAMAGES  (INCLUDING, BUT  NOT    */
    /*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,    */
    /*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY    */
    /*  THEORY OF  LIABILITY, WHETHER IN CONTRACT, STRICT  LIABILITY, OR TORT    */
    /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE    */
    /*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.     */
    /*                                                                           */
    /*****************************************************************************/
    
    
    
    extern "C" {
    
     void _nop();
    
    extern far void (  *_lock)();
    extern far void (*_unlock)();
    
     void _register_lock  (void (  *lock)());
     void _register_unlock(void (*unlock)());
    
    
    } /* extern "C" */
    
    
    
    /*
     * Copyright (c) 1992-2004 by P.J. Plauger.  ALL RIGHTS RESERVED.
     * Consult your license regarding permissions and restrictions.
    V4.02:1476 */
    
    
    /*****************************************************************************/
    /* stddef.h   v7.4.24                                                        */
    /*                                                                           */
    /* Copyright (c) 1993-2018 Texas Instruments Incorporated                    */
    /* http://www.ti.com/                                                        */
    /*                                                                           */
    /*  Redistribution and  use in source  and binary forms, with  or without    */
    /*  modification,  are permitted provided  that the  following conditions    */
    /*  are met:                                                                 */
    /*                                                                           */
    /*     Redistributions  of source  code must  retain the  above copyright    */
    /*     notice, this list of conditions and the following disclaimer.         */
    /*                                                                           */
    /*     Redistributions in binary form  must reproduce the above copyright    */
    /*     notice, this  list of conditions  and the following  disclaimer in    */
    /*     the  documentation  and/or   other  materials  provided  with  the    */
    /*     distribution.                                                         */
    /*                                                                           */
    /*     Neither the  name of Texas Instruments Incorporated  nor the names    */
    /*     of its  contributors may  be used to  endorse or  promote products    */
    /*     derived  from   this  software  without   specific  prior  written    */
    /*     permission.                                                           */
    /*                                                                           */
    /*  THIS SOFTWARE  IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS    */
    /*  "AS IS"  AND ANY  EXPRESS OR IMPLIED  WARRANTIES, INCLUDING,  BUT NOT    */
    /*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR    */
    /*  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT    */
    /*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
    /*  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL  DAMAGES  (INCLUDING, BUT  NOT    */
    /*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,    */
    /*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY    */
    /*  THEORY OF  LIABILITY, WHETHER IN CONTRACT, STRICT  LIABILITY, OR TORT    */
    /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE    */
    /*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.     */
    /*                                                                           */
    /*****************************************************************************/
    
    
    extern "C" namespace std {
    
    
    typedef int ptrdiff_t;
    
    typedef unsigned size_t;
    
    
    
    } /* extern "C" namespace std */
    
    
    
    /*-----------------------------------------------------------------------*/
    /* Define _win_t, for compiling GCC libraries with the TI compiler.      */
    /* GCC's library (newlib) expects wint_t to be defined here, in stddef.h,*/
    /* which is arguably incorrect, but we go along for compatibility.       */
    /* This is outside the _STDDEF guard in case this file has already       */
    /* been included without __need_wint_t.                                  */
    /*-----------------------------------------------------------------------*/
    
    
    /*
     * Copyright (c) 1992-2004 by P.J. Plauger.  ALL RIGHTS RESERVED.
     * Consult your license regarding permissions and restrictions.
    V4.02:1476 */
    /*****************************************************************************/
    /* STDINT.H v7.4.24                                                          */
    /*                                                                           */
    /* Copyright (c) 2002-2018 Texas Instruments Incorporated                    */
    /* http://www.ti.com/                                                        */
    /*                                                                           */
    /*  Redistribution and  use in source  and binary forms, with  or without    */
    /*  modification,  are permitted provided  that the  following conditions    */
    /*  are met:                                                                 */
    /*                                                                           */
    /*     Redistributions  of source  code must  retain the  above copyright    */
    /*     notice, this list of conditions and the following disclaimer.         */
    /*                                                                           */
    /*     Redistributions in binary form  must reproduce the above copyright    */
    /*     notice, this  list of conditions  and the following  disclaimer in    */
    /*     the  documentation  and/or   other  materials  provided  with  the    */
    /*     distribution.                                                         */
    /*                                                                           */
    /*     Neither the  name of Texas Instruments Incorporated  nor the names    */
    /*     of its  contributors may  be used to  endorse or  promote products    */
    /*     derived  from   this  software  without   specific  prior  written    */
    /*     permission.                                                           */
    /*                                                                           */
    /*  THIS SOFTWARE  IS PROVIDED BY THE COPYRIGHT  HOLDERS AND CONTRIBUTORS    */
    /*  "AS IS"  AND ANY  EXPRESS OR IMPLIED  WARRANTIES, INCLUDING,  BUT NOT    */
    /*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR    */
    /*  A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT    */
    /*  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,    */
    /*  SPECIAL,  EXEMPLARY,  OR CONSEQUENTIAL  DAMAGES  (INCLUDING, BUT  NOT    */
    /*  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,    */
    /*  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY    */
    /*  THEORY OF  LIABILITY, WHETHER IN CONTRACT, STRICT  LIABILITY, OR TORT    */
    /*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE    */
    /*  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.     */
    /*                                                                           */
    /*****************************************************************************/
    
    /* 7.18.1.1 Exact-width integer types */
    
        typedef   signed char   int8_t;
        typedef unsigned char  uint8_t;
        typedef          short  int16_t;
        typedef unsigned short uint16_t;
        typedef          int    int32_t;
        typedef unsigned int   uint32_t;
    
        typedef          __int40_t  int40_t;
        typedef unsigned __int40_t uint40_t;
    
        typedef          long long  int64_t;
        typedef unsigned long long uint64_t;
    
    /* 7.18.1.2 Minimum-width integer types */
    
        typedef  int8_t   int_least8_t;
        typedef uint8_t  uint_least8_t;
    
        typedef  int16_t  int_least16_t;
        typedef uint16_t uint_least16_t;
        typedef  int32_t  int_least32_t;
        typedef uint32_t uint_least32_t;
    
        typedef  int40_t  int_least40_t;
        typedef uint40_t uint_least40_t;
    
        typedef  int64_t  int_least64_t;
        typedef uint64_t uint_least64_t;
    
    /* 7.18.1.3 Fastest minimum-width integer types */
    
        typedef  int32_t  int_fast8_t;
        typedef uint32_t uint_fast8_t;
        typedef  int32_t  int_fast16_t;
        typedef uint32_t uint_fast16_t;
    
        typedef  int32_t  int_fast32_t;
        typedef uint32_t uint_fast32_t;
    
        typedef  int40_t  int_fast40_t;
        typedef uint40_t uint_fast40_t;
    
        typedef  int64_t  int_fast64_t;
        typedef uint64_t uint_fast64_t;
    
    /* 7.18.1.4 Integer types capable of holding object pointers */
        typedef          int intptr_t;
        typedef unsigned int uintptr_t;
    
    /* 7.18.1.5 Greatest-width integer types */
        typedef          long long intmax_t;
        typedef unsigned long long uintmax_t;
    
    /* 
       According to footnotes in the 1999 C standard, "C++ implementations
       should define these macros only when __STDC_LIMIT_MACROS is defined
       before <stdint.h> is included." 
    */
    
    
    struct Matrix3x3
    {
    	struct _Alloc
    	{
    		float linear[3*3];
    	} __attribute__((aligned(sizeof(uint64_t))));
    
    	_Alloc alloc;
    
    	Matrix3x3()
    	{
    		*(volatile uint32_t *)0x01234567 = 5432;
    	}
    
    	Matrix3x3(_Alloc const & _alloc) : alloc(_alloc)
    	{
    		*(volatile uint32_t *)0x12345678 = 4321;
    	}
    
    	Matrix3x3(Matrix3x3 const & other)
    	:
    		alloc(other.alloc)
    	{
    		*(volatile uint32_t *)0x23456789 = 3210;
    	}
    
    	Matrix3x3
    	operator-(Matrix3x3 const & restrict rhs) const;
    
    	friend Matrix3x3
    	operator+(Matrix3x3 const & restrict lhs, Matrix3x3 const & restrict rhs);
    };
    
    Matrix3x3
    Matrix3x3::operator-(Matrix3x3 const & restrict rhs) const
    {
    	Matrix3x3 result;
    	for(uint32_t i = 0; i < 3*3; ++i)
    	{
    		result.alloc.linear[i] = this->alloc.linear[i] - rhs.alloc.linear[i];
    	}
    	return result;
    }
    
    Matrix3x3
    operator+(Matrix3x3 const & restrict lhs, Matrix3x3 const & restrict rhs)
    {
    	Matrix3x3 result;
    	for(uint32_t i = 0; i < 3*3; ++i)
    	{
    		result.alloc.linear[i] = lhs.alloc.linear[i] + rhs.alloc.linear[i];
    	}
    	return result;
    }
    

    Sorry for all the edits, I don't see a way to preview the post before submitting it.

    To illustrate this test case, I compiled the code using our existing toolchain, then grabbed the generated commands, sanitized them, and put them into a make.sh. I then cleared out the build folder and ran make.sh from the build folder. The (sanitized) results are provided, along with make.sh.

    The special addresses and values in the constructors are to quickly identify which constructors are being called in the assembly. The behavior is unchanged if they're removed.

  • Thank you for the test case.  I filed the issue EXT_EP-9755 to have this issue investigated.  It does not report a bug, but requests an improvement in the compiler.  You are welcome to follow it with the link below in my signature.

    Thanks and regards,

    -George

  • Thanks, George (and Chester).

    I looked at the issue you created; so you compiled the code with CGT 8.3.4 as well and saw the same behavior? So it appears as though RVO is not implemented in any version of the C6000 compiler, as you originally suggested? While we're on the subject can you please confirm whether 7.4.24 is the newest/recommended CGT for our platform?

    Given that we are on a legacy platform it looks like we will probably never be able to take advantage of any of future compiler improvements, and due to the copy overhead will probably never be able to use operator* or any similar functions that do not operate in-place. That's a shame, but we should still be able to use other in-place operators like +=, -=, etc which should not depend on RVO for efficiency.

    Thanks again for looking into this!

  • Edward Kaszubski said:
    I looked at the issue you created; so you compiled the code with CGT 8.3.4 as well and saw the same behavior?

    Yes

    Edward Kaszubski said:
    So it appears as though RVO is not implemented in any version of the C6000 compiler, as you originally suggested?

    Yes

    Edward Kaszubski said:
    please confirm whether 7.4.24 is the newest/recommended CGT for our platform?

    It is.  To elaborate ... It is the last release of the C6000 compiler to support C6700+, as well as the older COFF ABI.  You use both.

    Edward Kaszubski said:
    Given that we are on a legacy platform it looks like we will probably never be able to take advantage of any of future compiler improvements

    Unfortunately, that is accurate.

    All the same, thank you for bringing this issue to our attention.  I cannot make any promises.  But it seems likely this will get addressed in a future release.

    Thanks and regards,

    -George

  • One partial solution to consider is inlining.  You already build with --opt_level=3, so automatic inlining is among the optimizations which are used.  Consider using the option --auto_inline=large_number to inline functions that could use RVO.  Please search the C6000 compiler manual for the sub-chapter titled Automatic Inline Expansion.

    Thanks and regards,

    -George

  • I should have included it in my test case but I believe during my initial testing I tried force-inlining with #pragma FUNC_ALWAYS_INLINE() to no avail; the extra stack push and memcpy was still taking place, just in main() instead of in operator+/operator-. I'll repeat that experiment along with your suggestion in case I'm not remembering correctly or in case these scenarios are handled differently by the compiler. Thanks!

  • I tried the following forms of inlining:

    1. Manually, via #pragma FUNC_ALWAYS_INLINE()
    2. Implicitly, by providing the function definition inside the class definition
    3. Automatically, via --auto_inline=999999

    None of these had the desired effect; the copy constructor (and therefore memcpy) was still called in all cases, but just in main() instead of in the Matrix functions.

    Here are some (N)RVO references including additional examples/test cases:

    https://en.wikipedia.org/wiki/Copy_elision

    https://en.cppreference.com/w/cpp/language/copy_elision

    https://docs.microsoft.com/en-us/previous-versions/ms364057(v=vs.80)

    https://shaharmike.com/cpp/rvo/#return-value-optimization

  • Inlining does not directly address the RVO problem.  Rather, because everything now occurs within a single function, there is a chance some of the copies may be optimized away.  As you have seen, it does not always work out.

    Thanks and regards,

    -George