Skip to content

Commit d2f7f1b

Browse files
Force inlining of inline print[ln] methods
Add GCC __attribute__ ((__always_inline__)) to inlined methods in Print.h. This seems necessary since not doing so increases the executable size (probably because that would create several function definitions), even with LTO optimizations. This change combined with the inlining of print/printf methods seems to reduce the executable size for most applications by a fair amount. (Note that the `inline` keyword does not imply actual inlining.)
1 parent ceee9e9 commit d2f7f1b

File tree

2 files changed

+32
-24
lines changed

2 files changed

+32
-24
lines changed

Diff for: hardware/arduino/avr/cores/arduino/Print.h

+16-12
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#define OCT 8
3232
#define BIN 2
3333

34+
#define _always_inline __attribute__ ((__always_inline__)) // undefined at end
35+
3436
class Print
3537
{
3638
private:
@@ -61,22 +63,24 @@ class Print
6163
size_t print(unsigned long, int = DEC);
6264
size_t print(double, int = 2);
6365

64-
size_t print(const char str[]) { return write(str); }
65-
size_t print(const char c) { return write(c); }
66-
size_t print(const Printable &x) { return x.printTo(*this); }
66+
_always_inline size_t print(const char str[]) { return write(str); }
67+
_always_inline size_t print(const char c) { return write(c); }
68+
_always_inline size_t print(const Printable &x) { return x.printTo(*this); }
6769

68-
size_t print( signed char n, int f = DEC) { return print(( signed long) n, f); }
69-
size_t print( signed short n, int f = DEC) { return print(( signed long) n, f); }
70-
size_t print( signed int n, int f = DEC) { return print(( signed long) n, f); }
71-
size_t print(unsigned char n, int f = DEC) { return print((unsigned long) n, f); }
72-
size_t print(unsigned short n, int f = DEC) { return print((unsigned long) n, f); }
73-
size_t print(unsigned int n, int f = DEC) { return print((unsigned long) n, f); }
74-
size_t print( float n, int f = 2 ) { return print(( double ) n, f); }
70+
_always_inline size_t print( signed char n, int f = DEC) { return print(( signed long) n, f); }
71+
_always_inline size_t print( signed short n, int f = DEC) { return print(( signed long) n, f); }
72+
_always_inline size_t print( signed int n, int f = DEC) { return print(( signed long) n, f); }
73+
_always_inline size_t print(unsigned char n, int f = DEC) { return print((unsigned long) n, f); }
74+
_always_inline size_t print(unsigned short n, int f = DEC) { return print((unsigned long) n, f); }
75+
_always_inline size_t print(unsigned int n, int f = DEC) { return print((unsigned long) n, f); }
76+
_always_inline size_t print( float n, int f = 2 ) { return print(( double ) n, f); }
7577

7678
size_t println(void);
7779

78-
template<typename T> size_t println(const T &arg) { size_t t = print(arg); return t + println(); }
79-
template<typename T> size_t println(const T &n, int f) { size_t t = print(n, f); return t + println(); }
80+
template<typename T> _always_inline size_t println(const T &arg) { size_t t = print(arg); return t + println(); }
81+
template<typename T> _always_inline size_t println(const T &n, int f) { size_t t = print(n, f); return t + println(); }
8082
};
8183

84+
#undef _always_inline
85+
8286
#endif

Diff for: hardware/arduino/sam/cores/arduino/Print.h

+16-12
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
#define OCT 8
3232
#define BIN 2
3333

34+
#define _always_inline __attribute__ ((__always_inline__)) // undefined at end
35+
3436
class Print
3537
{
3638
private:
@@ -61,22 +63,24 @@ class Print
6163
size_t print(unsigned long, int = DEC);
6264
size_t print(double, int = 2);
6365

64-
size_t print(const char str[]) { return write(str); }
65-
size_t print(const char c) { return write(c); }
66-
size_t print(const Printable &x) { return x.printTo(*this); }
66+
_always_inline size_t print(const char str[]) { return write(str); }
67+
_always_inline size_t print(const char c) { return write(c); }
68+
_always_inline size_t print(const Printable &x) { return x.printTo(*this); }
6769

68-
size_t print( signed char n, int f = DEC) { return print(( signed long) n, f); }
69-
size_t print( signed short n, int f = DEC) { return print(( signed long) n, f); }
70-
size_t print( signed int n, int f = DEC) { return print(( signed long) n, f); }
71-
size_t print(unsigned char n, int f = DEC) { return print((unsigned long) n, f); }
72-
size_t print(unsigned short n, int f = DEC) { return print((unsigned long) n, f); }
73-
size_t print(unsigned int n, int f = DEC) { return print((unsigned long) n, f); }
74-
size_t print( float n, int f = 2 ) { return print(( double ) n, f); }
70+
_always_inline size_t print( signed char n, int f = DEC) { return print(( signed long) n, f); }
71+
_always_inline size_t print( signed short n, int f = DEC) { return print(( signed long) n, f); }
72+
_always_inline size_t print( signed int n, int f = DEC) { return print(( signed long) n, f); }
73+
_always_inline size_t print(unsigned char n, int f = DEC) { return print((unsigned long) n, f); }
74+
_always_inline size_t print(unsigned short n, int f = DEC) { return print((unsigned long) n, f); }
75+
_always_inline size_t print(unsigned int n, int f = DEC) { return print((unsigned long) n, f); }
76+
_always_inline size_t print( float n, int f = 2 ) { return print(( double ) n, f); }
7577

7678
size_t println(void);
7779

78-
template<typename T> size_t println(const T &arg) { size_t t = print(arg); return t + println(); }
79-
template<typename T> size_t println(const T &n, int f) { size_t t = print(n, f); return t + println(); }
80+
template<typename T> _always_inline size_t println(const T &arg) { size_t t = print(arg); return t + println(); }
81+
template<typename T> _always_inline size_t println(const T &n, int f) { size_t t = print(n, f); return t + println(); }
8082
};
8183

84+
#undef _always_inline
85+
8286
#endif

0 commit comments

Comments
 (0)