This slide presentation (PDF)

Code Generation Tools Tips & Tricks
For All TI Code Generation Tools
July 2008
1
Actually Read the Readme
•
•
•
•
•
This talk only covers the highlights
Many more features covered in the readme files
Critical detail as well
Well worth the 1 hour it takes to read it
Find it at install\target\readme.1st
– install: Directory where CCS is installed
– target: C2000, C5400, C5500, C6000, or tms470
2
Agenda
•
•
•
•
•
•
•
•
•
•
•
•
3
Recommended Development Flow
Types and Alignment
16 x 16 Î 32 Multiply
Memory Models
Diagnostics
C Headers in Assembly
Object Format vs. Debug Format
More Useful Utilities
Interrupt Intrinsics
Predefined Symbols for Version
Remaining Tips
Top 10 Mistaken Ideas
Characterize Common Problems
• Common problems seen when learning C/C++
• Difference between == and =
• Must use int when comparing to EOF
getchar();
cc == getchar();
while (c
(c !=
!= EOF)
EOF) //
// cc must
must be
be type
type int
int
while
{{
……
getchar();
cc == getchar();
}}
• 1.0 is a double
• This talk covers a similar class of issues
commonly seen by users new to TI compilers
4
Recommended Development Flow
Start
No
Edit
Compile -g
Debug
Works?
Yes
No
Done
Yes
Goals Met?
• Separate use of –g and -o
5
Profile
Compile -o
Optimization vs. Debug
• As one improves the other degrades
• If you combine them together …
• Effects on debugging
– Operations reordered
– Variables eliminated
• Effects on performance
– Instruction scheduling is impaired
• Compare performance -o vs. –o -g
– C6x MP3 decoder
– -o runs 16% faster than –o -g
6
Optimization Levels
Option
Scope
Default
None
-o0
Statement
-o1
Block
-o2 or -o
Function
-o3
File
low
high
• Optimization is critical!
• Not on by default
• Option is –olevel where level is 0-3
• Start with level 2
7
More Optimization Hints
• Optimization may uncover user errors like:
– Uninitialized variables
– Loose adherence to ANSI standard
– Failure to use volatile
• Use volatile on variables modified by:
– Interrupts
– Peripherals
– Other processors
• volatile controls order of access, not timing
8
Agenda
•
•
•
•
•
•
•
•
•
•
•
•
9
Recommended Development Flow
Types and Alignment
16 x 16 Î 32 Multiply
Memory Models
Diagnostics
C Headers in Assembly
Object Format vs. Debug Format
More Useful Utilities
Interrupt Intrinsics
Predefined Symbols for Version
Remaining Tips
Top 10 Mistaken Ideas
Type Sizes by CPU
Hosted
C6000TM
470
C55xTM
C28xTM
char
8
8
8
16
16
short
16
16
16
16
16
int
32
32
32
16
16
long
32
40
32
32
32
long long
64
64
64
40
32
float
32
32
32
32
32
double
64
64
64
32
32
long double
64
64
64
32
32
Type
• Shaded sizes Æ different from hosted systems
10
Type Differences
• Because char is 16-bits on C55xTM and C28xTM
– sizeof(int) == sizeof(char) == 1
– Redefines the term byte
– 8-bit wide external streams must be handled carefully
– Application note SPRA757 on fread()/fwrite()
• On 470 plain char is unsigned
– Use plain char only for ASCII chars
• Floating point is very slow on CPU’s without
hardware support
11
Standard Integer Typedefs
• stdint.h defines standard names for exact width
integer types
#if
#if
defined(__TMS320C2000__) ||
|| defined(_TMS320C5XX)
defined(_TMS320C5XX) \\
defined(__TMS320C2000__)
|| defined(__TMS320C55X__)
defined(__TMS320C55X__)
||
typedef
int
int16_t;
typedef
int
int16_t;
typedef unsigned
unsigned int
int uint16_t;
uint16_t;
typedef
typedef
long int32_t;
int32_t;
typedef
long
typedef unsigned
unsigned long
long uint32_t;
uint32_t;
typedef
#elif defined(_TMS320C6X)
defined(_TMS320C6X) ||
|| defined(__TMS470__)
defined(__TMS470__)
#elif
typedef signed
signed char
char int8_t;
int8_t;
typedef
typedef unsigned
unsigned char
char uint8_t;
uint8_t;
typedef
typedef
short int16_t;
int16_t;
typedef
short
typedef unsigned
unsigned short
short uint16_t;
uint16_t;
typedef
typedef
int
int32_t;
typedef
int
int32_t;
typedef unsigned
unsigned int
int uint32_t;
uint32_t;
typedef
#elif defined(__MSP430__)
defined(__MSP430__)
#elif
……
• Other typedefs: minimum width, fastest, etc.
• No need to define your own
12
inttypes.h
• Another header file for standardizing types
• Includes stdint.h
• Also defines printf format strings
#include <inttypes.h>
<inttypes.h>
#include
……
printf(“%” PRId32
PRId32 “\n”,
“\n”, (int32_t)
(int32_t) 1);
1); //
// portable
portable
printf(“%”
Printf(“%d\n”, (int32_t)
(int32_t) 1);
1);
// not
not portable
portable
Printf(“%d\n”,
//
– Note careful use of commas in first printf
13
Alignment & Structures
• Alignment is different from hosted systems
• Misaligned access
– x86: Works but imposes cycle penalty
– TI CPUs: Fails silently
• TI CPUs alignment == size of type (few
exceptions)
• Structures are laid out differently between CPU’s
–
–
–
–
14
Order of members is guaranteed
Any member, or the whole struct, may be aligned
No method for packing data in structs
Affects exchanging data with external sources
Agenda
•
•
•
•
•
•
•
•
•
•
•
•
15
Recommended Development Flow
Types and Alignment
16 x 16 Î 32 Multiply
Memory Models
Diagnostics
C Headers in Assembly
Object Format vs. Debug Format
More Useful Utilities
Interrupt Intrinsics
Predefined Symbols for Version
Remaining Tips
Top 10 Mistaken Ideas
16 X 16 Î 32 Multiply
• Do not write …
long_var = short_var1 * short_var2;
• Instead write …
long_var = (long) short_var1 * (long) short_var2;
•
•
•
•
Very important when sizeof(int) != sizeof(long)
Accurately represents operation
Implemented efficiently
Details in application note SPRA683
– Search for SPRA683 at www.ti.com
16
Agenda
•
•
•
•
•
•
•
•
•
•
•
•
17
Recommended Development Flow
Types and Alignment
16 x 16 Î 32 Multiply
Memory Models
Diagnostics
C Headers in Assembly
Object Format vs. Debug Format
More Useful Utilities
Interrupt Intrinsics
Predefined Symbols for Version
Remaining Tips
Top 10 Mistaken Ideas
Understanding Memory Models
Large
Small
Full
Partial
Code Size
Larger
Smaller
Speed
Slower
Faster
See docs
Default
Memory Range
To enable
18
Understanding Memory Models
19
CPU
Extends
Because
C6000TM
Code
PC-relative branches
C6000TM
Data
DP-offset global variables
C55xTM
Data
2 ways to access globals
2 sizes of address registers
C28xTM
Data
2 sizes of address registers
Agenda
•
•
•
•
•
•
•
•
•
•
•
•
20
Recommended Development Flow
Types and Alignment
16 x 16 Î 32 Multiply
Memory Models
Diagnostics
C Headers in Assembly
Object Format vs. Debug Format
More Useful Utilities
Interrupt Intrinsics
Predefined Symbols for Version
Remaining Tips
Top 10 Mistaken Ideas
Compiler Diagnostics
Remark
Warning
Error
Severity
Low
Medium
High
Build fails?
No
No
Yes
To enable
-pdr
Default
Default
• Is it okay to ignore remarks?
21
Automatic Error Detection
• Remarks expose common bugs
• This complete program compiles fine
void main()
main() {{ printf(“hello,
printf(“hello, world\n”);
world\n”); }}
void
• But doesn’t work
• Compile with –pdr to see remarks
“hello.c”, line
line 1:
1: remark:
remark: function
function declared
declared implicitly
implicitly
“hello.c”,
• Always build with –pdr!
• Take remarks seriously
• Always include required RTS header files
#include <stdio.h>
<stdio.h>
#include
• Always prototype user functions
22
Elevate Remark to Error
• Force remark to cause build to fail
• Use 2 separate compilation steps
• First, use –pden –pdr to see remark number
"hello.c", line
line 1:
1: remark
remark #225-D:
#225-D: function
function declared
declared implicitly
implicitly
"hello.c",
• Second, use –pdsenum to elevate the remark
• In this case –pdse225 gives
"hello.c", line
line 1:
1: error:
error: function
function declared
declared implicitly
implicitly
"hello.c",
error detected
detected in
in the
the compilation
compilation of
of "hello.c".
"hello.c".
11 error
>> Compilation
Compilation failure
failure
>>
• Can use –pdse225, without –pdr, on all builds
23
Control Diagnostic Levels
• First identify diagnostic id with -pden
Set level to:
Remark
Option
-pdsrid
#pragma
#pragma diag_remark id
Warning
-pdswid
#pragma diag_warning id
Error
-pdseid
#pragma diag_error id
Default
none
-pdsid
#pragma diag_default id
Suppress
#pragma diag_suppress id
• Diagnostics with “-D” appended to id can be
suppressed or changed
– All warnings and remarks
– A few errors
• #pragma is alternative to -pdsXXX
• #pragma provides line by line control
24
Diagnostic Control Example
int ex(int i)
{
switch (i)
{
case 10 :
return val();
break;
/* line 7
*/
/* line 9
*/
…
}
}
C:\dir> cl55 –pden –pdr ex.c
"ex.c", line 7: remark #225-D: function declared implicitly
"ex.c", line 9: warning #112-D: statement is unreachable
25
Diagnostic Control Example
#pragma diag_error 225
/* Require explicit function decls
int ex(int i)
{
switch (i)
{
case 10 :
return val();
/* line 7
#pragma diag_suppress 112
/* suppress msg on break
break;
/* line 9
#pragma diag_default 112
/* restore msg level
…
}
}
C:\dir> cl55 –pden –pdr ex.c
"ex.c", line 7: error #225-D: function declared implicitly
1 error detected in the compilation of "ex.c".
>> Compilation failure
• #pragma is alternative to -pdsXXX
• #pragma provides precise control
26
*/
*/
*/
*/
*/
Verbose Diagnostics -pdv
• For this source line
extern struct
struct example;
example;
extern
• The diagnostic is
“ex.c", line
line 1:
1: warning:
warning: aa storage
storage class
class may
may not
not be
be specified
specified here
here
“ex.c",
• To avoid confusion add -pdv
“ex.c", line
line 1:
1: warning:
warning: aa storage
storage class
class may
may not
not be
be specified
specified here
here
“ex.c",
extern struct
struct example;
example;
extern
^^
27
Agenda
•
•
•
•
•
•
•
•
•
•
•
•
28
Recommended Development Flow
Types and Alignment
16 x 16 Î 32 Multiply
Memory Models
Diagnostics
C Headers in Assembly
Object Format vs. Debug Format
More Useful Utilities
Interrupt Intrinsics
Predefined Symbols for Version
Remaining Tips
Top 10 Mistaken Ideas
C Headers in Assembly
.cdecls optional
optional parameters
parameters
.cdecls
%{
%{
/* C/C++
C/C++ code
code here,
here, usually
usually #include’s
#include’s */
*/
/*
%}
%}
•
Converted constructs (usually found in .h files)
– function/variable declarations (prototypes)
– structs, unions, enumerations
– Non-function-like macros
•
NOT converted
– function/variable definitions
– function-like macros
•
•
•
•
29
Each .cdecls region is separate context
Conversion after pre-processing
Option to warn on each construct NOT converted
Includes generated assembly code in listing file
How C/C++ is Transformed
hd.h
#define WANT_ID 1
#define NAME ”Jari\n”
extern int var;
extern float cvt(int src);
struct duo {
int ifld;
float ffld;
};
enum status {
OK = 1,
FAIL = 256
};
30
.cdecls C, LIST, “hd.h”
----------------------------.define ”1”, WANT_ID
.define ”””Jari\n”””, NAME
.global _var
.global _cvt
duo .struct 0,
ifld .field 16
.field 16
ffld .field 32
.endstruct
status .enum
OK
.emember
FAIL
.emember
.endenum
2
; pretty and
; informative
; comments
1
256
Typical Usage
hd.h
#define WANT_ID 1
#define NAME ”Jari\n”
extern int var;
extern float cvt(int src);
struct duo {
int ifld;
float ffld;
};
enum status {
OK = 1,
FAIL = 256
};
31
.cdecls C, LIST, ”hd.h”
.data
.if $defined(WANT_ID)
id:
.cstring NAME
.endif
.bss data, $sizeof(duo)
data: .tag duo
...
hope:
AR1 = #data
AC0 = *AR1(#(duo.ifld)) << 16
dbl(*AR1(#(duo.ffld))) = AC0
AR0 = #id
T0 = #(status.OK)
return
Agenda
•
•
•
•
•
•
•
•
•
•
•
•
32
Recommended Development Flow
Types and Alignment
16 x 16 Î 32 Multiply
Memory Models
Diagnostics
C Headers in Assembly
Object Format vs. Debug Format
More Useful Utilities
Interrupt Intrinsics
Predefined Symbols for Version
Remaining Tips
Top 10 Mistaken Ideas
Object Format vs. Debug Format
• COFF and ELF are object file formats
• Stabs and Dwarf are debug information formats
• Unfortunately, sometimes the term COFF is used
to refer to Stabs debug format
• Object file formats
– All current tools support COFF
– Future tools will support ELF
• Debug file formats
– Tools before CCS 2.2 supported only Stabs
– CCS 2.2 tools support Stabs (default) and Dwarf
– CCS 3.1 tools support Dwarf (default) and Stabs
(deprecated)
– Future tools will support Dwarf only
33
Agenda
•
•
•
•
•
•
•
•
•
•
•
•
34
Recommended Development Flow
Types and Alignment
16 x 16 Î 32 Multiply
Memory Models
Diagnostics
C Headers in Assembly
Object Format vs. Debug Format
More Useful Utilities
Interrupt Intrinsics
Predefined Symbols for Version
Remaining Tips
Top 10 Mistaken Ideas
More Useful Utilities
• nmXX: Lists symbol table in .out or .obj file
• stripXX: Strips symbol and debug information
from .out file
• demXX: Demangles symbols into their C++ form
• disXX: Disassembler
– Not on some ISA’s
• Replace XX with the abbreviation for your ISA,
e.g. nm6x, strip55, etc.
• Documented in online help
35
Agenda
•
•
•
•
•
•
•
•
•
•
•
•
36
Recommended Development Flow
Types and Alignment
16 x 16 Î 32 Multiply
Memory Models
Diagnostics
C Headers in Assembly
Object Format vs. Debug Format
More Useful Utilities
Interrupt Intrinsics
Predefined Symbols for Version
Remaining Tips
Top 10 Mistaken Ideas
Interrupt Intrinsics
• For enabling/disabling interrupts
unsigned int
int _disable_interrupts();
_disable_interrupts();
// 33 cycles
cycles on
on C6000
C6000
unsigned
//
unsigned int
int _enable_interrupts();
_enable_interrupts();
// 33 cycles
cycles on
on C6000
C6000
unsigned
//
void
_restore_interrupts(unsigned int);
int); //
// 11 cycle
cycle on
on C6000
C6000
void
_restore_interrupts(unsigned
• Disable and enable return interrupt state before
change; use that value when restoring state
• Barriers to optimization
• Usage example …
unsigned int
int local;
local;
unsigned
local == _disable_interrupts();
_disable_interrupts();
local
if (sem)
(sem) sem--;
sem--;
/* atomic
atomic test/update
test/update of
of semaphore
semaphore */
*/
if
/*
_restore_interrupts(local);
_restore_interrupts(local);
• Replacement for HWI_disable(), HWI_restore()
– Faster. HWI_disable on C64x takes 16 cycles.
• Cycle counts given are “best case” numbers
37
– Ignores cache effects, memory latency, etc.
Agenda
•
•
•
•
•
•
•
•
•
•
•
•
38
Recommended Development Flow
Types and Alignment
16 x 16 Î 32 Multiply
Memory Models
Diagnostics
C Headers in Assembly
Object Format vs. Debug Format
More Useful Utilities
Interrupt Intrinsics
Predefined Symbols for Version
Remaining Tips
Top 10 Mistaken Ideas
Predefined Symbols for Version
• __TI_COMPILER_VERSION__ and
__TI_ASSEMBLER_VERSION__
• Returns int corresponding to compiler version
• Version number breaks down:
–
–
–
–
Major number (1-2 digits)
Minor version (3 digits)
Patch version (3 digits)
Example: v5.1.0 Î 5 001 000 Î 5001000
• Workaround compiler bugs
#if defined(_TMS320C6X)
defined(_TMS320C6X) &&
&& __TI_COMPILER_VERSION__
__TI_COMPILER_VERSION__ ==
== 5001000
5001000
#if
workaround C6x
C6x compiler
compiler bug
bug
workaround
#endif
#endif
• Target independent test for TI compiler
#if defined(__TI_COMPILER_VERSION__)
defined(__TI_COMPILER_VERSION__)
#if
does not
not work
work with
with older
older compilers!
compilers!
does
#endif
#endif
39
Agenda
•
•
•
•
•
•
•
•
•
•
•
•
40
Recommended Development Flow
Types and Alignment
16 x 16 Î 32 Multiply
Memory Models
Diagnostics
C Headers in Assembly
Object Format vs. Debug Format
More Useful Utilities
Interrupt Intrinsics
Predefined Symbols for Version
Remaining Tips
Top 10 Mistaken Ideas
Remaining Tips
• C++ code is usually very efficient
• Avoid asm() statements. Instead:
– Use intrinsics int_prod =
– Call assembly routines
_smpy(int_op1, int_op2); // C6000
• #pragma is compiler specific and does not port
• C++ is not a proper superset of C
– http://david.tribble.com/text/cdiffs.htm (link)
• Manuals online
– http://www.ti.com/sc/docs/psheets/man_dsp.htm (link)
• C FAQ
– http://www.eskimo.com/~scs/C-faq/faq.html (link)
• C++ FAQ
– http://www.parashift.com/c++-faq-lite (link)
41
Agenda
•
•
•
•
•
•
•
•
•
•
•
•
42
Recommended Development Flow
Types and Alignment
16 x 16 Î 32 Multiply
Memory Models
Diagnostics
C Headers in Assembly
Object Format vs. Debug Format
More Useful Utilities
Interrupt Intrinsics
Predefined Symbols for Version
Remaining Tips
Top 10 Mistaken Ideas
Top 10 Mistaken Ideas
1. Development: Embedded == Hosted
2. Don’t worry about memory placement
3. Ignore remarks (-pdr)
4. Optimization does not matter
5. It’s easy to debug optimized code
6. 8-bit char is ANSI standard
7. Structures work the same across all processors
8. Default memory model is always big enough
9. Ignore linker warnings (–w)
10. Global variables are initialized to 0
43